2
0

i8086.inc 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2013 by the Free Pascal development team.
  4. Processor dependent implementation for the system unit for
  5. intel i8086+
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. procedure fpc_cpuinit;
  13. begin
  14. end;
  15. {$ifndef FPC_SYSTEM_HAS_FILLCHAR}
  16. {$define FPC_SYSTEM_HAS_FILLCHAR}
  17. procedure FillChar(var x;count:SizeUInt;value:byte);assembler;nostackframe;
  18. asm
  19. mov bx, sp
  20. mov cx, ss:[bx + 4 + extra_param_offset] // count
  21. jcxz @@Done
  22. {$ifdef FPC_X86_DATA_NEAR}
  23. mov di, ss:[bx + 6 + extra_param_offset] // @x
  24. mov ax, ds
  25. mov es, ax
  26. {$else FPC_X86_DATA_NEAR}
  27. les di, ss:[bx + 6 + extra_param_offset] // @x
  28. {$endif FPC_X86_DATA_NEAR}
  29. mov al, ss:[bx + 2 + extra_param_offset] // value
  30. mov ah, al
  31. shr cx, 1
  32. {$ifdef FPC_ENABLED_CLD}
  33. cld
  34. {$endif FPC_ENABLED_CLD}
  35. rep stosw
  36. adc cx, cx
  37. rep stosb
  38. @@Done:
  39. end;
  40. {$endif FPC_SYSTEM_HAS_FILLCHAR}
  41. {$ifndef FPC_SYSTEM_HAS_FILLWORD}
  42. {$define FPC_SYSTEM_HAS_FILLWORD}
  43. procedure FillWord(var x;count : SizeInt;value : word);assembler;nostackframe;
  44. asm
  45. mov bx, sp
  46. mov cx, ss:[bx + 4 + extra_param_offset] // count
  47. or cx, cx
  48. jle @@Done
  49. {$ifdef FPC_X86_DATA_NEAR}
  50. mov di, ss:[bx + 6 + extra_param_offset] // @x
  51. mov ax, ds
  52. mov es, ax
  53. {$else FPC_X86_DATA_NEAR}
  54. les di, ss:[bx + 6 + extra_param_offset] // @x
  55. {$endif FPC_X86_DATA_NEAR}
  56. mov ax, ss:[bx + 2 + extra_param_offset] // value
  57. {$ifdef FPC_ENABLED_CLD}
  58. cld
  59. {$endif FPC_ENABLED_CLD}
  60. rep stosw
  61. @@Done:
  62. end;
  63. {$endif FPC_SYSTEM_HAS_FILLWORD}
  64. {$ifndef FPC_SYSTEM_HAS_FILLDWORD}
  65. {$define FPC_SYSTEM_HAS_FILLDWORD}
  66. procedure FillDWord(var x;count : SizeInt;value : dword);assembler;nostackframe;
  67. asm
  68. mov bx, sp
  69. mov cx, ss:[bx + 6 + extra_param_offset] // count
  70. or cx, cx
  71. jle @@Done
  72. {$ifdef FPC_X86_DATA_NEAR}
  73. mov di, ss:[bx + 8 + extra_param_offset] // @x
  74. mov ax, ds
  75. mov es, ax
  76. {$else FPC_X86_DATA_NEAR}
  77. les di, ss:[bx + 8 + extra_param_offset] // @x
  78. {$endif FPC_X86_DATA_NEAR}
  79. mov ax, ss:[bx + 2 + extra_param_offset] // lo(value)
  80. mov bx, ss:[bx + 4 + extra_param_offset] // hi(value)
  81. {$ifdef FPC_ENABLED_CLD}
  82. cld
  83. {$endif FPC_ENABLED_CLD}
  84. cmp ax, bx
  85. jne @@lo_hi_different
  86. shl cx, 1
  87. rep stosw
  88. jmp @@Done
  89. @@lo_hi_different:
  90. stosw
  91. xchg ax, bx
  92. stosw
  93. xchg ax, bx
  94. loop @@lo_hi_different
  95. @@Done:
  96. end;
  97. {$endif FPC_SYSTEM_HAS_FILLDWORD}
  98. procedure MoveData(srcseg,srcoff,destseg,destoff:Word;n:Word);assembler;nostackframe;
  99. asm
  100. mov bx, sp
  101. mov cx, ss:[bx + 2 + extra_param_offset] // count
  102. jcxz @@Done
  103. mov ax, ds // backup ds
  104. lds si, ss:[bx + 8 + extra_param_offset] // @source
  105. les di, ss:[bx + 4 + extra_param_offset] // @dest
  106. cmp si, di
  107. jb @@BackwardsMove
  108. {$ifdef FPC_ENABLED_CLD}
  109. cld
  110. {$endif FPC_ENABLED_CLD}
  111. shr cx, 1
  112. rep movsw
  113. adc cx, cx
  114. rep movsb
  115. jmp @@AfterMove // todo, add mov ds,ax & ret here for performance reasons
  116. @@BackwardsMove:
  117. std
  118. add si, cx
  119. add di, cx
  120. dec si
  121. dec di
  122. rep movsb // todo: movsw
  123. cld
  124. @@AfterMove:
  125. mov ds, ax
  126. @@Done:
  127. end;
  128. {$ifndef FPC_SYSTEM_HAS_MOVE}
  129. {$define FPC_SYSTEM_HAS_MOVE}
  130. procedure Move(const source;var dest;count:SizeUInt);[public, alias: 'FPC_MOVE'];assembler;nostackframe;
  131. asm
  132. mov bx, sp
  133. mov cx, ss:[bx + 2 + extra_param_offset] // count
  134. jcxz @@Done
  135. mov ax, ds // for far data models, backup ds; for near data models, use to initialize es
  136. {$ifdef FPC_X86_DATA_NEAR}
  137. mov es, ax
  138. mov si, ss:[bx + 6 + extra_param_offset] // @source
  139. mov di, ss:[bx + 4 + extra_param_offset] // @dest
  140. {$else FPC_X86_DATA_NEAR}
  141. lds si, ss:[bx + 8 + extra_param_offset] // @source
  142. les di, ss:[bx + 4 + extra_param_offset] // @dest
  143. {$endif FPC_X86_DATA_NEAR}
  144. cmp si, di
  145. jb @@BackwardsMove
  146. {$ifdef FPC_ENABLED_CLD}
  147. cld
  148. {$endif FPC_ENABLED_CLD}
  149. shr cx, 1
  150. rep movsw
  151. adc cx, cx
  152. rep movsb
  153. jmp @@AfterMove // todo, add mov ds,ax & ret here for performance reasons
  154. @@BackwardsMove:
  155. std
  156. add si, cx
  157. add di, cx
  158. dec si
  159. dec di
  160. rep movsb // todo: movsw
  161. cld
  162. @@AfterMove:
  163. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  164. mov ds, ax
  165. {$endif}
  166. @@Done:
  167. end;
  168. {$endif FPC_SYSTEM_HAS_MOVE}
  169. {$ifndef FPC_SYSTEM_HAS_INDEXBYTE}
  170. {$define FPC_SYSTEM_HAS_INDEXBYTE}
  171. function IndexByte(Const buf;len:SizeInt;b:byte):SizeInt; assembler; nostackframe;
  172. asm
  173. mov bx, sp
  174. mov cx, ss:[bx + 4 + extra_param_offset] // len
  175. jcxz @@NotFound
  176. {$ifdef FPC_X86_DATA_NEAR}
  177. mov di, ss:[bx + 6 + extra_param_offset] // @buf
  178. mov ax, ds
  179. mov es, ax
  180. {$else FPC_X86_DATA_NEAR}
  181. les di, ss:[bx + 6 + extra_param_offset] // @buf
  182. {$endif FPC_X86_DATA_NEAR}
  183. mov si, di // save the start of the buffer in si
  184. mov al, ss:[bx + 2 + extra_param_offset] // b
  185. {$ifdef FPC_ENABLED_CLD}
  186. cld
  187. {$endif FPC_ENABLED_CLD}
  188. repne scasb
  189. je @@Found
  190. @@NotFound:
  191. mov ax, 0FFFFh // return -1
  192. jmp @@Done
  193. @@Found:
  194. sub di, si
  195. xchg ax, di
  196. dec ax
  197. @@Done:
  198. end;
  199. {$endif FPC_SYSTEM_HAS_INDEXBYTE}
  200. {$ifndef FPC_SYSTEM_HAS_INDEXWORD}
  201. {$define FPC_SYSTEM_HAS_INDEXWORD}
  202. function IndexWord(Const buf;len:SizeInt;b:word):SizeInt; assembler; nostackframe;
  203. asm
  204. mov bx, sp
  205. mov cx, ss:[bx + 4 + extra_param_offset] // len
  206. jcxz @@NotFound
  207. {$ifdef FPC_X86_DATA_NEAR}
  208. mov di, ss:[bx + 6 + extra_param_offset] // @buf
  209. mov ax, ds
  210. mov es, ax
  211. {$else FPC_X86_DATA_NEAR}
  212. les di, ss:[bx + 6 + extra_param_offset] // @buf
  213. {$endif FPC_X86_DATA_NEAR}
  214. mov si, cx // save the length of the buffer in si
  215. mov ax, ss:[bx + 2 + extra_param_offset] // b
  216. {$ifdef FPC_ENABLED_CLD}
  217. cld
  218. {$endif FPC_ENABLED_CLD}
  219. repne scasw
  220. je @@Found
  221. @@NotFound:
  222. mov ax, 0FFFFh // return -1
  223. jmp @@Done
  224. @@Found:
  225. sub si, cx
  226. xchg ax, si
  227. dec ax
  228. @@Done:
  229. end;
  230. {$endif FPC_SYSTEM_HAS_INDEXWORD}
  231. {$ifndef FPC_SYSTEM_HAS_INDEXDWORD}
  232. {$define FPC_SYSTEM_HAS_INDEXDWORD}
  233. function IndexDWord(Const buf;len:SizeInt;b:DWord):SizeInt; assembler; nostackframe;
  234. asm
  235. mov bx, sp
  236. mov cx, ss:[bx + 6 + extra_param_offset] // len
  237. jcxz @@NotFound
  238. {$ifdef FPC_X86_DATA_NEAR}
  239. mov di, ss:[bx + 8 + extra_param_offset] // @buf
  240. mov ax, ds
  241. mov es, ax
  242. {$else FPC_X86_DATA_NEAR}
  243. les di, ss:[bx + 8 + extra_param_offset] // @buf
  244. {$endif FPC_X86_DATA_NEAR}
  245. mov si, cx // save the length of the buffer in si
  246. mov ax, ss:[bx + 2 + extra_param_offset] // b
  247. mov bx, ss:[bx + 4 + extra_param_offset]
  248. {$ifdef FPC_ENABLED_CLD}
  249. cld
  250. {$endif FPC_ENABLED_CLD}
  251. jmp @@LoopStart
  252. @@SkipWord:
  253. scasw
  254. @@LoopStart:
  255. scasw
  256. loopne @@SkipWord
  257. jne @@NotFound
  258. xchg ax, bx
  259. scasw
  260. je @@Found
  261. jcxz @@NotFound
  262. xchg ax, bx
  263. jmp @@LoopStart
  264. @@Found:
  265. sub si, cx
  266. xchg ax, si
  267. dec ax
  268. jmp @@Done
  269. @@NotFound:
  270. mov ax, 0FFFFh // return -1
  271. @@Done:
  272. end;
  273. {$endif FPC_SYSTEM_HAS_INDEXDWORD}
  274. {$ifndef FPC_SYSTEM_HAS_COMPAREBYTE}
  275. {$define FPC_SYSTEM_HAS_COMPAREBYTE}
  276. function CompareByte(Const buf1,buf2;len:SizeInt):SizeInt; assembler; nostackframe;
  277. asm
  278. xor ax, ax // initialize ax=0 (it's the result register, we never use it for anything else in this function)
  279. mov bx, sp
  280. mov cx, ss:[bx + 2 + extra_param_offset] // len
  281. jcxz @@Done
  282. mov dx, ds // for far data models, backup ds; for near data models, use to initialize es
  283. {$ifdef FPC_X86_DATA_NEAR}
  284. mov es, dx
  285. mov si, ss:[bx + 6 + extra_param_offset] // @buf1
  286. mov di, ss:[bx + 4 + extra_param_offset] // @buf2
  287. {$else FPC_X86_DATA_NEAR}
  288. lds si, ss:[bx + 8 + extra_param_offset] // @buf1
  289. les di, ss:[bx + 4 + extra_param_offset] // @buf2
  290. {$endif FPC_X86_DATA_NEAR}
  291. {$ifdef FPC_ENABLED_CLD}
  292. cld
  293. {$endif FPC_ENABLED_CLD}
  294. xor bx, bx
  295. shr cx, 1
  296. adc bx, bx // remainder goes to bx
  297. jcxz @@BytewiseComparison
  298. repe cmpsw
  299. je @@BytewiseComparison
  300. // we found an unequal word
  301. // let's go back and compare it bytewise
  302. mov bl, 2
  303. dec si
  304. dec si
  305. dec di
  306. dec di
  307. @@BytewiseComparison:
  308. mov cx, bx
  309. jcxz @@Equal
  310. repe cmpsb
  311. je @@Equal
  312. // ax is 0
  313. sbb ax, ax
  314. shl ax, 1
  315. inc ax
  316. @@Equal:
  317. // ax is 0
  318. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  319. mov ds, dx
  320. {$endif}
  321. @@Done:
  322. end;
  323. {$endif FPC_SYSTEM_HAS_COMPAREBYTE}
  324. {$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
  325. {$define FPC_SYSTEM_HAS_COMPAREWORD}
  326. function CompareWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler; nostackframe;
  327. asm
  328. xor ax, ax // initialize ax=0 (it's the result register, we never use it for anything else in this function)
  329. mov bx, sp
  330. mov cx, ss:[bx + 2 + extra_param_offset] // len
  331. jcxz @@Done
  332. mov dx, ds // for far data models, backup ds; for near data models, use to initialize es
  333. {$ifdef FPC_X86_DATA_NEAR}
  334. mov es, dx
  335. mov si, ss:[bx + 6 + extra_param_offset] // @buf1
  336. mov di, ss:[bx + 4 + extra_param_offset] // @buf2
  337. {$else FPC_X86_DATA_NEAR}
  338. lds si, ss:[bx + 8 + extra_param_offset] // @buf1
  339. les di, ss:[bx + 4 + extra_param_offset] // @buf2
  340. {$endif FPC_X86_DATA_NEAR}
  341. {$ifdef FPC_ENABLED_CLD}
  342. cld
  343. {$endif FPC_ENABLED_CLD}
  344. repe cmpsw
  345. je @@Equal
  346. // ax is 0
  347. sbb ax, ax
  348. shl ax, 1
  349. inc ax
  350. @@Equal:
  351. // ax is 0
  352. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  353. mov ds, dx
  354. {$endif}
  355. @@Done:
  356. end;
  357. {$endif FPC_SYSTEM_HAS_COMPAREWORD}
  358. {$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
  359. {$define FPC_SYSTEM_HAS_COMPAREDWORD}
  360. function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt; assembler; nostackframe;
  361. asm
  362. xor ax, ax // initialize ax=0 (it's the result register, we never use it for anything else in this function)
  363. mov bx, sp
  364. mov cx, ss:[bx + 2 + extra_param_offset] // len
  365. jcxz @@Done
  366. cmp cx, 4000h
  367. jb @@NotTooBig
  368. mov cx, 4000h
  369. @@NotTooBig:
  370. shl cx, 1
  371. mov dx, ds // for far data models, backup ds; for near data models, use to initialize es
  372. {$ifdef FPC_X86_DATA_NEAR}
  373. mov es, dx
  374. mov si, ss:[bx + 6 + extra_param_offset] // @buf1
  375. mov di, ss:[bx + 4 + extra_param_offset] // @buf2
  376. {$else FPC_X86_DATA_NEAR}
  377. lds si, ss:[bx + 8 + extra_param_offset] // @buf1
  378. les di, ss:[bx + 4 + extra_param_offset] // @buf2
  379. {$endif FPC_X86_DATA_NEAR}
  380. {$ifdef FPC_ENABLED_CLD}
  381. cld
  382. {$endif FPC_ENABLED_CLD}
  383. repe cmpsw
  384. je @@Equal
  385. // ax is 0
  386. sbb ax, ax
  387. shl ax, 1
  388. inc ax
  389. shr cx, 1
  390. jnc @@Skip
  391. xchg ax, bx
  392. xor ax, ax
  393. cmpsw
  394. je @@hi_equal
  395. // ax is 0
  396. sbb ax, ax
  397. shl ax, 1
  398. inc ax
  399. jmp @@Skip
  400. @@hi_equal:
  401. xchg ax, bx
  402. @@Equal:
  403. // ax is 0
  404. @@Skip:
  405. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  406. mov ds, dx
  407. {$endif}
  408. @@Done:
  409. end;
  410. {$endif FPC_SYSTEM_HAS_COMPAREDWORD}
  411. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  412. {$define FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  413. function fpc_pchar_length(p:pchar):sizeint;assembler;nostackframe;[public,alias:'FPC_PCHAR_LENGTH']; compilerproc;
  414. asm
  415. mov bx, sp
  416. {$ifdef FPC_X86_DATA_NEAR}
  417. mov ax, ss:[bx + 2 + extra_param_offset] // p
  418. test ax, ax
  419. jz @@Done
  420. xchg ax, di
  421. mov ax, ds
  422. mov es, ax
  423. {$else FPC_X86_DATA_NEAR}
  424. les di, ss:[bx + 2 + extra_param_offset] // p
  425. mov ax, es
  426. or ax, di
  427. jz @@Done
  428. {$endif FPC_X86_DATA_NEAR}
  429. mov cx, 0FFFFh
  430. xor ax, ax
  431. {$ifdef FPC_ENABLED_CLD}
  432. cld
  433. {$endif FPC_ENABLED_CLD}
  434. repne scasb
  435. dec ax
  436. dec ax
  437. sub ax, cx
  438. @@Done:
  439. end;
  440. {$endif FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  441. {$define FPC_SYSTEM_HAS_SPTR}
  442. Function Sptr : Pointer;assembler;nostackframe;
  443. asm
  444. mov ax, sp
  445. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  446. mov dx, ss
  447. {$endif}
  448. end;
  449. {$define FPC_SYSTEM_HAS_PTR}
  450. function Ptr(sel,off: Word):farpointer;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  451. asm
  452. mov si, sp
  453. mov ax, ss:[si + 2 + extra_param_offset] // off
  454. mov dx, ss:[si + 4 + extra_param_offset] // sel
  455. end;
  456. {$define FPC_SYSTEM_HAS_CSEG}
  457. function CSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  458. begin
  459. CSeg:=fpc_x86_get_cs;
  460. end;
  461. {$define FPC_SYSTEM_HAS_DSEG}
  462. function DSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  463. begin
  464. DSeg:=fpc_x86_get_ds;
  465. end;
  466. {$define FPC_SYSTEM_HAS_SSEG}
  467. function SSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}
  468. begin
  469. SSeg:=fpc_x86_get_ss;
  470. end;
  471. {$IFNDEF INTERNAL_BACKTRACE}
  472. {$define FPC_SYSTEM_HAS_GET_FRAME}
  473. function get_frame:pointer;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  474. asm
  475. mov ax, bp
  476. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  477. mov dx, ss
  478. {$endif}
  479. end;
  480. {$ENDIF not INTERNAL_BACKTRACE}
  481. {$define FPC_SYSTEM_HAS_GET_PC_ADDR}
  482. Function Get_pc_addr : CodePointer;assembler;nostackframe;
  483. asm
  484. mov bx, sp
  485. mov ax, ss:[bx]
  486. {$ifdef FPC_X86_CODE_FAR}
  487. mov dx, ss:[bx+2]
  488. {$endif FPC_X86_CODE_FAR}
  489. end;
  490. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  491. function get_caller_addr(framebp:pointer;addr:codepointer=nil):codepointer;nostackframe;assembler;
  492. asm
  493. mov si, sp
  494. {$ifdef FPC_X86_CODE_FAR}
  495. xor dx, dx
  496. {$endif FPC_X86_CODE_FAR}
  497. {$ifdef FPC_X86_DATA_NEAR}
  498. mov ax, ss:[si + 4 + extra_param_offset + extra_param_offset] // framebp
  499. {$ifdef WIN16}
  500. mov cx, ax
  501. and al, $FE
  502. {$endif WIN16}
  503. or ax, ax
  504. jz @@Lg_a_null
  505. xchg ax, bx // 1 byte shorter than a mov
  506. mov ax, [bx+2]
  507. {$ifdef FPC_X86_CODE_FAR}
  508. {$ifdef WIN16}
  509. test cl, 1
  510. jnz @@farretaddr
  511. mov dx, ss:[si + 2 + extra_param_offset + extra_param_offset] // Seg(addr^)
  512. jmp @@retsegdone
  513. @@farretaddr:
  514. mov dx, [bx+4]
  515. @@retsegdone:
  516. {$else WIN16}
  517. mov dx, [bx+4]
  518. {$endif WIN16}
  519. {$endif FPC_X86_CODE_FAR}
  520. {$else FPC_X86_DATA_NEAR}
  521. les ax, ss:[si + 4 + extra_param_offset + extra_param_offset] // framebp
  522. {$ifdef WIN16}
  523. mov cx, ax
  524. and al, $FE
  525. {$endif WIN16}
  526. mov dx, es
  527. or dx, ax
  528. jz @@Lg_a_null
  529. xchg ax, bx // 1 byte shorter than a mov
  530. mov ax, es:[bx+2]
  531. {$ifdef FPC_X86_CODE_FAR}
  532. {$ifdef WIN16}
  533. test cl, 1
  534. jnz @@farretaddr
  535. mov dx, ss:[si + 2 + extra_param_offset + extra_param_offset] // Seg(addr^)
  536. jmp @@retsegdone
  537. @@farretaddr:
  538. mov dx, es:[bx+4]
  539. @@retsegdone:
  540. {$else WIN16}
  541. mov dx, es:[bx+4]
  542. {$endif WIN16}
  543. {$endif FPC_X86_CODE_FAR}
  544. {$endif FPC_X86_DATA_NEAR}
  545. @@Lg_a_null:
  546. end;
  547. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  548. function get_caller_frame(framebp:pointer;addr:codepointer=nil):pointer;nostackframe;assembler;
  549. asm
  550. {$ifdef FPC_X86_DATA_NEAR}
  551. mov si, sp
  552. mov ax, ss:[si + 4 + extra_param_offset + extra_param_offset] // framebp
  553. {$ifdef WIN16}
  554. and al, $FE
  555. {$endif WIN16}
  556. or ax, ax
  557. jz @@Lgnf_null
  558. xchg ax, si // 1 byte shorter than a mov
  559. lodsw
  560. @@Lgnf_null:
  561. {$else FPC_X86_DATA_NEAR}
  562. mov si, sp
  563. les ax, ss:[si + 4 + extra_param_offset + extra_param_offset] // framebp
  564. {$ifdef WIN16}
  565. and al, $FE
  566. {$endif WIN16}
  567. mov dx, es
  568. or dx, ax
  569. jz @@Lgnf_null
  570. xchg ax, si // 1 byte shorter than a mov
  571. seges lodsw
  572. {$ifdef WIN16}
  573. and al, $FE
  574. {$endif WIN16}
  575. mov dx, es
  576. @@Lgnf_null:
  577. {$endif FPC_X86_DATA_NEAR}
  578. end;
  579. function InterLockedDecrement (var Target: smallint) : smallint;nostackframe;assembler;
  580. asm
  581. mov si, sp
  582. {$ifdef FPC_X86_DATA_NEAR}
  583. mov bx, ss:[si + 2 + extra_param_offset] // Target
  584. {$else FPC_X86_DATA_NEAR}
  585. mov cx, ds
  586. lds bx, ss:[si + 2 + extra_param_offset] // Target
  587. {$endif FPC_X86_DATA_NEAR}
  588. pushf
  589. cli
  590. sub word [bx], 1
  591. mov ax, [bx]
  592. popf
  593. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  594. mov ds, cx
  595. {$endif}
  596. end;
  597. function InterLockedDecrement (var Target: longint) : longint;nostackframe;assembler;
  598. asm
  599. mov si, sp
  600. {$ifdef FPC_X86_DATA_NEAR}
  601. mov bx, ss:[si + 2 + extra_param_offset] // Target
  602. {$else FPC_X86_DATA_NEAR}
  603. mov cx, ds
  604. lds bx, ss:[si + 2 + extra_param_offset] // Target
  605. {$endif FPC_X86_DATA_NEAR}
  606. pushf
  607. cli
  608. sub word [bx], 1
  609. sbb word [bx+2], 0
  610. mov ax, [bx]
  611. mov dx, [bx+2]
  612. popf
  613. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  614. mov ds, cx
  615. {$endif}
  616. end;
  617. function InterLockedIncrement (var Target: smallint) : smallint;nostackframe;assembler;
  618. asm
  619. mov si, sp
  620. {$ifdef FPC_X86_DATA_NEAR}
  621. mov bx, ss:[si + 2 + extra_param_offset] // Target
  622. {$else FPC_X86_DATA_NEAR}
  623. mov cx, ds
  624. lds bx, ss:[si + 2 + extra_param_offset] // Target
  625. {$endif FPC_X86_DATA_NEAR}
  626. pushf
  627. cli
  628. add word [bx], 1
  629. mov ax, [bx]
  630. popf
  631. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  632. mov ds, cx
  633. {$endif}
  634. end;
  635. function InterLockedIncrement (var Target: longint) : longint;nostackframe;assembler;
  636. asm
  637. mov si, sp
  638. {$ifdef FPC_X86_DATA_NEAR}
  639. mov bx, ss:[si + 2 + extra_param_offset] // Target
  640. {$else FPC_X86_DATA_NEAR}
  641. mov cx, ds
  642. lds bx, ss:[si + 2 + extra_param_offset] // Target
  643. {$endif FPC_X86_DATA_NEAR}
  644. pushf
  645. cli
  646. add word [bx], 1
  647. adc word [bx+2], 0
  648. mov ax, [bx]
  649. mov dx, [bx+2]
  650. popf
  651. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  652. mov ds, cx
  653. {$endif}
  654. end;
  655. function InterLockedExchange (var Target: smallint;Source : smallint) : smallint;nostackframe;assembler;
  656. asm
  657. mov si, sp
  658. {$ifdef FPC_X86_DATA_NEAR}
  659. mov bx, ss:[si + 4 + extra_param_offset] // Target
  660. {$else FPC_X86_DATA_NEAR}
  661. mov cx, ds
  662. lds bx, ss:[si + 4 + extra_param_offset] // Target
  663. {$endif FPC_X86_DATA_NEAR}
  664. mov ax, ss:[si + 2 + extra_param_offset] // Source
  665. xchg word [bx], ax
  666. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  667. mov ds, cx
  668. {$endif}
  669. end;
  670. function InterLockedExchange (var Target: longint;Source : longint) : longint;nostackframe;assembler;
  671. asm
  672. mov si, sp
  673. {$ifdef FPC_X86_DATA_NEAR}
  674. mov bx, ss:[si + 6 + extra_param_offset] // Target
  675. {$else FPC_X86_DATA_NEAR}
  676. mov cx, ds
  677. lds bx, ss:[si + 6 + extra_param_offset] // Target
  678. {$endif FPC_X86_DATA_NEAR}
  679. mov ax, ss:[si + 2 + extra_param_offset] // Lo(Source)
  680. mov dx, ss:[si + 4 + extra_param_offset] // Hi(Source)
  681. pushf
  682. cli
  683. xchg word [bx], ax
  684. xchg word [bx+2], dx
  685. popf
  686. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  687. mov ds, cx
  688. {$endif}
  689. end;
  690. function InterLockedExchangeAdd (var Target: smallint;Source : smallint) : smallint;nostackframe;assembler;
  691. asm
  692. mov si, sp
  693. {$ifdef FPC_X86_DATA_NEAR}
  694. mov bx, ss:[si + 4 + extra_param_offset] // Target
  695. {$else FPC_X86_DATA_NEAR}
  696. mov cx, ds
  697. lds bx, ss:[si + 4 + extra_param_offset] // Target
  698. {$endif FPC_X86_DATA_NEAR}
  699. mov di, ss:[si + 2 + extra_param_offset] // Source
  700. pushf
  701. cli
  702. mov ax, [bx]
  703. add word [bx], di
  704. popf
  705. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  706. mov ds, cx
  707. {$endif}
  708. end;
  709. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;nostackframe;assembler;
  710. asm
  711. mov si, sp
  712. {$ifdef FPC_X86_DATA_NEAR}
  713. mov bx, ss:[si + 6 + extra_param_offset] // Target
  714. {$else FPC_X86_DATA_NEAR}
  715. mov cx, ds
  716. lds bx, ss:[si + 6 + extra_param_offset] // Target
  717. {$endif FPC_X86_DATA_NEAR}
  718. mov di, ss:[si + 2 + extra_param_offset] // Lo(Source)
  719. mov si, ss:[si + 4 + extra_param_offset] // Hi(Source)
  720. pushf
  721. cli
  722. mov ax, [bx]
  723. mov dx, [bx+2]
  724. add word [bx], di
  725. adc word [bx+2], si
  726. popf
  727. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  728. mov ds, cx
  729. {$endif}
  730. end;
  731. function InterlockedCompareExchange(var Target: smallint; NewValue: smallint; Comperand: smallint): smallint;assembler;
  732. asm
  733. {$ifdef FPC_X86_DATA_NEAR}
  734. mov bx, [Target] // Target
  735. {$else FPC_X86_DATA_NEAR}
  736. mov cx, ds
  737. lds bx, [Target] // Target
  738. {$endif FPC_X86_DATA_NEAR}
  739. mov di, [Comperand]
  740. pushf
  741. cli
  742. mov ax, [bx]
  743. cmp ax, di
  744. jne @@not_equal
  745. mov di, [NewValue]
  746. mov [bx], di
  747. @@not_equal:
  748. popf
  749. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  750. mov ds, cx
  751. {$endif}
  752. end;
  753. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;assembler;
  754. asm
  755. {$ifdef FPC_X86_DATA_NEAR}
  756. mov bx, [Target] // Target
  757. {$else FPC_X86_DATA_NEAR}
  758. mov cx, ds
  759. lds bx, [Target] // Target
  760. {$endif FPC_X86_DATA_NEAR}
  761. mov di, word [Comperand]
  762. mov si, word [Comperand+2]
  763. pushf
  764. cli
  765. mov ax, [bx]
  766. mov dx, [bx+2]
  767. cmp ax, di
  768. jne @@not_equal
  769. cmp dx, si
  770. jne @@not_equal
  771. mov di, word [NewValue]
  772. mov si, word [NewValue+2]
  773. mov [bx], di
  774. mov [bx+2], si
  775. @@not_equal:
  776. popf
  777. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  778. mov ds, cx
  779. {$endif}
  780. end;
  781. {****************************************************************************
  782. Stack checking
  783. ****************************************************************************}
  784. procedure fpc_stackcheck_i8086;[public,alias:'FPC_STACKCHECK_I8086'];compilerproc;assembler;nostackframe;
  785. const
  786. STACK_MARGIN=512;
  787. asm
  788. { on entry: AX = required stack size to check if available
  789. (function is called before stack allocation) }
  790. {$ifdef FPC_MM_HUGE}
  791. push ds
  792. push ax
  793. mov ax, SEG @DATA
  794. mov ds, ax
  795. pop ax
  796. {$endif FPC_MM_HUGE}
  797. add ax, STACK_MARGIN
  798. jc @@stack_overflow
  799. add ax, word ptr [__stkbottom]
  800. jc @@stack_overflow
  801. cmp ax, sp
  802. ja @@stack_overflow
  803. @@no_overflow:
  804. {$ifdef FPC_MM_HUGE}
  805. pop ds
  806. {$endif FPC_MM_HUGE}
  807. ret
  808. @@stack_overflow:
  809. { check StackError flag, to avoid recursive calls from the exit routines }
  810. cmp byte ptr [StackError], 1
  811. je @@no_overflow
  812. mov byte ptr [StackError], 1
  813. { cleanup return address (and maybe saved ds) from call to this function }
  814. {$if defined(FPC_MM_HUGE)}
  815. add sp, 6
  816. {$elseif defined(FPC_X86_CODE_FAR)}
  817. pop ax
  818. pop ax
  819. {$else}
  820. pop ax
  821. {$endif}
  822. { call HandleError(202) }
  823. {$ifdef CPU8086}
  824. xor ax, ax
  825. push ax
  826. mov al, 202
  827. push ax
  828. {$else}
  829. push 0
  830. push 202
  831. {$endif}
  832. call HandleError
  833. end;
  834. {****************************************************************************
  835. BSR/BSF
  836. ****************************************************************************}
  837. const
  838. bsr8bit: array [Byte] of Byte = (
  839. $ff,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  840. 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  841. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  842. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  843. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  844. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  845. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  846. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
  847. );
  848. bsf8bit: array [Byte] of Byte = (
  849. $ff,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  850. 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  851. 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  852. 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  853. 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  854. 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  855. 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
  856. 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
  857. );
  858. {$define FPC_SYSTEM_HAS_BSR_BYTE}
  859. function BsrByte(const AValue: Byte): Byte;
  860. begin
  861. BsrByte := bsr8bit[AValue];
  862. end;
  863. {$define FPC_SYSTEM_HAS_BSF_BYTE}
  864. function BsfByte(const AValue: Byte): Byte;
  865. begin
  866. BsfByte := bsf8bit[AValue];
  867. end;
  868. {$define FPC_SYSTEM_HAS_BSR_WORD}
  869. function BsrWord(const AValue: Word): Byte; assembler;
  870. asm
  871. lea bx, bsr8bit
  872. xor cl, cl
  873. mov ax, word [AValue]
  874. test ah, ah
  875. jz @@0
  876. mov cl, 8
  877. mov al, ah
  878. @@0: xlatb
  879. add al, cl
  880. end;
  881. {$define FPC_SYSTEM_HAS_BSF_WORD}
  882. function BsfWord(const AValue: Word): Byte; assembler;
  883. asm
  884. lea bx, bsf8bit
  885. xor cl, cl
  886. mov ax, word [AValue]
  887. test al, al
  888. jnz @@0
  889. or al, ah
  890. jz @@0
  891. add cl, 8
  892. @@0: xlatb
  893. add al, cl
  894. end;
  895. {$define FPC_SYSTEM_HAS_BSR_DWORD}
  896. function BsrDword(const AValue: DWord): Byte; assembler;
  897. asm
  898. lea bx, bsr8bit
  899. mov cl, 16
  900. mov ax, word [AValue+2]
  901. test ax, ax
  902. jnz @@0
  903. xor cl, cl
  904. mov ax, word [AValue]
  905. @@0: test ah, ah
  906. jz @@1
  907. add cl, 8
  908. mov al, ah
  909. @@1: xlatb
  910. add al, cl
  911. end;
  912. {$define FPC_SYSTEM_HAS_BSF_DWORD}
  913. function BsfDword(const AValue: DWord): Byte; assembler;
  914. asm
  915. lea bx, bsf8bit
  916. xor cl, cl
  917. mov ax, word [AValue]
  918. test ax, ax
  919. jnz @@0
  920. or ax, word [AValue+2]
  921. jz @@1
  922. mov cl, 16
  923. @@0: test al, al
  924. jnz @@1
  925. add cl, 8
  926. mov al, ah
  927. @@1: xlatb
  928. add al, cl
  929. end;
  930. {$define FPC_SYSTEM_HAS_BSR_QWORD}
  931. function BsrQword(const AValue: QWord): Byte; assembler;
  932. asm
  933. lea bx, bsr8bit
  934. mov cl, 48
  935. mov ax, word [AValue+6]
  936. test ax, ax
  937. jnz @@0
  938. mov cl, 32
  939. or ax, word [AValue+4]
  940. jnz @@0
  941. mov cl, 16
  942. or ax, word [AValue+2]
  943. jnz @@0
  944. xor cl, cl
  945. mov ax, word [AValue]
  946. @@0: test ah, ah
  947. jz @@1
  948. add cl, 8
  949. mov al, ah
  950. @@1: xlatb
  951. add al, cl
  952. end;
  953. {$define FPC_SYSTEM_HAS_BSF_QWORD}
  954. function BsfQword(const AValue: QWord): Byte; assembler;
  955. asm
  956. lea bx, bsf8bit
  957. xor cl, cl
  958. mov ax, word [AValue]
  959. test ax, ax
  960. jnz @@0
  961. mov cl, 16
  962. or ax, word [AValue+2]
  963. jnz @@0
  964. mov cl, 32
  965. or ax, word [AValue+4]
  966. jnz @@0
  967. xor cl, cl
  968. or ax, word [AValue+6]
  969. jz @@1
  970. mov cl, 48
  971. @@0: test al, al
  972. jnz @@1
  973. add cl, 8
  974. mov al, ah
  975. @@1: xlatb
  976. add al, cl
  977. end;
  978. {****************************************************************************
  979. HexStr
  980. ****************************************************************************}
  981. {$define FPC_HAS_HEXSTR_POINTER_SHORTSTR}
  982. function HexStr(Val: NearPointer): ShortString;
  983. begin
  984. HexStr:=HexStr(Word(Val),4);
  985. end;
  986. function HexStr(Val: NearCsPointer): ShortString;
  987. begin
  988. HexStr:='CS:'+HexStr(Word(Val),4);
  989. end;
  990. function HexStr(Val: NearDsPointer): ShortString;
  991. begin
  992. HexStr:='DS:'+HexStr(Word(Val),4);
  993. end;
  994. function HexStr(Val: NearEsPointer): ShortString;
  995. begin
  996. HexStr:='ES:'+HexStr(Word(Val),4);
  997. end;
  998. function HexStr(Val: NearSsPointer): ShortString;
  999. begin
  1000. HexStr:='SS:'+HexStr(Word(Val),4);
  1001. end;
  1002. function HexStr(Val: NearFsPointer): ShortString;
  1003. begin
  1004. HexStr:='FS:'+HexStr(Word(Val),4);
  1005. end;
  1006. function HexStr(Val: NearGsPointer): ShortString;
  1007. begin
  1008. HexStr:='GS:'+HexStr(Word(Val),4);
  1009. end;
  1010. function HexStr(Val: FarPointer): ShortString;
  1011. type
  1012. TFarPointerRec = record
  1013. Offset, Segment: Word;
  1014. end;
  1015. begin
  1016. HexStr:=HexStr(TFarPointerRec(Val).Segment,4)+':'+HexStr(TFarPointerRec(Val).Offset,4);
  1017. end;
  1018. function HexStr(Val: HugePointer): ShortString;{$ifdef SYSTEMINLINE}inline;{$endif}
  1019. begin
  1020. HexStr:=HexStr(FarPointer(Val));
  1021. end;
  1022. {****************************************************************************
  1023. FPU
  1024. ****************************************************************************}
  1025. const
  1026. { Internal constants for use in system unit }
  1027. FPU_Invalid = 1;
  1028. FPU_Denormal = 2;
  1029. FPU_DivisionByZero = 4;
  1030. FPU_Overflow = 8;
  1031. FPU_Underflow = $10;
  1032. FPU_StackUnderflow = $20;
  1033. FPU_StackOverflow = $40;
  1034. FPU_ExceptionMask = $ff;
  1035. { Detects the FPU and initializes the Test8087 variable (and Default8087CW):
  1036. 0 = NO FPU
  1037. 1 = 8087
  1038. 2 = 80287
  1039. 3 = 80387+ }
  1040. procedure DetectFPU;
  1041. var
  1042. localfpucw: word;
  1043. begin
  1044. asm
  1045. xor bx, bx { initialization, 0=NO FPU }
  1046. { FPU presence detection }
  1047. fninit
  1048. mov byte [localfpucw + 1], 0
  1049. nop
  1050. fnstcw localfpucw
  1051. cmp byte [localfpucw + 1], 3
  1052. jne @@Done { No FPU? }
  1053. inc bx
  1054. { FPU found; now test if it's a 8087 }
  1055. and byte [localfpucw], $7F { clear the interrupt enable mask (IEM) }
  1056. fldcw localfpucw
  1057. fdisi { try to set the interrupt enable mask }
  1058. fstcw localfpucw
  1059. test byte [localfpucw], $80 { IEM set? }
  1060. jnz @@Done { if yes, we have an 8087 }
  1061. inc bx
  1062. { we have a 287+; now test if it's a 80287 }
  1063. finit
  1064. fld1
  1065. fldz
  1066. fdiv { calculate 1/0 }
  1067. fld st { copy the value }
  1068. fchs { change the sign }
  1069. fcompp { compare. if the FPU distinguishes +inf from -inf, it's a 387+ }
  1070. fstsw localfpucw
  1071. mov ah, byte [localfpucw + 1]
  1072. sahf
  1073. je @@Done
  1074. inc bx { 387+ }
  1075. @@Done:
  1076. mov Test8087, bl
  1077. end ['AX','BX'];
  1078. if Test8087<=2 then
  1079. Default8087CW:=$1330
  1080. else
  1081. Default8087CW:=$1332;
  1082. end;
  1083. {$ifndef FPC_SYSTEM_HAS_SYSINITFPU}
  1084. {$define FPC_SYSTEM_HAS_SYSINITFPU}
  1085. Procedure SysInitFPU; assembler;
  1086. asm
  1087. fninit
  1088. fldcw Default8087CW
  1089. fwait
  1090. end;
  1091. {$endif ndef FPC_SYSTEM_HAS_SYSINITFPU}
  1092. {$define FPC_SYSTEM_HAS_SYSRESETFPU}
  1093. Procedure SysResetFPU; assembler;
  1094. asm
  1095. fninit
  1096. fwait
  1097. fldcw Default8087CW
  1098. end;
  1099. {$I int32p.inc}
  1100. {$I hugeptr.inc}