! Utility routines for EDWIN on EMAS

!%include "edwins_device"
%external %routine %spec PROMPT (%string (63) STR)
%external %integer %fn %spec IN STREAM
%external %integer %fn %spec X29call
!%external %integer %fn %spec output stream
%external %integer %fn %spec UINFI (%integer PARM)
%external %string (255) %fn %spec UINFS (%integer PARM)
%external %routine %spec MESSAGES (%string (255) STATE)
%external %routine %spec XMODE (%string (255) S)
%system %routine %spec CONSOLE (%integer FN, %integer %name A, L)

%own %string (255) BUFF = ""

%external %routine SET IN %alias "EDWIN_SET_IN" (%string (255) DEV)
   ! Ignored on EMAS
%end

%external %routine SET OUT %alias "EDWIN_SET_OUT" (%string (255) DEV)
   ! Ignored on EMAS
%end

%external %routine TTMODE %alias "EDWIN_TTMODE" (%integer STATE)
   ! Set terminal characteristics -
   ! 0 => Normal mode => SET MODE  G=OFF
   ! 1 => Graphics output mode => SET MODE  G=ON  (subsystem not seeing it!)
   ! 2 => Graphics input mode  NOT YET IMPLEMENTED.
   ! Also suppress terminal messages while in Graphmode.
   %const %integer MESSAGE INFO = 22
   %own %integer MESSAGE STATE = 0
   %integer A, L
   %own %byte %integer %array SETGaF (0:4) = 4, 11, 1, 17, 1
   %own %byte %integer %array SETNoG (0:4) = 2, 11, 0 (*)

   %if UINFI(2)=2 %start; ! Batch mode
       SELECT OUTPUT (0)
       PRINT STRING ("Graphics I/O in batch mode ignored")
       NEWLINE
       VIEWING = -1
       %return
   %finish

   %if STATE = 0 %start
       ! Return to normal -
!       A = ADDR (SETNoG(0))
!       L = 1
!       CONSOLE (17, A, L)
! No, because a bunch of hackers got it wrong!
       MESSAGES ("ON") %if MESSAGE STATE = 0
       %return
   %finish
   %if STATE&1#0 %start
       ! Set Graphics output mode
       %if X29Call=0 %start    { TCP }
           A = ADDR (SETGaF(0))
           L = 1
           CONSOLE (17, A, L)
       %else                   { PAD }
           XMODE ("T")
       %finish
       MESSAGE STATE = UINFI (MESSAGE INFO)
       MESSAGES ("OFF") %if MESSAGE STATE = 0
       %return
   %finish
%end

%external %routine KILL INPUT %alias "EDWIN_KILL_INPUT"
   %integer A, L
   CONSOLE (8, A, L)
%end

%external %routine FLUSH OUTPUT %alias "EDWIN_FLUSH"
   %integer A, L

   %return %if BUFF="" %or VIEWING<0

   %if VIEWING=0 %start
       A = ADDR (BUFF) + 1
       L = LENGTH (BUFF)
       CONSOLE (10, A, L)
   %else
       L = output stream
       SELECT OUTPUT (VIEWING)
       PRINT CH (CHARNO(BUFF,A)) %for A=1,1,LENGTH(BUFF)
       SELECT OUTPUT (L)
   %finish
   BUFF = ""
%end

%external %routine TTPUT %alias "EDWIN_TTPUT" (%integer I)
   BUFF = BUFF.TO STRING (I)
   FLUSH OUTPUT %if LENGTH(BUFF)>253
%end

%external %integer %fn TTREAD %alias "EDWIN_TTREAD"
   %integer ST, SYM
   %string (255) OLD PROMPT
   ST = IN STREAM
   SELECT INPUT (0)
   OLD PROMPT = UINFS(4)
   PROMPT (TO STRING (127))
   READ CH (SYM)
   PROMPT (OLD PROMPT)
   SELECT INPUT (ST)
   %result = SYM
%end

%external %integer %fn TTGET %alias "EDWIN_TTGET"
   %result = TTREAD;  ! For EMAS at present.
%end

%external %integer %fn MULDIV %alias "EDWIN___MUL_DIV" (%integer A, B, C)
   %long %integer AB, RES, REM

   %result = 0 %if A=0 %or B=0 %or C=0
   AB = lengthenI(A) * lengthenI (B)
   RES = AB // lengthenI(C)
   REM = AB - RES * lengthenI(C)
   RES = RES + 1 %if REM > C//2
   %result = RES
%end

%external %routine TEK INPUT %alias "EDWIN___TEK_INPUT" (%integer %name State, X, Y, %integer INVOKE CURSOR)
   %integer st, a, b, c, d, e
   %string (255) old prompt
   Kill input
   flush output
   ST = in stream
   select input (0)
   old prompt = UINFS(4)
   prompt (to string(27).to string (invoke cursor))
   read ch (state) %until state>=' '
   read ch (a);   read ch (b);   read ch (c);   read ch (d)
   read ch (e) %until e<' '
   prompt (old prompt)
   select input (st)
   X = (A&31)<<5!B&31
   Y = (C&31)<<5!D&31
%end

%external %routine OPER MESSAGE %alias "EDWIN_OPER_MESSAGE" (%string (255) S)
   %integer OS
   OS = output stream
   Select output (0)
   Print string (S)
   Newline
   Select output (OS)
%end

%external %routine OPER INTERACT %alias "EDWIN_OPER_INTERACT" (%string (255) S)
   %string (127) OLD PROMPT
   %integer IS, REPLY
   %on 9 %start
       Prompt (OLD PROMPT)
       %signal 9
   %finish
   IS = In Stream
   Select input (0)
   OLD PROMPT = UINFS(4) { Current prompt }
   Prompt (S)
   Read symbol (REPLY) %until REPLY&95='Y'
   Read symbol (REPLY) %until REPLY=NL
   Select input (IS)
   Prompt (OLD PROMPT)
%end

%end %of %file
