Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 1581 → Rev 1582

/sved/trunk/makefile
15,7 → 15,7
all: sved.com
 
sved.com: sved.obj deflang.obj
wasm startup.asm
wasm -DSTACKSIZE=1024 -DNOSTACKCHECK startup.asm
wlink @sved.lnk
upx -9 --8086 sved.com
 
/sved/trunk/startup.asm
1,15 → 1,47
; minimalist Watcom C startup routine - TINY memory model ONLY - (.COM files)
; kindly contributed by Bernd Boeckmann
; WMINICRT - minimal runtime for (Open) Watcom C to generate DOS .COM files
;
; The default behaviour of the runtime is:
; - sets up a stack of 400H bytes
; - releases additional memory beyond stack to DOS
; - panics on initialization, if not enough memory for stack size
; - panics if running out of stack during execution
;
; WASM definitions:
; STACKSIZE=<value> define stack size other than 400h
; NOSTACKCHECK do not assemble __STK function
; STACKSTAT remember the minimum SP, maintained by __STK__
; and exported via _stack_low_.
;
; To build an executable without build- and linker scripts run:
; wasm startup.asm
; wcc -0 -bt=dos -ms -os -zl your_c_file.c
; wlink system dos com file startup,your_c_file
; To change the stack size, add -DSTACKSIZE=<value> to the wasm call
;
; To compile without stack checking:
; a) compile this startup file with wasm -DNOSTACKCHECK startup.asm
; b) call the C compiler with -s flag
;
; To build a debug version of your program:
; wasm -d1 startup.asm
; wcc -bt=dos -ms -d2 -zl your_c_file.c
; wlink system dos com debug all option map file startup,your_c_file
;
; TODO:
; - display stack statistics on program termination if STACKSTAT is enabled
; - proper Makefiles
; - many more (optional) things while keeping it small :-)
 
.8086
 
STACK_SIZE = 2048
IFNDEF STACKSIZE
STACKSIZE = 400h
ENDIF
 
DGROUP group _TEXT,_DATA,CONST,CONST2,_BSS,_EOF
DGROUP group _TEXT,_DATA,CONST,CONST2,_BSS,_STACK
 
extrn "C",main : near
 
; public _cstart_, _small_code_, __STK
public _cstart_, _small_code_
 
_TEXT segment word public 'CODE'
17,8 → 49,7
 
_small_code_ label near
 
_cstart_:
 
_cstart_ proc
; DOS puts the COM program in the largest memory block it can find
; and sets SP to the end of this block. On top of that, it reserves
; the entire memory (not only the process' block) to the program, which
26,42 → 57,77
; for this reasons it is beneficial to resize the memory block we occupy
; into a more reasonable value
 
; step 1: if SP > COM size + stack size, then set SP explicitely
; POTENTIAL error: offset DGROUP:_EOF + STACK_SIZE may overflow!
; Has to be detected at linking stage, but WLINK does not catch it.
adjustsp:
cmp sp, offset DGROUP:_EOF + STACK_SIZE
jbe resizemem ; JBE instead of JLE (unsigned comparison!)
mov sp, offset DGROUP:_EOF + STACK_SIZE
@verify_stack_size:
cmp sp,offset DGROUP:_stack_end_
ja @resize_mem
mov dx,offset @memerr
jmp _panic_
@memerr db 'MEMERR$'
 
; step 2: resize our memory block to sp bytes (ie. sp/16 paragraphs)
resizemem:
mov ah, 4ah
mov bx, sp
shr bx, 1
shr bx, 1
shr bx, 1
shr bx, 1
inc bx
@resize_mem:
mov sp,offset DGROUP:_stack_end_
IFDEF STACKSTAT
mov [_stack_low_],sp
ENDIF STACKSTAT
mov ah,4ah
mov bx,sp
add bx,0fh
shr bx,1
shr bx,1
shr bx,1
shr bx,1
int 21h
 
; clear _BSS to be ANSI C conformant
mov di, offset DGROUP:_BSS
mov cx, offset DGROUP:_EOF
sub cx, di
xor al, al
mov di,offset DGROUP:_BSS
mov cx,offset DGROUP:_STACK
sub cx,di
shr cx,1
xor ax,ax
cld
rep stosb
rep stosw
 
call main
mov ah, 4ch
int 21h
call main
mov ah,4ch
int 21h
_cstart_ endp
 
; Stack overflow checking routine is absent. Remember to compile your
; programs with the -s option to avoid referencing __STK
;__STK:
; ret
_panic_ proc
; output error message in DX, then terminate with FF
mov ah,9
int 21h
mov ax,4cffh ; terminate if not enough stack space
int 21h
_panic_ endp
 
IFNDEF NOSTACKCHECK
 
public __STK
__STK proc
; ensures that we have enough stack space left. the needed bytes are
; given in AX. panics if stack low.
sub ax,sp ; subtract needed bytes from SP
neg ax ; SP-AX = -(AX-SP)
cmp ax,offset DGROUP:_STACK - 2 ; -2 is to compensate for __STK ret addr
jae @l1 ; enough stack => return, else panic
int 3 ; trap into debugger
mov dx,offset @stkerr
add sp,200h ; make sure we have enough stack to call DOS
jmp _panic_
@stkerr db 'STKERR$'
@l1:
IFDEF STACKSTAT ; update lowest stack pointer if statistics enabled
cmp [_stack_low_],ax
jbe @r
mov [_stack_low_],ax
ENDIF STACKSTAT
@r:
ret
__STK endp
 
ENDIF
 
_DATA segment word public 'DATA'
_DATA ends
 
72,15 → 138,20
CONST2 ends
 
_BSS segment word public 'BSS'
IFDEF STACKSTAT
public _stack_low_
_stack_low_: dw 1 dup(?)
ENDIF STACKSTAT
_BSS ends
 
; _EOF should be the last segment in .COM (see linker memory map)
; if not, someone introduced other segments, or startup.obj is not the first
; linker object file
_EOF segment word public
_EOF ends
; stack definition, available memory is checked at runtime
; defined as segment so that linker may detect .COM size overflow
_STACK segment para public 'TINY_STACK'
public _stack_end_
db STACKSIZE dup(?)
_stack_end_:
_STACK ends
 
_TEXT ends
 
end _cstart_