tsrcalc.mod 7.7 KB

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