;--- Init routine -----------------------------------------------------------

Init	clr.l	hitcnt(a5)	; hits = 0
	clr.w	column(a5)	; start at column 2 on 1st line

	lea	padpos(pc),a0	; set up pad character
	move.b	#"-",(a0)
	tst.l	padzero(a5)
	beq.s	1$
	move.b	#"0",(a0)
1$

; set up start and end addresses

	move.l	begaddr(a5),d0
	bne.s	.got
	clr.l	start(a5)
	move.l	4.w,a0
	move.l	MaxLocMem(a0),end(a5)
	bra	Search

.got	move.l	d0,a0
	bsr.s	hexconv
	tst.l	d1
	beq.s	.nhex
	move.l	d0,start(a5)

	move.l	endaddr(a5),d0
	beq.s	.noend
	move.l	d0,a0
	bsr.s	hexconv
	tst.l	d1
	beq.s	.nhex
	move.l	d0,end(a5)
	bra	Search

.nhex	error	BAD_NUMBER
	rts
.noend	error	REQUIRED_ARG_MISSING
	rts

hexconv	include	hex.asm

;--- Search routine ---------------------------------------------------------

Search	move.l	start(a5),a0
	move.l	end(a5),a1
	cmp.l	a0,a1
	beq.s	.cleanup	; if start=end then exit
	bhi.s	.noswap		; if start>end then swap start and end
	exg.l	a0,a1
.noswap	move.l	a0,start(a5)
	move.l	a1,end(a5)

	move.l	searchstr(a5),str(a5)
	print	begin(pc),str(a5)

; search routine
; a4=string to search for
; a3=current position in memory (outer)
; a2=current position in memory (inner)

	move.l	start(a5),a3
	move.l	searchstr(a5),a4
	tst.b	(a4)		; if string = '' then exit
	beq.s	.cleanup
.next_outer
	move.b	(a4),d0
	cmp.b	(a3)+,d0
	bne.s	.no_start
	lea	1(a4),a1	; a1=2nd byte of search string
	move.l	a3,a2		; a2=2nd byte of matched memory
.next_inner
	tst.b	(a1)		; if search string ends during inner loop
	beq.s	.matched_whole	; then we must have matched fully
	cmp.b	(a1)+,(a2)+
	beq.s	.next_inner
.return
.no_start
	cmp.l	end(a5),a3
	bne.s	.next_outer

.cleanup
	print	done(pc),hitcnt(a5)
	rts

.matched_whole
	cmp.l	a3,a4
	beq.s	1$		; don't report own copy
	cmp.b	#'"',-1(a3)	; don't report if begins with quotes
	beq.s	1$

	; we got a match!

	move.l	a3,address(a5)
	print	hit(pc),address(a5)
	addq.l	#1,hitcnt(a5)

	; check for CTRL-C and die if neccessary
	move.l	4.w,a6
	moveq	#0,d0
	moveq	#0,d1
	jsr	_LVOSetSignal(a6)
	move.l	dosbase(a5),a6
	btst.l	#SIGBREAKB_CTRL_C,d0
	beq.s	2$
	error	BREAK
	bra.s	.cleanup

2$	addq.w	#1,column(a5)
	cmp.w	#6,column(a5)
	blt.s	1$
	print	newline(pc)	; write newline every 7 columns
	clr.w	column(a5)
1$	bra.s	.return		; return to outer loop

begin	dc.b	'Grepping memory for "%ls" from $%lx to $%lx:',10,0
done	dc.b	10,'Grep finished, %ld hit(s).',10,0
hit	dc.b	'$%-8lx   ',0
newline=hit-2
padpos=hit+2

