Subversion Repositories SvarDOS

Rev

Rev 1582 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1582 mateusz.vi 1
; WMINICRT - minimal runtime for (Open) Watcom C to generate DOS .COM files
2
;
3
; The default behaviour of the runtime is:
4
;   - sets up a stack of 400H bytes
5
;   - releases additional memory beyond stack to DOS
6
;   - panics on initialization, if not enough memory for stack size
7
;   - panics if running out of stack during execution
8
;
9
; WASM definitions:
10
;   STACKSIZE=<value>     define stack size other than 400h
11
;   NOSTACKCHECK          do not assemble __STK function
12
;   STACKSTAT             remember the minimum SP, maintained by __STK__
13
;                         and exported via _stack_low_.
14
;
15
; To build an executable without build- and linker scripts run:
16
;   wasm startup.asm
17
;   wcc -0 -bt=dos -ms -os -zl your_c_file.c
18
;   wlink system dos com file startup,your_c_file
19
; To change the stack size, add -DSTACKSIZE=<value> to the wasm call
20
;
21
; To compile without stack checking:
22
;   a) compile this startup file with wasm -DNOSTACKCHECK startup.asm
23
;   b) call the C compiler with -s flag
24
;
25
; To build a debug version of your program:
26
;   wasm -d1 startup.asm
27
;   wcc -bt=dos -ms -d2 -zl your_c_file.c
28
;   wlink system dos com debug all option map file startup,your_c_file
29
;
30
; TODO:
31
;   - display stack statistics on program termination if STACKSTAT is enabled
32
;   - proper Makefiles
33
;   - many more (optional) things while keeping it small :-)
1558 mateusz.vi 34
 
1556 mateusz.vi 35
.8086
36
 
1582 mateusz.vi 37
IFNDEF STACKSIZE
38
STACKSIZE = 400h
39
ENDIF
1556 mateusz.vi 40
 
1582 mateusz.vi 41
      DGROUP group _TEXT,_DATA,CONST,CONST2,_BSS,_STACK
1556 mateusz.vi 42
 
43
      extrn   "C",main : near
44
 
45
      public _cstart_, _small_code_
46
 
47
_TEXT segment word public 'CODE'
48
      org   100h
49
 
50
_small_code_ label near
51
 
1582 mateusz.vi 52
_cstart_ proc
1556 mateusz.vi 53
      ; DOS puts the COM program in the largest memory block it can find
54
      ; and sets SP to the end of this block. On top of that, it reserves
55
      ; the entire memory (not only the process' block) to the program, which
56
      ; makes it impossible to allocate memory or run child processes.
57
      ; for this reasons it is beneficial to resize the memory block we occupy
58
      ; into a more reasonable value
59
 
1582 mateusz.vi 60
    @verify_stack_size:
61
      cmp sp,offset DGROUP:_stack_end_
62
      ja @resize_mem
63
      mov dx,offset @memerr
64
      jmp _panic_
65
      @memerr db 'MEMERR$'
1556 mateusz.vi 66
 
67
      ; step 2: resize our memory block to sp bytes (ie. sp/16 paragraphs)
1582 mateusz.vi 68
    @resize_mem:
69
      mov sp,offset DGROUP:_stack_end_
70
      IFDEF STACKSTAT
71
        mov [_stack_low_],sp
72
      ENDIF STACKSTAT
73
      mov ah,4ah
74
      mov bx,sp
75
      add bx,0fh
76
      shr bx,1
77
      shr bx,1
78
      shr bx,1
79
      shr bx,1
1556 mateusz.vi 80
      int 21h
81
 
1558 mateusz.vi 82
      ; clear _BSS to be ANSI C conformant
1582 mateusz.vi 83
      mov di,offset DGROUP:_BSS
84
      mov cx,offset DGROUP:_STACK
85
      sub cx,di
86
      shr cx,1
87
      xor ax,ax
1558 mateusz.vi 88
      cld
1582 mateusz.vi 89
      rep stosw
1558 mateusz.vi 90
 
1582 mateusz.vi 91
      call main
92
      mov ah,4ch
93
      int 21h
94
_cstart_ endp
1556 mateusz.vi 95
 
1582 mateusz.vi 96
_panic_ proc
97
      ; output error message in DX, then terminate with FF
98
      mov ah,9
99
      int 21h
100
      mov ax,4cffh      ; terminate if not enough stack space
101
      int 21h
102
_panic_ endp
1556 mateusz.vi 103
 
1582 mateusz.vi 104
      IFNDEF NOSTACKCHECK
105
 
106
public __STK
107
__STK proc
108
      ; ensures that we have enough stack space left. the needed bytes are
109
      ; given in AX. panics if stack low.
110
      sub ax,sp         ; subtract needed bytes from SP
111
      neg ax            ; SP-AX = -(AX-SP)
112
      cmp ax,offset DGROUP:_STACK - 2 ; -2 is to compensate for __STK ret addr
113
      jae @l1           ; enough stack => return, else panic
114
      int 3             ; trap into debugger
115
      mov dx,offset @stkerr
116
      add sp,200h       ; make sure we have enough stack to call DOS
117
      jmp _panic_
118
      @stkerr db 'STKERR$'
119
@l1:
120
      IFDEF STACKSTAT   ; update lowest stack pointer if statistics enabled
121
        cmp [_stack_low_],ax
122
        jbe @r
123
        mov [_stack_low_],ax
124
      ENDIF STACKSTAT
125
@r:
126
      ret
127
__STK endp
128
 
129
      ENDIF
130
 
1558 mateusz.vi 131
_DATA segment word public 'DATA'
132
_DATA ends
1556 mateusz.vi 133
 
1558 mateusz.vi 134
CONST segment word public 'DATA'
135
CONST ends
1556 mateusz.vi 136
 
1558 mateusz.vi 137
CONST2 segment word public 'DATA'
138
CONST2 ends
1556 mateusz.vi 139
 
1558 mateusz.vi 140
_BSS  segment word public 'BSS'
1582 mateusz.vi 141
      IFDEF STACKSTAT
142
        public _stack_low_
143
        _stack_low_:  dw 1 dup(?)
144
      ENDIF STACKSTAT
1558 mateusz.vi 145
_BSS  ends
1556 mateusz.vi 146
 
1582 mateusz.vi 147
; stack definition, available memory is checked at runtime
148
; defined as segment so that linker may detect .COM size overflow
149
_STACK segment para public 'TINY_STACK'
150
public _stack_end_
151
      db STACKSIZE dup(?)
152
_stack_end_:
153
_STACK ends
1556 mateusz.vi 154
 
155
_TEXT ends
156
 
157
      end _cstart_