go32.tex 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  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. \functionl{Allocate\_Ldt\_Descriptors}{AllocateLdtDescriptors}{(Count :
  218. word)}{word}
  219. {\var{Allocate\_ldt\_descriptors} allocates \var{Count} descriptors in the
  220. Local Descriptor Table (LDT).
  221. The descriptors allocated must be initialized by the application with
  222. other function calls.
  223. The function returns a base descriptor with a limit and size value set to
  224. zero.
  225. {\em Notes:}
  226. \begin{itemize}
  227. \item Only works with real DPMI.
  228. \item If more than one descriptor was requested, the function returns a base
  229. selector referencing the first of a contiguous array of descriptors. The
  230. selector values for subsequent descriptors in the array can be
  231. calculated by adding the value returned by
  232. \var{get\_next\_selector\_increment\_value.}
  233. \end{itemize}
  234. }{None.}{
  235. \seep{SetSegmentBaseAddress},
  236. \seep{SetSegmentLimit},
  237. \seef{GetLinearAddr},
  238. \seep{FreeLdtDescriptor},
  239. \seef{GetNextSelectorIncrementValue}
  240. }
  241. \begin{FPCList}
  242. \item[Example]
  243. \begin{verbatim}
  244. uses go32;
  245. var VGAsel : word;
  246. r : trealregs;
  247. begin
  248. {...}
  249. r.realeax := $13; realintr($10, r);
  250. { set VGA mode }
  251. {...}
  252. VGAsel := allocate_ldt_descriptors(1);
  253. { allocate one descriptor to the VGA }
  254. set_segment_base_address(VGAsel,
  255. get_linear_addr($A0000,$FFFF));
  256. { set the base address to the VGA }
  257. set_segment_limit(VGAsel, $FFFF);
  258. { set the limit of the descriptor }
  259. {...}
  260. seg_fillchar(VGAsel, 100*320+100, 1, #15);
  261. { put a pixel at (6/100) in color 15 }
  262. readln;
  263. {...}
  264. free_ldt_descriptor(VGAsel);
  265. r.realeax := $3; realintr($10, r);
  266. { set textmode again }
  267. {...}
  268. end.
  269. \end{verbatim}
  270. \end{FPCList}
  271. \functionl{Create\_Code\_Segment\_Alias\_Descriptor}
  272. {CreateCodeSegmentAliasDescriptor}{(Des : Word)}{Word}
  273. {\var{Create\_Code\_Segment\_Alias\_Descriptor}
  274. Creates a new descriptor that has the same base and limit as the
  275. specified descriptor. In effect, the function returns a copy of the
  276. descriptor.
  277. {\em Notes:}
  278. \begin{itemize}
  279. \item Only works under real DPMI.
  280. \item The descriptor alias returned by this function will not track changes
  281. to the original descriptor. In other words, if an alias is created with
  282. this function, and the base or limit of the original segment is then
  283. changed, the two descriptors will no longer map the same memory.
  284. \end{itemize}
  285. }
  286. {None.}
  287. {}
  288. \begin{FPCList}
  289. \item[Example]
  290. \begin{verbatim}
  291. uses go32;
  292. var copysel : word;
  293. begin
  294. copysel := create_code_segment_alias_descriptor(get_ds);
  295. {...}
  296. free_ldt_descriptor(copysel);
  297. end.
  298. \end{verbatim}
  299. \end{FPCList}
  300. \procedure {Disable}{}{
  301. Clears the interrupt flag with CLD and disables the interrupts.
  302. }
  303. {None.}{\seep{Enable}}
  304. \par {\bf NOTE: }This
  305. function works only in DPMI mode\par
  306. \procedure{Enable}{}{
  307. Sets the interrupt flag with STI and allows the processor to handle
  308. interrupts.
  309. }{None.}{\seep{Disable}}
  310. \procedurel{Free\_Ldt\_Descriptor}{FreeLdtDescriptor}{(Sel : word)}
  311. {
  312. \var{Free\_Ldt\_Descriptor} frees a previously allocated selector
  313. with descriptor \var{Sel}
  314. {\em Notes:}
  315. \begin{itemize}
  316. \item Only works with real DPMI.
  317. \item After this call this selector is invalid and must not be used for any
  318. memory operations anymore.
  319. \item Each descriptor allocated with \var{allocate\_ltd\_descriptor} must be
  320. freed
  321. individually with this function, even if it was previously allocated as
  322. a part of a contiguous array of descriptors.
  323. \end{itemize}
  324. }
  325. {None.}
  326. {\seef{AllocateLdtDescriptors}}
  327. For an example, see \seef{AllocateLdtDescriptors}.
  328. \functionl{get\_cs}{GetCs}{}{word}{Returns the value of the CS
  329. register.}{None.}{\seef{GetDs},\seef{GetSs}}
  330. \functionl{Get\_Descriptor\_Access\_right}{GetDescriptorAccesRight}{(Des: word)}{Longint}
  331. {\var{Get\_Descriptor\_Access\_right} gets the access rights of a
  332. descriptor \var{Des}.}
  333. {None.}{seef{SetDescriptorAccesRight}}
  334. \functionl{get\_ds}{GetDs}{}{word}{Returns the value of the DS
  335. register.}{None.}{\seef{GetCs},\seef{GetSs}}
  336. \functionl{Get\_Linear\_Addr}{GetLinearAddr}{(PhysAddr : longint;Size : longint)}{longint}
  337. {\var{Get\_Linear\_Addr} converts a physical address \var{PhysAddr} into
  338. a linear address.
  339. {\em Notes:}
  340. \begin{itemize}
  341. \item Only works under real DPMI.
  342. \end{itemize}
  343. }{None.}{}
  344. For an example, see \seef{AllocateLdtDescriptors}.
  345. \procedurel{get\_meminfo}{GetMeminfo}{(var meminfo : tmeminfo)}{
  346. Returns the current state of memory allocation of the \dos extender.
  347. \textbf{NOTE: }This procedure has nothing to do with the Pascal function
  348. \var{maxavail} and \var{memavail}.}{None.}
  349. {\htmlref{tmeminfo}{ty:tmeminfo}}
  350. \Functionl{Get\_Next\_Selector\_Increment\_Value}
  351. {GetNextSelectorIncrementValue}{word}
  352. {\var{Get\_Next\_Selector\_Increment\_Value} returns the selector increment
  353. value when allocating multiple subsequent descriptors
  354. The function \var{allocate\_ldt\_descriptors} can allocate an array of
  355. contiguous descriptors, but only return the selector for the first. The
  356. value returned by this function can be used to calculate the selectors
  357. for subsequent descriptors in the array.
  358. {\em Notes:}
  359. \begin{itemize}
  360. \item Only works under real DPMI.
  361. \item the increment is always a power of 2.
  362. \end{itemize}
  363. }
  364. {None.}
  365. {\seef{AllocateLdtDescriptors}}
  366. \procedurel{get\_pm\_interrupt}{GetPmInterrupt}{(vector : byte;var intaddr : tseginfo)}
  367. {
  368. Returns the address of the current protected mode handler for the interrupt
  369. \var{vector}.}{None.}
  370. {\seep{SetPmInterrupt},\htmlref{tseginfo}{ty:tseginfo}}
  371. \functionl{get\_run\_mode}{GetRunMode}{}{word}{
  372. This function returns the mode which the extender is currently running.
  373. The function is mostly used to determine if DPMI is supported.
  374. }{None.}
  375. {\htmlref{rm}{co:rmmode}}
  376. Example :
  377. \begin{verbatim}
  378. uses
  379. go32;
  380. begin
  381. if get_run_mode=rm_dpmi then
  382. writeln('DPMI available')
  383. else
  384. writeln('No DPMI available');
  385. end.
  386. \end{verbatim}
  387. \functionl{Get\_Segment\_Base\_Address}{GetSegmentBaseAddress}{(Sel: word)}{Longint}
  388. {
  389. \var{Get\_Segment\_Base\_Address} returns the 32-bit linear base address
  390. from the LDT descriptor for the specified segment (\var{Sel}).
  391. {\em Notes:}
  392. \begin{itemize}
  393. \item Only works under real DPMI.
  394. \end{itemize}
  395. }
  396. {None.}
  397. {\seep{SetSegmentBaseAddress}}
  398. \begin{FPCList}
  399. \item[Example:]
  400. \begin{verbatim}
  401. uses go32;
  402. begin
  403. Writeln(get_segment_base_address(get_ds));
  404. end.
  405. \end{verbatim}
  406. \end{FPCList}
  407. \functionl{get\_ss}{GetSs}{word}{Returns the value of the SS
  408. register.}{None.}{\seef{GetDs},\seef{GetCs}}
  409. \functionl{Global\_Dos\_Alloc}{GlobalDosAlloc}{(Len : longint)}{longint}
  410. {\var{Global\_Dos\_Alloc}
  411. allocates a block of memory with length \var{Len} from the \dos memory pool,
  412. i.e. memory below the 1 MB boundary that is controlled by \dos.
  413. Such memory blocks are typically used to exchange data with real mode
  414. programs, TSRs, or device drivers.
  415. The function returns both the real mode segment base address of
  416. the block and one or more descriptors that can be used by protected mode
  417. applications to access the block.
  418. The high word is the selector to this block, and the low word the
  419. \dos real mode segment. The offset of this block is always zero.
  420. {\em Notes:}
  421. \begin{itemize}
  422. \item Should only used for temporary buffers to get real mode information
  423. (e.g. interrupts that need a data structure in ES:DI), because every
  424. single block needs an unique selector.
  425. \end{itemize}
  426. }{None.}{\seep{GlobalDosFree}}
  427. \begin{FPCList}
  428. \item[Example]
  429. \begin{verbatim}
  430. uses go32;
  431. procedure dosalloc (var selector : word;
  432. var segment : word;
  433. size : longint);
  434. var result : longint;
  435. begin
  436. result := global_dos_alloc(size);
  437. selector := word(result);
  438. segment := word(result shr 16);
  439. end;
  440. procedure dosfree(selector : word);
  441. begin
  442. global_dos_free(selector);
  443. end;
  444. var selector : word;
  445. segment : word;
  446. r : trealregs;
  447. begin
  448. fillchar(r, sizeof(r), 0);
  449. fillchar(any_record, sizeof(any_record), 0);
  450. dosalloc(selector, segment, sizeof(VBE_vgainfo));
  451. { allocate a real mode memory block }
  452. any_record.any_entry := 1000;
  453. dosmemput(segment, 0, any_record, sizeof(any_record));
  454. { copy the record to real mode memory }
  455. r.realeax := $0000;
  456. r.reales := segment; r.realedi := 0;
  457. realintr(IntNr, r); { do our interrupt }
  458. dosmemget(segment, 0, any_record, sizeof(any_record));
  459. { get the record from real mode memory }
  460. dosfree(selector); { free selector afterwards }
  461. end.
  462. \end{verbatim}
  463. \end{FPCList}
  464. \procedurel{Global\_Dos\_Free}{GlobalDosFree}{(Sel : word)}
  465. {var{Global\_Dos\_Free} frees a previously allocated \dos memory
  466. block, described by selector \var{Sel}.
  467. }
  468. {None.}
  469. {\seef{GlobalDosAlloc}}
  470. For an example, see \seef{GlobalDosAlloc}.
  471. \function{inportb}{(port : word)}{byte}{Reads a byte from the given I/O
  472. port.}{None.}{\seep{outportb},\seef{inportw},\seef{inportl}}
  473. \function{inportl}{(port : word)}{longint}{Reads a longint from the given I/O
  474. port.}{None.}{\seep{outportl},\seef{inportw},\seef{inportb}}
  475. \function{inportw}{(port : word)}{word}{Reads a word from the given I/O
  476. port.}{None.}{\seep{outportw},\seef{inportb},\seef{inportl}}
  477. \procedure{outportb}{(port : word;data : byte)}{Writes a byte to the
  478. specified port.}{None.}{\seef{inportb},\seep{outportw},\seep{outportl}}
  479. \procedure{outportl}{(port : word;data : longint)}{Writes a longint to the
  480. specified port.}{None.}{\seef{inportl},\seep{outportb},\seep{outportw}}
  481. \procedure{outportw}{(port : word;data : word)}{Writes a word to the
  482. specified port.}{None.}{\seef{inportw},\seep{outportb},\seep{outportl}}
  483. \procedure{realintr}{(intnr : word;var regs : trealregs)}{
  484. \textbf {NOTE: }This procedure works only in DPMI mode.}
  485. {None.}{}
  486. \procedurel{seg\_fillchar}{SegFillChar}{(seg : word;ofs : longint;count : longint;c :
  487. char)}
  488. {Fills a memory area specified by a 48 bit pointer with the given number
  489. of chars.
  490. \textbf {NOTE:} Be careful using this function in non-DPMI mode.
  491. }{None.}{\seep{SegFillWord}, \seep{SegMove}}
  492. \procedurel {seg\_fillword}{SegFillWord}{(seg : word;ofs : longint;count : longint;w :
  493. word)}{Fills a memory area specified by a 48 bit pointer with the given number
  494. of words.
  495. \textbf {NOTE:} Be careful using this function in non-DPMI mode.
  496. }{None.}{\seep{SegFillChar}, \seep{SegMove}}
  497. \functionl{Segment\_To\_Descriptor}{SegmentToDescriptor}{(Seg : Word)}{Word}
  498. {\var{Segment\_To\_Descriptor} Maps a real mode segment (paragraph) address
  499. (in \var{Seg}) onto an descriptor that can be used by a protected mode
  500. program to access the same memory.
  501. The function returns a selector to the DOS real-mode segment.
  502. {\em Notes:}
  503. \begin{itemize}
  504. \item Only works with real DPMI.
  505. \item The descriptors limit will be set to 64KB.
  506. \item multiple calls to this function with the same segment address will
  507. return the same selector.
  508. \item Descriptors created by this function can never be modified or freed.
  509. For this reason this function shouldn't be used too often. Programs
  510. which need to examine various real mode addresses using the same
  511. selector should use the function \var{allocate\_ldt\_descriptors} and change
  512. the base address as necessary.
  513. \end{itemize}
  514. }
  515. {None.}
  516. {}
  517. \begin{FPCList}
  518. \item[Example]
  519. \begin{verbatim}
  520. uses go32;
  521. var r : trealregs;
  522. VGAsel : word;
  523. begin
  524. r.realeax := $13; realintr($10, r);
  525. { set VGA mode 13h }
  526. VGASel := segment_to_descriptor($A000);
  527. {...}
  528. seg_fillchar(VGAsel, 100*320+6, 1, #15);
  529. { put a pixel at (6/100) in color 15 }
  530. readln;
  531. {...}
  532. r.realeax := $3; realintr($10, r);
  533. end.
  534. \end{verbatim}
  535. \end{FPCList}
  536. \procedurel{seg\_move}{SegMove}{(sseg : word;source : longint;dseg : word;dest : longint;count :
  537. longint)}
  538. {This procedure copies data when the source and destination are specified
  539. by 48 bit pointers. For example, this function is used by the DPMI version
  540. of \var{dosmemget} and \var{dosmemput}. }{The procedure checks only
  541. for overlapping if source selector equals the destination selector.
  542. Be also careful using this function in non-DPMI
  543. mode.}{\seep{SegFillWord},\seep{SegFillChar}}
  544. \functionl{Set\_Descriptor\_Access\_right}{SetDescriptorAccesRight}{(Des: word; W: word)}{Longint}
  545. {\var{Set\_Descriptor\_Access\_right} sets the access rights of a
  546. descriptor \var{Des}.}
  547. {None.}{seef{GetDescriptorAccesRight}}
  548. \procedurel{set\_pm\_interrupt}{SetPmInterrupt}{(vector : byte;const intaddr : tseginfo)}
  549. {Sets a new protected mode handler for the interrupt \var{vector}.}
  550. {None.}{\seep{GetPmInterrupt}, \htmlref{tseginfo}{ty:tseginfo}}
  551. \procedurel{Set\_Segment\_Base\_Address}{SetSegmentBaseAddress}
  552. {(var Des : word;Sel : longint)}
  553. {\var{{Set\_Segment\_Base\_Address}} sets the 32-bit linear base address
  554. of the descriptor \var{Des} for the specified selector \var{Sel}.
  555. {\em Notes:}
  556. \begin{itemize}
  557. \item only works under real DPMI
  558. \end{itemize}
  559. }
  560. {None.}
  561. { \seef{AllocateLdtDescriptors}, \seep{SetSegmentLimit}}
  562. For an example, see \seef{AllocateLdtDescriptors}.
  563. \procedurel{Set\_Segment\_Limit}{SetSegmentLimit}{(Des : word;Len : longint)}
  564. {\var{Set\_Segment\_Limit} sets the limit of the descriptor \var{Des}
  565. to the specified length \var{Len}
  566. {\em Notes:}
  567. \begin{itemize}
  568. \item Only works under real DPMI.
  569. \item The new limit is the byte length of the segment-1.
  570. \item Segment limits bigger than or equal to 1MB must be page aligned, they
  571. must have the lower 12 bits set.
  572. \end{itemize}
  573. }
  574. {None}
  575. { \seep{SetSegmentBaseAddress}, \seef{AllocateLdtDescriptors}}
  576. For an example, see \seef{AllocateLdtDescriptors}.