windows-nt/Source/XPSP1/NT/base/mvdm/wow16/win87em/emthread.asm

177 lines
3.9 KiB
NASM
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
;
;
; Copyright (C) Microsoft Corporation, 1987
;
; This Module contains Proprietary Information of Microsoft
; Corporation and should be treated as Confidential.
;
subttl emthread.asm - Emulator multi-thread support for OS/2
page
thread1static=1 ; set DS = EMULATOR_DATA for thread 1
; dynamically allocate data areas for other threads
_DATA segment word public 'DATA'
_DATA ends
DGROUP group _DATA
_DATA segment word public 'DATA'
extrn __FPDSARRAY:WORD
ifdef i386
extrn __threadid:FWORD ; far pointer to ???? thread id
else
extrn __threadid:DWORD ; far pointer to WORD thread id
endif
_DATA ends
dataoffset equ offset DGROUP:
include os2dll.inc ; defines _SIGNAL_LOCK
; and other lock values;
; must be synchronized with
; \clib\include\86\os2dll.inc
; and \clib\include\os2dll.h
extrn __lockf:FAR
extrn __unlockf:FAR
LOAD_DS_EDI macro
local TIDOk, LoadDone
;
; loads ds:edi with far pointer to thread's DS selector
; (pointer into __FPDSARRAY)
;
; uses eax,edi,es,ds
;
; sets eax = 2 * (thread id)
;
mov ax,DGROUP
mov ds,ax ; set DS = DGROUP temporarily
assume ds:DGROUP
les edi,[__threadid] ; ES:eDI = far pointer to thread id
mov ax,es:[edi] ; AX = thread id (far ptr to WORD)
cmp ax, MAXTHREADID
jbe TIDOk
push ax
call LoadDS_EDI
pop ax
shl ax, 1 ; thread id times 2
jmp short LoadDone
TIDOk:
shl eax,1 ; thread id times 2
mov edi,dataoffset __FPDSARRAY
add edi,eax ; index into __FPDSARRAY
LoadDone:
endm
LOADthreadDS macro
;
; loads thread's DS from __FPDSARRAY indexed by thread id
; preserves all registers except DS and eAX
;
; __FPDSARRAY[0] = MAXTHREAD
; __FPDSARRAY[i] = emulator DS for thread i, 1<=i<=MAXTHREAD
;
push edi ; save eDI
push es ; save ES
LOAD_DS_EDI ; get pointer (ds:edi) to thread's DS
mov ds,ds:[edi] ; set up DS to thread's data area
assume ds:EMULATOR_DATA ; or dynamically allocated copy
pop es
pop edi ; restore DI
endm
ALLOCthreadDS macro
pub allocperthread
LOAD_DS_EDI ; get pointer into __FPDSARRAY
; eAX = 2 * (thread_id)
ifdef thread1static
;
; for thread 1, use EMULATOR_DATA segment
;
cmp eax,2 ; thread 1?
jnz allocds ; no - dynamically allocate DS
mov ax,EMULATOR_DATA ; yes - use static area
mov ds:[edi],ax ; store new DS into __FPDSARRAY
mov ds,ax
assume ds:EMULATOR_DATA ; or dynamically allocated copy
mov es,ax ; ES = DS = EMULATOR_DATA
jmp allocdone
else
jmp allocds
endif ;thread1static
pub allocerror
mov ax,-3 ; return allocation error
stc
ret
;
ifdef thread1static
; for threads other than thread 1, allocate new DS from the system
else
; for all threads, allocate new DS from the system
endif
;
pub allocds
assume ds:DGROUP
push offset __fptaskdata ; size of per-thread data area
push ds ; ds:di = addr of thread's DS
push edi
push 0 ; non-shared segment
os2call DOSALLOCSEG
or ax,ax ; allocation error?
jnz allocerror ; yes - cause thread init to fail
mov di,ds:[edi] ; set ES = DS = thread's data selector
mov ds,di
mov es,di
assume ds:EMULATOR_DATA ; or dynamically allocated copy
pub allocdone
;
; ES = DS = selector for emulator data area
;
mov edx,offset __fptaskdata ; dx = size of emulator data area
sub edx,offset EMULATOR_DATA; jwm
xor ax,ax ; prepare to zero out data segment
xor edi,edi ; start at offset zero
mov edi,offset EMULATOR_DATA; jwm : begin at the beginning
mov ecx,edx ; cx = size of segment (even)
shr ecx,1 ; halve it
rep stosw ; zero it!
endm
FREEthreadDS macro
pub freeperthread
assume ds:EMULATOR_DATA ; or dynamically allocated copy
ifdef thread1static
mov ax,ds
cmp ax,EMULATOR_DATA ; don't free thread 1's area
je nofreeseg
endif ;thread1static
push ds
os2call DOSFREESEG ; free per-thread emulator data area
nofreeseg:
LOAD_DS_EDI ; get pointer into __FPDSARRAY
mov word ptr ds:[edi],0 ; zero out __FPDSARRAY element
; for the current thread
assume ds:EMULATOR_DATA
endm