 Hallo? Oh, okay. Ja, willkommen zum Vortrag, das Steckschwein, in dem ich den unser Hobbyprojekt, das Steckschwein an 8-bit Homebrew-Computer ein bisschen vorstellen möchte. So erst die Frage, ich bin jetzt vorbereitet, den Vortrag auf Deutsch zu halten. So if there are any preferences about the language, I'm prepared to do it in German. I could try to ring it in English if there's a preference. So what is going to be? Deutsch? Okay, Deutsch it is. Okay, also ich fange jetzt mal an mit einem kleinen historischen Abriss, wie wir das überhaupt mit angefangen haben und mit den Anfängen auf dem Steckbrett und uns dann quasi hervorgearbeitet haben bis zu einem richtigen Rechner und dann entschlossen haben, jetzt noch was wissen. Das war, also angefangen haben wir Ende 2013 und haben uns dann quasi iterativ vorgearbeitet, man könnte fast sagen Agil, bis hin zu Produkt-Increment und so. So, am Anfang war das NOP. Ja, NOP wird den meisten hier was sagen, nehme ich an. Und wie das halt so ist, wenn man als Elektronik-Noob eigentlich eher sich an so ein Projekt setzt, will man ja erst mal wissen, bin ich überhaupt auf der richtigen Pferde und man will die möglichst einfache Variante der Schaltung erst mal probieren, um zu gucken, ob der Prozessor überhaupt das macht, was man jetzt erwarten würde. Und deswegen haben wir Folgendes gemacht. Wir haben den Prozessor genommen, haben den Datenbus hart auf die NOP Instruktion verdrahtet, haben ein bisschen Takt drauf gegeben und an den Adressbus einfach mal LEDs angeschlossen und die Erwartung war, wenn wir da jetzt Takt drauf geben, das anschalten, dann müsste das aussehen wie ein 16B-Zehler, weil er ja dann natürlich sich neue Instruktion aus dem Speicher holt und dementsprechend die Adresse hochzählt und so. Und das war dann auch so. Und das sah dann ungefähr so aus, das ist jetzt schon der nächste Schritt, man müsste sich jetzt im Prinzip das hier einmal kurz wegdenken, dann wäre man bei dem Aufbau, den wir dem mehr angefangen haben. Als nächstes haben wir gedacht, okay, dann brennen wir uns mal ein App-ROM mit ein paar Instruktionen drauf, die anders sind als NOP und gucken dann mal, was passiert und damit wir sehen, was er macht, dann sieht man da oben an den LEDs den Datenbus, die roten. Wer sich auskennt, weiß vielleicht auch gerade, welche Instruktionen anliegt. Es gibt auch ein kurzes Video zu, das sind so die bescheidenen Anfänge, das sich mal mitgeschrieben hat, was gerade lief. Als nächstes ein kleines S-Ramen dazu und jetzt hatte man plötzlich tatsächlich einen funktionierenden Computer. Jetzt haben wir nicht nur irgendwie ein Ding, was der Instruktion aus dem ROM liest und Sachen ausführt. Wir haben jetzt auch einen Stack und eine Zero-Page dazu gekriegt und können jetzt im Prinzip auch JSR und RTS Unterprogramm aufrufe und Zeug. Wir können Sachen wegspeichern, zusammen addieren und Zeugs. Wir haben nur keine Schnittstellen zur Außenwelt, aber im Prinzip ist es ein vollständiger Computer, Ziel erreicht, Klasse. Aber so weit sind wir jetzt gekommen und dann haben wir uns gedacht, jetzt wollen wir was wissen, jetzt wollen wir einen richtigen Computer bauen. Das war so eine Idee, die wir uns quasi in den Kopf gesetzt haben. Wir wollen einen Einplatinenrechner wie der C64 auch, wo alles drauf ist, Videochip, Soundchip, IO-Möglichkeiten. Wir wollten ihn aber mit modernen Schnittstellen ausstatten, modernen hier in Anführungszeichen. Massenspeicher haben uns überlegt, eine SD-Karte reicht völlig, also mit Disketten im Jahr 2013 noch anzufangen, ist halt auch Quatsch. Man kriegt für ein paar Euro eine 16-Gigabyte SD-Karte, die kann man mit SPI ansprechen, hat dann mit minimalstem Hardwareaufwand, hat man da gigabyteweise Massenspeicher. Mehr braucht man da nicht. Die nächste moderne Schnittstelle ist natürlich PS2, muss sein, und eine richtige erst 232-Schnittstelle, damit man halt Code draufladen kann oder so. Und dann ist diese ganze Steckbrettgeschichte dann im Laufe der Zeit ein bisschen eskaliert und sie dann irgendwann so aus. Und im Prinzip waren wir jetzt schon da, wo wir hin wollten. Wir haben zwei Megahertz, wir haben 64K, wir haben ROM, wir haben eine serielle Schnittstelle, wir haben eine RTC sogar. Mit dem Hintergedanken, dass man ja, wenn man irgendwann ein Datei-System hat, da auch irgendwie gültige Timestamps reinschreiben kann. PS2-Tastatur ist dran, SD-Karte läuft, wir haben jetzt noch ein LCD-Display, damit wir was sehen können. Und das sind jetzt gerade so die bescheidenen Anfänge da, den TMS9929 als Videochip dran zu basteln, eigentlich. Und da hat dann das ganze Ding auf dem Steckbrett auch eine Komplexität erreicht, wo es dann auch nicht mehr händelbar wurde. Also hier noch mal kurz die Videogeschichte, dann gab es hinten noch eine Analogschaltung, die halt das Videosignal aus dem 9929en RGB umgewandelt hat. Also da musste ich mega einen abgebrochen, kann man so sagen. Und letztendlich wusste man irgendwann nicht mehr, es lief nicht stabil, ob ich jetzt, habe ich jetzt im Code irgendwas? Habe ich da jetzt im Bug, ist es ein Wackelkontakt, wo muss ich suchen? Und das war einfach aussichtslos, da auf dem Steckbrett noch irgendwie weiterzukommen. Und dann haben wir uns für den nächsten Schritt entschieden, dass wir Platinen machen lassen. Also das ganze Schaltpläne, so wie wir sie haben nehmen, in Layout übertragen, Platinen herstellen lassen und damit weiter. Ja, das ist so das erste Erfolgserlebnis, was wir hatten, nachdem wir ja schon gedacht haben, das wird nichts mehr. Dann auf dem Steckbrett dann noch irgendwie dem ein Bild zu entlocken. Man sieht auch hier ein paar Speicherfehler, die Zeichen sind nicht ganz vollständig. Aber das war ein langer Weg dahin und frustrierend. Und besser sollte es dann werden mit Platinen, die haben wir uns dann zuerst herstellen lassen. Und zwar haben wir dann die einzelnen Baugruppen, wir haben es in vier Boards aufgeteilt. Es gibt einen CPU Memory Board, das sieht man hier ganz oben. Es gibt ein I.O. Board, wo halt die SD-Karte, die VR drauf legt und so. Es gibt ein Videobord, das sieht man hier noch nicht, das kam dann noch später dazu. Und der UART mit der serienen Schnittstelle war noch einzeln. Und so konnte man halt die einzelnen Baugruppen unabhängig voneinander weiterentwickeln, bis man dann irgendwann den Stand erreicht, mit dem man dann glücklich ist und wo man weitergehen möchte. Aber da will ich jetzt noch nicht vorgreifen. Ja, das ist dann eine spätere Revision mit neueren Platinen. Da ist jetzt die Integrationsdichte ein bisschen gestiegen. Da ist der UART mit auf das I.O. Board gekommen, sinnvollerweise. Das da unten, das Lochaster-Ding, das ist so ein Prototyp des Soundboards, das es so nie gegeben hat, denn das ist dann irgendwann auf die Videoplatine gewandert. Also ist mit damit draufgekommen. Und dann hat es im Prinzip so was wie ein Multimedia-Board, kann man so sagen. Und hier ist es jetzt schon so, dass wir den Videochip abgegraded haben, weg vom TMS9929, weil er ist schon sehr oldschool. Zum V9938, V58 von Yamaha, das quasi der Nachfolger, von dessen Nachfolger. Und der kann ein bisschen mehr, aber noch nicht genug. Aber läuft zumindest super stabil und den müssen wir jetzt erstmal ausreizen. Also eigentlich haben wir es da schon erreicht. Unser Ziel, den funktionsfähigen Computer mit allen drum und dran zu bauen, haben wir erreicht, ist zwar noch unser 3-Platin-Sandwich. Und dann standen wir vor der Entscheidung, nehmen wir das jetzt und machen daraus unsere Einplatinen-Version oder wollen wir das doch noch mal wissen und können da vielleicht noch mal einen draufsetzen. Und wer uns kennt, weiß, dass wir noch einen draufgesetzt haben. Und zwar haben wir dann gedacht, jetzt 64K, schön und gut, aber 512K ist besser. Und das war dann so der letzte Schritt, den wir noch gemacht haben, bevor wir dann zum Einplatinen gegangen sind. Und da muss ich jetzt kurz das Memory-Mapping mal beschreiben, wie wir das gemacht haben. Also in der alten 64K-Version war es dann so, dass die ersten 8K, da ist entweder ROM eingeblendet oder RAM. Da haben wir dann quasi diskreten Register aufgebaut, wo man sich von den 32K eine von vier 8K-Bänken da einblenden kann und Raum zum Buten und so weiter. Oder wahlweise konnte man das ROM auch ausblenden, dann konnte man da was RAM zugreifen und hat man quasi während das ROM eingeblendet ist, in diesem Bereich geschrieben, ist es im RAM gelandet. Also da stand dann der C64 ein bisschen Pate bei dem Design. Mit 512K müssen wir natürlich ein bisschen was anderes machen und da haben wir uns überlegt, wir werfen das Ganze ein bisschen über einen Haufen und teilen jetzt unsere 64K-Adressraum in vier Slots haben wir es genannt, zu je 16K ein und dann nehmen wir vier solcher Register und nehmen die 512K und die 32K-ROM und teilen die auch in 16K-Blöcke ein. Jetzt haben wir quasi für jeden dieser Slots, haben wir jetzt ein Register und in das Register schraube ich einfach rein, welchen Block ich haben will. Dann kann ich mir quasi über diese vier Register, kann ich mir meine 64K-Adressraum in 16K-Schritten einfach so zusammen stöpseln, wie ich es gerne haben möchte. Ja, muss man dann halt in das Software mit umgehen. Das ist genau, das sollte ich mal drauf eingehen. Man sieht es nicht, das ist eigentlich Hexadezimal. Also wir haben von der Numerierung das so gemacht, dass die von 0 bis 31 ist halt logischerweise RAM und das gesetzte Bit7 kennzeichnet halt eine ROM-Page. Also man könnte jetzt auch nicht nur zwei Pages adressieren, man könnte auch da ein 512K-Flash-ROM einbauen und dann hätte man da auch ein 32-ROM-Pages. Jetzt kenne ich machen müssen, dass das Hexadezimal ist, aber genau das ist das ROM und das ist alles RAM. Also hier sieht man, dass quasi in den obersten 16K ist halt die erste ROM-Page eingeblendet. Genau. So, das ist jetzt unser Ansatz. Mit dem wollen wir erstmal starten. Und da ist es natürlich interessant, dass in slot 0, also quasi auch die Zero Page unter Stack enthalten ist und da könnte man zum Beispiel, hätte man jetzt 32 Stacks und 32 Zero Pages und dann könnte man sich überlegen, vielleicht ist das dann nützlich, wenn man sich mal irgendwie mit Multitasking beschäftigen wollen würde, aber es ist natürlich auch ein Akt, das dann jeweils auszutauschen und das stabil zu machen. Und ist dementsprechend ein ziemlich flexibler Ansatz. Bietet viele Möglichkeiten, aber es hat auch relativ dumm. Es gibt keinen Supervisor-Mode, die MMU, wenn man das so nennen möchte, macht jetzt nicht viel von selber. Das müsste halt dann das Betriebssystem oder was auch immer, müsste halt dann sich irgendwie merken, was wohin gestopft wurde. Ja, mal schauen. So sieht es jetzt aus. Zwei Stück von dem Ding liegen bei uns hinten am Stand und sind quasi in Aktion bewunderbar. Und damit haben wir quasi unseren ersten Meilenstein erreicht, unseren Einplatinencomputer mit den Features wie was wollten, nach knapp zehn Jahren Steckschwein, müssen wir nächstes Jahr mal was Cooles machen. So, und damit haben wir jetzt erstmal Spaß. Aber wie geht es weiter? Ideen gehen einem ja nicht aus. Als nächstes, ja, muss ein größerer CPLD her, denn das ist halt ein altes Ding. Den haben wir auch schon ziemlich vollgestofft mit dem Kram. Größerer CPLD zieht nach sich, dass wir uns mit 3,3 Volt beschäftigen müssen. Noch ist alles nativ fünf Volt. CPLD ist im Prinzip ein Gull auf Steroiden beziehungsweise eine Vorschufe zum FPGA. Also es ist also auch ein programmierbarer Logikbaustein, ein bisschen simtler aufgebaut als ein FPGA, aber schon mehr als ein Gull. So, und als nächstes, wenn wir da einen größeren CPLD haben, dann unser Peripheribus ist SPI, also die Kille-Aplikation der Fürwahl-TSD-Karte. Das machen wir bei BitBank über die 6522 VR, und eigentlich wollte ich die ganze Zeit schon das Ganze in Hardware machen auf dem CPLD, weil es einfach schneller ist und besser und toller. Mit dem größeren CPLD wäre das ein Feature, was ich unbedingt irgendwann nochmal machen möchte. Dann träume ich von einem priorisierenden, vektorisierenden Interab-Controller, dass ich quasi für jede Interab-Queli eine eigene Interab-Leitung mache, und der dann quasi auch den Adressbrustern jedes Mal so umbiegt, dass jede Interab-Queli auch ihre eigene Interab-Vektor kriegt, was der 6502 so nicht kennt. Das heißt, wir bescheißen ihn nicht nur mit den Adressleitungen zum Speicher, sondern auch mit der Interab-Leitung. USB, mal gucken. Wenn wir das andere haben, dann gucken wir uns das auch mal an. Aber, hm? Ja, USB-C, klar. Ja, klar, ich meine, PS2-Laster-Touren werden langsam schwierig zu beschaffen. Also muss man sich irgendwann was überlegen, was man, wie man da weitermacht. Ja, gut. Das war jetzt so bei der kurze historische Abriss, was wir die letzten zehn Jahre so getrieben haben in unserem Projekt. Wenn da jetzt schon mal Fragen sind, bitte. Warum Vektor Interabt? Was macht ihr da so, was macht ihr viel mit Interabts? Du brauchst mehrere Interabts, oder? Na ja, es ist eigentlich natürlich weniger die unbedingte technische Herausforderung als viel mehr Spieltrieb. Dass es einfach cool wäre, so was einzubauen und da so ein bisschen das, was größere, richtige Computer quasi haben, da mit reinzunehmen. Und weil es natürlich von der Programmierung her schön ist. Man hat dann quasi nicht eine Interabtservice-Routine, die halt dann jedes Mal, wenn sie aufgerufen wird, abklappern muss, wer war es denn? Wenn man einfach weiß, okay, wenn es da knallt, dann kommt es von da. Also das jedes Device, der UART, der VDP, seine eigene Interab-Routine hat, die dann einfach die Initiatät aufgerufen wird. Und wie wollt ihr das machen dann? Also es kommt ein Interabt rein und dann wird schon eine Adresse irgendwo in den Register getan. Ja, so ähnlich. Also die Idee ist, dass halt, ja, am CPLD hängen die verschiedenen Interab-Leitungen von den verschiedenen Interabquellen und je nachdem, welche gezogen wird, verbiegt halt quasi der CPLD den Adressbus. Das hat an der Stelle, wo die CPU ihren Interab-Vektor adressiert, eigentlich eine andere Adresse eingeblendet wird und da liegt dann der Vektor. Ja, das ist zumindest so die Idee. Aber jetzt haben wir erstmal genau ein anderes Zeug mit der aktuellen Version. Ja. Noch eine Frage kurz. Euer Steckbrett, da war noch ein Datum dran. Man kann es nicht recht sehen, ist es 2011 gewesen oder 2013 oder 2014, wie lange läuft es schon? Wir haben angefangen Ende 2013 und so die intensivste Zeit, sage ich mal, war bis Mitte 2014, wo wir dann mit dem Steckbrett, mit dem Videochip und so weiter auch einfach viele Änderungen noch an der Hardware vorgenommen haben, was dann mit den Platinen nicht mehr so einfach war. Und dann wurde es halt ein bisschen ruhiger, weil man kann ja nicht mehr einfach jetzt an einer fertigen Platine die Hardware halb umstricken und so. Also wenn keine Fragen mehr sind, dann machen wir kurz den Switch und dann erzählt Marco noch was zu unserem Emulator, den wir auch haben und unseren Entwicklungsmethoden generell. Test. Ja, hi. Ich bin Marco, der andere Teil von der Steckschmein Crowd. Ich will das dann nicht sehen. Mach das weg. Okay. Und ich möchte heute über mehr den Software teil sprechen, also wie wir mit dem Steckschmein, wie wir ohne der Steckschmein Hardware entwickeln und entsprechend Software stellen. Das Ganze geht zurück. Also wir haben natürlich programmiert und es gab verschiedene Hardware-Revisionen und man hat dann immer probiert SteckOS und Shell und FAT-Dreiber und was wir alles programmiert haben um die Hardware anzusprechen. Das ist natürlich auch ein Moving Target, weil die Hardware sich weiterentwickelt hat. Thomas hat es ja gesagt, neue Boards, neue Revisionen, die Hardware hat sich wieder geändert und so weiter. Und da wir jetzt auch nicht nebeneinander wohnen und remote, brauche ich ja irgendwie eine Möglichkeit, wenn er die Hardware macht, dass ich auch Software entwickeln kann. Und auch um ein bisschen die Komplexität, also was heißt die Komplexität, also auch um effizient Software entwickeln zu können, kann ich nicht auf Hardware entwickeln. Und die Spitze des Eisbergs war 2019, da war Michael Stein, müsste eigentlich auch bekannt sein, aus dem X16 Projekt oder aus diversen anderen Beiträgen, page-table.com, er kam zu mir und hat die Frage gestellt, wie könnt ihr für das Steckschwein Software entwickeln ohne einen Emulator? Und dann war ich irgendwie traurig und am Boden zerstört und dann sind wir nach Hause gefahren von Berlin nach München runter und das ging mir nicht aus dem Kopf. Und letztlich bin ich dann mit ihm ausforscht gewesen und habe ich natürlich überlegt, klar, ein Emulator macht Sinn. Und warum? Klar, ein Emulator, damit kann ich viel einfacher debacken und auch traceen, kann irgendwie viel schneller Fehler finden. Ich kann eine Idee Integration mir vorstellen und ich kann die Produktivität dadurch steigern. Also schreibe ich ein Emulator. Habe ich noch nie gemacht? Ich bin jetzt nicht ganz technisch unbelegt, aber wenn man die Entwicklung betrifft, macht das auch professionell. Ja, was brauche ich, um einen Emulator zu entwickeln? Zunächst einmal, wir haben eine 65002-CPU, also muss ich irgendwie Code haben, der quasi die 65002-CPU emuliert. Gut, das sollte nicht schwer sein, das gibt es wahrscheinlich. Schwieriger wird es mit dem Graphicship. Thomas hat gesagt, wir haben diesen Nachfolger-Nachfolger, das ist der Yamaha 958. Die Memory-Logik aus dem CPU-D mit dem Banking hat er vorgestellt, das muss alles nachgebaut werden und wir haben auch diverse IO-Geschichten, die VR, SD-Karte, seriale Schnittstellen, Joystick Ports und wir haben auch ein Soundship drauf, wir haben eine Real-Time Clock, das muss man alles emulieren. Okay, fangen wir mal bei der CPU an. Da gab es eine Vorlage auch von dem X6-Projekt. Den Tipp habe ich auch von Michael bekommen, die haben ja für den X6 auch ein Emulator gebaut und im Prinzip hat er uns die Steilvorlage gegeben und hier ist eine Implementierung drin. Also die Steilvorlage aus dem X6-Emulator von Michael, der hat uns im Prinzip das Gerüst gegeben, da war im Prinzip nur CPU drin und Memory und die Idee, wie man da starten kann. Und das habe ich aufgenommen und umgebaut und zumindestens auf das Memory-Modell vom Steckschwein in der ersten Inkarnation der Hardware implementiert und umgesetzt und man hatte dann ziemlich schnell auch ein Emulator. Okay, dieses ganze Projekt, muss man sich vorstellen, ist auf Sdl2, auf der Sdl2 Library aufgebaut, es ist so ein simple Direct-Media-Layer, es ist ein ganz einfaches Toolkit um UI auf Unix-Systems und Windows, also plattformübergreifend, im Prinzip bevor es noch Qt gab, ist damals Sdl entstanden, es ist eigentlich auch spät den 19er wahrscheinlich, ja doch. Und man hat hier ein ziemlich einfaches Programmiermodell mit einem Framebuffer auch im Screenschreiben. Okay, CPU, Haken, das haben wir bekommen, weiter geht es mit dem Videochip. Okay, der Videochip. Schaut man sich das Daten-Plat von dem Videochip an, das ist mehr 100 Seiten lang und wenn ich das emulieren möchte, dann brauche ich auch ein tiefgreifendes Verständnis, wie funktioniert denn eigentlich dieser Videochip? Also wie sind die Zugriffzeiten, wie sind die Timings, was passiert da in den Videomodi, wie hat man die Adressierung gemacht, wie funktioniert das mit den Sprites, das muss ja alles emuliert werden. Und das erschien mir ziemlich komplex und ziemlich viel Programmierarbeit. Und gerade auch bei dem 9958, wo die Command Engine dazu gekommen ist, also wo man an irgendwie Blittkommandos hatte, Linienkommandos und so weiter, das muss man alles nachbauen. Okay, dachte ich, kann eigentlich nicht sein, dass ich der erste bin, der mit so einem Emulator mit diesem Videochip zu tun hat. Wir haben zusammen und ja, Volltreffer, dieser Videochip ist aus dem MSX Rechnern, also MSX1, 2, MSX Plus, hatten dann alle den 9958 verbaute Ende der 80er und natürlich gibt es Emulationsprojekte. Also letztlich bin ich dann auf ein Version gestoßen. Das ist das Blue MSX, das wird aber nicht mehr gemaintaint seit, ich glaube das letzte Update war 2012, basiert noch auf SDL1. Aber war zumindest ein Ansatz und eine Idee. Also was habe ich gemacht? Ich habe die Library mir runtergenommen, habe alles entschlagt, was ich dazu nicht brauche, weil ja im Prinzip das Blue MSX ist ein kompletter Emulator für alle MSX-Systeme. Also richtig krass, was der Typ, der das gemacht hat, da geschrieben hat, da kann man Video-Modi einstellen, auch man kann Komposite, Video-Ausgangssignale faken, dann wird das so grisselig. Also das ist schon echt fancy und auch Inline Assembler verwendet, weil damals die Performance nicht gereicht hat, also der hat sich da richtig ausgetobt. Ich habe das alles entschlagt, habe nur den Code rausgenommen für unseren Videochip. Und weil das SDL1 ist, habe ich natürlich unseren Emulator zurückportiert auf SDL1. Macht nichts, weil so viel UI war nicht. Das hat ein bisschen gedauert, aber am Ende ist es mir gelungen, die Emulation für ein Videochip einzubauen. Okay, wir haben also CPU, wir haben den Videochip. Als nächstes die Memo-Leogik, der Thomas vorgestellt hat. Hier nochmal kurz die Übersicht mit den Slots und den Banks, die wir einplanen können über die Register. Okay, also ist jetzt nicht so schwierig, wenn ich mir das im Code anschaue. Also da nochmal das logische Schaltbild, die CPU, adressiert. Und über die Register, in der Hardware von den CPUs, wird quasi der Addressbus extended von 18 hoch, Addressleitung. Und damit gehen wir auf das 512K RAM. Okay, wie sieht das im Code aus? Ich habe hier oben mal 2 Zeilen VHDL. Da sieht man einfach das ShipSelect für Rom und Ram als Signal, also invertierendes Flanke. Und da wird im Prinzip, haben wir intern in dem CPU so ein array mit den Registern, also diese sogenannte BankTable. Und dann wird dann im Prinzip die Addressleitung der CPU entsprechend selektiert. Je nachdem, welches Register angesprochen wird. Also das macht dieser Ausdruck. So, wenn ich das natürlich im C Code im Emulator mache, habe ich das ähnlich. Wenn ich also eine Adresse haben möchte, also eine Extended-Adress, dann muss ich erst mal schauen, welche Bank ist selektiert. Dann setze ich mir hier den Pointer. Das andere, das geht jetzt leider hier nicht mehr drauf. Das ist das Screen zu klein. Schade, okay. Und am Ende habe ich einen Ausdruck, der mir diese Extended-Adresse berechnet. Dann kann ich dann mir in meinem Emulator mit Malog 512k bereithalten. Und dann kann ich damit arbeiten. Okay. Also Memory-Logik kein Problem. Das war eine leichte Übung, sag ich jetzt mal. Gut. Peripherie, was ist da zu sagen? Also wir haben eine 6522-Nivir, die bei uns das Bitbanging macht, für die SD-Karte. Und wir haben noch ein U-Art und wir haben auch Joysticks. Bei Navier ist es so, dass wir keine komplette Implementierung in Navier haben. Es gibt tatsächlich auch eine Bibliothek, da ist eine komplette Via implementiert. Ich habe mich da beschränkt auch wirklich auf unsere Funktionalitäten. Das heißt also, die wichtigsten Adressen von Navier, wie das Schiftregister und der Statusregister, das wird behandelt, um eben gerade so SD-Karte emulieren zu können. Und der eine SD-Karte ist eigentlich, ist eigentlich ganz trivial. Da ist letztlich, sag ich mal, in dem Emulator, öffne ich im Prinzip ein Image, das ist eine Datei, und in der mache ich dann mit Zieg, gehe ich dann auf die Blöcke, die rechne ich dann raus. Wird also im Emulator, das ist ein Block auf der SD-Karte adressiert, LBA-Adressierung, gebt mir mal Block 20, rechne ich halt aus, 20 mal 512, ziehe ich in der Datei, laht das Ding rein, bittbänge das emuliert quasi über die Via raus, und dann habe ich meinen Block über die SD-Karte emuliert gelesen. Uhr ist ein bisschen tricky, funktioniert auch noch nicht so richtig. Auch da habe ich mich ein bisschen wieder inspirieren lassen von einem QEMU-Projekt, was ich haben wollte für den Emulator, ist eine echte Emulation der seriöllen Schnittstelle, dass ich es wirklich sagen kann, ich kann sowas wie mit Socat, ein Unix-Tool, dass ich sage, ich kann so eine Pipeumleitung machen, also ich starte den Emulator, da macht ein TTY auf, und den den kann ich dann auch lesen und schreiben. Es wäre es wirklich eine seriölle Schnittstelle, und dann kann ich dann auch tatsächlich mit Tools wie X-Modem, Z-Modem, ja, und direkt benutzen. Funktioniert aber noch nicht richtig. Ich habe jetzt ein Workaround, wie wir unser X-Modem upload machen, aber es ist noch nicht sauber emuliert, also wer da eine Idee hat, gerne. Joysticks, okay, das ist trivial. Da gibt es bei der SDL 1 und auch später bei der SDL 2 entsprechende API, da kann man also ein Controller anschließen, den auslesen, und dann emulieren wir im Prinzip, ich lese die SDL, die API aus, für einem Joystick, und im Prinzip, wenn von dem Code, der in dem Emulator läuft, der Joystick angesprochen wird, dann lieferst du halt die Daten daraus. Okay, genau, wir haben auch, wir haben ein Soundship auf unserer App, das ist ein OPL2-Ship, das ist der 3812, so einer der OPL, von der OPL-Serie, so der, ja, am meisten, der sollte eigentlich bekannt sein, der ist von den Soundplastern, den gibt es halt auch, wirklich noch Massenweise zu kaufen, und den haben wir, deswegen bei uns auf dem Steckschwein in Verwendung. Was ist hier zu sagen, für die Emulierung, auch das ist ein bisschen schwierig, für die Emulation, also was da passiert, in dem, diese FM-Synthese, in dem Chip, das muss natürlich emuliert werden, auch da dachte ich, na ja, ich bin nicht der Erste, der das macht, also gibt es bestimmt irgendjemanden, der sich darum gekümmert hat, und da gibt es tatsächlich eine C-Datei, wo diese Operatoren und diese ganze Mathematik drin ist, und die das emuliert, und das findet man auch im Meme-Projekt die Emulation, von diesem 38-12-Chip haben. Als nächstes haben wir noch eine Real-Time-Clock, das ist 1306 von, ne, ne Maxim, TI ist das, ne Maxim. Okay, danke. Gut, was ist da zu sagen, bei einem Emulator, also die RTC dieser Chip wird auf der Hardware per SP angesprochen, weil das ist unser Peripheribus und heißt also am Ende wieder via BitBang etc. Beim Emulator ist es jetzt ziemlich trivial, weil ich kann dann einfach die Systemzeit auslesen und antworte im Prinzip, wenn die angefragt wird, die entsprechenden Werte, es würde der Chip da vorliegen, muss man also nichts initialisieren, die geht halt immer richtig. Wir haben 96 Byte, den wir auch nutzen auf dem Steckschwein, zum Beispiel so, um Keyboard-Settings zu speichern oder den Bootloader, was der Kernel laden soll etc. Und in diesen 96 Bytes stehen diese Informationen, inkl. Checksumme und der Emulator macht das genauso, er nimmt also diese 96 Byte, schmeißt die in das Homeverzeichnis vom Nutzer und dort ist es gesichert. Okay. Das sieht dann, oh je. Na toll, jetzt habe ich keine Schelle. Ich will aber. Ne. Ne. Good. Das ist jetzt also der Emulator. Also ich fahre dann hoch, ich gebe ein Rom-Image an und eine SD-Karten-Image und dann bute ich im Prinzip das Steckschwein, ich kann das auch, kann ich Fullscreen machen hier klein. Aber und das ist auch jetzt erst in den letzten Monat entstanden. Ich habe eine SDL2-Portierung mittlerweile gemacht auf das Ganze, weil dann ich kann ich nämlich hier so Sachen machen, wie das Scaling, das funktioniert im SDL2 viel, viel besser. Und ja, ich kann jetzt hier zum Beispiel sagen, Uhrzeit, ach überraschend, geht ziemlich genau. Wie ich ja sagte, das ist jetzt hier funktioniert. Oder ob man was hört, oder nur aus dem Notebook-Gekrechte. Also das ist jetzt im Prinzip, hat er nicht. Der ist no line in. Really? Ah, okay, ein. Also Sound Emulation, wie gesagt, das ist der 3812-Schiff emuliert, code inspiriert aus einem Mem-Projekt, funktioniert. Genau. Das ist ein Graphic-Modil. Was kann ich da zeigen? Also, ja, natürlich auch ein Basic. Das ist in dem Fall hier so ein EH-Basic. Da gibt es dann auch ein, da gibt es dann so Sachen, Mandelbrot, nee, langweilig. Ich mache jetzt mal hier sowas. Da kann man dann auch sowas machen. Und funktioniert nicht. Worum nicht? Okay. Nee, dann muss man doch was anderes nehmen. Das ist ein Basic-Programm. Der hat jetzt mit dem Ries heißen, noch ein Thema. Ah, da war der Würfel. Ja, okay. Das ist dann also ein Basic-Programm mit einem Video-Modus, MSX Video-Modus 6, 512 Pixel. Ja, 512 x 212 und 4 Farben. Also sowas geht auch. Zack. Jo. Okay. Das ist ein Debugger. Der ist integriert. Also da komme ich dann hier rein. Kann ich da also einfach mal per F12. Zack, bin ich im Monitor und kann dann im Prinzip mir angucken, was da gerade passiert. Also das hilft auch ungemein bei der Entwicklung. Man kann also hier auch unten per Kommando noch im Memory rumschaufeln. Also kann ich jetzt hier gucken, Memory, Adresse, Hex 1000, 4096 oder weiter oben. Oder ich kann hier in der Zero-Page schauen, was da gerade passiert. Wir sehen hier auch die, wir sehen auch hier die Banking-Register, BR0123. Da sieht man also in der Bank 0, Bank, im Slot, im Slot, muss ich nur umbinden. BR01 ist RAM, also einfach die untersten 32K von dem 512K Baumstein sind selektiert. Der dritte Slot, BR02, ist also noch ROM, aktiv. Und der vierte Slot, BR03, ist die letzte Page in dem 512K-Ram, da ist jetzt gerade der Kernel drin. Wieso ist das 31, das ist der Dezimal. Ne, 3, 1, 4, das ist der Käse. Das ist Dezimal, das ist der Doof. Ich will da Hex haben. Na ja, okay. Gut, das soll es eigentlich zur Demo gewesen sein. Wie komme ich jetzt wieder in meinen Tingsbums? Genau. Okay. Wie geht es weiter in Richtung Emulation und Integration? Wir nutzen zur Entwicklung, oder ich primär, Visual Studio Code. Was ich haben möchte ist, was jetzt noch nicht toll ist, ist quasi eine richtige Idee Integration. Also ich will im Visual Code, wenn ich C Code, Java Code oder sonst was entwickeln, ich will da durchsteppen. Ich will da einfach debacken können mit unserem Emulator. Da gibt es natürlich eine Arpy, eine Debugger extension, da muss man also ein Adapter implementieren, dann kann man im Prinzip die IDE benutzen, weil Visual Studio liefert ja schon den Debugger-UI, muss man ja eigentlich nur die Arpy, den Kontakt erfüllen und schon kann man die Daten liefern, hat man super Debugger. Also das ist das, was ich habe, das ist das, was ich habe, das ist das Toolchain für unsere Entwicklung. Und zum Glück gibt es natürlich jemanden, der sich damit schon befasst hat. Also es gibt den Alchemy 65, das ist im Prinzip genau diese Adapter-Implementierung. Allerdings mit Masen X, das ist ein NAS-Emulator und ich werde den jetzt umbiegen und im Prinzip unseren Steckschwan-Emulator anzapfen und dann habe ich da wahrscheinlich ziemlich schnell die Integration am Start. Das gibt es dann wahrscheinlich spätestens nächstes Jahr. Wenn ich das habe, kann ich natürlich dann auch Steckschwan-Code, die Bucking machen, direkt über den Emulator. Ich kann mir Video-Speicher anzeigen lassen und Ram-Rom-Banks, das ist also noch das, was ich vorhab. Okay, das war der Emulator-Part. Es gibt noch einen anderen Part, und zwar Software-Entwicklung, was ich halt so täglich machen muss, soll, darf. Es ist halt also so ein bisschen mehr so testdriven Entwicklung und da geht es in die Richtung Unit-Tests und warum brauchen wir das? Steckschwan-Code, weil im Prinzip unser Library-Code ist, na ja, komplex, würde ich jetzt nicht sagen, aber ist halt umfangreich geworden und im Prinzip Verhalten abzusichern und die Produktivität zu steigern und auch testdriven hat auch den Vorteil, dass ich mehr Gedanken mache, wie modularisier ich meine Bibliotheksfunktion. Brauche ich irgendwie, brauchen wir die Möglichkeit, dass wir Tests haben, um quasi uns Verhalten abzusichern und auch irgendwie Regressions-Tests fahren zu können und die Kurzqualität zu verbessern. Wie sieht so was aus? Was brauche ich? Ich brauche eine Test-Abi letztlich und für gewisse Teile natürlich auch Mox, also beispielsweise SD-Karte oder andere Peripherie, die ich jetzt im Unit-Test ja irgendwie abstrahieren muss, weil ich jetzt da nicht immer den Emulator im Hintergrund haben will. Wie sieht so was aus? Also angelehnt an so Unit-Test-Frameworks und auf die 650.02 CPU adaptiert. Es gibt halt eine Reihe von Makros im CA65 Style, also ein Assert-A, wie Assert-Akku, XY-Register, ich kann Memory-Assorten, also sag hier Assert 32 und mein Erwartungswert und die Adresse und danach packe ich die Bytes, die ich da erwarte und dann kann ich ein Assort machen. Das habe ich in meinem Funktionsaufruf gemacht. Ich kann das Zero-Fleck Assorten oder Strings, also null terminiert, den Output kann ich capturen und kann danach fragen über die Output-Routine, was ist da rausgekommen, passt das so und ich kann auch hart meinen Test-Fail schlagen lassen aufgrund eines Konditionals. Das sieht man hier unten ganz. Wie sieht das jetzt konkret aus im Code? Also links habe ich beispielsweise eine Funktion, die heißt Hacks Out, so meine Unit-Under-Test und rechts dazu habe ich den Testcode, das heißt also ich mache CA65-Like den Import auf diese Funktion und dann habe ich einfach hier oben, sage ich, ich möchte bitte 7E ausgeben und rufe dann diese Funktion auf und kann danach mein Assert-Macro anwenden und dann erwarte ich, dass da im Prinzip im Output-Stream ein 7E gelandet ist und dann wird durch die Funktion, also Assert-Out 7E als Zeichenkette soll bitte schön in Output-Stream geschrieben worden sein und der Akku soll immer noch 7E enthalten und so kann ich im Prinzip meine Tests aufbauen und am Ende vom Tests gibt es ein Break und dann springt der Testcode wieder raus weil wir unter der Haube verwenden wir den PAI65, den Python-Implementierung. Wie gesagt, ob das dann nochmal der Emulator wird, dann drunterschnallen für die Unitests, muss man sehen, weil wir nicht so viele Tools haben, also ich will ein Standard Tools haben oder wir wollen Standard Tools haben, ich will nicht da noch ein Python haben müssen, dass man sich installieren muss und da noch irgendwas, sondern einfach Emulator und C-Compiler und das war's. CA65, Toolchain und das war's. Okay, was gibt's noch? Man kann auch nicht Funktionale-Tests machen, aber momentan ist es so bei dem PAI65 Integration, dass ich sogar Zyklen assurken kann, also ich kann im Prinzip eine Funktion aufrufen und kann sagen, okay, pass auf, ich mache ein Reset vorher und dann zählt er die Zyklen, weil diese Emulation von der CPU zählt er die Zyklen und dann kann ich danach fragen, okay, ich gelb einen Threshold an und wenn der überschritten wird, dann zerreißt es mir ein Test. Also wenn irgendjemand was implementiert und dann irgendwie zu teure Operation macht, dann ist es so, dass es nicht so gut geht, sondern weil das Performance-Goal nicht gehalten wird. Gibt da noch ein paar Hilfsmakros um irgendwelche Adressen zu vergleichen? Ja, okay. Ja, und am Ende landet das Ganze natürlich bei uns im GitHub, unsere Repositories. Also wir haben mehrere Repositories für die verschiedenen Sachen, Hardware-Code, Emulator und da hängt eine GitHub-Hatchen dahinter und da wird das ausgeführt letztlich, und wie wir hier sehen, natürlich grün, alles. Zumindest wenn ich eingecheckt habe, oder? Genau, und damit haben wir auch immer gleich Feedback. Wenn wir das geändert haben, passt das alles noch. Okay, ja, ein kleiner Abriss in die Steckschwein-Entwicklungswelt und wenn ihr Fragen habt, dann bitte gerne. Ist der Emulator genau auf die Geschwindigkeit von dem Steckschwein getaktet? Ja, der Momentan läuft, der, ne, stimmt nicht, stimmt nicht, der Steckschwein läuft mit 10 MHz und der Emulator mit 8. Also der Sync ist aber noch ein bisschen ungenau, weil es gibt dann irgendwelche Clitches mit dem Video, aber tatsächlich ist das noch so ein Thema, das ist nicht hundertprozentig. Also der ist schon Zykling genau, durch diese Fake-602-Implementierung werden die Zyklinge gezählt, aber was jetzt so das Echtzeitverhalten betrifft, ist ja nicht hundertprozent. Da muss man noch ein bisschen nachschärfen. Zu deinem Unitest, wo das Sammlerlisting war, kannst du das nochmal hören? Wie funktioniert das? Du hast gesagt, da hast du einen beiden Zeug dahinter? Ja, im Prinzip. Du kombalierst, du übersetzt das und dann stattest das an und wie greppt sich das beiden das Assert daraus oder hat es den Sourcecode noch neben dran oder interpretiert es direkt den Sourcecode? Ne, das wird ja auch kompelliert. Also das ist die Lipp, das wird kompelliert. Das sind Makros, genau. Die Unitest-Abi, das sind Makros. Das wird dann auch ausgeführt in den Pi 65. Also es wird der Code geladen und das wird der Unitest geladen und ausgeführt. Und dann wird im Prinzip der Assert, was halt Makros sind, am Ende steht da irgendwie JDR ausgeführt und der läuft durch oder schlägt fehl und dann bricht das Script letztlich ab, dann bricht der Bild letztlich auch stehen, Expected, Wars und, ja, hätte man vielleicht noch mal eine Folie einbauen können. Hätte ich das den Negativ-Fall zeigen, aber wir können uns das gerne anschauen. Also, hast du vielleicht auch Hill-Testing so in Aussicht? Sorry, was für Tests? Also Hardware in the Loop. Also du hast hier so Tomulator Software in the Loop und würde das überhaupt Sinn machen. Um zu prüfen, dass, keine Ahnung, dass der Emulator zur Hardware 100% passt oder so, keine Ahnung. Wäre dann die Kür, ja. Ne, aber habe ich, haben wir nicht. Also der Emulator wird im Prinzip der Hardware jetzt so nachempfunden, aber tatsächlich emuliert er ja auch nicht 100% nicht den CPLD. Also da gibt es irgendwo eine Memory-C-Datei, die macht diese Clou-Logik. Also da läuft das dann alles zusammen. Also nee, haben wir nicht. Okay, dann, Dankeschön.