TSRCALC.MOD 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. (*========================================================
  2. == TopSpeed Modula-2 V3.10 ==
  3. == demo program: ==
  4. == ==
  5. == Terminate and Stay Resident Calculator ==
  6. == ==
  7. ========================================================*)
  8. (*# data(stack_size=>2000H) *)
  9. (*# check(stack=>off,index=>off,range=>off,overflow=>off,nil_ptr=>off) *)
  10. (*# debug(vid=>off) *)
  11. MODULE TSRcalc;
  12. (* ==== *)
  13. IMPORT IO,Window,Lib,SYSTEM,Storage;
  14. IMPORT TSR ;
  15. CONST Ix = 30;
  16. Iy = 10;
  17. Sx = 22;
  18. Sy = 2;
  19. TYPE LONGSET = SET OF [0..31];
  20. StateType = (DigState,NumState,OptState);
  21. ModeType = (DecMode,HexMode,BinMode);
  22. ModeInfRec = RECORD
  23. Name:ARRAY[1..4] OF CHAR;
  24. Base:CARDINAL;
  25. END;
  26. ModeInfArr = ARRAY ModeType OF ModeInfRec;
  27. CONST ModeInf = ModeInfArr(ModeInfRec("Dec",10),ModeInfRec("Hex",16),ModeInfRec
  28. ("Bin",2));
  29. VAR Value,Other,Memory :LONGINT;
  30. Mode :ModeType;
  31. State :StateType;
  32. Q,C,Opt :CHAR;
  33. W :Window.WinType;
  34. X,Y :CARDINAL;
  35. CONST KeyL = CHR(128+75);
  36. KeyR = CHR(128+77);
  37. KeyU = CHR(128+72);
  38. KeyD = CHR(128+80);
  39. Key5 = CHR(128+63);
  40. Key10 = CHR(128+68);
  41. PROCEDURE BiosGetKey():CHAR;
  42. (* ========== *)
  43. VAR R:SYSTEM.Registers;
  44. BEGIN
  45. R.AH := 0;
  46. Lib.Intr(R,016H);
  47. IF R.AL<>0 THEN
  48. RETURN CHR(R.AL);
  49. ELSE
  50. RETURN CHR(128+R.AH);
  51. END;
  52. END BiosGetKey;
  53. PROCEDURE UpdateDisplay;
  54. (* ============== *)
  55. CONST Width = 16;
  56. VAR I:CARDINAL;
  57. BEGIN
  58. Window.GotoXY(4,1);
  59. CASE Mode OF
  60. | DecMode:IO.WrLngInt(Value,Width);
  61. | HexMode:IO.WrLngHex(Value,Width);
  62. | BinMode:FOR I := Width-1 TO 0 BY -1 DO
  63. IO.WrChar(CHR(ORD('0')+ORD(I IN LONGSET(Value))));
  64. END;
  65. END;
  66. Window.GotoXY(4,2);
  67. IO.WrStr(ModeInf[Mode].Name);
  68. IO.WrStr(" ");
  69. IF Memory<>0 THEN
  70. IO.WrStr("M");
  71. ELSE
  72. IO.WrStr(" ");
  73. END;
  74. END UpdateDisplay;
  75. PROCEDURE Crash(L:CARDINAL);
  76. (* ===== *)
  77. VAR I:SHORTCARD;
  78. J:CARDINAL;
  79. P,Q:BITSET;
  80. BEGIN
  81. Q := BITSET(SYSTEM.In(061H));
  82. P := Q*{2..7};
  83. J := L;
  84. WHILE J>0 DO
  85. SYSTEM.Out(061H,SHORTCARD(P));
  86. FOR I := 0 TO SHORTCARD([400H:J]^) DO
  87. P := P/{1};
  88. END;
  89. DEC(J);
  90. END;
  91. SYSTEM.Out(061H,SHORTCARD(Q));
  92. L := L DIV 100;
  93. IF (X>=L) AND (Y>=L) THEN
  94. FOR J := 1 TO L DO
  95. DEC(X);
  96. DEC(Y);
  97. Window.Change(W,X,Y,X+Sx+J+J,Y+Sy+J+J);
  98. END;
  99. FOR J := L TO 1 BY -1 DO
  100. INC(X);
  101. INC(Y);
  102. Window.Change(W,X,Y,X+Sx+J+J-1,Y+Sy+J+J-1);
  103. END;
  104. END
  105. END Crash;
  106. PROCEDURE RunCalc;
  107. (* ======= *)
  108. VAR I,F:CARDINAL;
  109. R:SYSTEM.Registers;
  110. BEGIN
  111. Window.PutOnTop(W);
  112. Window.Use(W);
  113. LOOP
  114. CASE C OF
  115. | 'c':Value := 0;
  116. Other := 0;
  117. Opt := '=';
  118. | '0'..'9','A'..'F',
  119. Key5..Key10:IF C<='9' THEN
  120. DEC(C,ORD('0'));
  121. ELSIF (C>='A')AND(C<='F') THEN
  122. DEC(C,ORD('A'));
  123. INC(C,10);
  124. ELSE
  125. DEC(C,ORD(Key5));
  126. INC(C,10);
  127. END;
  128. IF ORD(C)<ModeInf[Mode].Base THEN
  129. IF State<>DigState THEN
  130. Value := 0;
  131. END;
  132. State := DigState;
  133. IF Value<=MAX(LONGINT) DIV LONGINT(ModeInf[Mode].Base)
  134. THEN
  135. Value := Value*LONGINT(ModeInf[Mode].Base)+LONGINT(ORD
  136. (C));
  137. ELSE
  138. Crash(50);
  139. END;
  140. ELSE
  141. Crash(100);
  142. END;
  143. | 10C:IF State = DigState THEN
  144. Value := Value DIV LONGINT(ModeInf[Mode].Base);
  145. END;
  146. | 'e':Value := 0;
  147. State := NumState;
  148. | '+','-','*','/','a','o','x','=',CHR(13),'X','O':
  149. IF State<>OptState THEN
  150. CASE Opt OF
  151. | '+':Other := Other+Value;
  152. | '-':Other := Other-Value;
  153. | '*':Other := Other*Value;
  154. | '/':
  155. IF Value = 0 THEN Other := MAX(LONGINT)
  156. ELSE Other := Other DIV Value;
  157. END;
  158. | 'a':Other := LONGINT(LONGSET(Other)*LONGSET(Value));
  159. | 'O',
  160. 'o':Other := LONGINT(LONGSET(Other)+LONGSET(Value));
  161. | 'X',
  162. 'x':Other := LONGINT(LONGSET(Other)/LONGSET(Value));
  163. | CHR(13),
  164. '=':Other := Value;
  165. END;
  166. Value := Other;
  167. State := OptState;
  168. END;
  169. Opt := C;
  170. | 'd':Mode := DecMode;
  171. State := NumState;
  172. | 'H',
  173. 'h':Mode := HexMode;
  174. State := NumState;
  175. | 'b':Mode := BinMode;
  176. State := NumState;
  177. | 'M',
  178. 'm':C := BiosGetKey();
  179. CASE CAP(C) OF
  180. | '+':Memory := Memory+Value;
  181. | '-':Memory := Memory-Value;
  182. | '*':Memory := Memory*Value;
  183. | '/':Memory := Memory DIV Value;
  184. | 'R':Value := Memory;
  185. State := NumState;
  186. | 'C':Memory := 0;
  187. | '=':Memory := Value;
  188. END;
  189. State := NumState;
  190. | KeyL,KeyR,
  191. KeyU,KeyD:
  192. IF (C = KeyL) AND (X>0) THEN DEC(X);
  193. ELSIF (C = KeyR) AND (X+Sx<78) THEN INC(X);
  194. ELSIF (C = KeyU) AND (Y>0) THEN DEC(Y);
  195. ELSIF (C = KeyD) AND (Y+Sy<23) THEN INC(Y);
  196. ELSE
  197. F := 2000;
  198. WHILE (X<>Ix) OR (Y<>Iy) DO
  199. FOR I := 1 TO 10 DO
  200. Lib.Sound(F);
  201. Lib.Delay(5);
  202. DEC(F,F DIV 50);
  203. END;
  204. IF X>Ix THEN DEC(X); END;
  205. IF X<Ix THEN INC(X); END;
  206. IF Y>Iy THEN DEC(Y); END;
  207. IF Y<Iy THEN INC(Y); END;
  208. Window.Change(W,X,Y,X+Sx+1,Y+Sy+1);
  209. END;
  210. Lib.NoSound;
  211. Crash(800);
  212. C := ' ';
  213. EXIT;
  214. END;
  215. Window.Change(W,X,Y,X+Sx+1,Y+Sy+1);
  216. | ' ':;
  217. | CHR(27):
  218. C := ' ';
  219. EXIT;
  220. | CHR(45+128): (* ALT X *)
  221. TSR.DeInstall ;
  222. EXIT ;
  223. |
  224. ELSE
  225. Crash(200);
  226. END;
  227. UpdateDisplay;
  228. C := BiosGetKey();
  229. END;
  230. Window.Hide(W);
  231. END RunCalc;
  232. BEGIN
  233. IO.WrStr("Installing TOPSPEED-CALC,"); IO.WrLn;
  234. IO.WrStr("AltZ to activate."); IO.WrLn;
  235. X := Ix;
  236. Y := Iy;
  237. W := Window.Open(Window.WinDef(Ix,Iy,Ix+Sx+1,Iy+Sy+1,
  238. Window.White,Window.Black,
  239. FALSE,FALSE,TRUE,TRUE,
  240. Window.DoubleFrame,Window.Black,
  241. Window.Green));
  242. Window.SetTitle(W," TOPSPEED-CALC ",Window.CenterUpperTitle);
  243. Memory := 0;
  244. Mode := DecMode;
  245. State := NumState;
  246. C := 'c';
  247. TSR.Install(RunCalc,TSR.KBFlagSet{TSR.Alt},44,400H) ; (* ALT Z *)
  248. Window.Clear ;
  249. IO.WrStr("TOPSPEED-CALC Deinstalled.");
  250. IO.WrLn;
  251. END TSRcalc.
  252. (*======================================================*)
  253.