; Subroutine to check if an address range is available for allocation
; as shared memory.
; Input:  bx = segment start address
;	  di = # of bytes / 16
; Returns with carry set if range is occupied
; All registers saved and restored
;
	public	occupied_chk
occupied_chk:
	push	ax			; save registers
	push	bx
	push	cx
	push	dx
	push	si
	push	di
	push	ds
;
; first check if there is any ROM in our range
;
	add	di,bx			; end of range to check
	mov	dx,0c000h-(2048 shr 4)	; start of possible ROM area
occ_next2k:
	add	dx,2048 shr 4		; next 2k segment
occ_nextROM:
	cmp	dx,di			; ROM addr above our range?
	jae	occ_chk_RAM		; -yes, go check for RAM
	mov	ds,dx			; -no, check for ROM
	xor	si,si
	mov	cx,0aa55h		; ROM signature
	mov	ax,[si]
	cmp	ax,cx			; any signature?
	jne	occ_next2k
	mov	ch,[si+2]		; ROM length in 512 byte blocks
	xor	cl,cl
	push	cx
	shl	cx,1			; # of bytes to checksum
	xor	ah,ah			; clear accumulated checksum
occ_chksum:
	lodsb				; get a byte
	add	ah,al			; add modulo 100h
	loop	occ_chksum		; repeat for all bytes
	pop	cx
	or	ah,ah			; is checksum zero?
	jnz	occ_next2k		; -no, check next 2k addr 
	shr	cx,1			; -yes, valid ROM found
	shr	cx,1
	shr	cx,1
	add	dx,cx			; end of ROM
	cmp	dx,bx			; does it reach into our area?
	ja	occ_is_ROM
	jmp	occ_nextROM
;
; no ROM found in our range, check for RAM
;
occ_chk_RAM:
	mov	ds,bx			; point segment at start of range
	sub	di,bx			; compute # of bytes
	mov	cl,4
	shl	di,cl
	xor	bx,bx			; clear word pointer
	mov	ax,0a5a5h		; test pattern
	mov	si,05a5ah		;   and its complement
occ_nextword:
	pushf
	cli				; disable interrupts
	mov	cx,[bx] 		; save original contents
	mov	dx,[bx+2]		; save original contents
	mov	[bx],si 		; put our pattern
	mov	[bx+2],ax		; drain any capacitive memory
	cmp	[bx],si 		; is our pattern still there?
	mov	[bx],cx 		; restore original contents
	mov	[bx+2],dx		; restore original contents
	jne	occ_no_RAM
	mov	[bx],ax 		; put the complement pattern
	mov	[bx+2],si		; drain capacitive memory
	cmp	[bx],ax 		; our pattern still there?
	mov	[bx],cx 		; restore original contents
	mov	[bx+2],dx		; restore original contents
	je	occ_is_RAM		; -yes, range is occupied
occ_no_RAM:
	popf				; enable interrupt
	add	bx,2			; check next word
	cmp	bx,di			; at end of range?
	jb	occ_nextword
	clc				; clear carry - range is available
	jmp	short occ_return
occ_is_RAM:
	popf				; enable interrupts
occ_is_ROM:
	stc				; set carry - range is occupied
occ_return:
	pop	ds			; restore registers
	pop	di
	pop	si
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret

