summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/ATTRIB/ATTRIBA.ASM')
-rw-r--r--v4.0/src/CMD/ATTRIB/ATTRIBA.ASM480
1 files changed, 480 insertions, 0 deletions
diff --git a/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM b/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM
new file mode 100644
index 0000000..4f9c312
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM
@@ -0,0 +1,480 @@
1 page ,132 ;
2 title New_C.C - DOS entry to the KWC's 'C' programs
3
4;
5; This module has been modified extensively for my personal
6; use.
7;
8; name XCMAIN -- initiate execution of C program
9;
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
14; the command line.
15;
16; Also defined in this module is the exit entry point
17; XCEXIT.
18;
19; $salut (4,12,18,41)
20SETBLOCK EQU 4AH ;MODIFY ALLOCATED MEMORY BLOCKS
21 ;ES = SEGMENT OF THE BLOCK
22 ;BX = NEW REQUESTED BLOCK SIZE
23 ; IN PARAGRAPHS
24 ;OUTPUT: BX=MAX SIZE POSSIBLE IF CY SET
25 ;AX = ERROR CODE IF CY SET
26
27RET_CD_EXIT EQU 4CH ;EXIT TO DOS, PASSING RETURN CODE
28 ;AL=RETURN CODE
29
30RET_EXIT equ 4ch ;AN000; ;terminate
31ABORT equ 2 ;AN000; ;if >=, retry
32XABORT equ 1 ;AN000; ;errorlevel return in al
33
34
35 extrn _inmain:near ;AC000;
36 extrn _Reset_appendx:near ;AN000;
37 extrn _old_int24_off:dword ;AN000;
38
39
40psp segment at 0 ;<--emk
41psp_ret dw ? ;int 20h
42psp_memsz dw ? ;memory size
43 org 2ch
44psp_env dw ? ;segid of environment
45 org 80h
46psp_parlen db ? ;length of DOS command line parms
47psp_par db 127 dup(?) ;DOS command line parms
48psp ends
49 page
50
51;
52; The following segment serves only to force "pgroup" lower in
53; memory.
54;
55
56base segment PARA PUBLIC 'DATA'
57
58 db 00dh,00ah
59 db "----------\x0d\x0a"
60 db " DOS ATTRIB function \x0d\x0a"
61 db "--------------------\x0d\x0a"
62 db 00dh,00ah,01ah
63
64base ends
65
66
67;
68; The data segment defines locations which contain the offsets
69; of the base and top of the stack.
70;
71
72_data segment PARA public 'DATA'
73
74 irp name,<_top,_base,_cs,_ss,_psp,_env,_rax,_rbx,_rcx,_rdx,_rds,_rsi,_rbp,_res,_rdi>
75 public name
76name dw 0
77 endm
78
79_data ends
80
81;
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.
84;
85
86stack segment PARA stack 'data'
87
88SBase dw 128 dup (?)
89
90stack ends
91
92null segment para public 'BEGDATA'
93null ends
94const segment word public 'CONST'
95const ends
96_bss segment word public 'BSS'
97_bss ends
98pgroup group base,_text
99dgroup group null, _data, const, _bss, stack
100
101 page
102
103;
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).
109;
110
111_text segment PARA public 'CODE'
112
113 public XCMAIN
114
115 assume cs:pgroup
116 assume ds:psp ;<--emk
117 assume es:psp ;<--emk
118 assume ss:stack ;<--emk
119
120XCMAIN proc far
121
122 mov ax,dgroup
123 mov ds,ax ;initialize ds and ss
124 assume ds:dgroup
125
126 mov bx,psp_memsz ;total memory size (paragraphs)
127 sub bx,ax
128 test bx,0f000h
129; $IF Z ;branch if more than or equal 64K bytes
130 JNZ $$IF1
131
132 mov cl,4
133 shl bx,cl ;highest available byte
134; $ELSE
135 JMP SHORT $$EN1
136$$IF1:
137 mov bx,0fff0h
138; $ENDIF
139$$EN1:
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
145
146 mov _ss,ss
147 mov _cs,cs
148 mov _top,bx ;save top of stack
149
150 mov ax,offset DGroup:SBase
151 mov _base,ax ;store ptr to bottom of stack
152
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
155
156 mov bx,sp ; bx = length of the stack
157 shr bx,1
158 shr bx,1
159 shr bx,1
160 shr bx,1 ; bx = number of paragraphs in stack,
161 add bx,1 ; (fudge factor!)<--emk ,was 10
162 mov ax,ss
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
166 mov ah,setblock
167 int 021h
168
169; end of added code!
170
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
175
176; more modified code, picking up argv[0] from the environment!
177
178 mov ds,psp_env ;set ds to segid of environment from es:psp
179 assume ds:nothing
180
181 mov _env,ds ;remember where environment is
182
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.
187; $DO COMPLEX
188 JMP SHORT $$SD4
189$$DO4:
190 inc si ;bump index to look at next byte in env
191; $STRTDO
192$$SD4:
193 cmp word ptr [si],0 ;is this a double null delimiter?
194; $ENDDO E ;ifdouble null found, exit
195 JNE $$DO4
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.
202
203;continue stepping thru env looking for one more null byte, which indicates
204;the end of the invocation command.
205; $DO
206$$DO7:
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
210 JNE $$DO7
211
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)
216 dec dx
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
223 push es
224 mov ax,ss
225 mov es,ax
226 xchg cx,dx ; length of argv[0] to copy, save length of parms
227 rep movsb ; (ds:si) already point to argv[0]
228 pop es
229 mov ss:byte ptr [di],' ' ;store trailing blank!
230 inc di
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,
234 JCXZ $$IF9
235
236 mov si,offset psp_par ;point to DOS command line parms in psp
237; $DO
238$$DO10:
239 mov al,es:[si] ;move bytes to stack
240 mov ss:[di],al
241 inc si
242 inc di
243; $ENDDO LOOP
244 LOOP $$DO10
245; $ENDIF ;bytes to move?
246$$IF9:
247 xor ax,ax
248 mov ss:[di],al ;store null byte
249 mov ax,ss
250 mov ds,ax ;es, ds, and ss are all equal
251 assume ds:DGroup
252
253 mov es,ax ;es, ds, and ss are all equal
254 assume es:DGroup
255
256 mov ax,_rdi ;AN000; restore offset of parms on stack
257 push ax ;ptr to command line
258
259 call _inmain ;AC000; call C main
260
261 mov ah,ret_cd_exit ;return to DOS
262 int 21h ;errorlevel ret code in al
263
264XCMAIN endp
265
266 page
267
268;
269; name XCEXIT -- terminate execution of C program
270;
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.
275;
276; input - al = binary return code for dos/ERRORLEVEL
277;
278
279 assume cs:PGroup
280 assume ds:DGroup
281 assume es:DGroup
282 assume ss:DGroup
283
284 public xcexit
285XCEXIT proc far
286
287 mov ah,ret_cd_exit ; <--- kwc
288 int 021h ; <--- kwc
289
290XCEXIT endp
291
292;--------------------------------------------------------------------------
293
294 PAGE
295
296CENTER MACRO NAMELIST
297 PUSH BP ; SAVE CURRENT BP
298 MOV BP,SP ; POINT AT STACK WITH BP
299WORKOFS = 0
300 IRP ANAME,<NAMELIST> ; FOR EACH WORKING VARIABLE
301 IFNB <&ANAME>
302WORKOFS = WORKOFS-2 ; WE WILL ALLOCATE ONE
303 DOEQU &ANAME,%WORKOFS ; WORD ON THE STACK THAT
304 ENDIF
305 ENDM ; IS UNDER SS,BP
306 ADD SP,WORKOFS
307 ENDM
308
309DOEQU MACRO NAME,VALUE
310&NAME EQU &VALUE
311 ENDM
312
313CEXIT MACRO VALUE
314 MOV SP,BP
315 POP BP
316 RET
317 ENDM
318
319 PAGE
320
321; INPUT PARAMATERS PASSED ON STACK
322
323PARMS STRUC
324
325OLD_BP DW ? ; SAVED BP
326RETADD DW ? ; RETURN ADDRESS
327PARM_1 DW ?
328PARM_2 DW ?
329PARM_3 DW ?
330PARM_4 DW ?
331PARM_5 DW ?
332PARM_6 DW ?
333PARM_7 DW ?
334PARM_8 DW ?
335
336PARMS ENDS
337
338SAVE_SS DW 0
339SAVE_SP DW 0
340
341 PAGE
342
343;************************************************************************
344; ;
345; Subroutine Name: ;
346; getpspbyte ;
347; ;
348; Subroutine Function: ;
349; get a byte from PSP ; ;
350; ;
351; Input: ;
352; SS:[BP]+PARM1 = offset in PSP ;
353; ;
354; Output: ;
355; AL = byte from PSP:offset ;
356; ;
357; C calling convention: ;
358; char = getpspbyte(offset); ;
359; ;
360;************************************************************************
361
362MOFFSET EQU PARM_1 ;AN000;
363
364 ASSUME CS:PGROUP ;AN000;
365 ASSUME DS:DGROUP ;AN000;
366 ASSUME ES:DGROUP ;AN000;
367 ASSUME SS:DGROUP ;AN000;
368
369 PUBLIC _GETPSPBYTE ;AN000;
370_GETPSPBYTE PROC NEAR ;AN000;
371
372 CENTER ;AN000;
373
374 PUSH DS ;AN000;
375
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
380
381 POP DS ;AN000;
382
383 CEXIT ;AN000;
384
385_GETPSPBYTE ENDP
386
387
388;************************************************************************
389; ;
390; Subroutine Name: ;
391; putpspbyte ;
392; ;
393; Subroutine Function: ;
394; put a byte into PSP ; ;
395; ;
396; Input: ;
397; SS:[BP]+MVALUE = byte in AL ;
398; SS:[BP]+MOFFSET = offset in PSP ;
399; ;
400; Output: ;
401; none ;
402; ;
403; C calling convention: ;
404; putpspbyte(offset,char); ;
405; ;
406;************************************************************************
407
408
409MVALUE EQU PARM_2 ;AN000;
410MOFFSET EQU PARM_1 ;AN000;
411
412 ASSUME CS:PGROUP ;AN000;
413 ASSUME DS:DGROUP ;AN000;
414 ASSUME ES:DGROUP ;AN000;
415 ASSUME SS:DGROUP ;AN000;
416
417 PUBLIC _PUTPSPBYTE ;AN000;
418_PUTPSPBYTE PROC NEAR ;AN000;
419
420 CENTER ;AN000;
421
422 PUSH ES ;AN000;
423
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
428
429 POP ES ;AN000;
430
431 CEXIT ;AN000;
432
433_PUTPSPBYTE ENDP
434
435
436;-------------------------------------------------------------------
437;
438; MODULE: crit_err_handler()
439;
440; PURPOSE: Supplies assembler exit routines for
441; critical error situations
442;
443; CALLING FORMAT:
444; crit_err_handler;
445;-------------------------------------------------------------------
446 public _crit_err_handler ;AN000;
447 public vector ;AN000;
448vector dd 0 ;AN000;
449; ;AN000;
450_crit_err_handler proc near ;AN000;
451 pushf ;AN000;
452 push ax ; save registers ;AN000;
453 push ds ;AN000;
454 mov ax,dgroup ;get C data segment ;AN000;
455 mov ds,ax ;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;
461 pop ax ;AN000;
462; ;AN000;
463 call dword ptr cs:vector ; invoke DOS err hndlr ;AN000;
464 cmp al,ABORT ; what was the user's response ;AN000;
465 jnge retry ; ;AN000;
466; ;AN000;
467 mov ax,dgroup ;get C data segment ;AN000;
468 mov ds,ax ;AN000;
469 mov es,ax ;AN000;
470 call _Reset_appendx ; restore user's orig append/x ;AN000;
471; ;AN000;
472 mov ax,(RET_EXIT shl 8)+XABORT ; return to DOS w/criterr error ;AN000;
473 int 21h ; ;AN000;
474retry: ;AN000;
475 iret ;AN000;
476; ;AN000;
477_crit_err_handler endp ;AN000;
478_text ends ;AN000;
479 end XCMAIN ;AN000;
480 \ No newline at end of file