watcom.pp 30 KB

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