	.sbttl	define macros from IN:K11MAC.MAC
	.nlist

;	include file for kermit-11
;
;	Brian Nelson  01-Dec-83  13:56:12


	k11inc	=	1

;	the $RWDAT psect MUST be first for RT11 so that the added
;	QUEUE words are never mapped by APR1 for the XM exec.

	.psect	$rtque	,rw,d,gbl,rel,ovr
	.psect	$rwdat	,rw,d,gbl,rel,con
	.psect	$code	,ro,i,lcl,rel,con
	.psect	$pdata	,ro,d,lcl,rel,con
	.psect

	soh	=	1		; packet start for synch
	cr	=	15		; a lonely carriage return
	lf	=	12		; it's normal companion
	ff	=	14		; sometimes a form feed is nice
	space	=	40		; don't ask
	del	=	177		; the RUBOUT
	esc	=	33		; and at last, escape

	r0	=	%0
	r1	=	%1
	r2	=	%2
	r3	=	%3
	r4	=	%4
	r5	=	%5
	sp	=	%6
	pc	=	%7




	.macro	strcat	dst,src
	mov	src	,-(sp)
	mov	dst	,-(sp)
	jsr	pc	,strcat
	.globl	strcat
	.endm	strcat


	.macro	strcmp	s1,s2
	mov	s2	,-(sp)
	mov	s1	,-(sp)
	call	strcmp
	.globl	strcmp
	.endm	strcmp

	.macro	strcpy	dst,src
	mov	src	,-(sp)
	mov	dst	,-(sp)
	jsr	pc	,strcpy
	.globl	strcpy
	.endm	strcpy

	.macro	textsrc	text
	.if b	,text
	.ift
	mov	#fgetcr0,getcroutine
	clr	tgetaddr
	.iff
	mov	#tgetcr0,getcroutine
	mov	text	,tgetaddr
	.endc
	.globl	getcroutine,tgetaddr,fgetcr0,tgetcr0
	.endm	textsrc




;	The following macro is for RT systems w/o clock. It will loop for
;	the .twait, you must insert check as in:
;
;	tst	clkflg			; does this systems have a clock
;	bne	10$			; yes
;	cpuwait	#time			; no
;	br	20$			; 
; 10$:	.twait	#rtwork,#timarg		; clock is present with twait support
; 20$:

	.macro	cpuwait	ticks		; loop for specified number of ticks
	mov	ticks	,-(sp)		; Adjust the inner loop for timing of
	clr	-(sp)			; 1/60 of a second (one clock tick)
	mov	#13700/2,(sp)		; this inner loop takes 1/60 second
	dec	(sp)			; with a vaule of 13700 (8) on a
	bne	.-2			; PDP 11/44, try 13700/2 for default.
	dec	2(sp)			; end of inner loop, now do the outer
	bne	.-14			; loop
	cmp	(sp)+	,(sp)+		; all done
	.endm	cpuwait





;	Define IXOR macro to get around the mode restrictions for
;	the hardware XOR  instruction and to fix for RT11 systems
;	that don't have the EIS chip option.



	.macro	indexm	reg		; check for auto increment/decrement
	.ntype	$$$0	,reg		; modes for macro's that can't have
	.if	ne	,$$$0-27	; always allow pc autoincrement
	$$$0	=	<$$$0 & 177770>/10 ; these modes in their arg list.
	.ift				;
	.if	ge	,$$$0-2		; get the mode into 0..7
	.ift				; if mode >= 2 and mode <= 5 then error
	.iif	ge	,5-$$$0, .error	; can't use auto inc/dec mode here
	.endc				;
	.endc				;
	.endm	indexm			; end of indexm macro


	.macro	ixor	reg,dst		; do this for rt11 versions
	.chksp	reg			; can't allow SP args
	.chksp	dst			; can't allow SP args
	indexm	reg			; check for allowed addressing mode
	indexm	dst			; check for allowed addressing mode
	mov	reg	,-(sp)		; it's much simpler to do this
	bic	dst	,@sp		; for all rt systems rather than
	bic	reg	,dst		; to be selective
	bis	(sp)+	,dst		; all done
	.endm	ixor			; for RT11 xor

	.macro	xor	reg,dst
	ixor	reg,dst
	.endm	xor




	.macro	clrpar	reg
	clr	-(sp)
	bisb	reg	,@sp
	call	clrpar
	clr	reg
	bisb	(sp)+	,reg
	.globl	clrpar
	.endm	clrpar

	.macro	setpar	src,dst
	movb	src	,-(sp)
	call	dopari
	movb	(sp)+	,dst
	global	<dopari>
	.endm	setpar


	.macro	tochar	src,dst
	clr	-(sp)
	bisb	src	,@sp
	add	#40	,@sp
	movb	(sp)+	,dst
	.endm	tochar

	.macro	unchar	src,dst
	clr	-(sp)
	bisb	src	,@sp
	sub	#40	,@sp
	movb	(sp)+	,dst
	.endm	unchar

	.macro	ctl	src,dst
	clr	-(sp)
	bisb	src	,@sp
	call	l$xor
	movb	(sp)+	,dst
	global	<l$xor>
	.endm	ctl
	

	.macro	spack	type,pnum,len,msg
	.if b	,len
	.ift
	.iif nb	,msg	,.error	; bad call to SPACK macro
	calls	spack$	,<type,pnum,#0,#null>
	.iff
	calls	spack$	,<type,pnum,len,msg>
	.endc
	.globl	null
	.endm	spack

	.macro	rpack	len.a,pakn.a,msg.a
	sub	#10	,sp
	mov	sp	,r1
	calls	rpack$	,<msg.a,r1>
	mov	(r1)+	,len.a
	mov	(r1)+	,pakn.a
	mov	@r1	,r1
	add	#10	,sp
	.endm	rpack

	.macro	strlen	string
	mov	string	,r0
	call	l$len
	global	<l$len>
	.endm	strlen

	.macro	push	reg
	mov	reg	,-(sp)
	.endm	push

	.macro	pop	reg
	mov	(sp)+	,reg
	.endm	pop

	.macro	rodata
	.psect	$pdata
	.endm	rodata


	.macro	code
	.psect	$code
	.endm	code

	.macro	direrr	val
	mov	val	,-(sp)
	call	direr$
	.globl	direr$
	.endm	direrr



	.macro	copyz	from,to,maxlen
	.if	b,maxlen
	.ift
	clr	-(sp)
	.iff
	mov	maxlen	,-(sp)
	.endc
	mov	from	,-(sp)
	mov	to	,-(sp)
	call	copyz$
	.globl	copyz$
	.endm	copyz


	.macro	message	txt,docr
	.save
	.psect	$pdata
	$$ = .
	.if b	,<txt>
	.ift
	.byte	15,12,0
	.iff
	.asciz	@txt@
	.endc
	.even
	.restore
	mov	#$$	,-(sp)		; dump the text next please
	call	mout			; to the terminal
	.globl	mout			; perhaps
	.if nb	,<txt>
	.ift
	.iif nb,docr, message
	.endc
	.endm	message

	.macro	scan	ch,str
	mov	str	,-(sp)
	clr	-(sp)
	bisb	ch	,@sp
	call	scanch
	.globl	scanch
	.endm	scan

	.macro	incm64	val
	save	<r2,r3>
	mov	val	,r3
	inc	r3
	clr	r2
	div	#100	,r2
	mov	r3	,val
	unsave	<r3,r2>
	.endm	incm64

	.macro	iferr	lab
	tst	r0
	bne	lab
	.endm	iferr

	.macro	.newline	; print crlf on channel 0 (KB:)
	call	l$pcrlf
	.globl	l$pcrlf
	.endm	.newline

	.macro	save	list
	.if b , <list>
	.ift
	 save	<r0,r1,r2,r3,r4,r5>
	.iff
	.irp	x,<list>
	 mov	x,-(sp)
		.endr
	.endc
	.endm	save


	.macro	unsave	list
	.if b , <list>
	.ift
	unsave	<r5,r4,r3,r2,r1,r0>
	.iff
	.irp	x,<list>
	 mov	(sp)+,x
		.endr
	.endc
	.endm	unsave

	.macro	print	s,l
	.print	s,l
	.endm	print

	.macro	.print	stradr	,strlen

	 .ntype	$$6	,stradr
	 .iif eq, $$6 - 25, .error stradr; can't use (r5)+ in .print
	 .iif eq, $$6 - 45, .error stradr; can't use -(r5) in .print
	  save	<r5>			; Same as the RT11 .print but
	  .if 	b	,strlen		; allows an optional length
	   .ift				; to be passed as an argument.
	     clr -(sp)
	   .iff
	     mov strlen	,-(sp)
	  .endc

	  mov	stradr	,-(sp)
	  mov	sp	,r5
	  call	l$ttyou			; Example: .print r5,#12.
	  .globl	l$ttyou
	  add	#4	,sp		;          .print #str
	  unsave	<r5>		;   str:   .asciz /HELLO/

	.endm	.print

	.MACRO	GLOBAL	LIST
	.GLOBL	LIST
	.ENDM	GLOBAL

	.MACRO	.ASSUME	ARG1,COND,ARG2
	.IF	COND	<ARG1>-<ARG2>
	.IFF
	.ERROR	ARG1 ;"COND ARG2" FAILS
	.ENDC
	.ENDM	.ASSUME

	.macro	.chksp	arg
	.ntype	$$5	,arg
	.iif eq,<$$5 & 7>-6, .error arg ; Illegal use of SP(r6) in call
	.endm	.chksp

	.macro	decout	val
	mov	r5	,-(sp)
	clr	-(sp)
	mov	val	,-(sp)
	mov	sp	,r5
	call	l$wrdec
	cmp	(sp)+	,(sp)+
	mov	(sp)+	,r5
	.globl	l$wrdec
	.endm	decout

	.macro	octout	val
	calls	l$wroct	,<val>
	.endm	octout

	.macro	deccvt	val,buf,width
	mov	r5	,-(sp)
	.if	b,width
	.ift
	clr	-(sp)
	.iff
	mov	width	,-(sp)
	.endc
	mov	val	,-(sp)
	mov	buf	,-(sp)
	mov	sp	,r5
	call	l$cvtnum
	add	#6	,sp
	mov	(sp)+	,r5
	.globl	l$cvtn
	.endm	deccvt


;	CALLS macro
;
;	subroutine call with arguements passed in an area
;	pointed to by R5 (similiar to F4 and BP2). All args
;	are pushed onto the stack, with the first args  at
;	the lower address and the last ones at the  higher
;	addresses. R5 will point to the SP before the call.
;	R5 is saved and restored.



	.macro	calls	name,arglst,gbl	; standard  call  macro using
					; the hardware stack (%6) for
	  .if b, gbl
	  .ift
	   .globl	name
	  .iff
	  .iif dif, 'gbl ,nogbl, .globl name
	  .iif dif, 'gbl ,NOGBL, .globl name
	  .endc
	  $$	=	0		; arguement transmission with
	  .irp	x	,<arglst>	; r5 passed as  a pointer  to
	    $$	=	$$ + 1		; to the arguement list.  The
	  .endr				; called name is declared globl
	 .if eq	,$$			; No args present ? If so, gen
	  .ift				; a simple jsr pc call to sub.
	    jsr	pc	,name		; No argument list given.
	  .iff

	    push	r5		; At least one arg in <arglst>
	    .if eq , $$ - 1		; One arguement in the list

	     .ift
	      mov	arglst	,-(sp)	; One arg. Generate less code
	      .chksp	arglst		; Check for SP modes on param.
	      mov	sp	,r5	; Set pointer to argument list
	      jsr	pc	,name	; call the subroutine
	      tst	(sp)+		; pop parameter list from stack
	      pop	r5		; restore r5 pointer

	     .iff			; argcount > 1


	      $$2	=	$$	; more than 1 arguement. Thus
	      .rept	$$		; extract the args in reverse
	      $$1	=	0	; order so that we might save
	      .irp x	,<arglst>	; a little core (4 words).
	       $$1	=	$$1 + 1	; Scan the arg list until we
	       .if eq	, $$2 - $$1	; we come to the last one we
		.ift			; before the one we just did.
		 .chksp	x		; Check for SP addressing mode.
		 mov	x	,-(sp)	; Push it, and exit the .irp.
		 .mexit			; exit
	       .endc
	      .endr
	      $$2 = $$2 - 1		; backwards to previous arg.
	      .endr
	      mov	sp	,r5	; Set up the argument lst ptr.
	      jsr	pc	,name	; and go to the routine.
	      .if ne , $$ - 2		; Gen 'Add 2*argnum, sp' ?
	      .ift			; yes, else gen CMP (sp)+,(sp)+
	       add	#$$*2	,sp	; fix the stack up, restore r5
	      .iff
	       cmp	(sp)+	,(sp)+
	      .endc
	      unsave	<r5>		; restore r5 pointer
	      .endc
	 .endc

	.endm	calls			; thats all


	

	.macro	bdump	adr,siz
	mov	siz	,-(sp)
	mov	adr	,-(sp)
	call	dump$b
	global	<dump$b>
	.endm	bdump



	.macro	dispat	val,dsp,baseval,basedsp,default
	.save
	.if nb	,baseval
	.ift
	.psect	genval	,ro,d,lcl,rel,con
baseval:
	.psect	gendsp	,ro,d,lcl,rel,con
basedsp:
	.word	default
	.iff
	.psect	genval	,ro,d,lcl,rel,con
	.if b	,val
	.ift
	.byte	0
	.even
	.iff
	.byte	val
	.psect	gendsp	ro,d,lcl,rel,con
	.word	dsp
	.endc
	.endc
	.restore
	.endm

	.macro	prsbuf	dst
	mov	dst	,r0
	call	prsarg
	.globl	prsarg
	.endm	prsbuf

	.macro	malloc	size
	mov	size	,r0
	call	malloc
	.globl	malloc
	.endm	malloc


;	offset into local and remote's parameter vectors

	p.spsiz	=	0		; spsizinelength
	p.time	=	1		; timeout
	p.npad	=	2		; number of pad characters
	p.padc	=	3		; the pad character
	p.eol	=	4		; eol char
	p.qctl	=	5		; control chracter quoting
	p.qbin	=	6		; 8 bit quote
	p.chkt	=	7		; flavor of checksuming to do
	p.rept	=	10		; repeated character prefix
	p.capas	=	11		; capability bitmask
	p.winds	=	12		; /43/ window size
	p.mxl1	=	13		; /43/ High order, long packet size
	p.mxl2	=	14		; /43/ Low order of long packet size
	p.vend	=	17		; end of parameter vector

	CAPA.A	=	10		; bit set for attribute handling
	CAPA.S	=	4		; /42/ Bit set for sliding windows
	CAPA.L	=	2		; /42/ Bit mask for long packets

	log$pa	=	1		; if set in TRACE then log all packets
	log$fi	=	2		; if set in TRACE then log all files
	log$co	=	4		; virtual terminal logging to disk
	log$st	=	10		; state logging
	log$rp	=	20		; dump each rpack character to local tt
	log$io	=	40		; dump anything read or sent
	log$al	=	log$fi ! log$pa	; all bits possible in TRACE
	log$al	=	log$co ! log$st ! log$al ! log$rp ! log$io
	log$op	=	100000		; the logfile is open now


	par$od	=	1		; set parity odd
	par$ev	=	2		; set parity even
	par$ma	=	3		; set parity mark
	par$sp	=	4		; set parity space
	par$no	=	5		; set parity none

	terminal=	-1		; terminal
	TEXT	=	0		; normal ascii text files
	BINARY	=	1		; image mode
	DECNAT	=	2		; 8bit record type /52/

	ter$cc	=	1		; if set for ttyini then allow ^C
	ter$xo	=	2		; if ter$bi then set xon/xoff back
	ter$bi	=	4		; use raw binary mode please
					; NOTE: ter$bi overrides ter$cc always
	ter$pa	=	10

	con$esc	=	'\-100

	sy$11m	=	1		;	for rsx11m
	sy$ias	=	3		;	for ias
	sy$rsts	=	4		;	for rsts
	sy$vms	=	5		;	for vms ame
	sy$mpl	=	6		;	for m+
	sy$rt	=	7		;	for rt11
	sy$pos	=	11
	sy$pro	=	11		;	for p/os ??


;	The PRO$XXX values directly correspond to the values used in RSTS
;	The JOB$XXX values are the values we would need to know at runtime
;	PRO$XXX value is stored (only ONCE, at startup) in PROCTYP
;	JOB$XXX value is stored (only ONCE, at startup) in JOBTYPE

	PRO$LOC	=:	0		; /45/ Process is a real user
	PRO$DIA	=:	1		; /45/ Dialup user
	PRO$BAT	=:	2		; /45/ Process is a batch user
	PRO$NET	=:	4		; /45/ Process is via DECNET
	PRO$SER	=:	6		; /45/ Process is Decnet server
	JOB$INT	=:	0		; /45/ Job is local,dial or net
	JOB$BAT	=:	1		; /45/ Job is batch

	LN$MAX	=	80.
	LN$CNT	=	5
	LN$ALL	=	10.

	tty	=	0		;
	vt100	=	1		;
	vt200	=	2
	vtpos	=	3
	vtprt11	=	4

	$rdata	=	1
	$sdata	=	2

	MAXLNG	=	600.		; /42/ Long packet buffer size


	.list
