Forum: Mikrocontroller und Digitale Elektronik Raspi Pi Pico schnell genug um 4Mhz Z80 zu sniffen?


von Christoph L. (christoph_l979)


Lesenswert?

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
von Harald K. (kirnbichler)


Lesenswert?

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?

von Christoph L. (christoph_l979)


Lesenswert?

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 :-)

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

Klingt nach Kabuki...

von Christoph L. (christoph_l979)


Lesenswert?

Kabuki?

von Wolfgang R. (Firma: www.wolfgangrobel.de) (mikemcbike)


Lesenswert?

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
von Harald K. (kirnbichler)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Harald K. (kirnbichler)


Lesenswert?

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.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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.

von H. H. (Gast)


Lesenswert?

Andreas S. schrieb:
> Der Z80 unterstützt keine verschlüsselten Speicher.

Der Kabuki Z80 schon.

von Harald K. (kirnbichler)


Lesenswert?

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.

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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
von Harald K. (kirnbichler)


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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...

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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
von Harald K. (kirnbichler)


Lesenswert?

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.ä.

von Norbert (der_norbert)


Lesenswert?

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. ;-)

von Christoph Z. (christophz)


Lesenswert?

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/

von Ob S. (Firma: 1984now) (observer)


Angehängte Dateien:

Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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?

von Joachim B. (jar)


Lesenswert?

Norbert schrieb:
> Da muss sich der Spieler schon etwas
> Mühe geben. ;-)

wenn er es denn schafft, nicht jeder Mensch schafft alle Level.

von Norbert (der_norbert)


Lesenswert?

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.

von Harald K. (kirnbichler)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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?

von Mi N. (msx)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Harald K. (kirnbichler)


Lesenswert?

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?

von Christoph L. (christoph_l979)


Lesenswert?


von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Klaus R. (klausro)


Lesenswert?

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

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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
von Harald K. (kirnbichler)


Lesenswert?

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

von Joachim B. (jar)


Lesenswert?

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.

von Christian (grobig80)


Lesenswert?

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.

von Christian M. (christian_m280)


Lesenswert?

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

von Christian (grobig80)


Lesenswert?

... 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?

von Christoph L. (christoph_l979)


Lesenswert?

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

von Christoph L. (christoph_l979)


Lesenswert?

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 :-)

von Harald K. (kirnbichler)


Lesenswert?

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.

von Joachim B. (jar)


Lesenswert?

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.

von Christian (grobig80)


Lesenswert?

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.

von Harald K. (kirnbichler)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Joachim B. (jar)


Lesenswert?

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
von Andreas M. (amesser)


Lesenswert?

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.

von Georg G. (df2au)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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. :-(

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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?

von Christoph L. (christoph_l979)


Lesenswert?

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
von Christoph L. (christoph_l979)


Lesenswert?

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 :-(

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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
von Norbert (der_norbert)


Lesenswert?

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…

von Andreas M. (amesser)


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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…

von Lu (oszi45)


Angehängte Dateien:

Lesenswert?

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?

von Georg G. (df2au)


Lesenswert?

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
von Rick (rick)


Lesenswert?

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.

von Harald K. (kirnbichler)


Lesenswert?

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).

von Rick (rick)


Lesenswert?

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...

von Georg G. (df2au)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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...

von Harald K. (kirnbichler)


Lesenswert?

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.

von Georg G. (df2au)


Lesenswert?

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.

von Harald K. (kirnbichler)


Lesenswert?

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.

von Mi N. (msx)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.

von Norbert (der_norbert)


Lesenswert?

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
von Georg G. (df2au)


Lesenswert?

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.

von Joachim B. (jar)


Lesenswert?

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
von Christoph L. (christoph_l979)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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...

von Joachim B. (jar)


Lesenswert?

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.)

von Christoph L. (christoph_l979)


Lesenswert?

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 :-)

von Christoph L. (christoph_l979)


Lesenswert?

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.

von Christoph L. (christoph_l979)


Lesenswert?

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

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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...

von Harald K. (kirnbichler)


Lesenswert?

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.

von Lu (oszi45)


Lesenswert?

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!

von Christoph L. (christoph_l979)


Lesenswert?

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
von Harald K. (kirnbichler)


Lesenswert?

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

von Georg G. (df2au)


Lesenswert?

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.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.

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
Noch kein Account? Hier anmelden.