PACK.MOD 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. (*%T _fcall *) (*# call(near_call=>on,seg_name=>Btree) *) (*%E *)
  2. IMPLEMENTATION MODULE Pack;
  3. (*
  4. Copyright (C) 1990 Jensen & Partners International
  5. *)
  6. IMPORT Btree, apack2;
  7. (*%T _mthread *)
  8. IMPORT Process;
  9. (*%E *)
  10. MODULE inline;
  11. EXPORT MemMove, MemFastMove, AddAddr, IncAddr, DecAddr;
  12. TYPE
  13. A2 = ARRAY[0..1] OF SHORTCARD;
  14. A3 = ARRAY[0..2] OF SHORTCARD;
  15. A6 = ARRAY[0..5] OF SHORTCARD;
  16. A8 = ARRAY[0..7] OF SHORTCARD;
  17. A19 = ARRAY[0..18] OF SHORTCARD;
  18. A21 = ARRAY[0..20] OF SHORTCARD;
  19. (*%T _fptr *)
  20. (*# save *)
  21. (*# call(inline=>on) *)
  22. (*# call(reg_param=>(si,ax,di,es,cx),reg_saved=>(ax,bx,dx,ds,es,st1,st2,st3,st4,st5,st6)) *)
  23. PROCEDURE MemMove(s,r: ADDRESS; c: CARDINAL)=A21(0E3H,013H,(* jcxz $1 *)
  24. 09CH, (* pushf *)
  25. 01EH, (* push ds *)
  26. 08EH,0D8H,(* mov ds,ax *)
  27. 03BH,0FEH,(* cmp di,si *)
  28. 072H,007H,(* jb $0 *)
  29. 003H,0F1H,(* add si,cx *)
  30. 003H,0F9H,(* add di,cx *)
  31. 04EH, (* dec si *)
  32. 04FH, (* dec di *)
  33. 0FDH, (* std *)
  34. (* $0: *)
  35. 0F3H,0A4H,(* rep ;movsb *)
  36. 01FH, (* pop ds *)
  37. 09DH); (* popf *)
  38. (* $1: *)
  39. (*# restore *)
  40. (*# save *)
  41. (*# call(inline=>on) *)
  42. (*# call(reg_param=>(si,ax,di,es,cx),reg_saved=>(ax,bx,dx,ds,es,st1,st2,st3,st4,st5,st6)) *)
  43. PROCEDURE MemFastMove(s,r: ADDRESS; c: CARDINAL)=A8(0E3H,006H,(* jcxz $0 *)
  44. 01EH, (* push ds *)
  45. 08EH,0D8H,(* mov ds,ax *)
  46. 0F3H,0A4H,(* rep ;movsb *)
  47. 01FH); (* pop ds *)
  48. (* $0: *)
  49. (*# restore *)
  50. (*# save *)
  51. (*# call(inline=>on) *)
  52. (*# call(reg_param=>(ax,dx,cx),reg_saved=>(bx,cx,dx,si,di,ds,es,st1,st2,st3,st4,st5,st6)) *)
  53. PROCEDURE AddAddr(A: ADDRESS; I: CARDINAL): ADDRESS=A2(003H,0C1H);(*add ax,cx*)
  54. (*# restore *)
  55. (*# save *)
  56. (*# call(inline=>on) *)
  57. (*# call(reg_param=>(bx,es,ax),reg_saved=>(ax,bx,cx,dx,si,di,ds,es,st1,st2,st3,st4,st5,st6)) *)
  58. PROCEDURE IncAddr(VAR a: ADDRESS; i: CARDINAL)=A3(026H,001H,007H); (* add es:[bx],cx *)
  59. (*# restore *)
  60. (*# save *)
  61. (*# call(inline=>on) *)
  62. (*# call(reg_param=>(bx,es,ax),reg_saved=>(ax,bx,cx,dx,si,di,ds,es,st1,st2,st3,st4,st5,st6)) *)
  63. PROCEDURE DecAddr(VAR a: ADDRESS; i: CARDINAL)=A3(026H,029H,007H); (* sub es:[bx],cx *)
  64. (*# restore *)
  65. (*%E *)
  66. (*%F _fptr *)
  67. (*# save *)
  68. (*# call(inline=>on) *)
  69. (*# call(reg_param=>(si,di,cx),reg_saved=>(ax,bx,dx,ds,st1,st2,st3,st4,st5,st6)) *)
  70. PROCEDURE MemMove(s,r: ADDRESS; c: CARDINAL)=A19(0E3H,011H,(* jcxz $1 *)
  71. 09CH, (* pushf *)
  72. 01EH, (* push ds *)
  73. 007H, (* pop es *)
  74. 03BH,0FEH,(* cmp di,si *)
  75. 072H,007H,(* jb $0 *)
  76. 003H,0F1H,(* add si,cx *)
  77. 003H,0F9H,(* add di,cx *)
  78. 04EH, (* dec si *)
  79. 04FH, (* dec di *)
  80. 0FDH, (* std *)
  81. (* $0: *)
  82. 0F3H,0A4H,(* rep; movsb*)
  83. 09DH); (* popf *)
  84. (* $1: *)
  85. (*# restore *)
  86. (*# save *)
  87. (*# call(inline=>on) *)
  88. (*# call(reg_param=>(si,di,cx),reg_saved=>(ax,bx,dx,ds,st1,st2,st3,st4,st5,st6)) *)
  89. PROCEDURE MemFastMove(s,r: ADDRESS; c: CARDINAL)=A6(0E3H,004H, (* jcxz $0 *)
  90. 01EH, (* push ds *)
  91. 007H, (* pop es *)
  92. 0F3H,0A4H); (* rep; movsb*)
  93. (* $0: *)
  94. (*# restore *)
  95. (*# save *)
  96. (*# call(inline=>on) *)
  97. (*# call(reg_param=>(ax,cx),reg_saved=>(bx,cx,dx,si,di,ds,es,st1,st2,st3,st4,st5,st6)) *)
  98. PROCEDURE AddAddr(A: ADDRESS; I: CARDINAL): ADDRESS=A2(003H,0C1H);(*add ax,cx*)
  99. (*# restore *)
  100. (*# save *)
  101. (*# call(inline=>on) *)
  102. (*# call(reg_param=>(bx,ax),reg_saved=>(ax,bx,cx,dx,si,di,ds,es,st1,st2,st3,st4,st5,st6)) *)
  103. PROCEDURE IncAddr(VAR a: ADDRESS; i: CARDINAL)=A2(001H,007H); (* add [bx],cx *)
  104. (*# restore *)
  105. (*# save *)
  106. (*# call(inline=>on) *)
  107. (*# call(reg_param=>(bx,ax),reg_saved=>(ax,bx,cx,dx,si,di,ds,es,st1,st2,st3,st4,st5,st6)) *)
  108. PROCEDURE DecAddr(VAR a: ADDRESS; i: CARDINAL)=A2(029H,007H); (* sub [bx],cx *)
  109. (*# restore *)
  110. (*%E *)
  111. END inline;
  112. TYPE
  113. PackBlk = RECORD
  114. _up,_p : CARDINAL;
  115. END;
  116. PackBlkPtr = POINTER TO PackBlk;
  117. PROCEDURE Packer(n: CARDINAL; in: ADDRESS; out: ADDRESS): CARDINAL;
  118. VAR
  119. ofs : CARDINAL;
  120. BEGIN
  121. ofs := Ofs(out^);
  122. WHILE n#0 DO
  123. IF n>apack2.buf_size THEN
  124. PackBlkPtr(out)^._up := apack2.buf_size;
  125. ELSE
  126. PackBlkPtr(out)^._up := n;
  127. END;
  128. (*%T _mthread *) Process.Lock(); (*%E *)
  129. PackBlkPtr(out)^._p := apack2.Pack(PackBlkPtr(out)^._up,in);
  130. (*%T _mthread *) Process.Unlock(); (*%E *)
  131. IF PackBlkPtr(out)^._up<=PackBlkPtr(out)^._p THEN
  132. PackBlkPtr(out)^._p := PackBlkPtr(out)^._up;
  133. MemFastMove(in,AddAddr(out,SIZE(PackBlk)),PackBlkPtr(out)^._p);
  134. ELSE
  135. MemFastMove(ADR(apack2.p),AddAddr(out,SIZE(PackBlk)),PackBlkPtr(out)^._p);
  136. END;
  137. DEC(n,PackBlkPtr(out)^._up);
  138. IncAddr(in,PackBlkPtr(out)^._up);
  139. IncAddr(out,SIZE(PackBlk)+PackBlkPtr(out)^._p);
  140. END;
  141. PackBlkPtr(out)^._up := 0;
  142. PackBlkPtr(out)^._p := 0;
  143. RETURN Ofs(out^)-ofs+SIZE(PackBlk);
  144. END Packer;
  145. PROCEDURE Unpacker(n: CARDINAL; in: ADDRESS; out: ADDRESS);
  146. BEGIN
  147. WHILE PackBlkPtr(in)^._p#0 DO
  148. IF PackBlkPtr(in)^._up=PackBlkPtr(in)^._p THEN
  149. MemFastMove(AddAddr(in,SIZE(PackBlk)),out,PackBlkPtr(in)^._up);
  150. ELSE
  151. MemFastMove(AddAddr(in,SIZE(PackBlk)),ADR(apack2.p),PackBlkPtr(in)^._p);
  152. (*%T _mthread *) Process.Lock(); (*%E *)
  153. apack2.Unpack(PackBlkPtr(in)^._up,out);
  154. (*%T _mthread *) Process.Unlock(); (*%E *)
  155. END;
  156. IncAddr(out,PackBlkPtr(in)^._up);
  157. IncAddr(in,SIZE(PackBlk)+PackBlkPtr(in)^._p);
  158. END;
  159. END Unpacker;
  160. PROCEDURE UnpackedSize(n: CARDINAL; in: ADDRESS): CARDINAL;
  161. VAR
  162. tmp : CARDINAL;
  163. BEGIN
  164. tmp := 0;
  165. WHILE PackBlkPtr(in)^._p#0 DO
  166. INC(tmp,PackBlkPtr(in)^._up);
  167. IncAddr(in,SIZE(PackBlk)+PackBlkPtr(in)^._p);
  168. END;
  169. RETURN tmp;
  170. END UnpackedSize;
  171. PROCEDURE Packing(): BOOLEAN;
  172. BEGIN
  173. RETURN TRUE;
  174. END Packing;
  175. PROCEDURE AdjustBlock(rs: CARDINAL): CARDINAL;
  176. BEGIN
  177. INC(rs,(rs+apack2.buf_size-1) DIV apack2.buf_size * SIZE(CARDINAL)*2);
  178. RETURN rs;
  179. END AdjustBlock;
  180. BEGIN
  181. Btree.Packer := Packer;
  182. Btree.Unpacker := Unpacker;
  183. Btree.UnpackedSize := UnpackedSize;
  184. Btree.Packing := Packing;
  185. Btree.AdjustBlock := AdjustBlock;
  186. END Pack.
  187.