go32.pp 31 KB

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