go32.pp 32 KB

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