**********************************************************************
* Programma: Esempi/FreeMem.s                                        *  
*                                                                    *
* Un dimostrativo dell'uso di Intuition per visualizzare in una      *
* finestra la quantità di memoria disponibile al sistema             *
*                                                                    *
* Testo sorgente (C) 1987 HiSoft, Tutti i diritti sono riservati     *
*                                                                    *
* Sia il testo sorgente che l'eseguibile possono essere distribuiti  *
* liberamente, purchè gratuitamente e senza rimuovere l'intestazione *
**********************************************************************

* Maiuscole diverse da minuscole e Debugging attivo
	opt	c+,d+

* Includiamo macro e costanti di sistema
	incdir	":include/"

	include	intuition/intuition.i
	include	intuition/intuition_lib.i
	include	exec/exec_lib.i
	include	graphics/graphics_lib.i
	include	exec/memory.i
	include	libraries/dos_lib.i
	include	libraries/dos.i

* Costante di rivisualizzazione del display
timeout	equ	25				in 50esimi di secondo

* Apriamo la libreria Intuition
	lea	intname(pc),a1
	moveq	#0,d0				Indifferente versione
	CALLEXEC OpenLibrary
	tst.l	d0
	beq	goawayfast			Fallita apertura
	move.l	d0,_IntuitionBase		Memorizza puntatore

* Apriamo la libreria grafica
	lea	grafname(pc),a1
	moveq	#0,d0
	CALLEXEC OpenLibrary
	tst.l	d0
	beq	goawaycloseint
	move.l	d0,_GfxBase

* Apriamo la libreria DOS
	lea	dosname(pc),a1
	moveq	#0,d0
	CALLEXEC OpenLibrary
	tst.l	d0
	beq	goawayclosegraf
	move.l	d0,_DOSBase

* Apriamo una finestra per il testo
	lea	windowdef(pc),a0
	CALLINT	OpenWindow
	tst.l	d0
	beq	goawaycloseall			Esci se fallita
	move.l	d0,windowptr			Memorizza puntatore

	move.l	#-1,oldfreemem

* Ciclo principale: visualizza quantità RAM, attende e ripete
mainloop
	moveq	#MEMF_PUBLIC,d1
	CALLEXEC AvailMem			Legge quantità

* Letta memoria libera, verifichiamo se cambiata dall'ultima
	cmp.l	oldfreemem,d0
	beq	messagetest			Non stampare se eguale
	move.l	d0,oldfreemem

* Memoria libera in D0.l, che convertiamo in stringa esadecimale
	lea	thestring(pc),a0
	bsr	hexconvert

* Sostituiamo spazi di testa con zeri
	lea	thestring(pc),a0
	moveq	#7-1,d0				Massimo
convspaces
	cmp.b	#'0',(a0)
	bne.s	noconvspaces
	move.b	#' ',(a0)+
	dbf	d0,convspaces			Conversione
noconvspaces

* Aggiusta posizione del cursore
	moveq	#4,d0				Posizione X
	moveq	#20,d1				Posizione Y
	move.l	windowptr(pc),a1
	move.l	wd_RPort(a1),a1			RastPort finestra
	CALLGRAF Move

* Stampiamo la stringa
	move.l	windowptr(pc),a1
	move.l	wd_RPort(a1),a1
	lea	thestring(pc),a0		stringa
	moveq	#thestringlen,d0		lunghezza
	CALLGRAF Text

* Ora vediamo se arriva qualche messaggio
messagetest
	move.l	windowptr(pc),a0
	move.l	wd_UserPort(a0),a0		Porta messaggi finestra
	CALLEXEC GetMsg
	tst.l	d0
	beq.s	nomessage

* C'era un messaggio, che nel nostro caso è sicuramente CLOSEWINDOW
* perciò rispondiamo e terminiamo
	move.l	d0,a1
	CALLEXEC ReplyMsg
	bra.s	closewindow

* Nessun messaggio in attesa, allora sospendiamo per un pò e poi
* ripetiamo il ciclo 
nomessage
	move.l	#timeout,d1
	CALLDOS	Delay				Attende un poco
	bra	mainloop			Ripete ciclo

* Clickato il gadget di chiusura, chiudiamo finestra
closewindow
	move.l	windowptr(pc),a0
	CALLINT	CloseWindow

* Chiude tutte le librerie
goawaycloseall
	move.l	_DOSBase,a1
	CALLEXEC CloseLibrary

* Chiude la libreria grafica
goawayclosegraf
	move.l	_GfxBase,a1
	CALLEXEC CloseLibrary

* Finito, chiudiamo la libreria Intuition
goawaycloseint
	move.l	_IntuitionBase,a1
	CALLEXEC CloseLibrary

goawayfast
	moveq	#0,d0
	rts

* Converte D0.l in una stringa esadecimale a (A0)
hexconvert
	moveq	#8-1,d1			Conteggio cifre
hexclp	rol.l	#4,d0
	move.l	d0,d2			Salvala
	and.b	#$f,d0
	cmp.b	#9,d0
	ble.s	hexdig
	addq.b	#7,d0
hexdig	add.b	#'0',d0
	move.b	d0,(a0)+		Crea una cifra
	move.l	d2,d0			Rimette long
	dbf	d1,hexclp		Ripete per tutte le cifre
	rts

* Definizione della finestra qui
windowdef	dc.w	50,50			Posizione X,Y
	dc.w	200,25				Larghezza ed altezza
	dc.b	-1,-1				Penne di default
	dc.l	CLOSEWINDOW			Flag di IDCMP
	dc.l	WINDOWDEPTH!WINDOWCLOSE!SMART_REFRESH!ACTIVATE!WINDOWDRAG
	dc.l	0				Nessun gadget
	dc.l	0				Nessun checkmark custom
	dc.l	windowtitle			Intestazione finestra
	dc.l	0				Nessuno schermo
	dc.l	0				Nessuna bitmap
	dc.w	0,0,0,0				Limiti dimensioni, irrilevanti
	dc.w	WBENCHSCREEN			Nel Workbench

* Stringhe qui
intname		INTNAME				Nome 'intuition.library'
grafname	GRAFNAME			Nome 'graphics.library'
dosname		DOSNAME				Nome 'dos.library'

windowtitle	dc.b	' ',$a9,' HiSoft 1987 ',0
thestring	dc.b	'00000000 bytes liberi'
thestringlen	equ	*-thestring

* Variabili interne
_IntuitionBase	dc.l	0			Per Intuition
_GfxBase	dc.l	0			Per Graphics
_DOSBase	dc.l	0			Per DOS
windowptr	dc.l	0			Per puntatore finestra
oldfreemem	dc.l	0			Per memoria libera
		end

