Text Mode GUI selbst erstellen [BP7]

Text Mode GUI selbst erstellen [BP7]

Beitragvon Mr Vain » Sa 1. Jul 2017, 21:48

Hi zusammen,

seit langem (...Jahre??) habe ich mich wieder mit der Programmierung unter DOS beschaeftigt und meine Lieblings-IDE Borland Pascal 7.0 auf meinem 486er gestartet.

Vor einiger Zeit hatte ich mal ein paar (wenige) Programme geschrieben, wo ich mir grafische Elemente fuer den Textmodus erstellt habe. Da mir Turbo Vision iwie zu kompliziert und umstaendlich war, wollte ich es mir halt einfach machen und die Elemente selber bauen :-) Dass die Verwaltung der Bildschirmobjekte doch etwas aufwaendiger ist, musste ich dann bald feststellen, weshalb dieses Projekt dann nur eingeschraenkt funktionierte und nie ganz fertig wurde...

Nun habe ich ein paar Konzepte entwickelt (auf die viele andere sicher auch schon gekommen sind...), mit der das Ganze einfacher werden soll. Kurz gesagt: Ich moechte meine Text Mode GUI wieder neu auflegen 8-)

Hier mal ein kleiner Vorgeschmack, wie ich es mir vorstelle ;-)
Bild

Bisherige Meilensteine:
- Zeichnen in einen Offscreen Bereich
- Kopieren von Offscreen in den Bildschirmspeicher ($B800)
- bischen Assembler-Gefrickel zum Abstellen des nervigen Blinkens, sodass man auch helle Farben als Hintergrund nutzen kann
- Maussteuerung (mit Assembler-Codeschnipseln)
- Definition eines TView-Objekts
- von TView abgeleitetes TControl-Objekt, was auch OnMove- und OnClick-Methoden besitzt
- Desktop-Objekt mit Statuszeile
- Fensterobjekt mit Titelleiste

Noch zu erledigen:
- Viele weitere Objekte wie Mainmenu, Edit, ComboBox, ScrollBar, ProgressBar, CheckBox, RadioButton, etc...
- Fenster sollen skalierbar sein
- Reihenfolge der Fenster variabel -> Organisation der Reihenfolge der Objekte in einer Liste ist bereits realisiert
- Zuordnung von Objekten zu einem Fenster
- ...und was mir jetzt gerade nicht einfaellt ;-)

Mein Ziel ist es, dass die Text Mode GUI auch besser aussieht, als das altbackene Turbo Vision :mrgreen:

Ich hoffe dazu auf eure Hilfe, z.B. wie ich Routinen mit Assembler umsetzen kann.
Fan von klassischer PC Hardware.
1) Am5x86 auf ASUS VL/I 486SV2GX4, 1MB L2, 64MB RAM, VLB-Monster
2) Am5x86 auf ECS UM8810P-AIO, 512KB L2, 64MB RAM, PCI-486er

Komplett-PCs und Hardware gesucht? -> Mein Hardware Flohmarkt
Mr Vain
DOS-Guru
 
Beiträge: 522
Registriert: Sa 28. Sep 2013, 22:01

Re: Text Mode GUI selbst erstellen [BP7]

Beitragvon DOSferatu » Di 4. Jul 2017, 07:09

Hier sind mal meine (unsortierten) Gedanken und Anmerkungen dazu:

Ich habe immer mal wieder Textmode (und Grafikmode) TUI/GUIs gebaut und jedes Mal war der anfängliche Plan, das endlich mal als eine "Standardlösung" zu designen, d.h. als wiederverwendbare GUI, deren Elemente für ein Programm auch mit einem anderen Programm "angeordnet" werden können, so daß für die Position, Modus usw der einzelnen Elemente eine
Art Skript verwendet wird.

Mein (bisher nicht veröffentlichter) Editor "TheGame3" nutzt z.B. eine solche "geskriptete" GUI, die ganzen Menüs mit ihren Buttons, Eingabefeldern, Pulldowns usw. werden extern zusammengestellt und in TheGame3 nur noch angezeigt.
Hier gibt es auch die (von Dir erwähnte) Zuordnung von Objekten (ich nenne sie "Elemente") zu anderen Elementen, also hauptsächlich Fenstern. Die Koordinaten eines "zugeordneten" Elements beziehen sich dabei dann nicht mehr auf den ganzen Bildschirm, sondern auf die des Hauptobjekts - klickt man einen z.B. Button an, wird die Button-Nummer und die des Haupt-Elements gemeldet usw...

Ursprünglich sollte das Ganze auch noch mehr Elemente enthalten, Funktionen, die eigentlich besser bei Checkboxen und Radiobuttons aufgehoben gewesen wären, habe ich dort bisher mit so generalisierten Buttons erzeugt - andererseits wäre es (durch die skriptbasierte Steuerung der GUI) auch möglich, Buttons mit diesen Modi später an der gleichen Stelle als Optionen/Radiobuttons darzustellen.

Aber ich habe die Entwicklung an diesem "Elements" eingestellt; es wird nur in TheGame3 genutzt. Ich wollte, wie bereits erwähnt, hier immer mal etwas "generelles" schaffen, aber ich komme schon kaum dazu, meine ganzen Tools zu bauen - und eigentlich wollte ich ja endlich mal wieder ein Spiel schreiben.

Das Problem ist, daß, immer, wenn ich etwas "fertig" oder "quasi-fertig" habe, es mir nicht mehr so ganz gefällt - und dann denke ich jedes Mal: Das hätte an der Stelle eleganter und weniger umständlich gemacht werden können, dieser Parameter ist "zu mächtig" (weil z.B. neue Features durch Hinzufügen von Bits "angeflanscht" wurden) und hätte "sauberer" gemacht werden müssen oder diese Funktion kann zu wenig und erfordert dauernd zusätzliche Workarounds durch das Hauptprogramm.

Und dann ergibt es sich während der Benutzung der GUI (oder TUI) immer wieder, daß einem bestimmte Features fehlen, die für das Programm, das mit dieser GUI/TUI gesteuert werden sollen, wichtig wären - und jedes Mal überlegt man dann von neuem: Ist das "zu speziell" und ich "workarounde" die Funktion im Programm oder sollte man es als neue Funktion in die GUI selbst einbauen?

Das Ganze sollte dann ja auch wieder syntax-kompatibel mit der bereits bestehenden GUI sein, d.h. das Skript für die bestehenden und bereits benutzten Elemente soll dafür nicht verändert werden, also: Braucht ein Element eine neue Funktion, muß diese dann so eingebaut werden bzw deren Parameter so gestaltet werden, daß Skripte, die vor dem Einbau der neuen Funktion bereits geschrieben wurden, immer noch unverändert funktionieren.

Schlußendlich hatte das Ganze bei mir bisher (leider!) immer den Effekt, daß ich mit all der "Workarounderei" wieder mal so eine "Hybrid-Lösung" gemurkst hatte, die zwar im aktuellen Projekt funktionierte, aber kaum wirklich brauchbar war um vom aktuellen Projekt auch auf andere Projekte übertragen zu werden. Und daher habe ich - leider - bisher immer wieder für jedes neue Projekt neue GUI-Elemente gebaut. Meist liegt das daran, daß ich irgendwann mal mit dem Projekt selbst fertig werden wollte - und die GUI/TUI selbst nie selbst "das Projekt" waren, sondern nur Mittel zum Zweck.

Ein Beispiel für eine TUI (die längst nicht alle Funktionen hat, die ich mir von einer TUI wünschen würde) ist in meinem Programm "Prism" (befehlsbasierter, "MOD-ähnlicher" Musik-Editor) zu sehen. (Die TUI/GUI ist hier etwas Besonderes: Sie ist eigentlich Textmode, hat aber außer den reinen Textmodes (80x25, 80x50) auch zusätzlich in (VESA-) Grafik simulierte Textmodes - was für das Hauptprogramm keine Rolle spielt, da alles mit den gleichen Zugriffen erfolgt, d.h. die Elemente "wissen nicht", ob sie Textmode oder Grafikmode dargestellt sind. Das Ganze dient eigentlich nur dazu, dem User mehr Platz auf dem Bildschirm zur Verfügung zu stellen.)

Was Assembler angeht: Ja, ich benutze inzwischen oft und gern Assembler - und wenn ich die Zeit und Kraft aufbringen würde, würde ich am liebsten ALLES in Assembler schreiben. Hier ist aber meiner Meinung nach der Mittelweg der beste, um in absehbarer Zeit zu einem gescheiten Ergebnis zu gelangen. Sollte der Geschwindigkeitszuwachs von Assembler zu Hochsprache (z.B. Pascal) eher gering sein und man auch in Hochsprache durch geschickte Programmierung (wiederverwendeter Code) eine speichersparende Lösung erhalten, so lohnt sich meist keine Umsetzung in Assembler.

Außerdem gibt es ja auch immer die Möglichkeit, zunächst Dinge in Hochsprache zu schreiben und ausgiebig auf Funktion zu testen und wenn alles so läuft wie es soll, es erst dann in Assembler umzusetzen - somit verlegt man einen Großteil des Debuggings auf den Hochsprachenteil anstatt auf den Assemblerteil. (Debugging ist in Assembler meiner Erfahrung nach wesentlich anstrengender und zeitraubender.)

Allerdings kann bei einer generalisierten Lösung alles 100% in Assembler umzusetzen (oder lediglich die Prozedurköpfe in Hochsprache) ebenfalls eine gute Wahl sein - um dem eigentlichen Programm, das die GUI/TUI nutzen soll, so viel wie möglich Speicher und Ressourcen übrigzulassen. Ich hatte auch schon einmal den Gedanken, das Ganze so "API-artig" zu bauen, d.h. daß die jeweiligen Funktionen durch Zugriffe auf einen Software-INT aufgerufen werden - somit könnte man die GUI/TUI quasi unabhängig vom Programm laden und nutzen und (abwärtskompatible) Änderungen an der GUI/TUI würden keine Neukompilierung des Programms erfordern. Andererseits muß sich in diesem Fall das Programm dann auch hundertprozentig auf die GUI/TUI "verlassen können": Macht die GUI/TUI komische Dinge, ist das Programm diesem Umstand dann ausgeliefert (ja, so wie in Windows, wenn Treiber schlampig programmiert sind).

Mein Problem ist inzwischen oft der Zeitmangel - oder, falls ich mal Zeit haben sollte, die Müdigkeit. Unter der Woche ist "Freizeit" die paar Stunden nach dem Job vor dem Schlafengehen - d.h. die Tageszeit, wo man am müdesten ist. Und Wochenenden vergehen oft schneller als man denkt. Außerdem ist Programmierung auch teilweise ein kreativer Vorgang - aber Ideen oder Elan lassen sich nicht steuern auf eine bestimmte Tageszeit, wenn man sie braucht. Und völlig übermüdet ein neues einigermaßen komplexes Projekt anzufangen ist meist schon eine schlechte Idee. Die ganzen "Notlösungen", die man da anfangs einbaut, damit man überhaupt zu einer testbaren/ausführbaren Version kommt, werden dann später manchmal leider zum "Standard", d.h sie verbleiben inhärenter Bestandteil des ganzen Projekts, "weil es endlich brauchbar funktioniert".

Inzwischen habe ich einen - im Vergleich zu früher - wesentlich geringeren Software-Output, weil ich (bedingt durch schlechte Erfahrungen mit "Schnellschuß-Projekten") jetzt oft dazu neige, dem Ganzen eine relativ lange Planungsphase voranzuschieben. Ehe ich etwas wirklich in Programmcode umsetze, habe ich in Textfiles schon etliche Ideen/Konzepte/Formate aufgebaut, abgeändert, teilweise völlig gelöscht und wieder von vorn begonnen.

Für Unterprogramme (d.h. Routinen, Virtuelle Maschinen, o.ä., die von anderen Programmen benutzt werden sollen) ist mir die Methode, das ganze "während seiner Entstehung wachsen zu lassen" inzwischen etwas zuwider geworden. Das bedeutet NICHT, daß es nicht später neue Versionen mit neuen Features geben kann. Was ich damit meine ist eher, daß ich nicht mehr bereits bei der ersten Version damit anfangen will, benötigte und in der Planung nicht vorgesehene Features "außenrum anzuflanschen". Irgendwann hat das Ganze mehr "Angeflanschtes" um den "Kern" herum als den eigentlichen "Kern" - der dann kaum noch genutzt wird. Und dieser Kern ist aber noch das Einzige, was dem ursprünglich im Plan vorgesehenen Konzept entspricht. Damit hat man dann nur Lösungen, die unheimlich viel "Nacharbeit" durch das Hauptprogramm erfordern. Früher habe ich das mit der "Modularisierung" nicht so eng gesehen und hatte dann zwar funktionierende, aber eben leider auch "klotz-artige" Programme. Inzwischen VERSUCHE ich zumindest, diesem Zustand entgegenzuwirken.

Der Nachteil daran ist, daß man wahnsinnig viel Zeit mit Planung verbringt, sowie damit, wirklich total "entkoppelte" Units und Routinen zu bauen. Inzwischen habe ich da schon einiges fertig - leider ist aber keins davon eine GUI/TUI dabei, die man wirklich "einfach so" in ein Programm "einsetzen" könnte.

Man hat ja bei der Programmierung unter DOS und Realmode (bzw. 16/32bit Hybriden) auch noch andere Dinge zu beachten - nämlich, daß der vorhandene Speicher es einem verbietet, hier zu viele - zwar elegante, aber eben speicherfressende - "Spielerchen" zu machen und daß auch die Rechenleistung eines durchschnittlichen "DOS-Rechners" berücksichtigt werden muß: D.h. daß man hier natürlich nicht über etliche Abstraktionsebenen arbeiten kann, die alle zusätzliche Rechenzeit (und Speicher) für die Schnittstellen benötigen würden.

Inzwischen neige ich hier WIRKLICH dazu, schon im Vorfeld das alles sehr genau festzulegen, so daß man sich hinterher nicht zu wundern braucht "wo denn der ganze Speicher geblieben ist", sondern schon genau weiß, wieviel Speicher sowohl Programmcode als auch Daten die Unit/Bibliothek bzw ihre Unterfunktionen belegen. (Ja, ich messe bei der Programmierung den Programmspeicher aus, vor allem bei Assembler-Unterprogrammen.)

Mein Hauptaugenmerk liegt ja - bei aller Mühe, die ganzen Formate zu "erfinden" und Tools zu bauen - schlußendlich darauf, damit Computerspiele zu bauen (daher der Name Imperial Games). Und wenn daraus ein Gesamtprogramm (Spiel) werden soll, müssen die einzelnen Komponenten ja nicht nur für sich allein funktionieren, sondern auch gemeinsam in einem Hauptprogramm - und das Ganze so, daß auch für das Hauptprogramm noch genügend Rechenzeit und Speicher verbleiben.

Und ja: Auch diese "Spiel-Engine", die ich im Moment (wenn ich mal Zeit habe) baue, wird wieder eine Art (einfache) GUI erhalten - quasi ein einfaches "Menü-System", um, wie bei alten Konsolenspielen, so einfache Dinge wie START, SKILL, OPTIONEN, MUSIK, TASTENBELEGUNG zu ermöglichen - und ein bißchen mehr, damit man das Ganze nicht zu sehr einschränken muß.

Hier hadere ich noch mit mir, ob ich - so wie in Xpyderz - die ganzen Darstellungs-Skripte so in den Speicher lade und ein parser-artiger Skriptinterpreter das Ganze dann ausführt - ODER ob ich da extern bei der Erstellung des Spiels einen "Compiler" davorschalte, der diese Skripts in einen Bytecode umwandelt, der einfacher zu interpretieren wäre. Letzteres könnte wahrscheinlich im Spiel selbst einiges an Speicher und Rechenzeit einsparen, würde aber wieder die Entwicklung erschweren, weil zum Testen dann jedes Mal erst alles bytecode-compiliert werden müßte.

Entscheidungen, Entscheidungen...

Zum Thema skalierbare Fenster: Damit habe ich eher schlechte Erfahrungen gemacht, weil die Anordnung der Elemente ja schon irgendwie sinnvoll und fest sein muß - wo sollen diese hin, wenn das Fenster zu klein ist? Wenn das Fenster größer wird, was soll dann auf dem restlichen, nicht genutzten Platz stehen? Leere?

Im Textmode kann man ja auch nicht "halb-skalieren", d.h. wenn man z.B. ein 10 Zeichen hohes Fenster auf 15 Zeichen vergrößert, wird ein einzeliges Eingabefeld ja nicht 1,5 Zeilen hoch. Man könnte dann zwar die Abstände der im Fenster enthaltenen Elemente dynamisch gestalten - aber das Ganze muß ja trotzdem noch gut aussehen.

Einfacher ist es natürlich bei so mehrzeilgen "Text-Eingabefeldern" oder Pulldowns/Listenfeldern - hier wäre eine Skalierung weniger ein Problem.

Variable Fensterreihenfolge UND skalierbare Fenster sind zwar auch ein schöner Ansatz - das habe ich z.B. in Pirate-Chat (ein IRC-Client, gibt's auf meiner Webseite) so umgesetzt - aber es ist ein Pain-in-the-Ass, das umzusetzen. Da gibt es verschiedene Ansätze - alle brauchen Speicher und es läuft darauf hinaus, die maximale Anzahl von möglichen Fenstern zu begrenzen.

Anmerkung dazu: Die Umsetzung in Assembler zur Darstellung der Elemente sollte nicht allzu schwer sein; der Zugriff auf den Textmode-Speicher ist ja recht einfach.

Bei mehrzeiligen Texteingabe-Feldern würde ich an Deiner Stelle unbedingt Dinge für den Zeilenumbruch so früh wie möglich festlegen. Dieser Kram beißt einem sonst später in den Hintern.

Na gut - so viel erst einmal dazu von meiner Seite. Ich hätte noch mehr, aber der Text wird immer länger...

Wie ist das eigentlich bei Dir gedacht: Werden die einzelnen Elemente direkt als "Unterprogramme" aufgerufen -
z.B. BUTTON(X,Y,BREITE,HOEHE,TEXT,RESULTAT)
oder so -
oder erhält das Ganze ein Skript oder Bytecode oder ähnliches, das z.B. die Elemente zusammenfaßt und auf diese reagiert und automatisch auf Eingaben reagiert und "automatisch" Speicherinhalte ändert und dem Hauptprogramm nur entsprechende Ergebnisse liefert?
DOSferatu
DOS-Übermensch
 
Beiträge: 1086
Registriert: Di 25. Sep 2007, 11:05

Re: Text Mode GUI selbst erstellen [BP7]

Beitragvon Mr Vain » Mo 10. Jul 2017, 18:06

Yo! Das is mal ne Antwort :like: :-)

Da kann ich noch einige gute Ideen fuer mein Vorhaben rausziehen. Also die Verwaltung der Objekte wollte ich mit einer globalen Komponentenliste organisieren. Im Prinzip einfach ne Lineare Liste, wo als RECORD der Zeiger auf das Bildschirmobjekt (z.B. Fenster, Statusleiste, Desktop, ...) gespeichert wird, und dazu noch Zeiger fuer Vorgaenger- und Nachfolgerobjekt. Dann soll die Reihenfolge der Objekte in dieser Liste ja aenderbar sein, sodass beim Zeichnen der Objekte sich auch die geaenderte Abfolge darstellt. Das Generieren der Objekte mit Hilfe eines Skripts ist eine sehr interessante Idee. So aehnlich war das bei Turbo Vision mit den Streams auch, wimre... Aber wenn das zu kompliziert wird, dann gehts auch ohne Skript. Es soll eine Unit (oder DLL) werden, aus der ich die Objekte einfach so verwenden kann.

Das Ermitteln, welches Fenster angeklickt wurde, hab ich mit einer OnClick-Methode realisiert, die im TControl definiert ist und somit auch alle davon abgeleiteten Objekte (Fenster, Buttons, etc) besitzen. Dabei gehe ich dann in der Komponentenliste Objekt fuer Objekt durch und rufe die OnClick mit den Mauszeigerkoordinaten auf. Dabei fange ich sinnigerweise mit dem Objekt an, dass am weitesten "vorne" auf dem Bildschirm ist. Mann muss sich das Ganze dann wie Layers vorstellen, die uebereinander liegen. Dabei soll die Statuszeile immer ganz vorne sein, und der Desktop dann auf der ganz hinteren Layer. Beim Zeichnen fange ich dann die Komponentenliste von hinten an. Dabei hilft die doppelt verkettete Listenstruktur sehr viel weiter. Ist schonmal das betreffende Objekt ermittelt, werden alle diesem Bildschirmobjekt zugeordneten Objekte (MainMenu, Buttons, Edits, ScrollBars etc.) abgefragt.

Bisher ueberlege ich noch an einem geschickten Event-Handling, womit ich die Mausereignisse und die Abfrage der Tastaturscancodes, natuerlich in Assembler 8-) , vereinen kann. Ein Mausklick soll ein gleichwertiges Event sein wie ein Tastendruck. Das von Borland in der CRT mitgelieferte READKEY (...) naja, lassen wir dass :mrgreen: ...kein F11, F12 usw.

Ich moechte eine Tastaturabfrage realisieren, die nicht das ganze Programm anhaelt und auf Tastendruck wartet. Viel eher moechte ich das sog. "Polling" umsetzen, damit das Hauptprogramm "im Hintergrund" weiter arbeiten kann (z.b. Uhrzeit anzeigen, Berechnungen ausfuehren, ...).
Bisherige Versuche mit MOV AX,$11 haben nicht so ganz funktioniert, MOV AX,$10 geht hingegen ohne Probleme. Aber das ist ja wieder kein Polling... Aus dem SWAG-Archiv hab ich schon einige Beispiele angeschaut und ausprobiert. Die Moeglichkeit mit MEMW[$40:17] und MEMW[$40:18] scheint mir bisher die Beste zu sein.
Fan von klassischer PC Hardware.
1) Am5x86 auf ASUS VL/I 486SV2GX4, 1MB L2, 64MB RAM, VLB-Monster
2) Am5x86 auf ECS UM8810P-AIO, 512KB L2, 64MB RAM, PCI-486er

Komplett-PCs und Hardware gesucht? -> Mein Hardware Flohmarkt
Mr Vain
DOS-Guru
 
Beiträge: 522
Registriert: Sa 28. Sep 2013, 22:01

Re: Text Mode GUI selbst erstellen [BP7]

Beitragvon drzeissler » Di 11. Jul 2017, 14:23

...in 1989 hab ich mal unter GW-Basic versucht das Look- and Feel der Workbench des Amiga nachzubauen...und bin kläglich gescheitert...war aber auch mehr ein Gag um den Amiga-Kumpels mal zu zeigen, was eine EuroPC kann... :)
CPU: 486 DX2/66 MOBO: SNI-D882 RAM: 3x16MB - FDD: 3,5" 1,44MB HDD: 6,4GB Seagate ISA(1): Audican32Plus PCI(1): 3com TX 905 OS: MsDos622 - Win95a - WinNT 3.51
drzeissler
DOS-Gott
 
Beiträge: 2978
Registriert: Mo 8. Feb 2010, 16:59

Re: Text Mode GUI selbst erstellen [BP7]

Beitragvon Mr Vain » So 16. Jul 2017, 18:42

Yo!

Anbei erstmal ein Zwischenstand, wie es bisher lauffaehig ist. Was ich vom alten Projekt noch nicht aktualisiert habe, ist noch durch die {} auskommentiert.

...mit Zeigern rumspielen unter nem BP7 auf MS-DOS kostet manchmal echt Nerven :shock: :evil:

...muss die Dateien erst noch hochladen :roll:

In dieser Unit befinden sich alle visuellen Objekte
OBJDOS.PAS

Diese Unit steuert die Maus und soll noch ein Event-Handling bereitstellen, was Maus und Tastaturabfragen kombiniert
OBJIO.PAS

Und ein kleines Testprogramm, um die Objekte einzubinden
OBJTEST.PAS


Bisher ueberlege ich noch, ob ich die Abfrage von Maus und Tastatur wohl besser mit einem Interrupt ausfuehren lasse. Bisher hab ich aber mit Interrupt-Prozeduren noch sehr wenig Erfahrung. Frueher hab ich viel Pascal unter Windows 2000 programmiert und da gingen bestimmte Sachen wie Inline-Anweisungen nicht. Reines bzw. sauberes Assembler in Borland Pascal hat aber immer funktioniert 8-)

Sicherlich kann man noch viel von dem Code in Assembler umsetzen. Den Maus-Teil hatte ich auch schonmal in reinem Assembler, aber hier musste/wollte ich Parameter uebergeben. Deshalb wieder der Rueckschritt mit dem RECORD Registers, der in der Unit DOS vordeklariert ist.
Fan von klassischer PC Hardware.
1) Am5x86 auf ASUS VL/I 486SV2GX4, 1MB L2, 64MB RAM, VLB-Monster
2) Am5x86 auf ECS UM8810P-AIO, 512KB L2, 64MB RAM, PCI-486er

Komplett-PCs und Hardware gesucht? -> Mein Hardware Flohmarkt
Mr Vain
DOS-Guru
 
Beiträge: 522
Registriert: Sa 28. Sep 2013, 22:01


Zurück zu Programmierung

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast