go32.pp 31 KB

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