go32.pp 31 KB

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