Extended.mod 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. IMPLEMENTATION MODULE Extended ;
  2. FROM Instruction IMPORT Fetch ;
  3. FROM Stack IMPORT Pop, Push, PopReal, PushReal ;
  4. FROM Memory IMPORT CopyBytes, FillBytes, WriteSlot, ReadSlot,
  5. TopOfMemory ;
  6. FROM Local IMPORT GetSP, SetSP ;
  7. FROM Console IMPORT Fatal ;
  8. VAR
  9. hp : LONGCARD ;
  10. PROCEDURE HeapPtr () : LONGCARD ;
  11. BEGIN
  12. IF hp = 0 THEN
  13. hp := TopOfMemory () ;
  14. END ;
  15. RETURN hp ;
  16. END HeapPtr ;
  17. PROCEDURE Shl64 (u: LONGCARD; n: CARDINAL) : LONGCARD ;
  18. VAR i: CARDINAL ;
  19. BEGIN
  20. IF n >= 64 THEN
  21. RETURN 0 ;
  22. END ;
  23. FOR i := 1 TO n DO
  24. u := u * 2 ;
  25. END ;
  26. RETURN u ;
  27. END Shl64 ;
  28. PROCEDURE Mul64 (a, b: LONGCARD) : LONGCARD ;
  29. VAR ah, al, bh, bl, lolo, mid: LONGCARD ;
  30. BEGIN
  31. ah := a DIV 4294967296 ;
  32. al := a MOD 4294967296 ;
  33. bh := b DIV 4294967296 ;
  34. bl := b MOD 4294967296 ;
  35. lolo := al * bl ;
  36. mid := VAL (LONGCARD, VAL (CARDINAL, ah * bl + al * bh)) ;
  37. RETURN lolo + mid * 4294967296 ;
  38. END Mul64 ;
  39. PROCEDURE AllocateHeap (size: LONGCARD) : LONGCARD ;
  40. VAR sz: LONGCARD ;
  41. BEGIN
  42. sz := size ;
  43. IF (sz MOD 8) # 0 THEN
  44. sz := sz + 8 - (sz MOD 8) ;
  45. END ;
  46. hp := HeapPtr () - sz ;
  47. RETURN hp ;
  48. END AllocateHeap ;
  49. PROCEDURE Execute ;
  50. VAR sfun, hbit, lbit: CARDINAL ;
  51. dst, src, size, a, b, v, mark: LONGCARD ;
  52. nw, i, sp: LONGCARD ;
  53. BEGIN
  54. sfun := Fetch () ;
  55. CASE sfun OF
  56. | 0 : (* drop *)
  57. v := Pop () ;
  58. | 1, 2 : (* enter/leave monitor : no-op *)
  59. | 3 : (* long_negate *)
  60. v := Pop () ;
  61. Push (0 - v) ;
  62. | 4 : (* build_field_mask : (1<<hi) - (1<<lo) *)
  63. hbit := VAL (CARDINAL, Pop ()) ;
  64. lbit := VAL (CARDINAL, Pop ()) ;
  65. Push (Shl64 (1, hbit MOD 64) - Shl64 (1, lbit MOD 64)) ;
  66. | 5 : (* ALLOCATE *)
  67. size := Pop () ;
  68. dst := Pop () ;
  69. WriteSlot (dst, AllocateHeap (size)) ;
  70. | 6 : (* DEALLOCATE (no-op free) *)
  71. size := Pop () ;
  72. dst := Pop () ;
  73. WriteSlot (dst, 0) ;
  74. | 7 : (* MARK *)
  75. dst := Pop () ;
  76. WriteSlot (dst, HeapPtr ()) ;
  77. | 8 : (* RELEASE *)
  78. dst := Pop () ;
  79. mark := ReadSlot (dst) ;
  80. hp := mark ;
  81. WriteSlot (dst, 0) ;
  82. | 9 : (* FREEMEM *)
  83. Push (TopOfMemory () - HeapPtr ()) ;
  84. | 0AH, 0BH, 0CH : (* TRANSFER/IOTRANSFER/NEWPROCESS *)
  85. Fatal ("extended: processes unimplemented") ;
  86. | 0DH : (* BIOS (no-op) *)
  87. sfun := VAL (CARDINAL, Pop ()) ;
  88. v := Pop () ;
  89. | 0EH : (* MOVE *)
  90. size := Pop () ;
  91. dst := Pop () ;
  92. src := Pop () ;
  93. CopyBytes (src, dst, size) ;
  94. | 0FH : (* FILL *)
  95. v := Pop () ;
  96. size := Pop () ;
  97. src := Pop () ;
  98. FillBytes (src, size, VAL (CARDINAL, v)) ;
  99. | 10H : (* INP (no-op) *)
  100. Push (0) ;
  101. | 11H : (* OUT (no-op) *)
  102. sfun := VAL (CARDINAL, Pop ()) ;
  103. v := Pop () ;
  104. | 12H : (* reserve_string *)
  105. src := Pop () ;
  106. size := Pop () ;
  107. nw := (size + 7) DIV 8 ;
  108. dst := GetSP () - nw * 8 ;
  109. SetSP (dst) ;
  110. i := 0 ;
  111. WHILE i < nw DO
  112. WriteSlot (dst + i * 8, ReadSlot (src + i * 8)) ;
  113. i := i + 1 ;
  114. END ;
  115. Push (dst) ;
  116. | 13H : (* assert : pop 0 -> raise RangeError *)
  117. v := Pop () ;
  118. IF v = 0 THEN
  119. Fatal ("assertion failed") ;
  120. END ;
  121. | 14H : (* uc_less *)
  122. b := Pop () ; a := Pop () ;
  123. IF a < b THEN Push (1) ELSE Push (0) END ;
  124. | 15H : (* uc_less_eq *)
  125. b := Pop () ; a := Pop () ;
  126. IF a <= b THEN Push (1) ELSE Push (0) END ;
  127. | 16H : (* uc_greater *)
  128. b := Pop () ; a := Pop () ;
  129. IF a > b THEN Push (1) ELSE Push (0) END ;
  130. | 17H : (* uc_greater_eq *)
  131. b := Pop () ; a := Pop () ;
  132. IF a >= b THEN Push (1) ELSE Push (0) END ;
  133. | 18H : (* uc_add *)
  134. b := Pop () ; a := Pop () ;
  135. Push (a + b) ;
  136. | 19H : (* uc_sub *)
  137. b := Pop () ; a := Pop () ;
  138. Push (a - b) ;
  139. | 1AH : (* uc_mul *)
  140. b := Pop () ; a := Pop () ;
  141. Push (Mul64 (a, b)) ;
  142. | 1BH : (* uc_div *)
  143. b := Pop () ; a := Pop () ;
  144. IF b = 0 THEN Fatal ("divide by zero") END ;
  145. Push (a DIV b) ;
  146. | 1CH : (* uc_mod *)
  147. b := Pop () ; a := Pop () ;
  148. IF b = 0 THEN Fatal ("divide by zero") END ;
  149. Push (a MOD b) ;
  150. | 1DH : (* uc_to_real *)
  151. v := Pop () ;
  152. PushReal (FLOAT (VAL (LONGINT, v))) ;
  153. | 1EH : (* real_to_uc *)
  154. Push (VAL (LONGCARD, VAL (INTEGER, TRUNC (PopReal ())))) ;
  155. ELSE
  156. Fatal ("extended: illegal sub-opcode") ;
  157. END ; (* CASE *)
  158. END Execute ;
  159. END Extended.