;
;	tasm /ml/m4/zi c1dos.asm
;
MASM
;ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
;
; PMODE/W Assembly Startup for CC386.EXE (c) Kirill Jo$$ :-)
;
;ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
.386p

STACK_SIZE = 40*1024h	; Stack size

;	This is equ copy from C0DOS.ASM :-)

_TEXT		segment para public use32 'CODE'
	extrn	__argv_arr:DWORD,__argc:DWORD,__environ:DWORD
	extrn	_main:PROC
_TEXT		ends
cstartup        SEGMENT DWORD PUBLIC USE32 'INITDATA'
InitStart       label dword
                ENDS
_STARTUPEND_       SEGMENT DWORD PUBLIC USE32 'INITDATA'
InitEnd         label dword
                ENDS
crundown        SEGMENT DWORD PUBLIC USE32 'EXITDATA'
ExitStart       label dword
                ENDS
_RUNDOWNEND_       SEGMENT DWORD PUBLIC USE32 'EXITDATA'
ExitEnd         label dword
                ENDS
cppinit         SEGMENT DWORD PUBLIC USE32 'CPPINIT'
CppStart        label dword
		dd	cpproutine,130
                ENDS
_CPPEND_        SEGMENT DWORD PUBLIC USE32 'CPPINIT'
CppEnd          label dword
		ENDS
cppexit         SEGMENT DWORD PUBLIC USE32 'CPPEXIT'
CpprStart        label dword
		dd	cpproutine,130
                ENDS
_CPPREND_        SEGMENT DWORD PUBLIC USE32 'CPPEXIT'
CpprEnd          label dword
		ENDS
_DATA   	SEGMENT DWORD PUBLIC USE32 'DATA'
                ENDS
_BSS	        SEGMENT DWORD PUBLIC USE32 'BSS'
BssStart	label dword
                ENDS
_BSSEND	        SEGMENT DWORD PUBLIC USE32 'BSS'
BssEnd		label dword
                ENDS
_STACK		segment para stack use32 'STACK'
		align 4
		db  STACK_SIZE  dup(?)
stack_offset	label	dword
                ENDS

;
;       23-04-99 delete from GROUP _TEXT - real FLAT model !!!
;
;DGROUP group _TEXT, cstartup,_STARTUPEND_,crundown,_RUNDOWNEND_,cppinit,_CPPEND_,_DATA,_BSS,_BSSEND, _STACK

DGROUP group cstartup,_STARTUPEND_,crundown,_RUNDOWNEND_,cppinit,_CPPEND_,_DATA,_BSS,_BSSEND, _STACK

public  __rexit, __stacktop
public  __pspseg, __linear, __rmseg


_DATA   	SEGMENT DWORD PUBLIC USE32 'DATA'
;
;       Tested for : DOS4G, DOS4GW, 4GWPRO, PMODEW, WDOSX, DOS32A, ZRDX
;
banner  db 'Startup for DOS/4GW like (c) Kirill Joss. [',??date,']',10,13,36
	db "Copyright (c) 1997-2000 LADsoft C runtime library"
	db " (i386/DOS PMODE/W)"
	align 4
__linear	dd	0
__stacktop	dd	0
stackpos	df	0
__pspseg	dw	0
__rmseg		dw	0


                ENDS

_TEXT           segment para public use32 'CODE'
;_TEXT           SEGMENT
                assume cs:_TEXT,ds:DGROUP

start:
        jmp short real_start
;
;	You can delete 'WATCOM', 
;		but it NOT work with Watcom Debbuger & DOS/4G or DOS/4GW :)
;
		db 'WATCOM', 0 	; The "WATCOM" string is needed in
				; order to run under DOS/4G and WatcomDebug.

;ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ
; CODE
;ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ

;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
; Entry To ASM Code (_main)
; In:
;   CS - Code Selector    Base: 00000000h - Limit: 4G
;   DS - Data Selector    Base: 00000000h - Limit: 4G
;   ES - PSP Selector     Base: PSP Seg   - Limit: 100h
;   FS - ?
;   GS - ?
;   SS - Data Selector    Base: 00000000h - Limit: 4G
;   ESP -> STACK segment
;   Direction Flag - ?
;   Interrupt Flag - ?
;   All Other Registers Are Undefined!
;°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
real_start:
	mov	[__stacktop],esp
        sti                             ; Set The Interrupt Flag
        cld                             ; Clear The Direction Flag

	mov 	[__pspseg], es		; Save psp seg
	
	mov 	eax,ds
	mov	es,eax
	mov 	fs,eax
	mov	gs,eax

ifdef COPYRIGHT                 ; JOSS
	mov edx,offset banner
	mov ah,9
	int 21h
endif
;
; Clear BSS
;
	mov	edi,offset DGROUP:BssStart
	mov	ecx,offset DGROUP:BssEnd
	sub	ecx,edi
	sub	eax,eax
	cld
	rep	stosb
;
; Execute startup routines
;
	push 	ds			; reset es to ds
	pop 	es
	mov	ecx,offset DGROUP:InitStart
	mov	edx,offset DGROUP:InitEnd
	call	sexproc			; good name : SEXproc
	cld
;
; Execute C++ class initializers
;
	mov	ecx,offset DGROUP:CppStart
	mov	edx,offset DGROUP:CppEnd
	call	sexproc			; good name : SEXproc
	cld
;
;
; Call main
;
	push	__environ
	push	__argv_arr
	push	__argc
ifdef DEBUG
		extrn monitor_init:proc
		call monitor_init
endif
	call	_main
	add	esp,12

; exit/abort comes here
;
__rexit:
	push	eax		; saving C return code
;
; Execute C++ class rundown routines
;
	mov	ecx,offset DGROUP:CpprStart
	mov	edx,offset DGROUP:CpprEnd
	call	sexproc
	cld
;
; Execute rundown routines
;
	mov	ecx,offset DGROUP:ExitStart
	mov	edx,offset DGROUP:ExitEnd
	call	sexproc
exitpos:
	pop	eax
	mov	ah,4ch
	int	21h
;
; Handle startup/rundown routines
;
sexproc:
		cmp	ecx,edx		
		jz	short sexpdone	
		mov	edi,ecx
		sub	ebx,ebx
		sub	eax,eax
spl2:
		cmp	edi,edx
		jz	short spo
		test	dword ptr [edi+4],-1
		jz	short spl3
		cmp	eax,[edi+4]
		jnc	short spl3
		mov	ebx,edi
		mov	eax,[edi+4]
spl3:
		add	edi,8
		jmp	spl2
spo:
		or	ebx,ebx
		jz	short sexpdone
		mov	dword ptr [ebx+4],0
		push	edx
		push	ecx
		call	[ebx]
		pop	ecx
		pop	edx
		jmp	sexproc
sexpdone:
		ret

; This is called as the first thing from the C++ main routine
cpproutine:
		ret
_TEXT		ends

end start