1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603 |
- \chapter{The GO32 unit}
- \label{ch:go32unit}
- \FPCexampledir{go32ex}
- This chapter of the documentation describe the GO32 unit for the Free Pascal
- compiler under \dos. It was donated by Thomas Schatzl
- (tom\_at\[email protected]), for which my thanks.
- This unit was first written for \dos by Florian Kl"ampfl.
- This chapter is divided in four sections. The first two sections are an
- introduction to the GO32 unit. The third section lists the pre-defined
- constants, types and variables. The last section describes the functions
- which appear in the interface part of the GO32 unit.
- \section{Introduction}
- These docs contain information about the GO32 unit. Only the GO32V2 DPMI
- mode is discussed by me here due to the fact that new applications shouldn't
- be created with the older GO32V1 model. The go32v2 version is much more advanced and
- better. Additionally a lot of functions only work in DPMI mode anyway.
- I hope the following explanations and introductions aren't too confusing at
- all. If you notice an error or bug send it to the FPC mailing list or
- directly to me.
- So let's get started and happy and error free coding I wish you....
- Thomas Schatzl, 25. August 1998
- \section{Protected mode memory organization}
- \subsection{What is DPMI}
- The \dos Protected Mode Interface helps you with various aspects of protected
- mode programming. These are roughly divided into descriptor handling, access
- to \dos memory, management of interrupts and exceptions, calls to real mode
- functions and other stuff. Additionally it automatically provides swapping
- to disk for memory intensive applications.
- A DPMI host (either a Windows \dos box or CWSDPMI.EXE) provides these
- functions for your programs.
- \subsection{Selectors and descriptors}
- Descriptors are a bit like real mode segments; they describe (as the name
- implies) a memory area in protected mode. A descriptor contains information
- about segment length, its base address and the attributes of it (i.e. type,
- access rights, ...).
- These descriptors are stored internally in a so-called descriptor table,
- which is basically an array of such descriptors.
- Selectors are roughly an index into this table.
- Because these 'segments' can be up to 4 GB in size, 32 bits aren't
- sufficient anymore to describe a single memory location like in real mode.
- 48 bits are now needed to do this, a 32 bit address and a 16 bit sized
- selector. The GO32 unit provides the tseginfo record to store such a
- pointer.
- But due to the fact that most of the time data is stored and accessed in the
- \%ds selector, FPC assumes that all pointers point to a memory location of
- this selector. So a single pointer is still only 32 bits in size. This value
- represents the offset from the data segment base address to this memory
- location.
- \subsection{FPC specialities}
- The \%ds and \%es selector MUST always contain the same value or some system
- routines may crash when called. The \%fs selector is preloaded with the
- DOSMEMSELECTOR variable at startup, and it MUST be restored after use,
- because again FPC relys on this for some functions. Luckily we asm
- programmers can still use the \%gs selector for our own purposes, but for how
- long ?
- See also:
- % tseginfo, dosmemselector, \dos memory access,
- \seefl{get\_cs}{getcs},
- \seefl{get\_ds}{getds},
- \seefl{gett\_ss}{getss},
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{free\_ldt\_descriptor}{freeldtdescriptor},
- \seefl{segment\_to\_descriptor}{segmenttodescriptor},
- \seefl{get\_next\_selector\_increment\_value}{getnextselectorincrementvalue},
- \seefl{get\_segment\_base\_address}{getsegmentbaseaddress},
- \seefl{set\_segment\_base\_address}{setsegmentbaseaddress},
- \seefl{set\_segment\_limit}{setsegmentlimit},
- \seefl{create\_code\_segment\_alias\_descriptor}{createcodesegmentaliasdescriptor}
- \subsection{\dos memory access}
- \dos memory is accessed by the predefined \var{dosmemselector} selector;
- the GO32 unit additionally provides some functions to help you with standard tasks,
- like copying memory from heap to \dos memory and the likes. Because of this
- it is strongly recommened to use them, but you are still free to use the
- provided standard memory accessing functions which use 48 bit pointers. The
- third, but only thought for compatibility purposes, is using the
- \var{mem[]}-arrays. These arrays map the whole 1 Mb \dos space. They shouldn't be
- used within new programs.
- To convert a segment:offset real mode address to a protected mode linear
- address you have to multiply the segment by 16 and add its offset. This
- linear address can be used in combination with the DOSMEMSELECTOR variable.
- See also:
- \seep{dosmemget},
- \seepl{dosmemput}{dosmemput},
- \seepl{dosmemmove}{dosmemmove},
- \seepl{dosmemfillchar}{dosmemfillchar},
- \seepl{dosmemfillword}{dosmemfillword},
- mem[]-arrays,
- \seepl{seg\_move}{segmove},
- \seepl{seg\_fillchar}{segfillchar},
- \seepl{seg\_fillword}{segfillword}.
- \subsection{I/O port access}
- The I/O port access is done via the various \seef{inportb}, \seep{outportb}
- functions
- which are available. Additionally Free Pascal supports the Turbo Pascal
- PORT[]-arrays but it is by no means recommened to use them, because they're
- only for compatibility purposes.
- See also: \seep{outportb}, \seef{inportb}, PORT[]-arrays
- \subsection{Processor access}
- These are some functions to access various segment registers (\%cs, \%ds, \%ss)
- which makes your work a bit easier.
- See also: \seefl{get\_cs}{getcs}, \seefl{get\_ds}{getds},
- \seefl{get\_ss}{getss}
- \subsection{Interrupt redirection}
- Interrupts are program interruption requests, which in one or another way
- get to the processor; there's a distinction between software and hardware
- interrupts. The former are explicitely called by an 'int' instruction and
- are a bit comparable to normal functions. Hardware interrupts come from
- external devices like the keyboard or mouse. Functions that handle hardware
- interrupts are called handlers.
- \subsection{Handling interrupts with DPMI}
- The interrupt functions are real-mode procedures; they normally can't be
- called in protected mode without the risk of an protection fault. So the
- DPMI host creates an interrupt descriptor table for the application.
- Initially all software interrupts (except for int 31h, 2Fh and 21h function
- 4Ch) or external hardware interrupts are simply directed to a handler that
- reflects the interrupt in real-mode, i.e. the DPMI host's default handlers
- switch the CPU to real-mode, issue the interrupt and switch back to
- protected mode. The contents of general registers and flags are passed to
- the real mode handler and the modified registers and flags are returned to
- the protected mode handler. Segment registers and stack pointer are not
- passed between modes.
- \subsection{Protected mode interrupts vs. Real mode interrupts}
- As mentioned before, there's a distinction between real mode interrupts and
- protected mode interrupts; the latter are protected mode programs, while the
- former must be real mode programs. To call a protected mode interrupt
- handler, an assembly 'int' call must be issued, while the other is called
- via the realintr() or intr() function. Consequently, a real mode interrupt
- then must either reside in \dos memory (<1MB) or the application must
- allocate a real mode callback address via the get\_rm\_callback() function.
- \subsection{Creating own interrupt handlers}
- Interrupt redirection with FPC pascal is done via the set\_pm\_interrupt() for
- protected mode interrupts or via the set\_rm\_interrupt() for real mode
- interrupts.
- \subsection{Disabling interrupts}
- The GO32 unit provides the two procedures disable() and enable() to disable
- and enable all interrupts.
- \subsection{Hardware interrupts}
- Hardware interrupts are generated by hardware devices when something unusual
- happens; this could be a keypress or a mouse move or any other action. This
- is done to minimize CPU time, else the CPU would have to check all installed
- hardware for data in a big loop (this method is called 'polling') and this
- would take much time.
- A standard IBM-PC has two interrupt controllers, that are responsible for
- these hardware interrupts: both allow up to 8 different interrupt sources
- (IRQs, interrupt requests). The second controller is connected to the first
- through IRQ 2 for compatibility reasons, e.g. if controller 1 gets an IRQ 2,
- he hands the IRQ over to controller 2. Because of this up to 15 different
- hardware interrupt sources can be handled.
- IRQ 0 through IRQ 7 are mapped to interrupts 8h to Fh and the second
- controller (IRQ 8 to 15) is mapped to interrupt 70h to 77h.
- All of the code and data touched by these handlers MUST be locked (via the
- various locking functions) to avoid page faults at interrupt time. Because
- hardware interrupts are called (as in real mode) with interrupts disabled,
- the handler has to enable them before it returns to normal program
- execution. Additionally a hardware interrupt must send an EOI (end of
- interrupt) command to the responsible controller; this is acomplished by
- sending the value 20h to port 20h (for the first controller) or A0h (for the
- second controller).
- The following example shows how to redirect the keyboard interrupt.
- \FPCexample{keyclick}
- \subsection{Software interrupts}
- Ordinarily, a handler installed with
- \seefl{set\_pm\_interrupt}{setpminterrupt} only services software
- interrupts that are executed in protected mode; real mode software
- interrupts can be redirected by \seefl{set\_rm\_interrupt}{setrminterrupt}.
- See also \seefl{set\_rm\_interrupt}{setrminterrupt},
- \seefl{get\_rm\_interrupt}{getrminterrupt},
- \seefl{set\_pm\_interrupt}{setpminterrupt},
- \seefl{get\_pm\_interrupt}{getpminterrupt},
- \seefl{lock\_data}{lockdata},
- \seefl{lock\_code}{lockcode},
- \seep{enable},
- \seep{disable},
- \seepl{outportb}{outportb}
- Executing software interrupts
- Simply execute a realintr() call with the desired interrupt number and the
- supplied register data structure.
- But some of these interrupts require you to supply them a pointer to a
- buffer where they can store data to or obtain data from in memory. These
- interrupts are real mode functions and so they only can access the first Mb
- of linear address space, not FPC's data segment.
- For this reason FPC supplies a pre-initialized \dos memory location within
- the GO32 unit. This buffer is internally used for \dos functions too and so
- it's contents may change when calling other procedures. It's size can be
- obtained with \seefl{tb\_size}{tbsize} and it's linear address via
- \seefl{transfer\_buffer}{transferbuffer}.
- Another way is to allocate a completely new \dos memory area via the
- \seefl{global\_dos\_alloc}{globaldosalloc} function for your use and
- supply its real mode address.
- See also:
- \seefl{tb\_size}{tbsize},
- \seefl{transfer\_buffer}{transferbuffer}.
- \seefl{global\_dos\_alloc}{globaldosalloc},
- \seefl{global\_dos\_free}{globaldosfree},
- \seef{realintr}
- The following examples illustrate the use of software interrupts.
- \FPCexample{softint}
- \FPCexample{rmpmint}
- \subsection{Real mode callbacks}
- The callback mechanism can be thought of as the converse of calling a real
- mode procedure (i.e. interrupt), which allows your program to pass
- information to a real mode program, or obtain services from it in a manner
- that's transparent to the real mode program.
- In order to make a real mode callback available, you must first get the real
- mode callback address of your procedure and the selector and offset of a
- register data structure. This real mode callback address (this is a
- segment:offset address) can be passed to a real mode program via a software
- interrupt, a \dos memory block or any other convenient mechanism.
- When the real mode program calls the callback (via a far call), the DPMI
- host saves the registers contents in the supplied register data structure,
- switches into protected mode, and enters the callback routine with the
- following settings:
- \begin{itemize}
- \item interrupts disabled
- \item \var{\%CS:\%EIP} = 48 bit pointer specified in the original call to
- \seefl{get\_rm\_callback}{getrmcallback}
- \item \var{\%DS:\%ESI} = 48 bit pointer to to real mode \var{SS:SP}
- \item \var{\%ES:\%EDI} = 48 bit pointer of real mode register data
- structure.
- \item \var{\%SS:\%ESP} = locked protected mode stack
- \item All other registers undefined
- \end{itemize}
- The callback procedure can then extract its parameters from the real mode
- register data structure and/or copy parameters from the real mode stack to
- the protected mode stack. Recall that the segment register fields of the
- real mode register data structure contain segment or paragraph addresses
- that are not valid in protected mode. Far pointers passed in the real mode
- register data structure must be translated to virtual addresses before they
- can be used with a protected mode program.
- The callback procedure exits by executing an IRET with the address of the
- real mode register data structure in \var{\%ES:\%EDI}, passing information back to
- the real mode caller by modifying the contents of the real mode register
- data structure and/or manipulating the contents of the real mode stack. The
- callback procedure is responsible for setting the proper address for
- resumption of real mode execution into the real mode register data
- structure; typically, this is accomplished by extracting the return address
- from the real mode stack and placing it into the \var{\%CS:\%EIP} fields of the real
- mode register data structure. After the IRET, the DPMI host switches the CPU
- back into real mode, loads ALL registers with the contents of the real mode
- register data structure, and finally returns control to the real mode
- program.
- All variables and code touched by the callback procedure MUST be locked to
- prevent page faults.
- See also: \seefl{get\_rm\_callback}{getrmcallback},
- \seefl{free\_rm\_callback}{freermcallback},
- \seefl{lock\_code}{lockcode},
- \seefl{lock\_data}{lockdata}
- \section{Types, Variables and Constants}
- \subsection{Constants}
- \subsubsection{Constants returned by get\_run\_mode}
- Tells you under what memory environment (e.g. memory manager) the program
- currently runs.
- \begin{verbatim}
- rm_unknown = 0; { unknown }
- rm_raw = 1; { raw (without HIMEM) }
- rm_xms = 2; { XMS (for example with HIMEM, without EMM386) }
- rm_vcpi = 3; { VCPI (for example HIMEM and EMM386) }
- rm_dpmi = 4; { DPMI (for example \dos box or 386Max) }
- \end{verbatim}
- Note: GO32V2 {\em always} creates DPMI programs, so you need a suitable DPMI
- host like \file{CWSDPMI.EXE} or a Windows \dos box. So you don't need to check it,
- these constants are only useful in GO32V1 mode.
- \subsubsection{Processor flags constants}
- They are provided for a simple check with the flags identifier in the
- trealregs type. To check a single flag, simply do an AND operation with the
- flag you want to check. It's set if the result is the same as the flag
- value.
- \begin{verbatim}
- const carryflag = $001;
- parityflag = $004;
- auxcarryflag = $010;
- zeroflag = $040;
- signflag = $080;
- trapflag = $100;
- interruptflag = $200;
- directionflag = $400;
- overflowflag = $800;
- \end{verbatim}
- \subsection{Predefined types}
- \begin{verbatim}
- type tmeminfo = record
- available_memory : Longint;
- available_pages : Longint;
- available_lockable_pages : Longint;
- linear_space : Longint;
- unlocked_pages : Longint;
- available_physical_pages : Longint;
- total_physical_pages : Longint;
- free_linear_space : Longint;
- max_pages_in_paging_file : Longint;
- reserved : array[0..2] of Longint;
- end;
- \end{verbatim}
- Holds information about the memory allocation, etc.
- \begin{FPCtable}{ll}{Record description}
- Record entry & Description \\ \hline
- \var{available\_memory} & Largest available free block in bytes. \\
- \var{available\_pages} & Maximum unlocked page allocation in pages \\
- \var{available\_lockable\_pages} & Maximum locked page allocation in pages. \\
- \var{linear\_space} & Linear address space size in pages. \\
- \var{unlocked\_pages} & Total number of unlocked pages. \\
- \var{available\_physical\_pages} & Total number of free pages.\\
- \var{total\_physical\_pages} & Total number of physical pages. \\
- \var{free\_linear\_space} & Free linear address space in pages.\\
- \var{max\_pages\_in\_paging\_file} & Size of paging file/partition in
- pages. \\
- \end{FPCtable}
- NOTE: The value of a field is -1 (0ffffffffh) if the value is unknown, it's
- only guaranteed, that \var{available\_memory} contains a valid value.
- The size of the pages can be determined by the get\_page\_size() function.
- \begin{verbatim}
- type
- trealregs = record
- case Integer of
- 1: { 32-bit }
- (EDI, ESI, EBP, Res, EBX, EDX, ECX, EAX: Longint;
- Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word);
- 2: { 16-bit }
- (DI, DI2, SI, SI2, BP, BP2, R1, R2: Word;
- BX, BX2, DX, DX2, CX, CX2, AX, AX2: Word);
- 3: { 8-bit }
- (stuff: array[1..4] of Longint;
- BL, BH, BL2, BH2, DL, DH, DL2, DH2, CL,
- CH, CL2, CH2, AL, AH, AL2, AH2: Byte);
- 4: { Compat }
- (RealEDI, RealESI, RealEBP, RealRES, RealEBX,
- RealEDX, RealECX, RealEAX: Longint;
- RealFlags, RealES, RealDS, RealFS, RealGS,
- RealIP, RealCS, RealSP, RealSS: Word);
- end;
- registers = trealregs;
- \end{verbatim}
- These two types contain the data structure to pass register values to a
- interrupt handler or real mode callback.
- \begin{verbatim}
- type tseginfo = record
- offset : Pointer; segment : Word; end;
- \end{verbatim}
- This record is used to store a full 48-bit pointer. This may be either a
- protected mode selector:offset address or in real mode a segment:offset
- address, depending on application.
- See also: Selectors and descriptors, \dos memory access, Interrupt
- redirection
- \subsection{Variables.}
- \begin{verbatim}
- var dosmemselector : Word;
- \end{verbatim}
- Selector to the \dos memory. The whole \dos memory is automatically mapped to
- this single descriptor at startup. This selector is the recommened way to
- access \dos memory.
- \begin{verbatim}
- var int31error : Word;
- \end{verbatim}
- This variable holds the result of a DPMI interrupt call. Any nonzero value
- must be treated as a critical failure.
- \section{Functions and Procedures}
- \begin{functionl}{allocate\_ldt\_descriptors}{allocateldtdescriptors}
- \Declaration
- Function allocate\_ldt\_descriptors (count : Word) : Word;
- \Description
- Allocates a number of new descriptors.
- Parameters:
- \begin{description}
- \item[count:\ ] specifies the number of requested unique descriptors.
- \end{description}
- Return value: The base selector.
- Notes: The descriptors allocated must be initialized by the application with
- other function calls. This function returns descriptors with a limit and
- size value set to zero. If more than one descriptor was requested, the
- function returns a base selector referencing the first of a contiguous array
- of descriptors. The selector values for subsequent descriptors in the array
- can be calculated by adding the value returned by the
- \seefl{get\_next\_selector\_increment\_value}{getnextselectorincrementvalue}
- function.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{free\_ldt\_descriptor}{freeldtdescriptor},
- \seefl{get\_next\_selector\_increment\_value}{getnextselectorincrementvalue},
- \seefl{segment\_to\_descriptor}{segmenttodescriptor},
- \seefl{create\_code\_segment\_alias\_descriptor}{createcodesegmentaliasdescriptor},
- \seefl{set\_segment\_limit}{setsegmentlimit},
- \seefl{set\_segment\_base\_address}{setsegmentbaseaddress}
- \end{functionl}
- \FPCexample{seldes}
- \begin{functionl}{allocate\_memory\_block}{allocatememoryblock}
- \Declaration
- Function allocate\_memory\_block (size:Longint) : Longint;
- \Description
- Allocates a block of linear memory.
- Parameters:
- \begin{description}
- \item[size:\ ] Size of requested linear memory block in bytes.
- \end{description}
- Returned values: blockhandle - the memory handle to this memory block. Linear
- address of the requested memory.
- Notes: WARNING: According to my DPMI docs this function is not implemented
- correctly. Normally you should also get a blockhandle to this block after
- successful operation. This handle can then be used to free the memory block
- afterwards or use this handle for other purposes. Since the function isn't
- implemented correctly, and doesn't return a blockhandle, the block can't be
- deallocated and is hence unusuable !
- This function doesn't allocate any descriptors for this block, it's the
- applications resposibility to allocate and initialize for accessing this
- memory.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{free\_memory\_block}{freememoryblock}
- \end{functionl}
- \begin{procedure}{copyfromdos}
- \Declaration
- Procedure copyfromdos (var addr; len : Longint);
- \Description
- Copies data from the pre-allocated \dos memory transfer buffer to the heap.
- Parameters:
- \begin{description}
- \item[addr:\ ] data to copy to.
- \item[len:\ ] number of bytes to copy to heap.
- \end{description}
- Notes:
- Can only be used in conjunction with the \dos memory transfer buffer.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{tb\_size}{tbsize}, \seefl{transfer\_buffer}{transferbuffer},
- \seep{copytodos}
- \end{procedure}
- \begin{procedure}{copytodos}
- \Declaration
- Procedure copytodos (var addr; len : Longint);
- \Description
- Copies data from heap to the pre-allocated \dos memory buffer.
- Parameters:
- \begin{description}
- \item[addr:\ ] data to copy from.
- \item[len:\ ] number of bytes to copy to \dos memory buffer.
- \end{description}
- Notes: This function fails if you try to copy more bytes than the transfer
- buffer is in size. It can only be used in conjunction with the transfer
- buffer.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{tb\_size}{tbsize}, \seefl{transfer\_buffer}{transferbuffer},
- \seep{copyfromdos}
- \end{procedure}
- \begin{functionl}{create\_code\_segment\_alias\_descriptor}{createcodesegmentaliasdescriptor}
- \Declaration
- Function create\_code\_segment\_alias\_descriptor (seg : Word) : Word;
- \Description
- Creates a new descriptor that has the same base and limit as the specified
- descriptor.
- Parameters:
- \begin{description}
- \item[seg:\ ] Descriptor.
- \end{description}
- Return values: The data selector (alias).
- Notes: In effect, the function returns a copy of the descriptor. The
- descriptor alias returned by this function will not track changes to the
- original descriptor. In other words, if an alias is created with this
- function, and the base or limit of the original segment is then changed, the
- two descriptors will no longer map the same memory.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
-
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{set\_segment\_limit}{setsegmentlimit},
- \seefl{set\_segment\_base\_address}{setsegmentbaseaddress}
- \end{functionl}
- \begin{procedure}{disable}
- \Declaration
- Procedure disable ;
- \Description
- Disables all hardware interrupts by execution a CLI instruction.
- Parameters: None.
- \Errors
- None.
- \SeeAlso
- \seep{enable}
- \end{procedure}
- \begin{procedure}{dosmemfillchar}
- \Declaration
- Procedure dosmemfillchar (seg, ofs : Word; count : Longint; c : char);
- \Description
- Sets a region of \dos memory to a specific byte value.
- Parameters:
- \begin{description}
- \item[seg:\ ] real mode segment.
- \item[ofs:\ ] real mode offset.
- \item[count:\ ] number of bytes to set.
- \item[c:\ ] value to set memory to.
- \end{description}
- Notes: No range check is performed.
- \Errors
- None.
- \SeeAlso
-
- \seep{dosmemput},
- \seep{dosmemget},
- \seep{dosmemmove}{dosmemmove},
- \seepl{dosmemfillword}{dosmemfillword},
- \seepl{seg\_move}{segmove},
- \seepl{seg\_fillchar}{segfillchar},
- \seepl{seg\_fillword}{segfillword}
- \end{procedure}
- \FPCexample{textmess}
- \begin{procedure}{dosmemfillword}
- \Declaration
- Procedure dosmemfillword (seg,ofs : Word; count : Longint; w : Word);
- \Description
- Sets a region of \dos memory to a specific word value.
- Parameters:
- \begin{description}
- \item[seg:\ ] real mode segment.
- \item[ofs:\ ] real mode offset.
- \item[count:\ ] number of words to set.
- \item[w:\ ] value to set memory to.
- \end{description}
- Notes: No range check is performed.
- \Errors
- None.
- \SeeAlso
-
- \seep{dosmemput},
- \seepl{dosmemget}{dosmemget},
- \seepl{dosmemmove}{dosmemmove},
- \seepl{dosmemfillchar}{dosmemfillchar},
- \seepl{seg\_move}{segmove},
- \seepl{seg\_fillchar}{segfillchar},
- \seepl{seg\_fillword}{segfillword}
- \end{procedure}
- \begin{procedure}{dosmemget}
- \Declaration
- Procedure dosmemget (seg : Word; ofs : Word; var data; count : Longint);
- \Description
- Copies data from the \dos memory onto the heap.
- Parameters:
- \begin{description}
- \item[seg:\ ] source real mode segment.
- \item[ofs:\ ] source real mode offset.
- \item[data:\ ] destination.
- \item[count:\ ] number of bytes to copy.
- \end{description}
- Notes: No range checking is performed.
- \Errors
- None.
- \SeeAlso
- \seep{dosmemput},
- \seep{dosmemmove},
- \seep{dosmemfillchar},
- \seep{dosmemfillword},
- \seepl{seg\_move}{segmove},
- \seepl{seg\_fillchar}{segfillchar},
- \seepl{seg\_fillword}{segfillword}
- \end{procedure}
- For an example, see \seefl{global\_dos\_alloc}{globaldosalloc}.
- \begin{procedure}{dosmemmove}
- \Declaration
- Procedure dosmemmove (sseg, sofs, dseg, dofs : Word; count : Longint);
- \Description
- Copies count bytes of data between two \dos real mode memory locations.
- Parameters:
- \begin{description}
- \item[sseg:\ ] source real mode segment.
- \item[sofs:\ ] source real mode offset.
- \item[dseg:\ ] destination real mode segment.
- \item[dofs:\ ] destination real mode offset.
- \item[count:\ ] number of bytes to copy.
- \end{description}
- Notes: No range check is performed in any way.
- \Errors
- None.
- \SeeAlso
- \seep{dosmemput},
- \seep{dosmemget},
- \seep{dosmemfillchar},
- \seep{dosmemfillword}
- \seepl{seg\_move}{segmove},
- \seepl{seg\_fillchar}{segfillchar},
- \seepl{seg\_fillword}{segfillword}
- \end{procedure}
- For an example, see \seepl{seg\_fillchar}{segfillchar}.
- \begin{procedure}{dosmemput}
- \Declaration
- Procedure dosmemput (seg : Word; ofs : Word; var data; count : Longint);
- \Description
- Copies heap data to \dos real mode memory.
- Parameters:
- \begin{description}
- \item[seg:\ ] destination real mode segment.
- \item[ofs:\ ] destination real mode offset.
- \item[data:\ ] source.
- \item[count:\ ] number of bytes to copy.
- \end{description}
- Notes: No range checking is performed.
- \Errors
- None.
- \SeeAlso
- \seep{dosmemget},
- \seep{dosmemmove},
- \seep{dosmemfillchar},
- \seep{dosmemfillword},
- \seepl{seg\_move}{segmove},
- \seepl{seg\_fillchar}{segfillchar},
- \seepl{seg\_fillword}{segfillword}
- \end{procedure}
- For an example, see \seefl{global\_dos\_alloc}{globaldosalloc}.
- \begin{procedure}{enable}
- \Declaration
- Procedure enable ;
- \Description
- Enables all hardware interrupts by executing a STI instruction.
- Parameters: None.
- \Errors
- None.
- \SeeAlso
- \seep{disable}
- \end{procedure}
- \begin{functionl}{free\_ldt\_descriptor}{freeldtdescriptor}
- \Declaration
- Function free\_ldt\_descriptor (des : Word) : boolean;
- \Description
- Frees a previously allocated descriptor.
- Parameters:
- \begin{description}
- \item[des:\ ] The descriptor to be freed.
- \end{description}
- Return value: \var{True} if successful, \var{False} otherwise.
- Notes: After this call this selector is invalid and must not be used for any
- memory operations anymore. Each descriptor allocated with
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors} must be freed
- individually with this function,
- even if it was previously allocated as a part of a contiguous array of
- descriptors.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{get\_next\_selector\_increment\_value}{getnextselectorincrementvalue}
- \end{functionl}
- For an example, see
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors}.
- \begin{functionl}{free\_memory\_block}{freememoryblock}
- \Declaration
- Function free\_memory\_block (blockhandle :
- Longint) : boolean;
- \Description
- Frees a previously allocated memory block.
- Parameters:
- \begin{description}
- \item{blockhandle:} the handle to the memory area to free.
- \end{description}
- Return value: \var{True} if successful, \var{false} otherwise.
- Notes: Frees memory that was previously allocated with
- \seefl{allocate\_memory\_block}{allocatememoryblock} .
- This function doesn't free any descriptors mapped to this block,
- it's the application's responsibility.
- \Errors
- Check \var{int31error} variable.
- \SeeAlso
- \seefl{allocate\_memory\_block}{allocatememoryblock}
- \end{functionl}
- \begin{functionl}{free\_rm\_callback}{freermcallback}
- \Declaration
- Function free\_rm\_callback (var intaddr : tseginfo) : boolean;
- \Description
- Releases a real mode callback address that was previously allocated with the
- \seefl{get\_rm\_callback}{getrmcallback} function.
- Parameters:
- \begin{description}
- \item[intaddr:\ ] real mode address buffer returned by
- \seefl{get\_rm\_callback}{getrmcallback} .
- \end{description}
- Return values: \var{True} if successful, \var{False} if not
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{set\_rm\_interrupt}{setrminterrupt},
- \seefl{get\_rm\_callback}{getrmcallback}
- \end{functionl}
- For an example, see \seefl{get\_rm\_callback}{getrmcallback}.
- \begin{functionl}{get\_cs}{getcs}
- \Declaration
- Function get\_cs : Word;
- \Description
- Returns the cs selector.
- Parameters: None.
- Return values: The content of the cs segment register.
- \Errors
- None.
- \SeeAlso
- \seefl{get\_ds}{getds}, \seefl{get\_ss}{getss}
- \end{functionl}
- For an example, see \seefl{set\_pm\_interrupt}{setpminterrupt}.
- \begin{functionl}{get\_descriptor\_access\_rights}{getdescriptoraccessrights}
- \Declaration
- Function get\_descriptor\_access\_rights (d : Word) : Longint;
- \Description
- Gets the access rights of a descriptor.
- Parameters:
- \begin{description}
- \item{d} selector to descriptor.
- \end{description}
- Return value: Access rights bit field.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
-
- \seefl{set\_descriptor\_access\_rights}{setdescriptoraccessrights}
- \end{functionl}
- \begin{functionl}{get\_ds}{getds}
- \Declaration
- Function get\_ds : Word;
- \Description
- Returns the ds selector.
- Parameters: None.
- Return values: The content of the ds segment register.
- \Errors
- None.
- \SeeAlso
- \seefl{get\_cs}{getcs}, \seefl{get\_ss}{getss}
- \end{functionl}
- \begin{functionl}{get\_linear\_addr}{getlinearaddr}
- \Declaration
- Function get\_linear\_addr (phys\_addr : Longint; size : Longint) : Longint;
- \Description
- Converts a physical address into a linear address.
- Parameters:
- \begin{description}
- \item [phys\_addr:\ ] physical address of device.
- \item [size:\ ] Size of region to map in bytes.
- \end{description}
- Return value: Linear address that can be used to access the physical memory.
- Notes: It's the applications resposibility to allocate and set up a
- descriptor for access to the memory. This function shouldn't be used to map
- real mode addresses.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
-
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors}, \seefl{set\_segment\_limit}{setsegmentlimit},
- \seefl{set\_segment\_base\_address}{setsegmentbaseaddress}
- \end{functionl}
- \begin{functionl}{get\_meminfo}{getmeminfo}
- \Declaration
- Function get\_meminfo (var meminfo : tmeminfo) : boolean;
- \Description
- Returns information about the amount of available physical memory, linear
- address space, and disk space for page swapping.
- Parameters:
- \begin{description}
- \item[meminfo:\ ] buffer to fill memory information into.
- \end{description}
- Return values: Due to an implementation bug this function always returns
- \var{False}, but it always succeeds.
- Notes: Only the first field of the returned structure is guaranteed to
- contain a valid value. Any fields that are not supported by the DPMI host
- will be set by the host to \var{-1 (0FFFFFFFFH)} to indicate that the information
- is not available. The size of the pages used by the DPMI host can be
- obtained with the \seefl{get\_page\_size}{getpagesize} function.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{get\_page\_size}{getpagesize}
- \end{functionl}
- \FPCexample{meminfo}
- \begin{functionl}{get\_next\_selector\_increment\_value}{getnextselectorincrementvalue}
- \Declaration
- Function get\_next\_selector\_increment\_value : Word;
- \Description
- Returns the selector increment value when allocating multiple subsequent
- descriptors via \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors}.
- Parameters: None.
- Return value: Selector increment value.
- Notes: Because \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors} only returns the selector for the
- first descriptor and so the value returned by this function can be used to
- calculate the selectors for subsequent descriptors in the array.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{free\_ldt\_descriptor}{freeldtdescriptor}
- \end{functionl}
- \begin{functionl}{get\_page\_size}{getpagesize}
- \Declaration
- Function get\_page\_size : Longint;
- \Description
- Returns the size of a single memory page.
- Return value: Size of a single page in bytes.
- Notes: The returned size is typically 4096 bytes.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{get\_meminfo}{getmeminfo}
- \end{functionl}
- For an example, see \seefl{get\_meminfo}{getmeminfo}.
- \begin{functionl}{get\_pm\_interrupt}{getpminterrupt}
- \Declaration
- Function get\_pm\_interrupt (vector : byte; var intaddr : tseginfo) : boolean;
- \Description
- Returns the address of a current protected mode interrupt handler.
- Parameters:
- \begin{description}
- \item[vector:\ ] interrupt handler number you want the address to.
- \item[intaddr:\ ] buffer to store address.
- \end{description}
- Return values: \var{True} if successful, \var{False} if not.
- Notes: The returned address is a protected mode selector:offset address.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{set\_pm\_interrupt}{setpminterrupt},
- \seefl{set\_rm\_interrupt}{setrminterrupt}, \seefl{get\_rm\_interrupt}{getrminterrupt}
- \end{functionl}
- For an example, see \seefl{set\_pm\_interrupt}{setpminterrupt}.
- \begin{functionl}{get\_rm\_callback}{getrmcallback}
- \Declaration
- Function get\_rm\_callback (pm\_func : pointer; const reg : trealregs; var rmcb: tseginfo) : boolean;
- \Description
- Returns a unique real mode \var{segment:offset} address, known as a "real mode
- callback," that will transfer control from real mode to a protected mode
- procedure.
- Parameters:
- \begin{description}
- \item[pm\_func:\ ] pointer to the protected mode callback function.
- \item[reg:\ ] supplied registers structure.
- \item[rmcb:\ ] buffer to real mode address of callback function.
- \end{description}
- Return values: \var{True} if successful, otherwise \var{False}.
- Notes: Callback addresses obtained with this function can be passed by a
- protected mode program for example to an interrupt handler, device driver,
- or TSR, so that the real mode program can call procedures within the
- protected mode program or notify the protected mode program of an event. The
- contents of the supplied regs structure is not valid after function call,
- but only at the time of the actual callback.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{free\_rm\_callback}{freermcallback}
- \end{functionl}
- \FPCexample{callback}
- \begin{functionl}{get\_rm\_interrupt}{getrminterrupt}
- \Declaration
- Function get\_rm\_interrupt (vector : byte; var intaddr :
- tseginfo) : boolean;
- \Description
- Returns the contents of the current machine's real mode interrupt vector for
- the specified interrupt.
- Parameters:
- \begin{description}
- \item[vector:\ ] interrupt vector number.
- \item[intaddr:\ ] buffer to store real mode \var{segment:offset} address.
- \end{description}
- Return values: \var{True} if successful, \var{False} otherwise.
- Notes: The returned address is a real mode segment address, which isn't
- valid in protected mode.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{set\_rm\_interrupt}{setrminterrupt},
- \seefl{set\_pm\_interrupt}{setpminterrupt},
- \seefl{get\_pm\_interrupt}{getpminterrupt}
- \end{functionl}
- \begin{functionl}{get\_run\_mode}{getrunmode}
- \Declaration
- Function get\_run\_mode : Word;
- \Description
- Returns the current mode your application runs with.
- Return values: One of the constants used by this function.
- \Errors
- None.
- \SeeAlso
- constants returned by \seefl{get\_run\_mode}{getrunmode}
- \end{functionl}
- \FPCexample{getrunmd}
- \begin{functionl}{get\_segment\_base\_address}{getsegmentbaseaddress}
- \Declaration
- Function get\_segment\_base\_address
- (d : Word) : Longint;
- \Description
- Returns the 32-bit linear base address from the descriptor table for the
- specified segment.
- Parameters:
- \begin{description}
- \item[d:\ ] selector of the descriptor you want the base address of.
- \end{description}
- Return values: Linear base address of specified descriptor.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{set\_segment\_base\_address}{setsegmentbaseaddress},
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{set\_segment\_limit}{setsegmentlimit},
- \seefl{get\_segment\_limit}{getsegmentlimit}
- \end{functionl}
- For an example, see
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors}.
- \begin{functionl}{get\_segment\_limit}{getsegmentlimit}
- \Declaration
- Function get\_segment\_limit (d : Word) : Longint;
- \Description
- Returns a descriptors segment limit.
- Parameters:
- \begin{description}
- \item [d:\ ] selector.
- \end{description}
- Return value: Limit of the descriptor in bytes.
- \Errors
- Returns zero if descriptor is invalid.
- \SeeAlso
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{set\_segment\_limit}{setsegmentlimit},
- \seefl{set\_segment\_base\_address}{setsegmentbaseaddress},
- \seefl{get\_segment\_base\_address}{getsegmentbaseaddress},
- \end{functionl}
- \begin{functionl}{get\_ss}{getss}
- \Declaration
- Function get\_ss : Word;
- \Description
- Returns the ss selector.
- Parameters: None.
- Return values: The content of the ss segment register.
- \Errors
- None.
- \SeeAlso
- \seefl{get\_ds}{getds}, \seefl{get\_cs}{getcs}
- \end{functionl}
- \begin{functionl}{global\_dos\_alloc}{globaldosalloc}
- \Declaration
- Function global\_dos\_alloc (bytes : Longint) : Longint;
- \Description
- Allocates a block of \dos real mode memory.
- Parameters:
- \begin{description}
- \item [bytes:\ ] size of requested real mode memory.
- \end{description}
- Return values: The low word of the returned value contains the selector to
- the allocated \dos memory block, the high word the corresponding real mode
- segment value. The offset value is always zero.
- This function allocates memory from \dos memory pool, i.e. memory below the 1
- MB boundary that is controlled by \dos. Such memory blocks are typically used
- to exchange data with real mode programs, TSRs, or device drivers. The
- function returns both the real mode segment base address of the block and
- one descriptor that can be used by protected mode applications to access the
- block. This function should only used for temporary buffers to get real mode
- information (e.g. interrupts that need a data structure in ES:(E)DI),
- because every single block needs an unique selector. The returned selector
- should only be freed by a \seefl{global\_dos\_free}{globaldosfree} call.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{global\_dos\_free}{globaldosfree}
- \end{functionl}
- \FPCexample{buffer}
- \begin{functionl}{global\_dos\_free}{globaldosfree}
- \Declaration
- Function global\_dos\_free (selector :Word) : boolean;
- \Description
- Frees a previously allocated \dos memory block.
- Parameters:
- \begin{description}
- \item[selector:\ ] selector to the \dos memory block.
- \end{description}
- Return value: \var{True} if successful, \var{False} otherwise.
- Notes: The descriptor allocated for the memory block is automatically freed
- and hence invalid for further use. This function should only be used for
- memory allocated by \seefl{global\_dos\_alloc}{globaldosalloc}.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{global\_dos\_alloc}{globaldosalloc}
- \end{functionl}
- For an example, see \seefl{global\_dos\_alloc}{globaldosalloc}.
- \begin{function}{inportb}
- \Declaration
- Function inportb (port : Word) : byte;
- \Description
- Reads 1 byte from the selected I/O port.
- Parameters:
- \begin{description}
- \item[port:\ ] the I/O port number which is read.
- \end{description}
- Return values: Current I/O port value.
- \Errors
- None.
- \SeeAlso
- \seep{outportb}, \seef{inportw}, \seef{inportl}
- \end{function}
- \begin{function}{inportl}
- \Declaration
- Function inportl (port : Word) : Longint;
- \Description
- Reads 1 longint from the selected I/O port.
- Parameters:
- \begin{description}
- \item[port:\ ] the I/O port number which is read.
- \end{description}
- Return values: Current I/O port value.
- \Errors
- None.
- \SeeAlso
- \seep{outportb}, \seef{inportb}, \seef{inportw}
- \end{function}
- \begin{function}{inportw}
- \Declaration
- Function inportw (port : Word) : Word;
- \Description
- Reads 1 word from the selected I/O port.
- Parameters:
- \begin{description}
- \item[port:\ ] the I/O port number which is read.
- \end{description}
- Return values: Current I/O port value.
- \Errors
- None.
- \SeeAlso
- \seep{outportw} \seef{inportb}, \seef{inportl}
- \end{function}
- \begin{functionl}{lock\_code}{lockcode}
- \Declaration
- Function lock\_code (functionaddr : pointer; size : Longint) : boolean;
- \Description
- Locks a memory range which is in the code segment selector.
- Parameters:
- \begin{description}
- \item[functionaddr:\ ] address of the function to be locked.
- \item[size:\ ] size in bytes to be locked.
- \end{description}
- Return values: \var{True} if successful, \var{False} otherwise.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
-
- \seefl{lock\_linear\_region}{locklinearregion},
- \seefl{lock\_data}{lockdata},
- \seefl{unlock\_linear\_region}{unlocklinearregion},
- \seefl{unlock\_data}{unlockdata},
- \seefl{unlock\_code}{unlockcode}
- \end{functionl}
- For an example, see \seefl{get\_rm\_callback}{getrmcallback}.
- \begin{functionl}{lock\_data}{lockdata}
- \Declaration
- Function lock\_data (var data; size : Longint) : boolean;
- \Description
- Locks a memory range which resides in the data segment selector.
- Parameters:
- \begin{description}
- \item[data:\ ] address of data to be locked.
- \item[size:\ ] length of data to be locked.
- \end{description}
- Return values: \var{True} if successful, \var{False} otherwise.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{lock\_linear\_region}{locklinearregion},
- \seefl{lock\_code}{lockcode},
- \seefl{unlock\_linear\_region}{unlocklinearregion},
- \seefl{unlock\_data}{unlockdata},
- \seefl{unlock\_code}{unlockcode}
- \end{functionl}
- For an example, see \seefl{get\_rm\_callback}{getrmcallback}.
- \begin{functionl}{lock\_linear\_region}{locklinearregion}
- \Declaration
- Function lock\_linear\_region (linearaddr, size : Longint) : boolean;
- \Description
- Locks a memory region to prevent swapping of it.
- Parameters:
- \begin{description}
- \item[linearaddr:\ ] the linear address of the memory are to be locked.
- \item[size:\ ] size in bytes to be locked.
- \end{description}
- Return value: \var{True} if successful, False otherwise.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{lock\_data}{lockdata},
- \seefl{lock\_code}{lockcode},
- \seefl{unlock\_linear\_region}{unlocklinearregion},
- \seefl{unlock\_data}{unlockdata},
- \seefl{unlock\_code}{unlockcode}
- \end{functionl}
- \begin{procedure}{outportb}
- \Declaration
- Procedure outportb (port : Word; data : byte);
- \Description
- Sends 1 byte of data to the specified I/O port.
- Parameters:
- \begin{description}
- \item[port:\ ] the I/O port number to send data to.
- \item[data:\ ] value sent to I/O port.
- \end{description}
- Return values: None.
- \Errors
- None.
- \SeeAlso
- \seef{inportb}, \seep{outportl}, \seep{outportw}
- \end{procedure}
- \FPCexample{outport}
- \begin{procedure}{outportl}
- \Declaration
- Procedure outportl (port : Word; data : Longint);
- \Description
- Sends 1 longint of data to the specified I/O port.
- Parameters:
- \begin{description}
- \item[port:\ ] the I/O port number to send data to.
- \item[data:\ ] value sent to I/O port.
- \end{description}
- Return values: None.
- \Errors
- None.
- \SeeAlso
- \seef{inportl}, \seep{outportw}, \seep{outportb}
- \end{procedure}
- For an example, see \seep{outportb}.
- \begin{procedure}{outportw}
- \Declaration
- Procedure outportw (port : Word; data : Word);
- \Description
- Sends 1 word of data to the specified I/O port.
- Parameters:
- \begin{description}
- \item[port:\ ] the I/O port number to send data to.
- \item[data:\ ] value sent to I/O port.
- \end{description}
- Return values: None.
- \Errors
- None.
- \SeeAlso
- \seef{inportw}, \seep{outportl}, \seep{outportb}
- \end{procedure}
- For an example, see \seep{outportb}.
- \begin{function}{realintr}
- \Declaration
- Function realintr (intnr: Word; var regs : trealregs) : boolean;
- \Description
- Simulates an interrupt in real mode.
- Parameters:
- \begin{description}
- \item[intnr:\ ] interrupt number to issue in real mode.
- \item[regs:\ ] registers data structure.
- \end{description}
- Return values: The supplied registers data structure contains the values
- that were returned by the real mode interrupt. \var{True} if successful, \var{False} if
- not.
- Notes: The function transfers control to the address specified by the real
- mode interrupt vector of intnr. The real mode handler must return by
- executing an IRET.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \end{function}
- \FPCexample{flags}
- \begin{procedurel}{seg\_fillchar}{segfillchar}
- \Declaration
- Procedure seg\_fillchar (seg : Word; ofs : Longint; count : Longint; c : char);
- \Description
- Sets a memory area to a specific value.
- Parameters:
- \begin{description}
- \item[seg:\ ] selector to memory area.
- \item[ofs:\ ] offset to memory.
- \item[count:\ ] number of bytes to set.
- \item[c:\ ] byte data which is set.
- \end{description}
- Return values: None.
- Notes: No range check is done in any way.
- \Errors
- None.
- \SeeAlso
- \seepl{seg\_move}{segmove},
- \seepl{seg\_fillword}{segfillword},
- \seepl{dosmemfillchar}{dosmemfillchar},
- \seepl{dosmemfillword}{dosmemfillword},
- \seepl{dosmemget}{dosmemget},
- \seepl{dosmemput}{dosmemput},
- \seepl{dosmemmove}{dosmemmove}
- \end{procedurel}
- \FPCexample{vgasel}
- \begin{procedurel}{seg\_fillword}{segfillword}
- \Declaration
- Procedure seg\_fillword (seg : Word; ofs : Longint; count : Longint; w :Word);
- \Description
- Sets a memory area to a specific value.
- Parameters:
- \begin{description}
- \item[seg:\ ] selector to memory area.
- \item[ofs:\ ] offset to memory.
- \item[count:\ ] number of words to set.
- \item[w:\ ] word data which is set.
- \end{description}
- Return values: None.
- Notes: No range check is done in any way.
- \Errors
- None.
- \SeeAlso
-
- \seepl{seg\_move}{segmove},
- \seepl{seg\_fillchar}{segfillchar},
- \seepl{dosmemfillchar}{dosmemfillchar},
- \seepl{dosmemfillword}{dosmemfillword},
- \seepl{dosmemget}{dosmemget},
- \seepl{dosmemput}{dosmemput},
- \seepl{dosmemmove}{dosmemmove}
- \end{procedurel}
- For an example, see
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors}.
- \begin{functionl}{segment\_to\_descriptor}{segmenttodescriptor}
- \Declaration
- Function segment\_to\_descriptor (seg : Word) : Word;
- \Description
- Maps a real mode segment (paragraph) address onto an descriptor that can be
- used by a protected mode program to access the same memory.
- Parameters:
- \begin{description}
- \item [seg:\ ] the real mode segment you want the descriptor to.
- \end{description}
- Return values: Descriptor to real mode segment address.
- Notes: The returned descriptors limit will be set to 64 kB. Multiple calls
- to this function with the same segment address will return the same
- selector. Descriptors created by this function can never be modified or
- freed. Programs which need to examine various real mode addresses using the
- same selector should use the function
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors} and change
- the base address as necessary.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{free\_ldt\_descriptor}{freeldtdescriptor},
- \seefl{set\_segment\_base\_address}{setsegmentbaseaddress}
- \end{functionl}
- For an example, see \seepl{seg\_fillchar}{segfillchar}.
- \begin{procedurel}{seg\_move}{segmove}
- \Declaration
- Procedure seg\_move (sseg : Word; source : Longint; dseg : Word; dest :
- Longint; count : Longint);
- \Description
- Copies data between two memory locations.
- Parameters:
- \begin{description}
- \item[sseg:\ ] source selector.
- \item[source:\ ] source offset.
- \item[dseg:\ ] destination selector.
- \item[dest:\ ] destination offset.
- \item[count:\ ] size in bytes to copy.
- \end{description}
- Return values: None.
- Notes: Overlapping is only checked if the source selector is equal to the
- destination selector. No range check is done.
- \Errors
- None.
- \SeeAlso
-
- \seepl{seg\_fillchar}{segfillchar},
- \seepl{seg\_fillword}{segfillword},
- \seepl{dosmemfillchar}{dosmemfillchar},
- \seepl{dosmemfillword}{dosmemfillword},
- \seepl{dosmemget}{dosmemget},
- \seepl{dosmemput}{dosmemput},
- \seepl{dosmemmove}{dosmemmove}
- \end{procedurel}
- For an example, see
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors}.
- \begin{functionl}{set\_descriptor\_access\_rights}{setdescriptoraccessrights}
- \Declaration
- Function set\_descriptor\_access\_rights (d : Word; w : Word) : Longint;
- \Description
- Sets the access rights of a descriptor.
- Parameters:
- \begin{description}
- \item[d:\ ] selector.
- \item[w:\ ] new descriptor access rights.
- \end{description}
- Return values: This function doesn't return anything useful.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{get\_descriptor\_access\_rights}{getdescriptoraccessrights}
- \end{functionl}
- \begin{functionl}{set\_pm\_interrupt}{setpminterrupt}
- \Declaration
- Function set\_pm\_interrupt (vector : byte; const intaddr : tseginfo) : boolean;
- \Description
- Sets the address of the protected mode handler for an interrupt.
- Parameters:
- \begin{description}
- \item[vector:\ ] number of protected mode interrupt to set.
- \item[intaddr:\ ] selector:offset address to the interrupt vector.
- \end{description}
- Return values: \var{True} if successful, \var{False} otherwise.
- Notes: The address supplied must be a valid \var{selector:offset}
- protected mode address.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{get\_pm\_interrupt}{getpminterrupt},
- \seefl{set\_rm\_interrupt}{setrminterrupt},
- \seefl{get\_rm\_interrupt}{getrminterrupt}
- \end{functionl}
- \FPCexample{intpm}
- \begin{functionl}{set\_rm\_interrupt}{setrminterrupt}
- \Declaration
- Function set\_rm\_interrupt (vector : byte; const intaddr :
- tseginfo) : boolean;
- \Description
- Sets a real mode interrupt handler.
- Parameters:
- \begin{description}
- \item[vector:\ ] the interrupt vector number to set.
- \item[intaddr:\ ] address of new interrupt vector.
- \end{description}
- Return values: \var{True} if successful, otherwise \var{False}.
- Notes: The address supplied MUST be a real mode segment address, not a
- \var{selector:offset} address. So the interrupt handler must either reside in \dos
- memory (below 1 Mb boundary) or the application must allocate a real mode
- callback address with \seefl{get\_rm\_callback}{getrmcallback}.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
-
- \seefl{get\_rm\_interrupt}{getrminterrupt},
- \seefl{set\_pm\_interrupt}{setpminterrupt}, \seefl{get\_pm\_interrupt}{getpminterrupt},
- \seefl{get\_rm\_callback}{getrmcallback}
- \end{functionl}
- \begin{functionl}{set\_segment\_base\_address}{setsegmentbaseaddress}
- \Declaration
- Function set\_segment\_base\_address (d : Word; s : Longint) : boolean;
- \Description
- Sets the 32-bit linear base address of a descriptor.
- Parameters:
- \begin{description}
- \item[d:\ ] selector.
- \item[s:\ ] new base address of the descriptor.
- \end{description}
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{get\_segment\_base\_address}{getsegmentbaseaddress},
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{set\_segment\_limit}{setsegmentlimit},
- \seefl{get\_segment\_base\_address}{getsegmentbaseaddress},
- \seefl{get\_segment\_limit}{getsegmentlimit}
- \end{functionl}
- \begin{functionl}{set\_segment\_limit}{setsegmentlimit}
- \Declaration
- Function set\_segment\_limit (d : Word; s : Longint) : boolean;
- \Description
- Sets the limit of a descriptor.
- Parameters:
- \begin{description}
- \item[d:\ ] selector.
- \item[s:\ ] new limit of the descriptor.
- \end{description}
- Return values: Returns \var{True} if successful, else \var{False}.
- Notes: The new limit specified must be the byte length of the segment - 1.
- Segment limits bigger than or equal to 1MB must be page aligned, they must
- have the lower 12 bits set.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors},
- \seefl{set\_segment\_base\_address}{setsegmentbaseaddress},
- \seefl{get\_segment\_limit}{getsegmentlimit},
- \seefl{set\_segment\_limit}{setsegmentlimit}
- \end{functionl}
- For an example, see
- \seefl{allocate\_ldt\_descriptors}{allocateldtdescriptors}.
- \begin{functionl}{tb\_size}{tbsize}
- \Declaration
- Function tb\_size : Longint;
- \Description
- Returns the size of the pre-allocated \dos memory buffer.
- Parameters: None.
- Return values: The size of the pre-allocated \dos memory buffer.
- Notes:
- This block always seems to be 16k in size, but don't rely on this.
- \Errors
- None.
- \SeeAlso
- \seefl{transfer\_buffer}{transferbuffer}, \seep{copyfromdos}
- \seep{copytodos}
- \end{functionl}
- \begin{functionl}{transfer\_buffer}{transferbuffer}
- \Declaration
- Function transfer\_buffer : Longint;
- \Description
- \var{transfer\_buffer} returns the offset of the transfer buffer.
- \Errors
- None.
- \SeeAlso
- \seefl{tb\_size}{tbsize}
- \end{functionl}
- \begin{functionl}{unlock\_code}{unlockcode}
- \Declaration
- Function unlock\_code (functionaddr : pointer; size : Longint) : boolean;
- \Description
- Unlocks a memory range which resides in the code segment selector.
- Parameters:
- \begin{description}
- \item[functionaddr:\ ] address of function to be unlocked.
- \item[size:\ ] size bytes to be unlocked.
- \end{description}
- Return value: \var{True} if successful, \var{False} otherwise.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{unlock\_linear\_region}{unlocklinearregion},
- \seefl{unlock\_data}{unlockdata},
- \seefl{lock\_linear\_region}{locklinearregion},
- \seefl{lock\_data}{lockdata},
- \seefl{lock\_code}{lockcode}
- \end{functionl}
- For an example, see \seefl{get\_rm\_callback}{getrmcallback}.
- \begin{functionl}{unlock\_data}{unlockdata}
- \Declaration
- Function unlock\_data (var data; size : Longint) : boolean;
- \Description
- Unlocks a memory range which resides in the data segment selector.
- Paramters:
- \begin{description}
- \item[data:\ ] address of memory to be unlocked.
- \item[size:\ ] size bytes to be unlocked.
- \end{description}
- Return values: \var{True} if successful, \var{False} otherwise.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{unlock\_linear\_region}{unlocklinearregion},
- \seefl{unlock\_code}{unlockcode},
- \seefl{lock\_linear\_region}{locklinearregion},
- \seefl{lock\_data}{lockdata},
- \seefl{lock\_code}{lockcode}
- \end{functionl}
- For an example, see \seefl{get\_rm\_callback}{getrmcallback}.
- \begin{functionl}{unlock\_linear\_region}{unlocklinearregion}
- \Declaration
- Function unlock\_linear\_region (linearaddr, size : Longint) : boolean;
- \Description
- Unlocks a previously locked linear region range to allow it to be swapped
- out again if needed.
- Parameters:
- \begin{description}
- \item[linearaddr:\ ] linear address of the memory to be unlocked.
- \item[size:\ ] size bytes to be unlocked.
- \end{description}
- Return values: \var{True} if successful, \var{False} otherwise.
- \Errors
- Check the \var{int31error} variable.
- \SeeAlso
- \seefl{unlock\_data}{unlockdata},
- \seefl{unlock\_code}{unlockcode},
- \seefl{lock\_linear\_region}{locklinearregion},
- \seefl{lock\_data}{lockdata},
- \seefl{lock\_code}{lockcode}
- \end{functionl}
|