Metropoli BBS
VIEWER: c0c3.asm MODE: TEXT (ASCII)
; INIT code

;This file will call all funcs within the _INIT_ segment for any init it
;may require.
; For Borland and Watcom:
;Each entire in the segment must be as follows
;  db 0   ;this must be zero (else it will not be called)
;  db ?   ;this is the priority of the func.  0=highest  0xff=lowest
;  dd ?   ;offset of rountine to call
; For Micro$oft C++:
;Each entire in the segment must be as follows
;  dd ?   ;offset of rountine to call

;Borland INIT segments
_INIT_ segment word public use32 'INITDATA'
bc_init_start:
_INIT_ ends

_INITEND_ segment word public use32 'INITDATA'
bc_init_end:
_INITEND_ ends

_EXIT_ segment word public use32 'EXITDATA'
bc_exit_start:
_EXIT_ ends

_EXITEND_ segment word public use32 'EXITDATA'
bc_exit_end:
_EXITEND_ ends

;Watcom INIT segments
XIB segment word public use32 'DATA'
wc_init_start:
XIB ends
XIE segment word public use32 'DATA'
wc_init_end:
XIE ends
CONST2  SEGMENT word PUBLIC USE32 'DATA'
wc_exit_start:
CONST2  ends
CONST2END  SEGMENT word PUBLIC USE32 'DATA'
wc_exit_end:
CONST2END  ends

;option dotname  ;need to allow . for MS segment names
;Micro$oft INIT segments (these are stupid!)
.CRT$XCU        SEGMENT DWORD PUBLIC USE32 'DATA'
mc_init_start:
.CRT$XCU        ENDS
.CRT$XCUEND     SEGMENT DWORD PUBLIC USE32 'DATA'
mc_init_end:
.CRT$XCUEND     ENDS

.code

call_init proc private  ;(this code striped from BCv5.0 c0s.obj)
    ;dos4gwint3
    mov esi,offset bc_init_start
    mov edi,offset bc_init_end
    call i__15

    mov esi,offset wc_init_start
    mov edi,offset wc_init_end
    call i__15

    mov esi,offset mc_init_start
    mov edi,offset mc_init_end
i__13:
    cmp esi,edi
    jnz i__14
    ret
i__14:
    call dword ptr[esi]
    add esi,4
    jmp i__13

i__15:
    mov       ax,0100H
    mov       edx,edi
    mov       ebx,esi
i__16:
    cmp       ebx,edi
    je        i__18
    cmp       byte ptr [ebx],0ffH
    je        i__17
    mov       cl,byte ptr [ebx+1]
    xor       ch,ch
    cmp       cx,ax
    jae       i__17
    mov       ax,cx
    mov       edx,ebx
i__17:
    add       ebx,0006H
    jmp       i__16
i__18:
    cmp       edx,edi
    je        i__20
    mov       ebx,edx
    mov       byte ptr [ebx],0ffH
    call      dword ptr [ebx+2]
    jmp       i__15
i__20:
    ret       
call_init endp

call_exit proc private
    ;dos4gwint3
    mov esi,offset bc_exit_start
    mov edi,offset bc_exit_end
    call e__15

    ;Watcom seems to mix two segments together.  CONST2 contains the
    ;destructors but...it seems after that there is addition crap not needed
    ;So far what I have seen is that each destructor has 4 bytes preceding
    ;them, in each case the 1st byte was always '4'.  I just continue until I
    ;the 1st byte is not '4'.  It may though accidently in the future, I hope
    ;this never happens
    mov esi,offset wc_exit_start
    mov edi,offset wc_exit_end
e__13:
    cmp bptr[esi],4     ;WC deconstructor?
    jnz e__13b
    cmp esi,edi
    jnz e__14
e__13b:
    ret
e__14:
    call dword ptr[esi+4]
    add esi,12
    jmp e__13

    ret

  ;There is no M$C uninit segment.  They must uninit somehow else, how?
  ; I don't know but I know it does work !?

e__15:
    mov       ax,0100H
    mov       edx,edi
    mov       ebx,esi
e__16:
    cmp       ebx,edi
    je        e__18
    cmp       byte ptr [ebx],0ffH
    je        e__17
    mov       cl,byte ptr [ebx+1]
    xor       ch,ch
    cmp       cx,ax
    jae       e__17
    mov       ax,cx
    mov       edx,ebx
e__17:
    add       ebx,0006H
    jmp       e__16
e__18:
    cmp       edx,edi
    je        e__20
    mov       ebx,edx
    mov       byte ptr [ebx],0ffH
    call      dword ptr [ebx+2]
    jmp       e__15
e__20:
    ret       

call_exit endp

[ RETURN TO DIRECTORY ]