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 : Assembleur - ExecMaster
(Article écrit par Max et extrait d'Amiga News Tech - novembre 1991)
|
|
Avec le programme Espion de la Mémoire,
vous avez pu explorer tout le système graphique de l'Amiga. ExecMaster va plus loin
en vous permettant en plus de modifier à votre guise les structures les plus importantes du noyau multitâche d'Exec.
De fait, si le procédé peut paraître identique, la réalisation est totalement différente. D'abord, le
langage machine a été choisi car lorsque que l'on s'amuse avec Exec, il vaut mieux être le plus rapide
possible. Ensuite, le fait même de pouvoir modifier les données affichées rendait tout à fait caduque
la méthode mise en oeuvre dans l'utilitaire d'espionnage de la mémoire créé il y a deux mois.
ExecMaster vous est proposé ici dans sa version 0.7, c'est-à-dire qu'il s'agit quasiment de ce que
les professionnels de l'informatique nomment une version bêta. Le listing en fin d'article est conséquent
(jugez par vous même...). On va d'abord s'attaquer au programme principal, qui vous
permettra au moins de voir comment tout cela fonctionne. En fin d'article, on passera aux définitions de l'écran,
aux fenêtres, aux gadgets et aux menus utilisés.
Présentation
Le menu principal "Affichage" propose de visualiser les différentes tâches en service dans le système,
les bibliothèques, périphériques logiques et ressources présents en mémoire, les ports publics connus
d'Exec, les modules résidents, les listes mémoire et les interruptions actives. Toutes ces données
ne sont pas obligatoirement modifiables, aussi un second menu apparaît-il en fonction de ce qui est en
cours de visualisation.
ExecMaster permet de changer la priorité d'une tâche, de la "geler" provisoirement (c'est-à-dire de suspendre
son exécution) et de la "réchauffer" (la réintroduire dans la liste des tâches candidates à l'utilisation
du processeur). Vous pouvez également ouvrir et fermer une bibliothèque particulière, ou éliminer de la
mémoire toutes celles qui ne sont pas présentement utilisées. Quant aux ports, vous pouvez les "cacher"
(les supprimer de la liste des ports publics, mais sans les détruire) ou bien les "révéler" (les réintroduire dans
la liste). Enfin, vous pouvez changer la priorité d'un type de mémoire donné, par exemple pour faire en
sorte que le système alloue de la mémoire Chip en priorité. Tout cela s'effectue à la souris, via les menus adéquats.
Principe
Dans tous les cas, étant donné que l'on parcourt des listes publiques modifiables par une autre tâche à n'importe
quel instant, il convient d'interdire d'abord le multitâche et même carrément les interruptions, de lire les
données de la liste en cours et de les copier dans un tampon mémoire supplémentaire, pour finalement les
afficher après avoir rétabli le multitâche. Une routine, AffList, se charge de tout cela : elle parcourt
la liste pointée par a2 jusqu'à sa fin, en appelant à chaque itération la routine pointée par a3 et chargée
de mettre en forme les données trouvées. AffList est appelée quasiment par toutes les routines d'affichage,
sauf celles qui ne dépendent pas d'une liste (au sens Exec du terme), comme les interruptions
ou les modules résidents.
Geler une tâche est très simple : il suffit de la retirer de sa liste actuelle (Ready ou Waiting) et de
l'insérer dans une autre, interne au programme. Ainsi, Exec ne sait plus que cette tâche existe et elle
"s'arrête" tout bonnement de tourner. Le processus inverse est utilisé pour la "réchauffer".
Notez qu'ExecMaster refuse de se geler lui-même (c'est la moindre des choses !) et qu'il ne vérifie pas, en
quittant, si des tâches sont encore gelées. Faites donc attention.
Ouvrir et fermer une bibliothèque particulière ne pose aucun problème, on peut peut-être seulement se demander
comment la virer de la mémoire si elle n'est pas actuellement utilisée. Très simple : il suffit d'essayer
d'allouer une très grosse quantité de mémoire, et le tour est joué ; Exec supprime alors tout ce qui peut l'être :
bibliothèques, périphériques logiques, ressources, polices...
Pour "cacher" et "révéler" un port, on procède de la même manière que pour geler et réchauffer une tâche :
on le supprime de la liste des ports publics pour l'insérer dans une autre, interne au programme et inversement.
Cela ne détruit pas le port lui-même, même si FindPort() ne peut plus le trouver. Là encore, ExecMaster ne
fait aucune vérification quant au nombre de ports encore cachés avant de quitter, donc prudence...
Améliorations
Beaucoup sont possibles (je vous rappelle que ce n'est là que la version 0.7), par exemple terminer
définitivement une tâche donnée (gare aux allocations mémoire qui ne seront pas libérées) ou carrément la
désassembler depuis son PC actuel... On peut également envoyer des signaux et/ou des messages aux ports,
lister d'autres structures (input-handlers, vecteurs Reset...) avec toutes les applications qui en découlent.
L'imagination est la seule limite aux possibilités d'un tel programme (sans me vanter).
A signaler
...que l'idée d'ExecMaster ne vient pas de moi, mais de l'allemand Werner Günther, auteur
du domaine public Xoper dont la version 2.2 est un véritable petit bijou (moins évident à utiliser car
entièrement au clavier) que tout programmeur se doit de posséder. D'ailleurs, je vous l'ai glissée
quelque part sur la disquette
d'accompagnement de ce numéro de l'ANT. Merci qui ?
;
; ExecMaster v0.7 - © 1991, Max pour ANT
;
opt o+,ow-
incdir "include:"
include "exec/alerts.i"
include "exec/execbase.i"
include "exec/tasks.i"
include "exec/memory.i"
include "exec/resident.i"
include "intuition/intuition.i"
include "libraries/dos.i"
include "libraries/dosextens.i"
include "exec/exec_lib.i"
include "intuition/intuition_lib.i"
include "graphics/graphics_lib.i"
include "libraries/dos_lib.i"
include "misc/easystart.i"
; ***** Macros
EXEC MACRO
movea.l $4.w,a6
jsr _LVO\1(a6)
ENDM
DOS MACRO
movea.l DosBase(a5),a6
jsr _LVO\1(a6)
ENDM
INT MACRO
movea.l IntBase(a5),a6
jsr _LVO\1(a6)
ENDM
GFX MACRO
movea.l GfxBase(a5),a6
jsr _LVO\1(a6)
ENDM
CALL MACRO
jsr _LVO\1(a6)
ENDM
; ************************************
rsreset
XItem rs.b 0 ; Structure MenuItem étendue
xi_Item rs.b mi_SIZEOF ; Item standard
xi_Func rs.l 1 ; Fonction à exécuter ou NULL
xi_SIZE rs.w 0
rsreset
Ligne rs.b 0
lg_Num rs.w 1 ; Numéro de la ligne
lg_Data rs.b 38 ; Données pour RawDoFmt()
lg_Str rs.b 80 ; Buffer ASCII pour RawDoFmt()
lg_SIZE rs.b 0
rsreset
Args rs.l 2
WBmsg rs.l 1
DosBase rs.l 1
IntBase rs.l 1
GfxBase rs.l 1
screen rs.l 1
window rs.l 1
rport rs.l 1
tasks rs.b LH_SIZE ; Liste des tâches "gelées"
ports rs.b LH_SIZE ; Liste des ports "cachés"
ligne_y rs.w 1
lignes rs.w 1
fini rs.w 1
VARSIZE rs.w 0
; ************************************
Start lea VARS(pc),a5
movem.l d0/a0,Args(a5)
lea dosname(pc),a1
moveq #0,d0
EXEC OpenLibrary
move.l d0,DosBase(a5)
beq NoDos
lea intname(pc),a1
moveq #0,d0
CALL OpenLibrary
move.l d0,IntBase(a5)
beq NoInt
lea gfxname(pc),a1
moveq #0,d0
CALL OpenLibrary
move.l d0,GfxBase(a5)
beq NoGfx
lea ns(pc),a0
INT OpenScreen
move.l d0,screen(a5)
beq NoScr
lea nw(pc),a0
move.l d0,nw_Screen(a0)
INT OpenWindow
move.l d0,window(a5)
beq NoWin
movea.l d0,a0
move.l wd_RPort(a0),rport(a5)
lea MainMenuList(pc),a1
CALL SetMenuStrip
lea tasks(a5),a0
NEWLIST a0
lea ports(a5),a0
NEWLIST a0
suba.l a1,a1
EXEC FindTask
movea.l d0,a1
moveq #20,d0
CALL SetTaskPri
sf fini(a5)
; ************************************
MainLoop:
tst.b fini(a5)
bne Exit
movea.l window(a5),a0
movea.l wd_UserPort(a0),a0
EXEC WaitPort
AllMsgs movea.l window(a5),a0
movea.l wd_UserPort(a0),a0
EXEC GetMsg
tst.l d0
beq.s MainLoop
movea.l d0,a1
move.l im_Class(a1),d3
move.w im_Code(a1),d2
CALL ReplyMsg
cmpi.l #MENUPICK,d3
bne.s AllMsgs
DoMenus moveq #0,d0
move.w d2,d0
lea MainMenuList(pc),a0
INT ItemAddress
tst.l d0
beq AllMsgs
movea.l d0,a1
move.l xi_Func(a1),d0
beq.s .nofunc
movea.l d0,a0
movem.l d0-d7/a0-a6,-(sp) ; Sauve les registres
movea.l $4.w,a6 ; Prépare a6
lea txtbuff,a4 ; et a4
jsr (a0) ; Saute à la routine
movem.l (sp)+,d0-d7/a0-a6 ; Récupère les registres
.nofunc move.w mi_NextSelect(a1),d2
bra.s DoMenus
; ************************************
Exit move.l window(a5),d0
beq.s .nomenu
movea.l d0,a0
INT ClearMenuStrip
.nomenu movea.l window(a5),a0
INT CloseWindow
NoWin movea.l screen(a5),a0
INT CloseScreen
NoScr movea.l GfxBase(a5),a1
EXEC CloseLibrary
NoGfx movea.l IntBase(a5),a1
EXEC CloseLibrary
NoInt movea.l DosBase(a5),a1
EXEC CloseLibrary
NoDos moveq #0,d0
rts
; ************************************
SetMenu move.l a0,-(sp)
movea.l window(a5),a0
INT ClearMenuStrip
movea.l window(a5),a0
lea MainMenuList(pc),a1
move.l (sp)+,mu_NextMenu(a1)
INT SetMenuStrip
rts
; ************************************
PTitre move.l a0,-(sp)
moveq #0,d0 ; Efface l'écran
movea.l rport(a5),a1
GFX SetRast
moveq #3,d0
movea.l rport(a5),a1
CALL SetAPen
moveq #0,d0 ; Affiche le titre
moveq #20,d1
movea.l rport(a5),a1
CALL Move
movea.l (sp)+,a0
moveq #0,d0
move.b (a0)+,d0
movea.l rport(a5),a1
CALL Text
moveq #1,d0
movea.l rport(a5),a1
CALL SetAPen
moveq #0,d0 ; Positionne le curseur
moveq #30,d1 ; pour la 1re ligne
move.w d1,ligne_y(a5)
movea.l rport(a5),a1
CALL Move
rts
; ************************************
NewLine addq.w #8,ligne_y(a5) ; Descend d'1 ligne de texte
move.w ligne_y(a5),d1
moveq #0,d0
movea.l rport(a5),a1
CALL Move
rts
; ************************************
; Affiche la liste pointée par a2 en appelant la
; routine de formatage pointée par a3
AffList move.w #$4000,$dff09a ; Affiche une liste complète
.all movea.l LH_HEAD(a2),a2
tst.l LN_SUCC(a2)
beq.s .endlst
lea lg_Data(a4),a1 ; Dans le buffer adéquat
jsr (a3) ; Appelle la routine de formatage
bsr.s DoFmt ; des données
bra.s .all
.endlst move.w #$c000,$dff09a ; Rétablit les interruptions
rts
; ************************************
; Vérifie si le noeud pointé par a1 se trouve
; dans la liste pointée par a0
ChkList move.w #$4000,$dff09a
.all movea.l LH_HEAD(a0),a0
tst.l LN_SUCC(a0)
beq.s .end
cmpa.l a0,a1
bne.s .all
.end move.w #$c000,$dff09a
cmpa.l a0,a1
rts
; ************************************
; Vérifie si d0 est un numéro de ligne valide et si oui,
; renvoie l'adresse du Noeud concerné dans a1
CheckID move.l d0,d1
bmi.s .non
cmp.w lignes(a5),d0
bcc.s .non
mulu #lg_SIZE,d0
movea.l lg_Data(a4,d0.l),a1
move.b #4,ccr ; Positionne Z
rts
.non movea.l screen(a5),a0
INT DisplayBeep
move.b #0,ccr ; Efface Z
rts
; ************************************
DoFmt movem.l d0-d3/d7/a0-a3/a6,-(sp)
moveq #-1,d7
move.w lignes(a5),lg_Num(a4)
addq.w #1,lignes(a5)
movea.l a4,a1
lea .putch(pc),a2
lea lg_Str(a4),a3
EXEC RawDoFmt
cmpi.b #80,d7
bls.s .ok1
moveq #80,d7
.ok1 move.l d7,d0
lea lg_Str(a4),a0
movea.l rport(a5),a1
GFX Text
bsr NewLine
lea lg_SIZE(a4),a4
movem.l (sp)+,d0-d3/d7/a0-a3/a6
rts
.putch move.b d0,(a3)+
addq.l #1,d7
rts
; ************************************
GetNum movem.l d1-d7/a0-a6,-(sp)
lea w3gad(pc),a1
ori.w #LONGINT,gg_Activation(a1)
bra.s DoGadget
GetStr movem.l d1-d7/a0-a6,-(sp)
lea w3gad(pc),a1
andi.w #~LONGINT,gg_Activation(a1)
DoGadget:
movea.l gg_SpecialInfo(a1),a1
clr.w si_BufferPos(a1)
clr.w si_DispPos(a1)
clr.w si_NumChars(a1)
clr.l si_LongInt(a1)
movea.l si_Buffer(a1),a1
clr.b (a1)
moveq #-1,d4
move.l a0,d2
.ok1 movea.l window(a5),a0
INT ClearMenuStrip
lea nw3(pc),a0
move.l screen(a5),nw_Screen(a0)
move.l d2,nw_Title(a0)
CALL OpenWindow
move.l d0,d2
beq .nowin
.Loop movea.l d2,a0
movea.l wd_UserPort(a0),a0
EXEC WaitPort
.all movea.l d2,a0
movea.l wd_UserPort(a0),a0
EXEC GetMsg
tst.l d0
beq.s .Loop
movea.l d0,a1
move.l im_Class(a1),d3
CALL ReplyMsg
cmpi.l #GADGETUP,d3
beq.s .gotit
cmpi.l #ACTIVEWINDOW,d3
bne.s .all
.activ lea w3gad(pc),a0
movea.l d2,a1
suba.l a2,a2
INT ActivateGadget
bra .all
.gotit move.l strinfo+si_LongInt(pc),d4
.close movea.l d2,a0
INT CloseWindow
.nowin movea.l window(a5),a0
lea m1(pc),a1
CALL SetMenuStrip
move.l d4,d0
movem.l (sp)+,d1-d7/a0-a6
rts
; ************************************
Affiche_taches:
lea m2(pc),a0
bsr SetMenu
lea ttitre(pc),a0
bsr PTitre
clr.w lignes(a5)
movea.l $4.w,a6
lea AffTask(pc),a3
movea.l ThisTask(a6),a2
lea lg_Data(a4),a1
jsr (a3)
bsr DoFmt
lea TaskReady(a6),a2
bsr AffList
lea TaskWait(a6),a2
bsr AffList
lea tasks(a5),a2
bra AffList
AffTask lea tfmt(pc),a0
move.l a2,(a1)
move.l TC+LN_NAME(a2),18(a1)
bne.s .ok1
move.l #Defaut,18(a1)
.ok1 move.l #tasktxt,4(a1)
move.l #Defaut,14(a1)
cmpi.b #NT_PROCESS,TC+LN_TYPE(a2)
bne.s .ok2
move.l pr_CLI(a2),d0
beq.s .ok2
addq.l #4,4(a1)
move.l pr_TaskNum(a2),14(a1)
lsl.l #2,d0
movea.l d0,a0
move.l cli_CommandName(a0),d0
lsl.l #2,d0
movea.l d0,a0
tst.b (a0)+
beq.s .ok1.1
move.l a0,18(a1)
.ok1.1 lea tfmt2(pc),a0
.ok2 moveq #0,d0
move.b TC_STATE(a2),d0
bpl.s .ok1.2 ; Si le bit 7 est positionné,
moveq #7,d0 ; alors la tâche est "gelée"
.ok1.2 lsl.w #3,d0
add.l #tstxt,d0
move.l d0,8(a1)
move.b TC+LN_PRI(a2),d0
ext.w d0
move.w d0,12(a1)
rts
ttitre dc.b .len-*
dc.b " N° Adresse Type Etat Pri Num No"
.len dc.b "m"
even
tfmt dc.b "%3d %08lx %.4s %-7.7s %4d %.3s %s",0
tfmt2 dc.b "%3d %08lx %.4s %-7.7s %4d %3ld %s",0
even
tstxt dc.b "Invalid Added Running Ready "
dc.b "Waiting Except Removed Frozen "
tasktxt dc.b "TaskProc"
even
Pri_tache:
lea pritxt(pc),a0
bsr GetNum
bsr CheckID
bne.s .err
lea TaskReady(a6),a0
bsr ChkList
beq.s .id_ok
lea TaskWait(a6),a0
bsr ChkList
beq.s .id_ok
lea tasks(a5),a0
bsr ChkList
bne.s .err
.id_ok lea pritxt2(pc),a0
bsr GetNum
EXEC SetTaskPri
.err lea txtbuff,a4
bra Affiche_taches
pritxt dc.b "N° de tâche :",0
even
pritxt2 dc.b "Priorité : ",0
even
Gele_tache:
lea geltxt(pc),a0
bsr GetNum
bsr CheckID
bne.s .err
cmpa.l ThisTask(a6),a1 ; On ne se gèle pas nous-mêmes !
beq.s .err
lea TaskReady(a6),a0
bsr ChkList
beq.s .ok_id
lea TaskWait(a6),a0
bsr ChkList
bne.s .err
.ok_id CALL Disable
bset #7,TC_STATE(a1) ; Pour Affiche_taches
move.l a1,-(sp)
CALL Remove ; Enlève le noeud de sa lite
lea tasks(a5),a0
movea.l (sp)+,a1
CALL AddHead ; et le met dans la notre
CALL Enable
.err lea txtbuff,a4
bra Affiche_taches
geltxt dc.b "Geler N° :",0
even
Chauffe_tache:
lea tasks(a5),a0
IFEMPTY a0,.err
lea chautxt(pc),a0
bsr GetNum
bsr CheckID
bne.s .err
lea tasks(a5),a0
bsr ChkList
bne.s .err
.ok_id CALL Disable
lea tasks(a5),a0
move.l a1,-(sp)
CALL Remove
lea TaskWait(a6),a0
movea.l (sp)+,a1
bclr #7,TC_STATE(a1)
cmpi.b #TS_WAIT,TC_STATE(a1)
beq.s .ok1
lea TaskReady(a6),a0
.ok1 CALL AddTail
CALL Enable
.err lea txtbuff,a4
bra Affiche_taches
chautxt dc.b "Réchauffer N°:",0
even
; ************************************
Affiche_libraries:
lea m3(pc),a0
bsr SetMenu
lea ltitre(pc),a0
bsr PTitre
clr.w lignes(a5)
movea.l $4.w,a6
lea LibList(a6),a2
lea AffLibs(pc),a3
bra AffList
AffLibs move.l a2,(a1)
moveq #0,d0
move.b LIB_VERSION+1(a2),d0
move.w d0,4(a1)
move.b LIB_REVISION+1(a2),d0
move.w d0,6(a1)
move.b LIB_FLAGS(a2),d0
ext.w d0
move.w d0,8(a1)
move.b LIB_OPENCNT+1(a2),d0
move.w d0,10(a1)
move.l LIB+LN_NAME(a2),12(a1)
bne.s .ok1
move.l #Defaut,12(a1)
.ok1 lea lfmt(pc),a0
rts
ltitre dc.b .len-*
dc.b " N° Adresse Version Flg Cnt No"
.len dc.b "m"
even
lfmt dc.b "%3d %08lx %3d.%-3d $%02x %3d %s",0
even
Ouvre_lib:
lea libtxt(pc),a0
bsr GetStr
lea strbuf(pc),a1
moveq #0,d0
EXEC OpenLibrary
tst.l d0
bne.s .ok
movea.l screen(a5),a0
INT DisplayBeep
.ok lea txtbuff,a4
bra Affiche_libraries
libtxt dc.b "Nom library :",0
even
Ferme_lib:
lea libtxt(pc),a0
bsr GetStr
movea.l $4.w,a6
lea LibList(a6),a0
lea strbuf(pc),a1
CALL FindName
tst.l d0
beq.s .err
movea.l d0,a1
CALL CloseLibrary
.err lea txtbuff,a4
bra Affiche_libraries
Purge_lib:
move.l #$ffffff,d0
moveq #1,d1
EXEC AllocMem
lea txtbuff,a4
bra Affiche_libraries
; ************************************
Affiche_devices:
suba.l a0,a0
bsr SetMenu
lea ltitre(pc),a0
bsr PTitre
clr.w lignes(a5)
movea.l $4.w,a6
lea DeviceList(a6),a2
lea AffLibs(pc),a3
bra AffList
; ************************************
Affiche_ports:
lea m4(pc),a0
bsr SetMenu
lea ptitre(pc),a0
bsr PTitre
clr.w lignes(a5)
movea.l $4.w,a6
lea PortList(a6),a2
lea AffPort(pc),a3
bsr AffList
lea ports(a5),a2
bra AffList
AffPort move.l a2,(a1)
move.l MP+LN_NAME(a2),4(a1)
bne.s .ok1
move.l #Defaut,4(a1)
.ok1 moveq #0,d0
move.b MP_FLAGS(a2),d0
bpl.s .ok1.2
moveq #4,d0
.ok1.2 lsl.w #3,d0
add.l #pftxt,d0
move.l d0,8(a1)
move.b MP_SIGBIT(a2),d0
andi.w #$ff,d0
move.w d0,12(a1)
move.l #Defaut,14(a1)
move.l MP_SIGTASK(a2),d0
beq.s .ok3
movea.l d0,a0
cmpi.b #NT_PROCESS,TC+LN_TYPE(a0)
bne.s .ok2
move.l pr_CLI(a0),d0
beq.s .ok2
lsl.l #2,d0
movea.l d0,a0
move.l cli_CommandName(a0),d0
lsl.l #2,d0
movea.l d0,a0
tst.b (a0)+
bne.s .ok4
movea.l MP_SIGTASK(a2),a0
movea.l TC+LN_NAME(a0),a0
.ok4 move.l a0,14(a1)
bra.s .ok3
.ok2 move.l TC+LN_NAME(a0),d0
beq.s .ok3
move.l d0,14(a1)
.ok3 lea pfmt(pc),a0
rts
ptitre dc.b .len-*
dc.b " N° Adresse Nom Flags Bit Tâch"
.len dc.b "e"
even
pfmt dc.b "%3d %08lx %-16.16s %.7s %2d %s",0
even
pftxt dc.b "Signal SoftInt Ignore Action Hidden "
even
Cache_port:
lea portxt(pc),a0
bsr GetNum
bsr CheckID
bne.s .err
lea PortList(a6),a0
bsr ChkList
bne.s .err
CALL Disable
bset #7,MP_FLAGS(a1) ; Pour Affiche_port
move.l a1,-(sp)
CALL Remove
lea ports(a5),a0
movea.l (sp)+,a1
CALL AddHead
CALL Enable
.err lea txtbuff,a4
bra Affiche_ports
portxt dc.b "N° du port :",0
even
Revele_port:
lea ports(a5),a0
IFEMPTY a0,.err
lea portxt2(pc),a0
bsr GetNum
bsr CheckID
bne.s .err
lea ports(a5),a0
bsr ChkList
bne.s .err
CALL Disable
move.l a1,-(sp)
lea ports(a5),a0
CALL Remove
lea PortList(a6),a0
movea.l (sp)+,a1
bclr #7,MP_FLAGS(a1)
CALL AddTail
.err lea txtbuff,a4
bra Affiche_ports
portxt2 dc.b "Montrer N° :",0
even
; ************************************
Affiche_memoire:
lea m5(pc),a0
bsr SetMenu
lea mtitre(pc),a0
bsr PTitre
clr.w lignes(a5)
movea.l $4.w,a6
lea MemList(a6),a2
lea AffMem(pc),a3
bra AffList
AffMem move.l a2,(a1)
move.l MH_LOWER(a2),4(a1)
move.l MH_UPPER(a2),8(a1)
move.l MH_FREE(a2),12(a1)
move.w MH_ATTRIBUTES(a2),16(a1)
move.b MH+LN_PRI(a2),d0
ext.w d0
move.w d0,18(a1)
move.l MH+LN_NAME(a2),20(a1)
bne.s .ok
move.l #Defaut,20(a1)
.ok lea mfmt(pc),a0
rts
mtitre dc.b .len-*
dc.b " N° Node Lower Upper Free Attr "
dc.b "Pri No"
.len dc.b "m"
even
mfmt dc.b "%3d %08lx %08lx %08lx %8ld %2d %3d %s",0
even
Pri_memoire:
lea memtxt(pc),a0
bsr GetNum
bsr CheckID
bne.s .err
lea memtxt2(pc),a0
bsr GetNum
movem.l d0/a1,-(sp)
CALL Disable
CALL Remove
lea MemList(a6),a0
movem.l (sp)+,d0/a1
move.b d0,LN_PRI(a1)
CALL Enqueue
CALL Enable
.err lea txtbuff,a4
bra Affiche_memoire
memtxt dc.b "N° du noeud :",0
even
memtxt2 dc.b "Priorité :",0
even
; ************************************
Affiche_resources:
suba.l a0,a0
bsr SetMenu
lea ltitre(pc),a0
bsr PTitre
clr.w lignes(a5)
movea.l $4.w,a6
lea ResourceList(a6),a2
lea AffLibs(pc),a3
bra AffList
; ************************************
Affiche_modules:
suba.l a0,a0
bsr SetMenu
lea otitre(pc),a0
bsr PTitre
clr.w lignes(a5)
movea.l $4.w,a6
movea.l ResModules(a6),a2
AffMods lea lg_Data(a4),a1
.next move.l (a2)+,d0
beq.s .ret
bgt.s .1
bclr #31,d0
movea.l d0,a2
bra.s .next
.1 movea.l d0,a0
move.l a0,(a1)
move.b RT_PRI(a0),d0
ext.w d0
move.w d0,4(a1)
move.b RT_VERSION(a0),d0
ext.w d0
move.w d0,6(a1)
move.b RT_TYPE(a0),d0
andi.w #15,d0
lsl.w #2,d0
move.l ottab(pc,d0.w),8(a1)
move.l RT_INIT(a0),12(a1)
move.l RT_NAME(a0),16(a1)
bne.s .ok1
move.l #Defaut,16(a1)
.ok1 lea ofmt(pc),a0
bsr DoFmt
bra.s AffMods
.ret rts
otitre dc.b .len-*
dc.b " N° Adresse Pri Ver Type Init No"
.len dc.b "m"
even
ofmt dc.b "%3d %08lx %3d %3d %-8s %08lx %s",0
even
ottab dc.l Defaut,otxt1,0,otxt2,0,0,0,0
dc.l otxt3,otxt4,0,0,0,0,0,0
otxt1 dc.b "Tâche",0
otxt2 dc.b "Device",0
otxt3 dc.b "Resource",0
otxt4 dc.b "Library",0
even
; ************************************
Affiche_interr:
suba.l a0,a0
bsr SetMenu
lea ititre(pc),a0
bsr PTitre
clr.w lignes(a5)
movea.l $4.w,a6
lea IntVects(a6),a6
move.l #intypes,d3
move.w #%1110001111111000,d1
moveq #15,d2
AffInts btst d2,d1
beq.s .serv
.handl lea lg_Data(a4),a1
move.l a6,(a1)
move.l IV_CODE(a6),4(a1)
beq.s .nxtint
move.l IV_NODE(a6),d0
beq.s .nxtint
movea.l d0,a0
move.b LN_PRI(a0),d0
ext.w d0
move.w d0,8(a1)
move.w #'H',10(a1)
move.l d3,12(a1)
move.l LN_NAME(a0),16(a1)
bne.s .ok1
move.l #Defaut,16(a1)
.ok1 lea ifmt(pc),a0
bsr DoFmt
bra.s .nxtint
.serv move.l IV_DATA(a6),a2
lea AffServ(pc),a3
bsr AffList
.nxtint addq.l #8,d3
lea IV_SIZE(a6),a6
dbra d2,AffInts
rts
AffServ move.l a2,(a1)
move.l IV_CODE(a6),4(a1)
move.b LN_PRI(a2),d0
ext.w d0
move.w d0,8(a1)
move.w #'S',10(a1)
move.l d3,12(a1)
move.l LN_NAME(a2),16(a1)
bne.s .ok2
move.l #Defaut,16(a1)
.ok2 lea ifmt(pc),a0
rts
ititre dc.b .len-*
dc.b " N° Node Code Pri Type No"
.len dc.b "m"
even
ifmt dc.b "%3d %08lx %08lx %3d %c %-7.7s %s",0
even
intypes dc.b "TBE DSKBLK SOFTINT PORTS "
dc.b "COPER VERTB BLIT AUD0 "
dc.b "AUD1 AUD2 AUD3 RBF "
dc.b "DSKSYNC EXTER INTEN NIM "
even
; ************************************
Affiche_Quitter:
st fini(a5)
rts
; ************************************
VARS dcb.b VARSIZE
dosname dc.b "dos.library",0
intname dc.b "intuition.library",0
gfxname dc.b "graphics.library",0,0
Defaut dc.b "--------",0,0
; ************************************
include "em_windows.s"
include "em_menus.s"
; ************************************
section BUFFER,BSS
txtbuff ds.b lg_SIZE*100 ; ça doit être assez, sinon boum !
; ************************************
END
|
Fenêtres et menus
Histoire de vous simplifier les choses, voici un petit mode d'emploi des deux listings suivants :
vous les tapez, vous les mettez dans le même répertoire qu'ExecMaster.s et vous assemblez le tout
pour obtenir un programme exécutable du nom de ExecMaster, et c'est tout ! Avouez que c'était simple.
Si, juste une petite précision : le premier listing s'appelle em_windows.s et contient la définition
de l'écran et des fenêtres d'ExecMaster, et le second s'appelle em_menus.s et contient la définition de tous
les menus du programme.
em_windows.s
ns dc.w 0,0,640,256,2
dc.b 1,2
dc.w V_HIRES,CUSTOMSCREEN
dc.l 0,sctitre,0,0
nw dc.w 0,0,640,256
dc.b 1,2
dc.l MENUPICK
dc.l BACKDROP|BORDERLESS|ACTIVATE|NOCAREREFRESH
dc.l 0,0,0,0,0
dc.w 0,0,0,0
dc.w CUSTOMSCREEN
nw3 dc.w 134,0,300,10
dc.b 1,2
dc.l GADGETUP|ACTIVEWINDOW
dc.l ACTIVATE|RMBTRAP
dc.l w3gad,0,0,0,0
dc.w 0,0,0,0
dc.w CUSTOMSCREEN
w3gad dc.l 0
dc.w 120,1,150,8
dc.w GADGHCOMP|SELECTED
dc.w TOPBORDER|RELVERIFY|LONGINT
dc.w STRGADGET
dc.l 0,0,0,0,strinfo
dc.w 0
dc.l 0
strinfo dc.l strbuf,strbuf+40
dc.w 1,40,0,0,0,0,0,0
dc.l 0,0,0,0
strbuf dc.b '0'
dcb.b 79,0
Palette dc.w $0356,$0FFF,$0000,$00AF
sctitre dc.b "ExecMaster 0.7 - © 1991, Max pour ANT",0
even
|
em_menus.s
; ***** Menu 'Affichage'
MainMenuList:
m1 dc.l 0
dc.w 2,0,79,0,MENUENABLED
dc.l m1Name,m1Item1
dc.w 0,0,0,0
m1Item1 dc.l m1Item2 ; Affiche/Taches
dc.w 0,0,195,10
dc.w CHECKIT|ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l %11111111111111111111111111111110,m1IT1,0
dc.b 'T',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_taches ; xi_Func
m1IT1 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt1,0
m1Item2 dc.l m1Item3 ; Affiche/Libraries
dc.w 0,10,195,10
dc.w CHECKIT|ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l %11111111111111111111111111111101,m1IT2,0
dc.b 'L',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_libraries ; xi_Func
m1IT2 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt2,0
m1Item3 dc.l m1Item4 ; Affiche/Devices
dc.w 0,20,195,10
dc.w CHECKIT|ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l %11111111111111111111111111111011,m1IT3,0
dc.b 'D',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_devices ; xi_Func
m1IT3 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt3,0
m1Item4 dc.l m1Item5 ; Affiche/Ports
dc.w 0,30,195,10
dc.w CHECKIT|ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l %11111111111111111111111111110111,m1IT4,0
dc.b 'P',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_ports ; xi_Func
m1IT4 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt4,0
m1Item5 dc.l m1Item6 ; Affiche/Mémoire
dc.w 0,40,195,10
dc.w CHECKIT|ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l %11111111111111111111111111101111,m1IT5,0
dc.b 'M',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_memoire ; xi_Func
m1IT5 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt5,0
m1Item6 dc.l m1Item7 ; Affiche/Resources
dc.w 0,50,195,10
dc.w CHECKIT|ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l %11111111111111111111111111011111,m1IT6,0
dc.b 'R',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_resources ; xi_Func
m1IT6 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt6,0
m1Item7 dc.l m1Item8 ; Affiche/Modules résidents
dc.w 0,60,195,10
dc.w CHECKIT|ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l %11111111111111111111111110111111,m1IT7,0
dc.b 'O',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_modules ; xi_Func
m1IT7 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt7,0
m1Item8 dc.l m1Item9 ; Affiche/Interruptions
dc.w 0,70,195,10
dc.w CHECKIT|ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l %11111111111111111111111101111111,m1IT8,0
dc.b 'I',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_interr ; xi_Func
m1IT8 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt8,0
m1Item9 dc.l 0 ; Affiche/Quitter
dc.w 0,85,195,10
dc.w ITEMTEXT|COMMSEQ|ITEMENABLED|HIGHCOMP
dc.l 0,m1IT9,0
dc.b 'Q',0
dc.l 0
dc.w MENUNULL
dc.l Affiche_Quitter ; xi_Func
m1IT9 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m1Txt9,0
; ***** Menu 'Tâches'
m2 dc.l 0
dc.w 87,0,79,0,MENUENABLED
dc.l m2Name,m2Item1
dc.w 0,0,0,0
m2Item1 dc.l m2Item2 ; Tâches/SetTaskPri
dc.w 0,0,120,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m2IT1,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Pri_tache ; xi_Func
m2IT1 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m2Txt1,0
m2Item2 dc.l m2Item3 ; Tâches/Geler
dc.w 0,10,120,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m2IT2,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Gele_tache ; xi_Func
m2IT2 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m2Txt2,0
m2Item3 dc.l 0 ; Tâches/Réchauffer
dc.w 0,20,120,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m2IT3,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Chauffe_tache ; xi_Func
m2IT3 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m2Txt3,0
; ***** Menu 'Libraries'
m3 dc.l 0
dc.w 87,0,79,0,MENUENABLED
dc.l m3Name,m3Item1
dc.w 0,0,0,0
m3Item1 dc.l m3Item2 ; Libraries/Ouvrir
dc.w 0,0,90,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m3IT1,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Ouvre_lib ; xi_Func
m3IT1 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m3Txt1,0
m3Item2 dc.l m3Item3 ; Libraries/Fermer
dc.w 0,10,90,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m3IT2,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Ferme_lib ; xi_Func
m3IT2 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m3Txt2,0
m3Item3 dc.l 0 ; Libraries/Purger
dc.w 0,20,90,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m3IT3,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Purge_lib ; xi_Func
m3IT3 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m3Txt3,0
; ***** Menu Ports
m4 dc.l 0
dc.w 87,0,79,0,MENUENABLED
dc.l m4Name,m4Item1
dc.w 0,0,0,0
m4Item1 dc.l m4Item2 ; Ports/Cacher
dc.w 0,0,100,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m4IT1,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Cache_port ; xi_Func
m4IT1 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m4Txt1,0
m4Item2 dc.l 0
dc.w 0,10,100,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m4IT2,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Revele_port ; xi_Func
m4IT2 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m4Txt2,0
; ***** Menu 'Mémoire'
m5 dc.l 0
dc.w 87,0,79,0,MENUENABLED
dc.l m5Name,m5Item1
dc.w 0,0,0,0
m5Item1 dc.l 0
dc.w 0,0,100,10
dc.w ITEMTEXT|ITEMENABLED|HIGHCOMP
dc.l 0,m5IT1,0
dc.b 0,0
dc.l 0
dc.w MENUNULL
dc.l Pri_memoire ; xi_Func
m5IT1 dc.b 1,2,RP_JAM2,0
dc.w 20,1
dc.l 0,m5Txt1,0
; ***** Chaînes ASCII
TOPAZ80 dc.l TOPAZname
dc.w TOPAZ_EIGHTY
dc.b 0,0
TOPAZname dc.b "topaz.font",0
m1Name dc.b "Affichage",0
m1Txt1 dc.b "Tâches",0
m1Txt2 dc.b "Libraries",0
m1Txt3 dc.b "Devices",0
m1Txt4 dc.b "Ports",0
m1Txt5 dc.b "Mémoire",0
m1Txt6 dc.b "Resources",0
m1Txt7 dc.b "Modules résidents",0
m1Txt8 dc.b "Interruptions",0
m1Txt9 dc.b "Quitter",0
m2Name dc.b "Contrôles",0
m2Txt1 dc.b "SetTaskPri",0
m2Txt2 dc.b "Geler",0
m2Txt3 dc.b "Réchauffer",0
m3Name dc.b "Contrôles",0
m3Txt1 dc.b "Ouvrir",0
m3Txt2 dc.b "Fermer",0
m3Txt3 dc.b "Purger",0
m4Name dc.b "Contrôles",0
m4Txt1 dc.b "Cacher",0
m4Txt2 dc.b "Révéler",0
m5Name dc.b "Contrôles",0
m5Txt1 dc.b "Priorité",0
even
|
|