windows-nt/Source/XPSP1/NT/base/mvdm/wow16/timer/libinit.asm

440 lines
9.6 KiB
NASM
Raw Normal View History

2020-09-26 03:20:57 -05:00
;
; LibInit.asm library stub to do local init for a Dynamic linked library
;
; NOTE!!!! link this MODULE first or you will be sorry!!!!
;
?PLM=1 ; pascal call convention
?WIN=0 ; Windows prolog/epilog code
?DF=1
PMODE=1
.286
.xlist
include cmacros.inc
include windows.inc
include sysinfo.inc
include mmddk.inc
include mmsystem.inc
include timer.inc
;include vtdapi.inc
.list
.list
sBegin Data
;
; Stuff needed to avoid the C runtime coming in
;
; also known as "MAGIC THAT SAVED ME" - Glenn Steffler 2/7/90
;
; Do not remove!!
;
DD 0 ; So null pointers get 0
maxRsrvPtrs = 5
DW maxRsrvPtrs
usedRsrvPtrs = 0
labelDP <PUBLIC,rsrvptrs>
DefRsrvPtr MACRO name
globalW name,0
usedRsrvPtrs = usedRsrvPtrs + 1
ENDM
DefRsrvPtr pLocalHeap ; Local heap pointer
DefRsrvPtr pAtomTable ; Atom table pointer
DefRsrvPtr pStackTop ; top of stack
DefRsrvPtr pStackMin ; minimum value of SP
DefRsrvPtr pStackBot ; bottom of stack
if maxRsrvPtrs-usedRsrvPtrs
DW maxRsrvPtrs-usedRsrvPtrs DUP (0)
endif
public __acrtused
__acrtused = 1
sEnd Data
;
;
; END of nasty stuff...
;
externA WinFlags
externFP LocalInit
externFP Disable286
externFP Enable286
externW wMaxResolution
externW wMinPeriod
; here lies the global data
sBegin Data
public wEnabled
wEnabled dw 0 ; enable = 1 ;disable = 0
public PS2_MCA
ifdef NEC_98
PS2_MCA db 0 ; Micro Channel Flag
public bClockFlag ; save machine clock
bClockFlag db 0 ; 5Mhz = 0 ; 8Mhz = other
else ; NEC_98
PS2_MCA db ? ; Micro Channel Flag
endif ; NEC_98
sEnd Data
assumes es,nothing
sBegin CodeInit
assumes cs,CodeInit
assumes ds,Data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Library unload function
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Disable routine is same as WEP
cProc WEP,<FAR,PUBLIC>,<>
; parmW silly_param
cBegin nogen
errn$ Disable
cEnd nogen
cProc Disable,<FAR,PUBLIC>,<>
; parmW silly_param
cBegin nogen
push ds
mov ax,DGROUP ; set up DS==DGROUP for exported funcs
mov ds,ax
assumes ds,Data
xor ax,ax ; return value = no error
cmp wEnabled,ax ; Q: enabled ?
jz dis_done ; N: exit
mov wEnabled,ax ; disabled now
mov ax,WinFlags
test ax,WF_WIN386
jnz dis_386
; running under win286
dis_286:
call Disable286
jmp dis_done
; running under win386
dis_386:
call Disable286
dis_done:
pop ds
ret 2
cEnd nogen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Library Enable function
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cProc Enable,<FAR,PUBLIC>,<>
; parmW silly_param
cBegin nogen
mov ax,wEnabled
or ax,ax ; Q: already enabled ?
jnz enable_done ; Y: exit
inc wEnabled ; mark as being enabled
ifdef NEC_98
;
; Get system clock
;
mov ax,0002h
mov bx,0040h ; get segment addres
; make descriptor(real mode segment)
; return the segment descriptor
; in the case of exist the appointed segment descriptor already
; (not make sure repeatedly)
int 31h
jc error_exit ; in the case of failed ->jmp
push es
mov es,ax
mov al,byte ptr es:[101h] ; get system info
and al,80h
mov byte ptr bClockFlag,al ; save clock
pop es
endif ; NEC_98
mov ax,WinFlags
test ax,WF_WIN386
jnz enable_386
; running under win286
enable_286:
call Enable286
jmp enable_done
; running under win386
enable_386:
call Enable286
enable_done:
ret 2
ifdef NEC_98
error_exit:
dec wEnabled ; mark as being enabled
xor ax,ax
ret 2
endif ; NEC_98
cEnd nogen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Library entry point
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
public LibInit
LibInit proc far
; CX = size of heap
; DI = module handle
; DS = automatic data segment
; ES:SI = address of command line (not used)
jcxz lib_heapok ; heap size zero? jump over unneeded LocalInit call
cCall LocalInit,<ds,ax,cx> ; dataseg, 0, heapsize
or ax,ax
jnz lib_heapok ; if heap set continue on
lib_error:
xor ax,ax
ret ; return FALSE (ax = 0) -- couldn't init
lib_heapok:
mov ax,WinFlags
test ax,WF_WIN386
jnz lib_386
; running under win286
lib_286:
call Lib286Init
jmp lib_realdone ; win 286 will enable timer on first event request
; running under win386
lib_386:
call Lib286Init
lib_realdone:
ret
LibInit endp
sEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Win 386 timer VTD code for initialization, and removal
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
externFP GetVersion ; in KERNEL
externFP MessageBox ; in USER
externFP LoadString ; in USER
sBegin CodeInit
assumes cs,CodeInit
assumes ds,Data
;externNP VTDAPI_GetEntryPt
; Assumes DI contains module handle
cProc WarningMessage <NEAR,PASCAL> <>
LocalV aszErrorTitle, 32
LocalV aszErrorMsg, 256
cBegin
lea ax, WORD PTR aszErrorTitle
cCall LoadString, <di, IDS_ERRORTITLE, ss, ax, 32>
lea ax, WORD PTR aszErrorMsg
cCall LoadString, <di, IDS_ERRORTEXT, ss, ax, 256>
lea ax, WORD PTR aszErrorTitle
lea bx, WORD PTR aszErrorMsg
cCall MessageBox, <NULL, ss, bx, ss, ax, MB_SYSTEMMODAL+MB_OK+MB_ICONHAND>
cEnd
if 0
Lib386Init proc near
call VTDAPI_GetEntryPt ; this will return 0 if the VxD is not loaded
or ax,ax
jnz Lib386InitOk
ifndef NEC_98
DOUT <TIMER: *** unable to find vtdapi.386 ***>
endif ; NEC_98
;
; warn the USER that we can't find our VxD, under windows 3.0
; we can't bring up a message box, so only do this in win 3.1
;
cCall GetVersion
xchg al,ah
cmp ax,030Ah
jb Lib386InitFail
cCall WarningMessage,<>
Lib386InitFail:
xor ax,ax
Lib386InitOk:
ret
Lib386Init endp
endif
Disable386 proc near
errn$ Enable386 ; fall through
Disable386 endp
Enable386 proc near
mov ax,1 ; nothing to do
ret
Enable386 endp
sEnd Code386
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Win 286 timer drv code for initialization, and removal
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
externW Events
externFP tddISR ; in local.asm
externFP GlobalWire ; in KERNEL
externFP GlobalPageLock ; in KERNEL
sBegin CodeInit
assumes cs,CodeInit
assumes ds,Data
Lib286Init proc near
; get the system configuration
;
; the FIXED_286 segment is not loaded, load it and pagelock it.
;
mov dx,seg tddISR ; get the 286 code segment
mov es,dx
mov ax,es:[0] ; load it!
cCall GlobalWire, <dx> ; get it low in memory
cCall GlobalPageLock, <dx> ; and nail it down!
ifndef NEC_98
mov PS2_MCA,0 ; Initialize PS2_MCA = FALSE
stc ; Set this in case BIOS doesn't
mov ah,GetSystemConfig
int 15h
jc Lib286Init_NoMicroChannel ; Successful call?
or ah,ah ; Valid return?
jnz Lib286Init_NoMicroChannel
test es:[bx.SD_feature1],SF1_MicroChnPresent
jz Lib286Init_NoMicroChannel
inc PS2_MCA ; PS2_MCA = TRUE
endif ; NEC_98
Lib286Init_NoMicroChannel:
push di
push ds
pop es
mov di,DataOFFSET Events ; ES:DI --> Events
xor ax,ax
mov cx,(MAXEVENTS * SizeEvent)/2
rep stosw ; zero out event structures.
; set up one event as the standard call-back routine for the
; BIOS timer service
;
ifdef NEC_98
mov ax,0002h
mov bx,0040h
int 31h
jc error_init
push es
mov es,ax
test byte ptr es:[101h],80h
pop es
mov cx,0f000h
jz @f
mov cx,0c300h
@@:
xor bx,bx
else ; NEC_98
xor bx,bx ; BX:CX = 64k
xor cx,cx
inc bx
endif ; NEC_98
mov di,DataOFFSET Events ; DS:DI --> Events
mov [di].evTime.lo,cx ; Program next at ~= 55ms
mov [di].evTime.hi,bx ; standard 18.2 times per second event
mov [di].evDelay.lo,cx ; First event will be set off
mov [di].evDelay.hi,bx ; at 55ms (65536 ticks)
mov [di].evResolution,TDD_MINRESOLUTION ; Allow 55ms either way
mov [di].evFlags,TIME_BIOSEVENT+TIME_PERIODIC
mov ax,WinFlags
test ax,WF_CPU286
jz @f
mov wMaxResolution,TDD_MAX286RESOLUTION
mov wMinPeriod,TDD_MIN286PERIOD
@@:
ifdef NEC_98
mov ax,0001h
else ; NEC_98
mov ax,bx ; Return TRUE
endif ; NEC_98
mov [di].evID,ax ; enable event
pop di
ret
ifdef NEC_98
error_init:
xor ax,ax
pop di
ret
endif ; NEC_98
Lib286Init endp
sEnd
end LibInit