go32.pp 31 KB

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