* Avail.a:	An assembler version of that 'popular' program.
*
* Author:
*		James E. Cooper Jr.
*		113-1B Collier Pl.
*		Cary, NC  27513
*
* Notes:
*		First working version. 10/87  jec
*
* Included equate files.
* -----------------------------------------------------------------------
	NOLIST
	INCLUDE "exec/execbase.i"
	INCLUDE "exec/memory.i"
	INCLUDE "libraries/dos.i"
	INCLUDE "offsets/exec.i"
	INCLUDE "offsets/dos.i"
	LIST

	ifd	CAPE
	EXEOBJ
	objfile 'ram:Avail'
	optimon -1
	endc

* Local Equates
* ------------------------------------------------------------------------
TRUE	EQU	-1
FALSE	EQU	0

* A structure definition
* -------------------------------------------------------------------------

v_CHIPSTR	EQU	-128	; name
v_CHIP		EQU	-124	; storage for free chip parm
v_ICHIP 	EQU	-120	;    "     "  chip in use
v_MCHIP 	EQU	-116	;    "     "  max chip
v_LCHIP 	EQU	-112	;    "     "  free chip largest hunk
v_FASTSTR	EQU	-108
v_FAST		EQU	-104	;    "     "   "   fast parm
v_IFAST 	EQU	-100	;    "     "  fast in use
v_MFAST 	EQU	-96	;    "     "  max fast
v_LFAST 	EQU	-92	;    "     "  free chip largest hunk
v_TOTALSTR	EQU	-88
v_TOTAL 	EQU	-84	;    "     "   "   total parm
v_ITOTAL	EQU	-80	;    "     "  total in use
v_MTOTAL	EQU	-76	;    "     "  Max total
v_LTOTAL	EQU	-72	;    "     "  free total largest hunk
v_OUTPUT	EQU	-68	; storage for output string

* The code segment
* -------------------------------------------------------------------------

	link	a4,#-128		; make space for variables

	moveq	#0,d0

	;------ get Exec's library base pointer:
	LEA.L	DOSName(PC),A1          ; name of dos library
	moveq	#LIBRARY_VERSION,d0

	move.l	a0,a5			; save A0 for later use
	move.l	_AbsExecBase,a6
	Call	OpenLibrary
	MOVE.L	D0,a6			; Save library pointer
	BNE.S	gotdos

	moveq	#RETURN_FAIL,D0 	; give up
	unlk	a4
	rts				; and get out of here!

gotdos:
*
*	; REGISTER USAGE:
*	;	A0-2	= scratch
*	;	A3	= pointer to output string area, for store routine
*	;	A4	= pointer to variable storage
*	;	A5	= scratch
*	;	A6	= dos library base pointer
*	;	D0-3	= AmigaDOS scratch argument registers
*	;	D4	= scratch
*	;	D5	= output handle
*	;	D6	= DOSBase
*
	move.l	a4,d0			; store away for later
	moveq	#127,d4 		; initialize counter
zero:
	move.b	#0,-(a4)                ; zero the data space
	dbra	d4,zero
	move.l	d0,a4			; and get the pointer again
*	Obtain the output handle (needed for write)
	Call	Output
	move.l	a6,d6			; save DOSBase for later calls
	MOVE.L	D0,D5			; Save for the write
	move.l	_AbsExecBase,a6
	Call	Forbid			; don't let 'em change while we ask
	move.l	MemList+LH_HEAD(a6),d0  ; first node in MemList
checkchip:
	move.l	d0,a5			; move node address to address reg
	move.w	MH_ATTRIBUTES(a5),d4    ; get node attributes
	btst	#MEMB_CHIP,d4		; is it chip?
	beq.s	checkfast		; no, go on
	lea	v_CHIP(a4),a3           ; yes, add to chip totals
	bsr	AddIt			; call routine to add to totals
checkfast:
	btst	#MEMB_FAST,d4		; is it fast?
	beq.s	checkpublic		; no, go on
	lea	v_FAST(a4),a3           ; yes, add to fast totals
	bsr.s	AddIt
checkpublic:
	btst	#MEMB_PUBLIC,d4 	; public?
	beq.s	next			; no
	lea	v_TOTAL(a4),a3          ; yes, add it
	bsr.s	AddIt
next:
	move.l	LN_SUCC(a5),d0          ; get address of next node
	bne.s	checkchip		; ...and loop back if valid
	move.l	#MEMF_CHIP+MEMF_LARGEST,d1 ; to find largest hunk in chip ram
	Call	AvailMem
	move.l	d0,v_LCHIP(a4)          ; store
	move.l	d0,d2			; ...and save a copy
	move.l	#MEMF_FAST+MEMF_LARGEST,d1 ; to find largest hunk in fast ram
	Call	AvailMem
	move.l	d0,v_LFAST(a4)          ; store
	cmp.l	d0,d2			; ...and find out which was larger
	blt.s	ok			; fast was larger
	move.l	d2,d0			; chip	"     "
ok:
	move.l	d0,v_LTOTAL(a4)         ; store largest of all
	Call	Permit			; done - they can load all they want
	lea	CHIPNAME(PC),a1
	move.l	a1,v_CHIPSTR(a4)        ; store string pointer for first line
	addq.l	#CHIPLEN,a1
	move.l	a1,v_FASTSTR(a4)        ;   "      "      "     "  second  "
	addq.l	#FASTLEN,a1
	move.l	a1,v_TOTALSTR(a4)       ; etc.
	move.l	d5,d1			; Output file handle
	move.l	#TITLE,d2		; pointer to buffer
	moveq	#TITLEN,d3		; number chars to write
	bsr.s	printit 		; print the title
	lea	v_CHIPSTR(a4),a1        ; CHIP first
	bsr.s	printf
	lea	v_FASTSTR(a4),a1        ; then FAST
	bsr.s	printf
	lea	v_TOTALSTR(a4),a1       ; and finally TOTAL
	bsr.s	printf
	moveq	#RETURN_OK,D0		; give good return code
	unlk	a4			; clean up stack
	rts				; and get the ____ outa Dodge!

* Subroutines
* ------------------------------------------------------------------------
******************************************************************************
* AddIt:	routine to add memory parts to variables
******************************************************************************

AddIt:
	move.l	MH_FREE(a5),d0
	add.l	d0,(a3)                 ; add to available
	move.l	MH_UPPER(a5),d0
	sub.l	MH_LOWER(a5),d0
	add.l	d0,8(a3)                ; add to Max section
	move.l	8(a3),d0
	sub.l	(a3),d0                 ; subtract available
	move.l	d0,4(a3)                ; and we have in-use amount
	rts

******************************************************************************
* printf:	print routine
******************************************************************************

printf:
	lea	FMT(PC),a0              ; load format string
	lea	store(PC),a2            ; routine that puts chars in output
	lea	v_OUTPUT(a4),a3         ; where to put 'em
	move.l	a3,a5			; also, save it for PRINT
	Call	RawDoFmt		; have system 'make' output string
	move.l	d5,d1			; Output file handle
	move.l	a5,d2			; pointer to buffer
	moveq	#127,d0 		; absurd number > max
	moveq	#0,d3			; init char count
lenloop:
	tst.b	(a5)+                   ; NULL yet?
	beq.s	printit 		; yes, goforit!
	addq.l	#1,d3			; increment char count
	dbra	d0,lenloop		; and check again
printit:
	move.l	d6,a6			; recover DOSBase
	Call	Write			; and print it all out!
	move.l	_AbsExecBase,a6 	; and restore Exec Base for next call
	rts

******************************************************************************
* STORE:	routine used by _LVORawDoFmt to store output string
******************************************************************************

store:
	move.b	d0,(a3)+
	rts

******************************************************************************
* Data declarations
******************************************************************************

	CNOP	0,4
DOSName 	DOSNAME
CHIPNAME	DC.B	'chip',0
CHIPLEN 	EQU	*-CHIPNAME
FASTNAME	DC.B	'fast',0
FASTLEN 	EQU	*-FASTNAME
TOTALNAME	DC.B	'total',0
TITLE		DC.B	'Type  Available    In-Use   Maximum   Largest',10
TITLEN		EQU	*-TITLE
FMT		DC.B	'%-5s  %8ld  %8ld  %8ld  %8ld',10,0
	END

