go32.pp 32 KB

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