Hallo zusammen, ich bin dabei ein altes ROM zu decrypten und würde dazu gerne im laufenden System die ROM zugriffe einer 4Mhz Z80 CPU sniffen. Die ROM Zugriffe passieren im System maximal all 1µs (ein memory access kann minimal 4 Taktzyklen lang sein, aber auch erheblich länger). Ich möchte jetzt folgendes machen: Pico an den Address und Datenbus anschließen, sowie die RD und IORQ Leitungen (die werden im System benötigt). Wenn die richtige Bedingung vorliegt (also ROM read und das richtige ROM selektiert ist), dann möchte ich die Daten vom Datenbus lesen (also den Output vom ROM Modul) und in ein 16 KByte Array schreiben. Dazu muß ich die unteren 14 Bits der Adresse auslesen und die 8 bits vom Datenbus lesen. Das ROM ist immer im Adressbereich C000-FFFF, also muß ich mir die oberen beiden bits nicht merken und komme mit 16Kbyte klar. Ich habe jetzt über den Raspberry PI pico nachgedacht. Der hat genug GPIOs, ist sehr billig und hat 256kb RAM intern, was ja für meinen Bedarf (Programm + Daten) ausreicht. Für den Anschluß muß ich noch den Signallevel konvertieren (5 to 3.3V). Einzige Frage die ich nicht genau beurteilen kann (habe ich keine Erfahrung): Ist der Pico schnell genug mit den 133Mhz um das maximal 1Mhz schnelle read from ROM zuverlässig zu capturen? Wenn das ROM aktiv ist, muß der PICO nichts weiter tun als auf einen Interrupt auf der RD Leitung zu reagieren und dann Adressleitungen und Datenleitungen zu lesen und das Datenbyte in das Array an der Position der Adressleitungen zu schreiben. Das sollte mit ein paar C Befehlen erledigt sein. Ansonsten befindet sich die CPU im Grunde in einer Warteschleife und wartet auf den nächsten Interrupt, oder gibt gerne auch Irgendwas auf der Console aus etc. Also, was meint Ihr - ist der PICO schnell genug dafür? Gruß Christoph
:
Bearbeitet durch User
Christoph L. schrieb: > Die ROM Zugriffe passieren im System maximal all 1ms (ein memory access > kann minimal 4 Taktzyklen lang sein, aber auch erheblich länger). Nicht Millisekunden, Mikrosekunden (µs). Christoph L. schrieb: > Ist der Pico schnell genug mit den 133Mhz um das maximal > 1mhz schnelle read from ROM zuverlässig zu capturen? MHz, nicht mhz. mHz wären Millihertz. Ja, er sollte definitiv schnell genug sein, insbesondere, wenn man die programmierbaren I/Os nutzt. Ist das Ziel der Übung einfach nur das Auslesen des ROMs? Warum steckst Du das nicht in ein geeignetes Programmiergerät?
Danke, korrigiert. Der Hauptgrund ist, daß das Rom encrypted ist mit etwas das man nicht einfach durch einen decrypter laufen lassen kann. Es sitzt in einem Modul und hat ein bissl logic zwische dem EPROM und dem Datenbus sitzen. Die Logic verknüft ~(~M1) AND ((ADR3 XOR DATA5) OR (ADR5 XOR DATA2)) In einfachen Worten: Immer wenn kein M1 zyklus der CPU vorliegt, dann XORe die Datenbits mit den dazugehörigen Addressbits. Da ich aber rein am ROM code nicht erkennen kann wan ein M1 zyklus vorliegt (OP code read), muß ich das entweder vollkommen disassemblieren und die read routinge des Disassemblers patchen (habe ich schon gemacht) und zu 90% erfolgreicht disassembled, oder eben das echte System den Code ausführen lassen und den Datenbuss nach decryption sniffen. Das heißt das hier ist der Ansatz zum 2. Punkt. Ist ein ROM Modul aus den 80er Jahren für den Schneider CPC 464 (Vortex X-Modul). Leider gibt es den originalen Source code für das ROM nicht, also reengineering. Kleines vollkommen nutzloses Hobbyprojekt :-)
https://hackaday.com/tag/kabuki/ Encrypted Z80... Die fanden sich oft in Arcadeplatinen wie z.B. Pang! und hatten den Opcode decrypted, nicht aber die Daten. Das musste man mühsam durch M1 heraustesten. Die Decryption Tabelle war Akkugestützt flüchtig im Kabuki abgelegt. Akku leer - Spiel tot.
:
Bearbeitet durch User
Christoph L. schrieb: > In einfachen Worten: Ok, das ist 'ne Erklärung. Bei der Herangehensweise findest Du natürlich nur die Datenbereiche, zu denen während der Laufzeit des Programmes zugegriffen wird. Wenn es aber Codepfade gibt, die nur unter bestimmten Bedingungen aufgerufen werden, fehlen die in Deinem decodierten Ergebnis, solange Du nicht sicher dafür sorgen kannst, daß die entsprechenden Bedingungen erfüllt werden. Und gerade bei einem Spiel kann ich mir so etwas gut vorstellen, da könnte es Spielelevel geben, die man erst mal erreichen muss, oder besondere "Belohnungsbildschirme", die erst bei Erreichen einer gewissen Punkt- oder Levelanzahl zu sehen sind. Du könntest das ROM mitsamt seinem Decoder an ein Programmiergerät (o.ä.*) hängen und es einmal komplett mit aktivierter M1-Leitung und einmal komplett mit deaktivierter M1-Leitung auslesen. *) Selbst stricken: Adress- und Steuerleitungen mit dem Pico erzeugen, resultierende Datenleitungen einlesen. Geschwindigkeit ist hier dann irrelevant, da nicht dem lebenden System auf die Finger geguckt werden muss.
Ah, ja nahe dran. Hier ist es keine CPU die encrypted ist, sondern das ROM selber. Das heißt im ROM sind die Bytes für die Daten encrypted, aber die Opcodes selber nicht. Das heißt man muß einen Spezial-Assembler bauen, der eben die Opcodes unverändert lässt, aber die Daten in verschlüsselter Form ausspuckt. Die Logik ist hier glücklicherweise in Hardware implementiert, so daß die nicht kaputt gehen kann, mal abgesehen von defekten Bausteinen. Für die CPU sind die Daten okay (kein Code notwendig), aber das ROM kann man eben so nicht auslesen. Danke für den Link, sehr interessant.
Harald K. schrieb: > Du könntest das ROM mitsamt seinem Decoder an ein Programmiergerät > (o.ä.*) hängen und es einmal komplett mit aktivierter M1-Leitung und > einmal komplett mit deaktivierter M1-Leitung auslesen. > > *) Selbst stricken: Adress- und Steuerleitungen mit dem Pico erzeugen, > resultierende Datenleitungen einlesen. Geschwindigkeit ist hier dann > irrelevant, da nicht dem lebenden System auf die Finger geguckt werden > muss. Ich glaube das funktioniert nicht, das hatte ich schon mal überlegt. Nehmen wir mal an M1 ist active high, weil das einfacher zu schreiben ist. Wenn wir also alles mit aktiviertem M1 auslesen, dann ist das so, als ob wir das ROM direkt auslesen. Es wird also kein decoding gemacht. Und alles wird am Datenbus so ausgegeben, wie es im ROM steht. Wenn ich allerdings mit deaktiviertem M1 lese, dann wird alles decoded. Ich habe also zwei zu 100% unterschiedliche ROMS. Damit kann ich nicht herausbekommen, was mal ein Opcode war und was nicht. Habe ich hier einen Denkfehler? Wäre tolle wenn ja :-) Zum Thema Datenbereiche etc. hast Du vollkommen recht. Glücklicherweise handelt es sich hier um eine Firmware für einen Floppy Controller. Das meiste ist per RSX-Befehlen direkt anzuspringen und die CPM BIOS calls sind der schwierigere Teil. Aber da ich ja schon zu 90% erfolgreich mit der Dissassemblierungsmethode war, soll dieses Vorgehen quasi nur die Lücke schließen. Insbesondere sehr schwierig sind reine Datenbereiche, die dann Code enthalten der ins RAM kopiert wird und dort ausgeführt wird. Wenn da irgendwas schief geht, dann fliegt einem das um die Ohren. Das heißt diese Datenbereiche müssen alle decodiert werden, währen code segmente, die einfach nur nicht identifiziert wurden mit dem M1 im Sinn decodiert werden müssen.
Ach so noch was. Natürlich habe ich schon einen decoder in software geschrieben, der die logic auf das ausgelesene ROM anwendet, aber da scheitere ich dann genau daran, daß ich eben nicht weiß (nur auf Basis des ROMs) was ein M1 zyklus (Opcode) ist und nicht decodiert werden müsste und was nur "Daten" für die CPU sind.
Christoph L. schrieb: > Ah, ja nahe dran. Hier ist es keine CPU die encrypted ist, sondern das > ROM selber. Ja, das ist schon klar. Das Problem halt ist, herauszufinden, welche der Bytes Opcodes sind (d.h. mit aktivem M1 gelesen werden) und welche nicht. Mit der Analyse zur Laufzeit ist das aufgrund des Codepfadproblems halt nicht eindeutig bestimmbar.
Christoph L. schrieb: > ich bin dabei ein altes ROM zu decrypten und würde dazu gerne im > laufenden System die ROM zugriffe einer 4Mhz Z80 CPU sniffen. Der Z80 unterstützt keine verschlüsselten Speicher. Daher muss auch nichts entschlüsselt werden, sondern liegt im Klartext vor. > Ich möchte jetzt folgendes machen: > Pico an den Address und Datenbus anschließen, sowie die RD und IORQ > Leitungen (die werden im System benötigt). IORQ hat nichts mit den ROM-Zugriffen zu tun. MREQ zeigt Speicherzugriffe an. > Dazu muß ich die unteren 14 Bits der Adresse auslesen und die 8 bits vom > Datenbus lesen. Das ROM ist immer im Adressbereich C000-FFFF, also muß > ich mir die oberen beiden bits nicht merken und komme mit 16Kbyte klar. Es bietet sich eher an, das Auslesen durch die /CE- bzw. /CS-Leitung(en) des ROMs zu triggern. Welche dieser Leitungen mit dem Adressdecoder verbunden ist/sind, hängt vom (EP)ROM-Typ und der konkreten Schaltung ab. > Also, was meint Ihr - ist der PICO schnell genug dafür? Ja, sofern nicht die Nebenfunktionen wie z.B. UART-Übertragung zu lange Interruptsperren o.ä. verwenden.
Andreas S. schrieb: > Der Z80 unterstützt keine verschlüsselten Speicher. Daher muss auch > nichts entschlüsselt werden, sondern liegt im Klartext vor. Das hat Christoph eigentlich schon ausreichend erklärt. Zwischen dem ROM und der CPU sitzt eine Logik, die die vom ROM gelieferten Daten "aufbereitet", und zwar in Abhängigkeit des M1-Signales (und zweier Adressleitungen): Christoph L. schrieb: > Die Logic verknüft ~(~M1) AND ((ADR3 XOR DATA5) OR (ADR5 XOR DATA2)) > > In einfachen Worten: > Immer wenn kein M1 zyklus der CPU vorliegt, dann XORe die Datenbits mit > den dazugehörigen Addressbits.
Harald K. schrieb: > Andreas S. schrieb: >> Der Z80 unterstützt keine verschlüsselten Speicher. Daher muss auch >> nichts entschlüsselt werden, sondern liegt im Klartext vor. > > Das hat Christoph eigentlich schon ausreichend erklärt. Oh, vielleicht hätte ich meine Antwort sofort vollständig verfassen und das Schreiben nicht zwischendurch für längere Zeit unterbrechen sollen... Die ganzen zwischenzeitlichen Nachrichten hatte ich nicht rechtzeitig gelesen.
Christoph L. schrieb: > Einzige Frage die ich nicht genau beurteilen kann (habe ich keine > Erfahrung): Ist der Pico schnell genug mit den 133Mhz um das maximal > 1Mhz schnelle read from ROM zuverlässig zu capturen? Hab's zum Spaß gerade mal in Python (40 verschwenderische Zeilen) auf dem Pico Pi kodiert. Eine Million Lesezugriffe, Maskierung der relevanten Daten (Adr,data,iorq,rd) und das Abspeichern der opcodes in ein Array brauchen 640074µs.
Andreas S. schrieb: > IORQ hat nichts mit den ROM-Zugriffen zu tun. MREQ zeigt > Speicherzugriffe an. Das stimmt im allgemeinen, aber im Besonderen brauche ich die IORQ Leitung um den ROM Select abzufangen. Ich darf ja nur bestimmte ROM reads lesen. Das ist eine Eigenart des Schneider CPC, nicht normalerweise einer Z80 CPU als solchem. > Es bietet sich eher an, das Auslesen durch die /CE- bzw. /CS-Leitung(en) > des ROMs zu triggern. Welche dieser Leitungen mit dem Adressdecoder > verbunden ist/sind, hängt vom (EP)ROM-Typ und der konkreten Schaltung > ab. Ich wollte es mir einfach machen, und mich einfach an den BUS hängen, also parallel zum ROM. Aber ich kann natürlich einfach die /CE /OE Leitungen vom ROM abfangen und weiß dann genau, wann der konkrete ROM baustein was ausgibt. Dann nur noch die konkreten decodierten Daten abgreifen. Das ist sicher einfacher ... einfach zwei kleine drähte an den EPROM Sockel anlöten - fertig. Noch zum Verständnis: Der CPC hat zwei Teile. Zuerst muß auf dem Erweiterungsboard eine ROM Select Schaltung sein. Diese zieht das /OE auf null, wenn das entsprechende ROM selectiert wurde. Zusätzlich liefert dann das GateArray ein /ROMEN signal welches mit dem /CE signal des ROMs verbunden wird. Das kann also direkt verwendet werden und ich muß mich nicht om /MREQ und /RD kümmern, da bei /ROMEN durch das GateArray und die logik darin schon sichergestellt ist, daß es ein /RD und ein /MREQ (und noch ein paar interne Register) handelt. Also diese beiden Signale sind mir daher egal und ich kann mich auf /ROMEN verlassen. IORQ brauche ich nur für ROM-Select und das muß ich auch auswerten. (Einfacher /OE abgreifen am originalen controller, der diese Logic ja schon implementiert hat). > >> Also, was meint Ihr - ist der PICO schnell genug dafür? > > Ja, sofern nicht die Nebenfunktionen wie z.B. UART-Übertragung zu lange > Interruptsperren o.ä. verwenden. Ich werde das so realisieren, daß ich während des tracings nichts anderes mache (höchstens beim debugging), so daß ich im Grunde nur in einer Warteschleife hänge und auf den nächsten Interrupt warte, aber den Interrupt nicht disable in der Warteschleife etc.
Norbert schrieb: > Christoph L. schrieb: >> Einzige Frage die ich nicht genau beurteilen kann (habe ich keine >> Erfahrung): Ist der Pico schnell genug mit den 133Mhz um das maximal >> 1Mhz schnelle read from ROM zuverlässig zu capturen? > > Hab's zum Spaß gerade mal in Python (40 verschwenderische Zeilen) auf > dem Pico Pi kodiert. > Eine Million Lesezugriffe, Maskierung der relevanten Daten > (Adr,data,iorq,rd) und das Abspeichern der opcodes in ein Array brauchen > 640074µs. Okay, wenn es in Python geht, geht es auch in C :-) Ich könnte auch ein Arduino Mega nehmen, aber der läuft nur mit 16Mhz. Das hätte den Vorteil, daß er 5V tolerant ist. Dummerweise hat der kein RAM (nur sehr wenig - 8kb reicht nicht). Also könnte ich mit Arduino evtl. nur die Steurleitungen bearbeiten und ein SRAM direkt an die Datenleitungen und die Adressleitungen hängen und den /WR mit dem Arduino steuern und /CE kommt durch den Abgriff am ROM /OE (also Rom Select). /WR müsste ich dann vom /ROMEN generieren mit etwas delay, damit das ROM auch daten ausgegeben hat und dann nach kurzer Zeit (für das SRAM was mir vorschwebt dann nach 70-100ns wieder wegnehmen. Damit habe ich einen sauberen write und das innerhalb der offiziellen Zyklen, da die CPU ja 500ns braucht von /RD bis wirklich gelesen wird und das EPROM 70ns Antwort Zeit hat. Also nach 70ns liegt das Signal am EPROM ausgang an, und dann brauche ich noch 50ns für das SRAM um die Daten zu schreiben. Klingt das nach einem Plan? Der Arudino würde dann beim Tracing nur auf einen Eingang hören und einen Ausgang steuern. Das müsste doch mit 16Mhz funktionieren? Ach ja - wenn das tracing fertig ist, kann ich dann in aller Ruhe das SRAM auslesen und über Serielle Schnittstelle an den PC übertragen.
:
Bearbeitet durch User
Christoph L. schrieb: > Ich wollte es mir einfach machen, und mich einfach an den BUS hängen, > also parallel zum ROM. Direkt am ROM bekommst Du aber nicht die Daten, die Du bekommen willst. Du musst Dich zwischen CPU und "Verwirr-Logik" anklemmen, sonst siehst Du nur das, was im ROM steht (und was Du mit 'nem Programmiergerät auslesen kannst). Da Dich aber das interessiert, was die CPU sieht, musst Du Dich zwischen dem Busstecker Deines CPC und dem Steckmodul einklinken.
Christoph L. schrieb: > Okay, wenn es in Python geht, geht es auch in C :-) So isses. (Wenn man sich die zusätzliche Arbeit ohne zusätzlichen Nutzen machen will ;-) ) > Ich könnte auch ein Arduino Mega nehmen, aber der läuft nur mit 16Mhz. > Das hätte den Vorteil, daß er 5V tolerant ist. Beim RP2040 jeweils einen 22kΩ in Serie zu den Eingängen. Mit dem internen Pull-Down aktiviert fließen da nur noch vernachlässigbar wenige µA.
Norbert schrieb: > Christoph L. schrieb: >> Ich könnte auch ein Arduino Mega nehmen, aber der läuft nur mit 16Mhz. >> Das hätte den Vorteil, daß er 5V tolerant ist. > > Beim RP2040 jeweils einen 22kΩ in Serie zu den Eingängen. Mit dem > internen Pull-Down aktiviert fließen da nur noch vernachlässigbar wenige > µA. Quellimpedanz im Bereich >10 kOhm, Lastkapazität im Bereich >10 pF und dann 4MHz? Wenn das mal nicht verdammt eng wird...
Vollkommen abstruse Idee .... Einen CPC Emulator auf einem Raspi nehmen und das Modul direkt anschließen und direkt während der runtime disassembeln ... also quasi live disassembler durch das was die CPU wirklich sieht. Das könnte in einem Emulator so funktionieren. Aber ist irgendwie auch nicht mal so eben gemacht.
Ob S. schrieb: > Wenn das mal nicht verdammt eng wird... Hmmm, ja. Muss das Scope letztlich entscheiden. Flanken dürfen gerne ›rund‹ sein, Schmitt-Trigger (bei 1/2 Vcc ± 100mV) Eingänge hat der pico ja. Christoph L. schrieb: > Einen CPC Emulator auf einem Raspi nehmen und das Modul direkt > anschließen und direkt während der runtime disassembeln ... also quasi > live disassembler durch das was die CPU wirklich sieht. Das könnte in > einem Emulator so funktionieren. Wozu? Ändert sich doch nichts. Die 16KiB einsammeln, rüber auf den erwachsenen Computer und dann genüsslich auseinander nehmen. Da fällt mir gerade auf, dann wird das olle Programm ja 41 Zeilen lang… ;-)
:
Bearbeitet durch User
Norbert schrieb: > Wozu? Ändert sich doch nichts. Die 16KiB einsammeln, rüber auf den > erwachsenen Computer und dann genüsslich auseinander nehmen. Meine Anmerkungen zur Codeabdeckung hast Du auch gelesen? Solange das laufende Programm nicht alle Codepfade ausführt, wird nicht der vollständige Inhalt des ROMs gelesen, sondern nur der für den Ablauf des Teils des Programmes. Wie ich schon schrieb, enthalten Spiele aber auch Code, der nur unter bestimmten Bedingungen ausgeführt wird, z.B. ein spezieller "Belohnungsbildschirm", der nur ausgegeben wird, wenn alle "Level" durchspielt wurden o.ä.
Harald K. schrieb: > Meine Anmerkungen zur Codeabdeckung hast Du auch gelesen? Ja selbstverständlich Harald. Dann lässt man es halt solange laufen bis alles eingelesen ist. Und wenn's Tage und Wochen dauert. Da muss sich der Spieler schon etwas Mühe geben. ;-)
Christoph L. schrieb: > Dazu muß ich die unteren 14 Bits der Adresse auslesen und die 8 bits vom > Datenbus lesen. Das ROM ist immer im Adressbereich C000-FFFF, also muß > ich mir die oberen beiden bits nicht merken und komme mit 16Kbyte klar. Das was du eigentlich suchst nennt sich Logic Analyser. Mit denen wird genau sowas gemacht (früher sogar mit Z80 Disassembler...) Christoph L. schrieb: > Also, was meint Ihr - ist der PICO schnell genug dafür? Ja. Gibt mittleerweile 3-4 fertige Logic Analyser Projekte die den PICO nutzen und auch Treiber für Sigrok/Pulseview mitbringen (glaub noch keiner davon in Sigrok Mainline). Z. B. hier beschrieben: https://hackaday.com/2022/03/02/need-a-logic-analyzer-use-your-pico/
Norbert schrieb: > Ob S. schrieb: >> Wenn das mal nicht verdammt eng wird... > > Hmmm, ja. Muss das Scope letztlich entscheiden. Man kann sowas auch ausrechnen. Sogar ausrechnen lassen. Siehe Anhang.
Ob S. schrieb: > Man kann sowas auch ausrechnen. Sogar ausrechnen lassen. Siehe Anhang. Stimmt. Der Herr Euler hat uns freundlicherweise eine passende Zahl hinterlassen. Falls man's selbst machen möchte. LTspice habbich übrigens auch. (Sogar genutzt) Wo kommen denn die 10kΩ R2 her? Der RP2040 hat zwischen 50kΩ und 80kΩ Pull-Down. Da sah das vorhin, als ich es probiert hatte, schon ganz anders aus.
Norbert schrieb: > Wo kommen denn die 10kΩ R2 her? Ich war zu faul, im DB nachzuschauen. > Der RP2040 hat zwischen 50kΩ und 80kΩ > Pull-Down. > Da sah das vorhin, als ich es probiert hatte, schon ganz anders aus. Das ändert rein garnix an der Amplitude des AC-Anteils. Verschiebt die Sache bloß DC-mäßig nach oben. Um das sagen zu können, brauchte ich nichtmal erneut LTSpice anwerfen.
Ob S. schrieb: > Verschiebt die > Sache bloß DC-mäßig nach oben. Um das sagen zu können, brauchte ich > nichtmal erneut LTSpice anwerfen. Und wenn die Amplitude nun plötzlich deutlich über und unter die Hysterese geht?
Norbert schrieb: > Da muss sich der Spieler schon etwas > Mühe geben. ;-) wenn er es denn schafft, nicht jeder Mensch schafft alle Level.
Joachim B. schrieb: > wenn er es denn schafft, nicht jeder Mensch schafft alle Level. Muss er ja nicht selbst machen. Für den Gegenwert eines halb-verrotteten Cheeseburgers mit Pommes bekommt man problemlos ein kindlich-schlichtes Gemüt gemietet. In einem der anderen Threads hier gibt es sogar einen Kandidaten mit einem ganz besonders schlichten Gemüt der sich für solch eine Aufgabe MAXimal eignen würde.
Norbert schrieb: > Für den Gegenwert eines halb-verrotteten Cheeseburgers mit Pommes > bekommt man problemlos ein kindlich-schlichtes Gemüt gemietet. Möchte man dem aber seinen historischen Computer zur Verfügung stellen? Eher nicht.
Norbert schrieb: > Ob S. schrieb: >> Verschiebt die >> Sache bloß DC-mäßig nach oben. Um das sagen zu können, brauchte ich >> nichtmal erneut LTSpice anwerfen. > > Und wenn die Amplitude nun plötzlich deutlich über und unter die > Hysterese geht? Dann reicht das zwar, um ein (näherungsweise symmetrisches) Taktsignal einzulesen, aber nicht, um auch die anderen Signale korrekt zu erfassen, die ja alles andere als symmetrisch sein werden.
Harald K. schrieb: > Norbert schrieb: >> Wozu? Ändert sich doch nichts. Die 16KiB einsammeln, rüber auf den >> erwachsenen Computer und dann genüsslich auseinander nehmen. > > Meine Anmerkungen zur Codeabdeckung hast Du auch gelesen? > > Solange das laufende Programm nicht alle Codepfade ausführt, wird nicht > der vollständige Inhalt des ROMs gelesen, sondern nur der für den Ablauf > des Teils des Programmes. > > Wie ich schon schrieb, enthalten Spiele aber auch Code, der nur unter > bestimmten Bedingungen ausgeführt wird, z.B. ein spezieller > "Belohnungsbildschirm", der nur ausgegeben wird, wenn alle "Level" > durchspielt wurden o.ä. Wie schon gesagt, es handelt sich hier um ein ROM für einen Disk-Kontroller - nicht um ein Spiel. Also kann man das mit in menschlichem Ermessen durchspielen, insbesondere da ich nahezu alle Funktionen disassembliert habe und auch weiß, was wie wo passiert, und was die Funktionen so alle machen. Der CPM Teil macht noch ein paar Probleme - da passiert im Aufruf der BIOS funktionen etwas eigenartiges, was zu Abstürzen führt. Also ein einfacher Widerstand führt nicht zu einem Ergebnis. Das Signal, das ich abgreifen möchte muß schon akkurat vorliegen, da ich nur 500µs Zeit habe die echten Daten nach anliegen des Signals auszulesen. Es wäre einfach super, wenn es einen PICO oder was ähnliches gäbe was 5V tolerant ist. Also schnell genug und mit genug IO-Pins und genug RAM um das direkt und ohne irgendwelche zwischenlösungen zu erreichen. Gibt es da einen µController, der das kann?
Christoph L. schrieb: > Es wäre > einfach super, wenn es einen PICO oder was ähnliches gäbe was 5V > tolerant ist. Da Du nur Signale einlesen willst, schalte einfach einen 2k2 Widerstand vor jeden Eingang. Die Geschichte ist doch problemlos umsetzbar.
Und damit zerblase ich mir nicht den PICO? Der ist nicht 5V tolerant und die Eingänge vertragen maximal zusammen 50µA ... wenn ich also 24 Eingänge anhänge, dann ist es im Worstcase max 2µA je Eingang, falls alle Eingänge grade High sind. Auf der anderen Seite haben wir es aber mit NMOS zu tun, die können zum Teil einige mA schieben können. Insbesondere bei dem ROM Modul ist es ja nicht das EPROM, das da schiebt, sondern die TTL Bausteine, die hinter den DatenLeitungen hängen. Will nur sicher gehen, nicht daß die 5 Euro jetzt ein Wahnsinniger Verlust wären, wenn der PICO über die Wupper geht, aber es wäre mir doch sehr unangenehm, im Sinne ElektroSchrott. Sicher ist es kein Problem da die Vorwiederstände zwischenzuhängen, insbesondere wenn es nur 2k2 sind. Allerdings sind jetzt hier im Thread schon zig vorwiederstände vorgeschlagen worden - das macht mich da etwas unsicher.
Christoph L. schrieb: > Wie schon gesagt, es handelt sich hier um ein ROM für einen > Disk-Kontroller - nicht um ein Spiel. OK, das hatte ich wohl übersehen. > Also kann man das mit in menschlichem Ermessen durchspielen, Sicher? Das Ding kann z.B. auch Fehlerbehandlung machen, die ohne ein entsprechend fehlerhaftes Medium nicht aufgerufen wird. Oder besondere Arten von Formatierung unterstützen, die ebenfalls nicht immer aufgerufen werden. > insbesondere da ich nahezu alle Funktionen disassembliert habe Das wiederum macht mich jetzt stutzig. Wie kannst Du (nahezu) alle Funktionen disassembliert haben, wenn Du noch nicht mal den decodierten ROM-Inhalt vorliegen hast?
Ich glaube ich mache mir das einfach.. Das hier sollte doch die Lösung sein? https://www.amazon.de/FREENOVE-Breakout-Raspberry-Terminal-Shield/dp/B0BFB53Y2N/ref=sr_1_2?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=2GT6U15SYQ77K&keywords=Breakout+Board+f%C3%BCr+Raspberry+Pi+Pico&qid=1707560588&sprefix=breakout+board+f%C3%BCr+raspberry+pi+pico%2Caps%2C77&sr=8-2
Christoph L. schrieb: > Also ein einfacher Widerstand führt nicht zu einem Ergebnis. Das Signal, > das ich abgreifen möchte muß schon akkurat vorliegen, da ich nur 500µs > Zeit habe die echten Daten nach anliegen des Signals auszulesen. Also mit den korrekten Einheiten hast du es wirklich nicht so, oder? Es werden natürlich eher 500ns sein. > Es wäre > einfach super, wenn es einen PICO oder was ähnliches gäbe was 5V > tolerant ist. Bestmögliche Näherung wäre wohl ein AVR128DA/B/D. Der kann direkt mit 5V betrieben werden, schafft 32MHz Takt, enthält konfigurierbare Logik, die sich sicherlich in deiner Anwendung sinnvoll nutzen ließe und er bietet 16kB SRAM intern. Die jeweils kleinste Variante mit 28Pins gibt's sogar in DIL zu kaufen. Was mir außerdem noch zu dem Thema eingefallen ist: du brauchst eigentlich garnicht so viel RAM. Du kannst vorab ja das Ziel-ROM auslesen und dann in zwei Varianten in den Flash des AVR legen, einmal "as is" und einmal, als wären alle Bytes "verschlüsselt". Die genannte Teile haben 128kByte Flash, das sollte also kein Problem sein. Dann brauchst du im SRAM nur noch eine Bitmap mit einem Bit/Nutzbyte aufbauen, was eben sagt: hole das Byte aus dem "as is"-Image oder aus dem "verschlüsselt"-Image.
Harald K. schrieb: > Christoph L. schrieb: >> Wie schon gesagt, es handelt sich hier um ein ROM für einen >> Disk-Kontroller - nicht um ein Spiel. > > OK, das hatte ich wohl übersehen. > >> Also kann man das mit in menschlichem Ermessen durchspielen, > > Sicher? Das Ding kann z.B. auch Fehlerbehandlung machen, die ohne ein > entsprechend fehlerhaftes Medium nicht aufgerufen wird. Oder besondere > Arten von Formatierung unterstützen, die ebenfalls nicht immer > aufgerufen werden. > >> insbesondere da ich nahezu alle Funktionen disassembliert habe > > Das wiederum macht mich jetzt stutzig. Wie kannst Du (nahezu) alle > Funktionen disassembliert haben, wenn Du noch nicht mal den decodierten > ROM-Inhalt vorliegen hast? Ich habe einen Disassembler genommen, der als Source Code vorlag und diesem Beigebracht die Logic beim Lesen aus dem Speicher anzuwenden. Dieser funktioniert auf Basis von graphen und rennt so ab den gegebenen Einsprungadressen alles ab. Über bleiben die reinen Datenbereiche (z.B. Code, der zur Ausführung ins RAM kopiert wird) und eben Bereiche, die so nicht angesprungen werden. Das sind insbesondere CPM BIOS Calls, die über eine Lookup Tabelle angesprungen werden (eine Basisadresse + ein Wert, der dann zu einem JMP oder Call führt). Und der Wert ist dann auch noch als zwei Bytes hinter dem CALL realisiert, wo dann die angesprungene Routine dann vom Stack die Rücksprungadresse holt und dort die nächsten zwei Bytes ausliest um auf die Adresse zu kommen. Das heißt alles in allem häßlich und fehlerhaft. Daher will ich genau diese Bereiche Sniffen um den Code direkt zu lesen und nicht zu interpretieren. Ich habe das ROM also teilweise dekodiert vorliegen (ungefähr 98% correct würde ich sagen), aber das hilft nichts, wenn die CPM Funktionen dann abschmieren, weil ein paar unwesentliche Adressen nicht korrekt sind.
Christoph L. schrieb: > Und damit zerblase ich mir nicht den PICO? Der ist nicht 5V tolerant und > die Eingänge vertragen maximal zusammen 50µA Woher hast du die 50µA? Waren es nicht eher max 50mA? https://forums.raspberrypi.com/viewtopic.php?t=300735 Leider ist nicht ganz klar, ob die 50mA jetzt für source und sink gelten. Auch könnten es die absolute max. Rating sein. Auf S. 619 im Datenblatt https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf steht folgendes (also eher die 50mA nicht ausreizen): Maximum Total IOVDD current IIOVDD_MAX 50 mA Sum of all current being sourced by GPIO and QSPI pins Maximum Total VSS current due to IO (IOVSS) IIOVSS_MAX 50 mA Sum of all current being sunk into GPIO and QSPI pins
Klaus R. schrieb: > Christoph L. schrieb: >> Und damit zerblase ich mir nicht den PICO? Der ist nicht 5V tolerant und >> die Eingänge vertragen maximal zusammen 50µA > > Woher hast du die 50µA? Waren es nicht eher max 50mA? > https://forums.raspberrypi.com/viewtopic.php?t=300735 > > Leider ist nicht ganz klar, ob die 50mA jetzt für source und sink > gelten. Auch könnten es die absolute max. Rating sein. > > Auf S. 619 im Datenblatt > https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf steht > folgendes (also eher die 50mA nicht ausreizen): > > Maximum Total > IOVDD current > IIOVDD_MAX 50 mA Sum of all current > being sourced by > GPIO and QSPI > pins > > Maximum Total > VSS current due to > IO (IOVSS) > IIOVSS_MAX 50 mA Sum of all current > being sunk into > GPIO and QSPI > pins Ja ich habs irgendwie heute nicht mit Einheiten - 50mA stimmt. Damit ist das Problem schon mal Faktor 1000 kleiner ;-) Du meinst, das in Total (egal welche Richtung) nicht mehr als 50mA durch den PICO fließen dürfen vs. 2x50mA je Richtung? Ich fürchte auch es ist eher ersteres - max 50mA total. Auf jeden Fall ist es mal sicherer damit zu rechnen. Damit wäre der Wiederstand dann für 2mA pro Line x24 bei 5V auf 2500Ohm zu setzen. 2k7 sollte also gut passen.
Ob S. schrieb: > Was mir außerdem noch zu dem Thema eingefallen ist: du brauchst > eigentlich garnicht so viel RAM. Du kannst vorab ja das Ziel-ROM > auslesen und dann in zwei Varianten in den Flash des AVR legen, einmal > "as is" und einmal, als wären alle Bytes "verschlüsselt". Die genannte > Teile haben 128kByte Flash, das sollte also kein Problem sein. > > Dann brauchst du im SRAM nur noch eine Bitmap mit einem Bit/Nutzbyte > aufbauen, was eben sagt: hole das Byte aus dem "as is"-Image oder aus > dem "verschlüsselt"-Image. Das ist eine gute Idee ... ich brauche ja eigentlich nur zu Wissen bei welchen Reads/Adressen M1 zyklen sind. Also muß ich tatsächlich nur M1 sowie CE/OE vom ROM abgreifen und dann M1 in eine Bitmap schreiben. So kann ich dann auf dem PC nachher beim Decoding die M1 aus einer Tabelle ziehen und so nicht dekodieren und alles andere wird dekodiert. Ich brauche ja nicht wirklich alle echten Daten aus dem ROM.
:
Bearbeitet durch User
Christoph L. schrieb: > Ich habe einen Disassembler genommen, der als Source Code vorlag und > diesem Beigebracht die Logic beim Lesen aus dem Speicher anzuwenden. > Dieser funktioniert auf Basis von graphen und rennt so ab den gegebenen > Einsprungadressen alles ab. Ah, das erklärt's. Sehr gut. Christoph L. schrieb: > Daher will ich genau diese Bereiche Sniffen um den Code direkt zu lesen > und nicht zu interpretieren. Ja, das ist verständlich. Nur halte ich es dennoch für optimistisch, daß damit wirklich alle Codepfade gefunden werden; Du müsstest letztlich jede der CPM-BIOS-Funktionen mit allen möglichen Parametern aufrufen und gleichzeitig alle möglichen Fehlerfälle seitens des angeschlossenen Laufwerks durchspielen, um wirklich auf Nummer Sicher zu gehen. Kannst Du dieses Aufrufen der BIOS-Funktionen nicht auch Deinem Disassembler beibringen? Deren Interface müsste ja dokumentiert sein, also ist klar, welche Parameter zu verwenden sind. Nur das Simulieren des Laufwerks und dessen potentieller Fehlermeldungen fehlt dann noch. Wenn Du Deinem Assembler schon das wechselweise Zugreifen auf den "verschlüsselten" und "unverschlüsselten" Speicher beigebracht hast, hast Du auch eine Art Logging implementiert, so daß Du quasi eine Art Bitmap der Speicherzugriffe erstellen kannst (mit drei Zuständen: kein Zugriff, M1-Zugriff, normaler Zugriff)? Dann könntest Du recht leicht sehen, welche Adressbereiche im ROM noch nie untersucht wurden. Nochwas: Christoph L. schrieb: > Wie schon gesagt, es handelt sich hier um ein ROM für einen > Disk-Kontroller Daß das ein Disk-Kontroller sein soll, erschließt sich nur eingeweihten, denn das hast Du so gar nicht geschrieben, sondern nur "Vortex-X" erwähnt. Ich nehme an, daß das das Ding hier ist: https://cpcrulez.fr/hardware-interface-vortex-x_modul.htm
Christoph L. schrieb: > Du meinst, das in Total (egal welche Richtung) nicht mehr als 50mA durch > den PICO fließen dürfen vs. 2x50mA je Richtung? 2x 50mA ist bei den SoC schon mal falsch, maximal 50mA in Summe über die Ports nach + oder -. Den SoC fehlt die typische Schutzschaltung der AVR Arduino mit Dioden und Widerstand zur Strombegrenzung. Seit dem ersten Raspi wurde als sicher empfunden die 50mA durch alle Ports zu teilen, damals 50/17 und kam so auf rund 3mA pro Port. Man darf auch nicht die Obergrenzen der VCC und GND Bondings ignorieren denn die GPU zieht ja auch je nach Arbeit ihren Strom darüber und damals war der GPU Strom so maximal 150mA was mit den Ports 50mA den Maxstrom von 200mA ergibt. Die neueren Taktzahlen sind höher die GPU stärker der Strom wohl höher, siehe Datenblätter wenn verfügbar.
Hmm interessante Aufgabe, evtl hab ich etwas noch nicht ganz verstanden aber das klingt so als könntest du das einfach in software lösen. Zwei dumps, einmal opcodes clear und daten verschlüsselt und einmal anders herum und einer Adresse von der du weißt das sie einen opcode enthällt (hast du ja durch das was du vorher ja schon entschlüsselt hast) dann ist es doch nur noch vergleichen zwischen den dumps und austauschen der verschlüsselten mit den unverschlüsselten daten.
Du könntest es zum Auslesen ähnlich machen wie hier: https://hackaday.io/project/159973-z80-mbc2-a-4-ics-homebrew-z80-computer "The 74HC00 is used as RS flipflop to stop the Z80 CPU during I/O operation, giving the needed time to the Atmega32A to interact with the Z80 bus, [...]" Gruss Chregu
... kann meinen vorherigen Beitrag nicht mehr bearbeiten, war n schnellschuss und sehr wahrscheinlich daneben. Wie funktioniert das mit der verschlüsselung? Wie wird zwischen hier wird jetzt ein opcode gelesen und hier daten die entschlüsselt werden müssen unterschieden?
Harald K. schrieb: > Ja, das ist verständlich. Nur halte ich es dennoch für optimistisch, daß > damit wirklich alle Codepfade gefunden werden; Du müsstest letztlich > jede der CPM-BIOS-Funktionen mit allen möglichen Parametern aufrufen und > gleichzeitig alle möglichen Fehlerfälle seitens des angeschlossenen > Laufwerks durchspielen, um wirklich auf Nummer Sicher zu gehen. Das bleibt weiterhin ein Problem, ja - es bleibt kein Einfaches unterfangen. Wobei ich hoffe, daß wenn ich einmal die Einsprungteile korrekt habe (das sind nur wenige Stellen), daß dann auch der Rest passt. Das was direkt als Code im ROM ausgeführt wird ist in der Regel schon richtig. Problematisch sind so stellen, wo ein Call passiert, der aber nie dorthin zurück kommt (also eigentlich ein JMP) und die nächsten zwei Bytes dann eine Offsetadresse sind. Dann werden diese vom Disassembler als next Opcode gelesen und dann also falsch behandelt. > Kannst Du dieses Aufrufen der BIOS-Funktionen nicht auch Deinem > Disassembler beibringen? Deren Interface müsste ja dokumentiert sein, > also ist klar, welche Parameter zu verwenden sind. Das kann ich nicht im Disassembler Lösen, da das Problem nicht die BIOS Funktionen sind, sondern die Art und weise wie sie aufgerufen werden. Es werden einfach zwei Bytes nach einem Call falsch interpretiert (müssten dekodiert werden, werden es aber nicht). Das kann ich nur mit einem Emulator und Debugger nachvollziehen und das ist sehr sehr mühsam. > > Nur das Simulieren des Laufwerks und dessen potentieller Fehlermeldungen > fehlt dann noch. Das wäre dann der nächste Schritt. > Dann könntest Du recht leicht sehen, welche Adressbereiche im ROM noch > nie untersucht wurden. Welche Bereiche noch nicht decoded sind, weiß ich, weil das der Assembler als data bytes (DB) ausgibt - kann man direkt sehen, daß dort kein Diassembling stattgefunden hat. So kann man leicht Stringtabellen, Jumptabellen und Parameterblocks z.b. für den Diskmonitor finden. Sobald man weiß was was ist, kann man es dann auch in den Kontext bringen. Aber das ist wie gesagt das kleinere Problem. > > Ich nehme an, daß das das Ding hier ist: > > https://cpcrulez.fr/hardware-interface-vortex-x_modul.htm Jap, das ist es. grobig80 schrieb: >Hmm interessante Aufgabe, evtl hab ich etwas noch nicht ganz verstanden >aber das klingt so als könntest du das einfach in software lösen. Zwei >dumps, einmal opcodes clear und daten verschlüsselt und einmal anders >herum und einer Adresse von der du weißt das sie einen opcode enthällt >(hast du ja durch das was du vorher ja schon entschlüsselt hast) dann >ist es doch nur noch vergleichen zwischen den dumps und austauschen der >verschlüsselten mit den unverschlüsselten daten. Das Problem ist, daß man nicht weiß was OPcodes sind. Wenn ich wüsste was die Opcodes sind und was Daten (also das was hinter dem ersten Bytes des Opcodes kommt, oder reine Daten (Strings etc)), dann wäre es eine äußerst ineffektive Schutzmethode. Der Schutz ist so simpel und doch so effektiv, daß man sich auch 40 Jahre später noch die Zähne ausbeisst. Christian M. schrieb: >Du könntest es zum Auslesen ähnlich machen wie hier: >https://hackaday.io/project/159973-z80-mbc2-a-4-ics-homebrew-z80-computer
Christian schrieb: > ... kann meinen vorherigen Beitrag nicht mehr bearbeiten, war n > schnellschuss und sehr wahrscheinlich daneben. Wie funktioniert das mit > der verschlüsselung? Wie wird zwischen hier wird jetzt ein opcode > gelesen und hier daten die entschlüsselt werden müssen unterschieden? Das hatte ich hier geschrieben. Es wird in Abhängigkeit des /M1 signals entschieden, was ein OpCode ist und dann nicht durch die Entschlüsselung läuft. Also Entweder /M1 ist aktiv oder Entschlüsselung. Christoph L. schrieb: > Danke, > > korrigiert. > > Der Hauptgrund ist, daß das Rom encrypted ist mit etwas das man nicht > einfach durch einen decrypter laufen lassen kann. > > Es sitzt in einem Modul und hat ein bissl logic zwische dem EPROM und > dem Datenbus sitzen. > > Die Logic verknüft ~(~M1) AND ((ADR3 XOR DATA5) OR (ADR5 XOR DATA2)) > > In einfachen Worten: > Immer wenn kein M1 zyklus der CPU vorliegt, dann XORe die Datenbits mit > den dazugehörigen Addressbits. Da ich aber rein am ROM code nicht > erkennen kann wan ein M1 zyklus vorliegt (OP code read), muß ich das > entweder vollkommen disassemblieren und die read routinge des > Disassemblers patchen (habe ich schon gemacht) und zu 90% erfolgreicht > disassembled, oder eben das echte System den Code ausführen lassen und > den Datenbuss nach decryption sniffen. > > Das heißt das hier ist der Ansatz zum 2. Punkt. > > Ist ein ROM Modul aus den 80er Jahren für den Schneider CPC 464 (Vortex > X-Modul). > > Leider gibt es den originalen Source code für das ROM nicht, also > reengineering. Kleines vollkommen nutzloses Hobbyprojekt :-)
Joachim B. schrieb: > Den SoC fehlt die typische Schutzschaltung der AVR Arduino mit Dioden > und Widerstand zur Strombegrenzung. Du verwechselst da was. Es geht nicht um einen der Kleincomputer aus der "Raspberry Pi"-Serie, sondern um einen Microcontroller, der, wenn auf eine Platine gelötet, unglücklicherweise als "Raspberry Pi Pico" bezeichnet wird. Das aber ist der RP2040, kein SOC, sondern ein normaler und recht bodenständiger Zweikern-ARM. Übrigens enthalten AVR-Arduinos keinerlei Schutzbeschaltung, die über das hinausgeht, was in AVRs selbst verbaut ist.
Harald K. schrieb: > Übrigens enthalten AVR-Arduinos keinerlei Schutzbeschaltung, die über > das hinausgeht, was in AVRs selbst verbaut ist. nicht anderes hatte ich geschrieben, was hast du verstanden, die interne Schutzschaltung wurde ja bei den alten 8-bit AVR x-mal gezeigt. Da funktionierte sogar Rück-Speisung über die Ports solange die Schutzdioden nicht übermäßig gefordert werden. Timer für Canon Cam an der FB Buchse, nicht von mir aber trotzdem genial. Harald K. schrieb: > Das aber ist der RP2040, kein SOC OK muß ich mal suchen, dachte das ist nur ein weiterer BCM SoC, die bringen ja immer wieder Neue raus.
Christoph L. schrieb: > Es wird in Abhängigkeit des /M1 signals entschieden, was ein OpCode ist > und dann nicht durch die Entschlüsselung läuft. > > Also Entweder /M1 ist aktiv oder Entschlüsselung. ah ok, Danke. Ja das ist dann so überhaupt nicht mehr trivial. Das mitschneiden der Daten scheint dann der Beste nächste Schritt zu sein. Zumindest um an mehr Adressen mit opcodes etc. zu kommem um es dem disassembler "einfacher" zu machen.
Joachim B. schrieb: > nicht anderes hatte ich geschrieben, was hast du verstanden Du hat nicht AVRs, sondern AVR-Arduinos geschrieben. Das erste sind Microcontroller, das zweite Platinen mit Microcontroller und etwas Zusatzbeschaltung drauf. Joachim B. schrieb: > OK muß ich mal suchen, dachte das ist nur ein weiterer BCM SoC Nein, das ist ein durchaus interessanter ARM-µC mit 264 kiB SRAM im 48poligen QFN-Gehäuse, zwei Cortex-M0+-Kerne mit 133 MHz, sehr leistungsfähigen mit einer Art Statemachine programmierbaren I/O-Pins ... und ohne Flash-ROM. Das muss extern beigeschnallt werden. https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html Das Ding gibts auch fertig auf (mittlerweile zwei) Platinen, die dann (ungeschickterweise) "Raspberry Pi Pico" genannt werden: https://www.raspberrypi.com/products/raspberry-pi-pico/ Die zweite Variante enthält noch WLAN/BT-Hardware.
Christian M. schrieb: > Du könntest es zum Auslesen ähnlich machen wie hier: > > https://hackaday.io/project/159973-z80-mbc2-a-4-ics-homebrew-z80-computer > > "The 74HC00 is used as RS flipflop to stop the Z80 CPU during I/O > operation, giving the needed time to the Atmega32A to interact with the > Z80 bus, [...]" > > Gruss Chregu Ja, die benutzen den WAIT Pin der CPU um sie zum Warten zu veranlassen. Das Funktioniert auch beim Z80. Allerdings funktioniert der WAIT erst am Ende eines M-Zyklusses, so daß man die Daten innerhalb des Zyklusses abgegriffen haben muß, um Sie nicht zu verlieren. Die /RD und /MREQ lines werden vorher freigegeben, der Output am ROM also deaktiviert bevor der WAIT beginnt. Man kann also im WAIT selber die Daten nicht mehr lesen. Ich bau mal ein MiniSetup nuf für die Auswertung von /M1. Dazu muß ich aber immernoch die Adresse lesen, /M1, sowie /CE und /OE am ROM. Dann muß der Arduino in der Lage sein innerhalb dieser Zeit zwei Register zu lesen. Das heißt er reagiert auf /CE AND /OE AND /M1 und muß dann zwei Register ASAP lesen, den Adressbus. Dann WAIT ausgeben und den Rest der Logik machen. Das sollte funktionieren - ist aber schon sehr Zeitkritisch, was den ersten Teil angeht.
Harald K. schrieb: > Joachim B. schrieb: >> nicht anderes hatte ich geschrieben, was hast du verstanden > > Du hat nicht AVRs, sondern AVR-Arduinos geschrieben. Das erste sind > Microcontroller, das zweite Platinen mit Microcontroller und etwas > Zusatzbeschaltung drauf. schade jetzt kackst du wieder Krümel, ich wählte meine Worte mit Bedacht damit es JEDER verstehen kann, du bist offensichtlich immer auf Worte verdrehen geeicht. Ob die alten 8-Bit AVR nackt oder auf Arduino Platinen daherkommen ist doch sowas von schnurzpiepegal!
:
Bearbeitet durch User
Der Pico schafft das locker. Es gibt inzwischen ein fertiges Sigrock Modul dafür. Da steht irgendwas von 120MS/s bei 21 Inputs und 50k Samplespeicher. Eine PIO Unit kann theoretisch pro Takt 32 Bit samplen und das per DMA in den RAM schieben.
16kBytes Z80 OPcode aufdröseln sollte kein unüberwindbares Problem sein, zumal es Assembler ist und kein hochoptimierter C-Compiler seine Finger im Spiel hatte. Ich würde mir zwei ROM-Dumps nehmen (Original und komplett verdreht) und dann mit Notepad und dem Z80 Pocket Guide ans Werk gehen. Am Einsprungpunkt anfangen und dann linear durchgehen. Ein CP/M Bios ist sehr gerade gestrickt und auch die Ansteuerung des Laufwerks ist kein Geheimnis. Das klingt erst einmal nervtötend, ist aber bestimmt schneller zielführend als erst eine Zusatzhardware aufzubauen und zu entwanzen. Dazu kommt, dass dir anschliessend die Code Analyse auch nicht erspart bleibt.
Christoph L. schrieb: > Dann muß der Arduino in der Lage sein innerhalb dieser Zeit zwei > Register zu lesen. Das heißt er reagiert auf /CE AND /OE AND /M1 und muß > dann zwei Register ASAP lesen, den Adressbus. Dann WAIT ausgeben und den > Rest der Logik machen. > > Das sollte funktionieren - ist aber schon sehr Zeitkritisch, was den > ersten Teil angeht. Deswegen benutzt du lieber meine Empfehlung AVR128Dx. Damit kannst du schonmal die AND-Logik in Hardware abbilden (CCL), brauchst also in der Software nur noch auf ein Signal lauschen. Außérdem hast du den doppelten Takt zur Verfügung, kannst also in einem Z80-Cycle 32 Instruktionen ausführen statt nur 16. Da sollte genug Power sein, um ohne das WAIT-Geraffel auszukommen. Also ich jedenfalls könnte es damit umsetzen.
Ob S. schrieb: > > Deswegen benutzt du lieber meine Empfehlung AVR128Dx. Damit kannst du > schonmal die AND-Logik in Hardware abbilden (CCL), brauchst also in der > Software nur noch auf ein Signal lauschen. Außérdem hast du den > doppelten Takt zur Verfügung, kannst also in einem Z80-Cycle 32 > Instruktionen ausführen statt nur 16. > > Da sollte genug Power sein, um ohne das WAIT-Geraffel auszukommen. Also > ich jedenfalls könnte es damit umsetzen. Habe jetzt mal nach AVR128DB64 boards geguckt. Sieht ja soweit okay aus. Aber was meinst Du mit doppeltem Takt? Laut Datenblatt hat der AVR128DB64 eine max clock von 24Mhz, wie alle AVR128DBs ... Dummerweise haben die immer noch sehr wenig RAM. Zu mehr als der Bitmap reicht es nicht - wenn ich also das ROM abspeichern möchte, dann brauche ich deutlich mehr Speicher (16KB nur für das ROM). Irgendwie scheint halt 5V tolerance aus der Mode zu kommen. :-(
Georg G. schrieb: > 16kBytes Z80 OPcode aufdröseln sollte kein unüberwindbares Problem sein, > zumal es Assembler ist und kein hochoptimierter C-Compiler seine Finger > im Spiel hatte. > Ich würde mir zwei ROM-Dumps nehmen (Original und komplett verdreht) und > dann mit Notepad und dem Z80 Pocket Guide ans Werk gehen. Am > Einsprungpunkt anfangen und dann linear durchgehen. Ein CP/M Bios ist > sehr gerade gestrickt und auch die Ansteuerung des Laufwerks ist kein > Geheimnis. > Das klingt erst einmal nervtötend, ist aber bestimmt schneller > zielführend als erst eine Zusatzhardware aufzubauen und zu entwanzen. > Dazu kommt, dass dir anschliessend die Code Analyse auch nicht erspart > bleibt. Das wäre ja super, wenn es nur CPM wäre. Das sind 16kbyte ROM randvoll mit allem möglichen. Der Schneider CPC hat einen BASIC mode, mit einem Teil dafür, einen CPM Mode mit einem BIOS dafür (was zum Teil vom BASIC auch verwendet wird) und dann noch einen kompletten Monitor/Debugger/Disassembler etc. Einfach mal so eben ist es nicht und da es sehr optimiert werden musste um es eben in die 16Kbyte zu bekommen ist es auch sehr verschachtelt. Wie schon geschrieben, die Code Analyse ist zu 95% schon durch und das verfahren mit den beiden ROMs führt zu nichts. Ich habe einen Disassembler verändert, so daß er abhängig vom Opcode byte entschlüsselt oder nicht. Das hat schon zu weiten Teilen geklappt. Problematisch sind halt wie auch schon geschrieben die CALLs mit anschließenden zwei Addressbytes. Sowas wie RST#3 beim CPC, der ein FAR Call ist. Direkt hinter dem RST#3 steht eine Adresse, die aber nicht von der CPU selber ausgewertet wird (wie z.B. Call), sondern diese Adresse Zeigt wiederum auf einen sogenannten FAR pointer (Address, Romnummer) und all das wird in der Firmware des CPC dann ausgewertet. Das heißt ein Disassembler weiß das natürlich nicht und würde nach einem RST#3 einfach das nächste Byte als Opcode interpretieren. Das habe ich soweit im Griff, weil ich ja RSTs direkt entsprechend behandeln kann. Aber wenn das gleiche mit Calls gemacht wird wo hinter dem 3 byte Call noch eine Addresse steht (also Daten), der Disassembler aber hinter dem Call erstaunlicherweise einen OpCode Erwartet, dann ist das halt mist. Die Haben halt den Call dazu benutzt um die Addresse hinter dem Call auf dem Stack zu haben, aber tatsächlich handelt es sich dabei um einen JMP auf eien Addresse die mitteles einer Basisadresse und dem Offset hinter dem Call ermittelt wird und dann dort hineingesprungen wird. Der RET führt dann zu der Routine zurück die das Stück mit dem Call aufgerufen hat. Soweit ist das schon alles klar - und trotzdem ist es unglaublich schwer alle diese Calls zu finden und dann den Disassembler dazu zu überreden, daß nach dem Call nicht weiter Disassembliert wird und vor allem die nächsten zwei Bytes dann databytes sind. Also alles nicht so ganz so simple. Wenn es einfach wäre, dann hätte das jemand in den letzten 40 Jahren schon lange fertig gemacht. Wie schon mehrfach geschrieben ist dieses Projekt hier nur um die letzten Reste und klarheiten zu bekommen, also eine weitere Informationsquelle aus dem echten System.
Christoph L. schrieb: > Habe jetzt mal nach AVR128DB64 boards geguckt. Da braucht man doch kein Board für. Einen AVR128DB28 nagelt man einfach auf Lochraster/Streifenleiter und gut isses. Das ist ja das Geile an den Dingern, die gibt's auch noch in DIL. > Aber was meinst Du mit doppeltem Takt? Laut Datenblatt hat der > AVR128DB64 eine max clock von 24Mhz, wie alle AVR128DBs Offiziell ja. Tatsächlich laufen sie aber auch mit 32MHz, dann aber nicht über den kompletten spezifizierten Bereich der Umgebungstemperatur. Sprich: so lange du das Ding nur in einer Umgebung mit nicht allzusehr über Zimmertemperatur betreibst, läuft es problemlos. Deutsche Sommertemperaturen (im Schatten) machen jedenfalls noch keinerlei Probleme. > Dummerweise > haben die immer noch sehr wenig RAM. 16kB finde ich schon ganz ordentlich. Wie groß ist denn der ROM eigentlich, um den es geht?
Ob S. schrieb: > Damit kannst du > schonmal die AND-Logik in Hardware abbilden (CCL) Habe mich grade mal im Arduino Mega Schlau gemacht. Ich kann ja direkt ganze Register verwenden. Und glücklicherweise gibt es hier auch genug. Wenn ich jetzt z.B. den PortC mit den Bits 0-2 auf pullup und input setze, während ich den rest auf output setze, dann kann ich sehr einfach prüfen ob alle drei signale low sind. if (PINC == 0) { addressL = PINA addressh = PINB data = PINH set waitpin_high mach was mit den Daten set waitpin_low //bissl warten, damit die Leitungen den neuen Status zeigen. nop nop nop } Der kritische Teil sollte in ein paar takten durch sein. Evtl. muss ich sogar nach Erkennen der drei signale noch ein winiziges bischen warten, damit die Signale auch anliegen (ein zwei NOPs).
:
Bearbeitet durch User
Ob S. schrieb: > Offiziell ja. Tatsächlich laufen sie aber auch mit 32MHz, dann aber > nicht über den kompletten spezifizierten Bereich der > Umgebungstemperatur. Sprich: so lange du das Ding nur in einer Umgebung > mit nicht allzusehr über Zimmertemperatur betreibst, läuft es > problemlos. Deutsche Sommertemperaturen (im Schatten) machen jedenfalls > noch keinerlei Probleme. > >> Dummerweise >> haben die immer noch sehr wenig RAM. > > 16kB finde ich schon ganz ordentlich. Wie groß ist denn der ROM > eigentlich, um den es geht? Ja, kommt auf den Anwendungsfall an. In meinem Fall mit dem tracing eines 16KByte großen ROMs, muß der Speicher eben 16KB nur dafür haben. Und dann muß ja noch wenigstens etwas Platz für Variablen sein. Das hier ist halt ein Grenzfall und wenn ich mir da den PICO angucke, dann ist der Super - aber eben wieder nicht 5V tolerant :-(
Christoph L. schrieb: > Der kritische Teil sollte in ein paar takten durch sein. Evtl. muss ich > sogar nach Erkennen der drei signale noch ein winiziges bischen warten, > damit die Signale auch anliegen (ein zwei NOPs). Igitt. C für zeitkritische Sachen. Dann würde ich doch eher zu der Pico-Lösung raten. Mußt du halt die knapp 4€ ausgeben, die die entsprechende Zahl Level-Shifter kostet. Aber: der eigentliche Trick würde auch dort nicht in C, sondern in Asm passieren. Nur ist es dort halt das Asm der PIOs, nicht AVR-Asm. Merke: C ist nicht dafür gedacht, exakte Timings zu generieren. Das war nie der Plan.
Ob S. schrieb: > Christoph L. schrieb: > >> Der kritische Teil sollte in ein paar takten durch sein. Evtl. muss ich >> sogar nach Erkennen der drei signale noch ein winiziges bischen warten, >> damit die Signale auch anliegen (ein zwei NOPs). > > Igitt. C für zeitkritische Sachen. Dann würde ich doch eher zu der > Pico-Lösung raten. Mußt du halt die knapp 4€ ausgeben, die die > entsprechende Zahl Level-Shifter kostet. Aber: der eigentliche Trick > würde auch dort nicht in C, sondern in Asm passieren. Nur ist es dort > halt das Asm der PIOs, nicht AVR-Asm. > > Merke: C ist nicht dafür gedacht, exakte Timings zu generieren. Das war > nie der Plan. Naja, es sind ja nicht nur die Level Shifter - sondern das ganz muß auch noch funktionieren. PlanB für einen PICO mit den PIOs wäre, sn74lvc244s zu verwenden und somit 3.3V an die IOs zu legen. Dann zwei PIO programme ... Programm 1 checked ob die drei Signale anliegen und löst dann interrupt aus. Programm 2 würde dann nur einen Port mit 22 bit auf einen Rutsch auslesen. Oder kann ich in einem SM auch auf verschiedene Portgruppen zugreifen? Ansonsten könnte alternativ noch gehen - check 3 pins (am Anfang) wenn = 0 dann read 25 pins und in FIFO. Das schöne ist, daß die Reihenfolge der Pins, wie die High gehen immer gleich ist. Zuerst /CE (ROM_SELECT funktion), und dann /OE. Wenn ich die Daten komplett speicher, dann muß ich /M1 nicht auswerten, da es mir ja egal ist - allerdings kann ich das separat mitführen, also M1 in einer Bitmap noch extra. Daher einlesen mit dem PIO und dann ab in die FIFO nach 25 bits (autopush oder wie das heißt). Und warten kann ich dann auch gleich direkt die richtige Anzahl an Zeit mit dem Autowait, bevor ich dann die nächste Schleife mache. Und wenn ich den PIO auf 10Mhz takte, dann habe ich 10 PIO Zyklen je Memory Zyklus der CPU. Das heißt ich kann das Warten gut timen. Um es einfach zu sagen, mir Gefällt der PICO schon besser dafür, hab aber im moment keinen und es ist ein ziemlicher zusätzlicher Verkabelungsaufwand für die vier octal buffer.
Christoph L. schrieb: > Dann zwei PIO programme ... Programm 1 checked ob die drei Signale > anliegen und löst dann interrupt aus. > > Programm 2 würde dann nur einen Port mit 22 bit auf einen Rutsch > auslesen. Die drei Signale extern verknüpfen und das Resultat auf einen JMP Pin für die PIO legen. Dann sparst du dir das ganze ISR Zeug und lässt die PIO selbst triggern und lesen und das 32Bit Wort in den FIFO spucken. Anschließend warten bis der JMP Pin sich beruhigt (zurück geschaltet) hat und dann geht alles von vorn los. Den FIFO kann man zu Fuß auslesen (ja, geht auch per ISR oder DMA, aber wozu? Die Aufgabe ist gemütlich und der FIFO ist acht Werte tief!) Daten und Adresse splitten und in ein 16KiB Array schreiben. Fettich! Das Ding läuft mit dreistelligen Megahertzen, da kann man sich dann auch gerne die Programmiersprache seiner geringsten Abneigung frei wählen.
Norbert schrieb: > Die drei Signale extern verknüpfen und das Resultat auf einen JMP Pin > für die PIO legen. Das ist nicht nötig. Die PIO ist zwar bezüglich ihrer logischen Fähigkeiten recht eingeschränkt, aber das Verzweigen anhand dreier Signale, die allesamt null sein sollen kann sie schon locker leisten. Also das Äquivalent zu der gezeigten Arduino-"Lösung" des TO. Der Unterschied wäre halt nur: sie kann das innerhalb zweier PIO-Takte ermitteln, also mit einer Abtastrate von 66.7Mhz (wenn man im spezifizierten Taktbereich bleibt). > Dann sparst du dir das ganze ISR Zeug und lässt die PIO selbst triggern Genau. > Das Ding läuft mit dreistelligen Megahertzen, da kann man sich dann auch > gerne die Programmiersprache seiner geringsten Abneigung frei wählen. LOL. Aber wirklich: ganz genau so isses. Bis man dann bei anspruchsvolleren Anwendungen dann doch irgendwann wieder auf Limits stößt. Wenn die PIOs schneller leifern, als die weitere Verarbeitung in der MCU hinterher kommt. Das ist aber im konkreten Anwendungsfall eher nicht zu befüchten.
Norbert schrieb: > Christoph L. schrieb: >> Dann zwei PIO programme ... Programm 1 checked ob die drei Signale >> anliegen und löst dann interrupt aus. >> >> Programm 2 würde dann nur einen Port mit 22 bit auf einen Rutsch >> auslesen. > > Die drei Signale extern verknüpfen und das Resultat auf einen JMP Pin > für die PIO legen. > Dann sparst du dir das ganze ISR Zeug und lässt die PIO selbst triggern > und lesen und das 32Bit Wort in den FIFO spucken. Anschließend warten > bis der JMP Pin sich beruhigt (zurück geschaltet) hat und dann geht > alles von vorn los. > Den FIFO kann man zu Fuß auslesen (ja, geht auch per ISR oder DMA, aber > wozu? Die Aufgabe ist gemütlich und der FIFO ist acht Werte tief!) Daten > und Adresse splitten und in ein 16KiB Array schreiben. > Fettich! > > Das Ding läuft mit dreistelligen Megahertzen, da kann man sich dann auch > gerne die Programmiersprache seiner geringsten Abneigung frei wählen. Jap, und den externen kann ich mir sparen, weil tatsächlich das /OE bei jedem zyklus neu gesetzt wird. Das heißt es wird vor dem lesen angeschaltet und dann wieder abgeschaltet und für den neuen zyklus wieder angeschaltet. Das heißt ich kann sowas tun. loop: //wait for the ROM to get selected WAIT 0 PIN 0 ;/CE //wait for the rom to get enabled WAIT 0 PIN 1 ;/OE //now read it into the IN SHIFT register and outpush IN PINS,25 ;14 Address bits + 8 data bits + 3 control bits //wait for the rom to get disabled WAIT 1 PIN 1 ;OE JMP loop Da der Pico hier viel schneller ist, kann ich auch keinen read verpassen. Ich muss vermutlich aber zwischen dem /OE und dem lesen noch was warten, da das ROM ja 70ns benötigt um die Informationen bereitzustellen. Also evtl. die Frequenz des PIOs doch was drosseln auf 10ns pro takt. dann komme ich recht gut hin mit ein paar delays - in etwas so: WAIT 0 PIN 1 [8] ;/OE ... das heißt nachdem OE active ist, warte ich 80ns und dann einlesen. ... Autopush kann ich hier machen - das heißt nach 25 geshifteten bits, einfach automatisch ins FIFO schieben. Das sollte es eigentlich auf PIO Seite sein. Konnte btw, nichts finden, wo man mit dem JMP auf PIN 1 high wartet. Ich konnte nur JMP PIN finden (vordefiniert), aber was passiert wenn der PIN noch 0 ist?
:
Bearbeitet durch User
Christoph L. schrieb: > aber was passiert wenn der > PIN noch 0 ist? Dann springt er nicht. Also danach einfach einen konditionslosen Sprung. Sozusagen komplementär. JMP(pin, label_hi) # wenn pin high JMP(label_lo) # sonst…
Jede PIO Unit hat vier unabhängige Statemachines. Diese können sich untereinander mit IRQs synchronisieren. D.h. du könntest die Logik auf einer Statemachine implementieren und das Samplen auf einer anderen.
Andreas M. schrieb: > Jede PIO Unit hat vier unabhängige Statemachines. Diese können sich > untereinander mit IRQs synchronisieren. D.h. du könntest die Logik auf > einer Statemachine implementieren und das Samplen auf einer anderen. Das kann er. Auch in der gleichen SM. Aber die Befehle für die Logik brauchen Zeit (wenn auch nur wenige ns) und sie addieren sich. Wenn das schnell genug ist…
Jetzt muß ich mal ganz dumm zwischenfragen. Könnt Ihr evtl. über den Busrequest die Herrschaft über den Bus erlangen und alles abfragen, was Euch fehlt?
BUSREQ und Co sind für die Anbindung eines DMA Controllers gedacht. Damit geht die CPU in Lauerstellung und gibt alle Busleitungen frei. Da u.A. auch die M1 Leitung freigegeben wird, passt die ganze Dekodierung dann nicht mehr. Bringt also nichts.
:
Bearbeitet durch User
Christoph L. schrieb: > Dann muß der Arduino in der Lage sein innerhalb dieser Zeit zwei > Register zu lesen. Das heißt er reagiert auf /CE AND /OE AND /M1 und muß > dann zwei Register ASAP lesen, den Adressbus. Dann WAIT ausgeben und den > Rest der Logik machen. > > Das sollte funktionieren - ist aber schon sehr Zeitkritisch, was den > ersten Teil angeht. So ähnlich hatte ich das mal bei einem 1,7 MHz-Z80-System probiert (nur sniffen). Das ging schon mit einem STM32 nicht wirklich gut. Obwohl man dort die Adressen und die Daten+Steuerleitungen mit nur jeweils einem Portzugriff einlesen kann. Letztendlich habe ich nur noch in einer Schleife die Bussignale gesampelt und einen Puffer gefüllt. Damit geht aber nur noch Offline-Analyse. Meine Intention war es das Ganze mit Zugriffen auf bestimmte Speicher- oder IO-Adressen zu triggern. Heute würde ich mir daher den RP2040 näher anschauen.
Lu O. schrieb: > Könnt Ihr evtl. über den Busrequest die Herrschaft über den > Bus erlangen und alles abfragen, was Euch fehlt? Das würde nicht helfen. Der fiese Trick dieses Controllers besteht darin, daß der laufende Code selbst entscheidet, welche Bytes "verschlüsselt" werden - nämlich nur die, die Opcodes enthalten (d.h. bei aktivem M1 gelesen werden). Alle anderen Bytes aber sind nicht "verschlüsselt", d.h. auch Parameter für Opcodes. Ein Beispiel: SUB 0x22 LD H,0x92 In "unverschlüselt" ist das die Bytefolge 0xd6 0x22 0x26 0x92 Die Bytes 0xd6 und 0x26 sind die Opcodes, die Bytes 0x22 und 0x92 aber sind die "Parameter" der Instruktionen. 0xd6 und 0x26 werden von der Rom-Logik "verschlüsselt", die beiden anderen Bytes aber nicht. Wenn Du nun mit einem Busrequest die CPU anhälts, und den ROM-Adressbereich ausliest, dann erhältst Du die "Parameter" in korrekter Form, aber falsche Opcodes, denn Deine Lesefunktion weiß nicht, welches Byte sie als Opcode und welches Byte sie als Daten zu lesen hat. Und damit ist man keinen Schritt weiter als wenn man das ROM mit einem Programmiergerät ausliest (oder auf dem cpc464 ein kleines Programm schreibt, das einen Hexdump des interessanten Speicherbereichs ausgibt).
Ein bissel Frage ich mich ja auch, welchen Weg die Entwickler genutzt haben, um den Code zu verschlüsseln. Da muß ja fast ein modifizierter Assembler zum Einsatz gekommen sein...
Rick schrieb: > Da muß ja fast ein modifizierter Assembler zum Einsatz gekommen sein. Damals (TM) gab es den Assembler im Quellcode dazu. Da war es eine Kleinigkeit, solche "Schikanen" einzubauen. Beliebt war auch, Datenleitungen zu tauschen oder der Sprung auf das zweite Byte einer Instruktion. Einen "normalen" User konnte man damit etwas verwirren, Profis haben nur müde gegrinst.
Christoph L. schrieb: > Das heißt ich kann sowas tun. > > loop: > //wait for the ROM to get selected > WAIT 0 PIN 0 ;/CE > > //wait for the rom to get enabled > WAIT 0 PIN 1 ;/OE > > //now read it into the IN SHIFT register and outpush > IN PINS,25 ;14 Address bits + 8 data bits + 3 control bits > > //wait for the rom to get disabled > WAIT 1 PIN 1 ;OE > JMP loop Also das würde ich definitiv anders machen. Aber: mir fehlt hier irgendwie das alles entscheidende M1-Signal und auch die genaue Aufgabe des Codes. Der Code sieht eher so aus, als willst du erst ein ROM-Image aufbauen. Wie weiter oben schon erwähnt, ist das aber überhaupt nicht nötig, weil du es vorab bereits gewinnen und in den zwei Varianten bereitstellen kannst. Es kann also sinnvollerweise nur noch um die Gewinnung der Bitmap gehen. Und dazu brauchen die Daten überhaupt nicht eingelesen werden, nur die Adresse. Und das auch nur dann, wenn halt M1 Low ist. Der MCU-Code muß dann bloß noch die von der PIO gelieferten Adressen benutzen, um in der Bitmap jeweils eine 1 zu setzen. Ich vermute darüber hinaus, dass die Sache insgesamt sowieso nicht ganz so einfach ist. Wenn ich so einen Kopierschutz bauen würde, würde ich natürlich auch dafür sorgen, dass es keine eindeutige Abbildungsfunktion geben kann. D.h.: ein und dasselbe Byte im ROM mal als Opcode und mal als Datum verwendet wird. Es reichen ja eine Handvoll Bytes, verteilt über strategisch wichtige Stellen...
Ob S. schrieb: > Wenn ich so einen Kopierschutz bauen würde, würde ich > natürlich auch dafür sorgen, dass es keine eindeutige Abbildungsfunktion > geben kann. D.h.: ein und dasselbe Byte im ROM mal als Opcode und mal > als Datum verwendet wird. Das ließe sich aber mit einer Laufzeitbeobachtung herausfinden. Wie Du schon sagtest, alle Lesezugriffe auf den ROM-Adressbereich erfassen, und den Zustand von M1 dazu, um eine Bitmap zu erhalten. Die Bitmap sollte zwei Bits pro Adresse enthalten, eines, das gesetzt wird, wenn mit aktivem M1 zugegriffen wird, und eines, das gesetzt wird, wenn mit inaktivem M1 zugegriffen wird. Lässt man das ausreichend lange laufen (um alle Codepfade zu befriedigen), sollten sich derartige "Fiesheiten" leicht feststellen lassen.
Mal ein anderer, primitiverer Ansatz: Entscheidend ist doch, was die CPU sieht. Also brauchen wir den Adressbus und den Datenbus direkt an der CPU. Der Abtastzeitpunkt wird durch /MEMRQ und /RD und /CE-Eprom bestimmt, Feiglinge warten noch 20ns, bevor sie die Daten lesen. Zum Abspeichern wird ein Array passender Größe mit 0x00 initialisiert und die gelesenen Daten werden stumpf an der jeweiligen Adresse abgespeichert. Nachdem einige Zeit mit dem Rechner gespielt wurde, wird das Array ausgelesen und kann mit einem normalen Disasm behandelt werden. Natürlich bleiben Lücken. Da muss man dann bei Bedarf händisch heran gehen. Der Hardware und Software Aufwand sind drastisch geringer. Noch eine Anmerkung: Ein typisches CP/M Bios hat etwa 2kBytes Größe. Der Aufbau ist bestens dokumentiert. Damit würde ich anfangen.
Georg G. schrieb: > Mal ein anderer, primitiverer Ansatz: Entscheidend ist doch, was die CPU > sieht. Also brauchen wir den Adressbus und den Datenbus direkt an der > CPU. Reicht nicht, aus genau dem Grund, den "observer" angesprochen hat. Es ist nicht ausgeschlossen, daß ein und dieselbe Adresse mal als Code und mal als Daten angesprochen wird, d.h. mit aktivem und mit inaktivem M1. Das würde bei Deinem Vorgehen nicht erfasst werden können.
Christoph L. schrieb: > Damit wäre der Wiederstand dann für 2mA pro Line x24 bei 5V auf 2500Ohm > zu setzen. 2k7 sollte also gut passen. Abgesehen vom "Wiehern" frage ich mich, wie Du auf 2 mA kommmst. Bei 3,3 V des RP2040, (maximal) 5 V der Z80 Logik und 0,5 V Durchlassspannung der Eingangsdioden müssen ca. 1,2 V (5 - 3,8) Spannungsabfall berücksichtigt werden. Bei 2,2 kOhm fließen da rund 0,5 mA. Die NMOS Mikroprozessoren waren noch auf TTL-Pegel ausgelegt, sodaß bei geringer Ausgangsbelastung, der '1'-Pegel schon garkeine 5 V mehr erreichen konnte. Norbert schrieb: > Andreas M. schrieb: >> Jede PIO Unit hat vier unabhängige Statemachines. Diese können sich >> untereinander mit IRQs synchronisieren. D.h. du könntest die Logik auf >> einer Statemachine implementieren und das Samplen auf einer anderen. > > Das kann er. Auch in der gleichen SM. > Aber die Befehle für die Logik brauchen Zeit (wenn auch nur wenige ns) > und sie addieren sich. Wenn das schnell genug ist… Das wird es sicherlich sein. Normale EPROMs hatten seinerzeit 450 ns und extravagante 250 ns Zugriffszeit. Das könnte man vielleicht noch in einer Hochsprache erledigen - mit PIO sicherlich kein Probelm.
Harald K. schrieb: > Die Bitmap sollte zwei Bits pro Adresse enthalten, eines, das gesetzt > wird, wenn mit aktivem M1 zugegriffen wird, und eines, das gesetzt wird, > wenn mit inaktivem M1 zugegriffen wird. > > Lässt man das ausreichend lange laufen (um alle Codepfade zu > befriedigen), sollten sich derartige "Fiesheiten" leicht feststellen > lassen. Ja. Die Crux ist halt die Unwägbarkeit, ob wirklich alle möglichen Codepfade bereits durchlaufen wurden. Das wurde ja schon viel früher in diesem Thread erwähnt. Der eigentliche Punkt ist aber: Wenn der Kopierschutz diesen Mechanismus benutzt, kann es eben kein ROM geben, was ihn aushebelt. Dann ist die einzige Möglichkeit ein funktionaler Nachbau des "Decoders". Aber halt, neue Idee, viel einfacher: Man nimmt einfach zwei echte ROMs. Eines enthält die "as is"-Variante, das andere die vollständig verschlüsselte. Dann braucht man nur noch mittels M1 zu steuern, an welches der beiden ROMs das OE für den aktuellen Cycle geht.
Na gut, dann nochmals einfacher. ROM Dump machen. PiPico: Ein 16KiB array mit ff füllen. Im laufenden System bei jedem Zugriff den M1 status für jede genutzte Adresse als 00|01 speichern. Regelmäßig (alle paar paar Sekunden) das Array zB. über DMA->UART übertragen. Braucht keinerlei Rechenzeit. Auf dem PC eine simple Anzeige des kompletten Speicherbereiches als Bitmap Grafik anzeigen. ff (nicht besucht) ->schwarz 00 (Daten) ->grün 01 (Opcode) ->rot Da kann man dem Zeug beim Arbeiten sogar zuschauen. Der gespeicherte M1 Status hilft dann beim Disassemblieren bzw. dekodieren gemäß Vorgabe. Das ganze leicht anpassen für doppelte Nutzung Opcodes/Daten.
:
Bearbeitet durch User
Harald K. schrieb: > nicht ausgeschlossen, daß ein und dieselbe Adresse mal als Code > und mal als Daten angesprochen wird Das wäre mir völlig egal. Der Code muss ohnehin analysiert werden. Dann merkt man das sofort und kann diese Ecke händisch genauer überprüfen. Das Erzeugen des Disasm Listings ist 10% der Wegstrecke. Die richtige Arbeit beginnt erst danach.
Georg G. schrieb: > Beliebt war auch, > Datenleitungen zu tauschen nicht nur die, auch die Adressleitungen, der Tausch ist ja statisch und gilt immer und ist am ausgelöteten ROM oder EPROM nicht zu erkennen. (Ich erinnere mich ganz dunkel kann die Quelle aber nicht mehr benennen)
:
Bearbeitet durch User
Ich Antworte hier mal auf eine Sammlung von Punkten, die durch verschiedene Autoren eingebracht wurde. Ich kann aber nicht jeden einzelnen hier Sinnvoll zitieren, da ich nicht threads für Zitate selektieren kann. 1. Zum Thema mehrere PIOs/SMs und IRQs. Ja das könnte man machen, ist hier aber nicht notwendig und verkompliziert den Code. Ist außerdem nicht schneller. Hier ist es ja so, daß die technische Umsetzung in der lebenden Maschine zwei Dinge erfordert. 1. Selectieren eines ROMs 2. Dann aktivieren des Roms mit einer bestimmten Adresse 3. Dann ausgabe des Inhaltes der Adresse durch das ROM. Schritt 1 passiert nicht ständig und benötigt zwischen diesen Schritt und der ersten tatsächlichen Verwendung des ROMs in der Firmware des Computers noch ein paar weitere Z80 Befehle. Das heißt es vergehen einige µs dazwischen. Der PIO kann aber mit einer Taktfrequenz von 125Mhz und damit 8ns arbeiten. Weiterhin liegen zwischen Schritt 2 und 3 mindestens die Antwortzeit des ROM (240ns typisch, aber bei dem von mir geplanten FLASH Eprom sogar nur 70ns). Die CPU selber wartet aber 500ns bevor sie tatsächlich die Daten liest um eben genau dem ROM die notwendige Zeit zu geben. Das Zeitfenster in dem ich also die Daten gelesen haben muß ist vom Moment /CE bis 500ns später, wenn die CPU das signal irgendwann wieder wegnimmt. Das ist genau mit der von mir beschriebenen Methode problemlos möglich - ich muss sogar aufpassen, daß ich lange genug warte bevor ich versuche zu lesen. 2. BUSREQ: > Könnt Ihr evtl. über den Busrequest die Herrschaft über den > Bus erlangen und alles abfragen, was Euch fehlt? Kann nicht verwendet werden, da die CPU erst im nächsten Fetch zyklus (e.g. M1) darauf reagiert. Das heißt ein Opcode wird erst komplett zu Ende gelesen und bearbeitet, bevor die CPU dann über BUSACK dem sender signalisiert, daß es alle control, address und datenleitung in high impedanz gesetzt hat. 3. Harald K. schrieb warum einfach nur lesen nichts hilft Danke Harald, es ist im Grunde so wie Du schreibst - in der realen Hardware genau umgekehrt. M1 Zyklen führen zu unveränderten Ausgabe des ROM bytes alle Parameter oder Daten werden decrypted. 4. Rick fragte, wie die Verschlüsselt wurden >Ein bissel Frage ich mich ja auch, welchen Weg die Entwickler genutzt >haben, um den Code zu verschlüsseln. >Da muß ja fast ein modifizierter Assembler zum Einsatz gekommen sein... Da habe ich auch lange drüber nachgedacht, aber es ist einfach der Assembler. Es wurden grundsätzlich 2 Pass Assembler verwendet und jeder Assembler weiß ja was Opcode und was Parameter oder Daten sind. Alles was nicht Opcode ist, wird halt verschlüsselt und die notwendige Addresse dazu weiß man im 2. Pass ja (man weiß genau wo man ist im Code). Ist bei der Erzeugung also recht einfach zu erreichen indem man den Assembler eben dieses Encoding bybringt. Das sind zwei einfache XORs von zwei bits auf basis der Adresse (bits) 5. Zum Thema Motivation. >Also das würde ich definitiv anders machen. Aber: mir fehlt hier >irgendwie das alles entscheidende M1-Signal und auch die genaue Aufgabe >des Codes. Wenn ich nur eine Hardware bauen wollte, die das reproduziert, dann würde ich einfach ein PAL nehmen und fertig. Der ganze Aufwand der Dekodierung macht keinen Sinn, wenn man einfach die Hardware (heute) sehr simpel nachbauen kann. Man könnte auch Alles (inklusive ROM) in einem FPGA oder CPLD unterbringen und das noch simpler gestalten. Oder man kann einen µController nehmen der das dann tut. Aber das ist nicht die Intention. Die Intention ist es den Quelltext vollständig zu haben. Das heißt es muß final dekodiert werden. Entweder auf dem Weg des Mitschreibens, oder auf dem Weg der Erlangung der dafür notwendigen Informationen (M1) um es offline machen zu können. Der Weg meines PIO scriptes ist wie folgt: Ich prüfe die notwendigen Bedingungen ob ein ROM zugriff erfolgt (e.g. /OE /CE) und capture dann mit dem PIO alles, was für die weitere Auswertunge in dern ARM cores notwendig ist: Das sind M1, Address und Datenleitungen. Theoretisch brauche ich auch M1 nicht, aber ich möchte eben die Bitmap für M1 mitlesen. Ob ich noch mittracken will, wenn eine Zelle gar nicht getroffen wurde (weiße Flecken) muss ich mir noch überlegen, dafür hat der PICO aber definitv genug RAM um das auch noch zu machen. Natürlich muß dann der ARM das Datenbyte in ein Array schreiben und M1 in eine Bitmap und ggfs. noch eine zweite Bitmap für das mapping (gelesen oder nicht gelesen). 6. Eindeutige Abbildungsfunktion. > Wenn ich so einen Kopierschutz bauen würde, würde ich > natürlich auch dafür sorgen, dass es keine eindeutige Abbildungsfunktion > geben kann. D.h.: ein und dasselbe Byte im ROM mal als Opcode und mal > als Datum verwendet wird. Das ist sicher eine sehr gute Idee, funktioniert aber mit diesem verwendeten in Hardware implementierten Decoder nicht. Der verwendete Algorithmus ist auch so schon unmöglich zu hacken - ohne das komplette ROM mitzutracen, wie wir hier grade besprechen. Das war sicher damals eher unmöglich, bzw. hat 16kb SRAM und ein bisschen logic benötigt. Das wäre in den 1980 definitiv ausserhalb der Reichweite von Leuten wie mir gewesen, der das privat mal eben cracken will um es dann zu vermarkten. 7. von Georg G. >Mal ein anderer, primitiverer Ansatz: Entscheidend ist doch, was die CPU >sieht. Also brauchen wir den Adressbus und den Datenbus direkt an der >CPU. Der Abtastzeitpunkt wird durch /MEMRQ und /RD und /CE-Eprom >bestimmt, Feiglinge warten noch 20ns, bevor sie die Daten lesen. Ja, so ist es. Das verwendete System macht es aber einfacher. Durch die Logic des Rombankings kann ich eben statt der /MEMRQ und /RD signale einfach das /OE neben dem /CE abfragen, weil genau das die Logic ist wie das ROM mal was ausgibt. Zwischen /MEMRQ und /RD hängt noch das GateArray des Schneider CPC, das daraus das /ROMEN signal erstellt, wenn ein ROM selectiert ist (also noch eine Bedingung die im GateArray Registern programmiert wird). Diese /ROMEN signal ist genau was am ROM direct als /OE anliegt. Daher ist es hier einfacher. Und ja, der Rest passt. Zum Thema CPM BIOS, hast Du da eine gute kommentierte Disassembler Routine ? BTW. Ohne correcte Opcodes ist es dann weiterhin nicht zu lesen und es bedeutet leider auch nicht, das der Schneider CPC das dann genau so macht. Das fängt schon am IO handling an, und hört sicher bei der RST und CALL implementierung auf. Bin ich oben schon mal drauf eingegangen. Aber es könnte trotzdem helfen. Ich habe ein Kommentiertes AMSDOS ROM, das ist das Original Amstrad was auch eine CPM Implementierung enthält. Weiterhin ist nicht nur das BIOS drin, sondern auch das BDOS, also weite Teile des Betriebssystems sind ebenfalls im ROM. 8. Harald K. >Reicht nicht, aus genau dem Grund, den "observer" angesprochen hat. Es >ist nicht ausgeschlossen, daß ein und dieselbe Adresse mal als Code >und mal als Daten angesprochen wird, d.h. mit aktivem und mit inaktivem >M1 Da habe ich mir Lange den Kopf drüber zerbrochen. Ich habe nach viel Überlegung am Ende entschlossen, daß ein und dasselbe Byte nicht Code oder Daten sein kann, weil es ansonsten via M1 zu vollkommen verschiedenen Ergebnissen führen würde und das nicht geht. Es kann ja kein self modifying code sein (weil es eben im ROM ist) und die Daten kommen vollkommen verschieden heraus je nachdem ob M1 oder nicht M1. Es gibt nur all 256 Bytes einen Bereich von genau 8 Bytes der immer unverschlüsselt ist, egal was für Bytes. Aber den genau zu finden und dann sowas da abzulegen wäre schon wirklich schwierig bei der Codeerstellung. -halte ich im Hinterkopf, beschäftige ich mich aber nicht mit. 9. Mi N. >Abgesehen vom "Wiehern" frage ich mich, wie Du auf 2 mA kommmst. Bei 3,3 >V des RP2040, (maximal) 5 V der Z80 Logik und 0,5 V Durchlassspannung >der Eingangsdioden müssen ca. 1,2 V (5 - 3,8) Spannungsabfall >berücksichtigt werden. Bei 2,2 kOhm fließen da rund 0,5 mA. Ich habe die vollen 5V angenommen ... aber das stimmen vermutlich Deine Überlegungen. Klar ist, je kleiner der Widerstand desto besser das Flankenverhalten. 10. Ob S. >Aber halt, neue Idee, viel einfacher: Man nimmt einfach zwei echte >ROMs. Eines enthält die "as is"-Variante, das andere die vollständig >verschlüsselte. Dann braucht man nur noch mittels M1 zu steuern, an >welches der beiden ROMs das OE für den aktuellen Cycle geht. Ja, das würde sicher gehen, wenn man Hardware nachbauen möchte, und das geht sogar mit einem EPROM mit 32k total einfach. Einfach das M1 signal an A15 anlegen und fertig. In die unteren 16kbyte kommt dann das unveränderte ROM und in die oberen das encryptete ROM. Fertig ist das Ding komplett ohne weitere Logic. Interessanter Ansatz. Aber es ist nicht wirklich das Ziel, was ich dahinter verfolge. Mein Ziel ist es den Code zu extrahieren und zu verstehen. Puh, lange Antwort, aber interessanter Input.
Joachim B. schrieb: > Georg G. schrieb: >> Beliebt war auch, >> Datenleitungen zu tauschen > > nicht nur die, auch die Adressleitungen, der Tausch ist ja statisch und > gilt immer und ist am ausgelöteten ROM oder EPROM nicht zu erkennen. > (Ich erinnere mich ganz dunkel kann die Quelle aber nicht mehr benennen) Das ist aber nur ein sehr begrenzt sinnvoller kopierschutz, weil man dann mit der CPU immer noch einfach das komplette ROM auslesen kann. Das ist hier genau verhindert worden, da einfach nur reads auf das ROM immer decrypted, was aber für Opcodes nicht passieren düfte. Also ist der ausgelesene Code auch falsch. Also ich muß echt meinen Hut ziehen vor der Idee, die die Kollegen von Vortex damals hatten. Das ist echt unglaublich schwierig das zu Disassemblieren, weil immer der Verdacht besteht, das irgendwas nicht korrekt dekodiert wurde. Kann man schon daran sehen, wieviel Brainpower hier jetzt schon reingesteckt wurde von Euch allen.
Christoph L. schrieb: > 6. Eindeutige Abbildungsfunktion. >> Wenn ich so einen Kopierschutz bauen würde, würde ich >> natürlich auch dafür sorgen, dass es keine eindeutige Abbildungsfunktion >> geben kann. D.h.: ein und dasselbe Byte im ROM mal als Opcode und mal >> als Datum verwendet wird. > > Das ist sicher eine sehr gute Idee, funktioniert aber mit diesem > verwendeten in Hardware implementierten Decoder nicht. Natürlich würde das hervorragend funktionieren. > Der verwendete > Algorithmus ist auch so schon unmöglich zu hacken Tsss... Ich habe damals(tm) noch ganz andere Sachen gecrackt. Diese ist vergleichsweise trivial. > Das war sicher damals > eher unmöglich Nein. Es war damals zwar nur sehr schwer möglich, das zu cracken. Aber es war relativ einfach, das als Kopierschutz zu verwenden. Und genau deshalb wurde das eben auch gemacht. Möglichst einfach für den Ersteller, möglichst kompliziert für potentielle Cracker. Genau das macht einen "guten" Kopierschutz aus, jedenfalls aus der Sicht dessen, der die Entscheidung fällt, ihn einzusetzen. Damals wie heute übrigens, da hat sich nicht wirklich was geändert...
Christoph L. schrieb: > Das ist aber nur ein sehr begrenzt sinnvoller kopierschutz kann sein, vielleicht war es auch nur einfacher für den Router! (aber in der Zeit der gesteckten EPROM OS/Basic durchaus als Kopierschutz brauchbar, vor allem bei verschiedenen PCB Versionen, bei apple & cbm mir nie begegnet, da waren alle bytes schön in der Reihe sortiert.)
Ob S. schrieb: > Christoph L. schrieb: > >> 6. Eindeutige Abbildungsfunktion. >>> Wenn ich so einen Kopierschutz bauen würde, würde ich >>> natürlich auch dafür sorgen, dass es keine eindeutige Abbildungsfunktion >>> geben kann. D.h.: ein und dasselbe Byte im ROM mal als Opcode und mal >>> als Datum verwendet wird. >> >> Das ist sicher eine sehr gute Idee, funktioniert aber mit diesem >> verwendeten in Hardware implementierten Decoder nicht. > > Natürlich würde das hervorragend funktionieren. Praktisch nicht. Du müsstest vorhersagen: entweder welcher Opcode zu welchem Byte wird und das das zufällig genau das ist, was Du brauchst als Datenbyte. oder genau den Bereich treffen wo M1 und /M1 das gleiche decrypting ergeben. Das geht bestimmt irgendwie - aber realistisch nicht umzusetzen. Man muß sich dabei ja auch vor Augen halten, daß Vortex den Code damals warten können musste. Es gabe mehrer Versionen des ROMs. Je mehr ich von solchen "Tricks" einbaue, desto schlimmer wird das. Und ich glaube, daß der Code auch so gut genug war. Es hat meines Wissens nach nie einen Nachbau gegeben. Also scheint es einfach nicht wirtschaftlich gewesen zu sein. Ich meine, daß was ich heute damit machen will ist ja auch was ganz anderes. Wenn ich es nur hätte kopieren wollen, dann hätte ich ja nur die Logik herausbekommen müssen (habe ich ja auch reverse engineered) und dann einfach nachbauen mit dem original ROM. Und wenn ich dann wie ich etwas weiter oben mal drüber nachgedacht hätte, dann hätte ein 32kb ROM das ganze komplett ohne die decoder logik gemacht. Das reverse engineering trotz abgeschliffener Chips hat mich 2 Tage inklusive Schematic und vollkommener Logikanalyse über den Decoder gebraucht. Zugegeben ich konnte einen logic analyser in meinem Eprommer benutzen, der hat direkt rausgefunden, was die abgeschliffenen Chips waren. Und dann nur noch tracen, Schematic erstellen und voila - logik gehackt. Ich bin da sicher kein experte und jemand in den 80er, der sowas designed hätte warscheinlich sehr einfach herausgefunden, welche 74er logicchip verwendet werden. Das ist ja auch kein Hexenwerk. Insofern hat es nur dazu geführt, daß der Code nicht direkt gelesen werden konnte, hätte aber keine schamlosen Raubkopien inklusive der Logic verhindert. Und die CopyrightMessage zu verändern wäre jetzt schon gegangen :-)
Joachim B. schrieb: > Christoph L. schrieb: >> Das ist aber nur ein sehr begrenzt sinnvoller kopierschutz > > kann sein, vielleicht war es auch nur einfacher für den Router! > (aber in der Zeit der gesteckten EPROM OS/Basic durchaus als > Kopierschutz brauchbar, vor allem bei verschiedenen PCB Versionen, bei > apple & cbm mir nie begegnet, da waren alle bytes schön in der Reihe > sortiert.) Ja, im CPC kommt das auch nicht vor. Alle originalen ROMs sind klartext. Das ist eines der wenigen Module, wo ich das kenne. Ob das dann final den Aufwand überhaupt wert war... keine Ahnung. Die haben auch eine RAM Erweiterung rausgebracht, das ROM darauf ist auch nicht encoded.
Vielen Dank für die vielen guten Anregungen und die spannenden Diskussionen. Ich habe jetzt folgenden Pfad vor: 1. PICO nehmen. 2. Habe mir ein paar Levelconverter besorgt - werde aber erstmal mit Widerständen vor den Eingängen starten. 3. PIO verwenden um die Daten zu lesen 4. Dann drei Arrays verwenden. 1. Array für M1 und read tracking (ich habe ja genug Speicher - nochmal ein byte jeweils, FF wenn nicht gelesen 0 oder 1 entsprechend M1). 2. Array für Datenbyte. Wenn das mit einer sehr genau bekannten und dokumentierten Funktion läuft, dann das Ding vollständig durchtesten insbesondere die Funktionen, die bei meinem Disassemblierten und Recompilierten Code im Emulator auf die Fresse fliegen. Danke schon mal. Wenn es Euch interessiert halte ich Euch gerne mit Details auf dem laufenden. Sagt mir aber auch, wenn es Euch eher belästigt. Liebe Grüße Christoph
Christoph L. schrieb: > Du müsstest vorhersagen: > entweder welcher Opcode zu welchem Byte wird und das das zufällig genau > das ist, was Du brauchst als Datenbyte. Für ein Asm-Programm ist das überhaupt kein Problem. Damals wurden tatsächlich auch noch viele Programme rein in Asm verfasst. Aber auch später war es kein Problem, da wurden dann halt vom SDK des Kopierschutz-Lieferanten entsprechende Asm-Einschübe im Code plaziert. > oder genau den Bereich treffen wo M1 und /M1 das gleiche decrypting > ergeben. Brauchen sie doch auch garnicht. Du hast offensichtlich das Konzept nicht wirklich verstanden. > Das geht bestimmt irgendwie - aber realistisch nicht umzusetzen. Du bist halt nicht aus der alten Garde, die noch wirklich bis in's Detail verstanden hat, was sie da tut...
Christoph L. schrieb: > Praktisch nicht. > > Du müsstest vorhersagen: > entweder welcher Opcode zu welchem Byte wird und das das zufällig genau > das ist, was Du brauchst als Datenbyte. Doch, das ist gut möglich. Eine "Kopierschutzroutine" prüft, ob ein an einer bestimmten Adresse gelesenes Byte einen bestimmten Wert hat - und diese Adresse ist halt eine Adresse, die im sonstigen Programmablauf einen Opcode speichert (d.h. mit aktivem M1 gelesen wird). Wenn die Routine den korrekten Opcode liest, weiß sie, daß sie auf der falschen Hardware läuft, wenn die Routine den anderen (verschlüsselten) Wert liest, kann sie annehmen, daß sie auf der richtigen Hardware läuft.
Wenn ich mich so erinnere, war der Reassembler selten richtig erfolgreich. Hinzu kam noch, dass durch Stack-Manipulation manches recht undurchsichtig wurde. Hut ab, wenns klappt!
Harald K. schrieb: > Doch, das ist gut möglich. Eine "Kopierschutzroutine" prüft, ob ein an > einer bestimmten Adresse gelesenes Byte einen bestimmten Wert hat - und > diese Adresse ist halt eine Adresse, die im sonstigen Programmablauf > einen Opcode speichert (d.h. mit aktivem M1 gelesen wird). Ach jetzt verstehe ich was Ihr wollt. Ja sowas ist natürlich extrem leicht machbar. Damit haben wir hier es nicht zu tun. Lu schrieb: >Wenn ich mich so erinnere, war der Reassembler selten richtig >erfolgreich. Hinzu kam noch, dass durch Stack-Manipulation manches recht >undurchsichtig wurde. Hut ab, wenns klappt! Hier geht es zuerst mal um das reine Disassembling. Der ein neue Assembling ist letzten endes nur Proof, das es auch korrekt ist. Wie ich schon schrieb ist 95% schon klar. Ich weiß sogar genau was ich tracen will. Große bereiche sind schon zu 100% dekodiert und auch schon analysiert und kommentiert. Es geht um die letzten 5%, die einfach in der realen Hardware einfacher zu sehen sind. Quasi ein Hardware debugger - wobei leider die Stati der physischen CPU nicht so richtig zu sehen sind. Das wäre natürlich der absolute hit. Auf einem PICO den code mittracen, wissen wann ein Opcode komplett gelesen ist (inclusive Paramererbytes) (lookuptable für die Anzahl Bytes je Opcode etc) und dann einen Hardware Interrupt absetzen und den Z80 veranlassen die Register zu dumpen. Ist allerdings grade bei diesem Thema hier schwierig, da wir es mit Hardwaresteuerung zu tun haben (Diskcontroller) und diese Firmware für viele Teile die Interrupts abschaltet, also ein NMI zu ganz anderen Problemen führen wird. Im Schneider CPC gibt es Systemseitig keine NMIs, nur Maskeable-Interrupts. Ist aber hier alles nur Schmuck am Nachthemd, weil es mir eher um die PICO Seite der Dinge geht und nicht so sehr zu argumentieren, was ein Kopierschutz alles könnte oder nicht könnte, sondern wie man diese spezifische Problem angeht.
:
Bearbeitet durch User
Christoph L. schrieb: > Damit haben wir hier es nicht zu tun. Sicher? Dann kommt allerdings die Frage auf, warum der Hersteller der Platine überhaupt diesen Aufriss betrieben hat. Christoph L. schrieb: > Quasi ein Hardware debugger - wobei leider die Stati der physischen CPU > nicht so richtig zu sehen sind. Neuere Prozessorarchitekturen haben dafür Debuginterface à la JTAG. Aber vielleicht genügt ja auch das hier schon: https://github.com/hoglet67/AtomBusMon
Lu O. schrieb: > Reassembler selten richtig erfolgreich Der einzige wirklich erfolgreiche Disasm ist das Hirn vor dem Bildschirm. Und das muss trainiert werden, wenn es gut sein soll. Speziell bei ASM Programmen muss man die Denke des ursprünglichen Programmierers erfassen, um effektiv zu arbeiten. Programme aus USA sehen anders aus als aus Fernost. Heute im Zeitalter der Hochsprache ist das anders. Da hilft es sehr, wenn man den verwendeten Compiler kennt und dann die Lib-Funktionen schon mal maschinell erkennen kann.
Georg G. schrieb: > Der einzige wirklich erfolgreiche Disasm ist das Hirn vor dem > Bildschirm. Ja, das sehe ich genauso. Aber nach Meinung einiger Forumsteilnehmer stehen wir ja kurz davor, dass die KI das leisten wird... Diese Sache wäre doch mal ein hübscher Test für diese KI-Gläubigen. Und sie hätten es ja noch richtig gut: sie könnten den Scheiß mit dem Wissen der bekannten "Verschlüsselung" und mit dem umfassenden Wissen über das Verhalten des Z80-Busses trainieren. Aber ich sage: dieser nutzlose Dreck wäre nichtmal bei diesen hervorragenden Voraussetzungen in endlicher Zeit in der Lage, irgendwas brauchbares zu liefern... Ist noch viel zu dumm dazu.
Hallo zusammen, nach langer Pause an dem Thema habe ich jetzt die letzten Tage versucht das Pico PIO projekt so umzusetzen. Ich kann lesen etc. Aber ich bekomme murks dabei raus. Mein code ist wirkich ziemlich simpel: PIO Code .program meinprogramm .wrap_target WAIT 0 GPIO 28 ;warten auf trigger input down WAIT 1 GPIO 28 [9] ; warten auf trigger input high nop [19] ; und insgesamt 250ns warten in pins,22 (für den Test nur 14 bit adressbus und datenbus .wrap Das ganze wird mit autopush und eben automatischem Loop verwendet. Sind nur 4 PIO anweisungen. Soweit ich das verstanden habe, sollte das ohne Latenz funktionieren, also all 22 pins in einem Zyklus gelesen werden und dann danach direkt in den FIFO gestopft. Das funktioniert aber nicht zuverlässig. Im ARM code lese ich die FIFO, dann extrahiere ich die Adresse und das Datenbyte. Dann gucke ich ob in meinem Array das schon mal geschrieben wurde, und wenn ja vergleiche das Datenbyte mit dem im Array gespeichertem Wert. Ich habe zwei Flag - read und missmatch. read wird gesetzt wenn es schon mal gelesen wurde und missmatch wenn im Array was anderes steht. So kann ich also mit meiner dump() funktion schnell sehen, ob die Werte verändert sind. Derzeit lese ich damit erstmal das normale OS ROM aus, welches ja vollkommen unverschlüsselt ist und auf jeden Fall immer die gleichen Werte ausgeben muß. Das problem ist, daß ich mal die richtigen Werte bekommen (kann ich ja gut nachvollziehen, wie die sein sollen), und mal vollkommen anderes, quasi schon zufällig. Ich hab ein bissl mit der Wait time rumgespielt um herauszubekommen, ob ich nicht richtig im Timing sitze, aber ich habe irgendwie das Gefühl, daß ich nicht alle bits gleichzeitig lese und zu einem Zeitpunkt Teilweise die bits schon den Wert verloren haben?. Irgendwie sieht ist das nicht stabil, wenn auch schnell genug. Ich weiß, das ist aus der Ferne echt schwierig, aber ich würde mich über Anregungen freuen. Ach ja, mein Trigger auf PIN28 ist derzeit ein sehr simpler NOR mit ~ROMEN und A14 drauf. Das heißt wenn A14 low ist, dann sind wir im OS ROM und ~ROMEN liegt direkt auf ~CE vom ROM. Wenn also beides LOW ist, dann sollte das richtige ROM angesprochen sein und dann bekomme ich meinen Trigger. ~ROMEN wird vom Gatearray produziert aus ~MREQ und ~RD, ist aber jedenfalls direkt der CE signal für den ROM chip. Also sollte mir das Signal doch zuverlässig sagen, wenn das OS ROM angesprochen wird und es dürfte keine Abweichenden Einleseoperationen geben? Werde das jetzt noch mal mit einem direktem logicprobe auslesen, was der so sieht.
Nur so am Rande: Mit dem rp2040 hat jemand einen Logikanalysator gebaut - 24 Kanäle und 100 Msps, und mit dem rp2350 auch 200 und sogar 400 Msps. https://github.com/gusmanb/logicanalyzer
Spontane Frage, was ist mit A15? Und wie sieht die Systemarchitektur in dem genannten Z80 system aus? IMHO wäre es nach einem Jahr Stille im Thread und einer veränderten Aufgabenstellung sinnvoll, einen neuen thread mit angepassten Titel zu starten. Das man mit einen RasPi-Pico aussreichend schnell sniffen kann, sollte jetzt klar sein. Und nicht zuletzt nach diversen Berichten über die Tauglichkeit einer pico-basierten Hardware für Arbeiten am ZX-Spectrum (ja, sind dort nicht 4 sondern 3,5 MHz): * https://hackaday.com/2024/12/12/pico-logic-analyzer-gets-new-version/ " You can set the level shifters to use 5 V, 3.3 V, or an external voltage. Since [Happy] is working on a ZX Spectrum, the 5 V conversion is a necessity. "
:
Bearbeitet durch User
Geht es immer noch um das vortex X-Modul? Denn hier https://cpcrulez.fr/hardware-interface-vortex-x_modul.htm gibt es ein paar Infos. Wenn man sich weiter klickt (https://cpcrulez.fr/applications_disc-vdos.htm) findet man ein ROM zum Download https://cpcrulez.fr/applications_disc-vdos.htm
Hi, da hast Du sicher recht. Hier jetzt mal nachrichtlich, was ich nun im Ende gemacht habe: Mit dem Pico habe ich einfach keine stabilen Signale hingebkommen, vermutlich schon deswegen, weil die verdrahtung mittels Perfboard an sich schon mist ist und die Kabel vermutlich die Gesamtsituation nicht so richtig verbessert haben. Also anderes vorgehen. 3M ProbeKlammer 40pin DIP auf die CPU geschnallt und den Kingst LA5032 direkt an die CPU angehängt. Zusätzlich vom ROM dann die anderen Pins abgegriffen. Dann das ganze mit sigrok gesampelt und durch den Z80 decoder gejagt. Der Z80 decoder ist allerdings echte Grütze. Das Signal wird nicht am rising edge von /RD gesampelt, sondern am falling edge. Daher kommt der durcheinander weil die Datenleitungen flippen während des Signals. Also Umprogrammiert und schon gibt es sehr stabile Ausgabe - direkt im Assembler. Nun noch schnell mit ChatGPT ein python script geschrieben, daß mir addressen, datenbus bytes und instruktions (assembler) in Zeilen bringt und schon hat man was, mit dem man gut arbeiten kann. Ich kann sogar sehen, was der BUS bei OUT,IN, PUSH etc macht und welche Werte konkret wohin geschrieben werden. Also das macht dann das Disassemblieren noch einfacher. Jedenfalls für meinen Zweck jetzt super. Hannes J. schrieb: > Geht es immer noch um das vortex X-Modul? > > Denn hier https://cpcrulez.fr/hardware-interface-vortex-x_modul.htm gibt > es ein paar Infos. Wenn man sich weiter klickt > (https://cpcrulez.fr/applications_disc-vdos.htm) findet man ein ROM zum > Download https://cpcrulez.fr/applications_disc-vdos.htm Ja, das gibt es und ja, es geht um das X-Modul. Aber erstens ist das die Version 1.0 (ich habe 2.11 (latest)) und zweitens ist das einfach nur der Dump, da sind wir gleich wieder am Anfang aller Probleme. Ein Dump von 2.11 ist auch verfügbar (hab ich hochgeladen im CPC-Wiki). Ich hab schon mal bei Vortex nachgefragt, doch leider haben die keinen Source code mehr. Die haben aber das ROM zur freien Verwendung offiziell freigegeben, können jedoch keinen Support leisten ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.