Consolidated /docs into /pubs
This commit is contained in:
parent
9d356c582b
commit
71d117fa02
106 changed files with 350 additions and 317 deletions
|
|
@ -1,648 +0,0 @@
|
|||
Page 60,132
|
||||
;-----------------------------------------------------------------------------
|
||||
; BEGIN LISTING 3
|
||||
;-----------------------------------------------------------------------------
|
||||
;
|
||||
; EMULOAD.ASM
|
||||
;
|
||||
; Copyright (c) 1991, 1995-Present Robert Collins
|
||||
;
|
||||
; You have my permission to copy and distribute this software for
|
||||
; non-commercial purposes. Any commercial use of this software or
|
||||
; source code is allowed, so long as the appropriate copyright
|
||||
; attributions (to me) are intact, *AND* my email address is properly
|
||||
; displayed.
|
||||
;
|
||||
; Basically, give me credit, where credit is due, and show my email
|
||||
; address.
|
||||
;
|
||||
;-----------------------------------------------------------------------------
|
||||
;
|
||||
; Robert R. Collins email: rcollins@x86.org
|
||||
;
|
||||
;-----------------------------------------------------------------------------
|
||||
;
|
||||
; This utility uses '386 LOADALL to emulate '286 LOADALL.
|
||||
; All 16-bit registers are zero-extended to 32-bit
|
||||
; registers. All 24-bit physical addresses are zero-
|
||||
; extended to 32-bit registers. '386-specific registers
|
||||
; not used in '286 LOADALL are either set to the current
|
||||
; values (Debug registers), or zeroed (segment registers).
|
||||
;
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; This program assumes that you have run the '386 LOADALL
|
||||
; test prior to installing this TSR. Obviously if LOADALL
|
||||
; has been removed from the '386 mask, then this program
|
||||
; will never work. Likewise, it is easier for me to
|
||||
; document the need to run the LOADALL test program, than
|
||||
; to incorporate it into this code.
|
||||
;
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; EMULOAD returns ERROR codes to DOS that can be
|
||||
; intecepted by the batch file command 'IF ERRORLEVEL'.
|
||||
; The following ERRORLEVEL codes are generated by this
|
||||
; program:
|
||||
; 0 = EMULOAD driver now installed in memory
|
||||
; 1 = Attempted removal of the EMULOAD driver from
|
||||
; memory failed because EMULOAD was not in already
|
||||
; in memory.
|
||||
; 2 = The EMULOAD driver was already in memory when an
|
||||
; attempt was made to install it again.
|
||||
; 3 = Bogus command line argument(s).
|
||||
; 4 = Help requested.
|
||||
; 5 = The EMULOAD driver was sucessfully removed from
|
||||
; memory.
|
||||
; 6 = Can't install the EMULOAD driver because this
|
||||
; computer isn't an 80386.
|
||||
;
|
||||
;---------------------------------------------------------------
|
||||
;
|
||||
; Compilation instructions:
|
||||
; MASM EMULOAD; (MASM 5.1)
|
||||
; LINK EMULOAD;
|
||||
; EXE2BIN EMULOAD EMULOAD.COM
|
||||
; DEL EMULOAD.EXE
|
||||
;
|
||||
; The resultant EMULOAD.COM file is 1473 bytes, while the
|
||||
; TSR portion is 1072 bytes.
|
||||
;
|
||||
;---------------------------------------------------------------
|
||||
; Compiler directives
|
||||
;---------------------------------------------------------------
|
||||
Title EMULOAD
|
||||
.radix 16
|
||||
.8086
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Interrupt vector segment
|
||||
;---------------------------------------------------------------
|
||||
ABS0 segment at 0
|
||||
org 6*4
|
||||
INT_6 dd ?
|
||||
|
||||
org 800h
|
||||
Loadall_286 dd ?
|
||||
ABS0 ends
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Structure definitions
|
||||
;---------------------------------------------------------------
|
||||
Desc_cache2 STRUC ; 80286 Descriptor cache
|
||||
A15_A00 dw ? ; register layout.
|
||||
A23_A16 db ?
|
||||
_Type2 db ?
|
||||
_Limit2 dw ?
|
||||
Desc_cache2 ENDS
|
||||
|
||||
|
||||
Desc_cache3 STRUC ; 80386 Descriptor cache
|
||||
_Access db 0 ; register layout
|
||||
_Type db ?
|
||||
_CS32 db 0
|
||||
db 0
|
||||
_Addr dd ?
|
||||
_Limit dd ?
|
||||
Desc_cache3 ENDS
|
||||
|
||||
|
||||
|
||||
Loadall_struc2 STRUC ; 80286 LOADALL table
|
||||
dw 3 dup (?) ; RESERVED
|
||||
_286Msw dw ? ; MSW
|
||||
dw 7 dup (?) ; RESERVED
|
||||
_286Tr dw ? ; TR
|
||||
_Flags dw ? ; FLAGS
|
||||
_286Ip dw ? ; IP
|
||||
_286Ldt dw ? ; LDT
|
||||
_286Ds dw ? ; DS
|
||||
_286Ss dw ? ; SS
|
||||
_286Cs dw ? ; CS
|
||||
_286Es dw ? ; ES
|
||||
_286Di dw ? ; DI
|
||||
_286Si dw ? ; SI
|
||||
_286Bp dw ? ; BP
|
||||
_286Sp dw ? ; SP
|
||||
_286Bx dw ? ; BX
|
||||
_286Dx dw ? ; DX
|
||||
_286Cx dw ? ; CX
|
||||
_286Ax dw ? ; AX
|
||||
ES_Desc286 dw 3 dup (?) ; ES Desc. Cache
|
||||
CS_Desc286 dw 3 dup (?) ; CS Desc. Cache
|
||||
SS_Desc286 dw 3 dup (?) ; SS Desc. Cache
|
||||
DS_Desc286 dw 3 dup (?) ; DS Desc. Cache
|
||||
Gdt_Desc286 dw 3 dup (?) ; GDTR
|
||||
Ldt_Desc286 dw 3 dup (?) ; LDTR
|
||||
Idt_Desc286 dw 3 dup (?) ; IDTR
|
||||
TSS_Desc286 dw 3 dup (?) ; TSSR
|
||||
Loadall_Struc2 ENDS
|
||||
|
||||
Loadall_struc3 STRUC
|
||||
_Cr0 dd ? ; EAX
|
||||
_Eflags dd ? ; EFLAGS
|
||||
_Eip dd ? ; EIP
|
||||
_Edi dd ? ; EDI
|
||||
_Esi dd ? ; ESI
|
||||
_Ebp dd ? ; EBP
|
||||
_Esp dd ? ; ESP
|
||||
_Ebx dd ? ; EBX
|
||||
_Edx dd ? ; EDX
|
||||
_Ecx dd ? ; ECX
|
||||
_Eax dd ? ; EAX
|
||||
_Dr6 dd ? ; DR6
|
||||
_Dr7 dd ? ; DR7
|
||||
_Tr dd ? ; TR
|
||||
_Ldt dd ? ; LDT
|
||||
_Gs dd ? ; GS
|
||||
_Fs dd ? ; FS
|
||||
_Ds dd ? ; DS
|
||||
_Ss dd ? ; SS
|
||||
_Cs dd ? ; CS
|
||||
_Es dd ? ; ES
|
||||
TSS_Desc dd 3 dup (?) ; TSSR
|
||||
IDT_Desc dd 3 dup (?) ; IDTR
|
||||
Gdt_Desc dd 3 dup (?) ; GDTR
|
||||
Ldt_Desc dd 3 dup (?) ; LDTR
|
||||
GS_Desc dd 3 dup (?) ; GS Desc. Cache
|
||||
FS_Desc dd 3 dup (?) ; FS Desc. Cache
|
||||
DS_Desc dd 3 dup (?) ; DS Desc. Cache
|
||||
SS_Desc dd 3 dup (?) ; SS Desc. Cache
|
||||
CS_Desc dd 3 dup (?) ; CS Desc. Cache
|
||||
ES_Desc dd 3 dup (?) ; ES Desc. Cache
|
||||
dd 0ah dup (?) ; RESERVED
|
||||
Loadall_Struc3 ENDS
|
||||
|
||||
INT_VEC STRUC
|
||||
int_offset dw ?
|
||||
int_segment dw ?
|
||||
INT_VEC ENDS
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Equate definitions
|
||||
;---------------------------------------------------------------
|
||||
LOADALL286 equ 050fh
|
||||
CRLF equ <0dh,0ah>
|
||||
CRLF$ equ <0dh,0ah,'$'>
|
||||
INT6 equ [bp-4]
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Macro definitions
|
||||
;---------------------------------------------------------------
|
||||
LOADALL_386 MACRO
|
||||
db 0fh,07h
|
||||
ENDM
|
||||
|
||||
|
||||
PRINT_STRING MACRO MSG_NAME
|
||||
mov ah,9
|
||||
mov dx,offset MSG_NAME
|
||||
int 21h
|
||||
ENDM
|
||||
|
||||
|
||||
|
||||
_TEXT SEGMENT PARA PUBLIC 'CODE'
|
||||
Assume CS:_TEXT, DS:_TEXT, ES:_TEXT, SS:_TEXT
|
||||
Org 100h
|
||||
.386p
|
||||
;---------------------------------------------------------------
|
||||
Emulate_286_Loadall Proc Far
|
||||
;---------------------------------------------------------------
|
||||
jmp EMULOAD ; goto beginning instruction
|
||||
|
||||
Align 4
|
||||
;---------------------------------------------------------------
|
||||
; Local Data
|
||||
;---------------------------------------------------------------
|
||||
Loadall_tbl Loadall_Struc3 <>
|
||||
|
||||
emuload_msg db "80286 LOADALL EMULATOR utility.",CRLF
|
||||
db "Version 1.0 Only for 80386 computers."
|
||||
db CRLF
|
||||
db "Copyright (c) 1991 Robert Collins."
|
||||
db CRLF$
|
||||
emu_msg_len equ $-emuload_msg
|
||||
|
||||
align 4
|
||||
;---------------------------------------------------------------
|
||||
; TSR Code begins here as an INT06 replacement.
|
||||
;---------------------------------------------------------------
|
||||
Int06: push bp
|
||||
mov bp,sp
|
||||
push si
|
||||
push ds
|
||||
lds si,[bp][2] ; get CS:IP of bogus
|
||||
; opcode
|
||||
cmp word ptr [si],LOADALL286; was it LOADALL?
|
||||
jne @Not_LOADALL ; nope
|
||||
mov di,0
|
||||
mov ds,di
|
||||
mov di,cs
|
||||
mov es,di
|
||||
mov edi,offset Loadall_tbl
|
||||
|
||||
Assume DS:ABS0, ES:_TEXT, SS:NOTHING
|
||||
;---------------------------------------------------------------
|
||||
; Convert 80286 registers to 80386 counterparts. The sequencing
|
||||
; order follows the 80386 LOADALL table.
|
||||
;---------------------------------------------------------------
|
||||
; While mapping MSW to CR0, bit5 in CR0 is documented as
|
||||
; RESERVED on the '386 DX, and '1' on the '386 SX. Bit6 is
|
||||
; defined as 'NE' (Numeric Exception) on the '486. If we wanted
|
||||
; this code to work on the '486, then we should mask the lower
|
||||
; nibble of MSW with CR0. But the '486 doesn't have LOADALL,
|
||||
; so this isn't necesary. Next consider the Reserved bit5 on
|
||||
; the '386 DX. Since LOADALL completely redefines the CPU
|
||||
; state, it is safe to clear this reserved bit instead of
|
||||
; masking it with MSW.
|
||||
;---------------------------------------------------------------
|
||||
mov eax,cr0 ; MSW --> CR0
|
||||
mov ax,Loadall_286._286Msw
|
||||
mov Loadall_tbl._CR0,eax
|
||||
movzx eax,Loadall_286._Flags ; FLAGS --> EFLAGS
|
||||
mov Loadall_tbl._EFLAGS,eax
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Hereafter MOVZX isn't needed because the upper 16-bits are
|
||||
; guaranteed to be 0.
|
||||
;---------------------------------------------------------------
|
||||
mov ax,Loadall_286._286IP ; IP --> EIP
|
||||
mov Loadall_tbl._EIP,eax
|
||||
mov ax,Loadall_286._286DI ; DI --> EDI
|
||||
mov Loadall_tbl._EDI,eax
|
||||
mov ax,Loadall_286._286SI ; SI --> ESI
|
||||
mov Loadall_tbl._ESI,eax
|
||||
mov ax,Loadall_286._286BP ; BP --> EBP
|
||||
mov Loadall_tbl._EBP,eax
|
||||
mov ax,Loadall_286._286SP ; SP --> ESP
|
||||
mov Loadall_tbl._ESP,eax
|
||||
mov ax,Loadall_286._286BX ; BX --> EBX
|
||||
mov Loadall_tbl._EBX,eax
|
||||
mov ax,Loadall_286._286DX ; DX --> EDX
|
||||
mov Loadall_tbl._EDX,eax
|
||||
mov ax,Loadall_286._286CX ; CX --> ECX
|
||||
mov Loadall_tbl._ECX,eax
|
||||
mov ax,Loadall_286._286AX ; AX --> EAX
|
||||
mov Loadall_tbl._EAX,eax
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; DR6 & DR7 aren't in the '286, so let's use the current values.
|
||||
; By keeping the current values, guarantees that any ICE
|
||||
; breakpoints, or debug register breakpoints are preserved.
|
||||
; (ICE breakpoints use (at least) the upper two of the
|
||||
; 'RESERVED' bits in DR7.
|
||||
;---------------------------------------------------------------
|
||||
mov eax,dr6 ; Keep DR6
|
||||
mov Loadall_tbl._DR6,eax
|
||||
mov eax,dr7 ; Keep DR7
|
||||
mov Loadall_tbl._DR7,eax
|
||||
|
||||
movzx eax,Loadall_286._286TR ; TR --> TR
|
||||
mov Loadall_tbl._TR,eax
|
||||
mov ax,Loadall_286._286LDT ; LDT --> LDT
|
||||
mov Loadall_tbl._LDT,eax
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; FS & GS aren't in the '286, so let's zero them out.
|
||||
;---------------------------------------------------------------
|
||||
xor ax,ax
|
||||
mov Loadall_tbl._GS,eax ; Clear GS
|
||||
mov Loadall_tbl._FS,eax ; Clear FS
|
||||
|
||||
mov ax,Loadall_286._286DS ; DS --> DS
|
||||
mov Loadall_tbl._DS,eax
|
||||
mov ax,Loadall_286._286SS ; SS --> SS
|
||||
mov Loadall_tbl._SS,eax
|
||||
mov ax,Loadall_286._286CS ; CS --> CS
|
||||
mov Loadall_tbl._CS,eax
|
||||
mov ax,Loadall_286._286ES ; ES --> ES
|
||||
mov Loadall_tbl._ES,eax
|
||||
|
||||
;-----------------------------------------------------------
|
||||
; Convert '286 descriptor cache register entries to '386
|
||||
; format.
|
||||
;-----------------------------------------------------------
|
||||
mov esi,offset Loadall_286.TSS_Desc286
|
||||
mov edi,offset Loadall_tbl.TSS_Desc
|
||||
call CVT_Desc
|
||||
mov esi,offset Loadall_286.IDT_Desc286
|
||||
mov edi,offset Loadall_tbl.IDT_Desc
|
||||
call CVT_Desc
|
||||
mov esi,offset Loadall_286.GDT_Desc286
|
||||
mov edi,offset Loadall_tbl.GDT_Desc
|
||||
call CVT_Desc
|
||||
mov esi,offset Loadall_286.LDT_Desc286
|
||||
mov edi,offset Loadall_tbl.LDT_Desc
|
||||
call CVT_Desc
|
||||
|
||||
;-----------------------------------------------------------
|
||||
; Fill in FS & GS descriptor cache entires with 0.
|
||||
;-----------------------------------------------------------
|
||||
mov Loadall_tbl.GS_Desc._Type,93h
|
||||
mov Loadall_tbl.GS_Desc._Addr,0
|
||||
mov Loadall_tbl.GS_Desc._Limit,0ffffh
|
||||
mov Loadall_tbl.FS_Desc._Type,93h
|
||||
mov Loadall_tbl.FS_Desc._Addr,0
|
||||
mov Loadall_tbl.FS_Desc._Limit,0ffffh
|
||||
|
||||
;-----------------------------------------------------------
|
||||
; Convert '286 descriptor cache register entries to '386
|
||||
; format.
|
||||
;-----------------------------------------------------------
|
||||
mov esi,offset Loadall_286.DS_Desc286
|
||||
mov edi,offset Loadall_tbl.DS_Desc
|
||||
call CVT_Desc
|
||||
mov esi,offset Loadall_286.SS_Desc286
|
||||
mov edi,offset Loadall_tbl.SS_Desc
|
||||
call CVT_Desc
|
||||
mov esi,offset Loadall_286.CS_Desc286
|
||||
mov edi,offset Loadall_tbl.CS_Desc
|
||||
call CVT_Desc
|
||||
mov esi,offset Loadall_286.ES_Desc286
|
||||
mov edi,offset Loadall_tbl.ES_Desc
|
||||
call CVT_Desc
|
||||
mov edi,offset Loadall_tbl
|
||||
LOADALL_386
|
||||
HLT ; This instruction never
|
||||
; gets executed
|
||||
|
||||
@Not_LOADALL:
|
||||
pop ds
|
||||
pop si
|
||||
pop bp
|
||||
|
||||
Orig_int06:
|
||||
jmp far ptr INT_6
|
||||
Emulate_286_Loadall endp
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
CVT_Desc proc near ; Convert '286 descriptor table
|
||||
; ; cache register format to '386
|
||||
; ; format.
|
||||
;---------------------------------------------------------------
|
||||
; Input: DS:ESI = Pointer to '286 descriptor cache entry
|
||||
; DS:EDI = Pointer to '386 descriptor cache entry
|
||||
; Output: None
|
||||
; Register(s) modified: EAX, EBX, ECX
|
||||
;---------------------------------------------------------------
|
||||
mov eax,[esi] ; get 24-bit base &
|
||||
; access rights
|
||||
mov ebx,eax ; make a copy
|
||||
movzx ecx,[esi]._Limit2 ; get 16-bit limit
|
||||
rol eax,8 ; put access in AL
|
||||
and ebx,00ffffffh ; make 24-bit address
|
||||
mov ES:[edi]._Type,al ; store Access
|
||||
mov ES:[edi]._Addr,ebx ; store Address
|
||||
mov ES:[edi]._Limit,ecx ; store Limit
|
||||
ret
|
||||
CVT_Desc endp
|
||||
|
||||
TSR_End label word
|
||||
;---------------------------------------------------------------
|
||||
; End of TSR program
|
||||
;---------------------------------------------------------------
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Local DATA used for initialization code only.
|
||||
;---------------------------------------------------------------
|
||||
bogus_msg1 db "Unrecognized command line argument."
|
||||
db CRLF$
|
||||
bogus_msg2 db "Not 80386 computer.",7,CRLF$
|
||||
|
||||
driver_msg1 db "Resident driver installed."
|
||||
db CRLF$
|
||||
driver_msg2 db "Resident driver already installed."
|
||||
db 7,CRLF$
|
||||
driver_msg3 db "Resident driver removed from memory."
|
||||
db CRLF$
|
||||
driver_msg4 db "Resident driver was not already "
|
||||
db "installed",7,CRLF$
|
||||
help_msg db CRLF
|
||||
db "Syntax: EMULOAD",CRLF
|
||||
db " EMULOAD -R (to remove from "
|
||||
db "memory)",CRLF$
|
||||
|
||||
|
||||
ASSUME DS:_TEXT
|
||||
;---------------------------------------------------------------
|
||||
EMULOAD proc near ; Beginning of initialization
|
||||
; ; code as the NON-TSR part of
|
||||
; ; the program.
|
||||
;---------------------------------------------------------------
|
||||
cld ; clear direction flag
|
||||
Print_String emuload_msg ; Print initialization
|
||||
; message.
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Check CPU type
|
||||
;---------------------------------------------------------------
|
||||
call CPU_TYPE ; Get CPU type
|
||||
and al,0fh ; mask out CPU sub-type
|
||||
cmp al,3 ; 80386?
|
||||
jz short @F ; yes
|
||||
Print_String Bogus_msg2 ; Not 80386 computer
|
||||
mov ax,4c06h ; set function to DOS
|
||||
int 21h ; exit to DOS
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Check command line argument
|
||||
;---------------------------------------------------------------
|
||||
@@: xor ax,ax ; clear AX
|
||||
mov si,80h ; get start of PSP
|
||||
lodsb ; get command line len.
|
||||
or ax,ax ; Any command line args?
|
||||
jz short Installed? ; nope
|
||||
mov cx,ax ; put into counter
|
||||
mov di,si ;
|
||||
mov al,' ' ; skip past superfluous
|
||||
repz scasb ; blank characters
|
||||
cmp byte ptr [di],0dh ; are we at the end?
|
||||
jz short Installed? ; yep
|
||||
cmp byte ptr [di-1],'-' ; check if it's a switch
|
||||
jnz short @F ; if not, then error
|
||||
mov si,di ; get pointer
|
||||
lodsb ; get cmd line switch
|
||||
cmp al,'r' ; remove driver?
|
||||
jz short remove_driver ; yep
|
||||
cmp al,'R' ; remove driver?
|
||||
jz short remove_driver ; go remove driver
|
||||
cmp al,'?' ; help?
|
||||
jnz short @F ; nope
|
||||
Print_String help_msg ; Print help message
|
||||
mov ax,4c04h ; set return code
|
||||
int 21h ; exit to DOS
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Bogus command line argument
|
||||
;---------------------------------------------------------------
|
||||
@@: Print_String bogus_msg1 ; Invalid command line
|
||||
mov ax,4c03h ; set function code
|
||||
int 21h ; exit to DOS
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Remove driver from memory
|
||||
;---------------------------------------------------------------
|
||||
remove_driver:
|
||||
call check_installed ; Driver installed?
|
||||
jnz short @F ; driver not installed
|
||||
mov bp,sp ; create stack frame
|
||||
push ds ; save (DS)
|
||||
mov dx,ABS0 ; get bottom of memory
|
||||
mov ds,dx ; make segment register
|
||||
|
||||
ASSUME DS:ABS0, ES:_TEXT
|
||||
;---------------------------------------------------------------
|
||||
; Restore original INT6 vector
|
||||
;---------------------------------------------------------------
|
||||
; We can restore the original INT6 by getting the vector from
|
||||
; our current memory resident driver -- not the DS from the
|
||||
; code now executing. The original DS is the same as the code
|
||||
; segment for our EMULOAD driver. Hence we only need to get
|
||||
; the original segment value from the memory resident image.
|
||||
; And we get this by looking at the segment for INT6!
|
||||
;---------------------------------------------------------------
|
||||
mov es,int_6.int_segment ; Original DS
|
||||
mov ax,es:orig_int06[1].int_offset ; Original INT6
|
||||
mov bx,es:orig_int06[1].int_segment ; " "
|
||||
mov int_6.int_offset,ax ; Restore orig.
|
||||
mov int_6.int_segment,bx ; INT6
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Free memory pointed to by ES
|
||||
;---------------------------------------------------------------
|
||||
mov ah,49h ; DOS FREE_MEM function
|
||||
int 21h ; free allocated memory
|
||||
mov ds,[bp-2] ; get original (DS)
|
||||
|
||||
ASSUME DS:_TEXT
|
||||
;---------------------------------------------------------------
|
||||
; Now split with TSR removed from memory.
|
||||
;---------------------------------------------------------------
|
||||
Print_String driver_msg3 ; Driver removed
|
||||
mov ax,4c05h ; set function to DOS
|
||||
int 21h ; exit to DOS
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; If EMULOAD was not in memory, then come here and split with
|
||||
; the error code.
|
||||
;---------------------------------------------------------------
|
||||
@@: Print_String driver_msg4 ; Driver not installed
|
||||
mov ax,4c01h ; set function to DOS
|
||||
int 21h ; exit to DOS
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Check for driver already installed
|
||||
;---------------------------------------------------------------
|
||||
Installed?:
|
||||
call check_installed ; check if driver is
|
||||
jnz short @F ; already installed?
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Driver already installed
|
||||
;---------------------------------------------------------------
|
||||
Print_String driver_msg2 ; Driver already inst.
|
||||
mov ax,4c02h ; set function to DOS
|
||||
int 21h ; exit to DOS
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Driver not yet installed
|
||||
;---------------------------------------------------------------
|
||||
@@: Print_String driver_msg1 ; Driver now installed
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Install driver into memory
|
||||
;---------------------------------------------------------------
|
||||
xor dx,dx ; Point to INT. vectors
|
||||
mov ds,dx ; complete the move
|
||||
ASSUME ds:ABS0
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Chain to INT6 by replacing and saving the original INT6
|
||||
; vector.
|
||||
;---------------------------------------------------------------
|
||||
mov ax,int_6.int_offset ; Orig. offset
|
||||
mov bx,int_6.int_segment ; Orig. segment
|
||||
mov orig_int06[1].int_offset,ax ; save old INT6
|
||||
mov orig_int06[1].int_segment,bx ; vector.
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Now replace the original INT6 vector.
|
||||
;---------------------------------------------------------------
|
||||
mov dx,offset cs:int06 ; Get new INT6 vector
|
||||
mov int_6.int_offset,dx ; as CS:INT6
|
||||
mov int_6.int_segment,cs ;
|
||||
|
||||
ASSUME DS:_TEXT
|
||||
;---------------------------------------------------------------
|
||||
; Terminate and Stay Resident
|
||||
;---------------------------------------------------------------
|
||||
mov dx,cs ; make DS=CS
|
||||
mov ds,dx
|
||||
mov es,ds:[2ch] ; get DOS env. segment
|
||||
mov ah,49h ; release memory func.
|
||||
int 21h ; release memory
|
||||
mov dx,offset tsr_end ; get ending address
|
||||
shr dx,4 ; divide by 16
|
||||
adc dx,1 ; check for remainder;
|
||||
; add 1
|
||||
mov ax,3100h ; set return code to DOS
|
||||
int 21h
|
||||
EMULOAD endp
|
||||
|
||||
|
||||
ASSUME ES:ABS0
|
||||
;---------------------------------------------------------------
|
||||
; Check to see if the EMULOAD driver is installed in memory.
|
||||
; It is possible to check if a TSR program is already installed
|
||||
; in memory by looking for a semaphore in the memory image.
|
||||
; Luckily we can locate the memory image of our TSR by looking
|
||||
; at the current INT6 vector. The INT6 code segment is the
|
||||
; segment of the TSR! So this routine looks in this segment
|
||||
; for the inital banner message:
|
||||
;
|
||||
; 80286 LOADALL EMULATOR utility.
|
||||
; Version 1.0 Only for 80386 computers.
|
||||
; Copyright (c) 1991 Robert Collins.
|
||||
;
|
||||
; If this message is found, then the TSR is in memory. If
|
||||
; another TSR has chained to the same INT6 vector, this
|
||||
; technique will fail to find EMULOAD, as it very well should!
|
||||
;---------------------------------------------------------------
|
||||
Check_installed proc near
|
||||
;---------------------------------------------------------------
|
||||
; Input: None
|
||||
; Output: NZ if NOT installed
|
||||
; ZF if ALREADY installed
|
||||
; Register(s) modified: CX, SI, DI
|
||||
;---------------------------------------------------------------
|
||||
push es ; save (ES)
|
||||
mov cx,ABS0 ; get bios data segment
|
||||
mov es,cx ; put in (ES)
|
||||
mov cx,emu_msg_len ; # of bytes to compare
|
||||
mov si,offset emuload_msg ; get address of message
|
||||
les di,ES:INT_6 ; get INT6 vector
|
||||
sub di,int06-emuload_msg ; point to theoretical
|
||||
; start of message
|
||||
repz cmpsb ; check data
|
||||
pop es ; restore (ES)
|
||||
ret ; split
|
||||
Check_installed endp
|
||||
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; Include the CPU_TYPE procedure & LOADALL test
|
||||
;---------------------------------------------------------------
|
||||
Include CPU_TYPE.ASM
|
||||
|
||||
_TEXT ends
|
||||
end Emulate_286_LOADALL
|
||||
|
||||
;---------------------------------------------------------------
|
||||
; END LISTING 3
|
||||
;---------------------------------------------------------------
|
||||
Loading…
Reference in a new issue