	.title dskpat - general disk block patcher
	.ident	/003B/
	.enabl	lc
;
; Author: L. M. Fraser		Apr, 80		V3 - Mar, 82
;
	.mcall	fhdof$,hmbof$
	.mcall	qiow$,dir$,alun$,exit$s,glun$,svtk$,spwn$,wtse$
	.mcall	istat$,state$,tran$
;
;+
; DSKPAT - Disk block patcher
;
;-
;BUILD+
;
; mac	dskpat,dskpat/-sp=[1,1]exemc/ml,[uic]dskpat
; tkb	dskpat,dskpat/-sp=dskpat
;	/
;	asg=ti:1	! command input lun
;	asg=ti:2	! dump lun #1
;	asg=lp:3	! dump lun #2
;	asg=nl:3	! disk lun (nl: for safty)
;BUILD-

	.nlist	bex
	hmbof$
	fhdof$
; defines
	NSAVE	= 4	; number save buffers
	DMPROW	= 10	; number of rows per dump
	CR = 15
	LF = 12
	BEL = 7
	SPC = 40

; task build time stamp
	.psect	$$dbts
$dbts::	.blkw	10	; date/time block from TKB

; documentation
	.psect	string
hlptxt:
	.ascii	<CR><LF>/DSKPAT - General DISK Block Patcher/
	.ascii	/  Task built: /
bldtxt:
.ascii	/				                    /
.ascii	<CR><LF>/  Functions:                                   V003B/
.ascii	<CR><LF>/	get [ LBN ] /
.ascii	<CR><LF>/	put [ LBN ] /
.ascii	<CR><LF>/	set {LBN, READONLY, INDEXF, BAD, TERMINAL, PRINTER}/
.ascii	<CR><LF>/	next/
.ascii	<CR><LF>/	dump {o,b,a,r,h,f,d} [ loc ]/
.ascii	<CR><LF>/	  {octal, byte, ascii, rad50, home, file, directory}/
.ascii	<CR><LF>/	modify loc val/
.ascii	<CR><LF>/	display loc/
.ascii	<CR><LF>/	status/
.ascii	<CR><LF>/	home [ set,verify ]/
.ascii	<CR><LF>/	block [ set,verify ]/
.ascii	<CR><LF>/	save [ buf ]/
.ascii	<CR><LF>/	restore [ buf ]/
.ascii	<CR><LF>/	mcr command_line_text/
.ascii	<CR><LF>/	done/
.ascii	<CR><LF>/	help/
.ascii	<CR><LF>/  Missing options default to NEXT, ZERO or VERIFY/
.ascii	<CR><LF>/  LBNs can be #, NEXT, PREV, BOOT, HOME, INDEX, or LAST/
	.byte	CR, LF

	hlptxl	= .-hlptxt
	.even

; macros
	.macro error string,pre,?aaa,?bbb
	br	bbb
aaa:
	.if nb pre
	.ascii	/pre -- /
	.endc
	.ascii	/string/
	.even
bbb:
	trap 	<bbb-aaa>/2
	.word	aaa
	.endm
;
	.psect	dpbs
; directive dpb's
msg:	qiow$ io.wvb,1,1,,iosb,,<cmdbuf,,40>
dev:	qiow$ io.rpr,1,1,,iosb,,<cmdbuf,80.,,prmtd,prmtdl,0>
cmd:	qiow$ io.rpr,1,1,,iosb,,<cmdbuf,80.,,prmtc,prmtcl,0>
dump:	qiow$ io.wvb,2,2,,iosb,,<dmpbuf,,40>
disk:	qiow$ io.rlb,4,4,,iosbdd,,<blkbuf,512.,,0,0>
att:	qiow$ io.att,4,4,,iosbdd
det:	qiow$ io.det,4,4,,iosbdd
alun:	alun$ 4,NL,0
glun:	glun$ 4,lunbuf
svtk:	svtk$ sstvec,10
spawn:	spwn$ mcr...,,,,,1,,exstat,cmdbuf,80.
wait:	wtse$ 1
;
	.psect	string

prmtd:	.ascii	<CR><LF><BEL>/Device? /
 prmtdl	= .-prmtd
prmtc:	.ascii	<CR><LF>/*Cmd? /
 prmtcl	= .-prmtc
	.even
;
asc:	.rad50	/nulsohstxetxeotenqackbelbs ht lf vt /
	.rad50	/ff cr so si dledc1dc2dc3dc4naksynetb/
	.rad50	/canem subescfs gs rs us sp /
;
romsg:	.asciz	/READONLY/
null:	.asciz	/ /
;

func	= disk + q.iofn
blkl	= disk + q.iopl+10
blkh	= disk + q.iopl+6
;
	.psect	data
;		should add oddadd to list in 0 & 1
sstvec:	.word	0,0,0,0,0,0,trap,0
lunbuf:	.blkw	8.			; get lun buffer
exstat:	.blkw	8.			; spawn exit status block
;
cmdbuf:	.blkb	80.			; command input buffer
dmpbuf:	.blkb	132.			; dump output buffer
	; don't separate iosb and blkbuf ****
iosb:	.word	0,0			; QIO status block
iosbdd:	.word	0,0			; Disk QIO status block
blkbuf:	.blkb	512.			; disk bufer
	; don't separate iosb and blkbuf ****
savbuf:
	.rept	nsave
	  .blkb	512.			; save buffers
	.endr
savlbn:
	.rept	nsave
	  .word	0,0			; saved buffer LBN's
	.endr
lastlb	= lunbuf+g.lucw+2		; last good LBN on volume
idxlbn:	.word	0,0			; indexf file LBN from home block
;
pflags:	.word	0			; permanent flags word
					;  low byte  - latching per device
					;  high byte - latching is permanent
; defined bits for pflags
	ROFLG = 1			; device is readonly

flags:	.word	0			; flags word
loc:	.word	0			; buffer offset
val:	.word	0			; value buffer
;
savblk:	.word	0			; save buffer used
dswsav:	.word	0			; saved $DSW
;
fmt:	.word	0			; format string address
argblk:	.blkw	40.			; argument block for EDMSG
;
	.psect	format
;
fmtoct:	.asciz	/%8P/			; octal format
fmtbyt:	.asciz	/%P-	%16B/		; byte format
fmtasc:	.asciz	/%P-	%16E/		; extended ascii format
fmtr50:	.asciz	/%8R/			; radix 50 format
fmtdir:	.asciz	/FID:%P:%P:%P %X/	; directory structure
; status display
fmtsta:	.ascii	/ ** STATUS ** %2A%B:  %I%N/
	.ascii	/Next  LBN:	%T%N/
	.ascii	/Saved LBN:	%VT%N/
	.ascii	/MAX   LBN:	%T%N/
	.asciz	/$DSW = %P  IOSB = %4B%N/
	.even
;
; dispatch table for dump routines
dispat:	.word	dmpoct,dmpbyt,dmpasc,dmpr50,dmphom,dmpfil,dmpdir,0,0,0
	.page
	.psect	code
;
; code ....
; entry point and initialization ..
dskpat::
	dir$	#svtk			; set up trap catcher
	mov	#bldtxt,r0		; point to tkb time loc
	mov	#$dbts,r1		; and to block set up by tkb
	call	$dat			; load in date string
	movb	#spc,(r0)+		; space it out
	mov	#4,r2			; request tenths of seconds
	call	$tim			; convert it
	br	getdev			;
;
deverr:	mov	$dsw,dswsav		; save $DSW for status
	error	<Device error>
;
; device loop ..
getdev:
	dir$	#dev			; get device spec
	bcs	10$			; abort on error
	cmpb	iosb,#IS.SUC		; QIO OK?
	beq	20$			; continue if good
10$:	exit$s				; exit program
;
20$:	mov	iosb+2,r1		; any thing there?
	beq	getdev			; no, get another line
	mov	#cmdbuf,r0		; point to chars received
	mov	#alun+a.luna,r1		;  and to out loc
	mov	#2,r2			; fixup only two
	call	$cvtuc			; copy and make upper case
	mov	#cmdbuf+2,r0		; point to any digits
	call	$cotb			; convert any unit number
	mov	r1,alun+a.lunu		; set unit number
	cmpb	r2,#':			; finished device right
	bne	deverr			; report error
	dir$	#alun			; assign device
	bcs	deverr			; something wrong on CS
	dir$	#glun			; OK, find about disk
	bcs	deverr
; probably should do mountable, etc checks here, but screw it, let him think
	dir$	#att			; attach disk
	bcs	deverr
	clrb	lunbuf+g.lucw+3		; flush drivers trash
	sub	#1,lastlb+2		; convert from size to LBN
	sbc	lastlb			;  and high part
	mov	#-1,idxlbn		; trash any saved indexf LBN
	clrb	pflags			; clear device specific flags
;
; command loop
getcmd::
	clr	flags			; init some data
	clr	loc
	clr	val
	dir$	#cmd			; get a command
	bcs	10$			; abort on error
	cmpb	iosb,#IS.SUC		; QIO OK?
	beq	20$			; continue if good
10$:	exit$s				; exit program
;
; set up for .tpars
20$:	mov	iosb+2,r3		; length of string
	beq	getcmd			;  can't be null
	mov	#cmdbuf,r4		; addr of string
	mov	r4,r0			; copy addr
	mov	r0,r1			; convert in place
	mov	r3,r2			;  this many chars
	call	$cvtuc
	mov	#3*256.,r1		; three char min, ignore blanks
	mov	#cmdkey,r2		; key tables
	mov	#first,r5		; transaction table addr
	.if df de$bug
	call	.tpard			; state tracking entry
	.iff
	call	.tpars
	.endc
	bcc	30$			; cc = no error
	error	<Illegal option>
30$:	tst	flags			; check exit flag
	bpl	getcmd			; do another command
	jmp	getdev			; or another device

	.page
;
; tpars state tables
	.dsabl lc
	.if df de$bug
	istat$	cmdtab,cmdkey,$DEBUG
	.iff
	istat$	cmdtab,cmdkey
	.endc
;
	state$	first
	tran$	"get",st.get,ac.get
	tran$	"put",st.get,ac.put
	tran$	"set",st.get,,1,flags
	tran$	"next",$exit,ac.nxt
	tran$	"dump",st.dmp
	tran$	"dmp",st.dmp
	tran$	"modify",st.mod
	tran$	"display",st.dsp
	tran$	"dsp",st.dsp
	tran$	"status",$exit,ac.sta
	tran$	"home",st.chk,,1,flags
	tran$	"block",st.chk
	tran$	"file",st.chk
	tran$	"done",$exit,,-1,flags
	tran$	"save",st.sav,,1,flags
	tran$	"restore",st.sav
	tran$	"mcr",st.mcr
	tran$	"help",$exit,ac.hlp
	tran$	'?,$exit,ac.hlp
;
	state$	st.get
	tran$	"next",$exit,incblk
	tran$	"previous",$exit,decblk
	tran$	"boot",$exit,booblk
	tran$	"home",$exit,homblk
	tran$	"indexf",$exit,idxblk
	tran$	"last",$exit,lstblk
	tran$	$eos,$exit,chkio
	tran$	$numbr,$exit,setblk
	tran$	"readonly",$exit,,ROFLG,pflags
	tran$	"inspect",$exit,,ROFLG,pflags
	tran$	"bad",$exit,ac.bad
	tran$	"terminal",$exit,ac.ter
	tran$	"printer",$exit,ac.pri
	tran$	$lamda,$exit,syntax
;
	state$	st.dmp
	tran$	'o,st.dm1,,0,flags
	tran$	'b,st.dm1,,2,flags
	tran$	'a,st.dm1,,4,flags
	tran$	'r,st.dm1,,6,flags
	tran$	'h,st.dm1,,10,flags
	tran$	'f,st.dm1,,12,flags
	tran$	'd,st.dm1,,14,flags
	tran$	$eos,st.dm1
	tran$	$numbr,$exit,ac.dmp
;
	state$	st.dm1
	tran$	$eos,$exit,ac.dm1
	tran$	$numbr,$exit,ac.dmp
	tran$	$lamda,$exit,syntax
;
	state$	st.mod
	tran$	$numbr,st.mo1,ac.mod
	tran$	$lamda,$exit,syntax
;
	state$	st.mo1
	tran$	$numbr,st.mo2,ac.mo1
	tran$	$lamda,$exit,syntax
;
	state$	st.mo2
	tran$	$eos,$exit
	tran$	$lamda,$exit,syntax
;
	state$	st.dsp
	tran$	$eos,$exit,ac.ds1
	tran$	$numbr,$exit,ac.dsp
	tran$	$lamda,$exit,syntax
;
	state$	st.sav
	tran$	$eos,$exit,ac.sa1
	tran$	$numbr,$exit,ac.sav
	tran$	$lamda,$exit,syntax
;
	state$	st.chk
	tran$	"set",st.ck1,,200,flags
	tran$	"verify",st.ck1
	tran$	$eos,st.ck1
	tran$	$lamda,$exit,syntax
;
	state$	st.ck1
	tran$	$lamda,$exit,ac.chk
;
	state$	st.mcr
	tran$	$eos,$exit,syntax
	tran$	$lamda,$exit,ac.mcr
;
; end of tables
	state$
	.page
	.enabl	lc
;
; action routines
	.psect	code
;
ac.get:	mov	#io.rlb,func		; set QIO to read
	return
;
ac.put:	bit	#ROFLG,pflags		; readonly access set?
	bne	10$			; bit set -> no writes
	mov	#io.wlb,func		; set QIO to write
	return
10$:	error	<Function set READONLY>
	return
;
incblk:	add	#1,blkl			; bump LBN low part
	adc	blkh			;  and high part
	br	chkio			; and do it
;
decblk:	sub	#1,blkl			; decrement LBN
	sbc	blkh
	br	chkio
;
booblk:	clr	blkl			; set to boot block
	clr	blkh			;  i.e. LBN 0
	br	chkio
;
homblk:	mov	#1,blkl			;  i.e. LBN 1
	clr	blkh			; set to home block
	br	chkio
;
idxblk:	tst	flags			; do setup if !=
	bne	setidx			; go get
	mov	idxlbn,blkh		; set to saved index file LBN
	bmi	10$			; if mi idx not set
	mov	idxlbn+2,blkl		; set up low part of LBN
	br	doio
10$:	error	<Must "set INDEX" to get LBN from HOME block first>
; the -1 left in blkh here is invalid anywhere, must explicitly get next LBN
	return
;
lstblk:	mov	lastlb,blkh		; set to last good block
	mov	lastlb+2,blkl		;
	br	chkio
;
setidx:	mov	blkbuf+2,idxlbn		; save index file LBN
	mov	blkbuf+4,idxlbn+2	;  and low part
	add	blkbuf,idxlbn+2		; skip over index bitmap
	adc	idxlbn			;
	return
;
setblk:	mov	.pnumb,blkl		; set low lbn
	mov	.pnumh,blkh		;  and high part
;
chkio:	tst	flags			; do I/O only if =
	beq	doio			; now do physical I/O
	return
;
; really should check block requested aginst MAX, but I'll let DRQIO do it
doio:	dir$	#disk			; do I/O to disk
	bcs	10$			; any dir errors
	cmpb	iosbdd,#IS.SUC		;  or I/O errors
	bne	10$			; yes report'em
	return				; nope, cont
10$:	mov	$dsw,dswsav		;
	error	<QIO error>		; report problem
	return
;
ac.ter:	mov	#2,dump+q.iolu		; set to terminal dumping
	return
ac.pri:	mov	#3,dump+q.iolu		; or to printer dumps
	return
;
ac.nxt:	add	#1,blkl			; increment LBN
	adc	blkh			;   (a 24 bit number)
	return
;
ac.dmp:	mov	.pnumb,loc		; get starting loc
ac.dm1:	call	dodump			; do dump
	return
;
ac.dsp:	mov	.pnumb,loc		; pick up number
ac.ds1:	mov	loc,r0			; copy offset
	mov	r0,r1			;  and again
	ror	r1			; byte address?
	bcs	10$			;  use movb
	mov	blkbuf(r0),r1		; get word needed
	br	20$
10$:	clr	r1			; init reg
	bisb	blkbuf(r0),r1		; pick up value
20$:	mov	#cmdbuf,r0		; point to buffer
;conversion routine from M+ TDX
cvt:	; enter w/ r0->buffer, r1=value
	mov	r1,-(sp)		; save the word value
	mov	r0,-(sp)		; save buffer addr
	mov	#40,r2			; clear buffer
10$:	mov	#"  ,(r0)+		; space fill
	sob	r2,10$			; loop
	mov	(sp)+,r0		; restore buffer addr
	movb	#11,(r0)+		; space over a tab
	clr	r2
	call	$cbdmg			; put in decimal word
	add	#2,r0
	clr	r1
	bisb	(sp),r1			; low order byte
	clr	r2
	call	$cbdmg			; decimal byte
	movb	#',,(r0)+
	clr	r1
	bisb	1(sp),r1
	clr	r2
	call	$cbdmg			; decimal high byte
	add	#2,r0			; some space
	movb	#'#,(r0)+
	mov	(sp),r1
	mov	pc,r2			; non-zero
	call	$cbomg
	add	#2,r0
	movb	#'#,(r0)+
	clr	r1
	bisb	(sp),r1
	mov	pc,r2
	call	$cbtmg
	movb	#',,(r0)+
	clr	r1
	bisb	1(sp),r1
	mov	pc,r2
	call	$cbtmg
	add	#2,r0
	movb	#'$,(r0)+
	mov	(sp),r1
	mov	#8720.,r2
	call	$cbta
	add	#2,r0
	movb	#'%,(r0)+
	mov	(sp),r1
	call	$c5ta
	add	#2,r0
	movb	#'",(r0)+
	cmpb	(sp),#40
	blos	20$
	cmpb	(sp),#177
	beq	23$
	bhi	25$
	movb	(sp),(r0)+
	br	30$
20$:	movb	#'<,(r0)+
	clr	r1
	bisb	(sp),r1
	asl	r1
	mov	asc(r1),r1
22$:	call	$c5ta
	movb	#'>,(r0)+
	br	30$
23$:	mov	#^rdel,r1
	br	22$
25$:	inc	r0
30$:
	cmpb	1(sp),#40
	blos	120$
	cmpb	1(sp),#177
	beq	123$
	bhi	130$
	movb	1(sp),(r0)+
	br	130$
120$:	movb	#'<,(r0)+
	clr	r1
	bisb	1(sp),r1
	asl	r1
	mov	asc(r1),r1
122$:	call	$c5ta
	movb	#'>,(r0)+
	br	130$
123$:	mov	#^rdel,r1
	br	122$
130$:	tst	(sp)+
	mov	#cmdbuf,r1		; get buffer addr
	sub	r1,r0			; get length
	mov	r1,msg+q.iopl		; set addr into DPB
	mov	r0,msg+q.iopl+2		; set len into DPB
	dir$	#msg			; do output
	return
;
ac.mod:	mov	.pnumb,loc		; set loc to fix
	return
;
ac.mo1:	mov	loc,r0			; get offset to fix
	mov	r0,r1			; copy offset
	ror	r1			; low bit set?
	bcs	10$			; yes, use byte manipulation
	mov	.pnumb,blkbuf(r0)	;  and do it
	return
10$:	movb	.pnumb,blkbuf(r0)	; set this high byte
	return
;
ac.sta:	mov	#argblk,r0		; get arg block
	mov	r0,r2			; copy for later
	mov	#lunbuf+g.luna,(r0)+	; point to device name
	mov	#lunbuf+g.lunu,(r0)+	;  and to unit number
	bit 	#ROFLG,pflags		; is device readonly?
	bne	10$			; NE means yes
	mov	#null,(r0)+		; point to null string
	br	20$
10$:	mov	#romsg,(r0)+		;  or to "READONLY" string
20$:	mov	#blkh,(r0)+		; point to next LBN field
	mov	#NSAVE,(r0)+		; repeat count for save buffers
	mov	#savlbn,r1		; first save LBN
	.rept NSAVE
	mov	r1,(r0)+		;  and location
	add	#4,r1			; point to next
	.endr
	mov	#lunbuf+g.lucw+2,(r0)+	; size of device
	mov	dswsav,(r0)+		; $DSW
	mov	#iosbdd,(r0)+		;  and I/O status block
;
	mov	#cmdbuf,r0		; get output buf
	mov	#fmtsta,r1		; get format string
	call	$edmsg			; make the string
	mov	#cmdbuf,msg+q.iopl	; set buffer address
	mov	r1,msg+q.iopl+2		;  and length
	dir$	#msg			; do it!!!!
	return
;
ac.sav:	mov	.pnumb,savblk		; set buffer to use
ac.sa1:	mov	savblk,r0		; get buffer to use
	cmp	r0,#nsave		; valid buffer?
	bmi	1$
	add	#2,(sp)			; reject trans
	return
1$:	mov	r0,r2			; save buffer number
	swab	r0			; mul by 512.
	asl	r0
	add	#savbuf,r0		; point to selected buffer
;
	tst	flags			; ne => save
	bne	10$
; restore
	mov	#blkbuf,r1		; set output to block buffer
	br	20$			; use common copy code
; save
10$:	mov	r0,r1			; copy output buffer addr
	asl	r2			; mul buf # by 4
	asl	r2
	mov	blkh,savlbn(r2)		; copy LBN
	mov	blkl,savlbn+2(r2)
	mov	#blkbuf,r0		; set input to block buffer
; common copy
20$:	mov	#256.,r2		; this many words
30$:	mov	(r0)+,(r1)+		; move it
	sob	r2,30$			; loop
	return
;
ac.chk: mov	#blkbuf,r0		; point to buffer
	clr	r1			; init for sum
	tstb	flags			; mi -> verify only
	bpl	ver.cs			; go verify for this block
	bit	#1,flags		; eq ->block sum
	beq	20$			; block only
	mov	#H.CHK1/2,r2		; location of first CS
10$:	add	(r0)+,r1		; calc sum
	sob	r2,10$			; loop
	mov	r1,(r0)			; load check sum
20$:	mov	#blkbuf,r0		; buffer again
	clr	r1			; init sum again
	mov	#255.,r2		; do whole block now
30$:	add	(r0)+,r1		; calc sum
	sob	r2,30$			; loop
	mov	r1,(r0)			; load it
	return
; verify only
ver.cs:	bit	#1,flags		; eq ->block sum
	beq	20$			; block only
	mov	#H.CHK1/2,r2		; location of first CS
10$:	add	(r0)+,r1		; calc sum
	sob	r2,10$			; loop
	cmp	r1,(r0)			; check-sum right
	bne	cserr			; report error
	error	<H.CHK1 OK>
20$:	mov	#blkbuf,r0		; buffer again
	clr	r1			; init sum again
	mov	#255.,r2		; do whole block now
30$:	add	(r0)+,r1		; calc sum
	sob	r2,30$			; loop
	cmp	r1,(r0)			; this one right?
	bne	cserr			; go report it
csok:	error	<Block-sum OK>
	return
;
cserr:	error	<Bad check-sum>
	return
;
dodump:	mov	flags,r1		; index into table
	mov	r3,-(sp)		; save a register
	mov	#DMPROW,r3		; do this many rows
	jmp	@dispat(r1)		; go to it...
; these following use the data itself as input for edmsg (r2 ->next data)
; octal
dmpoct:	mov	#1,r0			; mask odd bytes
	mov	#fmtoct,fmt		; set format address
	br	dmpcm1
; rad50
dmpr50:	mov	#1,r0			; mask odd bytes
	mov	#fmtr50,fmt		; select rad50 format
	br	dmpcm1
; directory
dmpdir:	mov	#17,r0			;  directories use mod 20
	mov	#fmtdir,fmt		; set format
; fall thru
dmpcm1:	mov	#blkbuf,r2		; data buffer addr
	bic	r0,loc			; mask offset for valid data
	add	loc,r2			; point to word
10$:	mov	#dmpbuf,r0		; place to put it all
	mov	loc,r1			; get current pointer
	mov	r2,-(sp)		; protect r2 from cbomg
	call	$cbomg			; convert
	mov	(sp)+,r2		; restore r2
	movb	#'-,(r0)+		; insert a separator
	movb	#11,(r0)+		; insert a TAB
	mov	fmt,r1			; get correct format
	call	$edmsg			; convert'em
	sub	#dmpbuf,r0		; calc length
	mov	r0,dump+q.iopl+2	; set length of buffer
	dir$	#dump			; send it out
	add	#20,loc			; update pointer
	sob	r3, 10$			; loop
	mov	(sp)+,r3		; restore reg
	return
; these use a single address and repeat count for edmsg
; bytes
dmpbyt:	mov	#fmtbyt,fmt		; select format string
	br	dmpcom
; ascii
dmpasc:	mov	#fmtasc,fmt		; select ascii format
;;;	br	dmpcom			; fall thru
; common code
dmpcom:	mov	#blkbuf,r0		; point to data
	bic	#1,loc			;  can't handle odd bytes
	add	loc,r0			; and to words
	mov	r0,argblk+2		;  data buffer address
;
10$:	mov	#dmpbuf,r0		; set output buffer address
	mov	fmt,r1			; and format address
	mov	#argblk,r2		; arg pointer
	mov	loc,(r2)		; put in the location
	call	$edmsg
	mov	r1,dump+q.iopl+2	; set up length
	dir$	#dump
	add	#20,loc			; update pointer
	add	#20,argblk+2		; bump to next data
	sob	r3,10$			; loop
	mov	(sp)+,r3		; restore reg
	return
; these are one shot specials
; home block
dmphom:
; file header
dmpfil:	error <not done yet>
	return
;
ac.hlp:	mov	#hlptxt,msg+q.iopl	; set text address
	mov	#hlptxl,msg+q.iopl+2	;  and length
	dir$	#msg			; dump it out
	return
;
ac.mcr:	mov	r4,spawn+s.pwca		; set command line address
	mov	r3,spawn+s.pwcl		;  and length
	dir$	#det			; release disk device
	dir$	#spawn			; start sub task
	bcs	20$			; error if CS
	dir$	#wait			; wait for it
	mov	exstat,dswsav		; put exit status where user can get it
	dir$	#att			; grab disk again
	return
;
20$:	mov	$dsw,dswsav		; save dsw
	error	<Bad SPAWN>
	return
;
ac.bad:
	error	<not done yet>
	return
;
syntax: error	<Syntax error>
	return
;
trap:	mov	(sp)+,msg+q.iopl+2	; get msg length
	mov	@(sp),msg+q.iopl	; and address
	add	#2,(sp)			; skip address
	dir$	#msg			; send msg
	rtt				; return from trap
;
	.end	dskpat

