watcom.pp 30 KB

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