go32.pp 35 KB

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