BYTEFIDD.MOD 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. IMPLEMENTATION MODULE ByteFiddler;
  2. (*
  3. * REPERTOIRE
  4. * Release 1.6
  5. * By Charles Bradford and Cole Brecheen
  6. * (c) Copyright 1985-1992 PMI
  7. * Green Bay, Wisconsin
  8. * All rights reserved
  9. * (414) 468-6040
  10. *
  11. * $Header: D:/logfiles/mods/bytefidd.mov 1.5 10 Mar 1991 15:25:24 coleb $
  12. *
  13. *)
  14. IMPORT ErrorManager;
  15. IMPORT LowLevel;
  16. IMPORT SYSTEM;
  17. VAR
  18. Initialized : BOOLEAN;
  19. PROCEDURE Init();
  20. BEGIN
  21. IF Initialized THEN
  22. RETURN;
  23. ELSE
  24. Initialized := TRUE;
  25. END;
  26. ErrorManager.Init();
  27. LowLevel.Init();
  28. END Init;
  29. TYPE
  30. BitRange = [0..15];
  31. WordConverter =
  32. RECORD
  33. CASE : BOOLEAN OF
  34. TRUE :
  35. x : SYSTEM.WORD;
  36. | FALSE :
  37. lo, hi : CHAR;
  38. END;
  39. END;
  40. LongConverter =
  41. RECORD
  42. CASE : BOOLEAN OF
  43. TRUE: long: LONGINT;
  44. | FALSE: locard, hicard: CARDINAL;
  45. END;
  46. END;
  47. PROCEDURE BitRangeToInt(TheSet : BITSET; LowBit, HighBit : CARDINAL;
  48. VAR answer : CARDINAL);
  49. (*BitRangeToInt lets us specify the bits that store the
  50. value in which we're interested, and it loads that value
  51. into the last parameter in the list.*)
  52. BEGIN
  53. LowLevel.ShiftLeft(TheSet, 15-HighBit);
  54. (*Assumes bit 15 is most significant.*)
  55. LowLevel.ShiftRight(TheSet, LowBit+(15-HighBit));
  56. answer := CARDINAL(TheSet);
  57. END BitRangeToInt;
  58. PROCEDURE BytesToWord(lobyte, hibyte : CARDINAL) : CARDINAL;
  59. (*Takes two bytes and stores them in a single word. The
  60. last byte in the parameter list is most significant.*)
  61. VAR
  62. conv : WordConverter;
  63. BEGIN
  64. conv.lo := CHR(lobyte);
  65. conv.hi := CHR(hibyte);
  66. RETURN (CARDINAL(conv.x));
  67. END BytesToWord;
  68. PROCEDURE CardinalToDate(TheInt : CARDINAL; VAR month, day, year :
  69. CARDINAL);
  70. VAR
  71. TheSet : BITSET;
  72. BEGIN
  73. (*CardinalToDate*)
  74. TheSet := BITSET(TheInt);
  75. (*
  76. Diagnostics.diagB( 'TheDate', TheSet );
  77. *)
  78. BitRangeToInt(TheSet, 0, 4, day);
  79. BitRangeToInt(TheSet, 5, 8, month);
  80. BitRangeToInt(TheSet, 9, 15, year);
  81. INC(year, 80);
  82. END CardinalToDate;
  83. PROCEDURE CardinalToTime(TheCardinal : CARDINAL; VAR hours,
  84. minutes, seconds : CARDINAL);
  85. VAR
  86. TheSet : BITSET;
  87. BEGIN
  88. (*CardinalToTime*)
  89. TheSet := BITSET(TheCardinal);
  90. (*
  91. Diagnostics.diagB( 'TheTime', TheSet );
  92. *)
  93. BitRangeToInt(TheSet, 11, 15, hours);
  94. BitRangeToInt(TheSet, 5, 10, minutes);
  95. BitRangeToInt(TheSet, 0, 4, seconds);
  96. seconds := seconds*2;
  97. (*We double seconds because the operating system stores
  98. this value in two-second increments.*)
  99. END CardinalToTime;
  100. PROCEDURE DateToCardinal(month, day, year : CARDINAL) : CARDINAL;
  101. CONST
  102. msg = 'Invalid date';
  103. VAR
  104. BitSet1, BitSet2 : BITSET;
  105. buf : BitRange;
  106. BEGIN
  107. (*DateToCardinal*)
  108. IF year>1900 THEN
  109. year := year-1900;
  110. END;
  111. IF ((year>=80) AND (year<=199)) THEN
  112. year := year-80;
  113. ELSE
  114. (*
  115. Diagnostics.diagC( 'year', year );
  116. *)
  117. ErrorManager.WARN(msg);
  118. END;
  119. IF ((month<1) OR (month>12)) THEN
  120. (*
  121. Diagnostics.diagC( 'month', month );
  122. *)
  123. ErrorManager.WARN(msg);
  124. END;
  125. IF ((day<1) OR (day>31)) THEN
  126. (*
  127. Diagnostics.diagC( 'day', day );
  128. *)
  129. ErrorManager.WARN(msg);
  130. END;
  131. BitSet2 := BITSET(0);
  132. BitSet1 := BITSET(day);
  133. FOR buf := 0 TO 15 DO
  134. IF buf IN BitSet1 THEN
  135. INCL(BitSet2, buf);
  136. END;
  137. END;
  138. BitSet1 := BITSET(month);
  139. FOR buf := 0 TO 15 DO
  140. IF buf IN BitSet1 THEN
  141. INCL(BitSet2, buf+5);
  142. END;
  143. END;
  144. BitSet1 := BITSET(year);
  145. FOR buf := 0 TO 15 DO
  146. IF buf IN BitSet1 THEN
  147. INCL(BitSet2, buf+9);
  148. END;
  149. END;
  150. RETURN CARDINAL(BitSet2);
  151. END DateToCardinal;
  152. PROCEDURE HighByte( TheCard: CARDINAL ): CHAR;
  153. VAR
  154. tmp: WordConverter;
  155. BEGIN
  156. tmp.x := SYSTEM.WORD(TheCard);
  157. RETURN tmp.hi;
  158. END HighByte;
  159. PROCEDURE HighCard( TheLong: LONGINT ): CARDINAL;
  160. VAR
  161. tmp: LongConverter;
  162. BEGIN
  163. tmp.long := TheLong;
  164. RETURN tmp.hicard;
  165. END HighCard;
  166. PROCEDURE LowByte( TheCard: CARDINAL ): CHAR;
  167. VAR
  168. tmp: WordConverter;
  169. BEGIN
  170. tmp.x := SYSTEM.WORD(TheCard);
  171. RETURN tmp.lo;
  172. END LowByte;
  173. PROCEDURE LowCard( TheLong: LONGINT ): CARDINAL;
  174. VAR
  175. tmp: LongConverter;
  176. BEGIN
  177. tmp.long := TheLong;
  178. RETURN tmp.locard;
  179. END LowCard;
  180. PROCEDURE PeekChar( TheAdr: SYSTEM.ADDRESS ): CHAR;
  181. VAR
  182. tmp: LowLevel.Address8086;
  183. BEGIN
  184. tmp.a := TheAdr;
  185. RETURN tmp.b^;
  186. END PeekChar;
  187. PROCEDURE PokeChar( TheChar: CHAR; TheAdr: SYSTEM.ADDRESS );
  188. VAR
  189. tmp: LowLevel.Address8086;
  190. BEGIN
  191. tmp.a := TheAdr;
  192. tmp.b^ := TheChar;
  193. END PokeChar;
  194. PROCEDURE Size( VAR AnyObject: ARRAY OF SYSTEM.BYTE ): CARDINAL;
  195. BEGIN
  196. RETURN HIGH(AnyObject) + 1;
  197. END Size;
  198. PROCEDURE swap(VAR TheWord : SYSTEM.WORD);
  199. (*Reverses the order of the high and low bytes in TheWord.*)
  200. VAR
  201. conv : WordConverter;
  202. tmp : CHAR;
  203. BEGIN
  204. conv.x := TheWord;
  205. tmp := conv.hi;
  206. conv.hi := conv.lo;
  207. conv.lo := tmp;
  208. TheWord := conv.x;
  209. END swap;
  210. PROCEDURE TimeToCardinal(hours, minutes, seconds : CARDINAL) : CARDINAL;
  211. CONST
  212. msg = 'Invalid time';
  213. VAR
  214. BitSet1, BitSet2 : BITSET;
  215. buf : BitRange;
  216. BEGIN
  217. (*TimeToCardinal*)
  218. IF (hours>23) THEN
  219. (*
  220. Diagnostics.diagC( 'hours', hours );
  221. *)
  222. ErrorManager.WARN(msg);
  223. END;
  224. IF (minutes>59) THEN
  225. (*
  226. Diagnostics.diagC( 'minutes', minutes );
  227. *)
  228. ErrorManager.WARN(msg);
  229. END;
  230. IF (seconds>59) THEN
  231. (*
  232. Diagnostics.diagC( 'seconds', seconds );
  233. *)
  234. ErrorManager.WARN(msg);
  235. END;
  236. BitSet2 := BITSET(0);
  237. BitSet1 := BITSET(seconds DIV 2);
  238. FOR buf := 0 TO 15 DO
  239. IF buf IN BitSet1 THEN
  240. INCL(BitSet2, buf);
  241. END;
  242. END;
  243. BitSet1 := BITSET(minutes);
  244. FOR buf := 0 TO 15 DO
  245. IF buf IN BitSet1 THEN
  246. INCL(BitSet2, buf+5);
  247. END;
  248. END;
  249. BitSet1 := BITSET(hours);
  250. FOR buf := 0 TO 15 DO
  251. IF buf IN BitSet1 THEN
  252. INCL(BitSet2, buf+11);
  253. END;
  254. END;
  255. RETURN CARDINAL(BitSet2);
  256. END TimeToCardinal;
  257. BEGIN
  258. Initialized := FALSE;
  259. Init();
  260. END ByteFiddler.