|
|
|
|
 |
Voici le source de la routine d'écriture de la zone d'entête, c'est à dire du champ adresse, en DOS 3.3, elle se trouve à l'adresse $BC56.
Rappelons briévement que ce champ adresse est écrit une fois pour toutes lors de l'initialisation (formattage)
de la disquette et qu'il permet de savoir quel est le n° de volume, le numéro de piste sur laquelle on est positionné,
et le n° de secteur que l'on va lire si l'on accède au champ de données qui suit. Voici le schéma déjà bien
connu maintenant
|
SYNC
WBYTE
WBYTE11 WBYTE9
WAIT12
|
SEC
LDA $C08D,X
LDA $C08E,X
BMI ERROR
LDA #$FF
STA $C08F,X
CMP $C08C,X
PHA
PLA
JSR WAIT12
JSR WAIT12
STA C08D,X
CMP C08C,X
NOP
DEY
BNE SYNC
LDA #$D5
JSR WBYTE9
LDA #$AA
JSR WBYTE9
LDA #$96
JSR WBYTE9
LDA VOLUME
JSR WBYTE
LDA TRACK
JSR WBYTE
LDA SECT
JSR WBYTE
LDA VOLUME
EOR TRACK
EOR SECT
PHA
LSR
ORA SECT
STA $C08D,X
LDA $C08C,X
PLA
ORA #$AA
JSR WBYTE11
LDA #$DE
JSR WBYTE9
LDA #$AA
JSR WBYTE9
LDA #$EB
JSR WBYTE9
CLC
LDA $C08E,X
LDA $C08C,X
RTS
PHA
LSR
ORA ZBUF
STA CO8D,X
CMP CO8C,X
PLA
NOP
NOP
NOP
ORA #$AA
NOP
NOP
PHA
PLA
STA CO8D,X
CMP CO8C,X
RTS
|
; prépare le cas d'erreur
; test WRITE PROTECT
; et initialise le LSS
; Erreur, disk protégé
; $FF valeur nibble syncro.
; (5 cycles)
; (4 cycles)
; (3 cycles)
; (4 cycles)
; (6 + 6 cycles)
; (6 + 6 cycles)
; (5 cycles)
; (4 cycles)
; (2 cycles)
; (2 cycles)
; (2 cycles / 3 cycles)
; (2 cycles)
; (6 cycles + 9 cycles)
; (2 cycles)
; (6 + 9 cycles)
; (2 cycles)
; (6 + 9 cycles)
; (3 cycles)
; (6 + 8 cycles)
; (3 cycles)
; (6 + 8 cycles)
; (3 cycles)
; (6 + 8 cycles)
; (3 cycles)
; (3 cycles)
; (3 cycles)
; (3 cycles)
; (2 cycles)
; (3 cycles)
; (5 cycles)
; (4 cycles)
; (4 cycles)
; (2 cycles)
; (6 + 11 cycles)
; (2 cycles)
; (6 + 9 cycles)
; (2 cycles)
; (6 + 9 cycles)
; (2 cycles)
; (6 + 9 cycles)
; (2 cycles)
; STOP
; 3 cycles
; 2 cycles
; 3 cycles
; 5 cycles
; 4 cycles
; 4 cycles
; 2 cycles
; 2 cycles
; 2 cycles
; 2 cycles
; 2 cycles R11
; 2 cycles R11 R9
; 3 cycles R11 R9
; 4 cycles R11 R9
; 5 cycles
; 4 cycles
; 6 cycles
|
Ici commence le timing pour l'écriture
du premier $FF en 40 cycles
pour timing pour timing pour timing pour timing. Jusqu'ici il y a les 40 cycles
A partir d'ici il y a la boucle d'écriture
des autres $FF en 40 cycles
pour timing
Si Boucle = 3 cycles car va sur SYNC
Ecriture dernier $FF (voir A plus bas)
Pour le $D5 voir B
Pour le $AA voir C
Pour le $96 voir D
Pour le N° de volume voir E
Pour le N° de piste voir F
Pour le N° de secteur voir G
Pour le checksum voir H
= $00 en fait
Enclenche l'écriture du 1er nibble de checksum
Pour $DE voir I
Pour $AA voir J
Pour $EB voir K
Pour sortir sans erreur ... un comble nous le verrons
Arrêt du mode écriture
Sauve la valeur à coder en 4.4
puis calcule la valeur du 1er NIBBLE du codage 4.4 Contient la valeur $00
<-- Enclenche l'écriture du 1er nibble codé 4.4
du n°volume, piste, secteur et checksum,
ET calcule la valeur de 2éme nibble en codage 4.4
pour timing pour timing pour timing calcul 4.4 pour timing pour timing PHA et PLA pour timing <-- et jusqu'ici il y a bien 32 cycles
Ces 15 cycles jusqu'au RTS inclus comptent pour le nibble suivant... qui vient juste
d'être calculé pour le 2éme nibble codé 4.4 quand on entre par WBYTE
|
REMARQUES GENERALES : |
Il faut bien comprendre que les instructions NOP, JSR, RTS et parfois PHA PLA marquées "pour timing"
n'ont réellement pas d'autre raison d'être QUE DE PERMETTRE A LA ROUTINE D'ECRITURE D'AVOIR LE NOMBRE
DE CYCLES MACHINES ADEQUAT ce qui permet au SEQUENCER d'écrire correctement les nibbles !
C'est en cela que les routines d'écriture sont dites avoir un timing critique.
Vous noterez que le décompte des 32 cycles est réalisé aussi bien entre deux $C08D,X que deux C08C,X.
|
A. ECRITURE DES $FF DE SYNCHRONISATION |
|
Le premier $FF écrit commence son décompte de cycles dès le STA $C08F,X qui enclenche l'écriture, on a donc
les cycles affichés en jaune dans le listing ci-dessus soit :
5 (STA) + 4 (CMP) + 3 (PHA) + 4 (PLA) + 6 (JSR) + 6 (RTS) + 6 (JSR) + 6 (RTS) = 40 cycles
Les $FF suivants sont écrits au sein d'une boucle qui commence au STA C08D,X (en magenta sur le listing)
jusque'au test de branchement BNE SYNC qui comptera pour 3 cycles car le branchement est bien effectué
sur SYNC et qui s'arrête au second JSR WAIT12 ce qui nous donne :
5 (STA) + 4 (CMP) + 2 (NOP) + 2 (DEY) + 3 (BNE) + 6 (JSR) + 6 (RTS) + 6 (JSR) + 6 (RTS) = 40 cycles
Ce dernier $FF est écrit en fin de boucle et commence donc son timing dès
l'intruction STA $C08D,X juste derrière le JSR WAIT12. Cela donne 5 + 4 + 2 + 2 + 2 pour le BNE car il N'Y A PAS
DE BRANCHEMENT... + 2 pour le LDA #$D5 + 6 pour le JSR + 9 pour la route WBYTE9 soit un total de :
5 + 4 + 2 + 2 + 2 + 2 + 6 + 9 = 32 cycles ! et non 40 ... mais cela n'a aucune importance car on est synchronisé
depuis bien longtemps (5 $FF maximum suffisent y compris le dernier en synchronisation)
|
B. ECRITURE DU $D5 |
| Certains débutants font parfois l'erreur de croire que le $D5 est écrit dès
le JSR du JSR WBYTE ce qui est FAUX car en fait cette valeur n'est passée au SEQUENCER qu'au milieu de cette routine
c'est à dire au moyen du STA C08D,X (c'est pour cela que le décompte WBYTE9 donne bien 9 cycles car ce STA et la suite comptent
pour l'écriture du nibble suivant...$D5 en ce qui nous concerne pour l'instant.
Nous avons donc 5 + 4 + 6 (le RTS de WBYTE9) qui nous amméne donc au LDA #$AA pour 2 cycles puis nous avons à nouveau un
JSR WBYTE9 ce qui donne 6 + les 9 de WBYTE9 soit un total de :
5 + 4 + 6 + 2 + 6 + 9 = 32 cycles... décidément c'est magique !
|
C. ECRITURE DU $AA |
| Tout comme pour le $D5, le $AA est écrit en décalé
par rapport aux LDA #$AA. Le décompte se fait de la même façon que pour le $D5 à savoir :
- la reprise de la fin de routine de WBYTE9 soit 5 + 4 + 6
- les 2 cycles du LDA
- les 6 du JSR WBYTE
- les 6 du JSR + les 9 de la routine WBYTE9
soit un total de : 5 + 4 + 6 + 2 + 6 + 9 = 32 cycles.
|
D. ECRITURE DU $96 |
| Tout comme pour le $D5 et $AA, le $96 est écrit en décalé
par rapport au LDA #$96. Le décompte se fait pour partie de la même façon que pour les précédents à savoir :
- la reprise de la fin de routine de WBYTE9 soit 5 + 4 + 6
- les 3 cycles du LDA VOLUME car il s'agit d'un chargement en page 0
- cette fois la sous routine n'est pas la même (WBYTE et non WBYTE9), on a + 6 pour le JSR et + 3 + 2 + 3
pour la partie de la sous routine concernée
soit un total de : 5 + 4 + 6 + 3 + 6 + 3 + 2 + 3 = 32 cycles tout de même...
Ce qui peut perturber dans cette partie c'est de voir l'accumulateur changer de valeur
en particulier avec l'instruction ORA de la sous-routine WBYTE. Maix cela montre en
fait très clairement que le programme 6502 est bien INDEPENDANT de ce que fait le
SEQUENCER après qu'il lui ait passé la valeur à écrire dans le DATA REGISTER. Ici
que constate-t-on ? Le $96 a été passé au DATA REGISTER des le STA C08D,X de
la sous-routine WBYTE9 précédente et à partir de ce moment le SEQUENCER écrit bien ce
$96 en 32 cycles pendant que le programme 6502 fait autre chose à savoir : CALCULE LA VALEUR
DU PREMIER NIBBLE DE CODAGE 4.4 DU NUMERO DE VOLUME...
|
E. ECRITURE DU NUMERO DE VOLUME |
| Nous venons de voir que la routine WBYTE
prépare le calcul du premier NIBBLE POUR LE CODAGE 4.4 du NUMERO DE VOLUME, arrivé
à ce stade celle-ci est passée au DATA REGISTER par l'instruction STA $C08D,C puis
le programme continue à calculer le SECOND NIBBLE en précisément 32 cycles qui sont
ajustés avec des instructions de remplissage pour le timing (NOP, PHA PLA) car ce
calcul est réalisé plus rapidement.
Cette seconde valeur est alors passée au DATA REGISTER par l'instruction STA C08D,X
juste avant l'instruction SHIFT et le RTS en de routine. Les trois dernières instructions
compteront alors pour 15 cycles pour le décompte des 32 cycles d'écriture du second nibble car à
ces 15 cycles viennent s'ajouter les 3 du LDA TRACK car TRACK est une adresse en page 0,
les 6 + 8 du JSR WBYTE ce qui fait :
15 + 3 + 6 + 8 soit bien 32 cycles.
|
F. ECRITURE DU NUMERO DE PISTE |
| Pour le premier nibble il est écrit en seconde partie de la routine
WBYTE. Et pour le second cela se passe exactement comme ci-dessus, on reprend les 15 cycles de la fin de routine
WBYTE auxquels on ajoute + 3 du LDA SECT + 6 + 8 du JSR WBYTE ce qui fait : 15 + 3 + 6 + 8 = 32 cycles
|
G. ECRITURE DU N° DE SECTEUR |
| Lègerement différent cette fois car si on reprend les 15 cycles
de la fin de WBYTE pour le 2éme nibble, par contre on ajoute cette fois
+ 3 (LDA) + 3 (EOR) + 3 (EOR) + 3 (PHA) + 2 (LSR) + 3 (ORA) ce qui donne au total :
15 + 3 + 3 + 3 + 3 + 2 + 3 = 32 cycles.
|
H. ECRITURE DU CHECKSUM |
| Le 1er nibble est écrit pendant le calcul du second
c'est-à dire au STA $C08D,X placé juste après le ORA SECT ce qui donne : 5 + 4 + 4 + 2 + 6 + 11 = 32 cycles.
Le second nibble de checksum sera écrit à partir de la fin de la routine WBYTE11 ce qui prend les fameux 15 cycles
bien connus maintenant auxquels s'ajoutent +2 (LDA #$DE) + 6 (JSR) + 9 (WBYTE9) soit : 15 + 2 + 6 + 9 = 32 cycles.
|
I. ECRITURE DU $DE |
| On revient toujours sur du classique, le $DE est passé
au SEQUENCER en fin de la routine WBYTE9 ce qui apporte les 15 cycles auxquels on ajoute + 2 (LDA #$AA)+ 6 (JSR)
+ 9 (WBYTE9) ce qui donne 15 + 2 + 6 + 9 = 32 cycles
|
J. ECRITURE DU $AA |
| Toujours pareil que ci-dessus, le $AA est passé
au SEQUENCER en fin de la routine WBYTE9 ce qui apporte les 15 cycles auxquels on ajoute + 2 (LDA #$EB)+ 6 (JSR)
+ 9 (WBYTE9) ce qui donne 15 + 2 + 6 + 9 = 32 cycles
|
K. ECRITURE DU $EB |
| Toujours pareil que ci-dessus, le $EB est passé
au SEQUENCER en fin de la routine WBYTE9 ce qui apporte les 15 cycles auxquels on ajoute + 2 cycles du CLC
qui permet de sortir de la routine sans erreur... ET L'ECRITURE S'ARRETE !!!!
Ce qui ne permet ABSOLUMENT PAS d'avoir un $EB écrit correctement!
Eh oui le DOS 3.3 n'écrit pas cet $EB du champ adresse... mais heureusement il ne le vérifie pas non plus.
Pourquoi ?
C'est un mystère car il y a pourtant un vide disponible de 33 octets derrière cette routine (de $BCDF à $BCFF)
donc on ne fait pas de saut de page et c'était largement suffisant pour faire propre. Si vous pensiez que
la RWTS du DOS 3.3 était un modéle parfait eh bien désolé de vous décevoir...
|
|
|
|