.;+ XXTAB.CMD	- Creates an RSX-11M-PLUS device database
.;
.; 11-Jan-85	G Altobello
.;
	.enable substitution
	.disable lowercase		! no lowercase input allowed

	.sets ident "19-Aug-85"		! change to reflect last revision

	.goto begin

.CAVEAT:
;
; *** Revision history:
;
; 02-May-85	GWA	- Changed $CTB0:: to a local symbol.
; 15-Jul-85	GWA	- Moved "s$st2" substitution from SCBGEN to KRBGEN.
; 16-Jul-85	GWA	- Added "NPR device?" question and UMR work area to KRB.
;			- CSR/vector entry now follows all other questions.
;			- Omitted letters G, I, O, and Q in controller ident so
;			  we match DEC's bizarre lettering scheme.
;			- K.OFF always gets defined.
; 05-Aug-85	GWA	- Added test of "contig" for U.SCB parameter, so multi
;			  UCB's point to correct SCB if contiguous KRB/SCB.
; 11-Aug-85	GWA	- Fixed calculation for K.HPU
; 13-Aug-85	GWA	- Added .PSECT directive.
; 19-Aug-85	GWA	- Removed U.PRM comment at end of UCB since this isn't a
;			  real offset (Well, it is, but not what you'd expect.)
;
;
; *** Caveats -- for all those who would use or modify this program:
;
;	- The KRBs are named $XXA, $XXB, etc.  This is accomplished by a
;	  less-than-lovely usage of .IRPC and .IF macros, which is the best
;	  I could do.  Read the generated code carefully, and it will become
;	  obvious how things work.  The .DISABLE CND directive is used to
;	  keep the listing from becoming too crowded.
;
;	- A reminder that because SUBSTITUTION mode is enabled in this command
;	  file, two single quote characters must be used in a contraction.  If
;	  you don''t use two, you''ll get a substitution error (if you''re
;	  lucky).  This only applies to modifications to this command file.
;
;	- If you select the non-contiguous KRB/SCB format, you get one SCB for
;	  each UCB.
;
;	- All possible input combinations have not yet been tested...so check
;	  any output to be sure it is what you wanted.
;
	.return

.;
.; We start running here!
.;

.begin:
	.setn cnt 7					! ascii bell code
	.sets bell "'cnt%v'"				! ascii bell string

	.sets months "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"
	.sets alpha "ABCDEFHJKLMNPRSTUVWXYZ"		! max 21. controllers

	.enable decimal
	;
	; RSX-11M+ Device Table Generator		Ident: 'ident'
	;
	;	Type CRTL-Z to abort.
	;
	.ask yn Do you want to see the caveats
	.ift yn .gosub caveat

	.asks name What''s your name (for posterity...)
	.if name = "" .sets name "ANON"

	.asks [2:2] dev Enter the two-letter device mnenomic
	;
	.askn [1:21:1] nkrb Enter number of controllers (KRB''s) for device 'dev':
	;
	.askn [1:64:1] nucb Enter number of units attached to each controller
	;
	.askn [4:7:5] num Enter device priority
	.sets devpri "PR'num'"
	;
	; Answer the next question "Y" if your device needs the KRB extension
	;	for a UMR mapping assignment block.
	;
	.ask nprdev Is this an NPR device
	;

	.if nucb > 1 .goto 50		! more than one unit/controller?
	.; single unit controllers here
	.sett suc
	;	- This is a single unit controller
	.sett contig
	;
	;	- You will have the contiguous KRB/SCB format
	.setf ucbtbl
	;
	;	- There will be no UCB table in the KRB
	.goto 60

	.; multi-unit controllers here
.50:	.setf suc		! not a single-unit controller
	.ask contig Do you want the contiguous KRB/SCB format
	;
	.ask ucbtbl Should the KRB have a UCB table

.60:

.; get csr/vector for all controllers

	;
	; You must now enter the CSR''s and vectors for each controller.
	;	Enter two octal numbers separated by a comma, like this: 177560,60

.10:
	;
	.disable decimal	! default to octal
	.setn cnt 1

.; get the numbers & check them. beep & re-prompt if no good.
.20:
	.sets ltr alpha[cnt:cnt]
	.asks str Enter CSR/vector for controller "'dev''ltr'"
	.parse str "," csrs vecs
	.if csrs = "" .or .if vecs = "" .goto 30
	.test csrs
	.iff <octal> .goto 30
	.test vecs
	.ift <octal> .goto 35
.30:	;'bell'
	.goto 20

.; okay the data, create and assign vars.
.35:	.setn csr'ltr' 'csrs'
	.setn vec'ltr' 'vecs'
	.inc cnt
	.if cnt <= nkrb .goto 20

	;
	; Here are the controllers you have defined:
	;
	;	Controller	CSR	Vector
	;	==========	======	======
	.setn cnt 1
.40:
	.sets ltr alpha[cnt:cnt]
	.setn csr csr'ltr'
	.setn vec vec'ltr'
	;	   'dev''ltr'		'csr'	'vec'
	.inc cnt
	.if cnt <= nkrb .goto 40
	;
	.ask yn Are these correct
	.iff yn .goto 10
	;
	.enable decimal

	;
	;
	; *** Now beginning to build the file 'dev'TAB.MAC --
	;	this will take a few seconds.
	;
	.open 'dev'TAB.MAC

	.parse <date> "-" dy mn yr
	.; dy & yr are numbers, now convert mn from 3-letter string to number
	.test months mn
	.setn foo (<strlen>/3)+1
	.if foo < 10 .sets mn "0'foo'"
	.if foo > 9 .sets mn "'foo'"

	.sets x$$x11 dev[1:1]+"$$"+dev[2:2]+"11" ! macro var for # of ctrlrs

	.sets s$st2 "0"		! define s.st2 initialization value
	.ift contig .sets s$st2 "S2.CON"	! if contiguous krb/scb

	.sets k$sts "KS.OFL"	! define k.sts init value
	.ift ucbtbl .sets k$sts k$sts+"+KS.UCB"	! if ucb table in krb

	.ift contig .sets ctg$ "CONTIGUOUS KRB/SCB"
	.iff contig .sets ctg$ "EACH UCB HAS AN SCB"

	.ift ucbtbl .sets utb$ "UCB TABLE FOLLOWS KRB"
	.iff ucbtbl .sets utb$ "NO UCB TABLE IN KRB"

	.sets nucb$ ""
	.if nucb > 1 .sets nucb$ "S"

	.sets krb$ ""
	.ift contig .sets krb$ "/SCB"

.;
.; file data follows...
.;
	
	.disable decimal	! back to octal...
	.enable data
	.TITLE	'dev'TAB	- 'dev': DRIVER DATABASE
	.IDENT	/'mn%d''dy%d''yr%d'/
	
	.LIST	ME		; LIST MACRO EXPANSIONS
	
;
; 'dev': DRIVER DATABASE FOR RSX-11M-PLUS
;
; CREATED FOR DEVICE 'dev': ON '<date>' AT '<time>' BY 'name'
;
; OPTIONS SELECTED:	- DEVICE PRIORITY = 'devpri'
;			- 'nucb' UNIT'nucb$' PER CONTROLLER
;			- 'ctg$'
;			- 'utb$'
;
; REVISION HISTORY
; =================
;
;
	
	.DSABL	GBL		; NO GLOBAL DEFAULTS
	
	.MCALL	DEVDF$,HWDDF$
	DEVDF$			; DEFINE DEVICE CONTROL BLOCK OFFSETS
	HWDDF$			; DEFINE HARDWARE REGISTERS
	
	
LD$'dev'=	0				; LOADABLE DRIVER (REQUIRED)
'x$$x11'=	'nkrb%d'.				; # OF CONTROLLERS
NUCB=	'nucb%d'.				; # OF UCBS PER CONTROLLER
	
	
;
; DEFINE ALL CSRS/VECTORS
;
	
.disable data
	
	.setn cnt 1
.defcv:
	.sets ltr alpha[cnt:cnt]
	.setn csr csr'ltr'
	.setn vec vec'ltr'
	.data CSR'ltr'=	'csr'		; 'dev''ltr' CSR/VECTOR
	.data VEC'ltr'=	'vec'
	.data
	.inc cnt
	.if cnt <= nkrb .goto defcv
	
	.enable data
.PAGE
;
; DEFINE THE MACROS
;
	
;
; $WORD - CONCATENATE A NUMERIC ARGUMENT TO A LABEL FOR .WORD
;
	.MACRO	$WORD	LAB,NUM
	.WORD	LAB''NUM
	.ENDM	$WORD
	
;
; UCBGEN - GENERATE ONE UCB
;
; ARGS:	UNIT	= NUMBER OF UCB TO BE GENERATED
;	LTR	= ALPHA OF OWNING KRB
;
	
	.MACRO	UCBGEN UNIT,LTR
	
; UCB:	'dev'''LTR''UNIT
	
UCBST=	.
	.WORD	0		; U.OWN
.'dev'''LTR''UNIT::
	.WORD	$'dev'DCB		; U.DCB
	.WORD	.-2		; U.RED
	.BYTE	0		; U.CTL
	.BYTE	0		; U.STS
	.BYTE	UNIT		; U.UNIT
	.BYTE	US.OFL		; U.ST2
	.WORD	0		; U.CW1
	.WORD	0		; U.CW2
	.WORD	0		; U.CW3
	.WORD	0		; U.CW4
.disable data
.iff contig .data	.WORD	$'dev'''LTR''UNIT		; U.SCB  ADDRESS OF SCB
.ift contig .data	.WORD	$'dev'''LTR''0		; U.SCB  ADDRESS OF SCB
.enable data
	.WORD	0		; U.ATT
	.WORD	0,0		; U.BUF
	.WORD	0		; U.CNT
UCBND=	.
UCBLEN=	UCBND-UCBST		; UCB LENGTH
	
	.ENDM	UCBGEN
	
.disable data
	
	.ift contig .goto noscb	! no scb macro if contiguous krb/scb
	.enable data
.PAGE
;
; SCBGEN - GENERATE ONE SCB
;
; ARGS:	UNIT	= NUMBER OF SCB TO BE GENERATED
;	LTR	= ALPHA OF KRB THIS SCB REFERS TO
;
	
	.MACRO	SCBGEN	UNIT,LTR
	
; SCB:	'dev'''LTR''UNIT
	
$'dev'''LTR''UNIT::
	.WORD	0		; S.LHD
	.WORD	.-2
	.WORD	0,0,0,0		; S.FRK
	.WORD	0		; S.KS5
	.WORD	0		; S.PKT
	.BYTE	0		; S.CTM
	.BYTE	0		; S.ITM
	.BYTE	0		; S.STS
	.BYTE	0		; S.ST3
	.WORD	0		; S.ST2
	.WORD	$'dev'''LTR		; S.KRB
	
	.ENDM	SCBGEN
	
.disable data
	
.noscb:	.enable data
.PAGE
;
; KRBGEN - GENERATE A KRB'krb$'
;
; ARGS:	UNIT	= NUMBER OF KRB TO BE GENERATED
;	LTR	= ALPHA OF KRB TO BE GENERATED
;
	
	.MACRO	KRBGEN	UNIT,LTR
	
; KRB'krb$':	'dev'''LTR
	
				; K.PRM
	.BYTE	'devpri'		; K.PRI
	.BYTE	VEC''LTR/4		; K.VCT
	.BYTE	UNIT*2		; K.CON
	.BYTE	0		; K.IOC
	.WORD	'k$sts'		; K.STS
$'dev'''LTR::
	.WORD	CSR''LTR		; K.CSR
	.WORD	'dev'''LTR-$'dev'''LTR	; K.OFF
	.BYTE	NUCB-1		; K.HPU
	.BYTE	0		; UNUSED
.disable data	

	.iff suc .data	.WORD	0		; K.OWN
	.ift suc .data	.WORD	.'dev'''LTR''0		; K.OWN/S.OWN

	.iff contig .data	.WORD	0		; K.CRQ
	.iff contig .data	.WORD	.-2
	.iff contig .goto nocon
	
	.; the scb part of contiguous krb/scb follows	
	.enable data
$'dev'''LTR''0::
	.WORD	0		; K.CRQ/S.LHD
	.WORD	.-2
	.WORD	0,0,0,0		; S.FRK
	.WORD	0		; S.KS5
	.WORD	0		; S.PKT
	.BYTE	0		; S.CTM
	.BYTE	0		; S.ITM
	.BYTE	0		; S.STS
	.BYTE	0		; S.ST3
	.WORD	's$st2'		; S.ST2
	.WORD	$'dev'''LTR		; S.KRB
.disable data

.nocon:
	.ift nprdev .data	.IFDF	M$$EXT
	.ift nprdev .data	.BLKW	M.LGTH		; UMR work area
	.ift nprdev .data	.ENDC

	.data 
	.data 'dev'''LTR:

	.iff ucbtbl .goto notbl
	.enable data
	
; UCB TABLE
	
	.NLIST
UCBCT=	0
	.REPT	NUCB
	.LIST
	$WORD	.'dev'''LTR,\UCBCT
	.NLIST
UCBCT=	UCBCT+1
	.ENDR
	.LIST
	.WORD	-1		; END OF TABLE
.disable data
	
.notbl:
	.enable data
	
	
	.ENDM	KRBGEN
	
.PAGE
;**************************************************************************
;**************************************************************************
;*********************                               **********************
;*********************     GENERATE THE DATABASE     **********************
;*********************                               **********************
;**************************************************************************
;**************************************************************************
	
	
	.NLIST	MD			; SUPPRESS CLUTTER
	.NLIST	MC
	
	.PSECT	'dev'TAB,D
	
	
$'dev'DAT::				; START OF TABLE
	
;
; *** DCB ***
;
	
$'dev'DCB::
	.WORD	0			; D.LNK  ADDR OF NEXT DCB
	.WORD	.'dev'A0			; D.UCB  ADDR OF 1ST UCB
	.ASCII	/'dev'/			; D.NAM  DEVICE NAME
	.BYTE	0,<'x$$x11'*NUCB>-1	; D.UNIT    (LO, HI)
	.WORD	UCBLEN			; D.UCBL  SIZE OF A UCB
	.WORD	0			; D.DSP
	.WORD	0			; D.MSK	LEGAL 0-15.  (FUNCTION MASK)
	.WORD	0			;	CTRL
	.WORD	0			;	NOOP
	.WORD	0			;	ACP
	.WORD	0			;	LEGAL 16.-31.
	.WORD	0			;	CTRL
	.WORD	0			;	NOOP
	.WORD	0			;	ACP
	.WORD	0			; D.PCB  PCB ADDRESS
	
.PAGE
;
; *** UCB ***
;
	
	.NLIST
KRBCT=	0
	.IRPC	LTR,<ABCDEFHJKLMNPRSTUVWXYZ>
	.IF NE	KRBCT-'x$$x11'
UCBCT=	0
	.REPT	NUCB
	.LIST
	UCBGEN	\UCBCT,LTR
	.NLIST
UCBCT=	UCBCT+1
	.ENDM
KRBCT=	KRBCT+1
	.ENDC
	.ENDM
	.LIST
	
.disable data
	
	.ift contig .goto mkkrb
	.enable data
.PAGE
;
; *** SCB ***
;
	
	.NLIST
KRBCT=	0
	.IRPC	LTR,<ABCDEFHJKLMNPRSTUVWXYZ>
	.IF NE	KRBCT-'x$$x11'
SCBCT=	0
	.REPT	NUCB
	.LIST
	SCBGEN	\SCBCT,LTR
	.NLIST
SCBCT=	SCBCT+1
	.ENDM
KRBCT=	KRBCT+1
	.ENDC
	.ENDM
	.LIST
	
.disable data
	
.mkkrb:
	.enable data
.PAGE
;
; *** KRB ***
;
	
	.NLIST
KRBCT=	0
	.IRPC	LTR,<ABCDEFHJKLMNPRSTUVWXYZ>
	.IF NE	KRBCT-'x$$x11'
	.LIST
	KRBGEN	\KRBCT,LTR
	.NLIST
KRBCT=KRBCT+1
	.ENDC
	.ENDM
	.LIST
	
.PAGE
;
; *** CTB ***
;
	
				; L.CLK
	.WORD	0		; L.ICB
$CTB0:
	.WORD	0		; L.LNK
	.ASCII	/'dev'/		; L.NAM
	.WORD	$'dev'DCB		; L.DCB
	.BYTE	'x$$x11'		; L.NUM
	.BYTE	0		; L.STS
	
$'dev'CTB::			; L.KRB
	.NLIST
KRBCT=	0
	.IRPC	LTR,<ABCDEFHJKLMNPRSTUVWXYZ>
	.IF NE	KRBCT-'x$$x11'
	.LIST
	.WORD	$'dev'''LTR
	.NLIST
KRBCT=	KRBCT+1
	.ENDC
	.ENDM
	.LIST
	
	
$'dev'END::
	
	.END
.disable data
	
	.close
	;
	; File 'dev'TAB.MAC has been created.
	;
	; You must now edit that file, adding any necessary bit definitions or
	;	device-dependent storage to the macro definitions.
	;
	; After editing, MAC the file as usual.
	;
.exit
