133 lines
3.5 KiB
NASM
133 lines
3.5 KiB
NASM
; name XCMAIN -- initiate execution of C program
|
||
;
|
||
; description This is the main module for a C program on the
|
||
; MS-DOS implementation. It initializes the segment
|
||
; registers, sets up the stack, and calls the C main
|
||
; function _main with a pointer to the remainder of
|
||
; the command line.
|
||
;
|
||
; Also defined in this module is the exit entry point
|
||
; XCEXIT.
|
||
;
|
||
pgroup group base,prog,tail
|
||
dgroup group data,stack
|
||
assume cs:pgroup
|
||
;
|
||
; The following segment serves only to force "pgroup" lower in
|
||
; memory.
|
||
;
|
||
base segment 'prog'
|
||
db ?
|
||
base ends
|
||
;
|
||
; The data segment defines locations which contain the offsets
|
||
; of the base and top of the stack.
|
||
;
|
||
data segment public 'data'
|
||
public _top, _base
|
||
_top dw 0
|
||
_base dw 0
|
||
data ends
|
||
;
|
||
; The stack segment defines the base (lowest address) of the
|
||
; stack. Note that in this module it is NOT defined to be
|
||
; of the STACK combining type, thus allowing a .COM file to be
|
||
; made of the resulting .EXE file.
|
||
;
|
||
stack segment 'data'
|
||
sbase dw 128 dup (?)
|
||
stack ends
|
||
;
|
||
; The tail segment allows this module to determine the paragraph
|
||
; at which the data segment begins, without use of a relocatable
|
||
; value.
|
||
;
|
||
tail segment byte 'prog'
|
||
db "MS-C V 1.04 "
|
||
last db 0 ;last byte in PGROUP
|
||
tail ends
|
||
;
|
||
; The main program must set up the initial segment registers
|
||
; and the stack pointer, and set up a far return to the MS-DOS
|
||
; exit point at ES:0. The command line bytes from the program
|
||
; segment prefix are moved onto the stack, and a pointer to
|
||
; them supplied to the C main module _main (which calls main).
|
||
;
|
||
prog segment byte public 'prog'
|
||
public XCMAIN, XCEXIT
|
||
extrn _main:near
|
||
assume cs:pgroup, ds:dgroup, ss:dgroup
|
||
org 0ffh
|
||
XCMAIN proc far
|
||
cli
|
||
mov ax,offset pgroup:last ;get offset of last byte
|
||
add ax,16
|
||
mov cl,4
|
||
shr ax,cl ;number of paragraphs in PGROUP
|
||
mov bx,cs
|
||
add ax,bx ;base of DGROUP
|
||
mov ds,ax ;initialize ds and ss
|
||
mov ss,ax
|
||
mov bx,es:2 ;total memory size (paragraphs)
|
||
sub bx,ax
|
||
test bx,0f000h
|
||
jnz m1 ;branch if more than 64K bytes
|
||
mov cl,4
|
||
shl bx,cl ;highest available byte
|
||
jmp short m2
|
||
m1: mov bx,0fff0h
|
||
m2: mov sp,bx ;set stack pointer
|
||
sti
|
||
mov _top,bx ;save top of stack
|
||
mov ax,offset dgroup:sbase
|
||
mov _base,ax ;store ptr to bottom of stack
|
||
push es ;push ptr to pgm segment prefix
|
||
xor ax,ax
|
||
push ax ;instr ptr for far return
|
||
mov bp,sp ;save in bp
|
||
mov si,80h ;ptr to command line bytes
|
||
mov cl,es:[si] ;get number of bytes
|
||
inc si
|
||
xor ch,ch ;clear high byte
|
||
mov bx,cx
|
||
add bx,4 ;3 bytes additional, 1 for rounding
|
||
and bx,0fffeh ;force even number of bytes
|
||
sub sp,bx ;allocate space on stack
|
||
mov di,sp
|
||
mov byte ptr [di],'c' ;store dummy program name
|
||
inc di
|
||
jcxz m4 ;skip if no bytes to move
|
||
mov byte ptr [di],' '
|
||
inc di
|
||
m3: mov al,es:[si] ;move bytes to stack
|
||
mov [di],al
|
||
inc si
|
||
inc di
|
||
loop m3
|
||
m4: xor ax,ax
|
||
mov [di],al ;store null byte
|
||
mov ax,ds
|
||
mov es,ax ;es, ds, and ss are all equal
|
||
mov ax,sp
|
||
push ax ;ptr to command line
|
||
call _main ;call C main
|
||
mov sp,bp ;restore ptr to far return
|
||
ret ;return to MS-DOS
|
||
XCMAIN endp
|
||
;
|
||
; name XCEXIT -- terminate execution of C program
|
||
;
|
||
; description This function terminates execution of the current
|
||
; program by returning to MS-DOS. The error code
|
||
; argument normally supplied to XCEXIT is ignored
|
||
; in this implementation.
|
||
;
|
||
XCEXIT proc far
|
||
mov ax,_top ;load stack ptr with top address
|
||
sub ax,4
|
||
mov sp,ax
|
||
ret ;return
|
||
XCEXIT endp
|
||
prog ends
|
||
end XCMAIN
|
||
|