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