Commodore VC 20 (SFT 9)

Oh mein Gott als Gunnar das VC20 Handbuch erwähnt hat…da kamen längst vergessene Erinnerungen hoch! Das hatte mein verstorbener Vater! Als Kind habe ich darin geblättert! Ich glaube ich konnte zu der Zeit noch gar nicht lesen und hab mir nur fasziniert die Bilder angesehen. Das war ein Ringbuch, oder? Allein für diese Erinnerung hat sich der Podcast gelohnt. Danke!!!

3 „Gefällt mir“

Der Stil des Handbuchs und die Haptik als Ringbuch ist wirklich der Hammer.

Das Handbuch wird zumindest auf der Packung gar nicht beworben. Ich glaube auch nicht, dass jemand den VC20 gekauft hat weil das Handbuch so gut war. Ohne Handbuch wären Farbe, Preis und Tastatur schon Argument genug gewesen.
Hat man sich bei Commodore vielleicht nur deshalb Mühe mit dem Handbuch gegeben, damit die Hotline nicht überlastet wird?

Jedenfalls war ein Handbuch in dieser Qualität zwingend nötig für so ein „Volksgerät“. Das hat Commodore schon gut erkannt. Schade, dass die Handbücher beim Amiga dann deutlich schlechter waren.

1 „Gefällt mir“

Ich denke, das gute Handbuch samt Programmierkurs war aus mehreren Gründen wichtig für Commodore:

  • Um den Anspruch der Benutzerfreundlichkeit zu erfüllen,
  • Um das Gerät glaubwürdig als Lernwerkzeug bewerben zu können,
  • Um den Fehler des anfänglich unbrauchbaren PET-Handbuchs nicht zu wiederholen,
  • Um sich von der Atari-Konkurrenz abzuheben (die nähere Infos zur Programmierung geheim hielt),
  • Um möglichst schnell die Softwarebibliothek zu füllen,
  • Um eine Generation von Programmierern hervorzubringen, die in Commodore-BASIC geschult sind und dieses Wissen vielleicht auch auf die PET-Klasse übertragen. Damals sah Commodore den Weg vom VC-20 zum PET noch als typischen Upgrade-Pfad.

Mini-Trivia: Angeblich hat Elon Musk mit diesem Handbuch das Programmieren gelernt (sein erster Rechner war ein VC-20 mit 8 kB). Wäre er mal dabei geblieben :wink:

Schade, dass solche guten Handbücher ausgestorben sind - auch wenn mir klar ist, dass das nötig war. Mir fällt spontan noch ein weiteres Beispiel ein: Das Handbuch zu Microsoft Publisher 95 oder 97 enthielt einen erstaunlich umfangreichen, gut gemachten Layout-Einsteigerkurs, der mir damals bei der Schülerzeitung sehr geholfen hat. Der beschrieb sogar, wie man knackige Überschriften formuliert - das geht ja weit hinaus über die bloße Beschreibung der Programmfunktionen. Toll! So etwas bleibt jahrzehntelang positiv im Gedächtnis, wie man sieht.

3 „Gefällt mir“

Stimmt - ich habe mir die Packung gerade noch einmal angesehen, das Handbuch kommt darauf nicht vor. Wahrscheinlich wirkte der Gedanke ans Handbuch-Studium abschreckend, zumindest für die jugendliche Zielgruppe. Aber sie hätten es ja anders verkaufen können: „Mit Gratis-Programmierkurs!“

Hier ein schönes Video um die Zeit und die Stimmung von damals zu veranschaulichen.
Bei 27:58 wird der VC 20 vorgestellt. Bei 21:12 beginnt aber schon das Thema Computerspiele.
Es lohnt sich aber auch in das ganze Video abzutauchen :slight_smile:

https://youtu.be/4qq8O-aO3Eg

1 „Gefällt mir“

Die Bebilderung fürs Gaming ist noch einigermaßen bemerkenswert: Der Opa mit dem Enkelkind.
30 Jahre vor der Wii haben sie da schon alle Altersgruppen angesprochen.

Nur die Frauen sind da noch nicht modern und müssen noch mit Stift und Papier schreiben.

2 „Gefällt mir“

Stimmt, aber seltsamerweise hat keiner einen Joystick in der Hand :smiley:
Ich starre seit einer Weile auf den Bildinhalt in der Mitte und frage mich, was dieses bunte Muster wohl darstellen soll? Ein Spiel ist das eher nicht, eine erkennbare Grafik aber auch nicht. Testbild? Absturz? Rohrschachtest?

1 „Gefällt mir“

Großartig! Ich freue mich besonders über das Wort „Spielekartuschen“. Und über diesen zeitgenössischen Optimismus: Schon bald werde man mit dem Computer ganz normal sprechen können.

Gab es zum Erscheinen eigentlich schon einen passenden Monitor von Commodore?
In der Werbung und auch auf der Box da oben wird immer ein Fernseher gezeigt.

Super Folge, danke dafür!

Kleine Ergänzung: Es wurde gesagt, dass es keinen Designfehler gab der zur famosem Langsamkeit des 1541 (und später 1540) Laufwerk geführt hat, sondern dass das nur daran läge, dass die Software-Routinen überstürzt entwickelt wurden. Das ist nicht falsch (deswegen die Existenz von rein softwaremäßigen Schnellladern die die Sache etwas verbessern), aber nicht die Hauptursache: Tatsächlich gab es einen sehr folgenschweren Hardware-Bug im VIA, dem verwendeten I/O-Chip, der die eigentlich geplante Geschwindigkeit verhindert hatte. Der VIA hatte nämlich ein nicht funktionierendes Shift-Register.

Vereinfacht gesagt hätte mit dem Shift-Register die Hardware die meiste Arbeit in der Kommunikation gemacht, und die CPU und Software nur fertige Bytes vom VIA „abgeholt“, sobald dieser signalisiert dass eines „fertig“ sei. Das stellte sich dann aber einfach als kaputt heraus, ohne mögliche Software-Workarounds die das Shift-Register retten konnten, so dass die Software nun stattdessen „bit banging“ betreiben musste: Das bedeutet, dass sie jedes einzelne Bit auf dem Bus selbst schalten und timen muss. Das ist auf der CPU von damals viel langsamer als wenn die extra Hardware vom VIA das abnehmen würde.

Tragischerweise wurde es dann beim C64 sogar noch langsamer als beim VC-20: Weil der VIC-II, also der im C64 verbaute Nachfolger des VIC (der Grafik-Chip, nicht der ganze Computer), der CPU regelmäßig Buszeit wegnahm, sie also von der Arbeit abhielt, konnte sie nicht mehr so schnell bit bangen, und das zum C64 gehörende 1541 Laufwerk ist tragischerweise sogar langsamer als die zum VC-20 gehörende vorherige 1540.

Die Geschichte ist, wie so oft bei der Geburt von Computern, im Detail noch viel komplizierter. Zum Beispiel ist‘s es recht überraschend, dass das Problem beim C64, bei dem das Shift-Register gar nicht mehr kaputt war, weiter besteht. Da fiel anscheinend auch wieder einiges zusammen um zu dem Ergebnis zu kommen.

Das ist aber keine Kritik an den Podcast. Hinter solchen Problemen steckt oft wirklich eine fraktale Komplexität. Würde der Podcast versuchen solche Details völlig abzudecken, müsste er vermutlich ein paar langweilige Stunden damit verbringen nur dieses eine Detail aufzudröseln. Und das obwohl die Ingenieure dahinter das Wirrwarr an Problemen und Ereignissen die zu der suboptimalen Lösung geführt haben vielleicht selbst nicht mehr ganz wiedergeben könnten…

3 „Gefällt mir“

Blöde Frage vielleicht, weil ich von Schachalgorithmen gar keine Ahnung hab, aber wieso ist das jetzt genau exponentiell? Wenn‘s nur darum ging, bereits berechnete Teilzugfolgen abzuspeichern zu können statt neu berechnen zu müssen, wäre das doch nur polynomiell, oder überseh ich da was?

Ja, das stimmt, von diesem Bug habe ich bei der Recherche auch gelesen - in der Episode habe ich das Thema etwas abgekürzt und dabei hoffentlich nicht zu stark vereinfacht. Danke für die ausführlichen Ausführungen :slight_smile:

Jetzt wird es ein bisschen technisch. Wie lange ein Algorithmus braucht um ein Problem zu lösen, wird von uns Informatikern durch das Laufzeitverhalten bei wachsender Problemgröße beschrieben. Wir sprechen dabei von der O-Notation. Hierbei ist der Buchstabe „n“ die Problemgröße (also irgendwas von 0 bis unendlich) die wir in ein Laufzeitverhalten einsetzen.

Da es lediglich um das Verhalten geht, ist der Wert von n nicht weiter wichtig. Die gebräuchlichsten Laufzeiten sind:

n (linear) - Das Problem wächst linear mit der Größe. n=2 dauert doppelt so lange wie n=1. n=3 dauert dreimal so lange etc…

n^2 (quadratisch) - Also n hoch 2. Das Problem wächst quadratisch im Sinne von 1^2=1, 2^2 = 4, 3^2 = 9, 4^2 = 16.

2^n (exponentiell) - Hier wirds hart… jetzt haben wir 2^1, 2^2, 2^3 - das sieht im Vergleich zur quadratischen Laufzeit noch gut aus. Aber das exponentielle Wachstum ist eine Größenfalle - insbesondere weil der Mensch nicht dazu gemacht ist das Ausmaß von Exponentialzahlen sofort zu erfassen. Wo 10^2 noch 100 ist ist 2^10 schon 1024. Für 2^20 sind wir bei gut 1 Mio - bei 20^2 hingegen nur bei 400.

Exponentiell ist ein Problem dass sich selbst bei der Vergrößerung nochmal mit seiner bisherigen Größe multipliziert. Die Zugtiefenberechnung beim Schach ist genau so ein Problem. Informatiker versuchen exponentielle Laufzeiten zu vermeiden. Das klappt aber nicht immer.

Es gibt noch komplexere Laufzeiten die logarithmisch (log(n), n * log(n)) oder polynomiell (n^k) ausgeprägt sind. Diese sind wesentlich kürzer als quadratische oder exponentielle Laufzeiten, aber eben nicht immer erreichbar. Wir verwenden die O-Notation um Laufzeiten für alle denkbaren Probleme zu beschreiben - also genauso für Such- oder Sortieralgorithmen. Eigentlich für alle denkbaren Verarbeitungsprobleme.

In ihrer Gesamtheit sind die Probleme zudem meist komplexer… eine „genaue“ Beschreibung kann z.B. n^2 + n + 5 sein. Da die 5 aber nicht über die Problemgröße mitskaliert und ein einfaches + bei einer quadratischen Laufzeit nur einen minimalen Einflussfaktor darstellt, runden wir dieser zusätzliche Terme einfach weg. Die Kernaussage bleibt am Ende, mit wieviel langsamer ein Computer die Aufgabe löst, wenn ich die Problemgröße anhebe.

Soo… das war jetzt ein bisschen kompliziert und theoretisch. Es ist aber auch etwas, dass ich „frischen“ Programmierern immer nahelege zu verstehen, damit jeder weiß, in welches Laufzeitverhalten der von ihm geschriebene Algorithmus eventuell abdriften könnte.

Ja, die Frage war ja gerade, ob der Laufzeitzuwachs mangels Speicher nicht polynomial statt exponentiell ist. Polynomial schließt quadratisch mit ein, da ist k=2 (und damit relativ betrachtet kürzer als viele andere polynomiale Laufzeiten).

Der Spielbaum möglicher Brettzustände verdoppelt sich in der Größe halt mit jedem vorberechneten Zug und damit gibt es auch exponentiell viele Zugfolgen auszuwerten. Die kann man nun ohne viel Speicher zu verbrauchen durch iterieren, bewerten und am Ende halt den nach dieser Bewertung besten Zug ausführen, aber das braucht dann halt exponentiell viele solcher Bewertungen.

Also, naiv zumindest. State-pruning (Äste des Baumes abtrennen, die offensichtlich nicht zielführend sind) ist in tatsächlichen KI-Algorithmen afaik ein recht zentraler Punkt um das überhaupt halbwegs effizient umzusetzen. Da bin ich aber auch kein Experte.

Da sind wir aber beim Punkt @Kirby. Agentensysteme bauen darauf auf, dass sie eine Knowledge-Base… also einen angesammelten State haben aus dem sie eine Bewertung treffen. Das ist hier etwas schwierig, da grade Arbeitsspeicher die limitierende Komponente ist und kein physischer Speicher zum Auslagern zur Verfügung steht.

Ich glaube dass die hohen Laufzeiten sehr viel damit zutun haben, dass hier immer wieder State neu errechnet werden muss - und wir hier nicht durch bereits errechnete Ergebnis wieder durchiterieren können. Jetzt müsste halt der Schachkenner sagen ab wann ein bestimmter Entscheidungsweg eindeutig als „ineffizient“ oder „verdammt“ bezeichnet werden kann, damit man den Entscheidungsbaum an einer Stelle verlassen kann. Ich glaube zwar, dass die Programme solche Zustandsbewertungen haben. Vermutlich kommen da aber erst zum Zug wenn eine Partie kulminiert.

Ansonsten spricht die Steigerung der Zugzeit je nach Schwierigkeitsgrad irgendwie schon für ein exponentielles Problem. Ich denke bei moderneren Programmen gibt es dann vermutlich andere Tricks inkls. Heuristiken die bestimmte Situation schon im vorab nach einem Pattern bewerten. Ich glaube hier wird stumpf alles durchlaufen, was im Entscheidungsbaum so drinhängt.

PS: Eine andere Frage ist ob es Teilbewertungen für bestimmte Muster gibt, die aus der Berechnung des vorherigen Zuges für den Folgezug übernommen werden können - insbesondere dann wenn der gegnerische Zug Teil dieser Vorberechnungen war. Das ist dann aber jeweils nur ein Ast ganz oben im Baum, der noch eine neue Tiefenstufe hinzubekommt. Das dürfte die Laufzeit nicht retten.

Der Zustand ist hier aber doch nur das derzeitige Brett, oder sehe ich da was falsch? Wenn das angezeigt werden kann, müsste das ja einmalig auch in den Arbeitsspeicher passen. Kann natürlich sein, dass dann für die Bewertung von Folgezügen der aus den Zügen resultierende Zustand jedes Mal neu berechnet werden muss, aber das würde in der Laufzeit m.E. nur einen recht untergeordneten Effekt haben.

Ah, oder geht es darum, dass du davon ausgehst, dass ohnehin nie der ganze Brettzustand (also auch nicht der aktuelle) im Speicher liegt, sondern nur die Züge vom Start? Das würde in der Tat dazu führen, dass die KI mit länger andauerndem Spiel auch zusätzlich zur Tiefe des Entscheidungsbaums immer langsamer wird, ja.

Zugegebenermaßen hab ich die Folge noch nicht gehört, kann schon gut sein, dass ich hier auf Basis unvollständiger Kenntnis schreibe. :sweat_smile:

Das ist eben der Punkt, warum ich ein bisschen zweifle. Algorithmen mit exponentieller Laufzeit gehen üblicherweise sehr schnell sehr schief. Das stelle ich mir mehr als „trivialste Spielsituationen gehen noch in ein paar Sekunden oder Minuten, aber ganz plötzlich bräuchte der Computer 26 Jahre, und bei der nächsten Situation dann schon 4000“.

Polynomiale Algorithmen, besonders quadratische, sind heimtückischer, weil sie viel länger sinnvoll bleiben, dann aber so eklig ins „wenig sinnvolle“ abdriften. Da dauern zwei versehentlich verschachtelte Schleife dann z.B. bei 100 Items einen unmerklichen Bruchteil einer Sekunde, 1000 Items brauchen eine wahrnehmbare einzige Sekunde, und 5000 Items plötzlich 25 Sekunden.

„Accidentally quadratic“ nennt man das auch, und ist viel eher eine Falle als exponentiell. Es wird unerwartet langsam und nervig, aber im Gegensatz zur exponentiellen Laufzeit driftet es nicht gleich in den Hitzetod des Universums ab.

Ich hab das coole Handbuch auch noch hier. Vor ein paar Jahren in einer alten Bücherkiste gefunden (klassischer „Dachbodenfund“) und dann in mein Retro-Bücherregal einsortiert. Mit dem Buch hab ich tatsächlich der erste mal „programmiert“. Also eher abgetippt, weil ich nicht wirklich verstanden habe, was ich da tue. Ich muss so 7/8 gewesen sein.




7 „Gefällt mir“

Mhm… nee nicht ganz. Sagen wir mal wir beginnen mit dem Ausgangsbrett einer Schachpartie. Der weiße Spieler hat insgesamt 20 Zugmöglichkeiten - 2 unterschiedliche mit jedem der 8 Bauern und 4 unterschiedliche mit seinen Springern. Da sind wir bei einer Zugtiefe von 1 bei 20 Möglichkeiten…

Nun hat der schwarze Spieler aber 20 Möglichkeiten auf jeweils jede dieser 20 Möglichkeiten zu antworten… das heißt 20*20 Zustände für Zugtiefe 2.

Ich glaube man kann für die ersten Züge davon ausgehen, dass man ungefähr in diesem Handlungsrahmen bleibt. Zur Mitte des Spiels hin, dürfte dieser durch das Freilegen der frei ziehbaren Figuren immens anwachsen. Zum Spielende hingegen wieder auf dem Ausgangszustand zurückfallen. Gehen wir mal konstant von 20 Zugmöglichkeiten in den ersten 7 Zügen aus um das Problem zu vereinfachen…

20^7 ist halt eine Sache wo der exponentielle Faktor den Kopf schon wegbläst - das sind nämlich 127 Mio. Lösungskombinationen. Davon kann nicht mal ein Bruchteil im Speicher gehalten werden. Die Folge daraus ist, dass ich bereits berechnete Ergebnisse nicht mit in den nächsten Zug nehmen kann… Beispiel…

Ich habe den kompletten Baum ausgerechnet und unter den 127 Mio. die besten Zugreihenfolge ermittelt. Ich führe den Zug durch. Danach führt mein Gegenspieler einen Zug durch. Den Lösungsraum aller jetzt folgenden Züge bis zu einer Tiefe 5 habe ich bereits vorher errechnet, muss es aber nochmal tun, weil ich aufgrund der Lösungsmenge nicht die Möglichkeit hatte die Zwischenergebnisse im Speicher zu halten. Das heißt… Plain Field, alles neu. Viel hätte das aber eh nicht gespart bei diesem gigantischen Lösungsraum.

Nun ist es eine Frage wie der Algorithmus gestrickt ist… Ich kann halt wie eine klassische Baumiterationsimplementierung immer auf das linke Blatt laufen und damit die Äste einzeln durchgehen. 6 zusätzliche Spielbretter aus der Iteration gibt der Baum vermutlich her. Alternativ kann man sich auch Zugreihenfolgen statt Spielbretter merken, da das Spielbrett immer aus der Zugreihenfolge rekonstruiert werden kann.

Wie kann man das schneller machen? Naja, das Programm wird sich bei der Iteration vermutlich die erfolgversprechenste Zugreihenfolge merken. Je nachdem wie ein Brettzustand bewertet wird (ich glaube da liegt nochmal ein richtig dicker Berechnungsblock drin) kann man bestimmte Zweige, die wenig erfolgsversprechend sind, einfach kappen (also im Vorhinein schon in der Bewertung zurückfallen). Außerdem kann man bereits errechnete Zustände, je nach Wahrscheinlichkeit ihrer Rückkehr, auslagern. Da ists mit dem RAM aber - wie gesagt - zu eng. Und ob die Übertragungsraten auf physische Speichermedien bei den alten Geräten da helfen ist auch fragwürdig (bei Modulen / Tapes steht das eh außer Frage).

KI ist hier noch nicht wirklich im Spiel… nur ein Algorithmus der mehr oder minder Brute-Force bewertet. Eine KI hieße wir haben eventuell noch eine selbstlernende Komponente die angewandte Kombinationen hinsichtlich ihres Erfolges im Spiel abspeichert und zukünftig in ihre Bewertung einfließen lässt. Ich habe zu dem Thema mal gehört, dass Schach Profis Computerzüge sofort erkennen - weil das Varianten sind die so abgefahren und undurchsichtig gespielt werden, dass ein Mensch nie darauf käme. Die sind für eine KI in der Bewertung vermutlich auch deshalb erstrebenswert weil sie menschliche Gegner, die ja mehr auf bekannte Varianten und Zugabfolgen eingestellt sind, teilweise aus dem Konzept bringen. Ich bin da aber auch kein Profi.

Kurzum: Allein aufgrund der Problemgröße und Ausführungszeit tippe ich hier auf exponentiell / BruteForce. Das sagt aber nichts über die Komplexität und „Güte“ des eigentlichen Bewertungsalgorithmus für ein einzelnes Brett aus.