From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/DEV/XMA2EMS/LIM40B.INC | 3468 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 3468 insertions(+) create mode 100644 v4.0/src/DEV/XMA2EMS/LIM40B.INC (limited to 'v4.0/src/DEV/XMA2EMS/LIM40B.INC') diff --git a/v4.0/src/DEV/XMA2EMS/LIM40B.INC b/v4.0/src/DEV/XMA2EMS/LIM40B.INC new file mode 100644 index 0000000..1e7683f --- /dev/null +++ b/v4.0/src/DEV/XMA2EMS/LIM40B.INC @@ -0,0 +1,3468 @@ + + page +;========================================================================= +; This module contains all the EQU's, STRUC's, data, and routines necessary +; for LIMDMS.INC. +; This module is to be INCLUDE'd as part of LIMDMS.INC. +; +;========================================================================= + +;========================================================================= +;========== Begin EQUate Definitions ===================================== +;========================================================================= + +AAJ_Option_Max equ 1h ;max option value ;an000; dms; +AAJ_Segment equ 1h ;segment request value ;an000; dms; +AAJ_No_Pages_To_Map equ 0h ;0 page map request ;an000; dms; + +MAC_Stack_Status_Request equ 02h ;stack size request ;an000; dms; + +ER_Conv_Memory equ 00h ;conv. memory request ;an000; dms; +ER_EMS_Memory equ 01h ;EMS memory request ;an000; dms; +EMS_Page_Size_In_Bytes equ (16*1024)-1 ;page size in bytes ;an000; dms; +ER_Max_Type equ 01h ;max type possible ;an000; dms; +ER_Max_Function equ 01h ;max function possible ;an000; dms; +ER_Move equ 00h ;move data ;an000; dms; +ER_Exchange equ 01h ;exchange data ;an000; dms; +ER_EMS_Page_FE equ 0FEh ;phys. page FEh ;an000; dms; +ER_EMS_Page_FF equ 0FFh ;phys. page FFh ;an000; dms; +ER_Dest_EMS_Memory equ 01h ;bit 0 set ;an000; dms; +ER_Source_EMS_Memory equ 02h ;bit 1 set ;an000; dms; +ER_Up equ 00h ;signal forward move ;an000; dms; +ER_Down equ 0ffh ;signal reverse move +ER_10H equ 10h ;equ for 10h ;an000; dms; + +AR_Sub_Max equ 01h ;5ah max. sub functions ;an000; dms; + +;========================================================================= +;========== End EQUate Definitions ======================================= +;========================================================================= + + page +;========================================================================= +;========== Begin STRUC Definitions ====================================== +;========================================================================= + +Log_Phys_Map_Struc struc ;page structure ;an000; dms; + + Log_Page_Number dw ? ;logical page number ;an000; dms; + Phys_Page_Number_Seg dw ? ;physical page or seg ;an000; dms; + ; determined by AL +Log_Phys_Map_Struc ends + + +Map_And_Jump_Struc struc ;carries jump info. ;an000; dms; + + Target_Address dd ? ;jump address ;an000; dms; + Log_Phys_Map_Len db ? ;entry count in ;an000; dms; + ; Log_Phys_Map_Struct + Log_Phys_Map_Ptr dd ? ;Log_Phys_Map_Struct ptr;an000; dms; + +Map_And_Jump_Struc ends ;an000; dms; + + +Map_And_Call_Struc struc ;carries jump info. ;an000; dms; + + MAC_Target_Address dd ? ;jump address ;an000; dms; + MAC_New_Page_Map_Len db ? ;entry count in ;an000; dms; + ; Log_Phys_Map_Struct + ; for new map scheme + MAC_New_Page_Map_Ptr dd ? ;Log_Phys_Map_Struc ptr ;an000; dms; + ; for new map scheme + MAC_Old_Page_Map_Len db ? ;entry count in ;an000; dms; + ; Log_Phys_Map_Struc + ; for old map scheme + MAC_Old_Page_Map_Ptr dd ? ;Log_Phys_Map_Struc ptr ;an000; dms; + ; for old map scheme + MAC_Reserved dw 4 DUP (?) ;Used to restore map ;an000; dms; + ; context + +Map_And_Call_Struc ends ;an000; dms; + + +Move_Source_Dest_Struc struc ;structure for move ;an000; dms; + + Region_Length_Low_Word dw ? ; + Region_Length_High_Word dw ? ;length of region ;an000; dms; + + Source_Memory_Type db ? ;conv/EMS ;an000; dms; + Source_Handle dw ? ;handle if EMS, else 0 ;an000; dms; + Source_Initial_Offset dw ? ;offset of source region;an000; dms; + Source_Initial_Seg_Page dw ? ;logical page if EMS ;an000; dms; + ; seg if conv. + Dest_Memory_Type db ? ;conv/EMS ;an000; dms; + Dest_Handle dw ? ;handle if EMS, else 0 ;an000; dms; + Dest_Initial_Offset dw ? ;offset of source region;an000; dms; + Dest_Initial_Seg_Page dw ? ;logical page if EMS ;an000; dms; + ; seg if conv. +Move_Source_Dest_Struc ends ;end structure ;an000; dms; + +Realloc_Struc Struc ;BP addressible struc ;an000; dms; + + Realloc_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms; + Realloc_Alloc_Byte db ? ;reserved ;an000; dms; + Realloc_Reg_DI dw ? ;reserved ;an000; dms; + Realloc_Handle dw ? ;handle ;an000; dms; + + Realloc_Page_Count dw ? ;new page count ;an000; dms; + Realloc_Page_Alloc dw ? ;pages to be allocated ;an000; dms; + Realloc_Page_Dealloc dw ? ;pages to be deallocated ;an000; dms; + + Realloc_Handle_Xref_Index dw ? ;index to end of handle table ;an000; dms; + Realloc_LookUp_Index dw ? ;index to applicable handle ;an000; dms; + Realloc_Mult dw ? ;multiplier ;an000; dms; + +Realloc_Struc Ends ;end structure ;an000; dms; + +AAJ_Struc Struc ;BP addressible struc ;an000; dms; + + AAJ_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms; + AAJ_Xref_Pages dw ? ;save logical page count ;an000; dms; + AAJ_Handle dw ? ;saved handle ;an000; dms; + AAJ_Option db ? ;saved selector state ;an000; dms; + AAJ_LookUp_Index dw ? ;save index ;an000; dms; + AAJ_Mult dw ? ;multiplier ;an000; dms; + +AAJ_Struc Ends ;end structure ;an000; dms; + +MAC_Struc Struc ;BP addressible struc ;an000; dms; + + MAC_Reserved_Area db size Instance_Entry_Struc dup (?) ;an000; dms; + MAC_LookUp_Index dw ? ;save index ;an000; dms; + MAC_Xref_Pages dw ? ;save logical page count ;an000; dms; + MAC_Option db ? ;saved selector state ;an000; dms; + + EMS_Reg_ES dw ? ;ES reg ;an000; dms; + EMS_Reg_DS dw ? ;DS reg ;an000; dms; + EMS_Reg_FL dw ? ;FL reg ;an000; dms; + EMS_Reg_SI dw ? ;SI reg ;an000; dms; + EMS_Reg_DI dw ? ;DI reg ;an000; dms; + EMS_Reg_DX dw ? ;DX reg ;an000; dms; + EMS_Reg_CX dw ? ;CX reg ;an000; dms; + EMS_Reg_BX dw ? ;BX reg ;an000; dms; + + MAC_M_C_Data db size Map_And_Call_Struc dup (?) ;an000; dms; + MAC_M_C_Log db size Log_Phys_Map_Struc*Map_Count_Def dup (?) ;an000; dms; + MAC_Map_Table db size Mappable_Phys_Page_Struct*Map_Count_Def dup (?) ;an000; dms; + MAC_Mult dw ? ;multiplier ;an000; dms; + +MAC_Struc Ends ;end structure ;an000; dms; + + +ER_Struc Struc ;BP addressible struc ;an000; dms; + + ER_Reserved db size Instance_Entry_Struc dup (?) ;an000; dms; + ER_Direction_Flag db ER_Up ;default to forward move;an000; dms; + + ER_Sub_Function db ? ;save subfunction byte ;an000; dms; + + ER_Src_Abs_Beg_Low dw ? ;abs add of src EMS page;an000; dms; + ER_Src_Abs_Beg_High dw ? ; beginning of trf area;an000; dms; + ER_Src_Abs_End_Low dw ? ;abs add of src EMS page;an000; dms; + ER_Src_Abs_End_High dw ? ; end of trf area ;an000; dms; + + ER_Dst_Abs_Beg_Low dw ? ;abs add of src EMS page;an000; dms; + ER_Dst_Abs_Beg_High dw ? ; beginning of trf area;an000; dms; + ER_Dst_Abs_End_Low dw ? ;abs add of src EMS page;an000; dms; + ER_Dst_Abs_End_High dw ? ; end of trf area ;an000; dms; + + ER_Current_Move_Count dw ? ;bytes moved this time ;an000; dms; + + ER_Move_Xchg_Buffer1 db 10h dup (?) ;buffer for move/xchg ;an000; dms; + ER_Move_Xchg_Buffer2 db 10h dup (?) ;buffer for move/xchg ;an000; dms; + + ER_Move_Count_Low dw ? ;low word of count ;an000; dms; + ER_Move_Count_High dw ? ;high word of count ;an000; dms; + + ER_Source_Phys_Page dw ? ;page number of source ;an000; dms; + ER_Dest_Phys_Page dw ? ;page number of dest ;an000; dms; + + ER_Source_Page dw ? ;active source page ;an000; dms; + ER_Dest_Page dw ? ;active dest page ;an000; dms; + + ER_Source_Handle dw ? ;active handle ;an000; dms; + ER_Dest_Handle dw ? ;active handle ;an000; dms; + ; 10h byte moves + + ER_Save_Context_Buffer dw 2*Type Mappable_Phys_Page_Struct dup (0) ;room for 2 pgs;an000; dms; + + ER_Dest_Seg dw ? ;seg value of dest ;an000; dms; + ER_Source_Seg dw ? ;seg value of source ;an000; dms; + + ER_Dest_Off dw ? ;off value of dest ;an000; dms; + ER_Source_Off dw ? ;off value of source ;an000; dms; + + ER_Mem_Type dw ? ;memory type ;an000; dms; + + +ER_Struc Ends ;end structure ;an000; dms; + +;========================================================================= +;========== End STRUC Definitions ======================================== +;========================================================================= + + page +;========================================================================= +;========== Begin Macro Definitions ====================================== +;========================================================================= + + +;========================================================================= +; MAC_Expand_Stack_And_Copy : This routine will place data in the +; instance table by copying the data pointed +; at by ES:DI. +; +; Inputs : AX - Size of stack adjustment +; ES:DI - Pointer to data to be copied to stack +; +; Outputs : BP - data place in instance table +; +;========================================================================= + +MAC_Expand_Stack_And_Copy proc + + mov cx,ax ;get adjustment factor ;an000; dms; + shr cx,1 ;convert to word move ;an000; dms; + mov ax,es ;get data source seg ;an000; dms; + mov ds,ax ;place in ds ;an000; dms; + mov si,di ;get data source off ;an000; dms; + + mov ax,cs ;get dest. seg ;an000; dms; + mov es,ax ;place in es ;an000; dms; + mov di,bx ;get dest. off ;an000; dms; + + cli ;ints off ;an000; dms; + rep movsw ;move data to stack ;an000; dms; + sti ;ints on ;an000; dms; + + ret ;end routine ;an000; dms; + +MAC_Expand_Stack_And_Copy endp + + page +;========================================================================= +; MAC_Shrink_Stack_And_Copy : This routine move data from the instance +; table and place it at ES:DI. +; +; Inputs : AX - Size of stack adjustment +; ES:DI - Pointer to where data is to be copied +; +; Outputs : BP - data removed from instance table +; +;========================================================================= + +MAC_Shrink_Stack_And_Copy proc + + mov cx,ax ;get adjustment factor ;an000; dms; + mov ax,cs ;get data source seg ;an000; dms; + mov ds,ax ;place in ds ;an000; dms; + mov si,bx ;get data source off ;an000; dms; + mov ax,cx ;save count across move ;an000; dms; + shr cx,1 ;convert to word move ;an000; dms; + + cli ;ints off ;an000; dms; + rep movsw ;move data from stack ;an000; dms; + sti ;ints on ;an000; dms; + + ret ;end routine ;an000; dms; + +MAC_Shrink_Stack_And_Copy endp + + +;========================================================================= +;========== End Macro Definitions ======================================== +;========================================================================= + + page +;========================================================================= +;========== Begin Generic PROC Definitions =============================== +;========================================================================= + +;========================================================================= +; Map_Pages : This routine will map the pages being +; requested in the struc pointed to by +; DS:SI. +; +; Inputs : ES:DI - Pointer to data in Log_Phys_Map_Struc format +; CX - Count of data iterations in ES:DI +; DX - handle +; BX - page count for handle +; AL - option +; +; Outputs : Revised map +; AH - 0 = no error +; > 0 = error +;========================================================================= + +Map_Pages proc ; ;an000; dms; + + push si ;save reg ;an000; dms; + + mov si,ax ;save option ;an000; dms; + cmp cx,AAJ_No_Pages_To_Map ;no pages? ;an000; dms; + je Map_Error_Exit ;yes - exit loop ;an000; dms; + +Map_Loop_Continue: + + cmp [di].Log_Page_Number,bx ;logical page out of ;an000; dms; + ; range? + jbe Map_Get_Segment ;no - in range ;an000; dms; + mov ah,EMS_Code8A ;yes - out of range ;an000; dms; + jmp Map_Error_Exit ;exit routine ;an000; dms; + +Map_Get_Segment: + + cmp si,AAJ_Segment ;segment request? ;an000; dms; + mov ax,[di].Phys_Page_Number_Seg ;get physical page ;an000; dms; + jne Map_Page_Request ;no - page request ;an000; dms; + push dx ;save handle + mov dx,[di].Phys_Page_Number_Seg ;get segment ;an000; dms; + call Get_Phys_Seg_Page ;get the associated ;an000; dms; + ; page for the segment + mov ax,dx ;place page in ax ;an000; dms; + pop dx ;restore handle + jnc Map_Page_Request ;no error - continue ;an000; dms; + mov ah,EMS_Code8B ;phys page not found ;an000; dms; + jmp Map_Error_Exit ;exit routine ;an000; dms; + +Map_Page_Request: + + push bx ;save bx across call ;an000; dms; + mov bx,[di].Log_Page_Number ;logical page to map ;an000; dms; + call Map_L_To_P ;map the page ;an000; dms; + pop bx ;restore bx ;an000; dms; + or ah,ah ;error? ;an000; dms; + jnz Map_Error_Exit ;pass error on & exit ;an000; dms; + add di,Type Log_Phys_Map_Struc ;adjust pointer ;an000; dms; + loop Map_Loop_Continue ;continue loop ;an000; dms; + xor ax,ax ;signal good finish ;an000; dms; + +Map_Error_Exit: + + pop si ;restore reg ;an000; dms; + + ret ;return to caller ;an000; dms; + +Map_Pages endp ;end proc ;an000; dms; + + + page +;========================================================================= +; Get_Phys_Seg_Page : This routine will obtain the physical page +; number for a given segment. +; +; Inputs : DX - Segment value +; Outputs : DX - Physical page number +; CY - Error +; NC - No error +;========================================================================= + +Get_Phys_Seg_Page proc ;begin routine ;an000; dms; + + push ax ;save regs ;an000; dms; + push cx ; ;an000; dms; + push di ; ;an000; dms; + + cli ;ints off ;an000; dms; + mov di,offset Map_Table ;point to table map ;an000; dms; + mov cx,Map_Count ;number of table entries;an000; dms; + sti ;ints on ;an000; dms; + +GPSP_Loop: + + cli ;ints off ;an000; dms; + cmp dx,cs:[di].Phys_Page_Segment ;segment match? ;an000; dms; + je GPSP_Got_Segment ;yes ;an000; dms; + add di,Type Mappable_Phys_Page_Struct ;adjust pointer ;an000; dms; + loop GPSP_Loop ;continue search ;an000; dms; + +GPSP_Got_Segment: + + sti ;ints on ;an000; dms; + cmp cx,0 ;data found? ;an000; dms; + je GPSP_Not_Found ;exit with error ;an000; dms; + mov dx,cs:[di].Phys_Page_Number ;exit with page number ;an000; dms; + clc ;clear cy ;an000; dms; + jmp GPSP_Found ;exit ;an000; dms; + +GPSP_Not_Found: + + stc ;signal error ;an000; dms; + +GPSP_Found: ;exit ;an000; dms; + + pop di ;restore regs ;an000; dms; + pop cx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +Get_Phys_Seg_Page endp ;end proc ;an000; dms; + + +;========================================================================= +;========== End Generic PROC Definitions ================================= +;========================================================================= + + + + page + +;------------------------------------------------------------------- +; Reallocate Pages - Function 18 +; +; Entry - AX = 51?? +; BX = count of new allocation pages +; DX = handle +; +; Exit - AH = status +; BX = new page count +; if error - original page count +;------------------------------------------------------------------- +reallocate proc + + push cx ;save affected regs ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + + push ds ;save segments ;an000; dms; + push es ; ;an000; dms; + + mov ax,cs ;get code segment ;an000; dms; + mov ds,ax ;put int ds and ;an000; dms; + mov es,ax ; es ;an000; dms; + + + mov cs:[bp].Realloc_Page_Count,bx ;new page count ;an000; dms; + mov cs:[bp].Realloc_Handle,dx ;handle ;an000; dms; + + + + mov ax,cs:[bp].Realloc_Handle ;get handle for search ;an000; dms; + mov cs:[bp].Realloc_Mult,Type H_LookUp_Struc;handle lookup table ;an000; dms; + mul cs:[bp].Realloc_Mult ;obtain index position ;an000; dms; + mov cs:[bp].Realloc_LookUp_Index,ax ;index to handle ;an000; dms; + mov di,ax ;place index in si ;an000; dms; + mov dx,cs:[bp].Realloc_Handle ;get handle number ;an000; dms; + + + cmp dx,Num_Handles-1 ;dx > handle count? ;an000; dms; + jbe Realloc_Handle_Search ;handle within range ;an000; dms; + mov ah,EMS_Code83 ;EMS handle non-existent;an000; dms; + jmp Realloc_Error_Exit ;exit program ;an000; dms; + +Realloc_Handle_Search: + + cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; + jne Realloc_Status_Of_Handle ;handle good ;an000; dms; + mov ah,EMS_Code83 ;EMS handle not alloc ;an000; dms; + jmp Realloc_Error_Exit ;exit program ;an000; dms; + +Realloc_Status_Of_Handle: + + + mov ax,Handle_LookUp_Table.H_Pages[di] ;get current page count ;an000; dms; + sub ax,cs:[bp].Realloc_Page_Count ;more or less pages? ;an000; dms; + jc Realloc_More_Pages ;more pages to alloc ;an000; dms; + +Realloc_Less_Pages: + + mov bx,ax ;pages to deallocate ;an000; dms; + mov cs:[bp].Realloc_Page_Dealloc,ax ;save dealloc value ;an000; dms; + + mov si,Handle_LookUp_Table.H_Pal_Ptr[di] ;get start of links ;an000; dms; + mov cx,Handle_LookUp_Table.H_Pages[di] ;current pages allocated;an000; dms; + sub cx,bx ;pages to remain alloc ;an000; dms; + + +Realloc_Dealloc_Loop1: + + cmp cx,0 ;pages? ;an000; dms; + je Realloc_Dealloc_Loop1_Exit ;no - exit ;an000; dms; + shl si,1 + mov si,Page_Alloc_List[si] ;get next pointer ;an000; dms; + dec cx ;dec loop count ;an000; dms; + jmp Realloc_Dealloc_Loop1 ;continue ;an000; dms; + +Realloc_Dealloc_Loop1_Exit: + +;***** Adjust pointers ***** + + mov cx,cs:[bp].Realloc_Page_Dealloc ;get dealloc count ;an000; dms; + mov ax,cs:PAL_Free_Ptr ;get the free ptr ;an001; dms; + cmp cx,0 ;0 pages to dealloc? ;an001; dms; + je Realloc_Dealloc_Loop2_Exit1 ;yes - bypass dealloc ;an001; dms; + mov cs:PAL_Free_Ptr,si ;no - set new free ptr ;an001; dms; + dec cx ;don't loop past last pg;an001; dms; + +Realloc_Dealloc_Loop2: + + cmp cx,0 ;end of deallocate? ;an000; dms; + je Realloc_Dealloc_Loop2_Exit ;yes - exit ;an000; dms; + shl si,1 ;get index entry ;an001; dms; + mov si,Page_Alloc_List[si] ;get next ptr ;an001; dms; + dec cx ;decrement counter ;an000; dms; + jmp Realloc_Dealloc_Loop2 + +Realloc_Dealloc_Loop2_Exit: + + shl si,1 ;get index entry ;an001; dms; + mov Page_Alloc_List[si],ax ;pt. last page to orig. ;an001; dms; + ; free ptr. + +Realloc_Dealloc_Loop2_Exit1: + + mov ax,cs:[bp].Realloc_Page_Count ;new page count ;an000; dms; + mov Handle_LookUp_Table.H_Pages[di],ax ; ;an000; dms; + + mov ax,cs:[bp].Realloc_Page_Dealloc ;adj. value ;an000; dms; + add cs:Free_Pages,ax ;free up page ;an000; dms; + + mov bx,cs:[bp].Realloc_Page_Count ;pass back page request ;an000; dms; + xor ah,ah ;clear error ;an000; dms; + jmp Realloc_Exit ;exit ;an000; dms; + +Realloc_More_Pages: + + mov cx,cs:[bp].Realloc_Page_Count ;get page request count ;an000; dms; + mov di,cs:[bp].Realloc_LookUp_Index ;get LookUp Table ptr ;an000; dms; + mov ax,Handle_LookUp_Table.H_Pages[di] ;get current page count ;an000; dms; + sub cx,ax ;get additional pages ;an000; dms; + mov cs:[bp].Realloc_Page_Alloc,cx ;new pages to alloc ;an000; dms; + cmp cx,Free_Pages ;> pages remaining? ;an000; dms; + jbe Realloc_Pages ;reallocate pages ;an000; dms; + mov ah,EMS_Code87 ;Too few pages avail ;an000; dms; + jmp Realloc_Error_Exit ;exit prog ;an000; dms; + +Realloc_Pages: + + mov cx,Handle_LookUp_Table.H_Pages[di] ;current pages allocated;an000; dms; + cmp cx,0 ;any pages? ;an000; dms; + jne Realloc_More_Pages_Cont ;yes ;an000; dms; + cmp cs:[bp].Realloc_Page_Alloc,0 ;any pages requested? ;an000; dms; + je Realloc_Alloc_Loop1_Exit ;continue ;an000; dms; + + mov cx,cs:[bp].Realloc_Page_Alloc ;get new page count ;an001; dms; + cli ;ints off ;an001; dms; + call EMS_Page_Contig_Chk ;contig pages avail? ;an001; dms; + jnc Realloc_New_Pages + mov ah,EMS_Code87 ;Too few pages avail ;an000; dms; + sti ;ints on ;an001; dms; + jmp Realloc_Error_Exit ;exit prog ;an000; dms; + +Realloc_New_Pages: + + call EMS_Link_Set ;set up page list ;an001; dms; + + mov Handle_LookUp_Table.H_Pal_Ptr[di],si ;set table to pointer ;an000; dms; + mov Handle_LookUp_Table.H_Pages[di],cx ;new page count ;an000; dms; + mov bx,cs:[bp].Realloc_Page_Count ;return new page count ;an001; dms; + sub cs:Free_Pages,bx ;new free count ;an000; dms; + sti ;ints on ;an001; dms; + xor ax,ax ;clear error flag ;an001; dms; + + jmp Realloc_Exit ;exit routine ;an001; dms; + + +Realloc_More_Pages_Cont: + + dec cx + mov si,Handle_LookUp_Table.H_Pal_Ptr[di] ;get start of links ;an000; dms; + +Realloc_Alloc_Loop1: + cmp cx,0 ;at end ;an000; dms; + je Realloc_Alloc_Loop1_Exit ;yes ;an000; dms; + shl si,1 ;word entry ;an000; dms; + mov si,Page_Alloc_List[si] ;get next pointer ;an000; dms; + dec cx ;decrement loop count ;an000; dms; + jmp Realloc_Alloc_Loop1 ;continue ;an000; dms; + +Realloc_Alloc_Loop1_Exit: + + mov cx,cs:[bp].Realloc_Page_Alloc ;new pages to alloc ;an000; dms; + cmp cx,0 ;pages requested? ;an001; dms; + je Realloc_Alloc_Exit ;no - exit routine ;an001; dms; + + mov bx,si ;save si ;an001; dms; + cli ;ints off ;an001; dms; + call EMS_Page_Contig_Chk ;contig pages? ;an001; dms; + jnc Realloc_Next_Pages ;yes ;an001; dms; + mov ah,EMS_Code87 ;Too few pages avail ;an000; dms; + sti ;ints on ;an001; dms; + jmp Realloc_Error_Exit ;exit prog ;an000; dms; + +Realloc_Next_Pages: + +;;;; mov ax,si ;ptr to new list ;an001; dms; +;;;; inc ax ;contig to new links? ;an001; dms; +;;;; cmp ax,bx ; ;an001; dms; +;;;; je Realloc_Next_Pages1 ;yes continue ;an001; dms; +;;;; mov ah,EMS_Code87 ;Too few pages avail ;an000; dms; +;;;; sti ;ints on ;an001; dms; +;;;; jmp Realloc_Error_Exit ;exit prog ;an000; dms; + +Realloc_Next_Pages1: + + call EMS_Link_Set ;set up page list ;an001; dms; + mov ax,si ;ptr to new list ;an001; dms; + mov si,bx ;end of old list ;an001; dms; + shl si,1 ;index entry ;an001; dms; + mov Page_Alloc_List[si],ax ;pick up new links ;an001; dms; + +Realloc_Alloc_Exit: + + mov bx,cs:[bp].Realloc_Page_Alloc ;additional pages ;an001; dms; + sub cs:Free_Pages,bx ;new free count ;an000; dms; + mov bx,cs:[bp].Realloc_Page_Count ;pass back page request ;an000; dms; + mov Handle_LookUp_Table.H_Pages[di],bx ;new page count ;an000; dms; + sti ;ints on ;an001; dms; + xor ah,ah ;clear ah ;an000; dms; + jmp Realloc_Exit ;exit ;an000; dms; + + +Realloc_Error_Exit: + + cli ;ints off ;an000; dms; + mov si,cs:[bp].Realloc_LookUp_Index ;get handle index ;an000; dms; + mov bx,Handle_LookUp_Table.H_Pages[si] ;get orig. count ;an000; dms; + mov Handle_LookUp_Table.H_Pages[si],bx ;new page count ;an000; dms; + sti ;ints on ;an000; dms; + +Realloc_Exit: + + pop es ;restore segments ;an000; dms; + pop ds ; ;an000; dms; + + pop si ;restore regs ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop cx ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +reallocate endp + + + + page +;========================================================================= +;=============== Function 55h Logic - Alter Page Map & Jump ============= +;========================================================================= +;========================================================================= +; Alter_And_Jump - This routine alters the page map and jumps +; to the specified address. +; +; Inputs : AH - 55h (Alter page map & jump) +; AL - Physical page number/segment selector +; 0 = Physical page numbers specified +; 1 = Segment addresses specified in lieu of +; physical page numbers +; DX - handle number +; DS:SI - Pointer to map and jump structure +; (see Map_And_Jump_Struct above) +; +; Outputs : Revised map +; AH - Non-zero if error +; +;========================================================================= +Alter_And_Jump proc ;modify map ;an000; dms; + + push bx ;save regs for jump ;an000; dms; + push cx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + + pushf ;save flags ;an000; dms; + push ds ;save segments ;an000; dms; + push es ; ;an000; dms; + + mov bx,cs ;get code segment ;an000; dms; + mov es,bx ; es ;an000; dms; + + mov cs:[bp].AAJ_Handle,dx ;save handle ;an000; dms; + mov cs:[bp].AAJ_Option,al ;save selector option ;an000; dms; + + + + cmp dx,Num_Handles-1 ;dx > handle count ;an000; dms; + jbe AAJ_Check_Reusable ;continue test ;an000; dms; + mov ah,EMS_Code83 ;EMS handle bad ;an000; dms; + jmp AAJ_Error_Exit ;exit routine ;an000; dms; + +AAJ_Check_Reusable: + + mov ax,dx ;get handle ;an000; dms; + mov cs:[bp].AAJ_Mult,Type H_LookUp_Struc ;handle lookup table ;an000; dms; + mul cs:[bp].AAJ_Mult ;obtain index position ;an000; dms; + mov cs:[bp].AAJ_LookUp_Index,ax ;index to handle ;an000; dms; + mov di,ax ;place index in di ;an000; dms; + + cli ;ints off ;an000; dms; + mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms; + mov cs:[bp].AAJ_Xref_Pages,ax ;save logical page count;an000; dms; + sti ;ints on ;an000; dms; + cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; + jne AAJ_Good_Handle ;handle good ;an000; dms; + mov ah,EMS_Code83 ;EMS handle bad ;an000; dms; + jmp AAJ_Error_Exit ;exit routine ;an000; dms; + +AAJ_Good_Handle: + + cmp cs:[bp].AAJ_Option,AAJ_Option_Max ;option in range? ;an000; dms; + jbe AAJ_Good_Option ;option good ;an000; dms; + mov ah,EMS_Code8F ;bad option ;an000; dms; + jmp AAJ_Error_Exit ;exit routine ;an000; dms; + +AAJ_Good_Option: + + les di,[si].Log_Phys_Map_Ptr ;point to map data ;an000; dms; + xor cx,cx ;clear loop counter ;an000; dms; + mov cl,[si].Log_Phys_Map_Len ;get loop count ;an000; dms; + mov dx,cs:[bp].AAJ_Handle ;get handle for call ;an000; dms; + mov bx,cs:[bp].AAJ_Xref_Pages ;logical page count ;an000; dms; + xor ah,ah ;clear high word ;an000; dms; + mov al,cs:[bp].AAJ_Option ;option selected ;an000; dms; + call Map_Pages ;map the pages requested;an000; dms; + or ah,ah ;error? ;an000; dms; + jnz AAJ_Error_Exit ;exit with error cond. ;an000; dms; + +AAJ_Loop_Exit: + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + popf ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop cx ; ;an000; dms; + pop bx ; ;an000; dms; + + mov cs:[bp].IE_Alloc_Byte,Unallocated ;deallocate instance ;an000; dms; + + jmp dword ptr [si].Target_Address ;jump to address & run ;an000; dms; + +AAJ_Error_Exit: + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + popf ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop cx ; ;an000; dms; + pop bx ; ;an000; dms; + + + ret ;return to caller ;an000; dms; + +Alter_And_Jump endp ;end proc ;an000; dms; + + + + page +;========================================================================= +;=============== Function 56h Logic - Alter Page Map & Call ============= +;========================================================================= + + + +;========================================================================= +; Alter_And_Call - This routine alters the page map and calls +; the specified address. The mapping context +; is saved on entry to the routine and restored +; on exit from the routine. +; +; Inputs : AH - 56h (Alter page map & call) +; AL - Physical page number/segment selector +; 0 = Physical page numbers specified +; 1 = Segment addresses specified in lieu of +; physical page numbers +; 2 = Give minimum required stack size +; DX - handle number +; DS:SI - Pointer to map and jump structure +; (see Map_And_Call_Struc above) +; +; Outputs : Revised map +; AH - Non-zero if error +; BX - Function 2 = size in bytes needed for stack +; +;========================================================================= + + +Alter_And_Call proc ;modify map & call ;an000; dms; + + cmp al,MAC_Stack_Status_Request ;stack report? ;an000; dms; + je MAC_Calc_Stack_Status ;yes ;an000; dms; + jb MAC_Alter_And_Call ;no - new mapping ;an000; dms; + mov ah,EMS_Code8F ;error occurred ;an000; dms; + jmp MAC_Stack_Exit ;exit routine ;an000; dms; + +MAC_Calc_Stack_Status: + + mov bx,8h ;room for call address ;an000; dms; + ; and return address + xor ax,ax ;signal no error ;an000; dms; + jmp MAC_Stack_Exit ;exit routine ;an000; dms; + +MAC_Alter_And_Call: + + cli ;ints off ;an000; dms; + mov cs:[bp].EMS_Reg_BX,bx ; ;an000; dms; + mov bx,ax ;save ax across flags ;an000; dms; + lahf ;move flags to ah ;an000; dms; + mov cs:[bp].EMS_Reg_FL,ax ;save flags ;an000; dms; + mov ax,bx ;restore ax ;an000; dms; + mov cs:[bp].EMS_Reg_CX,cx ; ;an000; dms; + mov cs:[bp].EMS_Reg_DX,dx ; ;an000; dms; + mov cs:[bp].EMS_Reg_DI,di ; ;an000; dms; + mov cs:[bp].EMS_Reg_SI,si ; ;an000; dms; + mov cs:[bp].EMS_Reg_DS,ds ; ;an000; dms; + mov cs:[bp].EMS_Reg_ES,es ; ;an000; dms; + + mov cs:[bp].MAC_Option,al ;save option ;an000; dms; + sti ;ints on ;an000; dms; + cmp dx,Num_Handles-1 ;dx > handle count ;an000; dms; + jbe MAC_Check_Reusable ;continue test ;an000; dms; + mov ah,EMS_Code83 ;EMS handle bad ;an000; dms; + jmp MAC_Error_Exit ;exit routine ;an000; dms; + +MAC_Check_Reusable: + + mov ax,dx ;get handle ;an000; dms; + mov cs:[bp].MAC_Mult,Type H_LookUp_Struc ;handle lookup table ;an000; dms; + mul cs:[bp].MAC_Mult ;obtain index position ;an000; dms; + mov cs:[bp].MAC_LookUp_Index,ax ;index to handle ;an000; dms; + mov di,ax ;place index in di ;an000; dms; + + cli ;ints off ;an000; dms; + mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms; + mov cs:[bp].MAC_Xref_Pages,ax ;save logical page count;an000; dms; + cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; + sti ;ints on ;an000; dms; + jne MAC_Verify_New_Count ;handle good ;an000; dms; + mov ah,EMS_Code83 ;EMS handle bad ;an000; dms; + jmp MAC_Error_Exit ;exit routine ;an000; dms; + +MAC_Verify_New_Count: + + cli ;ints off ;an000; dms; + mov ax,Map_Count ;get phys. page count ;an000; dms; + sti ;ints on ;an000; dms; + cmp [si].MAC_New_Page_Map_Len,al ;> physical pages ;an000; dms; + jbe MAC_Verify_Old_Count ;no - continue ;an000; dms; + mov ah,EMS_Code8B ;out of range ;an000; dms; + jmp MAC_Error_Exit ;exit routine ;an000; dms; + +MAC_Verify_Old_Count: + + cli ;ints off ;an000; dms; + mov ax,Map_Count ;get phys. page count ;an000; dms; + sti ;ints on ;an000; dms; + cmp [si].MAC_Old_Page_Map_Len,al ;> physical pages ;an000; dms; + jbe MAC_Do_Alter_and_Call ;no - continue ;an000; dms; + mov ah,EMS_Code8B ;yes - error ;an000; dms; + jmp MAC_Error_Exit ;exit routine ;an000; dms; + +MAC_Do_Alter_And_Call: + + jmp MAC_Build_Stack_And_Map ;build stack and map ;an000; dms; + ; new pages +MAC_Return_Routine: + + jmp MAC_Strip_Stack_And_Map ;restore data strucs ;an000; dms; + ; and map old pages + +MAC_Exit: +MAC_Error_Exit: + + cli ;ints off ;an000; dms; + mov bx,ax ;save ax ;an000; dms; + mov ax,cs:[bp].EMS_Reg_FL ;obtain entry flag stat ;an000; dms; + sahf ;put in flags reg ;an000; dms; + mov ax,bx ;restore ax ;an000; dms; + mov bx,cs:[bp].EMS_Reg_BX ; ;an000; dms; + mov cx,cs:[bp].EMS_Reg_CX ; ;an000; dms; + mov dx,cs:[bp].EMS_Reg_DX ; ;an000; dms; + mov di,cs:[bp].EMS_Reg_DI ; ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ; ;an000; dms; + mov ds,cs:[bp].EMS_Reg_DS ; ;an000; dms; + mov es,cs:[bp].EMS_Reg_ES ; ;an000; dms; + sti ;ints on ;an000; dms; + +MAC_Stack_Exit: + + ret ;return to caller ;an000; dms; + + +;========================================================================= +; MAC_Build_Stack_And_Map : This routine will build the required +; stack structure for a re-entrant +; routine and map the new pages. +; +; Inputs : DS:SI - Pointer to data in Map_And_Call_Struc format +; +; Outputs : BP - Instance table to reflect data copyied to it +; New mapped pages +; AH - 0 = no error +; >0 = error (determined by Map_Pages) +; +; Instance Table carries this data: Old Map Data +; New Map Data +; Map & Call Data +; Context +;========================================================================= + +MAC_Build_Stack_And_Map: + + mov cs:[bp].EMS_Reg_DS,ds ;save DS ;an000; dms; + mov cs:[bp].EMS_Reg_SI,si ;save SI ;an000; dms; + + mov ax,word ptr [si].MAC_Old_Page_Map_Ptr[+2];get the segment ;an000; dms; + mov es,ax ; of the old map ;an000; dms; + mov di,word ptr [si].MAC_Old_Page_Map_Ptr[+0];get its offset ;an000; dms; + + mov al,[si].MAC_Old_Page_Map_Len ;get length of data ;an000; dms; + cbw ;convert to word ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,Type Log_Phys_Map_Struc ;struc size + mul bx ;get total byte count ;an000; dms; + cli ;ints off ;an000; dms; + mov bx,offset MAC_M_C_Log ;offset in struc ;an000; dms; + sti ;ints on ;an000; dms; + add bx,bp ;actual offset ;an000; dms; + call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms; + ; copy of data and + ; copy the data + mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; + + mov ax,word ptr [si].MAC_New_Page_Map_Ptr[+2];get the segment ;an000; dms; + mov es,ax ; of the old map ;an000; dms; + mov di,word ptr [si].MAC_New_Page_Map_Ptr[+0];get its offset ;an000; dms; + + mov al,[si].MAC_New_Page_Map_Len ;get length of data ;an000; dms; + cbw ;conver to word ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,Type Log_Phys_Map_Struc ;struc size + mul bx ;get total byte count ;an000; dms; + cli ;ints off ;an000; dms; + mov bx,offset MAC_M_C_Log ;Ptr in struc ;an000; dms; + add bx,size MAC_M_C_Log/2 ;next entry ;an000; dms; + sti ;ints on ;an000; dms; + add bx,bp ;offset BP relative ;an000; dms; + call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms; + ; copy of data and + ; copy the data + mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; + + mov ax,ds ;move seg of data to ;an000; dms; + mov es,ax ; es ;an000; dms; + mov di,si ;move off of data ;an000; dms; + mov ax,Type Map_And_Call_Struc ;get size of structure ;an000; dms; + cli ;ints off ;an000; dms; + mov bx,offset MAC_M_C_Data + sti ;ints on ;an000; dms; + add bx,bp ;offset BP relative ;an000; dms; + call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms; + ; copy of data and + ; copy the data + mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; + + mov ax,cs ;get seg of context ;an000; dms; + mov es,ax ; in es ;an000; dms; + cli ;ints off ;an000; dms; + mov di,offset cs:Map_Table ;get offset of context ;an000; dms; + mov ax,Map_Count ;get context entry count;an000; dms; + sti ;ints on ;an000; dms; + xor dx,dx ;clear dx ;an000; dms; + mov bx,Type Mappable_Phys_Page_Struct ;get struc size ;an000; dms; + mul bx ;get size in bytes ;an000; dms; + cli ;ints off ;an000; dms; + mov bx,offset cs:MAC_Map_Table + sti ;ints on ;an000; dms; + add bx,bp ;offset BP relative ;an000; dms; + call MAC_Expand_Stack_And_Copy ;set up stack for ;an000; dms; + ; copy of data and + ; copy the data + mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; + + push cs ;save return segment ;an000; dms; + mov ax,offset MAC_Return_Routine ;save return offset ;an000; dms; + push ax ; ;an000; dms; + + mov ax,word ptr [si].MAC_Target_Address[+2] ;get seg of call far ;an000; dms; + mov bx,word ptr [si].MAC_Target_Address[+0] ;get offset of call far ;an000; dms; + push ax ;put on stack ;an000; dms; + push bx ; ;an000; dms; + + les di,[si].MAC_New_Page_Map_Ptr ;set up for call ;an000; dms; + xor cx,cx ;clear cx ;an000; dms; + mov cl,[si].MAC_New_Page_Map_Len ;get array size ;an000; dms; + mov dx,cs:[bp].EMS_Reg_DX ;get handle for call ;an000; dms; + mov bx,cs:[bp].MAC_Xref_Pages ;get handle page count ;an000; dms; + xor ah,ah ;clear high word ;an000; dms; + mov al,cs:[bp].MAC_Option ;get option ;an000; dms; + + call Map_Pages ;map the new pages ;an000; dms; + or ah,ah ;error? ;an000; dms; + jnz MAC_Error_Strip_Stack ;take data off stack ;an000; dms; + + cli ;ints off ;an000; dms; + mov ax,cs:[bp].EMS_Reg_FL ;obtain entry flag stat ;an000; dms; + sahf ;put in flags reg ;an000; dms; + mov bx,cs:[bp].EMS_Reg_BX ; ;an000; dms; + mov cx,cs:[bp].EMS_Reg_CX ; ;an000; dms; + mov dx,cs:[bp].EMS_Reg_DX ; ;an000; dms; + mov di,cs:[bp].EMS_Reg_DI ; ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ; ;an000; dms; + mov ds,cs:[bp].EMS_Reg_DS ; ;an000; dms; + mov es,cs:[bp].EMS_Reg_ES ; ;an000; dms; + sti ;ints on ;an000; dms; + +Retf_Fake_Out Proc Far ;this proc is to ;an000; dms; + ; simulate a RETF + ; instruction + ret ;performs a far return ;an000; dms; + +Retf_Fake_Out Endp ;end of retf fake out ;an000; dms; + + +MAC_Error_Strip_Stack: + + add sp,8h ;adjust for return add. ;an000; dms; + ; and target add. on + ; error + jmp MAC_Error_Exit ;exit routine ;an000; dms; + + +;========================================================================= +; MAC_Strip_Stack_And_Map : This routine will strip the stack of all +; the data placed on by MAC_Build_Stack_And_Map. +; +; Inputs : CS:BP - Pointer to data on the instance table +; +; Outputs : All data area restored +; Pages remapped to original +; AH - 0 = no error +; >0 = error (determined by Map_Pages) +; +; Instance Table carries this data: Old Map Data +; New Map Data +; Map & Call Data +; Context +;========================================================================= + +MAC_Strip_Stack_And_Map: ;an000; dms; + + mov ax,cs ;seg of context ;an000; dms; + mov es,ax ;place in es ;an000; dms; + cli ;ints off ;an000; dms; + mov di,offset cs:Map_Table ;get off of context ;an000; dms; + mov ax,Map_Count ;get entries in context ;an000; dms; + sti ;ints on ;an000; dms; + xor dx,dx ;clear dx ;an000; dms; + mov bx,Type Mappable_Phys_Page_Struct ;struc size ;an000; dms; + mul bx ;get byte count ;an000; dms; + cli ;ints off ;an000; dms; + mov bx,offset MAC_Map_Table + sti ;ints on ;an000; dms; + add bx,bp ;offset BP relative ;an000; dms; + call MAC_Shrink_Stack_And_Copy ;restore context ;an000; dms; + + mov si,cs:[bp].EMS_Reg_SI ;restore pointer ;an000; dms; + mov ds,cs:[bp].EMS_Reg_DS ; to data struc ;an000; dms; + + mov ax,ds ;transfer seg of struc ;an000; dms; + mov es,ax ; to dest. segment ;an000; dms; + mov di,si ;di=dest. offset ;an000; dms; + mov ax,Type Map_And_Call_Struc ;get size to move ;an000; dms; + cli ;ints off ;an000; dms; + mov bx,offset MAC_M_C_Data + sti ;ints on ;an000; dms; + add bx,bp ;offset BP relative ;an000; dms; + call MAC_Shrink_Stack_And_Copy ;restore Map & Call buf ;an000; dms; + + mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; + + mov ax,word ptr [si].MAC_New_Page_Map_Ptr[+2];get the segment ;an000; dms; + mov es,ax ; of the old map ;an000; dms; + mov di,word ptr [si].MAC_New_Page_Map_Ptr[+0];get its offset ;an000; dms; + + mov al,[si].MAC_New_Page_Map_Len ;get length of data ;an000; dms; + cbw ;convert to word ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,Type Log_Phys_Map_Struc ;struc size ;an000; dms; + mul bx ;get total byte count ;an000; dms; + cli ;ints off ;an000; dms; + mov bx,offset MAC_M_C_Log + sti ;ints on ;an000; dms; + add bx,size MAC_M_C_Log/2 + add bx,bp ;offset BP relative ;an000; dms; + call MAC_Shrink_Stack_And_Copy ;restore new page data ;an000; dms; + + mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; + + mov ax,word ptr [si].MAC_Old_Page_Map_Ptr[+2];get the segment ;an000; dms; + mov es,ax ; of the old map ;an000; dms; + mov di,word ptr [si].MAC_Old_Page_Map_Ptr[+0];get its offset ;an000; dms; + + mov al,[si].MAC_Old_Page_Map_Len ;get length of data ;an000; dms; + cbw ;convert to word ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,Type Log_Phys_Map_Struc ;struc size ;an000; dms; + mul bx ;get total byte count ;an000; dms; + cli ;ints off ;an000; dms; + mov bx,offset MAC_M_C_Log + sti ;ints on ;an000; dms; + add bx,bp ;offset BP relative ;an000; dms; + call MAC_Shrink_Stack_And_Copy ;set up stack for ;an000; dms; + + mov ds,cs:[bp].EMS_Reg_DS ;restore ds ;an000; dms; + mov si,cs:[bp].EMS_Reg_SI ;restore si ;an000; dms; + + mov dx,cs:[bp].EMS_Reg_DX ;get DX reg + + les di,[si].MAC_Old_Page_Map_Ptr ;set up for call ;an000; dms; + xor cx,cx ;clear cx ;an000; dms; + mov cl,[si].MAC_Old_Page_Map_Len ;get array size ;an000; dms; + mov bx,cs:[bp].MAC_Xref_Pages ;get handle page count ;an000; dms; + xor ah,ah ;clear high byte ;an000; dms; + mov al,cs:[bp].MAC_Option ;get option ;an000; dms; + + call Map_Pages ;map the new pages ;an000; dms; + + jmp MAC_Exit ;exit the program ;an000; dms; + + +Alter_And_Call endp ;end proc ;an000; dms; + + + page +;========================================================================= +;=============== Function 57h Logic - Move/Exchange Memory Region ======= +;========================================================================= + +;========================================================================= +; Exchng_Region - This routine moves/exchanges memory regions +; specified by the user. The following types of +; moves/exchanges are possible: +; +; Source Destination +; ------------------- ---------------------- +; Conventional Memory Expanded Memory +; Expanded Memory Conventional Memory +; Expanded Memory Expanded Memory +; +; Inputs : AH - 57h (Move/Exchange Memory Region) +; AL - Type of transfer +; 0 = Move memory +; 1 = Exchange memory +; DS:SI - Pointer to Move_Source_Dest Structure +; +; Outputs : Revised map +; AH - Non-zero if error +;========================================================================= + + +Exchng_Region proc + + push bx ;save regs ;an000; dms; + push cx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + push es ; ;an000; dms; + + mov cs:[bp].ER_Sub_Function,al ;save subfunction ;an000; dms; + cmp al,ER_Max_Function ;valid function? ;an000; dms; + jbe ER_Valid_Sub_Function ;yes - continue ;an000; dms; + mov ah,EMS_Code8F ;no - error ;an000; dms; + jmp ER_Error_Exit ;exit routine ;an000; dms; + +ER_Valid_Sub_Function: + + call ER_Type_Check ;Proper types & ;an000; dms; + or ah,ah ; type combinations? ;an000; dms; + jnz ER_Error_Exit ;no - exit routine ;an000; dms; + + call ER_Handle_Check ;valid handles? ;an000; dms; + or ah,ah ; ;an000; dms; + jnz ER_Error_Exit ;no - exit routine ;an000; dms; + + call ER_Length_Check ;Region fits in page ;an000; dms; + or ah,ah ; and <= 1Mb? ;an000; dms; + jnz ER_Error_Exit ;no - exit routine ;an000; dms; + + call ER_Wrap_Check ;> 1Mb wrap on move? ;an000; dms; + or ah,ah ; ;an000; dms; + jnz ER_Error_Exit ;yes - exit routine ;an000; dms; + + call ER_Overlap_Check ;conv. memory overlaps ;an000; dms; + or ah,ah ; EMS page frame? ;an000; dms; + jnz ER_Error_Exit ;yes - exit routine ;an000; dms; + + call ER_Log_Page_Test ;offset valid for log. ;an000; dms; + or ah,ah ; page? ;an000; dms; + jnz ER_Error_Exit ;no - exit routine ;an000; dms; + + cmp cs:[bp].ER_Sub_Function,ER_Move ;move? ;an000; dms; + je ER_Move_Call ;yes - perform move ;an000; dms; + call ER_EMS_Overlap_Check ;EMS pages overlap? ;an000; dms; + or ah,ah ; + jz ER_Exchange_No_Overlap ;no - exit with error ;an000; dms; + mov ah,EMS_Code97 ;signal error ;an000; dms; + jmp ER_Error_Exit ;exit with error code ;an000; dms; + +ER_Exchange_No_Overlap: + + call ER_Exchange_Data ;no - perform exchange ;an000; dms; + jmp ER_Exit ;exit the routine ;an000; dms; + +ER_Move_Call: + + call ER_EMS_Overlap_Check ;see if we had a move ;an000; dms; + ; overlap + push ax ;save result across call;an000; dms; + call ER_Move_Data ;perform the move ;an000; dms; + pop ax ;restore result ;an000; dms; + + ER_Exit: + ER_Error_Exit: + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop cx ; ;an000; dms; + pop bx ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +Exchng_Region endp + + +;========================================================================= +; ER_Handle_Check : This routine checks to see if the EMS handles +; specified are valid. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +; Possible error codes: 83h +;========================================================================= + +ER_Handle_Check proc ;check requested handles;an000; dms; + + push dx ;save regs ;an000; dms; + push di ; ;an000; dms; + + cmp [si].Source_Memory_Type,ER_Conv_Memory ;Conv memory for source?;an000; dms; + je ER_Handle_Check_Dest ;yes - ck dest. handle ;an000; dms; + + push dx ;save dx ;an000; dms; + xor dx,dx ;clear it ;an000; dms; + mov ax,[si].Source_Handle ;get handle requested ;an000; dms; + mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms; + mul dx ;obtain index position ;an000; dms; + mov di,ax ;place index in di ;an000; dms; + pop dx ;restore dx ;an000; dms; + + cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; + je ER_Handle_Check_Error_Exit ;handle not allocated ;an000; dms; + +ER_Handle_Check_Dest: + + cmp [si].Dest_Memory_Type,ER_Conv_Memory ;Conv memory for dest? ;an000; dms; + je ER_Handle_Check_Good_Exit ;yes - exit routine ;an000; dms; + + push dx ;save dx ;an000; dms; + xor dx,dx ;clear it ;an000; dms; + mov ax,[si].Dest_Handle ;get handle requested ;an000; dms; + mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms; + mul dx ;obtain index position ;an000; dms; + mov di,ax ;place index in di ;an000; dms; + pop dx ;restore dx ;an000; dms; + + cmp Handle_LookUp_Table.H_Pages[di],Reusable_Handle ;handle allocated ;an000; dms; + je ER_Handle_Check_Error_Exit ;handle not allocated ;an000; dms; + +ER_Handle_Check_Good_Exit: + + xor ah,ah ;signal no error ;an000; dms; + jmp ER_Handle_Check_Exit ;exit program ;an000; dms; + +ER_Handle_Check_Error_Exit: + + mov ah,EMS_Code83 ;signal error ;an000; dms; + +ER_Handle_Check_Exit: + + pop di ;restore regs ;an000; dms; + pop dx ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Handle_Check endp ;end proc ;an000; dms; + + + +;========================================================================= +; ER_Length_Check : This routine checks to see if the region length +; specified exceeds the page count of either the +; source or destination EMS handle pages allocated. +; It also checks to determine if the region length +; exceeds 1 Mb. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +; Possible error codes: 93h +; 96h +; 8Ah +;========================================================================= + +ER_Length_Check proc ;check region length ;an000; dms; + + push bx ;save regs ;an000; dms; + push cx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + + mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms; + mov bx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms; + cmp cx,ER_10H ;> 1Mb ;an000; dms; + ja ER_Length_Check_Error96 ;exit with error ;an000; dms; + cmp cx,ER_10H ;high word = 10h? ;an000; dms; + jne ER_Length_Check_Cont ;no - continue ;an000; dms; + cmp bx,0 ;low word other than 0? ;an000; dms; + je ER_Length_Check_Cont ;no - good value ;an000; dms; + +ER_Length_Check_Error96: + + mov ah,EMS_Code96 ;signal error ;an000; dms; + jmp ER_Length_Check_Exit ;exit routine + +ER_Length_Check_Cont: + + cmp [si].Source_Memory_Type,ER_Conv_Memory ;Conv memory for source?;an000; dms; + je ER_Length_Check_Dest ;yes - ck dest. length ;an000; dms; + + push dx ;save dx ;an000; dms; + xor dx,dx ;clear it ;an000; dms; + mov ax,[si].Source_Handle ;get handle requested ;an000; dms; + mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms; + mul dx ;obtain index position ;an000; dms; + mov di,ax ;place index in di ;an000; dms; + pop dx ;restore dx ;an000; dms; + + mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms; + ; for source handle + sub ax,[si].Source_Initial_Seg_Page ;pages in EMS to fill ;an000; dms; + push ax ;save ax ;an000; dms; + dec ax ;make it 0 based ;an000; dms; + pop ax ;restore ax ;an000; dms; + js ER_Length_Check_Error8A_Exit ;page out of range ;an000; dms; + + xor dx,dx ;clear it ;an000; dms; + mov dx,EMS_Page_Size_In_Bytes+1 ;page size in bytes ;an000; dms; + mul dx ;get total bytes to trf ;an000; dms; + sub ax,[si].Source_Initial_Offset ;get byte count in 1st ;an000; dms; + sbb dx,0 + + mov bx,ax ;prepare for DWORD comp ;an000; dms; + mov ax,dx ; ;an000; dms; + + mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms; + mov dx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms; + + call ER_Dword_Compare ;region > target? ;an000; dms; + jc ER_Length_Check_Error93_Exit ;CY = region > target ;an000; dms; + + +ER_Length_Check_Dest: + + cmp [si].Dest_Memory_Type,ER_Conv_Memory ;Conv memory for dest? ;an000; dms; + je ER_Length_Check_Good_Exit ;yes - exit routine ;an000; dms; + + push dx ;save dx ;an000; dms; + xor dx,dx ;clear it ;an000; dms; + mov ax,[si].Dest_Handle ;get handle requested ;an000; dms; + mov dx,Type H_LookUp_Struc ;handle lookup table ;an000; dms; + mul dx ;obtain index position ;an000; dms; + mov di,ax ;place index in di ;an000; dms; + pop dx ;restore dx ;an000; dms; + + mov ax,Handle_LookUp_Table.H_Pages[di] ;get logical page count ;an000; dms; + + sub ax,[si].Dest_Initial_Seg_Page ;pages in EMS to fill ;an000; dms; + push ax ;save ax ;an000; dms; + dec ax ;make it 0 based ;an000; dms; + pop ax ;restore ax ;an000; dms; + js ER_Length_Check_Error8A_Exit ;page out of range ;an000; dms; + + xor dx,dx ;clear high word ;an000; dms; + mov dx,EMS_Page_Size_In_Bytes+1 ;page size in bytes ;an000; dms; + mul dx ;get total bytes to trf ;an000; dms; + sub ax,[si].Dest_Initial_Offset ;get byte count in 1st ;an000; dms; + sbb dx,0 + + mov bx,ax ;prepare for DWORD comp ;an000; dms; + mov ax,dx ; ;an000; dms; + + mov cx,[si].Region_Length_High_Word ;get size of the region ;an000; dms; + mov dx,[si].Region_Length_Low_Word ; in CX:BX ;an000; dms; + + call ER_Dword_Compare ;region > target? ;an000; dms; + jc ER_Length_Check_Error93_Exit ;CY = region > target ;an000; dms; + + +ER_Length_Check_Good_Exit: + + xor ah,ah ;signal no error ;an000; dms; + jmp ER_Length_Check_Exit ;exit routine ;an000; dms; + +ER_Length_Check_Error93_Exit: + + mov ah,EMS_Code93 ;signal error ;an000; dms; + jmp ER_Length_Check_Exit ;exit routine ;an000; dms; + +ER_Length_Check_Error8A_Exit: + + mov ah,EMS_Code8A ;signal error ;an000; dms; + +ER_Length_Check_Exit: ;main exit ;an000; dms; + + pop di ;restore regs ;an000; dms; + pop dx ; ;an000; dms; + pop cx ; ;an000; dms; + pop bx ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Length_Check endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Type_Check : This routine checks the source/destination type +; specified to determine if they are within the +; proper range. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +; Possible error codes: 98h +;========================================================================= + +ER_Type_Check proc ;check type ;an000; dms; + + cmp [si].Source_Memory_Type,ER_Max_Type ;type within range? ;an000; dms; + ja ER_Type_Check_Error_Exit ;no - error exit ;an000; dms; + + cmp [si].Dest_Memory_Type,ER_Max_Type ;type within range? ;an000; dms; + ja ER_Type_Check_Error_Exit ;no - error exit ;an000; dms; + + +ER_Type_Check_Good_Exit: + + xor ah,ah ;signal no error ;an000; dms; + jmp ER_Type_Check_Exit ;exit routine ;an000; dms; + +ER_Type_Check_Error_Exit: + + mov ah,EMS_Code98 ;signal error ;an000; dms; + +ER_Type_Check_Exit: + + ret ;return to caller ;an000; dms; + +ER_Type_Check endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Wrap_Check : This routine checks to determine if there will be +; a wrap of conventional memory beyond 1Mb. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +; Possible error codes: A2h +;========================================================================= + +ER_Wrap_Check proc ;cks. conv. mem. wrap ;an000; dms; + + push dx ;save regs ;an000; dms; + push bx ; ;an000; dms; + + cmp [si].Source_Memory_Type,ER_Conv_Memory ;conv. memory? ;an000; dms; + jne ER_Wrap_Check_Dest ;no -check dest. ;an000; dms; + + mov ax,[si].Source_Initial_Seg_Page ;get segment ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,ER_10H ;adjust segment to ;an000; dms; + ; absolute address + mul bx ; ;an000; dms; + add ax,[si].Source_Initial_Offset ;add in offset ;an000; dms; + adc dx,0 ;pick up carry if any ;an000; dms; + + add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; + ; trf size + adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; + ; trf size + cmp dx,ER_10H ;> 1Mb? ;an000; dms; + jae ER_Wrap_Check_Error_Exit ;yes - signal error ;an000; dms; + jmp ER_Wrap_Check_Good_Exit ;no - signal no error ;an000; dms; + +ER_Wrap_Check_Dest: + + cmp [si].Dest_Memory_Type,ER_Conv_Memory ;conv. memory? ;an000; dms; + jne ER_Wrap_Check_Good_Exit ;no - exit routine ;an000; dms; + + mov ax,[si].Dest_Initial_Seg_Page ;get segment ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,ER_10H ;adjust segment to ;an000; dms; + ; absolute address + mul bx ; ;an000; dms; + add ax,[si].Dest_Initial_Offset ;add in offset ;an000; dms; + adc dx,0 ;pick up carry if any ;an000; dms; + + add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; + ; trf size + adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; + ; trf size + cmp dx,ER_10H ;> 1Mb? ;an000; dms; + jae ER_Wrap_Check_Error_Exit ;yes - signal error ;an000; dms; + +ER_Wrap_Check_Good_Exit: + + xor ah,ah ;signal no error ;an000; dms; + jmp ER_Wrap_Check_Exit ;exit routine ;an000; dms; + +ER_Wrap_Check_Error_Exit: + + mov ah,EMS_CodeA2 ;signal error ;an000; dms; + +ER_Wrap_Check_Exit: + + pop bx ;restore regs ;an000; dms; + pop dx ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Wrap_Check endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Overlap_Check : This routine checks to determine if the conventional +; memory region and expanded memory region overlap. +; Specifically, does the conventional memory region +; overlap the physical page addresses used for +; expanded memory? +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +; Possible error codes: 94h +; +; Algorithm : +; +; If Beg.Src.Add. < Beg.Dst.Add +; If (End.Src.Add - Beg.Dst.Add) > 0 +; signal OVERLAP +; Else +; signal NO-OVERLAP +; EndIf +; Else +; If (End.Dst.Add - Beg.Src.Add) > 0 +; signal OVERLAP +; Else +; signal NO-OVERLAP +; EndIf +; EndIf +;========================================================================= + +ER_Overlap_Check proc ;check for overlap ;an000; dms; + + push dx ;save regs ;an000; dms; + call ER_Save_Context ;save context ;an000; dms; + + cmp [si].Source_Memory_Type,ER_Conv_Memory ;conventional memory? ;an000; dms; + je ER_Overlap_Check_Source ;yes - check overlap ;an000; dms; + ;no - see if dest is + ; conv. memory + + cmp [si].Dest_Memory_Type,ER_Conv_Memory ;conventional memory? ;an000; dms; + jne ER_Overlap_Jump_Good ;no - exit routine ;an000; dms; + +ER_Overlap_Check_Dest: + + mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms; + ; the page frame save + ;buffer + add di,bp ;offset BP relative ;an000; dms; + cli ;ints off ;an000; dms; + cmp Map_Count,2 ;>= 2 page frames ;an000; dms; + sti ;ints on ;an000; dms; + jb ER_Overlap_Check_Dest_1_Frame ;no - use 1st. frame ;an000; dms; + add di,Type Mappable_Phys_Page_Struct ;yes - adjust ptr to ;an000; dms; + ; next frame for dest. +ER_Overlap_Check_Dest_1_Frame: + + ;**** calc abs address of the bottom of EMS transfer area + + mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,ER_10H ;para size ;an000; dms; + mul bx ;make abs address ;an000; dms; + mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save abs. address of ;an000; dms; + mov cs:[bp].ER_Src_Abs_Beg_High,dx ; phys page beg. ;an000; dms; + + ;**** calc abs address of the top of EMS transfer area + + add ax,EMS_Page_Size_In_Bytes ;make abs address ;an000; dms; + adc dx,0 ; ;an000; dms; + mov cs:[bp].ER_Src_Abs_End_Low,ax ;save abs. address ;an000; dms; + mov cs:[bp].ER_Src_Abs_End_High,dx ; of phys page end ;an000; dms; + + ;**** calc abs address of the bottom of CONV transfer area + + mov ax,[si].Dest_Initial_Seg_Page ;get segment ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,ER_10H ;para size ;an000; dms; + mul bx ;make abs address ;an000; dms; + add ax,[si].Dest_Initial_Offset ;get offset ;an000; dms; + adc dx,0 ;pick up carry ;an000; dms; + mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save initial seg start ;an000; dms; + mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save initial off start ;an000; dms; + + ;**** calc abs address of the top of CONV transfer area + + add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; + ; trf size + adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; + mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save initial seg start ;an000; dms; + mov cs:[bp].ER_Dst_Abs_End_High,dx ;save initial off start ;an000; dms; + + call ER_General_Overlap_Test ;test for overlap ;an000; dms; + + jc ER_Overlap_Error_Exit ;exit with error ;an000; dms; + +ER_Overlap_Jump_Good: + + jmp ER_Overlap_Good_Exit ;exit good ;an000; dms; + +ER_Overlap_Check_Source: + + mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms; + ; the page frame save + ;buffer + add di,bp ;offset BP relative ;an000; dms; + + ;**** calc abs address of the bottom of EMS transfer area + + mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,ER_10H ;para size ;an000; dms; + mul bx ;make abs address ;an000; dms; + mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save abs. address of ;an000; dms; + mov cs:[bp].ER_Src_Abs_Beg_High,dx ; phys page beg. ;an000; dms; + + ;**** calc abs address of the top of EMS transfer area + + mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; + mov dx,EMS_Page_Size_In_Bytes ;get end of phys page ;an000; dms; + mov bx,ER_10H ;para size ;an000; dms; + mul bx ;make abs address ;an000; dms; + mov cs:[bp].ER_Src_Abs_End_Low,ax ;save abs. address ;an000; dms; + mov cs:[bp].ER_Src_Abs_End_High,dx ; of phys page end ;an000; dms; + + ;**** calc abs address of the bottom of CONV transfer area + + mov ax,[si].Source_Initial_Seg_Page ;get segment ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,ER_10H ;para size ;an000; dms; + mul bx ;make abs address ;an000; dms; + add ax,[si].Source_Initial_Offset ;get offset ;an000; dms; + adc dx,0 ;pick up carry ;an000; dms; + mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save initial seg start ;an000; dms; + mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save initial off start ;an000; dms; + + ;**** calc abs address of the top of CONV transfer area + + add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; + ; trf size + adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; + mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save initial seg start ;an000; dms; + mov cs:[bp].ER_Dst_Abs_End_High,dx ;save initial off start ;an000; dms; + + call ER_General_Overlap_Test ;test for overlap ;an000; dms; + + jnc ER_Overlap_Good_Exit ;exit good ;an000; dms; + jmp ER_Overlap_Error_Exit ;exit bad + +ER_Overlap_Good_Exit: + + xor ah,ah ;signal no error ;an000; dms; + jmp ER_Overlap_Exit ;exit ;an000; dms; + +ER_Overlap_Error_Exit: + + mov ah,EMS_Code94 ;signal error ;an000; dms; + +ER_Overlap_Exit: + + call ER_Restore_Context ;restore context ;an000; dms; + + pop dx ;restore regs ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Overlap_Check endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_EMS_Overlap_Check : This routine determines if the source and target +; EMS regions overlap when both the source and target +; reside in EMS. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +; Possible error codes: 92h +; +; Algorithm : +; +; If Beg.Src.Add. < Beg.Dst.Add +; If (End.Src.Add - Beg.Dst.Add) > 0 +; signal OVERLAP +; Else +; signal NO-OVERLAP +; EndIf +; Else +; If (End.Dst.Add - Beg.Src.Add) > 0 +; signal OVERLAP +; Else +; signal NO-OVERLAP +; EndIf +; EndIf +;========================================================================= + +ER_EMS_Overlap_Check proc ;check for overlap ;an000; dms; + + push bx ;save regs ;an000; dms; + push dx ; ;an000; dms; + + cmp [si].Source_Memory_Type,ER_EMS_Memory ;Source EMS? ;an000; dms; + jne ER_EMS_Overlap_Exit ;no - exit routine ;an000; dms; + + cmp [si].Dest_Memory_Type,ER_EMS_Memory ;Dest. EMS? ;an000; dms; + jne ER_EMS_Overlap_Exit ;no - exit routine ;an000; dms; + + mov bx,[si].Source_Handle ;get source handle ;an000; dms; + cmp bx,[si].Dest_Handle ;source = dest? ;an000; dms; + jne ER_EMS_Overlap_Good_Exit ;no - exit routine ;an000; dms; + +ER_EMS_Overlap_Calc_N_Ck: + + ;**** calc absolute beginning address of source page + + mov ax,[si].Source_Initial_Seg_Page ;get start page ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,EMS_Page_Size_In_Bytes ;get page size ;an000; dms; + mul bx ;convert page to abs ;an000; dms; + ; address + add ax,[si].Source_Initial_Offset ;add in offset value ;an000; dms; + adc dx,0 ;pick up carry ;an000; dms; + + mov cs:[bp].ER_Src_Abs_Beg_Low,ax ;save low word of add + mov cs:[bp].ER_Src_Abs_Beg_High,dx ;save high word of add ;an000; dms; + + ;**** calc absolute ending address of source page + + add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; + ; length + adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; + ; length + mov cs:[bp].ER_Src_Abs_End_Low,ax ;save low word of end ;an000; dms; + mov cs:[bp].ER_Src_Abs_End_High,dx ;save high word of end ;an000; dms; + + ;**** calc absolute beginning address of dest. page + + mov ax,[si].Dest_Initial_Seg_Page ;get start page ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov bx,EMS_Page_Size_In_Bytes ;get page size ;an000; dms; + mul bx ;convert page to abs ;an000; dms; + ; address + add ax,[si].Dest_Initial_Offset ;add in offset value ;an000; dms; + adc dx,0 ;pick up carry ;an000; dms; + + mov cs:[bp].ER_Dst_Abs_Beg_Low,ax ;save low word of add + mov cs:[bp].ER_Dst_Abs_Beg_High,dx ;save high word of add ;an000; dms; + + ;**** calc absolute ending address of dest. page + + add ax,[si].Region_Length_Low_Word ;add in low word of ;an000; dms; + ; length + adc dx,[si].Region_Length_High_Word ;add in high word of ;an000; dms; + ; length + mov cs:[bp].ER_Dst_Abs_End_Low,ax ;save low word of end ;an000; dms; + mov cs:[bp].ER_Dst_Abs_End_High,dx ;save high word of end ;an000; dms; + + ;**** Actual test for overlap - corresponds to algorithm above + + call ER_General_Overlap_Test ;test for overlap ;an000; dms; + jnc ER_EMS_Overlap_Good_Exit ;no error ;an000; dms; + +ER_EMS_Overlap_Error_Exit: + + mov ah,EMS_Code92 ;signal error ;an000; dms; + jmp ER_EMS_Overlap_Exit ;exit ;an000; dms; + +ER_EMS_Overlap_Good_Exit: + + xor ah,ah ;no error ;an000; dms; + +ER_EMS_Overlap_Exit: + + pop dx ;restore regs ;an000; dms; + pop bx ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_EMS_Overlap_Check endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_General_Overlap_Test:This routine determines if the source and target +; EMS regions overlap when both the source and target +; reside in EMS. +; +; Inputs : ER_Src_Abs_Beg_Low - Low word of beginning trf area of source +; ER_Src_Abs_Beg_High - High word of beginning trf area of source +; +; ER_Src_Abs_End_Low - Low word of ending trf area of source +; ER_Src_Abs_End_High - High word of ending trf area of source +; +; : ER_Dst_Abs_Beg_Low - Low word of beginning trf area of dest. +; ER_Dst_Abs_Beg_High - High word of beginning trf area of dest. +; +; ER_Dst_Abs_End_Low - Low word of ending trf area of dest. +; ER_Dst_Abs_End_High - High word of ending trf area of dest. +; +; Outputs : NC - no overlap +; CY - overlap +; +; Algorithm : +; +; If Beg.Src.Add. < Beg.Dst.Add +; If (End.Src.Add - Beg.Dst.Add) > 0 +; signal OVERLAP +; Else +; signal NO-OVERLAP +; EndIf +; Else +; If (End.Dst.Add - Beg.Src.Add) > 0 +; signal OVERLAP +; Else +; signal NO-OVERLAP +; EndIf +; EndIf +;========================================================================= + +ER_General_Overlap_Test proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push bx ; ;an000; dms; + push cx ; ;an000; dms; + push dx ; ;an000; dms; + + mov ax,cs:[bp].ER_Src_Abs_Beg_High ;get source beg. add. ;an000; dms; + mov bx,cs:[bp].ER_Src_Abs_Beg_Low ; ;an000; dms; + mov cx,cs:[bp].ER_Dst_Abs_Beg_High ;get dest. beg. add. ;an000; dms; + mov dx,cs:[bp].ER_Dst_Abs_Beg_Low ; ;an000; dms; + call ER_Dword_Compare ; +; $if c ;< dest. beg. add.? ;an000; dms; + JNC ER_IF1 + mov ax,cs:[bp].ER_Src_Abs_End_Low ;get end address ;an000; dms; + mov dx,cs:[bp].ER_Src_Abs_End_High ; ;an000; dms; + sub ax,cs:[bp].ER_Dst_Abs_Beg_Low ;End.Src.Add-Beg.Dst.Add;an000; dms; + sbb dx,cs:[bp].ER_Dst_Abs_Beg_High ; ;an000; dms; +; $if ns ;yes - overlap ;an000; dms; + JS ER_IF2 + stc ;signal error ;an000; dms; + mov cs:[bp].ER_Direction_Flag,ER_Down ;signal reverse move ;an000; dms; +; $else ;no - not sure yet ;an000; dms; + JMP SHORT ER_EN2 +ER_IF2: + clc ;signal no overlap ;an000; dms; + mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms; +; $endif ; ;an000; dms; +ER_EN2: +; $else ;not sure if src < dst ;an000; dms; + JMP SHORT ER_EN1 +ER_IF1: + mov ax,cs:[bp].ER_Dst_Abs_End_Low ;get end address ;an000; dms; + mov dx,cs:[bp].ER_Dst_Abs_End_High ; ;an000; dms; + sub ax,cs:[bp].ER_Src_Abs_Beg_Low ;End.Dst.Add-Beg.Src.Add;an000; dms; + sbb dx,cs:[bp].ER_Src_Abs_Beg_High ; ;an000; dms; +; $if ns ;yes - overlap ;an000; dms; + JS ER_IF6 + stc ;signal error ;an000; dms; + mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms; +; $else ;no - not sure yet ;an000; dms; + JMP SHORT ER_EN6 +ER_IF6: + clc ;signal no overlap ;an000; dms; + mov cs:[bp].ER_Direction_Flag,ER_Up ;forward move ;an000; dms; +; $endif ; ;an000; dms; +ER_EN6: +; $endif ; ;an000; dms; +ER_EN1: + + pop dx ;restore regs ;an000; dms; + pop cx ; ;an000; dms; + pop bx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_General_Overlap_Test endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Dword_Compare : This routine determines whether or not a dword +; value is greater than another dword value. +; +; Inputs : AX - Source high word +; BX - Source low word +; CX - Destination high word +; DX - Destination low word +; +; Outputs : NC - source >= destination +; CY - source < destination +;========================================================================= + +ER_Dword_Compare proc ; ;an000; dms; + + cmp ax,cx ;src high < dest high? ;an000; dms; +; $if b ;yes ;an000; dms; + JNB ER_IF10 + stc ;signal less than ;an000; dms; +; $else ;no ;an000; dms; + JMP SHORT ER_EN10 +ER_IF10: + cmp ax,cx ;src high > dest high? ;an000; dms; +; $if a ;yes ;an000; dms; + JNA ER_IF12 + clc ;signal greater than ;an000; dms; +; $else ;no ;an000; dms; + JMP SHORT ER_EN12 +ER_IF12: + cmp bx,dx ;src low < dest low? ;an000; dms; +; $if b ;yes ;an000; dms; + JNB ER_IF14 + stc ;signal less than ;an000; dms; +; $else ;no ;an000; dms; + JMP SHORT ER_EN14 +ER_IF14: + cmp bx,dx ;src low > dest low? ;an000; dms; +; $if a ;yes ;an000; dms; + JNA ER_IF16 + clc ;signal greater than ;an000; dms; +; $else ;no ;an000; dms; + JMP SHORT ER_EN16 +ER_IF16: + clc ; ;an000; dms; +; $endif ; ;an000; dms; +ER_EN16: +; $endif ; ;an000; dms; +ER_EN14: +; $endif ; ;an000; dms; +ER_EN12: +; $endif ; ;an000; dms; +ER_EN10: + + ret ; ;an000; dms; + +ER_Dword_Compare endp ; ;an000; dms; + + + +;========================================================================= +; ER_Segment_Adjust : This routine adjusts the segment:offset to a value +; with an offset less than 16. +; +; Inputs : AX:DX - Segment:Offset to be adjusted +; +; Outputs : AX:DX - New Segment:Offset value +;========================================================================= + +ER_Segment_Adjust proc ;adjust segment value ;an000; dms; + + push bx ;save bx ;an000; dms; + push cx ; ;an000; dms; + + mov bx,ax ;save segment value ;an000; dms; + mov ax,dx ;get offset ;an000; dms; + xor dx,dx ;clear high word ;an000; dms; + mov cx,ER_10h ;divide by 10h ;an000; dms; + div cx ;get seg adjustment ;an000; dms; + ; factor + add ax,bx ;adjust segment up ;an000; dms; + ; dx contains new off. ;an000; dms; + pop cx ;restore regs ;an000; dms; + pop bx ;restore bx ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Segment_Adjust endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Log_Page_Test : This routine checks the offset specified for +; the logical page to determine if the offset is +; within the valid ranges for the page size. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +; Possible error codes: 95h +;========================================================================= + +ER_Log_Page_Test proc ; ;an000; dms; + + mov ax,EMS_Page_Size_In_Bytes ;get page size ;an000; dms; + + cmp [si].Source_Memory_Type,ER_EMS_Memory ;EMS memory specified? ;an000; dms; + jne ER_Log_Dest_Test ;no - check dest. ;an000; dms; + + cmp ax,[si].Source_Initial_Offset ;> EMS page size ;an000; dms; + jae ER_Log_Good_Exit ;good exit ;an000; dms; + jmp ER_Log_Error_Exit ;error - bad exit ;an000; dms; + +ER_Log_Dest_Test: + + cmp [si].Dest_Memory_Type,ER_EMS_Memory ;EMS memory specified? ;an000; dms; + jne ER_Log_Good_Exit ;good exit ;an000; dms; + + cmp ax,[si].Dest_Initial_Offset ;> EMS page size ;an000; dms; + jae ER_Log_Good_Exit ;good exit ;an000; dms; + +ER_Log_Error_Exit: + + mov ah,EMS_Code95 ;signal error ;an000; dms; + jmp ER_Log_Exit ;exit routine ;an000; dms; + +ER_Log_Good_Exit: + + xor ah,ah ;signal no error ;an000; dms; + +ER_Log_Exit: + + ret ;return to caller ;an000; dms; + +ER_Log_Page_Test endp ;end proc ;an000; dms; + +;========================================================================= +; ER_Save_Context : This routine saves the context for page frames +; needed for the move/exchange. +; +; Inputs : none +; +; Outputs : ER_Save_Context_Buffer - save context for the needed page frames +;========================================================================= + +ER_Save_Context proc ;save contexts ;an000; dms; + + push ax ;save regs ;an000; dms; + push cx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + push es ; ;an000; dms; + + mov ax,cs ;make ds/es = cs ;an000; dms; + mov ds,ax ; ;an000; dms; + mov es,ax ; ;an000; dms; + + mov si,offset cs:Map_Table ;ptr to page frame table;an000; dms; + mov di,offset cs:ER_Save_Context_Buffer ;get dest. offset + add di,bp ;offset BP relative ;an000; dms; + + mov cx,2 ;default frame save ;an000; dms; + cli ;ints off ;an000; dms; + cmp Map_Count,2 ;2 page frames? ;an000; dms; + jae ER_Save_Context_Loop ;< = 2 - continue ;an000; dms; + mov cx,Map_Count ;max frame count to save;an000; dms; + +ER_Save_Context_Loop: + + sti ;ints on ;an000; dms; + push cx ;save cx ;an000; dms; + mov cx,Type Mappable_Phys_Page_Struct ;get byte count to trf ;an000; dms; + cli ;ints off ;an000; dms; + rep movsb ;perform save ;an000; dms; + sti ;ints on ;an000; dms; + pop cx ;restore cx ;an000; dms; + loop ER_Save_Context_Loop ;continue ;an000; dms; + +ER_Save_Exit: + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop cx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Save_Context endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Restore_Context : This routine restores the context for page frames +; saved. These pages were used for the +; move/exchange requested. +; +; Inputs : ER_Save_Context_Buffer - contains saved context +; +; Outputs : restored context for the saved page frames +;========================================================================= + +ER_Restore_Context proc ;restore contexts ;an000; dms; + + push ax ;save regs ;an000; dms; + push cx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + push es ; ;an000; dms; + + mov ax,cs ;make ds/es = cs ;an000; dms; + mov ds,ax ; ;an000; dms; + mov es,ax ; ;an000; dms; + + mov di,offset cs:Map_Table ;ptr to page frame table;an000; dms; + mov si,offset cs:ER_Save_Context_Buffer ;get dest. offset + add si,bp ;offset BP relative ;an000; dms; + + mov cx,2 ;default frame restore ;an000; dms; + cli ;ints off ;an000; dms; + cmp Map_Count,2 ;2 page frames? ;an000; dms; + jae ER_Restore_Context_Loop ;< = 2 - continue ;an000; dms; + mov cx,Map_Count ;max frame count to rest;an000; dms; + +ER_Restore_Context_Loop: + + sti ;ints on ;an000; dms; + mov al,byte ptr ds:[si].Phys_Page_Number ;get physical page num. ;an000; dms; + mov bx,word ptr ds:[si].PPM_Log_Page ;get logical page num. ;an000; dms; + mov dx,word ptr ds:[si].PPM_Handle ;get handle number ;an000; dms; + call Map_L_To_P ;map in orig. page ;an000; dms; + + push cx ;save cx ;an000; dms; + mov cx,Type Mappable_Phys_Page_Struct ;get byte count to trf ;an000; dms; + cli ;ints off ;an000; dms; + rep movsb ;perform save ;an000; dms; + sti ;ints on ;an000; dms; + pop cx ;restore cx ;an000; dms; + loop ER_Restore_Context_Loop ;continue ;an000; dms; + +ER_Restore_Exit: + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop cx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Restore_Context endp ;end proc ;an000; dms; + + + +;========================================================================= +; ER_Det_Src_Dest_Seg : This routine determines the applicable segment, +; offset, and page to be used for the move/exchange. +; This routine sets the pages/addresses to the end +; of the area to be moved/exchanged, if the move +; is to be a reverse move. If the move is to be +; a forward move, the pages/addresses are set to +; the beginning of the area to be moved/exchanged. +; In this way an overlapping move can be +; performed without overlaying data it is to move. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : ER_Source_Seg - Segment value of source +; ER_Dest_Seg - Segment value of destination +; +; ER_Source_Off - Offset value of source +; ER_Dest_Off - Offset value of destination +; +; ER_Source_Page - Source EMS page +; ER_Dest_Page - Destination EMS page +; +; ER_Source_Handle - Source handle +; ER_Dest_Handle - Destination handle +; +; ER_Source_Phys_Page - Physical page number +; ER_Dest_Phys_Page - Physical page number +;========================================================================= + +ER_Det_Src_Dest_Seg proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push bx ; ;an000; dms; + push cx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push ds ; ;an000; dms; + push es ; ;an000; dms; + + + cmp [si].Source_Memory_Type,ER_EMS_Memory ;EMS? ;an000; dms; + jne ER_Det_Source_Conv ;no - conventional mem. ;an000; dms; + + mov di,offset cs:ER_Save_Context_Buffer ;get addressibility to ;an000; dms; + ; the page frame save + ;buffer + add di,bp ;offset BP relative + mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; + mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms; + + mov ax,[si].Source_Handle ;get source handle ;an000; dms; + mov cs:[bp].ER_Source_Handle,ax ;save handle ;an000; dms; + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF22 + mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms; + mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms; + add ax,[si].Source_Initial_Offset ;pick up offset value ;an000; dms; + adc dx,0 ;pick up carry ;an000; dms; + mov bx,4000h ;get page size ;an000; dms; + div bx ;get end logical page ;an000; dms; + add ax,[si].Source_Initial_Seg_Page ;adjust it for 1st. ;an000; dms; + mov cs:[bp].ER_Source_Page,ax ;save log. page ;an000; dms; + dec dx ;adjust to end point ;an000; dms; + mov cs:[bp].ER_Source_Off,dx ;save offset in last pg ;an000; dms; + +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN22 +ER_IF22: + mov ax,[si].Source_Initial_Seg_Page ;get page ;an000; dms; + mov dx,[si].Source_Initial_Offset ;get offset ;an000; dms; + mov cs:[bp].ER_Source_Page,ax ;save page ;an000; dms; + mov cs:[bp].ER_Source_Off,dx ;save offset ;an000; dms; +; $endif ; ;an000; dms; +ER_EN22: + mov ax,cs:[di].Phys_Page_Number ;get phys. page ;an000; dms; + mov cs:[bp].ER_Source_Phys_Page,ax ;save it ;an000; dms; + jmp ER_Det_Dest_Check ;jump to dest check ;an000; dms; + +ER_Det_Source_Conv: + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF25 + mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms; + mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms; + mov bx,ER_10h ;get bytes/para ;an000; dms; + div bx ;get para count ;an000; dms; + ; AX = para's + ; DX = offset + mov bx,ax ;save across adjust call;an000; dms; + mov cx,dx ; ;an000; dms; + mov ax,[si].Source_Initial_Seg_Page ;get seg value ;an000; dms; + mov dx,[si].Source_Initial_Offset ;get off value ;an000; dms; + dec dx ;adjust to end byte + call ER_Segment_Adjust ;adjust it downward ;an000; dms; + add ax,bx ;new segment value ;an000; dms; + add dx,cx ;new offset value ;an000; dms; + + mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms; + mov cs:[bp].ER_Source_Off,dx ;save offset in var ;an000; dms; +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN25 +ER_IF25: + mov ax,[si].Source_Initial_Seg_Page ;get seg value ;an000; dms; + mov dx,[si].Source_Initial_Offset ;get off value ;an000; dms; + mov cs:[bp].ER_Source_Seg,ax ;save it in variable ;an000; dms; + mov cs:[bp].ER_Source_Off,dx ;save offset in var ;an000; dms; +; $endif ; ;an000; dms; +ER_EN25: + + +ER_Det_Dest_Check: + + cmp [si].Dest_Memory_Type,ER_EMS_Memory ;Dest. EMS? ;an000; dms; + jne ER_Det_Dest_Conv ;no - conventional mem. ;an000; dms; + + mov di,offset cs:ER_Save_Context_Buffer ;save frame buffer ;an000; dms; + add di,bp ;offset BP relative ;an000; dms; + cli ;ints off ;an000; dms; + cmp Map_Count,1 ;> 1 page frame? ;an000; dms; + sti ;ints on ;an000; dms; + jb ER_Det_Dest_Check1 ;don't adjust pointer ;an000; dms; + add di,Type Mappable_Phys_Page_Struct ;next entry in save buf ;an000; dms; + +ER_Det_Dest_Check1: + + mov ax,cs:[di].Phys_Page_Segment ;get seg value ;an000; dms; + mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms; + + mov ax,[si].Dest_Handle ;get dest. handle ;an000; dms; + mov cs:[bp].ER_Dest_Handle,ax ;save handle ;an000; dms; + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF28 + mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms; + mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms; + add ax,[si].Dest_Initial_Offset ;pick up offset value ;an000; dms; + adc dx,0 ;pick up carry ;an000; dms; + + mov bx,4000h ;get page size ;an000; dms; + div bx ;get end logical page ;an000; dms; + add ax,[si].Dest_Initial_Seg_Page ;adjust it for 1st. ;an000; dms; + mov cs:[bp].ER_Dest_Page,ax ;save log. page ;an000; dms; + dec dx ;adjust to end point ;an000; dms; + mov cs:[bp].ER_Dest_Off,dx ;save off. in last page ;an000; dms; + +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN28 +ER_IF28: + mov ax,[si].Dest_Initial_Seg_Page ;get page ;an000; dms; + mov dx,[si].Dest_Initial_Offset ;get offset ;an000; dms; + mov cs:[bp].ER_Dest_Page,ax ;save log. page ;an000; dms; + mov cs:[bp].ER_Dest_Off,dx ;save off. in last page ;an000; dms; +; $endif ; ;an000; dms; +ER_EN28: + mov ax,cs:[di].Phys_Page_Number ;get phys page number ;an000; dms; + mov cs:[bp].ER_Dest_Phys_Page,ax ;save it ;an000; dms; + jmp ER_Det_Exit ;exit routine ;an000; dms; + +ER_Det_Dest_Conv: + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF31 + mov ax,[si].Region_Length_Low_Word ;get low word of move ;an000; dms; + mov dx,[si].Region_Length_High_Word ;get high word ;an000; dms; + mov bx,ER_10H ;get bytes/para ;an000; dms; + div bx ;get para count ;an000; dms; + ; AX = para's + ; DX = offset + mov bx,ax ;save across adjust call;an000; dms; + mov cx,dx ; ;an000; dms; + mov ax,[si].Dest_Initial_Seg_Page ;get seg value ;an000; dms; + mov dx,[si].Dest_Initial_Offset ;get off value ;an000; dms; + dec dx ;adjust to end byte ;an000; dms; + call ER_Segment_Adjust ;adjust it downward ;an000; dms; + add ax,bx ;new segment value ;an000; dms; + add dx,cx ;new offset value ;an000; dms; + + mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms; + mov cs:[bp].ER_Dest_Off,dx ;save offset in var ;an000; dms; +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN31 +ER_IF31: + mov ax,[si].Dest_Initial_Seg_Page ;get seg value ;an000; dms; + mov dx,[si].Dest_Initial_Offset ;get off value ;an000; dms; + mov cs:[bp].ER_Dest_Seg,ax ;save it in variable ;an000; dms; + mov cs:[bp].ER_Dest_Off,dx ;save offset in var ;an000; dms; +; $endif ; ;an000; dms; +ER_EN31: + + +ER_Det_Exit: + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop cx ; ;an000; dms; + pop bx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Det_Src_Dest_Seg endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Det_Move_Count : This initializes the count variables for the +; loop iteration counter of the move/exchange. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : ER_Move_Count_Low - low word value of move count +; ER_Move_Count_High - high word value of move count +;========================================================================= + + +ER_Det_Move_Count proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push dx ; ;an000; dms; + + mov ax,[si].Region_Length_Low_Word ;get low word count ;an000; dms; + mov dx,[si].Region_Length_High_Word ;get high word count ;an000; dms; + mov cs:[bp].ER_Move_Count_Low,ax ;save low word ;an000; dms; + mov cs:[bp].ER_Move_Count_High,dx ;save high word ;an000; dms; + + pop dx ;restore regs ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Det_Move_Count endp ;end proc ;an000; dms; + +;========================================================================= +; ER_Move_Source_To_Buffer : This routine moves the source data to +; the buffer before it is transferred to +; its final destination. +; +; Inputs : BP - carries type of memory for source/dest +; Bit 0 - Destination (EMS if set) +; Bit 1 - Source (EMS if set) +; +; Outputs : ER_Move_Xchg_Buffer1 - Source data +;========================================================================= + +ER_Move_Source_To_Buffer proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push bx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push es ; ;an000; dms; + + test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms; + jz ER_Move_Source_Conv_Mem ;no - adjust seg:off ;an000; dms; + jmp ER_Move_Source_EMS_Mem ;yes- continue move ;an000; dms; + +ER_Move_Source_Conv_Mem: + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF34 + mov ax,ds ;adjust segment:off ;an000; dms; + dec ax ;segment - 1 para ;an000; dms; + mov ds,ax ; ;an000; dms; + add si,ER_10H ;adjust offset for 1 ;an000; dms; +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN34 +ER_IF34: + mov ax,ds ;get segment value ;an000; dms; + mov dx,si ;get offset value ;an000; dms; + call ER_Segment_Adjust ;adjust the seg:off ;an000; dms; + mov ds,ax ;restore ds ;an000; dms; + mov si,dx ;restore offset ;an000; dms; +; $endif ; ;an000; dms; +ER_EN34: + jmp ER_Move_Source_Count ;determine count ;an000; dms; + +ER_Move_Source_EMS_Mem: + + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF37 + cmp si,0ffffh ;beginning of log page ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF38 + dec cs:[bp].ER_Source_Page ;adjust page ptr ;an000; dms; + mov si,EMS_Page_Size_In_Bytes;get page size ;an000; dms; +; $endif ; ;an000; dms; +ER_IF38: +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN37 +ER_IF37: + cmp si,4000h ;wrap beyond page ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF41 + inc cs:[bp].ER_Source_Page ;adjust page ptr ;an000; dms; + xor si,si ;clear si ;an000; dms; +; $endif ; ;an000; dms; +ER_IF41: +; $endif ; ;an000; dms; +ER_EN37: + mov bx,cs:[bp].ER_Source_Page ;pass page to map ;an000; dms; + call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms; + +ER_Move_Source_Count: + + mov cx,ER_10H ;default count ;an000; dms; + cmp cs:[bp].ER_Move_Count_High,0 ;high word set ;an000; dms; + jne ER_Move_Source_High_Set ;yes - use default ;an000; dms; + cmp cs:[bp].ER_Move_Count_Low,cx ;>= 10h bytes ;an000; dms; + jae ER_Move_Source_High_Set ;yes - use default ;an000; dms; + mov cx,cs:[bp].ER_Move_Count_Low ;no - use last few bytes;an000; dms; + +ER_Move_Source_High_Set: + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF44 + cmp si,di ;source >= dest? ;an000; dms; +; $if b ;no ;an000; dms; + JNB ER_IF45 + cmp si,ER_10H ;source >= 10h? ;an000; dms; +; $if b ;no ;an000; dms; + JNB ER_IF46 + mov cx,si ;get move count ;an000; dms; + inc cx ;always 1 byte off ;an000; dms; +; $endif ; ;an000; dms; +ER_IF46: +; $else ;source >= dest ;an000; dms; + JMP SHORT ER_EN45 +ER_IF45: + cmp di,ER_10H ;dest >= 10h? ;an000; dms; +; $if b ;no ;an000; dms; + JNB ER_IF49 + mov cx,di ;get move count ;an000; dms; + inc cx ;always 1 byte off ;an000; dms; +; $endif ; ;an000; dms; +ER_IF49: +; $endif ; ;an000; dms; +ER_EN45: +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN44 +ER_IF44: + cmp si,di ;source >= dest? ;an000; dms; +; $if a ;yes ;an000; dms; + JNA ER_IF53 + mov ax,4000h ;get end of page ;an000; dms; + sub ax,si ;get bytes remaining ;an000; dms; + cmp ax,ER_10H ;source >= 10h ;an000; dms; +; $if b ;no ;an000; dms; + JNB ER_IF54 + mov cx,ax ;get remaining count ;an000; dms; +; $endif ; ;an000; dms; +ER_IF54: +; $else ;source >= dest ;an000; dms; + JMP SHORT ER_EN53 +ER_IF53: + mov ax,4000h ;get end of page ;an000; dms; + sub ax,di ;get bytes remaining ;an000; dms; + cmp ax,ER_10H ;dest >= 10h ;an000; dms; +; $if b ;no ;an000; dms; + JNB ER_IF57 + mov cx,ax ;get remaining count ;an000; dms; +; $endif ; ;an000; dms; +ER_IF57: +; $endif ; ;an000; dms; +ER_EN53: +; $endif ; ;an000; dms; +ER_EN44: + + jmp ER_Move_Source_Default_Count ;continue routine ;an000; dms; + +ER_Move_Source_Default_Count: + + mov cs:[bp].ER_Current_Move_Count,cx ;save current move cnt ;an000; dms; + + sub cs:[bp].ER_Move_Count_Low,cx ;get new count ;an000; dms; + sbb cs:[bp].ER_Move_Count_High,0 ;pick up borrow ;an000; dms; + + mov ax,cs ;get seg for buffer ;an000; dms; + mov es,ax ;put into es ;an000; dms; + mov di,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms; + add di,bp ;offset BP relative ;an000; dms; + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF61 + add di,ER_10H ;end of buffer + 1 ;an000; dms; + dec di ;end of buffer ;an000; dms; +; $endif ; ;an000; dms; +ER_IF61: + + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF63 + std ;reverse move ;an000; dms; +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN63 +ER_IF63: + cld ; ;an000; dms; +; $endif ; ;an000; dms; +ER_EN63: + cli ;ints off ;an000; dms; + rep movsb ;move the data ;an000; dms; + sti ;ints on ;an000; dms; + +ER_Move_Source_Exit: + + pop es ;restore regs ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop bx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Move_Source_To_Buffer endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Move_Buffer_To_Dest : This routine moves the data in the buffer +; to the destination specified by the user. +; +; Inputs : BP - carries type of memory for source/dest +; Bit 0 - Destination (EMS if set) +; Bit 1 - Source (EMS if set) +; ER_Move_Xchg_Buffer1 - Source data +; +; Outputs : Adjusted segment:offset or page/offset +;========================================================================= + +ER_Move_Buffer_To_Dest proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push bx ; ;an000; dms; + push dx ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + + test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Source EMS? ;an000; dms; + jz ER_Move_Buffer_Conv_Mem ;no - adjust seg:off ;an000; dms; + jmp ER_Move_Buffer_EMS_Mem ;yes- continue move ;an000; dms; + +ER_Move_Buffer_Conv_Mem: + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF66 + mov ax,es ;adjust segment:off ;an000; dms; + dec ax ;segment - 1 para ;an000; dms; + mov es,ax ; ;an000; dms; + add di,ER_10H ;adjust offset for 1 ;an000; dms; +; $else ;forward move? ;an000; dms; + JMP SHORT ER_EN66 +ER_IF66: + mov ax,es ;adjust seg:off ;an000; dms; + mov dx,di ; ;an000; dms; + call ER_Segment_Adjust ; ;an000; dms; + mov es,ax ;new seg:off ;an000; dms; + mov di,dx ; ;an000; dms; +; $endif ; ;an000; dms; +ER_EN66: + ; para + jmp ER_Move_Buffer_Count ;determine count ;an000; dms; + +ER_Move_Buffer_EMS_Mem: + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF69 + cmp di,0ffffh ;beginning of log page ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF70 + dec cs:[bp].ER_Dest_Page ;next page ;an000; dms; + mov di,EMS_Page_Size_In_Bytes;end of page ;an000; dms; +; $endif ; ;an000; dms; +ER_IF70: +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN69 +ER_IF69: + cmp di,4000h ;end of page? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF73 + inc cs:[bp].ER_Dest_Page ;next page ;an000; dms; + xor di,di ;clear di ;an000; dms; +; $endif ; ;an000; dms; +ER_IF73: +; $endif ; ;an000; dms; +ER_EN69: + mov bx,cs:[bp].ER_Dest_Page ;pass page to map ;an000; dms; + call ER_Map_Next_Dest_Page ;map in the page ;an000; dms; + +ER_Move_Buffer_Count: + + mov cx,cs:[bp].ER_Current_Move_Count ;get move from source ;an000; dms; + + mov ax,cs ;get seg for buffer ;an000; dms; + mov ds,ax ;put into es ;an000; dms; + mov si,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms; + add si,bp ;offset BP relative ;an000; dms; + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF76 + add si,ER_10H ;end of buffer + 1 ;an000; dms; + dec si ;end of buffer ;an000; dms; +; $endif ; ;an000; dms; +ER_IF76: + + cmp cs:[bp].ER_Direction_Flag,ER_Down ;reverse move? ;an000; dms; +; $if e ;yes ;an000; dms; + JNE ER_IF78 + std ;reverse move ;an000; dms; +; $else ;forward move ;an000; dms; + JMP SHORT ER_EN78 +ER_IF78: + cld ; ;an000; dms; +; $endif ; ;an000; dms; +ER_EN78: + cli ;ints off ;an000; dms; + rep movsb ;move the data ;an000; dms; + sti ;ints on ;an000; dms; + +ER_Move_Dest_Exit: + + pop ds ;restore regs ;an000; dms; + pop si ; ;an000; dms; + pop dx ; ;an000; dms; + pop bx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Move_Buffer_To_Dest endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Xchg_Source_To_Buffer : This routine moves the source data to +; the buffer before it is exchanged with +; the destination data. +; +; Inputs : BP - carries type of memory for source/dest +; Bit 0 - Destination (EMS if set) +; Bit 1 - Source (EMS if set) +; +; Outputs : ER_Move_Xchg_Buffer1 - Source data +;========================================================================= + +ER_Xchg_Source_To_Buffer proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push bx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + push es ; ;an000; dms; + + test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms; + jz ER_Xchg_Source_Conv_Mem ;no - adjust seg:off ;an000; dms; + jmp ER_Xchg_Source_EMS_Mem ;yes- continue move ;an000; dms; + +ER_Xchg_Source_Conv_Mem: + + mov ax,ds ;adjust segment:off ;an000; dms; + mov dx,si ; ;an000; dms; + call ER_Segment_Adjust ; ;an000; dms; + mov ds,ax ;new segment:off ;an000; dms; + mov si,dx ; ;an000; dms; + jmp ER_Xchg_Source_Count ;determine count ;an000; dms; + +ER_Xchg_Source_EMS_Mem: + + cmp si,4000h ;beginning of log page ;an000; dms; + je ER_Xchg_Source_EMS_Next ;yes - get next page ;an000; dms; + mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms; + call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms; + jmp ER_Xchg_Source_Count ;get count for move ;an000; dms; + +ER_Xchg_Source_EMS_Next: + + mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms; + inc bx ; adjusted upward ;an000; dms; + call ER_Map_Next_Src_Page ;map in the page ;an000; dms; + xor si,si ;reinit pointer ;an000; dms; + +ER_Xchg_Source_Count: + + mov cx,ER_10H ;default count ;an000; dms; + cmp cs:[bp].ER_Move_Count_High,0 ;high word set ;an000; dms; + jne ER_Xchg_Source_High_Set ;yes - use default ;an000; dms; + cmp cs:[bp].ER_Move_Count_Low,cx ;>= 10h bytes ;an000; dms; + jae ER_Xchg_Source_High_Set ;yes - use default ;an000; dms; + mov cx,cs:[bp].ER_Move_Count_Low ;no - use last few bytes;an000; dms; + +ER_Xchg_Source_High_Set: + + cmp si,di ;source >= dest? ;an000; dms; +; $if b ;no ;an000; dms; + JNB ER_IF81 + mov ax,4000h ;get end of page ;an000; dms; + sub ax,si ;get bytes remaining ;an000; dms; + cmp ax,ER_10H ;source >= 10h ;an000; dms; +; $if b ;no ;an000; dms; + JNB ER_IF82 + mov cx,ax ;get remaining count ;an000; dms; +; $endif ; ;an000; dms; +ER_IF82: +; $else ;source >= dest ;an000; dms; + JMP SHORT ER_EN81 +ER_IF81: + mov ax,4000h ;get end of page ;an000; dms; + sub ax,di ;get bytes remaining ;an000; dms; + cmp ax,ER_10H ;dest >= 10h ;an000; dms; +; $if b ;no ;an000; dms; + JNB ER_IF85 + mov cx,ax ;get remaining count ;an000; dms; +; $endif ; ;an000; dms; +ER_IF85: +; $endif ; ;an000; dms; +ER_EN81: + +ER_Xchg_Source_Default_Count: + + mov cs:[bp].ER_Current_Move_Count,cx ;save current move cnt ;an000; dms; + + sub cs:[bp].ER_Move_Count_Low,cx ;get new count ;an000; dms; + sbb cs:[bp].ER_Move_Count_High,0 ;pick up borrow ;an000; dms; + + mov ax,cs ;get seg for buffer ;an000; dms; + mov es,ax ;put into es ;an000; dms; + mov di,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms; + add di,bp ;offset BP relative ;an000; dms; + + cld ;forward move ;an000; dms; + cli ;ints off ;an000; dms; + rep movsb ;move the data ;an000; dms; + sti ;ints on ;an000; dms; + +ER_Xchg_Source_Exit: + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop bx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Xchg_Source_To_Buffer endp ;end proc ;an000; dms; + + +;========================================================================= +; ER_Xchg_Dest_To_Buffer : This routine moves the destination data to +; the buffer before it is exchanged with +; the source data. +; +; Inputs : BP - carries type of memory for source/dest +; Bit 0 - Destination (EMS if set) +; Bit 1 - Source (EMS if set) +; +; Outputs : ER_Move_Xchg_Buffer2 - Destination data +;========================================================================= + +ER_Xchg_Dest_To_Buffer proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push bx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + push es ; ;an000; dms; + + test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Dest EMS? ;an000; dms; + jz ER_Xchg_Dest_Conv_Mem ;no - adjust seg:off ;an000; dms; + jmp ER_Xchg_Dest_EMS_Mem ;yes- continue move ;an000; dms; + +ER_Xchg_Dest_Conv_Mem: + + mov ax,es ;adjust segment:off ;an000; dms; + mov dx,di ; ;an000; dms; + call ER_Segment_Adjust ; ;an000; dms; + mov es,ax ;new segment:off ;an000; dms; + mov di,dx ; ;an000; dms; + jmp ER_Xchg_Dest_Count ;determine count ;an000; dms; + +ER_Xchg_Dest_EMS_Mem: + + cmp di,4000h ;beginning of log page ;an000; dms; + je ER_Xchg_Dest_EMS_Next ;yes - get next page ;an000; dms; + mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms; + call ER_Map_Next_Dest_Page ;no - map in current pg;an000; dms; + jmp ER_Xchg_Dest_Count ;get count for move ;an000; dms; + +ER_Xchg_Dest_EMS_Next: + + mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms; + inc bx ; adjusted upward ;an000; dms; + call ER_Map_Next_Dest_Page ;map in the page ;an000; dms; + xor di,di ;reinit pointer ;an000; dms; + +ER_Xchg_Dest_Count: + + mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms; + mov ax,es ;get destination seg ;an000; dms; + mov ds,ax ;put into ds for buffer ;an000; dms; + ; transfer + mov si,di ;get destination off ;an000; dms; + mov ax,cs ;get seg for buffer ;an000; dms; + mov es,ax ;put into es ;an000; dms; + mov di,offset cs:ER_Move_Xchg_Buffer2 ;offset of buffer ;an000; dms; + add di,bp ;offset BP relative ;an000; dms; + + cld ;forward move ;an000; dms; + cli ;ints off ;an000; dms; + rep movsb ;move the data ;an000; dms; + sti ;ints on ;an000; dms; + +ER_Xchg_Dest_Exit: + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop bx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Xchg_Dest_To_Buffer endp ;end proc ;an000; dms; + + + + +;========================================================================= +; ER_Xchg_Buffer_To_Source ; This routine performs the actual exchange +; from the destination buffer to the source +; buffer. +; +; Inputs : BP - carries type of memory for source/dest +; Bit 0 - Destination (EMS if set) +; Bit 1 - Source (EMS if set) +; ER_Move_Xchg_Buffer2 - Destination data +; +; Outputs : Adjusted segment:offset or page/offset +;========================================================================= + +ER_Xchg_Buffer_To_Source proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push bx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push es ; ;an000; dms; + + test cs:[bp].ER_Mem_Type,ER_Source_EMS_Memory;Source EMS? ;an000; dms; + jz ER_Xchg_Buf2_Conv_Mem ;no - adjust seg:off ;an000; dms; + jmp ER_Xchg_Buf2_EMS_Mem ;yes- continue move ;an000; dms; + +ER_Xchg_Buf2_Conv_Mem: + + mov ax,ds ;adjust segment:off ;an000; dms; + mov dx,si ; ;an000; dms; + call ER_Segment_Adjust ; ;an000; dms; + mov ds,ax ;new segment:off ;an000; dms; + mov si,dx ; ;an000; dms; + jmp ER_Xchg_Buf2_Count ;determine count ;an000; dms; + +ER_Xchg_Buf2_EMS_Mem: + + cmp si,4000h ;beginning of log page ;an000; dms; + je ER_Xchg_Buf2_EMS_Next ;yes - get next page ;an000; dms; + mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms; + call ER_Map_Next_Src_Page ;no - map in current pg;an000; dms; + jmp ER_Xchg_Buf2_Count ;get count for move ;an000; dms; + +ER_Xchg_Buf2_EMS_Next: + + inc cs:[bp].ER_Source_Page ;adjust log page ;an000; dms; + mov bx,cs:[bp].ER_Source_Page ;pass log. page to call ;an000; dms; + call ER_Map_Next_Src_Page ;map in the page ;an000; dms; + xor si,si ;reinit pointer ;an000; dms; + +ER_Xchg_Buf2_Count: + + mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms; + + mov ax,ds ;get destination seg ;an000; dms; + mov es,ax ;put into ds for buffer ;an000; dms; + ; transfer + mov di,si ;get destination off ;an000; dms; + add si,cx ;adjust source ptr ;an000; dms; + push si ;save across xchg ;an000; dms; + push ds ; ;an000; dms; + + mov ax,cs ;get seg for buffer ;an000; dms; + mov ds,ax ;put into es ;an000; dms; + mov si,offset cs:ER_Move_Xchg_Buffer2 ;offset of buffer ;an000; dms; + add si,bp ;offset BP relative ;an000; dms; + + cld ;forward move ;an000; dms; + cli ;ints off ;an000; dms; + rep movsb ;move the data ;an000; dms; + sti ;ints on ;an000; dms; + + pop ds ;restore ptr ;an000; dms; + pop si ; ;an000; dms; + +ER_Xchg_Buf2_Exit: + + pop es ;restore regs ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop bx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Xchg_Buffer_To_Source endp ;end proc ;an000; dms; + + + +;========================================================================= +; ER_Xchg_Buffer_To_Dest ; This routine performs the actual exchange +; from the source buffer to the destination. +; +; Inputs : BP - carries type of memory for source/dest +; Bit 0 - Destination (EMS if set) +; Bit 1 - Source (EMS if set) +; ER_Move_Xchg_Buffer1 - Source data +; +; Outputs : Adjusted segment:offset or page/offset +;========================================================================= + +ER_Xchg_Buffer_To_Dest proc ; ;an000; dms; + + push ax ;save regs ;an000; dms; + push bx ; ;an000; dms; + push dx ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + + test cs:[bp].ER_Mem_Type,ER_Dest_EMS_Memory ;Dest EMS? ;an000; dms; + jz ER_Xchg_Buf1_Conv_Mem ;no - adjust seg:off ;an000; dms; + jmp ER_Xchg_Buf1_EMS_Mem ;yes- continue move ;an000; dms; + +ER_Xchg_Buf1_Conv_Mem: + + mov ax,es ;adjust segment:off ;an000; dms; + mov dx,di ; ;an000; dms; + call ER_Segment_Adjust ; ;an000; dms; + mov es,ax ;new segment:off ;an000; dms; + mov di,dx ; ;an000; dms; + jmp ER_Xchg_Buf1_Count ;determine count ;an000; dms; + +ER_Xchg_Buf1_EMS_Mem: + + cmp di,4000h ;beginning of log page ;an000; dms; + je ER_Xchg_Buf1_EMS_Next ;yes - get next page ;an000; dms; + mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms; + call ER_Map_Next_Dest_Page ;no - map in current pg;an000; dms; + jmp ER_Xchg_Buf1_Count ;get count for move ;an000; dms; + +ER_Xchg_Buf1_EMS_Next: + + inc cs:[bp].ER_Dest_Page ;adjust log page ;an000; dms; + mov bx,cs:[bp].ER_Dest_Page ;pass log. page to call ;an000; dms; + call ER_Map_Next_Dest_Page ;map in the page ;an000; dms; + mov di,EMS_Page_Size_In_Bytes ;reinit pointer ;an000; dms; + +ER_Xchg_Buf1_Count: + + mov cx,cs:[bp].ER_Current_Move_Count ;get move count ;an000; dms; + mov ax,cs ;get seg for buffer ;an000; dms; + mov ds,ax ;put into es ;an000; dms; + mov si,offset cs:ER_Move_Xchg_Buffer1 ;offset of buffer ;an000; dms; + add si,bp ;offset BP relative ;an000; dms; + + cld ;forward move ;an000; dms; + cli ;ints off ;an000; dms; + rep movsb ;move the data ;an000; dms; + sti ;ints on ;an000; dms; + +ER_Xchg_Buf1_Exit: + + pop ds ;restore regs ;an000; dms; + pop si ; ;an000; dms; + pop dx ; ;an000; dms; + pop bx ; ;an000; dms; + pop ax ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Xchg_Buffer_To_Dest endp ;end proc ;an000; dms; + + + +;========================================================================= +; ER_Map_Next_Src_Page : This routine maps in the page needed by +; the source of the move/exchange. +; +; Inputs : ER_Source_Phys_Page - Physical page of source +; ER_Source_Handle - Handle of source +; BX - logical page +; +; Outputs : newly mapped page +;========================================================================= + +ER_Map_Next_Src_Page proc ;map next src. page ;an000; dms; + + mov ax,cs:[bp].ER_Source_Phys_Page ;map the source page ;an000; dms; + mov dx,cs:[bp].ER_Source_Handle ;handle to use ;an000; dms; + call Map_L_To_P ;map the page ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Map_Next_Src_Page endp ;end proc ;an000; dms; + +;========================================================================= +; ER_Map_Next_Dest_Page : This routine maps in the page needed by +; the destination of the move/exchange. +; +; Inputs : ER_Dest_Phys_Page - Physical page of source +; ER_Dest_Handle - Handle of source +; BX - logical page to map +; +; Outputs : newly mapped page +;========================================================================= + +ER_Map_Next_Dest_Page proc ;map next dest. page ;an000; dms; + + mov ax,cs:[bp].ER_Dest_Phys_Page ;map the dest. page ;an000; dms; + mov dx,cs:[bp].ER_Dest_Handle ;handle to use ;an000; dms; + call Map_L_To_P ;map the page ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Map_Next_Dest_Page endp ;end proc ;an000; dms; + +;========================================================================= +; ER_Move_Data : This routine will perform the actual move of the +; data for the function 5700h. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +;========================================================================= + +ER_Move_Data proc ;move the data ;an000; dms; + + push bx ;save regs ;an000; dms; + push cx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + push es ; ;an000; dms; + + call ER_Save_Context ;save off max of 2 pages;an000; dms; + call ER_Det_Src_Dest_Seg ;determine segs ;an000; dms; + call ER_Det_Move_Count ;ER_10h_Move_Count = ;an000; dms; + ; # of 10h moves + ;ER_10h_Move_Remainder = + ; # of bytes remaining + +ER_Move_Data_Now: + + ;set the flags to signal + ;the memory type in use + ;for Source/Destination. + + xor al,al ;al signals type of mem ;an000; dms; + or al,[si].Source_Memory_Type ;get source memory type ;an000; dms; + shl al,1 ;put into bit 1 ;an000; dms; + or al,[si].Dest_Memory_Type ;get dest. memory type ;an000; dms; + cbw ;make it a word value ;an000; dms; + mov cs:[bp].ER_Mem_Type,ax ;put flags in var ;an000; dms; + ;bp = bit 0 - dest mem + ; bit 1 - src mem + + mov di,cs:[bp].ER_Dest_Off ;get dest. offset ;an000; dms; + mov es,cs:[bp].ER_Dest_Seg ;get dest. seg ;an000; dms; + + mov si,cs:[bp].ER_Source_Off ;get src. offset ;an000; dms; + mov ds,cs:[bp].ER_Source_Seg ;get src. seg ;an000; dms; + +ER_Move_Data_Loop: + + call ER_Move_Source_To_Buffer ;move data to buffer ;an000; dms; + call ER_Move_Buffer_To_Dest ;move buffer to dest. ;an000; dms; + + cmp cs:[bp].ER_Move_Count_High,0 ;end of move? ;an000; dms; + jne ER_Move_Data_Loop ;no - continue loop ;an000; dms; + cmp cs:[bp].ER_Move_Count_Low,0 ;end of move? ;an000; dms; + jne ER_Move_Data_Loop ;no - continue loop ;an000; dms; + ;yes - end of loop ;an000; dms; + +ER_Move_Data_Error_Exit: + + call ER_Restore_Context ;restore the context ;an000; dms; + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop cx ; ;an000; dms; + pop bx ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Move_Data endp ;end proc ;an000; dms; + + + +;========================================================================= +; ER_Exchange_Data : This routine will perform the actual exchange of +; data for the function 5701h. +; +; Inputs : DS:SI - Pointer to Move_Source_Dest_Struc data +; +; Outputs : AH - Non-zero on error +;========================================================================= + +ER_Exchange_Data proc ;xchg the data ;an000; dms; + + push bx ;save regs ;an000; dms; + push cx ; ;an000; dms; + push dx ; ;an000; dms; + push di ; ;an000; dms; + push si ; ;an000; dms; + push ds ; ;an000; dms; + push es ; ;an000; dms; + + call ER_Save_Context ;save off max of 2 pages;an000; dms; + call ER_Det_Src_Dest_Seg ;determine segs ;an000; dms; + call ER_Det_Move_Count ;ER_10h_Move_Count = ;an000; dms; + ; # of 10h moves + ;ER_10h_Move_Remainder = + ; # of bytes remaining + +ER_Xchg_Data_Now: + + ;set the flags to signal + ;the memory type in use + ;for Source/Destination. + + xor al,al ;al signals type of mem ;an000; dms; + or al,[si].Source_Memory_Type ;get source memory type ;an000; dms; + shl al,1 ;put into bit 1 ;an000; dms; + or al,[si].Dest_Memory_Type ;get dest. memory type ;an000; dms; + cbw ;make it a word value ;an000; dms; + mov cs:[bp].ER_Mem_Type,ax ;put flags in var ;an000; dms; + ;bp = bit 0 - dest mem + ; bit 1 - src mem + + mov di,cs:[bp].ER_Dest_Off ;get dest. offset ;an000; dms; + mov es,cs:[bp].ER_Dest_Seg ;get dest. seg ;an000; dms; + + mov si,cs:[bp].ER_Source_Off ;get src. offset ;an000; dms; + mov ds,cs:[bp].ER_Source_Seg ;get src. seg ;an000; dms; + +ER_Xchg_Data_Loop: + + call ER_Xchg_Source_To_Buffer ;move source to buf 1 ;an000; dms; + call ER_Xchg_Dest_To_Buffer ;move dest. to buf 2 ;an000; dms; + call ER_Xchg_Buffer_To_Source ;move buf2 to source ;an000; dms; + call ER_Xchg_Buffer_To_Dest ;move buf1 to dest. ;an000; dms; + + cmp cs:[bp].ER_Move_Count_High,0 ;end of move? ;an000; dms; + jne ER_Xchg_Data_Loop ;no - continue loop ;an000; dms; + cmp cs:[bp].ER_Move_Count_Low,0 ;end of move? ;an000; dms; + jne ER_Xchg_Data_Loop ;no - continue loop ;an000; dms; + ;yes - end of loop ;an000; dms; + +ER_Xchg_Data_Error_Exit: + + call ER_Restore_Context ;restore the context ;an000; dms; + + pop es ;restore regs ;an000; dms; + pop ds ; ;an000; dms; + pop si ; ;an000; dms; + pop di ; ;an000; dms; + pop dx ; ;an000; dms; + pop cx ; ;an000; dms; + pop bx ; ;an000; dms; + + ret ;return to caller ;an000; dms; + +ER_Exchange_Data endp ;end proc ;an000; dms; + + + + page + +;========================================================================= +;=============== Function 5Ah Logic - Allocate Raw Pages ============= +;========================================================================= + + +;========================================================================= +; Alloc_Raw - This routine allocates raw EMS pages, pages +; less than the standard 16k page. These pages +; are a sub-multiple of 16k. In the IBM version +; of this implementation the raw page is defined +; as 16k, thus we do not need to do anything +; special here. We map this call to the proc +; GET_HANDLE (function 43h) to allocate a handle. +; +; Inputs : AH - 5Ah (Allocate Raw Pages) +; BX - Number of raw pages to allocate +; +; Outputs : AH - Non-zero if error (Determined by Get_Handle proc) +; DX - Handle if no error +;========================================================================= + +Alloc_Raw proc ;Allocate raw pages ;an000; dms; + + PUSH BX + PUSH CX + PUSH DI + PUSH SI + PUSH DS ;save these registers + + PUSH CS ;get cs + POP DS ;into ds + + ;Remove test for BX = 0. This is @RH4 + ; valid under LIM 4.0 + + cmp al,AR_Sub_Max ;sub function out of range? ;an000; dms; + jna AR_OKSub ;no ;an000; dms; + mov ah,EMS_Code8F ;yes-signal error ;an000; dms; + jmp AR_Exit ;exit routine ;an000; dms; + +AR_OKSub: + + CMP BX,TOTAL_EMS_PAGES ;Enough total EMS pages? + JNA AR_OKTOTAL + MOV AH,EMS_CODE87 + JMP AR_EXIT + +AR_OKTOTAL: + cli ;ints off ;an000; dms; + CMP BX,FREE_PAGES ;Enough unallocated pages? + sti ;ints on ;an000; dms; + JNA AR_OKFREE + MOV AH,EMS_CODE88 + JMP AR_EXIT + ;----------------------------------------------------- + ; Search for a free handle @RH1 º + ;----------------------------------------------------- +AR_OKFREE: + MOV CX,NUM_HANDLES ;loop counter is #handles + DEC CX ;handle 0 reserved for op. sys. @RH1 + MOV DX,1 ;handle assignment set to 1 @RH1 + MOV DI,TYPE H_LOOKUP_STRUC ;init table index to 1st entry @RH1 +;-------------------------------- + CLI ;interrupts OFF during allocation +;-------------------------------- +AR_FREEHSRCH: + CMP HANDLE_LOOKUP_TABLE.H_PAGES[DI],REUSABLE_HANDLE + ;Is this handle available? @RH1 + JE AR_HFREE ;yes end search dx=handle id @RH1 + INC DX ;next handle assignment + ADD DI,TYPE H_LOOKUP_STRUC ;next entry in handle lookup @RH1 + ;repeat for all table entries + LOOP AR_FREEHSRCH + MOV AH,EMS_CODE85 ;no available handles + JMP AR_EXIT ;go to exit ;GGA + + ;----------------------------------------------------- + ; If here then there's enough pages for request. @RH1 º + ; DX = handle #, DI = ptr to hndl lookup entry @RH1 º +AR_HFREE: + + MOV CX,NUM_HANDLES ;loop counter + DEC CX ;handle 0 reserved for op. sys. @RH1 + ;si = index to hndl lookup tbl @RH1 + MOV SI,TYPE H_LOOKUP_STRUC ; for adding pages (skip 0 entry) @RH1 + XOR AX,AX ;clear page counter + CLC ;clear carry for addition +AR_PAGESUM: + CMP HANDLE_LOOKUP_TABLE.H_PAGES[SI],REUSABLE_HANDLE + JE AR_PGSUM_BOT ;If handle is free don't add @RH4 + ADD AX,HANDLE_LOOKUP_TABLE.H_PAGES[SI] + ;add lengths (pages) of PALs @RH1 + ADD SI,TYPE H_LOOKUP_STRUC ; next entry in handle lookup @RH1 +AR_PGSUM_BOT: + LOOP AR_PAGESUM + CMP AX,TOTAL_EMS_PAGES ;pages in handle lookup > total? @RH1 + JNA AR_CALCHLUP ;no OK @RH1 + MOV AH,EMS_CODE80 ;software error..we screwed up @RH1 + JMP AR_EXIT ;go to exit @RH1 ;GGA + +AR_CALCHLUP: ;calculate entry in hndl lkup tbl @RH1 + cmp bx,0 ;page request? ;an000; dms; + jne AR_Alloc_Cont ;yes continue ;an000; dms; + cli ;ints off ;an001; dms; + mov Handle_LookUp_Table.H_Pages[di],bx ;new page count ;an001; dms; + sti ;ints on ;an001; dms; + xor ah,ah ;clear flag ;an000; dms; + jmp AR_Exit ;exit routine ;an000; dms; + +AR_Alloc_Cont: + + cli ;ints off ;an001; dms; + mov cx,bx ;alloc count ;an000; dms; + call EMS_Page_Contig_Chk ;do we have contig pgs. ;an001; dms; + jnc AR_Alloc ;yes continue process ;an001; dms; + mov ah,EMS_Code88 ;no signal error ;an001; dms; + sti ;ints on ;an001; dms; + jmp AR_Exit ;exit routine ;an001; dms; + +AR_Alloc: + + call EMS_Link_Set ;set up links ;an001; dms; + + + sub Free_Pages,bx ;free = free - requested pages + mov Handle_LookUp_Table.H_Pages[di],bx ;page count ;an000; dms; + mov Handle_LookUp_Table.H_Pal_Ptr[di],si ;initialize to ptr for ;ac001; dms; + ; pages + sti ;ints on ;an001; dms; + xor ah,ah ;clear flag ;an000; dms; + + +AR_EXIT: ;GGA + + POP DS + POP SI + POP DI + POP CX + POP BX + + ret ;return to caller ;an000; dms; + +Alloc_Raw endp ;end proc ;an000; dms; + + page +;========================================================================= +;=============== Function 5Ch Logic - Prepare for Warm Boot ============= +;========================================================================= + + +;========================================================================= +; Prepare_Boot - This routine prepares the hardware for a +; warm boot. Since we have no special hardware +; requirements at this time, this routine sets +; a good error level and returns to the caller. +; +; Inputs : AH - 5Ch (Prepare for Warm Boot) +; +; Outputs : AH - Non-zero if error (Determined by Get_Handle proc) +;========================================================================= + +Prepare_Boot proc ;prepare for warm boot ;an000; dms; + + xor ah,ah ;signal no error ;an000; dms; + + ret ;return to caller ;an000; dms; + +Prepare_Boot endp ;end proc ;an000; dms; + + + -- cgit v1.2.3