18/08/2021

Un micro-ordinateur FLEX/6809 DIY - Partie 3

 Aujourd'hui, nous allons terminer la description de la partie matérielle et faire quelques tests.

 


Le matériel

Les schémas qui suivent vont transformer le petit ordinateur mono-carte "générique" décrit dans la partie 1 en un ordinateur capable de faire fonctionner le système d'exploitation Flex09 sur une paire de lecteurs de disquettes

Le port imprimante


Cette partie du circuit est construite autour d'un PIA 6821 qui a plusieurs usages :

  • Un port parallèle pour imprimante
  • Quelques signaux pour le contrôleur de disquette :
    • PSEL0, niveau haut pour sélectionner le lecteur 0
    • PSEL1, niveau haut pour sélectionner le lecteur 1
    • PSIDESELECT, niveau bas pour sélectionner la face inférieure de la disquette, niveau haut pour sélectionner la face supérieure
    • PDDEN, niveau bas pour sélectionner la double densité, niveau haut pour sélectionner la simple densité
  • Une LED
  • PSW1 qui est une entrée connectée sur le 4ème interrupteur du bloc de 4 switchs visible sur le schéma du port série (cf partie 1)

Le contrôleur de lecteurs de disquettes



Le contrôleur de disquettes est un WD1770. On aurait pu mettre aussi un WD1772 qui est presque identique (la principale différence est le paramétrage de la vitesse de déplacement de la tête de lecture). Ces 2 composants intègrent presque tout ce qu'il faut pour piloter un lecteur de disquettes.

Cette famille de composants Western Digital se retrouve dans beaucoup d'ordinateurs des années 80, par exemple l'Atari ST a un WD1772. Le code de Flex a également été fait à la base pour ces contrôleurs, donc c'est une bonne idée de partir sur cette voie !

Sur le schéma on va trouver plusieurs éléments :

  • Un oscillateur à 8Mhz fait avec 2 inverseurs. Le datasheet indique qu'il doit être précis à 0.1%. J'ai mis un condensateur variable pour pouvoir ajuster la fréquence si besoin
  • Les sorties du WD1770 sont protégées par un inverseur 74LS06
  • Il n'y a qu'une sortie 'Motor On' sur le WD1770, je la combine avec des portes ET et les signaux de sélection des lecteurs de disques PSEL0 et PSEL1 pour créer 2 commandes de moteur différentes

A noter que Flex permet de gérer 4 lecteurs de disquettes (et ça ne serait pas difficile à ajouter au schéma existant), mais j'ai voulu rester simple, et on peut déjà faire pas mal de choses avec 2 lecteurs !

Le port d'extension

 

J'ai prévu un port d'extension qui présente tous les signaux du 6809, plus quelques signaux qui viennent du circuit de décodage d'adresse. Physiquement il prend la forme d'un connecteur DIN 41612 à 2 rangées (2x32).

L'idée est de pouvoir ajouter une (ou plusieurs) cartes d'extension "empilées" sur la carte de base.
 
Je n'ai pas mis de buffer en amont de ce connecteur, il faudra obligatoirement en mettre sur les cartes d'extensions (74LS245 ou équivalent).

 Le circuit imprimé

J'ai finalement dessiné un PCB pour cet ordinateur, il fait la même dimension que mon circuit d'essai (12x18cm), en double face. L'illustration en tête de cet article donne idée de ce à quoi cela ressemble.

Au moment où j'écris cet article je n'ai pas encore commandé le PCB, du coup je ne sais pas (encore) garantir qu'il n'y a pas d'erreur !

Quelques tests

Le programme pia.asm (dans software/tests/pia) permet de faire quelques tests autour du PIA 6821. Il est composé de quelques routines à appeler depuis Assist09 avec la commande 'C'

Il s'assemble de la même façon que les programmes précédents :

as9 pia.asm -l c s cre s19

Pour le charger, utiliser la commande 'L' du moniteur et envoyer le fichier pia.s19

0001                               ; PIA / ASSIST09
0002
0003 e810                          PIA      EQU $E810
0004
0005 e810                          PRA      EQU PIA
0006 e810                          DDRA EQU PIA
0007 e811                          CRA      EQU PIA+1
0008 e812                          PRB      EQU PIA+2
0009 e812                          DDRB EQU PIA+2
0010 e813                          CRB      EQU PIA+3
0011
0012
0013 0100                               ORG $0100
0014
0015                               INIT
0016 0100 4f                 [ 2 ]      CLRA                    ; init PIA + select DDRA & DDRB
0017 0101 b7 e8 11           [ 5 ]      STA     CRA
0018 0104 b7 e8 13           [ 5 ]      STA     CRB
0019 0107 86 0f              [ 2 ]     LDA #$0F            ; PORTA b0..b3 = output
0020 0109 b7 e8 10           [ 5 ]      STA     DDRA
0021 010c 86 ff              [ 2 ]      LDA     #$FF            ; PORT B = output
0022 010e b7 e8 12           [ 5 ]      STA     DDRB
0023 0111 86 3e              [ 2 ]      LDA     #%00111110      ; select PRB
0024 0113 b7 e8 13           [ 5 ]      STA     CRB
0025 0116 39                 [ 5 ]      RTS
0026
0027 0117 86 34              [ 2 ] LEDOFF       LDA     #%00110100  ; turn off LED
0028 0119 b7 e8 11           [ 5 ]          STA CRA
0029 011c 39                 [ 5 ]          RTS
0030
0031 011d 86 3c              [ 2 ] LEDON   LDA  #%00111100  ; turn on LED
0032 011f b7 e8 11           [ 5 ]          STA CRA
0033 0122 39                 [ 5 ]          RTS
0034
0035                               PRTCHR
0036 0123 b7 e8 12           [ 5 ]          STA PRB         ; write data to printer port
0037 0126 86 34              [ 2 ]         LDA #%00110100  ; STROBE L
0038 0128 b7 e8 13           [ 5 ]         STA CRB
0039 012b 12                 [ 2 ]         NOP
0040 012c 86 3c              [ 2 ]         LDA #%00111100  ; STROBE H
0041 012e b7 e8 13           [ 5 ]         STA CRB
0042 0131 b6 e8 13           [ 5 ] PRTCHRW      LDA     CRB
0043 0134 2a fb              [ 3 ]          BPL PRTCHRW     ; loop if CRB.7 == 0
0044 0136 b6 e8 12           [ 5 ]         LDA PRB         ; read PRB to clear CRB.7
0045 0139 39                 [ 5 ]          RTS
0046
0047 013a 86 2a              [ 2 ] TST      LDA #42         ; print a '*'
0048 013c 8d e5              [ 7 ]          BSR PRTCHR
0049 013e 39                 [ 5 ]          RTS
0050
0051 013f bd 01 3a           [ 8 ] TSTL JSR     TST         ; print an infinite quantity of '*'
0052 0142 20 fb              [ 3 ]          BRA TSTL
0053
0054 0144 a6 80              [ 6 ] OUTSTR       LDA     ,X+         ; print message at address X
0055 0146 27 05              [ 3 ]          BEQ OUTSTRE
0056 0148 bd 01 23           [ 8 ]          JSR         PRTCHR
0057 014b 20 f7              [ 3 ]          BRA OUTSTR
0058 014d 39                 [ 5 ] OUTSTRE      RTS
0059
0060 014e 8e 01 54           [ 3 ] TESTSTR      LDX     #MSG        ; print a 'Hello World'
0061 0151 8d f1              [ 7 ]      BSR     OUTSTR
0062 0153 39                 [ 5 ]      RTS
0063
0064                               MSG
0065 0154 1b 78 31 1b 47 1b             FCB 27,120,49,27,71,27,104,2
     68 02
0066 015c 48 65 6c 6c 6f 2c             FCC /Hello, World!/
     20 57 6f 72 6c 64
     21
0067 0169 0d                            FCB 13
0068 016a 0a                            FCB 10
0069 016b 00                            FCB 0
0070

Le fichier .lst  indique les différents points d'entrée :

  • 0100 : initialisation du PIA
  • 0117 : éteindre la LED
  • 011d : allumer la LED
  • 013f : imprimer une infinité de '*' (enfin, tant qu'il y a du papier dans l'imprimante !)
  • 014e : imprimer un 'Hello World' 

 Une fois le programme chargé, un 'C 0100' va initialiser les registres du PIA (le datasheet est disponible dans le github). Ensuite, les commandes 'C0117' et 'C011d' permettent respectivement d'allumer et d'éteindre la LED.

Pour tester l'imprimante, il faut déjà ... en avoir une avec un port Centronic (donc un vieux modèle !). J'utilise pour mes tests une STAR LC-10, qui est une imprimante matricielle à 9 aiguilles.

Le protocole de communication est assez simple (voir l'implémentation dans le code ci-dessus, routine PRTCHR) :

  • envoyer le code du caractère à imprimer sur le port de données (port B)
  • faire une impulsion (état logique bas) sur le signal \ACK
  • attendre un front montant sur le signal \STROBE

Les commandes 'C 013F' et 'C014E' permettent de lancer les 2 tests.

 Ressources

 Le projet github est disponible ici : https://github.com/laurent-fr/LFlex21