[Thomson] SDDRIVE

Placez ici vos trucs et astuces, étalez sans retenue votre savoir-faire et votre science qui va nous permettre de redonner une apparence neuve et fonctionnelle à nos bouzes.

Modérateurs : Papy.G, fneck, Carl

Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Je savais que __sam__ voudrait en savoir plus :wink:

Pour le TO8 et le TO8D c'est pareil, sauf que le TO8D a un lecteur de disquette branché en permanence, alors que le TO8 n'avait pas de lecteur de disquette branché lors des essais. Il faut savoir que les TO8, TO8D et TO9+ font un reset du contrôleur avant d'initialiser le BASIC
S'il y a un lecteur, le contrôleur interne est sélectionné automatiquement au démarrage, il y a un reset du contrôleur interne, pas de problème.
Sans le lecteur, le contrôleur externe est sélectionné. Il y a donc un reset de SDDRIVE, mais ensuite l'initialisation du BASIC détruit des zones de travail et ça plante. J'ai testé un indicateur d'initialisation en $60FE pour ne pas faire le premier reset, et le problème disparaît.

L'optimisation du code consiste à remplacer les appels de subroutines de lecture et d'écriture par la recopie des instructions. J'ai fait deux macros pour remplacer les BSR. Le code est plus long, mais j'avais la place. Par contre maintenant l'EPROM est pleine comme un oeuf, il n'y aura pas d'Easter egg. Côté performances, en supprimant BSR et RTS (12 cycles) pour chaque lecture ou écriture d'octet (50 cycles) le gain est environ 25%.

Dans les démos de musique j'ai fait quelques optimisations supplémentaires. Par exemple, je remplace la lecture des deux octets de CRC par de simples tops d'horloge, vu que je ne contrôle pas ces deux octets.

Une autre bonne nouvelle est la possibilité de changer d'image de disquette sans éteindre l'ordinateur. Le programme de sélection est copié sur la carte SD (la disquette boot.sd n'est plus utilisée). Une procédure dans l'EPROM, en $A02E/$E02E, permet de l'appeler depuis le BASIC. Le programme de sélection est chargé en moins d'un dixième de seconde. Toutefois, dans beaucoup de jeux commerciaux et dans la plupart des démonstrations, on n'a plus accès au BASIC, il faudra donc, dans ces cas particuliers, couper l'alimentation.

La mise au point va encore durer quelques semaines, car à chaque fois que j'améliore un détail pour une machine il faut tester sur toutes les autres. Non seulement ça prend du temps, mais parfois ça ne marche pas, il faut trouver des contournements. Ce n'est pas facile...
Daniel
L'obstacle augmente mon ardeur.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Pendant les essais, j'ai eu des comportements bizarres (fonctionnement aléatoire), qui m'ont fait soupçonner à nouveau des problèmes d'interface. Après trois jours de recherches j'ai trouvé la cause : les EEPROMs AT28C16. Comme je modifie le programme du contrôleur SDDRIVE plusieurs dizaines de fois chaque jour, j'utilisais ces EEPROMs car elles sont plus pratiques que les classiques EPROMs effaçables aux ultra-violets.

Mais c'étaient elles les coupables. En revenant aux M2732A les ennuis ont disparu. Je ne sais pas pourquoi les AT28C16 sont moins fiables, mais plusieurs expériences l'ont confirmé. J'aurais plutôt supposé l'inverse...
Daniel
L'obstacle augmente mon ardeur.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Nouveau point sur le développement :

Aujourd'hui (19/12/2017) l'écriture de tous les programmes est terminée, ils sont tous testés et fonctionnent.
Il y aura peut-être des ajustements de dernière minute, mais les modifications seront mineures.
La partie soft comprend :
- Le contenu de l'EPROM du contrôleur SDDRIVE : bios pour la carte SD et lancement du programme de sélection.
- Le programme SDDRIVE.SEL permettant de sélectionner la disquette à monter dans un menu déroulant.
- Le programme SDDRIVE-MUSIC pour le streaming audio 6 bits / 15152 échantillons par seconde.

Il reste quelques soucis avec l'électronique, avec quelquefois des comportements bizarres. Du genre ça ne marche pas avec une AT28C16 mais ça marche avec une M2732A contenant le même programme. Curieusement j'ai eu aussi l'inverse, alors je n'y comprends plus rien. Par contre, quand ça marche, il n'y a jamais d'erreur. Je peux faire tourner des démos ou des jeux commerciaux en boucle pendant plusieurs heures sans jamais le moindre plantage.

Dès qu'une parade aura été trouvée je construirai un nouveau prototype. Ensuite les circuits imprimés pourront être fabriqués.
D'ores et déjà, après quelques jours d'utilisation, je peux témoigner de la facilité d'utilisation et de la rapidité du système : au démarrage du MO5 le menu de sélection de disquette est affiché avant même que le moniteur ait eu le temps de commuter. Ensuite, après sélection de la disquette, le DOS se charge en moins de 3 secondes, contre plus de 15 secondes avec une vraie disquette.
C'est exactement ce dont je rêvais le siècle dernier 8)
Daniel
L'obstacle augmente mon ardeur.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Nouveau point de fin d'année :
- Tous les problèmes électroniques sont résolus. Le schéma n'évoluera probablement pas, ou très peu.
- Le logiciel (BIOS d'accès à carte SD et programme de sélection de disquette) fonctionne bien.
- Un nouveau prototype a été construit aujourd'hui et donne (pour l'instant) entière satisfaction 8)

Donc tout va bien, la sortie officielle de ce nouveau périphérique Thomson est toujours prévue début 2018.
Ce n'est pas une révolution, mais une très grosse avancée par rapport à tous ses prédécesseurs.

Image

Je posterai bientôt des photos et d'autres explications.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: [Thomson] SDDRIVE

Message par Carl »

Daniel, sacré boulot ! 8)

Carl
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Quelques photos du dernier prototype :

sddrive_proto-dessus.jpg
sddrive_proto-dessus.jpg (135.3 Kio) Consulté 2794 fois
sddrive_proto-dessous.jpg
sddrive_proto-dessous.jpg (170.59 Kio) Consulté 2794 fois
sddrive_proto-boite.jpg
sddrive_proto-boite.jpg (102.31 Kio) Consulté 2794 fois
sddrive_proto-termine.jpg
sddrive_proto-termine.jpg (34.56 Kio) Consulté 2794 fois
sddrive_proto-connecte.jpg
sddrive_proto-connecte.jpg (47.36 Kio) Consulté 2794 fois
Daniel
L'obstacle augmente mon ardeur.
jasz
Messages : 1313
Inscription : 05 oct. 2016 20:05
Localisation : Quelque part dans le 31

Re: [Thomson] SDDRIVE

Message par jasz »

Je vois que la chose va bon train. 8)
En attendant la version officiel je souhaite à tous une très bonne fin d'année et vous souhaite plein de bonnes choses pour celle avenir.

Tous mes voeux.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Exemple de sélection et de chargement d'un jeu avec SDDRIVE :

sddrive_selection.jpg
sddrive_selection.jpg (90.94 Kio) Consulté 2756 fois
sddrive_flipper.jpg
sddrive_flipper.jpg (85.65 Kio) Consulté 2756 fois
Chargement de Flipper en 3 secondes (contre 10 minutes avec la cassette originale). Qui dit mieux ?

L'accès à l'écran de sélection est tellement rapide que j'ai dû le retarder de 400 millisecondes. En effet il se lançait trop vite au démarrage de l'ordinateur, avant que la tension soit stabilisée, et c'était l'une des causes de mes problèmes précédents. Avec cette temporisation, et une résistance de pull-up de 10K sur la sortie MISO de la carte SD, toutes les instabilités ont disparu sur toutes les machines et avec tous les types d'EPROM.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [Thomson] SDDRIVE

Message par hlide »

C'est beau ! mais une question me taraude : le principe est portable sur les autres ordinosaures ?
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

La réponse est un peu plus haut dans ce fil de discussion : viewtopic.php?f=18&t=8448&start=14

Voici le code, si quelqu'un veut l'adapter à d'autres ordinateurs :

Code : Tout sélectionner

/**************************************************\
*           S D D R I V E _ C O N T R O L          * 
*           (c) 2018 - Daniel Coulom               *  
*           http://dcmoto.free.fr/                 *
*           http://forum.system-cfg.com/           *
*--------------------------------------------------*
* Ce code est distribue gratuitement dans l'espoir *
* qu'il sera utile, mais sans aucune  garantie  et *
* sans  engager  la  responsabilité  de  l'auteur. *
* Vous  pouvez  l' utiliser,  le  modifier  et  le *
* diffuser librement, en conservant cette  licence *
* et les références de l'auteur dans   toutes  les *
* copies. L'exploitation commerciale est interdite.*
\**************************************************/

* Ce programme emule un controleur de disquette
* Thomson accedant a une image au format .sd par
* l'intermediaire de l'interface SDDRIVE.

* Credits : Les routines de calcul de LBA sont des
* adaptations du code original de Samuel Devulder.

/**************************************************\
*                Version 2018.01.01                *
*     (reporter la version en fin de programme)    *
\**************************************************/
* Historique
* 2018.01.01 Temporisation avant initialisation carte
* 2017.12.29 Retour erreur si la carte ne repond pas
* 2017.12.18 Lancement auto SDSEL une seule fois
* 2017.12.17 Lancement SDSEL dans la routine DKBOOT
* 2017.12.16 Refonte des routines RESET et SDSEL
* 2017.12.15 Sur TO8, SDSEL n'est pas lance au reset
* 2017.12.14 Sur MO6 pas de reset avant initial. BASIC
* 2017.12.14 Vecteur $A02E/$E02E pour appeler SDSEL
* 2017.12.13 Retour au BASIC après l'appel de SDSEL  
* 2017.12.13 Macros de lecture et ecriture octet  
* 2017.12.10 Appel SDDRIVE.SEL a chaque RESET  
* 2017.12.08 Chargement et execution de SDDRIVE.SEL  
* 2017.12.07 Optimisation routine CLOCK  
* 2017.12.03 Amelioration et optimisations mineures  
* 2017.11.28 B remplace X comme compteur dans EXCMD  
* 2017.11.27 ROLA/STA remplace ROL (sinon 2 tops) 
* 2017.11.26 Optimisation de la lecture d'un octet
* 2017.11.19 Version originale adaptee de CS91280     

*------------------------------------------------------
* VECTEURS EN RAM
*------------------------------------------------------
DK_OPC  EQU $6048   code commande controleur disquette
DK_DRV  EQU $6049   numero du lecteur de disquette
DK_TRK  EQU $604a   n° piste (2 octets)
DK_SEC  EQU $604c   n° secteur
DK_NUM  EQU $604d   entrelacement
DK_STA  EQU $604e   etat courant controleur disquette
DK_BUF  EQU $604f   adresse buffer secteur (2 octets)
* position tetes    n° piste + n° secteur (2 octets)
TRACK0  EQU $6051   position tete lecteur 0 (inutilise)
TRACK1  EQU $6053   position tete lecteur 1 (inutilise)
TRACK2  EQU $6055   position tete lecteur 2 (inutilise)
TRACK3  EQU $6057   position tete lecteur 3 (inutilise)
* indicateurs du controleur de disquette
ROTAT   EQU $6058   indicateur de rotation du moteur (inutilise)
DKFLG   EQU $6080   indicateur presence controleur disque

* Zones de travail en pile systeme pour le driver de la carte SD
SD_LB0  EQU $608E   adresse du debut du fichier .sd dans la carte SD
SD_TYP  EQU $6092   type de carte SD=0 SDHC=1
SD_CMD  EQU $6093   definition de la commande CMD17 ou CMD24
SD_LBA  EQU $6094   adresse du secteur courant dans la carte SD

DKWE5   EQU $60e5   code erreur
DKWE7   EQU $60e7   pointeur sur nom de fichier
DKWE9   EQU $60e9   pointeur sur buffer
DKWEB   EQU $60eb   type de fichier
DKWEC   EQU $60ec   flag de fichier 
DKWED   EQU $60ed   bloc libre dans la FAT
DKWF0   EQU $60f0   code operation logique
DKWF5   EQU $60f5   numero de secteur
DKWF6   EQU $60f6   numero de bloc  
DKWF7   EQU $60f7   nombre d'octets dans le dernier secteur du fichier
DKWF9   EQU $60f9   numero de bloc alloue
DKWFA   EQU $60fa   numero du premier secteur du bloc
DKWFB   EQU $60fb   numero de piste du bloc courant
BUFFER  EQU $6200   buffer de lecture/ecriture secteur

* Buffer de lecture des secteurs de la carte SD
BUF512  EQU $9C00 adresse buffer de lecture secteur 512 octets
BNSEC   EQU $9C0D nombre de secteurs par cluster (sur 1 octet)
BRES2   EQU $9C0E nombre de secteurs reserves pds faible
BRES1   EQU $9C0F nombre de secteurs reserves pds fort
BFATS2  EQU $9C16 taille FAT16 pds faible
BFATS1  EQU $9C17 taille FAT16 pds fort
BFATS4  EQU $9C24 taille FAT32 pds faible
BFATS3  EQU $9C25 taille FAT32 pds fort
BNFAT   EQU $9C10 nombre de FATs 
BNDIR2  EQU $9C11 nbre entrees directory pds faible
BNDIR1  EQU $9C12 nbre entrees directory pds fort
BLBA2   EQU $9DC6 LBA partition pds faible  
BLBA1   EQU $9DC7 LBA partition pds fort    
BBIND   EQU $9DBE boot indicator 
BSIGN   EQU $9DFE adresse de la signature dans le buffer
BUFEND  EQU $9E00 adresse de fin du buffer (+1)

* Information sur le partitionnement de la carte SD
CSIZ2   EQU $9E00 nombre de secteurs par cluster (sur 2 octets)
CSIZE   EQU $9E01 nombre de secteurs par cluster (sur 1 octet)
RSECT   EQU $9E02 nombre de secteurs reserves
PSECT   EQU $9E04 numero secteur debut partition
DSECT   EQU $9E06 numero secteur debut directory
FSECT   EQU $9E08 numero secteur du data cluster 0    

*******************************************************
* DESCRIPTION DES FONCTIONS SPECIALES SDDRIVE
*
* EXCMD Lance une commande pour la carte SD
* - Registre DP = $A7(MO) ou $E7(TO)
* - Registre U = adresse des parametres de la commande
*   (code commande + 4 octets + checksum + code retour)
* - Retour registre A (0 = OK, sinon erreur)
* - Les registres ne sont pas preserves (sauf DP) 
*
* RS512 Lit un secteur de 512 octets
* - CMDXX+1 = LBA secteur,   en $2094(MO) ou $6094(TO)
* - DK_BUF = Adresse buffer, en $204F(MO) ou $604F(TO)
* - Les registres ne sont pas preserves
* - Le registre DP est retabli en $20(MO) ou $60(TO)
*
*******************************************************

*------------------------------------------------------
* ROM DU CONTROLEUR
*------------------------------------------------------
  ORG $E000
  FCB $53        S  controleur carte SD     
  FCB $54        T  fat de 160 octets     
  FCB $44        D  double densite    
  FCB $40        @  checksum $53+$54+$44+$55=$140

OPTABL
  LBRA  DKCONT   fonctions standard      
  LBRA  DKBOOT   lancement du boot       
  LBRA  DKFMT    formatage               
  LBRA  LECFA    chargement de la fat    
  LBRA  RECFI    ouverture d'un fichier  
  LBRA  RECUP    effacement d'un fichier 
  LBRA  ECRSE    ecriture d'un secteur   
  LBRA  ALLOD    creation d'un fichier   
  LBRA  ALLOB    allocation d'un bloc    
  LBRA  MAJCL    mise a jour cluster     
  LBRA  FINTR    cloture d'ecriture      
  LBRA  RESETO   reset special TO8/TO8D/TO9/TO9+      
  LBRA  EXCMD    execution commande pour carte SD      
  LBRA  RS512    lecture secteur de 512 octets
  LBRA  DKSEL    selection d'une disquette

*------------------------------------------------------
* MACRO DE LECTURE D'UN OCTET AVEC SDDRIVE
* Le registre B doit contenir $7F avant l'appel
* Valeur de l'octet dans le registre A en sortie
* Duree totale de la lecture = 48 cycles
*------------------------------------------------------
READ_BYTE MACRO
  CMPB  <$BF          lecture bit 7              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 6              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 5              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 4              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 3              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 2              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 1              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 0              (4)
  ROLA                pousser dans A             (2)
  ENDM

*------------------------------------------------------
* MACRO D'ECRITURE D'UN OCTET AVEC SDDRIVE
* Valeur de l'octet dans le registre A en entree
* Duree totale de l'ecriture = 50 cycles
*------------------------------------------------------
WRITE_BYTE MACRO
  ROLA                b7 dans carry              (2)
  ROLA                b7 dans b0                 (2)
  STA   <$BF          ecriture bit 7             (4)
  ROLA                b6 dans b0                 (2)
  STA   <$BF          ecriture bit 6             (4)
  ROLA                b5 dans b0                 (2)
  STA   <$BF          ecriture bit 5             (4)
  ROLA                b4 dans b0                 (2)
  STA   <$BF          ecriture bit 4             (4)
  ROLA                b3 dans b0                 (2)
  STA   <$BF          ecriture bit 3             (4)
  ROLA                b2 dans b0                 (2)
  STA   <$BF          ecriture bit 2             (4)
  ROLA                b1 dans b0                 (2)
  STA   <$BF          ecriture bit 1             (4)
  ROLA                b0 dans b0                 (2)
  STA   <$BF          ecriture bit 0             (4)
  ENDM
  
*------------------------------------------------------
* DKSEL = Selection d'une disquette
*------------------------------------------------------
DKSEL
  PSHS  U,Y,X,DP,B,A  empilage des registres
  LBSR  SDSEL         selection de la disquette
  PULS  A,B,DP,X,Y,U,PC retour
  
*------------------------------------------------------
* DKBOOT = Lancement du boot
* Si la carte SD n'est pas initialisee :
* - selection d'une disquette
* - si secteur de boot valide lancement du boot 
* - sinon branchement au contenu de $001e 
* Si la carte SD est initialisee :
* - si secteur de boot valide lancement du boot 
* - sinon retour au programme appelant 
*------------------------------------------------------
DKBOOT
  LBSR  DPINIT        initialiser DP
  LDA   #$55          signature "disquette selectionnee"
  CMPA  <SD_LBA+4     test signature
  BEQ   DKB1          la carte est déjà initialisee
  LDD   >$001e        adresse lancement application
  PSHS  B,A           retour a l'adresse de lancement
  LBSR  SDSEL         selection d'une disquette
  BCS   DKB9          erreur de selection
DKB1
  CLR   <DK_DRV       0 dans le numero de lecteur
  CLR   <DK_TRK       toujours zero
  CLR   <DK_TRK+1     selection piste 0
  LDA   #$01          valeur pour secteur 1
  STA   <DK_SEC       selection secteur 1
  LEAU  BUFFER,PCR    adresse du buffer secteur
  STU   <DK_BUF       stockage adresse buffer
  LBSR  RS256         lecture secteur logique
  BCS   DKB9          erreur de lecture
  LEAU  BUFFER,PCR    adresse debut de buffer      
  LEAY  $7F,U         adresse fin de buffer
  PSHS  Y             empilage adresse fin de buffer
  LDA   #$55          calcul checksum boot
DKB4
  DEC   ,U            octet - 1
  COM   ,U            complement
  ADDA  ,U+           ajout checksum
  CMPU  ,S            test fin de buffer
  BNE   DKB4          octet suivant
  PULS  Y             pour retablir le pointeur de pile
  CMPA  ,U            test checksum boot
  BNE   DKB9          checksum fausse
  JMP   BUFFER,PCR    execute le boot
DKB9
  CLR   <DKFLG        Indicateur de presence controleur
  RTS                 lancement application a froid [$001e]

*------------------------------------------------------
* DKCONT = Fonctions standard
*------------------------------------------------------
DKCONT
  PSHS  U,Y,X,DP,B,A,CC                  
  LBSR  DPINIT        initialisation DP $20 ou $60
  CLRA                status=0
  PSHS  A             empile le status
  PULS  B             depile le status
  BSR   STDOP         execution de l'operation
  PULS  A             depile CC 
  EXG   A,CC          restaure CC
  LSRA                bit d'erreur dans CC
  PULS  A,B,DP,X,Y,U,PC
  
*------------------------------------------------------
* Execution fonction standard
*------------------------------------------------------
STDOP
  LDA   <DK_OPC       Code operation  
  LEAY  RESET,PCR     Reset controleur
  BITA  #$01          Bit reset
  BNE   STDOP2        Execution reset          
  LEAY  RS256,PCR     Lecture secteur logique
  BITA  #$02          Bit lecture secteur
  BNE   STDOP2        Execute lecture secteur   
  LEAY  SWRITE,PCR    Ecriture secteur logique
  BITA  #$08          Bit ecriture secteur
  BNE   STDOP2        Execute lecture secteur 
  LEAY  FIND0,PCR     Recherche piste 0
  BITA  #$20          Bit recherche piste 0
  BNE   STDOP2        Execute recherche piste 0
  LEAY  FINDT,PCR     Recherche piste
  BITA  #$40          Bit recherche piste x
  BNE   STDOP2        Execute recherche piste x
  BITA  #$04          Bit passage simple densite
  BNE   STDOP1        Ne rien faire
  BITA  #$10          Bit passage double densite
  BNE   STDOP1        Ne rien faire           
  COMB                Set Carry = fonction inconnue 
STDOP1
  RTS                 Retour       
STDOP2
  JMP   ,Y            Execution de la fonction

*------------------------------------------------------
* RESET SPECIAL POUR TO8/TO8D/TO9+
*------------------------------------------------------
RESETO
  ORCC  #$50          desactive les interruptions 
  LDA   #$60          valeur d'initialisation de DP
  TFR   A,DP          initialisation de DP
  LBSR  RESET         initialise la carte SD
  LDS   #$60CC        initialise pointeur pile systeme
  LDB   #$DF          type de disque
  LDA   $FFFF         dernier octet rom
  CMPA  #$EE          test rom TO8 version 1
  BEQ   RESETC        reset TO8 version 1
  CMPA  #$C8          test rom TO8D et TO8 v2
  BEQ   RESETD        reset TO8D et TO8 v2
  CMPA  #$A0          test rom TO9+
  BEQ   RESETP        reset TO9+ 
  JMP   [$FFFE]       sinon reset normal
RESETC
  JMP   $FE50         suite du reset du TO8 version 1
RESETD
  JMP   $FE4C         suite du reset du TO8D et TO8v2
RESETP
  JMP   $FE29         suite du reset du TO9+
  RTS

*------------------------------------------------------
* INITIALISATION DP POUR ACCES A LA CARTE SD
*------------------------------------------------------
SDCONF 
  ORCC  #$50          desactive les interruptions 
  TFR   PC,D          adresse courante            
  ANDA  #$F0          octet $A0 ou $E0
  ORA   #$07          ajout de 7
  TFR   A,DP          DP=$A7/$E7 pour acces carte SD
  RTS

*------------------------------------------------------
* INITIALISATION DP $20 (MO) OU $60 (TO)
*------------------------------------------------------
DPINIT
  TFR   PC,D          D=adresse courante            
  ANDA  #$70          valeur DP fonction de PC
  TFR   A,DP          DP = $20 ou $60
  RTS   

*------------------------------------------------------
* INITIALISATION DE LA CARTE SD
* CMD0 = SOFTWARE RESET
* Precedee de l'envoi de 80 tops d'horloge
* En cas d'erreur retour carry=1
*------------------------------------------------------
RESET
  LDX   #$0000        compteur de boucle
RESET0
  LEAX  -1,X          decrementation compteur
  BNE   RESET0        attente stabilisation tensions 
  BSR   SDCONF        initialise DP pour acces carte SD
  LDA   #$0A          pour 10 fois 8 tops
  LBSR  CLOCK         envoi de A*8 tops horloge 
  LEAU  CMD0,PCR      commande CMD0
  LBSR  EXCMD0        execution commande CMD0
  BCS   RESET8        erreur d'initialisation

*------------------------------------------------------
* CMD8 = SEND INTERFACE CONDITION
* Non reconnue par les cartes SD de version < 2.00
* c'est pourquoi le code retour n'est pas teste.
* Lire les 4 derniers octets de la reponse R7
*------------------------------------------------------
  LBSR  EXCMD         execution commande 
  LDA   #$04          pour 4 fois 8 tops
  LBSR  CLOCK         envoi 4 fois 8 tops horloge 

*------------------------------------------------------
* CMD55 + ACMD41 = INITIALISATION
* Retry en cas de code retour different de zero
* Abandon apres 512 tentatives. 
*------------------------------------------------------
  LDY   #$0200        compteur pour 512 essais
RESET1
  LEAY  -1,Y          decrementation compteur
  BEQ   RESET8        erreur apres 512 essais
  LEAU  CMD55,PCR     adresse commande CMD55
  LBSR  EXCMD         execution commande CMD55
  LBSR  EXCMD         execution commande ACMD41
  BCS   RESET1        carte non prete, nouvel essai

*------------------------------------------------------
* CMD58 = LECTURE OCR
* Permet de determiner le type de carte SD ou SDHC
*------------------------------------------------------
RESET2
  LBSR  EXCMD         execution commande
  BCS   RESET8        erreur commande
  CLR   SD_TYP,PCR    carte SD par defaut 
  LDB   #$7F          initialisation de B pour lecture 
  LBSR  RBYTE2        lecture OCR poids fort
  ASLA                isole le type de carte 
  BPL   RESET3        carte SD   : SD_TYP=0
  INC   SD_TYP,PCR    carte SDHC : SD_TYP=1

*------------------------------------------------------
* RESET termine sans erreur
*------------------------------------------------------
RESET3      
  LDA   #$03          pour 3 octets        
  LBSR  CLOCK         lecture OCR (octets 2, 3, 4)
  BSR   DPINIT        retablissement valeur DP 
  CLRA                clear carry
  RTS                 retour sans erreur

*------------------------------------------------------
* RESET termine en erreur
*------------------------------------------------------
RESET8
  BSR   DPINIT        retablissement valeur DP 
  COMA                set carry
  RTS                 retour en erreur
  
*------------------------------------------------------
* SDSEL = selection d'un fichier .sd
* L'appel de SDSEL en BASIC necessite
* CLEAR,&H4FFF (MO) ou CLEAR,&H8FFF (TO)
*------------------------------------------------------
SDSEL
*  PSHS  U,Y,X,DP,B,A     empilage des registres
  BSR   DPINIT           initialiser DP
  LDA   #$55             signature disquette selectionnee
  CMPA  <SD_LBA+4        test signature
  BEQ   RMBR             intialisation inutile
  BSR   RESET            initialisation de la carte 
  BCC   RMBR             OK, lecture du MBR
*  PULS  A,B,DP,X,Y,U,PC  retour en erreur
  RTS                    retour en erreur
  
*------------------------------------------------------
* Lecture du Master Boot Record (1er secteur physique)
* $1FE-$1FF: $55AA (signature)
* Premier descripteur (pour la premiere partition)
* $1BE: boot indicator ($00=non, $80=oui) 
* Si boot indicator different, ce n'est pas un MBR
* $1C6-$1C7: LBA (poids faible en tete) 
*------------------------------------------------------
RMBR
  LDD   #$0000        raz registre D
  STD   <SD_LBA       LBA (2 premiers octets)
  STD   <SD_LBA+2     LBA (2 derniers octets)
  STD   >PSECT        raz secteur debut partition
  LDD   #BUF512       adresse du buffer
  STD   <DK_BUF       stockage adresse buffer
  LBSR  RS512         lecture du secteur de 512 octets
  LDD   #$55AA        Signature secteur
  CMPD  >BSIGN        Test signature
  LBNE  SDSEL8        Signature incorrecte
  LSL   >BBIND        Boot indicator 
  BNE   ABOOT1        Pas de MBR, donc boot record
  LDA   >BLBA1        LBA partition pds fort    
  LDB   >BLBA2        LBA partition pds faible  
  STD   >PSECT        stockage secteur debut partition
  
*------------------------------------------------------
* Lecture du Boot Record
* Premier secteur au debut de la partition
* Registre D = numero secteur de debut de partition
*------------------------------------------------------
RBOOT
  STD   <SD_LBA+2     stockage pour CMD17 si carte SDHC
  TST   <SD_TYP       test du type de carte
  BNE   RBOOT1        carte SDHC, sinon calcul pour SD
  ASLB                multiplie par 2 (poids faible)  
  ROLA                multiplie par 2 (poids fort)
  STD   <SD_LBA+1     adresse = numero secteur * $200  
  CLRB                raz registre A
  STB   <SD_LBA+3     raz dernier octet adresse
RBOOT1 
  LBSR  RS512         lecture du secteur de 512 octets

*------------------------------------------------------
* Analyse du Boot Sector
* $1FE-$1FF: $55AA (signature)
* $00B-$00C: nombre d'octets par secteur (512)
* $00D: nombre de secteurs par cluster
* $00E-$00F: nombre de secteurs reserves
* $010: nombre de FATs
* $011-$012: nombre entrees directory (FAT16 seulement)
* $016-$017: nombre secteurs FAT (FAT16 seulement)
* $024-$027: nombre secteurs FAT (FAT32 seulement)
* $02C-$02D: numero cluster directory (FAT32)
* Attention: le debut des donnees commence au cluster 2
* - En FAT16: apres la directory
* - En FAT32: apres les FATs
* Pour faciliter les calculs, on retranche 2 fois le
* nombre de secteurs par cluster au debut des donnees.
* 
* Calcul du secteur physique du repertoire principal
* = numero du secteur de debut de partition
* + nombre de secteurs reserves
* + nombre de secteurs FAT * nombre de FAT
*
* Calcul du secteur physique du cluster zero
* = numero du secteur du debut du repertoire principal
* + nombre d'entrees repertoire / 16 (0 en FAT32)
* - nombre de secteurs par cluster * 2
*
*------------------------------------------------------
ABOOT
  LDD   #$55AA        Signature secteur
  CMPD  >BSIGN        Test signature
  LBNE  SDSEL8        Signature incorrecte
ABOOT1
  CLRA                
  LDB   >BNSEC        Nombre de secteurs par cluster
  STD   >CSIZ2        Stockage nbre secteurs par cluster
  LDA   >BRES1        Blocs reserves pds fort   ex: $00
  LDB   >BRES2        Blocs reserves pds faible ex: $04
  STD   >RSECT        stockage nbre secteurs reserves
* taille FAT (en FAT16) dans D  
  LDA   >BFATS1       Fat16 size pds fort       ex: $00
  LDB   >BFATS2       Fat16 size pds faible     ex: $F2
  STD   >BFATS2       stockage taille FAT16
  BNE   ABOOT2        FAT16 si different de zero  
* taille FAT (en FAT32) dans D  
* 2 octets poids fort ignores (simplification abusive ?)
  LDA   >BFATS3       Fat32 size pds fort       ex: $03
  LDB   >BFATS4       Fat32 size pds faible     ex: $AB
* taille totale fonction du nombre de FATs
ABOOT2
  DEC   >BNFAT        Nombre de FAT             ex: $02
  BEQ   ABOOT3        Une seule FAT
  ASLB                FAT size multiplie par 2  ex: $E4 
  ROLA                FAT size multiplie par 2  ex: $01
* Le registre D contient le nombre de secteurs des FATs
ABOOT3   
  ADDD  >RSECT        ajout nombre de secteurs reserves
  ADDD  >PSECT        ajout secteur de debut de partition
  STD   >DSECT        stockage secteur debut directory
  LDA   >BNDIR1       nbre entrees directory (poids fort)
  LDB   >BNDIR2       nbre entrees directory (poids faible)
  LSRA                division par 16
  RORB                pour obtenir
  LSRA                le nombre de secteurs
  RORB                de la directory
  LSRA                En FAT32 le nombre d'entrees  
  RORB                de la directory est nul
  LSRA                Le debut des donnees (cluster 2)
  RORB                commence apres les FATs 
  ADDD  >DSECT        ajout secteur debut directory
  SUBD  >CSIZ2        retrancher le nbre secteurs/cluster 
  SUBD  >CSIZ2        retrancher le nbre secteurs/cluster 
  STD   >FSECT        stockage numero secteur du cluster 0
  LDD   >DSECT        secteur de debut de directory

*------------------------------------------------------
* LECTURE DE LA DIRECTORY
* D contient le numero du secteur a lire
*------------------------------------------------------
RDSECT
  STD   <SD_LBA+2     stockage pour la commande 17
  TST   <SD_TYP       type de carte 0=SD 1=SDHC
  BNE   RDSEC1        carte SDHC
  ASLB                LBA multiplie par 2 
  ROLA                LBA multiplie par 2
  STD   <SD_LBA+1     LBA multiplie par $100
  CLRB
  STB   <SD_LBA+3     octet de poids faible a zero
RDSEC1
  LBSR  RS512         Lecture du secteur 
  LDX   #BUF512       Adresse du buffer

*------------------------------------------------------
* RECHERCHE FICHIER SDDRIVE.SEL DANS LA DIRECTORY
* Le registre X pointe sur l'entree en cours 
*------------------------------------------------------
RDIR1  
  CLRB                zero
  CMPB  ,X            Test premier octet
  LBEQ  SDSEL8        Fin de repertoire
  LEAY  FNAME,PCR     pointeur nom de fichier
  CLRA                pointeur dans le nom
RDIR2
  LDB   A,Y           caractere du nom de fichier
  CMPB  A,X           test du caractere
  BNE   RDIR3         difference de nom
  INCA                numero du caractere suivant
  CMPA  #$0B          test fin du nom de fichier
  BEQ   FSEL          le nom est identique
  BRA   RDIR2         test caractere suivant
FNAME
  FCC   "SDDRIVE SEL" nom du programme de selection  
RDIR3
  LEAX  32,X          Adresse entree suivante
  CMPX  #BUFEND       Fin du buffer
  BNE   RDIR1         Traitement entree suivante
* lecture secteur suivant
  LDD   >DSECT        secteur debut directory 
  ADDD  #$0001        secteur suivant  
  STD   >DSECT        nouveau debut directory 
  BRA   RDSECT        lecture secteur directory

*------------------------------------------------------
* INITIALISATION DU LBA DU FICHIER SDDRIVE.SEL
* CSIZE = nombre de secteurs par cluster (1 octet)
* FSECT = numero de secteur du cluster 0 (2 octets)
* 26,X = n° cluster relatif au boot sector (poids faible)
* 27,X = n° cluster relatif au boot sector (poids fort)
* LBA0      =    XX YY
* N*CLUSTER = UU VV 00 (UU VV = N*A)
*           + 00 ZZ TT (ZZ TT = N*B)
* LBA       = (UU+carry2) (VV+XX+ZZ+carry1) (TT+YY)
*                     /|\    |          /|\    |
*                      |_____|           |_____|
* (adaptation du code original de Samuel Devulder)
*------------------------------------------------------
FSEL  
  LDD   >FSECT     ; secteur origine
  STD   <SD_LBA+2  ; stockage secteur origine
  LDA   27,X       ; Cluster poids fort
  LDB   >CSIZE     ; Nombre de secteurs par cluster
  MUL              ; D = msb(CLUSTER)*N = UU VV
  ADDB  <SD_LBA+2  ; octet de poids fort du secteur origine 
  ADCA  #0         ; D = UU (VV+XX). Nota: Si SD_LBA+1 contient déjà 0, ADDD SD_LBA+1 suffit.
  STD   <SD_LBA+1  ; sauvé en SD_LBA+1
  LDA   26,X       ; Cluster poids faible
  LDB   >CSIZE     ; Nombre de secteurs par cluster
  MUL              ; D = lsb(CLUSTER)*N = ZZ TT
  ADDD  <SD_LBA+2  ; D = (VV+XX+ZZ+carry1) (TT+YY)
  STD   <SD_LBA+2  ; (VV+XX+ZZ+carry1) (TT+YY) placé en LBA+2
  LDB   <SD_LBA+1  ; B=UU
  ADCB  #0         ; B=UU+carry2
  CLRA             ; A=0
  STD   <SD_LBA    ; SD_LBA = 00 (UU+carry2) (VV+XX+ZZ+carry1) (TT+YY)
  TST   <SD_TYP
  BNE   FLOAD      ; ben oui  tout est déjà fait pour les cartes SDHC
* recopie + decalage pour carte SD
  STB   ,-S        ; sauvegarde UU+carry2
  LDD   <SD_LBA+2  ; D=(VV+XX+ZZ+carry1) (TT+YY)
  LSLB
  ROLA             ; D*2
  STD   <SD_LBA+1  ; sauvé en SD_LBA+1
  LDB   ,S+        ; UU+carry2
  ROLB             ; (UU+carry2)*2 + "carry de D*2"
  STB   <SD_LBA    ; sauvé en SD_LBA
  CLR   <SD_LBA+3  ; 0 au bon endroit

*------------------------------------------------------
* CHARGEMENT ET EXECUTION DU FICHIER SDDRIVE.SEL
*------------------------------------------------------
FLOAD
  LDD   #$9000        adresse du buffer
FLOAD1  
  STD   <DK_BUF       stockage adresse buffer
  PSHS  B,A           empilage registre D
  LBSR  RS512         lecture du secteur de 512 octets
  BSR   NEXTS         calcul LBA du secteur suivant
  PULS  B,A           depilage registre D
  ADDD  #$0200        adresse du buffer suivant
  CMPD  #$9800        test de fin
  BNE   FLOAD1        secteur suivant
* execution 
  JSR   $9000         lancement programme SDDRIVE.SEL 
  LDA   #$55          signature disquette selectionnee
  STA   <SD_LBA+4     stockage de la signature
  BRA   SDSEL9        retour OK
SDSEL8
  COMA                retour en erreur carry=1  
SDSEL9
  RTS                 retour

*------------------------------------------------------
* CALCUL LBA DU SECTEUR SUIVANT
*------------------------------------------------------
NEXTS
  TST   <SD_TYP       type de carte 0=SD 1=SDHC
  BNE   NEXTS1        carte SDHC
  LDD   <SD_LBA+1     n° de secteur multiplie par 2
  ADDD  #$0002        secteur suivant
  STD   <SD_LBA+1     n° de secteur multiplie par 2
  BRA   NEXTS9        retour
NEXTS1
  LDD   <SD_LBA+2     n° de secteur
  ADDD  #$0001        secteur suivant
  STD   <SD_LBA+2     n° de secteur
NEXTS9
  RTS 

*------------------------------------------------------
* ATTENTE D'UN OCTET AVEC BIT 7 A ZERO (SDDRIVE)
* Le registre B n'est pas préservé
* Valeur de l'octet dans le registre A en sortie
*------------------------------------------------------
RBYTE0
  LDX   #$0100        compteur pour 256 boucles 
  LDB   #$7F          initialiser B pour lecture
RBYTE1
  LEAX  -1,X          decrementation compteur
  BEQ   RBYTE2        pas de bit 0 trouve
  CMPB  <$BF          lecture d'un bit dans carry
  BCS   RBYTE1        si bit 1, continuer a lire
  CLRA                sinon mettre zero dans A
  BRA   RBYTE3        lire les 7 autres bits
RBYTE2
  CMPB  <$BF          lecture bit 7              (4)
  ROLA                pousser dans A             (2)
RBYTE3
  CMPB  <$BF          lecture bit 6              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 5              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 4              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 3              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 2              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 1              (4)
  ROLA                pousser dans A             (2)
  CMPB  <$BF          lecture bit 0              (4)
  ROLA                pousser dans A             (2)
  RTS                 retour octet dans A        (5)

*------------------------------------------------------
* ATTENTE CARTE PRETE AVANT EXECUTION D'UNE COMMANDE
* Appel necessaire pour toutes les commandes sauf CMD0
* Lors de l'envoi de CMD0 la carte n'est pas encore
* prete, il faut appeler directement EXCMD0
*------------------------------------------------------
EXCMD
  LDB   #$7F          initialisation de B pour lecture 
  BSR   RBYTE2        lecture d'un octet dans A
  INCA                ajout de 1 ($FF --> $00) 
  BNE   EXCMD         attente carte prete

*------------------------------------------------------
* EXECUTION D'UNE COMMANDE
* Le registre U pointe sur les 6 octets de la commande
* Le registre B n'est pas preserve.
* le code retour est dans le registre A
*------------------------------------------------------
EXCMD0
  LDB   #$06          nombre d'octets de commande
EXCMD2
  LDA   ,U+           chargement octet de commande
  WRITE_BYTE          ecriture de l'octet
  DECB                decrementation compteur
  BNE   EXCMD2        il reste des octets a envoyer
EXCMD3
  BSR   RBYTE0        lecture d'un octet aligne  
  CMPA  ,U+           test code de retour
  BEQ   EXCMD4        code bon
  COMB                carry set en erreur
EXCMD4
  RTS                 retour
  
*------------------------------------------------------
* Lancement de la commande CMD17
* et attente d'un debut de secteur
*------------------------------------------------------
LCMD17
  LDA   #$51       code CMD17
  STA   <SD_CMD    initialise le code commande  
  LDY   <DK_BUF    adresse du buffer
  LBSR  SDCONF     configuration pour acces carte SD 
  LEAU  SD_CMD,PCR adresse CMD17
  BSR   EXCMD      execution CMD17 
LCMD18
  LDB   #$7F       initialisation de B pour lecture 
  BSR   RBYTE2     lecture d'un octet dans A
  CMPA  #$FE       comparaison avec $FE
  BNE   LCMD18     attente debut secteur
  RTS              retour
  
*------------------------------------------------------
* Lecture d'un secteur de 256 octets
* LBA fonction de: unite, piste, secteur, type carte
* Adresse du buffer dans DK_BUF
* Ecriture du buffer indexee par le registre Y
*------------------------------------------------------
RS256
  LBSR  SETLBA     calcul SD_LBA
  BCS   RS259      erreur unite/piste/secteur 
  BSR   LCMD17     lancement de la commande CMD17
  BCS   RS259      erreur execcution CMD17 
  CLRA             compteur pour 256 boucles 
  PSHS  A          empilage du compteur
  LDB   #$7F       initialisation B pour lecture
* lire 256 octets
RS257
  READ_BYTE        lecture d'un octet
  STA   ,Y+        stockage dans le buffer
  DEC   ,S         decrementation compteur 
  BNE   RS257      nouvelle lecture
  PULS  A          depilage compteur 
* ignorer 256 octets
  BSR  CLOCK       envoi de 256 * 8 tops
* ignorer 2 octets de CRC
  LDA   #$02       pour 2 octets
  BSR   CLOCK      ignorer 2 octets
* retour
  LBSR  DPINIT     retablissement valeur DP
  CLRA             clear Carry
RS259
  RTS              retour 
  
*------------------------------------------------------
* Lecture d'un secteur de 512 octets
* LBA pre-initialise dans CMDXX
* Adresse du buffer dans DK_BUF
* Ecriture du buffer indexee par le registre Y
*------------------------------------------------------
RS512
  LBSR  DPINIT     initialisation DP $20 ou $60
  BSR   LCMD17     lancement de la commande CMD17
  CLRA             compteur pour 256 boucles 
  PSHS  A          empilage du compteur
  LDB   #$7F       initialisation B pour lecture
* lire 256 octets
RS513
  READ_BYTE        lecture d'un octet
  STA   ,Y+        stockage dans le buffer
  DEC   ,S         decrementation compteur 
  BNE   RS513      nouvelle lecture
* lire 256 octets
RS514
  READ_BYTE        lecture d'un octet
  STA   ,Y+        stockage dans le buffer
  DEC   ,S         decrementation compteur 
  BNE   RS514      nouvelle lecture
  PULS  A          depilage compteur 
* ignorer 2 octets de CRC
  LDA   #$02       pour 2 octets
  BSR   CLOCK      ignorer 2 octets CRC
* retour
  LBSR  DPINIT     retablissement valeur DP
  CLRA             clear Carry
  RTS

*------------------------------------------------------
* ENVOI DE 8*A TOPS D'HORLOGE
* Le registre B est preserve. Au retour A=0
*------------------------------------------------------
CLOCK
  CMPB  <$BF          envoi d'un top d'horloge
  CMPB  <$BF          envoi d'un top d'horloge
  CMPB  <$BF          envoi d'un top d'horloge
  CMPB  <$BF          envoi d'un top d'horloge
  CMPB  <$BF          envoi d'un top d'horloge
  CMPB  <$BF          envoi d'un top d'horloge
  CMPB  <$BF          envoi d'un top d'horloge
  CMPB  <$BF          envoi d'un top d'horloge
  DECA
  BNE   CLOCK                            
  RTS                                      

*------------------------------------------------------
* Calcul du LBA carte SD : SD_LBA =
* SD_LBA0+(512-511*SD_TYP)*(1280*DK_DRV+16*DK_TRK+DK_SEC-1)
* DK_DRV  n° lecteur de disquette
* DK_TRK  n° piste (2 octets)
* DK_SEC  n° secteur
* SD_TYP  type SD/SDHC
* (adaptation du code original de Samuel Devulder)
*------------------------------------------------------
SETLBA
  PSHS  U,X,B,A       empilage des registres utilise
  LEAU  SD_LBA,PCR    U=adresse du LBA
  LDB   <DK_TRK+1     numero de piste
  BMI   SETLB8        erreur secteur
  CMPB  #$50          test piste 80
  BHS   SETLB8        erreur secteur
  LDA   #16           nombre de secteurs par piste 
  MUL                 multiplie par numero de piste
  TFR   D,X           X=DK_TRK*16
  LDB   <DK_SEC       numero du secteur
  BEQ   SETLB8        erreur secteur=0
  CMPB  #$10          test secteur 16
  BHI   SETLB8        erreur secteur>16
  DECB                ramene intervalle [0-15]  
  ABX                 X=DK_TRK*16+DK_SEC-1
  CLRA                A=0
  CLRB                B=0
  STD  ,U             LBA(poids fort) initialise a zero
  LDA  <DK_DRV        A=numero d'unite
  CMPA  #$04          test unite 4
  BHS   SETLB7        erreur unite>=4 
  LSLA                multiplie par 2 
  LSLA                multiplie par 2
  ADDA <DK_DRV        ajoute l'unite (5*256=1280)
  LEAX D,X            X=1280*DK_DRV+16*DK_TRK+DK_SEC-1
  TFR  X,D            valeur dans D
* multiplication par 512-511*SD_TYP
  LEAX 4,U            type de carte
  TST  <SD_TYP        test type de carte
  BNE  SETLB2         carte SDHC
  LSLB                pour carte SD il faut multiplier
  ROLA                le numero de secteur par deux
  CLR  ,-X            raz octet de poids faible du LBA
SETLB2
  STD  -2,X           SD_LBA = 0 XX XX 0 ou 0 0 XX XX
* addition SD_LBA = SD_LBA + SD_LB0 sur 32bits
  LDD  <SD_LB0+2
  ADDD 2,U      
  STD  2,U
  LDD  <SD_LB0
  ADCB 1,U
  ADCA #0             en vrai ",u" mais c'est équivalent car on a toujours 0 à cette adresse
  STD  ,U
  CLRA                raz bit carry
  BRA   SETLB9        retour sans erreur
SETLB7  
  LBSR  ERR10         erreur unite  
  BRA   SETLB9
SETLB8  
  LBSR  ERR04         erreur de secteur  
SETLB9
  PULS  A,B,X,U,PC    retour
    
*------------------------------------------------------
* Ecriture d'un secteur disquette
* dans secteur SD complete a 512
*------------------------------------------------------
SWRITE
  BSR  SETLBA      calcul SD_LBA
  LBCS  SWRIT9     erreur unite/piste/secteur
  LDA   #$58       code CMD24
  STA   <SD_CMD    initialise code commande  
  LDY   <DK_BUF    adresse du buffer
  LBSR  SDCONF     configuration pour acces carte SD 
  LEAU  SD_CMD,PCR adresse CMD24
  LBSR  EXCMD      execution CMD24 
  LDA   #$FE       indicateur debut bloc 
  WRITE_BYTE       ecriture de l'octet
  CLRA             compteur pour 256 boucles 
  PSHS  A          empilage du compteur octets
* ecrire 256 octets du buffer
SWRIT2
  LDA   ,Y+        lecture dans le buffer
  WRITE_BYTE       ecriture d'un octet 
  DEC   ,S         decrementation compteur octets
  BNE   SWRIT2     nouvelle ecriture
  PULS  A          depilage compteur octets 
* ecrire 256 octets $FF
  LBSR  CLOCK      envoyer 256 tops d'horloge
* ecrire 2 octets de CRC $FF
  LDA   #$02       pour 2 octets
  LBSR  CLOCK      envoi 2 fois 8 tops horloge
  LBSR  DPINIT     retablissement valeur DP 
  CLRA             clear Carry
SWRIT9
  RTS   

*------------------------------------------------------
* Retour d'un code erreur
*------------------------------------------------------
ERRSET
  STA   <DK_STA
  COMA  
  RTS   

*------------------------------------------------------
* Erreur de secteur
*------------------------------------------------------
ERR04
  LDA   #$04
  BRA   ERRSET

*------------------------------------------------------
* Erreur unite
*------------------------------------------------------
ERR10
  LDA   #$10
  BRA   ERRSET

*------------------------------------------------------
* Recherche piste
* Recherche piste 0
*------------------------------------------------------
FINDT
FIND0
  CLRA             clear CC
  RTS              retour

*------------------------------------------------------
* DKFMT = formatage de la disquette
*------------------------------------------------------
DKFMT
  PSHS  U,Y,X,DP,B,A,CC              
  ORCC  #$50       desactive les interruptions 
  LBSR  DPINIT     initialisation DP $20 ou $60
  CLR   <DK_TRK            
  CLR   <DK_TRK+1  piste 0     
  LBSR  FMTRK      formatage piste 0 
  LBSR  INIT20     initialisation piste 20 
  PULS  CC,A,B,DP,X,Y,U,PC
  
*------------------------------------------------------
* Formatage d'une piste
*------------------------------------------------------
FMTRK
  LDA   #$E5       caractere de remplissage
  BSR   INIBUF     remplissage buffer
  LDA   #$01       numero premier secteur
  STA   <DK_SEC    stockage numero secteur         
FMTRK1
  LBSR  SWRITE     ecriture d'un secteur
  LDA   <DK_SEC    numero de secteur
  CMPA  #$10       secteur 16
  BEQ   FMTRK9     fin de piste
  INCA             incrementation secteur
  STA   <DK_SEC    stockage numero secteur
  BRA   FMTRK1     secteur suivant
FMTRK9
  RTS              retour
  
*------------------------------------------------------
* Remplissage du buffer de secteur
*------------------------------------------------------
INIBUF
  LDY   <DK_BUF    initialisation adresse
  CLRB             nombre octets secteur
INIB1
  STA   ,Y+        stockage octet remplissage
  DECB             decrementation compteur
  BNE   INIB1      octet suivant 
  RTS              retour
  
*------------------------------------------------------
* Initialisation piste 20
*------------------------------------------------------
INIT20
  LDX   #$0014     piste 20 
  STX   <DK_TRK
  LDA   #$FF       valeur de remplissage
  BSR   INIBUF     remplissage buffer
  LDA   #$08
  ORA   <DK_OPC
  STA   <DK_OPC
  CLRB             initialisation n° secteur
INIT21
  INCB             secteur suivant
  STB   <DK_SEC
  LBSR  DKCONT     ecriture du secteur
  BLO   INIT29
  CMPB  #$10       secteur 16
  BNE   INIT21
  LDX   <DK_BUF
  CLR   ,X         premier octet FAT = 0
  LDD   #$FEFE     blocs reserves
  STD   $29,X      pour piste 20
  LDA   #$02
  STA   <DK_SEC
  LBSR  DKCONT     ecriture du secteur
  BLO   INIT29     retour en erreur
  CLRA             pas d'erreur
INIT29
  RTS   

*------------------------------------------------------
* SCRATCH DOS
*------------------------------------------------------
SCRDOS
  FCC   "SCRATCH"
  FCC   " DOS"

*------------------------------------------------------
* FINTR = cloture d'ecriture
*------------------------------------------------------
FINTR
  LDB   <DKWF0     code operation logique   
  CMPB  #$02
  BEQ   FINTR3 
  DEC   <DKWF0     code operation logique
  BSR   RECFI      ouverture fichier
  BLO   FINTR9
  TSTB  
  BEQ   FINTR1
  LBSR  RECUP
  BLO   FINTR9
FINTR1
  INC   <DKWF0     code operation logique
  BSR   RECFI
  BLO   FINTR9
  LDB   #$0a
  LDX   <DKWE7
FINTR2
  LDA   B,X
  STA   B,Y
  DECB  
  BGE   FINTR2
  BSR   ECRSE      ecriture secteur
  BLO   FINTR9
****************** sauvegarde de la FAT
FINTR3
  LDA   #$02
  STA   <DK_SEC    secteur 2
  LDB   #$14
  CLRA  
  STD   <DK_TRK    piste 20
  LDD   <DKWED     adresse de la FAT
  STD   <DK_BUF    adresse du buffer secteur
  BSR   ECRSE      ecriture secteur
  BLO   FINTR9     erreur ecriture
  CLR   <$f0       indicateur cloture fichier
FINTR9
  RTS   

*------------------------------------------------------
* LECFA = Lecture de la FAT
*------------------------------------------------------
LECFA
  LDX   <DKWED     adresse de la FAT
  STX   <DK_BUF    adresse du buffer secteur
  LDA   #$02       numero secteur a lire
  BRA   LSEC20     lecture secteur piste 20

*------------------------------------------------------
* Sortie en erreur
*------------------------------------------------------
RETERR
  STA   <DKWE5
  COMA  
  COMA  
  RTS   

*------------------------------------------------------
* Chargement 1er secteur catalogue
*------------------------------------------------------
LDIR0
  LDA   #$03
  LDX   <DKWE9     pointeur sur buffer
  STX   <DK_BUF

*------------------------------------------------------
* Chargement secteur piste 20
*------------------------------------------------------
LSEC20
  STA   <DK_SEC
  LDB   #$14
  CLRA  
  STD   <DK_TRK
  LDA   #$02
  BRA   SECTIO

*------------------------------------------------------
* ECRSE = Ecriture d'un secteur
*------------------------------------------------------
ECRSE
  LDA   #$08

*------------------------------------------------------
* Operation sur secteur
*------------------------------------------------------
SECTIO
  STA   <DK_OPC
  LDY   <DKWE9     pointeur sur buffer
  LBSR  OPTABL
  LDA   #$03
  RTS   

*------------------------------------------------------
* RECFI = Ouverture d'un fichier
*------------------------------------------------------
RECFI
  BSR   LDIR0      charge 1er secteur catalogue 
RECFI1
  BLO   RETERR     sort si erreur
  LDX   #$0008     compteur de noms dans X
  LDY   <DKWE9     pointeur sur buffer
RECFI2
  LDU   <DKWE7
  LDB   <DKWF0     code operation logique
  CMPB  #$03
  BNE   RECFI3
  LEAU  SCRDOS,PCR adresse du nom de fichier
RECFI3
  CLRB  
RECFI4
  CMPB  #$0b
  BHS   RECFI8
  LDA   B,Y
  CMPA  #$ff
  BEQ   RECFI7
  INCB  
  CMPA  ,U+
  BEQ   RECFI4
  LEAY  $20,Y
  LEAX  -$01,X
  BNE   RECFI2
  INC   <DK_SEC
  LDA   <DK_SEC
  CMPA  #$10
  BHI   RECFI7
  LBSR  OPTABL
  LDA   #$03          erreur I/O
  BRA   RECFI1
RECFI7
  CLRB  
  BRA   RECFI9
RECFI8
  LDB   $0b,Y
  CMPB  <DKWEB
  BNE   RECFI7
  LDB   $0c,Y
  CMPB  <DKWEC
  BNE   RECFI7
  LDB   <DK_SEC
  LDA   $0d,Y
  STA   <DKWF6
  CLR   <DKWF5
  LDX   $0e,Y
  STX   <DKWF7
  STY   <DKWFA
RECFI9
  STB   <DKWF9     numero de bloc alloue
  CLRA
  RTS

*------------------------------------------------------
* ALLOD = allocation d'un fichier
*------------------------------------------------------
ALLOD
  LDY   <DKWED     adresse de la FAT
  BSR   ALLOB4     test place libre
ALLOD1
  BLO   RECFI1     erreur plus de place
  STB   <DKWF6     numero de bloc
  LBSR  LDIR0      charge debut directory
ALLOD2  
  BLO   ALLOD1     sortie en erreur
  LDY   <DKWE9     pointeur sur buffer
  LDX   #$0008     compteur de noms dans X
ALLOD3
  LDB   ,Y         premier octet du nom 
  BEQ   ALLOD6     0=fichier efface
  LDA   #$05
  CMPB  #$ff
  BEQ   ALLOD6
  LEAY  $20,Y
  LEAX  -$01,X
  BNE   ALLOD3
  INC   <DK_SEC
  LDA   <DK_SEC
  CMPA  #$10
  BHI   ALLOD4
  LBSR  OPTABL     charge le secteur suivant 
  LDA   #$03
  BRA   ALLOD2
ALLOD4
  LDA   #$05       code "disque plein"
ALLOD5
  BRA   ALLOD1     sort avec erreur
ALLOD6
  LDX   <DKWE7
  LDB   <DKWF0     code operation logique
  CMPB  #$03
  BNE   ALLOD7
  LEAX  SCRDOS,PCR adresse nom de fichier
ALLOD7
  LDB   #$0a
ALLOD8
  LDA   B,X        recopie le nom de fichier
  STA   B,Y        dans le catalogue
  DECB  
  BGE   ALLOD8
  LDA   <DKWEB     type de fichier 
  STA   $0b,Y
  LDA   <DKWEC     recopie le numero de bloc
  LDB   <DKWF6     dans le catalogue
  STD   $0c,Y
  LBRA  ECRSE      ecriture du repertoire

*------------------------------------------------------
* ALLOB = allocation d'un bloc
*------------------------------------------------------
ALLOB
  LDB   <DKWF6     numero de bloc
  CMPB  #$50
  BHI   ALLOB3
ALLOB1
  TSTB  
ALLOB2
  BEQ   ALLOB4
  LDA   B,Y
  CMPA  #$ff
  BEQ   ALLOB8
  DECB  
  CMPB  #$50
  BLS   ALLOB1
ALLOB3
  ADDB  #$02
  CMPB  #$A1
  BRA   ALLOB2
ALLOB4
  LDB   #$50  
ALLOB5
  LDA   #$05
  CMPB  #$A0
  LBHI  RETERR
  LDA   B,Y
  CMPA  #$ff
  BEQ   ALLOB8
  PSHS  B
  SUBB  #$50
  NEGB  
  ADDB  #$50
  LDA   B,Y
  CMPA  #$ff
  BEQ   ALLOB6
  PULS  B  
  INCB  
  BRA   ALLOB5
ALLOB6
  LEAS  $01,S 
ALLOB8
  CLR   B,Y
  DECB  
  STB   <DKWF9     numero de bloc alloue
ALLOB9
  CLRA
  RTS

*------------------------------------------------------
* RECUP = liberation d'un bloc
*------------------------------------------------------
RECUP
  LDA   $0d,Y
  STA   <DKWF6     numero de bloc
  CLR   ,Y
  LBSR  ECRSE
  BLO   ALLOD5
  LDY   <DKWED
  LDB   <DKWF6     numero de bloc
RECUP1
  INCB  
  LDA   B,Y
  CLR   B,Y
  DEC   B,Y
  TFR   A,B
  CMPA  #$c0
  BLO   RECUP1
  BRA   ALLOB9

*------------------------------------------------------
* MAJCL = Mise a jour cluster
*------------------------------------------------------
MAJCL
  LDB   <DKWF6       numero bloc                              
  CLRA  
  LSRB               divise par 2
  STD   <DKWFB       numero piste
  INCA  
  STA   <DKWF5
  BHS   MAJCL9 
  LDA   #$09   
MAJCL9
  STA   <DKWFA 
  RTS   

*------------------------------------------------------
* COMMANDES CARTE SD
*------------------------------------------------------
CMD0
  FCB   $40           go iddle state
  FDB   $0000
  FDB   $0000
  FCB   $95           checksum obligatoire           
  FCB   $01           code retour attendu  
*------------------------------------------------------
CMD8
  FCB   $48           send interface condition
  FDB   $0000
  FDB   $01AA
  FCB   $87           checksum obligatoire  
  FCB   $00           code retour attendu  
*------------------------------------------------------
CMD55
  FCB   $77           application command
  FDB   $0000
  FDB   $0000
  FCB   $FF           checksum non testee  
  FCB   $00           code retour attendu  
*------------------------------------------------------
AC41
  FCB   $69           activate card initialization 
  FDB   $4000
  FDB   $0000 
  FCB   $FF           checksum non testee  
  FCB   $00           code retour attendu  
*------------------------------------------------------
CMD58
  FCB   $7A           read OCR
  FDB   $0000
  FDB   $0000
  FCB   $FF           checksum non testee
  FCB   $00           code retour attendu  
*------------------------------------------------------
 
*------------------------------------------------------
* Signature SDDRIVE
*------------------------------------------------------
  ORG   $E6FF
  FCB   $DC           signature DC  
 
*------------------------------------------------------
* Commentaires
*------------------------------------------------------
  FCC   'SDDRIVE         '
  FCC   'Controleur de ca'
  FCC   'rte SD pour les '
  FCC   'ordinateurs Thom'
  FCC   'son TO et MO - S'
  FCC   'imule quatre uni'
  FCC   'tes de disquette'
  FCC   's 3"1/2 double d'
  FCC   'ensite.         '
  FCC   '                '
  FCC   '                '
  FCC   '                '
  FCC   '================'
  FCC   'Daniel Coulom   '
  FCC   'dcmoto.free.fr  '
  FCC   'Vers. 2018.01.01'
 
  END
Daniel
L'obstacle augmente mon ardeur.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Le circuit imprimé est commandé :

sddrive_pcb_top.png
sddrive_pcb_top.png (35.23 Kio) Consulté 2704 fois

Une nouvelle page a été créée pour ce projet à la section Bricolage du site dcmoto : http://dcmoto.free.fr/bricolage/index.html
Daniel
L'obstacle augmente mon ardeur.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Le circuit imprimé est fabriqué et devrait être livré dans une semaine. La suite au prochain épisode...
Pièces jointes
elecrow-pcb.jpg
elecrow-pcb.jpg (49.4 Kio) Consulté 2650 fois
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: [Thomson] SDDRIVE

Message par Carl »

Daniel, SDDRIVE sait lire les fichiers LEP ?
Image1.jpg
Image1.jpg (266.6 Kio) Consulté 2639 fois
Carl
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SDDRIVE

Message par Daniel »

Carl est extraordinaire : il voit tout !

Malheureusement SDDRIVE ne sait rien faire d'un fichier .lep. Je ne sais pas pourquoi il est sur cette carte SD, c'est sûrement une erreur de ma part. SDDRIVE affiche tous les fichiers contenus dans le répertoire principal de la carte, il n'y a aucun filtre. Si un label a été donné à la carte SD, il apparaît aussi dans la liste, de même que le répertoire System Volume Information ajouté parfois par Windows 10. Mais SDDRIVE peut utiliser uniquement les fichiers au format sd (même s'ils n'ont pas l'extension .sd).

Il y a une seule exception : sddrive.sel est un fichier binaire contenant le programme de sélection de l'image de disquette. Au démarrage de l'ordinateur le contrôleur charge ce programme et l'exécute. C'est un peu le même principe que le lancement de la disquette boot.sd par le contrôleur CS91-280, sauf qu'avec SDDRIVE on charge seulement le programme de sélection pour gagner du temps. C'est presque instantané.

La bonne nouvelle du jour : petite modification d'une valeur de résistance de pull up du signal CLK, pour supprimer un cas d'instabilité. Quand la tension de l'ordinateur descendait au-dessous de 4,9V tout fonctionnait encore normalement, sauf SDDRIVE qui avait alors des erreurs aléatoires. En remplaçant une résistance de 1K par 560 ohms toutes les erreurs disparaissent, et la tension peut baisser jusqu'à 4,8 V sans inconvénient.

Et un truc de fou, qui explique les soucis que j'ai eu avec les TO8, alors que les TO8D fonctionnaient bien. Sur la carte mère du TO8 le vernis recouvre une petite partie du connecteur d'extension. Si on enfonce à fond le connecteur femelle HE901, il arrive que des contacts ne se fassent pas à cause du vernis. En ramenant le connecteur en arrière d'un millimètre tout est bon. Quand je pense à tout le temps perdu en vérifications pour trouver le problème (trois ou quatre jours), je maudis les ingénieurs qui ont dessiné le masque du circuit imprimé.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
Carl
Modérateur
Messages : 13253
Inscription : 08 avr. 2007 13:21
Localisation : http://www.doledujura.fr
Contact :

Re: [Thomson] SDDRIVE

Message par Carl »

Daniel,
j'ai passé pas mal de temps à utiliser les fichiers LEP et ton outil SDLEP pour les générer...si bien que pour moi, l'extension LEP ne passe plus inaperçu :roll:

ps : le jour ou tu proposeras des kits SDDRIVE, je pense que je me laisser tenter :wink:

Carl
Répondre