i8086.inc 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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:SizeInt;value:byte);assembler;nostackframe;
  18. asm
  19. mov bx, sp
  20. mov cx, ss:[bx + 4 + extra_param_offset] // count
  21. or cx, cx
  22. jle @@Done
  23. {$ifdef FPC_X86_DATA_NEAR}
  24. mov di, ss:[bx + 6 + extra_param_offset] // @x
  25. mov ax, ds
  26. mov es, ax
  27. {$else FPC_X86_DATA_NEAR}
  28. les di, ss:[bx + 6 + extra_param_offset] // @x
  29. {$endif FPC_X86_DATA_NEAR}
  30. mov al, ss:[bx + 2 + extra_param_offset] // value
  31. mov ah, al
  32. shr cx, 1
  33. {$ifdef FPC_ENABLED_CLD}
  34. cld
  35. {$endif FPC_ENABLED_CLD}
  36. rep stosw
  37. adc cx, cx
  38. rep stosb
  39. @@Done:
  40. end;
  41. {$endif FPC_SYSTEM_HAS_FILLCHAR}
  42. {$ifndef FPC_SYSTEM_HAS_FILLWORD}
  43. {$define FPC_SYSTEM_HAS_FILLWORD}
  44. procedure FillWord(var x;count : SizeInt;value : word);assembler;nostackframe;
  45. asm
  46. mov bx, sp
  47. mov cx, ss:[bx + 4 + extra_param_offset] // count
  48. or cx, cx
  49. jle @@Done
  50. {$ifdef FPC_X86_DATA_NEAR}
  51. mov di, ss:[bx + 6 + extra_param_offset] // @x
  52. mov ax, ds
  53. mov es, ax
  54. {$else FPC_X86_DATA_NEAR}
  55. les di, ss:[bx + 6 + extra_param_offset] // @x
  56. {$endif FPC_X86_DATA_NEAR}
  57. mov ax, ss:[bx + 2 + extra_param_offset] // value
  58. {$ifdef FPC_ENABLED_CLD}
  59. cld
  60. {$endif FPC_ENABLED_CLD}
  61. rep stosw
  62. @@Done:
  63. end;
  64. {$endif FPC_SYSTEM_HAS_FILLWORD}
  65. {$define FPC_SYSTEM_HAS_SPTR}
  66. Function Sptr : Pointer;assembler;nostackframe;
  67. asm
  68. mov ax, sp
  69. end;
  70. {$define FPC_SYSTEM_HAS_PTR}
  71. function Ptr(sel,off: Word):farpointer;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  72. asm
  73. mov si, sp
  74. mov ax, ss:[si + 2 + extra_param_offset] // off
  75. mov dx, ss:[si + 4 + extra_param_offset] // sel
  76. end;
  77. {$define FPC_SYSTEM_HAS_CSEG}
  78. function CSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  79. asm
  80. mov ax, cs
  81. end;
  82. {$define FPC_SYSTEM_HAS_DSEG}
  83. function DSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  84. asm
  85. mov ax, ds
  86. end;
  87. {$define FPC_SYSTEM_HAS_SSEG}
  88. function SSeg: Word;{$ifdef SYSTEMINLINE}inline;{$endif}assembler;nostackframe;
  89. asm
  90. mov ax, ss
  91. end;
  92. {$IFNDEF INTERNAL_BACKTRACE}
  93. {$define FPC_SYSTEM_HAS_GET_FRAME}
  94. function get_frame:pointer;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
  95. asm
  96. mov ax, bp
  97. end;
  98. {$ENDIF not INTERNAL_BACKTRACE}
  99. {$define FPC_SYSTEM_HAS_GET_PC_ADDR}
  100. Function Get_pc_addr : CodePointer;assembler;nostackframe;
  101. asm
  102. mov bx, sp
  103. mov ax, ss:[bx]
  104. {$ifdef FPC_X86_CODE_FAR}
  105. mov dx, ss:[bx+2]
  106. {$endif FPC_X86_CODE_FAR}
  107. end;
  108. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  109. function get_caller_addr(framebp:pointer;addr:codepointer=nil):codepointer;nostackframe;assembler;
  110. asm
  111. mov si, sp
  112. {$ifdef FPC_X86_CODE_FAR}
  113. xor dx, dx
  114. {$endif FPC_X86_CODE_FAR}
  115. mov ax, ss:[si + 4 + extra_param_offset + extra_param_offset] // framebp
  116. or ax, ax
  117. jz @@Lg_a_null
  118. xchg ax, bx
  119. mov bx, [bx+2]
  120. {$ifdef FPC_X86_CODE_FAR}
  121. mov dx, [bx+4]
  122. {$endif FPC_X86_CODE_FAR}
  123. xchg ax, bx
  124. @@Lg_a_null:
  125. end;
  126. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  127. function get_caller_frame(framebp:pointer;addr:codepointer=nil):pointer;nostackframe;assembler;
  128. asm
  129. mov si, sp
  130. mov ax, ss:[si + 4 + extra_param_offset + extra_param_offset] // framebp
  131. or ax, ax
  132. jz @@Lgnf_null
  133. xchg ax, bx
  134. mov bx, [bx]
  135. xchg ax, bx
  136. @@Lgnf_null:
  137. end;
  138. {TODO: fix, use smallint?}
  139. function InterLockedDecrement (var Target: longint) : longint;nostackframe;assembler;
  140. asm
  141. push bp
  142. mov bp, sp
  143. mov bx, ss:[bp + 4 + extra_param_offset] // Target
  144. sub word [bx], 1
  145. sbb word [bx+2], 0
  146. mov ax, [bx]
  147. mov dx, [bx+2]
  148. pop bp
  149. end;
  150. {TODO: fix, use smallint?}
  151. function InterLockedIncrement (var Target: longint) : longint;nostackframe;assembler;
  152. asm
  153. push bp
  154. mov bp, sp
  155. mov bx, ss:[bp + 4 + extra_param_offset] // Target
  156. add word [bx], 1
  157. adc word [bx+2], 0
  158. mov ax, [bx]
  159. mov dx, [bx+2]
  160. pop bp
  161. end;
  162. {TODO: fix, use smallint?}
  163. function InterLockedExchange (var Target: longint;Source : longint) : longint;
  164. begin
  165. InterLockedExchange := Target;
  166. Target := Source;
  167. end;
  168. {TODO: implement}
  169. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;
  170. begin
  171. runerror(304);
  172. end;
  173. {TODO: implement}
  174. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
  175. begin
  176. runerror(304);
  177. end;
  178. {****************************************************************************
  179. FPU
  180. ****************************************************************************}
  181. const
  182. { Internal constants for use in system unit }
  183. FPU_Invalid = 1;
  184. FPU_Denormal = 2;
  185. FPU_DivisionByZero = 4;
  186. FPU_Overflow = 8;
  187. FPU_Underflow = $10;
  188. FPU_StackUnderflow = $20;
  189. FPU_StackOverflow = $40;
  190. FPU_ExceptionMask = $ff;
  191. { use Default8087CW instead
  192. fpucw : word = $1300 or FPU_StackUnderflow or FPU_Underflow or FPU_Denormal;
  193. }
  194. { returns true if FPU is present }
  195. function DetectFPU: boolean;
  196. var
  197. localfpucw: word;
  198. begin
  199. asm
  200. fninit
  201. mov byte [localfpucw + 1], 0
  202. fnstcw localfpucw
  203. end;
  204. DetectFPU:=(localfpucw and $FF00)=$0300;
  205. end;
  206. {$define FPC_SYSTEM_HAS_SYSINITFPU}
  207. Procedure SysInitFPU;
  208. var
  209. { these locals are so we don't have to hack pic code in the assembler }
  210. localmxcsr: dword;
  211. localfpucw: word;
  212. begin
  213. localfpucw:=Default8087CW;
  214. asm
  215. fninit
  216. fldcw localfpucw
  217. fwait
  218. end;
  219. softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
  220. end;
  221. {$define FPC_SYSTEM_HAS_SYSRESETFPU}
  222. Procedure SysResetFPU;
  223. var
  224. { these locals are so we don't have to hack pic code in the assembler }
  225. localmxcsr: dword;
  226. localfpucw: word;
  227. begin
  228. localfpucw:=Default8087CW;
  229. asm
  230. fninit
  231. fwait
  232. fldcw localfpucw
  233. end;
  234. softfloat_exception_flags:=0;
  235. end;