go32.pp 30 KB

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