home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD Shareware Masterblend
/
cdsharewaremasterblend.iso
/
utils
/
mem-expa
/
xm286.asm
< prev
next >
Wrap
Assembly Source File
|
1989-03-21
|
13KB
|
528 lines
;**************************************************************************
;* * * * 286 LOADALL information * * *
;**************************************************************************
;* * Segment Descriptor Access Bytes
DEF_ACCESS EQU 92H
DEF_LIMIT EQU 0FFFFH
SEGREG_DESCRIPTOR STRUC
SEG_BASE_LO DW 0
SEG_BASE_HI DB 0
SEG_ACCESS DB DEF_ACCESS
SEG_LIMIT DW DEF_LIMIT
SEGREG_DESCRIPTOR ENDS
DTR_DESCRIPTOR STRUC
DTR_BASE DW ?
DB ?
DB 0
DTR_LIMIT DW ?
DTR_DESCRIPTOR ENDS
LODAL286 MACRO
DW 050Fh
ENDM
;*******************************************************************************
;
; MoveExtended286
; XMM Move Extended Memory Block for the 80286
;
; Copyright (c) 1988, Microsoft Corporation
;
; Entry:
; ES:BX Points to a MoveExtendedStruc
;
; Return:
; AX = 1 Success
; AX = 0 Failure
; Error Code in BL
;
; Registers Destroyed:
; Flags, CX, SI, DI, ES
;
; WARNING
; =======
;
; This routine enables interrupts and can be re-entered
;
; Notes:
; The case of copying from conventional to conventional memory
; is not treated specially in this example.
;
; History:
; Wed Jul 13 - AWG - Original version
;-------------------------------------------------------------------------------
ifndef XM286INCLUDED
public MoveExtended286
endif
MoveExtended286 proc near
assume cs:code, ds:code, es:nothing
sti ; Be nice
push bp ; Set up stack frame so we
mov bp, sp ; can have local variables
sub sp, 18 ; Space for local variables
Count = -4 ; Local DWORD for byte count
MEReturn = -6 ; Local WORD for return code
SrcHandle = -8
DstHandle = -10
SrcLinear = -14
DstLinear = -18
push bx
push dx
xor ax, ax
mov [bp.MEReturn], ax ; Assume success
mov [bp.SrcHandle], ax
mov [bp.DstHandle], ax
mov ax, word ptr es:[si.bCount] ; Pick up length specified
mov word ptr [bp.Count], ax
mov cx, word ptr es:[si.bCount+2]
mov word ptr [bp.Count+2], cx
or cx, ax
jcxz MEM2_Exit ; Exit immediately if zero
lea bx, [si.SourceHandle] ; Normalize Source
call GetLinear286 ; Linear address in DX:AX
jc short MEM2_SrcError ; Have Dest Error Code
mov word ptr [bp.SrcLinear], ax ; Save Linear address
mov word ptr [bp.SrcLinear+2], dx
mov [bp.SrcHandle], bx ; Save Handle for Unlock
lea bx, [si.DestHandle] ; Normalize Destination
call GetLinear286
jc short MEM2_Error
mov word ptr [bp.DstLinear], ax ; Save Linear address
mov word ptr [bp.DstLinear+2], dx
mov [bp.DstHandle], bx ; Save Handle for Unlock
shr word ptr [bp.Count+2], 1 ; Make word count
rcr word ptr [bp.Count], 1
jc short MEM2_InvCount ; Odd count not allowed
call LocalEnableA20 ; Enable A20 for LoadAll code
cmp ax, 1
jne short MEM2_Error
call DoLoadAll
call LocalDisableA20
cmp ax, 1
jne short MEM2_Error
MEM2_Exit:
mov bx, [bp.SrcHandle] ; Unlock Handles if necessary
or bx, bx
jz short NoSrcHandle
dec [bx.cLock] ; Unlock Source
NoSrcHandle:
mov bx, [bp.DstHandle]
or bx, bx
jz short NoDstHandle
dec [bx.cLock] ; Unlock Destination
NoDstHandle:
pop dx
pop bx
mov ax, 1
cmp word ptr [bp.MEReturn], 0
jz short MEM2_Success
dec ax
mov bl, byte ptr [bp.MEReturn]
MEM2_Success:
mov sp, bp ; Unwind stack
pop bp
ret
MEM2_SrcError:
cmp bl, ERR_LENINVALID ; Invalid count
je short MEM2_Error ; yes, no fiddle
sub bl, 2 ; Convert to Source error code
jmp short MEM2_Error
MEM2_InvCount:
mov bl, ERR_LENINVALID
MEM2_Error:
mov byte ptr [bp.MEReturn], bl ; Pass error code through
jmp short MEM2_Exit
;*******************************************************************************
;
; GetLinear286
; Convert Handle and Offset (or 0 and SEG:OFFSET) into Linear address
; Locks Handle if necessary
; Nested with MoveExtended286 to access local variables
;
; Entry:
; ES:BX Points to structure containing:
; Handle dw
; Offset dd
; [BP.Count] Count of bytes to move
;
; Return:
; BX Handle of block (0 if conventional)
; AX:DX Linear address
; CARRY => Error
; Error code in BL
;
; Registers Destroyed:
; Flags, CX, DI
;
;-------------------------------------------------------------------------------
GetLinear286 proc near
push si
cli ; NO INTERRUPTS
mov si, word ptr es:[bx+2] ; Offset from start of handle
mov di, word ptr es:[bx+4] ; in DI:SI
mov bx, word ptr es:[bx] ; Handle in bx
or bx, bx
jz short GL2_Conventional
test [bx.Flags], USEDFLAG ; Valid Handle?
jz short GL2_InvHandle
mov ax, [bx.Len] ; Length of Block
mov cx, 1024
mul cx ; mul is faster on the 286
sub ax, si
sbb dx, di ; DX:AX = max possible count
jc short GL2_InvOffset ; Base past end of block
sub ax, word ptr [bp.Count]
sbb dx, word ptr [bp.Count+2]
jc short GL2_InvCount ; Count too big
inc [bx.cLock] ; Lock the Handle
mov ax, [bx.Base]
mul cx
add ax, si ; Linear address
adc dx, di ; in DX:AX
GL2_OKExit:
clc
GL2_Exit:
sti
pop si
ret
GL2_Conventional:
mov ax, di ; Convert SEG:OFFSET into
mov dx, 16 ; 24 bit address
mul dx
add ax, si
adc dx, 0 ; DX:AX has base address
mov di, dx
mov si, ax
add si, word ptr [bp.Count] ; Get End of Block + 1 in DI:SI
adc di, word ptr [bp.Count+2]
cmp di, 010h ; 32-bit cmp
ja short GL2_InvCount
jb short GL2_OKExit
cmp si, 0FFF0h
jbe GL2_OKExit ; Must be < 10FFEFh + 2
GL2_InvCount:
mov bl, ERR_LENINVALID
jmp short GL2_Error
GL2_InvHandle:
mov bl, ERR_DHINVALID ; Dest handle invalid
jmp short GL2_Error
GL2_InvOffset:
mov bl, ERR_DOINVALID ; Dest Offset invalid
GL2_Error:
stc
jmp short GL2_Exit
GetLinear286 endp
;*******************************************************************************
;
; DoLoadAll
; Use 286 LoadAll for copy - see warnings below
; Nested within MoveExtended286
;
; Entry:
; [BP.Count] Word count for move
; [BP.SrcLinear] Linear address of the source
; [BP.DstLinear] Linear address of the destination
;
; Interrupts are ON
;
; Return:
; CARRY => Error
; Error code in BL
;
; Registers Destroyed:
; Flags, AX, BX, CX, DX, SI, DI
;
;-------------------------------------------------------------------------------
EVEN ;* WORD alignment for data
; Swap buffer for contents of 80:0
cwBuffer EQU 51
rgwSwap80 DW cwBuffer DUP (?)
; LOADALL data buffer placed at 80:0
;
LOADALL_TBL LABEL BYTE
DB 6 DUP(0)
LDSW DW ?
DB 14 DUP (0)
TR DW 0
LFLAGS DW 0 ; High 4 bits 0, Int off, Direction clear
; Trace clear. Rest don't care.
LIP DW OFFSET AFTER_LOADALL
LDT DW 0
LDSS DW 8000H
LSSS DW 80H
LCSS DW ?
LESS DW 8000H
LDI DW 0
LSI DW Offset rgwSwap80
LBP DW 0
LSP DW ?
LBX DW ?
LDX DW ?
LCX DW cwBuffer
LAX DW 80H
ESDES SEGREG_DESCRIPTOR <>
CSDES SEGREG_DESCRIPTOR <>
SSDES SEGREG_DESCRIPTOR <800H,0>
DSDES SEGREG_DESCRIPTOR <>
GDTDES DTR_DESCRIPTOR <>
LDTDES DTR_DESCRIPTOR <0D000H,0,0FFH,0088H>
IDTDES DTR_DESCRIPTOR <>
TSSDES DTR_DESCRIPTOR <0C000H,0,0FFH,0800H>
DescSaved dw -1 ; Flag for reentrancy
SaveDesc macro reg
push word ptr [reg] ; Save 3 word descriptor
push word ptr [reg+2] ; pointed to by reg
push word ptr [reg+4]
endm
RestoreDesc macro reg
pop word ptr [reg+4] ; Restore 3 word descriptor
pop word ptr [reg+2] ; pointed to by reg
pop word ptr [reg]
endm
NOP4 macro
sti ; Faster than nop
sti
sti
sti
endm
DoLoadAll proc near
assume cs:code, ds:code, es:nothing
cld ;* just to be sure
mov ax, word ptr [bp.SrcLinear] ; Create descriptors for source
mov dl, byte ptr [bp.SrcLinear+2] ; and destination of transfer
mov cx, word ptr [bp.DstLinear]
mov dh, byte ptr [bp.DstLinear+2]
xchg [DSDES].SEG_BASE_LO,ax ; Fill in table and pick up
xchg [DSDES].SEG_BASE_HI,dl ; old values
xchg [ESDES].SEG_BASE_LO,cx
xchg [ESDES].SEG_BASE_HI,dh
mov bx,Offset IDTDES
mov si,Offset GDTDES
inc [DescSaved]
jz short DLA_NoSave ; Don't save old values first time
push ax ; Save these so we can be re-entrant
push cx
push dx