home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MOS / FPUSUPPO.I < prev    next >
Encoding:
Text File  |  1994-02-15  |  9.1 KB  |  3 lines

  1. ⓪ IMPLEMENTATION MODULE FPUSupport;
  2. ⓪ (*$Y+,X+,F-*)
  3. ⓪ 
  4. ⓪ (*
  5. ⓪!* 27.11.90  Routinen laufen auch, wenn Aufrufer schon im Supervisormode ist.
  6. ⓪!* 29.07.91  keine Privilegsverletzung mehr, wenn im Usermode (hyperCACHE030);
  7. ⓪!*           Sprung in Supervisormode nun korrekt (ging bisher gar nicht?!).
  8. ⓪!*           FSAVE bei externalFPU rettet nun Frame in umgekehrter Reihenfolge,
  9. ⓪!*           so daß es nun endlich korrekt funktioniert.
  10. ⓪!* 15.02.94  Keine Low-Byte-Zugriffe mehr auf fpstat wg. Mega STE
  11. ⓪!*
  12. ⓪!* >> Konzept noch nicht perfekt: Wenn Coroutinen ggf.automatisch den
  13. ⓪!*   FPU-Context switchen sollen, würden noch Low-Level-versionen
  14. ⓪!*   von Save/RestoreContext benötigt. Ggf. "usedFPU", "MaxContextSize"
  15. ⓪!*   und diese Low-Level Routinen in ein Modul "FPUBase" packen.
  16. ⓪!*   Die Low-Level-Routinen f. Runtime können hier nicht rein, weil
  17. ⓪!*   hier Storage importiert wird und das zu zirkul. Importen führt.
  18. ⓪!*)
  19. ⓪ 
  20. ⓪ FROM SYSTEM IMPORT ASSEMBLER, BYTE;
  21. ⓪ 
  22. ⓪ FROM Storage IMPORT ALLOCATE, DEALLOCATE;
  23. ⓪ 
  24. ⓪ IMPORT MOSGlobals, SFP004;
  25. ⓪ 
  26. ⓪ FROM SysInfo IMPORT FPUType, FPU, FPUModel;
  27. ⓪ 
  28. ⓪ VAR usedFPU: FPUType;  (* zeigt die verwendete FPU an *)
  29. ⓪$model: CARDINAL;
  30. ⓪ 
  31. ⓪ CONST movemSize = 8*12 + 3*4;
  32. ⓪&contextSize = movemSize + 2 + 2 + 256 + 4;
  33. ⓪ 
  34. ⓪ (* Die Größe errechnet sich aus:
  35. ⓪!* 8 * FPn (je 12 Byte)
  36. ⓪!* je 4 für FPCR/SR/IAR
  37. ⓪!* 2 für evtl. nicht-Null-Flag
  38. ⓪!* 2 für Frame-Word von FSAVE
  39. ⓪!* interne Daten bei Busy State Frame (256 max. möglich)
  40. ⓪!* 4 zur Sicherheit *)
  41. ⓪ 
  42. ⓪ TYPE FPUContext = POINTER TO ARRAY [1..contextSize] OF BYTE;
  43. ⓪ 
  44. ⓪ 
  45. ⓪ PROCEDURE NewContext     (VAR context: FPUContext);
  46. ⓪"BEGIN
  47. ⓪$NEW (context);
  48. ⓪$IF context = NIL THEN
  49. ⓪&ASSEMBLER
  50. ⓪(TRAP    #6
  51. ⓪(DC.W    MOSGlobals.OutOfMemory
  52. ⓪&END;
  53. ⓪$ELSE
  54. ⓪&ASSEMBLER
  55. ⓪(; Illegales State Frame erzeugen
  56. ⓪(MOVE.L  context(A6),A1
  57. ⓪(MOVE.L  (A1),A0
  58. ⓪(MOVE.W  #$FFFF,movemSize(A0)
  59. ⓪&END;
  60. ⓪$END;
  61. ⓪"END NewContext;
  62. ⓪ 
  63. ⓪ PROCEDURE DisposeContext (VAR context: FPUContext);
  64. ⓪"BEGIN
  65. ⓪$DISPOSE (context)
  66. ⓪"END DisposeContext;
  67. ⓪ 
  68. ⓪ (*$L-*)
  69. ⓪ 
  70. ⓪ PROCEDURE FPUInit;
  71. ⓪"BEGIN
  72. ⓪$ASSEMBLER
  73. ⓪(CMPI    #externalFPU,usedFPU
  74. ⓪(BNE     intern
  75. ⓪(JMP     SFP004.FPUReset
  76. ⓪$intern:
  77. ⓪(CMPI    #internalFPU,usedFPU
  78. ⓪(BNE     none
  79. ⓪(FMOVE   #$0000F400,FPCR  ; s. 'Runtime'
  80. ⓪$none:
  81. ⓪$END
  82. ⓪"END FPUInit;
  83. ⓪ 
  84. ⓪ (* wird nicht exportiert, da FPUContext eh nur opaque ist und ein manuelles
  85. ⓪!* allozieren damit gar nicht möglich ist.
  86. ⓪ PROCEDURE MaxContextSize (): LONGCARD;
  87. ⓪!(*
  88. ⓪"* Liefert die maximal nötige Größe des Context-Puffers in Byte.
  89. ⓪"* Damit kann der Bereich notfalls auf eine andere Weise reserviert
  90. ⓪"* werden, statt 'NewContext' zu benutzen.
  91. ⓪"* Dann sollte der für 'FPUContext' angelegte Pu
  92. ⓪"*)
  93. ⓪ PROCEDURE MaxContextSize (): LONGCARD;
  94. ⓪"BEGIN
  95. ⓪$ASSEMBLER
  96. ⓪(MOVE.L  #contextSize,(A3)+
  97. ⓪$END
  98. ⓪"END MaxContextSize;
  99. ⓪ *)
  100. ⓪ 
  101. ⓪ PROCEDURE AcknowledgeException (context: FPUContext);
  102. ⓪"BEGIN
  103. ⓪$ASSEMBLER
  104. ⓪(; Setze Bit 27 im BIU
  105. ⓪(MOVE.L  -(A3),A1
  106. ⓪(CMPI    #internalFPU,usedFPU
  107. ⓪(BNE     noAckn
  108. ⓪(LEA     movemSize(A1),A1
  109. ⓪(TST.B   (A1)
  110. ⓪(BEQ     noAckn          ; kein Ackn bei Null-State
  111. ⓪(CLR     D0
  112. ⓪(MOVE.B  1(A1),D0
  113. ⓪(BSET    #3,(A1,D0.W)
  114. ⓪&noAckn
  115. ⓪$END
  116. ⓪"END AcknowledgeException;
  117. ⓪ 
  118. ⓪ 
  119. ⓪ CONST   A2stat  =  0;             (* Response word of MC68881 read *)
  120. ⓪(A2ctrl  =  2;             (* Control  word of MC68881 write *)
  121. ⓪(A2save  =  4;             (* Save     word of MC68881 read *)
  122. ⓪(A2restore= 6;             (* Restore  word of MC68881 r/w *)
  123. ⓪(A2cmd   =  10;            (* Command  word of MC68881 write *)
  124. ⓪(A2cond  =  14;            (* Condition word of MC68881 write *)
  125. ⓪(A2op    =  16;            (* Operand  long of MC68881 read/write *)
  126. ⓪(A2regsel=  $14;           (* register select long read *)
  127. ⓪ 
  128. ⓪ PROCEDURE SaveContext    (context: FPUContext);
  129. ⓪"BEGIN
  130. ⓪$ASSEMBLER
  131. ⓪(MOVEQ   #1,D0
  132. ⓪(MOVE.L  D0,-(A7)
  133. ⓪(MOVE    #$20,-(A7)
  134. ⓪(TRAP    #1              ;Super(1)
  135. ⓪(MOVEQ   #-1,D2
  136. ⓪(TST     D0              ; sind wir schon im Supervisormode ?
  137. ⓪(BNE     supv
  138. ⓪(
  139. ⓪(MOVE.W  D0,4(A7)
  140. ⓪(TRAP    #1              ;Super(0)
  141. ⓪(MOVE.L  D0,A7           ; SSP wiederherstellen
  142. ⓪(MOVE    #$CFFF,D2
  143. ⓪&supv
  144. ⓪(MOVE    SR,D1
  145. ⓪(AND     D2,D1
  146. ⓪(MOVE.W  D1,-(A7)
  147. ⓪(
  148. ⓪(MOVE.L  -(A3),A1
  149. ⓪(MOVE.L  A1,A0
  150. ⓪(ADDA.W  #movemSize,A1
  151. ⓪(
  152. ⓪(CMPI    #externalFPU,usedFPU
  153. ⓪(BNE.W   intern
  154. ⓪(
  155. ⓪(MOVE.L  A3,D1
  156. ⓪(MOVEA.W #$FA40,A2
  157. ⓪(MOVEA.W #$FA50,A3       ; fpop
  158. ⓪(
  159. ⓪ wait    MOVE.W  A2save(A2),D0
  160. ⓪(CMPI.W  #$300,D0
  161. ⓪(BCC     start           ; > $300
  162. ⓪(CMPI.W  #$100,D0
  163. ⓪(BCS     nullstate       ; < $100
  164. ⓪(CMPI.W  #$200,D0
  165. ⓪(BCS     wait
  166. ⓪(; Format Error
  167. ⓪(CLR.W   (A1)            ; IDLE-format word sichern
  168. ⓪(MOVE.L  D1,A3
  169. ⓪(MOVE.W  (A7)+,SR
  170. ⓪(ADDQ.L  #6,A7
  171. ⓪(LINK    A5,#0
  172. ⓪(JSR     SFP004.FPUError
  173. ⓪(UNLK    A5
  174. ⓪(RTS
  175. ⓪ nullstate:
  176. ⓪(MOVE.W  D0,(A1)         ; null-format word sichern
  177. ⓪(BRA.W   endextern
  178. ⓪ 
  179. ⓪ start   MOVE.W  D0,(A1)+        ; format word sichern
  180. ⓪(; Anzahl der Bytes im Lower Byte -> Anz. der Longs berechnen
  181. ⓪(ANDI    #$FF,D0
  182. ⓪(ADDA.W  D0,A1
  183. ⓪(LSR     #2,D0
  184. ⓪(SUBQ    #1,D0
  185. ⓪(; während der Datenübertragung des FSAVE keine Interrupts zulassen
  186. ⓪(MOVE    SR,D2
  187. ⓪(MOVE    #$2700,SR
  188. ⓪ loop    MOVE.L  (A3),-(A1)
  189. ⓪(TST.W   (A2)            ; fpstat wg. Synchr. lesen
  190. ⓪(DBRA    D0,loop
  191. ⓪(MOVE    D2,SR
  192. ⓪(
  193. ⓪(; FMOVEM FP0-FP7,(A0)+
  194. ⓪(TST.W   (A2)
  195. ⓪(MOVE.W  #1111000011111111%,A2cmd(A2)
  196. ⓪(TST.W   (A2)
  197. ⓪(TST.W   (A2)
  198. ⓪(TST.W   A2regsel(A2)
  199. ⓪(TST.W   (A2)
  200. ⓪(MOVEQ   #7,D0
  201. ⓪ again   MOVE.L  (A3),(A0)+
  202. ⓪(TST.W   (A2)            ; fpstat wg. Synchr. lesen
  203. ⓪(MOVE.L  (A3),(A0)+
  204. ⓪(TST.W   (A2)            ; fpstat wg. Synchr. lesen
  205. ⓪(MOVE.L  (A3),(A0)+
  206. ⓪(TST.W   (A2)            ; fpstat wg. Synchr. lesen
  207. ⓪(DBRA    D0,again
  208. ⓪(
  209. ⓪(; FMOVEM FPCR/FPSR/FPIAR,(A0)+
  210. ⓪(MOVE.W  #1011110000000000%,A2cmd(A2)    ;$BC00
  211. ⓪(TST.W   (A2)
  212. ⓪(;TST.W   (A2)
  213. ⓪(;TST.W   A2regsel(A2)
  214. ⓪(;TST.W   (A2)
  215. ⓪(MOVE.L  (A3),(A0)+
  216. ⓪(TST.W   (A2)            ; fpstat wg. Synchr. lesen
  217. ⓪(MOVE.L  (A3),(A0)+
  218. ⓪(TST.W   (A2)            ; fpstat wg. Synchr. lesen
  219. ⓪(MOVE.L  (A3),(A0)+
  220. ⓪(TST.W   (A2)            ; fpstat wg. Synchr. lesen
  221. ⓪$endextern:
  222. ⓪(MOVE.L  D1,A3
  223. ⓪(BRA     none
  224. ⓪ 
  225. ⓪$intern:
  226. ⓪(CMPI    #internalFPU,usedFPU
  227. ⓪(BNE     none
  228. ⓪(FSAVE   (A1)
  229. ⓪(TST.B   (A1)
  230. ⓪(BEQ     none
  231. ⓪(FMOVEM  FP0-FP7,-(A1)
  232. ⓪(FMOVEM  FPCR/FPSR/FPIAR,-(A1)
  233. ⓪$none:
  234. ⓪(MOVE.W  (A7)+,SR
  235. ⓪(ADDQ.L  #6,A7
  236. ⓪$END
  237. ⓪"END SaveContext;
  238. ⓪ 
  239. ⓪ PROCEDURE RestoreContext (context: FPUContext);
  240. ⓪"BEGIN
  241. ⓪$ASSEMBLER
  242. ⓪(MOVEQ   #1,D0
  243. ⓪(MOVE.L  D0,-(A7)
  244. ⓪(MOVE    #$20,-(A7)
  245. ⓪(TRAP    #1              ;Super(1)
  246. ⓪(MOVEQ   #-1,D2
  247. ⓪(TST     D0              ; sind wir schon im Supervisormode ?
  248. ⓪(BNE     supv
  249. ⓪(
  250. ⓪(MOVE.W  D0,4(A7)
  251. ⓪(TRAP    #1              ;Super(0)
  252. ⓪(MOVE.L  D0,A7           ; SSP wiederherstellen
  253. ⓪(MOVE    #$CFFF,D2
  254. ⓪&supv
  255. ⓪(MOVE    SR,D1
  256. ⓪(AND     D2,D1
  257. ⓪(MOVE.W  D1,-(A7)
  258. ⓪(
  259. ⓪(MOVE.L  -(A3),A1
  260. ⓪(MOVE.L  A1,A0
  261. ⓪(ADDA.W  #movemSize,A1
  262. ⓪(
  263. ⓪(CMPI    #externalFPU,usedFPU
  264. ⓪(BNE.W   intern
  265. ⓪(
  266. ⓪(TST.B   (A1)
  267. ⓪(BEQ.W   nullstate
  268. ⓪(
  269. ⓪(MOVE.L  A3,D1
  270. ⓪(MOVEA.W #$FA40,A2
  271. ⓪(MOVEA.W #$FA50,A3
  272. ⓪(
  273. ⓪(; first reset FPU to be able to transfer the regs
  274. ⓪(MOVE.W  #3,A2ctrl(A2)   ; write abort-cmd
  275. ⓪(
  276. ⓪(; FMOVEM (A0)+,FP0-FP7
  277. ⓪(MOVE.W  #1101000011111111%,A2cmd(A2)
  278. ⓪(TST.W   (A2)
  279. ⓪(TST.W   (A2)
  280. ⓪(TST.W   A2regsel(A2)
  281. ⓪(TST.W   (A2)
  282. ⓪(MOVEQ   #7,D0
  283. ⓪ again   MOVE.L  (A0)+,(A3)
  284. ⓪(TST.W   (A2)
  285. ⓪(MOVE.L  (A0)+,(A3)
  286. ⓪(TST.W   (A2)
  287. ⓪(MOVE.L  (A0)+,(A3)
  288. ⓪(TST.W   (A2)
  289. ⓪(DBRA    D0,again
  290. ⓪(
  291. ⓪(; FMOVEM (A0)+,FPCR/FPSR/FPIAR
  292. ⓪(MOVE.W  #1001110000000000%,A2cmd(A2)
  293. ⓪(TST.W   (A2)
  294. ⓪(;TST.W   (A2)
  295. ⓪(;TST.W   A2regsel(A2)
  296. ⓪(;TST.W   (A2)
  297. ⓪(MOVE.L  (A0)+,(A3)
  298. ⓪(TST.W   (A2)
  299. ⓪(MOVE.L  (A0)+,(A3)
  300. ⓪(TST.W   (A2)
  301. ⓪(MOVE.L  (A0)+,(A3)
  302. ⓪(TST.W   (A2)
  303. ⓪ 
  304. ⓪(; FRESTORE (A1)
  305. ⓪(MOVE.W  (A1)+,D0
  306. ⓪(MOVE.W  D0,A2restore(A2)
  307. ⓪(CMP.W   A2restore(A2),D0
  308. ⓪(BEQ     start
  309. ⓪(
  310. ⓪(MOVE.L  D1,A3
  311. ⓪(
  312. ⓪(; Format Error
  313. ⓪ error   MOVE.W  (A7)+,SR
  314. ⓪(ADDQ.L  #6,A7
  315. ⓪(LINK    A5,#0
  316. ⓪(JSR     SFP004.FPUError
  317. ⓪(UNLK    A5
  318. ⓪(RTS
  319. ⓪ 
  320. ⓪ nullstate:
  321. ⓪(MOVEA.W #$FA46,A2       ; fprestore
  322. ⓪(MOVE.W  (A1),D0
  323. ⓪(MOVE.W  D0,(A2)         ; FRESTORE
  324. ⓪(CMP.W   (A2),D0
  325. ⓪(BEQ     none
  326. ⓪(BRA     error
  327. ⓪(
  328. ⓪ start   ; Anzahl der Bytes im Lower Byte -> Anz. der Longs berechnen
  329. ⓪(ANDI    #$FF,D0
  330. ⓪(LSR     #2,D0
  331. ⓪(SUBQ    #1,D0
  332. ⓪(; während der Datenübertragung keine Interrupts zulassen
  333. ⓪(MOVE    SR,D2
  334. ⓪(MOVE    #$2700,SR
  335. ⓪ loop    MOVE.L  (A1)+,(A3)
  336. ⓪(TST.W   (A2)
  337. ⓪(DBRA    D0,loop
  338. ⓪(MOVE    D2,SR
  339. ⓪(MOVE.L  D1,A3
  340. ⓪(BRA     none
  341. ⓪(
  342. ⓪$intern:
  343. ⓪(CMPI    #internalFPU,usedFPU
  344. ⓪(BNE     none
  345. ⓪(TST.B   (A1)
  346. ⓪(BEQ     null_rst
  347. ⓪(FMOVEM  (A0)+,FPCR/FPSR/FPIAR
  348. ⓪(FMOVEM  (A0)+,FP0-FP7
  349. ⓪$null_rst:
  350. ⓪(FRESTORE (A1)
  351. ⓪$none:
  352. ⓪(MOVE.W  (A7)+,SR
  353. ⓪(ADDQ.L  #6,A7
  354. ⓪$END
  355. ⓪"END RestoreContext;
  356. ⓪ 
  357. ⓪ BEGIN
  358. ⓪"usedFPU:= FPU ();
  359. ⓪$(* egal, ob die vorhandene FPU auch wirklich benutzt wird: wenn hier
  360. ⓪%* eine der Funktionen aufgerufen wird, ists auf jeden Fall nicht die
  361. ⓪%* falsche. *)
  362. ⓪"model:= FPUModel ();
  363. ⓪ END FPUSupport.
  364. ⓪ ə
  365. (* $FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$000001F9$FFEE3A76$00002226$FFEE3A76$00000893$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76Ç$000001F3T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$00001588$00001625$00001715$00001ACA$00001BC4$00001C48$00001CB5$00001D59$00001FFB$0000165D$00001CED$0000003E$000001F9$000001C0$000001F6$000001D4ÇÇé*)
  366.