watcom.pp 30 KB

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