2
0

watcom.pp 28 KB

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