rawio.red 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. % RAWIO.RED - Support routines for PSL Emode
  2. %
  3. % Author: Eric Benson
  4. % Computer Science Dept.
  5. % University of Utah
  6. % Date: 17 August 1981
  7. % Copyright (c) 1981, 1982 University of Utah
  8. % Modified and maintained by William F. Galway.
  9. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  10. % DEC-20 version
  11. FLUID '(!*rawio); % T if terminal is using "raw" i.o.
  12. CompileTime <<
  13. load if!-system;
  14. load syslisp$
  15. off UserMode; % csp 8/20/82
  16. if_system(Dec20,
  17. <<
  18. load monsym$
  19. load jsys$
  20. >>)
  21. >>;
  22. BothTimes if_system(Dec20, % CompileTime probably suffices.
  23. <<
  24. FLUID '( % Global?
  25. OldCCOCWords
  26. OldTIW
  27. OldJFNModeWord
  28. );
  29. lisp procedure BITS1 U;
  30. if not NumberP U then Error(99, "Non-numeric argument to BITS")
  31. else lsh(1, 35 - U);
  32. macro procedure BITS U;
  33. begin scalar V;
  34. V := 0;
  35. for each X in cdr U do V := lor(V, BITS1 X);
  36. return V;
  37. end;
  38. >>);
  39. LoadTime if_system(Dec20,
  40. <<
  41. OldJfnModeWord := NIL; % Flag "modes not saved yet"
  42. lap '((!*entry PBIN expr 0)
  43. % Read a single character from the TTY as a Lisp integer
  44. (pbin) % Issue PBIN
  45. (!*CALL Sys2Int) % Turn it into a number
  46. (!*exit 0)
  47. );
  48. lap '((!*entry PBOUT expr 1)
  49. % write a single charcter to the TTY, works for integers and single char IDs
  50. % Don't bother with Int2Sys?
  51. (pbout)
  52. (!*exit 0)
  53. );
  54. lap '((!*entry CharsInInputBuffer expr 0)
  55. % Returns the number of characters in the terminal input buffer.
  56. (!*MOVE (WConst 8#101) (reg 1)) % The input file (the terminal, =
  57. % 8#101)
  58. (sibe) % skip if input buffer empty
  59. (skipa (reg 1) (reg 2)) % otherwise # chars in r2
  60. (setz (reg 1) 0) % if skipped, then zero
  61. (!*CALL Sys2Int) % Turn it into a number
  62. (!*exit 0)
  63. );
  64. lap '((!*entry RFMOD expr 1)
  65. % returns the JFN mode word as Lisp integer
  66. (hrrzs (reg 1))
  67. (rfmod)
  68. (!*MOVE (reg 2) (reg 1)) % Get mode word from R2
  69. (!*CALL Sys2Int)
  70. (!*exit 0)
  71. );
  72. lap '((!*entry RFCOC expr 1)
  73. % returns the 2 CCOC words for JFN as dotted pair of Lisp integers
  74. (hrrzs (reg 1))
  75. (rfcoc)
  76. (!*PUSH (reg 2)) % save the first word
  77. (!*MOVE (reg 3) (reg 1))
  78. (!*CALL Sys2Int) % make second into number
  79. (exch (reg 1) (indexed (reg st) 0)) % grab first word, save
  80. % tagged 2nd word.
  81. (!*CALL Sys2Int) % make first into number
  82. (!*POP (reg 2))
  83. (!*JCALL Cons) % and cons them together
  84. );
  85. lap '((!*entry RTIW expr 1)
  86. % Returns terminal interrupt word for specified process, or -5 for entire job,
  87. % as Lisp integer
  88. (hrrzs (reg 1)) % strip tag
  89. (rtiw)
  90. (!*MOVE (reg 2) (reg 1)) % result in r2, return in r1
  91. (!*JCALL Sys2Int) % return as Lisp integer
  92. );
  93. lisp procedure SaveInitialTerminalModes();
  94. % Save the terminal modes, if not already saved.
  95. if null OldJfnModeWord then
  96. << OldJFNModeWord := RFMOD(8#101);
  97. OldCCOCWords := RFCOC(8#101);
  98. OldTIW := RTIW(-5);
  99. >>;
  100. lap '((!*entry SFMOD expr 2)
  101. % SFMOD(JFN, ModeWord);
  102. % set program related modes for the specified terminal
  103. (hrrzs (reg 1))
  104. (!*PUSH (reg 1))
  105. (!*MOVE (reg 2) (reg 1))
  106. (!*CALL Int2Sys)
  107. (!*MOVE (reg 1) (reg 2))
  108. (!*POP (reg 1))
  109. (sfmod)
  110. (!*exit 0)
  111. );
  112. lap '((!*entry STPAR expr 2)
  113. % STPAR(JFN, ModeWord);
  114. % set device related modes for the specified terminal
  115. (hrrzs (reg 1))
  116. (!*PUSH (reg 1))
  117. (!*MOVE (reg 2) (reg 1))
  118. (!*CALL Int2Sys)
  119. (!*MOVE (reg 1) (reg 2))
  120. (!*POP (reg 1))
  121. (stpar)
  122. (!*exit 0)
  123. );
  124. lap '((!*entry SFCOC expr 3)
  125. % SFCOC(JFN, CCOCWord1, CCOCWord2);
  126. % set control character output control for the specified terminal
  127. (hrrzs (reg 1))
  128. (!*PUSH (reg 1))
  129. (!*PUSH (reg 3))
  130. (!*MOVE (reg 2) (reg 1))
  131. (!*CALL Int2Sys)
  132. (exch (reg 1) (indexed (reg st) 0))
  133. (!*CALL Int2Sys)
  134. (!*MOVE (reg 1) (reg 3))
  135. (!*POP (reg 2))
  136. (!*POP (reg 1))
  137. (sfcoc)
  138. (!*exit 0)
  139. );
  140. lap '((!*entry STIW expr 2)
  141. % STIW(JFN, ModeWord);
  142. % set terminal interrupt word for the specified terminal
  143. (hrrzs (reg 1))
  144. (!*PUSH (reg 1))
  145. (!*MOVE (reg 2) (reg 1))
  146. (!*CALL Int2Sys)
  147. (!*MOVE (reg 1) (reg 2))
  148. (!*POP (reg 1))
  149. (stiw)
  150. (!*exit 0)
  151. );
  152. lisp procedure EchoOff();
  153. % A bit of a misnomer, perhaps "on_rawio" would be better.
  154. % Off echo, On formfeed, send all control characters
  155. % Allow input of 8-bit characters (meta key)
  156. if not !*rawio then % Avoid doing anything if already "raw mode"
  157. <<
  158. SaveInitialTerminalModes();
  159. % Note that 8#101, means "the terminal".
  160. % Clear bit 24 to turn echo off,
  161. % bits 28,29 turn off "translation"
  162. SFMOD(8#101, LAND(OldJFNModeWord, LNOT BITS(24, 28, 29)));
  163. % Set bit 0 to indicate "has mechanical tab" (so cntrl-L gets
  164. % through?).
  165. % Clear bit 34 to turn off cntrl-S/cntrl-Q
  166. STPAR(8#101, LAND(lor(OldJFNModeWord, BITS 1), LNOT BITS(34)));
  167. % More nonsense to turn off processing of control characters?
  168. SFCOC(8#101,
  169. LNOT(8#252525252525),
  170. LNOT(8#252525252525));
  171. % Turn off terminal interrupts for entire job (-5), for everything
  172. % except cntrl-C (the bit number three that's one).
  173. STIW(-5,8#040000000000);
  174. !*rawio := T; % Turn on flag
  175. >>;
  176. lisp procedure EchoOn();
  177. % Restore initial terminal echoing modes
  178. <<
  179. % Avoid doing anything if OldJFNModeWord is NIL, means terminal mode
  180. % already "restored".
  181. if OldJFNModeWord then
  182. <<
  183. SFMOD(8#101,OldJFNModeWord);
  184. STPAR(8#101,OldJFNModeWord);
  185. SFCOC(8#101,car OldCCOCWords,cdr OldCCOCWords);
  186. STIW(-5,OldTIW);
  187. >>;
  188. % Set to NIL so that things get saved again by
  189. % SaveInitialTerminalModes. (The terminal status may have been changed
  190. % between times.)
  191. OldJFNModeWord := NIL;
  192. !*rawio := NIL; % Indicate "cooked" i/o.
  193. >>;
  194. % Flush output buffer for stdoutput. (On theory that we're using buffered
  195. % I/O to speed things up.)
  196. Symbolic Procedure FlushStdOutputBuffer();
  197. NIL; % Just a dummy routine for the 20.
  198. >>
  199. );
  200. % END OF DEC-20 version.
  201. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  202. % VAX Unix version
  203. LoadTime if_system(Unix,
  204. <<
  205. % EchoOn, EchoOff, and CharsInInputBuffer are part of "kernel".
  206. Symbolic Procedure PBIN();
  207. % Read a "raw character". NOTE--assumption that 0 gives terminal input.
  208. VaxReadChar(0); % Just call this with "raw mode" on.
  209. Symbolic Procedure PBOUT(chr);
  210. % NOTE ASSUMPTION that 1 gives terminal output.
  211. VaxWriteChar(1,chr);
  212. >>);
  213. % END OF Unix version.
  214. fluid '(!*EMODE);
  215. LoadTime
  216. <<
  217. !*EMODE := NIL;
  218. Symbolic Procedure rawio_break();
  219. % Redefined break handler to turn echoes back on after a break, unless
  220. % EMODE is running.
  221. <<
  222. if !*rawio and not !*EMODE then
  223. EchoOn();
  224. pre_rawio_break(); % May want to be paranoid and use a "catch(nil,
  225. % '(pre_rawio_break)" here.
  226. >>;
  227. % Carefully redefine the break handler.
  228. if null getd('pre_rawio_break) then
  229. <<
  230. CopyD('pre_rawio_break, 'Break);
  231. CopyD('break, 'rawio_break);
  232. >>;
  233. >>;