go32.pp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. and implements some stuff for protected mode programming
  5. Copyright (c) 1999-2000 by the Free Pascal development team.
  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. unit go32;
  13. {$S-,R-,I-,Q-} {no stack check, used by DPMIEXCP !! }
  14. interface
  15. const
  16. { contants for the run modes returned by get_run_mode }
  17. rm_unknown = 0;
  18. rm_raw = 1; { raw (without HIMEM) }
  19. rm_xms = 2; { XMS (for example with HIMEM, without EMM386) }
  20. rm_vcpi = 3; { VCPI (for example HIMEM and EMM386) }
  21. rm_dpmi = 4; { DPMI (for example DOS box or 386Max) }
  22. { flags }
  23. carryflag = $001;
  24. parityflag = $004;
  25. auxcarryflag = $010;
  26. zeroflag = $040;
  27. signflag = $080;
  28. trapflag = $100;
  29. interruptflag = $200;
  30. directionflag = $400;
  31. overflowflag = $800;
  32. type
  33. tmeminfo = record
  34. available_memory,
  35. available_pages,
  36. available_lockable_pages,
  37. linear_space,
  38. unlocked_pages,
  39. available_physical_pages,
  40. total_physical_pages,
  41. free_linear_space,
  42. max_pages_in_paging_file,
  43. reserved0,
  44. reserved1,
  45. reserved2 : longint;
  46. end;
  47. tseginfo = record
  48. offset : pointer;
  49. segment : word;
  50. end;
  51. trealregs = record
  52. case integer of
  53. 1: { 32-bit } (EDI, ESI, EBP, Res, EBX, EDX, ECX, EAX: longint;
  54. Flags, ES, DS, FS, GS, IP, CS, SP, SS: word);
  55. 2: { 16-bit } (DI, DI2, SI, SI2, BP, BP2, R1, R2: word;
  56. BX, BX2, DX, DX2, CX, CX2, AX, AX2: word);
  57. 3: { 8-bit } (stuff: array[1..4] of longint;
  58. BL, BH, BL2, BH2, DL, DH, DL2, DH2,
  59. CL, CH, CL2, CH2, AL, AH, AL2, AH2: byte);
  60. 4: { Compat } (RealEDI, RealESI, RealEBP, RealRES,
  61. RealEBX, RealEDX, RealECX, RealEAX: longint;
  62. RealFlags,
  63. RealES, RealDS, RealFS, RealGS,
  64. RealIP, RealCS, RealSP, RealSS: word);
  65. end;
  66. registers = trealregs;
  67. { this works only with real DPMI }
  68. function allocate_ldt_descriptors(count : word) : word;
  69. function free_ldt_descriptor(d : word) : boolean;
  70. function segment_to_descriptor(seg : word) : word;
  71. function get_next_selector_increment_value : word;
  72. function get_segment_base_address(d : word) : longint;
  73. function set_segment_base_address(d : word;s : longint) : boolean;
  74. function set_segment_limit(d : word;s : longint) : boolean;
  75. function set_descriptor_access_right(d : word;w : word) : longint;
  76. function create_code_segment_alias_descriptor(seg : word) : word;
  77. function get_linear_addr(phys_addr : longint;size : longint) : longint;
  78. function get_segment_limit(d : word) : longint;
  79. function get_descriptor_access_right(d : word) : longint;
  80. function get_page_size:longint;
  81. function map_device_in_memory_block(handle,offset,pagecount,device:longint):boolean;
  82. function realintr(intnr : word;var regs : trealregs) : boolean;
  83. { is needed for functions which need a real mode buffer }
  84. function global_dos_alloc(bytes : longint) : longint;
  85. function global_dos_free(selector : word) : boolean;
  86. var
  87. { selector for the DOS memory (only usable if in DPMI mode) }
  88. dosmemselector : word;
  89. { result of dpmi call }
  90. int31error : word;
  91. { this procedure copies data where the source and destination }
  92. { are specified by 48 bit pointers }
  93. { Note: the procedure checks only for overlapping if }
  94. { source selector=destination selector }
  95. procedure seg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
  96. { fills a memory area specified by a 48 bit pointer with c }
  97. procedure seg_fillchar(seg : word;ofs : longint;count : longint;c : char);
  98. procedure seg_fillword(seg : word;ofs : longint;count : longint;w : word);
  99. {************************************}
  100. { this works with all PM interfaces: }
  101. {************************************}
  102. function get_meminfo(var meminfo : tmeminfo) : boolean;
  103. function get_pm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
  104. function set_pm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
  105. function get_rm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
  106. function set_rm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
  107. function get_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
  108. function set_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
  109. function get_pm_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
  110. function set_pm_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
  111. function free_rm_callback(var intaddr : tseginfo) : boolean;
  112. function get_rm_callback(pm_func : pointer;const reg : trealregs;var rmcb : tseginfo) : boolean;
  113. function get_cs : word;
  114. function get_ds : word;
  115. function get_ss : word;
  116. { locking functions }
  117. function allocate_memory_block(size:longint):longint;
  118. function free_memory_block(blockhandle : longint) : boolean;
  119. function request_linear_region(linearaddr, size : longint;
  120. var blockhandle : longint) : boolean;
  121. function lock_linear_region(linearaddr, size : longint) : boolean;
  122. function lock_data(var data;size : longint) : boolean;
  123. function lock_code(functionaddr : pointer;size : longint) : boolean;
  124. function unlock_linear_region(linearaddr, size : longint) : boolean;
  125. function unlock_data(var data;size : longint) : boolean;
  126. function unlock_code(functionaddr : pointer;size : longint) : boolean;
  127. { disables and enables interrupts }
  128. procedure disable;
  129. procedure enable;
  130. function inportb(port : word) : byte;
  131. function inportw(port : word) : word;
  132. function inportl(port : word) : longint;
  133. procedure outportb(port : word;data : byte);
  134. procedure outportw(port : word;data : word);
  135. procedure outportl(port : word;data : longint);
  136. function get_run_mode : word;
  137. function transfer_buffer : longint;
  138. function tb_segment : longint;
  139. function tb_offset : longint;
  140. function tb_size : longint;
  141. procedure copytodos(var addr; len : longint);
  142. procedure copyfromdos(var addr; len : longint);
  143. procedure dpmi_dosmemput(seg : word;ofs : word;var data;count : longint);
  144. procedure dpmi_dosmemget(seg : word;ofs : word;var data;count : longint);
  145. procedure dpmi_dosmemmove(sseg,sofs,dseg,dofs : word;count : longint);
  146. procedure dpmi_dosmemfillchar(seg,ofs : word;count : longint;c : char);
  147. procedure dpmi_dosmemfillword(seg,ofs : word;count : longint;w : word);
  148. const
  149. { this procedures are assigned to the procedure which are needed }
  150. { for the current mode to access DOS memory }
  151. { It's strongly recommended to use this procedures! }
  152. dosmemput : procedure(seg : word;ofs : word;var data;count : longint)=@dpmi_dosmemput;
  153. dosmemget : procedure(seg : word;ofs : word;var data;count : longint)=@dpmi_dosmemget;
  154. dosmemmove : procedure(sseg,sofs,dseg,dofs : word;count : longint)=@dpmi_dosmemmove;
  155. dosmemfillchar : procedure(seg,ofs : word;count : longint;c : char)=@dpmi_dosmemfillchar;
  156. dosmemfillword : procedure(seg,ofs : word;count : longint;w : word)=@dpmi_dosmemfillword;
  157. implementation
  158. {$asmmode ATT}
  159. { the following procedures copy from and to DOS memory using DPMI }
  160. procedure dpmi_dosmemput(seg : word;ofs : word;var data;count : longint);
  161. begin
  162. seg_move(get_ds,longint(@data),dosmemselector,seg*16+ofs,count);
  163. end;
  164. procedure dpmi_dosmemget(seg : word;ofs : word;var data;count : longint);
  165. begin
  166. seg_move(dosmemselector,seg*16+ofs,get_ds,longint(@data),count);
  167. end;
  168. procedure dpmi_dosmemmove(sseg,sofs,dseg,dofs : word;count : longint);
  169. begin
  170. seg_move(dosmemselector,sseg*16+sofs,dosmemselector,dseg*16+dofs,count);
  171. end;
  172. procedure dpmi_dosmemfillchar(seg,ofs : word;count : longint;c : char);
  173. begin
  174. seg_fillchar(dosmemselector,seg*16+ofs,count,c);
  175. end;
  176. procedure dpmi_dosmemfillword(seg,ofs : word;count : longint;w : word);
  177. begin
  178. seg_fillword(dosmemselector,seg*16+ofs,count,w);
  179. end;
  180. procedure test_int31(flag : longint);
  181. begin
  182. asm
  183. pushl %ebx
  184. movw $0,INT31ERROR
  185. movl flag,%ebx
  186. testb $1,%bl
  187. jz .Lti31_1
  188. movw %ax,INT31ERROR
  189. xorl %eax,%eax
  190. jmp .Lti31_2
  191. .Lti31_1:
  192. movl $1,%eax
  193. .Lti31_2:
  194. popl %ebx
  195. end;
  196. end;
  197. function global_dos_alloc(bytes : longint) : longint;
  198. begin
  199. asm
  200. pushl %ebx
  201. movl bytes,%ebx
  202. addl $0xf,%ebx // round up
  203. shrl $0x4,%ebx // convert to Paragraphs
  204. movl $0x100,%eax // function 0x100
  205. int $0x31
  206. jnc .LDos_OK
  207. movw %ax,INT31ERROR
  208. xorl %eax,%eax
  209. jmp .LDos_end
  210. .LDos_OK:
  211. shll $0x10,%eax // return Segment in hi(Result)
  212. movw %dx,%ax // return Selector in lo(Result)
  213. .LDos_end:
  214. movl %eax,__result
  215. popl %ebx
  216. end;
  217. end;
  218. function global_dos_free(selector : word) : boolean;
  219. begin
  220. asm
  221. movw Selector,%dx
  222. movl $0x101,%eax
  223. int $0x31
  224. setnc %al
  225. movb %al,__RESULT
  226. end;
  227. end;
  228. function realintr(intnr : word;var regs : trealregs) : boolean;
  229. begin
  230. regs.realsp:=0;
  231. regs.realss:=0;
  232. asm
  233. { save all used registers to avoid crash under NTVDM }
  234. { when spawning a 32-bit DPMI application }
  235. pushl %edi
  236. pushl %ebx
  237. pushw %fs
  238. movw intnr,%bx
  239. xorl %ecx,%ecx
  240. movl regs,%edi
  241. { es is always equal ds }
  242. movl $0x300,%eax
  243. int $0x31
  244. popw %fs
  245. setnc %al
  246. movb %al,__RESULT
  247. popl %ebx
  248. popl %edi
  249. end;
  250. end;
  251. procedure seg_fillchar(seg : word;ofs : longint;count : longint;c : char);
  252. begin
  253. asm
  254. pushl %edi
  255. movl ofs,%edi
  256. movl count,%ecx
  257. movb c,%dl
  258. { load es with selector }
  259. pushw %es
  260. movw seg,%ax
  261. movw %ax,%es
  262. { fill eax with duplicated c }
  263. { so we can use stosl }
  264. movb %dl,%dh
  265. movw %dx,%ax
  266. shll $16,%eax
  267. movw %dx,%ax
  268. movl %ecx,%edx
  269. shrl $2,%ecx
  270. cld
  271. rep
  272. stosl
  273. movl %edx,%ecx
  274. andl $3,%ecx
  275. rep
  276. stosb
  277. popw %es
  278. popl %edi
  279. end;
  280. end;
  281. procedure seg_fillword(seg : word;ofs : longint;count : longint;w : word);
  282. begin
  283. asm
  284. pushl %edi
  285. movl ofs,%edi
  286. movl count,%ecx
  287. movw w,%dx
  288. { load segment }
  289. pushw %es
  290. movw seg,%ax
  291. movw %ax,%es
  292. { fill eax }
  293. movw %dx,%ax
  294. shll $16,%eax
  295. movw %dx,%ax
  296. movl %ecx,%edx
  297. shrl $1,%ecx
  298. cld
  299. rep
  300. stosl
  301. movl %edx,%ecx
  302. andl $1,%ecx
  303. rep
  304. stosw
  305. popw %es
  306. popl %edi
  307. end;
  308. end;
  309. procedure seg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
  310. begin
  311. if count=0 then
  312. exit;
  313. if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
  314. asm
  315. pushl %esi
  316. pushl %edi
  317. pushw %es
  318. pushw %ds
  319. cld
  320. movl count,%ecx
  321. movl source,%esi
  322. movl dest,%edi
  323. movw dseg,%ax
  324. movw %ax,%es
  325. movw sseg,%ax
  326. movw %ax,%ds
  327. movl %ecx,%eax
  328. shrl $2,%ecx
  329. rep
  330. movsl
  331. movl %eax,%ecx
  332. andl $3,%ecx
  333. rep
  334. movsb
  335. popw %ds
  336. popw %es
  337. popl %edi
  338. popl %esi
  339. end ['ECX','EAX']
  340. else if (source<dest) then
  341. { copy backward for overlapping }
  342. asm
  343. pushl %esi
  344. pushl %edi
  345. pushw %es
  346. pushw %ds
  347. std
  348. movl count,%ecx
  349. movl source,%esi
  350. movl dest,%edi
  351. movw dseg,%ax
  352. movw %ax,%es
  353. movw sseg,%ax
  354. movw %ax,%ds
  355. addl %ecx,%esi
  356. addl %ecx,%edi
  357. movl %ecx,%eax
  358. andl $3,%ecx
  359. orl %ecx,%ecx
  360. jz .LSEG_MOVE1
  361. { calculate esi and edi}
  362. decl %esi
  363. decl %edi
  364. rep
  365. movsb
  366. incl %esi
  367. incl %edi
  368. .LSEG_MOVE1:
  369. subl $4,%esi
  370. subl $4,%edi
  371. movl %eax,%ecx
  372. shrl $2,%ecx
  373. rep
  374. movsl
  375. cld
  376. popw %ds
  377. popw %es
  378. popl %edi
  379. popl %esi
  380. end ['ESI','EDI','ECX'];
  381. end;
  382. procedure outportb(port : word;data : byte);
  383. begin
  384. asm
  385. movw port,%dx
  386. movb data,%al
  387. outb %al,%dx
  388. end ['EAX','EDX'];
  389. end;
  390. procedure outportw(port : word;data : word);
  391. begin
  392. asm
  393. movw port,%dx
  394. movw data,%ax
  395. outw %ax,%dx
  396. end ['EAX','EDX'];
  397. end;
  398. procedure outportl(port : word;data : longint);
  399. begin
  400. asm
  401. movw port,%dx
  402. movl data,%eax
  403. outl %eax,%dx
  404. end ['EAX','EDX'];
  405. end;
  406. function inportb(port : word) : byte;
  407. begin
  408. asm
  409. movw port,%dx
  410. inb %dx,%al
  411. movb %al,__RESULT
  412. end ['EAX','EDX'];
  413. end;
  414. function inportw(port : word) : word;
  415. begin
  416. asm
  417. movw port,%dx
  418. inw %dx,%ax
  419. movw %ax,__RESULT
  420. end ['EAX','EDX'];
  421. end;
  422. function inportl(port : word) : longint;
  423. begin
  424. asm
  425. movw port,%dx
  426. inl %dx,%eax
  427. movl %eax,__RESULT
  428. end ['EAX','EDX'];
  429. end;
  430. function get_cs : word;assembler;
  431. asm
  432. movw %cs,%ax
  433. end;
  434. function get_ss : word;assembler;
  435. asm
  436. movw %ss,%ax
  437. end;
  438. function get_ds : word;assembler;
  439. asm
  440. movw %ds,%ax
  441. end;
  442. function set_pm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
  443. begin
  444. asm
  445. pushl %ebx
  446. movl intaddr,%eax
  447. movl (%eax),%edx
  448. movw 4(%eax),%cx
  449. movl $0x205,%eax
  450. movb vector,%bl
  451. int $0x31
  452. pushf
  453. call test_int31
  454. movb %al,__RESULT
  455. popl %ebx
  456. end;
  457. end;
  458. function set_rm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
  459. begin
  460. asm
  461. pushl %ebx
  462. movl intaddr,%eax
  463. movw (%eax),%dx
  464. movw 4(%eax),%cx
  465. movl $0x201,%eax
  466. movb vector,%bl
  467. int $0x31
  468. pushf
  469. call test_int31
  470. movb %al,__RESULT
  471. popl %ebx
  472. end;
  473. end;
  474. function set_pm_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
  475. begin
  476. asm
  477. pushl %ebx
  478. movl intaddr,%eax
  479. movl (%eax),%edx
  480. movw 4(%eax),%cx
  481. movl $0x212,%eax
  482. movb e,%bl
  483. int $0x31
  484. pushf
  485. call test_int31
  486. movb %al,__RESULT
  487. popl %ebx
  488. end;
  489. end;
  490. function set_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
  491. begin
  492. asm
  493. pushl %ebx
  494. movl intaddr,%eax
  495. movl (%eax),%edx
  496. movw 4(%eax),%cx
  497. movl $0x203,%eax
  498. movb e,%bl
  499. int $0x31
  500. pushf
  501. call test_int31
  502. movb %al,__RESULT
  503. popl %ebx
  504. end;
  505. end;
  506. function get_pm_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
  507. begin
  508. asm
  509. pushl %ebx
  510. movl $0x210,%eax
  511. movb e,%bl
  512. int $0x31
  513. pushf
  514. call test_int31
  515. movb %al,__RESULT
  516. movl intaddr,%eax
  517. movl %edx,(%eax)
  518. movw %cx,4(%eax)
  519. popl %ebx
  520. end;
  521. end;
  522. function get_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
  523. begin
  524. asm
  525. pushl %ebx
  526. movl $0x202,%eax
  527. movb e,%bl
  528. int $0x31
  529. pushf
  530. call test_int31
  531. movb %al,__RESULT
  532. movl intaddr,%eax
  533. movl %edx,(%eax)
  534. movw %cx,4(%eax)
  535. popl %ebx
  536. end;
  537. end;
  538. function get_pm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
  539. begin
  540. asm
  541. pushl %ebx
  542. movb vector,%bl
  543. movl $0x204,%eax
  544. int $0x31
  545. pushf
  546. call test_int31
  547. movb %al,__RESULT
  548. movl intaddr,%eax
  549. movl %edx,(%eax)
  550. movw %cx,4(%eax)
  551. popl %ebx
  552. end;
  553. end;
  554. function get_rm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
  555. begin
  556. asm
  557. pushl %ebx
  558. movb vector,%bl
  559. movl $0x200,%eax
  560. int $0x31
  561. pushf
  562. call test_int31
  563. movb %al,__RESULT
  564. movl intaddr,%eax
  565. movzwl %dx,%edx
  566. movl %edx,(%eax)
  567. movw %cx,4(%eax)
  568. popl %ebx
  569. end;
  570. end;
  571. function free_rm_callback(var intaddr : tseginfo) : boolean;
  572. begin
  573. asm
  574. movl intaddr,%eax
  575. movw (%eax),%dx
  576. movw 4(%eax),%cx
  577. movl $0x304,%eax
  578. int $0x31
  579. pushf
  580. call test_int31
  581. movb %al,__RESULT
  582. end;
  583. end;
  584. { here we must use ___v2prt0_ds_alias instead of from v2prt0.s
  585. because the exception processor sets the ds limit to $fff
  586. at hardware exceptions }
  587. var
  588. ___v2prt0_ds_alias : word; external name '___v2prt0_ds_alias';
  589. function get_rm_callback(pm_func : pointer;const reg : trealregs;var rmcb : tseginfo) : boolean;
  590. begin
  591. asm
  592. pushl %esi
  593. pushl %edi
  594. movl pm_func,%esi
  595. movl reg,%edi
  596. pushw %es
  597. movw ___v2prt0_ds_alias,%ax
  598. movw %ax,%es
  599. pushw %ds
  600. movw %cs,%ax
  601. movw %ax,%ds
  602. movl $0x303,%eax
  603. int $0x31
  604. popw %ds
  605. popw %es
  606. pushf
  607. call test_int31
  608. movb %al,__RESULT
  609. movl rmcb,%eax
  610. movzwl %dx,%edx
  611. movl %edx,(%eax)
  612. movw %cx,4(%eax)
  613. popl %edi
  614. popl %esi
  615. end;
  616. end;
  617. function allocate_ldt_descriptors(count : word) : word;
  618. begin
  619. asm
  620. movw count,%cx
  621. xorl %eax,%eax
  622. int $0x31
  623. movw %ax,__RESULT
  624. end;
  625. end;
  626. function free_ldt_descriptor(d : word) : boolean;
  627. begin
  628. asm
  629. pushl %ebx
  630. movw d,%bx
  631. movl $1,%eax
  632. int $0x31
  633. pushf
  634. call test_int31
  635. movb %al,__RESULT
  636. popl %ebx
  637. end;
  638. end;
  639. function segment_to_descriptor(seg : word) : word;
  640. begin
  641. asm
  642. pushl %ebx
  643. movw seg,%bx
  644. movl $2,%eax
  645. int $0x31
  646. movw %ax,__RESULT
  647. popl %ebx
  648. end;
  649. end;
  650. function get_next_selector_increment_value : word;
  651. begin
  652. asm
  653. movl $3,%eax
  654. int $0x31
  655. movw %ax,__RESULT
  656. end;
  657. end;
  658. function get_segment_base_address(d : word) : longint;
  659. begin
  660. asm
  661. pushl %ebx
  662. movw d,%bx
  663. movl $6,%eax
  664. int $0x31
  665. xorl %eax,%eax
  666. movw %dx,%ax
  667. shll $16,%ecx
  668. orl %ecx,%eax
  669. movl %eax,__RESULT
  670. popl %ebx
  671. end;
  672. end;
  673. function get_page_size:longint;
  674. begin
  675. asm
  676. pushl %ebx
  677. movl $0x604,%eax
  678. int $0x31
  679. shll $16,%ebx
  680. movw %cx,%bx
  681. movl %ebx,__RESULT
  682. popl %ebx
  683. end;
  684. end;
  685. function request_linear_region(linearaddr, size : longint;
  686. var blockhandle : longint) : boolean;
  687. var
  688. pageofs : longint;
  689. begin
  690. pageofs:=linearaddr and $3ff;
  691. linearaddr:=linearaddr-pageofs;
  692. size:=size+pageofs;
  693. asm
  694. pushl %ebx
  695. pushl %esi
  696. movl $0x504,%eax
  697. movl linearaddr,%ebx
  698. movl size,%ecx
  699. movl $1,%edx
  700. xorl %esi,%esi
  701. int $0x31
  702. pushf
  703. call test_int31
  704. movb %al,__RESULT
  705. movl blockhandle,%eax
  706. movl %esi,(%eax)
  707. movl %ebx,pageofs
  708. popl %esi
  709. popl %ebx
  710. end;
  711. if pageofs<>linearaddr then
  712. request_linear_region:=false;
  713. end;
  714. function allocate_memory_block(size:longint):longint;
  715. begin
  716. asm
  717. pushl %ebx
  718. pushl %esi
  719. movl $0x501,%eax
  720. movl size,%ecx
  721. movl %ecx,%ebx
  722. shrl $16,%ebx
  723. andl $65535,%ecx
  724. int $0x31
  725. jnc .Lallocate_mem_block_err
  726. xorl %ebx,%ebx
  727. xorl %ecx,%ecx
  728. .Lallocate_mem_block_err:
  729. shll $16,%ebx
  730. movw %cx,%bx
  731. shll $16,%esi
  732. movw %di,%si
  733. movl %ebx,__RESULT
  734. popl %esi
  735. popl %ebx
  736. end;
  737. end;
  738. function free_memory_block(blockhandle : longint) : boolean;
  739. begin
  740. asm
  741. pushl %esi
  742. movl blockhandle,%esi
  743. movl %esi,%edi
  744. shll $16,%esi
  745. movl $0x502,%eax
  746. int $0x31
  747. pushf
  748. call test_int31
  749. movb %al,__RESULT
  750. popl %esi
  751. end;
  752. end;
  753. function lock_linear_region(linearaddr, size : longint) : boolean;
  754. begin
  755. asm
  756. pushl %ebx
  757. pushl %edi
  758. pushl %esi
  759. movl $0x600,%eax
  760. movl linearaddr,%ecx
  761. movl %ecx,%ebx
  762. shrl $16,%ebx
  763. movl size,%esi
  764. movl %esi,%edi
  765. shrl $16,%esi
  766. int $0x31
  767. pushf
  768. call test_int31
  769. movb %al,__RESULT
  770. popl %esi
  771. popl %edi
  772. popl %ebx
  773. end;
  774. end;
  775. function lock_data(var data;size : longint) : boolean;
  776. var
  777. linearaddr : longint;
  778. begin
  779. if get_run_mode<>rm_dpmi then
  780. exit;
  781. linearaddr:=longint(@data)+get_segment_base_address(get_ds);
  782. lock_data:=lock_linear_region(linearaddr,size);
  783. end;
  784. function lock_code(functionaddr : pointer;size : longint) : boolean;
  785. var
  786. linearaddr : longint;
  787. begin
  788. if get_run_mode<>rm_dpmi then
  789. exit;
  790. linearaddr:=longint(functionaddr)+get_segment_base_address(get_cs);
  791. lock_code:=lock_linear_region(linearaddr,size);
  792. end;
  793. function unlock_linear_region(linearaddr,size : longint) : boolean;
  794. begin
  795. asm
  796. pushl %ebx
  797. pushl %edi
  798. pushl %esi
  799. movl $0x601,%eax
  800. movl linearaddr,%ecx
  801. movl %ecx,%ebx
  802. shrl $16,%ebx
  803. movl size,%esi
  804. movl %esi,%edi
  805. shrl $16,%esi
  806. int $0x31
  807. pushf
  808. call test_int31
  809. movb %al,__RESULT
  810. popl %esi
  811. popl %edi
  812. popl %ebx
  813. end;
  814. end;
  815. function unlock_data(var data;size : longint) : boolean;
  816. var
  817. linearaddr : longint;
  818. begin
  819. if get_run_mode<>rm_dpmi then
  820. exit;
  821. linearaddr:=longint(@data)+get_segment_base_address(get_ds);
  822. unlock_data:=unlock_linear_region(linearaddr,size);
  823. end;
  824. function unlock_code(functionaddr : pointer;size : longint) : boolean;
  825. var
  826. linearaddr : longint;
  827. begin
  828. if get_run_mode<>rm_dpmi then
  829. exit;
  830. linearaddr:=longint(functionaddr)+get_segment_base_address(get_cs);
  831. unlock_code:=unlock_linear_region(linearaddr,size);
  832. end;
  833. function set_segment_base_address(d : word;s : longint) : boolean;
  834. begin
  835. asm
  836. pushl %ebx
  837. movw d,%bx
  838. leal s,%eax
  839. movw (%eax),%dx
  840. movw 2(%eax),%cx
  841. movl $7,%eax
  842. int $0x31
  843. pushf
  844. call test_int31
  845. movb %al,__RESULT
  846. popl %ebx
  847. end;
  848. end;
  849. function set_descriptor_access_right(d : word;w : word) : longint;
  850. begin
  851. asm
  852. pushl %ebx
  853. movw d,%bx
  854. movw w,%cx
  855. movl $9,%eax
  856. int $0x31
  857. pushf
  858. call test_int31
  859. movw %ax,__RESULT
  860. popl %ebx
  861. end;
  862. end;
  863. function set_segment_limit(d : word;s : longint) : boolean;
  864. begin
  865. asm
  866. pushl %ebx
  867. movw d,%bx
  868. leal s,%eax
  869. movw (%eax),%dx
  870. movw 2(%eax),%cx
  871. movl $8,%eax
  872. int $0x31
  873. pushf
  874. call test_int31
  875. movb %al,__RESULT
  876. popl %ebx
  877. end;
  878. end;
  879. function get_descriptor_access_right(d : word) : longint;
  880. begin
  881. asm
  882. movzwl d,%eax
  883. lar %eax,%eax
  884. jz .L_ok
  885. xorl %eax,%eax
  886. .L_ok:
  887. movl %eax,__RESULT
  888. end;
  889. end;
  890. function get_segment_limit(d : word) : longint;
  891. begin
  892. asm
  893. movzwl d,%eax
  894. lsl %eax,%eax
  895. jz .L_ok2
  896. xorl %eax,%eax
  897. .L_ok2:
  898. movl %eax,__RESULT
  899. end;
  900. end;
  901. function create_code_segment_alias_descriptor(seg : word) : word;
  902. begin
  903. asm
  904. pushl %ebx
  905. movw seg,%bx
  906. movl $0xa,%eax
  907. int $0x31
  908. pushf
  909. call test_int31
  910. movw %ax,__RESULT
  911. popl %ebx
  912. end;
  913. end;
  914. function get_meminfo(var meminfo : tmeminfo) : boolean;
  915. begin
  916. asm
  917. pushl %edi
  918. movl meminfo,%edi
  919. movl $0x500,%eax
  920. int $0x31
  921. pushf
  922. movb %al,__RESULT
  923. call test_int31
  924. popl %edi
  925. end;
  926. end;
  927. function get_linear_addr(phys_addr : longint;size : longint) : longint;
  928. begin
  929. asm
  930. pushl %ebx
  931. pushl %edi
  932. pushl %esi
  933. movl phys_addr,%ebx
  934. movl %ebx,%ecx
  935. shrl $16,%ebx
  936. movl size,%esi
  937. movl %esi,%edi
  938. shrl $16,%esi
  939. movl $0x800,%eax
  940. int $0x31
  941. pushf
  942. call test_int31
  943. shll $16,%ebx
  944. movw %cx,%bx
  945. movl %ebx,__RESULT
  946. popl %esi
  947. popl %edi
  948. popl %ebx
  949. end;
  950. end;
  951. procedure disable;assembler;
  952. asm
  953. cli
  954. end;
  955. procedure enable;assembler;
  956. asm
  957. sti
  958. end;
  959. var
  960. _run_mode : word;external name '_run_mode';
  961. function get_run_mode : word;
  962. begin
  963. get_run_mode:=_run_mode;
  964. end;
  965. function map_device_in_memory_block(handle,offset,pagecount,device:longint):boolean;
  966. begin
  967. asm
  968. pushl %ebx
  969. pushl %edi
  970. pushl %esi
  971. movl device,%edx
  972. movl handle,%esi
  973. movl offset,%ebx
  974. movl pagecount,%ecx
  975. movl $0x0508,%eax
  976. int $0x31
  977. pushf
  978. setnc %al
  979. movb %al,__RESULT
  980. call test_int31
  981. popl %esi
  982. popl %edi
  983. popl %ebx
  984. end;
  985. end;
  986. {*****************************************************************************
  987. Transfer Buffer
  988. *****************************************************************************}
  989. function transfer_buffer : longint;
  990. begin
  991. transfer_buffer := go32_info_block.linear_address_of_transfer_buffer;
  992. end;
  993. function tb_segment : longint;
  994. begin
  995. tb_segment:=go32_info_block.linear_address_of_transfer_buffer shr 4;
  996. end;
  997. function tb_offset : longint;
  998. begin
  999. tb_offset:=go32_info_block.linear_address_of_transfer_buffer and $f;
  1000. end;
  1001. function tb_size : longint;
  1002. begin
  1003. tb_size := go32_info_block.size_of_transfer_buffer;
  1004. end;
  1005. procedure copytodos(var addr; len : longint);
  1006. begin
  1007. if len>tb_size then
  1008. runerror(217);
  1009. seg_move(get_ds,longint(@addr),dosmemselector,transfer_buffer,len);
  1010. end;
  1011. procedure copyfromdos(var addr; len : longint);
  1012. begin
  1013. if len>tb_size then
  1014. runerror(217);
  1015. seg_move(dosmemselector,transfer_buffer,get_ds,longint(@addr),len);
  1016. end;
  1017. var
  1018. _core_selector : word;external name '_core_selector';
  1019. begin
  1020. int31error:=0;
  1021. dosmemselector:=_core_selector;
  1022. end.
  1023. {
  1024. $Log$
  1025. Revision 1.7 2003-10-03 21:46:25 peter
  1026. * stdcall fixes
  1027. Revision 1.6 2002/09/07 16:01:18 peter
  1028. * old logs removed and tabs fixed
  1029. Revision 1.5 2002/09/07 12:31:16 carl
  1030. - removed support_ports option (cleanup)
  1031. }