[carte Centronics] La joie de la rétro-ingégneurie.

C'est le lieu des discussions diverses et variées, mais toujours en rapport avec le thème général du forum et dans l'esprit de celui-ci.

Modérateurs : Papy.G, fneck, Carl

Avatar du membre
seki
Messages : 90
Enregistré le : 08 juil. 2016 02:29
Localisation : La cambrousse près de Metz
Contact :

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par seki » 29 août 2019 11:47

J'adore ce genre d'enquête de rétro-ingéniérie. :D
Et merci à Gilles pour le lien vers la doc "undocumented" du Z80.
Les meilleurs programmes ont été écrits lorsque le programmeur était censé travailler sur autre chose. - Melinda Varian

hlide
Messages : 1037
Enregistré le : 29 nov. 2017 10:23

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par hlide » 29 août 2019 16:39

Xavier_AL a écrit :
28 août 2019 23:11
Ce ne serai pas le "IN C,(n)", car C fait parti des flag de AF
La doc "undocumented..." comporte une erreur en mentionnant IN F,(n) une fois alors qu'elle est marquée IN F,(C) ou IN (C) partout ailleurs. Elle provoque juste une lecture sur le port I/O sans affecter un registre MAIS toute opération de IN affecte le registre F qui contient les flags, d'où le nommage optionnel de F (IN F,(C) et IN (C) désigne la même chose).

http://clrhome.org/table/#in%20(c)
Inputs a byte from port c and affects flags only.
C: unaffected, N: reset, P/V: detect parity, H: reset, Z: affected as defined, S: affected as defined.
Du fait qu'elle est non officielle, il vaut mieux ne pas l'utiliser si ce n'est pas à bon escient car ça peut introduite une incompatibilité si on remplace le Z80 d'origine par un clone qui ne serait pas entièrement compatible vis-à-vis des instructions non officielles.

hlide
Messages : 1037
Enregistré le : 29 nov. 2017 10:23

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par hlide » 29 août 2019 16:50

Apparemment les Z80 de type NMOS conservent cette compatibilité des instructions non officielles. Les versions CMOS conservent encore ces instructions non officielles mais je connais une instruction qui n'est pas compatible : OUT (C),0.

Cette instruction présente un octet $00 sur le bus de donnée dans la version NMOS et un octet $FF dans la version CMOS. C'est de cette façon que l'on peut détecter si le processeur acheté à une source non fiable vend bien des CMOS et non des NMOS maquillés en CMOS. En particulier, des NMOS Z80@<8MHz vendus comme des CMOS Z80@20Mhz.
Modifié en dernier par hlide le 29 août 2019 16:56, modifié 1 fois.

Patrick
Messages : 964
Enregistré le : 16 mai 2009 09:30
Localisation : Clermont-Ferrand

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par Patrick » 29 août 2019 16:54

Pour être certain que ton émulateur Z80 est correct une bonne solution est de lui faire passer les tests ZEXDOC et ZEXALL.
ZEXDOC teste toutes les instructions documentées.
ZEXALL teste toutes les instructions documentées et non documentées.
Pour implémenter ces dernières, le document The Undocumented Z80 Documented (version la plus récente 0.91) est utile.
Le document MEMPTR, esoteric register of the ZiLOG Z80 CPU l'est également pour les bits 3 et 5 du registre F.
Patrick

Avatar du membre
Xavier_AL
Messages : 633
Enregistré le : 06 déc. 2017 20:30

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par Xavier_AL » 29 août 2019 20:57

hlide a écrit : J'ai vu des cas où on pouvait utiliser un IN ou OUT sans se servir de donnée : c'est le simple fait de faire un /IOREQ à une adresse de port
Et c'est bien là le problème, j'ai vu des mémoires tampon internes à des cartes (contrôleur disquette) qui utilisait les mêmes adresses que la ROM (\ROMCS), et qui se chargée avec des POKEs (LD (hl),a). Tous les \RD lisaient la ROM moniteur (Basic). Et pour la lire, il fallait active une IORQ!

Il y a deux façons d'émuler une carte… la simple et la façon réelle.
Avec la simple, on considère que la carte est un sous-système qui fait un job, et on traite les données en brut, sans se soucier de la cuisine interne de la carte!

Par exemple, pour un lecteur de disquette ou de cassette, on nourrit l'émulateur avec un buffer, et on ne prend pas en charge le décodage.
Le problème pour ce type d'émulation, c'est qu'il sera impossible d'utiliser le périphérique de manière "non standard", à l'image du CRTC des Amstrads.
Il restera toujours des procès "Boîte noire" qui n'auront pas d'émulation complète car gérés en interne ou autonome.

Mais, en général, la programmation est soumise à la consommation de ressources matérielle, la compatibilité standard et l'utilité en cours d'émulation.

Du côté du désassemblage, comme le notait hlide… on se retrouve avec des instructions non standard … avec des annotations tout autant non-standard !
En deux mots, les assembleurs ne trouveront pas d'opcode pour "IN F,(C)".
Il faudra donc désassembler en tant que donnée ".db ED,70 ; IN F,(C)" pour pouvoir le réassembler correctement.
Un assembleur standard donnera une erreur de syntaxe dans le cas d'une mnémonique non conforme.
Un ToDo en plus…

hlide
Messages : 1037
Enregistré le : 29 nov. 2017 10:23

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par hlide » 30 août 2019 12:32

Attention, le Z80 a deux espaces même s'il partagent son bus d'adresse et de donnée pour ces deux espaces. L'un est l'espace mémoire qui est accédé quand /MEMRQ est actif et l'autre est l'espace entrée/sortie qui est accessible quand /IORQ est actif. Les deux ne peuvent pas être actifs en même temps. Une ROM devrait être lisible seulement si /MEMRQ est actif. Donc je ne comprend pas trop que ce que tu entends par "Et pour la lire, il fallait active une IORQ!".

Ou alors, tu es en train de dire :
- /MEMRQ et /WR actifs -> écriture dans le tampon via LD (HL),A.
- /MEMRQ et /RD actifs -> lecture dans la ROM.
- /IORQ et /RD actifs -> lecture dans le tampon via IN A,(C).

Avatar du membre
Xavier_AL
Messages : 633
Enregistré le : 06 déc. 2017 20:30

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par Xavier_AL » 30 août 2019 17:11

Oui, en deux mots c'était ça:
- /MEMRQ et /WR actifs -> écriture dans le tampon via LD (HL),A.
- /MEMRQ et /RD actifs -> lecture dans la ROM.
- /IORQ et /RD actifs -> lecture dans le tampon via IN A,(C).

Mais l'IORQ servait de trigger pour la lecture \RD en ROM (\romcs).
La lecture en ROM reste prioritaire, mais la lecture demande un IN A,(nn) pour basculer sur la RAM!
Donc,
LD HL,0
LD DE,0
LD BC,$1000
LDIR
Par exemple, copie la ROM sur la RAM.
Un (zut, c'était un OUT!) … OUT (nn),a où LD A,1 (par exemple) active la ROM en miroir.
La machine à partir de ce moment lisait la RAM au lieu de la ROM... qui pouvait être modifiée.
OUT (nn),a où LD A,0 rebasculait sur la ROM !

Ce procédé permettait de récupérer un espace d'adressage déjà utilisé en mémoire... sur une plage de mémoire déjà utilisée.
La lecture était impossible sans la commutation, mais était utilisable en utilisant la ROM interne de la machine!
Ce procédé a été trouvé dans la Memotech HRG sur ZX81.

Mais, sur cette carte Centronics, et sur la carte Memotech Memotext, ces cartes utilisent un décodeur d'adresse programmable qui a pour but de réadresser des adresses en ROM dans le but de la "Patcher", afin de réorienter des routines (CLS,LPRINT...) vers des routines sur une ROM embarquée.
Le but est de déterminer quelles adresses ont été modifiées.

Sur la MemoText, quatre adresses ont été patchées… et sur la Centronics, je dois faire la comparaison de l'ancienne ROM Basic et la "nouvelle" !
Car la ROM embarquée ne suffit pas, car les PEEK sur la machines, sont réorientés au niveau hard, et donc dispatchée un peu partout dans la ROM basic et à des adresses préenregistrée.

La ROM disponible (dump) montre bien cette modification d'adressage, car la fin de la ROM est "vide" !
Sûrement relocalisée ailleurs en mémoire (Rom Basic?).

Le dump a été effectué sur la machine elle-même, et non en lisant la rom avec un lecteur dédié.
Car, dans ce cas, la ROM serai complète.

Il faut donc que je retrouve les morceaux dispersés en mémoire.
Et n'ayant pas cet extension, il est difficile de faire les tests.

Avatar du membre
fneck
Site Admin
Messages : 12884
Enregistré le : 01 avr. 2007 12:03
Localisation : Drôme Provençale (26)
Contact :

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par fneck » 30 août 2019 18:59

Vu l'activité sur le topic je le déplace de catégorie afin qu'il ne soit pas purgé automatiquement 8)

hlide
Messages : 1037
Enregistré le : 29 nov. 2017 10:23

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par hlide » 30 août 2019 19:01

Je suis perdu là...

J'ai relu ton premier post et je ne vois rien d'anormal dans les faits : le IN A,($3F) récupère un statut dont le bit 0 est placé dans le carry. Si ce carry est à 1, on continue de "poll-er". Le bit 0 du port I/O $3F indique donc un état BUSY. Une fois passé à l'état prêt, on "examine" le port I/O $2F. Sauf que ça parait bizarre d'avoir un registre A en entrée (sinon pourquoi cette séquence LD A,10 : ... : PUSH AF : ... : POPAF, n'est-ce pas?). Donc j'en déduis que celui qui écoute le port I/O $2F récupère la donnée en a[15..8] (bus d'adresse) sur un signal /IORQ et (peut-être)sur un signal /RD. Le registre A sera ensuite affecté avec les valeurs de d[7..0] (bus de donnée) mais je suppose que c'est ignoré par le code qui appelle la fonction (des fois que ce serait une astuce pour placer un statut sur d[7..0] en réponse... je déconne !). Ma foi, ça permettrait d'utiliser a[15..8] uniquement en "output" et d[7..0] uniquement en "input". Il faudrait décaper la carte :twisted: pour réaliser le schematics et déterminer la raison.

Du coup, un OUT ($2F),A ne devrait pas donner la même chose qu'un IN A, ($2F). En fait, l'usage de ce OUT pour $2F devrait être interdit.

Dans quel but dirons-nous ? faire une économie de signaux ? le bus a[15..0] est déterminé sur le signal actif de /IORQ. Oui mais alors comment tu lis un caractère (opération inverse) ? Sais-tu comment on lit un caractère ?
Modifié en dernier par hlide le 30 août 2019 21:23, modifié 2 fois.

hlide
Messages : 1037
Enregistré le : 29 nov. 2017 10:23

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par hlide » 30 août 2019 19:17

Et sinon un schematics existant ? ça démystifierait pas mal je pense.

Avatar du membre
Xavier_AL
Messages : 633
Enregistré le : 06 déc. 2017 20:30

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par Xavier_AL » 30 août 2019 21:08

Salut,

Oui, c'est bien ça le problème qui me taraude…
LD A,10 : …
: PUSH AF
: ... ; Truc qui sert à rien...
: POPAF,
:... Chargement du registre donnée à envoyer !

Donc, avant de spéculer… je dois préciser que la carte est donnée pour une interface imprimante !
Elle ne procure qu'une sortie Centronics et dans la doc., rien sur le traitement des entrées…
A mon avis, elle traite en interne les entrées de status, et non les bits Datas en entrée.
Donc, j'en ai conclu que ce "truc qui sert à rien" servait à réinitialiser un buffer interne de 8bits.
Mais, vu le PUSH et le POP... on se retrouve avec une valeur de A fantaisiste au premier cycle, et un A en rotation qui reprend les données de la carte pour une autre rotation… pas trop logique!

Je vais voire la nature des composants… on a peut-être un buffer à zéroter mais j'y croie pas trop.

/!\ Merci, Fabien.

Avatar du membre
Xavier_AL
Messages : 633
Enregistré le : 06 déc. 2017 20:30

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par Xavier_AL » 30 août 2019 21:16

IC1 PAL16L8-4CN Programmable Logic chip
IC2 74LS373 Octal transparent latch
IC3 6331-IN 32 x 8 bit (256 bit) PROM
IC4 2716 EPROM (2K bytes)
IC5 74LS02 Quad 2-input NOR gates
SANY0183[1].JPG
SANY0183[1].JPG (131.42 Kio) Vu 290 fois
SANY0185[1].JPG
SANY0185[1].JPG (120.34 Kio) Vu 290 fois
Source (1024MAK - Moggy) : https://www.sinclairzxworld.com/viewtop ... 3&start=30

J'attends le complément de la ROM soudée… sur listing imprimé.

hlide
Messages : 1037
Enregistré le : 29 nov. 2017 10:23

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par hlide » 30 août 2019 21:54

Ah si c'est une imprimante, ça veut dire que tu ne peux que lui balancer des caractères et non en lire. Du coup, tout ça a du sens en fait :

- a[7..0] : adresse port I/O pour indiquer le registre I/O, le sens lecture ou écriture en embarqué dans l'adresse.
- a[15..8] : en lecture seul, le caractère sur 8-bit à envoyer au contrôleur de l'imprimante.
- d[7..0] : en écriture seul, le statut du contrôleur de l'imprimante dont on sait que le bit 0 indique sa disponibilité (entendre par que l'on peut lui envoyer une commande à exécuter).

Après je ne connais pas tous les détails de l'adressage du port I/O du ZX81 et ceux spécifiques à l'imprimante. Est-ce que $2F et 3F sont les seuls ?

Ok, j'ai accès à un tableau des I/O ports du ZX81 :

Code : Tout sélectionner

IO-MAP

    CS0:
    $07   ZXPAND
    $17   
    $0F   MMC-IF Card Select,  ZON-X81 (Data-Write)
    $1F   MMC-IF PIPO,  ZON-X81-Clone (Data-Write)

    CS1:
    $27   8255 Port A
    $37   8255 Port C
    $2F   8255 Port B
    $3F   8255 Command (WO!)

    CS2:   ("PIO2")
    $47   PIO Port A
    $57   PIO Command A
    $4F   PIO Port B
    $5F   PIO Command B

    CS3:
    $67   (Centronics-Printerport)
    $77   RAMDISK Latch (48k)
    $6F   Centronics-Printerport
    $7F   EEPROM-Latch (8k)

    CS4:
    $87   SIO Port A
    $97   SIO Command A
    $8F   SIO Port B
    $9F   SIO Command B

    CS5:
    $A7   CTC 0
    $B7   CTC 1
    $AF   CTC 2
    $BF   CTC 3

    CS6:   ("PIO3")
    $C7   (PIO Port A)
    $D7   (PIO Command A)
    $CF   (PIO Port B), ZON-X81 (Latch, Data-Read)
    $DF   (PIO Command B), ZON-X81-Clone (Latch, Data-Read)

    CS7:
    $E7   
    $F7   
    $EF   
    $FF   ROM: Zeilensync
Et je note que le poids faible est toujours $7 ou $F :
Due to incomplete address decoding (printer and keyboard use only one address line LOW as /enable) you also may use only i/o addresses with A0, A1 and A2 HIGH.
Kempston compatible joystick interfaces also normally use minimal decoding using A5 low only. Some do not even decode the /RD signal...
Bon, on n'est pas bien avancé...

Donc :
- a[15..8] : caractère à envoyer si a[4] à 1.
- a[7..5] : encode CS0, CS1, CS2, CS3, CS5, CS6, CS7. Dans notre cas, c'est CS1.
- a[4] : 0 : statut en lecture, 1 : caractère à envoyer.
- a[3] : utilisé ici ? toujours à 1 ou à combiner avec a[4] pour quatre registres I/O au lieu de deux ?
- a[2..0] : toujours à 1 sinon gare au conflit !
- d[7..0] : statut si a[4] = 0.

Effectivement, ça simplifie les signaux, on s'en fiche de /RD (et de /WR), juste /IOREQ avec a[7..5] = 1 et a[4].
Modifié en dernier par hlide le 30 août 2019 22:36, modifié 2 fois.

hlide
Messages : 1037
Enregistré le : 29 nov. 2017 10:23

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par hlide » 30 août 2019 22:05

Xavier_AL a écrit :
30 août 2019 21:08
et un A en rotation qui reprend les données de la carte pour une autre rotation…
Ce n'est pas utilisé comme rotation, ça sert juste à déporter le bit 0 du registre A affecté par le port $2F dans le flag C en quatre cycles seulement. Si on avait utilisé AND 1 : JR NZ, poll_again, ça aurait coûter plus de cycles, plus d'octets donc pas malin en soi. L'instruction RRCA est utilisée comme astuce dans bien des cas et là ce n'est clairement pas pour envoyer du A en sériel (surtout pour du centronics, en parallèle, ça n'aurait pas de sens) : c'est j'attends d'abord que l'interlocuteur est disponible pour récupérer mon octet et j'envois mon octet donc aucune rotation à faire en soi.

hlide
Messages : 1037
Enregistré le : 29 nov. 2017 10:23

Re: [carte Centronics] La joie de la rétro-ingégneurie.

Message par hlide » 30 août 2019 23:35

La première photo a un angle trop appuyée pour voir les traces qui vont vraiment entre le connecteur de bord et le PAL. Il faudrait que la carte soit un peu plus en vertical comme dans le deuxième.

Répondre