Get State Save/Restore Addresses


When a program uses the raw mode switch services (see
function 0603H) or issues DOS calls from a hardware
interrupt handler, it will need to save the state of
the current task before changing modes. This service
returns the addresses of two procedures used to save the state of
the current task's registers. For example, the real
mode address is used to save the state of the protected
mode registers. The protected mode address is used to
save the state of the real mode registers. This can be
used to save the state of the alternate mode's
registers before they are modified by the mode switch
call. The current mode's registers can be saved by
simply pushing them on the stack.

Note: It is not necessary to call this service if
using the translation services 0300h, 0301h or 0302h.
It is provided for programs that use the raw mode
switch service.

To Call

AX = 0305h

Returns

If function was successful:
Carry flag is clear
AX = Size of buffer in bytes required to save state
BX:CX = Real mode address used to save/restore state
SI:(E)DI = Protected mode address used to save/restore
state

If function was not successful:
Carry flag is set

Parameters To State-Save Procedures

Execute a far call to the appropriate address (real or
pmode) with:
ES:(E)DI = Pointer to state-save buffer
AL = 0 to save state
AL = 1 to restore state

Programmer's Notes

o Some implementations of DPMI will not require the
state to be saved. In this case, the buffer size
returned will be zero. However, it is still valid
to call the addresses returned, although they will
just return without performing any useful
function.
o The save/restore functions will not modify any
registers.
o The address returned in BX:CX must only be called
in real mode. The address returned in SI:(E)DI
must only be called in protected mode.
o 16-bit programs should call the address returned
in SI:DI to save the real mode state. 32-bit
programs should call the address returned in
SI:EDI.


Example Code

The following code is a sample protected mode timer
interrupt handler that saves the state of the real mode
registers, issues DOS calls, and restores the state.
This code assumes that the Int 31h function 0305h has
been executed and that the call address and buffer size
have been saved in local variables.

Sample_Timer_Code:
pushf
call FAR PTR cs:[Next_Timer_Handler]
sti
;
; Save protected mode registers
;
push ds
push es
pusha
;
; Save real mode registers
;
mov ds, cs:[My_Local_DS]
mov ax, ss
mov es, ax
sub sp, [State_Save_Size]
mov di, sp
xor al, al
call [PM_Save_Restore_State]

;
; Raw mode switch here
;
.
.
.
;
; Restore real mode registers
;
mov ax, ss
mov es, ax
mov di, sp
mov al, 1
call [PM_Save_Restore_State]
add sp, [State_Save_Size]
;
; Restore protected mode registers and return
;
popa
pop es
pop ds

iret