PPUSBCOMM: Transfert de fichiers USB à Port Parallèle

Résumé du projet

PPUSBComm est un outil permettant de copier des fichiers depuis un système Linux doté d'un port USB vers un système tournant sous DOS via son port parallèle.

Caractéristiques:
  • Logiciel côté cible très léger. Fonctionne sur CPU 8086/8088 et plus récents.
  • Testé sur Tandy 1000 avec MS-Dos 2.11
  • Interface matérielle (USB à Port parallèle) basée sur mon circuit Multiuse PCB-X. Simple à réaliser.
  • Transferts à 1.17 kilooctets à la seconde (sur Tandy 1000 EX)
  • Permet le transfert de fichiers.
  • Permet le transfert d'une image de disquette directement vers une disquette cible. (Nouveau dans v1.1)




Montage

Il n'y a que 8 fils à souder entre le port parallèle et le circuit multiuse PCB-X, tel que documenté dans le tableau ci-dessous. S'il s'agit d'un système Tandy 1000 avec un port de type «card edge» à 34 contacts plutôt qu'un DB25 standard, le «pinout» est un peu différent, d'où la colonne intitulée Tandy 1000.

Signal port parallèleDB25Tandy 1000Multiuse PCB-XCommentaires
Busy11213 PPUSBCOMM vers port parallèle
Ack10192 PPUSBCOMM vers port parallèle
Paper out/end12231 PPUSBCOMM vers port parallèle
Error15280 PPUSBCOMM vers port parallèle
Data 023SCK (PB1) Port parallèle vers PPUSBCOMM
Data 135MOSI (PB2) Port parallèle vers PPUSBCOMM
Data 247MISO (PB3) Port parallèle vers PPUSBCOMM
GND18,192,4GNDCommun
Voici quelques photos de mon montage:
Montage PPUSBCOMM

Montage PPUSBCOMM

Montage PPUSBCOMM

Montage PPUSBCOMM

Montage PPUSBCOMM

Montage PPUSBCOMM





Téléchargement

Voici les téléchargements pour ce projet:
Version 1.1.0
19 mars 2016 (Samedi)
Ajout de rxdisk.com, permettant de recevoir une image de disquette pour l'y écrire directement.
Fichier(s):
ppusbcomm-1.1.0.tar.gz (41 KB)
ppusbcomm-1.1.0.hex (15.5 KB)
Afficher les versions précédentes
Version 1.0.0
26 décembre 2015 (Samedi)
Première version
Fichier(s):
ppusbcomm-1.0.0.tar.gz (37.6 KB)
ppusbcomm-1.0.0.hex (15.5 KB)
Légende:
  • Fichier .hex: Permet de mettre à jour ou de programmer le micro-contrôleur pour la première fois.
  • Fichier .tar.gz: Contient le code source ainsi que les fichiers exécutables pour DOS (.com) déjà compilés:
    • /: Sources pour le code du micro-contrôleur.
    • tools/: Sources de l'outil en ligne de commande Linux (hôte).
    • dostools/rxfiles.com: Outil de réception de fichiers. 786 octets.
    • dostools/rxdisk.com: Outil de réception et d'écriture d'image de disquette. 1156 octets. (Depuis v1.1)
    • dostools/hexdump.com: Outil pour afficher le contenu d'un fichier en hex. Utile pour débogguer. 190 octets.
    • dostools/chksum.com: Outil pour calculer le «checksum» d'un fichier. Formats BSD et SysV comme GNU sum, sauf que l'affichage est en hexa. Utile pour débogguer. 349 octets.
    • dostools/hello.com: Affiche la chaîne de caractères 'Hello'. 24 octets. Pour tests.
    • dostools/: Sources .asm (pour nasm) des outils DOS ci-dessus.
Programmation: Si vous travaillez sous Linux avec les sources, il suffit de faire 'make flash'. Assurez-vous d'avoir compilé l'outil en ligne de commande sous le dossier 'tools' pour que le script de programmation puisse faire entrer le circuit en mode «bootloader» automatiquement.

Sinon, les étapes manuelles sont:
# Entrer en mode «bootloader» (non-requis pour les cartes neuves n'ayant jamais été programmées
$ tools/ppusbcomm -f --bootloader

# Programmation d'un firmware avec dfu-programmer:
$ dfu-programmer atmega32u2 erase                   # Étape 1: Efface le firmware courant
$ dfu-programmer atmega32u2 flash ppusbcomm.hex     # Étape 2: Programme le nouveau firmware
$ dfu-programmer atmega32u2 start                   # Étape 3: Démarrage du nouveau firmware



Utilisation (transfert de fichiers)

Réception de hello.com

Réception de hello.com

Pour transférer un ou des fichiers, il suffit de lancer rxfiles.com du côté cible (DOS), et du côté hôte, la commande ppusbcomm:
# Transfert d'un fichier
$ ./ppusbcomm -f --upload ../dostools/hello.com

Du côté DOS, rxfiles.com reste actif tant que la touche ESC n'est pas appuyée et recevra et enregistrera chaque fichier. Pour transférer plusieurs fichiers, la commande ci-dessus peut simplement être répétée. Sinon, lorsqu'il y a beaucoup de fichiers à transférer, je fais une boucle comme ceci:
# Transfert les fichiers d'un répertoire
$ for i in `find /chemin/vers/votre/repertoire -type f` ; do ./ppusbcomm -f --upload $i ; done




Utilisation (transfert d'image de disquette)

Transfert en cours

Transfert en cours

Dans la version 1.1, j'ai ajouté un outil nommé rxdisk.com permettant de transférer des images de disquettes. L'outil du côté cible (DOS) écrit les donnés reçues de l'hôte directement dans des secteurs consécutifs de la disquette, tout comme le ferait l'outil rawrite. On pourrait penser que j'aurais pu d'abord transférer le fichier d'image avec rxfiles.com, et ensuite simplement utiliser rawrite, mais ce n'est pas possible toujours possible:
  1. Lorsque l'ordinateur cible n'a pas de disque dur, le fichier d'image doit pouvoir être stocké dans une disquette, souvent de même taille. Lorsqu'il s'agit d'un fichier d'image contenant 100% des secteurs d'une disquette, impossible de le stocker dans une disquette de même taille en tant que fichier.
  2. Lorsque l'ordinateur cible n'a qu'un lecteur de disquettes, comme rawrite lit le fichier par petits morceaux tout en écrivant vers la disquette, les donnés source ne seraient plus disponibles dès que la disquette source serait remplacée par la disquette cible que nous souhaitions créer.
  3. Modifier rawrite pour que le fichier d'image soit lu en mémoire au complet au démarrage, permettant de l'écrire tranquilement vers une nouvelle disquette est hors de question sur plusieurs machines (ex: Un PC ne comportant que 256K ne peut pas tenir une image de 360K!). Et même si c'était via plusieurs séquences de changement de disquette (comme avec diskcopy) le problème de stockage décrit en (1) ci-dessus demeure. (À moins de stocker le fichier d'image en deux morceaux sur deux disquettes différentes...)
Comme les 3 difficultés ci-dessus sont applicables à mon Tandy 1000, un outil écrivant directement sur la disquette cible m'a semblé être la meilleure solution.

Pour transférer une image de disquette, il suffit de lancer rxdisk.com du côté cible (DOS). L'outil demande de changer pour la disquette cible puis d'appuyer sur la touche entrée. Cela fait, l'outil examine la disquette pour déterminer le nombre de secteurs par piste. La prochine étape est le lancement du logiciel de transfert côté hôte, ppusbcomm:
# Transfert d'une image de disquette
$ ./ppusbcomm -f --disk testing/tandycat.dsk

Prêt

Prêt

Écriture des secteurs

Écriture des secteurs

Succès!

Succès!


Le jeu Alley Cat utilisé ici est une version modifiée (datant fin 2015) permettant d'avoir la musique à trois voies et la palette de couleur plus variée comme sur le système PCjr, mais sur les systèmes Tandy. J'ai transformé le .EXE résultant en version disquette en via mon outil booterify (publication à venir).

Pout tout savoir sur les patch pour convertir Alley Cat à « Tandy cat », consultez ce forum:
Tandy sound and video patch for Alley Cat


rxdisk.com est également une bonne façon de recréer les disquettes système Tandy distribuées ici:
http://www.oldskool.org/guides/tvdog/system.html



«Bootstrap»

Comment faire pour installer rxfiles.com avant d'avoir rxfiles.com dans le système DOS de destination? Outre le transfert par disquette (difficile lorsqu'on ne possède qu'un seul lecteur) il est probablement possible de recopier les 697 octets de rxfiles.com à l'aide de l'outil DEBUG de msdos, mais je n'ai jamais essayé.

J'ai plutôt opté pour une implémentation minimale de rxfiles en BASIC. Elle est minimale en ce qu'elle n'arrête pas le transfert (il faut faire CTRL+BREAK une fois terminé) et ne ferme pas le fichier (il faut faire CLOSE#1 avant de quitter). De plus, il faut saisir le nom de fichier car le bloc d'en-tête contenant normalement la taille et le nom de fichier n'est pas supporté. D'ailleurs, il faut utiliser l'option --noheader de ppusbcomm pour ne pas le transmettre, sinon le fichier commencera avec!
# Transfert d'un fichier sans en-tête (pour bootstrap)
$ ./ppusbcomm -f --upload ../dostools/hello.com --noheader

1 CLS 10 INPUT "Destination filename: ",FILENAME$ 12 OPEN FILENAME$ FOR OUTPUT AS #1 100 PRINT "Waiting for block" 110 OUT &H378,0 115 GOSUB 1000 120 IF D = 0 THEN GOTO 132 125 PRINT "Block available" 126 GOTO 200 132 OUT &H378,1 133 GOTO 110 200 PRINT "Readying block" 205 FOR I = 0 TO 31 207 OUT &H378,2 208 GOSUB 1000 209 BYTE = D * 16 ' shift left 4 210 OUT &H378,3 211 GOSUB 1000 212 BYTE = BYTE + D 216 PRINT #1,CHR$(BYTE); 220 NEXT I 225 PRINT "block done" 230 GOTO 100 1000 A = INP(&H379) 1001 D = ((A AND 8)\8) + ((A AND &HE0)\16) 1002 RETURN
Notes:
  • Ce code est extrêmement lent. La vitesse de transfert est d'environ 20 octets par seconde.
  • Le fichier résultant contient toujours un octet en trop (valeur 0x1A). Je crois qu'il s'agit d'un octet indiquant la fin du fichier en basic. (Note: La version de BASIC incluses avec MS-DOS 2.11 n'a pas de mode BINARY pour l'écriture de fichier. Cela aurait peut-être aidé.).
  • Le fichier résultant est toujours d'une taille multiple de 32. Les octets superflus seront à zéro.
  • Heureusement, les octets en trops sont inoffensifs lors du transfert de rxfiles.com!



Fonctionnement

Les entrées Busy, Ack, Paper out et Error représentent les bits 3,2,1 et 0 respectivement. Dans l'autre direction, les bits de donnés 0 à 2 sont utilisés.

La communication se fait par blocs de 32 octets (64 nibbles) comme ceci:


Important: Le « handshake » n'est pas complet. L'assomption faite par rxfiles.com est que la carte ppusbcomm réponds assez rapidement aux changements d'états sur les lignes de donnés. Sur un PC plus rapide que mon Tandy 1000 EX (CPU 8088 à 7.16MHz) il est possible qu'il faille ajouter des délais dans rxfilles.com.


Le port parallèle du Tandy 1000 EX

Le port parallèle du Tandy 1000 EX n'utilise pas un connecteur DB25, mais plutôt un connecteur « card edge » comme pour les lecteurs de disquettes souples 5 1/4". Le « pinout » est différent, mais grâce au Tandy 1000-series FAQ, il est facile de s'y retrouver.

L'astuce est de trouver un câble de disquette ne comportant pas le petit bout de plastique destiné à en empêcher le branchement inversé:
L'arrière du Tandy 1000 EX

L'arrière du Tandy 1000 EX

Connecteur utilisable

Connecteur utilisable

Connecteur inutilisable

Connecteur inutilisable

Branchement

Branchement


Reste bien sûr les possibilités d'acheter un connecteur neuf, ou de modifier un connecteur existant.

Pour être bien certain de ne pas avoir fait d'erreurs sur l'orientation du branchement et le numérotage des signaux, j'ai fait un test rapide avec une DEL sur la ligne Data 0. Un petit logiciel en BASIC le fait clignoter. Cela a également confirmé que l'adresse 0x378 était bien celle du port parallèle sur le Tandy 1000 EX.
Test avec une DEL

Test avec une DEL

10 OUT &H378, 0 11 PRINT "OFF" 15 GOSUB 100 20 OUT &H378, 255 21 PRINT "ON" 30 GOSUB 100 40 GOTO 10 100 FOR I = 0 TO 255 ' Délais 101 NEXT I 102 RETURN




Pourquoi ce projet?

J'ai un ordinateur Tandy 1000 EX doté d'un lecteur de disquettes DD (double densité 360K). Pour écrire des disquettes qui seront lisibles ce lecteur, il faut absolument utiliser un lecteur DD.

Cela pose problème car toutes mes autres machines ont des lecteurs HD (Haute densité). Pour essayer un nouveau jeu, je dois donc retirer le lecteur de disquettes du Tandy 1000 pour l'installer temporairement dans un autre PC, copier les fichiers puis remettre le lecteur à sa place d'origine. Beaucoup trop pénible.

J'ai pensé à quelques solutions que je n'ai pas retenues, voici pourquoi:
  • Remplacement du lecteur de disquette: Difficile car le BIOS de cette machine ne supporte pas les lecteurs haute densité.
  • Utilisation d'un émulateur de disquettes: Je perdrais le plaisir de manipuler ces anciennes disquettes ainsi que la satisfaction d'entendre le bruit du lecteur. De plus, j'aurais du l'acheter en étant certain que l'émulation d'un lecteur double densité est supportée, et il aurait fallu que j'attende de le recevoir.
  • Transfert de fichiers par port série: Impossible, pas de port série sur cette machine.
Le seul port qui semblait utilsable était le port parallèle. Je me souviens qu'il existait un logiciel nommé Laplink qui, combiné à un câble reliant les ports parallèles de deux PC, permettait le transfert de fichiers. La solution parfaite!

Mais il y avait quelques obstacles à utiliser Laplink:
  • Je ne possèdait pas ce logiciel, et j'ignorais s'il pouvait fonctionner avec MS-Dos 2.11 sur le CPU 8088 du Tandy 1000.
  • L'idéal pour moi était de pouvoir transférer ces fichiers depuis mon système Linux. (Avoir une autre machine fonctionnant sous Dos n'est pas pratique)
  • Le port parallèle du Tandy 1000 n'a que 4 bits en entrée (le signal SELECT est apparamment contrôlé par un cavalier) et j'ignore si dans ces conditions Laplink aurait fonctionné.
C'est pourquoi j'ai décidé développer mon propre système qui:
  • Utilise USB du côté master (Facile à utiliser avec Linux, et pas de dépendence sur un port qui se fait très rare de nos jours)
  • N'utilise que 4 bits d'entrée (Donc compatible avec le Tandy 1000 malgré les limitations de son port)
  • Écrit en assembleur 8086/8088 (Tourne donc sans problème sur le CPU 8088 du Tandy 1000, et l'assembleur donne un exécutable très compact



Succès!

Grace à ce système, j'ai le plaisir de transférer et de rejouer à quelques vieux jeux:
Pipes

Pipes

Montezuma's revenge

Montezuma's revenge

Block out

Block out

Oh non, 256K ne suffisent pas :(

Oh non, 256K ne suffisent pas :(


Note: Les photos ci-dessus montrent un Tandy 1000 EX avec écran VGA. Cela est rendu possible par l'adaptateur CGA à VGA que j'ai construit.


Références

  • Interfacing the Standard Parallel Port: http://retired.beyondlogic.org/spp/parallel.htm
  • Tandy 1000-series FAQ: http://www.oldskool.org/guides/tvdog/1kfaq.html
  • Intel x86 JUMP quick reference: http://unixwiz.net/techtips/x86-jumps.html
  • HelpPC Reference Library: http://stanislavs.org/helppc/
  • GW-BASIC User's Guide: http://www.antonis.de/qbebooks/gwbasman/
  • Parallel port: https://en.wikipedia.org/wiki/Parallel_port



Avertissement

Je ne saurais être tenu responsable pour les dommages que l'utilisation des informations ou la mise en œuvre des instructions présentées sur cette page pourrait causer à votre équipement, à vous-même ou à autrui. Aussi, je ne donne aucune garantie quant à l'exactitude des informations et à leur fonctionnement.