TERM.MOD 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * TERM.MOD - COMMS Toolkit terminal emulation *
  5. * *
  6. * COPYRIGHT (C) 1988..1992 Clarion Software Corporation. *
  7. * All Rights Reserved *
  8. * *
  9. *--------------------------------------------------------------------------*)
  10. IMPLEMENTATION MODULE Term;
  11. IMPORT SYSTEM,Lib,IO,Str,Window,Keyboard;
  12. TYPE
  13. CharSets = (UK,US,SpecialChar);
  14. Attributes = (Blue,Green,Red,Bold,BlueBack,GreenBack,RedBack,Blink);
  15. AttrSet = SET OF Attributes;
  16. AttributeMap = ARRAY[0..23],[0..79] OF AttrSet;
  17. CharMap = ARRAY[0..23],[0..79] OF CHAR;
  18. CONST
  19. NormalAttr = AttrSet{Blue,Green,Red}; (* Lightgray on Black *)
  20. VAR
  21. G0,G1,CurrCharSet : CharSets;
  22. (* for handling protected field attributes *)
  23. CurrAttr,ProtAttr : AttrSet;
  24. Map : AttributeMap;
  25. ScrMap : CharMap;
  26. cx,cy,p1,p2,
  27. ScreenTop,
  28. ScreenBottom : CARDINAL;
  29. DECPrivate,
  30. OriginMode,AutoWrap,
  31. NewLineMode,KbdLocked,
  32. LocalEcho,ANSIKeys,
  33. NumKeyPad,Protected,
  34. EditMode,DeferredEdit,
  35. DeferredTransmit,
  36. TransmitOK,
  37. WantsFullPage,
  38. Initialised : BOOLEAN;
  39. TransmitMode : (Line,PartialPage,FullPage);
  40. VTMode : Emulations;
  41. RxState : (Normal,GotESC,GotBrack,GotLParen,GotRParen,GotHash,ReadingP1,ReadingP2,VT52Line,VT52Col,ANSICmd);
  42. TabStop : ARRAY[0..79] OF BOOLEAN;
  43. CSave : RECORD
  44. cx,cy : CARDINAL;
  45. Top,Bottom : CARDINAL;
  46. OrgMode : BOOLEAN;
  47. END;
  48. Kbd : RECORD
  49. rptr,wptr : CARDINAL;
  50. Buff : ARRAY[0..255] OF CHAR;
  51. END;
  52. (*.............................................*)
  53. PROCEDURE SetColor(NewAttr:AttrSet);
  54. BEGIN
  55. Window.TextColor(VAL(Window.Color,SHORTCARD(NewAttr) MOD 16));
  56. Window.TextBackground(VAL(Window.Color,SHORTCARD(NewAttr) DIV 16));
  57. END SetColor;
  58. (*.............................................*)
  59. PROCEDURE ResetTerm;
  60. VAR
  61. i : CARDINAL;
  62. BEGIN
  63. VTMode := EmVT100;
  64. RxState := Normal;
  65. G0 := US;
  66. G1 := SpecialChar;
  67. CurrCharSet := G0;
  68. ScreenTop := 0;
  69. ScreenBottom := 23;
  70. OriginMode := FALSE;
  71. AutoWrap := TRUE;
  72. NewLineMode := FALSE;
  73. KbdLocked := FALSE;
  74. LocalEcho := FALSE;
  75. ANSIKeys := TRUE;
  76. NumKeyPad := TRUE;
  77. Protected := FALSE;
  78. EditMode := FALSE;
  79. DeferredEdit := FALSE;
  80. DeferredTransmit := FALSE;
  81. TransmitMode := Line;
  82. WantsFullPage := FALSE;
  83. CurrAttr := NormalAttr;
  84. ProtAttr := CurrAttr;
  85. SetColor(CurrAttr);
  86. Lib.Fill(ADR(Map),SIZE(Map),NormalAttr);
  87. Lib.Fill(ADR(ScrMap),SIZE(ScrMap),' ');
  88. cx := 0;
  89. cy := 0;
  90. WITH CSave DO
  91. cx := 0;
  92. cy := 0;
  93. Top := 0;
  94. Bottom := 23;
  95. OrgMode := FALSE;
  96. END;
  97. FOR i:=0 TO 79 DO
  98. TabStop[i] := (i MOD 8)=0;
  99. END;
  100. WITH Kbd DO
  101. rptr := 0;
  102. wptr := 0;
  103. END;
  104. END ResetTerm;
  105. (*.............................................*)
  106. PROCEDURE StuffKbdBuffer(s:ARRAY OF CHAR; Lnth:CARDINAL);
  107. VAR
  108. i : CARDINAL;
  109. BEGIN
  110. i:=0;
  111. WHILE i<Lnth DO
  112. WITH Kbd DO
  113. Buff[wptr]:=s[i];
  114. wptr := (wptr+1) MOD 100H;
  115. END;
  116. INC(i);
  117. END;
  118. END StuffKbdBuffer;
  119. (*.............................................*)
  120. PROCEDURE GotoXY(x,y:CARDINAL);
  121. BEGIN
  122. IF y>23 THEN
  123. y:=23;
  124. END;
  125. IF x>79 THEN
  126. x:=79;
  127. END;
  128. Window.GotoXY(x+1,y+1);
  129. cx:=x;
  130. cy:=y;
  131. END GotoXY;
  132. (*.............................................*)
  133. PROCEDURE SelectEmulation(Which:Emulations);
  134. BEGIN
  135. ResetTerm;
  136. Window.Clear;
  137. GotoXY(0,0);
  138. VTMode := Which;
  139. END SelectEmulation;
  140. (*.............................................*)
  141. PROCEDURE Scroll(lines:INTEGER);
  142. VAR
  143. i : CARDINAL;
  144. x,y : CARDINAL;
  145. l : ARRAY[0..Window.ScreenWidth-1] OF WORD;
  146. BEGIN
  147. (* Do physical scroll *)
  148. x := Window.WhereX();
  149. y := Window.WhereY();
  150. IF lines = 0 THEN
  151. FOR i := ScreenTop+1 TO ScreenBottom+1 DO
  152. Window.GotoXY(1,i);
  153. Window.ClrEol;
  154. END;
  155. ELSE
  156. REPEAT
  157. IF lines < 0 THEN
  158. FOR i := ScreenBottom TO ScreenTop+1 BY -1 DO
  159. Window.RdBufferLn(Window.Used(),1,i,SYSTEM.ADR(l),80);
  160. Window.WrBufferLn(Window.Used(),1,i+1,SYSTEM.ADR(l),80);
  161. END;
  162. Window.GotoXY(1,ScreenTop+1);
  163. Window.ClrEol;
  164. INC(lines);
  165. ELSE
  166. FOR i := ScreenTop+2 TO ScreenBottom+1 DO
  167. Window.RdBufferLn(Window.Used(),1,i,SYSTEM.ADR(l),80);
  168. Window.WrBufferLn(Window.Used(),1,i-1,SYSTEM.ADR(l),80);
  169. END;
  170. Window.GotoXY(1,ScreenBottom+1);
  171. Window.ClrEol;
  172. DEC(lines);
  173. END;
  174. UNTIL ABS(lines) = 0;
  175. END;
  176. Window.GotoXY(x,y);
  177. (* Now scroll attribute map *)
  178. IF lines<>0 THEN
  179. IF lines>0 THEN (* Scroll up *)
  180. i:=ScreenTop;
  181. REPEAT
  182. Map[i] := Map[i+1];
  183. ScrMap[i] := ScrMap[i+1];
  184. INC(i);
  185. UNTIL i=ScreenBottom;
  186. ELSE (* Scroll down *)
  187. i:=ScreenBottom;
  188. REPEAT
  189. Map[i] := Map[i-1];
  190. ScrMap[i] := ScrMap[i-1];
  191. DEC(i);
  192. UNTIL i=ScreenTop;
  193. END;
  194. Lib.Fill(ADR(Map[i]),80,NormalAttr);
  195. Lib.Fill(ADR(ScrMap[i]),80,' ');
  196. END;
  197. END Scroll;
  198. (*.......................................*)
  199. PROCEDURE Translate(c:CHAR):CHAR;
  200. CONST
  201. FormChars = ' ±????øñ??Ù¿ÚÀÅÄÄÄÄÄôÁ³óòãØœ=';
  202. BEGIN
  203. IF CurrCharSet<>US THEN
  204. IF CurrCharSet=SpecialChar THEN
  205. IF (c>=CHR(95)) AND (c<=CHR(126)) THEN
  206. c := FormChars[ORD(c)-95];
  207. END;
  208. ELSIF c='#' THEN (* Must be UK char set *)
  209. c := 'œ';
  210. END;
  211. END;
  212. RETURN c;
  213. END Translate;
  214. (*.............................................*)
  215. PROCEDURE FindUnprotected():BOOLEAN;
  216. BEGIN
  217. IF Map[cy,cx]-ProtAttr<>AttrSet{} THEN RETURN(TRUE) END;
  218. LOOP
  219. IF Map[cy,cx]-ProtAttr=AttrSet{} THEN
  220. (* on a protected char position - skip! *)
  221. IF cx=79 THEN
  222. IF cy<ScreenBottom THEN
  223. INC(cy); cx:=0
  224. ELSE
  225. RETURN FALSE
  226. END
  227. ELSE
  228. INC(cx);
  229. END;
  230. ELSE
  231. GotoXY(cx,cy);
  232. RETURN TRUE
  233. END;
  234. END;
  235. END FindUnprotected;
  236. (*.............................................*)
  237. PROCEDURE Output(c:CHAR);
  238. BEGIN
  239. IF (c<' ') OR (c=CHR(127)) THEN
  240. CASE ORD(c) OF
  241. 7 : IO.WrChar(c); |
  242. 8 : IF cx>0 THEN
  243. GotoXY(cx-1,cy);
  244. END; |
  245. 9 : IF cx<79 THEN
  246. REPEAT
  247. INC(cx);
  248. UNTIL (cx=79) OR (TabStop[cx]);
  249. GotoXY(cx,cy);
  250. END; |
  251. 10..12 : IF NewLineMode THEN
  252. cx:=0;
  253. END;
  254. IF cy=ScreenBottom THEN
  255. Scroll(1);
  256. ELSE
  257. INC(cy);
  258. END;
  259. GotoXY(cx,cy); |
  260. 13 : GotoXY(0,cy); |
  261. 14 : CurrCharSet := G1; |
  262. 15 : CurrCharSet := G0; |
  263. END
  264. ELSE
  265. IF (NOT Protected) OR FindUnprotected() THEN
  266. Map[cy,cx] := CurrAttr;
  267. ScrMap[cy,cx] := c;
  268. IO.WrChar(Translate(c));
  269. IF (cx=79) AND (AutoWrap) THEN
  270. Output(CHR(10)); GotoXY(0,cy);
  271. ELSIF cx<79 THEN
  272. INC(cx);
  273. END;
  274. END;
  275. END;
  276. END Output;
  277. (*.............................................*)
  278. PROCEDURE DECModeChange(c:CHAR);
  279. VAR
  280. Lnth : CARDINAL;
  281. Seq : ARRAY[0..9] OF CHAR;
  282. BEGIN
  283. CASE p1 OF
  284. 0 : (*Error -ignore*) |
  285. 1 : (*Cursor Key*)
  286. IF NOT NumKeyPad THEN
  287. ANSIKeys := c='l';
  288. END; |
  289. 2 : IF c='l' THEN
  290. SelectEmulation(EmVT52);
  291. END; |
  292. 3 : (*Select 80/132 Columns - not supported*) |
  293. 4 : (*Select smooth/jump scrolling - not supported*)|
  294. 5 : (*Normal or Reverse Screen - not implemented*) |
  295. 6 : (*origin*)
  296. OriginMode := c='h'; |
  297. 7 : (*Auto-wrap*)
  298. AutoWrap := c='h'; |
  299. 8 : (*Kbd Auto-repeat on/off - not supported*) |
  300. 10 : (*Editing*)
  301. EditMode := c='h'; |
  302. 11 : (*Line Transmit*)
  303. IF c='h' THEN
  304. TransmitMode := Line
  305. ELSIF WantsFullPage THEN
  306. TransmitMode := FullPage
  307. ELSE
  308. TransmitMode := PartialPage
  309. END; |
  310. 13 : (*Space compression / Field delimiter*) |
  311. 14 : (*Transmit execution*)
  312. DeferredTransmit := (c='l'); |
  313. 15 : (* Printer status request *)
  314. IF c='n' THEN
  315. Seq:=' [?13n';
  316. Seq[0]:=CHR(27);
  317. StuffKbdBuffer(Seq,6);
  318. END; |
  319. 16 : (*Edit key execution*)
  320. DeferredEdit := c='l'; |
  321. 18 : (*Printer form feed*) |
  322. 19 : (*Printer extent*) |
  323. END;
  324. END DECModeChange;
  325. (*.............................................*)
  326. PROCEDURE EraseField(x,y,w:CARDINAL);
  327. VAR
  328. i,oldx,oldy : CARDINAL;
  329. BEGIN
  330. (* This routine is only called if protected fields are in effect *)
  331. oldx:=cx;
  332. oldy:=cy;
  333. i:=0;
  334. GotoXY(x,y);
  335. WHILE i<w DO
  336. IF Map[y,x+i]-ProtAttr<>AttrSet{} THEN
  337. Map[y,x+i] := CurrAttr;
  338. ScrMap[y,x+i] := ' ';
  339. IO.WrChar(' ');
  340. ELSE
  341. GotoXY(x+i+1,cy);
  342. END;
  343. INC(i);
  344. END;
  345. GotoXY(oldx,oldy);
  346. END EraseField;
  347. (*.............................................*)
  348. PROCEDURE EraseLineToCursor;
  349. BEGIN
  350. IF Protected THEN
  351. EraseField(0,cy,cx+1);
  352. ELSE
  353. Lib.Fill(ADR(Map[cy]),cx+1,NormalAttr);
  354. Lib.Fill(ADR(ScrMap[cy]),cx+1,' ');
  355. Window.DirectWrite(0,cy,ADR(ScrMap[cy]),cx);
  356. END;
  357. END EraseLineToCursor;
  358. (*.............................................*)
  359. PROCEDURE EraseCursorToEol;
  360. BEGIN
  361. IF Protected THEN
  362. EraseField(cx,cy,cx+1);
  363. ELSE
  364. Window.ClrEol;
  365. END;
  366. END EraseCursorToEol;
  367. (*.............................................*)
  368. PROCEDURE EraseScreenToCursor;
  369. VAR
  370. i,x,y : CARDINAL;
  371. BEGIN
  372. i:=0;
  373. x:=cx;
  374. y:=cy;
  375. WHILE i<y DO
  376. GotoXY(0,i);
  377. EraseCursorToEol;
  378. INC(i);
  379. END;
  380. GotoXY(x,y);
  381. EraseLineToCursor;
  382. END EraseScreenToCursor;
  383. (*.............................................*)
  384. PROCEDURE ClrEos;
  385. VAR
  386. i,x,y : CARDINAL;
  387. BEGIN
  388. i:=0;
  389. x:=cx;
  390. y:=cy;
  391. EraseCursorToEol;
  392. i:=y+1;
  393. WHILE i<=23 DO
  394. GotoXY(0,i);
  395. EraseCursorToEol;
  396. INC(i);
  397. END;
  398. GotoXY(x,y);
  399. END ClrEos;
  400. (*.............................................*)
  401. PROCEDURE FieldWidth():CARDINAL;
  402. VAR
  403. i,Max : CARDINAL;
  404. BEGIN
  405. IF Protected THEN
  406. i:=cx;
  407. IF Map[cy,i]=ProtAttr THEN
  408. RETURN(0);
  409. END;
  410. WHILE (i<80) AND (Map[cy,i]<>ProtAttr) DO
  411. INC(i);
  412. END;
  413. Max := i-1;
  414. ELSE
  415. Max := 79;
  416. END;
  417. RETURN Max;
  418. END FieldWidth;
  419. (*.............................................*)
  420. PROCEDURE DelChar;
  421. VAR
  422. i,Max : CARDINAL;
  423. a : AttrSet;
  424. BEGIN
  425. Max := FieldWidth();
  426. IF Max=0 THEN
  427. RETURN;
  428. END;
  429. i:=cx;
  430. a:=Map[cy,i];
  431. SetColor(a);
  432. WHILE i<Max DO
  433. Map[cy,i] := Map[cy,i+1];
  434. ScrMap[cy,i] := ScrMap[cy,i+1];
  435. IF Map[cy,i]<>a THEN
  436. a:=Map[cy,i]; SetColor(a);
  437. END;
  438. IO.WrChar(ScrMap[cy,i]);
  439. INC(i);
  440. END;
  441. IF Map[cy,i]<>a THEN
  442. a:=Map[cy,i];
  443. SetColor(a);
  444. END;
  445. ScrMap[cy,i]:=' ';
  446. IO.WrChar(' ');
  447. GotoXY(cx,cy);
  448. END DelChar;
  449. (*.............................................*)
  450. PROCEDURE GetCursorPosition(VAR s:ARRAY OF CHAR; VAR Lnth:CARDINAL);
  451. VAR
  452. TempStr : ARRAY[0..9] OF CHAR;
  453. Ok : BOOLEAN;
  454. BEGIN
  455. Str.CardToStr(LONGCARD(cy+1),TempStr,10,Ok);
  456. Str.CardToStr(LONGCARD(cx+1),s,10,Ok);
  457. Lnth := Str.Length(TempStr)+Str.Length(s)+4;
  458. Str.Concat(TempStr,' [',TempStr);
  459. Str.Concat(s,';',s);
  460. Str.Concat(s,TempStr,s);
  461. Str.Concat(s,s,'R');
  462. s[0]:=CHR(27);
  463. END GetCursorPosition;
  464. (*.............................................*)
  465. PROCEDURE Transmit;
  466. (* not implemented *)
  467. END Transmit;
  468. (*.............................................*)
  469. PROCEDURE CursorMovement ( dir : CHAR ; dist : CARDINAL );
  470. BEGIN
  471. IF dist=0 THEN
  472. dist:=1;
  473. END ;
  474. CASE dir OF
  475. 'A' : IF dist>cy THEN
  476. cy:=0;
  477. ELSE
  478. DEC(cy,dist);
  479. END; |
  480. 'B' : INC(cy,dist);
  481. IF cy>ScreenBottom THEN
  482. cy := ScreenBottom;
  483. END; |
  484. 'C' : INC(cx,dist);
  485. IF cy>79 THEN
  486. cy := 79;
  487. END; |
  488. 'D' : IF dist>cx THEN
  489. cx:=0;
  490. ELSE
  491. DEC(cx,dist);
  492. END; |
  493. END;
  494. GotoXY(cx,cy);
  495. END CursorMovement ;
  496. (*.............................................*)
  497. PROCEDURE EraseCommand ( type : CHAR ; function : CARDINAL );
  498. VAR
  499. x,y : CARDINAL;
  500. BEGIN
  501. CASE type OF
  502. 'J' : CASE function OF
  503. 0 : ClrEos; |
  504. 1 : EraseScreenToCursor; |
  505. 2 : x:=cx;
  506. y:=cy;
  507. GotoXY(0,0);
  508. ClrEos;
  509. GotoXY(x,y); |
  510. END; |
  511. 'K' : CASE function OF
  512. 0 : EraseCursorToEol; |
  513. 1 : EraseLineToCursor; |
  514. 2 : x:=cx;
  515. GotoXY(0,cy);
  516. EraseCursorToEol;
  517. GotoXY(x,cy); |
  518. END; |
  519. END ;
  520. END EraseCommand ;
  521. (*.............................................*)
  522. PROCEDURE CheckCode(c:CHAR);
  523. VAR
  524. x,y : CARDINAL;
  525. Seq : ARRAY[0..9] OF CHAR;
  526. BEGIN
  527. IF DECPrivate THEN
  528. DECModeChange(c)
  529. ELSE
  530. CASE c OF
  531. 'A'..'D' : CursorMovement(c,p1); |
  532. 'c' : (* Device attributes request *)
  533. Seq:=' [?7c';
  534. Seq[0]:=CHR(27);
  535. StuffKbdBuffer(Seq,5); |
  536. 'g' : IF p1=0 THEN
  537. TabStop[cx]:=FALSE;
  538. ELSIF p1=3 THEN
  539. FOR x:=0 TO 79 DO
  540. TabStop[x]:=FALSE;
  541. END;
  542. END; |
  543. 'H','f' : IF p1=0 THEN
  544. p1:=1;
  545. END;
  546. IF p2=0 THEN
  547. p2:=1;
  548. END;
  549. GotoXY(p2-1,p1-1); |
  550. 'h','l' : CASE p1 OF
  551. 2 : KbdLocked := (c='h'); |
  552. 6 : Protected := (c='l'); |
  553. 12 : LocalEcho := (c='l'); |
  554. 16 : WantsFullPage := (c='h'); |
  555. 20 : NewLineMode := (c='h'); |
  556. END; |
  557. 'J','K' : EraseCommand(c,p1); |
  558. 'L' : IF (cy>=ScreenTop) AND (cy<=ScreenBottom) THEN
  559. y:=ScreenTop;
  560. ScreenTop:=cy;
  561. WHILE p1>0 DO
  562. Scroll(-1);
  563. DEC(p1);
  564. END;
  565. ScreenTop:=y;
  566. END; |
  567. 'M' : IF (cy>=ScreenTop) AND (cy<=ScreenBottom) THEN
  568. y:=ScreenTop;
  569. ScreenTop:=cy;
  570. WHILE p1>0 DO
  571. Scroll(1);
  572. DEC(p1);
  573. END;
  574. ScreenTop:=y;
  575. END; |
  576. 'm' : (* Select graphic rendition *)
  577. CASE p1 OF
  578. 0 : CurrAttr := NormalAttr ; |
  579. 1 : INCL(CurrAttr,Bold); |
  580. 4 : CurrAttr := CurrAttr-AttrSet{Red,Green}+AttrSet{Blue};|
  581. 5 : INCL(CurrAttr,Blink); |
  582. 7 : CurrAttr := AttrSet(
  583. (SHORTCARD(CurrAttr*AttrSet{Red,Green,Blue})<<4)+
  584. (SHORTCARD(CurrAttr*AttrSet{RedBack,GreenBack,BlueBack})>>4)+
  585. (SHORTCARD(CurrAttr*AttrSet{Bold,Blink})));|
  586. 8 : CurrAttr := AttrSet{}; |
  587. END;
  588. SetColor(CurrAttr); |
  589. 'n' : (* Device status reports *)
  590. Seq[0]:=CHR(27);
  591. Seq[1]:='[';
  592. Seq[3]:='n';
  593. x:=4;
  594. CASE p1 OF
  595. 5 : Seq[2]:='0';(* VDU status request *) |
  596. 6 : GetCursorPosition(Seq,x); |
  597. ELSE
  598. x := 0;
  599. END;
  600. IF x>0 THEN
  601. StuffKbdBuffer(Seq,x);
  602. END; |
  603. 'P' : WHILE p1>0 DO
  604. DelChar;
  605. DEC(p1);
  606. END; |
  607. 'r' : IF (p1>=1) AND (p2>0) AND (p2<=24) AND (p1<p2) THEN
  608. ScreenTop := p1-1;
  609. ScreenBottom := p2-1;
  610. ELSE
  611. ScreenTop:=0;
  612. ScreenBottom:=23;
  613. END;
  614. GotoXY(0,ScreenTop); |
  615. '}' : (* Set protection attributes *)
  616. CASE p1 OF
  617. 0 : ProtAttr := NormalAttr; |
  618. 1 : INCL(ProtAttr,Bold); |
  619. 4 : ProtAttr := ProtAttr-AttrSet{Red,Green}+AttrSet{Blue};|
  620. 5 : INCL(ProtAttr,Blink); |
  621. 7 : ProtAttr := AttrSet(
  622. (SHORTCARD(ProtAttr*AttrSet{Red,Green,Blue})<<4)+
  623. (SHORTCARD(ProtAttr*AttrSet{RedBack,GreenBack,BlueBack})>>4)+
  624. (SHORTCARD(ProtAttr*AttrSet{Bold,Blink})));|
  625. 8 : ProtAttr := AttrSet{}; |
  626. ELSE
  627. IF p1=254 THEN
  628. ProtAttr:=NormalAttr;
  629. END;
  630. END;
  631. END;
  632. END;
  633. END CheckCode;
  634. (*.............................................*)
  635. PROCEDURE ShortCode(c:CHAR);
  636. VAR
  637. x,y : CARDINAL;
  638. Seq : ARRAY[0..9] OF CHAR;
  639. BEGIN
  640. CASE c OF
  641. 'c' : (* Reset *)
  642. SelectEmulation(EmVT100); |
  643. 'D' : IF cy<23 THEN
  644. GotoXY(cx,cy+1);
  645. ELSE
  646. Scroll(1);
  647. END; |
  648. 'E' : Output(CHR(10));
  649. GotoXY(0,cy); |
  650. 'H' : TabStop[cx]:=TRUE; |
  651. 'M' : IF cy>0 THEN
  652. GotoXY(cx,cy-1);
  653. ELSE
  654. Scroll(-1);
  655. END; |
  656. 'N' : (* G2 char set - not supported *) |
  657. 'Z' : (* Identity Request *)
  658. Seq:=' [?7c';
  659. Seq[0]:=CHR(27);
  660. StuffKbdBuffer(Seq,5); |
  661. 'O' : (* G3 char set - not supported *) |
  662. '7' : CSave.cx:=cx;
  663. CSave.cy:=cy;
  664. WITH CSave DO
  665. Top:=ScreenTop;
  666. Bottom:=ScreenBottom;
  667. OrgMode:=OriginMode;
  668. END; |
  669. '8' : WITH CSave DO
  670. ScreenTop:=Top;
  671. ScreenBottom:=Bottom;
  672. OriginMode:=OrgMode;
  673. GotoXY(cx,cy);
  674. END; |
  675. '=' : NumKeyPad := FALSE;(* application keypad mode *)|
  676. '>' : NumKeyPad := TRUE;
  677. ANSIKeys := TRUE; |
  678. END;
  679. END ShortCode;
  680. (*.............................................*)
  681. PROCEDURE NewCharSet(c:CHAR; VAR Gx:CharSets);
  682. BEGIN
  683. CASE c OF
  684. 'A' : Gx:=UK; |
  685. 'B' : Gx:=US; |
  686. '0' : Gx:=SpecialChar; |
  687. '1' : (* not supported *) |
  688. '2' : (* not supported *) |
  689. END;
  690. END NewCharSet;
  691. (*.............................................*)
  692. PROCEDURE VT100RxSM(c:CHAR);
  693. BEGIN
  694. CASE RxState OF
  695. Normal : IF c=CHR(27) THEN
  696. DECPrivate := FALSE;
  697. p1:=0;
  698. p2:=0;
  699. RxState := GotESC
  700. ELSE
  701. Output(c)
  702. END; |
  703. GotESC : IF c='[' THEN
  704. RxState := GotBrack
  705. ELSIF c='(' THEN
  706. RxState := GotLParen
  707. ELSIF c=')' THEN
  708. RxState := GotRParen
  709. ELSIF c='#' THEN
  710. RxState := GotHash
  711. ELSE
  712. ShortCode(c);
  713. RxState := Normal;
  714. END; |
  715. GotBrack : IF c='?' THEN
  716. DECPrivate := TRUE;
  717. RxState := ReadingP1;
  718. ELSIF (c>='0') AND (c<='9') THEN
  719. p1 := ORD(c)-48;
  720. RxState := ReadingP1;
  721. ELSIF (c=';') THEN
  722. RxState := ReadingP2;
  723. ELSE
  724. CheckCode(c);
  725. RxState := Normal;
  726. END; |
  727. GotLParen : NewCharSet(c,G0);
  728. RxState := Normal; |
  729. GotRParen : NewCharSet(c,G1);
  730. RxState := Normal; |
  731. GotHash : RxState := Normal; (* ignore line attributes *) |
  732. ReadingP1 : IF (c>='0') AND (c<='9') THEN
  733. p1 := p1*10 + ORD(c)-48;
  734. ELSIF c=';' THEN
  735. RxState := ReadingP2
  736. ELSE
  737. CheckCode(c);
  738. RxState := Normal;
  739. END; |
  740. ReadingP2 : IF (c>='0') AND (c<='9') THEN
  741. p2 := p2*10 + ORD(c)-48;
  742. ELSE
  743. CheckCode(c);
  744. RxState := Normal;
  745. END; |
  746. END;
  747. END VT100RxSM;
  748. (*.............................................*)
  749. VAR
  750. CursorY : CARDINAL;
  751. PROCEDURE VT52RxSM(c:CHAR);
  752. VAR
  753. Seq : ARRAY[0..3] OF CHAR;
  754. BEGIN
  755. CASE RxState OF
  756. Normal : IF c=CHR(27) THEN
  757. RxState:=GotESC
  758. ELSE
  759. Output(c)
  760. END; |
  761. GotESC : CASE c OF
  762. '<' : SelectEmulation(EmVT100); |
  763. '=' : NumKeyPad:=FALSE; |
  764. '>' : NumKeyPad:=TRUE; |
  765. 'F' : CurrCharSet:=SpecialChar; |
  766. 'G' : CurrCharSet:=US; |
  767. 'A'..'D' : CursorMovement(c,1); |
  768. 'H' : GotoXY(0,0); |
  769. 'Y' : RxState := VT52Line; |
  770. 'I' : IF cy>ScreenTop THEN
  771. DEC(cy);
  772. ELSE
  773. Scroll(-1);
  774. END;
  775. GotoXY(cx,cy); |
  776. 'K' : EraseCursorToEol; |
  777. 'J' : ClrEos; |
  778. 'Z' : Seq:=' /Z';
  779. Seq[0]:=CHR(27);
  780. StuffKbdBuffer(Seq,3); |
  781. END;
  782. IF RxState<>VT52Line THEN
  783. RxState:=Normal;
  784. END; |
  785. VT52Line : IF c>=' ' THEN
  786. CursorY := ORD(c)-32;
  787. RxState := VT52Col;
  788. ELSE
  789. RxState := Normal;
  790. END; |
  791. VT52Col : IF c>=' ' THEN
  792. GotoXY(ORD(c)-32,CursorY);
  793. END;
  794. RxState := Normal; |
  795. END;
  796. END VT52RxSM;
  797. (*.............................................*)
  798. VAR
  799. ANSIp : ARRAY[1..9] OF CARDINAL ;
  800. ANSIn : [0..9];
  801. PROCEDURE ANSIRxSM(c:CHAR);
  802. (* Reduced PC compatible ANSI driver *)
  803. VAR
  804. i : CARDINAL;
  805. W : Window.WinType;
  806. wc : Window.Color;
  807. Seq : ARRAY[0..9] OF CHAR;
  808. BEGIN
  809. CASE RxState OF
  810. Normal : IF c=CHR(27) THEN
  811. RxState:=GotESC;
  812. ELSE
  813. Output(c);
  814. END; |
  815. GotESC : IF c='[' THEN
  816. RxState:=ANSICmd;
  817. FOR i := 1 TO 9 DO
  818. ANSIp[i] := 0;
  819. END ;
  820. ANSIn := 1;
  821. ELSE
  822. Output(c);
  823. RxState:=Normal;
  824. END; |
  825. ANSICmd : RxState:=Normal;
  826. CASE c OF
  827. '0'..'9' : ANSIp[ANSIn] := ANSIp[ANSIn]*10+ORD(c)-ORD('0');
  828. RxState:=ANSICmd; |
  829. ';' : IF ANSIn<9 THEN
  830. INC(ANSIn);
  831. END;
  832. RxState:=ANSICmd; |
  833. 'f','H' : IF ANSIp[1] > 0 THEN
  834. DEC(ANSIp[1]);
  835. END;
  836. IF ANSIp[2] > 0 THEN
  837. DEC(ANSIp[2]);
  838. END;
  839. GotoXY(ANSIp[2],ANSIp[1]); |
  840. 'A'..'D' : CursorMovement(c,ANSIp[1]); |
  841. 'J','K' : EraseCommand(c,ANSIp[1]); |
  842. 's' : CSave.cx:=cx;
  843. CSave.cy:=cy; |
  844. 'u' : GotoXY(CSave.cx,CSave.cy); |
  845. 'n' : IF ANSIp[1]=6 THEN
  846. GetCursorPosition(Seq,i);
  847. IF i>0 THEN
  848. StuffKbdBuffer(Seq,i);
  849. END;
  850. END; |
  851. 'm' : FOR i := 1 TO ANSIn DO
  852. CASE ANSIp[i] OF
  853. 0 : CurrAttr := NormalAttr; |
  854. 1 : INCL(CurrAttr,Bold); |
  855. 4 : CurrAttr := CurrAttr-AttrSet{Red,Green}+AttrSet{Blue}; |
  856. 5 : INCL(CurrAttr,Blink); |
  857. 7 : CurrAttr := AttrSet((SHORTCARD(CurrAttr*AttrSet{Red,Green,Blue})<<4)+(SHORTCARD(CurrAttr*AttrSet{RedBack,GreenBack,BlueBack})>>4)+(SHORTCARD(CurrAttr*AttrSet{Bold,Blink})));|
  858. 8 : CurrAttr := AttrSet{}; |
  859. 30 : CurrAttr := CurrAttr-AttrSet{Red,Green,Blue}; |
  860. 31 : CurrAttr := CurrAttr-AttrSet{Green,Blue}+AttrSet{Red}; |
  861. 32 : CurrAttr := CurrAttr-AttrSet{Red,Blue}+AttrSet{Green}; |
  862. 33 : CurrAttr := CurrAttr-AttrSet{Blue}+AttrSet{Red,Green}; |
  863. 34 : CurrAttr := CurrAttr-AttrSet{Red,Green}+AttrSet{Blue}; |
  864. 35 : CurrAttr := CurrAttr-AttrSet{Green}+AttrSet{Red,Blue}; |
  865. 36 : CurrAttr := CurrAttr-AttrSet{Red}+AttrSet{Blue,Green}; |
  866. 37 : CurrAttr := CurrAttr+AttrSet{Red,Blue,Green}; |
  867. 40 : CurrAttr := CurrAttr-AttrSet{RedBack,GreenBack,BlueBack}; |
  868. 41 : CurrAttr := CurrAttr-AttrSet{GreenBack,BlueBack}+AttrSet{RedBack}; |
  869. 42 : CurrAttr := CurrAttr-AttrSet{RedBack,BlueBack}+AttrSet{GreenBack}; |
  870. 43 : CurrAttr := CurrAttr-AttrSet{BlueBack}+AttrSet{RedBack,GreenBack}; |
  871. 44 : CurrAttr := CurrAttr-AttrSet{RedBack,GreenBack}+AttrSet{BlueBack}; |
  872. 45 : CurrAttr := CurrAttr-AttrSet{GreenBack}+AttrSet{RedBack,BlueBack}; |
  873. 46 : CurrAttr := CurrAttr-AttrSet{RedBack}+AttrSet{BlueBack,GreenBack}; |
  874. 47 : CurrAttr := CurrAttr+AttrSet{RedBack,BlueBack,GreenBack}; |
  875. END;
  876. SetColor(CurrAttr);
  877. END;
  878. ELSE
  879. Output(c);
  880. END;
  881. END;
  882. END ANSIRxSM;
  883. (*.............................................*)
  884. PROCEDURE WrChar(c:CHAR);
  885. BEGIN
  886. IF ORD(c)>127 THEN
  887. c:=CHR(ORD(c)-128);
  888. END;
  889. CASE VTMode OF
  890. EmVT100: VT100RxSM(c); (* call VT100 receive state machine *) |
  891. EmVT52: VT52RxSM(c); (* call VT52 receive state machine *) |
  892. EmANSI: ANSIRxSM(c); (* call ANSI receive state machine *) |
  893. END;
  894. END WrChar;
  895. (*.............................................*)
  896. PROCEDURE KeyTranslate;
  897. (* Emulate sequences produced by VT100 or VT52 keyboard. There is a *)
  898. (* dearth of keypad keys on the IBM for this, so instead, to use *)
  899. (* cursor keys you use the unshifted keys. To access the numeric *)
  900. (* keypad (or the application keys in alterate mode) you hold down *)
  901. (* shift while pressing the appropriate keys. This still leaves us *)
  902. (* five keys short for the keypad "enter" and PF1..PF4. The "Enter" *)
  903. (* key is produced by F6 on the PC, and PF1..PF4 correspond to F7..F8*)
  904. (* on the PC. *)
  905. VAR
  906. c : CHAR;
  907. Lnth : CARDINAL;
  908. Seq : ARRAY[0..2] OF CHAR;
  909. BEGIN
  910. c := Keyboard.RdKey();
  911. IF c=0C THEN
  912. (* NOTE: Alt-Key combinations are reserved for use by the comms *)
  913. (* package, so if this turns out to be one we need to insert the*)
  914. (* preceding NUL into the kbd.buff also, otherwise the equivalent*)
  915. (* VT100 sequence gets stuffed into the keyboard buffer. *)
  916. c := Keyboard.RdKey();
  917. Seq[0]:=CHR(27);
  918. Lnth:=3;
  919. IF c=CHR(64) THEN
  920. IF NumKeyPad THEN
  921. Seq[0]:=CHR(13);
  922. Lnth:=1;
  923. IF NewLineMode THEN
  924. Seq[1]:=CHR(10);
  925. Lnth:=2;
  926. END;
  927. ELSE
  928. Seq[1]:='O';
  929. Seq[2]:='M';
  930. END;
  931. ELSIF (c>=CHR(65)) AND (c<=CHR(68)) THEN
  932. IF VTMode=EmVT100 THEN
  933. Seq[1]:='O';
  934. ELSE
  935. Seq[1]:='?';
  936. END;
  937. CASE ORD(c) OF
  938. 65 : Seq[2]:='P'; |
  939. 66 : Seq[2]:='Q'; |
  940. 67 : Seq[2]:='R'; |
  941. 68 : Seq[2]:='S'; |
  942. END;
  943. IF (VTMode=EmVT52) AND (NumKeyPad) THEN
  944. Seq[1]:=Seq[2];
  945. Lnth:=2;
  946. END;
  947. ELSE
  948. IF ANSIKeys THEN
  949. Seq[1]:='[';
  950. ELSE
  951. Seq[1]:='O';
  952. END;
  953. CASE ORD(c) OF
  954. 72 : Seq[2]:='A'; (* cursor up *) |
  955. 75 : Seq[2]:='D'; (* cursor left *) |
  956. 77 : Seq[2]:='C'; (* cursor right *) |
  957. 80 : Seq[2]:='B'; (* cursor down *) |
  958. ELSE
  959. Seq[0]:=0C; Seq[1]:=c; StuffKbdBuffer(Seq,2);
  960. RETURN
  961. END;
  962. IF VTMode=EmVT52 THEN
  963. Seq[1]:=Seq[2];
  964. Lnth:=2;
  965. END;
  966. END;
  967. StuffKbdBuffer(Seq,Lnth);
  968. ELSIF (Keyboard.ScanCode>=CHR(71)) AND (Keyboard.ScanCode<=CHR(83)) THEN
  969. IF NumKeyPad THEN
  970. IF c='+' THEN
  971. c:=',';
  972. END;
  973. StuffKbdBuffer(c,1);
  974. ELSE
  975. Seq[0]:=CHR(27);
  976. IF VTMode=EmVT100 THEN
  977. Seq[1]:='O';
  978. ELSE
  979. Seq[1]:='?';
  980. END;
  981. CASE c OF
  982. '0' : Seq[2]:='p'; |
  983. '1' : Seq[2]:='q'; |
  984. '2' : Seq[2]:='r'; |
  985. '3' : Seq[2]:='s'; |
  986. '4' : Seq[2]:='t'; |
  987. '5' : Seq[2]:='u'; |
  988. '6' : Seq[2]:='v'; |
  989. '7' : Seq[2]:='w'; |
  990. '8' : Seq[2]:='x'; |
  991. '9' : Seq[2]:='y'; |
  992. '-' : Seq[2]:='m'; |
  993. '+' : Seq[2]:='l'; |
  994. '.' : Seq[2]:='n'; |
  995. END;
  996. StuffKbdBuffer(Seq,3);
  997. END;
  998. ELSE
  999. Seq[0]:=c;
  1000. Lnth:=1;
  1001. IF (c=CHR(13)) AND (NewLineMode) THEN
  1002. Seq[1]:=CHR(10); Lnth:=2;
  1003. END;
  1004. StuffKbdBuffer(Seq,Lnth);
  1005. END;
  1006. END KeyTranslate;
  1007. (*.............................................*)
  1008. PROCEDURE RdKey():CHAR;
  1009. VAR
  1010. c : CHAR;
  1011. BEGIN
  1012. LOOP
  1013. WITH Kbd DO
  1014. IF rptr<>wptr THEN
  1015. c:=Buff[rptr];
  1016. rptr:=(rptr+1) MOD 100H;
  1017. EXIT
  1018. ELSE
  1019. KeyTranslate();
  1020. END;
  1021. END;
  1022. END;
  1023. RETURN c;
  1024. END RdKey;
  1025. (*.............................................*)
  1026. PROCEDURE KeyPressed():BOOLEAN;
  1027. BEGIN
  1028. IF Kbd.rptr<>Kbd.wptr THEN
  1029. RETURN TRUE
  1030. ELSIF Keyboard.KeyPressed() THEN
  1031. KeyTranslate();
  1032. RETURN KeyPressed();
  1033. ELSE
  1034. RETURN FALSE
  1035. END;
  1036. END KeyPressed;
  1037. (*.............................................*)
  1038. PROCEDURE ClearScreen;
  1039. BEGIN
  1040. GotoXY(0,0);
  1041. ClrEos;
  1042. END ClearScreen;
  1043. (*.............................................*)
  1044. PROCEDURE EmulateVT100;
  1045. BEGIN
  1046. SelectEmulation(EmVT100);
  1047. END EmulateVT100;
  1048. (*.............................................*)
  1049. PROCEDURE EmulateVT52;
  1050. BEGIN
  1051. SelectEmulation(EmVT52);
  1052. END EmulateVT52;
  1053. (*.............................................*)
  1054. PROCEDURE EmulateANSI;
  1055. BEGIN
  1056. SelectEmulation(EmANSI);
  1057. END EmulateANSI;
  1058. (*.............................................*)
  1059. PROCEDURE Emulation():Emulations;
  1060. BEGIN
  1061. RETURN VTMode;
  1062. END Emulation;
  1063. (*.............................................*)
  1064. BEGIN
  1065. ResetTerm;
  1066. END Term.
  1067.