sysos.inc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2001 by Free Pascal development team
  4. This file implements all the base types and limits required
  5. for a minimal POSIX compliant subset required to port the compiler
  6. to a new OS.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. const
  14. carryflag = 1;
  15. type
  16. tseginfo=packed record
  17. offset : pointer;
  18. segment : word;
  19. end;
  20. var
  21. old_int00 : tseginfo;cvar;
  22. old_int75 : tseginfo;cvar;
  23. {$asmmode ATT}
  24. {*****************************************************************************
  25. Go32 Helpers
  26. *****************************************************************************}
  27. function far_strlen(selector : word;linear_address : longint) : longint;assembler;
  28. asm
  29. movl linear_address,%edx
  30. movl %edx,%ecx
  31. pushl %gs
  32. movw selector,%gs
  33. .Larg19:
  34. movb %gs:(%edx),%al
  35. testb %al,%al
  36. je .Larg20
  37. incl %edx
  38. jmp .Larg19
  39. .Larg20:
  40. popl %gs
  41. movl %edx,%eax
  42. subl %ecx,%eax
  43. end;
  44. function tb : longint;
  45. begin
  46. tb:=go32_info_block.linear_address_of_transfer_buffer;
  47. end;
  48. function tb_segment : longint;
  49. begin
  50. tb_segment:=go32_info_block.linear_address_of_transfer_buffer shr 4;
  51. end;
  52. function tb_offset : longint;
  53. begin
  54. tb_offset:=go32_info_block.linear_address_of_transfer_buffer and $f;
  55. end;
  56. function tb_size : longint;
  57. begin
  58. tb_size:=go32_info_block.size_of_transfer_buffer;
  59. end;
  60. function dos_selector : word;
  61. begin
  62. dos_selector:=go32_info_block.selector_for_linear_memory;
  63. end;
  64. function get_ds : word;assembler;
  65. asm
  66. movw %ds,%ax
  67. end;
  68. function get_cs : word;assembler;
  69. asm
  70. movw %cs,%ax
  71. end;
  72. procedure sysseg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
  73. begin
  74. if count=0 then
  75. exit;
  76. if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
  77. asm
  78. pushl %esi
  79. pushl %edi
  80. pushw %es
  81. pushw %ds
  82. cld
  83. movl count,%ecx
  84. movl source,%esi
  85. movl dest,%edi
  86. movw dseg,%ax
  87. movw %ax,%es
  88. movw sseg,%ax
  89. movw %ax,%ds
  90. movl %ecx,%eax
  91. shrl $2,%ecx
  92. rep
  93. movsl
  94. movl %eax,%ecx
  95. andl $3,%ecx
  96. rep
  97. movsb
  98. popw %ds
  99. popw %es
  100. popl %edi
  101. popl %esi
  102. end
  103. else if (source<dest) then
  104. { copy backward for overlapping }
  105. asm
  106. pushl %esi
  107. pushl %edi
  108. pushw %es
  109. pushw %ds
  110. std
  111. movl count,%ecx
  112. movl source,%esi
  113. movl dest,%edi
  114. movw dseg,%ax
  115. movw %ax,%es
  116. movw sseg,%ax
  117. movw %ax,%ds
  118. addl %ecx,%esi
  119. addl %ecx,%edi
  120. movl %ecx,%eax
  121. andl $3,%ecx
  122. orl %ecx,%ecx
  123. jz .LSEG_MOVE1
  124. { calculate esi and edi}
  125. decl %esi
  126. decl %edi
  127. rep
  128. movsb
  129. incl %esi
  130. incl %edi
  131. .LSEG_MOVE1:
  132. subl $4,%esi
  133. subl $4,%edi
  134. movl %eax,%ecx
  135. shrl $2,%ecx
  136. rep
  137. movsl
  138. cld
  139. popw %ds
  140. popw %es
  141. popl %edi
  142. popl %esi
  143. end;
  144. end;
  145. function strcopy(dest,source : pchar) : pchar;assembler;
  146. var
  147. saveeax,saveesi,saveedi : longint;
  148. asm
  149. movl %edi,saveedi
  150. movl %esi,saveesi
  151. {$ifdef REGCALL}
  152. movl %eax,saveeax
  153. movl %edx,%edi
  154. {$else}
  155. movl source,%edi
  156. {$endif}
  157. testl %edi,%edi
  158. jz .LStrCopyDone
  159. leal 3(%edi),%ecx
  160. andl $-4,%ecx
  161. movl %edi,%esi
  162. subl %edi,%ecx
  163. {$ifdef REGCALL}
  164. movl %eax,%edi
  165. {$else}
  166. movl dest,%edi
  167. {$endif}
  168. jz .LStrCopyAligned
  169. .LStrCopyAlignLoop:
  170. movb (%esi),%al
  171. incl %edi
  172. incl %esi
  173. testb %al,%al
  174. movb %al,-1(%edi)
  175. jz .LStrCopyDone
  176. decl %ecx
  177. jnz .LStrCopyAlignLoop
  178. .balign 16
  179. .LStrCopyAligned:
  180. movl (%esi),%eax
  181. movl %eax,%edx
  182. leal 0x0fefefeff(%eax),%ecx
  183. notl %edx
  184. addl $4,%esi
  185. andl %edx,%ecx
  186. andl $0x080808080,%ecx
  187. jnz .LStrCopyEndFound
  188. movl %eax,(%edi)
  189. addl $4,%edi
  190. jmp .LStrCopyAligned
  191. .LStrCopyEndFound:
  192. testl $0x0ff,%eax
  193. jz .LStrCopyByte
  194. testl $0x0ff00,%eax
  195. jz .LStrCopyWord
  196. testl $0x0ff0000,%eax
  197. jz .LStrCopy3Bytes
  198. movl %eax,(%edi)
  199. jmp .LStrCopyDone
  200. .LStrCopy3Bytes:
  201. xorb %dl,%dl
  202. movw %ax,(%edi)
  203. movb %dl,2(%edi)
  204. jmp .LStrCopyDone
  205. .LStrCopyWord:
  206. movw %ax,(%edi)
  207. jmp .LStrCopyDone
  208. .LStrCopyByte:
  209. movb %al,(%edi)
  210. .LStrCopyDone:
  211. {$ifdef REGCALL}
  212. movl saveeax,%eax
  213. {$else}
  214. movl dest,%eax
  215. {$endif}
  216. movl saveedi,%edi
  217. movl saveesi,%esi
  218. end;
  219. procedure syscopytodos(addr : longint; len : longint);
  220. begin
  221. if len > tb_size then
  222. HandleError(217);
  223. sysseg_move(get_ds,addr,dos_selector,tb,len);
  224. end;
  225. procedure syscopyfromdos(addr : longint; len : longint);
  226. begin
  227. if len > tb_size then
  228. HandleError(217);
  229. sysseg_move(dos_selector,tb,get_ds,addr,len);
  230. end;
  231. procedure sysrealintr(intnr : word;var regs : trealregs);
  232. begin
  233. regs.realsp:=0;
  234. regs.realss:=0;
  235. regs.realres:=0; { spec says so, play it safe }
  236. asm
  237. pushl %ebx
  238. pushl %edi
  239. pushl %fs // Go32.RealIntr does it too (NTVDM bug),
  240. // "pushl" to avoid size prefix
  241. movw intnr,%bx
  242. xorl %ecx,%ecx
  243. movl regs,%edi
  244. movw $0x300,%ax
  245. int $0x31
  246. popl %fs
  247. popl %edi
  248. popl %ebx
  249. end;
  250. end;
  251. procedure set_pm_interrupt(vector : byte;const intaddr : tseginfo);
  252. begin
  253. asm
  254. pushl %ebx
  255. movl intaddr,%eax
  256. movl (%eax),%edx
  257. movw 4(%eax),%cx
  258. movl $0x205,%eax
  259. movb vector,%bl
  260. int $0x31
  261. popl %ebx
  262. end;
  263. end;
  264. procedure get_pm_interrupt(vector : byte;var intaddr : tseginfo);
  265. begin
  266. asm
  267. pushl %ebx
  268. movb vector,%bl
  269. movl $0x204,%eax
  270. int $0x31
  271. movl intaddr,%eax
  272. movl %edx,(%eax)
  273. movw %cx,4(%eax)
  274. popl %ebx
  275. end;
  276. end;
  277. procedure getinoutres(def : word);
  278. var
  279. regs : trealregs;
  280. begin
  281. regs.realeax:=$5900;
  282. regs.realebx:=$0;
  283. sysrealintr($21,regs);
  284. InOutRes:=lo(regs.realeax);
  285. case InOutRes of
  286. 19 : InOutRes:=150;
  287. 21 : InOutRes:=152;
  288. 32 : InOutRes:=5;
  289. end;
  290. if InOutRes=0 then
  291. InOutRes:=Def;
  292. end;