go32.tex 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. %
  2. % $Id$
  3. % This file is part of the FPC documentation.
  4. % Copyright (C) 1997, by Michael Van Canneyt
  5. %
  6. % The FPC documentation is free text; you can redistribute it and/or
  7. % modify it under the terms of the GNU Library General Public License as
  8. % published by the Free Software Foundation; either version 2 of the
  9. % License, or (at your option) any later version.
  10. %
  11. % The FPC Documentation is distributed in the hope that it will be useful,
  12. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. % Library General Public License for more details.
  15. %
  16. % You should have received a copy of the GNU Library General Public
  17. % License along with the FPC documentation; see the file COPYING.LIB. If not,
  18. % write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. % Boston, MA 02111-1307, USA.
  20. %
  21. \chapter{The GO32 unit.}
  22. This chapter describes the \var{GO32} unit for Free Pascal under \dos.
  23. The unit was first written for \dos by Florian kl\"ampfl.
  24. This chapter is divided in three sections.
  25. \begin{itemize}
  26. \item The first section is an introduction to the GO32 unit.
  27. \item The second section lists the pre-defined constants, types and variables.
  28. \item The third section describes the functions which appear in the
  29. interface part of the GO32 unit.
  30. \end{itemize}
  31. Many function descriptions were made by Thomas Schatzl\footnote{
  32. E-Mail: \var{tom\_at\[email protected]}}, for which my thanks.
  33. \section{Introduction}
  34. The GO32 provides an interface to the \dos extender, \dos memory access,
  35. I/O ports and processor access. Some of this functions work with all modes
  36. of the extender, other only with DPMI.
  37. \subsection{DOS memory access}
  38. The \dos memory access is done by the \var{dosmem}
  39. functions and it's \textbf {strongly recommended } to use these functions.
  40. Example:
  41. \begin{verbatim}
  42. function shift_state : byte;
  43. begin
  44. { $40:$17 contains the current contents of the shift,
  45. alt and strg keys}
  46. dosmemget($40,$17,shift_state,1);
  47. end;
  48. \end{verbatim}
  49. \subsection{I/O port access}
  50. The I/O port access is done by the \var{inport} and \var{outport} functions.
  51. It's not necessary to use these functions but it makes life easier. \fpc
  52. \textbf {doesn't} support the \var{PORT} array, as under Turbo Pascal.
  53. \subsection{Processor access}
  54. There are some functions to access the segment registers, which makes
  55. your work easier.
  56. \subsection{Interrupt redirection}
  57. The \file{GO32} unit helps you to redirect interrupts. \var{SetIntVec}
  58. and \var{GetIntVec} don't work with \fpc. This is now done via the functions
  59. \var{set\_pm\_interrupt} and \var{get\_pm\_interrupt}.
  60. As an example we show how to redirect the interrupt \var{8h}.
  61. \begin{verbatim}
  62. { the unit CRT _is_ needed because the program doesn't get
  63. an interrupt while DOS is active }
  64. uses
  65. go32,crt;
  66. var
  67. timer : longint;
  68. ds : word;
  69. procedure s; { interrupt;}
  70. { comes with versions > 0.9.2 of FPCPascal }
  71. begin
  72. asm
  73. { save used registers }
  74. pushl %eax
  75. pushw %ds
  76. { load ds }
  77. { prefix for cs }
  78. .byte 0x2e
  79. movw ALAB,%ax
  80. movw %ax,%ds
  81. end;
  82. inc(timer);
  83. asm
  84. { restore processor state }
  85. popw %ds
  86. popl %eax
  87. leave
  88. { call old interrupt }
  89. ljmp %cs:OLDINT
  90. iret
  91. { we need some data in the code segment, }
  92. { since only CS is set in the }
  93. { entry point of the procedure }
  94. ALAB:
  95. .word 0
  96. { old vector as 48 bit pointer (16:32) }
  97. OLDINT:
  98. .long 0
  99. .word 0
  100. end;
  101. end;
  102. var
  103. oldint,myint : tseginfo;
  104. i : longint;
  105. begin
  106. timer:=0;
  107. { save old interrupt }
  108. get_pm_interrupt(8,oldint);
  109. ds:=get_ds;
  110. asm
  111. { copy some data to the code segment }
  112. movw _DS,%ax
  113. movw %ax,ALAB
  114. movl _OLDINT,%eax
  115. movl %eax,OLDINT
  116. movw _OLDINT+4,%ax
  117. movw %ax,OLDINT+4
  118. end;
  119. { new handler }
  120. myint.segment:=get_cs;
  121. myint.offset:=@s;
  122. { install the handler }
  123. set_pm_interrupt(8,myint);
  124. { do something }
  125. for i:=1 to 10000 do
  126. writeln(timer);
  127. { install the old handler }
  128. set_pm_interrupt(8,oldint);
  129. end.
  130. \end{verbatim}
  131. \section{Types, Variables and Constants}
  132. \subsection{Constants}
  133. \begin{verbatim}
  134. Const
  135. rm_unknown = 0;
  136. rm_raw = 1; { raw (without HIMEM) }
  137. rm_xms = 2; { XMS (for example with HIMEM, without EMM386) }
  138. rm_vcpi = 3; { VCPI (for example HIMEM and EMM386) }
  139. rm_dpmi = 4; { DPMI (for example DOS box or 386Max) }
  140. \end{verbatim}\label{co:rmmode}
  141. These constants can be returned by the \htmlref{get\_run\_mode}{GetRunMode} function.
  142. \subsection{Types}
  143. \begin{verbatim}
  144. type
  145. tmeminfo = record
  146. available_memory : longint;
  147. available_pages : longint;
  148. available_lockable_pages : longint;
  149. linear_space : longint;
  150. unlocked_pages : longint;
  151. available_physical_pages : longint;
  152. total_physical_pages : longint;
  153. free_linear_space : longint;
  154. max_pages_in_paging_file : longint;
  155. reserved : array[0..2] of longint;
  156. end;
  157. \end{verbatim}\label{ty:tmeminfo}
  158. Returns information about the memory allocation etc.
  159. \textbf {NOTE:} The
  160. value of a field is zero if the value is unknown, it's only guaranteed,
  161. that \var{available\_memory} contains a valid value.
  162. \begin{verbatim}
  163. type
  164. trealregs = record
  165. case integer of
  166. 1: { 32-bit } (EDI, ESI, EBP, Res, EBX, EDX, ECX, EAX: longint;
  167. Flags, ES, DS, FS, GS, IP, CS, SP, SS: word);
  168. 2: { 16-bit } (DI, DI2, SI, SI2, BP, BP2, R1, R2: word;
  169. BX, BX2, DX, DX2, CX, CX2, AX, AX2: word);
  170. 3: { 8-bit } (stuff: array[1..4] of longint;
  171. BL, BH, BL2, BH2, DL, DH, DL2, DH2,
  172. CL, CH, CL2, CH2, AL, AH, AL2, AH2: byte);
  173. 4: { Compat } (RealEDI, RealESI, RealEBP, RealRES,
  174. RealEBX, RealEDX, RealECX, RealEAX: longint;
  175. RealFlags,
  176. RealES, RealDS, RealFS, RealGS,
  177. RealIP, RealCS, RealSP, RealSS: word);
  178. end;
  179. registers = trealregs;
  180. \end{verbatim}\label{ty:trealregs}
  181. This data structure is used to pass register values to an real mode
  182. interrupt handler.
  183. \begin{verbatim}
  184. type
  185. tseginfo = record
  186. offset : pointer;
  187. segment : word;
  188. end;
  189. \end{verbatim}\label{ty:tseginfo}
  190. This record is used to store a 48-bit pointer.
  191. \subsection{Variables.}
  192. \begin{verbatim}
  193. var
  194. { puts count bytes from data to ptr(seg:ofs) of the DOS memory }
  195. dosmemput : procedure(seg : word;ofs : word;var data;count : longint);
  196. { gets count bytes from ptr(seg:ofs) of the DOS memory to data }
  197. dosmemget : procedure(seg : word;ofs : word;var data;count : longint);
  198. { moves count bytes from ptr(sseg:sofs) to ptr(dseg:dofs) }
  199. dosmemmove : procedure(sseg,sofs,dseg,dofs : word;count : longint);
  200. { fills count bytes beginning with ptr(seg:ofs) with c }
  201. dosmemfillchar : procedure(seg,ofs : word;count : longint;c : char);
  202. { fills count words beginning with ptr(seg:ofs) with w }
  203. { this function is especially used by the CRT unit. }
  204. dosmemfillword : procedure(seg,ofs : word;count : longint;w : word);
  205. \end{verbatim}
  206. These procedure variables give you access to the \dos memory in each mode
  207. of the \dos extender. It is strongly recommended to use these functions.
  208. The procedural variables are assigned by the startup code of the \var{GO32}
  209. unit to the correct procedures.
  210. \begin{verbatim}
  211. var
  212. dosmemselector : word;
  213. \end{verbatim}
  214. Selector to the \dos memory. The whole \dos memory is mapped to a
  215. single segment. This function will only work in DPMI mode.
  216. \section{Functions and Procedures}
  217. \procedure {Disable}{}{
  218. Clears the interrupt flag with CLD and disables the interrupts.
  219. }
  220. {None.}{\seep{Enable}}
  221. \par {\bf NOTE: }This
  222. function works only in DPMI mode\par
  223. \procedure{Enable}{}{
  224. Sets the interrupt flag with STI and allows the processor to handle
  225. interrupts.
  226. }{None.}{\seep{Disable}}
  227. \procedurel{get\_meminfo}{GetMeminfo}{(var meminfo : tmeminfo)}{
  228. Returns the current state of memory allocation of the \dos extender.
  229. \textbf{NOTE: }This procedure has nothing to do with the Pascal function
  230. \var{maxavail} and \var{memavail}.}{None.}
  231. {\htmlref{tmeminfo}{ty:tmeminfo}}
  232. \procedurel{get\_pm\_interrupt}{GetPmInterrupt}{(vector : byte;var intaddr : tseginfo)}
  233. {
  234. Returns the address of the current protected mode handler for the interrupt
  235. \var{vector}.}{None.}
  236. {\seep{SetPmInterrupt},\htmlref{tseginfo}{ty:tseginfo}}
  237. \functionl{get\_run\_mode}{GetRunMode}{}{word}{
  238. This function returns the mode which the extender is currently running.
  239. The function is mostly used to determine if DPMI is supported.
  240. }{None.}
  241. {\htmlref{rm}{co:rmmode}}
  242. Example :
  243. \begin{verbatim}
  244. uses
  245. go32;
  246. begin
  247. if get_run_mode=rm_dpmi then
  248. writeln('DPMI available')
  249. else
  250. writeln('No DPMI available');
  251. end.
  252. \end{verbatim}
  253. \functionl{get\_cs}{GetCs}{}{word}{Returns the value of the CS
  254. register.}{None.}{\seef{GetDs},\seef{GetSs}}
  255. \functionl{get\_ds}{GetDs}{}{word}{Returns the value of the DS
  256. register.}{None.}{\seef{GetCs},\seef{GetSs}}
  257. \functionl{get\_ss}{GetSs}{word}{Returns the value of the SS
  258. register.}{None.}{\seef{GetDs},\seef{GetCs}}
  259. \function{inportb}{(port : word)}{byte}{Reads a byte from the given I/O
  260. port.}{None.}{\seep{outportb},\seef{inportw},\seef{inportl}}
  261. \function{inportw}{(port : word)}{word}{Reads a word from the given I/O
  262. port.}{None.}{\seep{outportw},\seef{inportb},\seef{inportl}}
  263. \function{inportl}{(port : word)}{longint}{Reads a longint from the given I/O
  264. port.}{None.}{\seep{outportl},\seef{inportw},\seef{inportb}}
  265. \procedure{outportb}{(port : word;data : byte)}{Writes a byte to the
  266. specified port.}{None.}{\seef{inportb},\seep{outportw},\seep{outportl}}
  267. \procedure{outportw}{(port : word;data : word)}{Writes a word to the
  268. specified port.}{None.}{\seef{inportw},\seep{outportb},\seep{outportl}}
  269. \procedure{outportl}{(port : word;data : longint)}{Writes a longint to the
  270. specified port.}{None.}{\seef{inportl},\seep{outportb},\seep{outportw}}
  271. \procedure{realintr}{(intnr : word;var regs : trealregs)}{
  272. \textbf {NOTE: }This procedure works only in DPMI mode.}
  273. {None.}{}
  274. \procedurel{seg\_fillchar}{SegFillChar}{(seg : word;ofs : longint;count : longint;c :
  275. char)}
  276. {Fills a memory area specified by a 48 bit pointer with the given number
  277. of chars.
  278. \textbf {NOTE:} Be careful using this function in non-DPMI mode.
  279. }{None.}{\seep{SegFillWord}, \seep{SegMove}}
  280. \procedurel {seg\_fillword}{SegFillWord}{(seg : word;ofs : longint;count : longint;w :
  281. word)}{Fills a memory area specified by a 48 bit pointer with the given number
  282. of words.
  283. \textbf {NOTE:} Be careful using this function in non-DPMI mode.
  284. }{None.}{\seep{SegFillChar}, \seep{SegMove}}
  285. \procedurel{seg\_move}{SegMove}{(sseg : word;source : longint;dseg : word;dest : longint;count :
  286. longint)}
  287. {This procedure copies data when the source and destination are specified
  288. by 48 bit pointers. For example, this function is used by the DPMI version
  289. of \var{dosmemget} and \var{dosmemput}. }{The procedure checks only
  290. for overlapping if source selector equals the destination selector.
  291. Be also careful using this function in non-DPMI
  292. mode.}{\seep{SegFillWord},\seep{SegFillChar}}
  293. \procedurel{set\_pm\_interrupt}{SetPmInterrupt}{(vector : byte;const intaddr : tseginfo)}
  294. {Sets a new protected mode handler for the interrupt \var{vector}.}
  295. {None.}{\seep{GetPmInterrupt}, \htmlref{tseginfo}{ty:tseginfo}}
  296. \functionl{Allocate\_Ldt\_Descriptors}{AllocateLdtDescriptors}{(Count :
  297. word)}{word}
  298. {\var{Allocate\_ldt\_descriptors} allocates \var{Count} descriptors in the
  299. Local Descriptor Table (LDT).
  300. The descriptors allocated must be initialized by the application with
  301. other function calls.
  302. The function returns a base descriptor with a limit and size value set to
  303. zero.
  304. {\em Notes:}
  305. \begin{itemize}
  306. \item Only works with real DPMI.
  307. \item If more than one descriptor was requested, the function returns a base
  308. selector referencing the first of a contiguous array of descriptors. The
  309. selector values for subsequent descriptors in the array can be
  310. calculated by adding the value returned by
  311. \var{get\_next\_selector\_increment\_value.}
  312. \end{itemize}
  313. }{None.}{
  314. \seep{SetSegmentBaseAddress},
  315. \seep{SetSegmentLimit},
  316. \seef{GetLinearAddr},
  317. \seep{FreeLdtDescriptor},
  318. \seef{GetNextSelectorIncrementValue}
  319. }
  320. \begin{FPCList}
  321. \item[Example]
  322. \begin{verbatim}
  323. uses go32;
  324. var VGAsel : word;
  325. r : trealregs;
  326. begin
  327. {...}
  328. r.realeax := $13; realintr($10, r);
  329. { set VGA mode }
  330. {...}
  331. VGAsel := allocate_ldt_descriptors(1);
  332. { allocate one descriptor to the VGA }
  333. set_segment_base_address(VGAsel,
  334. get_linear_addr($A0000,$FFFF));
  335. { set the base address to the VGA }
  336. set_segment_limit(VGAsel, $FFFF);
  337. { set the limit of the descriptor }
  338. {...}
  339. seg_fillchar(VGAsel, 100*320+100, 1, #15);
  340. { put a pixel at (6/100) in color 15 }
  341. readln;
  342. {...}
  343. free_ldt_descriptor(VGAsel);
  344. r.realeax := $3; realintr($10, r);
  345. { set textmode again }
  346. {...}
  347. end.
  348. \end{verbatim}
  349. \end{FPCList}
  350. \procedurel{Free\_Ldt\_Descriptor}{FreeLdtDescriptor}{(Sel : word)}
  351. {
  352. \var{Free\_Ldt\_Descriptor} frees a previously allocated selector
  353. with descriptor \var{Sel}
  354. {\em Notes:}
  355. \begin{itemize}
  356. \item Only works with real DPMI.
  357. \item After this call this selector is invalid and must not be used for any
  358. memory operations anymore.
  359. \item Each descriptor allocated with \var{allocate\_ltd\_descriptor} must be
  360. freed
  361. individually with this function, even if it was previously allocated as
  362. a part of a contiguous array of descriptors.
  363. \end{itemize}
  364. }
  365. {None.}
  366. {\seef{AllocateLdtDescriptors}}
  367. For an example, see \seef{AllocateLdtDescriptors}.
  368. \functionl{Segment\_To\_Descriptor}{SegmentToDescriptor}{(Seg : Word)}{Word}
  369. {\var{Segment\_To\_Descriptor} Maps a real mode segment (paragraph) address
  370. (in \var{Seg}) onto an descriptor that can be used by a protected mode
  371. program to access the same memory.
  372. The function returns a selector to the DOS real-mode segment.
  373. {\em Notes:}
  374. \begin{itemize}
  375. \item Only works with real DPMI.
  376. \item The descriptors limit will be set to 64KB.
  377. \item multiple calls to this function with the same segment address will
  378. return the same selector.
  379. \item Descriptors created by this function can never be modified or freed.
  380. For this reason this function shouldn't be used too often. Programs
  381. which need to examine various real mode addresses using the same
  382. selector should use the function \var{allocate\_ldt\_descriptors} and change
  383. the base address as necessary.
  384. \end{itemize}
  385. }
  386. {None.}
  387. {}
  388. \begin{FPCList}
  389. \item[Example]
  390. \begin{verbatim}
  391. uses go32;
  392. var r : trealregs;
  393. VGAsel : word;
  394. begin
  395. r.realeax := $13; realintr($10, r);
  396. { set VGA mode 13h }
  397. VGASel := segment_to_descriptor($A000);
  398. {...}
  399. seg_fillchar(VGAsel, 100*320+6, 1, #15);
  400. { put a pixel at (6/100) in color 15 }
  401. readln;
  402. {...}
  403. r.realeax := $3; realintr($10, r);
  404. end.
  405. \end{verbatim}
  406. \end{FPCList}
  407. \Functionl{Get\_Next\_Selector\_Increment\_Value}
  408. {GetNextSelectorIncrementValue}{word}
  409. {\var{Get\_Next\_Selector\_Increment\_Value} returns the selector increment
  410. value when allocating multiple subsequent descriptors
  411. The function \var{allocate\_ldt\_descriptors} can allocate an array of
  412. contiguous descriptors, but only return the selector for the first. The
  413. value returned by this function can be used to calculate the selectors
  414. for subsequent descriptors in the array.
  415. {\em Notes:}
  416. \begin{itemize}
  417. \item Only works under real DPMI.
  418. \item the increment is always a power of 2.
  419. \end{itemize}
  420. }
  421. {None.}
  422. {\seef{AllocateLdtDescriptors}}
  423. \functionl{Get\_Segment\_Base\_Address}{GetSegmentBaseAddress}{(Sel: word)}{Longint}
  424. {
  425. \var{Get\_Segment\_Base\_Address} returns the 32-bit linear base address
  426. from the LDT descriptor for the specified segment (\var{Sel}).
  427. {\em Notes:}
  428. \begin{itemize}
  429. \item Only works under real DPMI.
  430. \end{itemize}
  431. }
  432. {None.}
  433. {\seep{SetSegmentBaseAddress}}
  434. \begin{FPCList}
  435. \item[Example:]
  436. \begin{verbatim}
  437. uses go32;
  438. begin
  439. Writeln(get_segment_base_address(get_ds));
  440. end.
  441. \end{verbatim}
  442. \end{FPCList}
  443. \procedurel{Set\_Segment\_Base\_Address}{SetSegmentBaseAddress}
  444. {(var Des : word;Sel : longint)}
  445. {\var{{Set\_Segment\_Base\_Address}} sets the 32-bit linear base address
  446. of the descriptor \var{Des} for the specified selector \var{Sel}.
  447. {\em Notes:}
  448. \begin{itemize}
  449. \item only works under real DPMI
  450. \end{itemize}
  451. }
  452. {None.}
  453. { \seef{AllocateLdtDescriptors}, \seep{SetSegmentLimit}}
  454. For an example, see \seef{AllocateLdtDescriptors}.
  455. \procedurel{Set\_Segment\_Limit}{SetSegmentLimit}{(Des : word;Len : longint)}
  456. {\var{Set\_Segment\_Limit} sets the limit of the descriptor \var{Des}
  457. to the specified length \var{Len}
  458. {\em Notes:}
  459. \begin{itemize}
  460. \item Only works under real DPMI.
  461. \item The new limit is the byte length of the segment-1.
  462. \item Segment limits bigger than or equal to 1MB must be page aligned, they
  463. must have the lower 12 bits set.
  464. \end{itemize}
  465. }
  466. {None}
  467. { \seep{SetSegmentBaseAddress}, \seef{AllocateLdtDescriptors}}
  468. For an example, see \seef{AllocateLdtDescriptors}.
  469. \functionl{Create\_Code\_Segment\_Alias\_Descriptor}
  470. {CreateCodeSegmentAliasDescriptor}{(Des : Word)}{Word}
  471. {\var{Create\_Code\_Segment\_Alias\_Descriptor}
  472. Creates a new descriptor that has the same base and limit as the
  473. specified descriptor. In effect, the function returns a copy of the
  474. descriptor.
  475. {\em Notes:}
  476. \begin{itemize}
  477. \item Only works under real DPMI.
  478. \item The descriptor alias returned by this function will not track changes
  479. to the original descriptor. In other words, if an alias is created with
  480. this function, and the base or limit of the original segment is then
  481. changed, the two descriptors will no longer map the same memory.
  482. \end{itemize}
  483. }
  484. {None.}
  485. {}
  486. \begin{FPCList}
  487. \item[Example]
  488. \begin{verbatim}
  489. uses go32;
  490. var copysel : word;
  491. begin
  492. copysel := create_code_segment_alias_descriptor(get_ds);
  493. {...}
  494. free_ldt_descriptor(copysel);
  495. end.
  496. \end{verbatim}
  497. \end{FPCList}
  498. \functionl{Get\_Linear\_Addr}{GetLinearAddr}{(PhysAddr : longint;Size : longint)}{longint}
  499. {\var{Get\_Linear\_Addr} converts a physical address \var{PhysAddr} into
  500. a linear address.
  501. {\em Notes:}
  502. \begin{itemize}
  503. \item Only works under real DPMI.
  504. \end{itemize}
  505. }{None.}{}
  506. For an example, see \seef{AllocateLdtDescriptors}.
  507. \functionl{Global\_Dos\_Alloc}{GlobalDosAlloc}{(Len : longint)}{longint}
  508. {\var{Global\_Dos\_Alloc}
  509. allocates a block of memory with length \var{Len} from the \dos memory pool,
  510. i.e. memory below the 1 MB boundary that is controlled by \dos.
  511. Such memory blocks are typically used to exchange data with real mode
  512. programs, TSRs, or device drivers.
  513. The function returns both the real mode segment base address of
  514. the block and one or more descriptors that can be used by protected mode
  515. applications to access the block.
  516. The high word is the selector to this block, and the low word the
  517. \dos real mode segment. The offset of this block is always zero.
  518. {\em Notes:}
  519. \begin{itemize}
  520. \item Should only used for temporary buffers to get real mode information
  521. (e.g. interrupts that need a data structure in ES:DI), because every
  522. single block needs an unique selector.
  523. \end{itemize}
  524. }{None.}{\seep{GlobalDosFree}}
  525. \begin{FPCList}
  526. \item[Example]
  527. \begin{verbatim}
  528. uses go32;
  529. procedure dosalloc (var selector : word;
  530. var segment : word;
  531. size : longint);
  532. var result : longint;
  533. begin
  534. result := global_dos_alloc(size);
  535. selector := word(result);
  536. segment := word(result shr 16);
  537. end;
  538. procedure dosfree(selector : word);
  539. begin
  540. global_dos_free(selector);
  541. end;
  542. var selector : word;
  543. segment : word;
  544. r : trealregs;
  545. begin
  546. fillchar(r, sizeof(r), 0);
  547. fillchar(any_record, sizeof(any_record), 0);
  548. dosalloc(selector, segment, sizeof(VBE_vgainfo));
  549. { allocate a real mode memory block }
  550. any_record.any_entry := 1000;
  551. dosmemput(segment, 0, any_record, sizeof(any_record));
  552. { copy the record to real mode memory }
  553. r.realeax := $0000;
  554. r.reales := segment; r.realedi := 0;
  555. realintr(IntNr, r); { do our interrupt }
  556. dosmemget(segment, 0, any_record, sizeof(any_record));
  557. { get the record from real mode memory }
  558. dosfree(selector); { free selector afterwards }
  559. end.
  560. \end{verbatim}
  561. \end{FPCList}
  562. \procedurel{Global\_Dos\_Free}{GlobalDosFree}{(Sel : word)}
  563. {var{Global\_Dos\_Free} frees a previously allocated \dos memory
  564. block, described by selector \var{Sel}.
  565. }
  566. {None.}
  567. {\seef{GlobalDosAlloc}}
  568. For an example, see \seef{GlobalDosAlloc}.
  569. \functionl{Set\_Descriptor\_Access\_right}{SetDescriptorAccesRight}{(Des: word; W: word)}{Longint}
  570. {\var{Set\_Descriptor\_Access\_right} sets the access rights of a
  571. descriptor \var{Des}.}
  572. {None.}{seef{GetDescriptorAccesRight}}
  573. \functionl{Get\_Descriptor\_Access\_right}{GetDescriptorAccesRight}{(Des: word)}{Longint}
  574. {\var{Get\_Descriptor\_Access\_right} gets the access rights of a
  575. descriptor \var{Des}.}
  576. {None.}{seef{SetDescriptorAccesRight}}