; Reprinted from Micro/Systems Journal, Vol. 1, No. 1, March-
; April 1985, article titled "Assembly Language Extensions for
; MS-Basic" by Ron Kreymborg.  
;

;**************************************************************;
; RELOC:   A program to move a page relocatable assembly       ;
; 	language module with an origin at zero to the top      ;
;       of available memory.                                   ;
;                                                              ;
;					     Ron Kreymborg     ;
;                                                              ;
; This code resides at the end of MBASIC                       ;
;**************************************************************;

	org	6000h

exit:	jmp	0		; original address of Basic
Šstart:	lxi	sp,stack

; Define code length and start address

	lxi	h,buff		; source for move
	mov	c,m		; get length of module
	inx	h
	mov	b,m
	mov	a,b		; anything there?
	ora	c
	jz	exit		; ..no

	lxi	d,0feh
	dad	d		; start of code
	xchg			; put in DE
	push	b		; save count
	push	b

; Compute destination address in HL

	lhld	6		; get bdos address
	shld	buff+100h	; insert in module
	mvi	l,0		; ensure we go to a page boundry
	inr	b		; convert length to pages
	mov	a,h
	sub	b
	mov	h,aŠ
; Now move the code to the address in HL

	pop	b		; restore byte count
	push	h		; save destination address
movlp:	ldax	d		; get byte of code
	mov	m,a		; move to new location
	inx	h		; step pointers
	inx	d
	dcx	b		; and decrement counter
	mov	a,c
	ora	b		; done?
	jnz	movlp		; ..no, loop

	pop	h		; restore destination
	shld	6		; setup new bdos vector
	xchg
	pop	b		; restore count

; Now BC has the byte count, HL points to the first byte of the
; bit map, and DE has the destination address

	push	h		; bit map address to top of stack
	mov	h,d		; (h) is relocated page offset

reclp:	mov	a,b		; check if done
	ora	cŠ	jz	exit		; ..yes, go start up Basic
	dcx	b		; decrease count
	mov	a,e		; is DE address modulo 8 bytes?
	ani	7		;   if so - must get next map byte
	jnz	rec2		; ..no

; Get next map byte via top of stack

	xthl			; get current map pointer
	mov	a,m		; get byte into A
	inx	h		; point to next byte
	xthl
	mov	l,a		; store in L

rec2:	mov	a,l		; check next bit in byte
	ral
	mov	l,a		; save for later
	jnc	rec3		; no relocation required

; Add in the offset for a set bit 

	ldax	d		; get byte
	add	h		; add offset
	stax	d		; store relocated byte back
rec3:	inx	d		; step to next byte in relocated
	jmp	reclp		;   code and around again
Š; <stack> must occur on an 8 bit boundry

	org	($ AND 0fff0h) + 10h

stack	equ	$
	db	0
buff:	dw	0	; zero for no module case

	end
