diff --git a/src/midas/xjsys.5 b/src/midas/xjsys.5 new file mode 100644 index 00000000..ddae1e56 --- /dev/null +++ b/src/midas/xjsys.5 @@ -0,0 +1,88 @@ +;-*-MIDAS-*- + +;XJSYS makes TENEX JSYS's look like ITS symbolic system calls. +;In general, load T with ,, +;where the inlist contains the JSYS followed by the input args +;(1 word each) followed by -1, and the outlist contains the +;addresses to store the values, followed by a -1. An input arg +;can be either the address of the value or 1000,,immediate value. +;Input and output args can all be indexed or indirect. +;Then PUSHJ to XJSYS. It will fetch the input args, do the JSYS, +;store the values, and then skip if the JSYS skipped. +;The accumulators 1-4 are not clobbered unless output addresses +;specify them (which works). T isn't clobbered either. + +;XJSYSP must be defined to be the accumulator XJSYS uses as its PDL. +;If P is not between 1 and 4, XJSYSP may be the same as P. +;Otherwise, it must be an accumulator not between 1 and 4, distinct +;from T. It will be clobbered. + +;Example: +; MOVE T,[[GTJFN ? ARG1 ? 1000,,IMARG2 ? -1],,[2 ? 1 ? BAR ? -1]] +; PUSHJ P,XJSYS +; error return +; success return +;Note that it puts the first value in AC 2 and the second in AC 1! +;The ACs are already restored by the time values are handed out. + +;Using the SYSCAL macro, the example above becomes +; SYSCAL GTJFN,[ARG1 ? 1000,,IMARG2][2 ? 1 ? BAR] +; error return +; success return + DEFINE SYSCAL NAME,IN,OUT + MOVE T,[[NAME ? IN ? -1],,[OUT ? -1]] + PUSHJ P,XJSYS +TERMIN + +DEFINE SYSBLK NAME,IN,OUT +[[NAME ? IN ? -1],,[OUT ? -1]]!TERMIN + +IFNDEF XJSYSP,XJSYSP==P +IFLE XJSYSP-4,.ERR XJSYSP must be greater than 4 +IFE XJSYSP-T,.ERR XJSYSP must be distinct from T +.HKILL XJSYSP +IFLE T-4,.ERR T must be greater than 4 + +XJSYS: +IFN XJSYSP-P, MOVE XJSYSP,P + ADD XJSYSP,[5,,5] ; Make room for 4 saved acs/args/vals and T + MOVSM T,(XJSYSP) +REPEAT 4,[ + MOVE T,(XJSYSP) ; Get address of input arg block + SKIPGE T,1+.RPCNT(T) ; Are there any more args? + JRST XJSYS1 + HRRI T,@T ; Yes => compute address of next arg + TLZ T,37 + TLZN T,1000 ; Get contents if not immediate. + MOVE T,(T) + MOVEM T,-<1+.RPCNT>(XJSYSP) ; Store arg in resting place on stack, +] ; 1st is closest to top. + + ; Now put original acs 1-4 on stack and get JSYS args out. +XJSYS1: +REPEAT 4,EXCH 1+.RPCNT,-<1+.RPCNT>(XJSYSP) + POP XJSYSP,T + XCT (T) ;Do the JSYS. + JRST XJSYS2 ;Propagate 0, 1 or 2 skips + CAIA ;back to our caller. + AOS -4(XJSYSP) + AOS -4(XJSYSP) + +XJSYS2: ; Restore ACs and put results on stack. +REPEAT 4,EXCH 1+.RPCNT,-.RPCNT(XJSYSP) + MOVSS T +REPEAT 4,[ + SKIPGE .RPCNT(T) +IFE XJSYSP-P, JRST XJSYSX+.RPCNT +.ELSE POPJ P, + POP XJSYSP,@.RPCNT(T) +] + POPJ P, + +IFE XJSYSP-P,[ +XJSYSX: SUB P,[1,,1] + SUB P,[1,,1] + SUB P,[1,,1] + SUB P,[1,,1] + POPJ P, +]