Selbstgemachter Computer von der AON-Karte

Kürzlich sind auf Habré mehrere Artikel über hausgemachte Computer erschienen, die aus verschiedenen nicht standardmäßigen Komponenten hergestellt wurden. Ich beschloss auch, über meinen Computer zu sprechen, der 1993 erstellt wurde. Im Zuge der allgemeinen Begeisterung für Sinclair wollte ich einen komplett originalen 8-Bit-Computer auf Basis von z80 haben und zusätzlich Software dafür erstellen, angefangen beim Betriebssystem bis hin zu Spielzeug. Was dabei herauskam, lesen Sie unter dem Schnitt.

Die erste Frage, die sich beim Erstellen Ihres Computers stellte, war die Frage der Architektur. Ich entschied, dass es kompakt genug sein würde, basierend auf dem z80-Prozessor, ohne ein Bild auf einem Fernseher anzuzeigen, aber mit einem LCD-Textbildschirm, einer ziemlich großen Tastatur, einer Tonausgabe in Form eines einfarbigen Hochtöners (damals Standard für die meisten Computer) und einem RS232-Anschluss zum Anschließen auf andere Computer zum Programmieren und Debuggen.

Es trat jedoch ein Problem auf, wo eine Leiterplatte für eine vollständig originale Schaltung erhältlich war, da die Chinesen 1993 noch keine Leiterplatten für die ganze Welt hergestellt hatten und es sehr teuer war, Entwicklung und Produktion im Werk zu bestellen. Und dann wandte ich mich den Tafeln zu, aus denen die Anrufer-IDs erstellt wurden - automatische Anrufer-IDs. Sie waren auf dem Mitinsky-Markt erhältlich, hatten die Möglichkeit, die von mir benötigten Komponenten zu installieren, mussten aber verbessert werden. Zum Verkauf standen verschiedene Arten solcher Leiterplatten, von denen ich, wenn ich mich recht erinnere, eine Leiterplatte namens "Rus" auswählte.

Ich möchte Sie für junge Leser daran erinnern, was AON war. Es war ein Telefon mit Tastenwahl (zu dieser Zeit war es übrigens ziemlich cool, da die meisten Telefone eine sich drehende Scheibe hatten), bestehend aus 12 Tasten und einer leuchtenden 9-Bit-7-Segment-Anzeige, auf der die Telefonnummer angezeigt wurde, wenn es war möglich, einige andere Informationen zu ermitteln. Die AON-Karte enthielt einen z80-Prozessor, einen parallelen Anschluss 8058055, eine Decoderschaltung, einen Timer 58053, ein 32-Kilobyte-ROM (mit UV-Löschung), einen statischen 8-Kilobyte-RAM, den an die Telefonleitung angeschlossenen analogen Teil und möglicherweise etwas anderes was ich in den letzten Jahren vergessen habe.

Die 12-Tasten-Tastatur und die Anzeige in der Anrufer-ID passten nicht zu mir, da sie normalerweise keine Informationen eingeben oder anzeigen konnten (insbesondere keine Buchstaben). Aus diesem Grund wurde beschlossen, eine hausgemachte Tastatur mit 40 Tasten und einen 24-stelligen 2-Zeilen-LCD-Bildschirm mit 24 Zeichen zu verwenden, der dann zum Verkauf angeboten wurde. Um die Tastatur und den LCD-Bildschirm zu verbinden, musste das AON-Schema geändert werden. Das erste, was ich tat, war, den gesamten analogen Teil der Telefonleitung wegzuwerfen, oder besser gesagt, ich habe ihn einfach nicht versiegelt. Gleichzeitig wurden die Ausgangszweige des Decoders, der die Indikatorentladung auswählte, und die Zweige des Parallelanschlusses 8058055 freigegeben. Der LCD-Bildschirm benötigte 4 Zeilen für die Übertragung von Informationen, für die Tastatur musste jedoch ein Decoder verwendet werden.Da 40 Tasten auf der Tastatur in einer Matrix aus 5 Reihen zu je 8 Teilen angeordnet waren, wurde beschlossen, diese 8 Tasten mit dem Decoder zu verbinden, damit sie gescannt werden können, indem dem Decodereingang verschiedene Kombinationen von drei Zeilen zugeführt und mit dem KR580VB55 5 Werte aus den Tastenreihen gelesen werden. Somit war der Scan-Code der gedrückten Taste auf der Tastatur ein Byte groß, wobei die ersten drei Bits die Spalte bestimmten, in der die Taste gedrückt wurde, und die verbleibenden 5 Bits angaben, in welcher Zeile diese Taste (oder mehrere Tasten gleichzeitig) gedrückt wurde . Außerdem war ich der Meinung, dass 8 Kilobyte RAM nicht ausreichen würden, und ersetzte es durch 32 Kilobyte. Gleichzeitig musste ich ein paar Spuren auf der Leiterplatte neu löten, zum Glück waren die 8- und 32-Kilobyte-RAM-Gehäuse in der Pinbelegung fast identisch. Auf diese Weise,Ich habe 32 Kilobyte ROM und 32 Kilobyte RAM (ich erinnere mich, dass der z80 maximal 64 Kilobyte adressieren kann, so dass ich den Adressraum maximal genutzt habe). Darüber hinaus gingen zwei weitere Leitungen von 8058055 an die serielle RS232-Schnittstelle, die für die Verbindung mit einem anderen Computer erforderlich ist. Ich habe all diese Wirtschaftlichkeit in den Fall des Testers gesteckt. Das Ergebnis ist dieses Design:

Bild

Nachdem die Hardware fertig war, war es Zeit, Software zu erstellen. Hier ist anzumerken, dass der Entstehungsprozess überhaupt nicht so aussah, wie er heute aussieht. Erstens wurde das meiste davon in Assembler z80 geschrieben (obwohl zu dieser Zeit fast alle Programme für solche Systeme in Assembler geschrieben wurden, außer BASIC). Für die Kompilierung vom Assembler in der ersten Phase half mir mein Freund, der einen Profi-Computer hatte - einen Sinclair-Klon, aber mit TR-DOS an Bord. Dann begann ich, meinen IBM-PC OS / 2 zu verwenden, auf dem MS-DOS in einem separaten Fenster ausgeführt wurde, in dem wiederum der TR-DOS-Emulator gestartet wurde, in dem die Kompilierung stattfand. Ich muss sagen, als die Software merklich wuchs, dauerte der Kompilierungs- und Montageprozess zehn Minuten. Das zweite Problem wardass es keine Debugging-Tools gab und es daher notwendig war, jedes Mal alles auf meinen selbstgemachten Computer herunterzuladen und zu überprüfen, wie es funktioniert (das erste, was getan werden musste, war ein Programm zum Arbeiten mit RS232 mit 9600 Bit pro Sekunde zum Herunterladen). Und schließlich sollte gesagt werden, dass es nach dem Debuggen des ROM-Images notwendig war, es in dieses ROM selbst zu schreiben, nachdem zuvor gelöscht wurde, was bereits dort geschrieben wurde. Die Löschung wurde unter Verwendung einer UV-Bräunungslampe durch ein spezielles Fenster im Mikroschaltungsgehäuse durchgeführt, das dann mit einem speziellen schwarzen Klebepapier abgedeckt wurde, das dazu dient, das Loch an der Seite einer 5-Zoll-Diskette abzudichten, um es vor dem Schreiben zu schützen. Da ich keinen Programmierer hatte, um eine neue Version der Software in ROM zu schreiben, musste ich jedes Mal, wenn ich zu meinem Freund ans andere Ende von Moskau musste,Wer hatte diesen Programmierer. Hier muss die Frage geklärt werden, wie es möglich war, das Image des ROM zu debuggen, ohne es in dieses ROM zu laden. Dafür gab es eine Basisadresse, die meine gesamte Software verwendete und die Adressen um 32 Kilobyte verschob. Das heißt, ein neues ROM-Image wurde in den RAM geladen und dort debuggt. Nach dem Debuggen wurde die Basisadresse auf Null gesetzt, alles wurde erneut kompiliert, und ich ging zu einem Freund, um eine neue Version im ROM zu schreiben.Alles wurde wieder kompiliert und ich ging zu einem Freund, um eine neue Version im ROM zu schreiben.Alles wurde wieder kompiliert und ich ging zu einem Freund, um eine neue Version im ROM zu schreiben.

Als der Prozess des "Codierens" - "Debuggens" - "Firmware" debuggt wurde, stellte sich die Frage, ein Betriebssystem zu schreiben. Das Betriebssystem musste Tastatureingaben unterstützen, Informationen auf einem LCD-Bildschirm anzeigen, die Ausgabe verschiedener Sounds unterstützen und dies alles parallel tun, wenn möglich, dh Multitasking. Für all dies wurde die folgende Architektur ausgewählt - es gab drei Arten von Aufgaben im Betriebssystem: mehrere Echtzeitaufgaben mit der höchsten Priorität, eine Benutzeraufgabe, die mit der Person selbst interagierte, und Hintergrundaufgaben, die funktionierten, wenn der Prozessor inaktiv war. Ich habe Aufgaben mit der höchsten Priorität für den Interrupt aufgehängt, der 10 Mal pro Sekunde vom KR580VI53-Timer generiert wurde. Es sollte gesagt werden, dass in der Anrufer-ID Interrupts 400 Mal pro Sekunde generiert wurden, da es notwendig war, den Indikator sehr oft zu aktualisieren, um dies zu tundamit eine Person kein Flackern bemerkt. Zusätzlich zur Aktualisierung der Anzeige in Interrupts wurde die Tastatur nach der Suche nach der gedrückten Taste abgefragt. Eine so häufige Unterbrechung in AON führte dazu, dass der größte Teil der Prozessorzeit tatsächlich für Interrupts aufgewendet wurde und ich wollte, dass mein Computer etwas anderes Nützliches tut. Da ich einen LCD-Bildschirm als Informationsanzeigegerät installiert habe, der über einen eigenen Speicher verfügt und keine dynamische Aktualisierung benötigt, war die Notwendigkeit einer solchen Interruptfrequenz nicht mehr erforderlich. Es wurde experimentell festgestellt, dass 10 Unterbrechungen pro Sekunde ausreichen, um die Tastatur abzufragen.dass der größte Teil der Prozessorzeit tatsächlich für Interrupts aufgewendet wurde und ich wollte, dass mein Computer etwas anderes Nützliches tut. Da ich einen LCD-Bildschirm als Informationsanzeigegerät installiert habe, der über einen eigenen Speicher verfügt und keine dynamische Aktualisierung benötigt, war die Notwendigkeit einer solchen Interruptfrequenz nicht mehr erforderlich. Es wurde experimentell festgestellt, dass 10 Unterbrechungen pro Sekunde ausreichen, um die Tastatur abzufragen.dass der größte Teil der Prozessorzeit tatsächlich für Interrupts aufgewendet wurde und ich wollte, dass mein Computer etwas anderes Nützliches tut. Da ich einen LCD-Bildschirm als Informationsanzeigegerät installiert habe, der über einen eigenen Speicher verfügt und keine dynamische Aktualisierung benötigt, war die Notwendigkeit einer solchen Interruptfrequenz nicht mehr erforderlich. Es wurde experimentell festgestellt, dass 10 Unterbrechungen pro Sekunde ausreichen, um die Tastatur abzufragen.

So wurden bei jedem Interrupt Echtzeitaufgaben gestartet und neue Informationen in eine spezielle Ereigniswarteschlange gestellt. Es gab verschiedene Arten von Ereignissen, die Informationen enthielten, die dem Ereignistyp entsprachen. Beispielsweise enthielt das Ereignis mit gedrückter Taste einen Scan-Code. Tatsächlich war eine der vorrangigen Aufgaben, die bei jedem Interrupt gestartet wurden, das Abfragen der Tastatur und das programmgesteuerte Entfernen von Kontaktsprüngen. Zusätzlich zu dieser Aufgabe gab es auch vorrangige Aufgaben - Zeitgeber, die die Benutzeraufgabe einstellen konnte und die nach einer bestimmten Zeit das entsprechende Ereignis in die Warteschlange stellten, Alarme, die zu einer bestimmten Zeit, Uhrzeit und einem bestimmten Kalender arbeiteten, und es gab auch eine Aufgabe, bei der Musik abgespielt wurde Die Programmierung von KR580VI53 und die Eingabe wurden mit Daten in Form von Notizen versehen. Auf diese Weise,Die Aufgabe des Benutzers könnte einfach anfangen, Musik abzuspielen und andere Dinge zu tun.

Nützliche Arbeit auf meinem Computer wurde von einer Benutzeraufgabe erledigt, die ereignisgesteuert war. Eine typische Ansicht einer solchen Aufgabe sah aus wie:

while(true) {
  Event e;

  GetEvent(e);

  /* process event */
}


Hier wartete die Funktion GetEvent (e) darauf, dass das Ereignis in der Warteschlange angezeigt wurde, und füllte beim Auftreten die Ereignisstruktur aus. Es ist klar, dass das Programm gemäß einem bestimmten Ereignis eine Endlosschleife verlassen und die Steuerung zurück an den Systemmonitor übertragen kann, der Benutzeraufgaben gestartet hat. Da Ereignisse in der Benutzeraufgabe normalerweise schnell verarbeitet wurden, wartete das Programm darauf, dass ein neues Ereignis in der GetEvent (e) -Prozedur angezeigt wurde. Um diese Erwartung irgendwie zu nutzen, wurden Hintergrundaufgaben eingeführt, die das Anwenderprogramm ausführen konnte und die unabhängig voneinander funktionierten. Das heißt, wenn ein Interrupt vom Timer auftritt, wurden die Echtzeitaufgaben zuerst durch Platzieren von Ereignissen in der Warteschlange erfüllt. Nach Abschluss des Interrupts verarbeitete die Benutzeraufgabe alle Ereignisse aus der Warteschlange und die verbleibende Zeit bis zum nächsten Interrupt für Hintergrundaufgaben.Heute sieht ein solches Schema natürlich aus, aber 1993 war es sehr fortschrittlich.

Es gab ein weiteres Problem im Zusammenhang mit der Tatsache, dass auf dem LCD-Bildschirm keine russischen Buchstaben angezeigt werden konnten. Dies lag an der Tatsache, dass solche Indikatoren gerade auf unserem Markt erschienen sind und niemand sie speziell russifiziert hat. Natürlich gab es keine Bibliotheken für die Arbeit mit ihnen, aber es gab nur eine Spezifikation und Beschreibung der Befehle. Daher mussten alle Arbeiten zur Initialisierung und zur Arbeit damit von Grund auf neu geschrieben werden. Ich habe das Problem mit der Russifizierung wie folgt gelöst: Es wurde eine spezielle Prozedur geschrieben, deren Eingabe eine Zeichenfolge mit russischem Text war, die angezeigt werden musste. Dieses Verfahren ersetzte alle lateinischen Buchstaben, die dem Lateinischen ähnlich waren, durch entsprechende lateinische Buchstaben, und diejenigen, die nicht ersetzt werden konnten, wurden im laufenden Betrieb mit benutzerdefinierten Bildern erstellt, die auf den LCD-Bildschirm heruntergeladen werden konnten. Es sollte notiert werdendass es acht solcher Benutzerbilder gab und dementsprechend im russischen Text nicht mehr als acht Buchstaben enthalten konnten, von denen Analoga nicht im lateinischen Alphabet waren. Aber normalerweise war es genug. Eine weitere lustige Gelegenheit, die ich genutzt habe, war, dass Sie eine lustige Animation erhalten, wenn Sie Benutzerbilder für einen Charakter ändern. Ich habe diese Gelegenheit im Pionierspiel genutzt, das ich weiter unten diskutieren werde, wo die Flagge über der gefundenen Mine im Wind flattert und die Bombe explodiert.Ich habe diese Gelegenheit im Pionierspiel genutzt, das ich weiter unten diskutieren werde, wo die Flagge über der Mine im Wind geflogen ist und die Bombe explodiert.Ich habe diese Gelegenheit im Pionierspiel genutzt, das ich weiter unten diskutieren werde, wo die Flagge über der Mine im Wind geflogen ist und die Bombe explodiert.

Jetzt erzähle ich Ihnen von den Benutzeraufgaben, die ich für meinen Computer erstellt habe. Als ich anfing, sie zu erstellen, wurde mir schnell klar, dass das Schreiben in Assembler, wie es damals jeder für Systeme wie Sinclair tat, ziemlich traurig ist. Da ich C auf einem IBM PC programmiert habe, habe ich darüber nachgedacht, ob es möglich ist, auf C und auf meinem Computer zu programmieren. Nach einiger Suche fand ich außerdem einen Compiler aus der C-Sprache für TR-DOS in seiner klassischen K & R-Version. Dieser Compiler war eher primitiv, er überprüfte beispielsweise nicht, ob die Anzahl der an die Prozedur übergebenen Parameter ihrer tatsächlichen Anzahl entsprach, ganz zu schweigen von der Überprüfung ihrer Typen. Aber wenn ich diesen Compiler für meinen Computer verwenden könnte, wäre das ein enormer Fortschritt. Das Problem war, wie der von diesem Compiler empfangene Code für meinen Computer angepasst werden konnte.Hier bin ich den klassischen Weg gegangen, den wir bereits vergessen haben, und 1993 haben sie sich noch daran erinnert. Auf diese Weise wurde der Quellcode nicht direkt in die Objektdatei, sondern in den Assembler-Quellcode kompiliert. Daher mussten nur Makros geschrieben werden, mit denen die aus dem Code kompilierten Assembler-Prozeduren aufgerufen werden konnten und umgekehrt, wobei die Parameter korrekt übertragen wurden. Die Verwendung dieses Compilers bot neben der Bequemlichkeit der Arbeit mit Code einen weiteren großen Vorteil: Es wurde möglich, mit ganzzahliger Multiplikation / Division zu arbeiten (ich erinnere mich, dass der z80 keine Befehle zur ganzzahligen Multiplikation und Division hat) und auch (siehe da!) Die Fähigkeit, mit Zahlen zu arbeiten Gleitkomma. Dafür musste ich mich jedoch mit der an den Compiler angehängten Bibliothek befassen,da alle mathematischen Operationen nach der Kompilierung als Aufruf dieser Bibliothek ausgeführt wurden. Das Problem war, dass diese Bibliothek temporäre Variablen verwendete, die der Compiler in das für TR-DOS spezifische Speichermodell legte, was natürlich nicht vollständig dem Speichermodell meines Computers entsprach. Ich musste nach all diesen temporären Variablen suchen und sie für Adressen wiederholen, die zu meinem RAM passen. Aber als Bonus habe ich viele Standardfunktionen wie Sinus und Cosinus erhalten, die ich in meinen Aufgaben verwendet habe, die ich unten diskutieren werde.Ich musste nach all diesen temporären Variablen suchen und sie für Adressen wiederholen, die zu meinem RAM passen. Aber als Bonus habe ich viele Standardfunktionen wie Sinus und Cosinus erhalten, die ich in meinen Aufgaben verwendet habe, die ich unten diskutieren werde.Ich musste nach all diesen temporären Variablen suchen und sie für Adressen wiederholen, die zu meinem RAM passen. Aber als Bonus habe ich viele Standardfunktionen wie Sinus und Cosinus erhalten, die ich in meinen Aufgaben verwendet habe, die ich unten diskutieren werde.

Das erste Programm, das mit dem C-Compiler erstellt wurde, war ein Programm zur Überprüfung des korrekten RAM-Betriebs. Dieses Programm durchlief den gesamten RAM, schrieb und las verschiedene Muster und verglich das Ergebnis. Darüber hinaus wurde der gesamte Prozess auf dem LCD-Bildschirm angezeigt, was auch den korrekten Betrieb der damit verbundenen Verfahren bestätigte. Es ist klar, dass dies nur ein Test des Stifts war, bevor interessantere Programme geschrieben wurden. Als nächstes habe ich einen Hex-Editor erstellt, um den Inhalt des RAM zu ändern. Dieser Editor verfügte bereits über umfangreiche Möglichkeiten, darunter nicht nur das Anzeigen und Bearbeiten von Speicherzellen, sondern auch das Suchen nach interessanten Bytes im RAM. Insbesondere wurde es möglich, kleine Programme in Maschinencodes direkt in den RAM zu schreiben. Um die Soundfunktionen Ihres Computers zu testen,Ich habe ein Programm wie eine „Spieluhr“ erstellt, in der verschiedene Melodien abgespielt wurden (ich erinnere mich, dass Melodien als Noten aufgenommen wurden). Außerdem wurde ein Programm für das Spiel „Bullen und Kühe“ geschrieben, in dem eine Person gebeten wurde, eine zufällige vierstellige Zahl zu erraten, die von einem Computer erfunden wurde (ja, ich habe auch einen Zufallszahlengenerator erstellt). In diesem Programm musste ich eine Bildlaufliste mit einem Verlauf bereits eingegebener Zahlen erstellen, da es unmöglich war, eine besonders lange Liste in zwei Zeilen anzuzeigen. Das nächste erstellte Programm war ein klassischer „Pionier“ auf einem 16x16-Feld. Da ich nur zwei Zeilen zur Verfügung hatte, scrollte ich, fügte musikalische Begleitung und Animation einer im Wind wehenden Flagge hinzu und explodierte Bomben. Außerdem habe ich zur Meditation ein Programm erstellt, in dem Würmer in eine zufällige Richtung kriechen.Verwenden der Möglichkeit, benutzerdefinierte Bilder auf den Bildschirm hochzuladen. Nun, und wo ohne den klassischen Tic-Tac-Toe? In ihnen habe ich den Minimax-Algorithmus getestet, dh der Computer hat (ziemlich schnell) alle Optionen berechnet und ist nie verloren gegangen. Da mein Betriebssystem Alarme, Uhrzeit und einen Kalender unterstützt, habe ich ein Benutzerprogramm erstellt, das Uhrzeit, Datum und mehrere Alarme einstellt, die bei Erreichen der eingestellten Zeit unterschiedliche Melodien abspielen. Und schließlich ist die Krone der Schöpfung in meinem Computer ein Programm zur Berechnung der Bewegungsbahn im Problem zweier Gravitationskörper. Das heißt, für eine gegebene Anfangsposition und Geschwindigkeit des Körpers sowie die Masse des anziehenden ZentrumsDas Problem der numerischen Integration eines Systems zweier nichtlinearer gewöhnlicher Differentialgleichungen zweiter Ordnung mit einem gegebenen Integrationsschritt wurde gelöst. Dazu habe ich eine Prozedur hinzugefügt, die diese Gleichungen numerisch integriert. Alle Variablen hatten ein doppeltes Gleitkommaformat. Hier betone ich noch einmal, dass es im z80-Prozessor nicht nur Hardware-Unterstützung für das Arbeiten mit Gleitkomma gibt, sondern auch die übliche Multiplikation / Division von ganzen Zahlen, alles wurde programmgesteuert durchgeführt. Diese Integration funktionierte ziemlich langsam, ungefähr einen Schritt pro Sekunde, aber es funktionierte!aber auch die übliche Multiplikation / Division von ganzen Zahlen, alles wurde programmatisch gemacht. Diese Integration funktionierte ziemlich langsam, ungefähr einen Schritt pro Sekunde, aber es funktionierte!aber auch die übliche Multiplikation / Division von ganzen Zahlen, alles wurde programmatisch gemacht. Diese Integration funktionierte ziemlich langsam, ungefähr einen Schritt pro Sekunde, aber es funktionierte!

Was ich noch implementieren wollte, aber es hat nicht geklappt - erstens die dynamische Zuweisung / Freigabe von Speicher, damit die Ressourcen jeder Aufgabe flexibel verwaltet werden können. Auch das Aufzeichnen / Lesen auf Band wurde nicht implementiert, wie dies im Sinclair der Fall war. Aber insgesamt war ich zufrieden mit dem, was ich geschafft habe. Ich betone, dass sich alles oben Genannte in einem 32-Kilobyte-ROM befand - der aktuellen Größe einer nicht so großen E-Mail.

Sie können meinen Computer hier in Aktion betrachten:




Und laden Sie hier seine Software herunter

All Articles