Obligement - L'Amiga au maximum

Vendredi 06 juin 2025 - 12:30  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

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


Trucs et astuces

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


Glossaire

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


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


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


[Retour en haut] / [Retour aux articles]