sysos.inc 6.8 KB

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