	.title	memdmp	Dump memory or registers
	.ident	"V02.00"
;+
;
; Index		Dump memory or registers
;
; Usage
;
;	memdmp(start, end);	/* Memory dump routine	*/
;	char *start;            /* First to dump */
;	char *end;              /* Last to dump */
;
;	regdmp();		/* Register dump */
;
; Internal
;
;	call	regdmp		;Register dump
;
;	mov	#end,-(sp)	;Last address	(or first)
;	mov	#start,-(sp)	;First address	(or last)
;	call	memdmp		;Dump memory
;
;	mov	#start,r0	;First address	(or first)
;	mov	#end,r1		;Last address	(or last)
;	call	$$dump		;Dump memory
;
;	mov	value,r0	;What to convert
;	mov	#buffer,r1	;Where it goes
;	call	$$toct		;Convert it
;
;	Return:
;		r0	unchanged
;		r1	-> first free byte in buffer
;		r2-r5	unchanged
;
; Description
;
;	Dump registers and/or memory.  All registers are preserved.
;
;	If memdmp is called with a zero argument, the stack will
;	be dumped.
;
; Bugs
;
;	Condition codes are not preserved.
;
;-
; Edit history
; V02.00 18-Oct-82 TTC		Rework of old CS library
;

start	=	20		;Start address on stack
end	=	22		;End address on stack

;
; Data areas
;
	.psect	c$strn

crlf:	.byte	15,12,0

stkmsg::
	.asciz	<15><12>/Stack Dump : /<15><12>

memsg::
	.ascii	<15><12>"Memory dump from "
m1:	.ascii	"??????"
	.ascii	" to "
m2:	.ascii	"??????"
	.ascii	":"
	.byte	0


$$regs::
	.ascii	"R0/?????? R1/?????? R2/?????? R3/?????? "
	.ascii	"R4/?????? R5/?????? SP/?????? PC/??????"
	.byte	0

line:	.blkb	6.+1+<8.*7>
	.byte	0
	.even

	.psect	c$code

memdmp::
	jsr	r5,$$svrg	;Register save sequence
	mov	start(sp),r0	;Start address
	mov	end(sp),r1	;End address
	call	$$dump		;Do it
	rts	pc		;And return

$$dump::
	mov	r5,-(sp)	;Save all registers
	mov	r4,-(sp)	;So a stack dump dumps
	mov	r3,-(sp)	;Them, too.
	mov	r2,-(sp)	;
	mov	r1,-(sp)	;End address is on top of stack
	mov	r0,r2		;Get start address
	bne	8$		;Memory dump branches
	mov	#stkmsg,r3	;No, it's a stack dump, r3 = message
	mov	sp,r2
	mov	sp,(sp)		;Fake: we can't find the initial
	add	#100,(sp)	;stack in rsx11-m
	br	10$

8$:	mov	#memsg,r3	;r3 = message

;
; Common dump routine.
;
	mov	r2,r0		;Get start address
	mov	#m1,r1		;Where text goes
	call	$$toct		;Make it readable
	mov	(sp),r0		;Get end address
	mov	#m2,r1		;Where it goes
	call	$$toct		;Print it

10$:
	mov	#crlf,-(sp)	;Print a <cr> <lf>
	call	ttosf
	mov	r3,(sp)		;Put message on stack
	call	ttosf		;Print message
	tst	(sp)+		;pop stack
;
; Normalize memory to 20 octal boundaries
;
	cmp	(sp),r2		;End lower than start?
	bhis	15$		;No, do it as planned
	mov	r2,r0		;Yes, fix
	mov	(sp),r2		; it
	mov	r0,(sp)		;  up.

15$:
	bic	#17,r2		;Round start down
	add	#17,(sp)	;Round end
	bic	#17,(sp)	;Up
20$:
	cmp	r2,(sp)		;Far enough?
	bhi	40$		;If so, exit
	mov	#8.,r3		;Do eight words
	mov	#line,r1	;To here
	mov	r2,r0		;First, do the start address
	call	$$toct		;Make it ascii
	movb	#'/,(r1)+	;Then some documentation
;
; Loop for each word to be dumped
;
30$:	movb	#' ,(r1)+	;First a space
	mov	(r2)+,r0	;Then, do
	call	$$toct		;The word
	dec	r3		;count it
	bne	30$		;and loop
	mov	#line,-(sp)
	call	ttosf
	mov	#crlf,(sp)
	call	ttosf
	tst	(sp)+
	br	20$		;Do next line, too
;
; Exit
;
40$:	tst	(sp)+		;Drop end address
	mov	(sp)+,r2	;Restore original registers
	mov	(sp)+,r3
	mov	(sp)+,r4
	mov	(sp)+,r5
	return


.sbttl	Register dump routine

regdmp::
	mov	r5,-(sp)	;Save all registers
	mov	r4,-(sp)
	mov	r3,-(sp)
	mov	r2,-(sp)
	mov	r1,-(sp)
	mov	r0,-(sp)
; Do the stack
	mov	#6.,r3		;How many general registers
	mov	sp,r2		;First register is at 0(sp)
	mov	#$$regs+3,r1

10$:	mov	(r2)+,r0	;Get word to dump
	call	$$toct		;Go for it
	add	#4,r1		;Space over " R?/"
	dec	r3		;count it
	bne	10$		;and loop
	mov	sp,r0		;Get stack
	add	#<7.*2>,r0	;When we were called
	call	$$toct		;Do it, too
	add	#4,r1		;Skip to PC entry
	mov	(r2)+,r0	;Get it in
	mov	#crlf,-(sp)
	call	ttosf
	call	$$toct
	mov	#$$regs,(sp)
	call	ttosf
	tst	(sp)+
	mov	(sp)+,r0	;Put them back
	mov	(sp)+,r1
	mov	(sp)+,r2
	mov	(sp)+,r3
	mov	(sp)+,r4
	mov	(sp)+,r5
	return


	.sbttl	Convert integer to six octal digits

$$toct::
	mov	r0,-(sp)	;Save r0 for return
	movb	#30,(r1)	;Magic number gets shifted to "0" or "1"
	sec			;This gets shifted around to force 6 digits
	br	30$		;Join main sequence
10$:	movb	#206,(r1)	;The "2" shifts into the carry to time loop
20$:	asl	r0		;Drop a bit (sec above will keep us going)
	rolb	(r1)		;Put a bit in
	bcs	20$		;Keep going if more bits
30$:	rol	r0		;Now for the last bit
	rolb	(r1)+		;Stuff it into the string
	cmp	r0,#100000	;Only the flag bit left?
	bne	10$		;No, get another byte
	mov	(sp)+,r0	;Restore r0
	return			;and exit.
	.end
