MASM

_TEXT           segment para public use16 'CODE'
_TEXT           ends

_DATA           segment word public use16 'DATA'
_DATA           ends

_BSS            segment byte public use16 'BSS'
_BSS            ends

_STACK          segment stack use16
_STACK          ends

INIT5_DATA	segment para public use16 'FAR_DATA'
INIT5_DATA	ends

_EOD            segment para public use16 'END_DATA'
_EOD            ends

DGROUP          group _DATA,_BSS,_STACK

_DATA           segment word public use16 'DATA'
		public __psp
		__psp dw 0
_DATA           ends

_TEXT           segment
		assume cs:_TEXT, ds:DGROUP, es:DGROUP, ss:DGROUP
		extrn _main:near
		extrn _premain:near
		extrn _timer_init:near

.386p

; Device driver header

                public SysStrat, SysIntr, _ReqHdr

                dw      -1, -1                ; Will be chaining address
                dw      1000000000000000b     ; Driver attribute - we don't support anything here...
                dw      offset SysStrat       ; Pointer to strategy routine
                dw      offset SysIntr        ; Pointer to interrupt routine
                db      "IWINIT",0,0          ; New driver name

_ReqHdr          label dword
ReqOfs          dw      ?
ReqSeg          dw      ?

DosStack        label   dword
DosSp           dw      ?
DosSs           dw      ?

ExeStart:       mov ax, DGROUP
		mov ds,ax
		mov es,ax
		mov bx,offset DGROUP:stacktop
		mov ss,ax
		mov sp,bx
		mov ax, 5100h
		int 21h
		mov __psp, bx
		mov ax, seg _EOD
		sub ax, bx
		inc ax
		mov es, bx
		mov bx, ax
		mov ax, 4a00h
		int 21h
		push ds
		pop es
		call _timer_init
		mov ax, 1	; executable startup
		push ax
		call _main
		add sp, 2
done:		mov  ah,4ch
		int  21h

SysStrat:       ;int  3
                mov     cs:ReqOfs,bx
                mov     cs:ReqSeg,es
                retf

SysIntr:        ;int 3

                pushfd
                pushad

                mov     cs:DosSs,ss
                mov     cs:DosSp,sp

                mov     ax,DGROUP
                mov     ds,ax
                mov     es,ax
                mov     bx,offset DGROUP:stacktop
                mov     ss,ax
                mov     sp,bx
		;int	3
		
		call	_timer_init
		mov	ax, 0	; .SYS startup
		push	ax
                call    _main
		add	sp, 2

sys_done:       cli
                mov     ss,cs:DosSs
                mov     sp,cs:DosSp
                sti

                les     di,cs:_ReqHdr
                mov     ax,0                    ; Don't go resident
                mov     word ptr es:[di+14],ax
                mov     es:[di+14+2],cs
                xor     ax,ax

                popad
                popfd
                retf
_TEXT           ends

_STACK          segment
		dw 512 dup (?)
stacktop        label word
_STACK          ends
		end     ExeStart
