go32.pp 32 KB

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