]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/ATTRIB/ATTRIBA.ASM
2 title New_C
.C
- DOS
entry to the KWC
's
'C' programs
5 ; This module has been modified extensively for my personal
8 ; name XCMAIN -- initiate execution of C program
10 ; description This is the main module for a C program on the
11 ; DOS implementation. It initializes the segment
12 ; registers, sets up the stack, and calls the C main
13 ; function _main with a pointer to the remainder of
16 ; Also defined in this module is the exit entry point
20 SETBLOCK EQU 4
AH ;MODIFY ALLOCATED MEMORY BLOCKS
21 ;ES = SEGMENT OF THE BLOCK
22 ;BX = NEW REQUESTED BLOCK SIZE
24 ;OUTPUT: BX=MAX SIZE POSSIBLE IF CY SET
25 ;AX = ERROR CODE IF CY SET
27 RET_CD_EXIT EQU 4
CH ;EXIT TO DOS, PASSING RETURN CODE
30 RET_EXIT equ 4
ch ;AN000; ;terminate
31 ABORT equ
2 ;AN000; ;if >=, retry
32 XABORT equ
1 ;AN000; ;errorlevel return in al
35 extrn _inmain
:near ;AC000;
36 extrn _Reset_appendx
:near ;AN000;
37 extrn _old_int24_off
:dword ;AN000;
40 psp
segment at 0 ;<--emk
42 psp_memsz dw ?
;memory size
44 psp_env dw ?
;segid of environment
46 psp_parlen db ?
;length of DOS command line parms
47 psp_par db 127 dup(?
) ;DOS command line parms
52 ; The following segment serves only to force "pgroup" lower in
56 base
segment PARA
PUBLIC 'DATA'
59 db "----------\x0d\x0a"
60 db " DOS ATTRIB function \x0d\x0a"
61 db "--------------------\x0d\x0a"
68 ; The data segment defines locations which contain the offsets
69 ; of the base and top of the stack.
72 _data
segment PARA
public 'DATA'
74 irp name
,<_top
,_base
,_cs
,_ss
,_psp
,_env
,_rax
,_rbx
,_rcx
,_rdx
,_rds
,_rsi
,_rbp
,_res
,_rdi
>
82 ; The stack segment is included to prevent the warning from the
83 ; linker, and also to define the base (lowest address) of the stack.
86 stack segment PARA
stack 'data'
92 null
segment para
public 'BEGDATA'
94 const
segment word public 'CONST'
96 _bss
segment word public 'BSS'
98 pgroup group base
,_text
99 dgroup group null
, _data
, const
, _bss
, stack
104 ; The main program must set up the initial segment registers
105 ; and the stack pointer, and set up a far return to the DOS
106 ; exit point at ES:0. The command line bytes from the program
107 ; segment prefix are moved onto the stack, and a pointer to
108 ; them supplied to the C main module _main (which calls main).
111 _text
segment PARA
public 'CODE'
116 assume
ds:psp
;<--emk
117 assume
es:psp
;<--emk
118 assume
ss:stack ;<--emk
123 mov ds,ax ;initialize ds and ss
126 mov bx,psp_memsz
;total memory size (paragraphs)
129 ; $IF Z ;branch if more than or equal 64K bytes
133 shl bx,cl ;highest available byte
140 cli ; disable interrupts while changing stack <---kwc
141 mov ss,ax ; set ss <---kwc
142 mov sp,bx ; set stack pointer <---kwc
143 sti ;enable interrupts
144 assume
ss:DGroup
;<--emk
148 mov _top
,bx ;save top of stack
150 mov ax,offset DGroup
:SBase
151 mov _base
,ax ;store ptr to bottom of stack
153 ; code added here to allow allocates and exec's in the c code
154 ; we will have to calculate the size of the code that has been loaded
156 mov bx,sp ; bx = length of the stack
160 shr bx,1 ; bx = number of paragraphs in stack,
161 add bx,1 ; (fudge factor!)<--emk ,was 10
163 add bx,ax ; bx = paragraph a little past the stack
164 mov ax,es ; ax = paragraph of the psp
165 sub bx,ax ; bx = number of paragraphs in code
171 mov _psp
,es ; save pointer to psp for setblock <---kwc
172 mov cl,psp_parlen
;get number of bytes <--emk
173 xor ch,ch ;cx = number of bytes of parms!
174 mov si,offset psp_par
;point to DOS command line parms <--emk
176 ; more modified code, picking up argv[0] from the environment!
178 mov ds,psp_env
;set ds to segid of environment from es:psp
181 mov _env
,ds ;remember where environment is
183 mov si,0 ;clear index to step thru env
184 ;The env has a set of keyword=operand, each one ending with a single null byte.
185 ;At the end of the last one is a double null. We are looking for the end of
186 ;all these keywords, by looking for the double null.
190 inc si ;bump index to look at next byte in env
193 cmp word ptr [si],0 ;is this a double null delimiter?
194 ; $ENDDO E ;ifdouble null found, exit
196 ;At end of env is the double null and a word counter
197 add si,4 ;step over this double null delimiter
198 ; and the following word counter
199 push si ;save pointer to next field in env
200 ;This is the invocation statement, including the path name, even if not specified
201 ;but supplied by PATH.
203 ;continue stepping thru env looking for one more null byte, which indicates
204 ;the end of the invocation command.
207 lodsb ;get a byte from env to al
208 cmp al,0 ;is this a null byte?
209 ; $ENDDO E ;quit if null is found
212 mov bx,si ; bx -> asciiz zero
213 pop si ; si -> first byte of agrv[0], the invocation command
214 sub bx,si ; bx = length of argv[0]
215 mov dx,bx ; (save for the copy later)
217 add bx,cx ; add in the length of the rest of the parms
218 inc bx ; add one for the asciiz zero!
219 and bx,0fffeh ;force even number of bytes
220 add bx,2 ;adjust for possible rounding error
221 sub sp,bx ;allocate space on stack
222 mov di,sp ; (es:di) -> where we will put the stuff
226 xchg cx,dx ; length of argv[0] to copy, save length of parms
227 rep movsb ; (ds:si) already point to argv[0]
229 mov ss:byte ptr [di],' ' ;store trailing blank!
231 mov _rdi
,di ;AN000; save start of command parms
232 xchg cx,dx ; restore length of parms
233 ; $IF NCXZ ;if some bytes to move,
236 mov si,offset psp_par
;point to DOS command line parms in psp
239 mov al,es:[si] ;move bytes to stack
245 ; $ENDIF ;bytes to move?
248 mov ss:[di],al ;store null byte
250 mov ds,ax ;es, ds, and ss are all equal
253 mov es,ax ;es, ds, and ss are all equal
256 mov ax,_rdi
;AN000; restore offset of parms on stack
257 push ax ;ptr to command line
259 call _inmain
;AC000; call C main
261 mov ah,ret_cd_exit
;return to DOS
262 int 21h
;errorlevel ret code in al
269 ; name XCEXIT -- terminate execution of C program
271 ; description This function terminates execution of the current
272 ; program by returning to DOS. The error code
273 ; argument normally supplied to XCEXIT is ignored
274 ; in this implementation.
276 ; input - al = binary return code for dos/ERRORLEVEL
287 mov ah,ret_cd_exit
; <--- kwc
292 ;--------------------------------------------------------------------------
296 CENTER
MACRO NAMELIST
297 PUSH BP ; SAVE CURRENT BP
298 MOV BP,SP ; POINT AT STACK WITH BP
300 IRP ANAME
,<NAMELIST
> ; FOR EACH WORKING VARIABLE
302 WORKOFS
= WORKOFS
-2 ; WE WILL ALLOCATE ONE
303 DOEQU
&ANAME
,%WORKOFS
; WORD ON THE STACK THAT
305 ENDM
; IS UNDER SS,BP
309 DOEQU
MACRO NAME
,VALUE
321 ; INPUT PARAMATERS PASSED ON STACK
325 OLD_BP
DW ?
; SAVED BP
326 RETADD
DW ?
; RETURN ADDRESS
343 ;************************************************************************
348 ; Subroutine Function: ;
349 ; get a byte from PSP ; ;
352 ; SS:[BP]+PARM1 = offset in PSP ;
355 ; AL = byte from PSP:offset ;
357 ; C calling convention: ;
358 ; char = getpspbyte(offset); ;
360 ;************************************************************************
362 MOFFSET EQU PARM_1
;AN000;
364 ASSUME
CS:PGROUP
;AN000;
365 ASSUME
DS:DGROUP
;AN000;
366 ASSUME
ES:DGROUP
;AN000;
367 ASSUME
SS:DGROUP
;AN000;
369 PUBLIC _GETPSPBYTE
;AN000;
370 _GETPSPBYTE PROC
NEAR ;AN000;
376 MOV DS,_PSP
;AN000; get save PSP segment
377 MOV SI,[BP].MOFFSET
;AN000; get offset into PSP
378 LODSB ;AN000; get PSP byte
379 MOV AH,0 ;AN000; zero high byte
388 ;************************************************************************
393 ; Subroutine Function: ;
394 ; put a byte into PSP ; ;
397 ; SS:[BP]+MVALUE = byte in AL ;
398 ; SS:[BP]+MOFFSET = offset in PSP ;
403 ; C calling convention: ;
404 ; putpspbyte(offset,char); ;
406 ;************************************************************************
409 MVALUE EQU PARM_2
;AN000;
410 MOFFSET EQU PARM_1
;AN000;
412 ASSUME
CS:PGROUP
;AN000;
413 ASSUME
DS:DGROUP
;AN000;
414 ASSUME
ES:DGROUP
;AN000;
415 ASSUME
SS:DGROUP
;AN000;
417 PUBLIC _PUTPSPBYTE
;AN000;
418 _PUTPSPBYTE PROC
NEAR ;AN000;
424 MOV AX,[BP].MVALUE
;AN000; get byte to store in PSP
425 MOV ES,_PSP
;AN000; get saved PSP segment
426 MOV DI,[BP].MOFFSET
;AN000; get offset in PSP
427 STOSB ;AN000; store the byte
436 ;-------------------------------------------------------------------
438 ; MODULE: crit_err_handler()
440 ; PURPOSE: Supplies assembler exit routines for
441 ; critical error situations
445 ;-------------------------------------------------------------------
446 public _crit_err_handler
;AN000;
447 public vector
;AN000;
450 _crit_err_handler proc
near ;AN000;
452 push ax ; save registers ;AN000;
454 mov ax,dgroup
;get C data segment ;AN000;
456 mov ax,word ptr ds:_old_int24_off
;get int24 offset ;AN000;
457 mov word ptr cs:vector
,ax ;AN000;
458 mov ax,word ptr ds:_old_int24_off
+2 ;get int24 segment ;AN000;
459 mov word ptr cs:vector
+2,ax ;AN000;
460 pop ds ;restore registers ;AN000;
463 call dword ptr cs:vector
; invoke DOS err hndlr ;AN000;
464 cmp al,ABORT
; what was the user's response ;AN000;
467 mov ax,dgroup
;get C data segment ;AN000;
470 call _Reset_appendx
; restore user's orig append/x ;AN000;
472 mov ax,(RET_EXIT
shl 8)+XABORT ; return to DOS w/criterr error ;AN000;
477 _crit_err_handler endp
;AN000;