go32.pp 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106
  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. movl bytes,%ebx
  201. addl $0xf,%ebx // round up
  202. shrl $0x4,%ebx // convert to Paragraphs
  203. movl $0x100,%eax // function 0x100
  204. int $0x31
  205. jnc .LDos_OK
  206. movw %ax,INT31ERROR
  207. xorl %eax,%eax
  208. jmp .LDos_end
  209. .LDos_OK:
  210. shll $0x10,%eax // return Segment in hi(Result)
  211. movw %dx,%ax // return Selector in lo(Result)
  212. .LDos_end:
  213. movl %eax,__result
  214. end;
  215. end;
  216. function global_dos_free(selector : word) : boolean;
  217. begin
  218. asm
  219. movw Selector,%dx
  220. movl $0x101,%eax
  221. int $0x31
  222. setnc %al
  223. movb %al,__RESULT
  224. end;
  225. end;
  226. function realintr(intnr : word;var regs : trealregs) : boolean;
  227. begin
  228. regs.realsp:=0;
  229. regs.realss:=0;
  230. asm
  231. { save all used registers to avoid crash under NTVDM }
  232. { when spawning a 32-bit DPMI application }
  233. pushw %fs
  234. movw intnr,%bx
  235. xorl %ecx,%ecx
  236. movl regs,%edi
  237. { es is always equal ds }
  238. movl $0x300,%eax
  239. int $0x31
  240. popw %fs
  241. setnc %al
  242. movb %al,__RESULT
  243. end;
  244. end;
  245. procedure seg_fillchar(seg : word;ofs : longint;count : longint;c : char);
  246. begin
  247. asm
  248. movl ofs,%edi
  249. movl count,%ecx
  250. movb c,%dl
  251. { load es with selector }
  252. pushw %es
  253. movw seg,%ax
  254. movw %ax,%es
  255. { fill eax with duplicated c }
  256. { so we can use stosl }
  257. movb %dl,%dh
  258. movw %dx,%ax
  259. shll $16,%eax
  260. movw %dx,%ax
  261. movl %ecx,%edx
  262. shrl $2,%ecx
  263. cld
  264. rep
  265. stosl
  266. movl %edx,%ecx
  267. andl $3,%ecx
  268. rep
  269. stosb
  270. popw %es
  271. end ['EAX','ECX','EDX','EDI'];
  272. end;
  273. procedure seg_fillword(seg : word;ofs : longint;count : longint;w : word);
  274. begin
  275. asm
  276. movl ofs,%edi
  277. movl count,%ecx
  278. movw w,%dx
  279. { load segment }
  280. pushw %es
  281. movw seg,%ax
  282. movw %ax,%es
  283. { fill eax }
  284. movw %dx,%ax
  285. shll $16,%eax
  286. movw %dx,%ax
  287. movl %ecx,%edx
  288. shrl $1,%ecx
  289. cld
  290. rep
  291. stosl
  292. movl %edx,%ecx
  293. andl $1,%ecx
  294. rep
  295. stosw
  296. popw %es
  297. end ['EAX','ECX','EDX','EDI'];
  298. end;
  299. procedure seg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
  300. begin
  301. if count=0 then
  302. exit;
  303. if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
  304. asm
  305. pushw %es
  306. pushw %ds
  307. cld
  308. movl count,%ecx
  309. movl source,%esi
  310. movl dest,%edi
  311. movw dseg,%ax
  312. movw %ax,%es
  313. movw sseg,%ax
  314. movw %ax,%ds
  315. movl %ecx,%eax
  316. shrl $2,%ecx
  317. rep
  318. movsl
  319. movl %eax,%ecx
  320. andl $3,%ecx
  321. rep
  322. movsb
  323. popw %ds
  324. popw %es
  325. end ['ESI','EDI','ECX','EAX']
  326. else if (source<dest) then
  327. { copy backward for overlapping }
  328. asm
  329. pushw %es
  330. pushw %ds
  331. std
  332. movl count,%ecx
  333. movl source,%esi
  334. movl dest,%edi
  335. movw dseg,%ax
  336. movw %ax,%es
  337. movw sseg,%ax
  338. movw %ax,%ds
  339. addl %ecx,%esi
  340. addl %ecx,%edi
  341. movl %ecx,%eax
  342. andl $3,%ecx
  343. orl %ecx,%ecx
  344. jz .LSEG_MOVE1
  345. { calculate esi and edi}
  346. decl %esi
  347. decl %edi
  348. rep
  349. movsb
  350. incl %esi
  351. incl %edi
  352. .LSEG_MOVE1:
  353. subl $4,%esi
  354. subl $4,%edi
  355. movl %eax,%ecx
  356. shrl $2,%ecx
  357. rep
  358. movsl
  359. cld
  360. popw %ds
  361. popw %es
  362. end ['ESI','EDI','ECX'];
  363. end;
  364. procedure outportb(port : word;data : byte);
  365. begin
  366. asm
  367. movw port,%dx
  368. movb data,%al
  369. outb %al,%dx
  370. end ['EAX','EDX'];
  371. end;
  372. procedure outportw(port : word;data : word);
  373. begin
  374. asm
  375. movw port,%dx
  376. movw data,%ax
  377. outw %ax,%dx
  378. end ['EAX','EDX'];
  379. end;
  380. procedure outportl(port : word;data : longint);
  381. begin
  382. asm
  383. movw port,%dx
  384. movl data,%eax
  385. outl %eax,%dx
  386. end ['EAX','EDX'];
  387. end;
  388. function inportb(port : word) : byte;
  389. begin
  390. asm
  391. movw port,%dx
  392. inb %dx,%al
  393. movb %al,__RESULT
  394. end ['EAX','EDX'];
  395. end;
  396. function inportw(port : word) : word;
  397. begin
  398. asm
  399. movw port,%dx
  400. inw %dx,%ax
  401. movw %ax,__RESULT
  402. end ['EAX','EDX'];
  403. end;
  404. function inportl(port : word) : longint;
  405. begin
  406. asm
  407. movw port,%dx
  408. inl %dx,%eax
  409. movl %eax,__RESULT
  410. end ['EAX','EDX'];
  411. end;
  412. function get_cs : word;assembler;
  413. asm
  414. movw %cs,%ax
  415. end;
  416. function get_ss : word;assembler;
  417. asm
  418. movw %ss,%ax
  419. end;
  420. function get_ds : word;assembler;
  421. asm
  422. movw %ds,%ax
  423. end;
  424. function set_pm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
  425. begin
  426. asm
  427. movl intaddr,%eax
  428. movl (%eax),%edx
  429. movw 4(%eax),%cx
  430. movl $0x205,%eax
  431. movb vector,%bl
  432. int $0x31
  433. pushf
  434. call test_int31
  435. movb %al,__RESULT
  436. end;
  437. end;
  438. function set_rm_interrupt(vector : byte;const intaddr : tseginfo) : boolean;
  439. begin
  440. asm
  441. movl intaddr,%eax
  442. movw (%eax),%dx
  443. movw 4(%eax),%cx
  444. movl $0x201,%eax
  445. movb vector,%bl
  446. int $0x31
  447. pushf
  448. call test_int31
  449. movb %al,__RESULT
  450. end;
  451. end;
  452. function set_pm_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
  453. begin
  454. asm
  455. movl intaddr,%eax
  456. movl (%eax),%edx
  457. movw 4(%eax),%cx
  458. movl $0x212,%eax
  459. movb e,%bl
  460. int $0x31
  461. pushf
  462. call test_int31
  463. movb %al,__RESULT
  464. end;
  465. end;
  466. function set_exception_handler(e : byte;const intaddr : tseginfo) : boolean;
  467. begin
  468. asm
  469. movl intaddr,%eax
  470. movl (%eax),%edx
  471. movw 4(%eax),%cx
  472. movl $0x203,%eax
  473. movb e,%bl
  474. int $0x31
  475. pushf
  476. call test_int31
  477. movb %al,__RESULT
  478. end;
  479. end;
  480. function get_pm_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
  481. begin
  482. asm
  483. movl $0x210,%eax
  484. movb e,%bl
  485. int $0x31
  486. pushf
  487. call test_int31
  488. movb %al,__RESULT
  489. movl intaddr,%eax
  490. movl %edx,(%eax)
  491. movw %cx,4(%eax)
  492. end;
  493. end;
  494. function get_exception_handler(e : byte;var intaddr : tseginfo) : boolean;
  495. begin
  496. asm
  497. movl $0x202,%eax
  498. movb e,%bl
  499. int $0x31
  500. pushf
  501. call test_int31
  502. movb %al,__RESULT
  503. movl intaddr,%eax
  504. movl %edx,(%eax)
  505. movw %cx,4(%eax)
  506. end;
  507. end;
  508. function get_pm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
  509. begin
  510. asm
  511. movb vector,%bl
  512. movl $0x204,%eax
  513. int $0x31
  514. pushf
  515. call test_int31
  516. movb %al,__RESULT
  517. movl intaddr,%eax
  518. movl %edx,(%eax)
  519. movw %cx,4(%eax)
  520. end;
  521. end;
  522. function get_rm_interrupt(vector : byte;var intaddr : tseginfo) : boolean;
  523. begin
  524. asm
  525. movb vector,%bl
  526. movl $0x200,%eax
  527. int $0x31
  528. pushf
  529. call test_int31
  530. movb %al,__RESULT
  531. movl intaddr,%eax
  532. movzwl %dx,%edx
  533. movl %edx,(%eax)
  534. movw %cx,4(%eax)
  535. end;
  536. end;
  537. function free_rm_callback(var intaddr : tseginfo) : boolean;
  538. begin
  539. asm
  540. movl intaddr,%eax
  541. movw (%eax),%dx
  542. movw 4(%eax),%cx
  543. movl $0x304,%eax
  544. int $0x31
  545. pushf
  546. call test_int31
  547. movb %al,__RESULT
  548. end;
  549. end;
  550. { here we must use ___v2prt0_ds_alias instead of from v2prt0.s
  551. because the exception processor sets the ds limit to $fff
  552. at hardware exceptions }
  553. var
  554. ___v2prt0_ds_alias : word; external name '___v2prt0_ds_alias';
  555. function get_rm_callback(pm_func : pointer;const reg : trealregs;var rmcb : tseginfo) : boolean;
  556. begin
  557. asm
  558. movl pm_func,%esi
  559. movl reg,%edi
  560. pushw %es
  561. movw ___v2prt0_ds_alias,%ax
  562. movw %ax,%es
  563. pushw %ds
  564. movw %cs,%ax
  565. movw %ax,%ds
  566. movl $0x303,%eax
  567. int $0x31
  568. popw %ds
  569. popw %es
  570. pushf
  571. call test_int31
  572. movb %al,__RESULT
  573. movl rmcb,%eax
  574. movzwl %dx,%edx
  575. movl %edx,(%eax)
  576. movw %cx,4(%eax)
  577. end;
  578. end;
  579. function allocate_ldt_descriptors(count : word) : word;
  580. begin
  581. asm
  582. movw count,%cx
  583. xorl %eax,%eax
  584. int $0x31
  585. movw %ax,__RESULT
  586. end;
  587. end;
  588. function free_ldt_descriptor(d : word) : boolean;
  589. begin
  590. asm
  591. movw d,%bx
  592. movl $1,%eax
  593. int $0x31
  594. pushf
  595. call test_int31
  596. movb %al,__RESULT
  597. end;
  598. end;
  599. function segment_to_descriptor(seg : word) : word;
  600. begin
  601. asm
  602. movw seg,%bx
  603. movl $2,%eax
  604. int $0x31
  605. movw %ax,__RESULT
  606. end;
  607. end;
  608. function get_next_selector_increment_value : word;
  609. begin
  610. asm
  611. movl $3,%eax
  612. int $0x31
  613. movw %ax,__RESULT
  614. end;
  615. end;
  616. function get_segment_base_address(d : word) : longint;
  617. begin
  618. asm
  619. movw d,%bx
  620. movl $6,%eax
  621. int $0x31
  622. xorl %eax,%eax
  623. movw %dx,%ax
  624. shll $16,%ecx
  625. orl %ecx,%eax
  626. movl %eax,__RESULT
  627. end;
  628. end;
  629. function get_page_size:longint;
  630. begin
  631. asm
  632. movl $0x604,%eax
  633. int $0x31
  634. shll $16,%ebx
  635. movw %cx,%bx
  636. movl %ebx,__RESULT
  637. end;
  638. end;
  639. function request_linear_region(linearaddr, size : longint;
  640. var blockhandle : longint) : boolean;
  641. var
  642. pageofs : longint;
  643. begin
  644. pageofs:=linearaddr and $3ff;
  645. linearaddr:=linearaddr-pageofs;
  646. size:=size+pageofs;
  647. asm
  648. movl $0x504,%eax
  649. movl linearaddr,%ebx
  650. movl size,%ecx
  651. movl $1,%edx
  652. xorl %esi,%esi
  653. int $0x31
  654. pushf
  655. call test_int31
  656. movb %al,__RESULT
  657. movl blockhandle,%eax
  658. movl %esi,(%eax)
  659. movl %ebx,pageofs
  660. end;
  661. if pageofs<>linearaddr then
  662. request_linear_region:=false;
  663. end;
  664. function allocate_memory_block(size:longint):longint;
  665. begin
  666. asm
  667. movl $0x501,%eax
  668. movl size,%ecx
  669. movl %ecx,%ebx
  670. shrl $16,%ebx
  671. andl $65535,%ecx
  672. int $0x31
  673. jnc .Lallocate_mem_block_err
  674. xorl %ebx,%ebx
  675. xorl %ecx,%ecx
  676. .Lallocate_mem_block_err:
  677. shll $16,%ebx
  678. movw %cx,%bx
  679. shll $16,%esi
  680. movw %di,%si
  681. movl %ebx,__RESULT
  682. end;
  683. end;
  684. function free_memory_block(blockhandle : longint) : boolean;
  685. begin
  686. asm
  687. movl blockhandle,%esi
  688. movl %esi,%edi
  689. shll $16,%esi
  690. movl $0x502,%eax
  691. int $0x31
  692. pushf
  693. call test_int31
  694. movb %al,__RESULT
  695. end;
  696. end;
  697. function lock_linear_region(linearaddr, size : longint) : boolean;
  698. begin
  699. asm
  700. movl $0x600,%eax
  701. movl linearaddr,%ecx
  702. movl %ecx,%ebx
  703. shrl $16,%ebx
  704. movl size,%esi
  705. movl %esi,%edi
  706. shrl $16,%esi
  707. int $0x31
  708. pushf
  709. call test_int31
  710. movb %al,__RESULT
  711. end;
  712. end;
  713. function lock_data(var data;size : longint) : boolean;
  714. var
  715. linearaddr : longint;
  716. begin
  717. if get_run_mode<>rm_dpmi then
  718. exit;
  719. linearaddr:=longint(@data)+get_segment_base_address(get_ds);
  720. lock_data:=lock_linear_region(linearaddr,size);
  721. end;
  722. function lock_code(functionaddr : pointer;size : longint) : boolean;
  723. var
  724. linearaddr : longint;
  725. begin
  726. if get_run_mode<>rm_dpmi then
  727. exit;
  728. linearaddr:=longint(functionaddr)+get_segment_base_address(get_cs);
  729. lock_code:=lock_linear_region(linearaddr,size);
  730. end;
  731. function unlock_linear_region(linearaddr,size : longint) : boolean;
  732. begin
  733. asm
  734. movl $0x601,%eax
  735. movl linearaddr,%ecx
  736. movl %ecx,%ebx
  737. shrl $16,%ebx
  738. movl size,%esi
  739. movl %esi,%edi
  740. shrl $16,%esi
  741. int $0x31
  742. pushf
  743. call test_int31
  744. movb %al,__RESULT
  745. end;
  746. end;
  747. function unlock_data(var data;size : longint) : boolean;
  748. var
  749. linearaddr : longint;
  750. begin
  751. if get_run_mode<>rm_dpmi then
  752. exit;
  753. linearaddr:=longint(@data)+get_segment_base_address(get_ds);
  754. unlock_data:=unlock_linear_region(linearaddr,size);
  755. end;
  756. function unlock_code(functionaddr : pointer;size : longint) : boolean;
  757. var
  758. linearaddr : longint;
  759. begin
  760. if get_run_mode<>rm_dpmi then
  761. exit;
  762. linearaddr:=longint(functionaddr)+get_segment_base_address(get_cs);
  763. unlock_code:=unlock_linear_region(linearaddr,size);
  764. end;
  765. function set_segment_base_address(d : word;s : longint) : boolean;
  766. begin
  767. asm
  768. movw d,%bx
  769. leal s,%eax
  770. movw (%eax),%dx
  771. movw 2(%eax),%cx
  772. movl $7,%eax
  773. int $0x31
  774. pushf
  775. call test_int31
  776. movb %al,__RESULT
  777. end;
  778. end;
  779. function set_descriptor_access_right(d : word;w : word) : longint;
  780. begin
  781. asm
  782. movw d,%bx
  783. movw w,%cx
  784. movl $9,%eax
  785. int $0x31
  786. pushf
  787. call test_int31
  788. movw %ax,__RESULT
  789. end;
  790. end;
  791. function set_segment_limit(d : word;s : longint) : boolean;
  792. begin
  793. asm
  794. movw d,%bx
  795. leal s,%eax
  796. movw (%eax),%dx
  797. movw 2(%eax),%cx
  798. movl $8,%eax
  799. int $0x31
  800. pushf
  801. call test_int31
  802. movb %al,__RESULT
  803. end;
  804. end;
  805. function get_descriptor_access_right(d : word) : longint;
  806. begin
  807. asm
  808. movzwl d,%eax
  809. lar %eax,%eax
  810. jz .L_ok
  811. xorl %eax,%eax
  812. .L_ok:
  813. movl %eax,__RESULT
  814. end;
  815. end;
  816. function get_segment_limit(d : word) : longint;
  817. begin
  818. asm
  819. movzwl d,%eax
  820. lsl %eax,%eax
  821. jz .L_ok2
  822. xorl %eax,%eax
  823. .L_ok2:
  824. movl %eax,__RESULT
  825. end;
  826. end;
  827. function create_code_segment_alias_descriptor(seg : word) : word;
  828. begin
  829. asm
  830. movw seg,%bx
  831. movl $0xa,%eax
  832. int $0x31
  833. pushf
  834. call test_int31
  835. movw %ax,__RESULT
  836. end;
  837. end;
  838. function get_meminfo(var meminfo : tmeminfo) : boolean;
  839. begin
  840. asm
  841. movl meminfo,%edi
  842. movl $0x500,%eax
  843. int $0x31
  844. pushf
  845. movb %al,__RESULT
  846. call test_int31
  847. end;
  848. end;
  849. function get_linear_addr(phys_addr : longint;size : longint) : longint;
  850. begin
  851. asm
  852. movl phys_addr,%ebx
  853. movl %ebx,%ecx
  854. shrl $16,%ebx
  855. movl size,%esi
  856. movl %esi,%edi
  857. shrl $16,%esi
  858. movl $0x800,%eax
  859. int $0x31
  860. pushf
  861. call test_int31
  862. shll $16,%ebx
  863. movw %cx,%bx
  864. movl %ebx,__RESULT
  865. end;
  866. end;
  867. procedure disable;assembler;
  868. asm
  869. cli
  870. end;
  871. procedure enable;assembler;
  872. asm
  873. sti
  874. end;
  875. var
  876. _run_mode : word;external name '_run_mode';
  877. function get_run_mode : word;
  878. begin
  879. get_run_mode:=_run_mode;
  880. end;
  881. function map_device_in_memory_block(handle,offset,pagecount,device:longint):boolean;
  882. begin
  883. asm
  884. movl device,%edx
  885. movl handle,%esi
  886. movl offset,%ebx
  887. movl pagecount,%ecx
  888. movl $0x0508,%eax
  889. int $0x31
  890. pushf
  891. setnc %al
  892. movb %al,__RESULT
  893. call test_int31
  894. end;
  895. end;
  896. {*****************************************************************************
  897. Transfer Buffer
  898. *****************************************************************************}
  899. function transfer_buffer : longint;
  900. begin
  901. transfer_buffer := go32_info_block.linear_address_of_transfer_buffer;
  902. end;
  903. function tb_segment : longint;
  904. begin
  905. tb_segment:=go32_info_block.linear_address_of_transfer_buffer shr 4;
  906. end;
  907. function tb_offset : longint;
  908. begin
  909. tb_offset:=go32_info_block.linear_address_of_transfer_buffer and $f;
  910. end;
  911. function tb_size : longint;
  912. begin
  913. tb_size := go32_info_block.size_of_transfer_buffer;
  914. end;
  915. procedure copytodos(var addr; len : longint);
  916. begin
  917. if len>tb_size then
  918. runerror(217);
  919. seg_move(get_ds,longint(@addr),dosmemselector,transfer_buffer,len);
  920. end;
  921. procedure copyfromdos(var addr; len : longint);
  922. begin
  923. if len>tb_size then
  924. runerror(217);
  925. seg_move(dosmemselector,transfer_buffer,get_ds,longint(@addr),len);
  926. end;
  927. var
  928. _core_selector : word;external name '_core_selector';
  929. begin
  930. int31error:=0;
  931. dosmemselector:=_core_selector;
  932. end.
  933. {
  934. $Log$
  935. Revision 1.6 2002-09-07 16:01:18 peter
  936. * old logs removed and tabs fixed
  937. Revision 1.5 2002/09/07 12:31:16 carl
  938. - removed support_ports option (cleanup)
  939. }