home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
asm
/
wasm
/
dispatch.asm
< prev
next >
Wrap
Assembly Source File
|
1987-03-27
|
7KB
|
275 lines
List-
;================================================
; The external dispatcher code. This file contains
; the code to allow a redirection table to interface
; with an external runtime library. Include this
; file in the application program along with the
; redirection tables (like IO.RED).
;================================================
; Macro to set up the dispatch information and
; transfer control to the dispatcher. The
; redirection routines should push BX, load their
; own dispatch index to BL, and jump to this
; code. One of these macros is needed for each
; external library. This code assumes that it's
; in the same segment as the dispatch code below.
;
; LIB_NAME - file name of the library file: string.
Dispatch Macro Lib_Name
Push Si
Mov Si, Offset Dat ;set control block offset
Jmp Library_Dispatcher ;branch to dispatch code
;--- control block for this library
Dat Label Word
Dw 0 ;initial status
Dw ? ;code offset (initialized when loaded)
Dw ? ;code segment (initialized when loaded)
Dw Offset Nam ;location of library name
Nam Db Lib_Name, 0 ;name of library file
Endm
;================================================
; Code to transfer request to library interface.
; The registers BX, SI, and DS should set the to
; the following: BL= dispatch index, SI= offset
; control block. The original values should be
; pushed on the stack. This code should be
; branched to, not called.
;
; On entry, the stack should look like the
; following:
;
; | SI | - top of stack (TOS)
; | BX |
; |<return>| - original return address
; | :: | put there by first call
;
; If there is an error, the error code is displayed
; and also returned in the ERRORLEVEL variable. The
; error codes are:
;
; 01 could not allocate memory
; 02 could not open library file
; 03 incompatible library version
; 04 error in library file
; 05 unknown error
Library_Dispatcher
;--- test if ready, and if so transfer to library (library does return)
Cs:
Test Word [Si], 1 ;test if ready bit set
Jz DispatchNotReady ;jump if not
Push Cs ;segment to return to
Cs:
Jmp Dword [Si+2] ;transfer to library
;--- ready bit not set, try to load
DispatchNotReady
Push Ax
Mov Al, 5 ;error number, in case file has been read
Cs:
Test Word [Si], 10b ;test if file has been read
Jnz DispatchCritErr ;jump if so, unknown error
Call Load_Library ;try to load library
Jc DispatchCritErr ;jump if unsuccessful
Pop Ax
Jmp Library_Dispatcher ;go back to the start otherwise
;--- some kind of error, could not load library, error code should be in AL
DispatchCritErr
Push Ax
Push Cs
Pop Ds ;set data segment
Sub Ah, Ah ;error number is in AX
Mov Bl, 10 ;number base
Div Al, Bl ;convert binary to decimal
Mov Bx, Offset DispatchCritMess ;message location
Add [Bx+14], Al ;set tens
Add [Bx+15], Ah ;set ones
Mov Ah, 9 ;display function
Mov Dx, Bx ;message
Int 21h ;execute
Pop Ax ;restore error number
Mov Ah, 4ch ;exit function
Int 21h ;execute
;--- data
Dispatch_Mark Equ 128 ;library marker
Dispatch_Ver Db 1, 0 ;library version (1.00)
DispatchCritMess Db 'Runtime error 00$' ;error message
;================================================
; Given the data block in DS:SI, an attempt is made
; to load the external library. If successful, the
; carry will be cleared, otherwise the carry will
; be set and AL will return the error code.
Load_Library Proc Near
Push Bx
Push Cx
Push Dx
Push Di
Push Ds
Push Cs
Pop Ds ;set data segment to control block
;--- open file
Mov Ax, 3d00h ;open file
Mov Dx, [Si+6] ;location of file name
Int 21h ;execute
Jnc LoadLibraryCont0 ;jump if ok
Mov Al, 2 ;error code
Jmp LoadLibraryErr0
;--- find size of file
LoadLibraryCont0
Mov Bx, Ax
Mov Ax, 4202h ;move to end of file
Sub Cx, Cx
Mov Dx, Cx ;offset 0000.0000 from end
Int 21h ;execute
Or Dx, Dx
Jz LoadLibraryCont1 ;jump if fewer than 10000H bytes, ok
Mov Al, 4 ;error code
Jmp LoadLibraryErr0
LoadLibraryCont1
Or Ax, Ax
Jnz LoadLibraryCont2 ;jump if more than zero bytes, ok
Mov Al, 4 ;error code
Jmp LoadLibraryErr0
;--- allocate memory
LoadLibraryCont2
Mov Cl, 4
Shr Ax, Cl ;make paragraph form
Inc Ax ;account for partial paragraph
Push Bx
Mov Bx, Ax
Mov Ah, 48h ;allocate function
Int 21h ;execute
Pop Bx
Jnc LoadLibraryCont3 ;jump if ok
Mov Al, 1 ;error code
Jmp LoadLibraryErr0
;--- save segment in library module and prepare for read
LoadLibraryCont3
Mov [Si+4], Ax ;save segment in control block
Push Ax
Pop Ds ;set data segment for read
;--- move read pointer back to start of file
Mov Ax, 4200h ;function
Sub Cx, Cx
Mov Dx, Cx ;offset 0000.0000
Int 21h ;execute
;--- read file into newly allocated memory
Mov Ah, 3fh ;function number
Mov Cx, 0ffffh ;read all bytes (size was checked earlier)
Sub Dx, Dx ;start of segment
Int 21h ;execute
;--- check checksum (total checksum of library should be zero)
Mov Cx, Ax ;set count (number of bytes read)
Sub Al, Al ;initial sum
Sub Di, Di ;start of segment
LoadLibraryLoop
Add Al, [Di] ;add next byte
Inc Di ;advance pointer
Loop LoadLibraryLoop ;loop back if more
Or Al, Al ;check if zero
Jz LoadLibraryCont4 ;jump if so, ok
Mov Al, 4 ;error code
Jmp LoadLibraryErr0
;--- library marker
LoadLibraryCont4
Cmp Byte [0], Dispatch_Mark ;check library marker
Je LoadLibraryCont5 ;jump if ok
Mov Al, 4 ;error code
Jmp LoadLibraryErr0
;--- version number
LoadLibraryCont5
Cs:
Mov Ax, Word Dispatch_Ver ;get highest compatible version
Mov Dx, [1] ;get library version
Xchg Al, Ah
Xchg Dl, Dh ;make most significant byte high
Cmp Ax, Dx ;compare version numbers
Jae LoadLibraryCont6 ;jump if loading lower or equal version, ok
Mov Al, 3 ;error code
Jmp LoadLibraryErr0
;--- loaded successfully
LoadLibraryCont6
Mov Ax, [3] ;get starting offset
Cs:
Mov [Si+2], Ax ;save offset
Cs:
Mov Word [Si], 11b ;set loaded and ready bits
Pop Ds
Pop Di
Pop Dx
Pop Cx
Pop Bx ;restore regs
Clc
Ret
;--- did not load correctly, error code in AL
LoadLibraryErr0
Pop Ds
Pop Di
Pop Dx
Pop Cx
Pop Bx ;restore regs
Stc
Ret
Endp