Suivez-nous sur X

|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : AMOS - Rechercher un fichier sans fenêtre de requête
(Article écrit par François Lionet et extrait d'Amiga News Tech - février 1992)
|
|
Ce mois-ci, quatre routinettes pour le prix d'une seule : l'ANT vous en donne toujours plus !
Les BASIC (GFA et AMOS) offrent une belle fonction : =Exist(), qui permet de savoir si un fichier
existe réellement avant de le charger. Je vous propose donc aujourd'hui la version routinette de cette
fonction : vous lui donnez un nom de fichier, et elle retourne vrai si ce fichier existe, ou faux
s'il n'existe pas.
La routinette détourne pour un bref instant la requête du système : on peut ainsi demander la présence
d'un nom de disque, ou d'un périphérique logique. Ultra-pratique, n'est-il pas ?
Plusieurs points d'entrée sont à votre disposition :
- _IntOpen : cette routine ouvre l'intuition.library en positionnant un drapeau
(Wb2.0). Ce drapeau n'est à -1 que lorsque l'Amiga utilise le Workbench 2.0 (ou une version postérieure).
- _Exist : la fonction elle-même.
- _ReqOff : arrêt de la requête système (system-request) et passage en mode Forbid. Veillez à ne pas rester dans ce
mode trop longtemps.
- _ReqOn : retour à la requête normal et au mode Permit.
Pour appeler ces routinettes, vous devez comme d'habitude mettre l'adresse de la page de données en A5.
L'exemple d'utilisation de ces routinettes est une nouvelle fonction CLI, recherchant le fichier (ou le disque)
donné en argument. Le résultat est affiché dans la fenêtre courante.
On se retrouve le mois prochain pour de nouvelles routinettes, nettes.
*--------------------------------------------------------------------
* ROUTINETTES numéro 3
*
* _Exist: recherche un fichier sans requester
* _ReqOff: plus de requester
* _ReqOn: requester de nouveau là
* _IntOpen: ouvre intuition.library avec détection de
* version
*
* Par François Lionet, paru dans l'A.N.T. du 1er Fevrier 1992
*--------------------------------------------------------------------
*---------------------- Definition de variables système
* Appel du dos
DosCall MACRO
move.l a6,-(sp)
move.l DosBase-Dt(a5),a6
jsr \1(a6)
move.l (sp)+,a6
ENDM
* Appel de fonction exec
ExeCall MACRO
move.l a6,-(sp)
move.l $4.w,a6
jsr \1(a6)
move.l (sp)+,a6
ENDM
* decalage des fonctions dos
_LVOLock equ -84
_LVOUnLock equ -90
_LVOWrite equ -48
_LVOOutput equ -60
* decalage des fonctions EXEC
_LVOOpenLibrary equ -552
_LVOCloseLibrary equ -414
_LVOSetFunction equ -420
_LVOForbid equ -132
_LVOPermit equ -138
* decalage des fonctions intuition
_LVOAutoRequest equ -$15c
_LVOEasyRequest equ -$24c
*---------------------- Demonstration
Start
* Adresse de la base des données
lea Dt(pc),a5
* Copie la ligne de commande dans un buffer
subq.w #2,d0 ; Attention, une ligne de
; commande est terminée pas
; $0A, ne pas le copier !
bmi .Err2
lea Buffer-Dt(a5),a1
.Loop move.b (a0)+,(a1)+
dbra d0,.Loop
clr.b (a0)+
* Ouvre intuition
bsr _IntOpen
beq.s .Err2
* Ouvre le dos
lea DosName-Dt(a5),a1
moveq #0,d0
ExeCall _LVOOpenLibrary
move.l d0,DosBase-Dt(a5) ; Une erreur est extremement
beq.s .Err1 ; improbable!
* Appelle la fonction
lea Buffer-Dt(a5),a0
bsr _Exist
* Imprime la reponse sur le canal standart
lea Buffer-Dt(a5),a1
lea Existe-Dt(a5),a0
moveq #LExiste,d3
tst.l d0
bne.s .Skip2
lea ExistePas-Dt(a5),a0
moveq #LExistePas,d3
.Skip2 move.l a0,d2
DosCall _LVOOutput ; Demande le canal de sortir,
move.l d0,d1
DosCall _LVOWrite
* Ferme le dos
move.l DosBase-Dt(a5),a1
ExeCall _LVOCloseLibrary
* Ferme intuition
.Err1 move.l IntBase-Dt(a5),a1
ExeCall _LVOCLoseLibrary
* Sortie
.Err2 moveq #0,d0
rts
*---------------------- Routinette 1: =Exist
* Entree
* A0= Nom du fichier
* Sortie
* D0= Faux (0) si fichier inexistant
* D0= Vrai (-1) si fichier trouve
_Exist
movem.l d1/a0-a1,-(sp)
* Plus de requester
bsr _ReqOff
* Essai de faire un lock sur le fichier
move.l a0,d1
DosCall _LVOLock
move.l d0,d2
* Remet le requeter, sans attendre
bsr _ReqOn
* Enleve le lock si il existe
move.l d2,d1
beq.s .NoLock
DosCall _LVOUnLock
.NoLock
* Retourne la réponse
move.l d2,d0
beq.s .Fin
moveq #-1,d0
.Fin movem.l (sp)+,d1/a0-a1
rts
*---------------------- Routinette 2: No Requester
* Entree:
* Néant
* Sortie:
* Néant
*
_ReqOff
movem.l a0-a1/d0-d1,-(sp)
* Inhibe le multitache
ExeCall _LVOForbid
* Branche le faux requester
lea _ReqNul(pc),a0
bsr.s _SetReq
move.l d0,ReqSave-Dt(a5)
movem.l (sp)+,a0-a1/d0-d1
rts
* Faux requester: ramene toujours "CANCEL"
*
_ReqNul
moveq #0,d0
rts
*---------------------- Routinette 3: Remet le requester
* Entree:
* Néant
* Sortie:
* Néant
*
_ReqOn
movem.l a0-a1/d0-d1,-(sp)
* Remet l'ancien requester
move.l ReqSave-Dt(a5),a0
bsr.s _SetReq
* Re-autorise le multitache.
ExeCall _LVOPermit
movem.l (sp)+,a0-a1/d0-d1
rts
*---------------------- Routinette 4: Ouvre intuition
* en trouvant la version
* Entree:
* Néant
* Sortie:
* D0= 0 si ouverture ratée
* D0<>0 si réussie
*
_IntOpen
movem.l a0-a1/d1-d2,-(sp)
* Essai l'ouverture de la version 2.0
moveq #-1,d2
moveq #36,d0
lea IntName-Dt(a5),a1
ExeCall _LVOOpenLibrary
tst.l d0
bne.s .Skip
* Ca n'a pas marche: WB 1.3!
moveq #0,d2
moveq #0,d0
lea IntName-Dt(a5),a1
ExeCall _LVOOpenLibrary
* Stocke le flag et l'adresse de base
.Skip move.w d2,WB2.0-Dt(a5)
move.l d0,IntBase-Dt(a5)
movem.l (sp)+,a0-a1/d1-d2
rts
******* Routine interne: fait le changement de vecteur
* et retourne l'ancien...
_SetReq
move.l a0,d0
move.l IntBase-Dt(a5),a1
lea _LVOAutoRequest,a0
tst.w WB2.0-Dt(a5)
beq.s .Skip
lea _LVOEasyRequest,a0
.Skip ExeCall _LVOSetFunction
rts
* La base des acces à la zone de donnee
Dt
WB2.0 dc.w 0
ReqSave dc.l 0
DosBase dc.l 0
IntBase dc.l 0
DosName dc.b "dos.library",0
IntName dc.b "intuition.library",0
Existe dc.b "Existe !",10
ExistePas dc.b "N'existe pas !",10
Finito dc.b 0
Buffer ds.b 128
LExiste equ ExistePas-Existe
LExistePas equ Finito-ExistePas
even
|
Annexe de Max
Tonton François serait-il un adepte du vieil adage "pourquoi faire simple quand on peut faire compliqué" ?
Pour interdire les requêtes "Please insert volume XXXXX: in any drive" d'AmigaDOS, il y a beaucoup
plus simple. Et surtout plus respectueux de l'Amiga.
Il suffit en effet de jeter un oeil à la structure Process que tout programme, à l'exception des tâches
simples créées par CreateTask() ou équivalente, possède : au décalage $B8 (184 décimal) de cette
structure, se trouve un champ nommé "pr_WindowPtr" qui contient un pointeur sur la fenêtre dans laquelle
AmigaDOS affichera au besoin ses requêtes. Ce champ contient normalement la valeur NULL, indiquant que c'est
la fenêtre (et donc l'écran) du Workbench qu'il faudra utiliser. En mettant ici l'adresse d'une fenêtre
à soi, on pourra faire en sorte que ces requêtes apparaissent dans le même écran que cette fenêtre, par exemple
dans un écran personnalisé (Custom Screen).
Mais le plus intéressant est qu'en initialisant "pr_WindowPtr" à -1, aucune requête ne sera affichée du tout, et AmigaDOS
se comportera exactement comme si l'utilisateur avait cliqué sur "Cancel". Il faudra bien entendu pas oublier
de remettre ce champ dans l'état dans lequel on l'avait trouvé en arrivant (normalement NULL, donc, mais on ne
sait jamais : autant sauver la valeur originale quelque part).
L'avantage de cette méthode, outre que c'est celle recommandée par les RKM, est qu'on n'est pas obligé d'interdire
le multitâche et que les autres programmes essayant de cohabiter ne seront pas influencés : leurs requêtes à
eux apparaîtront bel et bien... A moins qu'ils n'aient eux aussi usé du même truc.
;
; NoReqAussiEtPlusPropre.s
; Par Max pour Amiga NewsTech
;
INCDIR "include:"
INCLUDE "exec/exec_lib.i"
INCLUDE "libraries/dos.i"
INCLUDE "libraries/dosextens.i"
INCLUDE "libraries/dos_lib.i"
; Pour ceux qui aiment pas les includes : pr_WindowPtr = $B8
; *----------------------------------*
CALL MACRO
jsr _LVO\1(a6)
ENDM
; *----------------------------------*
Start lea dosname(pc),a1 ; Ouvre la dos.library
moveq #0,d0
movea.l $4.w,a6
CALL OpenLibrary
move.l d0,d7 ; DOSBase dans d7
beq.s NoDos
suba.l a1,a1 ; Où suis-je ?
CALL FindTask
movea.l d0,a4
move.l pr_WindowPtr(a4),d6 ; d6 = WindowPtr
moveq #-1,d0
move.l d0,pr_WindowPtr(a4) ; WindowPtr = -1
lea name(pc),a0 ; nom : 'PipiCaca:'
move.l a0,d1
moveq #ACCESS_READ,d2
movea.l d7,a6
CALL Lock ; Y'a peu de chance qu'un
move.l d0,d1 ; disque de ce nom existe,
beq.s .nolock ; mais on ne sait jamais !
CALL UnLock
.nolock move.l d6,pr_WindowPtr(a4) ; Remet WindowPtr
movea.l $4.w,a1 ; Referme la dos.library
exg a1,a6
CALL CloseLibrary
NoDos moveq #0,d0 ; That's all folks !
rts
; *----------------------------------*
dosname dc.b "dos.library",0
even
name dc.b "PipiCaca:",0
even
; *----------------------------------*
END
|
|