h52181
s 00027/00027/00128
d D 3.2 85/02/13 00:38:24 dan 2 1
c System V assembler syntax update
e
s 00155/00000/00000
d D 3.1 84/11/13 16:28:20 dan 1 0
c date and time created 84/11/13 16:28:20 by dan
e
u
U
t
T
I 1
/* memcheck.S -- Validate sections of RAM according to Memory Bitmap
 * copyright (c) American Information Systems Corporation
 *
 *	Daniel Steinberg
 *	August, 1984
 *
 *	AIS/UNIX-System V.2  code format
 *
 */
	.file "memcheck.S"

#include "RAMmonsize.m"
#include "3200config.h"

	.text

/* chk_bitmap (addr, length) -- Verify a block of memory
 *	in:	addr		Start Address  (if -1, return last RAM address)
 *	in:	length		Number of bytes
 *	return:	(int)		FALSE- if memory is not there
 *				TRUE - if memory is available
 *				>0   - if all memory is read/write
 *				-1   - if any part of memory is read-only
 *				(last RAM address if 'addr' == -1)
 *	thrown:	(NONE)
 *
 *	Checks the Memory Bitmap, constructed at initialization,
 *	to see if the block of memory specified exists and had
 *	no parity errors in it.  Returns TRUE if the memory block
 *	is available for use (-1 if memory is read-only).
 */
	.globl	_chk_bitmap
_chk_bitmap:
	movd	4(sp),r0	/* get start address */
D 2
	cmpqd	-1,r0		/* return last RAM address? */
E 2
I 2
	cmpqd	$-1,r0		/* return last RAM address? */
E 2
	beq	lastram		/* yes...go do it */
	movd	8(sp),r1	/* get number of bytes to check */
	bicd	$(A_Grain-1),r0	/* round down to start of block */
	divd	$A_Grain,r0	/* and convert to bitmap offset */
	addr	@A_membitmap,r2	/* Memory Bitmap address */
chkloop:
	tbitd	r0,0(r2)	/* this block of memory available? */
	bfc	chkrom		/* no */
D 2
	addqd	1,r0		/* yes...point to next segment */
E 2
I 2
	addqd	$1,r0		/* yes...point to next segment */
E 2
contram:
	subd	$A_Grain,r1	/* subtract GRAINsize from size ctr */
D 2
	cmpqd	0,r1		/* done yet? */
E 2
I 2
	cmpqd	$0,r1		/* done yet? */
E 2
	blt	chkloop		/* no....try next block */
D 2
	ret	0		/* yes...R0 is greater than zero */
E 2
I 2
	ret	$0		/* yes...R0 is greater than zero */
E 2

chkrom:
	movd	4(sp),r0		/* start address */
	movd	8(sp),r1		/* byte count */
	addd	r0,r1			/*  + address = end of area to check */
	cmpd	r1,@A_reset_addr	/* block ends in PROM? */
	bls	tryintctlr		/* no....check special page */
	addr	_edata,r2		/* get last PROM address */
	cmpd	r0,r2			/* block starts in PROM? */
	bls	prom			/* yes...return -1 */

tryintctlr:
	cmpd	r1,$INTCTLR		/* block ends after ICU? */
	bhi	prom			/* yes...map read-only */
					/* no....check allocated Zero-RAM */
tryzeroram:
#ifdef IMM_AS /*************** IMMEDIATE ADDRESS FLAG ******************/
	cmpd	r1,$A_zeroramstart	/* block ends in Zero-RAM area? */
	bls	nomem			/* no....give up */
	cmpd	r0,$A_zramend		/* block starts in Zero-RAM area? */
	blo	prom			/* yes */
#else  /********************** IMMEDIATE ADDRESS FLAG ******************/
	addr	@A_zeroramstart,r2
	cmpd	r1,r2			/* block ends in Zero-RAM area? */
	bls	nomem			/* no....give up */
	addr	@A_zramend,r2
	cmpd	r0,r2			/* block starts in Zero-RAM area? */
	blo	prom			/* yes */
#endif /********************** IMMEDIATE ADDRESS FLAG ******************/

try1stgrain:			/* first grain, after Zero-RAM, is read-write */
	cmpd	r0,$A_Grain		/* block starts in 1st grain? */
	bhs	nomem			/* no....give up */
	addr	@A_membitmap,r2		/* yes...prepare to jump into ram chk */
	addd	r0,r1			/* ASSUME A_zeroramstart == 0 */
D 2
	movqd	1,r0			/* start at first grain */
E 2
I 2
	movqd	$1,r0			/* start at first grain */
E 2
	br	contram			/* subtract Grainsize & continue chk */

D 2
nomem:	movqd	0,r0		/* memory unavailable...return FALSE */
	ret	0		/* (or if region crosses a boundary) */
E 2
I 2
nomem:	movqd	$0,r0		/* memory unavailable...return FALSE */
	ret	$0		/* (or if region crosses a boundary) */
E 2

D 2
tinymem:		/* from gettopmem() below */
E 2
I 2
tinymem:			/* from gettopmem() below */
E 2

D 2
prom:	movqd	-1,r0		/* memory is read-only */
	ret	0
E 2
I 2
prom:	movqd	$-1,r0		/* memory is read-only */
	ret	$0
E 2

lastram:			/* return 1st address after end of RAM */
	addr	@A_Grain,tos	/* set pseudo-allocate size */
D 2
	movqd	0,tos		/* set flag to locate RAM */
E 2
I 2
	movqd	$0,tos		/* set flag to locate RAM */
E 2
	bsr	_gettopmem	/* find last available RAM */
	adjspb	$-4		/* pop flag */
	addd	tos,r0		/* set to 1st address after RAM */
D 2
	ret	0		/* return address */
E 2
I 2
	ret	$0		/* return address */
E 2


/*
 * gettopmem (flg, size) - locate the highest available memory block
 *	in:	flg	FALSE: locate RAM / TRUE: allocate RAM
 *	in:	size	contiguous bytes to allocate
 *	return:	(int)	address of available block of memory
 *			(bitmap bits are cleared if 'flg' was 1 on entry)
 *			returns -1 if not enough memory
 *
 *	*** Does not ever allocate address 0 ***
 */
	.globl	_gettopmem
_gettopmem:
	addr	@A_membitmap,r2		/* Memory Bitmap address */
	movd	8(sp),r1		/* get 'size' parameter */
	addr	@((ENDMEM/A_Grain)-1),r0	/* point to highest RAM bit */
fnd1stbit:
D 2
	tbitd	r0,0(r2)	/* this block available? */
	bfs	found1st	/* yes...use it */
	acbd	-1,r0,fnd1stbit	/* no....try next lower */
	br	tinymem		/* Not enough memory to allocate */
E 2
I 2
	tbitd	r0,0(r2)		/* this block available? */
	bfs	found1st		/* yes...use it */
	acbd	$-1,r0,fnd1stbit	/* no....try next lower */
	br	tinymem			/* Not enough memory to allocate */
E 2

fndnxtbit:
D 2
	tbitd	r0,0(r2)	/* still available? */
	bfc	toosmall	/* no...try all over again */
E 2
I 2
	tbitd	r0,0(r2)		/* still available? */
	bfc	toosmall		/* no...try all over again */
E 2
found1st:
D 2
	subd	$A_Grain,r1	/* got one block anyway */
	cmpqd	0,r1		/* got enough? */
	bge	mark		/* yes...go mark it, if necessary */
	acbd	-1,r0,fndnxtbit	/* no....point to previous block bit */
	br	tinymem		/* Not enough memory to allocate */
E 2
I 2
	subd	$A_Grain,r1		/* got one block anyway */
	cmpqd	$0,r1			/* got enough? */
	bge	mark			/* yes...go mark it, if necessary */
	acbd	$-1,r0,fndnxtbit	/* no....point to previous block bit */
	br	tinymem			/* Not enough memory to allocate */
E 2

toosmall:			/* Look for another block of memory */
	movd	8(sp),r1	/* restore byte count */
	br	fnd1stbit	/* and keep looking */

mark:
	movd	8(sp),r1	/* restore byte count */
D 2
	cmpqd	0,4(sp)		/* allocate memory? */
E 2
I 2
	cmpqd	$0,4(sp)	/* allocate memory? */
E 2
	beq	nomark		/* no */
	save	[r0]		/* yes...save start block bit */
markloop:
	cbitd	r0,0(r2)	/* clear the 'available' bit */
	subd	$A_Grain,r1	/* count a block marked */
D 2
	addqd	1,r0		/* point to next bit */
	cmpqd	0,r1		/* marked all of memory? */
E 2
I 2
	addqd	$1,r0		/* point to next bit */
	cmpqd	$0,r1		/* marked all of memory? */
E 2
	blt	markloop	/* not yet */
	restore	[r0]		/* get start bit back */
nomark:
	muld	$A_Grain,r0	/* convert bit offset to address */
D 2
	ret	0		/* and return */
E 2
I 2
	ret	$0		/* and return */
E 2

E 1
