; ; Assembly language & data module ; for the PL/I FMS interface written in C ; .enabl lc .title pldfms .psect pldfms .iif ndf reentrant reentrant = 0 ;default to reentrant version ;0 means reentrant, -1 means non-reentrant, so .if eq reentrant ;means if reentrant, and .if ne reentrant means if not reentrant .enabl gbl ;all undeclared symbols are external .mcall $FDVDF ;get size parameters $FDVDF .globl T$LUN ;make sure FDVDAT is loaded (it defined FMS impure) ; ; Call interface between C and FMS ; $cfdv:: .if eq reentrant mov $VEXT,r1 mov vx$fms(r1),r0 ;argument block pointer is in impure .iff ;non-reentrant mov #fd$$nm,fd$$ar+f$nam ;most routines - name is in fixed scratch $cfdvn:: mov #fd$$ar,r0 ;lopen name must be in bigger temp, pointer set by C .endc ;call FMS & return directly to C (C called us by jsr pc,$cfdv/$cfdvn) .if eq reentrant jmp @vx$fmd(r1) ;reentrant - pointer to driver in impure for clustering .iff jmp $FDV ;non-reentrant - can jmp direct .endc .if eq reentrant ; ; reentrant version - define offsets to data from impure pointer ; .macro defblk $blk$=0 .endm .macro blk name, size name == $blk$ $blk$ = $blk$+size .endm .macro endblk size .if nb size size == $blk$ .endc .endm defblk blk fd$$ar, F$ASIZ ;argument block (must be at displacement 0 for $cfdv) blk fd$$rq, F$RSIZ ;required argument block ;(status block is in $$VEX1) blk fd$$nm, 6 ;space for one name blk fd$$cn, 2 ;pointer to current field name blk fd$$cx, 2 ;current field index blk fd$$im, 0 ;start of FMS impure area endblk fd$$sz ;size of our portion of impure area .endc .if ne reentrant ; ; non-reentrant version - variables are in static dirty data area ; fd$$ar::.blkb F$ASIZ ;argument block fd$$rq::.blkb F$RSIZ ;required argument block fd$$st::.blkw 2 ;status block fd$$nm::.blkb 6 ;space for one name fd$$cn::.blkw 1 ;pointer to current field name fd$$cx::.blkw 1 ;current field index fd$$in::.word 0 ;flag - whether impure area is initialized ; ; These pointers into above areas are needed because Macro does not ; allow equates based on globals (such as fd$fnc==fd$$ar+f$fnc), and ; because C does not pass global expressions to the task builder but ; compiles a bunch of code to evaluate them on every reference. ; fd$fnc:: .word fd$$ar+f$fnc fd$req:: .word fd$$ar+f$req fd$nam:: .word fd$$ar+f$nam fd$num:: .word fd$$ar+f$num fd$trm:: .word fd$$ar+f$trm fd$val:: .word fd$$ar+f$val fd$len:: .word fd$$ar+f$len fd$sts:: .word fd$$rq+f$sts fd$chn:: .word fd$$rq+f$chn fd$imp:: .word fd$$rq+f$imp .endc .end