;
; GRDP
;
; Copyright(c) LADsoft
;
; David Lindauer, camille@bluegrass.net
;
;
; Dump.asm
;
; Function: Handle the Dump command
;
	
	;MASM MODE
	.model small
	.386


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

DUMPLEN = 80h
	PUBLIC	dump
	PUBLIC  index,indexseg
	.data
index	dd	0		; Default for next dump
indexseg dw	0		;

;Debug reads each memory paragraph twice, once for the hex values and a
;second time for the ASCII values. This screws up at least two types of
;memory: memory-mapped IO when reads change the state of the device, and
;and FIFO devices with internal counters. So we read each location only once
;into this buffer, and then read the buffer to create the ASCII.

linedata db	16 DUP (?)	;holds line so we read it only once

	.code
;
; Dump one line
;
dumpline	PROC
	push	esi
	push	dx
	push	ebx        		; EBX MUST be on second of stack
	push	ecx			; ECX MUST be on top of stack
	sub	ax,ax
	mov	al,bl  		; AL = lower byte of address
	and	al,15		; AL = lower nibble
	mov	ecx,16		; Total bytes to dump
	jz	short doline	; Go do hexdump if start of line = 0
	neg	al		; Else calculate number of bytes in line
	add	al,16		;
	movzx	Ecx,ax		; To ECX

doline:
	sub	[esp],ecx	; Decrement count which is on stack
	add	[esp+4],ecx	; Increment address which is on stack
	mov	al,16		; Get count of amount to space over
	sub	al,cl		;
	jz	short puthex	; Don't space over any, just put out hex

	push	cx		; Else ecx = spacecount * 3
	mov	cx,ax		;
	add	cx,cx		;
	add	cx,ax		;
blanklp1:
	call	PrintSpace      ; Dump spaces
	loop	blanklp1	;
	pop	cx

puthex:
	push	cx
	mov	di,offset linedata	; Now get the bytes to our buffer
	movzx	edi,di
	push	ds
	push	fs 			; fs:si was source
	pop	ds
	movzx	ecx,cx
	db	67h		; addrsize
	rep	movsb
	pop	ds
	pop	cx
	mov	si,offset linedata	
	push	cx		;
hexlp:
	call	PrintSpace	; Print a space
	lodsb
	call	PrintByte	; Print byte in hex
	loop	hexlp		; Loop till done
	pop	cx		;

	call	printSpace	; Print two spaces to seperate ASCII dump
	call	PrintSpace	;

	mov	si,offset linedata	
	sub	ax,ax		; Calculate amoun to space over
	mov	al,16		;
	sub	al,cl		;
	jz	short putascii	; None to space over, put ascii
	push	cx		; ECX = space value
	mov	cx,ax
blanklp2:
	call	PrintSpace	; Space over
	loop	blanklp2	;
	pop	cx		;
	mov	si,offset linedata	

putascii:
	mov	dl,[si]		; Get char
	inc	si		; Increment buffer
	call	PureChar
	loop	putascii
	pop	ecx		; Get count from stack
	pop	ebx		; Get address from stack
	pop	dx
	pop	esi
	ret
dumpline	ENDP	
;
; Main DUMP routine
;
dump	PROC	
	mov	ecx,DUMPLEN	; Default amount to dump
	call	WadeSpace	; Wade to end of spaces
	jz	short atindex	;
	call	ReadAddress	; Else read start address
	jc	dudone		; Quit on error
	call	WadeSpace	; Wade through spaces
	jz	short dodump	;
	call	ReadNumber	; Else read end offset
	jc	short dudone	;
	sub	eax,ebx		; Calculate length of dump
	mov	ecx,eax		;
	jmp	short dodump	; Go do dump
atIndex:
	mov	ebx,[index]	; Assume we want to dump from last index
	mov	dx,[indexseg]	;
dodump:
	
	call	defDS		; get DS
	mov	fs,dx
	test	[optdwordcommand],-1
	jnz	dumplp
	movzx	ebx,bx
	mov	eax,10000h
	sub	eax,ebx
	cmp	eax,ecx
	jnc	dumplp
	mov	ecx,eax
dumplp:
	call	scankey
	jnz	dusetadr
	push	ebx		;
	call	crlf
	pop	ebx		;
	mov	ax,dx		; Print the selector
	call	PrintWord	;
	push	dx		;
	mov	dl,':'		; Print a ':'
	call	PutChar
	pop	dx		;
	mov	eax,ebx		;
	mov	esi,ebx
	and	eax,0fffffff0h  ; Address low nibble = 0
	test	[optdwordcommand],0ffh
	jz	adrword
	call	PrintdWord	; Print address
	jmp	adrcmb
adrword:
	call	PrintWord
adrcmb:
	call	dumpline	; Dump a line
	or	ecx,ecx		; Continue while count > 0
	jg	dumplp
dusetadr:		;
	mov	[index],ebx	; Save new index value
	mov	[indexseg],dx	;
	clc			; No errors
dudone:
	ret
dump	ENDP	
END