;
; GRDB
;
; Copyright(c) LADsoft
;
; David Lindauer, camille@bluegrass.net
;
;
; COMPARE.ASM
;
; Function: compare memory regions
;
	;MASM MODE
	.MODEL SMALL
	.386


include eprints.inc 
include einput.inc 
include emtrap.inc 
include eoptions.inc

	PUBLIC	compare
	PUBLIC	paddr


	.CODE

;Set DS if valid address provided in input
; INPUT: SI points to input to parse
; OUTPUT: DX contains segment address to use
;	CY if

cra	PROC
	call	ReadAddress		; read source address
	jc	crax			; none found
	test	[optdwordcommand],1	;see if flat real mode
	jnz	nomvz			;if set, no zero extend
	movzx	ebx,bx			;else extend
nomvz:
	call	defDS			; get data seg
crax:
	ret
cra	ENDP

;INPUT: AL has byte (two hex chars) to print

pbyte	PROC
	call	PrintByte
	call	printspace
	ret
pbyte	ENDP

;INPUT: EDX has segment address
;	EAX has offset address
;If flat real mode, print 32-bit offset, else print 16-bit offset

paddr	PROC
	xchg	eax,edx			;now EDX=offset, EAX=segment
	call	printword		;display segment
	xchg	edx,ebx			;store offset in EBX
	mov	dl,':'			;putchar wants char in DL
	call	putchar			;print colon
	mov	eax,ebx			;put offset in EAX
	test	[optdwordcommand],1	;printing 32-bit offsets?
	jnz	pdw			;if so, do that
	call	printword		;else just 16 bits
	call	printspace
	ret
pdw:
	call	printdword		;print 32-bit offset
	call	printspace
	ret
paddr	ENDP
;
; compare command
; syntax is c start,end,start2
;
compare	PROC
	call	WadeSpace		;find source address
	jz	errx			;not found (end of input)
	call	cra 			;start seg in DX, offset in EBX
	jc	errx			;not found
	push	dx			;save segment
	push	ebx			;and starting offset
	call	WadeSpace		;see if any more
	jz	errx2			;nope, didn't find
	call	ReadNumber		; read ending offset
	jc	errx2			;not found
	mov	ecx,eax			;get ending offset into ECX
	sub	ecx,ebx			;subtract starting offset
	jb	errx2			;error if end < start
	call	WadeSpace		;else keep reading input
	jz	errx2			;need a destination
	call	cra			; read dest seg and ofs
	jc	errx2			;not found
	call	WadeSpace		;make sure no more
	jnz	errx2			;if more, syntax error
	test	[optdwordcommand],1	;flat real mode?
	jnz	gotsz			;fine if so
	movzx	ebx,bx			;else zero extend dest offset
	movzx	ecx,cx			;and length to compare
	movzx	eax,word ptr [esp]	;and starting offset (on stack)
	mov	[esp],eax
gotsz:
	pop	esi    			;get start ofs from stack to ESI
	mov	edi,ebx			;and ending offset to EDI
	push	dx			;save segment
clp:
	push	ds			;save current DS
	push	es			;and ES
	mov	ds,[esp+6]		;pushed as DX just before clp:
	mov	es,[esp+4]		;pushed as DX on line 5 of routine
	db	67h			;dword override on operand
	repe	cmpsb			;cmp ds:[esi] with es:[edi]
	mov	al,ds:[esi-1]		;differing byte from source in AL
	mov	ah,es:[edi-1]		;and dest in AH
	pop	es			;back to our ds
	pop	ds			;and ES
	jz	cdone			;no difference in this case
	mov	dx,[esp+2]		;now dest segment into DX
	push	ax			;save differing bytes
	call	crlf			;new line
	mov	eax,esi			;location where different
	dec	eax			;minus cmpsb moved ESI past it
	call	paddr			;show ESI where different
	pop	ax			;restore differing bytes
	push	ax			;and save them again
	call	pbyte			;show source byte
	pop	ax			;get them back
	mov	al,ah			;setup dest byte
	call	pbyte			;and show that
	mov	eax,edi			;get dest offset
	mov	dx,[esp]		;and dest segment still on stack
	dec	eax			;minus correction for cmps
	call	paddr			;show dest seg:ofs
	jmp	clp			;find next difference
	
cdone:
	add	sp,4
	clc				; to clean up stack
	ret
errx2:
	add	sp,6
errx:
	stc
	ret
compare	endp
end