home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD2.mdf
/
doc
/
ems
/
demos
/
asmexamp
/
kernal.asm
next >
Wrap
Assembly Source File
|
1988-04-22
|
19KB
|
444 lines
PAGE 60, 132
NAME expanded_memory_dispatcher_kernal
;-----------------------------------------------------------------------------;
; Placing null segment declarations at this point forces the segment ;
; order for the remainder of the program. ;
;-----------------------------------------------------------------------------;
CODE SEGMENT PARA PUBLIC 'CODE'
ORG 100h
CODE ENDS
DATA SEGMENT PARA PUBLIC 'DATA'
DATA ENDS
STACK SEGMENT PARA 'STACK'
STACK ENDS
PAGE
;-----------------------------------------------------------------------------;
; E Q U A T E S & M A C R O S ;
;-----------------------------------------------------------------------------;
cr EQU 0Dh
lf EQU 0Ah
DISPLAY MACRO msg
MOV AH, 09h
LEA DX, msg
INT 21h
ENDM
PAGE
;-----------------------------------------------------------------------------;
; D A T A S E G M E N T F O R T H E K E R N A L ;
;-----------------------------------------------------------------------------;
DATA SEGMENT PARA PUBLIC 'DATA'
;-----------------------------------------------------------------------------;
; Messages. ;
;-----------------------------------------------------------------------------;
signon_msg DB 'Intel Expanded Memory Code Load & Execute Demo', cr, lf
DB '. ', cr, lf, '$'
emm_check_msg DB '. Checking for EMM loaded', cr, lf, '$'
emm_not_loaded_msg DB '. EMM not loaded', cr, lf, '$'
alloc_exp_mem_msg DB '. Allocating & mapping expanded memory', cr, lf, '$'
load_overlay_msg DB '. Loading overlay into expanded memory', cr, lf, '$'
calling_overlay_msg DB '. Calling loaded code in expanded memory', cr, lf, '$'
dealloc_exp_mem_msg DB '. Deallocating expanded memory', cr, lf, '$'
emm_err_msg DB '. EMM error occurred', cr, lf, '$'
;-----------------------------------------------------------------------------;
; Name of pseudo-overlay. ;
;-----------------------------------------------------------------------------;
pseudo_overlay_name DB 'OVERLAY.EXE', 0
;-----------------------------------------------------------------------------;
; Standard EMM device name. ;
;-----------------------------------------------------------------------------;
EMM_device_name DB 'EMMXXXX0'
;-----------------------------------------------------------------------------;
; Miscellaneous temps. ;
;-----------------------------------------------------------------------------;
exp_mem_segment DW ?
EMM_handle DW ?
com_file_entry_point DD ?
;-----------------------------------------------------------------------------;
; Structure definition for a DOS "load overlay" parameter block. ;
;-----------------------------------------------------------------------------;
parm_block_struct STRUC
load_segment DW ?
reloc_factor DW ?
parm_block_struct ENDS
parm_block parm_block_struct <>
DATA ENDS
PAGE
;-----------------------------------------------------------------------------;
; C O D E S E G M E N T F O R T H E K E R N A L ;
;-----------------------------------------------------------------------------;
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE, DS:DATA, ES:NOTHING, SS:STACK
;-----------------------------------------------------------------------------;
; We will establish a convention in which the first object located at the ;
; expanded memory page frame will be a data structure which describes ;
; the data & extra segments of the loaded overlay, the number of procedure ;
; entry points in the loaded overlay, and a list of far pointers to ;
; each of the procedures contained in the pseudo-overlay which is to be ;
; loaded in expanded memory. The developer must establish a convention ;
; for the sequence of the far pointers and what the procedures they point ;
; to do. Other information could be passed in this structure as well. ;
; Such as, number and types of parameters which are be passed by the ;
; calling procedures to the called procedures in the pseudo-overlay. ;
; ;
; This example uses a literal to determine the maximum number of far ;
; pointers which may be passed. To allocate additional space for a larger ;
; number of entries, simply increase the value of max_proc_entries. The ;
; example assumes a MAXIMUM of 64 entries can be returned. ;
;-----------------------------------------------------------------------------;
max_proc_entries EQU 64
pseudo_overlay_entry_struct STRUC
proc_data_segment DW ?
proc_extra_segment DW ?
proc_entry_count DW ?
proc_entry_ptr DD max_proc_entries DUP (?)
pseudo_overlay_entry_struct ENDS
PAGE
;-----------------------------------------------------------------------------;
; This is an example of how a set of procedures may be loaded into ;
; expanded memory and invoked any time it is desired. The procedures ;
; contained in the loaded program may be called at any time the main ;
; program desires to do so. In this example, the program will be a ;
; collection of four procedures written in assembler. They could also be ;
; written in a high level language provided that the language is able to ;
; generate COM style files with the initialization code located at offset ;
; 100h. The language must also be able to perform a far return because ;
; the calls made to the loaded procedures are inter-segment calls. ;
; ;
; We will refer to this collection of loaded procedures as a ;
; pseudo-overlay. The program which loads the pseudo-overlay will be ;
; referred to as the kernal. This example kernal loads only a single ;
; pseudo-overlay and immediately invokes all the procedures contained in ;
; the overlay. A programmer could as easily load as many overlays as ;
; desired simply by allocating additional pages, mapping in four or fewer ;
; pages (depending on the length of the pseudo-overlay code), and then ;
; loading the pseudo-overlay. A key point to remember is that the ;
; maximum size of the expanded memory page frame is 64K bytes. So, the ;
; overlays loaded cannot exceed 64K bytes in length. However, the ;
; programmer can load as many of them as is desired by allocating the ;
; expanded memory required up to a maximum of 8M bytes. Another key point ;
; to remember is that although the DOS "load & execute" function was used ;
; to load the overlays, the code and any data which was loaded remains ;
; present after the load takes place. The procedures contained in the ;
; pseudo-overlay may be accessed by the use of the list of pointers ;
; returned to the kernal. ;
; ;
; What functions are contained in the overlays is left as an excercise of ;
; the fertile imaginations of developers. ;
;-----------------------------------------------------------------------------;
main PROC NEAR
;---------------------------------------------------------------------;
; Initialization ;
;---------------------------------------------------------------------;
MOV AX, DATA
MOV DS, AX
DISPLAY signon_msg
check_for_emm_loaded:
;---------------------------------------------------------------------;
; Use the "interrupt vector" technique to determine whether ;
; EMM is loaded. ;
;---------------------------------------------------------------------;
DISPLAY emm_check_msg
CALL test_for_EMM
JE get_emm_page_frame
DISPLAY emm_not_loaded_msg
JMP exit
get_emm_page_frame:
;---------------------------------------------------------------------;
; Allocating expanded memory for overlay. ;
;---------------------------------------------------------------------;
DISPLAY alloc_exp_mem_msg
;---------------------------------------------------------------------;
; Get the page frame base address from EMM. ;
;---------------------------------------------------------------------;
MOV AH, 41h
INT 67h
OR AH, AH
JZ allocate_64K
JMP emm_err_exit
allocate_64K:
;---------------------------------------------------------------------;
; Allocate 4 pages of expanded memory for this example. More can ;
; be allocated depending on the number of overlays to be loaded. ;
; Actually, in the case of this example, only a single page is ;
; required because the example pseudo-overlay is extremely small. ;
;---------------------------------------------------------------------;
MOV exp_mem_segment, BX
MOV AH, 43h
MOV BX, 4
INT 67h
OR AH, AH
JZ map_64K
JMP emm_err_exit
map_64K:
;---------------------------------------------------------------------;
; Map in the first 4 logical pages at physical pages 0 thru 3. ;
; logical page 0 at physical page 0 ;
; logical page 1 at physical page 1 ;
; logical page 2 at physical page 2 ;
; logical page 3 at physical page 3 ;
; If additional overlays were required, each overlay would be ;
; loaded after mapping and a new set of logical pages would be ;
; mapped at the same phisical pages. ;
;---------------------------------------------------------------------;
MOV EMM_handle, DX
MOV CX, 4
map_pages_loop:
MOV AH, 44h
MOV BX, CX
DEC BX
MOV AL, BL
MOV DX, EMM_handle
INT 67h
OR AH, AH
LOOPE map_pages_loop
JE initialize_load_structure
JMP emm_err_exit
initialize_load_structure:
;---------------------------------------------------------------------;
; Load the overlay. ;
;---------------------------------------------------------------------;
DISPLAY load_overlay_msg
;---------------------------------------------------------------------;
; Initialize pseudo-overlay environment and procedure pointer area. ;
; This structure begins at the page frame segment address. ;
;---------------------------------------------------------------------;
MOV ES, exp_mem_segment
MOV DI, 0
MOV CX, (SIZE pseudo_overlay_entry_struct)
MOV AL, 0
REP STOSB
;---------------------------------------------------------------------;
; Compute the load address within expanded memory for the overlay. ;
; The address is rounded up to the next higher paragraph boundary ;
; immediately following the pseudo-overlay environment & procedure ;
; pointer structure. This computation takes into account the ;
; maximum number of procedure entry points which the pseudo-overlay ;
; is going to return to this program. ;
;---------------------------------------------------------------------;
MOV AX, (SIZE pseudo_overlay_entry_struct)
ADD AX, 000Fh
AND AX, 0FFF0h
MOV CX, 4
SHR AX, CL
ADD AX, exp_mem_segment
MOV parm_block.load_segment, AX
MOV parm_block.reloc_factor, AX
;---------------------------------------------------------------------;
; Build the entry point for the .COM file in this example. ;
;---------------------------------------------------------------------;
MOV WORD PTR com_file_entry_point[0], 100h
MOV WORD PTR com_file_entry_point[2], AX
;---------------------------------------------------------------------;
; Load the pseudo-overlay using the DOS "load overlay" function. ;
;---------------------------------------------------------------------;
MOV AH, 4Bh
MOV AL, 03h
LEA DX, pseudo_overlay_name
PUSH DS
POP ES
LEA BX, parm_block
INT 21h
JC emm_err_exit
;---------------------------------------------------------------------;
; Transfer control to the loaded pseudo-overlays initialization ;
; code. ;
;---------------------------------------------------------------------;
PUSH DS
PUSH ES
CALL DWORD PTR com_file_entry_point
POP ES
POP DS
OR AH, AH
JZ call_overlay_procedures
JMP emm_err_exit
call_overlay_procedures:
;---------------------------------------------------------------------;
; As an example of passing control to a procedure existing in ;
; expanded memory, each procedure contained in the overlay will be ;
; called in sequence. Obviously, a single procedure could be ;
; called just as easily. ;
;---------------------------------------------------------------------;
MOV ES, exp_mem_segment
MOV BX, 0
MOV DI, 0
MOV CX, ES:[BX].proc_entry_count
JCXZ deallocate_exp_memory
pseudo_overlay_call_loop:
;---------------------------------------------------------------------;
; Indicate that code in expanded memory is being called. ;
;---------------------------------------------------------------------;
DISPLAY calling_overlay_msg
;---------------------------------------------------------------------;
; Call the procedures loaded in the overlay. ;
;---------------------------------------------------------------------;
PUSH BX
PUSH CX
PUSH DI
PUSH ES
PUSH DS
LDS AX, ES:[BX+DI].proc_entry_ptr
MOV WORD PTR CS:temp_proc_entry_ptr[0], AX
MOV WORD PTR CS:temp_proc_entry_ptr[2], DS
;---------------------------------------------------------------------;
; Pass 2 numbers to the procedures. ;
;---------------------------------------------------------------------;
MOV AX, 123
MOV DX, 23
;---------------------------------------------------------------------;
; Set up pseudo-overlays segment environment. Call each procedure. ;
;---------------------------------------------------------------------;
MOV DS, ES:[BX].proc_data_segment
MOV ES, ES:[BX].proc_extra_segment
CALL DWORD PTR CS:temp_proc_entry_ptr
POP DS
POP ES
POP DI
POP CX
POP BX
;---------------------------------------------------------------------;
; Adjust index to the next procedure (4 bytes long) pointer & loop ;
; till all have been called. ;
;---------------------------------------------------------------------;
ADD DI, 4
LOOP pseudo_overlay_call_loop
deallocate_exp_memory:
;---------------------------------------------------------------------;
; Dellocating expanded memory for overlay. ;
;---------------------------------------------------------------------;
DISPLAY dealloc_exp_mem_msg
;---------------------------------------------------------------------;
; Return the allocated pages to the expanded memory manager. ;
;---------------------------------------------------------------------;
MOV AH, 45h
MOV DX, EMM_handle
INT 67h
OR AH, AH
JNZ emm_err_exit
exit:
;---------------------------------------------------------------------;
; Return a normal exit code. ;
;---------------------------------------------------------------------;
MOV AH, 4Ch
MOV AL, 0
INT 21h
emm_err_exit:
;---------------------------------------------------------------------;
; Display the fact that an EMM error occurred & exit. ;
;---------------------------------------------------------------------;
DISPLAY emm_err_msg
MOV AH, 4Ch
MOV AL, 1
INT 21h
;---------------------------------------------------------------------;
; CS relative far pointer used for transfer to the procedures in ;
; the pseudo_overlay. ;
;---------------------------------------------------------------------;
temp_proc_entry_ptr DD ?
main ENDP
PAGE
;-----------------------------------------------------------------------------;
; The following procedure tests for the presence of the EMM in the system. ;
; It returns the CARRY FLAG SET if the EMM is present. It returns the ;
; CARRY FLAG CLEAR if the EMM is not present. ;
;-----------------------------------------------------------------------------;
test_for_EMM PROC NEAR
;---------------------------------------------------------------------;
; Issue "get interrupt vector" DOS call. ;
;---------------------------------------------------------------------;
MOV AX, 3567h
INT 21h
;---------------------------------------------------------------------;
; Use the SEGMENT in ES returned by DOS, place the "device name ;
; field" OFFSET in DI. ;
;---------------------------------------------------------------------;
MOV DI, 000Ah
;---------------------------------------------------------------------;
; Place the OFFSET of the EMM device name string in SI, the SEGMENT ;
; is already in DS. ;
;---------------------------------------------------------------------;
LEA SI, EMM_device_name
;---------------------------------------------------------------------;
; Compare the name strings. Return the status of the compare in ;
; the ZERO flag. ;
;---------------------------------------------------------------------;
MOV CX, (SIZE EMM_device_name)
CLD
REPE CMPSB
RET
test_for_EMM ENDP
CODE ENDS
PAGE
;-----------------------------------------------------------------------------;
; S T A C K S E G M E N T F O R T H E K E R N A L ;
; A N D T H E P S E U D O - O V E R L A Y ;
;-----------------------------------------------------------------------------;
STACK SEGMENT PARA STACK 'STACK'
local_stack DW 256 DUP ('^^')
STACK ENDS
END main