Dernière mise à jour: mardi 19/09/2006 (correction
KEY_ESC par KEY_TAB sur la page html et le .dsk).
Introduction
Dans le cadre de mon projet FASTDSK, je vais
devoir écrire une
routine permettant de sélectionner un répertoire sur une
unité ProDOS disponible (pour la sauvegarde des disks images
.dsk), sachant qu'il faut pouvoir naviguer
d'un volume ProDOS à un autre facilement. Alors que je
réfléchissais à la solution à mettre en
oeuvre, je me suis tout naturellement demandé s'il n'existait
pas déjà un programme répondant à ces
caractéristiques et qui serait bien écrit.
J'ai alors tout de suite pensé à la routine qu'appelle
ProDOS quand un appel est fait à MLI Quit.
Je ne parle bien sur pas de la vieille routine des premières
versions de ProDOS où il fallait taper manuellement les noms de
volume/chemin (prefix) et de programme (next application) qu'on l'on
voulait
lancer en sortant de MLI et
qui balançait un message d'insulte (erreur) à la moindre
faute de frappe quand on ne connaissait pas par coeur le nom correct
à saisir:
Il a existé et existe tout un tas de sélecteurs qui sont
apparus à fur
et à mesure soit pour combler les lacunes des 1ère
versions de ProDOS
(comme le très célèbre BBB,
abrégé
de
Bird's Better Bye d'un des
auteurs fétiches des Beagle Bros,
à savoir Alan Bird ou
encore BYE80, la version de BBB
fonctionnant en 80 colonnes mise au point par Dave Ely)
ou pour des
améliorations de selecteur au goût de l'auteur (Super
Selector, Squirt, ...)
La dernière en date est signée David
Empson et s'intitule
QUITTER.SYSTEM. Comme vous l'aurez
deviné, il s'agit d'un SYS
externe qui n'est pas directement intégré dans ProDOS.
Quelques mots explicatifs de son auteur:
BBB runs in 40-column mode and the ProDOS-8 built-in
one looks quite different (from memory - I haven't seen it for ages).
I made a few improvements to Birds Better Bye (such as making it display
two columns of pathnames, and a "rescan" key). I distributed as part of
my freeware application Quitter.System, which gives additional features
such as booting directly from a specified slot and reconnecting GS/OS if
you have launched a P8 program selector.
Alan Bird's quit handler, which was included with AppleWorks 3.0, and
which
I improved and used in the QUITTER.SYSTEM program which I co-wrote with
a friend.
Tous ces sélecteurs sont sans aucun doute très biens,
mais je préfère le standard et s'il y en a un qui me va
bien c'est celui inclus dans la dernière release de
ProDOS 8 (la 2.0.3) et qui permet de choisir facilement en mode 80
colonnes l'unité (avec la touche TAB), et naviguer dans les
répertoires et sous répertoires à la recherche
d'un
SYS à lancer.
Exemple d'un 1er écran correspondant au volume d'un disque dur
/HD1:
Entrée dans un sous répertoire à la recherche
d'un SYS (il y en a 2 sur le cliché -ED.IT et EXER- avec tout un
tas de sous
répertoires identifiés par l'icone de folder):
Quand on va dans un répertoire sans sous répertoire ni
SYS, on est bon pour appuyer sur ESC et revenir au niveau
antérieur (ou changer de volume ProDOS):
Ok j'ai une routine sympa à portée de main.
Malheureusement après un tour d'horizon sur le net, il n'existe
pas à ma connaissance un source complet de cette version en
libre accès. Grrrr! Pas de chance. Surtout qu'il me faudrait la
modifier pour l'adapter à mes besoins (pas besoin de SYS,
afficher <select this directory> quand il n'y a aucun sous
répertoire, etc...)
Récupération
Il a donc fallu que je mette les mains dans le camboui pour extraire la
chose.
Comment s'y prendre?
Voilà comment j'ai fait...
Je sais déjà que la routine est incluse dans le fichier
ProDOS mais j'ignore où.
En effet l'adresse d'implantation dans ce fichier varie presque
à chaque
version
de ProDOS.
Je sais également que quelque soit la version, le code est
exécuté à partir de l'adresse $1000 quand un MLI
Quit est rencontré.
Je vais donc mettre un point d'arrêt sous AppleWin
pour voir un
peu la tête du code.
Je lance une disquette avec le bon ProDOS et un BASIC.SYSTEM.
Quand il me rend la main sous BASIC.SYSTEM, je passe en mode
débugger et saisis "BP 1000" suivi d'un "G".
Dès qu'il revient sur l'écran normal, je tape BYE et
attend de voir ce qu'il me présente comme résultat.
Il s'arrête tout d'abord sur le code qui recopie la routine en
$1000:
Je pourrais en savoir plus dès ce moment là, mais
à quoi bon analyser la routine quand un second "G"
m'amène directement sur le début du code:
Je note les 1er octets de la routine: D8AD82C09CF203.
Pour savoir où se trouve ce code dans le fichier ProDOS, je vais
à présent utiliser un programme utilitaire sympa
appelé LIST version 2.5.
Il permet non seulement de visualiser le contenu de plein de fichiers
aux formats différents mais aussi de faire des recherches sur
des
caractères ou des séquences hexa.
Je l'ai mis sur la disquette jointe. Son auteur est Stowe
Keller et
à l'époque c'était un shareware.
Je sélectionne le volume /MLIQUIT, puis le fichier ProDOS dont
il m'affiche le contenu:
Je tape open-apple F et sélectionne Hex quand il me demande le
type de "Find" que je veux.
Je tape alors la séquence d'octets de tout à l'heure et
lance la recherche en validant par return:
Et hop, il m'affiche alors l'offset où se trouve ce code,
à savoir $3D00.
Comme le fichier ProDOS commence en $2000, ma routine convoitée
se trouve donc en $2000+$3D00=$5D00.
Il n'y a plus qu'à sauvegarder la routine d'origine en tapant:
BLOAD PRODOS,TSYS,A$2000
BSAVE MLIQUIT.ORIG,A$5D00,L$0300
Reconstruction
Maintenant, on passe au classique boot de Merlin 8,
à
l'exécution de Sourceror et au
désassemblage de la
routine.
Une fois que c'est ok, le plus dur reste à faire: comprendre le
code et en faire un source commenté intelligible.
Le résultat de mon travail de retro-engineering se trouve sur le
disk image suivant. L'assemblage du source donne un autre BIN
appelé MLIQUIT que j'ai comparé avec MLIQUIT.ORIG
grâce à l'outil COPY 2+ 9.1
(option
Kompare files).
Le résultat est identique.

|
ProDOS
|
Download MLI Quit Source code from ProDOS 8 2.0.3
(gzipped)
|
Contenu de la disquette MLI_Quit.dsk:
PRODOS --> /MLIQUITT
PRODOS |
SYS | A$0000 | L$42E8 | B$0023
RAM.DRV.SYSTEM | SYS | A$2000 | L$04B9 | B$0004
BASIC.SYSTEM | SYS | A$2000 | L$2800 | B$0015
MLIQUIT.ORIG | BIN | A$5D00 | L$0300 | B$0003
MLIQUIT.S | TXT | A$0000 |
L$4F9C | B$0029
MLIQUIT | BIN |
A$1000 | L$0303 | B$0003
LIST
(DIR)
LIST.LAUNCH | SYS |
A$2000 | L$02DF | B$0003
LIST.SYSTEM | SYS |
A$2000 | L$9135 | B$004A
LIST.DESCR | AWP
| A$C003 | L$A713 | B$0055
LIST.CONFIG | BIN |
A$0000 | L$00F2 | B$0001.
Quelques explications
Organisation de la mémoire:
$0074-$00F2 : type des 127 objets possible
$0280-$02C0 : len+/pathname complet/00
$1000-$1302 : mli quit (cf source plus bas)
$1400-$1BF0 : buffer stockage des 127 noms d'objets possible (127 * 16
<-len+nom objet)
$1C00-$1FFF : buffer $400 octets pour open
$2000-$xxxx : buffer read (volume ou dir ou sys)
Fonctionnement simplifié:
Le programme se base sur la liste des unités actives.
Il commence soit par la dernière unité utilisée
(s'il y en a une) soit
par la dernière de la liste.
A partir de cette référence d'unité, il fait un
MLI Online pour obtenir
le nom de ce volume et ensuite il ne travaille plus que sur des noms.
S'en suit un MLI open et un MLI read pour accéder au catalog du
volume ou du dir.
Puis il lit le catalog objet par objet (descriptif), vérifie que
cet objet est ok et
l'ajoute le cas échéant dans la liste des noms.
En faisant un ESC ou un RETURN sur un répertoire, le programme
repart sur le MLI open
après avoir allonger ou raccourci le nom selon la touche
employée.
Explication rapide des variables utilisées pour l'affichage:
Quand une unité a été sélectionnée
par le programme, on se retrouve au niveau de la racine
(root) du volume. La variable DIR_LEVEL indique le niveau de
profondeur, c'est à dire
le nombre de répertoires valides à partir de cette racine
au fur et à mesure de la navigation
par l'utilisateur dans ce volume.
Quand l'unité n'est pas encore validée, on a DIR_LEVEL =
0.
Au niveau de la racine, on a DIR_LEVEL = 1.
Si l'utilisateur tape RETURN sur un nom de DIR, alors on augmente d'un
niveau.
S'il fait ESC, on diminue d'un niveau hiérarchique (sauf si on
est déja à la racine).
Exemple pour un volume /VOLUME/ avec 2 niveaux de répertoires
imbriqués DIR1 et DIR2,
on aura DIR_LEVEL=3 si l'utilisateur a fait 2 fois RETURN (sur DIR1
d'abord puis
DIR2).
/VOLUME/DIR1/DIR2/
1 2
3 <- DIR_LEVEL
Définition: DIR_LEVEL[0,1=root,nombre de sous-répertoires
sélectionnés par le user]
Exemple de contenu d'un répertoire après filtrage par le
programme qui ne garde
que les répertoires (DIR) et les fichiers système (SYS):
RANK FILENAME FILETYPE
01 NAME01 DIR
02 NAME02 DIR
03 NAME03 SYS
04 NAME04 DIR
05 NAME05 SYS
06 NAME06 SYS
07 NAME07 DIR
08 NAME08 DIR
09 NAME09 DIR
10 NAME10 DIR
11 NAME11 DIR
12 NAME12 DIR
13 NAME13 DIR
14 NAME14 DIR
15 NAME15 DIR
16 NAME16 SYS
17 NAME17 SYS
18 NAME18 SYS
19 NAME19 SYS
20 NAME20 DIR
21 NAME21 DIR
22 NAME22 SYS
Il y a 22 noms sélectionnables.
La variable CPT_NAME est un compteur sur le nombre d'objets (=noms).
Ici CPT_NAME = 22.
S'il n'y avait eu aucun DIR et SYS dans le répertoire courant,
on aurait eu CPT_NAME = 0
et il n'y aurait pas d'affichage.
Il ne faut pas confondre le nombre total d'objets d'un
répertoire et cette
liste de noms qui a été filtrée. Dans la suite de
l'explication, quand je parle de liste
de noms, je me réfère uniquement à la liste
filtrée (donc des noms que l'on veut
afficher).
Définition: CPT_NAME [0,nombre de noms avec max=127]
L'écran texte normal de l'Apple II permet d'avoir jusqu'à
24 lignes.
Ces lignes sont numérotées de 00 à 23.
La variable CV indique la valeur de l'ordonnée.
On réserve 2 lignes en haut et 2 en bas pour des affichages
différents.
Donc on ne peut afficher que 20 noms à la fois sur
l'écran de CV = 2 à CV = 21.
CV correspond à l'endroit où se trouve le nom en
video-inversé en cours de
sélection.
Définition: CV [2,21] pour l'affichage de la liste uniquement!!
L'utilisateur peut choisir d'aller dans un sous répertoire ou
sélectionner un SYS
pour le lancer. Il va donc faire défiler la liste des noms de 1
en 1 en utilisant les
touches HAUT et BAS.
Pour que l'on sache toujours sur quel nom il se trouve, on introduit la
notion
de pointeur sur la liste des noms. Ce pointeur correspond au nom
courant sur lequel
se trouve l'utilisateur. La variable utilisée est PTR_LIST.
Le 1er indice de cette variable est 0.
Quand PTR_LIST pointe sur NAME01, on a PTR_LIST = 0.
Pour NAME02, PTR_LIST = 1, etc...
Le nom correspondant à PTR_LIST apparait en
video-inversée sur l'écran.
Définition: PTR_LIST [0,CPT_NAME-1 avec max=126]
Dans la mesure où la liste peut compter jusqu'à 127 noms
et que l'on ne peut
en avoir que 20 à l'écran, il faut bien à un
moment où un autre que l'on
sache à partir du combien t-ième l'affichage écran
doit commencer.
C'est le rôle d'un autre pointeur: PTR_SCRN. (SCRN pour
screen=écran en anglais).
Il se réfère toujours à la liste de noms et pointe
sur le 1er nom
que l'on trouve en tête d'affichage sur l'écran.
Avec notre exemple, PTR_SCRN vaudra 0 tant que l'utilisateur
ne descendra pas avec la touche BAS au delà de NAME20.
S'il descend encore (PTR_LIST = 20 pointant sur NAME21),
alors l'affichage écran devra se faire à partir de NAME02
et dans ce
cas on a PTR_SCRN = 1.
Ce pointeur est réajusté en fait quand le nom en
video-inversée est soit
sur la 1ère ligne de l'écran soit sur la dernière
et que l'action
utilisateur le fait sortir de l'écran.
Définition: PTR_SCRN [0,max=max(PTR_LIST)-19=107]
Illustration:
Au début, l'utilisateur est sur le 1er nom.
NAME01 est en video-inversée.
PTR_LIST = 0.
PTR_SCRN = 0.
CV
***********************<SCREEN>**************************
00
*/VOLUME/DIR1/DIR2/
*
01
*
*
02 * [] NAME01 <- PTR_LIST (0) = PTR_SCRN
(0) *
03 * []
NAME02
*
04 *
NAME03
*
05 * []
NAME04
*
06 *
NAME05
*
07 *
NAME06
*
08 * []
NAME07
*
09 * []
NAME08
*
10 * []
NAME09
*
11 * []
NAME10
*
12 * []
NAME11
*
13 * []
NAME12
*
14 * []
NAME13
*
15 * []
NAME14
*
16 * []
NAME15
*
17 *
NAME16
*
18 *
NAME17
*
19 *
NAME18
*
20 *
NAME19
*
21 * []
NAME20
*
22
*
*
23 * RETURN: Select | TAB: Chg Vol
| ESC: Back *
*********************************************************
[] NAME21
NAME22 <-
CPT_NAME (22)
Il tape sur la touche flèche BAS une fois.
NAME02 est en vidéo-inversée.
PTR_LIST = 1.
PTR_SCRN = 0.
CV
***********************<SCREEN>**************************
00
*/VOLUME/DIR1/DIR2/
*
01
*
*
02 * [] NAME01 <- PTR_SCRN
(0)
*
03 * [] NAME02 <- PTR_LIST
(1)
*
04 *
NAME03
*
05 * []
NAME04
*
06 *
NAME05
*
07 *
NAME06
*
08 * []
NAME07
*
09 * []
NAME08
*
10 * []
NAME09
*
11 * []
NAME10
*
12 * []
NAME11
*
13 * []
NAME12
*
14 * []
NAME13
*
15 * []
NAME14
*
16 * []
NAME15
*
17 *
NAME16
*
18 *
NAME17
*
19 *
NAME18
*
20 *
NAME19
*
21 * []
NAME20
*
22
*
*
23 * RETURN: Select | TAB: Chg Vol
| ESC: Back *
*********************************************************
[] NAME21
NAME22 <-
CPT_NAME (22)
Il continue de descendre jusqu'à la dernière ligne de
l'écran.
NAME20 est en video-inversée.
PTR_LIST = 19.
PTR_SCRN = 0.
CV
***********************<SCREEN>**************************
00
*/VOLUME/DIR1/DIR2/
*
01
*
*
02 * [] NAME01 <- PTR_SCRN
(0)
*
03 * []
NAME02
*
04 *
NAME03
*
05 * []
NAME04
*
06 *
NAME05
*
07 *
NAME06
*
08 * []
NAME07
*
09 * []
NAME08
*
10 * []
NAME09
*
11 * []
NAME10
*
12 * []
NAME11
*
13 * []
NAME12
*
14 * []
NAME13
*
15 * []
NAME14
*
16 * []
NAME15
*
17 *
NAME16
*
18 *
NAME17
*
19 *
NAME18
*
20 *
NAME19
*
21 * [] NAME20 <- PTR_LIST
(19)
*
22
*
*
23 * RETURN: Select | TAB: Chg Vol
| ESC: Back *
*********************************************************
[] NAME21
NAME22 <-
CPT_NAME (22)
Il descend encore une fois.
NAME21 est en video-inversée.
PTR_LIST = 20.
PTR_SCRN = 1.
CV
[] NAME01
***********************<SCREEN>**************************
00
*/VOLUME/DIR1/DIR2/
*
01
*
*
02 * [] NAME02 <- PTR_SCRN
(1)
*
03 *
NAME03
*
04 * []
NAME04
*
05 *
NAME05
*
06 *
NAME06
*
07 * []
NAME07
*
08 * []
NAME08
*
09 * []
NAME09
*
10 * []
NAME10
*
11 * []
NAME11
*
12 * []
NAME12
*
13 * []
NAME13
*
14 * []
NAME14
*
15 * []
NAME15
*
16 *
NAME16
*
17 *
NAME17
*
18 *
NAME18
*
19 *
NAME19
*
20 * []
NAME20
*
21 * [] NAME21 <- PTR_LIST
(20)
*
22
*
*
23 * RETURN: Select | TAB: Chg Vol
| ESC: Back *
*********************************************************
NAME22 <-
CPT_NAME (22)
Source assemblé
1
2
LST OFF
3
ORG $1000
4
XC
; assemblage proc 65C02
5
6 ********************************
7
*
*
8 * ProDOS 8 V2.0.3 : MLI QUIT *
9 * (c)1983-1993 Apple Computer *
10
*
*
11 * Source by
Deckard *
12
*
*
13 ********************************
14
15 * Pour récupérer la routine MLI Quit
originale, faire:
16 * BLOAD PRODOS,A$2000,TSYS
17 * BSAVE MLIQUIT.ORIG,A$5D00,L$300
18
19 * Page 0 (usage standard)
20
21 WNDLFT EQU
$20 ; marge gauche
22 WNDWDTH EQU
$21 ; largeur
23 WNDTOP EQU
$22 ; marge haute [00,..]
24 WNDBTM EQU
$23 ; marge basse [..,23]
25
26 CH EQU
$24 ; screen x coord [0,79]
27 CV EQU
$25 ; screen y coord [0,23]
28 INVFLG EQU
$32 ; flag affichage
normal/inverse (ou flash)
29
30 * Page 0 (par MLI Quit)
31
32 TBL_SET_MARK EQU $60 ;
parms for MLI set mark
33 FIL_SET_MARK EQU $61 ;
file #
34 NEW_FILE_POS EQU $62 ;
$62/$63/$64 new file position
35
36 ZDEVCNT EQU
$65 ; copie de DEVCNT for work
37 PTR_LIST EQU
$67 ; pointeur sur liste des
noms [0,CPT_NAME-1]
38 CPT_NAME EQU
$68 ; nbr de noms ok dans le
répertoire [0,127]
39 LEN_NAME EQU
$69 ; name length
40 CPT_PRT_PAGE EQU $6A ;
compteur affichage noms sur l'écran
41 DIR_LEVEL EQU
$6B ; nbr de niveaux de
répertoire [0=unité non
42
; selectionnée, 1=root, ...]
43 PTR_NAME EQU
$6C ; et $6D. Pointeur sur
nom objet [0,126]
44 DIR_ELENGTH EQU $6E
; length (bytes) of each entry in the vol dir
45
; -> usually = $27
46 DIR_EP_BLK EQU
$6F ; entries per block
(usually = $0D)
47 FILE_COUNT EQU
$70 ; et $71 : nbr of active
entries in dir
48 CPT_SKIP_NAME EQU $72 ; nbr de
noms à sauter dans le block
49 PTR_SCRN EQU
$73 ; pointeur écran
[0,107]
50 FILE_TYPEL EQU
$74 ; liste des "file type"
des noms sélectionnables
51
; [$74,$F2]
52
53 * Ram
54
55 KEYBUFF EQU
$0280 ; keyboard buffer
56 SOFTEV EQU
$03F2 ; vector for warm start
57 OURCH EQU
$057B ; 80c CH
58 BUF_NAMES EQU $1400
; buffer des 127 noms possible
59 BUF_OPEN EQU
$1C00 ; $400 bytes buffer for mli open
60
61 * Ram spécifique programme
62
63 H2000 EQU
$2000 ; buffer read / adresse SYS loaded
64 VOL_HEADER EQU $2000 ;
début buffer (en-tete vol/dir)
65 ENTRY_LENGTH EQU VOL_HEADER+$23 ; positionnement pour :
taille d'une
66
; description d'objet (SYS/DIR) dans le répertoire
67
; (usually $27)
68
69 OBJ_HEADER EQU $2000 ;
début buffer (descriptif objet)
70 FILE_TYPE EQU OBJ_HEADER+$10 ; positionnement pour
: type objet
71 ACCESS EQU OBJ_HEADER+$1E ;
positionnement pour : détail accès objet
72
73 * Prodos global page
74
75 MLI EQU
$BF00 ; MLI entry addr
76 DEVNUM EQU
$BF30 ; last used drive+slot DSSS0000
77 DEVCNT EQU
$BF31 ; count of active devices
78 DEVLST EQU
$BF32 ; list of active devices
79 BITMAP EQU
$BF58 ; bitmap of low 48k of memory
80
81 * I/O
82
83 KEY EQU
$C000 ; key pressed
84 STROBE EQU
$C010 ; keyboard
85
86 * Rom
87
88 SETTXT EQU
$FB39 ; set for text mode
89 TABV EQU
$FB5B ; vtab to row in acc
90 SETPWRC EQU
$FB6F ; routine to calculate the 'funny
complement' for
91
; reset vector
92 BELL1 EQU
$FBD9 ; direct call to bell routine
93 HOME EQU
$FC58 ; clear screen
94 COUT EQU
$FDED ; user output routine
95 SETINV EQU
$FE80 ; set inverse video
96 SETNORM EQU
$FE84 ; set normal video
97
98 * Commandes prodos
99
100 ONLINE =
$C5
101 SET_PREFIX =
$C6
102 OPEN =
$C8
103 READ =
$CA
104 CLOSE =
$CC
105 SET_MARK =
$CE
106
107 ********************************
108
1000: D8 109
H1000
CLD
110
1001: AD 82 C0
111
LDA $C082 ; enables rom
112
; fait pointer reset sur le début de cette routine
1004: 9C F2 03
113
STZ SOFTEV ; low vector = 0
1007: A9 10
114
LDA #>H1000
1009: 8D F3 03
115
STA SOFTEV+1 ; high vector
100C: 20 6F FB
116
JSR SETPWRC ; calcule $03F4 (funny
complement)
100F: A9 A0
117
LDA #" " ; turn on the
video firmware
1011: 20 00 C3
118
JSR $C300 ; 80c firmware
119
1014: A2 17
120
LDX #23 ; declare
free l'espace ram 48k
1016: 9E 58 BF 121 :1
STZ BITMAP,X ; 0=free
1019: CA
122
DEX
101A: 10 FA
123
BPL :1
124
101C: EE 6F BF
125
INC BITMAP+23 ; sauf bit 0 -> $BF00-$BFFF (ProDOS
global page)
101F: A9 CF
126
LDA #%11001111 ; pages 2/3 free. 0/1 & 4 to 7 not free
1021: 8D 58 BF
127
STA BITMAP
128
1024: A9 02
129
LDA #2 ;
nbr de parms
1026: 85 60
130
STA TBL_SET_MARK ; pour MLI set mark
1028: AE 31 BF
131
LDX DEVCNT ; zone de travail du nbr
d'unités actives
102B: 86 65
132
STX ZDEVCNT ; pour passer de l'une
à l'autre
102D: AD 30 BF
133
LDA DEVNUM ; déja une
unité utilisée? (la dernière)
1030: D0 10
134
BNE PREPARE_UNIT ; oui, commence par celle-ci
135
136
137 *==============================*
138
*
*
139 * Sélectionne une
unité *
140
*
*
141 *==============================*
142
143
SELECT_UNIT
1032: A6 65
144
LDX ZDEVCNT ; nbr d'unité
1034: BD 32 BF
145
LDA DEVLST,X ; prend la dernière DSSS000
unité active pointée
1037: E0 01
146
CPX #1 ;
est-ce qu'on les a toutes faites?
1039: B0 04
147
BCS :1 ;
>=1 -> non
148
103B: AE 31 BF
149
LDX DEVCNT ; repart sur la
dernière (boucle)
103E: E8
150
INX
103F: CA 151
:1
DEX
1040: 86 65
152
STX ZDEVCNT ; nbr d'unité-1 [0,x]
pour préparer la prochaine
153
154
155 *==============================*
156
*
*
157 * Pré-traitement
unité *
158
*
*
159 *==============================*
160
161
PREPARE_UNIT
1042: 8D F5 12
162
STA UNIT ; unité
selectionnée
1045: 20 00 BF
163
JSR MLI ;
récupère le nom du volume sans / devant
1048: C5
164
DFB ONLINE
1049: F4 12
165
DA TBL_ONLINE
104B: B0 E5
166
BCS SELECT_UNIT ; unit error. Passe à la suivante.
167
104D: 64 6B
168
STZ DIR_LEVEL ; default: unit non encore
sélectionnée
104F: AD 81 02
169
LDA KEYBUFF+1 ; 1er caractère
récupéré DSSSLLLL
1052: 29 0F
170
AND #$0F ; garde que la
longueur
1054: F0 DC
171
BEQ SELECT_UNIT ; len=0 -> error. Try next unit
172
1056: 69 02
173
ADC #2 ;
len+2 (pour les 2 '/' rajoutés ci-dessous)
1058: AA
174
TAX
175
176
PREPARE_NAME
; point d'entrée lors d'un changement de DIR
1059: 8E 80 02
177
STX KEYBUFF ; sauve longueur
105C: A9 2F
178
LDA #'/'
105E: 8D 81 02
179
STA KEYBUFF+1 ; replace DSSSLLLL with first /
(volume name)
1061: 9D 80 02
180
STA KEYBUFF,X ; met aussi un / en fin de nom: /name/
1064: 9E 81 02
181
STZ KEYBUFF+1,X ; et un terminateur $00
182
1067: 20 00 BF
183
JSR MLI ;
ouverture unité ou répertoire
106A: C8
184
DFB OPEN
106B: EC 12
185
DA TBL_OPEN
106D: 90 10
186
BCC DO_VOL_DIR ; ok
187
188
; error
106F: A5 6B
189
LDA DIR_LEVEL ; l'unité était
sélectionnée?
1071: F0 BF
190
BEQ SELECT_UNIT ; non, va sur la prochaine unité ou
reste sur la
191
; meme en fonction de ZDEVCNT
192
193
; erreur lors de l'acces d'un sous-répertoire!
194
; l'unité est soit endommagée soit bad dir name
1073: 20 DD FB
195
JSR BELL1+4 ; signale erreur avec son
1076: 20 DA 11
196
JSR PREVIOUS_DIR ; essaie de remonter d'un niveau
1079: 8E 80 02
197
STX KEYBUFF ; stocke nouvelle longueur
107C: 4C B0 11
198
JMP KEY_USER ; attente touche & action
199
200
201 *==============================*
202
*
*
203 * Traitement du volume ou *
204 * d'un
répertoire *
205
*
*
206 *==============================*
207
208
DO_VOL_DIR
107F: E6 6B
209
INC DIR_LEVEL ; validation volume ou niveau de DIR
1081: 64 68
210
STZ CPT_NAME ; init nbr de noms
211
1083: AD F1 12
212
LDA FIL_OPEN ; fixe file number pour read &
set mark
1086: 8D FC 12
213
STA FIL_READ
1089: 85 61
214
STA FIL_SET_MARK
108B: A9 2B
215
LDA #$2B ; fixe len
read = taille volume/dir header
108D: 8D FF 12
216
STA RQL_READ
1090: 9C 00 13
217
STZ RQL_READ+1 ; high=0
1093: 20 B4 12
218
JSR DO_READ ; lecture descriptif (header)
1096: B0 1B
219
BCS GO_PRINT_LIST ; error
220
1098: A2 03
221
LDX #3 ;
sauvegarde en page 0 de "entry length",
109A: BD 23 20 222 :1
LDA ENTRY_LENGTH,X ; "entries per block" et "file count"
109D: 95 6E
223
STA DIR_ELENGTH,X
109F: CA
224
DEX
10A0: 10 F8
225
BPL :1
226
; positionne pour lecture prochain nom du catalog
10A2: 8D FF 12
227
STA RQL_READ ; length of 1 entry in vol dir
10A5: A9 01
228
LDA #1 ;
init compteur de noms à sauter dans le block.
10A7: 85 72
229
STA CPT_SKIP_NAME ; skip nom vol ou nom dir
10A9: 64 63
230
STZ NEW_FILE_POS+1 ; init positionnement high
10AB: 64 64
231
STZ NEW_FILE_POS+2
232
233 *==============================*
234
*
*
235 * Controles sur le nombre *
236 *
d'objets
*
237
*
*
238 *==============================*
239
10AD: A5 70
240
LDA FILE_COUNT ; est-ce qu'il y a au moins un objet valide?
10AF: 05 71
241
ORA FILE_COUNT+1
10B1: D0 02
242
BNE CHECK_NBR_NAM ; oui
243
; non -> affiche liste vide quand meme
244
245
GO_PRINT_LIST
10B3: 80 74
246
BRA PRINT_LIST ; toujours
247
248
CHECK_NBR_NAM
10B5: 24 71
249
BIT FILE_COUNT+1 ; + de 127 noms?
10B7: 30 FA
250
BMI GO_PRINT_LIST ; oui, arrete là
251
252
253 *==============================*
254
*
*
255 * Calcule le positionnement *
256 * à faire pour pointer sur le *
257 * prochain nom à
lire *
258
*
*
259 *==============================*
260
261
POSITION_NAME
262
; position dans le block [$0000-$01FF]
10B9: A5 63
263
LDA NEW_FILE_POS+1 ; init high position sans toucher au
résultat
10BB: 29 FE
264
AND #%11111110 ; des précédants
positionnements
10BD: 85 63
265
STA NEW_FILE_POS+1
10BF: A4 72
266
LDY CPT_SKIP_NAME ; nbr noms à sauter < ...
10C1: A9 00
267
LDA #0
10C3: C4 6F
268
CPY DIR_EP_BLK ; ... au nbr de noms par block?
10C5: 90 07
269
BCC :1 ;
oui (< $0D)
270
10C7: A8
271
TAY
; on saut un bloc entier
10C8: 84 72
272
STY CPT_SKIP_NAME ; repart sur le 1er nom du block suivant
273
; Y=0
10CA: E6 63
274
INC NEW_FILE_POS+1 ; skip 1 block (=512 octets)
10CC: E6 63 275
:2 INC NEW_FILE_POS+1
10CE: 88 276
:1
DEY
; -1 nom à sauter
10CF: 18
277
CLC
; prépare pour l'ADC qui suit
10D0: 30 06
278
BMI :3 ; ok
on a fini de comptabiliser le positionnement
279
; pour les noms à sauter
280
10D2: 65 6E
281
ADC DIR_ELENGTH ; ajoute la taille d'un descriptif d'objet
10D4: 90 F8
282
BCC :1
283
10D6: B0 F4
284
BCS :2 ;
dépassement (incrémente high pour accès 256 bytes
285
; suivants)
286
10D8: 69 04 287
:3 ADC
#$04 ; skip pointer fields en
début de block
10DA: 85 62
288
STA NEW_FILE_POS
289
10DC: 20 00 BF
290
JSR MLI ; ok
positionne sur début du prochain descriptif
10DF: CE
291
DFB SET_MARK ; du nom à traiter
10E0: 60 00
292
DA TBL_SET_MARK
10E2: B0 CF
293
BCS GO_PRINT_LIST ; err. Affiche déja ce qui a
été fait
294
10E4: 20 B4 12
295
JSR DO_READ ; lecture descriptif d'un nom
10E7: B0 CA
296
BCS GO_PRINT_LIST ; err. Affiche déja ce qui a
été fait
297
10E9: E6 72
298
INC CPT_SKIP_NAME ; saute ce nom pour accéder au
prochain
299
300
301 *==============================*
302
*
*
303 * Controle prise en compte *
304 * d'un nom du
catalog *
305
*
*
306 *==============================*
307
10EB: AD 00 20
308
LDA OBJ_HEADER ; controle objet supprimé
10EE: 29 F0
309
AND #$F0 ; vire len
10F0: F0 C7
310
BEQ POSITION_NAME ; deleted entry!
311
312
; ok il était défini comme nom actif. Signale
313
; que ca en fait un de moins dans le compteur
314
; fourni par l'en-tete
10F2: C6 70
315
DEC FILE_COUNT ; -1 nom dans la liste des actifs (low)
10F4: D0 02
316
BNE :4
317
10F6: C6 71
318
DEC FILE_COUNT+1 ; high
319
10F8: 6E 1E 20 320 :4
ROR ACCESS ; autorisé
à lire cet objet?
10FB: 90 B8
321
BCC CHECK_NBR_NAM ; non!
322
323
; ok traitable, vérifie à présent les types objet
10FD: AD 10 20
324
LDA FILE_TYPE
1100: C9 0F
325
CMP #$0F ; = DIR?
1102: F0 04
326
BEQ :5 ; oui
327
1104: C9 FF
328
CMP #$FF ; = SYS.
1106: D0 AD
329
BNE CHECK_NBR_NAM ; non -> suivant
330
1108: A6 68 331
:5 LDX
CPT_NAME ; nbr max de noms gérés dans le
répertoire?
110A: E0 80
332
CPX #128
110C: B0 1B
333
BCS PRINT_LIST ; oui (>=128). Arrete prise en compte
334
335
336 *==============================*
337
*
*
338 * Prise en compte d'un nom *
339
*
*
340 *==============================*
341
342
; acc=file type,X=position dans liste
110E: 95 74
343
STA FILE_TYPEL,X ; sauve le type de l'objet à son
indice
1110: 20 58 12
344
JSR CALC_PTR_NAME ; pointe sur position courante
345
1113: A0 0F
346
LDY #$0F ; dernier
caractère du nom
1115: B9 00 20 347 :6
LDA OBJ_HEADER,Y
1118: 91 6C
348
STA (PTR_NAME),Y
111A: 88
349
DEY
111B: 10 F8
350
BPL :6 ;
recopie tout le nom & storage type+len
351
111D: C8
352
INY
; Y=0
111E: 29 0F
353
AND #$0F ; garde que la
longueur (kill storage type)
1120: 91 6C
354
STA (PTR_NAME),Y ; save len
1122: E6 68
355
INC CPT_NAME ; un nom de plus
1124: D0 8F
356
BNE CHECK_NBR_NAM ; passe au suivant
357
358 *-------------------------------
359
360
GO_SEL_UNIT
1126: 4C 32 10
361
JMP SELECT_UNIT
362
363
364 *==============================*
365
*
*
366 * Affichage de la liste des *
367
*
noms
*
368
*
*
369 *==============================*
370
371
PRINT_LIST
1129: 20 00 BF
372
JSR MLI ; ferme
le volume/dir
112C: CC
373
DFB CLOSE
112D: F2 12
374
DA TBL_CLOSE
112F: B0 F5
375
BCS GO_SEL_UNIT ; err: passe à une autre unité
376
1131: 20 39 FB
377
JSR SETTXT ; mode text
1134: 20 58 FC
378
JSR HOME ; efface
écran
1137: A9 17
379
LDA #23 ;
positionne en bas écran
1139: 20 5B FB
380
JSR TABV
381
113C: A0 00
382
LDY #0 ;
affiche l'aide en ligne
113E: A9 14
383
LDA #20 ;
à partir de l'abscisse dans acc
1140: 20 4A 12
384
JSR PRINT_MSGX
385
1143: 20 AD 12
386
JSR CURSOR_UP_LFT ; curseur en haut à gauche
1146: A2 00
387
LDX #0 ;
affichage en haut de l'écran du pathname
1148: BD 81 02 388 :1
LDA KEYBUFF+1,X
114B: F0 06
389
BEQ :2 ;
arret quand rencontre du terminateur
390
114D: 20 AF 12
391
JSR PRINT_CHAR ; affichage caractère par
caractère
1150: E8
392
INX
1151: D0 F5
393
BNE :1
394
1153: 64 67 395
:2 STZ
PTR_LIST ; init pointeur liste des noms
1155: 64 73
396
STZ PTR_SCRN ; init pointeur écran
1157: A5 68
397
LDA CPT_NAME ; aucun nom?
1159: F0 55
398
BEQ KEY_USER ; oui. Attente autre touche.
399
115B: C9 15
400
CMP #21 ; plus
d'une page de noms?
115D: 90 02
401
BCC :3 ;
non. Fait ce nombre de noms et pas plus.
402
115F: A9 14
403
LDA #20 ; on fait
une page pleine
1161: 85 6A 404
:3 STA CPT_PRT_PAGE
405
1163: A9 02
406
LDA #2 ;
définition fenetre écran pour protéger
1165: 85 22
407
STA WNDTOP ; l'affichage du
pathname et de l'aide des touches
1167: 85 20
408
STA WNDLFT
1169: A9 16
409
LDA #22
116B: 85 21
410
STA WNDWDTH
116D: 85 23
411
STA WNDBTM
412
116F: 20 77 12 413 :4
JSR PRINT_NAME ; affiche le nom en normal
1172: E6 67
414
INC PTR_LIST ; un nom de plus dans la liste
1174: C6 6A
415
DEC CPT_PRT_PAGE ; un nom en moins à afficher sur
cet écran
1176: D0 F7
416
BNE :4 ;
pas fini
417
1178: 64 67
418
STZ PTR_LIST ; repositionne en haut de liste
117A: F0 2E
419
BEQ PRT_INV_NAME ; toujours (affiche nom inverse)
420
421
422 *==============================*
423
*
*
424 * Traitement flèche
HAUT *
425
*
*
426 *==============================*
427
117C: 20 77 12 428 KEY_UP JSR
PRINT_NAME ; affiche le nom pointé en normal
117F: A6 67
429
LDX PTR_LIST ; est-on au tout début de
la liste?
1181: F0 27
430
BEQ PRT_INV_NAME ; oui. Ne bouge pas (affiche nom
pointé en inverse)
431
1183: C6 67
432
DEC PTR_LIST ; pointeur liste-1
1185: A5 25
433
LDA CV ;
position écran
1187: C9 02
434
CMP #$02 ; est-on en
haut?
1189: D0 1F
435
BNE PRT_INV_NAME ; non. Affiche nom pointé en inverse
436
437
; comme on était en haut de l'écran et que le
438
; pointeur de noms sur la liste a fait -1, il faut
439
; repositionner le début de l'affichage sur ce nom,
440
; décaler la liste vers le bas et afficher ce
441
; ce précédant nom sur la 1ère ligne.
118B: C6 73
442
DEC PTR_SCRN ; pointeur écran-1
118D: A9 16
443
LDA #$16 ; ctrl-V ->
décalage écran vers le bas (SCROLLDOWN)
118F: D0 16
444
BNE GO_PRT ; toujours
445
446
447 *==============================*
448
*
*
449 * Traitement flèche
BAS *
450
*
*
451 *==============================*
452
1191: 20 77 12 453 KEY_DOWN JSR PRINT_NAME ;
affiche le nom pointé en normal
1194: A6 67
454
LDX PTR_LIST ; position actuelle pointeur
déja sur dernier
1196: E8
455
INX
; nom?
1197: E4 68
456
CPX CPT_NAME
1199: B0 0F
457
BCS PRT_INV_NAME ; oui. Reste sur place et affiche nom
pointé en
458
; inverse
119B: 86 67
459
STX PTR_LIST ; pointeur liste+1
119D: A5 25
460
LDA CV ;
est-on en bas de l'écran?
119F: C9 15
461
CMP #21
11A1: D0 07
462
BNE PRT_INV_NAME ; non pas encore
463
464
; on était en bas. Il faut descendre hors écran.
11A3: E6 73
465
INC PTR_SCRN ; positionne le pointeur
écran sur le nom suivant
11A5: A9 17
466
LDA #$17 ; ctrl-W ->
décalage écran vers le haut (SCROLLUP)
11A7: 20 ED FD 467 GO_PRT JSR
COUT
468
469
PRT_INV_NAME
11AA: 20 80 FE
470
JSR SETINV ; affichage du nom
pointé en inverse
11AD: 20 77 12
471
JSR PRINT_NAME
472
473
474 *==============================*
475
*
*
476 * Attente d'une touche et exec *
477 * action
correspondante *
478
*
*
479 *==============================*
480
11B0: AD 00 C0 481 KEY_USER LDA
KEY ; key pressed?
11B3: 10 FB
482
BPL KEY_USER ; non
483
11B5: 8D 10 C0
484
STA STROBE ; init keyboard
11B8: 20 84 FE
485
JSR SETNORM ; mode normal
486
11BB: A6 68
487
LDX CPT_NAME ; si aucun objet
sélectionnable
11BD: F0 0C
488
BEQ :1 ;
saute les touches correspondantes
489
11BF: C9 8D
490
CMP #$8D ; return?
11C1: F0 31
491
BEQ KEY_RETURN ; oui
492
11C3: C9 8A
493
CMP #$8A ; down?
11C5: F0 CA
494
BEQ KEY_DOWN ; oui
495
11C7: C9 8B
496
CMP #$8B ; up?
11C9: F0 B1
497
BEQ KEY_UP ; oui
498
11CB: C9 89 499
:1 CMP
#$89 ; tab?
11CD: F0 1E
500
BEQ KEY_TAB ; oui
501
11CF: C9 9B
502
CMP #$9B ; esc?
11D1: D0 DD
503
BNE KEY_USER ; non -> touche incorrecte.
Wait for next.
504
505
506 *==============================*
507
*
*
508 * Traitement
ESC *
509
*
*
510 *==============================*
511
11D3: 20 DA 11
512
JSR PREVIOUS_DIR ; essaie de remonter d'un niveau
11D6: C6 6B
513
DEC DIR_LEVEL ; level-1
11D8: 80 17
514
BRA NEW_DIR ; toujours
515
516
517 *==============================*
518
*
*
519 * Remonte d'un
répertoire *
520
*
*
521 *==============================*
522
523 * In : KEYBUFF = len+pathname
524 *
525 * Out: X = new length
526
527
PREVIOUS_DIR
528
11DA: AE 80 02
529
LDX KEYBUFF ; longueur pathname
11DD: CA 530
:1
DEX
; -1
11DE: BD 80 02
531
LDA KEYBUFF,X ; caractère pointé
11E1: C9 2F
532
CMP #'/' ; =
séparateur de répertoire?
11E3: D0 F8
533
BNE :1 ;
non, remonte encore jusqu'à en trouver un
534
11E5: E0 01
535
CPX #1 ;
est-ce la racine du volume?
11E7: D0 03
536
BNE :2 ; non
537
11E9: AE 80 02
538
LDX KEYBUFF ; ne bouge pas (on est sur
root)
11EC: 60 539
:2
RTS
540
541
542 *==============================*
543
*
*
544 * Traitement touche TAB *
545
*
*
546 *==============================*
547
11ED: 4C 32 10 548 KEY_TAB JMP
SELECT_UNIT ; passe à la next unit
549
550
551 *==============================*
552
*
*
553 * Traite un autre répertoire *
554
*
*
555 *==============================*
556
11F0: E8 557 NEW_DIR2
INX
; positionne sur dernier caractère+1
11F1: 4C 59 10 558 NEW_DIR JMP
PREPARE_NAME ; met '/' et traite ce dir
559
560
561 *==============================*
562
*
*
563 * Traitement touche RETURN *
564
*
*
565 *==============================*
566
567
KEY_RETURN
11F4: 20 00 BF
568
JSR MLI ; fait un
set prefix sur le directory
11F7: C6
569
DFB SET_PREFIX
11F8: F8 12
570
DA TBL_SET_PFX
11FA: B0 F1
571
BCS KEY_TAB ; marche pas -> passe à
l'unit suivante
572
11FC: A6 67
573
LDX PTR_LIST ; recherche adr nom sur objet
pointé
11FE: 20 58 12
574
JSR CALC_PTR_NAME
575
; Y=0
1201: AE 80 02
576
LDX KEYBUFF ; ajoute le nom à la
suite du pathname courant
1204: C8 577
:1
INY
1205: B1 6C
578
LDA (PTR_NAME),Y ; recopie le nom dans buffer clavier
1207: E8
579
INX
1208: 9D 80 02
580
STA KEYBUFF,X
120B: C4 69
581
CPY LEN_NAME ; dernier caractère?
120D: 90 F5
582
BCC :1 ; non
583
120F: 8E 80 02
584
STX KEYBUFF ; sauve nouvelle longueur
1212: A4 67
585
LDY PTR_LIST ; récupère le type
de l'objet pointé
1214: B9 74 00
586
LDA FILE_TYPEL,Y
1217: 10 D7
587
BPL NEW_DIR2 ; traite un autre DIR
588
589 * Lancement final du SYS sélectionné
590
1219: 20 39 FB
591
JSR SETTXT ; petit ménage
avant de partir
121C: 20 58 FC
592
JSR HOME
593
121F: A9 95
594
LDA #$95 ; ctrl-U ->
desactive sous prog 80c
1221: 20 ED FD
595
JSR COUT
596
1224: 20 00 BF
597
JSR MLI ;
ouverture du SYS
1227: C8
598
DFB OPEN
1228: EC 12
599
DA TBL_OPEN
122A: B0 C1
600
BCS KEY_TAB
601
122C: AD F1 12
602
LDA FIL_OPEN ; met file number pour read
122F: 8D FC 12
603
STA FIL_READ
1232: A9 FF
604
LDA #$FF ; pas de
limite de lecture (load all the file)
1234: 8D FF 12
605
STA RQL_READ
1237: 8D 00 13
606
STA RQL_READ+1
123A: 20 B4 12
607
JSR DO_READ ; chargement du SYS
123D: 08
608
PHP
123E: 20 00 BF
609
JSR MLI ;
ferme tous les fichers ouverts
1241: CC
610
DFB CLOSE
1242: F2 12
611
DA TBL_CLOSE
1244: 28
612
PLP
1245: B0 A6
613
BCS KEY_TAB ; error, retour à la
case départ. Je suis
614
; sceptique sur le bon fonctionnement (impact du
615
; ctrl-U???)
616
1247: 4C 00 20
617
JMP H2000 ; lancement final
du SYS. Tchao bambino...
618
619
620 *==============================*
621
*
*
622 * Affiche une chaine (message) *
623
*
*
624 *==============================*
625
626
PRINT_MSGX
124A: 85 24
627
STA CH ;
positionne curseur
628
PRINT_MSG
124C: B9 BB 12
629
LDA STRINGS,Y
124F: F0 06
630
BEQ :1 ;
terminateur
631
1251: 20 ED FD
632
JSR COUT ; affiche le
caractère
1254: C8
633
INY
; next char
1255: D0 F5
634
BNE PRINT_MSG ; always
1257: 60 635
:1
RTS
636
637
638 *==============================*
639
*
*
640 * Calcule adresse
début *
641 * informations d'un objet *
642
*
*
643 *==============================*
644
645 * In : X =
numéro objet (=nom)
646 *
647 * Out: Y = 0
648 * LEN_NAME = longueur du nom
649 * PTR_NAME = pointeur sur buffer
650
651
CALC_PTR_NAME
1258: 64 6D
652
STZ PTR_NAME+1 ; low=0
125A: 8A
653
TXA
; object number *16
125B: 0A
654
ASL
125C: 26 6D
655
ROL PTR_NAME+1
125E: 0A
656
ASL
125F: 26 6D
657
ROL PTR_NAME+1
1261: 0A
658
ASL
1262: 26 6D
659
ROL PTR_NAME+1
1264: 0A
660
ASL
1265: 26 6D
661
ROL PTR_NAME+1
1267: 85 6C
662
STA PTR_NAME
1269: A9 14
663
LDA #>BUF_NAMES ; + high début stockage
126B: 18
664
CLC
126C: 65 6D
665
ADC PTR_NAME+1
126E: 85 6D
666
STA PTR_NAME+1
1270: A0 00
667
LDY #0 ;
save name length
1272: B1 6C
668
LDA (PTR_NAME),Y
1274: 85 69
669
STA LEN_NAME
1276: 60
670
RTS
671
672
673 *==============================*
674
*
*
675 * Affichage d'un nom à l'écran *
676
*
*
677 *==============================*
678
679 * In : PTR_LIST indice nom à
écrire
680 * FILE_TYPEL tableau des
types des objets
681 *
INVFLG type d'affichage (normal/inverse)
682
683 * A noter que comme on affiche un espace avant et un espace
684 * après le nom, si on est en mode inverse, on les voit.
685
686
PRINT_NAME
1277: A9 02
687
LDA #2 ;
saute 2 positions horizontales
1279: 8D 7B 05
688
STA OURCH
127C: A6 67
689
LDX PTR_LIST ; pointeur nom dans liste - ptr
nom écran
127E: 8A
690
TXA
127F: 38
691
SEC
1280: E5 73
692
SBC PTR_SCRN ; résultat toujours [0,19]
1282: 1A
693
INC A
; saute les 2 1ère lignes figées
1283: 1A
694
INC A
1284: 20 5B FB
695
JSR TABV ;
positionnement vertical [2,21]
696
1287: B5 74
697
LDA FILE_TYPEL,X ; type objet
1289: 30 0E
698
BMI :1 ; =
SYS
699
700
; pour un DIR on ajoute l'icone dossier
128B: 9C 7B 05
701
STZ OURCH
128E: A5 32
702
LDA INVFLG ; sauve le mode
affichage actuel
1290: 48
703
PHA
1291: A0 2A
704
LDY #$2A ; affichage
icone folder
1293: 20 4C 12
705
JSR PRINT_MSG
1296: 68
706
PLA
; restaure le mode affichage actuel
1297: 85 32
707
STA INVFLG
708
1299: 20 A9 12 709 :1
JSR PRINT_SPACE ; affiche espace
129C: 20 58 12
710
JSR CALC_PTR_NAME ; calcule adr début nom
711
; Y=0
129F: C8 712
:2
INY
; first=1->skip len
12A0: B1 6C
713
LDA (PTR_NAME),Y ; affiche un caractère du nom
12A2: 20 AF 12
714
JSR PRINT_CHAR
12A5: C4 69
715
CPY LEN_NAME ; dernier caractère?
12A7: 90 F6
716
BCC :2 ; non
717
718
PRINT_SPACE
12A9: A9 A0
719
LDA #" " ; affiche
espace
12AB: D0 04
720
BNE DO_COUT ; always
721
722
CURSOR_UP_LFT
12AD: A9 99
723
LDA #$99 ; ctrl-Y ->
curseur en haut à gauche (top&left)
724
725
PRINT_CHAR
12AF: 09 80
726
ORA #%10000000 ; "caractère"
12B1: 4C ED FD 727 DO_COUT JMP
COUT ; affiche
728
729
730 *==============================*
731
*
*
732 * Effectue 1 lecture MLI read *
733
*
*
734 *==============================*
735
12B4: 20 00 BF 736 DO_READ JSR
MLI
12B7: CA
737
DFB READ
12B8: FB 12
738
DA TBL_READ
12BA: 60
739
RTS
740
741 *==============================*
742
*
*
743 * Chaines pour PRINT_MSG *
744
*
*
745 *==============================*
746
747
STRINGS
748
749 * Aide en ligne
750
12BB: D2 C5 D4
751
ASC "RETURN: Select | TAB: Chg Vol | ESC: Back"00
12BE: D5 D2 CE BA
12C2: A0 D3 E5 EC
12C6: E5 E3 F4 A0
12CA: FC A0 D4 C1
12CE: C2 BA A0 C3
12D2: E8 E7 A0 D6
12D6: EF EC A0 FC
12DA: A0 C5 D3 C3
12DE: BA A0 C2 E1
12E2: E3 EB 00
752
753 * Icone dossier
754
12E5: 0F
755
DFB $0F ; ctrl-O
-> mode inverse
12E6: 1B
756
DFB $1B ; esc
-> activation icones souris (MOUSON)
12E7: D8 D9
757
ASC "XY" ; icone folder
12E9: 18
758
DFB $18 ; ctrl-X
-> desactivation icones souris (MOUSOFF)
12EA: 0E
759
DFB $0E ; ctrl-N
-> mode normal
12EB: 00
760
DFB 0
; terminateur
761
762
763 *==============================*
764
*
*
765 * Tables pour
MLI *
766
*
*
767 *==============================*
768
769 * Open
770
12EC: 03 771 TBL_OPEN
DFB 3
12ED: 80 02
772
DA KEYBUFF ; addr of pathname
12EF: 00 1C
773
DA BUF_OPEN ; buffer
12F1: 00 774 FIL_OPEN
DFB 0
; file #
775
776 * Close
777
778
TBL_CLOSE
12F2: 01
779
DFB 1
12F3: 00
780
DFB 0
; close all opened files
781
782 * Online
783
784
TBL_ONLINE
12F4: 02
785
DFB 2
12F5: 60 786
UNIT DFB %01100000 ; value
not used (slot 6, drive 1)
12F6: 81 02
787
DA KEYBUFF+1 ; 16 bytes buffer for a specific
unit
788
789 * Set Prefix
790
791
TBL_SET_PFX
12F8: 01
792
DFB 1
12F9: 80 02
793
DA KEYBUFF ; addr of pathname
794
795 * Read
796
12FB: 04 797 TBL_READ
DFB 4
12FC: 01 798 FIL_READ
DFB 1
; file #
12FD: 00 20
799
DA H2000 ; addr data
buffer
12FF: 00 00 800 RQL_READ
DA $0000 ; requested
length
1301: 00 00
801
DA $0000 ; actual length
802
803 * Note: Une partie de la table n'apparait pas quand la routine
804 * est incluse dans ProDOS
en $5D00-$5FFF. Quand elle est
805 * recopiée en
$1000, elle fait plus de $300 de long.
806 * Comme ces derniers
octets de la table READ sont à
807 * zero en temps normal,
ce n'est en rien génant.
808
809
SAV MLIQUIT
Object saved as MLIQUIT,A$1000,L$0303,BIN
--End assembly, 771 bytes, Errors: 0
Symbol table - alphabetical order:
ACCESS =$201E
BELL1 =$FBD9 BITMAP
=$BF58 BUF_NAMES=$1400
BUF_OPEN=$1C00
CALC_PTR_NAME=$1258
CH
=$24 CHECK_NBR_NAM=$10B5
CLOSE
=$CC COUT
=$FDED
CPT_NAME=$68 CPT_PRT_PAGE=$6A
CPT_SKIP_NAME=$72
CURSOR_UP_LFT=$12AD
CV
=$25 DEVCNT =$BF31
DEVLST =$BF32
DEVNUM =$BF30
DIR_ELENGTH=$6E DIR_EP_BLK=$6F
DIR_LEVEL=$6B
DO_COUT =$12B1 DO_READ
=$12B4 DO_VOL_DIR=$107F
ENTRY_LENGTH=$2023
FILE_COUNT=$70
FILE_TYPE=$2010 FILE_TYPEL=$74
FIL_OPEN=$12F1
FIL_READ=$12FC
FIL_SET_MARK=$61
GO_PRINT_LIST=$10B3
GO_PRT =$11A7
GO_SEL_UNIT=$1126 H1000
=$1000 H2000 =$2000
HOME
=$FC58 INVFLG
=$32
KEY =$C000
KEYBUFF =$0280
KEY_DOWN=$1191 KEY_TAB
=$11ED
KEY_RETURN=$11F4 KEY_UP =$117C
KEY_USER=$11B0
LEN_NAME=$69
MLI =$BF00
NEW_DIR =$11F1
NEW_DIR2=$11F0
NEW_FILE_POS=$62
OBJ_HEADER=$2000 ONLINE =$C5
OPEN
=$C8 OURCH
=$057B
POSITION_NAME=$10B9 PREPARE_NAME=$1059
PREPARE_UNIT=$1042
PREVIOUS_DIR=$11DA
PRINT_CHAR=$12AF PRINT_LIST=$1129
PRINT_MSG=$124C
PRINT_MSGX=$124A
PRINT_NAME=$1277 PRINT_SPACE=$12A9
PRT_INV_NAME=$11AA
PTR_LIST=$67
PTR_NAME=$6C PTR_SCRN=$73
READ
=$CA
RQL_READ=$12FF
SELECT_UNIT=$1032 SETINV =$FE80
SETNORM =$FE84 SETPWRC
=$FB6F SETTXT
=$FB39 SET_MARK=$CE
SET_PREFIX=$C6
SOFTEV =$03F2 STRINGS
=$12BB STROBE =$C010
TABV
=$FB5B
TBL_CLOSE=$12F2
TBL_ONLINE=$12F4 TBL_OPEN=$12EC
TBL_READ=$12FB
TBL_SET_MARK=$60
TBL_SET_PFX=$12F8 UNIT
=$12F5
VOL_HEADER=$2000
WNDBTM =$23
WNDLFT =$20
WNDTOP =$22
WNDWDTH =$21
ZDEVCNT =$65
Symbol table - numerical order:
WNDLFT
=$20 WNDWDTH
=$21 WNDTOP
=$22 WNDBTM =$23
CH
=$24
CV
=$25 INVFLG
=$32 TBL_SET_MARK=$60
FIL_SET_MARK=$61
NEW_FILE_POS=$62 ZDEVCNT
=$65 PTR_LIST=$67
CPT_NAME=$68
LEN_NAME=$69
CPT_PRT_PAGE=$6A DIR_LEVEL=$6B
PTR_NAME=$6C
DIR_ELENGTH=$6E
DIR_EP_BLK=$6F FILE_COUNT=$70
CPT_SKIP_NAME=$72
PTR_SCRN=$73
FILE_TYPEL=$74 ONLINE
=$C5
SET_PREFIX=$C6
OPEN =$C8
READ =$CA
CLOSE =$CC
SET_MARK=$CE
KEYBUFF =$0280 SOFTEV
=$03F2 OURCH =$057B
H1000 =$1000
SELECT_UNIT=$1032
PREPARE_UNIT=$1042 PREPARE_NAME=$1059
DO_VOL_DIR=$107F
GO_PRINT_LIST=$10B3
CHECK_NBR_NAM=$10B5 POSITION_NAME=$10B9
GO_SEL_UNIT=$1126
PRINT_LIST=$1129 KEY_UP
=$117C KEY_DOWN=$1191
GO_PRT =$11A7
PRT_INV_NAME=$11AA
KEY_USER=$11B0 PREVIOUS_DIR=$11DA
KEY_TAB =$11ED
NEW_DIR2=$11F0 NEW_DIR
=$11F1 KEY_RETURN=$11F4
PRINT_MSGX=$124A
PRINT_MSG=$124C
CALC_PTR_NAME=$1258 PRINT_NAME=$1277
PRINT_SPACE=$12A9
CURSOR_UP_LFT=$12AD
PRINT_CHAR=$12AF DO_COUT =$12B1
DO_READ =$12B4 STRINGS
=$12BB
TBL_OPEN=$12EC FIL_OPEN=$12F1
TBL_CLOSE=$12F2
TBL_ONLINE=$12F4 UNIT
=$12F5 TBL_SET_PFX=$12F8
TBL_READ=$12FB
FIL_READ=$12FC
RQL_READ=$12FF BUF_NAMES=$1400
BUF_OPEN=$1C00
H2000 =$2000
VOL_HEADER=$2000 OBJ_HEADER=$2000
FILE_TYPE=$2010 ACCESS
=$201E
ENTRY_LENGTH=$2023
MLI =$BF00
DEVNUM =$BF30
DEVCNT =$BF31 DEVLST
=$BF32 BITMAP =$BF58
KEY
=$C000 STROBE
=$C010 SETTXT
=$FB39 TABV =$FB5B
SETPWRC =$FB6F
BELL1 =$FBD9
HOME =$FC58
COUT =$FDED
SETINV =$FE80 SETNORM
=$FE84