summaryrefslogtreecommitdiff
path: root/v2.0/source
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source')
-rw-r--r--v2.0/source/ALLOC.ASM371
-rw-r--r--v2.0/source/ANSI.txtbin0 -> 6784 bytes
-rw-r--r--v2.0/source/BUF.ASM508
-rw-r--r--v2.0/source/CHKDSK.ASM901
-rw-r--r--v2.0/source/CHKMES.ASM477
-rw-r--r--v2.0/source/CHKPROC.ASM1408
-rw-r--r--v2.0/source/COMEQU.ASM33
-rw-r--r--v2.0/source/COMLINKbin0 -> 128 bytes
-rw-r--r--v2.0/source/COMMAND.ASM788
-rw-r--r--v2.0/source/COMSEG.ASM38
-rw-r--r--v2.0/source/COMSW.ASM13
-rw-r--r--v2.0/source/CONFIG.txtbin0 -> 3456 bytes
-rw-r--r--v2.0/source/COPY.ASM579
-rw-r--r--v2.0/source/COPYPROC.ASM526
-rw-r--r--v2.0/source/CPARSE.ASM291
-rw-r--r--v2.0/source/CTRLC.ASM468
-rw-r--r--v2.0/source/DEBASM.ASM1264
-rw-r--r--v2.0/source/DEBCOM1.ASM694
-rw-r--r--v2.0/source/DEBCOM2.ASM1269
-rw-r--r--v2.0/source/DEBCONST.ASM1103
-rw-r--r--v2.0/source/DEBDATA.ASMbin0 -> 2816 bytes
-rw-r--r--v2.0/source/DEBEQU.ASM32
-rw-r--r--v2.0/source/DEBMES.ASMbin0 -> 5248 bytes
-rw-r--r--v2.0/source/DEBUASM.ASM868
-rw-r--r--v2.0/source/DEBUG.ASM838
-rw-r--r--v2.0/source/DEV.ASM439
-rw-r--r--v2.0/source/DEVDRIV.txt802
-rw-r--r--v2.0/source/DEVSYM.ASMbin0 -> 2688 bytes
-rw-r--r--v2.0/source/DIR.ASM1084
-rw-r--r--v2.0/source/DIRCALL.ASM507
-rw-r--r--v2.0/source/DISK.ASM1302
-rw-r--r--v2.0/source/DISKCOPY.ASMbin0 -> 6656 bytes
-rw-r--r--v2.0/source/DISKMES.ASMbin0 -> 7808 bytes
-rw-r--r--v2.0/source/DOSLINK5
-rw-r--r--v2.0/source/DOSMAC.ASMbin0 -> 6656 bytes
-rw-r--r--v2.0/source/DOSMAC_v211.ASM274
-rw-r--r--v2.0/source/DOSMES.ASM355
-rw-r--r--v2.0/source/DOSSEG.ASM17
-rw-r--r--v2.0/source/DOSSYM.ASM904
-rw-r--r--v2.0/source/DOSSYM_v211.ASM963
-rw-r--r--v2.0/source/EDLIN.ASM1846
-rw-r--r--v2.0/source/EDLMES.ASMbin0 -> 3200 bytes
-rw-r--r--v2.0/source/EDLPROC.ASM531
-rw-r--r--v2.0/source/EXE2BIN.ASM514
-rw-r--r--v2.0/source/EXEC.ASM1035
-rw-r--r--v2.0/source/EXEMES.ASMbin0 -> 768 bytes
-rw-r--r--v2.0/source/FAT.ASM362
-rw-r--r--v2.0/source/FC.ASM1684
-rw-r--r--v2.0/source/FCB.ASM512
-rw-r--r--v2.0/source/FCMES.ASMbin0 -> 2048 bytes
-rw-r--r--v2.0/source/FIND.ASM932
-rw-r--r--v2.0/source/FINDMES.ASMbin0 -> 1408 bytes
-rw-r--r--v2.0/source/FORMAT.ASM1627
-rw-r--r--v2.0/source/FORMAT.txt393
-rw-r--r--v2.0/source/FORMES.ASMbin0 -> 4529 bytes
-rw-r--r--v2.0/source/GENFOR.ASMbin0 -> 4096 bytes
-rw-r--r--v2.0/source/GETSET.ASM627
-rw-r--r--v2.0/source/HRDDRV.ASM501
-rw-r--r--v2.0/source/IFEQU.ASM18
-rw-r--r--v2.0/source/INCOMP.txtbin0 -> 2688 bytes
-rw-r--r--v2.0/source/INIT.ASM939
-rw-r--r--v2.0/source/INT24.txtbin0 -> 4224 bytes
-rw-r--r--v2.0/source/MISC.ASM648
-rw-r--r--v2.0/source/MORE.ASMbin0 -> 3712 bytes
-rw-r--r--v2.0/source/MOREMES.ASM17
-rw-r--r--v2.0/source/MSCODE.ASM615
-rw-r--r--v2.0/source/MSDATA.ASM342
-rw-r--r--v2.0/source/MSDOS.ASM12
-rw-r--r--v2.0/source/MSHEAD.ASM198
-rw-r--r--v2.0/source/MSINIT.ASM408
-rw-r--r--v2.0/source/PCLOCK.ASMbin0 -> 3200 bytes
-rw-r--r--v2.0/source/PRINT.ASM1645
-rw-r--r--v2.0/source/PRINT_v211.ASM1645
-rw-r--r--v2.0/source/PROC.ASM130
-rw-r--r--v2.0/source/PROFIL.ASM705
-rw-r--r--v2.0/source/PROFILE.txtbin0 -> 3968 bytes
-rw-r--r--v2.0/source/PROHST.HLP35
-rw-r--r--v2.0/source/QUICK.txtbin0 -> 3456 bytes
-rw-r--r--v2.0/source/RDATA.ASMbin0 -> 6784 bytes
-rw-r--r--v2.0/source/README.txt177
-rw-r--r--v2.0/source/RECMES.ASMbin0 -> 5760 bytes
-rw-r--r--v2.0/source/RECOVER.ASM876
-rw-r--r--v2.0/source/ROM.ASM530
-rw-r--r--v2.0/source/RUCODE.ASMbin0 -> 6912 bytes
-rw-r--r--v2.0/source/SKELIO.ASM1377
-rw-r--r--v2.0/source/SORT.ASM420
-rw-r--r--v2.0/source/SORTMES.ASMbin0 -> 2688 bytes
-rw-r--r--v2.0/source/STDBUF.ASMbin0 -> 256 bytes
-rw-r--r--v2.0/source/STDCALL.ASMbin0 -> 256 bytes
-rw-r--r--v2.0/source/STDCTRLC.ASMbin0 -> 256 bytes
-rw-r--r--v2.0/source/STDFCB.ASM16
-rw-r--r--v2.0/source/STDIO.ASM17
-rw-r--r--v2.0/source/STDPROC.ASM16
-rw-r--r--v2.0/source/STDSW.ASM34
-rw-r--r--v2.0/source/STRIN.ASM292
-rw-r--r--v2.0/source/SYS.ASM587
-rw-r--r--v2.0/source/SYSCALL.ASM749
-rw-r--r--v2.0/source/SYSCALL.txt1657
-rw-r--r--v2.0/source/SYSIMES.ASMbin0 -> 512 bytes
-rw-r--r--v2.0/source/SYSINIT.ASM1424
-rw-r--r--v2.0/source/SYSINIT.txtbin0 -> 3072 bytes
-rw-r--r--v2.0/source/SYSMES.ASM51
-rw-r--r--v2.0/source/TCODE.ASM1088
-rw-r--r--v2.0/source/TCODE2.ASM522
-rw-r--r--v2.0/source/TCODE3.ASM677
-rw-r--r--v2.0/source/TCODE4.ASM1002
-rw-r--r--v2.0/source/TCODE5.ASM953
-rw-r--r--v2.0/source/TDATA.ASM243
-rw-r--r--v2.0/source/TIME.ASMbin0 -> 7040 bytes
-rw-r--r--v2.0/source/TSPC.ASMbin0 -> 4480 bytes
-rw-r--r--v2.0/source/TUCODE.ASMbin0 -> 7808 bytes
-rw-r--r--v2.0/source/UINIT.ASMbin0 -> 896 bytes
-rw-r--r--v2.0/source/UTILITY.txt813
-rw-r--r--v2.0/source/WSBAUD.BASbin0 -> 1152 bytes
-rw-r--r--v2.0/source/WSMSGS.OVRbin0 -> 27264 bytes
-rw-r--r--v2.0/source/WSOVLY1.OVRbin0 -> 40960 bytes
-rw-r--r--v2.0/source/XENIX.ASM907
-rw-r--r--v2.0/source/XENIX2.ASM626
118 files changed, 52096 insertions, 0 deletions
diff --git a/v2.0/source/ALLOC.ASM b/v2.0/source/ALLOC.ASM
new file mode 100644
index 0000000..7b69826
--- /dev/null
+++ b/v2.0/source/ALLOC.ASM
@@ -0,0 +1,371 @@
1;
2; xenix memory calls for MSDOS
3;
4; CAUTION: The following routines rely on the fact that arena_signature and
5; arena_owner_system are all equal to zero and are contained in DI.
6;
7INCLUDE DOSSEG.ASM
8
9CODE SEGMENT BYTE PUBLIC 'CODE'
10 ASSUME SS:DOSGROUP,CS:DOSGROUP
11
12.xlist
13.xcref
14INCLUDE DOSSYM.ASM
15INCLUDE DEVSYM.ASM
16.cref
17.list
18
19TITLE ALLOC.ASM - memory arena manager
20NAME Alloc
21
22SUBTTL memory allocation utility routines
23PAGE
24;
25; arena data
26;
27 i_need arena_head,WORD ; seg address of start of arena
28 i_need CurrentPDB,WORD ; current process data block addr
29 i_need FirstArena,WORD ; first free block found
30 i_need BestArena,WORD ; best free block found
31 i_need LastArena,WORD ; last free block found
32 i_need AllocMethod,BYTE ; how to alloc first(best)last
33
34;
35; arena_free_process
36; input: BX - PID of process
37; output: free all blocks allocated to that PID
38;
39 procedure arena_free_process,NEAR
40 ASSUME DS:NOTHING,ES:NOTHING
41 MOV DI,arena_signature
42 MOV AX,[arena_head]
43 CALL Check_Signature ; ES <- AX, check for valid block
44
45arena_free_process_loop:
46 retc
47 PUSH ES
48 POP DS
49 CMP DS:[arena_owner],BX ; is block owned by pid?
50 JNZ arena_free_next ; no, skip to next
51 MOV DS:[arena_owner],DI ; yes... free him
52
53arena_free_next:
54 CMP BYTE PTR DS:[DI],arena_signature_end
55 ; end of road, Jack?
56 retz ; never come back no more
57 CALL arena_next ; next item in ES/AX carry set if trash
58 JMP arena_free_process_loop
59
60arena_free_process ENDP
61
62;
63; arena_next
64; input: DS - pointer to block head
65; output: AX,ES - pointers to next head
66; carry set if trashed arena
67;
68 procedure arena_next,NEAR
69 ASSUME DS:NOTHING,ES:NOTHING
70 MOV AX,DS ; AX <- current block
71 ADD AX,DS:[arena_size] ; AX <- AX + current block length
72 INC AX ; remember that header!
73;
74; fall into check_signature and return
75;
76; CALL check_signature ; ES <- AX, carry set if error
77; RET
78arena_next ENDP
79
80;
81; check_signature
82; input: AX - address of block header
83; output: ES=AX, carry set if signature is bad
84;
85 procedure check_signature,NEAR
86 ASSUME DS:NOTHING,ES:NOTHING
87 MOV ES,AX ; ES <- AX
88 CMP BYTE PTR ES:[DI],arena_signature_normal
89 ; IF next signature = not_end THEN
90 JZ check_signature_ok ; GOTO ok
91 CMP BYTE PTR ES:[DI],arena_signature_end
92 ; IF next signature = end then
93 JZ check_signature_ok ; GOTO ok
94 STC ; set error
95 return
96
97check_signature_ok:
98 CLC
99 return
100Check_signature ENDP
101
102;
103; Coalesce - combine free blocks ahead with current block
104; input: DS - pointer to head of free block
105; output: updated head of block, AX is next block
106; carry set -> trashed arena
107;
108 procedure Coalesce,NEAR
109 ASSUME DS:NOTHING,ES:NOTHING
110 CMP BYTE PTR DS:[DI],arena_signature_end
111 ; IF current signature = END THEN
112 retz ; GOTO ok
113 CALL arena_next ; ES, AX <- next block, Carry set if error
114 retc ; IF no error THEN GOTO check
115
116coalesce_check:
117 CMP ES:[arena_owner],DI
118 retnz ; IF next block isnt free THEN return
119 MOV CX,ES:[arena_size] ; CX <- next block size
120 INC CX ; CX <- CX + 1 (for header size)
121 ADD DS:[arena_size],CX ; current size <- current size + CX
122 MOV CL,ES:[DI] ; move up signature
123 MOV DS:[DI],CL
124 JMP coalesce ; try again
125Coalesce ENDP
126
127SUBTTL $Alloc - allocate space in memory
128PAGE
129;
130; Assembler usage:
131; MOV BX,size
132; MOV AH,Alloc
133; INT 21h
134; AX:0 is pointer to allocated memory
135; BX is max size if not enough memory
136;
137; Description:
138; Alloc returns a pointer to a free block of
139; memory that has the requested size in paragraphs.
140;
141; Error return:
142; AX = error_not_enough_memory
143; = error_arena_trashed
144;
145 procedure $ALLOC,NEAR
146 ASSUME DS:NOTHING,ES:NOTHING
147
148 XOR AX,AX
149 MOV DI,AX
150
151 MOV [FirstArena],AX ; init the options
152 MOV [BestArena],AX
153 MOV [LastArena],AX
154
155 PUSH AX ; alloc_max <- 0
156 MOV AX,[arena_head] ; AX <- beginning of arena
157 CALL Check_signature ; ES <- AX, carry set if error
158 JC alloc_err ; IF error THEN GOTO err
159
160alloc_scan:
161 PUSH ES
162 POP DS ; DS <- ES
163 CMP DS:[arena_owner],DI
164 JZ alloc_free ; IF current block is free THEN examine
165
166alloc_next:
167 CMP BYTE PTR DS:[DI],arena_signature_end
168 ; IF current block is last THEN
169 JZ alloc_end ; GOTO end
170 CALL arena_next ; AX, ES <- next block, Carry set if error
171 JNC alloc_scan ; IF no error THEN GOTO scan
172
173alloc_err:
174 POP AX
175
176alloc_trashed:
177 error error_arena_trashed
178
179alloc_end:
180 CMP [FirstArena],0
181 JNZ alloc_do_split
182
183alloc_fail:
184 invoke get_user_stack
185 POP BX
186 MOV [SI].user_BX,BX
187 error error_not_enough_memory
188
189alloc_free:
190 CALL coalesce ; add following free block to current
191 JC alloc_err ; IF error THEN GOTO err
192 MOV CX,DS:[arena_size]
193
194 POP DX ; check for max found size
195 CMP CX,DX
196 JNA alloc_test
197 MOV DX,CX
198
199alloc_test:
200 PUSH DX
201 CMP BX,CX ; IF BX > size of current block THEN
202 JA alloc_next ; GOTO next
203
204 CMP [FirstArena],0
205 JNZ alloc_best
206 MOV [FirstArena],DS ; save first one found
207alloc_best:
208 CMP [BestArena],0
209 JZ alloc_make_best ; initial best
210 PUSH ES
211 MOV ES,[BestArena]
212 CMP ES:[arena_size],CX ; is size of best larger than found?
213 POP ES
214 JBE alloc_last
215alloc_make_best:
216 MOV [BestArena],DS ; assign best
217alloc_last:
218 MOV [LastArena],DS ; assign last
219 JMP alloc_next
220
221;
222; split the block high
223;
224alloc_do_split_high:
225 MOV DS,[LastArena]
226 MOV CX,DS:[arena_size]
227 SUB CX,BX
228 MOV DX,DS
229 JE alloc_set_owner ; sizes are equal, no split
230 ADD DX,CX ; point to next block
231 MOV ES,DX ; no decrement!
232 DEC CX
233 XCHG BX,CX ; bx has size of lower block
234 JMP alloc_set_sizes ; cx has upper (requested) size
235
236;
237; we have scanned memory and have found all appropriate blocks
238; check for the type of allocation desired; first and best are identical
239; last must be split high
240;
241alloc_do_split:
242 CMP BYTE PTR [AllocMethod], 1
243 JA alloc_do_split_high
244 MOV DS,[FirstArena]
245 JB alloc_get_size
246 MOV DS,[BestArena]
247alloc_get_size:
248 MOV CX,DS:[arena_size]
249 SUB CX,BX ; get room left over
250 MOV AX,DS
251 MOV DX,AX ; save for owner setting
252 JE alloc_set_owner ; IF BX = size THEN (don't split)
253 ADD AX,BX
254 INC AX ; remember the header
255 MOV ES,AX ; ES <- DS + BX (new header location)
256 DEC CX ; CX <- size of split block
257alloc_set_sizes:
258 MOV DS:[arena_size],BX ; current size <- BX
259 MOV ES:[arena_size],CX ; split size <- CX
260 MOV BL,arena_signature_normal
261 XCHG BL,DS:[DI] ; current signature <- 4D
262 MOV ES:[DI],BL ; new block sig <- old block sig
263 MOV ES:[arena_owner],DI
264
265alloc_set_owner:
266 MOV DS,DX
267 MOV AX,[CurrentPDB]
268 MOV DS:[arena_owner],AX
269 MOV AX,DS
270 INC AX
271 POP BX
272 transfer SYS_RET_OK
273
274$alloc ENDP
275
276SUBTTL $SETBLOCK - change size of an allocated block (if possible)
277PAGE
278;
279; Assembler usage:
280; MOV ES,block
281; MOV BX,newsize
282; MOV AH,setblock
283; INT 21h
284; if setblock fails for growing, BX will have the maximum
285; size possible
286; Error return:
287; AX = error_invalid_block
288; = error_arena_trashed
289; = error_not_enough_memory
290; = error_invalid_function
291;
292 procedure $SETBLOCK,NEAR
293 ASSUME DS:NOTHING,ES:NOTHING
294 MOV DI,arena_signature
295 MOV AX,ES
296 DEC AX
297 CALL check_signature
298 JNC setblock_grab
299
300setblock_bad:
301 JMP alloc_trashed
302
303setblock_grab:
304 MOV DS,AX
305 CALL coalesce
306 JC setblock_bad
307 MOV CX,DS:[arena_size]
308 PUSH CX
309 CMP BX,CX
310 JBE alloc_get_size
311 JMP alloc_fail
312$setblock ENDP
313
314SUBTTL $DEALLOC - free previously allocated piece of memory
315PAGE
316;
317; Assembler usage:
318; MOV ES,block
319; MOV AH,dealloc
320; INT 21h
321;
322; Error return:
323; AX = error_invalid_block
324; = error_arena_trashed
325;
326 procedure $DEALLOC,NEAR
327 ASSUME DS:NOTHING,ES:NOTHING
328 MOV DI,arena_signature
329 MOV AX,ES
330 DEC AX
331 CALL check_signature
332 JC dealloc_err
333 MOV ES:[arena_owner],DI
334 transfer SYS_RET_OK
335
336dealloc_err:
337 error error_invalid_block
338$DEALLOC ENDP
339
340SUBTTL $AllocOper - get/set allocation mechanism
341PAGE
342;
343; Assembler usage:
344; MOV AH,AllocOper
345; MOV BX,method
346; MOV AL,func
347; INT 21h
348;
349; Error return:
350; AX = error_invalid_function
351;
352 procedure $AllocOper,NEAR
353 ASSUME DS:NOTHING,ES:NOTHING
354 CMP AL,1
355 JB AllocOperGet
356 JZ AllocOperSet
357 error error_invalid_function
358AllocOperGet:
359 MOV AL,BYTE PTR [AllocMethod]
360 XOR AH,AH
361 transfer SYS_RET_OK
362AllocOperSet:
363 MOV [AllocMethod],BL
364 transfer SYS_RET_OK
365$AllocOper ENDP
366
367do_ext
368
369CODE ENDS
370 END
371
diff --git a/v2.0/source/ANSI.txt b/v2.0/source/ANSI.txt
new file mode 100644
index 0000000..040d9d2
--- /dev/null
+++ b/v2.0/source/ANSI.txt
Binary files differ
diff --git a/v2.0/source/BUF.ASM b/v2.0/source/BUF.ASM
new file mode 100644
index 0000000..f1ad800
--- /dev/null
+++ b/v2.0/source/BUF.ASM
@@ -0,0 +1,508 @@
1;
2; buffer management for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17 i_need BuffHead,DWORD
18 i_need PreRead,WORD
19 i_need LastBuffer,DWORD
20 i_need CurBuf,DWORD
21 i_need WPErr,BYTE
22
23SUBTTL SETVISIT,SKIPVISIT -- MANAGE BUFFER SCANS
24PAGE
25 procedure SETVISIT,near
26ASSUME DS:NOTHING,ES:NOTHING
27
28; Inputs:
29; None
30; Function:
31; Set up a scan of I/O buffers
32; Outputs:
33; All visit flags = 0
34; NOTE: This pre-scan is needed because a hard disk error
35; may cause a scan to stop in the middle leaving some
36; visit flags set, and some not set.
37; DS:DI Points to [BUFFHEAD]
38; No other registers altered
39
40 LDS DI,[BUFFHEAD]
41 PUSH AX
42 XOR AX,AX
43SETLOOP:
44 MOV [DI.VISIT],AL
45 LDS DI,[DI.NEXTBUF]
46 CMP DI,-1
47 JNZ SETLOOP
48 LDS DI,[BUFFHEAD]
49 POP AX
50 return
51
52 entry SKIPVISIT
53ASSUME DS:NOTHING,ES:NOTHING
54
55; Inputs:
56; DS:DI Points to a buffer
57; Function:
58; Skip visited buffers
59; Outputs:
60; DS:DI Points to next unvisited buffer
61; Zero is set if skip to LAST buffer
62; No other registers altered
63
64 CMP DI,-1
65 retz
66 CMP [DI.VISIT],1
67 retnz
68 LDS DI,[DI.NEXTBUF]
69 JMP SHORT SKIPVISIT
70 return
71SetVisit ENDP
72
73
74SUBTTL SCANPLACE, PLACEBUF -- PUT A BUFFER BACK IN THE POOL
75PAGE
76 procedure ScanPlace,near
77ASSUME DS:NOTHING,ES:NOTHING
78
79; Inputs:
80; Same as PLACEBUF
81; Function:
82; Save scan location and call PLACEBUF
83; Outputs:
84; DS:DI Points to saved scan location
85; SI destroyed, other registers unchanged
86
87 PUSH ES
88 LES SI,[DI.NEXTBUF] ; Save scan location
89 CALL PLACEBUF
90 PUSH ES
91 POP DS ; Restore scan location
92 MOV DI,SI
93 POP ES
94 return
95ScanPlace ENDP
96
97NRETJ: JMP SHORT NRET
98
99 procedure PLACEBUF,NEAR
100ASSUME DS:NOTHING,ES:NOTHING
101
102; Input:
103; DS:DI points to buffer
104; Function:
105; Remove buffer from queue and re-insert it in proper place.
106; If buffer doesn't go at end, and isn't free, decrement
107; priorities.
108; NO registers altered
109;
110; DS:SI -- Curbuf, current buffer in list
111; ES:DI -- Buf, buffer passed as argument
112; BP:CX -- Pointsave, saved Buf.nextbuf
113; DX:BX -- Lastbuf, previous buffer in list
114; AL -- Inserted, Buf has been inserted
115; AH -- Removed, Buf has been removed
116
117 IF IBM
118 IF NOT IBM
119 invoke save_world
120 XOR AX,AX ; Inserted = Removed = FALSE
121 LES CX,[DI.NEXTBUF]
122 MOV BP,ES ; Pointsave = Buf.nextbuf
123 MOV SI,DS
124 MOV ES,SI ; Buf is ES:DI
125 LDS SI,[BUFFHEAD] ; Curbuf = HEAD
126 CALL POINTCOMP ; Buf == HEAD?
127 JNZ TNEWHEAD
128 CMP CX,-1 ; Buf is LAST?
129 JZ NRETJ ; Only one buffer, nothing to do
130 MOV WORD PTR [BUFFHEAD],CX
131 MOV WORD PTR [BUFFHEAD+2],BP ; HEAD = Pointsave
132 INC AH ; Removed = TRUE
133 MOV DS,BP
134 MOV SI,CX ; Curbuf = HEAD
135TNEWHEAD:
136 MOV BL,ES:[DI.BUFPRI]
137 CMP BL,[SI.BUFPRI]
138 JGE BUFLOOP
139NEWHEAD: ; If Buf.pri < HEAD.pri
140 MOV WORD PTR ES:[DI.NEXTBUF],SI
141 MOV WORD PTR ES:[DI.NEXTBUF+2],DS ; Buf.nextbuf = HEAD
142 MOV WORD PTR [BUFFHEAD],DI
143 MOV WORD PTR [BUFFHEAD+2],ES ; HEAD = Buf
144 INC AL ; Inserted = TRUE
145 OR AH,AH
146 JNZ NRET ; If Removed == TRUE
147BUFLOOP:
148 PUSH DS
149 PUSH SI
150 LDS SI,[SI.NEXTBUF]
151 CALL POINTCOMP
152 POP SI
153 POP DS
154 JNZ TESTINS
155 MOV WORD PTR [SI.NEXTBUF],CX ; If Curbuf.nextbuf == buf
156 MOV WORD PTR [SI.NEXTBUF+2],BP ; Curbuf.nextbuf = Pointsave
157 INC AH ; Removed = TRUE
158 OR AL,AL
159 JNZ SHUFFLE ; If Inserted == TRUE
160TESTINS:
161 OR AL,AL
162 JNZ LOOKBUF
163 PUSH CX ; If NOT Inserted
164 MOV CL,ES:[DI.BUFPRI]
165 CMP CL,[SI.BUFPRI]
166 POP CX
167 JGE LOOKBUF
168 PUSH DS ; If Buf.pri < Curbuf.pri
169 MOV DS,DX
170 MOV WORD PTR [BX.NEXTBUF],DI
171 MOV WORD PTR [BX.NEXTBUF+2],ES ; Lastbuf.nextbuf = Buf
172 POP DS
173 MOV WORD PTR ES:[DI.NEXTBUF],SI
174 MOV WORD PTR ES:[DI.NEXTBUF+2],DS ; Buf.nextbuf = Curbuf
175 INC AL ; Inserted = TRUE
176 OR AH,AH
177 JNZ SHUFFLE ; If Removed == TRUE
178LOOKBUF:
179 MOV BX,SI
180 MOV DX,DS ; Lastbuf = Curbuf
181 CMP WORD PTR [SI.NEXTBUF],-1
182 JZ ISLAST
183 LDS SI,[SI.NEXTBUF] ; Curbuf = Curbuf.nextbuf
184 JMP SHORT BUFLOOP
185ISLAST: ; If Curbuf is LAST
186 MOV WORD PTR [SI.NEXTBUF],DI
187 MOV WORD PTR [SI.NEXTBUF+2],ES ; Curbuf.nextbuf = Buf
188 MOV WORD PTR ES:[DI.NEXTBUF],-1
189 MOV WORD PTR ES:[DI.NEXTBUF+2],-1 ; Buf is LAST
190NRET:
191 invoke restore_world
192 return
193
194SHUFFLE:
195 LDS DI,[BUFFHEAD]
196DECLOOP:
197 CMP [DI.BUFPRI],FREEPRI
198 JZ NODEC
199 DEC [DI.BUFPRI]
200NODEC:
201 LDS DI,[DI.NEXTBUF]
202 CMP DI,-1
203 JNZ DECLOOP
204 JMP SHORT NRET
205 ENDIF
206 ENDIF
207
208 invoke save_world
209 LES CX,[DI.NEXTBUF]
210 CMP CX,-1 ; Buf is LAST?
211 JZ NRET ; Buffer already last
212 MOV BP,ES ; Pointsave = Buf.nextbuf
213 PUSH DS
214 POP ES ; Buf is ES:DI
215 LDS SI,[BUFFHEAD] ; Curbuf = HEAD
216 CALL POINTCOMP ; Buf == HEAD?
217 JNZ BUFLOOP
218 MOV WORD PTR [BUFFHEAD],CX
219 MOV WORD PTR [BUFFHEAD+2],BP ; HEAD = Pointsave
220 JMP SHORT LOOKEND
221
222BUFLOOP:
223 PUSH DS
224 PUSH SI
225 LDS SI,[SI.NEXTBUF]
226 CALL POINTCOMP
227 JZ GOTTHEBUF
228 POP AX
229 POP AX
230 JMP SHORT BUFLOOP
231
232GOTTHEBUF:
233 POP SI
234 POP DS
235 MOV WORD PTR [SI.NEXTBUF],CX ; If Curbuf.nextbuf == buf
236 MOV WORD PTR [SI.NEXTBUF+2],BP ; Curbuf.nextbuf = Pointsave
237LOOKEND:
238 PUSH DS
239 PUSH SI
240 LDS SI,[SI.NEXTBUF]
241 CMP SI,-1
242 JZ GOTHEEND
243 POP AX
244 POP AX
245 JMP SHORT LOOKEND
246
247GOTHEEND:
248 POP SI
249 POP DS
250 MOV WORD PTR [SI.NEXTBUF],DI
251 MOV WORD PTR [SI.NEXTBUF+2],ES ; Curbuf.nextbuf = Buf
252 MOV WORD PTR ES:[DI.NEXTBUF],-1
253 MOV WORD PTR ES:[DI.NEXTBUF+2],-1 ; Buf is LAST
254NRET:
255 invoke restore_world
256 return
257
258PLACEBUF ENDP
259
260 procedure PLACEHEAD,NEAR
261ASSUME DS:NOTHING,ES:NOTHING
262
263; SAME AS PLACEBUF except places buffer at head
264
265 invoke save_world
266 PUSH DS
267 POP ES
268 LDS SI,[BUFFHEAD]
269 MOV WORD PTR [BUFFHEAD],DI
270 MOV WORD PTR [BUFFHEAD+2],ES
271 MOV WORD PTR ES:[DI.NEXTBUF],SI
272 MOV WORD PTR ES:[DI.NEXTBUF+2],DS
273LOOKEND2:
274 PUSH DS
275 PUSH SI
276 LDS SI,[SI.NEXTBUF]
277 CALL POINTCOMP
278 JZ GOTHEEND2
279 POP AX
280 POP AX
281 JMP SHORT LOOKEND2
282
283GOTHEEND2:
284 POP SI
285 POP DS
286 MOV WORD PTR [SI.NEXTBUF],-1
287 MOV WORD PTR [SI.NEXTBUF+2],-1 ; Buf is LAST
288 JMP SHORT NRET
289
290PLACEHEAD ENDP
291
292SUBTTL POINTCOMP -- 20 BIT POINTER COMPARE
293PAGE
294 procedure PointComp,NEAR
295ASSUME DS:NOTHING,ES:NOTHING
296
297; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality
298; DO NOT USE FOR < or >
299; No Registers altered
300
301 CMP SI,DI
302 retnz
303 PUSH CX
304 PUSH DX
305 MOV CX,DS
306 MOV DX,ES
307 CMP CX,DX
308 POP DX
309 POP CX
310 return
311PointComp ENDP
312
313SUBTTL GETBUFFR -- GET A SECTOR INTO A BUFFER
314PAGE
315 procedure GETBUFFR,NEAR
316ASSUME DS:DOSGROUP,ES:NOTHING
317
318; Input:
319; AH = Priority buffer is to have
320; AL = 0 means sector must be pre-read
321; ELSE no pre-read
322; DX = Desired physical sector number
323; ES:BP = Pointer to drive parameters
324; Function:
325; Get the specified sector into one of the I/O buffers
326; And shuffle the queue
327; Output:
328; [CURBUF] Points to the Buffer for the sector
329; DX,ES:BP unchanged, all other registers destroyed
330
331 XOR SI,SI
332 entry GETBUFFRB
333 MOV [PREREAD],AX
334 MOV AL,ES:[BP.dpb_drive]
335 LDS DI,[LASTBUFFER]
336ASSUME DS:NOTHING
337 CMP DI,-1 ; Recency pointer valid?
338 JZ SKBUF ; No
339 CMP DX,[DI.BUFSECNO]
340 JNZ SKBUF ; Wrong sector
341 CMP AL,[DI.BUFDRV]
342 JNZ SKBUF ; Wrong Drive
343 JMP SHORT JUSTBUF ; Just asked for same buffer
344SKBUF:
345 LDS DI,[BUFFHEAD]
346NXTBFF:
347 CMP DX,[DI.BUFSECNO]
348 JNZ BUMP
349 CMP AL,[DI.BUFDRV]
350 JNZ BUMP
351 JMP SHORT SETINF
352BUMP:
353 LDS DI,[DI.NEXTBUF]
354 CMP DI,-1
355 JNZ NXTBFF
356 LDS DI,[BUFFHEAD]
357 PUSH SI
358 PUSH DX
359 PUSH BP
360 PUSH ES
361 CALL BUFWRITE ; Write out the dirty buffer
362 POP ES
363 POP BP
364 POP DX
365 POP SI
366RDSEC: ; Read in the new sector
367 TEST BYTE PTR [PREREAD],-1
368 JNZ SETBUF
369 LEA BX,[DI.BufInSiz] ; Point at buffer
370 MOV CX,1
371 PUSH SI
372 PUSH DI
373 PUSH DX
374 OR SI,SI
375 JZ NORMSEC
376 invoke FATSECRD
377 JMP SHORT GOTTHESEC ; Buffer is marked free if read barfs
378NORMSEC:
379 invoke DREAD ; Buffer is marked free if read barfs
380GOTTHESEC:
381 POP DX
382 POP DI
383 POP SI
384SETBUF:
385 MOV [DI.BUFSECNO],DX
386 MOV WORD PTR [DI.BUFDRVDP],BP
387 MOV WORD PTR [DI.BUFDRVDP+2],ES
388 XOR AH,AH
389 MOV AL,ES:[BP.dpb_drive]
390 MOV WORD PTR [DI.BUFDRV],AX
391SETINF:
392 MOV AX,1 ; Default to not a FAT sector
393 OR SI,SI
394 JZ SETSTUFFOK
395 MOV AL,ES:[BP.dpb_FAT_count]
396 MOV AH,ES:[BP.dpb_FAT_size]
397SETSTUFFOK:
398 MOV WORD PTR [DI.BUFWRTCNT],AX
399 CALL PLACEBUF
400JUSTBUF:
401 MOV WORD PTR [CURBUF+2],DS
402 MOV WORD PTR [LASTBUFFER+2],DS
403 PUSH SS
404 POP DS
405ASSUME DS:DOSGROUP
406 MOV WORD PTR [CURBUF],DI
407 MOV WORD PTR [LASTBUFFER],DI
408 return
409GETBUFFR ENDP
410
411
412SUBTTL FLUSHBUF -- WRITE OUT DIRTY BUFFERS
413PAGE
414 procedure FlushBuf,NEAR
415ASSUME DS:DOSGROUP,ES:NOTHING
416
417; Input:
418; DS = DOSGROUP
419; AL = Physical unit number
420; = -1 for all units
421; Function:
422; Write out all dirty buffers for unit, and flag them as clean
423; DS Preserved, all others destroyed (ES too)
424
425 LDS DI,[BUFFHEAD]
426ASSUME DS:NOTHING
427 MOV AH,-1
428NXTBUFF:
429 CMP [DI.BUFDRV],AH
430 JZ SKIPBFF ; Skip free buffers
431 CMP AH,AL
432 JZ DOBUFFER ; Do all dirty buffers
433 CMP AL,[DI.BUFDRV]
434 JNZ SKIPBFF ; Buffer not for this unit
435DOBUFFER:
436 CMP BYTE PTR [DI.BUFDIRTY],0
437 JZ SKIPBFF ; Buffer not dirty
438 PUSH AX
439 PUSH WORD PTR [DI.BUFDRV]
440 CALL BUFWRITE
441 POP AX
442 XOR AH,AH ; Buffer is clean
443 CMP AL,BYTE PTR [WPERR]
444 JNZ NOZAP
445 MOV AL,0FFH ; Invalidate buffer, it is inconsistent
446NOZAP:
447 MOV WORD PTR [DI.BUFDRV],AX
448 POP AX ; Search info
449SKIPBFF:
450 LDS DI,[DI.NEXTBUF]
451 CMP DI,-1
452 JNZ NXTBUFF
453 PUSH SS
454 POP DS
455 return
456FlushBuf ENDP
457
458
459SUBTTL BUFWRITE -- WRITE OUT A BUFFER IF DIRTY
460PAGE
461 procedure BufWrite,NEAR
462ASSUME DS:NOTHING,ES:NOTHING
463
464; Input:
465; DS:DI Points to the buffer
466; Function:
467; Write out all the buffer if dirty.
468; Output:
469; Buffer marked free
470; DS:DI Preserved, ALL others destroyed (ES too)
471
472 MOV AX,00FFH
473 XCHG AX,WORD PTR [DI.BUFDRV] ; Free, in case write barfs
474 CMP AL,0FFH
475 retz ; Buffer is free.
476 OR AH,AH
477 retz ; Buffer is clean.
478 CMP AL,BYTE PTR [WPERR]
479 retz ; If in WP error zap buffer
480 LES BP,[DI.BUFDRVDP]
481 LEA BX,[DI.BufInSiz] ; Point at buffer
482 MOV DX,[DI.BUFSECNO]
483 MOV CX,WORD PTR [DI.BUFWRTCNT]
484 MOV AL,CH ; [DI.BUFWRTINC]
485 XOR CH,CH
486 MOV AH,CH
487 PUSH DI
488WRTAGAIN:
489 PUSH CX
490 PUSH AX
491 MOV CX,1
492 PUSH BX
493 PUSH DX
494 invoke DWRITE ; Write out the dirty buffer
495 POP DX
496 POP BX
497 POP AX
498 POP CX
499 ADD DX,AX
500 LOOP WRTAGAIN
501 POP DI
502 return
503BufWrite ENDP
504
505do_ext
506
507CODE ENDS
508 END
diff --git a/v2.0/source/CHKDSK.ASM b/v2.0/source/CHKDSK.ASM
new file mode 100644
index 0000000..c305a1d
--- /dev/null
+++ b/v2.0/source/CHKDSK.ASM
@@ -0,0 +1,901 @@
1TITLE CHKDSK - MS-DOS Disk consistancy checker
2
3; CHKDSK Version 2.30
4; Verifies and repairs MS-DOS disk directory.
5
6
7; To build CHKDSK you need three modules:
8; CHKDSK CHKPROC CHKMES
9; They should be linked the that order as well.
10
11
12; REVISION HISTORY
13
14;REV 1.1
15; 05/21/82 Added rev number
16
17;REV 1.5
18; Mod by NANCYP to report on extents
19; Mod by AARONR to report volume ID
20
21;REV 2.0
22; Total rewrite for directories
23
24;REV 2.1
25; Added ^C and INT 24H handlers
26
27;REV 2.2
28; INTERNATIONAL support
29
30;REV 2.3
31; Split into two modules to allow assembly on a PC
32; CHKDSK and CHKPROC
33
34FALSE EQU 0
35TRUE EQU NOT FALSE
36
37DRVCHAR EQU ":"
38
39;The following defines the ranges of DOS version numbers for which this CHKDSK
40; is good
41
42DOSVER_LOW EQU 0136H ;1.54 in hex
43DOSVER_HIGH EQU 020BH ;2.11 in hex
44
45
46 INCLUDE DOSSYM.ASM
47
48FCB EQU 5CH
49
50;Drive parameter block from DOS header
51
52SUBTTL Segments used in load order
53
54CODE SEGMENT PUBLIC
55CODE ENDS
56
57CONST SEGMENT PUBLIC BYTE
58CONST ENDS
59
60DATA SEGMENT PUBLIC WORD
61DATA ENDS
62
63DG GROUP CODE,CONST,DATA
64
65SUBTTL Initialized Data
66PAGE
67CONST SEGMENT PUBLIC BYTE
68
69 PUBLIC HECODE,SWITCHAR,NOISY,DOFIX,CONBUF,ORPHCNT,ORPHSIZ,DOFIX
70 PUBLIC HIDCNT,HIDSIZ,DIRCNT,DIRSIZ,FILCNT,FILSIZ,BADSIZ,LCLUS
71 PUBLIC DOTENT,HAVFIX,SECONDPASS,NUL,ALLFILE,PARSTR,ERRSUB,LCLUS
72 PUBLIC DIRTYFAT,BADSIZ,DDOTENT,CROSSCNT,ORPHFCB,ORPHEXT,ALLDRV
73 PUBLIC FRAGMENT,USERDIR,DIRBUF,USERDIR,FIXMFLG,DOTMES,DIRCHAR
74
75 EXTRN IDMES1:BYTE,IDPOST:BYTE,VNAME:BYTE,MONTAB:BYTE
76 EXTRN TCHAR:BYTE,BADREAD_PRE:BYTE,BADREAD_POST:BYTE
77 EXTRN CRLF:BYTE,BADVER:BYTE,BADSUBDIR:BYTE,CENTRY:BYTE
78 EXTRN BADDRV:BYTE,BADCD:BYTE,BADRDMES:BYTE,OPNERR:BYTE
79 EXTRN CONTAINS:BYTE,EXTENTS:BYTE,NOEXTENTS:BYTE
80 EXTRN BADDRVM:BYTE,BADDRVM2:BYTE,BADIDBYT:BYTE
81
82
83DIRBUF LABEL BYTE ;Entry buffer for searches
84VOLID DB -1,0,0,0,0,0,8 ;Volume ID FCB
85VOLNAM DB 0,"???????????"
86 DB 25 DUP(0)
87
88ALLFILE DB -1,0,0,0,0,0,1EH ;Extended FCB
89ALLDRV DB 0,"???????????"
90 DB 25 DUP (?)
91
92ORPHFCB DB 0,"FILE0000"
93ORPHEXT DB "CHK"
94 DB 25 DUP (?)
95
96
97;Non-message data
98
99SWITCHAR DB "-"
100ROOTSTR LABEL BYTE
101DIRCHAR DB "/"
102NUL DB 0
103PARSTR DB "..",0
104DOTMES DB ".",0
105DOTENT DB ". "
106DDOTENT DB ".. "
107HECODE DB ?
108FIXMFLG DB 0 ;Flag for printing fixmes
109ERRSUB DW 0 ;Flag for bad subdir error
110FRAGMENT DB 0 ;Flag for extent processing
111DIRTYFAT DB 0 ;Dirty flag for FAT
112DIRCNT DW 0 ;# directories
113DIRSIZ DW 0 ;# alloc units in directories
114FILCNT DW 0 ;# reg files
115FILSIZ DW 0 ;# alloc units in reg files
116HIDCNT DW 0 ;# hidden files
117HIDSIZ DW 0 ;# alloc units in hidden files
118BADSIZ DW 0 ;# alloc units in bad sectors
119ORPHCNT DW 0 ;# orphan files made
120ORPHSIZ DW 0 ;# alloc units in orphan files
121LCLUS DW 0 ;# alloc units in lost clusters
122DISPFLG DB 0 ;used by number routines
123CROSSCNT DW 0 ;# crosslinked files (first pass)
124SECONDPASS DB 0 ;Pass flag
125HAVFIX DB 0 ;non zero if any fixes
126DOFIX DB 0 ;flag for F switch
127NOISY DB 0 ;flag for V switch
128USERDIR DB "/",0 ;Users current dir for drive
129 DB (DIRSTRLEN-1) DUP (?)
130CONBUF DB 15,0 ;Input buffer
131 DB 15 DUP (?)
132
133CONST ENDS
134
135SUBTTL Un-initialized Data
136PAGE
137DATA SEGMENT PUBLIC WORD
138
139 PUBLIC ZEROTRUNC,NAMBUF,MCLUS,THISDPB,STACKLIM,ERRCNT
140 PUBLIC SRFCBPT,ISCROSS,CSIZE,DSIZE,SSIZE,FAT,FATMAP
141 PUBLIC HARDCH,CONTCH,USERDEV,SECBUF,DOTSNOGOOD
142
143HARDCH DD ? ;Pointer to real INT 24 handler
144CONTCH DD ? ;Pointer to real INT 23 handler
145THISDPB DD ? ;Pointer to drive DPB
146USERDEV DB ? ;Users current device
147CSIZE DB ? ;Sectors per cluster
148SSIZE DW ? ;bytes per sector
149DSIZE DW ? ;# alloc units on disk
150MCLUS DW ? ;DSIZE + 1
151NAMBUF DB 14 DUP (?) ;Buffer
152DOTSNOGOOD DB ? ;. or .. error flag
153ZEROTRUNC DB ? ;Trimming flag
154ISCROSS DB ? ;Crosslink flag
155OLDCLUS DW ?
156SRFCBPT DW ?
157FATMAP DW OFFSET DG:FAT ;Offset of FATMAP table
158SECBUF DW ? ;Offset of sector buffer
159ERRCNT DB ? ;Used by FATread and write
160STACKLIM DW ? ;Stack growth limit
161
162INTERNATVARS internat_block <>
163 DB (internat_block_max - ($ - INTERNATVARS)) DUP (?)
164
165FAT LABEL WORD
166DATA ENDS
167
168
169SUBTTL Start of CHKDSK
170
171CODE SEGMENT PUBLIC
172ASSUME CS:DG,DS:DG,ES:DG,SS:DG
173
174 PUBLIC SUBERRP,DOTCOMBMES,FIGREC,FCB_TO_ASCZ,PRTCHR,EPRINT
175 PUBLIC PRINT,DOCRLF,DISP16BITS,DISP32BITS,DISPCLUS,CHECKFILES
176
177 EXTRN RDSKERR:NEAR,SETSWITCH:NEAR,PROMPTYN:NEAR,REPORT:NEAR
178 EXTRN PRINTCURRDIRERR:NEAR,PRINTTHISEL2:NEAR,CHECKERR:NEAR
179 EXTRN INT_23:NEAR,INT_24:NEAR,FINDCHAIN:NEAR,DONE:NEAR,AMDONE:NEAR
180 EXTRN FATAL:NEAR,DIRPROC:NEAR,CHKMAP:NEAR,CHKCROSS:NEAR,UNPACK:NEAR
181
182 ORG 100H
183
184CHKDSK:
185 JMP SHORT CHSTRT
186
187HEADER DB "Ver 2.30"
188
189CHSTRT:
190
191;Code to print header.
192; PUSH AX
193; MOV DX,OFFSET DG:HEADER
194; CALL PRINT
195; POP AX
196
197 PUSH AX ;Save DRIVE validity info
198 MOV AH,GET_VERSION
199 INT 21H
200 XCHG AH,AL ;Turn it around to AH.AL
201 CMP AX,DOSVER_LOW
202 JB GOTBADDOS
203 CMP AX,DOSVER_HIGH
204 JBE OKDOS
205GOTBADDOS:
206 MOV DX,OFFSET DG:BADVER
207 JMP CERROR
208
209OKDOS:
210 POP AX ;Get back drive info
211 MOV BX,0FFF0H
212 MOV DX,SP
213 CMP DX,BX
214 JAE STACKOK ;Lots of stack
215 MOV DX,DS:[2] ;High break
216 MOV CX,CS
217 SUB DX,CX
218 CMP DX,0FFFH
219 JAE SETSTACK ;Lots to grab
220 MOV CX,4 ;Suck up more stack (blast command)
221 SHL DX,CL
222 MOV BX,DX
223SETSTACK:
224 CLI
225 MOV SP,BX
226 STI
227STACKOK:
228 PUSH AX
229 MOV AH,DISK_RESET ;Flush everything, and invalidate
230 INT 21H
231 POP AX
232 CMP AL,0FFH ;Illegal drive specifier?
233 JNZ FILECHK ;No -- check for filename
234
235DRVERR:
236 MOV DX,OFFSET DG:BADDRV
237CERROR:
238 PUSH CS ;Make sure DS is OK
239 POP DS
240 CALL PRINT ;Print error message
241 INT 20H
242
243CERROR2:
244 PUSH DX
245 CALL DONE ;Reset users disk
246 POP DX
247 JMP SHORT CERROR
248
249FILECHK:
250 MOV AX,(CHAR_OPER SHL 8)
251 INT 21H
252 MOV [SWITCHAR],DL
253 CMP DL,"/"
254 JNZ SLASHOK
255 MOV [DIRCHAR],"\"
256 MOV [USERDIR],"\"
257SLASHOK:
258 CMP DS:(BYTE PTR FCB+1)," " ;Filename specified?
259 JZ DRVCHK ;No -- get the correct drive
260 MOV AL,[SWITCHAR]
261 CMP DS:(BYTE PTR FCB+1),AL ;Filename specified?
262 JZ DRVCHK ;No -- get the correct drive
263 MOV BYTE PTR [FRAGMENT],1 ;Set flag to perform fragment
264 ;check on specified files
265DRVCHK:
266 CALL SETSWITCH ;Look for switches
267 MOV AH,GET_DEFAULT_DRIVE ;Get current drive
268 INT 21H
269 MOV [USERDEV],AL ;Save for later
270 MOV AH,AL
271 INC AH ;A = 1
272 MOV BH,DS:(BYTE PTR FCB) ;See if drive specified
273 OR BH,BH
274 JZ SETDSK
275 MOV AL,BH
276 MOV AH,AL
277 DEC AL ;A = 0
278SETDSK:
279 MOV [ALLDRV],AH ;Target drive
280 MOV [VOLNAM],AH ;A = 1
281 MOV [ORPHFCB],AH ;A = 1
282 ADD [BADDRVM],AL ;A = 0
283 ADD [BADDRVM2],AL ;A = 0
284 MOV DL,AH ;A = 1
285 MOV AH,GET_DPB ;Get the DPB
286 INT 21H
287ASSUME DS:NOTHING
288 CMP AL,-1
289 JNZ DRVISOK ;Bad drive (should always be ok)
290 MOV DX,OFFSET DG:BADDRV
291CERROR2J: JMP CERROR2
292
293DRVISOK:
294 DEC DL ;A = 0
295 MOV AH,SET_DEFAULT_DRIVE ;Set Target
296 INT 21H
297 CMP [BX.dpb_current_dir],0
298 JZ CURRISROOT ;Save users current dir for target
299 MOV SI,BX
300 ADD SI,dpb_dir_text
301 MOV DI,OFFSET DG:USERDIR + 1
302SETDIRLP:
303 LODSB
304 STOSB
305 OR AL,AL
306 JZ CURRISROOT
307 JMP SHORT SETDIRLP
308CURRISROOT:
309 MOV WORD PTR [THISDPB+2],DS
310 PUSH CS
311 POP DS
312ASSUME DS:DG
313 MOV WORD PTR [THISDPB],BX
314 MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 23H
315 INT 21H
316 MOV WORD PTR [CONTCH],BX
317 MOV WORD PTR [CONTCH+2],ES
318 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
319 MOV DX,OFFSET DG:INT_23
320 INT 21H
321 MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 24H
322 INT 21H
323 MOV WORD PTR [HARDCH],BX
324 MOV WORD PTR [HARDCH+2],ES
325 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H
326 MOV DX,OFFSET DG:INT_24
327 INT 21H
328 PUSH CS
329 POP ES
330 MOV DX,OFFSET DG:ROOTSTR
331 MOV AH,CHDIR ;Start at root
332 INT 21H
333 MOV DX,OFFSET DG:BADCD
334 JC CERROR2J ;Couldn't get there
335 MOV DX,OFFSET DG:FAT ;Scratch space
336 MOV AH,SET_DMA
337 INT 21H
338 MOV DX,OFFSET DG:VOLID ;Look for VOL ID
339 MOV AH,DIR_SEARCH_FIRST
340 INT 21H
341 CMP AL,-1
342 JZ NOTVOLID
343 CALL PRINTID ;Have a VOL ID
344NOTVOLID:
345 LDS BX,[THISDPB]
346ASSUME DS:NOTHING
347 MOV AX,[BX.dpb_sector_size]
348 MOV [SSIZE],AX ;Sector size in bytes
349 MOV AL,[BX.dpb_cluster_mask]
350 INC AL
351 MOV [CSIZE],AL ;Sectros per cluster
352 MOV AX,[BX.dpb_max_cluster]
353 MOV [MCLUS],AX ;Bound for FAT searching
354 DEC AX
355 MOV [DSIZE],AX ;Total data clusters on disk
356 MOV AL,[BX.dpb_FAT_size] ;Sectors for one fat
357 XOR AH,AH
358 MOV CX,AX
359 MUL [SSIZE] ;Bytes for FAT
360 ADD [FATMAP],AX ;Allocate FAT space
361 MOV AX,[FATMAP]
362 ADD AX,[MCLUS]
363 ADD AX,2 ;Insurance
364 MOV [SECBUF],AX ;Allocate FATMAP space
365 ADD AX,[SSIZE]
366 ADD AX,20 ;Insurance
367 MOV [STACKLIM],AX ;Limit on recursion
368 MOV DI,CX
369 MOV CL,[BX.dpb_FAT_count] ;Number of FATs
370 MOV DX,[BX.dpb_first_FAT] ;First sector of FAT
371 PUSH CS
372 POP DS
373ASSUME DS:DG
374 MOV BX,OFFSET DG:FAT
375 MOV AL,[ALLDRV]
376 DEC AL
377 MOV AH,'1'
378RDLOOP:
379 XCHG CX,DI
380 PUSH DX
381 PUSH CX
382 PUSH DI
383 PUSH AX
384 INT 25H ;Read in the FAT
385 MOV [HECODE],AL
386 POP AX ;Flags
387 JNC RDOK
388 MOV DX,OFFSET DG:BADREAD_PRE ;Barfed
389 CALL PRINT
390 POP AX
391 PUSH AX
392 MOV DL,AH
393 CALL PRTCHR
394 MOV DX,OFFSET DG:BADREAD_POST
395 CALL PRINT
396 POP AX
397 POP CX
398 POP DI
399 POP DX
400 INC AH
401 ADD DX,DI
402 LOOP RDLOOP ;Try next FAT
403 CALL RDSKERR
404 JNZ NORETRY1
405 JMP NOTVOLID
406NORETRY1:
407 MOV BX,OFFSET DG:BADRDMES
408 JMP FATAL ;Couldn't read any FAT, BARF
409
410RDOK:
411 POP AX ;Clean up
412 POP AX
413 POP AX
414 POP AX
415 MOV SI,OFFSET DG:FAT
416 LODSB ;Check FAT ID byte
417 CMP AL,0F8H
418 JAE IDOK
419 MOV DX,OFFSET DG:BADIDBYT ;FAT ID bad
420 CALL PROMPTYN ;Ask user
421 JZ IDOK
422 JMP ALLDONE ;User said stop
423IDOK:
424 MOV DI,[FATMAP]
425 MOV CX,[MCLUS]
426 INC CX
427 XOR AL,AL
428 REP STOSB ;Initialize FATMAP to all free
429 MOV DX,OFFSET DG:DIRBUF ;FOR ALL SEARCHING
430 MOV AH,SET_DMA
431 INT 21H
432 XOR AX,AX
433 PUSH AX ;I am root
434 PUSH AX ;Parent is root
435 CALL DIRPROC
436 CALL CHKMAP ;Look for badsectors, orphans
437 CALL CHKCROSS ;Check for second pass
438 CALL DOCRLF
439 CALL REPORT
440
441ALLDONE:
442 CALL AMDONE
443 INT 20H ;Fini
444
445
446ASSUME DS:DG
447
448SUBTTL Check for extents in specified files
449PAGE
450CHECKFILES:
451;Search the directory for the files specified on the command line
452;and report the number of fragmented allocation units found in
453;each one.
454 CALL DOCRLF
455 MOV AH,SET_DMA
456 MOV DX,[FATMAP] ;Use the first free space available
457 MOV BP,DX
458 ADD BP,27 ;cluster in the directory entry
459 INT 21H
460 MOV AH,DIR_SEARCH_FIRST ;Look for the first file
461FRAGCHK:
462 MOV DX,FCB
463 INT 21H
464 OR AL,AL ;Did we find it?
465 JNZ MSGCHK ;No -- we're done
466 XOR AX,AX ;Initialize the fragment counter
467 MOV SI,[BP] ;Get the first cluster
468 CALL UNPACK
469 CMP DI,0FF8H ;End-of-file?
470 JAE NXTCHK ;Yes -- go report the results
471 INC SI
472 CMP SI,DI
473 JZ EACHCLUS
474 INC AX
475EACHCLUS:
476 MOV [OLDCLUS],DI ;Save the last cluster found
477 MOV SI,DI ;Get the next cluster
478 CALL UNPACK
479 INC [OLDCLUS] ;Bump the old cluster
480 CMP DI,[OLDCLUS] ;Are they the same?
481 JNZ LASTCLUS ;No -- check for end-of-file
482 JMP SHORT EACHCLUS ;Continue processing
483LASTCLUS:
484 CMP DI,0FF8H ;End-of-file?
485 JAE NXTCHK ;Yes -- go report the results
486 INC AX ;No -- found a fragement
487 JMP SHORT EACHCLUS ;Continue processing
488
489NXTCHK:
490 OR AX,AX
491 JZ GETNXT
492 MOV [FRAGMENT],2 ;Signal that we output at least one file
493 PUSH AX ;Save count of fragments
494 MOV SI,[FATMAP]
495 INC SI
496 CALL PRINTTHISEL2
497 CALL DOCRLF
498 MOV DX,OFFSET DG:CONTAINS ;Print message
499 CALL PRINT
500 POP SI ;Number of fragments found
501 INC SI ;Number non-contig blocks
502 XOR DI,DI
503 MOV BX,OFFSET DG:EXTENTS
504 PUSH BP
505 CALL DISP16BITS
506 POP BP
507GETNXT:
508 MOV AH,DIR_SEARCH_NEXT ;Look for the next file
509 JMP FRAGCHK
510
511MSGCHK:
512 CMP AH,DIR_SEARCH_FIRST
513 JNZ FILSPOK
514 MOV SI,FCB + 1 ;File not found error
515 CALL PRINTTHISEL2
516 CALL DOCRLF
517 MOV DX,OFFSET DG:OPNERR
518 CALL PRINT ;Bad file spec
519 RET
520FILSPOK:
521 CMP BYTE PTR [FRAGMENT],2
522 JZ CDONE
523 MOV DX,OFFSET DG:NOEXTENTS
524 CALL PRINT
525CDONE:
526 RET
527
528
529FIGREC:
530;Convert cluster number in BX to sector # AH of cluster in DX
531 LDS DI,[THISDPB]
532ASSUME DS:NOTHING
533 MOV CL,[DI.dpb_cluster_shift]
534 MOV DX,BX
535 DEC DX
536 DEC DX
537 SHL DX,CL
538 OR DL,AH
539 ADD DX,[DI.dpb_first_sector]
540 PUSH CS
541 POP DS
542ASSUME DS:DG
543 RET
544
545
546SUBTTL PRINTID - Print Volume ID info
547PAGE
548PRINTID:
549ASSUME DS:DG
550 MOV DX,OFFSET DG:INTERNATVARS
551 MOV AX,INTERNATIONAL SHL 8
552 INT 21H
553 MOV [DISPFLG],1 ;Don't sub spaces for leading zeros
554 MOV SI,OFFSET DG:FAT + 8
555 MOV DI,OFFSET DG:VNAME
556 MOV CX,11
557 REP MOVSB
558 MOV DX,OFFSET DG:IDMES1
559 CALL PRINT ;Print ID message
560 ADD SI,13
561 LODSW ;Get date
562 PUSH SI
563 MOV DX,AX
564 MOV AX,[INTERNATVARS.Date_tim_format]
565 OR AX,AX
566 JZ USPDAT
567 DEC AX
568 JZ EUPDAT
569 CALL P_YR
570 CALL P_DSEP
571 CALL P_MON
572 CALL P_DSEP
573 MOV CX,1000H ;Do not supress leading zeroes
574 CALL P_DAY
575 JMP P_TIME
576
577USPDAT:
578 CALL P_MONTH_NAM
579 MOV CX,1110H ;Supress at most 1 leading 0
580 CALL P_DAY
581 PUSH DX
582 MOV DL,','
583 CALL PRTCHR
584 MOV DL,' '
585 CALL PRTCHR
586 POP DX
587PYA:
588 CALL P_YR
589 JMP P_TIME
590
591EUPDAT:
592 MOV CX,1110H ;Supress at most 1 leading 0
593 CALL P_DAY
594 PUSH DX
595 MOV DL,' '
596 CALL PRTCHR
597 POP DX
598 CALL P_MONTH_NAM
599 JMP PYA
600
601P_DSEP:
602 PUSH DX
603 MOV DL,[INTERNATVARS.Date_sep]
604 CALL PRTCHR
605 POP DX
606 RET
607
608P_MONTH_NAM:
609 MOV AX,DX
610 PUSH DX
611 MOV CL,5
612 SHR AX,CL
613 AND AX,0FH ;Month in AX
614 DEC AX ;Make 0 indexed
615 MOV CX,AX
616 SHL AX,1
617 ADD AX,CX ;Mult by 3 chars/mo
618 MOV SI,OFFSET DG:MONTAB
619 ADD SI,AX
620 LODSB
621 MOV DL,AL
622 CALL PRTCHR
623 LODSB
624 MOV DL,AL
625 CALL PRTCHR
626 LODSB
627 MOV DL,AL
628 CALL PRTCHR
629 MOV DL,' '
630 CALL PRTCHR
631 POP DX
632 RET
633
634P_MON:
635 MOV SI,DX
636 PUSH DX
637 MOV CL,5
638 SHR SI,CL
639 AND SI,0FH ;Month in SI
640 CALL CONVERT
641 MOV DL,AL
642 MOV CX,1000H ;Do not supress leading 0
643 CALL OUTBYTE ;Print month
644 POP DX
645 RET
646
647P_DAY:
648 MOV SI,DX
649 PUSH DX
650 PUSH CX
651 AND SI,01FH ;SI has day
652 CALL CONVERT
653 POP CX
654 MOV DL,AL
655 CALL OUTBYTE ;Print day
656 POP DX
657 RET
658
659P_YR:
660 MOV SI,DX
661 PUSH DX
662 MOV CL,9
663 SHR SI,CL
664 AND SI,07FH ;SI has raw year
665 ADD SI,1980 ;Real year
666 CALL CONVERT
667 MOV CX,1000H ;Do not supress leading zeros
668 CALL OUTWORD ;Print year
669 POP DX
670 RET
671
672P_TIME:
673 MOV DL,' '
674 CALL PRTCHR
675 POP SI
676 ADD SI,-4
677 LODSW ;Get time
678 MOV DI,AX
679 MOV SI,DI
680 MOV CL,11
681 SHR SI,CL
682 AND SI,01FH ;SI has hour
683 CMP [INTERNATVARS.Time_24],0
684 JNZ ISOK2 ;24 hour time?
685 CMP SI,12
686 JB ISOK ;Is AM
687 MOV [TCHAR],'p'
688 JZ ISOK ;Is 12-1p
689 SUB SI,12 ;Is PM
690ISOK:
691 OR SI,SI
692 JNZ ISOK2
693 MOV SI,12 ;0 is 12a
694ISOK2:
695 CALL CONVERT
696 MOV CX,1110H ;Supress at most 1 leading 0
697 MOV DL,AL
698 CALL OUTBYTE ;Print hour
699 MOV DL,BYTE PTR [INTERNATVARS.Time_sep]
700 CALL PRTCHR
701 MOV SI,DI
702 MOV CL,5
703 SHR SI,CL
704 AND SI,03FH ;SI has minute
705 CALL CONVERT
706 MOV CX,1000H ;Do not supress leading zeroes
707 MOV DL,AL
708 CALL OUTBYTE ;Print minute
709 MOV DL,[TCHAR]
710 CMP [INTERNATVARS.Time_24],0
711 JNZ NOAP ;24 hour time, no a or p
712 CALL PRTCHR ;Print a or p
713NOAP:
714 MOV DX,OFFSET DG:IDPOST
715 CALL PRINT
716 MOV [DISPFLG],0
717 RET
718
719CONVERT:
720 MOV CX,16
721 XOR AX,AX
722CNVLOOP:
723 SHL SI,1
724 CALL CONVWRD
725 CLC
726 LOOP CNVLOOP
727 RET
728
729SUBTTL Misc Routines - Mostly I/O
730PAGE
731CONVWRD:
732 ADC AL,AL
733 DAA
734 XCHG AL,AH
735 ADC AL,AL
736 DAA
737 XCHG AL,AH
738RET1: RET
739
740UNSCALE:
741 SHR CX,1
742 JC RET1
743 SHL SI,1
744 RCL DI,1
745 JMP SHORT UNSCALE
746
747DISP16BITS:
748 MOV BYTE PTR DISPFLG,1
749 JMP SHORT DISP32BITS
750
751DISPCLUS:
752 MUL [SSIZE]
753 MOV CL,[CSIZE]
754 XOR CH,CH
755 MOV SI,AX
756 MOV DI,DX
757 CALL UNSCALE
758
759DISP32BITS:
760 PUSH BP
761 PUSH BX
762 XOR AX,AX
763 MOV BX,AX
764 MOV BP,AX
765 MOV CX,32
766CONVLP:
767 SHL SI,1
768 RCL DI,1
769 XCHG AX,BP
770 CALL CONVWRD
771 XCHG AX,BP
772 XCHG AX,BX
773 CALL CONVWRD
774 XCHG AX,BX
775 ADC AL,0
776 LOOP CONVLP
777 ; Conversion complete
778 MOV CX,1310H ;Print 3-digit number with 2 leading blanks
779 CMP BYTE PTR DISPFLG,0
780 JNZ FOURDIG
781 MOV CX,1810H ;Print 8-digit number with 2 leading blanks
782 XCHG DX,AX
783 CALL DIGIT
784 XCHG AX,BX
785 CALL OUTWORD
786FOURDIG:
787 MOV AX,BP
788 CALL OUTWORD
789 MOV BYTE PTR DISPFLG,0
790 POP DX
791 CALL PRINT
792 POP BP
793 RET
794
795OUTWORD:
796 PUSH AX
797 MOV DL,AH
798 CALL OUTBYTE
799 POP DX
800OUTBYTE:
801 MOV DH,DL
802 SHR DL,1
803 SHR DL,1
804 SHR DL,1
805 SHR DL,1
806 CALL DIGIT
807 MOV DL,DH
808DIGIT:
809 AND DL,0FH
810 JZ BLANKZER
811 MOV CL,0
812BLANKZER:
813 DEC CH
814 AND CL,CH
815 OR DL,30H
816 SUB DL,CL
817 CMP BYTE PTR DISPFLG,0
818 JZ PRTCHR
819 CMP DL,30H
820 JL RET2
821PRTCHR:
822 MOV AH,STD_CON_OUTPUT
823 INT 21H
824RET2: RET
825
826PRINTCNT:
827 LODSB
828 MOV DL,AL
829 INT 21H
830 LOOP PRINTCNT
831 RET
832
833EPRINT:
834 CALL CHECKERR
835 JNZ RET$1
836 JMP SHORT PRINT
837
838DOCRLF:
839 MOV DX,OFFSET DG:CRLF
840PRINT:
841 MOV AH,STD_CON_STRING_OUTPUT
842 INT 21H
843RET$1: RET
844
845DOTCOMBMES:
846 CMP [NOISY],0
847 JZ SUBERRP
848 PUSH DX
849 CALL PRINTCURRDIRERR
850 MOV DX,OFFSET DG:CENTRY
851 CALL EPRINT
852 POP DX
853 CALL EPRINT
854 CALL DOCRLF
855 RET
856
857SUBERRP:
858 MOV AL,1
859 XCHG AL,[ERRSUB]
860 CMP AL,0
861 JNZ RET32
862 MOV SI,OFFSET DG:NUL
863 CALL PRINTCURRDIRERR
864 MOV DX,OFFSET DG:BADSUBDIR
865 CALL EPRINT
866RET32: RET
867
868
869FCB_TO_ASCZ: ;Convert DS:SI to ASCIIZ ES:DI
870 MOV CX,8
871MAINNAME:
872 LODSB
873 CMP AL,' '
874 JZ SKIPSPC
875 STOSB
876SKIPSPC:
877 LOOP MAINNAME
878 LODSB
879 CMP AL,' '
880 JZ GOTNAME
881 MOV AH,AL
882 MOV AL,'.'
883 STOSB
884 XCHG AL,AH
885 STOSB
886 MOV CL,2
887EXTNAME:
888 LODSB
889 CMP AL,' '
890 JZ GOTNAME
891 STOSB
892 LOOP EXTNAME
893
894GOTNAME:
895 XOR AL,AL
896 STOSB
897 RET
898
899CODE ENDS
900 END CHKDSK
901
diff --git a/v2.0/source/CHKMES.ASM b/v2.0/source/CHKMES.ASM
new file mode 100644
index 0000000..83af5ba
--- /dev/null
+++ b/v2.0/source/CHKMES.ASM
@@ -0,0 +1,477 @@
1TITLE CHKDSK Messages
2
3FALSE EQU 0
4TRUE EQU NOT FALSE
5
6.xlist
7.xcref
8 INCLUDE DOSSYM.ASM
9;The DOST: prefix is a DEC TOPS/20 directory prefix. Remove it for
10; assembly in MS-DOS assembly environments using MASM. The DOSSYM.ASM
11; file must exist though, it is included with OEM distribution.
12.cref
13.list
14CODE SEGMENT PUBLIC BYTE
15CODE ENDS
16
17CONST SEGMENT PUBLIC BYTE
18 EXTRN HIDSIZ:WORD,HIDCNT:WORD,DIRCNT:WORD,DIRSIZ:WORD,FILCNT:WORD
19 EXTRN FILSIZ:WORD,ORPHCNT:WORD,ORPHSIZ:WORD,BADSIZ:WORD,LCLUS:WORD
20 EXTRN DOFIX:BYTE
21CONST ENDS
22
23DATA SEGMENT PUBLIC BYTE
24 EXTRN DSIZE:WORD
25DATA ENDS
26
27DG GROUP CODE,CONST,DATA
28
29
30CODE SEGMENT PUBLIC BYTE
31ASSUME CS:DG,DS:DG,ES:DG,SS:DG
32
33 PUBLIC RDSKERR,WDSKERR,SETSWITCH,PROMPTYN,DOINT26,CHAINREPORT,REPORT
34 EXTRN RDONE:NEAR,PRTCHR:NEAR,PRINT:NEAR,DOCRLF:NEAR
35 EXTRN DISP16BITS:NEAR,FINDCHAIN:NEAR
36 EXTRN DISP32BITS:NEAR,DISPCLUS:NEAR
37
38DOINT26:
39 PUSH CX
40 PUSH AX
41 PUSH DX
42 PUSH BX
43 INT 26H
44 MOV [HECODE],AL
45 POP AX ;FLAGS
46 POP BX
47 POP DX
48 POP AX
49 POP CX
50 JNC RET23
51 MOV SI,OFFSET DG:WRITING
52 CALL DSKERR
53 JZ DOINT26
54RET23: RET
55
56RDSKERR:
57 MOV SI,OFFSET DG:READING
58 JMP SHORT DSKERR
59
60WDSKERR:
61 MOV SI,OFFSET DG:WRITING
62DSKERR:
63 PUSH AX
64 PUSH BX
65 PUSH CX
66 PUSH DX
67 PUSH DI
68 PUSH ES
69 MOV AL,[HECODE]
70 CMP AL,12
71 JBE HAVCOD
72 MOV AL,12
73HAVCOD:
74 XOR AH,AH
75 MOV DI,AX
76 SHL DI,1
77 MOV DX,WORD PTR [DI+MESBAS] ; Get pointer to error message
78 CALL PRINT ; Print error type
79 MOV DX,OFFSET DG:ERRMES
80 CALL PRINT
81 MOV DX,SI
82 CALL PRINT
83 MOV DX,OFFSET DG:DRVMES
84 CALL PRINT
85ASK:
86 MOV DX,OFFSET DG:REQUEST
87 CALL PRINT
88 MOV AX,(STD_CON_INPUT_FLUSH SHL 8)+STD_CON_INPUT
89 INT 21H ; Get response
90 PUSH AX
91 CALL DOCRLF
92 POP AX
93 OR AL,20H ; Convert to lower case
94 CMP AL,"i" ; Ignore?
95 JZ EEXITNZ
96 CMP AL,"r" ; Retry?
97 JZ EEXIT
98 CMP AL,"a" ; Abort?
99 JNZ ASK
100 JMP RDONE
101
102EEXITNZ:
103 OR AL,AL ; Resets zero flag
104EEXIT:
105 POP ES
106 POP DI
107 POP DX
108 POP CX
109 POP BX
110 POP AX
111 RET
112
113PROMPTYN:
114;Prompt message in DX
115;Prompt user for Y or N answer. Zero set if Y
116 PUSH SI
117 CALL PRINT
118PAGAIN:
119 MOV DX,OFFSET DG:YES_NO
120 CALL PRINT
121 MOV DX,OFFSET DG:CONBUF
122 MOV AH,STD_CON_STRING_INPUT
123 INT 21H
124 CALL DOCRLF
125 MOV SI,OFFSET DG:CONBUF+2
126 CMP BYTE PTR [SI-1],0
127 JZ PAGAIN
128 LODSB
129 OR AL,20H ;Convert to lower case
130 CMP AL,'y'
131 JZ GOTANS
132 CMP AL,'n'
133 JZ GOTNANS
134 JMP PAGAIN
135GOTNANS:
136 OR AL,AL ;Reset zero
137GOTANS:
138 POP SI
139 RET
140
141SETSWITCH:
142;Look for F or V switch in command line
143 MOV SI,80H
144 LODSB
145 MOV DI,SI
146 MOV CL,AL
147 XOR CH,CH
148 JCXZ RET10 ;No parameters
149 MOV AL,[SWITCHAR]
150MORESCAN:
151 REPNZ SCASB
152 JNZ RET10
153 JCXZ BADSWITCHA
154 MOV AH,[DI]
155 INC DI
156 OR AH,20H ;Convert to lower case
157 CMP AH,'f'
158 JNZ CHECKV
159 INC [DOFIX]
160 JMP SHORT CHEKMORE
161CHECKV:
162 CMP AH,'v'
163 JZ SETNOISY
164 CALL BADSWITCH
165 JMP SHORT CHEKMORE
166SETNOISY:
167 INC [NOISY]
168CHEKMORE:
169 LOOP MORESCAN
170 RET
171
172BADSWITCHA:
173 MOV AH,' ' ;Print a non switch
174BADSWITCH:
175 PUSH AX
176 MOV DL,[SWITCHAR]
177 CALL PRTCHR
178 POP AX
179 PUSH AX
180 MOV DL,AH
181 CALL PRTCHR
182 MOV DX,OFFSET DG:BADSWMES
183 CALL PRINT
184 POP AX
185RET10: RET
186
187
188;**************************************
189; Prints XXX lost clusters found in YYY chains message
190; On entry SI is the XXX value and the YYY value is
191; in ORPHCNT.
192; NOTE:
193; The DISP16BITS routine prints the number in DI:SI followed
194; by the message pointed to by BX. If it is desired to
195; print a message before the first number, point at the
196; message with DX and call PRINT.
197
198CHAINREPORT:
199 XOR DI,DI
200 MOV BX,OFFSET DG:ORPHMES2
201 CALL DISP16BITS
202 CALL FINDCHAIN
203 MOV BX,OFFSET DG:CHNUMMES
204 MOV SI,[ORPHCNT]
205 XOR DI,DI
206 CALL DISP16BITS ;Tell user how many chains found
207 RET
208
209;*****************************************
210;Prints all of the reporting data
211;NOTE:
212; The DISPCLUS, DISP16BITS and DISP32BITS routines
213; print the number in DI:SI followed
214; by the message pointed to by BX. If it is desired to
215; print a message before the first number, point at the
216; message with DX and call PRINT.
217
218REPORT:
219 MOV AX,[DSIZE]
220 MOV BX,OFFSET DG:DSKSPC
221 CALL DISPCLUS ;Total size
222 CMP [HIDCNT],0
223 JZ USERLIN
224 MOV AX,[HIDSIZ] ;Hidden files
225 MOV BX,OFFSET DG:INMES
226 CALL DISPCLUS
227 MOV SI,[HIDCNT]
228 XOR DI,DI
229 MOV BX,OFFSET DG:HIDMES
230 CALL DISP16BITS
231USERLIN:
232 CMP [DIRCNT],0
233 JZ DIRLIN
234 MOV AX,[DIRSIZ]
235 MOV BX,OFFSET DG:INMES
236 CALL DISPCLUS
237 MOV SI,[DIRCNT]
238 XOR DI,DI
239 MOV BX,OFFSET DG:DIRMES
240 CALL DISP16BITS
241DIRLIN:
242 CMP [FILCNT],0
243 JZ ORPHLIN
244 MOV AX,[FILSIZ] ;Regular files
245 MOV BX,OFFSET DG:INMES
246 CALL DISPCLUS
247 MOV SI,[FILCNT]
248 XOR DI,DI
249 MOV BX,OFFSET DG:FILEMES
250 CALL DISP16BITS
251ORPHLIN:
252 MOV AX,[ORPHSIZ]
253 OR AX,AX
254 JZ BADLIN
255 MOV BX,OFFSET DG:INMES ;Orphans
256 CMP [DOFIX],0
257 JNZ ALLSET1
258 MOV BX,OFFSET DG:INMES2 ;Orphans
259ALLSET1:
260 CALL DISPCLUS
261 MOV SI,[ORPHCNT]
262 XOR DI,DI
263 MOV BX,OFFSET DG:ORPHMES
264 CALL DISP16BITS
265BADLIN:
266 MOV AX,[BADSIZ]
267 OR AX,AX
268 JZ AVAILIN
269 MOV BX,OFFSET DG:BADSPC ;Bad sectors
270 CALL DISPCLUS
271AVAILIN:
272 MOV AX,[DSIZE]
273 SUB AX,[DIRSIZ]
274 SUB AX,[FILSIZ]
275 SUB AX,[HIDSIZ]
276 SUB AX,[BADSIZ]
277 SUB AX,[ORPHSIZ]
278 SUB AX,[LCLUS]
279 MOV BX,OFFSET DG:FRESPC
280 CALL DISPCLUS ;Free space is whats left
281 MOV AX,DS:WORD PTR [2] ;Find out about memory
282 MOV DX,16
283 MUL DX
284 MOV SI,AX
285 MOV DI,DX
286 MOV BX,OFFSET DG:TOTMEM
287 CALL DISP32BITS
288 MOV AX,DS:WORD PTR [2]
289 MOV DX,CS
290 SUB AX,DX
291 MOV DX,16
292 MUL DX
293 MOV SI,AX
294 MOV DI,DX
295 MOV BX,OFFSET DG:FREMEM
296 CALL DISP32BITS
297 RET
298
299CODE ENDS
300
301
302CONST SEGMENT PUBLIC BYTE
303
304 EXTRN HECODE:BYTE,SWITCHAR:BYTE,NOISY:BYTE,DOFIX:BYTE,CONBUF:BYTE
305
306 PUBLIC CRLF2,CRLF,BADVER,BADDRV
307 PUBLIC BADSUBDIR,CENTRY,CLUSBAD,BADATT,BADSIZM
308 PUBLIC FIXMES,DIRECMES,CDDDMES
309 PUBLIC FREEBYMESF_PRE,FREEBYMES_PRE,FREEBYMESF_POST,FREEBYMES_POST
310 PUBLIC CREATMES,NDOTMES
311 PUBLIC BADTARG1,BADTARG2,BADCD,FATALMES,BADRDMES
312 PUBLIC BADDRVM,STACKMES,BADDPBDIR
313 PUBLIC BADDRVM2
314 PUBLIC NULNZ,NULDMES,BADCLUS,NORECDOT
315 PUBLIC NORECDDOT,IDMES1,IDPOST,VNAME,TCHAR
316 PUBLIC MONTAB,BADREAD_PRE,BADREAD_POST,BADWRITE_PRE
317 PUBLIC BADWRITE_POST,BADCHAIN,CROSSMES_PRE,CROSSMES_POST
318 PUBLIC FREEMES
319 PUBLIC OPNERR
320 PUBLIC CONTAINS,EXTENTS,NOEXTENTS,INDENT
321 PUBLIC BADIDBYT,PTRANDIR,PTRANDIR2
322
323
324MESBAS DW OFFSET DG:ERR0
325 DW OFFSET DG:ERR1
326 DW OFFSET DG:ERR2
327 DW OFFSET DG:ERR3
328 DW OFFSET DG:ERR4
329 DW OFFSET DG:ERR5
330 DW OFFSET DG:ERR6
331 DW OFFSET DG:ERR7
332 DW OFFSET DG:ERR8
333 DW OFFSET DG:ERR9
334 DW OFFSET DG:ERR10
335 DW OFFSET DG:ERR11
336 DW OFFSET DG:ERR12
337
338CRLF2 DB 13,10
339CRLF DB 13,10,"$"
340
341;Messages
342
343BADVER DB "Incorrect DOS version",13,10,"$"
344BADDRV DB "Invalid drive specification$"
345
346BADSWMES DB " Invalid parameter",13,10,"$"
347
348BADSUBDIR DB " Invalid sub-directory entry.",13,10,"$"
349CENTRY DB " Entry has a bad $"
350CLUSBAD DB " link$"
351BADATT DB " attribute$"
352BADSIZM DB " size$"
353
354;"BADTARG1<name of dir followed by CR LF>BADTARG2"
355BADTARG1 DB "Cannot CHDIR to $"
356BADTARG2 DB " tree past this point not processed.",13,10,"$"
357
358BADCD DB "Cannot CHDIR to root",13,10,"$"
359
360FATALMES DB "Processing cannot continue.",13,10,"$"
361BADRDMES DB "File allocation table bad drive "
362BADDRVM DB "A.",13,10,"$"
363STACKMES DB "Insufficient memory.",13,10,"$"
364BADDPBDIR DB "Invalid current directory.",13,10,"$"
365
366;INT 24 MESSAGE SHOULD AGREE WITH COMMAND
367
368READING DB "read$"
369WRITING DB "writ$"
370ERRMES DB " error $"
371DRVMES DB "ing drive "
372BADDRVM2 DB "A",13,10,"$"
373REQUEST DB "Abort, Retry, Ignore? $"
374ERR0 DB "Write protect$"
375ERR1 DB "Bad unit$"
376ERR2 DB "Not ready$"
377ERR3 DB "Bad command$"
378ERR4 DB "Data$"
379ERR5 DB "Bad call format$"
380ERR6 DB "Seek$"
381ERR7 DB "Non-DOS disk$"
382ERR8 DB "Sector not found$"
383ERR9 DB "No paper$"
384ERR10 DB "Write fault$"
385ERR11 DB "Read fault$"
386ERR12 DB "Disk$"
387
388
389NDOTMES DB " Does not exist.",13,10,"$"
390NULNZ DB " First cluster number is invalid,",13,10
391 DB " entry truncated.",13,10,"$"
392NULDMES DB " Directory is totally empty, no . or ..",13,10,"$"
393BADCLUS DB " Allocation error, size adjusted.",13,10,"$"
394NORECDOT DB " Cannot recover . entry, processing continued.",13,10,"$"
395NORECDDOT DB " Cannot recover .. entry,"
396
397;VOLUME ID
398
399;"IDMES1/name at VNAME<date and time>IDPOST"
400IDPOST DB 13,10,"$" ;WARNING this is currently the tail of
401 ; the previos message!!!
402IDMES1 DB "Volume "
403VNAME DB 12 DUP(' ')
404 DB "created $"
405TCHAR DB 'a'
406MONTAB DB "JanFebMarAprMayJunJulAugSepOctNovDec"
407
408
409
410;"BADREAD_PRE<# of FAT>BADREAD_POST"
411BADREAD_PRE DB "Disk error reading FAT $"
412
413;"BADWRITE_PRE<# of FAT>BADWRITE_POST"
414BADWRITE_PRE DB "Disk error writing FAT $"
415
416BADCHAIN DB " Has invalid cluster, file truncated."
417
418BADREAD_POST LABEL BYTE
419BADWRITE_POST LABEL BYTE
420
421;"<name of file followed by CR LF>CROSSMES_PRE<# of cluster>CROSSMES_POST"
422CROSSMES_POST DB 13,10,"$" ;WARNING Is tail of previos messages
423CROSSMES_PRE DB " Is cross linked on cluster $"
424
425;CHAINREPORT messages
426ORPHMES2 DB " lost clusters found in $"
427CHNUMMES DB " chains.",13,10,"$"
428
429FREEMES DB "Convert lost chains to files $"
430
431;REPORT messages
432ORPHMES DB " recovered files",13,10,"$"
433DSKSPC DB " bytes total disk space",13,10,"$"
434INMES DB " bytes in $"
435INMES2 DB " bytes would be in",13,10
436 DB " $"
437FILEMES DB " user files",13,10,"$"
438BADSPC DB " bytes in bad sectors",13,10,"$"
439HIDMES DB " hidden files",13,10,"$"
440DIRMES DB " directories",13,10,"$"
441FRESPC DB " bytes available on disk",13,10,13,10,"$"
442TOTMEM DB " bytes total memory",13,10,"$"
443FREMEM DB " bytes free",13,10,13,10,"$"
444
445;"<filename followed by CR LF>CONTAINS<# non-contig blocks>EXTENTS"
446CONTAINS DB " Contains $"
447EXTENTS DB " non-contiguous blocks.",13,10,"$"
448
449NOEXTENTS DB "All specified file(s) are contiguous.",13,10,"$"
450INDENT DB " $"
451
452BADIDBYT DB "Probable non-DOS disk."
453 DB 13,10,"Continue $"
454YES_NO DB "(Y/N)? $"
455PTRANDIR DB " Unrecoverable error in directory.",13,10
456PTRANDIR2 DB " Convert directory to file $"
457FIXMES DB 13,10,"Errors found, F parameter not specified."
458 DB 13,10,"Corrections will not be written to disk.",13,10,13,10,"$"
459DIRECMES DB "Directory $"
460CDDDMES DB " CHDIR .. failed, trying alternate method.",13,10,"$"
461
462
463FREEBYMESF_POST DB " bytes disk space freed.",13,10
464FREEBYMESF_PRE DB "$"
465FREEBYMES_POST DB " bytes disk space",13,10
466 DB " would be freed.",13,10
467FREEBYMES_PRE DB "$"
468
469
470CREATMES DB "Insufficient room in root directory."
471 DB 13,10,"Erase files in root and repeat CHKDSK.",13,10,"$"
472OPNERR DB " File not found.",13,10,"$"
473
474
475CONST ENDS
476 END
477
diff --git a/v2.0/source/CHKPROC.ASM b/v2.0/source/CHKPROC.ASM
new file mode 100644
index 0000000..b003f83
--- /dev/null
+++ b/v2.0/source/CHKPROC.ASM
@@ -0,0 +1,1408 @@
1TITLE CHKPROC - Procedures called from chkdsk
2
3FALSE EQU 0
4TRUE EQU NOT FALSE
5
6DRVCHAR EQU ":"
7
8 INCLUDE DOSSYM.ASM
9
10SUBTTL Segments used in load order
11
12CODE SEGMENT PUBLIC
13CODE ENDS
14
15CONST SEGMENT PUBLIC BYTE
16
17 EXTRN CLUSBAD:BYTE,BADATT:BYTE,BADSIZM:BYTE
18 EXTRN DIRECMES:BYTE,CDDDMES:BYTE,NDOTMES:BYTE
19 EXTRN BADTARG1:BYTE,BADTARG2:BYTE,FATALMES:BYTE
20 EXTRN STACKMES:BYTE,BADDPBDIR:BYTE,CREATMES:BYTE
21 EXTRN FREEBYMES_PRE:BYTE,FREEBYMESF_PRE:BYTE
22 EXTRN FREEBYMES_POST:BYTE,FREEBYMESF_POST:BYTE
23 EXTRN NULNZ:BYTE,NULDMES:BYTE,BADCLUS:BYTE
24 EXTRN NORECDDOT:BYTE,NORECDOT:BYTE,DOTMES:BYTE
25 EXTRN BADWRITE_PRE:BYTE,BADCHAIN:BYTE,CROSSMES_PRE:BYTE
26 EXTRN BADWRITE_POST:BYTE,CROSSMES_POST:BYTE,INDENT:BYTE
27 EXTRN PTRANDIR:BYTE,PTRANDIR2:BYTE,FREEMES:BYTE,FIXMES:BYTE
28
29 EXTRN NOISY:BYTE,DOFIX:BYTE,DIRBUF:WORD,DOTENT:BYTE,FIXMFLG:BYTE
30 EXTRN HAVFIX:BYTE,SECONDPASS:BYTE,LCLUS:WORD,DIRTYFAT:BYTE
31 EXTRN NUL:BYTE,ALLFILE:BYTE,PARSTR:BYTE,ERRSUB:WORD,USERDIR:BYTE
32 EXTRN HIDCNT:WORD,HIDSIZ:WORD,FILCNT:WORD,FILSIZ:WORD,DIRCHAR:BYTE
33 EXTRN DIRCNT:WORD,DIRSIZ:WORD,FRAGMENT:BYTE,HECODE:BYTE
34 EXTRN BADSIZ:WORD,ORPHSIZ:WORD,DDOTENT:BYTE,CROSSCNT:WORD
35 EXTRN ORPHCNT:WORD,ORPHFCB:BYTE,ORPHEXT:BYTE,ALLDRV:BYTE,DIRCHAR:BYTE
36
37CONST ENDS
38
39DATA SEGMENT PUBLIC WORD
40
41 EXTRN THISDPB:DWORD,HARDCH:DWORD,CONTCH:DWORD,USERDEV:BYTE
42 EXTRN CSIZE:BYTE,SSIZE:WORD,DSIZE:WORD,MCLUS:WORD,NAMBUF:BYTE
43 EXTRN DOTSNOGOOD:BYTE,ZEROTRUNC:BYTE,ISCROSS:BYTE,SRFCBPT:WORD
44 EXTRN FATMAP:WORD,SECBUF:WORD,ERRCNT:BYTE,STACKLIM:WORD,FAT:WORD
45
46DATA ENDS
47
48DG GROUP CODE,CONST,DATA
49
50SUBTTL Initialized Data
51PAGE
52
53
54CODE SEGMENT PUBLIC
55ASSUME CS:DG,DS:DG,ES:DG,SS:DG
56
57 PUBLIC INT_23,INT_24,FINDCHAIN,DONE,AMDONE,RDONE
58 PUBLIC FATAL,DIRPROC,CHKMAP,CHKCROSS,UNPACK
59 PUBLIC PRINTTHISEL2,CHECKERR,PRINTCURRDIRERR
60
61 EXTRN EPRINT:NEAR,DOCRLF:NEAR,PRINT:NEAR
62 EXTRN PROMPTYN:NEAR,DOINT26:NEAR,SUBERRP:NEAR
63 EXTRN DOTCOMBMES:NEAR,DISP16BITS:NEAR
64 EXTRN CHAINREPORT:NEAR,DISPCLUS:NEAR
65 EXTRN PRTCHR:NEAR,WDSKERR:NEAR,CHECKFILES:NEAR
66 EXTRN FCB_TO_ASCZ:NEAR,FIGREC:NEAR,RDSKERR:NEAR
67
68CHKPROC:
69
70SUBTTL DIRPROC -- Recursive directory processing
71
72; YOU ARE ADVISED NOT TO COPY THE FOLLOWING METHOD!!!
73
74DOTDOTHARDWAY:
75 LDS DI,[THISDPB]
76ASSUME DS:NOTHING
77 MOV [DI.dpb_current_dir],-1 ;Invalidate path
78 MOV SI,DI
79 ADD SI,dpb_dir_text
80 MOV CX,SI
81FINDEND:
82 LODSB ;Scan to end of current path
83 OR AL,AL
84 JNZ FINDEND
85 DEC SI ;Point at the NUL
86DELLOOP: ;Delete last element
87 CMP SI,CX
88 JZ SETROOT
89 CMP BYTE PTR [SI],"/"
90 JZ SETTERM
91 CMP BYTE PTR [SI],"\"
92 JZ SETTERM
93 DEC SI
94 JMP SHORT DELLOOP
95
96SETTERM:
97 MOV BYTE PTR [SI],0
98SETCURR:
99 PUSH CS
100 POP DS
101ASSUME DS:DG
102 MOV DX,OFFSET DG:DOTMES
103 MOV AH,CHDIR ;Chdir to altered path
104 INT 21H
105 RET
106
107SETROOT:
108ASSUME DS:NOTHING
109 MOV [DI.dpb_current_dir],0 ;Set Path to Root
110 JMP SHORT SETCURR ;The CHDIR will fail, but who cares
111
112
113;Structures used by DIRPROC
114
115SRCHFCB STRUC
116 DB 44 DUP (?)
117SRCHFCB ENDS
118SFCBSIZ EQU SIZE SRCHFCB
119THISENT EQU 17H ;Relative entry number of current entry
120
121DIRENT STRUC
122 DB 7 DUP (?) ;Ext FCB junk
123 DB ? ;Drive
124DIRNAM DB 11 DUP (?)
125DIRATT DB ?
126 DB 10 DUP (?)
127DIRTIM DW ?
128DIRDAT DW ?
129DIRCLUS DW ?
130DIRESIZ DD ?
131DIRENT ENDS
132ENTSIZ EQU SIZE DIRENT
133
134;Attribute bits
135
136RDONLY EQU 1
137HIDDN EQU 2
138SYSTM EQU 4
139VOLIDA EQU 8
140ISDIR EQU 10H
141
142ASSUME DS:DG
143
144NODOT: ;No .
145 PUSH AX ;Return from SRCH
146 CMP [NOISY],0
147 JNZ DOEXTMES1
148 CALL SUBERRP
149 JMP SHORT MESD1
150DOEXTMES1:
151 MOV SI,OFFSET DG:DOTMES
152 CALL PRINTCURRDIRERR
153 MOV DX,OFFSET DG:NDOTMES
154 CALL EPRINT
155MESD1:
156 XOR AX,AX
157 PUSH BX
158 PUSH BP
159 CALL GETENT
160 POP BP
161 PUSH BP
162 CMP BYTE PTR [DI],0E5H ;Have place to put .?
163 JNZ CANTREC ;Nope
164 MOV SI,OFFSET DG:DOTENT
165 MOV CX,11
166 REP MOVSB ;Name
167 PUSH AX
168 MOV AL,ISDIR
169 STOSB ;Attribute
170 ADD DI,10
171 XOR AX,AX
172 STOSW ;Date = 0
173 STOSW ;Time = 0
174 MOV AX,[BP+6]
175 STOSW ;Alloc #
176 XOR AX,AX
177 STOSW
178 STOSW ;Size
179 POP AX
180 MOV [HAVFIX],1 ;Have a fix
181 CMP [DOFIX],0
182 JZ DOTGOON ;No fix if not F
183 MOV CX,1
184 CALL DOINT26
185 JMP SHORT DOTGOON
186
187CANTREC:
188 INC [DOTSNOGOOD]
189 CMP [NOISY],0
190 JZ DOTGOON
191 MOV DX,OFFSET DG:NORECDOT
192 CALL EPRINT
193DOTGOON:
194 POP BP
195 POP BX
196 POP AX
197 MOV SI,OFFSET DG:DIRBUF
198 JMP CHKDOTDOT ;Go look for ..
199
200NODDOT: ;No ..
201 PUSH AX ;Return from SRCH
202 CMP [NOISY],0
203 JNZ DOEXTMES2
204 CALL SUBERRP
205 JMP SHORT MESD2
206DOEXTMES2:
207 MOV SI,OFFSET DG:PARSTR
208 CALL PRINTCURRDIRERR
209 MOV DX,OFFSET DG:NDOTMES
210 CALL EPRINT
211MESD2:
212 MOV AX,1
213 PUSH BX
214 PUSH BP
215 CALL GETENT
216 POP BP
217 PUSH BP
218 CMP BYTE PTR [DI],0E5H ;Place to put it?
219 JNZ CANTREC2 ;Nope
220 MOV SI,OFFSET DG:DDOTENT
221 MOV CX,11
222 REP MOVSB ;Name
223 PUSH AX
224 MOV AL,ISDIR
225 STOSB ;Attribute
226 ADD DI,10
227 XOR AX,AX
228 STOSW ;Date
229 STOSW ;Time
230 MOV AX,[BP+4]
231 STOSW ;Alloc #
232 XOR AX,AX
233 STOSW
234 STOSW ;Size
235 POP AX
236 MOV [HAVFIX],1 ;Got a fix
237 CMP [DOFIX],0
238 JZ NFIX ;No fix if no F, carry clear
239 MOV CX,1
240 CALL DOINT26
241NFIX:
242 POP BP
243 POP BX
244 POP AX
245 MOV SI,OFFSET DG:DIRBUF
246 JMP ROOTDIR ;Process files
247
248CANTREC2:
249 POP BP
250 POP BX
251 POP AX
252 CMP [NOISY],0
253 JZ DOTSBAD
254 MOV DX,OFFSET DG:NORECDDOT
255 CALL EPRINT
256 JMP DOTSBAD
257
258NULLDIRERR:
259 CMP [NOISY],0
260 JNZ DOEXTMES3
261 CALL SUBERRP
262 JMP SHORT DOTSBAD
263DOEXTMES3:
264 MOV SI,OFFSET DG:NUL
265 CALL PRINTCURRDIRERR
266 MOV DX,OFFSET DG:NULDMES
267 CALL EPRINT
268DOTSBAD: ;Can't recover
269 MOV DX,OFFSET DG:BADTARG2
270 CALL EPRINT
271 CALL DOTDOTHARDWAY
272 INC [DOTSNOGOOD]
273 JMP DIRDONE ;Terminate tree walk at this level
274
275ROOTDIRJ: JMP ROOTDIR
276
277PAGE
278DIRPROC:
279;Recursive tree walker
280;dirproc(self,parent)
281 MOV [DOTSNOGOOD],0 ;Init to dots OK
282 MOV [ERRSUB],0 ;No subdir errors yet
283 PUSH BP ;Save frame pointer
284 MOV BP,SP
285 SUB SP,SFCBSIZ ;Only local var
286 CMP SP,[STACKLIM]
287 JA STACKISOK
288 MOV BX,OFFSET DG:STACKMES ;Out of stack
289 JMP FATAL
290STACKISOK:
291 CMP [NOISY],0
292 JZ NOPRINT
293 CMP [SECONDPASS],0
294 JNZ NOPRINT ;Don't do it again on second pass
295 MOV DX,OFFSET DG:DIRECMES ;Tell user where we are
296 CALL PRINT
297 MOV SI,OFFSET DG:NUL
298 CALL PRINTCURRDIR
299 CALL DOCRLF
300NOPRINT:
301 MOV SI,OFFSET DG:ALLFILE
302 MOV DI,SP
303 PUSH DI
304 MOV CX,SFCBSIZ
305 REP MOVSB ;Initialize search FCB
306 POP DX
307 MOV BX,DX ;BX points to SRCH FCB
308 MOV AH,DIR_SEARCH_FIRST
309 INT 21H
310 CMP WORD PTR [BP+6],0 ;Am I the root
311 JZ ROOTDIRJ ;Yes, no . or ..
312 OR AL,AL
313 JZ NONULLDERR
314 JMP NULLDIRERR ;Dir is empty!
315NONULLDERR:
316 MOV SI,OFFSET DG:DIRBUF + DIRNAM
317 MOV DI,OFFSET DG:DOTENT
318 MOV CX,11
319 REP CMPSB
320 JZ DOTOK ;Got a . as first entry
321 JMP NODOT ;No .
322DOTOK:
323 MOV SI,OFFSET DG:DIRBUF
324 MOV AL,[SI.DIRATT]
325 TEST AL,ISDIR
326 JNZ DATTOK
327 PUSH SI ;. not a dir?
328 MOV SI,OFFSET DG:DOTMES
329 MOV DX,OFFSET DG:BADATT
330 CALL DOTCOMBMES
331 POP SI
332 OR [SI.DIRATT],ISDIR
333 CALL FIXENT ;Fix it
334DATTOK:
335 MOV AX,[SI.DIRCLUS]
336 CMP AX,[BP+6] ;. link = MYSELF?
337 JZ DLINKOK
338 PUSH SI ;Link messed up
339 MOV SI,OFFSET DG:DOTMES
340 MOV DX,OFFSET DG:CLUSBAD
341 CALL DOTCOMBMES
342 POP SI
343 MOV AX,[BP+6]
344 MOV [SI.DIRCLUS],AX
345 CALL FIXENT ;Fix it
346DLINKOK:
347 MOV AX,WORD PTR [SI.DIRESIZ]
348 OR AX,AX
349 JNZ BADDSIZ
350 MOV AX,WORD PTR [SI.DIRESIZ+2]
351 OR AX,AX
352 JZ DSIZOK
353BADDSIZ: ;Size should be zero
354 PUSH SI
355 MOV SI,OFFSET DG:DOTMES
356 MOV DX,OFFSET DG:BADSIZM
357 CALL DOTCOMBMES
358 POP SI
359 XOR AX,AX
360 MOV WORD PTR [SI.DIRESIZ],AX
361 MOV WORD PTR [SI.DIRESIZ+2],AX
362 CALL FIXENT ;Fix it
363DSIZOK: ;Get next (should be ..)
364 MOV DX,BX
365 MOV AH,DIR_SEARCH_NEXT
366 INT 21H
367CHKDOTDOT: ;Come here after . failure
368 OR AL,AL
369 JZ DOTDOTOK
370NODDOTJ: JMP NODDOT ;No ..
371DOTDOTOK:
372 MOV SI,OFFSET DG:DIRBUF + DIRNAM
373 MOV DI,OFFSET DG:DDOTENT
374 MOV CX,11
375 REP CMPSB
376 JNZ NODDOTJ ;No ..
377 MOV SI,OFFSET DG:DIRBUF
378 MOV AL,[SI.DIRATT]
379 TEST AL,ISDIR
380 JNZ DDATTOK ;.. must be a dir
381 PUSH SI
382 MOV SI,OFFSET DG:PARSTR
383 MOV DX,OFFSET DG:BADATT
384 CALL DOTCOMBMES
385 POP SI
386 OR [SI.DIRATT],ISDIR
387 CALL FIXENT ;Fix it
388DDATTOK:
389 PUSH SI
390 MOV AX,[SI.DIRCLUS]
391 CMP AX,[BP+4] ;.. link must be PARENT
392 JZ DDLINKOK
393 MOV SI,OFFSET DG:PARSTR
394 MOV DX,OFFSET DG:CLUSBAD
395 CALL DOTCOMBMES
396 POP SI
397 MOV AX,[BP+4]
398 MOV [SI.DIRCLUS],AX
399 CALL FIXENT ;Fix it
400DDLINKOK:
401 MOV AX,WORD PTR [SI.DIRESIZ]
402 OR AX,AX
403 JNZ BADDDSIZ
404 MOV AX,WORD PTR [SI.DIRESIZ+2]
405 OR AX,AX
406 JZ DDSIZOK
407BADDDSIZ: ;.. size should be 0
408 PUSH SI
409 MOV SI,OFFSET DG:PARSTR
410 MOV DX,OFFSET DG:BADSIZM
411 CALL DOTCOMBMES
412 POP SI
413 XOR AX,AX
414 MOV WORD PTR [SI.DIRESIZ],AX
415 MOV WORD PTR [SI.DIRESIZ+2],AX
416 CALL FIXENT ;Fix it
417DDSIZOK:
418 MOV DX,BX ;Next entry
419 MOV AH,DIR_SEARCH_NEXT
420 INT 21H
421
422ROOTDIR: ;Come here after .. failure also
423 OR AL,AL
424 JZ MOREDIR ;More to go
425 CMP WORD PTR [BP+6],0 ;Am I the root?
426 JZ DIRDONE ;Yes, no chdir
427 MOV DX,OFFSET DG:PARSTR
428 MOV AH,CHDIR ;Chdir to parent (..)
429 INT 21H
430 JNC DIRDONE ;Worked
431 CMP [NOISY],0
432 JZ DODDH
433 MOV SI,OFFSET DG:NUL
434 CALL PRINTCURRDIRERR
435 MOV DX,OFFSET DG:CDDDMES
436 CALL EPRINT
437DODDH:
438 CALL DOTDOTHARDWAY ;Try again
439DIRDONE:
440 MOV SP,BP ;Pop local vars
441 POP BP ;Restore frame
442 RET 4 ;Pop args
443
444MOREDIR:
445 MOV SI,OFFSET DG:DIRBUF
446 TEST [SI.DIRATT],ISDIR
447 JNZ NEWDIR ;Is a new directory
448 CMP [SECONDPASS],0
449 JZ FPROC1 ;First pass
450 CALL CROSSLOOK ;Check for cross links
451 JMP DDSIZOK ;Next
452FPROC1:
453 CMP [NOISY],0
454 JZ NOPRINT2
455 MOV DX,OFFSET DG:INDENT ;Tell user where we are
456 CALL PRINT
457 PUSH BX
458 MOV BX,SI
459 CALL PRINTTHISEL
460 CALL DOCRLF
461 MOV SI,BX
462 POP BX
463NOPRINT2:
464 MOV AL,81H ;Head of file
465 CALL MARKFAT
466 TEST [SI.DIRATT],VOLIDA
467 JNZ HIDENFILE ;VOL ID counts as hidden
468 TEST [SI.DIRATT],HIDDN
469 JZ NORMFILE
470HIDENFILE:
471 INC [HIDCNT]
472 ADD [HIDSIZ],CX
473 JMP DDSIZOK ;Next
474NORMFILE:
475 INC [FILCNT]
476 ADD [FILSIZ],CX
477 JMP DDSIZOK ;Next
478
479NEWDIR:
480 CMP [SECONDPASS],0
481 JZ DPROC1
482 CALL CROSSLOOK ;Check for cross links
483 JMP SHORT DPROC2
484DPROC1:
485 MOV AL,82H ;Head of dir
486 CALL MARKFAT
487 INC [DIRCNT]
488 ADD [DIRSIZ],CX
489 CMP [ZEROTRUNC],0
490 JZ DPROC2 ;Dir not truncated
491CONVDIR:
492 AND [SI.DIRATT],NOT ISDIR ;Turn into file
493 CALL FIXENT
494 JMP DDSIZOK ;Next
495DPROC2:
496 PUSH [ERRSUB]
497 PUSH BX ;Save my srch FCB pointer
498 PUSH [SI.DIRCLUS] ;MYSELF for next directory
499 PUSH [BP+6] ;His PARENT is me
500 ADD SI,DIRNAM
501 MOV DI,OFFSET DG:NAMBUF
502 PUSH DI
503 CALL FCB_TO_ASCZ
504 POP DX
505 MOV AH,CHDIR ;CHDIR to new dir
506 INT 21H
507 JC CANTTARG ;Barfed
508 CALL DIRPROC
509 POP BX ;Get my SRCH FCB pointer back
510 POP [ERRSUB]
511 CMP [DOTSNOGOOD],0
512 JNZ ASKCONV
513 JMP DDSIZOK ;Next
514
515CANTTARG:
516 POP AX ;Clean stack
517 POP AX
518 POP AX
519 POP AX
520 PUSH DX ;Save pointer to bad DIR
521 MOV DX,OFFSET DG:BADTARG1
522 CALL EPRINT
523 POP SI ;Pointer to bad DIR
524 CALL PRINTCURRDIRERR
525 MOV DX,OFFSET DG:BADTARG2
526 CALL EPRINT
527DDSIZOKJ: JMP DDSIZOK ;Next
528
529ASKCONV:
530 CMP [SECONDPASS],0
531 JNZ DDSIZOKJ ;Leave on second pass
532 MOV DX,OFFSET DG:PTRANDIR
533 CMP [NOISY],0
534 JNZ PRINTTRMES
535 MOV DX,OFFSET DG:PTRANDIR2
536PRINTTRMES:
537 CALL PROMPTYN ;Ask user what to do
538 JNZ DDSIZOKJ ;User say leave alone
539 PUSH BP
540 PUSH BX
541 MOV AX,[BX+THISENT] ;Entry number
542 CALL GETENT ;Get the entry
543 MOV SI,DI
544 MOV DI,OFFSET DG:DIRBUF
545 PUSH DI
546 ADD DI,DIRNAM
547 MOV CX,32
548 REP MOVSB ;Transfer entry to DIRBUF
549 POP SI
550 PUSH SI
551 MOV SI,[SI.DIRCLUS] ;First cluster
552 CALL GETFILSIZ
553 POP SI
554 POP BX
555 POP BP
556 MOV WORD PTR [SI.DIRESIZ],AX ;Fix entry
557 MOV WORD PTR [SI.DIRESIZ+2],DX
558 JMP CONVDIR
559
560SUBTTL FAT Look routines
561PAGE
562CROSSLOOK:
563;Same as MRKFAT only simpler for pass 2
564 MOV [SRFCBPT],BX
565 MOV BX,SI
566 MOV SI,[BX.DIRCLUS]
567 CALL CROSSCHK
568 JNZ CROSSLINKJ
569CHLP:
570 PUSH BX
571 CALL UNPACK
572 POP BX
573 XCHG SI,DI
574 CMP SI,0FF8H
575 JAE CHAINDONEJ
576 CALL CROSSCHK
577 JZ CHLP
578CROSSLINKJ: JMP SHORT CROSSLINK
579
580CROSSCHK:
581 MOV DI,[FATMAP]
582 ADD DI,SI
583 MOV AH,[DI]
584 TEST AH,10H
585 RET
586
587NOCLUSTERSJ: JMP NOCLUSTERS
588
589MARKFAT:
590; Map the file and perform checks
591; SI points to dir entry
592; AL is head mark with app type
593; On return CX is number of clusters
594; BX,SI preserved
595; ZEROTRUNC is non zero if the file was trimmed to zero length
596; ISCROSS is non zero if the file is cross linked
597
598 MOV [ZEROTRUNC],0 ;Initialize
599 MOV [ISCROSS],0
600 MOV [SRFCBPT],BX
601 MOV BX,SI
602 XOR CX,CX
603 MOV SI,[BX.DIRCLUS]
604 CMP SI,2
605 JB NOCLUSTERSJ ;Bad cluster # or nul file (SI = 0)
606 CMP SI,[MCLUS]
607 JA NOCLUSTERSJ ;Bad cluster #
608 PUSH BX
609 CALL UNPACK
610 POP BX
611 JZ NOCLUSTERSJ ;Bad cluster (it is marked free)
612 CALL MARKMAP
613 JNZ CROSSLINK
614 AND AL,7FH ;Turn off head bit
615CHASELOOP:
616 PUSH BX
617 CALL UNPACK
618 POP BX
619 INC CX
620 XCHG SI,DI
621 CMP SI,0FF8H
622 JAE CHAINDONE
623 CMP SI,2
624 JB MRKBAD
625 CMP SI,[MCLUS]
626 JBE MRKOK
627MRKBAD: ;Bad cluster # in chain
628 PUSH CX
629 PUSH DI
630 CALL PRINTTHISELERR
631 MOV DX,OFFSET DG:BADCHAIN
632 CALL EPRINT
633 POP SI
634 MOV DX,0FFFH ;Insert EOF
635 PUSH BX
636 CALL PACK
637 POP BX
638 POP CX
639CHAINDONEJ: JMP SHORT CHAINDONE
640
641MRKOK:
642 CALL MARKMAP
643 JZ CHASELOOP
644CROSSLINK: ;File is cross linked
645 INC [ISCROSS]
646 CMP [SECONDPASS],0
647 JZ CHAINDONE ;Crosslinks only on second pass
648 PUSH SI ;Cluster number
649 CALL PRINTTHISEL
650 CALL DOCRLF
651 MOV DX,OFFSET DG:CROSSMES_PRE
652 CALL PRINT
653 POP SI
654 PUSH BX
655 PUSH CX
656 MOV BX,OFFSET DG:CROSSMES_POST
657 XOR DI,DI
658 CALL DISP16BITS
659 POP CX
660 POP BX
661CHAINDONE:
662 TEST [BX.DIRATT],ISDIR
663 JNZ NOSIZE ;Don't size dirs
664 CMP [ISCROSS],0
665 JNZ NOSIZE ;Don't size cross linked files
666 CMP [SECONDPASS],0
667 JNZ NOSIZE ;Don't size on pass 2 (CX garbage)
668 MOV AL,[CSIZE]
669 XOR AH,AH
670 MUL [SSIZE]
671 PUSH AX ;Size in bytes of one alloc unit
672 MUL CX
673 MOV DI,DX ;Save allocation size
674 MOV SI,AX
675 SUB AX,WORD PTR [BX.DIRESIZ]
676 SBB DX,WORD PTR [BX.DIRESIZ+2]
677 JC BADFSIZ ;Size to big
678 OR DX,DX
679 JNZ BADFSIZ ;Size to small
680 POP DX
681 CMP AX,DX
682 JB NOSIZE ;Size within one Alloc unit
683 PUSH DX ;Size to small
684BADFSIZ:
685 POP DX
686 PUSH CX ;Save size of file
687 MOV WORD PTR [BX.DIRESIZ],SI
688 MOV WORD PTR [BX.DIRESIZ+2],DI
689 CALL FIXENT2 ;Fix it
690 CALL PRINTTHISELERR
691 MOV DX,OFFSET DG:BADCLUS
692 CALL EPRINT
693 POP CX ;Restore size of file
694NOSIZE:
695 MOV SI,BX
696 MOV BX,[SRFCBPT]
697 RET
698
699NOCLUSTERS:
700;File is zero length
701 OR SI,SI
702 JZ CHKSIZ ;Firclus is OK, Check size
703 MOV DX,OFFSET DG:NULNZ
704ADJUST:
705 PUSH DX
706 CALL PRINTTHISELERR
707 POP DX
708 CALL EPRINT
709 XOR SI,SI
710 MOV [BX.DIRCLUS],SI ;Set it to 0
711 MOV WORD PTR [BX.DIRESIZ],SI ;Set size too
712 MOV WORD PTR [BX.DIRESIZ+2],SI
713 CALL FIXENT2 ;Fix it
714 INC [ZEROTRUNC] ;Indicate truncation
715 JMP CHAINDONE
716
717CHKSIZ:
718 MOV DX,OFFSET DG:BADCLUS
719 CMP WORD PTR [BX.DIRESIZ],0
720 JNZ ADJUST ;Size wrong
721 CMP WORD PTR [BX.DIRESIZ+2],0
722 JNZ ADJUST ;Size wrong
723 JMP CHAINDONE ;Size OK
724
725UNPACK:
726;Cluster number in SI, Return contents in DI, BX destroyed
727;ZERO SET IF CLUSTER IS FREE
728 MOV BX,OFFSET DG:FAT
729 MOV DI,SI
730 SHR DI,1
731 ADD DI,SI
732 MOV DI,WORD PTR [DI+BX]
733 TEST SI,1
734 JZ HAVCLUS
735 SHR DI,1
736 SHR DI,1
737 SHR DI,1
738 SHR DI,1
739HAVCLUS:
740 AND DI,0FFFH
741 RET
742
743PACK:
744; SI CLUSTER NUMBER TO BE PACKED
745; DX DATA TO BE PLACED IN CLUSTER (SI)
746; BX,DX DESTROYED
747 MOV [DIRTYFAT],1 ;Set FAT dirty byte
748 MOV [HAVFIX],1 ;Indicate a fix
749 MOV BX,OFFSET DG:FAT
750 PUSH SI
751 MOV DI,SI
752 SHR SI,1
753 ADD SI,BX
754 ADD SI,DI
755 SHR DI,1
756 MOV DI,[SI]
757 JNC ALIGNED
758 SHL DX,1
759 SHL DX,1
760 SHL DX,1
761 SHL DX,1
762 AND DI,0FH
763 JMP SHORT PACKIN
764ALIGNED:
765 AND DI,0F000H
766PACKIN:
767 OR DI,DX
768 MOV [SI],DI
769 POP SI
770 RET
771
772
773
774MARKMAP:
775; Mark in AL
776; Cluster in SI
777; AL,SI,CX preserved
778; ZERO RESET IF CROSSLINK, AH IS THE MARK THAT WAS THERE
779 MOV DI,[FATMAP]
780 ADD DI,SI
781 MOV AH,[DI]
782 OR AH,AH
783 PUSH AX
784 JZ SETMARK
785 MOV AL,AH
786 INC [CROSSCNT] ;Count the crosslink
787 OR AL,10H ;Resets zero
788SETMARK:
789 MOV [DI],AL
790 POP AX
791 RET
792
793
794CHKMAP:
795;Compare FAT and FATMAP looking for badsectors orphans
796 MOV SI,[FATMAP]
797 INC SI
798 INC SI
799 MOV DX,2
800 MOV CX,[DSIZE]
801CHKMAPLP:
802 LODSB
803 OR AL,AL
804 JNZ CONTLP ;Already seen this one
805 XCHG SI,DX
806 CALL UNPACK
807 XCHG SI,DX
808 JZ CONTLP ;Free cluster
809 CMP DI,0FF7H ;Bad sector?
810 JNZ ORPHAN ;No, found an orphan
811 INC [BADSIZ]
812 MOV BYTE PTR [SI-1],4 ;Flag it
813 JMP CONTLP
814ORPHAN:
815 INC [ORPHSIZ]
816 MOV BYTE PTR [SI-1],8 ;Flag it
817CONTLP:
818 INC DX ;Next cluster
819 LOOP CHKMAPLP
820 MOV SI,[ORPHSIZ]
821 OR SI,SI
822 JZ RET18 ;No orphans
823 CALL RECOVER
824RET18: RET
825
826RECOVER:
827;free orphans or do chain recovery
828 CALL CHECKNOFMES
829 CALL DOCRLF
830 CALL CHAINREPORT
831 MOV DX,OFFSET DG:FREEMES
832 CALL PROMPTYN ;Ask user
833 JNZ NOCHAINREC
834 JMP CHAINREC
835NOCHAINREC:
836 MOV SI,[FATMAP] ;Free all orphans
837 INC SI
838 INC SI
839 MOV DX,2
840 MOV CX,[DSIZE]
841CHKMAPLP2:
842 LODSB
843 TEST AL,8
844 JZ NEXTCLUS
845 XCHG SI,DX
846 PUSH DX
847 XOR DX,DX
848 CALL PACK ;Mark as free
849 POP DX
850 XCHG SI,DX
851NEXTCLUS:
852 INC DX
853 LOOP CHKMAPLP2
854 XOR AX,AX
855 XCHG AX,[ORPHSIZ]
856 PUSH AX
857 MOV DX,OFFSET DG:FREEBYMESF_PRE
858 CMP [DOFIX],0
859 JNZ PRINTFMES
860 MOV DX,OFFSET DG:FREEBYMES_PRE
861PRINTFMES:
862 CALL PRINT
863 POP AX
864 MOV BX,OFFSET DG:FREEBYMESF_POST
865 CMP [DOFIX],0
866 JNZ DISPFRB
867 MOV BX,OFFSET DG:FREEBYMES_POST
868 MOV [LCLUS],AX
869DISPFRB:
870 CALL DISPCLUS ;Tell how much freed
871 RET
872
873FINDCHAIN:
874;Do chain recovery on orphans
875 MOV SI,[FATMAP]
876 INC SI
877 INC SI
878 MOV DX,2
879 MOV CX,[DSIZE]
880CHKMAPLP3:
881 LODSB
882 TEST AL,8 ;Orphan?
883 JZ NEXTCLUS2 ;Nope
884 TEST AL,1 ;Seen before ?
885 JNZ NEXTCLUS2 ;Yup
886 PUSH SI ;Save search environment
887 PUSH CX
888 PUSH DX
889 DEC SI
890 OR BYTE PTR [SI],81H ;Mark as seen and head
891 INC [ORPHCNT] ;Found a chain
892 MOV SI,DX
893CHAINLP:
894 CALL UNPACK
895 XCHG SI,DI
896 CMP SI,0FF8H
897 JAE CHGOON ;EOF
898 PUSH DI
899 CMP SI,2
900 JB INSERTEOF ;Bad cluster number
901 CMP SI,[MCLUS]
902 JA INSERTEOF ;Bad cluster number
903 CMP SI,DI
904 JZ INSERTEOF ;Tight loop
905 CALL CROSSCHK
906 TEST AH,8 ;Points to a non-orphan?
907 JNZ CHKCHHEAD ;Nope
908INSERTEOF:
909 POP SI ;Need to stick EOF here
910 MOV DX,0FFFH
911 CALL PACK
912 JMP SHORT CHGOON
913CHKCHHEAD:
914 TEST AH,80H ;Previosly marked head?
915 JZ ADDCHAIN ;Nope
916 AND BYTE PTR [DI],NOT 80H ;Turn off head bit
917 DEC [ORPHCNT] ;Wasn't really a head
918 POP DI ;Clean stack
919 JMP SHORT CHGOON
920ADDCHAIN:
921 TEST AH,1 ;Previosly seen?
922 JNZ INSERTEOF ;Yup, don't make a cross link
923 OR BYTE PTR [DI],1 ;Mark as seen
924 POP DI ;Clean stack
925 JMP CHAINLP ;Follow chain
926
927CHGOON:
928 POP DX ;Restore search
929 POP CX
930 POP SI
931NEXTCLUS2:
932 INC DX
933 LOOP CHKMAPLP3
934 RET
935
936CHAINREC:
937 LDS DI,[THISDPB]
938ASSUME DS:NOTHING
939 MOV CX,[DI.dpb_root_entries]
940 PUSH CS
941 POP DS
942ASSUME DS:DG
943 MOV SI,[FATMAP]
944 INC SI
945 INC SI
946 MOV DI,1
947 CALL NEXTORPH
948 PUSH SI
949 PUSH DI
950 MOV SI,DI
951 XOR AX,AX
952 MOV DX,[ORPHCNT]
953MAKFILLP:
954 PUSH AX
955 PUSH CX
956 PUSH DX
957 PUSH SI
958 CALL GETENT
959 POP SI
960 CMP BYTE PTR [DI],0E5H
961 JZ GOTENT
962 CMP BYTE PTR [DI],0
963 JNZ NEXTENT
964GOTENT:
965 MOV [HAVFIX],1 ;Making a fix
966 CMP [DOFIX],0
967 JZ ENTMADE ;Not supposed to, carry clear
968 MOV [DI+26],SI ;FIRCLUS Pointer
969 PUSH AX ;Save INT 26 data
970 PUSH DX
971 PUSH BX
972 MOV AH,DISK_RESET ;Force current state
973 INT 21H
974 MOV DX,OFFSET DG:ORPHFCB
975 MOV AH,FCB_OPEN
976OPAGAIN:
977 INT 21H
978 OR AL,AL
979 JNZ GOTORPHNAM
980 CALL MAKORPHNAM ;Try next name
981 JMP SHORT OPAGAIN
982
983GOTORPHNAM:
984 MOV SI,OFFSET DG:ORPHFCB + 1 ;ORPHFCB Now has good name
985 MOV CX,11
986 REP MOVSB
987 CALL MAKORPHNAM ;Make next name
988 XOR AX,AX
989 MOV CX,15
990 REP STOSB
991 MOV SI,[DI]
992 INC DI ;Skip FIRCLUS
993 INC DI
994 PUSH DI
995 CALL GETFILSIZ
996 POP DI
997 STOSW
998 MOV AX,DX
999 STOSW
1000 POP BX
1001 POP DX
1002 POP AX
1003 MOV CX,1
1004 CALL DOINT26
1005ENTMADE:
1006 POP DX
1007 POP CX
1008 POP AX
1009 POP DI
1010 POP SI
1011 DEC DX
1012 OR DX,DX
1013 JZ RET100
1014 CALL NEXTORPH
1015 PUSH SI
1016 PUSH DI
1017 MOV SI,DI
1018 JMP SHORT NXTORP
1019
1020NEXTENT:
1021 POP DX
1022 POP CX
1023 POP AX
1024NXTORP:
1025 INC AX
1026 LOOP MAKFILLPJ
1027 POP AX ;Clean Stack
1028 POP AX
1029 SUB [ORPHCNT],DX ;Couldn't make them all
1030 MOV DX,OFFSET DG:CREATMES
1031 CALL EPRINT
1032RET100: RET
1033
1034MAKFILLPJ: JMP MAKFILLP
1035
1036NEXTORPH:
1037 PUSH AX
1038 LODSB
1039 INC DI
1040 CMP AL,89H
1041 POP AX
1042 JZ RET100
1043 JMP SHORT NEXTORPH
1044
1045MAKORPHNAM:
1046 PUSH SI
1047 MOV SI,OFFSET DG:ORPHEXT - 1
1048NAM0:
1049 INC BYTE PTR [SI]
1050 CMP BYTE PTR [SI],'9'
1051 JLE NAMMADE
1052 MOV BYTE PTR [SI],'0'
1053 DEC SI
1054 JMP NAM0
1055
1056NAMMADE:
1057 POP SI
1058 RET
1059
1060GETFILSIZ:
1061;SI is start cluster, returns filesize as DX:AX
1062 XOR AX,AX
1063NCLUS:
1064 CALL UNPACK
1065 XCHG SI,DI
1066 INC AX
1067 CMP SI,0FF8H
1068 JAE GOTEOF
1069 CMP SI,2
1070 JAE NCLUS
1071GOTEOF:
1072 MOV BL,[CSIZE]
1073 XOR BH,BH
1074 MUL BX
1075 MUL [SSIZE]
1076 RET
1077
1078
1079
1080CHKCROSS:
1081;Check for Crosslinks, do second pass if any to find pairs
1082 MOV SI,[CROSSCNT]
1083 OR SI,SI
1084 JZ RET8 ;None
1085 CALL DOCRLF
1086 INC [SECONDPASS]
1087 XOR AX,AX
1088 PUSH AX
1089 PUSH AX
1090 CALL DIRPROC ;Do it again
1091RET8: RET
1092
1093SUBTTL AMDONE - Finish up routine
1094PAGE
1095AMDONE:
1096ASSUME DS:NOTHING
1097 CMP [DIRTYFAT],0
1098 JZ NOWRITE ;FAT not dirty
1099 CMP [DOFIX],0
1100 JZ NOWRITE ;Not supposed to fix
1101REWRITE:
1102 LDS BX,[THISDPB]
1103ASSUME DS:NOTHING
1104 MOV CL,[BX.dpb_FAT_size] ;Sectors for one fat
1105 XOR CH,CH
1106 MOV DI,CX
1107 MOV CL,[BX.dpb_FAT_count] ;Number of FATs
1108 MOV DX,[BX.dpb_first_FAT] ;First sector of FAT
1109 PUSH CS
1110 POP DS
1111ASSUME DS:DG
1112 MOV [ERRCNT],CH
1113 MOV BX,OFFSET DG:FAT
1114 MOV AL,[ALLDRV]
1115 DEC AL
1116 MOV AH,'1'
1117 PUSH CX
1118WRTLOOP:
1119 XCHG CX,DI
1120 PUSH DX
1121 PUSH CX
1122 PUSH DI
1123 PUSH AX
1124 INT 26H ;Write out the FAT
1125 MOV [HECODE],AL
1126 POP AX ;Flags
1127 JNC WRTOK
1128 INC [ERRCNT]
1129 MOV DX,OFFSET DG:BADWRITE_PRE
1130 CALL PRINT
1131 POP AX
1132 PUSH AX
1133 MOV DL,AH
1134 CALL PRTCHR
1135 MOV DX,OFFSET DG:BADWRITE_POST
1136 CALL PRINT
1137WRTOK:
1138 POP AX
1139 POP CX
1140 POP DI
1141 POP DX
1142 INC AH
1143 ADD DX,DI
1144 LOOP WRTLOOP ;Next FAT
1145 POP CX ;Number of FATs
1146 CMP CL,[ERRCNT] ;Error on all?
1147 JNZ NOWRITE ;no
1148 CALL WDSKERR
1149 JZ REWRITE
1150NOWRITE:
1151 MOV AH,DISK_RESET ;Invalidate any buffers in system
1152 INT 21H
1153 MOV DX,OFFSET DG:USERDIR ;Recover users directory
1154 MOV AH,CHDIR
1155 INT 21H
1156 CMP BYTE PTR [FRAGMENT],1 ;Check for any fragmented files?
1157 JNZ DONE ;No -- we're finished
1158 CALL CHECKFILES ;Yes -- report any fragments
1159DONE:
1160ASSUME DS:NOTHING
1161 MOV DL,[USERDEV] ;Recover users drive
1162 MOV AH,SET_DEFAULT_DRIVE
1163 INT 21H
1164 RET
1165
1166SUBTTL Routines for manipulating dir entries
1167PAGE
1168FIXENT2:
1169;Same as FIXENT only [SRFCBPT] points to the search FCB, BX points to the entry
1170 PUSH SI
1171 PUSH BX
1172 PUSH CX
1173 MOV SI,BX
1174 MOV BX,[SRFCBPT]
1175 CALL FIXENT
1176 POP CX
1177 POP BX
1178 POP SI
1179RET20: RET
1180
1181FIXENT:
1182;BX Points to search FCB
1183;SI Points to Entry to fix
1184 MOV [HAVFIX],1 ;Indicate a fix
1185 CMP [DOFIX],0
1186 JZ RET20 ;But don't do it!
1187 PUSH BP
1188 PUSH BX
1189 PUSH SI
1190 PUSH SI ;Entry pointer
1191 MOV AX,[BX+THISENT] ;Entry number
1192 CALL GETENT
1193 POP SI ;Entry pointer
1194 ADD SI,DIRNAM ;Point to start of entry
1195 MOV CX,32
1196 REP MOVSB
1197 INC CL
1198 CALL DOINT26
1199 POP SI
1200 POP BX
1201 POP BP
1202 RET
1203
1204GETENT:
1205;AX is desired entry number (in current directory)
1206;
1207;DI points to entry in SECBUF
1208;AX DX BX set to do an INT 26 to write it back out (CX must be reset to 1)
1209;ALL registers destroyed (via int 25)
1210 LDS DI,[THISDPB]
1211ASSUME DS:NOTHING
1212 MOV BX,[DI.dpb_current_dir]
1213 PUSH CS
1214 POP DS
1215ASSUME DS:DG
1216 CMP BX,0FF8H
1217 JB CLUSISOK
1218 MOV BX,OFFSET DG:BADDPBDIR ;This should never happen
1219 JMP FATAL
1220CLUSISOK:
1221 MOV CL,4
1222 SHL AX,CL
1223 XOR DX,DX
1224 SHL AX,1
1225 RCL DX,1 ;Account for overflow
1226 MOV CX,[SSIZE]
1227 AND CL,255-31 ;Must be a multiple of 32
1228 DIV CX ;DX is position in sector, AX is dir sector #
1229 OR BX,BX
1230 JZ WANTROOT
1231 DIV [CSIZE] ;AL # clusters to skip, AH position in cluster
1232 MOV CL,AL
1233 XOR CH,CH
1234 JCXZ GOTCLUS
1235 MOV SI,BX
1236SKIPLP:
1237 CALL UNPACK
1238 XCHG SI,DI
1239 LOOP SKIPLP
1240 MOV BX,SI
1241GOTCLUS:
1242 PUSH DX ;Position in sector
1243 CALL FIGREC ;Convert to sector #
1244DOROOTDIR:
1245 MOV BX,[SECBUF]
1246 MOV AL,[ALLDRV]
1247 DEC AL
1248RDRETRY:
1249 PUSH AX
1250 PUSH DX
1251 PUSH BX
1252 MOV CX,1
1253 INT 25H ;Read it
1254 MOV [HECODE],AL
1255 POP AX ;FLAGS
1256 POP BX
1257 POP DX
1258 POP AX
1259 JNC RDOK2
1260 CALL RDSKERR
1261 JZ RDRETRY
1262RDOK2:
1263 POP DI ;Offset into sector
1264 ADD DI,BX ;Add sector base offset
1265 RET
1266
1267WANTROOT:
1268 PUSH DX
1269 LDS DI,[THISDPB]
1270ASSUME DS:NOTHING
1271 MOV DX,AX
1272 ADD DX,[DI.dpb_dir_sector]
1273 PUSH CS
1274 POP DS
1275ASSUME DS:DG
1276 JMP DOROOTDIR
1277
1278CHECKNOFMES:
1279 MOV AL,1
1280 XCHG AL,[FIXMFLG]
1281 OR AL,AL
1282 JNZ RET14 ;Don't print it more than once
1283 CMP [DOFIX],0
1284 JNZ RET14 ;Don't print it if F switch specified
1285 PUSH DX
1286 MOV DX,OFFSET DG:FIXMES
1287 CALL PRINT
1288 POP DX
1289 RET
1290
1291CHECKERR:
1292 CALL CHECKNOFMES
1293 CMP [SECONDPASS],0
1294RET14: RET
1295
1296PRINTCURRDIRERR:
1297 CALL CHECKERR
1298 JNZ RET14
1299 CALL PRINTCURRDIR
1300 JMP SHORT ERREX
1301
1302PRINTTHISELERR:
1303 CALL CHECKERR
1304 JNZ RET14
1305 CALL PRINTTHISEL
1306ERREX:
1307 CALL DOCRLF
1308 RET
1309
1310PRINTTHISEL:
1311 MOV SI,BX
1312 ADD SI,DIRNAM
1313PRINTTHISEL2:
1314 MOV DI,OFFSET DG:NAMBUF
1315 PUSH DI
1316 CALL FCB_TO_ASCZ
1317 POP SI
1318PRINTCURRDIR:
1319 PUSH SI
1320 MOV DL,[ALLDRV]
1321 ADD DL,'@'
1322 CALL PRTCHR
1323 MOV DL,DRVCHAR
1324 CALL PRTCHR
1325 LDS SI,[THISDPB]
1326ASSUME DS:NOTHING
1327 CMP [SI.dpb_current_dir],0
1328 JZ CURISROOT
1329 MOV DL,[DIRCHAR]
1330 CALL PRTCHR
1331 ADD SI,dpb_dir_text
1332PCURRLP:
1333 LODSB
1334 OR AL,AL
1335 JZ CURISROOT
1336 MOV DL,AL
1337 CALL PRTCHR
1338 JMP PCURRLP
1339
1340CURISROOT:
1341 PUSH CS
1342 POP DS
1343ASSUME DS:DG
1344 POP SI
1345 CMP BYTE PTR [SI],0
1346 JZ LPDONE ;If tail string NUL, no '/'
1347 MOV DL,[DIRCHAR]
1348 CALL PRTCHR
1349ERRLOOP:
1350 LODSB
1351 OR AL,AL
1352 JZ LPDONE
1353 MOV DL,AL
1354 CALL PRTCHR
1355 JMP ERRLOOP
1356LPDONE:
1357 RET
1358
1359FATAL:
1360;Unrecoverable error
1361 MOV DX,OFFSET DG:FATALMES
1362 CALL PRINT
1363 MOV DX,BX
1364 CALL PRINT
1365 MOV DL,[USERDEV] ;At least leave on same drive
1366 MOV AH,SET_DEFAULT_DRIVE
1367 INT 21H
1368 INT 20H
1369
1370
1371INT_24_RETADDR DW OFFSET DG:INT_24_BACK
1372
1373INT_24 PROC FAR
1374ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
1375 PUSHF
1376 PUSH CS
1377 PUSH [INT_24_RETADDR]
1378 PUSH WORD PTR [HARDCH+2]
1379 PUSH WORD PTR [HARDCH]
1380 RET
1381INT_24 ENDP
1382
1383INT_24_BACK:
1384 CMP AL,2 ;Abort?
1385 JNZ IRETI
1386 CALL DONE ;Forget about directory, restore users drive
1387 INT 20H
1388IRETI:
1389 IRET
1390
1391INT_23:
1392 LDS DX,[HARDCH]
1393 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H
1394 INT 21H
1395 LDS DX,[CONTCH]
1396 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
1397 INT 21H
1398 PUSH CS
1399 POP DS
1400ASSUME DS:DG
1401 MOV [FRAGMENT],0
1402RDONE:
1403 CALL NOWRITE ;Restore users drive and directory
1404 INT 20H
1405
1406CODE ENDS
1407 END CHKPROC
1408
diff --git a/v2.0/source/COMEQU.ASM b/v2.0/source/COMEQU.ASM
new file mode 100644
index 0000000..81763fb
--- /dev/null
+++ b/v2.0/source/COMEQU.ASM
@@ -0,0 +1,33 @@
1;*************************************
2; COMMAND EQUs which are not switch dependant
3
4IFDEF IBM
5 INCLUDE IFEQU.ASM
6ENDIF
7
8
9SYM EQU ">"
10
11LINPERPAG EQU 23
12NORMPERLIN EQU 1
13WIDEPERLIN EQU 5
14COMBUFLEN EQU 128 ; Length of commmand buffer
15
16DRVCHAR EQU ":"
17
18FCB EQU 5CH
19
20VARSTRUC STRUC
21ISDIR DB ?
22SIZ DB ?
23TTAIL DW ?
24INFO DB ?
25BUF DB DIRSTRLEN + 20 DUP (?)
26VARSTRUC ENDS
27
28WSWITCH EQU 1 ; Wide display during DIR
29PSWITCH EQU 2 ; Pause (or Page) mode during DIR
30ASWITCH EQU 4 ; ASCII mode during COPY
31BSWITCH EQU 8 ; Binary mode during COPY
32VSWITCH EQU 10H ; Verify switch
33GOTSWITCH EQU 8000H ; Meta switch set if switch character encountered
diff --git a/v2.0/source/COMLINK b/v2.0/source/COMLINK
new file mode 100644
index 0000000..f7dd961
--- /dev/null
+++ b/v2.0/source/COMLINK
Binary files differ
diff --git a/v2.0/source/COMMAND.ASM b/v2.0/source/COMMAND.ASM
new file mode 100644
index 0000000..db2783a
--- /dev/null
+++ b/v2.0/source/COMMAND.ASM
@@ -0,0 +1,788 @@
1;
2; This version of COMMAND is divided into three distinct parts. First is the
3; resident portion, which includes handlers for interrupts 22H (terminate),
4; 23H (Cntrl-C), 24H (fatal error), and 27H (stay resident); it also has code
5; to test and, if necessary, reload the transient portion. Following the
6; resident is the init code, which is overwritten after use. Then comes the
7; transient portion, which includes all command processing (whether internal
8; or external). The transient portion loads at the end of physical memory,
9; and it may be overlayed by programs that need as much memory as possible.
10; When the resident portion of command regains control from a user program, a
11; checksum is performed on the transient portion to see if it must be
12; reloaded. Thus programs which do not need maximum memory will save the time
13; required to reload COMMAND when they terminate.
14
15;
16; REV 1.17
17; 05/19/82 Fixed bug in BADEXE error (relocation error must return to
18; resident since the EXELOAD may have overwritten the transient.
19; REV 1.18
20; 05/21/82 IBM version always looks on drive A
21; MSVER always looks on default drive
22;
23; REV 1.19
24; 06/03/82 Drive spec now entered in command line
25; 06/07/82 Added VER command (print DOS version number) and VOL command
26; (print volume label)
27; REV 1.20
28; 06/09/82 Prints "directory" after directories
29; 06/13/82 MKDIR, CHDIR, PWD, RMDIR added
30; REV 1.50
31; Some code for new 2.0 DOS, sort of HACKey. Not enough time to
32; do it right.
33; REV 1.70
34; EXEC used to fork off new processes
35; REV 1.80
36; C switch for single command execution
37; REV 1.90
38; Batch uses XENIX
39; Rev 2.00
40; Lots of neato stuff
41; IBM 2.00 level
42; Rev 2.01
43; 'D' switch for date time suppression
44; Rev 2.02
45; Default userpath is NUL rather than BIN
46; same as IBM
47; COMMAND split into pieces
48; Rev 2.10
49; INTERNATIONAL SUPPORT
50; Rev 2.11 COMMAND split into more pieces
51
52 INCLUDE DOSSYM.ASM
53 INCLUDE DEVSYM.ASM
54 INCLUDE COMSW.ASM
55 INCLUDE COMEQU.ASM
56
57CODERES SEGMENT PUBLIC
58CODERES ENDS
59
60DATARES SEGMENT PUBLIC BYTE
61 EXTRN COMBAD:BYTE,NEEDCOM:BYTE,DRVMSG:BYTE
62 EXTRN DEFMSG:BYTE,PROMPT:BYTE,EXECEMES:BYTE,EXEBAD:BYTE
63 EXTRN TOOBIG:BYTE,NOCOM:BYTE,RBADNAM:BYTE,INT_2E_RET:DWORD
64 EXTRN NOHANDMES:BYTE,BMEMMES:BYTE,HALTMES:BYTE,FRETMES:BYTE
65 EXTRN PARENT:WORD,HANDLE01:WORD,LOADING:BYTE,BATCH:WORD
66 EXTRN TRNSEG:WORD,COMDRV:BYTE,MEMSIZ:WORD,SUM:WORD,EXTCOM:BYTE
67 EXTRN IO_SAVE:WORD,PERMCOM:BYTE,SINGLECOM:WORD,VERVAL:WORD
68 EXTRN PIPEFLAG:BYTE,SAVE_PDB:WORD,COMSPEC:BYTE,TRANS:WORD
69 EXTRN TRANVARS:BYTE,LTPA:WORD,RSWITCHAR:BYTE,RDIRCHAR:BYTE
70 EXTRN RETCODE:WORD,FORFLAG:BYTE
71
72 IF IBMVER
73 EXTRN SYS_CALL:DWORD,ZEXEC:WORD,EXESEG:WORD,EXESUM:WORD
74 EXTRN USER_SS:WORD,USER_SP:WORD
75 ENDIF
76
77DATARES ENDS
78
79ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
80ENVIRONMENT ENDS
81
82INIT SEGMENT PUBLIC PARA
83 EXTRN CONPROC:NEAR
84INIT ENDS
85
86TAIL SEGMENT PUBLIC PARA
87TAIL ENDS
88
89TRANCODE SEGMENT PUBLIC PARA
90TRANCODE ENDS
91
92TRANDATA SEGMENT PUBLIC BYTE
93 EXTRN TRANDATAEND:BYTE
94TRANDATA ENDS
95
96TRANSPACE SEGMENT PUBLIC BYTE
97 EXTRN TRANSPACEEND:BYTE,HEADCALL:DWORD
98TRANSPACE ENDS
99
100TRANTAIL SEGMENT PUBLIC PARA
101TRANTAIL ENDS
102
103ZEXEC_CODE SEGMENT PUBLIC PARA
104ZEXEC_CODE ENDS
105
106ZEXEC_DATA SEGMENT PUBLIC BYTE
107ZEXEC_DATA ENDS
108
109RESGROUP GROUP CODERES,DATARES,ENVIRONMENT,INIT,TAIL
110TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
111EGROUP GROUP ZEXEC_CODE,ZEXEC_DATA
112
113ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
114
115 PUBLIC ECOMSPEC,ENVIREND,PATHSTRING
116
117 ORG 0
118ENVARENA DB 10H DUP (?) ; Pad for mem arena
119PATHSTRING DB "PATH="
120USERPATH LABEL BYTE
121
122 DB 0 ; Null path
123 DB "COMSPEC="
124ECOMSPEC DB "/COMMAND.COM"
125 DB 134 DUP (0)
126
127ENVIREND LABEL BYTE
128
129ENVIRONSIZ EQU $-PATHSTRING
130ENVIRONSIZ2 EQU $-ECOMSPEC
131ENVIRONMENT ENDS
132
133
134; START OF RESIDENT PORTION
135
136CODERES SEGMENT PUBLIC
137
138 PUBLIC GETCOMDSK2,LODCOM,THEADFIX,CONTCTERM,LOADCOM,INT_2E,LODCOM1
139 PUBLIC CHKSUM,SETVECT,EXT_EXEC,TREMCHECK,RESTHAND,CONTC,RSTACK
140 PUBLIC SAVHAND
141
142 IF IBMVER
143 PUBLIC EXECHK,SYSCALL,EXEC_WAIT
144 ENDIF
145
146ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
147
148 EXTRN RPRINT:NEAR,ASKEND:NEAR,DSKERR:NEAR
149
150
151 ORG 0
152ZERO = $
153
154 ORG 100H
155
156PROGSTART:
157 JMP RESGROUP:CONPROC
158
159 DB (80H - 3) DUP (?)
160RSTACK LABEL WORD
161
162IF IBMVER
163SYSCALL:
164 CMP AH,EXEC
165 JZ do_exec
166 JMP DWORD PTR [SYS_CALL]
167
168do_exec:
169 PUSH ES
170 PUSH DS
171 PUSH BP
172 PUSH DI
173 PUSH SI
174 PUSH DX
175 PUSH CX
176 PUSH BX
177 PUSH AX
178 MOV [user_ss],SS
179 MOV [user_sp],SP
180;
181; are we running on RSTACK already?
182;
183 PUSH CS
184 POP BX ; BX <- CS
185 PUSH SS
186 POP AX ; AX <- SS
187 CMP AX,BX ; IF AX == BX then no stack switch!
188 JZ Get_mem
189 MOV SS,BX
190ASSUME SS:RESGROUP
191 MOV SP,OFFSET RESGROUP:RSTACK
192
193Get_mem:
194 MOV BX,0FFFFH ; allocate all of memory
195 MOV AH,ALLOC
196 INT int_command
197 MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15
198 MOV CL,4
199 SHR AX,CL
200 MOV CX,AX ; Save in CX
201 CMP BX,AX ; enough for EXEC?
202 JB EXECMER ; nope... cry
203 MOV AH,ALLOC
204 INT int_command
205 JC EXECMER ; Memory arenas probably trashed
206 ADD BX,AX
207 MOV [MEMSIZ],BX
208 SUB BX,CX
209 MOV [EXESEG],BX ; exec
210 MOV ES,AX
211 MOV AH,DEALLOC
212 INT int_command
213 PUSH CS
214 POP DS
215ASSUME DS:RESGROUP
216 CALL EXECHK
217 CMP DX,[EXESUM]
218 JZ HAVEXEC ; EXEC OK
219 MOV DX,OFFSET RESGROUP:COMSPEC
220 MOV AX,OPEN SHL 8
221 INT int_command ; Open COMMAND.COM
222 JC EXECMER
223 MOV BX,AX ; Handle
224 MOV DX,OFFSET RESGROUP:TRANSTART
225 ADD DX,OFFSET TRANGROUP:EXECSTART - 100H
226 XOR CX,CX ; Seek loc
227 MOV AX,LSEEK SHL 8
228 INT int_command
229 MOV CX,OFFSET EGROUP:ZEXECCODEEND
230 MOV DS,[EXESEG]
231ASSUME DS:NOTHING
232 MOV AH,READ
233 INT int_command
234 PUSH AX
235 MOV AH,CLOSE
236 INT int_command ; Close COMMAND.COM
237 POP CX
238 CMP CX,OFFSET EGROUP:ZEXECCODEEND
239 JNZ EXECMER ; Size matched
240
241 CALL EXECHK
242 CMP DX,[EXESUM]
243 JNZ EXECMER
244HAVEXEC:
245 MOV [LOADING],0 ; Flag to DSKERR
246 CALL DWORD PTR [ZEXEC]
247 JMP SHORT EXECRET
248execmer:
249 LDS SI,DWORD PTR [user_Sp]
250 MOV [SI.user_AX],exec_not_enough_memory
251 PUSH [SI.user_F]
252 POPF
253 STC
254 PUSHF
255 POP [SI.user_F]
256execret:
257 MOV SS,[user_SS]
258ASSUME SS:NOTHING
259 MOV SP,[user_SP]
260 POP AX ; PUSH ES
261 POP BX ; PUSH DS
262 POP CX ; PUSH BP
263 POP DX ; PUSH DI
264 POP SI ; PUSH SI
265 POP DI ; PUSH DX
266 POP BP ; PUSH CX
267 POP DS ; PUSH BX
268 POP ES ; PUSH AX
269 IRET
270
271EXECHK:
272ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
273 PUSH DS
274 MOV DS,[EXESEG]
275 MOV CX,OFFSET EGROUP:ZEXECCODEEND
276 XOR SI,SI
277 JMP CHECK_SUM
278ENDIF
279
280EXEC_ERR: ; Select the correct error message
281 MOV DX,OFFSET RESGROUP:RBADNAM
282 CMP AX,exec_file_not_found
283 JZ GOTEXECEMES
284 CMP AX,error_access_denied
285 JZ GOTEXECEMES
286 MOV DX,OFFSET RESGROUP:TOOBIG
287 CMP AX,exec_not_enough_memory
288 JZ GOTEXECEMES
289 MOV DX,OFFSET RESGROUP:EXEBAD
290 CMP AX,exec_bad_format
291 JZ GOTEXECEMES
292 MOV DX,OFFSET RESGROUP:EXECEMES
293GOTEXECEMES:
294 PUSH CS
295 POP DS
296 CALL RPRINT
297 JMP SHORT NOEXEC
298
299EXT_EXEC:
300;
301; we are now running in free space. anything we do from here
302; on may get trashed. Move the stack (also in free space) to
303; allocated space because since EXEC restores the stack,
304; somebody may trash what is on the stack.
305;
306 MOV CX,CS
307 MOV SS,CX
308 MOV SP,OFFSET RESGROUP:RSTACK
309;
310; Oops!! We have to make sure that the EXEC code doesn't blop a newstack!
311;
312;
313 INT int_command ; Do the EXEC
314 JC EXEC_ERR ; EXEC failed
315EXEC_WAIT:
316 MOV AH,WAIT
317 INT int_command ; Get the return code
318 MOV [RETCODE],AX
319NOEXEC:
320 JMP LODCOM
321
322CONTC:
323 STI
324 MOV AX,CS
325 MOV DS,AX
326ASSUME DS:RESGROUP
327 MOV AH,DISK_RESET
328 INT int_command ; Reset disks in case files were open
329 TEST [BATCH],-1
330 JZ CONTCTERM
331 JMP ASKEND ; See if user wants to terminate batch
332CONTCTERM:
333 XOR BP,BP ; Indicate no read
334 MOV [FORFLAG],0 ; Turn off for processing
335 MOV [PIPEFLAG],0 ; Turn off any pipe
336 CMP [SINGLECOM],0 ; See if we need to set SINGLECOM
337 JZ NOSETSING
338 MOV [SINGLECOM],-1 ; Cause termination on pipe, batch, for
339NOSETSING:
340 CMP [EXTCOM],0
341 JNZ DODAB ; Internal ^C
342 JMP LODCOM1
343DODAB:
344 STC ; Tell DOS to abort
345ZZY PROC FAR
346 RET ; Leave flags on stack
347ZZY ENDP
348
349BADMEMERR: ; Allocation error loading transient
350 MOV DX,OFFSET RESGROUP:BMEMMES
351FATALC:
352 PUSH CS
353 POP DS
354 CALL RPRINT
355 CMP [PERMCOM],0
356 JZ FATALRET
357 CMP [SINGLECOM],0 ; If PERMCOM and SINGLECOM
358 JNZ FATALRET ; Must take INT_2E exit
359 MOV DX,OFFSET RESGROUP:HALTMES
360 CALL RPRINT
361STALL:
362 JMP STALL ; Crash the system nicely
363
364FATALRET:
365 MOV DX,OFFSET RESGROUP:FRETMES
366 CALL RPRINT
367FATALRET2:
368 CMP [PERMCOM],0 ; If we get here and PERMCOM,
369 JNZ RET_2E ; must be INT_2E
370IF IBM
371 LDS DX,DWORD PTR [SYS_CALL]
372ASSUME DS:NOTHING
373 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) + INT_COMMAND
374 INT int_command
375ENDIF
376 MOV AX,[PARENT]
377 MOV WORD PTR CS:[PDB_Parent_PID],AX
378 MOV AX,(EXIT SHL 8) ; Return to lower level
379 INT int_command
380
381RET_2E:
382 PUSH CS
383 POP DS
384ASSUME DS:RESGROUP,ES:NOTHING,SS:NOTHING
385 MOV [SINGLECOM],0 ; Turn off singlecom
386 MOV ES,[LTPA]
387 MOV AH,DEALLOC
388 INT int_command ; Free up space used by transient
389 MOV BX,[SAVE_PDB]
390 MOV AH,SET_CURRENT_PDB
391 INT int_command ; Current process is user
392 MOV AX,[RETCODE]
393 CMP [EXTCOM],0
394 JNZ GOTECODE
395 XOR AX,AX ; Internals always return 0
396GOTECODE:
397 MOV [EXTCOM],1 ; Force external
398 JMP [INT_2E_RET] ;"IRET"
399
400INT_2E: ; Magic command executer
401ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
402 POP WORD PTR [INT_2E_RET]
403 POP WORD PTR [INT_2E_RET+2] ;Get return address
404 POP AX ;Chuck flags
405 PUSH CS
406 POP ES
407 MOV DI,80H
408 MOV CX,64
409 REP MOVSW
410 MOV AH,GET_CURRENT_PDB
411 INT int_command ; Get user's header
412 MOV [SAVE_PDB],BX
413 MOV AH,SET_CURRENT_PDB
414 MOV BX,CS
415 INT int_command ; Current process is me
416 MOV [SINGLECOM],81H
417 MOV [EXTCOM],1 ; Make sure this case forced
418
419LODCOM: ; Termination handler
420 CMP [EXTCOM],0
421 JZ LODCOM1 ; If internal, memory already allocated
422 MOV BX,0FFFFH
423 MOV AH,ALLOC
424 INT int_command
425 MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15
426 MOV CL,4
427 SHR AX,CL
428
429 IF IBM
430 PUSH AX
431 MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15
432 MOV CL,4
433 SHR AX,CL
434 POP CX
435 ADD AX,CX
436 ENDIF
437
438 ADD AX,20H
439 CMP BX,AX ; Is less than 512 byte buffer worth it?
440 JNC MEMOK
441BADMEMERRJ:
442 JMP BADMEMERR ; Not enough memory
443MEMOK:
444 MOV AH,ALLOC
445 INT int_command
446 JC BADMEMERRJ ; Memory arenas probably trashed
447 MOV [EXTCOM],0 ; Flag not to ALLOC again
448 MOV [LTPA],AX ; New TPA is base just allocated
449 ADD BX,AX
450 MOV [MEMSIZ],BX
451
452 MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15
453 MOV CL,4
454 SHR AX,CL
455
456 IF IBM
457 PUSH AX
458 MOV AX,OFFSET EGROUP:ZEXECDATAEND + 15
459 MOV CL,4
460 SHR AX,CL
461 POP CX
462 ADD AX,CX
463 ENDIF
464
465 SUB BX,AX
466 MOV [TRNSEG],BX ; Transient starts here
467LODCOM1:
468 MOV AX,CS
469 MOV SS,AX
470ASSUME SS:RESGROUP
471 MOV SP,OFFSET RESGROUP:RSTACK
472 MOV DS,AX
473ASSUME DS:RESGROUP
474 CALL HEADFIX ; Make sure files closed stdin and stdout restored
475 XOR BP,BP ; Flag command ok
476 MOV AX,-1
477 XCHG AX,[VERVAL]
478 CMP AX,-1
479 JZ NOSETVER
480 MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
481 INT int_command
482NOSETVER:
483 CMP [SINGLECOM],-1
484 JNZ NOSNG
485 JMP FATALRET2 ; We have finished the single command
486NOSNG:
487 CALL SETVECT
488
489IF IBMVER
490 CALL EXECHK ; Check exe loader
491 CMP DX,[EXESUM]
492 JNZ BOGUS_COM
493ENDIF
494
495 CALL CHKSUM ; Check the transient
496 CMP DX,[SUM]
497 JZ HAVCOM ; Transient OK
498BOGUS_COM:
499 MOV [LOADING],1 ; Flag DSKERR routine
500 CALL LOADCOM
501CHKSAME:
502
503IF IBMVER
504 CALL EXECHK
505 CMP DX,[EXESUM]
506 JNZ ALSO_BOGUS
507ENDIF
508
509 CALL CHKSUM
510 CMP DX,[SUM]
511 JZ HAVCOM ; Same COMMAND
512ALSO_BOGUS:
513 CALL WRONGCOM
514 JMP SHORT CHKSAME
515HAVCOM:
516 MOV AX,CHAR_OPER SHL 8
517 INT int_command
518 MOV [RSWITCHAR],DL
519 CMP DL,'/'
520 JNZ USESLASH
521 MOV [RDIRCHAR],'\' ; Select alt path separator
522USESLASH:
523 MOV [LOADING],0 ; Flag to DSKERR
524 MOV SI,OFFSET RESGROUP:TRANVARS
525 MOV DI,OFFSET TRANGROUP:HEADCALL
526 MOV ES,[TRNSEG]
527 CLD
528 MOV CX,8
529 REP MOVSW ; Transfer INFO to transient
530 MOV AX,[MEMSIZ]
531 MOV WORD PTR DS:[PDB_block_len],AX ; Adjust my own header
532 JMP DWORD PTR [TRANS]
533
534; Far call to REMCHECK for TRANSIENT
535TREMCHECK PROC FAR
536 CALL REMCHECK
537 RET
538TREMCHECK ENDP
539
540REMCHECK:
541;All registers preserved. Returns zero if media removable, NZ if fixed
542; AL is drive (0=DEF, 1=A,...)
543 IF IBM
544 PUSH AX
545 OR AL,AL
546 JNZ GOTDRV2
547 MOV AH,GET_DEFAULT_DRIVE
548 INT int_command
549 INC AL ;A=1
550GOTDRV2:
551 PUSH BX
552 MOV BL,AL
553 INT 11H ;IBM EQUIP CALL
554 ROL AL,1
555 ROL AL,1
556 AND AL,3
557 JNZ NOT_SINGLE
558 INC AL
559NOT_SINGLE:
560 INC AL ; AL is now MAX floppy #
561 CMP BL,AL
562 POP BX
563 JBE SETREM ; Is an IBM floppy and so is removable
564 OR AL,AL ; Know AL is non-zero
565 JMP SHORT SETNREM
566SETREM:
567 ELSE
568 PUSH AX
569 ENDIF
570
571 XOR AX,AX ;Zero
572
573 IF IBM
574SETNREM:
575 ENDIF
576
577 POP AX
578 RET
579
580; Far call to HEADFIX for TRANSIENT
581THEADFIX PROC FAR
582 CALL HEADFIX
583 RET
584THEADFIX ENDP
585
586HEADFIX:
587 XOR BX,BX ; Clean up header
588 MOV CX,[IO_SAVE]
589 MOV DX,WORD PTR DS:[PDB_JFN_Table]
590 CMP CL,DL
591 JZ CHK1 ; Stdin matches
592 MOV AH,CLOSE
593 INT int_command
594 MOV DS:[PDB_JFN_Table],CL ; Restore stdin
595CHK1:
596 INC BX
597 CMP CH,DH ; Stdout matches
598 JZ CHKOTHERHAND
599 MOV AH,CLOSE
600 INT int_command
601 MOV DS:[PDB_JFN_Table+1],CH ; Restore stdout
602CHKOTHERHAND:
603 ADD BX,4 ; Skip 2,3,4
604 MOV CX,FilPerProc - 5 ; Already done 0,1,2,3,4
605CLOSELOOP:
606 MOV AH,CLOSE
607 INT int_command
608 INC BX
609 LOOP CLOSELOOP
610 RET
611
612SAVHAND:
613ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
614 PUSH DS
615 PUSH BX ; Set stdin to sterr, stdout to stderr
616 PUSH AX
617 MOV AH,GET_CURRENT_PDB
618 INT int_command ; Get user's header
619 MOV DS,BX
620 MOV AX,WORD PTR DS:[PDB_JFN_Table]
621 MOV [HANDLE01],AX ; Save user's stdin, stdout
622 MOV AL,DS:[PDB_JFN_Table+2]
623 MOV AH,AL
624 MOV WORD PTR DS:[PDB_JFN_Table],AX ; Dup stderr
625 POP AX
626 POP BX
627 POP DS
628 RET
629
630ASSUME DS:RESGROUP
631GETCOMDSK2:
632 CALL GETCOMDSK
633 JMP LODCOM1 ; Memory already allocated
634
635RESTHAND:
636 PUSH DS
637 PUSH BX ; Restore stdin, stdout to user
638 PUSH AX
639 MOV AH,GET_CURRENT_PDB
640 INT int_command ; Point to user's header
641 MOV AX,[HANDLE01]
642 MOV DS,BX
643ASSUME DS:NOTHING
644 MOV WORD PTR DS:[PDB_JFN_Table],AX ; Stuff his old 0 and 1
645 POP AX
646 POP BX
647 POP DS
648 RET
649ASSUME DS:RESGROUP,SS:RESGROUP
650
651HOPELESS:
652 MOV DX,OFFSET RESGROUP:NOCOM
653 JMP FATALC
654
655GETCOMDSK:
656 MOV DX,OFFSET RESGROUP:NEEDCOM
657GETCOMDSK3:
658 MOV AL,[COMDRV]
659 CALL REMCHECK
660 JNZ HOPELESS ;Non-removable media
661 CALL RPRINT
662 MOV DX,OFFSET RESGROUP:DRVMSG
663 CMP [COMDRV],0
664 JNZ GETCOM1
665 MOV DX,OFFSET RESGROUP:DEFMSG
666GETCOM1:
667 CALL RPRINT
668 MOV DX,OFFSET RESGROUP:PROMPT
669 CALL RPRINT
670 CALL GetRawFlushedByte
671 RET
672
673; flush world and get raw input
674GetRawFlushedByte:
675 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT
676 INT int_command ; Get char without testing or echo
677 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
678 INT int_command
679 return
680
681LOADCOM: ; Load in transient
682 INC BP ; Flag command read
683 MOV DX,OFFSET RESGROUP:COMSPEC
684 MOV AX,OPEN SHL 8
685 INT int_command ; Open COMMAND.COM
686 JNC READCOM
687 CMP AX,open_too_many_open_files
688 JNZ TRYDOOPEN
689 MOV DX,OFFSET RESGROUP:NOHANDMES
690 JMP FATALC ; Fatal, will never find a handle
691
692TRYDOOPEN:
693 CALL GETCOMDSK
694 JMP SHORT LOADCOM
695
696READCOM:
697 MOV BX,AX ; Handle
698 MOV DX,OFFSET RESGROUP:TRANSTART
699 XOR CX,CX ; Seek loc
700 MOV AX,LSEEK SHL 8
701 INT int_command
702 JC WRONGCOM1
703 MOV CX,OFFSET TRANGROUP:TRANSPACEEND - 100H
704
705 IF IBM
706 ADD CX,15
707 AND CX,0FFF0H
708 ADD CX,OFFSET EGROUP:ZEXECCODEEND
709 ENDIF
710
711 PUSH DS
712 MOV DS,[TRNSEG]
713ASSUME DS:NOTHING
714 MOV DX,100H
715 MOV AH,READ
716 INT int_command
717 POP DS
718ASSUME DS:RESGROUP
719WRONGCOM1:
720 PUSHF
721 PUSH AX
722 MOV AH,CLOSE
723 INT int_command ; Close COMMAND.COM
724 POP AX
725 POPF
726 JC WRONGCOM ; If error on READ
727 CMP AX,CX
728 JZ RET10 ; Size matched
729WRONGCOM:
730 MOV DX,OFFSET RESGROUP:COMBAD
731 CALL GETCOMDSK3
732 JMP SHORT LOADCOM ; Try again
733
734CHKSUM: ; Compute transient checksum
735 PUSH DS
736 MOV DS,[TRNSEG]
737 MOV SI,100H
738 MOV CX,OFFSET TRANGROUP:TRANDATAEND - 100H
739
740CHECK_SUM:
741 CLD
742 SHR CX,1
743 XOR DX,DX
744CHK:
745 LODSW
746 ADD DX,AX
747 LOOP CHK
748 POP DS
749RET10: RET
750
751SETVECT: ; Set useful vectors
752 MOV DX,OFFSET RESGROUP:LODCOM
753 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H ; Set Terminate address
754 INT int_command
755 MOV DX,OFFSET RESGROUP:CONTC
756 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ; Set Ctrl-C address
757 INT int_command
758 MOV DX,OFFSET RESGROUP:DSKERR
759 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H ; Set Hard Disk Error address
760 INT int_command
761 RET
762
763CODERES ENDS
764
765; This TAIL segment is used to produce a PARA aligned label in the resident
766; group which is the location where the transient segments will be loaded
767; initial.
768
769TAIL SEGMENT PUBLIC PARA
770 ORG 0
771TRANSTART LABEL WORD
772TAIL ENDS
773
774; This TAIL segment is used to produce a PARA aligned label in the transient
775; group which is the location where the exec segments will be loaded
776; initial.
777
778TRANTAIL SEGMENT PUBLIC PARA
779 ORG 0
780EXECSTART LABEL WORD
781TRANTAIL ENDS
782
783IF IBMVER
784 INCLUDE EXEC.ASM
785ENDIF
786
787 END PROGSTART
788
diff --git a/v2.0/source/COMSEG.ASM b/v2.0/source/COMSEG.ASM
new file mode 100644
index 0000000..81ab3c8
--- /dev/null
+++ b/v2.0/source/COMSEG.ASM
@@ -0,0 +1,38 @@
1; The following are all of the segments used in the load order
2
3CODERES SEGMENT PUBLIC
4CODERES ENDS
5
6DATARES SEGMENT PUBLIC
7DATARES ENDS
8
9ENVIRONMENT SEGMENT PUBLIC
10ENVIRONMENT ENDS
11
12INIT SEGMENT PUBLIC
13INIT ENDS
14
15TAIL SEGMENT PUBLIC
16TAIL ENDS
17
18TRANCODE SEGMENT PUBLIC
19TRANCODE ENDS
20
21TRANDATA SEGMENT PUBLIC
22TRANDATA ENDS
23
24TRANSPACE SEGMENT PUBLIC
25TRANSPACE ENDS
26
27TRANTAIL SEGMENT PUBLIC
28TRANTAIL ENDS
29
30ZEXEC_CODE SEGMENT PUBLIC
31ZEXEC_CODE ENDS
32
33ZEXEC_DATA SEGMENT PUBLIC
34ZEXEC_DATA ENDS
35
36RESGROUP GROUP CODERES,DATARES,ENVIRONMENT,INIT,TAIL
37TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
38EGROUP GROUP ZEXEC_CODE,ZEXEC_DATA
diff --git a/v2.0/source/COMSW.ASM b/v2.0/source/COMSW.ASM
new file mode 100644
index 0000000..830585f
--- /dev/null
+++ b/v2.0/source/COMSW.ASM
@@ -0,0 +1,13 @@
1; Use the following booleans to set assembly flags
2FALSE EQU 0
3TRUE EQU NOT FALSE
4
5IBMVER EQU true ; Switch to build IBM version of Command
6IBM EQU IBMVER
7MSVER EQU false ; Switch to build MS-DOS version of Command
8
9HIGHMEM EQU FALSE ; Run resident part above transient (high memory)
10KANJI EQU false ; Support for dual byte Microsoft KANJI standard
11IBMJAPAN EQU FALSE ;MUST BE TRUE (along with IBM and KANJI)
12
13 \ No newline at end of file
diff --git a/v2.0/source/CONFIG.txt b/v2.0/source/CONFIG.txt
new file mode 100644
index 0000000..bfb1985
--- /dev/null
+++ b/v2.0/source/CONFIG.txt
Binary files differ
diff --git a/v2.0/source/COPY.ASM b/v2.0/source/COPY.ASM
new file mode 100644
index 0000000..0456a4f
--- /dev/null
+++ b/v2.0/source/COPY.ASM
@@ -0,0 +1,579 @@
1TITLE COMMAND COPY routines.
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15DATARES SEGMENT PUBLIC
16 EXTRN VERVAL:WORD
17DATARES ENDS
18
19TRANDATA SEGMENT PUBLIC
20 EXTRN BADARGS:BYTE,BADCD:BYTE,BADSWT:BYTE,COPIED_PRE:BYTE
21 EXTRN COPIED_POST:BYTE
22 EXTRN INBDEV:BYTE,OVERWR:BYTE,FULDIR:BYTE,LOSTERR:BYTE
23 EXTRN NOSPACE:BYTE,DEVWMES:BYTE,NOTFND:BYTE
24TRANDATA ENDS
25
26TRANSPACE SEGMENT PUBLIC
27 EXTRN MELCOPY:BYTE,SRCPT:WORD,MELSTART:WORD,SCANBUF:BYTE
28 EXTRN DESTFCB2:BYTE,SDIRBUF:BYTE,SRCTAIL:WORD,CFLAG:BYTE
29 EXTRN NXTADD:WORD,DESTCLOSED:BYTE,ALLSWITCH:WORD,ARGC:BYTE
30 EXTRN PLUS:BYTE,BINARY:BYTE,ASCII:BYTE,FILECNT:WORD
31 EXTRN WRITTEN:BYTE,CONCAT:BYTE,DESTBUF:BYTE,SRCBUF:BYTE
32 EXTRN SDIRBUF:BYTE,DIRBUF:BYTE,DESTFCB:BYTE,FRSTSRCH:BYTE
33 EXTRN FIRSTDEST:BYTE,DESTISDIR:BYTE,DESTSWITCH:WORD,STARTEL:WORD
34 EXTRN DESTTAIL:WORD,DESTSIZ:BYTE,DESTINFO:BYTE,INEXACT:BYTE
35 EXTRN CURDRV:BYTE,DESTVARS:BYTE,RESSEG:WORD,SRCSIZ:BYTE
36 EXTRN SRCINFO:BYTE,SRCVARS:BYTE,USERDIR1:BYTE,NOWRITE:BYTE
37 EXTRN RDEOF:BYTE,SRCHAND:WORD,CPDATE:WORD,CPTIME:WORD
38 EXTRN SRCISDEV:BYTE,BYTCNT:WORD,TPA:WORD,TERMREAD:BYTE
39 EXTRN DESTHAND:WORD,DESTISDEV:BYTE,DIRCHAR:BYTE
40TRANSPACE ENDS
41
42
43; **************************************************
44; COPY CODE
45;
46
47TRANCODE SEGMENT PUBLIC BYTE
48
49 EXTRN RESTUDIR:NEAR,CERROR:NEAR,SWITCH:NEAR,DISP32BITS:NEAR
50 EXTRN PRINT:NEAR,TCOMMAND:NEAR,ZPRINT:NEAR,ONESPC:NEAR
51 EXTRN RESTUDIR1:NEAR,FCB_TO_ASCZ:NEAR,CRLF2:NEAR,SAVUDIR1:NEAR
52 EXTRN SETREST1:NEAR,BADCDERR:NEAR,STRCOMP:NEAR,DELIM:NEAR
53 EXTRN UPCONV:NEAR,PATHCHRCMP:NEAR,SCANOFF:NEAR
54
55 EXTRN CPARSE:NEAR
56
57 EXTRN SEARCH:NEAR,SEARCHNEXT:NEAR,DOCOPY:NEAR,CLOSEDEST:NEAR
58 EXTRN FLSHFIL:NEAR,SETASC:NEAR,BUILDNAME:NEAR,COPERR:NEAR
59
60 PUBLIC COPY,BUILDPATH,COMPNAME,ENDCOPY
61
62
63ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
64
65DOMELCOPY:
66 cmp [MELCOPY],0FFH
67 jz CONTMEL
68 mov SI,[SRCPT]
69 mov [MELSTART],si
70 mov [MELCOPY],0FFH
71CONTMEL:
72 xor BP,BP
73 mov si,[SRCPT]
74 mov bl,'+'
75SCANSRC2:
76 mov di,OFFSET TRANGROUP:SCANBUF
77 call CPARSE
78 test bh,80H
79 jz NEXTMEL ; Go back to start
80 test bh,1 ; Switch ?
81 jnz SCANSRC2 ; Yes
82 call SOURCEPROC
83 call RESTUDIR1
84 mov di,OFFSET TRANGROUP:DESTFCB2
85 mov ax,PARSE_FILE_DESCRIPTOR SHL 8
86 INT int_command
87 mov bx,OFFSET TRANGROUP:SDIRBUF + 1
88 mov si,OFFSET TRANGROUP:DESTFCB2 + 1
89 mov di,[SRCTAIL]
90 call BUILDNAME
91 jmp MELDO
92
93
94NEXTMEL:
95 call CLOSEDEST
96 xor ax,ax
97 mov [CFLAG],al
98 mov [NXTADD],ax
99 mov [DESTCLOSED],al
100 mov si,[MELSTART]
101 mov [SRCPT],si
102 call SEARCHNEXT
103 jz SETNMELJ
104 jmp ENDCOPY2
105SETNMELJ:
106 jmp SETNMEL
107
108COPY:
109; First order of buisness is to find out about the destination
110ASSUME DS:TRANGROUP,ES:TRANGROUP
111 xor ax,ax
112 mov [ALLSWITCH],AX ; no switches
113 mov [ARGC],al ; no arguments
114 mov [PLUS],al ; no concatination
115 mov [BINARY],al ; Binary not specifically specified
116 mov [ASCII],al ; ASCII not specifically specified
117 mov [FILECNT],ax ; No files yet
118 mov [WRITTEN],al ; Nothing written yet
119 mov [CONCAT],al ; No concatination
120 mov [MELCOPY],al ; Not a Mel Hallerman copy
121 mov word ptr [SCANBUF],ax ; Init buffer
122 mov word ptr [DESTBUF],ax ; Init buffer
123 mov word ptr [SRCBUF],ax ; Init buffer
124 mov word ptr [SDIRBUF],ax ; Init buffer
125 mov word ptr [DIRBUF],ax ; Init buffer
126 mov word ptr [DESTFCB],ax ; Init buffer
127 dec ax
128 mov [FRSTSRCH],al ; First search call
129 mov [FIRSTDEST],al ; First time
130 mov [DESTISDIR],al ; Don't know about dest
131 mov si,81H
132 mov bl,'+' ; include '+' as a delimiter
133DESTSCAN:
134 xor bp,bp ; no switches
135 mov di,offset trangroup:SCANBUF
136 call CPARSE
137 PUSHF ; save flags
138 test bh,80H ; A '+' argument?
139 jz NOPLUS ; no
140 mov [PLUS],1 ; yes
141NOPLUS:
142 POPF ; get flags back
143 jc CHECKDONE ; Hit CR?
144 test bh,1 ; Switch?
145 jz TESTP2 ; no
146 or [DESTSWITCH],BP ; Yes, assume destination
147 or [ALLSWITCH],BP ; keep tabs on all switches
148 jmp short DESTSCAN
149
150TESTP2:
151 test bh,80H ; Plus?
152 jnz GOTPLUS ; Yes, not a separate arg
153 inc [ARGC] ; found a real arg
154GOTPLUS:
155 push SI
156 mov ax,[STARTEL]
157 mov SI,offset trangroup:SCANBUF ; Adjust to copy
158 sub ax,SI
159 mov DI,offset trangroup:DESTBUF
160 add ax,DI
161 mov [DESTTAIL],AX
162 mov [DESTSIZ],cl ; Save its size
163 inc cx ; Include the NUL
164 rep movsb ; Save potential destination
165 mov [DESTINFO],bh ; Save info about it
166 mov [DESTSWITCH],0 ; reset switches
167 pop SI
168 jmp short DESTSCAN ; keep going
169
170CHECKDONE:
171 mov al,[PLUS]
172 mov [CONCAT],al ; PLUS -> Concatination
173 shl al,1
174 shl al,1
175 mov [INEXACT],al ; CONCAT -> inexact copy
176 mov dx,offset trangroup:BADARGS
177 mov al,[ARGC]
178 or al,al ; Good number of args?
179 jz CERROR4J ; no, not enough
180 cmp al,2
181 jbe ACOUNTOK
182CERROR4J:
183 jmp CERROR ; no, too many
184ACOUNTOK:
185 mov bp,offset trangroup:DESTVARS
186 cmp al,1
187 jnz GOT2ARGS
188 mov al,[CURDRV] ; Dest is default drive:*.*
189 add al,'A'
190 mov ah,':'
191 mov [bp.SIZ],2
192 mov di,offset trangroup:DESTBUF
193 stosw
194 mov [DESTSWITCH],0 ; no switches on dest
195 mov [bp.INFO],2 ; Flag dest is ambig
196 mov [bp.ISDIR],0 ; Know destination specs file
197 call SETSTARS
198GOT2ARGS:
199 cmp [bp.SIZ],2
200 jnz NOTSHORTDEST
201 cmp [DESTBUF+1],':'
202 jnz NOTSHORTDEST ; Two char file name
203 or [bp.INFO],2 ; Know dest is d:
204 mov di,offset trangroup:DESTBUF + 2
205 mov [bp.ISDIR],0 ; Know destination specs file
206 call SETSTARS
207NOTSHORTDEST:
208 mov di,[bp.TTAIL]
209 cmp byte ptr [DI],0
210 jnz CHKSWTCHES
211 mov dx,offset trangroup:BADCD
212 cmp byte ptr [DI-2],':'
213 jnz CERROR4J ; Trailing '/' error
214 mov [bp.ISDIR],2 ; Know destination is d:/
215 or [bp.INFO],6
216 call SETSTARS
217CHKSWTCHES:
218 mov dx,offset trangroup:BADSWT
219 mov ax,[ALLSWITCH]
220 cmp ax,GOTSWITCH
221 jz CERROR4J ; Switch specified which is not known
222
223; Now know most of the information needed about the destination
224
225 TEST AX,VSWITCH ; Verify requested?
226 JZ NOVERIF ; No
227 MOV AH,GET_VERIFY_ON_WRITE
228 INT int_command ; Get current setting
229 PUSH DS
230 MOV DS,[RESSEG]
231ASSUME DS:RESGROUP
232 XOR AH,AH
233 MOV [VERVAL],AX ; Save current setting
234 POP DS
235ASSUME DS:TRANGROUP
236 MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1 ; Set verify
237 INT int_command
238NOVERIF:
239 xor bp,bp ; no switches
240 mov si,81H
241 mov bl,'+' ; include '+' as a delimiter
242SCANFSRC:
243 mov di,offset trangroup:SCANBUF
244 call CPARSE ; Parse first source name
245 test bh,1 ; Switch?
246 jnz SCANFSRC ; Yes, try again
247 or [DESTSWITCH],bp ; Include copy wide switches on DEST
248 test bp,BSWITCH
249 jnz NOSETCASC ; Binary explicit
250 cmp [CONCAT],0
251 JZ NOSETCASC ; Not Concat
252 mov [ASCII],ASWITCH ; Concat -> ASCII copy if no B switch
253NOSETCASC:
254 push SI
255 mov ax,[STARTEL]
256 mov SI,offset trangroup:SCANBUF ; Adjust to copy
257 sub ax,SI
258 mov DI,offset trangroup:SRCBUF
259 add ax,DI
260 mov [SRCTAIL],AX
261 mov [SRCSIZ],cl ; Save its size
262 inc cx ; Include the NUL
263 rep movsb ; Save this source
264 mov [SRCINFO],bh ; Save info about it
265 pop SI
266 mov ax,bp ; Switches so far
267 call SETASC ; Set A,B switches accordingly
268 call SWITCH ; Get any more switches on this arg
269 call SETASC ; Set
270 call FRSTSRC
271 jmp FIRSTENT
272
273ENDCOPY:
274 CALL CLOSEDEST
275ENDCOPY2:
276 MOV DX,OFFSET TRANGROUP:COPIED_PRE
277 CALL PRINT
278 MOV SI,[FILECNT]
279 XOR DI,DI
280 CALL DISP32BITS
281 MOV DX,OFFSET TRANGROUP:COPIED_POST
282 CALL PRINT
283 JMP TCOMMAND ; Stack could be messed up
284
285SRCNONEXIST:
286 cmp [CONCAT],0
287 jnz NEXTSRC ; If in concat mode, ignore error
288 mov dx,offset trangroup:SRCBUF
289 call zprint
290 CALL ONESPC
291 mov dx,offset trangroup:NOTFND
292 jmp COPERR
293
294SOURCEPROC:
295 push SI
296 mov ax,[STARTEL]
297 mov SI,offset trangroup:SCANBUF ; Adjust to copy
298 sub ax,SI
299 mov DI,offset trangroup:SRCBUF
300 add ax,DI
301 mov [SRCTAIL],AX
302 mov [SRCSIZ],cl ; Save its size
303 inc cx ; Include the NUL
304 rep movsb ; Save this sorce
305 mov [SRCINFO],bh ; Save info about it
306 pop SI
307 mov ax,bp ; Switches so far
308 call SETASC ; Set A,B switches accordingly
309 call SWITCH ; Get any more switches on this arg
310 call SETASC ; Set
311 cmp [CONCAT],0
312 jnz LEAVECFLAG ; Leave CFLAG if concatination
313FRSTSRC:
314 xor ax,ax
315 mov [CFLAG],al ; Flag destination not created
316 mov [NXTADD],ax ; Zero out buffer
317 mov [DESTCLOSED],al ; Not created -> not closed
318LEAVECFLAG:
319 mov [SRCPT],SI ; remember where we are
320 mov di,offset trangroup:USERDIR1
321 mov bp,offset trangroup:SRCVARS
322 call BUILDPATH ; Figure out everything about the source
323 mov si,[SRCTAIL] ; Create the search FCB
324 return
325
326NEXTSRC:
327 cmp [PLUS],0
328 jnz MORECP
329ENDCOPYJ2:
330 jmp ENDCOPY ; Done
331MORECP:
332 xor bp,bp ; no switches
333 mov si,[SRCPT]
334 mov bl,'+' ; include '+' as a delimiter
335SCANSRC:
336 mov di,offset trangroup:SCANBUF
337 call CPARSE ; Parse first source name
338 JC EndCopyJ2 ; if error, then end (trailing + case)
339 test bh,80H
340 jz ENDCOPYJ2 ; If no '+' we're done
341 test bh,1 ; Switch?
342 jnz SCANSRC ; Yes, try again
343 call SOURCEPROC
344FIRSTENT:
345 mov di,FCB
346 mov ax,PARSE_FILE_DESCRIPTOR SHL 8
347 INT int_command
348 mov ax,word ptr [SRCBUF] ; Get drive
349 cmp ah,':'
350 jz DRVSPEC1
351 mov al,'@'
352DRVSPEC1:
353 sub al,'@'
354 mov ds:[FCB],al
355 mov ah,DIR_SEARCH_FIRST
356 call SEARCH
357 pushf ; Save result of search
358 call RESTUDIR1 ; Restore users dir
359 popf
360 jz NEXTAMBIG0
361 jmp SRCNONEXIST ; Failed
362NEXTAMBIG0:
363 xor al,al
364 xchg al,[FRSTSRCH]
365 or al,al
366 jz NEXTAMBIG
367SETNMEL:
368 mov cx,12
369 mov di,OFFSET TRANGROUP:SDIRBUF
370 mov si,OFFSET TRANGROUP:DIRBUF
371 rep movsb ; Save very first source name
372NEXTAMBIG:
373 xor al,al
374 mov [NOWRITE],al ; Turn off NOWRITE
375 mov di,[SRCTAIL]
376 mov si,offset trangroup:DIRBUF + 1
377 call FCB_TO_ASCZ ; SRCBUF has complete name
378MELDO:
379 cmp [CONCAT],0
380 jnz SHOWCPNAM ; Show name if concat
381 test [SRCINFO],2 ; Show name if multi
382 jz DOREAD
383SHOWCPNAM:
384 mov dx,offset trangroup:SRCBUF
385 call ZPRINT
386 call CRLF2
387DOREAD:
388 call DOCOPY
389 cmp [CONCAT],0
390 jnz NODCLOSE ; If concat, do not close
391 call CLOSEDEST ; else close current destination
392 jc NODCLOSE ; Concat flag got set, close didn't really happen
393 mov [CFLAG],0 ; Flag destination not created
394NODCLOSE:
395 cmp [CONCAT],0 ; Check CONCAT again
396 jz NOFLUSH
397 CALL FLSHFIL ; Flush output between source files on CONCAT
398 ; so LOSTERR stuff works correctly
399 TEST [MELCOPY],0FFH
400 jz NOFLUSH
401 jmp DOMELCOPY
402
403NOFLUSH:
404 call SEARCHNEXT ; Try next match
405 jnz NEXTSRCJ ; Finished with this source spec
406 mov [DESTCLOSED],0 ; Not created or concat -> not closed
407 jmp NEXTAMBIG ; Do next ambig
408
409NEXTSRCJ:
410 jmp NEXTSRC
411
412
413
414BUILDPATH:
415 test [BP.INFO],2
416 jnz NOTPFILE ; If ambig don't bother with open
417 mov dx,bp
418 add dx,BUF ; Set DX to spec
419 mov ax,OPEN SHL 8
420 INT int_command
421 jc NOTPFILE
422 mov bx,ax ; Is pure file
423 mov ax,IOCTL SHL 8
424 INT int_command
425 mov ah,CLOSE
426 INT int_command
427 test dl,devid_ISDEV
428 jnz ISADEV ; If device, done
429 test [BP.INFO],4
430 jz ISSIMPFILE ; If no path seps, done
431NOTPFILE:
432 mov dx,word ptr [BP.BUF]
433 cmp dh,':'
434 jz DRVSPEC5
435 mov dl,'@'
436DRVSPEC5:
437 sub dl,'@' ; A = 1
438 call SAVUDIR1
439 mov dx,bp
440 add dx,BUF ; Set DX for upcomming CHDIRs
441 mov bh,[BP.INFO]
442 and bh,6
443 cmp bh,6 ; Ambig and path ?
444 jnz CHECKAMB ; jmp if no
445 mov si,[BP.TTAIL]
446 cmp byte ptr [si-2],':'
447 jnz KNOWNOTSPEC
448 mov [BP.ISDIR],2 ; Know is d:/file
449 jmp short DOPCDJ
450
451KNOWNOTSPEC:
452 mov [BP.ISDIR],1 ; Know is path/file
453 dec si ; Point to the /
454DOPCDJ:
455 jmp short DOPCD
456
457CHECKAMB:
458 cmp bh,2
459 jnz CHECKCD
460ISSIMPFILE:
461ISADEV:
462 mov [BP.ISDIR],0 ; Know is file since ambig but no path
463 return
464
465CHECKCD:
466 call SETREST1
467 mov ah,CHDIR
468 INT int_command
469 jc NOTPDIR
470 mov di,dx
471 xor ax,ax
472 mov cx,ax
473 dec cx
474 repne scasb
475 dec di
476 mov al,[DIRCHAR]
477 mov [bp.ISDIR],2 ; assume d:/file
478 cmp al,[di-1]
479 jz GOTSRCSLSH
480 stosb
481 mov [bp.ISDIR],1 ; know path/file
482GOTSRCSLSH:
483 or [bp.INFO],6
484 call SETSTARS
485 return
486
487
488NOTPDIR:
489 mov [bp.ISDIR],0 ; assume pure file
490 mov bh,[bp.INFO]
491 test bh,4
492 retz ; Know pure file, no path seps
493 mov [bp.ISDIR],2 ; assume d:/file
494 mov si,[bp.TTAIL]
495 cmp byte ptr [si],0
496 jz BADCDERRJ2 ; Trailing '/'
497 cmp byte ptr [si],'.'
498 jz BADCDERRJ2 ; If . or .. pure cd should have worked
499 cmp byte ptr [si-2],':'
500 jz DOPCD ; Know d:/file
501 mov [bp.ISDIR],1 ; Know path/file
502 dec si ; Point at last '/'
503DOPCD:
504 xor bl,bl
505 xchg bl,[SI] ; Stick in a NUL
506 call SETREST1
507 mov ah,CHDIR
508 INT int_command
509 xchg bl,[SI]
510 retnc
511BADCDERRJ2:
512 JMP BADCDERR
513
514SETSTARS:
515 mov [bp.TTAIL],DI
516 add [bp.SIZ],12
517 mov ax,('.' SHL 8) OR '?'
518 mov cx,8
519 rep stosb
520 xchg al,ah
521 stosb
522 xchg al,ah
523 mov cl,3
524 rep stosb
525 xor al,al
526 stosb
527 return
528
529
530COMPNAME:
531 PUSH CX
532 PUSH AX
533 MOV si,offset trangroup:SRCBUF
534 MOV di,offset trangroup:DESTBUF
535 MOV CL,[CURDRV]
536 MOV CH,CL
537 CMP BYTE PTR [SI+1],':'
538 JNZ NOSRCDRV
539 LODSW
540 SUB AL,'A'
541 MOV CL,AL
542NOSRCDRV:
543 CMP BYTE PTR [DI+1],':'
544 JNZ NODSTDRV
545 MOV AL,[DI]
546 INC DI
547 INC DI
548 SUB AL,'A'
549 MOV CH,AL
550NODSTDRV:
551 CMP CH,CL
552 jnz RET81P
553 call STRCOMP
554 jz RET81P
555 mov ax,[si-1]
556 mov cx,[di-1]
557 push ax
558 and al,cl
559 pop ax
560 jnz RET81P ; Niether of the mismatch chars was a NUL
561; Know one of the mismatch chars is a NUL
562; Check for ".NUL" compared with NUL
563 cmp al,'.'
564 jnz CHECKCL
565 or ah,ah
566 jmp short RET81P ; If NUL return match, else no match
567CHECKCL:
568 cmp cl,'.'
569 jnz RET81P ; Mismatch
570 or ch,ch ; If NUL return match, else no match
571RET81P:
572 POP AX
573 POP CX
574 return
575
576TRANCODE ENDS
577
578 END
579
diff --git a/v2.0/source/COPYPROC.ASM b/v2.0/source/COPYPROC.ASM
new file mode 100644
index 0000000..f6e3bb1
--- /dev/null
+++ b/v2.0/source/COPYPROC.ASM
@@ -0,0 +1,526 @@
1TITLE COPYRPOC ;Procedures called by COPY
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15DATARES SEGMENT PUBLIC
16DATARES ENDS
17
18TRANDATA SEGMENT PUBLIC
19
20 EXTRN OVERWR:BYTE,FULDIR:BYTE,LOSTERR:BYTE
21 EXTRN DEVWMES:BYTE,INBDEV:BYTE,NOSPACE:BYTE
22
23TRANDATA ENDS
24
25TRANSPACE SEGMENT PUBLIC
26
27 EXTRN CFLAG:BYTE,NXTADD:WORD,DESTCLOSED:BYTE
28 EXTRN PLUS:BYTE,BINARY:BYTE,ASCII:BYTE,FILECNT:WORD
29 EXTRN WRITTEN:BYTE,CONCAT:BYTE,DESTBUF:BYTE,SRCBUF:BYTE
30 EXTRN SDIRBUF:BYTE,DIRBUF:BYTE,DESTFCB:BYTE,MELCOPY:BYTE
31 EXTRN FIRSTDEST:BYTE,DESTISDIR:BYTE,DESTSWITCH:WORD
32 EXTRN DESTTAIL:WORD,DESTINFO:BYTE,INEXACT:BYTE
33 EXTRN DESTVARS:BYTE,SRCINFO:BYTE,RDEOF:BYTE
34 EXTRN USERDIR1:BYTE,NOWRITE:BYTE
35 EXTRN SRCHAND:WORD,CPDATE:WORD,CPTIME:WORD
36 EXTRN SRCISDEV:BYTE,BYTCNT:WORD,TPA:WORD,TERMREAD:BYTE
37 EXTRN DESTHAND:WORD,DESTISDEV:BYTE,DIRCHAR:BYTE
38
39TRANSPACE ENDS
40
41TRANCODE SEGMENT PUBLIC BYTE
42
43 PUBLIC SEARCH,SEARCHNEXT,DOCOPY,CLOSEDEST,FLSHFIL,SETASC
44 PUBLIC BUILDNAME,COPERR
45
46 EXTRN PRINT:NEAR,BUILDPATH:NEAR,RESTUDIR1:NEAR
47 EXTRN COMPNAME:NEAR,ENDCOPY:NEAR
48
49ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
50
51
52SEARCHNEXT:
53 MOV AH,DIR_SEARCH_NEXT
54 TEST [SRCINFO],2
55 JNZ SEARCH ; Do serach-next if ambig
56 OR AH,AH ; Reset zero flag
57 return
58SEARCH:
59 PUSH AX
60 MOV AH,SET_DMA
61 MOV DX,OFFSET TRANGROUP:DIRBUF
62 INT int_command ; Put result of search in DIRBUF
63 POP AX ; Restore search first/next command
64 MOV DX,FCB
65 INT int_command ; Do the search
66 OR AL,AL
67 return
68
69DOCOPY:
70 mov [RDEOF],0 ; No EOF yet
71 mov dx,offset trangroup:SRCBUF
72 mov ax,OPEN SHL 8
73 INT int_command
74 retc ; If open fails, ignore
75 mov bx,ax ; Save handle
76 mov [SRCHAND],bx ; Save handle
77 mov ax,(FILE_TIMES SHL 8)
78 INT int_command
79 mov [CPDATE],dx ; Save DATE
80 mov [CPTIME],cx ; Save TIME
81 mov ax,(IOCTL SHL 8)
82 INT int_command ; Get device stuff
83 and dl,devid_ISDEV
84 mov [SRCISDEV],dl ; Set source info
85 jz COPYLP ; Source not a device
86 cmp [BINARY],0
87 jz COPYLP ; ASCII device OK
88 mov dx,offset trangroup:INBDEV ; Cannot do binary input
89 jmp COPERR
90
91COPYLP:
92 mov bx,[SRCHAND]
93 mov cx,[BYTCNT]
94 mov dx,[NXTADD]
95 sub cx,dx ; Compute available space
96 jnz GOTROOM
97 call FLSHFIL
98 CMP [TERMREAD],0
99 JNZ CLOSESRC ; Give up
100 mov cx,[BYTCNT]
101GOTROOM:
102 push ds
103 mov ds,[TPA]
104ASSUME DS:NOTHING
105 mov ah,READ
106 INT int_command
107 pop ds
108ASSUME DS:TRANGROUP
109 jc CLOSESRC ; Give up if error
110 mov cx,ax ; Get count
111 jcxz CLOSESRC ; No more to read
112 cmp [SRCISDEV],0
113 jnz NOTESTA ; Is a device, ASCII mode
114 cmp [ASCII],0
115 jz BINREAD
116NOTESTA:
117 MOV DX,CX
118 MOV DI,[NXTADD]
119 MOV AL,1AH
120 PUSH ES
121 MOV ES,[TPA]
122 REPNE SCASB ; Scan for EOF
123 POP ES
124 JNZ USEALL
125 INC [RDEOF]
126 INC CX
127USEALL:
128 SUB DX,CX
129 MOV CX,DX
130BINREAD:
131 ADD CX,[NXTADD]
132 MOV [NXTADD],CX
133 CMP CX,[BYTCNT] ; Is buffer full?
134 JB TESTDEV ; If not, we may have found EOF
135 CALL FLSHFIL
136 CMP [TERMREAD],0
137 JNZ CLOSESRC ; Give up
138 JMP SHORT COPYLP
139
140TESTDEV:
141 cmp [SRCISDEV],0
142 JZ CLOSESRC ; If file then EOF
143 CMP [RDEOF],0
144 JZ COPYLP ; On device, go till ^Z
145CLOSESRC:
146 mov bx,[SRCHAND]
147 mov ah,CLOSE
148 INT int_command
149 return
150
151CLOSEDEST:
152 cmp [DESTCLOSED],0
153 retnz ; Don't double close
154 MOV AL,BYTE PTR [DESTSWITCH]
155 CALL SETASC ; Check for B or A switch on destination
156 JZ BINCLOS
157 MOV BX,[NXTADD]
158 CMP BX,[BYTCNT] ; Is memory full?
159 JNZ PUTZ
160 call TRYFLUSH ; Make room for one lousy byte
161 jz NOCONC
162CONCHNG: ; Concat flag changed on us
163 stc
164 return
165NOCONC:
166 XOR BX,BX
167PUTZ:
168 PUSH DS
169 MOV DS,[TPA]
170 MOV WORD PTR [BX],1AH ; Add End-of-file mark (Ctrl-Z)
171 POP DS
172 INC [NXTADD]
173 MOV [NOWRITE],0 ; Make sure our ^Z gets written
174 MOV AL,[WRITTEN]
175 XOR AH,AH
176 ADD AX,[NXTADD]
177 JC BINCLOS ; > 1
178 CMP AX,1
179 JZ FORGETIT ; WRITTEN = 0 NXTADD = 1 (the ^Z)
180BINCLOS:
181 call TRYFLUSH
182 jnz CONCHNG
183 cmp [WRITTEN],0
184 jz FORGETIT ; Never wrote nothin
185 MOV BX,[DESTHAND]
186 MOV CX,[CPTIME]
187 MOV DX,[CPDATE]
188 CMP [INEXACT],0 ; Copy not exact?
189 JZ DODCLOSE ; If no, copy date & time
190 MOV AH,GET_TIME
191 INT int_command
192 SHL CL,1
193 SHL CL,1 ; Left justify min in CL
194 SHL CX,1
195 SHL CX,1
196 SHL CX,1 ; hours to high 5 bits, min to 5-10
197 SHR DH,1 ; Divide seconds by 2 (now 5 bits)
198 OR CL,DH ; And stick into low 5 bits of CX
199 PUSH CX ; Save packed time
200 MOV AH,GET_DATE
201 INT int_command
202 SUB CX,1980
203 XCHG CH,CL
204 SHL CX,1 ; Year to high 7 bits
205 SHL DH,1 ; Month to high 3 bits
206 SHL DH,1
207 SHL DH,1
208 SHL DH,1
209 SHL DH,1 ; Most sig bit of month in carry
210 ADC CH,0 ; Put that bit next to year
211 OR DL,DH ; Or low three of month into day
212 MOV DH,CH ; Get year and high bit of month
213 POP CX ; Get time back
214DODCLOSE:
215 MOV AX,(FILE_TIMES SHL 8) OR 1
216 INT int_command ; Set date and time
217 MOV AH,CLOSE
218 INT int_command
219 INC [FILECNT]
220 INC [DESTCLOSED]
221RET50:
222 CLC
223 return
224
225FORGETIT:
226 MOV BX,[DESTHAND]
227 CALL DODCLOSE ; Close the dest
228 MOV DX,OFFSET TRANGROUP:DESTBUF
229 MOV AH,UNLINK
230 INT int_command ; And delete it
231 MOV [FILECNT],0 ; No files transferred
232 JMP RET50
233
234TRYFLUSH:
235 mov al,[CONCAT]
236 push ax
237 call FLSHFIL
238 pop ax
239 cmp al,[CONCAT]
240 return
241
242FLSHFIL:
243; Write out any data remaining in memory.
244; Inputs:
245; [NXTADD] = No. of bytes to write
246; [CFLAG] <>0 if file has been created
247; Outputs:
248; [NXTADD] = 0
249
250 MOV [TERMREAD],0
251 cmp [CFLAG],0
252 JZ NOTEXISTS
253 JMP EXISTS
254NOTEXISTS:
255 call BUILDDEST ; Find out all about the destination
256 CALL COMPNAME ; Source and dest. the same?
257 JNZ PROCDEST ; If not, go ahead
258 CMP [SRCISDEV],0
259 JNZ PROCDEST ; Same name on device OK
260 CMP [CONCAT],0 ; Concatenation?
261 MOV DX,OFFSET TRANGROUP:OVERWR
262 JZ COPERRJ ; If not, overwrite error
263 MOV [NOWRITE],1 ; Flag not writting (just seeking)
264PROCDEST:
265 mov ax,(OPEN SHL 8) OR 1
266 CMP [NOWRITE],0
267 JNZ DODESTOPEN ; Don't actually create if NOWRITE set
268 mov ah,CREAT
269 xor cx,cx
270DODESTOPEN:
271 mov dx,offset trangroup:DESTBUF
272 INT int_command
273 MOV DX,OFFSET TRANGROUP:FULDIR
274 JC COPERRJ
275 mov [DESTHAND],ax ; Save handle
276 mov [CFLAG],1 ; Destination now exists
277 mov bx,ax
278 mov ax,(IOCTL SHL 8)
279 INT int_command ; Get device stuff
280 mov [DESTISDEV],dl ; Set dest info
281 test dl,devid_ISDEV
282 jz EXISTS ; Dest not a device
283 mov al,BYTE PTR [DESTSWITCH]
284 AND AL,ASWITCH+BSWITCH
285 JNZ TESTBOTH
286 MOV AL,[ASCII] ; Neither set, use current setting
287 OR AL,[BINARY]
288 JZ EXSETA ; Neither set, default to ASCII
289TESTBOTH:
290 JPE EXISTS ; Both are set, ignore
291 test AL,BSWITCH
292 jz EXISTS ; Leave in cooked mode
293 mov ax,(IOCTL SHL 8) OR 1
294 xor dh,dh
295 or dl,devid_RAW
296 mov [DESTISDEV],dl ; New value
297 INT int_command ; Set device to RAW mode
298 jmp short EXISTS
299
300COPERRJ:
301 jmp SHORT COPERR
302
303EXSETA:
304; What we read in may have been in binary mode, flag zapped write OK
305 mov [ASCII],ASWITCH ; Set ASCII mode
306 or [INEXACT],ASWITCH ; ASCII -> INEXACT
307EXISTS:
308 cmp [NOWRITE],0
309 jnz NOCHECKING ; If nowrite don't bother with name check
310 CALL COMPNAME ; Source and dest. the same?
311 JNZ NOCHECKING ; If not, go ahead
312 CMP [SRCISDEV],0
313 JNZ NOCHECKING ; Same name on device OK
314; At this point we know in append (would have gotten overwrite error on first
315; destination create otherwise), and user trying to specify destination which
316; has been scribbled already (if dest had been named first, NOWRITE would
317; be set).
318 MOV DX,OFFSET TRANGROUP:LOSTERR ; Tell him he's not going to get it
319 CALL PRINT
320 MOV [NXTADD],0 ; Set return
321 INC [TERMREAD] ; Tell Read to give up
322RET60:
323 return
324
325NOCHECKING:
326 mov bx,[DESTHAND] ; Get handle
327 XOR CX,CX
328 XCHG CX,[NXTADD]
329 JCXZ RET60 ; If Nothing to write, forget it
330 INC [WRITTEN] ; Flag that we wrote something
331 CMP [NOWRITE],0 ; If NOWRITE set, just seek CX bytes
332 JNZ SEEKEND
333 XOR DX,DX
334 PUSH DS
335 MOV DS,[TPA]
336ASSUME DS:NOTHING
337 MOV AH,WRITE
338 INT int_command
339 POP DS
340ASSUME DS:TRANGROUP
341 MOV DX,OFFSET TRANGROUP:NOSPACE
342 JC COPERR ; Failure
343 sub cx,ax
344 retz ; Wrote all supposed to
345 test [DESTISDEV],devid_ISDEV
346 jz COPERR ; Is a file, error
347 test [DESTISDEV],devid_RAW
348 jnz DEVWRTERR ; Is a raw device, error
349 cmp [INEXACT],0
350 retnz ; INEXACT so OK
351 dec cx
352 retz ; Wrote one byte less (the ^Z)
353DEVWRTERR:
354 MOV DX,OFFSET TRANGROUP:DEVWMES
355COPERR:
356 CALL PRINT
357 inc [DESTCLOSED]
358 cmp [CFLAG],0
359 jz ENDCOPYJ ; Never actually got it open
360 MOV bx,[DESTHAND]
361 MOV AH,CLOSE ; Close the file
362 INT int_command
363 MOV DX,OFFSET TRANGROUP:DESTBUF
364 MOV AH,UNLINK
365 INT int_command ; And delete it
366 MOV [CFLAG],0
367ENDCOPYJ:
368 JMP ENDCOPY
369
370
371SEEKEND:
372 xor dx,dx ; Zero high half of offset
373 xchg dx,cx ; cx:dx is seek location
374 mov ax,(LSEEK SHL 8) OR 1
375 INT int_command ; Seek ahead in the file
376 cmp [RDEOF],0
377 retz
378; If a ^Z has been read we must set the file size to the current
379; file pointer location
380 MOV AH,WRITE
381 INT int_command ; CX is zero, truncates file
382 return
383
384SETASC:
385; Given switch vector in AX,
386; Set ASCII switch if A is set
387; Clear ASCII switch if B is set
388; BINARY set if B specified
389; Leave ASCII unchanged if neither or both are set
390; Also sets INEXACT if ASCII is ever set. AL = ASCII on exit, flags set
391 AND AL,ASWITCH+BSWITCH
392 JPE LOADSW ; PE means both or neither are set
393 PUSH AX
394 AND AL,BSWITCH
395 MOV [BINARY],AL
396 POP AX
397 AND AL,ASWITCH
398 MOV [ASCII],AL
399 OR [INEXACT],AL
400LOADSW:
401 MOV AL,[ASCII]
402 OR AL,AL
403 return
404
405BUILDDEST:
406 cmp [DESTISDIR],-1
407 jnz KNOWABOUTDEST ; Already done the figuring
408 MOV DI,OFFSET TRANGROUP:USERDIR1
409 mov bp,offset trangroup:DESTVARS
410 call BUILDPATH
411 call RESTUDIR1
412
413; Now know all about the destination
414
415KNOWABOUTDEST:
416 xor al,al
417 xchg al,[FIRSTDEST]
418 or al,al
419 jnz FIRSTDST
420 jmp NOTFIRSTDEST
421FIRSTDST:
422 mov si,[DESTTAIL] ; Create an FCB of the original DEST
423 mov di,offset trangroup:DESTFCB
424 mov ax,PARSE_FILE_DESCRIPTOR SHL 8
425 INT int_command
426 mov ax,word ptr [DESTBUF] ; Get drive
427 cmp ah,':'
428 jz DRVSPEC4
429 mov al,'@'
430DRVSPEC4:
431 MOV CL,[ASCII] ; Save current ASCII setting
432 sub al,'@'
433 mov [DESTFCB],al
434 mov al,[DESTINFO]
435 mov ah,[SRCINFO]
436 and ax,0202H
437 or al,al
438 jz NOTMELCOPY
439 cmp al,ah
440 jnz NOTMELCOPY
441 cmp [PLUS],0
442 jz NOTMELCOPY
443 inc [MELCOPY] ; ambig source, ambig dest, and pluses
444 xor al,al
445 jmp short SETCONC
446
447NOTMELCOPY:
448 xor al,2 ; al=2 if unambig dest, =0 if ambig dest
449 and al,ah
450 shr al,1 ; al=1 if unambig dest AND ambig sorce
451 ; Implies concatination
452SETCONC:
453 or al,[PLUS] ; al=1 if concat
454 mov [CONCAT],al
455 shl al,1
456 shl al,1
457 mov [INEXACT],al ; Concat -> inexact copy
458 cmp [BINARY],0
459 jnz NOTFIRSTDEST ; Binary explicitly given, all OK
460 mov [ASCII],al ; Concat -> ASCII
461 or cl,cl
462 jnz NOTFIRSTDEST ; ASCII flag set before, DATA read correctly
463 or al,al
464 JZ NOTFIRSTDEST ; ASCII flag did not change states
465; At this point there may already be binary read data in the read buffer.
466; We need to find the first ^Z (if there is one) and trim the amount
467; of data in the buffer correctly.
468 MOV CX,[NXTADD]
469 JCXZ NOTFIRSTDEST ; No data, everything OK
470 MOV AL,1AH
471 PUSH ES
472 XOR DI,DI
473 MOV ES,[TPA]
474 REPNE SCASB ; Scan for EOF
475 POP ES
476 JNZ NOTFIRSTDEST ; No ^Z in buffer, everything OK
477 DEC DI ; Point at ^Z
478 MOV [NXTADD],DI ; New buffer
479NOTFIRSTDEST:
480 mov bx,offset trangroup:DIRBUF+1 ; Source of replacement chars
481 cmp [CONCAT],0
482 jz GOTCHRSRC ; Not a concat
483 mov bx,offset trangroup:SDIRBUF+1 ; Source of replacement chars
484GOTCHRSRC:
485 mov si,offset trangroup:DESTFCB+1 ; Original dest name
486 mov di,[DESTTAIL] ; Where to put result
487
488BUILDNAME:
489 mov cx,8
490BUILDMAIN:
491 lodsb
492 cmp al,"?"
493 jnz NOTAMBIG
494 mov al,byte ptr [BX]
495NOTAMBIG:
496 cmp al,' '
497 jz NOSTORE
498 stosb
499NOSTORE:
500 inc bx
501 loop BUILDMAIN
502 mov cl,3
503 cmp byte ptr [SI],' '
504 jz ENDDEST ; No extension
505 mov al,'.'
506 stosb
507BUILDEXT:
508 lodsb
509 cmp al,"?"
510 jnz NOTAMBIGE
511 mov al,byte ptr [BX]
512NOTAMBIGE:
513 cmp al,' '
514 jz NOSTOREE
515 stosb
516NOSTOREE:
517 inc bx
518 loop BUILDEXT
519ENDDEST:
520 xor al,al
521 stosb ; NUL terminate
522 return
523
524TRANCODE ENDS
525 END
526
diff --git a/v2.0/source/CPARSE.ASM b/v2.0/source/CPARSE.ASM
new file mode 100644
index 0000000..967efaa
--- /dev/null
+++ b/v2.0/source/CPARSE.ASM
@@ -0,0 +1,291 @@
1TITLE CPARSE
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15DATARES SEGMENT PUBLIC
16DATARES ENDS
17
18TRANDATA SEGMENT PUBLIC
19 EXTRN BADCPMES:BYTE
20TRANDATA ENDS
21
22TRANSPACE SEGMENT PUBLIC
23 EXTRN CURDRV:BYTE,ELPOS:BYTE,STARTEL:WORD
24 EXTRN SKPDEL:BYTE,SWITCHAR:BYTE,ELCNT:BYTE
25
26TRANSPACE ENDS
27
28TRANCODE SEGMENT PUBLIC BYTE
29
30ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP
31
32 EXTRN DELIM:NEAR,UPCONV:NEAR,PATHCHRCMP:NEAR
33 EXTRN SWLIST:BYTE,BADCDERR:NEAR,SCANOFF:NEAR,CERROR:NEAR
34
35 if KANJI
36 EXTRN TESTKANJ:NEAR
37 endif
38
39SWCOUNT EQU 5
40
41 PUBLIC CPARSE
42
43CPARSE:
44
45;-----------------------------------------------------------------------;
46; ENTRY: ;
47; DS:SI Points input buffer ;
48; ES:DI Points to the token buffer ;
49; BL Special delimiter for this call ;
50; Always checked last ;
51; set it to space if there is no special delimiter ;
52; EXIT: ;
53; DS:SI Points to next char in the input buffer ;
54; ES:DI Points to the token buffer ;
55; [STARTEL] Points to start of last element of path in token ;
56; points to a NUL for no element strings 'd:' 'd:/' ;
57; CX Character count ;
58; BH Condition Code ;
59; Bit 1H of BH set if switch character ;
60; Token buffer contains char after ;
61; switch character ;
62; BP has switch bits set (ORing only) ;
63; Bit 2H of BH set if ? or * in token ;
64; if * found element ? filled ;
65; Bit 4H of BH set if path sep in token ;
66; Bit 80H of BH set if the special delimiter ;
67; was skipped at the start of this token ;
68; Token buffer always starts d: for non switch tokens ;
69; CARRY SET ;
70; if CR on input ;
71; token buffer not altered ;
72; ;
73; DOES NOT RETURN ON BAD PATH ERROR ;
74; MODIFIES: ;
75; CX, SI, AX, BH, DX and the Carry Flag ; ;
76; ;
77; -----------------------------------------------------------------------;
78
79 xor ax,ax
80 mov [STARTEL],DI ; No path element (Is DI correct?)
81 mov [ELPOS],al ; Start in 8 char prefix
82 mov [SKPDEL],al ; No skip delimiter yet
83 mov bh,al ; Init nothing
84 pushf ; save flags
85 push di ; save the token buffer addrss
86 xor cx,cx ; no chars in token buffer
87moredelim:
88 LODSB
89 CALL DELIM
90 JNZ SCANCDONE
91 CMP AL,' '
92 JZ moredelim
93 CMP AL,9
94 JZ moredelim
95 xchg al,[SKPDEL]
96 or al,al
97 jz moredelim ; One non space/tab delimiter allowed
98 JMP x_done ; Nul argument
99
100SCANCDONE:
101
102 IF NOT KANJI
103 call UPCONV
104 ENDIF
105
106 cmp al,bl ; Special delimiter?
107 jnz nospec
108 or bh,80H
109 jmp short moredelim
110
111nospec:
112 cmp al,0DH ; a CR?
113 jne ncperror
114 jmp cperror
115ncperror:
116 cmp al,[SWITCHAR] ; is the char the switch char?
117 jne na_switch ; yes, process...
118 jmp a_switch
119na_switch:
120 cmp byte ptr [si],':'
121 jne anum_chard ; Drive not specified
122
123 IF KANJI
124 call UPCONV
125 ENDIF
126
127 call move_char
128 lodsb ; Get the ':'
129 call move_char
130 mov [STARTEL],di
131 mov [ELCNT],0
132 jmp anum_test
133
134anum_chard:
135 mov [STARTEL],di
136 mov [ELCNT],0 ; Store of this char sets it to one
137 call PATHCHRCMP ; Starts with a pathchar?
138 jnz anum_char ; no
139 push ax
140 mov al,[CURDRV] ; Insert drive spec
141 add al,'A'
142 call move_char
143 mov al,':'
144 call move_char
145 pop ax
146 mov [STARTEL],di
147 mov [ELCNT],0
148
149anum_char:
150
151 IF KANJI
152 call TESTKANJ
153 jz TESTDOT
154 call move_char
155 lodsb
156 jmp short notspecial
157
158TESTDOT:
159 ENDIF
160
161 cmp al,'.'
162 jnz testquest
163 inc [ELPOS] ; flag in extension
164 mov [ELCNT],0FFH ; Store of the '.' resets it to 0
165testquest:
166 cmp al,'?'
167 jnz testsplat
168 or bh,2
169testsplat:
170 cmp al,'*'
171 jnz testpath
172 or bh,2
173 mov ah,7
174 cmp [ELPOS],0
175 jz gotelcnt
176 mov ah,2
177gotelcnt:
178 mov al,'?'
179 sub ah,[ELCNT]
180 jc badperr2
181 xchg ah,cl
182 jcxz testpathx
183qmove:
184 xchg ah,cl
185 call move_char
186 xchg ah,cl
187 loop qmove
188testpathx:
189 xchg ah,cl
190testpath:
191 call PATHCHRCMP
192 jnz notspecial
193 or bh,4
194 test bh,2 ; If just hit a '/', cannot have ? or * yet
195 jnz badperr
196 mov [STARTEL],di ; New element
197 INC [STARTEL] ; Point to char after /
198 mov [ELCNT],0FFH ; Store of '/' sets it to 0
199 mov [ELPOS],0
200notspecial:
201 call move_char ; just an alphanum string
202anum_test:
203 lodsb
204
205 IF NOT KANJI
206 call UPCONV
207 ENDIF
208
209 call DELIM
210 je x_done
211 cmp al,0DH
212 je x_done
213 cmp al,[SWITCHAR]
214 je x_done
215 cmp al,bl
216 je x_done
217 cmp al,':' ; ':' allowed as trailer because
218 ; of devices
219 IF KANJI
220 je FOO15
221 jmp anum_char
222FOO15:
223 ELSE
224 jne anum_char
225 ENDIF
226
227 mov byte ptr [si-1],' ' ; Change the trailing ':' to a space
228 jmp short x_done
229
230badperr2:
231 mov dx,offset trangroup:BADCPMES
232 jmp CERROR
233
234badperr:
235 jmp BADCDERR
236
237cperror:
238 dec si ; adjust the pointer
239 pop di ; retrive token buffer address
240 popf ; restore flags
241 stc ; set the carry bit
242 return
243
244x_done:
245 dec si ; adjust for next round
246 jmp short out_token
247
248a_switch:
249 OR BH,1 ; Indicate switch
250 OR BP,GOTSWITCH
251 CALL SCANOFF
252 INC SI
253 cmp al,0DH
254 je cperror
255 call move_char ; store the character
256 CALL UPCONV
257 PUSH ES
258 PUSH DI
259 PUSH CX
260 PUSH CS
261 POP ES
262ASSUME ES:TRANGROUP
263 MOV DI,OFFSET TRANGROUP:SWLIST
264 MOV CX,SWCOUNT
265 REPNE SCASB
266 JNZ out_tokenp
267 MOV AX,1
268 SHL AX,CL
269 OR BP,AX
270out_tokenp:
271 POP CX
272 POP DI
273 POP ES
274ASSUME ES:NOTHING
275out_token:
276 mov al,0
277 stosb ; null at the end
278 pop di ; restore token buffer pointer
279 popf
280 clc ; clear carry flag
281 return
282
283move_char:
284 stosb ; store char in token buffer
285 inc cx ; increment char count
286 inc [ELCNT] ; increment element count for * substi
287 return
288
289TRANCODE ENDS
290 END
291
diff --git a/v2.0/source/CTRLC.ASM b/v2.0/source/CTRLC.ASM
new file mode 100644
index 0000000..054903d
--- /dev/null
+++ b/v2.0/source/CTRLC.ASM
@@ -0,0 +1,468 @@
1;
2; ^C status routines for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17 i_need DevIOBuf,BYTE
18 i_need DidCTRLC,BYTE
19 i_need INDOS,BYTE
20 i_need DSKSTCOM,BYTE
21 i_need DSKSTCALL,BYTE
22 i_need DSKSTST,WORD
23 i_need BCON,DWORD
24 i_need DSKCHRET,BYTE
25 i_need DSKSTCNT,WORD
26 i_need IDLEINT,BYTE
27 i_need CONSWAP,BYTE
28 i_need user_SS,WORD
29 i_need user_SP,WORD
30 i_need ERRORMODE,BYTE
31 i_need ConC_spSave,WORD
32 i_need Exit_type,BYTE
33 i_need PFLAG,BYTE
34 i_need ExitHold,DWORD
35 i_need WPErr,BYTE
36 i_need ReadOp,BYTE
37 i_need CONTSTK,WORD
38 i_need Exit_Code,WORD
39 i_need CurrentPDB,WORD
40 i_need DIVMES,BYTE
41 i_need DivMesLen,BYTE
42
43SUBTTL Checks for ^C in CON I/O
44PAGE
45ASSUME DS:NOTHING,ES:NOTHING
46
47 procedure DSKSTATCHK,NEAR ; Check for ^C if only one level in
48 CMP BYTE PTR [INDOS],1
49 retnz ; Do NOTHING
50 PUSH CX
51 PUSH ES
52 PUSH BX
53 PUSH DS
54 PUSH SI
55 PUSH CS
56 POP ES
57 PUSH CS
58 POP DS
59ASSUME DS:DOSGROUP
60 XOR CX,CX
61 MOV BYTE PTR [DSKSTCOM],DEVRDND
62 MOV BYTE PTR [DSKSTCALL],DRDNDHL
63 MOV [DSKSTST],CX
64 MOV BX,OFFSET DOSGROUP:DSKSTCALL
65 LDS SI,[BCON]
66ASSUME DS:NOTHING
67 invoke DEVIOCALL2
68 TEST [DSKSTST],STBUI
69 JNZ ZRET ; No characters available
70 MOV AL,BYTE PTR [DSKCHRET]
71DSK1:
72 CMP AL,"C"-"@"
73 JNZ RET36
74 MOV BYTE PTR [DSKSTCOM],DEVRD
75 MOV BYTE PTR [DSKSTCALL],DRDWRHL
76 MOV BYTE PTR [DSKCHRET],CL
77 MOV [DSKSTST],CX
78 INC CX
79 MOV [DSKSTCNT],CX
80 invoke DEVIOCALL2 ; Eat the ^C
81 POP SI
82 POP DS
83 POP BX ; Clean stack
84 POP ES
85 POP CX
86 JMP SHORT CNTCHAND
87
88ZRET:
89 XOR AL,AL ; Set zero
90RET36:
91 POP SI
92 POP DS
93 POP BX
94 POP ES
95 POP CX
96 return
97
98NOSTOP:
99 CMP AL,"P"-"@"
100 JZ INCHK
101
102 IF NOT TOGLPRN
103 CMP AL,"N"-"@"
104 JZ INCHK
105 ENDIF
106
107 CMP AL,"C"-"@"
108 JZ INCHK
109 return
110DSKSTATCHK ENDP
111
112 procedure SPOOLINT,NEAR
113 PUSHF
114 CMP BYTE PTR [IDLEINT],0
115 JZ POPFRET
116 CMP BYTE PTR [ERRORMODE],0
117 JNZ POPFRET ;No spool ints in error mode
118 INT int_spooler
119POPFRET:
120 POPF
121RET18: return
122SPOOLINT ENDP
123
124 procedure STATCHK,NEAR
125
126 invoke DSKSTATCHK ; Allows ^C to be detected under
127 ; input redirection
128 PUSH BX
129 XOR BX,BX
130 invoke GET_IO_FCB
131 POP BX
132 JC RET18
133 MOV AH,1
134 invoke IOFUNC
135 JZ SPOOLINT
136 CMP AL,'S'-'@'
137 JNZ NOSTOP
138 XOR AH,AH
139 invoke IOFUNC ; Eat Cntrl-S
140 JMP SHORT PAUSOSTRT
141PRINTOFF:
142PRINTON:
143 NOT BYTE PTR [PFLAG]
144 return
145
146PAUSOLP:
147 CALL SPOOLINT
148PAUSOSTRT:
149 MOV AH,1
150 invoke IOFUNC
151 JZ PAUSOLP
152INCHK:
153 PUSH BX
154 XOR BX,BX
155 invoke GET_IO_FCB
156 POP BX
157 JC RET18
158 XOR AH,AH
159 invoke IOFUNC
160 CMP AL,'P'-'@'
161 JZ PRINTON
162 IF NOT TOGLPRN
163 CMP AL,'N'-'@'
164 JZ PRINTOFF
165 ENDIF
166 CMP AL,'C'-'@'
167 retnz
168STATCHK ENDP
169
170 procedure CNTCHAND,NEAR
171; Ctrl-C handler.
172; "^C" and CR/LF is printed. Then the user registers are restored and
173; the user CTRL-C handler is executed. At this point the top of the stack
174; has 1) the interrupt return address should the user CTRL-C handler wish
175; to allow processing to continue; 2) the original interrupt return address
176; to the code that performed the function call in the first place. If
177; the user CTRL-C handler wishes to continue, it must leave all registers
178; unchanged and RET (not IRET) with carry CLEAR. If carry is SET then
179; an terminate system call is simulated.
180 MOV AL,3 ; Display "^C"
181 invoke BUFOUT
182 invoke CRLF
183 PUSH SS
184 POP DS
185ASSUME DS:DOSGROUP
186 CMP BYTE PTR [CONSWAP],0
187 JZ NOSWAP
188 invoke SWAPBACK
189NOSWAP:
190 CLI ; Prepare to play with stack
191 MOV SP,[user_SP]
192 MOV SS,[user_SS] ; User stack now restored
193ASSUME SS:NOTHING
194 invoke restore_world ; User registers now restored
195ASSUME DS:NOTHING
196 MOV BYTE PTR [INDOS],0 ; Go to known state
197 MOV BYTE PTR [ERRORMODE],0
198 MOV [ConC_spsave],SP ; save his SP
199 INT int_ctrl_c ; Execute user Ctrl-C handler
200 MOV [user_SS],AX ; save the AX
201 PUSHF ; and the flags (maybe new call)
202 POP AX
203 CMP SP,[ConC_spsave]
204 JNZ ctrlc_try_new ; new syscall maybe?
205ctrlc_repeat:
206 MOV AX,[user_SS] ; no...
207 transfer COMMAND ; Repeat command otherwise
208
209ctrlc_try_new:
210 SUB [ConC_spsave],2 ; Are there flags on the stack?
211 CMP SP,[ConC_spsave]
212 JZ ctrlc_new ; yes, new system call
213
214ctrlc_abort:
215 MOV AX,(EXIT SHL 8) + 0
216 MOV BYTE PTR [DidCTRLC],0FFh
217
218 transfer COMMAND ; give up by faking $EXIT
219
220ctrlc_new:
221 PUSH AX
222 POPF
223 POP [user_SS]
224 JNC ctrlc_repeat ; repeat operation
225 JMP ctrlc_abort ; indicate ^ced
226
227CNTCHAND ENDP
228
229SUBTTL DIVISION OVERFLOW INTERRUPT
230PAGE
231; Default handler for division overflow trap
232 procedure DIVOV,NEAR
233ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
234 MOV SI,OFFSET DOSGROUP:DIVMES
235 CALL RealDivOv
236 JMP ctrlc_abort ; Use Ctrl-C abort on divide overflow
237DIVOV ENDP
238
239;
240; RealDivOv: perform actual divide overflow stuff.
241; Inputs: none
242; Outputs: message to BCON
243;
244 procedure RealDivOv,NEAR ; Do divide overflow and clock process
245
246 PUSH CS ; get ES addressability
247 POP ES
248
249 PUSH CS ; get DS addressability
250 POP DS
251ASSUME DS:DOSGROUP
252
253 MOV BYTE PTR [DskStCom],DevWrt
254 MOV BYTE PTR [DskStCall],DRdWrHL
255 MOV [DskSTST],0
256 MOV BL,[DivMesLen]
257 XOR BH,BH
258 MOV [DskStCnt],BX
259 MOV BX,OFFSET DOSGROUP:DskStCall
260 MOV WORD PTR [DskChRet+1],SI ; transfer address (need an EQU)
261 LDS SI,[BCON]
262ASSUME DS:NOTHING
263 invoke DEVIOCALL2
264 MOV WORD PTR [DskChRet+1],OFFSET DOSGROUP:DevIOBuf
265 MOV [DskStCnt],1
266 return
267RealDivOv ENDP
268
269SUBTTL CHARHRD,HARDERR,ERROR -- HANDLE DISK ERRORS AND RETURN TO USER
270PAGE
271 procedure CHARHARD,NEAR
272ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
273
274; Character device error handler
275; Same function as HARDERR
276
277 MOV WORD PTR [EXITHOLD+2],ES
278 MOV WORD PTR [EXITHOLD],BP
279 PUSH SI
280 AND DI,STECODE
281 MOV BP,DS ;Device pointer is BP:SI
282 CALL FATALC
283 POP SI
284 return
285CHARHARD ENDP
286
287 procedure HardErr,NEAR
288ASSUME DS:NOTHING,ES:NOTHING
289
290; Hard disk error handler. Entry conditions:
291; DS:BX = Original disk transfer address
292; DX = Original logical sector number
293; CX = Number of sectors to go (first one gave the error)
294; AX = Hardware error code
295; DI = Original sector transfer count
296; ES:BP = Base of drive parameters
297; [READOP] = 0 for read, 1 for write
298 ;
299 XCHG AX,DI ; Error code in DI, count in AX
300 AND DI,STECODE ; And off status bits
301 CMP DI,WRECODE ; Write Protect Error?
302 JNZ NOSETWRPERR
303 PUSH AX
304 MOV AL,ES:[BP.dpb_drive]
305 MOV BYTE PTR [WPERR],AL ; Flag drive with WP error
306 POP AX
307NOSETWRPERR:
308 SUB AX,CX ; Number of sectors successfully transferred
309 ADD DX,AX ; First sector number to retry
310 PUSH DX
311 MUL ES:[BP.dpb_sector_size] ; Number of bytes transferred
312 POP DX
313 ADD BX,AX ; First address for retry
314 XOR AH,AH ; Flag disk section in error
315 CMP DX,ES:[BP.dpb_first_FAT] ; In reserved area?
316 JB ERRINT
317 INC AH ; Flag for FAT
318 CMP DX,ES:[BP.dpb_dir_sector] ; In FAT?
319 JB ERRINT
320 INC AH
321 CMP DX,ES:[BP.dpb_first_sector] ; In directory?
322 JB ERRINT
323 INC AH ; Must be in data area
324ERRINT:
325 SHL AH,1 ; Make room for read/write bit
326 OR AH,BYTE PTR [READOP]
327 entry FATAL
328 MOV AL,ES:[BP.dpb_drive] ; Get drive number
329 entry FATAL1
330 MOV WORD PTR [EXITHOLD+2],ES
331 MOV WORD PTR [EXITHOLD],BP ; The only things we preserve
332 LES SI,ES:[BP.dpb_driver_addr]
333 MOV BP,ES ; BP:SI points to the device involved
334FATALC:
335 CMP BYTE PTR [ERRORMODE],0
336 JNZ SETIGN ; No INT 24s if already INT 24
337 MOV [CONTSTK],SP
338 PUSH SS
339 POP ES
340ASSUME ES:DOSGROUP
341 CLI ; Prepare to play with stack
342 INC BYTE PTR [ERRORMODE] ; Flag INT 24 in progress
343 DEC BYTE PTR [INDOS] ; INT 24 handler might not return
344 MOV SS,[user_SS]
345ASSUME SS:NOTHING
346 MOV SP,ES:[user_SP] ; User stack pointer restored
347 INT int_fatal_abort ; Fatal error interrupt vector, must preserve ES
348 MOV ES:[user_SP],SP ; restore our stack
349 MOV ES:[user_SS],SS
350 MOV SP,ES
351 MOV SS,SP
352ASSUME SS:DOSGROUP
353 MOV SP,[CONTSTK]
354 INC BYTE PTR [INDOS] ; Back in the DOS
355 MOV BYTE PTR [ERRORMODE],0 ; Back from INT 24
356 STI
357IGNRET:
358 LES BP,[EXITHOLD]
359ASSUME ES:NOTHING
360 CMP AL,2
361 JZ error_abort
362 MOV BYTE PTR [WPERR],-1 ;Forget about WP error
363 return
364
365SETIGN:
366 XOR AL,AL ;Flag ignore
367 JMP SHORT IGNRET
368
369error_abort:
370 PUSH SS
371 POP DS
372ASSUME DS:DOSGROUP
373 CMP BYTE PTR [CONSWAP],0
374 JZ NOSWAP2
375 invoke SWAPBACK
376NOSWAP2:
377 MOV BYTE PTR [exit_Type],Exit_hard_error
378 MOV DS,[CurrentPDB]
379ASSUME DS:NOTHING
380
381;
382; reset_environment checks the DS value against the CurrentPDB. If they
383; are different, then an old-style return is performed. If they are
384; the same, then we release jfns and restore to parent. We still use
385; the PDB at DS:0 as the source of the terminate addresses.
386;
387; output: none.
388;
389 entry reset_environment
390 ASSUME DS:NOTHING,ES:NOTHING
391 PUSH DS ; save PDB of process
392
393 MOV AL,int_Terminate
394 invoke $Get_interrupt_vector ; and who to go to
395 MOV WORD PTR [EXITHOLD+2],ES ; save return address
396 MOV WORD PTR [EXITHOLD],BX
397
398 MOV BX,[CurrentPDB] ; get current process
399 MOV DS,BX ;
400 MOV AX,DS:[PDB_Parent_PID] ; get parent to return to
401 POP CX
402;
403; AX = parentPDB, BX = CurrentPDB, CX = ThisPDB
404; Only free handles if AX <> BX and BX = CX and [exit_code].upper is not
405; Exit_keep_process
406;
407 CMP AX,BX
408 JZ reset_return ; parentPDB = CurrentPDB
409 CMP BX,CX
410 JNZ reset_return ; CurrentPDB <> ThisPDB
411 PUSH AX ; save parent
412 CMP BYTE PTR [exit_type],Exit_keep_process
413 JZ reset_to_parent ; keeping this process
414
415 invoke arena_free_process
416
417 ; reset environment at [CurrentPDB]; close those handles
418 MOV CX,FilPerProc
419
420reset_free_jfn:
421 MOV BX,CX
422 PUSH CX
423 DEC BX ; get jfn
424 invoke $CLOSE ; close it, ignore return
425 POP CX
426 LOOP reset_free_jfn ; and do 'em all
427
428reset_to_parent:
429 POP [CurrentPDB] ; set up process as parent
430
431reset_return: ; come here for normal return
432 PUSH CS
433 POP DS
434 ASSUME DS:DOSGROUP
435 MOV AL,-1
436 invoke FLUSHBUF ; make sure that everything is clean
437
438 CLI
439 MOV BYTE PTR [INDOS],0 ;Go to known state
440 MOV BYTE PTR [WPERR],-1 ;Forget about WP error
441;
442; Snake into multitasking... Get stack from CurrentPDB person
443;
444 MOV DS,[CurrentPDB]
445 ASSUME DS:NOTHING
446 MOV SS,WORD PTR DS:[PDB_user_stack+2]
447 MOV SP,WORD PTR DS:[PDB_user_stack]
448
449 ASSUME SS:NOTHING
450 invoke restore_world
451 ASSUME ES:NOTHING
452 POP AX ; suck off CS:IP of interrupt...
453 POP AX
454 POP AX
455 MOV AX,0F202h ; STI
456 PUSH AX
457 PUSH WORD PTR [EXITHOLD+2]
458 PUSH WORD PTR [EXITHOLD]
459 STI
460 IRET ; Long return back to user terminate address
461HardErr ENDP
462
463 ASSUME SS:DOSGROUP
464
465do_ext
466
467CODE ENDS
468 END
diff --git a/v2.0/source/DEBASM.ASM b/v2.0/source/DEBASM.ASM
new file mode 100644
index 0000000..a0fb0db
--- /dev/null
+++ b/v2.0/source/DEBASM.ASM
@@ -0,0 +1,1264 @@
1TITLE DEBASM
2
3; Code for the ASSEMble command in the debugger
4
5.xlist
6.xcref
7 INCLUDE DEBEQU.ASM
8 INCLUDE DOSSYM.ASM
9.cref
10.list
11
12
13CODE SEGMENT PUBLIC BYTE 'CODE'
14CODE ENDS
15
16CONST SEGMENT PUBLIC BYTE
17
18 EXTRN DBMN:BYTE,CSSAVE:WORD,REG8:BYTE,REG16:BYTE,SIZ8:BYTE
19 EXTRN SYNERR:BYTE,OPTAB:BYTE,MAXOP:ABS
20
21CONST ENDS
22
23DATA SEGMENT PUBLIC BYTE
24
25 EXTRN HINUM:WORD,LOWNUM:WORD,ASSEM_CNT:BYTE
26 EXTRN ASSEM1:BYTE,ASSEM2:BYTE,ASSEM3:BYTE,ASSEM4:BYTE,ASSEM5:BYTE
27 EXTRN ASSEM6:BYTE,OPBUF:BYTE,OPCODE:WORD,REGMEM:BYTE,INDEX:WORD
28 EXTRN ASMADD:BYTE,ASMSP:WORD,MOVFLG:BYTE,SEGFLG:BYTE,TSTFLG:BYTE
29 EXTRN NUMFLG:BYTE,DIRFLG:BYTE,BYTEBUF:BYTE,F8087:BYTE,DIFLG:BYTE
30 EXTRN SIFLG:BYTE,BXFLG:BYTE,BPFLG:BYTE,NEGFLG:BYTE,MEMFLG:BYTE
31 EXTRN REGFLG:BYTE,AWORD:BYTE,MIDFLD:BYTE,MODE:BYTE
32
33DATA ENDS
34
35DG GROUP CODE,CONST,DATA
36
37
38CODE SEGMENT PUBLIC BYTE 'CODE'
39ASSUME CS:DG,DS:DG,ES:DG,SS:DG
40
41 PUBLIC ASSEM
42 PUBLIC DB_OPER,DW_OPER,ASSEMLOOP,GROUP2,AA_OPER,DCINC_OPER
43 PUBLIC GROUP1,ESC_OPER,FGROUPP,FGROUPX,FDE_OPER,FGROUPZ
44 PUBLIC FD9_OPER,FGROUP,FDB_OPER,FGROUPB,FGROUP3,FGROUP3W
45 PUBLIC FGROUPDS,INT_OPER,IN_OPER,DISP8_OPER,JMP_OPER,NO_OPER
46 PUBLIC OUT_OPER,L_OPER,MOV_OPER,POP_OPER,PUSH_OPER,ROTOP
47 PUBLIC TST_OPER,EX_OPER,GET_DATA16,CALL_OPER
48
49 EXTRN INBUF:NEAR,SCANB:NEAR,SCANP:NEAR,GETHX:NEAR,GET_ADDRESS:NEAR
50 EXTRN DEFAULT:NEAR,OUTDI:NEAR,BLANK:NEAR,PRINTMES:NEAR,TAB:NEAR
51
52;
53; Line by line assembler
54;
55
56ASSEM:
57 MOV BP,[CSSAVE] ; Default code segment
58 MOV DI,OFFSET DG:ASMADD ; Default address
59 CALL DEFAULT
60 MOV WORD PTR [ASMADD],DX ; Displacement of disassembly
61 MOV WORD PTR [ASMADD+2],AX ; Segment
62 MOV [ASMSP],SP ; Save sp in case of error
63
64ASSEMLOOP:
65 MOV SP,[ASMSP] ; Restore sp in case of error
66 LES DI,DWORD PTR ASMADD ; GET PC
67 CALL OUTDI ; OUTPUT ADDRESS
68 CALL BLANK ; SKIP A SPACE
69 PUSH CS
70 POP ES
71 CALL INBUF ; GET A BUFFER
72 CALL SCANB
73 JNZ OPLOOK
74 RET ; IF EMPTY JUST RETURN
75;
76; At this point ds:si points to the opcode mnemonic...
77;
78OPLOOK: XOR CX,CX ; OP-CODE COUNT = 0
79 MOV DI,OFFSET DG:DBMN
80OPSCAN: XOR BX,BX
81OPLOOP: MOV AL,[DI+BX]
82 AND AL,7FH
83 CMP AL,[SI+BX]
84 JZ OPMATCH
85 INC CX ; INCREMENT OP-CODE COUNT
86 CMP CX,MAXOP ; CHECK FOR END OF LIST
87 JB OP1
88 JMP ASMERR
89OP1: INC DI ; SCAN FOR NEXT OP-CODE...
90 TEST BYTE PTR [DI-1],80H
91 JZ OP1
92 JMP OPSCAN
93
94OPMATCH:INC BX ; COMPARE NEXT CHAR
95 TEST BYTE PTR [DI+BX-1],80H ; ARE WE DONE?
96 JZ OPLOOP ; ..IF NOT KEEP COMPARING
97 XCHG BX,CX
98 MOV AX,BX
99 SHL AX,1
100 ADD AX,BX
101 ADD AX,OFFSET DG:OPTAB
102 MOV BX,AX
103;
104; CX = COUNT OF CHARS IN OPCODE
105; BX = POINTER INTO OPCODE TABLE
106;
107 XOR AX,AX
108 MOV BYTE PTR [AWORD],AL
109 MOV WORD PTR [MOVFLG],AX ; MOVFLG + TSTFLG
110 MOV BYTE PTR [SEGFLG],AL ; ZERO SEGMENT REGISTER FLAG
111 MOV AH,00001010B ; SET UP FOR AA_OPER
112 MOV AL,BYTE PTR [BX]
113 MOV WORD PTR [ASSEM1],AX
114 MOV BYTE PTR [ASSEM_CNT],1
115
116 ADD SI,CX ; SI POINTS TO OPERAND
117 JMP WORD PTR [BX+1]
118;
119; 8087 INSTRUCTIONS WITH NO OPERANDS
120;
121FDE_OPER:
122 MOV AH,0DEH
123 JMP SHORT FDX_OPER
124FDB_OPER:
125 MOV AH,0DBH
126 JMP SHORT FDX_OPER
127FD9_OPER:
128 MOV AH,0D9H
129FDX_OPER:
130 XCHG AL,AH
131 MOV WORD PTR [ASSEM1],AX
132;
133; aad and aam instrucions
134;
135AA_OPER:INC BYTE PTR [ASSEM_CNT]
136;
137; instructions with no operands
138;
139NO_OPER:
140 CALL STUFF_BYTES
141 CALL SCANP
142 PUSH CS
143 POP ES
144 JNZ OPLOOK
145 JMP ASSEMLOOP
146;
147; push instruction
148;
149PUSH_OPER:
150 MOV AH,11111111B
151 JMP SHORT POP1
152;
153; pop instruction
154;
155POP_OPER:
156 MOV AH,10001111B
157POP1: MOV [ASSEM1],AH
158 MOV [MIDFLD],AL
159 INC BYTE PTR [MOVFLG] ; ALLOW SEGMENT REGISTERS
160 MOV BYTE PTR [AWORD],2 ; MUST BE 16 BITS
161 CALL GETREGMEM
162 CALL BUILDIT
163 MOV AL,[DI+2]
164 CMP AL,11000000B
165 JB DATRET
166 MOV BYTE PTR [DI],1
167 CMP BYTE PTR [MOVFLG],2
168 JNZ POP2
169 AND AL,00011000B
170 OR AL,00000110B
171 CMP BYTE PTR [MIDFLD],0
172 JNZ POP3
173 OR AL,00000001B
174 JMP SHORT POP3
175
176POP2: AND AL,111B
177 OR AL,01010000B
178 CMP BYTE PTR [MIDFLD],0
179 JNZ POP3
180 OR AL,01011000B
181POP3: MOV BYTE PTR [DI+1],AL
182 JMP ASSEM_EXIT
183;
184; ret and retf instructions
185;
186GET_DATA16:
187 CALL SCANB
188 MOV CX,4
189 CALL GETHX
190 JC DATRET
191 DEC BYTE PTR [ASSEM1] ; CHANGE OP-CODE
192 ADD BYTE PTR [ASSEM_CNT],2 ; UPDATE LENGTH
193 MOV WORD PTR [ASSEM2],DX ; SAVE OFFSET
194DATRET: JMP ASSEM_EXIT
195;
196; int instruction
197;
198INT_OPER:
199 CALL SCANB
200 MOV CX,2
201 CALL GETHX
202 JC ERRV1
203 MOV AL,DL
204 CMP AL,3
205 JZ DATRET
206 INC BYTE PTR [ASSEM1]
207 JMP DISPX
208;
209; in instruction
210;
211IN_OPER:
212 CALL SCANB
213 LODSW
214 CMP AX,"A"+4C00H ; "AL"
215 JZ IN_1
216 CMP AX,"A"+5800H ; "AX"
217 JZ IN_0
218ERRV1: JMP ASMERR
219IN_0: INC BYTE PTR [ASSEM1]
220IN_1: CALL SCANP
221 CMP WORD PTR [SI],"D"+5800H ; "DX"
222 JZ DATRET
223 MOV CX,2
224 CALL GETHX
225 JC ERRV1
226 AND BYTE PTR [ASSEM1],11110111B
227 MOV AL,DL
228 JMP DISPX
229;
230; out instruction
231;
232OUT_OPER:
233 CALL SCANB
234 CMP WORD PTR [SI],"D"+5800H ; "DX"
235 JNZ OUT_0
236 INC SI
237 INC SI
238 JMP SHORT OUT_1
239OUT_0: AND BYTE PTR [ASSEM1],11110111B
240 MOV CX,2
241 CALL GETHX
242 JC ERRV1
243 INC BYTE PTR [ASSEM_CNT]
244 MOV BYTE PTR [ASSEM2],DL
245OUT_1: CALL SCANP
246 LODSW
247 CMP AX,"A"+4C00H ; "AL"
248 JZ DATRET
249 CMP AX,"A"+5800H ; "AX"
250 JNZ ERRV1
251 INC BYTE PTR [ASSEM1]
252 JMP DATRET
253
254;
255; jump instruction
256;
257JMP_OPER:
258 INC BYTE PTR [TSTFLG]
259;
260; call instruction
261;
262CALL_OPER:
263 MOV BYTE PTR [ASSEM1],11111111B
264 MOV BYTE PTR [MIDFLD],AL
265 CALL GETREGMEM
266 CALL BUILD3
267 CMP BYTE PTR [MEMFLG],0
268 JNZ CALLJ1
269 CMP BYTE PTR [REGMEM],-1
270 JZ CALLJ2
271;
272; INDIRECT JUMPS OR CALLS
273;
274CALLJ1: CMP BYTE PTR [AWORD],1
275ERRZ4: JZ ERRV1
276 CMP BYTE PTR [AWORD],4
277 JNZ ASMEX4
278 OR BYTE PTR [DI+2],1000B
279 JMP SHORT ASMEX4
280;
281; DIRECT JUMPS OR CALLS
282;
283CALLJ2: MOV AX,[LOWNUM]
284 MOV DX,[HINUM]
285 MOV BL,[AWORD]
286 CMP BYTE PTR [NUMFLG],0
287 JZ ERRZ4
288
289; BL = NUMBER OF BYTES IN JUMP
290; DX = OFFSET
291; AX = SEGMENT
292
293CALLJ3:
294 MOV BYTE PTR [DI],5
295 MOV [DI+2],AX
296 MOV [DI+4],DX
297
298 MOV AL,10011010B ; SET UP INTER SEGMENT CALL
299 CMP BYTE PTR [TSTFLG],0
300 JZ CALLJ5
301 MOV AL,11101010B ; FIX UP FOR JUMP
302CALLJ5: MOV BYTE PTR [DI+1],AL
303 CMP BL,4 ; FAR SPECIFIED?
304 JZ ASMEX4
305 OR BL,BL
306 JNZ CALLJ6
307 CMP DX,WORD PTR [ASMADD+2] ; DIFFERENT SEGMENT?
308 JNZ ASMEX4
309
310CALLJ6: MOV BYTE PTR [DI],3
311 MOV AL,11101000B ; SET UP FOR INTRASEGMENT
312 OR AL,[TSTFLG]
313 MOV BYTE PTR [DI+1],AL
314
315 MOV AX,[LOWNUM]
316 SUB AX,WORD PTR [ASMADD]
317 SUB AX,3
318 MOV [DI+2],AX
319 CMP BYTE PTR [TSTFLG],0
320 JZ ASMEX4
321 CMP BL,2
322 JZ ASMEX4
323
324 INC AX
325 MOV CX,AX
326 CBW
327 CMP AX,CX
328 JNZ ASMEX3
329 MOV BYTE PTR [DI+1],11101011B
330 MOV [DI+2],AX
331 DEC BYTE PTR [DI]
332ASMEX4: JMP ASSEM_EXIT
333;
334; conditional jumps and loop instructions
335;
336DISP8_OPER:
337 MOV BP,WORD PTR [ASMADD+2] ; GET DEFAULT DISPLACEMENT
338 CALL GET_ADDRESS
339 SUB DX,WORD PTR [ASMADD]
340 DEC DX
341 DEC DX
342 CALL CHKSIZ
343 CMP CL,1
344 JNZ ERRV2
345DISPX: INC [ASSEM_CNT]
346 MOV BYTE PTR [ASSEM2],AL
347ASMEX3: JMP ASSEM_EXIT
348;
349; lds, les, and lea instructions
350;
351L_OPER:
352 CALL SCANB
353 LODSW
354 MOV CX,8
355 MOV DI,OFFSET DG:REG16
356 CALL CHKREG
357 JZ ERRV2 ; CX = 0 MEANS NO REGISTER
358 SHL AL,1
359 SHL AL,1
360 SHL AL,1
361 MOV BYTE PTR [MIDFLD],AL
362 CALL SCANP
363 CALL GETREGMEM
364 CMP BYTE PTR [AWORD],0
365 JNZ ERRV2
366 CALL BUILD2
367 JMP SHORT ASEXV
368;
369; dec and inc instructions
370;
371DCINC_OPER:
372 MOV BYTE PTR [ASSEM1],11111110B
373 MOV BYTE PTR [MIDFLD],AL
374 CALL GETREGMEM
375 CALL BUILDIT
376 TEST BYTE PTR [DI+1],1
377 JZ ASEXV
378 MOV AL,[DI+2]
379 CMP AL,11000000B
380 JB ASEXV
381 AND AL,1111B
382 OR AL,01000000B
383 MOV [DI+1],AL
384 DEC BYTE PTR [DI]
385ASEXV: JMP ASSEM_EXIT
386
387ERRV2: JMP ASMERR
388;
389; esc instruction
390;
391ESC_OPER:
392 INC BYTE PTR [AWORD]
393 CALL SCANB
394 MOV CX,2
395 CALL GETHX
396 CMP DX,64
397 JAE ERRV2
398 CALL SCANP
399 MOV AX,DX
400 MOV CL,3
401 SHR DX,CL
402 OR [ASSEM1],DL
403 AND AL,111B
404 SHL AL,CL
405 JMP GROUPE
406;
407; 8087 arithmetic instuctions
408;
409
410;
411; OPERANDS THAT ALLOW THE REVERSE BIT
412;
413FGROUPDS:
414 CALL SETMID
415 CALL GETREGMEM2
416 CALL BUILD3
417 CMP BYTE PTR [MODE],11000000B
418 JNZ FGROUP1
419 MOV AL,[DIRFLG]
420 OR AL,AL
421 JZ FEXIT
422 OR [DI+1],AL ; IF D=1...
423 XOR BYTE PTR [DI+2],00001000B ; ...REVERSE THE SENSE OF R
424 JMP SHORT FEXIT
425
426;
427; Here when instruction could have memory or register operand
428;
429FGROUPX:
430 CALL SETMID ; THIS ENTRY POINT FOR 1 MEM OPER
431 MOV BYTE PTR [DIRFLG],0
432 JMP SHORT FGRP2
433FGROUP:
434 CALL SETMID
435FGRP2:
436 CALL GETREGMEM2
437 CALL BUILD3
438 CMP BYTE PTR [MODE],11000000B
439 JNZ FGROUP1
440 MOV AL,[DIRFLG]
441 OR [DI+1],AL
442 JMP SHORT FEXIT
443FGROUP1:CALL SETMF
444FEXIT: JMP ASSEM_EXIT
445;
446; These 8087 instructions require a memory operand
447;
448FGROUPB:
449 MOV AH,5 ; MUST BE TBYTE
450 JMP SHORT FGROUP3E
451FGROUP3W:
452 MOV AH,2 ; MUST BE WORD
453 JMP SHORT FGROUP3E
454FGROUP3:
455 MOV AH,-1 ; SIZE CANNOT BE SPECIFIED
456FGROUP3E:
457 MOV [AWORD],AH
458 CALL SETMID
459 CALL GETREGMEM
460 CMP BYTE PTR [MODE],11000000B
461 JZ FGRPERR
462FGRP:
463 CALL BUILD3
464 JMP FEXIT
465;
466; These 8087 instructions require a register operand
467;
468FGROUPP: ; 8087 POP OPERANDS
469 MOV BYTE PTR [AWORD],-1
470 CALL SETMID
471 CALL GETREGMEM2
472 CMP BYTE PTR [DIRFLG],0
473 JNZ FGRP
474FGRPERR:JMP ASMERR
475
476FGROUPZ: ; ENTRY POINT WHERE ARG MUST BE MEM
477 CALL SETMID
478 MOV BYTE PTR [DIRFLG],0
479 CALL GETREGMEM
480 CMP BYTE PTR [MODE],11000000B
481 JZ FGRPERR
482 CALL BUILD3
483 CALL SETMF
484 JMP FEXIT
485;
486; not, neg, mul, imul, div, and idiv instructions
487;
488GROUP1:
489 MOV [ASSEM1],11110110B
490GROUPE:
491 MOV BYTE PTR [MIDFLD],AL
492 CALL GETREGMEM
493 CALL BUILDIT
494 JMP FEXIT
495;
496; shift and rotate instructions
497;
498ROTOP:
499 MOV [ASSEM1],11010000B
500 MOV BYTE PTR [MIDFLD],AL
501 CALL GETREGMEM
502 CALL BUILDIT
503 CALL SCANP
504 CMP BYTE PTR [SI],"1"
505 JZ ASMEXV1
506 CMP WORD PTR [SI],"LC" ; CL
507 JZ ROTOP1
508ROTERR: JMP ASMERR
509ROTOP1: OR BYTE PTR [ASSEM1],10B
510ASMEXV1:JMP ASSEM_EXIT
511;
512; xchg instruction
513;
514EX_OPER:
515 INC BYTE PTR [TSTFLG]
516;
517; test instruction
518;
519TST_OPER:
520 INC BYTE PTR [TSTFLG]
521 JMP SHORT MOVOP
522;
523; mov instruction
524;
525MOV_OPER:
526 INC BYTE PTR [MOVFLG]
527MOVOP: XOR AX,AX
528 JMP SHORT GROUPM
529;
530; add, adc, sub, sbb, cmp, and, or, xor instructions
531;
532GROUP2:
533 MOV BYTE PTR [ASSEM1],10000000B
534GROUPM:
535 MOV BYTE PTR [MIDFLD],AL
536
537 PUSH AX
538 CALL GETREGMEM
539 CALL BUILD2
540 CALL SCANP ; POINT TO NEXT OPERAND
541 MOV AL,BYTE PTR [ASSEM_CNT]
542 PUSH AX
543 CALL GETREGMEM
544 POP AX
545 MOV BYTE PTR [DI],AL
546 POP AX
547 MOV BL,BYTE PTR [AWORD]
548 OR BL,BL
549 JZ ERRV5
550 DEC BL
551 AND BL,1
552 OR BYTE PTR [DI+1],BL
553
554 CMP BYTE PTR [MEMFLG],0
555 JNZ G21V
556 CMP BYTE PTR [NUMFLG],0 ; TEST FOR IMMEDIATE DATA
557 JZ G21V
558 CMP BYTE PTR [SEGFLG],0
559 JNZ ERRV5
560 CMP BYTE PTR [TSTFLG],2 ; XCHG?
561 JNZ IMMED1
562ERRV5: JMP ASMERR
563G21V: JMP GRP21
564;
565; SECOND OPERAND WAS IMMEDIATE
566;
567IMMED1: MOV AL,BYTE PTR [DI+2]
568 CMP BYTE PTR [MOVFLG],0
569 JZ NOTMOV1
570 AND AL,11000000B
571 CMP AL,11000000B
572 JNZ GRP23 ; not to a register
573 ; MOVE IMMEDIATE TO REGISTER
574 MOV AL,BYTE PTR [DI+1]
575 AND AL,1 ; SET SIZE
576 PUSHF
577 SHL AL,1
578 SHL AL,1
579 SHL AL,1
580 OR AL,BYTE PTR [DI+2] ; SET REGISTER
581 AND AL,00001111B
582 OR AL,10110000B
583 MOV BYTE PTR [DI+1],AL
584 MOV AX,WORD PTR [LOWNUM]
585 MOV WORD PTR [DI+2],AX
586 POPF
587 JZ EXVEC
588 INC BYTE PTR [DI]
589EXVEC: JMP GRPEX
590
591NOTMOV1:AND AL,11000111B
592 CMP AL,11000000B
593 JZ IMMACC ; IMMEDIATE TO ACC
594
595 CMP BYTE PTR [TSTFLG],0
596 JNZ GRP23
597 CMP BYTE PTR [MIDFLD],1*8 ; OR?
598 JZ GRP23
599 CMP BYTE PTR [MIDFLD],4*8 ; AND?
600 JZ GRP23
601 CMP BYTE PTR [MIDFLD],6*8 ; XOR?
602 JZ GRP23
603 TEST BYTE PTR [DI+1],1 ; TEST IF BYTE OPCODE
604 JZ GRP23
605
606 MOV AX,[LOWNUM]
607 MOV BX,AX
608 CBW
609 CMP AX,BX
610 JNZ GRP23 ; SMALL ENOUGH?
611
612 MOV BL,[DI]
613 DEC BYTE PTR [DI]
614 OR BYTE PTR [DI+1],10B
615 JMP SHORT GRP23X
616
617IMMACC: MOV AL,BYTE PTR [DI+1]
618 AND AL,1
619 CMP BYTE PTR [TSTFLG],0
620 JZ NOTTST
621 OR AL,10101000B
622 JMP SHORT TEST1
623NOTTST: OR AL,BYTE PTR [MIDFLD]
624 OR AL,100B
625TEST1: MOV BYTE PTR [DI+1],AL
626 DEC BYTE PTR [DI]
627
628GRP23: MOV BL,BYTE PTR [DI]
629GRP23X: XOR BH,BH
630 ADD BX,DI
631 INC BX
632 MOV AX,WORD PTR [LOWNUM]
633 MOV WORD PTR [BX],AX
634 INC BYTE PTR [DI]
635 TEST BYTE PTR [DI+1],1
636 JZ GRPEX1
637 INC BYTE PTR [DI]
638GRPEX1: JMP GRPEX
639;
640; SECOND OPERAND WAS MEMORY OR REGISTER
641;
642GRP21:
643 CMP BYTE PTR [SEGFLG],0
644 JZ GRP28 ; FIRST OPERAND WAS A SEGMENT REG
645 MOV AL,BYTE PTR [REGMEM]
646 TEST AL,10000B
647 JZ NOTSEG1
648ERRV3: JMP ASMERR
649NOTSEG1:AND AL,111B
650 OR BYTE PTR [DI+2],AL
651 AND BYTE PTR [DI+1],11111110B
652 CMP BYTE PTR [MEMFLG],0
653 JNZ G22V
654 JMP GRPEX
655
656GRP28: AND BYTE PTR [DI+2],11000111B
657 MOV AL,BYTE PTR [DI+1] ; GET FIRST OPCODE
658 AND AL,1B
659 CMP BYTE PTR [MOVFLG],0
660 JZ NOTMOV2
661 OR AL,10001000B
662 JMP SHORT MOV1
663NOTMOV2:CMP BYTE PTR [TSTFLG],0
664 JZ NOTTST2
665 OR AL,10000100B
666 CMP BYTE PTR [TSTFLG],2
667 JNZ NOTTST2
668 OR AL,10B
669NOTTST2:OR AL,BYTE PTR [MIDFLD] ; MIDFLD IS ZERO FOR TST
670MOV1: MOV BYTE PTR [DI+1],AL
671 CMP BYTE PTR [MEMFLG],0
672G22V: JNZ GRP22
673;
674; SECOND OPERAND WAS A REGISTER
675;
676 MOV AL,BYTE PTR [REGMEM]
677 TEST AL,10000B ; SEGMENT REGISTER?
678 JZ NOTSEG
679 CMP BYTE PTR [MOVFLG],0
680 JZ ERRV3
681 MOV BYTE PTR [DI+1],10001100B
682
683NOTSEG: AND AL,111B
684 SHL AL,1
685 SHL AL,1
686 SHL AL,1
687 OR BYTE PTR [DI+2],AL
688;
689; SPECIAL FORM OF THE EXCHANGE COMMAND
690;
691 CMP BYTE PTR [TSTFLG],2
692 JNZ GRPEX
693 TEST BYTE PTR [DI+1],1
694 JZ GRPEX
695 PUSH AX
696 MOV AL,BYTE PTR [DI+2]
697 AND AL,11000000B
698 CMP AL,11000000B ; MUST BE REGISTER TO REGISTER
699 POP AX
700 JB GRPEX
701 OR AL,AL
702 JZ SPECX
703 MOV AL,[DI+2]
704 AND AL,00000111B
705 JNZ GRPEX
706 MOV CL,3
707 SHR BYTE PTR [DI+2],CL
708SPECX: MOV AL,[DI+2]
709 AND AL,00000111B
710 OR AL,10010000B
711 MOV BYTE PTR [DI+1],AL
712 DEC BYTE PTR [DI]
713 JMP SHORT GRPEX
714;
715; SECOND OPERAND WAS A MEMORY REFERENCE
716;
717GRP22: CMP BYTE PTR [TSTFLG],0
718 JNZ TST2
719 OR BYTE PTR [DI+1],10B
720TST2: MOV AL,BYTE PTR [DI+2]
721 CMP AL,11000000B ; MUST BE A REGISTER
722 JB ASMERR
723 CMP BYTE PTR [SEGFLG],0
724 JZ GRP223
725 AND AL,00011000B
726 JMP SHORT GRP222
727GRP223: AND AL,111B
728 SHL AL,1
729 SHL AL,1
730 SHL AL,1
731GRP222: OR AL,BYTE PTR [MODE]
732 OR AL,BYTE PTR [REGMEM]
733 MOV BYTE PTR [DI+2],AL
734 MOV AX,WORD PTR [LOWNUM]
735 MOV WORD PTR [DI+3],AX
736GRPSIZ: MOV BYTE PTR [DI],2
737 MOV AL,BYTE PTR [DI+2]
738 AND AL,11000111B
739 CMP AL,00000110B
740 JZ GRP24
741 AND AL,11000000B
742 CMP AL,01000000B
743 JZ GRP25
744 CMP AL,10000000B
745 JNZ GRPEX
746GRP24: INC BYTE PTR [DI]
747GRP25: INC BYTE PTR [DI]
748
749GRPEX: CMP BYTE PTR [MOVFLG],0
750 JZ ASSEM_EXIT
751;
752; TEST FOR SPECIAL FORM OF MOV AX,[MEM] OR MOV [MEM],AX
753;
754 MOV AL,[DI+1] ; GET OP-CODE
755 AND AL,11111100B
756 CMP AL,10001000B
757 JNZ ASSEM_EXIT
758 CMP BYTE PTR [DI+2],00000110B ; MEM TO AX OR AX TO MEM
759 JNZ ASSEM_EXIT
760 MOV AL,BYTE PTR [DI+1]
761 AND AL,11B
762 XOR AL,10B
763 OR AL,10100000B
764 MOV BYTE PTR [DI+1],AL
765 DEC BYTE PTR [DI]
766 MOV AX,[DI+3]
767 MOV WORD PTR [DI+2],AX
768
769ASSEM_EXIT:
770 CALL STUFF_BYTES
771 JMP ASSEMLOOP
772
773; Assem error. SI points to character in the input buffer
774; which caused error. By subtracting from start of buffer,
775; we will know how far to tab over to appear directly below
776; it on the terminal. Then print "^ Error".
777
778ASMERR:
779 SUB SI,OFFSET DG:(BYTEBUF-10) ; How many char processed so far?
780 MOV CX,SI ; Parameter for TAB in CX
781 CALL TAB ; Directly below bad char
782 MOV SI,OFFSET DG:SYNERR ; Error message
783 CALL PRINTMES
784 JMP ASSEMLOOP
785;
786; assemble the different parts into an instruction
787;
788BUILDIT:
789 MOV AL,BYTE PTR [AWORD]
790 OR AL,AL
791 JNZ BUILD1
792BLDERR: JMP ASMERR
793
794BUILD1: DEC AL
795 OR BYTE PTR [DI+1],AL ; SET THE SIZE
796
797BUILD2: CMP BYTE PTR [NUMFLG],0 ; TEST FOR IMMEDIATE DATA
798 JZ BUILD3
799 CMP BYTE PTR [MEMFLG],0
800 JZ BLDERR
801
802BUILD3: MOV AL,BYTE PTR [REGMEM]
803 CMP AL,-1
804 JZ BLD1
805 TEST AL,10000B ; TEST IF SEGMENT REGISTER
806 JZ BLD1
807 CMP BYTE PTR [MOVFLG],0
808 JZ BLDERR
809 MOV WORD PTR [DI+1],10001110B
810 INC BYTE PTR [MOVFLG]
811 INC BYTE PTR [SEGFLG]
812 AND AL,00000011B
813 SHL AL,1
814 SHL AL,1
815 SHL AL,1
816 OR AL,BYTE PTR 11000000B
817 MOV BYTE PTR [DI+2],AL
818 RET
819
820BLD1: AND AL,00000111B
821BLD4: OR AL,BYTE PTR [MODE]
822 OR AL,BYTE PTR [MIDFLD]
823 MOV BYTE PTR [DI+2],AL
824 MOV AX,WORD PTR [LOWNUM]
825 MOV WORD PTR [DI+3],AX
826 RET
827
828GETREGMEM:
829 MOV BYTE PTR [F8087],0
830GETREGMEM2:
831 CALL SCANP
832 XOR AX,AX
833 MOV WORD PTR [LOWNUM],AX ; OFFSET
834 MOV WORD PTR [DIFLG],AX ; DIFLG+SIFLG
835 MOV WORD PTR [BXFLG],AX ; BXFLG+BPFLG
836 MOV WORD PTR [NEGFLG],AX ; NEGFLG+NUMFLG
837 MOV WORD PTR [MEMFLG],AX ; MEMFLG+REGFLG
838 DEC AL
839 CMP BYTE PTR [F8087],0
840 JZ PUTREG
841 MOV AL,1 ; DEFAULT 8087 REG IS 1
842PUTREG: MOV BYTE PTR [REGMEM],AL
843
844GETLOOP:MOV BYTE PTR [NEGFLG],0
845GETLOOP1:
846 MOV AX,WORD PTR [SI]
847 CMP AL,','
848 JZ GOMODE
849 CMP AL,13
850 JZ GOMODE
851 CMP AL,';'
852 JZ GOMODE
853 CMP AL,9
854 JZ GETTB
855 CMP AL,' '
856 JNZ GOGET
857GETTB: INC SI
858 JMP GETLOOP1
859GOGET: JMP GETINFO
860;
861; DETERMINE THE MODE BITS
862;
863GOMODE: MOV DI,OFFSET DG:ASSEM_CNT
864 MOV BYTE PTR [MODE],11000000B
865 MOV BYTE PTR [ASSEM_CNT],2
866 CMP BYTE PTR [MEMFLG],0
867 JNZ GOMODE1
868 MOV AL,[NUMFLG]
869 OR AL,[REGFLG]
870 JNZ MORET
871 OR AL,[F8087]
872 JZ ERRET
873 MOV AL,[DI+1]
874 OR AL,[DIRFLG]
875 CMP AL,0DCH ; ARITHMETIC?
876 JNZ MORET
877 MOV BYTE PTR [DI+1],0DEH ; ADD POP TO NULL ARG 8087
878MORET: RET
879ERRET: JMP ASMERR
880
881GOMODE1:MOV BYTE PTR [MODE],0
882 CMP BYTE PTR [NUMFLG],0
883 JZ GOREGMEM
884
885 MOV BYTE PTR [DI],4
886 MOV AX,WORD PTR [DIFLG]
887 OR AX,WORD PTR [BXFLG]
888 JNZ GOMODE2
889 MOV BYTE PTR [REGMEM],00000110B
890 RET
891
892GOMODE2:MOV BYTE PTR [MODE],10000000B
893 CALL CHKSIZ1
894 CMP CL,2
895 JZ GOREGMEM
896 DEC BYTE PTR [DI]
897 MOV BYTE PTR [MODE],01000000B
898;
899; DETERMINE THE REG-MEM BITS
900;
901GOREGMEM:
902 MOV BX,WORD PTR [BXFLG]
903 MOV CX,WORD PTR [DIFLG]
904 XOR DX,DX
905GOREG0:
906 MOV AL,BL ; BX
907 ADD AL,CH ; SI
908 CMP AL,2
909 JZ GOGO
910 INC DL
911 MOV AL,BL
912 ADD AL,CL
913 CMP AL,2
914 JZ GOGO
915 INC DL
916 MOV AL,BH
917 ADD AL,CH
918 CMP AL,2
919 JZ GOGO
920 INC DL
921 MOV AL,BH
922 ADD AL,CL
923 CMP AL,2
924 JZ GOGO
925 INC DL
926 OR CH,CH
927 JNZ GOGO
928 INC DL
929 OR CL,CL
930 JNZ GOGO
931 INC DL ; BP+DISP
932 OR BH,BH
933 JZ GOREG1
934 CMP BYTE PTR [MODE],0
935 JNZ GOGO
936 MOV BYTE PTR [MODE],01000000B
937 INC BYTE PTR [DI]
938 DEC DL
939GOREG1: INC DL ; BX+DISP
940GOGO: MOV BYTE PTR [REGMEM],DL
941 RET
942
943GETINFO:CMP AX,'EN' ; NEAR
944 JNZ GETREG3
945GETREG0:MOV DL,2
946GETRG01:CALL SETSIZ1
947GETREG1:CALL SCANS
948 MOV AX,WORD PTR [SI]
949 CMP AX,"TP" ; PTR
950 JZ GETREG1
951 JMP GETLOOP
952
953GETREG3:MOV CX,5
954 MOV DI,OFFSET DG:SIZ8
955 CALL CHKREG ; LOOK FOR BYTE, WORD, DWORD, ETC.
956 JZ GETREG41
957 INC AL
958 MOV DL,AL
959 JMP GETRG01
960
961GETREG41:
962 MOV AX,[SI]
963 CMP BYTE PTR [F8087],0
964 JZ GETREG5
965 CMP AX,"TS" ; 8087 STACK OPERAND
966 JNZ GETREG5
967 CMP BYTE PTR [SI+2],","
968 JNZ GETREG5
969 MOV BYTE PTR [DIRFLG],0
970 ADD SI,3
971 JMP GETLOOP
972
973GETREG5:CMP AX,"HS" ; SHORT
974 JZ GETREG1
975
976 CMP AX,"AF" ; FAR
977 JNZ GETRG51
978 CMP BYTE PTR [SI+2],"R"
979 JNZ GETRG51
980 ADD SI,3
981 MOV DL,4
982 JMP GETRG01
983
984GETRG51:CMP AL,'['
985 JNZ GETREG7
986GETREG6:INC BYTE PTR [MEMFLG]
987 INC SI
988 JMP GETLOOP
989
990GETREG7:CMP AL,']'
991 JZ GETREG6
992 CMP AL,'.'
993 JZ GETREG6
994 CMP AL,'+'
995 JZ GETREG6
996 CMP AL,'-'
997 JNZ GETREG8
998 INC BYTE PTR [NEGFLG]
999 INC SI
1000 JMP GETLOOP1
1001
1002GETREG8: ; LOOK FOR A REGISTER
1003 CMP BYTE PTR [F8087],0
1004 JZ GETREGREG
1005 CMP AX,"TS"
1006 JNZ GETREGREG
1007 CMP BYTE PTR [SI+2],"("
1008 JNZ GETREGREG
1009 CMP BYTE PTR [SI+4],")"
1010 JNZ ASMPOP
1011 MOV AL,[SI+3]
1012 SUB AL,"0"
1013 JB ASMPOP
1014 CMP AL,7
1015 JA ASMPOP
1016 MOV [REGMEM],AL
1017 INC BYTE PTR [REGFLG]
1018 ADD SI,5
1019 CMP WORD PTR [SI],"S,"
1020 JNZ ZLOOP
1021 CMP BYTE PTR [SI+2],"T"
1022 JNZ ZLOOP
1023 ADD SI,3
1024ZLOOP: JMP GETLOOP
1025
1026GETREGREG:
1027 MOV CX,20
1028 MOV DI,OFFSET DG:REG8
1029 CALL CHKREG
1030 JZ GETREG12 ; CX = 0 MEANS NO REGISTER
1031 MOV BYTE PTR [REGMEM],AL
1032 INC BYTE PTR [REGFLG] ; TELL EVERYONE WE FOUND A REG
1033 CMP BYTE PTR [MEMFLG],0
1034 JNZ NOSIZE
1035 CALL SETSIZ
1036INCSI2: ADD SI,2
1037 JMP GETLOOP
1038
1039NOSIZE: CMP AL,11 ; BX REGISTER?
1040 JNZ GETREG9
1041 CMP WORD PTR [BXFLG],0
1042 JZ GETOK
1043ASMPOP: JMP ASMERR
1044
1045GETOK: INC BYTE PTR [BXFLG]
1046 JMP INCSI2
1047GETREG9:
1048 CMP AL,13 ; BP REGISTER?
1049 JNZ GETREG10
1050 CMP WORD PTR [BXFLG],0
1051 JNZ ASMPOP
1052 INC BYTE PTR [BPFLG]
1053 JMP INCSI2
1054GETREG10:
1055 CMP AL,14 ; SI REGISTER?
1056 JNZ GETREG11
1057 CMP WORD PTR [DIFLG],0
1058 JNZ ASMPOP
1059 INC BYTE PTR [SIFLG]
1060 JMP INCSI2
1061GETREG11:
1062 CMP AL,15 ; DI REGISTER?
1063 JNZ ASMPOP ; *** error
1064 CMP WORD PTR [DIFLG],0
1065 JNZ ASMPOP
1066 INC BYTE PTR [DIFLG]
1067 JMP INCSI2
1068
1069GETREG12: ; BETTER BE A NUMBER!
1070 MOV BP,WORD PTR [ASMADD+2]
1071 CMP BYTE PTR [MEMFLG],0
1072 JZ GTRG121
1073GTRG119:MOV CX,4
1074GTRG120:CALL GETHX
1075 JMP SHORT GTRG122
1076GTRG121:MOV CX,2
1077 CMP BYTE PTR [AWORD],1
1078 JZ GTRG120
1079 CMP BYTE PTR [AWORD],CL
1080 JZ GTRG119
1081 CALL GET_ADDRESS
1082GTRG122:JC ASMPOP
1083 MOV [HINUM],AX
1084 CMP BYTE PTR [NEGFLG],0
1085 JZ GETREG13
1086 NEG DX
1087GETREG13:
1088 ADD WORD PTR [LOWNUM],DX
1089 INC BYTE PTR [NUMFLG]
1090GETLOOPV:
1091 JMP GETLOOP
1092
1093CHKREG: PUSH CX
1094 INC CX
1095 REPNZ SCASW
1096 POP AX
1097 SUB AX,CX
1098 OR CX,CX
1099 RET
1100
1101STUFF_BYTES:
1102 PUSH SI
1103 LES DI,DWORD PTR ASMADD
1104 MOV SI,OFFSET DG:ASSEM_CNT
1105 XOR AX,AX
1106 LODSB
1107 MOV CX,AX
1108 JCXZ STUFFRET
1109 REP MOVSB
1110 MOV WORD PTR [ASMADD],DI
1111STUFFRET:
1112 POP SI
1113 RET
1114
1115SETSIZ:
1116 MOV DL,1
1117 TEST AL,11000B ; 16 BIT OR SEGMENT REGISTER?
1118 JZ SETSIZ1
1119 INC DL
1120SETSIZ1:
1121 CMP BYTE PTR [AWORD],0
1122 JZ SETSIZ2
1123 CMP BYTE PTR [AWORD],DL
1124 JZ SETSIZ2
1125SETERR: POP DX
1126 JMP ASMPOP
1127SETSIZ2:MOV BYTE PTR [AWORD],DL
1128 RET
1129;
1130; DETERMINE IF NUMBER IN AX:DX IS 8 BITS, 16 BITS, OR 32 BITS
1131;
1132CHKSIZ: MOV CL,4
1133 CMP AX,BP
1134 JNZ RETCHK
1135CHKSIZ1:MOV CL,2
1136 MOV AX,DX
1137 CBW
1138 CMP AX,DX
1139 JNZ RETCHK
1140 DEC CL
1141RETCHK: RET
1142;
1143; get first character after first space
1144;
1145SCANS: CMP BYTE PTR [SI],13
1146 JZ RETCHK
1147 CMP BYTE PTR [SI],"["
1148 JZ RETCHK
1149 LODSB
1150 CMP AL," "
1151 JZ SCANBV
1152 CMP AL,9
1153 JNZ SCANS
1154SCANBV: JMP SCANB
1155;
1156; Set up for 8087 op-codes
1157;
1158SETMID:
1159 MOV BYTE PTR [ASSEM1],0D8H
1160 MOV AH,AL
1161 AND AL,111B ; SET MIDDLE BITS OF SECOND BYTE
1162 SHL AL,1
1163 SHL AL,1
1164 SHL AL,1
1165 MOV [MIDFLD],AL
1166 MOV AL,AH ; SET LOWER BITS OF FIRST BYTE
1167 SHR AL,1
1168 SHR AL,1
1169 SHR AL,1
1170 OR [ASSEM1],AL
1171 MOV BYTE PTR [F8087],1 ; INDICATE 8087 OPERAND
1172 MOV BYTE PTR [DIRFLG],100B
1173 RET
1174;
1175; Set MF bits for 8087 op-codes
1176;
1177SETMF: MOV AL,[AWORD]
1178 TEST BYTE PTR [DI+1],10B
1179 JNZ SETMFI
1180 AND BYTE PTR [DI+1],11111001B ; CLEAR MF BITS
1181 CMP AL,3 ; DWORD?
1182 JZ SETMFRET
1183 CMP AL,4 ; QWORD?
1184 JZ SETMFRET2
1185 TEST BYTE PTR [DI+1],1
1186 JZ SETMFERR
1187 CMP AL,5 ; TBYTE?
1188 JZ SETMFRET3
1189 JMP SHORT SETMFERR
1190
1191SETMFI: CMP AL,3 ; DWORD?
1192 JZ SETMFRET
1193 CMP AL,2 ; WORD?
1194 JZ SETMFRET2
1195 TEST BYTE PTR [DI+1],1
1196 JZ SETMFERR
1197 CMP AL,4 ; QWORD?
1198 JNZ SETMFERR
1199 OR BYTE PTR [DI+1],111B
1200SETMFRET3:
1201 OR BYTE PTR [DI+1],011B
1202 OR BYTE PTR [DI+2],101000B
1203 JMP SHORT SETMFRET
1204SETMFRET2:
1205 OR BYTE PTR [DI+1],100B
1206SETMFRET:
1207 RET
1208
1209SETMFERR:
1210 JMP ASMPOP
1211
1212
1213DW_OPER:
1214 MOV BP,1
1215 JMP SHORT DBEN
1216
1217DB_OPER:
1218 XOR BP,BP
1219DBEN: MOV DI,OFFSET DG:ASSEM_CNT
1220 DEC BYTE PTR [DI]
1221 INC DI
1222DB0: XOR BL,BL
1223 CALL SCANP
1224 JNZ DB1
1225DBEX: JMP ASSEM_EXIT
1226DB1: OR BL,BL
1227 JNZ DB3
1228 MOV BH,BYTE PTR [SI]
1229 CMP BH,"'"
1230 JZ DB2
1231 CMP BH,'"'
1232 JNZ DB4
1233DB2: INC SI
1234 INC BL
1235DB3: LODSB
1236 CMP AL,13
1237 JZ DBEX
1238 CMP AL,BH
1239 JZ DB0
1240 STOSB
1241 INC BYTE PTR [ASSEM_CNT]
1242 JMP DB3
1243DB4: MOV CX,2
1244 CMP BP,0
1245 JZ DB41
1246 MOV CL,4
1247DB41: PUSH BX
1248 CALL GETHX
1249 POP BX
1250 JNC DB5
1251 JMP ASMERR
1252DB5: MOV AX,DX
1253 CMP BP,0
1254 JZ DB6
1255 STOSW
1256 INC BYTE PTR [ASSEM_CNT]
1257 JMP SHORT DB7
1258DB6: STOSB
1259DB7: INC BYTE PTR [ASSEM_CNT]
1260 JMP DB0
1261
1262CODE ENDS
1263 END ASSEM
1264
diff --git a/v2.0/source/DEBCOM1.ASM b/v2.0/source/DEBCOM1.ASM
new file mode 100644
index 0000000..8e992d9
--- /dev/null
+++ b/v2.0/source/DEBCOM1.ASM
@@ -0,0 +1,694 @@
1TITLE PART1 DEBUGGER COMMANDS
2
3; Routines to perform debugger commands except ASSEMble and UASSEMble
4
5.xlist
6.xcref
7 INCLUDE DEBEQU.ASM
8 INCLUDE DOSSYM.ASM
9.cref
10.list
11
12CODE SEGMENT PUBLIC BYTE 'CODE'
13CODE ENDS
14
15CONST SEGMENT PUBLIC BYTE
16
17 EXTRN SYNERR:BYTE
18
19 EXTRN DISPB:WORD,DSIZ:BYTE,DSSAVE:WORD
20 if sysver
21 EXTRN CIN:DWORD,PFLAG:BYTE
22 endif
23
24CONST ENDS
25
26DATA SEGMENT PUBLIC BYTE
27
28 EXTRN DEFLEN:WORD,BYTEBUF:BYTE,DEFDUMP:BYTE
29
30DATA ENDS
31
32DG GROUP CODE,CONST,DATA
33
34
35CODE SEGMENT PUBLIC BYTE 'CODE'
36ASSUME CS:DG,DS:DG,ES:DG,SS:DG
37
38
39 PUBLIC HEXCHK,GETHEX1,PRINT,DSRANGE,ADDRESS,HEXIN,PERROR
40 PUBLIC GETHEX,GET_ADDRESS,GETEOL,GETHX,PERR
41 PUBLIC PERR,MOVE,DUMP,ENTER,FILL,SEARCH,DEFAULT
42 if sysver
43 PUBLIC IN
44 EXTRN DISPREG:NEAR,DEVIOCALL:NEAR
45 endif
46
47 EXTRN OUT:NEAR,CRLF:NEAR,OUTDI:NEAR,OUTSI:NEAR,SCANP:NEAR
48 EXTRN SCANB:NEAR,BLANK:NEAR,TAB:NEAR,PRINTMES:NEAR,COMMAND:NEAR
49 EXTRN HEX:NEAR,BACKUP:NEAR
50
51
52DEBCOM1:
53
54; RANGE - Looks for parameters defining an address range.
55; The first parameter is the starting address. The second parameter
56; may specify the ending address, or it may be preceded by
57; "L" and specify a length (4 digits max), or it may be
58; omitted and a length of 128 bytes is assumed. Returns with
59; segment in AX, displacement in DX, and length in CX.
60
61DSRANGE:
62 MOV BP,[DSSAVE] ; Set default segment to DS
63 MOV [DEFLEN],128 ; And default length to 128 bytes
64RANGE:
65 CALL ADDRESS
66 PUSH AX ; Save segment
67 PUSH DX ; Save offset
68 CALL SCANP ; Get to next parameter
69 MOV AL,[SI]
70 CMP AL,"L" ; Length indicator?
71 JE GETLEN
72 MOV DX,[DEFLEN] ; Default length
73 CALL HEXIN ; Second parameter present?
74 JC GetDef ; If not, use default
75 MOV CX,4
76 CALL GETHEX ; Get ending address (same segment)
77 MOV CX,DX ; Low 16 bits of ending addr.
78 POP DX ; Low 16 bits of starting addr.
79 SUB CX,DX ; Compute range
80 JAE DSRNG2
81DSRNG1: JMP PERROR ; Negative range
82DSRNG2: INC CX ; Include last location
83 JCXZ DSRNG1 ; Wrap around error
84 POP AX ; Restore segment
85 RET
86GetDef:
87 POP CX ; get original offset
88 PUSH CX ; save it
89 NEG CX ; rest of segment
90 JZ RngRet ; use default
91 CMP CX,DX ; more room in segment?
92 JAE RngRet ; yes, use default
93 JMP RngRet1 ; no, length is in CX
94
95GETLEN:
96 INC SI ; Skip over "L" to length
97 MOV CX,4 ; Length may have 4 digits
98 CALL GETHEX ; Get the range
99RNGRET:
100 MOV CX,DX ; Length
101RngRet1:
102 POP DX ; Offset
103 MOV AX,CX
104 ADD AX,DX
105 JNC OKRET
106 CMP AX,1
107 JAE DSRNG1 ; Look for wrap error
108OKRET:
109 POP AX ; Segment
110 RET
111
112DEFAULT:
113; DI points to default address and CX has default length
114 CALL SCANP
115 JZ USEDEF ; Use default if no parameters
116 MOV [DEFLEN],CX
117 CALL RANGE
118 JMP GETEOL
119USEDEF:
120 MOV SI,DI
121 LODSW ; Get default displacement
122 MOV DX,AX
123 LODSW ; Get default segment
124 RET
125
126; Dump an area of memory in both hex and ASCII
127
128DUMP:
129 MOV BP,[DSSAVE]
130 MOV CX,DISPB
131 MOV DI,OFFSET DG:DEFDUMP
132 CALL DEFAULT ; Get range if specified
133 MOV DS,AX ; Set segment
134 MOV SI,DX ; SI has displacement in segment
135
136 IF ZIBO
137 PUSH SI ; save SI away
138 AND SI,0FFF0h ; convert to para number
139 CALL OutSI ; display location
140 POP SI ; get SI back
141 MOV AX,SI ; move offset
142 MOV AH,3 ; spaces per byte
143 AND AL,0Fh ; convert to real offset
144 MUL AH ; compute (AL+1)*3-1
145 OR AL,AL ; set flag
146 JZ InRow ; if xero go on
147 PUSH CX ; save count
148 MOV CX,AX ; move to convenient spot
149 CALL Tab ; move over
150 POP CX ; get back count
151 JMP InRow ; display line
152 ENDIF
153
154ROW:
155 CALL OUTSI ; Print address at start of line
156InRow:
157 PUSH SI ; Save address for ASCII dump
158 CALL BLANK
159BYTE0:
160 CALL BLANK ; Space between bytes
161BYTE1:
162 LODSB ; Get byte to dump
163 CALL HEX ; and display it
164 POP DX ; DX has start addr. for ASCII dump
165 DEC CX ; Drop loop count
166 JZ ToAscii ; If through do ASCII dump
167 MOV AX,SI
168 TEST AL,CS:(BYTE PTR DSIZ) ; On 16-byte boundary?
169 JZ ENDROW
170 PUSH DX ; Didn't need ASCII addr. yet
171 TEST AL,7 ; On 8-byte boundary?
172 JNZ BYTE0
173 MOV AL,"-" ; Mark every 8 bytes
174 CALL OUT
175 JMP SHORT BYTE1
176ENDROW:
177 CALL ASCII ; Show it in ASCII
178 JMP SHORT ROW ; Loop until count is zero
179ToAscii:
180 MOV AX,SI ; get offset
181 AND AL,0Fh ; real offset
182 JZ ASCII ; no loop if already there
183 SUB AL,10h ; remainder
184 NEG AL
185 MOV CL,3
186 MUL CL
187 MOV CX,AX ; number of chars to move
188 CALL Tab
189ASCII:
190 PUSH CX ; Save byte count
191 MOV AX,SI ; Current dump address
192 MOV SI,DX ; ASCII dump address
193 SUB AX,DX ; AX=length of ASCII dump
194 IF NOT ZIBO
195; Compute tab length. ASCII dump always appears on right side
196; screen regardless of how many bytes were dumped. Figure 3
197; characters for each byte dumped and subtract from 51, which
198; allows a minimum of 3 blanks after the last byte dumped.
199 MOV BX,AX
200 SHL AX,1 ; Length times 2
201 ADD AX,BX ; Length times 3
202 MOV CX,51
203 SUB CX,AX ; Amount to tab in CX
204 CALL TAB
205 MOV CX,BX ; ASCII dump length back in CX
206 ELSE
207 MOV CX,SI ; get starting point
208 DEC CX
209 AND CX,0Fh
210 INC CX
211 AND CX,0Fh
212 ADD CX,3 ; we have the correct number to tab
213 PUSH AX ; save count
214 CALL TAB
215 POP CX ; get count back
216 ENDIF
217ASCDMP:
218 LODSB ; Get ASCII byte to dump
219 AND AL,7FH ; ASCII uses 7 bits
220 CMP AL,7FH ; Don't try to print RUBOUT
221 JZ NOPRT
222 CMP AL," " ; Check for control characters
223 JNC PRIN
224NOPRT:
225 MOV AL,"." ; If unprintable character
226PRIN:
227 CALL OUT ; Print ASCII character
228 LOOP ASCDMP ; CX times
229 POP CX ; Restore overall dump length
230 MOV ES:WORD PTR [DEFDUMP],SI
231 MOV ES:WORD PTR [DEFDUMP+2],DS ; Save last address as default
232 CALL CRLF ; Print CR/LF and return
233 RET
234
235
236; Block move one area of memory to another. Overlapping moves
237; are performed correctly, i.e., so that a source byte is not
238; overwritten until after it has been moved.
239
240MOVE:
241 CALL DSRANGE ; Get range of source area
242 PUSH CX ; Save length
243 PUSH AX ; Save segment
244 PUSH DX ; Save source displacement
245 CALL ADDRESS ; Get destination address (same segment)
246 CALL GETEOL ; Check for errors
247 POP SI
248 MOV DI,DX ; Set dest. displacement
249 POP BX ; Source segment
250 MOV DS,BX
251 MOV ES,AX ; Destination segment
252 POP CX ; Length
253 CMP DI,SI ; Check direction of move
254 SBB AX,BX ; Extend the CMP to 32 bits
255 JB COPYLIST ; Move forward into lower mem.
256; Otherwise, move backward. Figure end of source and destination
257; areas and flip direction flag.
258 DEC CX
259 ADD SI,CX ; End of source area
260 ADD DI,CX ; End of destination area
261 STD ; Reverse direction
262 INC CX
263COPYLIST:
264 MOVSB ; Do at least 1 - Range is 1-10000H not 0-FFFFH
265 DEC CX
266 REP MOVSB ; Block move
267RET1: RET
268
269; Fill an area of memory with a list values. If the list
270; is bigger than the area, don't use the whole list. If the
271; list is smaller, repeat it as many times as necessary.
272
273FILL:
274 CALL DSRANGE ; Get range to fill
275 PUSH CX ; Save length
276 PUSH AX ; Save segment number
277 PUSH DX ; Save displacement
278 CALL LIST ; Get list of values to fill with
279 POP DI ; Displacement in segment
280 POP ES ; Segment
281 POP CX ; Length
282 CMP BX,CX ; BX is length of fill list
283 MOV SI,OFFSET DG:BYTEBUF ; List is in byte buffer
284 JCXZ BIGRNG
285 JAE COPYLIST ; If list is big, copy part of it
286BIGRNG:
287 SUB CX,BX ; How much bigger is area than list?
288 XCHG CX,BX ; CX=length of list
289 PUSH DI ; Save starting addr. of area
290 REP MOVSB ; Move list into area
291 POP SI
292; The list has been copied into the beginning of the
293; specified area of memory. SI is the first address
294; of that area, DI is the end of the copy of the list
295; plus one, which is where the list will begin to repeat.
296; All we need to do now is copy [SI] to [DI] until the
297; end of the memory area is reached. This will cause the
298; list to repeat as many times as necessary.
299 MOV CX,BX ; Length of area minus list
300 PUSH ES ; Different index register
301 POP DS ; requires different segment reg.
302 JMP SHORT COPYLIST ; Do the block move
303
304; Search a specified area of memory for given list of bytes.
305; Print address of first byte of each match.
306
307SEARCH:
308 CALL DSRANGE ; Get area to be searched
309 PUSH CX ; Save count
310 PUSH AX ; Save segment number
311 PUSH DX ; Save displacement
312 CALL LIST ; Get search list
313 DEC BX ; No. of bytes in list-1
314 POP DI ; Displacement within segment
315 POP ES ; Segment
316 POP CX ; Length to be searched
317 SUB CX,BX ; minus length of list
318SCAN:
319 MOV SI,OFFSET DG:BYTEBUF ; List kept in byte buffer
320 LODSB ; Bring first byte into AL
321DOSCAN:
322 SCASB ; Search for first byte
323 LOOPNE DOSCAN ; Do at least once by using LOOP
324 JNZ RET1 ; Exit if not found
325 PUSH BX ; Length of list minus 1
326 XCHG BX,CX
327 PUSH DI ; Will resume search here
328 REPE CMPSB ; Compare rest of string
329 MOV CX,BX ; Area length back in CX
330 POP DI ; Next search location
331 POP BX ; Restore list length
332 JNZ TEST ; Continue search if no match
333 DEC DI ; Match address
334 CALL OUTDI ; Print it
335 INC DI ; Restore search address
336 CALL CRLF
337TEST:
338 JCXZ RET1
339 JMP SHORT SCAN ; Look for next occurrence
340
341; Get the next parameter, which must be a hex number.
342; CX is maximum number of digits the number may have.
343
344GETHX:
345 CALL SCANP
346GETHX1:
347 XOR DX,DX ; Initialize the number
348 CALL HEXIN ; Get a hex digit
349 JC HXERR ; Must be one valid digit
350 MOV DL,AL ; First 4 bits in position
351GETLP:
352 INC SI ; Next char in buffer
353 DEC CX ; Digit count
354 CALL HEXIN ; Get another hex digit?
355 JC RETHX ; All done if no more digits
356 STC
357 JCXZ HXERR ; Too many digits?
358 SHL DX,1 ; Multiply by 16
359 SHL DX,1
360 SHL DX,1
361 SHL DX,1
362 OR DL,AL ; and combine new digit
363 JMP SHORT GETLP ; Get more digits
364
365GETHEX:
366 CALL GETHX ; Scan to next parameter
367 JMP SHORT GETHX2
368GETHEX1:
369 CALL GETHX1
370GETHX2: JC PERROR
371RETHX: CLC
372HXERR: RET
373
374
375; Check if next character in the input buffer is a hex digit
376; and convert it to binary if it is. Carry set if not.
377
378HEXIN:
379 MOV AL,[SI]
380
381; Check if AL has a hex digit and convert it to binary if it
382; is. Carry set if not.
383
384HEXCHK:
385 SUB AL,"0" ; Kill ASCII numeric bias
386 JC RET2
387 CMP AL,10
388 CMC
389 JNC RET2 ; OK if 0-9
390 AND AL,5FH
391 SUB AL,7 ; Kill A-F bias
392 CMP AL,10
393 JC RET2
394 CMP AL,16
395 CMC
396RET2: RET
397
398; Process one parameter when a list of bytes is
399; required. Carry set if parameter bad. Called by LIST.
400
401LISTITEM:
402 CALL SCANP ; Scan to parameter
403 CALL HEXIN ; Is it in hex?
404 JC STRINGCHK ; If not, could be a string
405 MOV CX,2 ; Only 2 hex digits for bytes
406 CALL GETHEX ; Get the byte value
407 MOV [BX],DL ; Add to list
408 INC BX
409GRET: CLC ; Parameter was OK
410 RET
411STRINGCHK:
412 MOV AL,[SI] ; Get first character of param
413 CMP AL,"'" ; String?
414 JZ STRING
415 CMP AL,'"' ; Either quote is all right
416 JZ STRING
417 STC ; Not string, not hex - bad
418 RET
419STRING:
420 MOV AH,AL ; Save for closing quote
421 INC SI
422STRNGLP:
423 LODSB ; Next char of string
424 CMP AL,13 ; Check for end of line
425 JZ PERR ; Must find a close quote
426 CMP AL,AH ; Check for close quote
427 JNZ STOSTRG ; Add new character to list
428 CMP AH,[SI] ; Two quotes in a row?
429 JNZ GRET ; If not, we're done
430 INC SI ; Yes - skip second one
431STOSTRG:
432 MOV [BX],AL ; Put new char in list
433 INC BX
434 JMP SHORT STRNGLP ; Get more characters
435
436; Get a byte list for ENTER, FILL or SEARCH. Accepts any number
437; of 2-digit hex values or character strings in either single
438; (') or double (") quotes.
439
440LIST:
441 MOV BX,OFFSET DG:BYTEBUF ; Put byte list in the byte buffer
442LISTLP:
443 CALL LISTITEM ; Process a parameter
444 JNC LISTLP ; If OK, try for more
445 SUB BX,OFFSET DG:BYTEBUF ; BX now has no. of bytes in list
446 JZ PERROR ; List must not be empty
447
448; Make sure there is nothing more on the line except for
449; blanks and carriage return. If there is, it is an
450; unrecognized parameter and an error.
451
452GETEOL:
453 CALL SCANB ; Skip blanks
454 JNZ PERROR ; Better be a RETURN
455RET3: RET
456
457; Command error. SI has been incremented beyond the
458; command letter so it must decremented for the
459; error pointer to work.
460
461PERR:
462 DEC SI
463
464; Syntax error. SI points to character in the input buffer
465; which caused error. By subtracting from start of buffer,
466; we will know how far to tab over to appear directly below
467; it on the terminal. Then print "^ Error".
468
469PERROR:
470 SUB SI,OFFSET DG:(BYTEBUF-1); How many char processed so far?
471 MOV CX,SI ; Parameter for TAB in CX
472 CALL TAB ; Directly below bad char
473 MOV SI,OFFSET DG:SYNERR ; Error message
474
475; Print error message and abort to command level
476
477PRINT:
478 CALL PRINTMES
479 JMP COMMAND
480
481; Gets an address in Segment:Displacement format. Segment may be omitted
482; and a default (kept in BP) will be used, or it may be a segment
483; register (DS, ES, SS, CS). Returns with segment in AX, OFFSET in DX.
484
485ADDRESS:
486 CALL GET_ADDRESS
487 JC PERROR
488ADRERR: STC
489 RET
490
491GET_ADDRESS:
492 CALL SCANP
493 MOV AL,[SI+1]
494 CMP AL,"S"
495 JZ SEGREG
496 MOV CX,4
497 CALL GETHX
498 JC ADRERR
499 MOV AX,BP ; Get default segment
500 CMP BYTE PTR [SI],":"
501 JNZ GETRET
502 PUSH DX
503GETDISP:
504 INC SI ; Skip over ":"
505 MOV CX,4
506 CALL GETHX
507 POP AX
508 JC ADRERR
509GETRET: CLC
510 RET
511SEGREG:
512 MOV AL,[SI]
513 MOV DI,OFFSET DG:SEGLET
514 MOV CX,4
515 REPNE SCASB
516 JNZ ADRERR
517 INC SI
518 INC SI
519 SHL CX,1
520 MOV BX,CX
521 CMP BYTE PTR [SI],":"
522 JNZ ADRERR
523 PUSH [BX+DSSAVE]
524 JMP SHORT GETDISP
525
526SEGLET DB "CSED"
527
528; Short form of ENTER command. A list of values from the
529; command line are put into memory without using normal
530; ENTER mode.
531
532GETLIST:
533 CALL LIST ; Get the bytes to enter
534 POP DI ; Displacement within segment
535 POP ES ; Segment to enter into
536 MOV SI,OFFSET DG:BYTEBUF ; List of bytes is in byte 2uffer
537 MOV CX,BX ; Count of bytes
538 REP MOVSB ; Enter that byte list
539 RET
540
541; Enter values into memory at a specified address. If the
542; line contains nothing but the address we go into "enter
543; mode", where the address and its current value are printed
544; and the user may change it if desired. To change, type in
545; new value in hex. Backspace works to correct errors. If
546; an illegal hex digit or too many digits are typed, the
547; bell is sounded but it is otherwise ignored. To go to the
548; next byte (with or without change), hit space bar. To
549; back CLDto a previous address, type "-". On
550; every 8-byte boundary a new line is started and the address
551; is printed. To terminate command, type carriage return.
552; Alternatively, the list of bytes to be entered may be
553; included on the original command line immediately following
554; the address. This is in regular LIST format so any number
555; of hex values or strings in quotes may be entered.
556
557ENTER:
558 MOV BP,[DSSAVE] ; Set default segment to DS
559 CALL ADDRESS
560 PUSH AX ; Save for later
561 PUSH DX
562 CALL SCANB ; Any more parameters?
563 JNZ GETLIST ; If not end-of-line get list
564 POP DI ; Displacement of ENTER
565 POP ES ; Segment
566GETROW:
567 CALL OUTDI ; Print address of entry
568 CALL BLANK ; Leave a space
569 CALL BLANK
570GETBYTE:
571 MOV AL,ES:[DI] ; Get current value
572 CALL HEX ; And display it
573PUTDOT:
574 MOV AL,"."
575 CALL OUT ; Prompt for new value
576 MOV CX,2 ; Max of 2 digits in new value
577 MOV DX,0 ; Intial new value
578GETDIG:
579 CALL IN ; Get digit from user
580 MOV AH,AL ; Save
581 CALL HEXCHK ; Hex digit?
582 XCHG AH,AL ; Need original for echo
583 JC NOHEX ; If not, try special command
584 MOV DH,DL ; Rotate new value
585 MOV DL,AH ; And include new digit
586 LOOP GETDIG ; At most 2 digits
587; We have two digits, so all we will accept now is a command.
588DWAIT:
589 CALL IN ; Get command character
590NOHEX:
591 CMP AL,8 ; Backspace
592 JZ BS
593 CMP AL,7FH ; RUBOUT
594 JZ RUB
595 CMP AL,"-" ; Back CLDto previous address
596 JZ PREV
597 CMP AL,13 ; All done with command?
598 JZ EOL
599 CMP AL," " ; Go to next address
600 JZ NEXT
601 MOV AL,8
602 CALL OUT ; Back CLDover illegal character
603 CALL BACKUP
604 JCXZ DWAIT
605 JMP SHORT GETDIG
606
607RUB:
608 MOV AL,8
609 CALL OUT
610BS:
611 CMP CL,2 ; CX=2 means nothing typed yet
612 JZ PUTDOT ; Put back the dot we backed CLDover
613 INC CL ; Accept one more character
614 MOV DL,DH ; Rotate out last digit
615 MOV DH,CH ; Zero this digit
616 CALL BACKUP ; Physical backspace
617 JMP SHORT GETDIG ; Get more digits
618
619; If new value has been entered, convert it to binary and
620; put into memory. Always bump pointer to next location
621
622STORE:
623 CMP CL,2 ; CX=2 means nothing typed yet
624 JZ NOSTO ; So no new value to store
625; Rotate DH left 4 bits to combine with DL and make a byte value
626 PUSH CX
627 MOV CL,4
628 SHL DH,CL
629 POP CX
630 OR DL,DH ; Hex is now converted to binary
631 MOV ES:[DI],DL ; Store new value
632NOSTO:
633 INC DI ; Prepare for next location
634 RET
635NEXT:
636 CALL STORE ; Enter new value
637 INC CX ; Leave a space plus two for
638 INC CX ; each digit not entered
639 CALL TAB
640 MOV AX,DI ; Next memory address
641 AND AL,7 ; Check for 8-byte boundary
642 JNZ GETBYTE ; Take 8 per line
643NEWROW:
644 CALL CRLF ; Terminate line
645 JMP GETROW ; Print address on new line
646PREV:
647 CALL STORE ; Enter the new value
648; DI has been bumped to next byte. Drop it 2 to go to previous addr
649 DEC DI
650 DEC DI
651 JMP SHORT NEWROW ; Terminate line after backing CLD
652
653EOL:
654 CALL STORE ; Enter the new value
655 JMP CRLF ; CR/LF and terminate
656
657; Console input of single character
658
659 IF SYSVER
660IN:
661 PUSH DS
662 PUSH SI
663 LDS SI,CS:[CIN]
664 MOV AH,4
665 CALL DEVIOCALL
666 POP SI
667 POP DS
668 CMP AL,3
669 JNZ NOTCNTC
670 INT 23H
671NOTCNTC:
672 CMP AL,'P'-'@'
673 JZ PRINTON
674 CMP AL,'N'-'@'
675 JZ PRINTOFF
676 CALL OUT
677 RET
678
679PRINTOFF:
680PRINTON:
681 NOT [PFLAG]
682 JMP SHORT IN
683
684 ELSE
685
686IN:
687 MOV AH,1
688 INT 21H
689 RET
690 ENDIF
691
692CODE ENDS
693 END DEBCOM1
694
diff --git a/v2.0/source/DEBCOM2.ASM b/v2.0/source/DEBCOM2.ASM
new file mode 100644
index 0000000..a800d4b
--- /dev/null
+++ b/v2.0/source/DEBCOM2.ASM
@@ -0,0 +1,1269 @@
1TITLE PART2 DEBUGGER COMMANDS
2
3; Routines to perform debugger commands except ASSEMble and UASSEMble
4
5.xlist
6.xcref
7 INCLUDE DEBEQU.ASM
8 INCLUDE DOSSYM.ASM
9.cref
10.list
11
12CODE SEGMENT PUBLIC BYTE 'CODE'
13CODE ENDS
14
15CONST SEGMENT PUBLIC BYTE
16
17 EXTRN NOTFND:BYTE,NOROOM:BYTE,DRVLET:BYTE,NOSPACE:BYTE,NAMBAD:BYTE
18 EXTRN TOOBIG:BYTE,ERRMES:BYTE
19 EXTRN EXEBAD:BYTE,HEXERR:BYTE,EXEWRT:BYTE,HEXWRT:BYTE
20 EXTRN EXECEMES:BYTE,WRTMES1:BYTE,WRTMES2:BYTE,ACCMES:BYTE
21
22 EXTRN FLAGTAB:WORD,EXEC_BLOCK:BYTE,COM_LINE:DWORD,COM_FCB1:DWORD
23 EXTRN COM_FCB2:DWORD,COM_SSSP:DWORD,COM_CSIP:DWORD,RETSAVE:WORD
24 EXTRN NEWEXEC:BYTE,HEADSAVE:WORD
25 EXTRN REGTAB:BYTE,TOTREG:BYTE,NOREGL:BYTE
26 EXTRN USER_PROC_PDB:WORD,STACK:BYTE,RSTACK:WORD,AXSAVE:WORD
27 EXTRN BXSAVE:WORD,DSSAVE:WORD,ESSAVE:WORD,CSSAVE:WORD,IPSAVE:WORD
28 EXTRN SSSAVE:WORD,CXSAVE:WORD,SPSAVE:WORD,FSAVE:WORD
29 EXTRN SREG:BYTE,SEGTAB:WORD,REGDIF:WORD,RDFLG:BYTE
30
31CONST ENDS
32
33DATA SEGMENT PUBLIC BYTE
34
35 EXTRN DEFDUMP:BYTE,TRANSADD:DWORD,INDEX:WORD,BUFFER:BYTE
36 EXTRN ASMADD:BYTE,DISADD:BYTE,NSEG:WORD,BPTAB:BYTE
37 EXTRN BRKCNT:WORD,TCOUNT:WORD,SWITCHAR:BYTE,XNXCMD:BYTE,XNXOPT:BYTE
38 EXTRN AWORD:BYTE,EXTPTR:WORD,HANDLE:WORD,PARSERR:BYTE
39
40DATA ENDS
41
42DG GROUP CODE,CONST,DATA
43
44
45CODE SEGMENT PUBLIC BYTE 'CODE'
46ASSUME CS:DG,DS:DG,ES:DG,SS:DG
47
48 PUBLIC DEFIO,SKIP_FILE,PREPNAME,DEBUG_FOUND
49 PUBLIC REG,COMPARE,GO,INPUT,LOAD
50 PUBLIC NAME,OUTPUT,TRACE,ZTRACE,DWRITE
51 if sysver
52 PUBLIC DISPREG
53 endif
54
55 EXTRN GETHEX:NEAR,GETEOL:NEAR
56 EXTRN CRLF:NEAR,BLANK:NEAR,OUT:NEAR
57 EXTRN OUTSI:NEAR,OUTDI:NEAR,INBUF:NEAR,SCANB:NEAR,SCANP:NEAR
58 EXTRN RPRBUF:NEAR,HEX:NEAR,OUT16:NEAR,DIGIT:NEAR
59 EXTRN COMMAND:NEAR,DISASLN:NEAR,SET_TERMINATE_VECTOR:NEAR
60 EXTRN RESTART:NEAR,DABORT:NEAR,TERMINATE:NEAR,DRVERR:NEAR
61 EXTRN FIND_DEBUG:NEAR,NMIInt:NEAR,NMIIntEnd:NEAR
62 EXTRN HEXCHK:NEAR,GETHEX1:NEAR,PRINT:NEAR,DSRANGE:NEAR
63 EXTRN ADDRESS:NEAR,HEXIN:NEAR,PERROR:NEAR
64
65
66DEBCOM2:
67DISPREG:
68 MOV SI,OFFSET DG:REGTAB
69 MOV BX,OFFSET DG:AXSAVE
70 MOV BYTE PTR TOTREG,13
71 MOV CH,0
72 MOV CL,NOREGL
73REPDISP:
74 SUB TOTREG,CL
75 CALL DISPREGLINE
76 CALL CRLF
77 MOV CH,0
78 MOV CL,NOREGL
79 CMP CL,TOTREG
80 JL REPDISP
81 MOV CL,TOTREG
82 CALL DISPREGLINE
83 CALL BLANK
84 CALL DISPFLAGS
85 CALL CRLF
86 MOV AX,[IPSAVE]
87 MOV WORD PTR [DISADD],AX
88 PUSH AX
89 MOV AX,[CSSAVE]
90 MOV WORD PTR [DISADD+2],AX
91 PUSH AX
92 MOV [NSEG],-1
93 CALL DISASLN
94 POP WORD PTR DISADD+2
95 POP WORD PTR DISADD
96 MOV AX,[NSEG]
97 CMP AL,-1
98 JZ CRLFJ
99 CMP AH,-1
100 JZ NOOVER
101 XCHG AL,AH
102NOOVER:
103 CBW
104 MOV BX,AX
105 SHL BX,1
106 MOV AX,WORD PTR [BX+SREG]
107 CALL OUT
108 XCHG AL,AH
109 CALL OUT
110 MOV AL,":"
111 CALL OUT
112 MOV DX,[INDEX]
113 CALL OUT16
114 MOV AL,"="
115 CALL OUT
116 MOV BX,[BX+SEGTAB]
117 PUSH DS
118 MOV DS,[BX]
119 MOV BX,DX
120 MOV DX,[BX]
121 POP DS
122 TEST BYTE PTR [AWORD],-1
123 JZ OUT8
124 CALL OUT16
125CRLFJ:
126 JMP CRLF
127OUT8:
128 MOV AL,DL
129 CALL HEX
130 JMP CRLF
131
132DISPREGJ:JMP DISPREG
133
134; Perform register dump if no parameters or set register if a
135; register designation is a parameter.
136
137REG:
138 CALL SCANP
139 JZ DISPREGJ
140 MOV DL,[SI]
141 INC SI
142 MOV DH,[SI]
143 CMP DH,13
144 JZ FLAG
145 INC SI
146 CALL GETEOL
147 CMP DH," "
148 JZ FLAG
149 MOV DI,OFFSET DG:REGTAB
150 XCHG AX,DX
151 PUSH CS
152 POP ES
153 MOV CX,REGTABLEN
154 REPNZ SCASW
155 JNZ BADREG
156 OR CX,CX
157 JNZ NOTPC
158 DEC DI
159 DEC DI
160 MOV AX,CS:[DI-2]
161NOTPC:
162 CALL OUT
163 MOV AL,AH
164 CALL OUT
165 CALL BLANK
166 PUSH DS
167 POP ES
168 LEA BX,[DI+REGDIF-2]
169 MOV DX,[BX]
170 CALL OUT16
171 CALL CRLF
172 MOV AL,":"
173 CALL OUT
174 CALL INBUF
175 CALL SCANB
176 JZ RET4
177 MOV CX,4
178 CALL GETHEX1
179 CALL GETEOL
180 MOV [BX],DX
181RET4: RET
182BADREG:
183 MOV AX,5200H+"B" ; BR ERROR
184 JMP ERR
185FLAG:
186 CMP DL,"F"
187 JNZ BADREG
188 CALL DISPFLAGS
189 MOV AL,"-"
190 CALL OUT
191 CALL INBUF
192 CALL SCANB
193 XOR BX,BX
194 MOV DX,[FSAVE]
195GETFLG:
196 LODSW
197 CMP AL,13
198 JZ SAVCHG
199 CMP AH,13
200 JZ FLGERR
201 MOV DI,OFFSET DG:FLAGTAB
202 MOV CX,32
203 PUSH CS
204 POP ES
205 REPNE SCASW
206 JNZ FLGERR
207 MOV CH,CL
208 AND CL,0FH
209 MOV AX,1
210 ROL AX,CL
211 TEST AX,BX
212 JNZ REPFLG
213 OR BX,AX
214 OR DX,AX
215 TEST CH,16
216 JNZ NEXFLG
217 XOR DX,AX
218NEXFLG:
219 CALL SCANP
220 JMP SHORT GETFLG
221DISPREGLINE:
222 LODS CS:WORD PTR [SI]
223 CALL OUT
224 MOV AL,AH
225 CALL OUT
226 MOV AL,"="
227 CALL OUT
228 MOV DX,[BX]
229 INC BX
230 INC BX
231 CALL OUT16
232 CALL BLANK
233 CALL BLANK
234 LOOP DISPREGLINE
235 RET
236REPFLG:
237 MOV AX,4600H+"D" ; DF ERROR
238FERR:
239 CALL SAVCHG
240ERR:
241 CALL OUT
242 MOV AL,AH
243 CALL OUT
244 MOV SI,OFFSET DG:ERRMES
245 JMP PRINT
246SAVCHG:
247 MOV [FSAVE],DX
248 RET
249FLGERR:
250 MOV AX,4600H+"B" ; BF ERROR
251 JMP SHORT FERR
252DISPFLAGS:
253 MOV SI,OFFSET DG:FLAGTAB
254 MOV CX,16
255 MOV DX,[FSAVE]
256DFLAGS:
257 LODS CS:WORD PTR [SI]
258 SHL DX,1
259 JC FLAGSET
260 MOV AX,CS:[SI+30]
261FLAGSET:
262 OR AX,AX
263 JZ NEXTFLG
264 CALL OUT
265 MOV AL,AH
266 CALL OUT
267 CALL BLANK
268NEXTFLG:
269 LOOP DFLAGS
270 RET
271
272; Input from the specified port and display result
273
274INPUT:
275 MOV CX,4 ; Port may have 4 digits
276 CALL GETHEX ; Get port number in DX
277 CALL GETEOL
278 IN AL,DX ; Variable port input
279 CALL HEX ; And display
280 JMP CRLF
281
282; Output a value to specified port.
283
284OUTPUT:
285 MOV CX,4 ; Port may have 4 digits
286 CALL GETHEX ; Get port number
287 PUSH DX ; Save while we get data
288 MOV CX,2 ; Byte output only
289 CALL GETHEX ; Get data to output
290 CALL GETEOL
291 XCHG AX,DX ; Output data in AL
292 POP DX ; Port in DX
293 OUT DX,AL ; Variable port output
294RET5: RET
295COMPARE:
296 CALL DSRANGE
297 PUSH CX
298 PUSH AX
299 PUSH DX
300 CALL ADDRESS ; Same segment
301 CALL GETEOL
302 POP SI
303 MOV DI,DX
304 MOV ES,AX
305 POP DS
306 POP CX ; Length
307 DEC CX
308 CALL COMP ; Do one less than total
309 INC CX ; CX=1 (do last one)
310COMP:
311 REPE CMPSB
312 JZ RET5
313; Compare error. Print address, value; value, address.
314 DEC SI
315 CALL OUTSI
316 CALL BLANK
317 CALL BLANK
318 LODSB
319 CALL HEX
320 CALL BLANK
321 CALL BLANK
322 DEC DI
323 MOV AL,ES:[DI]
324 CALL HEX
325 CALL BLANK
326 CALL BLANK
327 CALL OUTDI
328 INC DI
329 CALL CRLF
330 XOR AL,AL
331 JMP SHORT COMP
332
333ZTRACE:
334IF ZIBO
335; just like trace except skips OVER next INT or CALL.
336 CALL SETADD ; get potential starting point
337 CALL GETEOL ; check for end of line
338 MOV [TCOUNT],1 ; only a single go at it
339 MOV ES,[CSSAVE] ; point to instruction to execute
340 MOV DI,[IPSAVE] ; include offset in segment
341 XOR DX,DX ; where to place breakpoint
342 MOV AL,ES:[DI] ; get the opcode
343 CMP AL,11101000B ; direct intra call
344 JZ ZTrace3 ; yes, 3 bytes
345 CMP AL,10011010B ; direct inter call
346 JZ ZTrace5 ; yes, 5 bytes
347 CMP AL,11111111B ; indirect?
348 JZ ZTraceModRM ; yes, go figure length
349 CMP AL,11001100B ; short interrupt?
350 JZ ZTrace1 ; yes, 1 byte
351 CMP AL,11001101B ; long interrupt?
352 JZ ZTrace2 ; yes, 2 bytes
353 CMP AL,11100010B ; loop
354 JZ ZTrace2 ; 2 byter
355 CMP AL,11100001B ; loopz/loope
356 JZ ZTrace2 ; 2 byter
357 CMP AL,11100000B ; loopnz/loopne
358 JZ ZTrace2 ; 2 byter
359 AND AL,11111110B ; check for rep
360 CMP AL,11110010B ; perhaps?
361 JNZ Step ; can't do anything special, step
362 MOV AL,ES:[DI+1] ; next instruction
363 AND AL,11111110B ; ignore w bit
364 CMP AL,10100100B ; MOVS
365 JZ ZTrace2 ; two byte
366 CMP AL,10100110B ; CMPS
367 JZ ZTrace2 ; two byte
368 CMP AL,10101110B ; SCAS
369 JZ ZTrace2 ; two byte
370 CMP AL,10101100B ; LODS
371 JZ ZTrace2 ; two byte
372 CMP AL,10101010B ; STOS
373 JZ ZTrace2 ; two byte
374 JMP Step ; bogus, do single step
375
376ZTraceModRM:
377 MOV AL,ES:[DI+1] ; get next byte
378 AND AL,11111000B ; get mod and type
379 CMP AL,01010000B ; indirect intra 8 bit offset?
380 JZ ZTrace3 ; yes, three byte whammy
381 CMP AL,01011000B ; indirect inter 8 bit offset
382 JZ ZTrace3 ; yes, three byte guy
383 CMP AL,10010000B ; indirect intra 16 bit offset?
384 JZ ZTrace4 ; four byte offset
385 CMP AL,10011000B ; indirect inter 16 bit offset?
386 JZ ZTrace4 ; four bytes
387 JMP Step ; can't figger out what this is!
388ZTrace5:INC DX
389ZTrace4:INC DX
390ZTrace3:INC DX
391ZTrace2:INC DX
392ZTrace1:INC DX
393 ADD DI,DX ; offset to breakpoint instruction
394 MOV WORD PTR [BPTab],DI ; save offset
395 MOV WORD PTR [BPTab+2],ES ; save segment
396 MOV AL,ES:[DI] ; get next opcode byte
397 MOV BYTE PTR [BPTab+4],AL ; save it
398 MOV BYTE PTR ES:[DI],0CCh ; break point it
399 MOV [BrkCnt],1 ; only this breakpoint
400 JMP DExit ; start the operation!
401 ENDIF
402
403; Trace 1 instruction or the number of instruction specified
404; by the parameter using 8086 trace mode. Registers are all
405; set according to values in save area
406
407TRACE:
408 CALL SETADD
409 CALL SCANP
410 CALL HEXIN
411 MOV DX,1
412 JC STOCNT
413 MOV CX,4
414 CALL GETHEX
415STOCNT:
416 MOV [TCOUNT],DX
417 CALL GETEOL
418STEP:
419 MOV [BRKCNT],0
420 OR BYTE PTR [FSAVE+1],1
421DEXIT:
422IF NOT SYSVER
423 MOV BX,[USER_PROC_PDB]
424 MOV AH,SET_CURRENT_PDB
425 INT 21H
426ENDIF
427 PUSH DS
428 XOR AX,AX
429 MOV DS,AX
430 MOV WORD PTR DS:[12],OFFSET DG:BREAKFIX ; Set vector 3--breakpoint instruction
431 MOV WORD PTR DS:[14],CS
432 MOV WORD PTR DS:[4],OFFSET DG:REENTER ; Set vector 1--Single step
433 MOV WORD PTR DS:[6],CS
434 CLI
435
436 IF SETCNTC
437 MOV WORD PTR DS:[8CH],OFFSET DG:CONTC ; Set vector 23H (CTRL-C)
438 MOV WORD PTR DS:[8EH],CS
439 ENDIF
440
441 POP DS
442 MOV SP,OFFSET DG:STACK
443 POP AX
444 POP BX
445 POP CX
446 POP DX
447 POP BP
448 POP BP
449 POP SI
450 POP DI
451 POP ES
452 POP ES
453 POP SS
454 MOV SP,[SPSAVE]
455 PUSH [FSAVE]
456 PUSH [CSSAVE]
457 PUSH [IPSAVE]
458 MOV DS,[DSSAVE]
459 IRET
460STEP1:
461 CALL CRLF
462 CALL DISPREG
463 JMP SHORT STEP
464
465; Re-entry point from CTRL-C. Top of stack has address in 86-DOS for
466; continuing, so we must pop that off.
467
468CONTC:
469 ADD SP,6
470 JMP SHORT ReEnterReal
471
472; Re-entry point from breakpoint. Need to decrement instruction
473; pointer so it points to location where breakpoint actually
474; occured.
475
476BREAKFIX:
477 PUSH BP
478 MOV BP,SP
479 DEC WORD PTR [BP].OldIP
480 POP BP
481 JMP ReenterReal
482
483; Re-entry point from trace mode or interrupt during
484; execution. All registers are saved so they can be
485; displayed or modified.
486
487Interrupt_Frame STRUC
488OldBP DW ?
489OldIP DW ?
490OldCS DW ?
491OldF DW ?
492OlderIP DW ?
493OlderCS DW ?
494OlderF DW ?
495Interrupt_Frame ENDS
496
497REENTER:
498 PUSH BP
499 MOV BP,SP ; get a frame to address from
500 PUSH AX
501 MOV AX,CS
502 CMP AX,[BP].OldCS ; Did we interrupt ourselves?
503 JNZ GoReEnter ; no, go reenter
504 MOV AX,[BP].OldIP
505 CMP AX,OFFSET DG:NMIInt ; interrupt below NMI interrupt?
506 JB GoReEnter ; yes, go reenter
507 CMP [BP].OLDIP,OFFSET DG:NMIIntEnd
508 JAE GoReEnter ; interrupt above NMI interrupt?
509 POP AX ; restore state
510 POP BP
511 SUB SP,6 ; switch TRACE and NMI stack frames
512 PUSH BP
513 MOV BP,SP ; set up frame
514 PUSH AX ; get temp variable
515 MOV AX,[BP].OlderIP ; get NMI Vector
516 MOV [BP].OldIP,AX ; stuff in new NMI vector
517 MOV AX,[BP].OlderCS ; get NMI Vector
518 MOV [BP].OldCS,AX ; stuff in new NMI vector
519 MOV AX,[BP].OlderF ; get NMI Vector
520 AND AH,0FEh ; turn off Trace if present
521 MOV [BP].OldF,AX ; stuff in new NMI vector
522 MOV [BP].OlderF,AX
523 MOV [BP].OlderIP,OFFSET DG:ReEnter ; offset of routine
524 MOV [BP].OlderCS,CS ; and CS
525 POP AX
526 POP BP
527 IRET ; go try again
528GoReEnter:
529 POP AX
530 POP BP
531ReEnterReal:
532 MOV CS:[SPSAVE+SEGDIF],SP
533 MOV CS:[SSSAVE+SEGDIF],SS
534 MOV CS:[FSAVE],CS
535 MOV SS,CS:[FSAVE]
536 MOV SP,OFFSET DG:RSTACK
537 PUSH ES
538 PUSH DS
539 PUSH DI
540 PUSH SI
541 PUSH BP
542 DEC SP
543 DEC SP
544 PUSH DX
545 PUSH CX
546 PUSH BX
547 PUSH AX
548 PUSH SS
549 POP DS
550 MOV SS,[SSSAVE]
551 MOV SP,[SPSAVE]
552 POP [IPSAVE]
553 POP [CSSAVE]
554 POP AX
555 AND AH,0FEH ; turn off trace mode bit
556 MOV [FSAVE],AX
557 MOV [SPSAVE],SP
558 PUSH DS
559 POP ES
560 PUSH DS
561 POP SS
562 MOV SP,OFFSET DG:STACK
563 PUSH DS
564 XOR AX,AX
565 MOV DS,AX
566
567 IF SETCNTC
568 MOV WORD PTR DS:[8CH],OFFSET DG:DABORT ; Set Ctrl-C vector
569 MOV WORD PTR DS:[8EH],CS
570 ENDIF
571
572 POP DS
573 STI
574 CLD
575IF NOT SYSVER
576 MOV AH,GET_CURRENT_PDB
577 INT 21H
578 MOV [USER_PROC_PDB],BX
579 MOV BX,DS
580 MOV AH,SET_CURRENT_PDB
581 INT 21H
582ENDIF
583 DEC [TCOUNT]
584 JZ CheckDisp
585 JMP Step1
586CheckDisp:
587 MOV SI,OFFSET DG:BPTAB
588 MOV CX,[BRKCNT]
589 JCXZ SHOREG
590 PUSH ES
591CLEARBP:
592 LES DI,DWORD PTR [SI]
593 ADD SI,4
594 MOVSB
595 LOOP CLEARBP
596 POP ES
597SHOREG:
598 CALL CRLF
599 CALL DISPREG
600 JMP COMMAND
601
602SETADD:
603 MOV BP,[CSSAVE]
604 CALL SCANP
605 CMP BYTE PTR [SI],"="
606 JNZ RET$5
607 INC SI
608 CALL ADDRESS
609 MOV [CSSAVE],AX
610 MOV [IPSAVE],DX
611RET$5: RET
612
613; Jump to program, setting up registers according to the
614; save area. up to 10 breakpoint addresses may be specified.
615
616GO:
617 CALL SETADD
618 XOR BX,BX
619 MOV DI,OFFSET DG:BPTAB
620GO1:
621 CALL SCANP
622 JZ DEXEC
623 MOV BP,[CSSAVE]
624 CALL ADDRESS
625 MOV [DI],DX ; Save offset
626 MOV [DI+2],AX ; Save segment
627 ADD DI,5 ; Leave a little room
628 INC BX
629 CMP BX,1+BPMAX
630 JNZ GO1
631 MOV AX,5000H+"B" ; BP ERROR
632 JMP ERR
633DEXEC:
634 MOV [BRKCNT],BX
635 MOV CX,BX
636 JCXZ NOBP
637 MOV DI,OFFSET DG:BPTAB
638 PUSH DS
639SETBP:
640 LDS SI,ES:DWORD PTR [DI]
641 ADD DI,4
642 MOVSB
643 MOV BYTE PTR [SI-1],0CCH
644 LOOP SETBP
645 POP DS
646NOBP:
647 MOV [TCOUNT],1
648 JMP DEXIT
649
650SKIP_FILE:
651 MOV AH,CHAR_OPER
652 INT 21H
653 MOV [SWITCHAR],DL ; GET THE CURRENT SWITCH CHARACTER
654FIND_DELIM:
655 LODSB
656 CALL DELIM1
657 JZ GOTDELIM
658 CALL DELIM2
659 JNZ FIND_DELIM
660GOTDELIM:
661 DEC SI
662 RET
663
664PREPNAME:
665 MOV ES,DSSAVE
666 PUSH SI
667 MOV DI,81H
668COMTAIL:
669 LODSB
670 STOSB
671 CMP AL,13
672 JNZ COMTAIL
673 SUB DI,82H
674 XCHG AX,DI
675 MOV ES:(BYTE PTR [80H]),AL
676 POP SI
677 MOV DI,FCB
678 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
679 INT 21H
680 MOV BYTE PTR [AXSAVE],AL ; Indicate analysis of first parm
681 CALL SKIP_FILE
682 MOV DI,6CH
683 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
684 INT 21H
685 MOV BYTE PTR [AXSAVE+1],AL ; Indicate analysis of second parm
686RET23: RET
687
688
689; OPENS A XENIX PATHNAME SPECIFIED IN THE UNFORMATTED PARAMETERS
690; VARIABLE [XNXCMD] SPECIFIES WHICH COMMAND TO OPEN IT WITH
691;
692; VARIABLE [HANDLE] CONTAINS THE HANDLE
693; VARIABLE [EXTPTR] POINTS TO THE FILES EXTENSION
694
695DELETE_A_FILE:
696 MOV BYTE PTR [XNXCMD],UNLINK
697 JMP SHORT OC_FILE
698
699PARSE_A_FILE:
700 MOV BYTE PTR [XNXCMD],0
701 JMP SHORT OC_FILE
702
703EXEC_A_FILE:
704 MOV BYTE PTR [XNXCMD],EXEC
705 MOV BYTE PTR [XNXOPT],1
706 JMP SHORT OC_FILE
707
708OPEN_A_FILE:
709 MOV BYTE PTR [XNXCMD],OPEN
710 MOV BYTE PTR [XNXOPT],2 ; Try read write
711 CALL OC_FILE
712 JNC RET23
713 MOV BYTE PTR [XNXCMD],OPEN
714 MOV BYTE PTR [XNXOPT],0 ; Try read only
715 JMP SHORT OC_FILE
716
717CREATE_A_FILE:
718 MOV BYTE PTR [XNXCMD],CREAT
719
720OC_FILE:
721 PUSH DS
722 PUSH ES
723 PUSH AX
724 PUSH BX
725 PUSH CX
726 PUSH DX
727 PUSH SI
728 XOR AX,AX
729 MOV [EXTPTR],AX ; INITIALIZE POINTER TO EXTENSIONS
730 MOV AH,CHAR_OPER
731 INT 21H
732 MOV [SWITCHAR],DL ; GET THE CURRENT SWITCH CHARACTER
733
734 MOV SI,81H
735
736OPEN1: CALL GETCHRUP
737 CALL DELIM2 ; END OF LINE?
738 JZ OPEN4
739 CALL DELIM1 ; SKIP LEADING DELIMITERS
740 JZ OPEN1
741
742 MOV DX,SI ; SAVE POINTER TO BEGINNING
743 DEC DX
744OPEN2: CMP AL,"." ; LAST CHAR A "."?
745 JNZ OPEN3
746 MOV [EXTPTR],SI ; SAVE POINTER TO THE EXTENSION
747OPEN3: CALL GETCHRUP
748 CALL DELIM1 ; LOOK FOR END OF PATHNAME
749 JZ OPEN4
750 CALL DELIM2
751 JNZ OPEN2
752
753OPEN4: DEC SI ; POINT BACK TO LAST CHAR
754 PUSH [SI] ; SAVE TERMINATION CHAR
755 MOV BYTE PTR [SI],0 ; NULL TERMINATE THE STRING
756
757 MOV AL,[XNXOPT]
758 MOV AH,[XNXCMD] ; OPEN OR CREATE FILE
759 OR AH,AH
760 JZ OPNRET
761 MOV BX,OFFSET DG:EXEC_BLOCK
762 XOR CX,CX
763 INT 21H
764 MOV CS:[HANDLE],AX ; SAVE ERROR CODE OR HANDLE
765
766OPNRET: POP [SI]
767
768 POP SI
769 POP DX
770 POP CX
771 POP BX
772 POP AX
773 POP ES
774 POP DS
775 RET
776
777GETCHRUP:
778 LODSB
779 CMP AL,"a"
780 JB GCUR
781 CMP AL,"z"
782 JA GCUR
783 SUB AL,32
784 MOV [SI-1],AL
785GCUR: RET
786
787DELIM0: CMP AL,"["
788 JZ LIMRET
789DELIM1: CMP AL," " ; SKIP THESE GUYS
790 JZ LIMRET
791 CMP AL,";"
792 JZ LIMRET
793 CMP AL,"="
794 JZ LIMRET
795 CMP AL,9
796 JZ LIMRET
797 CMP AL,","
798 JMP SHORT LIMRET
799
800DELIM2: CMP AL,[SWITCHAR] ; STOP ON THESE GUYS
801 JZ LIMRET
802 CMP AL,13
803LIMRET: RET
804
805NAME:
806 CALL PREPNAME
807 MOV AL,BYTE PTR AXSAVE
808 MOV PARSERR,AL
809 PUSH ES
810 POP DS
811 PUSH CS
812 POP ES
813 MOV SI,FCB ; DS:SI points to user FCB
814 MOV DI,SI ; ES:DI points to DEBUG FCB
815 MOV CX,82
816 REP MOVSW
817RET6: RET
818
819BADNAM:
820 MOV DX,OFFSET DG:NAMBAD
821 JMP RESTART
822
823IFHEX:
824 CMP BYTE PTR [PARSERR],-1 ; Invalid drive specification?
825 JZ BADNAM
826 CALL PARSE_A_FILE
827 MOV BX,[EXTPTR]
828 CMP WORD PTR DS:[BX],"EH" ; "HE"
829 JNZ RET6
830 CMP BYTE PTR DS:[BX+2],"X"
831 RET
832
833IFEXE:
834 PUSH BX
835 MOV BX,[EXTPTR]
836 CMP WORD PTR DS:[BX],"XE" ; "EX"
837 JNZ RETIF
838 CMP BYTE PTR DS:[BX+2],"E"
839RETIF: POP BX
840 RET
841
842LOAD:
843 MOV BYTE PTR [RDFLG],READ
844 JMP SHORT DSKIO
845
846DWRITE:
847 MOV BYTE PTR [RDFLG],WRITE
848DSKIO:
849 MOV BP,[CSSAVE]
850 CALL SCANB
851 JNZ PRIMIO
852 JMP DEFIO
853PRIMIO: CALL ADDRESS
854 CALL SCANB
855 JNZ PRMIO
856 JMP FILEIO
857PRMIO: PUSH AX ; Save segment
858 MOV BX,DX ; Put displacement in proper register
859 MOV CX,1
860 CALL GETHEX ; Drive number must be 1 digit
861 PUSH DX
862 MOV CX,4
863 CALL GETHEX ; Logical record number
864 PUSH DX
865 MOV CX,3
866 CALL GETHEX ; Number of records
867 CALL GETEOL
868 MOV CX,DX
869 POP DX ; Logical record number
870 POP AX ; Drive number
871 CBW ; Turn off verify after write
872 MOV BYTE PTR DRVLET,AL ; Save drive in case of error
873 PUSH AX
874 PUSH BX
875 PUSH DX
876 MOV DL,AL
877 INC DL
878 MOV AH,GET_DPB
879 INT 21H
880 POP DX
881 POP BX
882 OR AL,AL
883 POP AX
884 POP DS ; Segment of transfer
885 JNZ DRVERRJ
886 CMP CS:BYTE PTR [RDFLG],WRITE
887 JZ ABSWRT
888 INT 25H ; Primitive disk read
889 JMP SHORT ENDABS
890
891ABSWRT:
892 INT 26H ; Primitive disk write
893ENDABS:
894 JNC RET0
895DRVERRJ: JMP DRVERR
896
897RET0:
898 POPF
899 RET
900
901DEFIO:
902 MOV AX,[CSSAVE] ; Default segment
903 MOV DX,100H ; Default file I/O offset
904 CALL IFHEX
905 JNZ EXECHK
906 XOR DX,DX ; If HEX file, default OFFSET is zero
907HEX2BINJ:JMP HEX2BIN
908
909FILEIO:
910; AX and DX have segment and offset of transfer, respectively
911 CALL IFHEX
912 JZ HEX2BINJ
913EXECHK:
914 CALL IFEXE
915 JNZ BINFIL
916 CMP BYTE PTR [RDFLG],READ
917 JZ EXELJ
918 MOV DX,OFFSET DG:EXEWRT
919 JMP RESTART ; Can't write .EXE files
920
921BINFIL:
922 CMP BYTE PTR [RDFLG],WRITE
923 JZ BINLOAD
924 CMP WORD PTR DS:[BX],4F00H + "C" ; "CO"
925 JNZ BINLOAD
926 CMP BYTE PTR DS:[BX+2],"M"
927 JNZ BINLOAD
928EXELJ:
929 DEC SI
930 CMP DX,100H
931 JNZ PRER
932 CMP AX,[CSSAVE]
933 JZ OAF
934PRER: JMP PERROR
935OAF: CALL OPEN_A_FILE
936 JNC GDOPEN
937 MOV AX,exec_file_not_found
938 JMP EXECERR
939
940GDOPEN: XOR DX,DX
941 XOR CX,CX
942 MOV BX,[HANDLE]
943 MOV AL,2
944 MOV AH,LSEEK
945 INT 21H
946 CALL IFEXE ; SUBTRACT 512 BYTES FOR EXE
947 JNZ BIN2 ; FILE LENGTH BECAUSE OF
948 SUB AX,512 ; THE HEADER
949BIN2: MOV [BXSAVE],DX ; SET UP FILE SIZE IN DX:AX
950 MOV [CXSAVE],AX
951 MOV AH,CLOSE
952 INT 21H
953 JMP EXELOAD
954
955NO_MEM_ERR:
956 MOV DX,OFFSET DG:TOOBIG
957 MOV AH,STD_CON_STRING_OUTPUT
958 INT 21H
959 JMP COMMAND
960
961WRTFILEJ: JMP WRTFILE
962NOFILEJ: JMP NOFILE
963
964BINLOAD:
965 PUSH AX
966 PUSH DX
967 CMP BYTE PTR [RDFLG],WRITE
968 JZ WRTFILEJ
969 CALL OPEN_A_FILE
970 JC NOFILEJ
971 MOV BX,[HANDLE]
972 MOV AX,(LSEEK SHL 8) OR 2
973 XOR DX,DX
974 MOV CX,DX
975 INT 21H ; GET SIZE OF FILE
976 MOV SI,DX
977 MOV DI,AX ; SIZE TO SI:DI
978 MOV AX,(LSEEK SHL 8) OR 0
979 XOR DX,DX
980 MOV CX,DX
981 INT 21H ; RESET POINTER BACK TO BEGINNING
982 POP AX
983 POP BX
984 PUSH BX
985 PUSH AX ; TRANS ADDR TO BX:AX
986 ADD AX,15
987 MOV CL,4
988 SHR AX,CL
989 ADD BX,AX ; Start of transfer rounded up to seg
990 MOV DX,SI
991 MOV AX,DI ; DX:AX is size
992 MOV CX,16
993 DIV CX
994 OR DX,DX
995 JZ NOREM
996 INC AX
997NOREM: ; AX is number of paras in transfer
998 ADD AX,BX ; AX is first seg that need not exist
999 CMP AX,CS:[PDB_block_len]
1000 JA NO_MEM_ERR
1001 MOV CXSAVE,DI
1002 MOV BXSAVE,SI
1003 POP DX
1004 POP AX
1005
1006RDWR:
1007; AX:DX is disk transfer address (segment:offset)
1008; SI:DI is length (32-bit number)
1009
1010RDWRLOOP:
1011 MOV BX,DX ; Make a copy of the offset
1012 AND DX,000FH ; Establish the offset in 0H-FH range
1013 MOV CL,4
1014 SHR BX,CL ; Shift offset and
1015 ADD AX,BX ; Add to segment register to get new Seg:offset
1016 PUSH AX
1017 PUSH DX ; Save AX,DX register pair
1018 MOV WORD PTR [TRANSADD],DX
1019 MOV WORD PTR [TRANSADD+2],AX
1020 MOV CX,0FFF0H ; Keep request in segment
1021 OR SI,SI ; Need > 64K?
1022 JNZ BIGRDWR
1023 MOV CX,DI ; Limit to amount requested
1024BIGRDWR:
1025 PUSH DS
1026 PUSH BX
1027 MOV BX,[HANDLE]
1028 MOV AH,[RDFLG]
1029 LDS DX,[TRANSADD]
1030 INT 21H ; Perform read or write
1031 POP BX
1032 POP DS
1033 JC BADWR
1034 CMP BYTE PTR [RDFLG],WRITE
1035 JNZ GOODR
1036 CMP CX,AX
1037 JZ GOODR
1038BADWR: MOV CX,AX
1039 STC
1040 POP DX ; READ OR WRITE BOMBED OUT
1041 POP AX
1042 RET
1043
1044GOODR:
1045 MOV CX,AX
1046 SUB DI,CX ; Request minus amount transferred
1047 SBB SI,0 ; Ripple carry
1048 OR CX,CX ; End-of-file?
1049 POP DX ; Restore DMA address
1050 POP AX
1051 JZ RET8
1052 ADD DX,CX ; Bump DMA address by transfer length
1053 MOV BX,SI
1054 OR BX,DI ; Finished with request
1055 JNZ RDWRLOOP
1056RET8: CLC ; End-of-file not reached
1057 RET
1058
1059NOFILE:
1060 MOV DX,OFFSET DG:NOTFND
1061RESTARTJMP:
1062 JMP RESTART
1063
1064WRTFILE:
1065 CALL CREATE_A_FILE ; Create file we want to write to
1066 MOV DX,OFFSET DG:NOROOM ; Creation error - report error
1067 JC RESTARTJMP
1068 MOV SI,BXSAVE ; Get high order number of bytes to transfer
1069 CMP SI,000FH
1070 JLE WRTSIZE ; Is bx less than or equal to FH
1071 XOR SI,SI ; Ignore BX if greater than FH - set to zero
1072WRTSIZE:
1073 MOV DX,OFFSET DG:WRTMES1 ; Print number bytes we are writing
1074 CALL RPRBUF
1075 OR SI,SI
1076 JZ NXTBYT
1077 MOV AX,SI
1078 CALL DIGIT
1079NXTBYT:
1080 MOV DX,CXSAVE
1081 MOV DI,DX
1082 CALL OUT16 ; Amount to write is SI:DI
1083 MOV DX,OFFSET DG:WRTMES2
1084 CALL RPRBUF
1085 POP DX
1086 POP AX
1087 CALL RDWR
1088 JNC CLSFLE
1089 CALL CLSFLE
1090 CALL DELETE_A_FILE
1091 MOV DX,OFFSET DG:NOSPACE
1092 JMP RESTARTJMP
1093 CALL CLSFLE
1094 JMP COMMAND
1095
1096CLSFLE:
1097 MOV AH,CLOSE
1098 MOV BX,[HANDLE]
1099 INT 21H
1100 RET
1101
1102EXELOAD:
1103 POP [RETSAVE] ; Suck up return addr
1104 INC BYTE PTR [NEWEXEC]
1105 MOV BX,[USER_PROC_PDB]
1106 MOV AX,DS
1107 CMP AX,BX
1108 JZ DEBUG_CURRENT
1109 JMP FIND_DEBUG
1110
1111DEBUG_CURRENT:
1112 MOV AX,[DSSAVE]
1113DEBUG_FOUND:
1114 MOV BYTE PTR [NEWEXEC],0
1115 MOV [HEADSAVE],AX
1116 PUSH [RETSAVE] ; Get the return address back
1117 PUSH AX
1118 MOV BX,CS
1119 SUB AX,BX
1120 PUSH CS
1121 POP ES
1122 MOV BX,AX
1123 ADD BX,10H ; RESERVE HEADER
1124 MOV AH,SETBLOCK
1125 INT 21H
1126 POP AX
1127 MOV WORD PTR [COM_LINE+2],AX
1128 MOV WORD PTR [COM_FCB1+2],AX
1129 MOV WORD PTR [COM_FCB2+2],AX
1130
1131 CALL EXEC_A_FILE
1132 JC EXECERR
1133 CALL SET_TERMINATE_VECTOR ; Reset int 22
1134 MOV AH,GET_CURRENT_PDB
1135 INT 21H
1136 MOV [USER_PROC_PDB],BX
1137 MOV [DSSAVE],BX
1138 MOV [ESSAVE],BX
1139 MOV ES,BX
1140 MOV WORD PTR ES:[PDB_exit],OFFSET DG:TERMINATE
1141 MOV WORD PTR ES:[PDB_exit+2],DS
1142 LES DI,[COM_CSIP]
1143 MOV [CSSAVE],ES
1144 MOV [IPSAVE],DI
1145 MOV WORD PTR [DISADD+2],ES
1146 MOV WORD PTR [DISADD],DI
1147 MOV WORD PTR [ASMADD+2],ES
1148 MOV WORD PTR [ASMADD],DI
1149 MOV WORD PTR [DEFDUMP+2],ES
1150 MOV WORD PTR [DEFDUMP],DI
1151 MOV BX,DS
1152 MOV AH,SET_CURRENT_PDB
1153 INT 21H
1154 LES DI,[COM_SSSP]
1155 MOV AX,ES:[DI]
1156 INC DI
1157 INC DI
1158 MOV [AXSAVE],AX
1159 MOV [SSSAVE],ES
1160 MOV [SPSAVE],DI
1161 RET
1162
1163EXECERR:
1164 MOV DX,OFFSET DG:NOTFND
1165 CMP AX,exec_file_not_found
1166 JZ GOTEXECEMES
1167 MOV DX,OFFSET DG:ACCMES
1168 CMP AX,error_access_denied
1169 JZ GOTEXECEMES
1170 MOV DX,OFFSET DG:TOOBIG
1171 CMP AX,exec_not_enough_memory
1172 JZ GOTEXECEMES
1173 MOV DX,OFFSET DG:EXEBAD
1174 CMP AX,exec_bad_format
1175 JZ GOTEXECEMES
1176 MOV DX,OFFSET DG:EXECEMES
1177GOTEXECEMES:
1178 MOV AH,STD_CON_STRING_OUTPUT
1179 INT 21H
1180 JMP COMMAND
1181
1182HEX2BIN:
1183 MOV [INDEX],DX
1184 MOV DX,OFFSET DG:HEXWRT
1185 CMP BYTE PTR [RDFLG],WRITE
1186 JNZ RDHEX
1187 JMP RESTARTJ2
1188RDHEX:
1189 MOV ES,AX
1190 CALL OPEN_A_FILE
1191 MOV DX,OFFSET DG:NOTFND
1192 JNC HEXFND
1193 JMP RESTART
1194HEXFND:
1195 XOR BP,BP
1196 MOV SI,OFFSET DG:(BUFFER+BUFSIZ) ; Flag input buffer as empty
1197READHEX:
1198 CALL GETCH
1199 CMP AL,":" ; Search for : to start line
1200 JNZ READHEX
1201 CALL GETBYT ; Get byte count
1202 MOV CL,AL
1203 MOV CH,0
1204 JCXZ HEXDONE
1205 CALL GETBYT ; Get high byte of load address
1206 MOV BH,AL
1207 CALL GETBYT ; Get low byte of load address
1208 MOV BL,AL
1209 ADD BX,[INDEX] ; Add in offset
1210 MOV DI,BX
1211 CALL GETBYT ; Throw away type byte
1212READLN:
1213 CALL GETBYT ; Get data byte
1214 STOSB
1215 CMP DI,BP ; Check if this is the largest address so far
1216 JBE HAVBIG
1217 MOV BP,DI ; Save new largest
1218HAVBIG:
1219 LOOP READLN
1220 JMP SHORT READHEX
1221
1222GETCH:
1223 CMP SI,OFFSET DG:(BUFFER+BUFSIZ)
1224 JNZ NOREAD
1225 MOV DX,OFFSET DG:BUFFER
1226 MOV SI,DX
1227 MOV AH,READ
1228 PUSH BX
1229 PUSH CX
1230 MOV CX,BUFSIZ
1231 MOV BX,[HANDLE]
1232 INT 21H
1233 POP CX
1234 POP BX
1235 OR AX,AX
1236 JZ HEXDONE
1237NOREAD:
1238 LODSB
1239 CMP AL,1AH
1240 JZ HEXDONE
1241 OR AL,AL
1242 JNZ RET7
1243HEXDONE:
1244 MOV [CXSAVE],BP
1245 MOV BXSAVE,0
1246 RET
1247
1248HEXDIG:
1249 CALL GETCH
1250 CALL HEXCHK
1251 JNC RET7
1252 MOV DX,OFFSET DG:HEXERR
1253RESTARTJ2:
1254 JMP RESTART
1255
1256GETBYT:
1257 CALL HEXDIG
1258 MOV BL,AL
1259 CALL HEXDIG
1260 SHL BL,1
1261 SHL BL,1
1262 SHL BL,1
1263 SHL BL,1
1264 OR AL,BL
1265RET7: RET
1266
1267
1268CODE ENDS
1269 END DEBCOM2
diff --git a/v2.0/source/DEBCONST.ASM b/v2.0/source/DEBCONST.ASM
new file mode 100644
index 0000000..e8f8c35
--- /dev/null
+++ b/v2.0/source/DEBCONST.ASM
@@ -0,0 +1,1103 @@
1.xlist
2.xcref
3INCLUDE debequ.asm
4INCLUDE dossym.asm
5.list
6.cref
7
8CODE SEGMENT PUBLIC BYTE 'CODE'
9CODE ENDS
10
11CONST SEGMENT PUBLIC BYTE
12CONST ENDS
13
14DATA SEGMENT PUBLIC BYTE
15DATA ENDS
16
17DG GROUP CODE,CONST,DATA
18
19CODE SEGMENT PUBLIC BYTE 'CODE'
20
21 EXTRN ALUFROMREG:NEAR,ALUTOREG:NEAR,ACCIMM:NEAR
22 EXTRN SEGOP:NEAR,ESPRE:NEAR,SSPRE:NEAR,CSPRE:NEAR
23 EXTRN DSPRE:NEAR,REGOP:NEAR,NOOPERANDS:NEAR
24 EXTRN SAVHEX:NEAR,SHORTJMP:NEAR,MOVSEGTO:NEAR
25 EXTRN WORDTOALU:NEAR,MOVSEGFROM:NEAR,GETADDR:NEAR
26 EXTRN XCHGAX:NEAR,LONGJMP:NEAR,LOADACC:NEAR,STOREACC:NEAR
27 EXTRN REGIMMB:NEAR,SAV16:NEAR,MEMIMM:NEAR,INT3:NEAR,SAV8:NEAR
28 EXTRN CHK10:NEAR,M8087:NEAR,M8087_D9:NEAR,M8087_DB:NEAR
29 EXTRN M8087_DD:NEAR,M8087_DF:NEAR,INFIXB:NEAR,INFIXW:NEAR
30 EXTRN OUTFIXB:NEAR,OUTFIXW:NEAR,JMPCALL:NEAR,INVARB:NEAR
31 EXTRN INVARW:NEAR,OUTVARB:NEAR,OUTVARW:NEAR,PREFIX:NEAR
32 EXTRN IMMED:NEAR,SIGNIMM:NEAR,SHIFT:NEAR,SHIFTV:NEAR
33 EXTRN GRP1:NEAR,GRP2:NEAR,REGIMMW:NEAR
34
35
36 EXTRN DB_OPER:NEAR,DW_OPER:NEAR,ASSEMLOOP:NEAR,GROUP2:NEAR
37 EXTRN NO_OPER:NEAR,GROUP1:NEAR,FGROUPP:NEAR,FGROUPX:NEAR
38 EXTRN FGROUPZ:NEAR,FD9_OPER:NEAR,FGROUPB:NEAR,FGROUP:NEAR
39 EXTRN FGROUPDS:NEAR,DCINC_OPER:NEAR,INT_OPER:NEAR,IN_OPER:NEAR
40 EXTRN DISP8_OPER:NEAR,JMP_OPER:NEAR,L_OPER:NEAR,MOV_OPER:NEAR
41 EXTRN OUT_OPER:NEAR,PUSH_OPER:NEAR,GET_DATA16:NEAR
42 EXTRN FGROUP3:NEAR,FGROUP3W:NEAR,FDE_OPER:NEAR,ESC_OPER:NEAR
43 EXTRN AA_OPER:NEAR,CALL_OPER:NEAR,FDB_OPER:NEAR,POP_OPER:NEAR
44 EXTRN ROTOP:NEAR,TST_OPER:NEAR,EX_OPER:NEAR
45
46CODE ENDS
47
48CONST SEGMENT PUBLIC BYTE
49
50 PUBLIC REG8,REG16,SREG,SIZ8,DISTAB,DBMN,ADDMN,ADCMN,SUBMN
51 PUBLIC SBBMN,XORMN,ORMN,ANDMN,AAAMN,AADMN,AASMN,CALLMN,CBWMN
52 PUBLIC UPMN,DIMN,CMCMN,CMPMN,CWDMN,DAAMN,DASMN,DECMN,DIVMN
53 PUBLIC ESCMN,HLTMN,IDIVMN,IMULMN,INCMN,INTOMN,INTMN,INMN,IRETMN
54 PUBLIC JAMN,JCXZMN,JNCMN,JBEMN,JZMN,JGEMN,JGMN,JLEMN,JLMN,JMPMN
55 PUBLIC JNZMN,JPEMN,JNZMN,JPEMN,JPOMN,JNSMN,JNOMN,JOMN,JSMN,LAHFMN
56 PUBLIC LDSMN,LEAMN,LESMN,LOCKMN,LODBMN,LODWMN,LOOPNZMN,LOOPZMN
57 PUBLIC LOOPMN,MOVBMN,MOVWMN,MOVMN,MULMN,NEGMN,NOPMN,NOTMN,OUTMN
58 PUBLIC POPFMN,POPMN,PUSHFMN,PUSHMN,RCLMN,RCRMN,REPZMN,REPNZMN
59 PUBLIC RETFMN,RETMN,ROLMN,RORMN,SAHFMN,SARMN,SCABMN,SCAWMN,SHLMN
60 PUBLIC SHRMN,STCMN,DOWNMN,EIMN,STOBMN,STOWMN,TESTMN,WAITMN,XCHGMN
61 PUBLIC XLATMN,ESSEGMN,CSSEGMN,SSSEGMN,DSSEGMN,BADMN
62
63 PUBLIC M8087_TAB,FI_TAB,SIZE_TAB,MD9_TAB,MD9_TAB2,MDB_TAB
64 PUBLIC MDB_TAB2,MDD_TAB,MDD_TAB2,MDF_TAB,OPTAB,MAXOP,SHFTAB,IMMTAB
65 PUBLIC GRP1TAB,GRP2TAB,SEGTAB,REGTAB,FLAGTAB,STACK
66
67 PUBLIC AXSAVE,BXSAVE,CXSAVE,DXSAVE,BPSAVE,SPSAVE,SISAVE
68 PUBLIC DISAVE,DSSAVE,ESSAVE,SSSAVE,CSSAVE,IPSAVE,FSAVE,RSTACK
69 PUBLIC REGDIF,RDFLG,TOTREG,DSIZ,NOREGL,DISPB,LBUFSIZ,LBUFFCNT
70 PUBLIC LINEBUF,PFLAG,COLPOS
71
72 IF SYSVER
73 PUBLIC CONFCB,POUT,COUT,CIN,IOBUFF,IOADDR,IOCALL,IOCOM,IOSTAT
74 PUBLIC IOCHRET,IOSEG,IOCNT
75 ENDIF
76
77 PUBLIC QFLAG,NEWEXEC,RETSAVE,USER_PROC_PDB,HEADSAVE,EXEC_BLOCK
78 PUBLIC COM_LINE,COM_FCB1,COM_FCB2,COM_SSSP,COM_CSIP
79
80REG8 DB "ALCLDLBLAHCHDHBH"
81REG16 DB "AXCXDXBXSPBPSIDI"
82SREG DB "ESCSSSDS",0,0
83SIZ8 DB "BYWODWQWTB",0,0
84; 0
85DISTAB DW OFFSET DG:ADDMN,ALUFROMREG
86 DW OFFSET DG:ADDMN,ALUFROMREG
87 DW OFFSET DG:ADDMN,ALUTOREG
88 DW OFFSET DG:ADDMN,ALUTOREG
89 DW OFFSET DG:ADDMN,ACCIMM
90 DW OFFSET DG:ADDMN,ACCIMM
91 DW OFFSET DG:PUSHMN,SEGOP
92 DW OFFSET DG:POPMN,SEGOP
93 DW OFFSET DG:ORMN,ALUFROMREG
94 DW OFFSET DG:ORMN,ALUFROMREG
95 DW OFFSET DG:ORMN,ALUTOREG
96 DW OFFSET DG:ORMN,ALUTOREG
97 DW OFFSET DG:ORMN,ACCIMM
98 DW OFFSET DG:ORMN,ACCIMM
99 DW OFFSET DG:PUSHMN,SEGOP
100 DW OFFSET DG:POPMN,SEGOP
101; 10H
102 DW OFFSET DG:ADCMN,ALUFROMREG
103 DW OFFSET DG:ADCMN,ALUFROMREG
104 DW OFFSET DG:ADCMN,ALUTOREG
105 DW OFFSET DG:ADCMN,ALUTOREG
106 DW OFFSET DG:ADCMN,ACCIMM
107 DW OFFSET DG:ADCMN,ACCIMM
108 DW OFFSET DG:PUSHMN,SEGOP
109 DW OFFSET DG:POPMN,SEGOP
110 DW OFFSET DG:SBBMN,ALUFROMREG
111 DW OFFSET DG:SBBMN,ALUFROMREG
112 DW OFFSET DG:SBBMN,ALUTOREG
113 DW OFFSET DG:SBBMN,ALUTOREG
114 DW OFFSET DG:SBBMN,ACCIMM
115 DW OFFSET DG:SBBMN,ACCIMM
116 DW OFFSET DG:PUSHMN,SEGOP
117 DW OFFSET DG:POPMN,SEGOP
118; 20H
119 DW OFFSET DG:ANDMN,ALUFROMREG
120 DW OFFSET DG:ANDMN,ALUFROMREG
121 DW OFFSET DG:ANDMN,ALUTOREG
122 DW OFFSET DG:ANDMN,ALUTOREG
123 DW OFFSET DG:ANDMN,ACCIMM
124 DW OFFSET DG:ANDMN,ACCIMM
125 DW OFFSET DG:ESSEGMN,ESPRE
126 DW OFFSET DG:DAAMN,NOOPERANDS
127 DW OFFSET DG:SUBMN,ALUFROMREG
128 DW OFFSET DG:SUBMN,ALUFROMREG
129 DW OFFSET DG:SUBMN,ALUTOREG
130 DW OFFSET DG:SUBMN,ALUTOREG
131 DW OFFSET DG:SUBMN,ACCIMM
132 DW OFFSET DG:SUBMN,ACCIMM
133 DW OFFSET DG:CSSEGMN,CSPRE
134 DW OFFSET DG:DASMN,NOOPERANDS
135; 30H
136 DW OFFSET DG:XORMN,ALUFROMREG
137 DW OFFSET DG:XORMN,ALUFROMREG
138 DW OFFSET DG:XORMN,ALUTOREG
139 DW OFFSET DG:XORMN,ALUTOREG
140 DW OFFSET DG:XORMN,ACCIMM
141 DW OFFSET DG:XORMN,ACCIMM
142 DW OFFSET DG:SSSEGMN,SSPRE
143 DW OFFSET DG:AAAMN,NOOPERANDS
144 DW OFFSET DG:CMPMN,ALUFROMREG
145 DW OFFSET DG:CMPMN,ALUFROMREG
146 DW OFFSET DG:CMPMN,ALUTOREG
147 DW OFFSET DG:CMPMN,ALUTOREG
148 DW OFFSET DG:CMPMN,ACCIMM
149 DW OFFSET DG:CMPMN,ACCIMM
150 DW OFFSET DG:DSSEGMN,DSPRE
151 DW OFFSET DG:AASMN,NOOPERANDS
152; 40H
153 DW OFFSET DG:INCMN,REGOP
154 DW OFFSET DG:INCMN,REGOP
155 DW OFFSET DG:INCMN,REGOP
156 DW OFFSET DG:INCMN,REGOP
157 DW OFFSET DG:INCMN,REGOP
158 DW OFFSET DG:INCMN,REGOP
159 DW OFFSET DG:INCMN,REGOP
160 DW OFFSET DG:INCMN,REGOP
161 DW OFFSET DG:DECMN,REGOP
162 DW OFFSET DG:DECMN,REGOP
163 DW OFFSET DG:DECMN,REGOP
164 DW OFFSET DG:DECMN,REGOP
165 DW OFFSET DG:DECMN,REGOP
166 DW OFFSET DG:DECMN,REGOP
167 DW OFFSET DG:DECMN,REGOP
168 DW OFFSET DG:DECMN,REGOP
169; 50H
170 DW OFFSET DG:PUSHMN,REGOP
171 DW OFFSET DG:PUSHMN,REGOP
172 DW OFFSET DG:PUSHMN,REGOP
173 DW OFFSET DG:PUSHMN,REGOP
174 DW OFFSET DG:PUSHMN,REGOP
175 DW OFFSET DG:PUSHMN,REGOP
176 DW OFFSET DG:PUSHMN,REGOP
177 DW OFFSET DG:PUSHMN,REGOP
178 DW OFFSET DG:POPMN,REGOP
179 DW OFFSET DG:POPMN,REGOP
180 DW OFFSET DG:POPMN,REGOP
181 DW OFFSET DG:POPMN,REGOP
182 DW OFFSET DG:POPMN,REGOP
183 DW OFFSET DG:POPMN,REGOP
184 DW OFFSET DG:POPMN,REGOP
185 DW OFFSET DG:POPMN,REGOP
186; 60H
187 DW OFFSET DG:DBMN,SAVHEX
188 DW OFFSET DG:DBMN,SAVHEX
189 DW OFFSET DG:DBMN,SAVHEX
190 DW OFFSET DG:DBMN,SAVHEX
191 DW OFFSET DG:DBMN,SAVHEX
192 DW OFFSET DG:DBMN,SAVHEX
193 DW OFFSET DG:DBMN,SAVHEX
194 DW OFFSET DG:DBMN,SAVHEX
195 DW OFFSET DG:DBMN,SAVHEX
196 DW OFFSET DG:DBMN,SAVHEX
197 DW OFFSET DG:DBMN,SAVHEX
198 DW OFFSET DG:DBMN,SAVHEX
199 DW OFFSET DG:DBMN,SAVHEX
200 DW OFFSET DG:DBMN,SAVHEX
201 DW OFFSET DG:DBMN,SAVHEX
202 DW OFFSET DG:DBMN,SAVHEX
203; 70H
204 DW OFFSET DG:JOMN,SHORTJMP
205 DW OFFSET DG:JNOMN,SHORTJMP
206 DW OFFSET DG:JCMN,SHORTJMP
207 DW OFFSET DG:JNCMN,SHORTJMP
208 DW OFFSET DG:JZMN,SHORTJMP
209 DW OFFSET DG:JNZMN,SHORTJMP
210 DW OFFSET DG:JBEMN,SHORTJMP
211 DW OFFSET DG:JAMN,SHORTJMP
212 DW OFFSET DG:JSMN,SHORTJMP
213 DW OFFSET DG:JNSMN,SHORTJMP
214 DW OFFSET DG:JPEMN,SHORTJMP
215 DW OFFSET DG:JPOMN,SHORTJMP
216 DW OFFSET DG:JLMN,SHORTJMP
217 DW OFFSET DG:JGEMN,SHORTJMP
218 DW OFFSET DG:JLEMN,SHORTJMP
219 DW OFFSET DG:JGMN,SHORTJMP
220; 80H
221 DW 0,IMMED
222 DW 0,IMMED
223 DW 0,IMMED
224 DW 0,SIGNIMM
225 DW OFFSET DG:TESTMN,ALUFROMREG
226 DW OFFSET DG:TESTMN,ALUFROMREG
227 DW OFFSET DG:XCHGMN,ALUFROMREG
228 DW OFFSET DG:XCHGMN,ALUFROMREG
229 DW OFFSET DG:MOVMN,ALUFROMREG
230 DW OFFSET DG:MOVMN,ALUFROMREG
231 DW OFFSET DG:MOVMN,ALUTOREG
232 DW OFFSET DG:MOVMN,ALUTOREG
233 DW OFFSET DG:MOVMN,MOVSEGTO
234 DW OFFSET DG:LEAMN,WORDTOALU
235 DW OFFSET DG:MOVMN,MOVSEGFROM
236 DW OFFSET DG:POPMN,GETADDR
237; 90H
238 DW OFFSET DG:NOPMN,NOOPERANDS
239 DW OFFSET DG:XCHGMN,XCHGAX
240 DW OFFSET DG:XCHGMN,XCHGAX
241 DW OFFSET DG:XCHGMN,XCHGAX
242 DW OFFSET DG:XCHGMN,XCHGAX
243 DW OFFSET DG:XCHGMN,XCHGAX
244 DW OFFSET DG:XCHGMN,XCHGAX
245 DW OFFSET DG:XCHGMN,XCHGAX
246 DW OFFSET DG:CBWMN,NOOPERANDS
247 DW OFFSET DG:CWDMN,NOOPERANDS
248 DW OFFSET DG:CALLMN,LONGJMP
249 DW OFFSET DG:WAITMN,NOOPERANDS
250 DW OFFSET DG:PUSHFMN,NOOPERANDS
251 DW OFFSET DG:POPFMN,NOOPERANDS
252 DW OFFSET DG:SAHFMN,NOOPERANDS
253 DW OFFSET DG:LAHFMN,NOOPERANDS
254; A0H
255 DW OFFSET DG:MOVMN,LOADACC
256 DW OFFSET DG:MOVMN,LOADACC
257 DW OFFSET DG:MOVMN,STOREACC
258 DW OFFSET DG:MOVMN,STOREACC
259 DW OFFSET DG:MOVBMN,NOOPERANDS
260 DW OFFSET DG:MOVWMN,NOOPERANDS
261 DW OFFSET DG:CMPBMN,NOOPERANDS
262 DW OFFSET DG:CMPWMN,NOOPERANDS
263 DW OFFSET DG:TESTMN,ACCIMM
264 DW OFFSET DG:TESTMN,ACCIMM
265 DW OFFSET DG:STOBMN,NOOPERANDS
266 DW OFFSET DG:STOWMN,NOOPERANDS
267 DW OFFSET DG:LODBMN,NOOPERANDS
268 DW OFFSET DG:LODWMN,NOOPERANDS
269 DW OFFSET DG:SCABMN,NOOPERANDS
270 DW OFFSET DG:SCAWMN,NOOPERANDS
271; B0H
272 DW OFFSET DG:MOVMN,REGIMMB
273 DW OFFSET DG:MOVMN,REGIMMB
274 DW OFFSET DG:MOVMN,REGIMMB
275 DW OFFSET DG:MOVMN,REGIMMB
276 DW OFFSET DG:MOVMN,REGIMMB
277 DW OFFSET DG:MOVMN,REGIMMB
278 DW OFFSET DG:MOVMN,REGIMMB
279 DW OFFSET DG:MOVMN,REGIMMB
280 DW OFFSET DG:MOVMN,REGIMMW
281 DW OFFSET DG:MOVMN,REGIMMW
282 DW OFFSET DG:MOVMN,REGIMMW
283 DW OFFSET DG:MOVMN,REGIMMW
284 DW OFFSET DG:MOVMN,REGIMMW
285 DW OFFSET DG:MOVMN,REGIMMW
286 DW OFFSET DG:MOVMN,REGIMMW
287 DW OFFSET DG:MOVMN,REGIMMW
288; C0H
289 DW OFFSET DG:DBMN,SAVHEX
290 DW OFFSET DG:DBMN,SAVHEX
291 DW OFFSET DG:RETMN,SAV16
292 DW OFFSET DG:RETMN,NOOPERANDS
293 DW OFFSET DG:LESMN,WORDTOALU
294 DW OFFSET DG:LDSMN,WORDTOALU
295 DW OFFSET DG:MOVMN,MEMIMM
296 DW OFFSET DG:MOVMN,MEMIMM
297 DW OFFSET DG:DBMN,SAVHEX
298 DW OFFSET DG:DBMN,SAVHEX
299 DW OFFSET DG:RETFMN,SAV16
300 DW OFFSET DG:RETFMN,NOOPERANDS
301 DW OFFSET DG:INTMN,INT3
302 DW OFFSET DG:INTMN,SAV8
303 DW OFFSET DG:INTOMN,NOOPERANDS
304 DW OFFSET DG:IRETMN,NOOPERANDS
305; D0H
306 DW 0,SHIFT
307 DW 0,SHIFT
308 DW 0,SHIFTV
309 DW 0,SHIFTV
310 DW OFFSET DG:AAMMN,CHK10
311 DW OFFSET DG:AADMN,CHK10
312 DW OFFSET DG:DBMN,SAVHEX
313 DW OFFSET DG:XLATMN,NOOPERANDS
314 DW 0,M8087 ; d8
315 DW 0,M8087_D9 ; d9
316 DW 0,M8087 ; da
317 DW 0,M8087_DB ; db
318 DW 0,M8087 ; dc
319 DW 0,M8087_DD ; dd
320 DW 0,M8087 ; de
321 DW 0,M8087_DF ; df
322; E0H
323 DW OFFSET DG:LOOPNZMN,SHORTJMP
324 DW OFFSET DG:LOOPZMN,SHORTJMP
325 DW OFFSET DG:LOOPMN,SHORTJMP
326 DW OFFSET DG:JCXZMN,SHORTJMP
327 DW OFFSET DG:INMN,INFIXB
328 DW OFFSET DG:INMN,INFIXW
329 DW OFFSET DG:OUTMN,OUTFIXB
330 DW OFFSET DG:OUTMN,OUTFIXW
331 DW OFFSET DG:CALLMN,JMPCALL
332 DW OFFSET DG:JMPMN,JMPCALL
333 DW OFFSET DG:JMPMN,LONGJMP
334 DW OFFSET DG:JMPMN,SHORTJMP
335 DW OFFSET DG:INMN,INVARB
336 DW OFFSET DG:INMN,INVARW
337 DW OFFSET DG:OUTMN,OUTVARB
338 DW OFFSET DG:OUTMN,OUTVARW
339; F0H
340 DW OFFSET DG:LOCKMN,PREFIX
341 DW OFFSET DG:DBMN,SAVHEX
342 DW OFFSET DG:REPNZMN,PREFIX
343 DW OFFSET DG:REPZMN,PREFIX
344 DW OFFSET DG:HLTMN,NOOPERANDS
345 DW OFFSET DG:CMCMN,NOOPERANDS
346 DW 0,GRP1
347 DW 0,GRP1
348 DW OFFSET DG:CLCMN,NOOPERANDS
349 DW OFFSET DG:STCMN,NOOPERANDS
350 DW OFFSET DG:DIMN,NOOPERANDS
351 DW OFFSET DG:EIMN,NOOPERANDS
352 DW OFFSET DG:UPMN,NOOPERANDS
353 DW OFFSET DG:DOWNMN,NOOPERANDS
354 DW 0,GRP2
355 DW 0,GRP2
356
357DBMN DB "D","B"+80H
358 DB "D","W"+80H
359 DB ";"+80H
360ADDMN DB "AD","D"+80H
361ADCMN DB "AD","C"+80H
362SUBMN DB "SU","B"+80H
363SBBMN DB "SB","B"+80H
364XORMN DB "XO","R"+80H
365ORMN DB "O","R"+80H
366ANDMN DB "AN","D"+80H
367AAAMN DB "AA","A"+80H
368AADMN DB "AA","D"+80H
369AAMMN DB "AA","M"+80H
370AASMN DB "AA","S"+80H
371CALLMN DB "CAL","L"+80H
372CBWMN DB "CB","W"+80H
373CLCMN DB "CL","C"+80H
374UPMN DB "CL","D"+80H ; CLD+80H
375DIMN DB "CL","I"+80H
376CMCMN DB "CM","C"+80H
377CMPBMN DB "CMPS","B"+80H ; CMPSB
378CMPWMN DB "CMPS","W"+80H ; CMPSW+80H
379CMPMN DB "CM","P"+80H
380CWDMN DB "CW","D"+80H
381DAAMN DB "DA","A"+80H
382DASMN DB "DA","S"+80H
383DECMN DB "DE","C"+80H
384DIVMN DB "DI","V"+80H
385ESCMN DB "ES","C"+80H
386 DB "FXC","H"+80H
387 DB "FFRE","E"+80H
388 DB "FCOMP","P"+80H
389 DB "FCOM","P"+80H
390 DB "FCO","M"+80H
391 DB "FICOM","P"+80H
392 DB "FICO","M"+80H
393 DB "FNO","P"+80H
394 DB "FCH","S"+80H
395 DB "FAB","S"+80H
396 DB "FTS","T"+80H
397 DB "FXA","M"+80H
398 DB "FLDL2","T"+80H
399 DB "FLDL2","E"+80H
400 DB "FLDLG","2"+80H
401 DB "FLDLN","2"+80H
402 DB "FLDP","I"+80H
403 DB "FLD","1"+80H
404 DB "FLD","Z"+80H
405 DB "F2XM","1"+80H
406 DB "FYL2XP","1"+80H
407 DB "FYL2","X"+80H
408 DB "FPTA","N"+80H
409 DB "FPATA","N"+80H
410 DB "FXTRAC","T"+80H
411 DB "FDECST","P"+80H
412 DB "FINCST","P"+80H
413 DB "FPRE","M"+80H
414 DB "FSQR","T"+80H
415 DB "FRNDIN","T"+80H
416 DB "FSCAL","E"+80H
417 DB "FINI","T"+80H
418 DB "FDIS","I"+80H
419 DB "FEN","I"+80H
420 DB "FCLE","X"+80H
421 DB "FBL","D"+80H
422 DB "FBST","P"+80H
423 DB "FLDC","W"+80H
424 DB "FSTC","W"+80H
425 DB "FSTS","W"+80H
426 DB "FSTEN","V"+80H
427 DB "FLDEN","V"+80H
428 DB "FSAV","E"+80H
429 DB "FRSTO","R"+80H
430 DB "FADD","P"+80H
431 DB "FAD","D"+80H
432 DB "FIAD","D"+80H
433 DB "FSUBR","P"+80H
434 DB "FSUB","R"+80H
435 DB "FSUB","P"+80H
436 DB "FSU","B"+80H
437 DB "FISUB","R"+80H
438 DB "FISU","B"+80H
439 DB "FMUL","P"+80H
440 DB "FMU","L"+80H
441 DB "FIMU","L"+80H
442 DB "FDIVR","P"+80H
443 DB "FDIV","R"+80H
444 DB "FDIV","P"+80H
445 DB "FDI","V"+80H
446 DB "FIDIV","R"+80H
447 DB "FIDI","V"+80H
448 DB "FWAI","T"+80H
449 DB "FIL","D"+80H
450 DB "FL","D"+80H
451 DB "FST","P"+80H
452 DB "FS","T"+80H
453 DB "FIST","P"+80H
454 DB "FIS","T"+80H
455HLTMN DB "HL","T"+80H
456IDIVMN DB "IDI","V"+80H
457IMULMN DB "IMU","L"+80H
458INCMN DB "IN","C"+80H
459INTOMN DB "INT","O"+80H
460INTMN DB "IN","T"+80H
461INMN DB "I","N"+80H ; IN
462IRETMN DB "IRE","T"+80H
463 DB "JNB","E"+80H
464 DB "JA","E"+80H
465JAMN DB "J","A"+80H
466JCXZMN DB "JCX","Z"+80H
467JNCMN DB "JN","B"+80H
468JBEMN DB "JB","E"+80H
469JCMN DB "J","B"+80H
470 DB "JN","C"+80H
471 DB "J","C"+80H
472 DB "JNA","E"+80H
473 DB "JN","A"+80H
474JZMN DB "J","Z"+80H
475 DB "J","E"+80H
476JGEMN DB "JG","E"+80H
477JGMN DB "J","G"+80H
478 DB "JNL","E"+80H
479 DB "JN","L"+80H
480JLEMN DB "JL","E"+80H
481JLMN DB "J","L"+80H
482 DB "JNG","E"+80H
483 DB "JN","G"+80H
484JMPMN DB "JM","P"+80H
485JNZMN DB "JN","Z"+80H
486 DB "JN","E"+80H
487JPEMN DB "JP","E"+80H
488JPOMN DB "JP","O"+80H
489 DB "JN","P"+80H
490JNSMN DB "JN","S"+80H
491JNOMN DB "JN","O"+80H
492JOMN DB "J","O"+80H
493JSMN DB "J","S"+80H
494 DB "J","P"+80H
495LAHFMN DB "LAH","F"+80H
496LDSMN DB "LD","S"+80H
497LEAMN DB "LE","A"+80H
498LESMN DB "LE","S"+80H
499LOCKMN DB "LOC","K"+80H
500LODBMN DB "LODS","B"+80H ; LODSB
501LODWMN DB "LODS","W"+80H ; LODSW+80H
502LOOPNZMN DB "LOOPN","Z"+80H
503LOOPZMN DB "LOOP","Z"+80H
504 DB "LOOPN","E"+80H
505 DB "LOOP","E"+80H
506LOOPMN DB "LOO","P"+80H
507MOVBMN DB "MOVS","B"+80H ; MOVSB
508MOVWMN DB "MOVS","W"+80H ; MOVSW+80H
509MOVMN DB "MO","V"+80H
510MULMN DB "MU","L"+80H
511NEGMN DB "NE","G"+80H
512NOPMN DB "NO","P"+80H
513NOTMN DB "NO","T"+80H
514OUTMN DB "OU","T"+80H ; OUT
515POPFMN DB "POP","F"+80H
516POPMN DB "PO","P"+80H
517PUSHFMN DB "PUSH","F"+80H
518PUSHMN DB "PUS","H"+80H
519RCLMN DB "RC","L"+80H
520RCRMN DB "RC","R"+80H
521REPZMN DB "REP","Z"+80H
522REPNZMN DB "REPN","Z"+80H
523 DB "REP","E"+80H
524 DB "REPN","E"+80H
525 DB "RE","P"+80H
526RETFMN DB "RET","F"+80H
527RETMN DB "RE","T"+80H
528ROLMN DB "RO","L"+80H
529RORMN DB "RO","R"+80H
530SAHFMN DB "SAH","F"+80H
531SARMN DB "SA","R"+80H
532SCABMN DB "SCAS","B"+80H ; SCASB
533SCAWMN DB "SCAS","W"+80H ; SCASW+80H
534SHLMN DB "SH","L"+80H
535SHRMN DB "SH","R"+80H
536STCMN DB "ST","C"+80H
537DOWNMN DB "ST","D"+80H ; STD
538EIMN DB "ST","I"+80H ; STI
539STOBMN DB "STOS","B"+80H ; STOSB
540STOWMN DB "STOS","W"+80H ; STOSW+80H
541TESTMN DB "TES","T"+80H
542WAITMN DB "WAI","T"+80H
543XCHGMN DB "XCH","G"+80H
544XLATMN DB "XLA","T"+80H
545ESSEGMN DB "ES",":"+80H
546CSSEGMN DB "CS",":"+80H
547SSSEGMN DB "SS",":"+80H
548DSSEGMN DB "DS",":"+80H
549BADMN DB "??","?"+80H
550
551M8087_TAB DB "ADD$MUL$COM$COMP$SUB$SUBR$DIV$DIVR$"
552FI_TAB DB "F$FI$F$FI$"
553SIZE_TAB DB "DWORD PTR $DWORD PTR $QWORD PTR $WORD PTR $"
554 DB "BYTE PTR $TBYTE PTR $"
555
556MD9_TAB DB "LD$@$ST$STP$LDENV$LDCW$STENV$STCW$"
557MD9_TAB2 DB "CHS$ABS$@$@$TST$XAM$@$@$LD1$LDL2T$LDL2E$"
558 DB "LDPI$LDLG2$LDLN2$LDZ$@$2XM1$YL2X$PTAN$PATAN$XTRACT$"
559 DB "@$DECSTP$INCSTP$PREM$YL2XP1$SQRT$@$RNDINT$SCALE$@$@$"
560
561MDB_TAB DB "ILD$@$IST$ISTP$@$LD$@$STP$"
562MDB_TAB2 DB "ENI$DISI$CLEX$INIT$"
563
564MDD_TAB DB "LD$@$ST$STP$RSTOR$@$SAVE$STSW$"
565MDD_TAB2 DB "FREE$XCH$ST$STP$"
566
567MDF_TAB DB "ILD$@$IST$ISTP$BLD$ILD$BSTP$ISTP$"
568
569
570OPTAB DB 11111111B ; DB
571 DW DB_OPER
572 DB 11111111B ; DW
573 DW DW_OPER
574 DB 11111111B ; COMMENT
575 DW ASSEMLOOP
576 DB 0 * 8 ; ADD
577 DW GROUP2
578 DB 2 * 8 ; ADC
579 DW GROUP2
580 DB 5 * 8 ; SUB
581 DW GROUP2
582 DB 3 * 8 ; SBB
583 DW GROUP2
584 DB 6 * 8 ; XOR
585 DW GROUP2
586 DB 1 * 8 ; OR
587 DW GROUP2
588 DB 4 * 8 ; AND
589 DW GROUP2
590 DB 00110111B ; AAA
591 DW NO_OPER
592 DB 11010101B ; AAD
593 DW AA_OPER
594 DB 11010100B ; AAM
595 DW AA_OPER
596 DB 00111111B ; AAS
597 DW NO_OPER
598 DB 2 * 8 ; CALL
599 DW CALL_OPER
600 DB 10011000B ; CBW
601 DW NO_OPER
602 DB 11111000B ; CLC
603 DW NO_OPER
604 DB 11111100B ; CLD
605 DW NO_OPER
606 DB 11111010B ; DIM
607 DW NO_OPER
608 DB 11110101B ; CMC
609 DW NO_OPER
610 DB 10100110B ; CMPB
611 DW NO_OPER
612 DB 10100111B ; CMPW
613 DW NO_OPER
614 DB 7 * 8 ; CMP
615 DW GROUP2
616 DB 10011001B ; CWD
617 DW NO_OPER
618 DB 00100111B ; DAA
619 DW NO_OPER
620 DB 00101111B ; DAS
621 DW NO_OPER
622 DB 1 * 8 ; DEC
623 DW DCINC_OPER
624 DB 6 * 8 ; DIV
625 DW GROUP1
626 DB 11011000B ; ESC
627 DW ESC_OPER
628 DB 00001001B ; FXCH
629 DW FGROUPP
630 DB 00101000B ; FFREE
631 DW FGROUPP
632 DB 11011001B ; FCOMPP
633 DW FDE_OPER
634 DB 00000011B ; FCOMP
635 DW FGROUPX ; Exception to normal P instructions
636 DB 00000010B ; FCOM
637 DW FGROUPX
638 DB 00010011B ; FICOMP
639 DW FGROUPZ
640 DB 00010010B ; FICOM
641 DW FGROUPZ
642 DB 11010000B ; FNOP
643 DW FD9_OPER
644 DB 11100000B ; FCHS
645 DW FD9_OPER
646 DB 11100001B ; FABS
647 DW FD9_OPER
648 DB 11100100B ; FTST
649 DW FD9_OPER
650 DB 11100101B ; FXAM
651 DW FD9_OPER
652 DB 11101001B ; FLDL2T
653 DW FD9_OPER
654 DB 11101010B ; FLDL2E
655 DW FD9_OPER
656 DB 11101100B ; FLDLG2
657 DW FD9_OPER
658 DB 11101101B ; FLDLN2
659 DW FD9_OPER
660 DB 11101011B ; FLDPI
661 DW FD9_OPER
662 DB 11101000B ; FLD1
663 DW FD9_OPER
664 DB 11101110B ; FLDZ
665 DW FD9_OPER
666 DB 11110000B ; F2XM1
667 DW FD9_OPER
668 DB 11111001B ; FYL2XP1
669 DW FD9_OPER
670 DB 11110001B ; FYL2X
671 DW FD9_OPER
672 DB 11110010B ; FPTAN
673 DW FD9_OPER
674 DB 11110011B ; FPATAN
675 DW FD9_OPER
676 DB 11110100B ; FXTRACT
677 DW FD9_OPER
678 DB 11110110B ; FDECSTP
679 DW FD9_OPER
680 DB 11110111B ; FINCSTP
681 DW FD9_OPER
682 DB 11111000B ; FPREM
683 DW FD9_OPER
684 DB 11111010B ; FSQRT
685 DW FD9_OPER
686 DB 11111100B ; FRNDINT
687 DW FD9_OPER
688 DB 11111101B ; FSCALE
689 DW FD9_OPER
690 DB 11100011B ; FINIT
691 DW FDB_OPER
692 DB 11100001B ; FDISI
693 DW FDB_OPER
694 DB 11100000B ; FENI
695 DW FDB_OPER
696 DB 11100010B ; FCLEX
697 DW FDB_OPER
698 DB 00111100B ; FBLD
699 DW FGROUPB
700 DB 00111110B ; FBSTP
701 DW FGROUPB
702 DB 00001101B ; FLDCW
703 DW FGROUP3W
704 DB 00001111B ; FSTCW
705 DW FGROUP3W
706 DB 00101111B ; FSTSW
707 DW FGROUP3W
708 DB 00001110B ; FSTENV
709 DW FGROUP3
710 DB 00001100B ; FLDENV
711 DW FGROUP3
712 DB 00101110B ; FSAVE
713 DW FGROUP3
714 DB 00101100B ; FRSTOR
715 DW FGROUP3
716 DB 00110000B ; FADDP
717 DW FGROUPP
718 DB 00000000B ; FADD
719 DW FGROUP
720 DB 00010000B ; FIADD
721 DW FGROUPZ
722 DB 00110100B ; FSUBRP
723 DW FGROUPP
724 DB 00000101B ; FSUBR
725 DW FGROUPDS
726 DB 00110101B ; FSUBP
727 DW FGROUPP
728 DB 00000100B ; FSUB
729 DW FGROUPDS
730 DB 00010101B ; FISUBR
731 DW FGROUPZ
732 DB 00010100B ; FISUB
733 DW FGROUPZ
734 DB 00110001B ; FMULP
735 DW FGROUPP
736 DB 00000001B ; FMUL
737 DW FGROUP
738 DB 00010001B ; FIMUL
739 DW FGROUPZ
740 DB 00110110B ; FDIVRP
741 DW FGROUPP
742 DB 00000111B ; FDIVR
743 DW FGROUPDS
744 DB 00110111B ; FDIVP
745 DW FGROUPP
746 DB 00000110B ; FDIV
747 DW FGROUPDS
748 DB 00010111B ; FIDIVR
749 DW FGROUPZ
750 DB 00010110B ; FIDIV
751 DW FGROUPZ
752 DB 10011011B ; FWAIT
753 DW NO_OPER
754 DB 00011000B ; FILD
755 DW FGROUPZ
756 DB 00001000B ; FLD
757 DW FGROUPX
758 DB 00001011B ; FSTP
759 DW FGROUPX
760 DB 00101010B ; FST
761 DW FGROUPX
762 DB 00011011B ; FISTP
763 DW FGROUPZ
764 DB 00011010B ; FIST
765 DW FGROUPZ
766 DB 11110100B ; HLT
767 DW NO_OPER
768 DB 7 * 8 ; IDIV
769 DW GROUP1
770 DB 5 * 8 ; IMUL
771 DW GROUP1
772 DB 0 * 8 ; INC
773 DW DCINC_OPER
774 DB 11001110B ; INTO
775 DW NO_OPER
776 DB 11001100B ; INTM
777 DW INT_OPER
778 DB 11101100B ; IN
779 DW IN_OPER
780 DB 11001111B ; IRET
781 DW NO_OPER
782 DB 01110111B ; JNBE
783 DW DISP8_OPER
784 DB 01110011B ; JAE
785 DW DISP8_OPER
786 DB 01110111B ; JA
787 DW DISP8_OPER
788 DB 11100011B ; JCXZ
789 DW DISP8_OPER
790 DB 01110011B ; JNB
791 DW DISP8_OPER
792 DB 01110110B ; JBE
793 DW DISP8_OPER
794 DB 01110010B ; JB
795 DW DISP8_OPER
796 DB 01110011B ; JNC
797 DW DISP8_OPER
798 DB 01110010B ; JC
799 DW DISP8_OPER
800 DB 01110010B ; JNAE
801 DW DISP8_OPER
802 DB 01110110B ; JNA
803 DW DISP8_OPER
804 DB 01110100B ; JZ
805 DW DISP8_OPER
806 DB 01110100B ; JE
807 DW DISP8_OPER
808 DB 01111101B ; JGE
809 DW DISP8_OPER
810 DB 01111111B ; JG
811 DW DISP8_OPER
812 DB 01111111B ; JNLE
813 DW DISP8_OPER
814 DB 01111101B ; JNL
815 DW DISP8_OPER
816 DB 01111110B ; JLE
817 DW DISP8_OPER
818 DB 01111100B ; JL
819 DW DISP8_OPER
820 DB 01111100B ; JNGE
821 DW DISP8_OPER
822 DB 01111110B ; JNG
823 DW DISP8_OPER
824 DB 4 * 8 ; JMP
825 DW JMP_OPER
826 DB 01110101B ; JNZ
827 DW DISP8_OPER
828 DB 01110101B ; JNE
829 DW DISP8_OPER
830 DB 01111010B ; JPE
831 DW DISP8_OPER
832 DB 01111011B ; JPO
833 DW DISP8_OPER
834 DB 01111011B ; JNP
835 DW DISP8_OPER
836 DB 01111001B ; JNS
837 DW DISP8_OPER
838 DB 01110001B ; JNO
839 DW DISP8_OPER
840 DB 01110000B ; JO
841 DW DISP8_OPER
842 DB 01111000B ; JS
843 DW DISP8_OPER
844 DB 01111010B ; JP
845 DW DISP8_OPER
846 DB 10011111B ; LAHF
847 DW NO_OPER
848 DB 11000101B ; LDS
849 DW L_OPER
850 DB 10001101B ; LEA
851 DW L_OPER
852 DB 11000100B ; LES
853 DW L_OPER
854 DB 11110000B ; LOCK
855 DW NO_OPER
856 DB 10101100B ; LODB
857 DW NO_OPER
858 DB 10101101B ; LODW
859 DW NO_OPER
860 DB 11100000B ; LOOPNZ
861 DW DISP8_OPER
862 DB 11100001B ; LOOPZ
863 DW DISP8_OPER
864 DB 11100000B ; LOOPNE
865 DW DISP8_OPER
866 DB 11100001B ; LOOPE
867 DW DISP8_OPER
868 DB 11100010B ; LOOP
869 DW DISP8_OPER
870 DB 10100100B ; MOVB
871 DW NO_OPER
872 DB 10100101B ; MOVW
873 DW NO_OPER
874 DB 11000110B ; MOV
875 DW MOV_OPER
876 DB 4 * 8 ; MUL
877 DW GROUP1
878 DB 3 * 8 ; NEG
879 DW GROUP1
880 DB 10010000B ; NOP
881 DW NO_OPER
882 DB 2 * 8 ; NOT
883 DW GROUP1
884 DB 11101110B ; OUT
885 DW OUT_OPER
886 DB 10011101B ; POPF
887 DW NO_OPER
888 DB 0 * 8 ; POP
889 DW POP_OPER
890 DB 10011100B ; PUSHF
891 DW NO_OPER
892 DB 6 * 8 ; PUSH
893 DW PUSH_OPER
894 DB 2 * 8 ; RCL
895 DW ROTOP
896 DB 3 * 8 ; RCR
897 DW ROTOP
898 DB 11110011B ; REPZ
899 DW NO_OPER
900 DB 11110010B ; REPNZ
901 DW NO_OPER
902 DB 11110011B ; REPE
903 DW NO_OPER
904 DB 11110010B ; REPNE
905 DW NO_OPER
906 DB 11110011B ; REP
907 DW NO_OPER
908 DB 11001011B ; RETF
909 DW GET_DATA16
910 DB 11000011B ; RET
911 DW GET_DATA16
912 DB 0 * 8 ; ROL
913 DW ROTOP
914 DB 1 * 8 ; ROR
915 DW ROTOP
916 DB 10011110B ; SAHF
917 DW NO_OPER
918 DB 7 * 8 ; SAR
919 DW ROTOP
920 DB 10101110B ; SCAB
921 DW NO_OPER
922 DB 10101111B ; SCAW
923 DW NO_OPER
924 DB 4 * 8 ; SHL
925 DW ROTOP
926 DB 5 * 8 ; SHR
927 DW ROTOP
928 DB 11111001B ; STC
929 DW NO_OPER
930 DB 11111101B ; STD
931 DW NO_OPER
932 DB 11111011B ; EI
933 DW NO_OPER
934 DB 10101010B ; STOB
935 DW NO_OPER
936 DB 10101011B ; STOW
937 DW NO_OPER
938 DB 11110110B ; TEST
939 DW TST_OPER
940 DB 10011011B ; WAIT
941 DW NO_OPER
942 DB 10000110B ; XCHG
943 DW EX_OPER
944 DB 11010111B ; XLAT
945 DW NO_OPER
946 DB 00100110B ; ESSEG
947 DW NO_OPER
948 DB 00101110B ; CSSEG
949 DW NO_OPER
950 DB 00110110B ; SSSEG
951 DW NO_OPER
952 DB 00111110B ; DSSEG
953 DW NO_OPER
954
955zzopcode label byte
956MAXOP = (zzopcode-optab)/3
957
958SHFTAB DW OFFSET DG:ROLMN,OFFSET DG:RORMN,OFFSET DG:RCLMN
959 DW OFFSET DG:RCRMN,OFFSET DG:SHLMN,OFFSET DG:SHRMN
960 DW OFFSET DG:BADMN,OFFSET DG:SARMN
961
962IMMTAB DW OFFSET DG:ADDMN,OFFSET DG:ORMN,OFFSET DG:ADCMN
963 DW OFFSET DG:SBBMN,OFFSET DG:ANDMN,OFFSET DG:SUBMN
964 DW OFFSET DG:XORMN,OFFSET DG:CMPMN
965
966GRP1TAB DW OFFSET DG:TESTMN,OFFSET DG:BADMN,OFFSET DG:NOTMN
967 DW OFFSET DG:NEGMN,OFFSET DG:MULMN,OFFSET DG:IMULMN
968 DW OFFSET DG:DIVMN,OFFSET DG:IDIVMN
969
970GRP2TAB DW OFFSET DG:INCMN,OFFSET DG:DECMN,OFFSET DG:CALLMN
971 DW OFFSET DG:CALLMN,OFFSET DG:JMPMN,OFFSET DG:JMPMN
972 DW OFFSET DG:PUSHMN,OFFSET DG:BADMN
973
974SEGTAB DW OFFSET DG:ESSAVE,OFFSET DG:CSSAVE,OFFSET DG:SSSAVE
975 DW OFFSET DG:DSSAVE
976
977REGTAB DB "AXBXCXDXSPBPSIDIDSESSSCSIPPC"
978
979; Flags are ordered to correspond with the bits of the flag
980; register, most significant bit first, zero if bit is not
981; a flag. First 16 entries are for bit set, second 16 for
982; bit reset.
983
984FLAGTAB DW 0
985 DW 0
986 DW 0
987 DW 0
988 DB "OV"
989 DB "DN"
990 DB "EI" ; "STI"
991 DW 0
992 DB "NG"
993 DB "ZR"
994 DW 0
995 DB "AC"
996 DW 0
997 DB "PE"
998 DW 0
999 DB "CY"
1000 DW 0
1001 DW 0
1002 DW 0
1003 DW 0
1004 DB "NV"
1005 DB "UP" ; "CLD"
1006 DB "DI"
1007 DW 0
1008 DB "PL"
1009 DB "NZ"
1010 DW 0
1011 DB "NA"
1012 DW 0
1013 DB "PO"
1014 DW 0
1015 DB "NC"
1016
1017 DB 80H DUP(?)
1018STACK LABEL BYTE
1019
1020
1021; Register save area
1022
1023AXSAVE DW 0
1024BXSAVE DW 0
1025CXSAVE DW 0
1026DXSAVE DW 0
1027SPSAVE DW 5AH
1028BPSAVE DW 0
1029SISAVE DW 0
1030DISAVE DW 0
1031DSSAVE DW 0
1032ESSAVE DW 0
1033RSTACK LABEL WORD ; Stack set here so registers can be saved by pushing
1034SSSAVE DW 0
1035CSSAVE DW 0
1036IPSAVE DW 100H
1037FSAVE DW 0
1038
1039REGDIF EQU AXSAVE-REGTAB
1040
1041; RAM area.
1042
1043RDFLG DB READ
1044TOTREG DB 13
1045DSIZ DB 0FH
1046NOREGL DB 8
1047DISPB DW 128
1048
1049LBUFSIZ DB BUFLEN
1050LBUFFCNT DB 0
1051LINEBUF DB 0DH
1052 DB BUFLEN DUP (?)
1053PFLAG DB 0
1054COLPOS DB 0
1055
1056 IF SYSVER
1057CONFCB DB 0
1058 DB "PRN "
1059 DB 25 DUP(0)
1060
1061POUT DD ?
1062COUT DD ?
1063CIN DD ?
1064IOBUFF DB 3 DUP (?)
1065IOADDR DD ?
1066
1067IOCALL DB 22
1068 DB 0
1069IOCOM DB 0
1070IOSTAT DW 0
1071 DB 8 DUP (0)
1072IOCHRET DB 0
1073 DW OFFSET DG:IOBUFF
1074IOSEG DW ?
1075IOCNT DW 1
1076 DW 0
1077 ENDIF
1078
1079QFLAG DB 0
1080NEWEXEC DB 0
1081RETSAVE DW ?
1082
1083USER_PROC_PDB DW ?
1084
1085HEADSAVE DW ?
1086
1087EXEC_BLOCK LABEL BYTE
1088 DW 0
1089COM_LINE LABEL DWORD
1090 DW 80H
1091 DW ?
1092COM_FCB1 LABEL DWORD
1093 DW FCB
1094 DW ?
1095COM_FCB2 LABEL DWORD
1096 DW FCB + 10H
1097 DW ?
1098COM_SSSP DD ?
1099COM_CSIP DD ?
1100
1101CONST ENDS
1102 END
1103
diff --git a/v2.0/source/DEBDATA.ASM b/v2.0/source/DEBDATA.ASM
new file mode 100644
index 0000000..fbe4a3f
--- /dev/null
+++ b/v2.0/source/DEBDATA.ASM
Binary files differ
diff --git a/v2.0/source/DEBEQU.ASM b/v2.0/source/DEBEQU.ASM
new file mode 100644
index 0000000..5a20f01
--- /dev/null
+++ b/v2.0/source/DEBEQU.ASM
@@ -0,0 +1,32 @@
1FALSE EQU 0
2TRUE EQU NOT FALSE
3
4IBMVER EQU true ; Set conditional switches
5MSVER EQU false
6
7SYSVER EQU FALSE ; if true, i/o direct to bios
8 ; so DOS can be debugged
9IBMJAPAN EQU FALSE
10
11SETCNTC EQU TRUE ; If this is FALSE, DEBUG will not set
12 ; the Control C int vector
13
14ZIBO EQU TRUE ; true if P traces over interrupts
15 ; and calls and dump looks pretty
16PROMPT EQU "-"
17FCB EQU 5CH
18EXEFCB EQU FCB
19BUFLEN EQU 80 ; Maximum length of line input buffer
20BPMAX EQU 10 ; Maximum number of breakpoints
21BPLEN EQU 5*BPMAX ; Length of breakpoint table
22REGTABLEN EQU 14 ; Number of registers
23SEGDIF EQU 0
24BUFSIZ EQU 512
25
26BXREG EQU "B"+5800H ; "BX"
27BPREG EQU "B"+5000H ; "BP"
28SIREG EQU "S"+4900H ; "SI"
29DIREG EQU "D"+4900H ; "DI"
30COMMA EQU 2C00H
31OPBUFLEN EQU 35
32 \ No newline at end of file
diff --git a/v2.0/source/DEBMES.ASM b/v2.0/source/DEBMES.ASM
new file mode 100644
index 0000000..791b2e5
--- /dev/null
+++ b/v2.0/source/DEBMES.ASM
Binary files differ
diff --git a/v2.0/source/DEBUASM.ASM b/v2.0/source/DEBUASM.ASM
new file mode 100644
index 0000000..6a53124
--- /dev/null
+++ b/v2.0/source/DEBUASM.ASM
@@ -0,0 +1,868 @@
1TITLE DEBUASM
2
3; Code for the UASSEMble command in the debugger
4
5.xlist
6.xcref
7 INCLUDE DEBEQU.ASM
8 INCLUDE DOSSYM.ASM
9.cref
10.list
11
12
13CODE SEGMENT PUBLIC BYTE 'CODE'
14CODE ENDS
15
16CONST SEGMENT PUBLIC BYTE
17
18 EXTRN SYNERR:BYTE
19 EXTRN NSEG:WORD,SISAVE:WORD,BPSAVE:WORD,DISAVE:WORD
20 EXTRN BXSAVE:WORD,DSSAVE:WORD,ESSAVE:WORD,CSSAVE:WORD,IPSAVE:WORD
21 EXTRN SSSAVE:WORD,CXSAVE:WORD,SPSAVE:WORD,FSAVE:WORD
22 EXTRN DISTAB:WORD,SHFTAB:WORD,IMMTAB:WORD,GRP1TAB:WORD,GRP2TAB:WORD
23 EXTRN DBMN:BYTE,ESCMN:BYTE,DISPB:WORD,STACK:BYTE,REG8:BYTE
24 EXTRN REG16:BYTE,SREG:BYTE,SIZ8:BYTE,SEGTAB:WORD,M8087_TAB:BYTE
25 EXTRN FI_TAB:BYTE,SIZE_TAB:BYTE,MD9_TAB:BYTE,MD9_TAB2:BYTE
26 EXTRN MDB_TAB:BYTE,MDB_TAB2:BYTE,MDD_TAB:BYTE,MDD_TAB2:BYTE
27 EXTRN MDF_TAB:BYTE
28
29CONST ENDS
30
31DATA SEGMENT PUBLIC BYTE
32
33 EXTRN DISADD:BYTE,DISCNT:WORD,BYTCNT:BYTE,TEMP:BYTE,AWORD:BYTE
34 EXTRN MIDFLD:BYTE,MODE:BYTE,REGMEM:BYTE,OPCODE:WORD,OPBUF:BYTE
35 EXTRN INDEX:WORD
36
37DATA ENDS
38
39DG GROUP CODE,CONST,DATA
40
41
42CODE SEGMENT PUBLIC BYTE 'CODE'
43ASSUME CS:DG,DS:DG,ES:DG,SS:DG
44
45
46 PUBLIC UNASSEM
47 PUBLIC DISASLN,MEMIMM,JMPCALL,SIGNIMM,ALUFROMREG,WORDTOALU
48 PUBLIC GRP2,PREFIX,OUTVARW,GRP1,SSPRE,MOVSEGTO,DSPRE,SHIFT
49 PUBLIC ESPRE,IMMED,CSPRE,OUTVARB,CHK10,ACCIMM,INT3,INVARB
50 PUBLIC MOVSEGFROM,LOADACC,OUTFIXB,XCHGAX,REGIMMW,SHORTJMP
51 PUBLIC SAV8,M8087,M8087_DB,M8087_DF,M8087_D9,M8087_DD
52 PUBLIC SAV16,SAVHEX,INFIXW,REGIMMB,OUTFIXW,SHIFTV,LONGJMP
53 PUBLIC INVARW,STOREACC,INFIXB,NOOPERANDS,ALUTOREG
54 PUBLIC SEGOP,REGOP,GETADDR
55
56 EXTRN CRLF:NEAR,PRINTMES:NEAR,BLANK:NEAR,TAB:NEAR,OUT:NEAR
57 EXTRN HEX:NEAR,DEFAULT:NEAR,OUTSI:NEAR,OUTDI:NEAR
58
59UNASSEM:
60 MOV BP,[CSSAVE] ; Default code segment
61 MOV DI,OFFSET DG:DISADD ; Default address
62 MOV CX,DISPB ; Default length
63 SHR CX,1
64 SHR CX,1
65 CALL DEFAULT
66 MOV WORD PTR [DISADD],DX ; Displacement of disassembly
67 MOV WORD PTR [DISADD+2],AX ; Segment
68 MOV WORD PTR [DISCNT],CX ; No. of bytes (but whole instructions)
69DISLP:
70 CALL DISASLN ; Disassemble one line
71 CALL CRLF
72 TEST [DISCNT],-1 ; See if we've used up the range
73 JNZ DISLP
74 RET
75
76GOTDIS: PUSH DS ; RE-GET LAST BYTE
77 PUSH SI
78 LDS SI,DWORD PTR [DISADD]
79 MOV AL,[SI-1]
80 POP SI
81 POP DS
82 RET
83
84GETDIS:
85 PUSH DS
86 LDS SI,DWORD PTR [DISADD]
87 LODSB ; Get the next byte of code
88 POP DS
89 MOV WORD PTR [DISADD],SI ; Update pointer
90 PUSH AX
91 CALL HEX ; Display each code byte
92 MOV SI,[DISCNT]
93 OR SI,SI ; Check if range exhausted
94 JZ ENDRNG ; If so, don't wrap around
95 DEC SI ; Count off the bytes
96 MOV [DISCNT],SI
97ENDRNG:
98 INC BYTE PTR[BYTCNT] ; Keep track of no. of bytes per line
99 POP AX
100 RET
101
102DSPRE: INC BYTE PTR [NSEG+1]
103SSPRE: INC BYTE PTR [NSEG+1]
104CSPRE: INC BYTE PTR [NSEG+1]
105ESPRE: INC BYTE PTR [NSEG+1]
106
107PREFIX:
108 POP BX ; Dump off return address
109 CALL FINLN
110 CALL CRLF
111DISASLN:
112 PUSH DS
113 LDS SI,DWORD PTR [DISADD]
114 CALL OUTSI ; Show disassembly address
115 POP DS
116 CALL BLANK
117DISASLN1:
118 MOV BYTE PTR [BYTCNT],0 ; Count of code bytes per line
119 MOV DI,OFFSET DG:OPBUF ; Point to operand buffer
120 MOV AL," "
121 MOV CX,OPBUFLEN-1 ; Don't do last byte which has end marker
122 REP STOSB ; Initialize operand buffer to blanks
123 MOV BYTE PTR [DI]," "+80H
124 CALL GETDIS ; Get opcode
125 MOV AH,0
126 MOV BX,AX
127 AND AL,1 ; Mask to "W" bit
128 MOV [AWORD],AL
129 MOV AL,BL ; Restore opcode
130 SHL BX,1
131 SHL BX,1 ; Multiply opcode by 4
132 ADD BX,OFFSET DG:DISTAB
133 MOV DX,[BX] ; Get pointer to mnemonic from table
134 MOV [OPCODE],DX ; Save it until line is complete
135 MOV DI,OFFSET DG:OPBUF ; Initialize for opcode routines
136 CALL WORD PTR [BX+2] ; Dispatch to opcode routine
137FINLN:
138 MOV SI,OFFSET DG:DISADD
139 MOV AH,[BYTCNT] ; See how many bytes in this instruction
140 ADD AH,AH ; Each uses two characters
141 MOV AL,14 ; Amount of space we want to use
142 SUB AL,AH ; See how many fill characters needed
143 CBW
144 XCHG CX,AX ; Parameter for TAB needed in CX
145 CALL TAB
146 MOV SI,[OPCODE]
147 OR SI,SI ; MAKE SURE THERE IS SOMETHING TO PRINT
148 JZ NOOPC
149 CALL PRINTMES ; Print opcode mnemonic
150 MOV AL,9
151 CALL OUT ; and a tab
152NOOPC: MOV SI,OFFSET DG:OPBUF
153 JMP PRINTMES ; and the operand buffer
154
155GETMODE:
156 CALL GETDIS ; Get the address mode byte
157 MOV AH,AL
158 AND AL,7 ; Mask to "r/m" field
159 MOV [REGMEM],AL
160 SHR AH,1
161 SHR AH,1
162 SHR AH,1
163 MOV AL,AH
164 AND AL,7 ; Mask to center 3-bit field
165 MOV [MIDFLD],AL
166 SHR AH,1
167 SHR AH,1
168 SHR AH,1
169 MOV [MODE],AH ; Leaving 2-bit "MOD" field
170 RET
171
172IMMED:
173 MOV BX,OFFSET DG:IMMTAB
174 CALL GETMNE
175FINIMM:
176 CALL TESTREG
177 JMP SHORT IMM
178
179MEMIMM:
180 CALL GETMODE
181 JMP SHORT FINIMM
182
183ACCIMM:
184 XOR AL,AL
185IMM1:
186 CALL SAVREG
187IMM:
188 MOV AL,","
189 STOSB
190 TEST BYTE PTR [AWORD],-1
191 JNZ SAV16
192SAV8:
193 CALL GETDIS
194 JMP SHORT SAVHEX
195
196LONGJMP:
197 PUSH DI
198 MOV DI,OFFSET DG:TEMP
199 CALL SAV16
200 POP DI
201 CALL SAV16
202 MOV AL,":"
203 STOSB
204 MOV SI,OFFSET DG:TEMP
205 MOV CX,4
206MOVDIG:
207 LODSB
208 STOSB
209 LOOP MOVDIG
210 RET
211SAV16:
212 CALL GETDIS ; Get low byte
213 MOV DL,AL
214 CALL GETDIS ; Get high byte
215 MOV DH,AL
216 CALL SAVHEX ; Convert and store high byte
217 MOV AL,DL
218SAVHEX:
219 MOV AH,AL
220 SHR AL,1
221 SHR AL,1
222 SHR AL,1
223 SHR AL,1
224 CALL SAVDIG
225 MOV AL,AH
226SAVDIG:
227 AND AL,0FH
228 ADD AL,90H
229 DAA
230 ADC AL,40H
231 DAA
232 STOSB
233 RET
234
235CHK10:
236 CALL GETDIS
237 CMP AL,10
238 JNZ SAVHEX
239 RET
240
241SIGNIMM:
242 MOV BX,OFFSET DG:IMMTAB
243 CALL GETMNE
244 CALL TESTREG
245 MOV AL,","
246 STOSB
247SAVD8:
248 CALL GETDIS ; Get signed 8-bit number
249 CBW
250 MOV DX,AX ; Save true 16-bit value in DX
251 MOV AH,AL
252 MOV AL,"+"
253 OR AH,AH
254; JZ nosign
255 JNS POSITIV ; OK if positive
256 MOV AL,"-"
257 NEG AH ; Get magnitude if negative
258POSITIV:
259 STOSB
260; nosign:
261 MOV AL,AH
262 JMP SHORT SAVHEX
263
264ALUFROMREG:
265 CALL GETADDR
266 MOV AL,","
267 STOSB
268REGFLD:
269 MOV AL,[MIDFLD]
270SAVREG:
271 MOV SI,OFFSET DG:REG8
272 CMP BYTE PTR [AWORD],1
273 JNE FNDREG
274SAVREG16:
275 MOV SI,OFFSET DG:REG16
276FNDREG:
277 CBW
278 ADD SI,AX
279 ADD SI,AX
280 MOVSW
281 RET
282
283SEGOP:
284 SHR AL,1
285 SHR AL,1
286 SHR AL,1
287SAVSEG:
288 AND AL,3
289 MOV SI,OFFSET DG:SREG
290 JMP SHORT FNDREG
291
292REGOP:
293 AND AL,7
294 JMP SHORT SAVREG16
295
296MOVSEGTO:
297 MOV BYTE PTR [AWORD],1
298 CALL GETADDR
299 MOV AL,","
300 STOSB
301 MOV AL,[MIDFLD]
302 JMP SHORT SAVSEG
303
304MOVSEGFROM:
305 CALL GETMODE
306 CALL SAVSEG
307 MOV BYTE PTR [AWORD],1
308 JMP SHORT MEMOP2
309
310GETADDR:
311 CALL GETMODE
312 JMP SHORT ADDRMOD
313
314WORDTOALU:
315 MOV BYTE PTR [AWORD],1
316ALUTOREG:
317 CALL GETMODE
318 CALL REGFLD
319MEMOP2:
320 MOV AL,","
321 STOSB
322ADDRMOD:
323 CMP BYTE PTR [MODE],3
324 MOV AL,[REGMEM]
325 JE SAVREG
326 XOR BX,BX
327 MOV BYTE PTR [NSEG],3
328 MOV BYTE PTR [DI],"["
329 INC DI
330 CMP AL,6
331 JNE NODRCT
332 CMP BYTE PTR [MODE],0
333 JE DIRECT ; Mode=0 and R/M=6 means direct addr.
334NODRCT:
335 MOV DL,AL
336 CMP AL,1
337 JBE USEBX
338 CMP AL,7
339 JE USEBX
340 CMP AL,3
341 JBE USEBP
342 CMP AL,6
343 JNE CHKPLS
344USEBP:
345 MOV BX,[BPSAVE]
346 MOV BYTE PTR [NSEG],2 ; Change default to Stack Segment
347 MOV AX,BPREG
348SAVBASE:
349 STOSW
350CHKPLS:
351 CMP DL,4
352 JAE NOPLUS
353 MOV AL,"+"
354 STOSB
355NOPLUS:
356 CMP DL,6
357 JAE DOMODE ; No index register
358 AND DL,1 ; Even for SI, odd for DI
359 JZ USESI
360 ADD BX,[DISAVE]
361 MOV AX,DIREG
362SAVINDX:
363 STOSW
364DOMODE:
365 MOV AL,[MODE]
366 OR AL,AL
367 JZ CLOSADD ; If no displacement, then done
368 CMP AL,2
369 JZ ADDDIR
370 CALL SAVD8 ; Signed 8-bit displacement
371ADDCLOS:
372 ADD BX,DX
373CLOSADD:
374 MOV AL,"]"
375 STOSB
376 MOV [INDEX],BX
377NOOPERANDS:
378 RET
379
380ADDDIR:
381 MOV AL,"+"
382 STOSB
383DIRECT:
384 CALL SAV16
385 JMP SHORT ADDCLOS
386
387USEBX:
388 MOV BX,[BXSAVE]
389 MOV AX,BXREG
390 JMP SHORT SAVBASE
391
392USESI:
393 ADD BX,[SISAVE]
394 MOV AX,SIREG
395 JMP SHORT SAVINDX
396
397SHORTJMP:
398 CALL GETDIS
399 CBW
400 ADD AX,WORD PTR [DISADD]
401 XCHG DX,AX
402SAVJMP:
403 MOV AL,DH
404 CALL SAVHEX
405 MOV AL,DL
406 JMP SAVHEX
407
408JMPCALL:
409 CALL GETDIS
410 MOV DL,AL
411 CALL GETDIS
412 MOV DH,AL
413 ADD DX,WORD PTR [DISADD]
414 JMP SHORT SAVJMP
415
416XCHGAX:
417 AND AL,7
418 CALL SAVREG16
419 MOV AL,","
420 STOSB
421 XOR AL,AL
422 JMP SAVREG16
423
424LOADACC:
425 XOR AL,AL
426 CALL SAVREG
427 MOV AL,","
428 STOSB
429MEMDIR:
430 MOV AL,"["
431 STOSB
432 XOR BX,BX
433 MOV BYTE PTR [NSEG],3
434 JMP DIRECT
435
436STOREACC:
437 CALL MEMDIR
438 MOV AL,","
439 STOSB
440 XOR AL,AL
441 JMP SAVREG
442
443REGIMMB:
444 MOV BYTE PTR [AWORD],0
445 JMP SHORT REGIMM
446REGIMMW:
447 MOV BYTE PTR [AWORD],1
448REGIMM:
449 AND AL,7
450 JMP IMM1
451
452INT3:
453 MOV BYTE PTR [DI],"3"
454 RET
455;
456; 8087 instructions whose first byte is 0dfh
457;
458M8087_DF:
459 CALL GET64F
460 JZ ISDD3
461 MOV SI,OFFSET DG:MDF_TAB
462 JMP NODB3
463;
464; 8087 instructions whose first byte is 0ddh
465;
466M8087_DD:
467 CALL GET64F
468 JZ ISDD3
469 MOV SI,OFFSET DG:MDD_TAB
470 JMP NOD93
471
472ISDD3:
473 MOV AL,DL
474 TEST AL,100B
475 JZ ISSTI
476 JMP ESC0
477ISSTI: AND AL,11B
478 MOV SI,OFFSET DG:MDD_TAB2
479 MOV CL,AL
480 CALL MOVBYT
481 JMP PUTRST
482;
483; 8087 instructions whose first byte is 0dbh
484;
485M8087_DB:
486 CALL GET64F
487 JZ ISDB3
488 MOV SI,OFFSET DG:MDB_TAB
489NODB3: CALL PUTOP
490 CALL PUTSIZE
491 JMP ADDRMOD
492
493ISDB3:
494 MOV AL,DL
495 TEST AL,100B
496 JNZ ISDBIG
497ESC0V: JMP ESC0
498ISDBIG: CALL GOTDIS
499 AND AL,11111B
500 CMP AL,4
501 JAE ESC0V
502 MOV SI,OFFSET DG:MDB_TAB2
503 JMP DOBIG
504;
505; 8087 instructions whose first byte is 0d9h
506;
507M8087_D9:
508 CALL GET64F
509 JZ ISD93
510
511 MOV SI,OFFSET DG:MD9_TAB
512NOD93: CALL PUTOP
513 AND AL,111B
514 CMP AL,3
515 JA NOSHO
516 MOV AL,DL
517 CALL PUTSIZE
518NOSHO: JMP ADDRMOD
519
520ISD93: MOV AL,DL
521 TEST AL,100B
522 JNZ ISD9BIG
523 AND AL,111B
524 OR AL,AL
525 JNZ NOTFLD
526 MOV AX,"DL"
527 STOSW
528 JMP SHORT PUTRST
529NOTFLD: CMP AL,1
530 JNZ NOTFXCH
531 MOV AX,"CX"
532 STOSW
533 MOV AL,"H"
534 JMP SHORT PUTRST1
535NOTFXCH:CMP AL,3
536 JNZ NOTFSTP
537 MOV AX,"TS"
538 STOSW
539 MOV AL,"P"
540PUTRST1:STOSB
541PUTRST: MOV AL,9
542 STOSB
543 JMP PUTST0
544
545NOTFSTP:CALL GOTDIS
546 CMP AL,11010000B ; CHECK FOR FNOP
547 JZ GOTFNOP
548 JMP ESC0
549GOTFNOP:MOV AX,"ON"
550 STOSW
551 MOV AL,"P"
552 STOSB
553 RET
554
555ISD9BIG:
556 CALL GOTDIS ; GET THE MODE BYTE
557 MOV SI,OFFSET DG:MD9_TAB2
558DOBIG: AND AL,11111B
559 MOV CL,AL
560 JMP MOVBYT
561;
562; entry point for the remaining 8087 instructions
563;
564M8087:
565 CALL GET64
566 CALL PUTFI ; PUT FIRST PART OF OPCODE
567 MOV AL,DL
568 CMP BYTE PTR [MODE],11B ; CHECK FOR REGISTER MODE
569 JZ MODEIS3
570 CALL PUTMN ; PUT MIDDLE PART OF OPCODE
571NO3: MOV AL,9 ; OUTPUT A TAB
572 STOSB
573 MOV AL,DL
574 CALL PUTSIZE ; OUTPUT THE OPERAND SIZE
575 JMP ADDRMOD
576
577MODEIS3:
578 TEST AL,100000B ; D BIT SET?
579 JZ MPUT ; NOPE...
580 TEST AL,000100B ; FDIV OR FSUB?
581 JZ MPUT ; NOPE...
582 XOR AL,1 ; REVERSE SENSE OF R
583 MOV DL,AL ; SAVE CHANGE
584MPUT: CALL PUTMN ; PUT MIDDLE PART OF OPCODE
585 MOV AL,DL
586 TEST AL,010000B
587 JZ NOPSH
588 MOV AL,"P"
589 STOSB
590NOPSH: MOV AL,9
591 STOSB
592 MOV AL,DL
593 AND AL,00000111B
594 CMP AL,2 ; FCOM
595 JZ PUTST0
596 CMP AL,3 ; FCOMP
597 JZ PUTST0
598 MOV AL,DL
599 TEST AL,100000B
600 JZ PUTSTST0
601;
602; output 8087 registers in the form st(n),st
603;
604PUTST0ST:
605 CALL PUTST0
606 MOV AL,','
607ISCOMP: STOSB
608
609PUTST: MOV AX,"TS"
610 STOSW
611 RET
612;
613; output 8087 registers in the form st,st(n)
614;
615PUTSTST0:
616 CALL PUTST
617 MOV AL,','
618 STOSB
619
620PUTST0: CALL PUTST
621 MOV AL,"("
622 STOSB
623 MOV AL,[REGMEM]
624 ADD AL,"0"
625 STOSB
626 MOV AL,")"
627 STOSB
628 RET
629;
630; output an 8087 mnemonic
631;
632PUTMN: MOV SI,OFFSET DG:M8087_TAB
633 MOV CL,AL
634 AND CL,00000111B
635 JMP SHORT MOVBYT
636;
637; output either 'FI' or 'F' for first byte of opcode
638;
639PUTFI: MOV SI,OFFSET DG:FI_TAB
640 JMP SHORT PUTFI2
641;
642; output size (dword, tbyte, etc.)
643;
644PUTSIZE:MOV SI,OFFSET DG:SIZE_TAB
645PUTFI2: CMP BYTE PTR [MODE],11B ; check if 8087 register
646 JNZ PUTFI3
647 AND AL,111000B ; LOOK FOR INVALID FORM OF 0DAH OPERANDS
648 CMP AL,010000B
649 JZ ESC0PJ
650 MOV AL,DL
651 CMP AL,110011B ; FCOMPP
652 JNZ GOFI
653 CMP BYTE PTR [REGMEM],1
654 JZ GOFI
655ESC0PJ: JMP ESC0P
656GOFI: XOR CL,CL
657 JMP SHORT MOVBYT
658;
659; Look for qword
660;
661PUTFI3: CMP AL,111101B
662 JZ GOTQU
663 CMP AL,111111B
664 JNZ NOTQU
665GOTQU: MOV CL,2
666 JMP SHORT MOVBYT
667;
668; look for tbyte
669;
670NOTQU: CMP AL,011101B
671 JZ GOTTB
672 CMP AL,111100B
673 JZ GOTTB
674 CMP AL,111110B
675 JZ GOTTB
676 CMP AL,011111B
677 JNZ NOTTB
678GOTTB: MOV CL,5
679 JMP SHORT MOVBYT
680
681NOTTB: MOV CL,4
682 SHR AL,CL
683 MOV CL,AL
684;
685; SI POINTS TO A TABLE OF TEXT SEPARATED BY "$"
686; CL = WHICH ELEMENT IN THE TABLE YOU WISH TO COPY TO [DI]
687;
688MOVBYT: PUSH AX
689 INC CL
690MOVBYT1:DEC CL
691 JZ MOVBYT3
692MOVBYT2:LODSB
693 CMP AL,'$'
694 JZ MOVBYT1
695 JMP MOVBYT2
696MOVBYT3:LODSB
697 CMP AL,'$'
698 JZ MOVBYT5
699 CMP AL,'@' ; THIS MEANS RESVERED OP-CODE
700 JNZ MOVBYT4
701 POP AX
702 JMP SHORT ESC0P ; GO DO AN ESCAPE COMMAND
703MOVBYT4:STOSB
704 JMP MOVBYT3
705MOVBYT5:POP AX
706 RET
707
708PUTOP: AND AL,111B
709 MOV CL,AL
710 CALL MOVBYT
711 MOV AL,9
712 STOSB
713 MOV AL,DL
714 RET
715
716GET64F: CALL GET64
717 MOV AL,"F"
718 STOSB
719 CMP BYTE PTR [MODE],3
720 MOV AL,DL
721 RET
722
723GET64:
724 AND AL,7
725 MOV DL,AL
726 CALL GETMODE
727 SHL DL,1
728 SHL DL,1
729 SHL DL,1
730 OR AL,DL
731 MOV DL,AL ; SAVE RESULT
732 RET
733
734ESC0P: POP DI ; CLEAN UP STACK
735ESC0: MOV WORD PTR [OPCODE],OFFSET DG:ESCMN
736 MOV AL,DL
737 MOV DI,OFFSET DG:OPBUF
738 JMP SHORT ESC1
739
740ESC: CALL GET64
741ESC1: CALL SAVHEX
742 CMP BYTE PTR [MODE],3
743 JZ SHRTESC
744 MOV BYTE PTR [AWORD],1
745 JMP MEMOP2
746
747SHRTESC:
748 MOV AL,","
749 STOSB
750 MOV AL,[REGMEM]
751 AND AL,7
752 JMP SAVREG
753
754INVARW:
755 CALL PUTAX
756 JMP SHORT INVAR
757INVARB:
758 CALL PUTAL
759INVAR: MOV AL,','
760 STOSB
761 JMP PUTDX
762
763INFIXW:
764 CALL PUTAX
765 JMP SHORT INFIX
766INFIXB:
767 CALL PUTAL
768INFIX: MOV AL,','
769 STOSB
770 JMP SAV8
771 STOSW
772 RET
773
774OUTVARB:
775 MOV BX,"LA"
776 JMP SHORT OUTVAR
777OUTVARW:
778 MOV BX,"XA"
779OUTVAR: CALL PUTDX
780OUTFV: MOV AL,','
781 STOSB
782 MOV AX,BX
783 STOSW
784 RET
785
786OUTFIXB:
787 MOV BX,"LA"
788 JMP SHORT OUTFIX
789OUTFIXW:
790 MOV BX,"XA"
791OUTFIX: CALL SAV8
792 JMP OUTFV
793
794PUTAL: MOV AX,"A"+4C00H ; "AL"
795 JMP SHORT PUTX
796PUTAX: MOV AX,"A"+5800H ; "AX"
797 JMP SHORT PUTX
798PUTDX: MOV AX,"D"+5800H ; "DX"
799PUTX: STOSW
800 RET
801
802SHFT:
803 MOV BX,OFFSET DG:SHFTAB
804 CALL GETMNE
805TESTREG:
806 CMP BYTE PTR [MODE],3
807 JZ NOFLG
808 MOV SI,OFFSET DG:SIZE_TAB
809 MOV CL,3
810 TEST BYTE PTR [AWORD],-1
811 JNZ TEST_1
812 INC CL
813TEST_1: CALL MOVBYT
814NOFLG:
815 JMP ADDRMOD
816
817SHIFTV:
818 CALL SHFT
819 MOV AL,","
820 STOSB
821 MOV WORD PTR [DI],"C"+4C00H ; "CL"
822 RET
823
824SHIFT:
825 CALL SHFT
826 MOV AX,"1,"
827 STOSW
828 RET
829
830GETMNE:
831 CALL GETMODE
832 MOV DL,AL
833 CBW
834 SHL AX,1
835 ADD BX,AX
836 MOV AX,[BX]
837 MOV [OPCODE],AX
838 MOV AL,DL
839 RET
840
841GRP1:
842 MOV BX,OFFSET DG:GRP1TAB
843 CALL GETMNE
844 OR AL,AL
845 JZ FINIMMJ
846 JMP TESTREG
847FINIMMJ:
848 JMP FINIMM
849
850GRP2:
851 MOV BX,OFFSET DG:GRP2TAB
852 CALL GETMNE
853 CMP AL,2
854 JB TESTREG
855 CMP AL,6
856 JAE INDIRECT
857 TEST AL,1
858 JZ INDIRECT
859 MOV AX,"AF" ; "FAR"
860 STOSW
861 MOV AX," R"
862 STOSW
863INDIRECT:
864 JMP ADDRMOD
865
866CODE ENDS
867 END UNASSEM
868
diff --git a/v2.0/source/DEBUG.ASM b/v2.0/source/DEBUG.ASM
new file mode 100644
index 0000000..91db1ca
--- /dev/null
+++ b/v2.0/source/DEBUG.ASM
@@ -0,0 +1,838 @@
1TITLE DEBUGger for MS-DOS
2; DEBUG-86 8086 debugger runs under 86-DOS version 2.30
3;
4; Modified 5/4/82 by AaronR to do all I/O direct to devices
5; Runs on MS-DOS 1.28 and above
6; REV 1.20
7; Tab expansion
8; New device interface (1.29 and above)
9; REV 2.0
10; line by line assembler added by C. Peters
11; REV 2.1
12; Uses EXEC system call
13; REV 2.2
14; Ztrace mode by zibo.
15; Fix dump display to indent properly
16; Parity nonsense by zibo
17;
18; REV 2.3
19; Split into seperate modules to allow for
20; assembly on an IBM PC
21;
22
23
24
25.xlist
26.xcref
27 INCLUDE DEBEQU.ASM
28 INCLUDE DOSSYM.ASM
29.cref
30.list
31
32 IF SYSVER
33
34; Structure for system call 72
35
36SYSINITVAR STRUC
37DPBHEAD DD ? ; Pointer to head of DPB-FAT list
38sft_addr DD ? ; Pointer to first FCB table
39; The following address points to the CLOCK device
40BCLOCK DD ?
41; The following address is used by DISKSTATCHK it is always
42; points to the console input device header
43BCON DD ? ; Console device entry points
44NUMIO DB 0 ; Number of disk tables
45MAXSEC DW 0 ; Maximum allowed sector size
46BUFFHEAD DD ?
47DEVHEAD DD ?
48SYSINITVAR ENDS
49
50 ENDIF
51
52
53CODE SEGMENT PUBLIC 'CODE'
54CODE ENDS
55
56CONST SEGMENT PUBLIC BYTE
57
58 EXTRN USER_PROC_PDB:WORD,STACK:BYTE,CSSAVE:WORD,DSSAVE:WORD
59 EXTRN SPSAVE:WORD,IPSAVE:WORD,LINEBUF:BYTE,QFLAG:BYTE
60 EXTRN NEWEXEC:BYTE,HEADSAVE:WORD,LBUFSIZ:BYTE,BACMES:BYTE
61 EXTRN BADVER:BYTE,ENDMES:BYTE,CARRET:BYTE,ParityMes:BYTE
62
63 IF IBMVER
64 EXTRN DSIZ:BYTE,NOREGL:BYTE,DISPB:WORD
65 ENDIF
66
67 IF SYSVER
68 EXTRN CONFCB:BYTE,POUT:DWORD,COUT:DWORD,CIN:DWORD,IOBUFF:BYTE
69 EXTRN IOADDR:DWORD,IOCALL:BYTE,IOCOM:BYTE,IOSTAT:WORD,IOCNT:WORD
70 EXTRN IOSEG:WORD,COLPOS:BYTE,BADDEV:BYTE,BADLSTMES:BYTE
71 EXTRN LBUFFCNT:BYTE,PFLAG:BYTE
72 ENDIF
73
74CONST ENDS
75
76DATA SEGMENT PUBLIC BYTE
77
78 EXTRN PARSERR:BYTE,DATAEND:WORD,ParityFlag:BYTE,DISADD:BYTE
79 EXTRN ASMADD:BYTE,DEFDUMP:BYTE,BYTEBUF:BYTE
80
81DATA ENDS
82
83DG GROUP CODE,CONST,DATA
84
85
86CODE SEGMENT PUBLIC 'CODE'
87ASSUME CS:DG,DS:DG,ES:DG,SS:DG
88
89 PUBLIC RESTART,SET_TERMINATE_VECTOR,DABORT,TERMINATE,COMMAND
90 PUBLIC FIND_DEBUG,CRLF,BLANK,TAB,OUT,INBUF,SCANB,SCANP
91 PUBLIC PRINTMES,RPRBUF,HEX,OUTSI,OUTDI,OUT16,DIGIT,BACKUP,RBUFIN
92
93 IF SYSVER
94 PUBLIC SETUDEV,DEVIOCALL
95 EXTRN DISPREG:NEAR,IN:NEAR
96 ENDIF
97
98 EXTRN PERR:NEAR,COMPARE:NEAR,DUMP:NEAR,ENTER:NEAR,FILL:NEAR
99 EXTRN GO:NEAR,INPUT:NEAR,LOAD:NEAR,MOVE:NEAR,NAME:NEAR
100 EXTRN REG:NEAR,SEARCH:NEAR,DWRITE:NEAR,UNASSEM:NEAR,ASSEM:NEAR
101 EXTRN OUTPUT:NEAR,ZTRACE:NEAR,TRACE:NEAR,GETHEX:NEAR,GETEOL:NEAR
102
103 EXTRN PREPNAME:NEAR,DEFIO:NEAR,SKIP_FILE:NEAR,DEBUG_FOUND:NEAR
104 EXTRN TrapParity:NEAR,ReleaseParity:NEAR
105
106 ORG 100H
107
108START:
109DEBUG:
110 JMP SHORT DSTRT
111
112HEADER DB "Vers 2.30"
113
114DSTRT:
115DOSVER_HIGH EQU 0200H ; 2.00 in hex
116 MOV AH,GET_VERSION
117 INT 21H
118 XCHG AH,AL ; Turn it around to AH.AL
119 CMP AX,DOSVER_HIGH
120 JAE OKDOS
121GOTBADDOS:
122 MOV DX,OFFSET DG:BADVER
123 MOV AH,STD_CON_STRING_OUTPUT
124 INT 21H
125 INT 20H
126
127OKDOS:
128 CALL TrapParity ; scarf up those parity guys
129 MOV AH,GET_CURRENT_PDB
130 INT 21H
131 MOV [USER_PROC_PDB],BX ; Initially set to DEBUG
132
133 IF SYSVER
134 MOV [IOSEG],CS
135 ENDIF
136
137 MOV SP,OFFSET DG:STACK
138 MOV [PARSERR],AL
139 MOV AH,GET_IN_VARS
140 INT 21H
141
142
143 IF SYSVER
144 LDS SI,ES:[BX.BCON]
145 MOV WORD PTR CS:[CIN+2],DS
146 MOV WORD PTR CS:[CIN],SI
147 MOV WORD PTR CS:[COUT+2],DS
148 MOV WORD PTR CS:[COUT],SI
149 PUSH CS
150 POP DS
151 MOV DX,OFFSET DG:CONFCB
152 MOV AH,FCB_OPEN
153 INT 21H
154 OR AL,AL
155 JZ GOTLIST
156 MOV DX,OFFSET DG:BADLSTMES
157 CALL RPRBUF
158 CALL RBUFIN
159 CALL CRLF
160 MOV CL,[LBUFFCNT]
161 OR CL,CL
162 JZ NOLIST1 ; User didn't specify one
163 XOR CH,CH
164 MOV DI,OFFSET DG:(CONFCB + 1)
165 MOV SI,OFFSET DG:LINEBUF
166 REP MOVSB
167 MOV DX,OFFSET DG:CONFCB
168 MOV AH,FCB_OPEN
169 INT 21H
170 OR AL,AL
171 JZ GOTLIST ; GOOD
172 MOV DX,OFFSET DG:BADDEV
173 CALL RPRBUF
174NOLIST1:
175 MOV WORD PTR [POUT+2],CS
176 MOV WORD PTR [POUT],OFFSET DG:LONGRET
177 JMP NOLIST
178
179XXX PROC FAR
180LONGRET:RET
181XXX ENDP
182 ENDIF
183
184GOTLIST:
185 IF SYSVER
186 MOV SI,DX
187 LDS SI,DWORD PTR DS:[SI.fcb_FIRCLUS]
188 MOV WORD PTR CS:[POUT+2],DS
189 MOV WORD PTR CS:[POUT],SI
190 ENDIF
191NOLIST:
192 MOV AX,CS
193 MOV DS,AX
194 MOV ES,AX
195
196; Code to print header
197; MOV DX,OFFSET DG:HEADER
198; CALL RPRBUF
199
200 CALL SET_TERMINATE_VECTOR
201
202 IF SETCNTC
203 MOV AL,23H ; Set vector 23H
204 MOV DX,OFFSET DG:DABORT
205 INT 21H
206 ENDIF
207
208 MOV DX,CS ; Get DEBUG's segment
209 MOV AX,OFFSET DG:DATAEND + 15 ; End of debug
210 SHR AX,1 ; Convert to segments
211 SHR AX,1
212 SHR AX,1
213 SHR AX,1
214 ADD DX,AX ; Add siz of debug in paragraphs
215 MOV AH,CREATE_PROCESS_DATA_BLOCK ; create program segment just after DEBUG
216 INT 21H
217 MOV AX,DX
218 MOV DI,OFFSET DG:DSSAVE
219 CLD
220 STOSW
221 STOSW
222 STOSW
223 STOSW
224 MOV WORD PTR [DISADD+2],AX
225 MOV WORD PTR [ASMADD+2],AX
226 MOV WORD PTR [DEFDUMP+2],AX
227 MOV AX,100H
228 MOV WORD PTR[DISADD],AX
229 MOV WORD PTR[ASMADD],AX
230 MOV WORD PTR [DEFDUMP],AX
231 MOV DS,DX
232 MOV ES,DX
233 MOV DX,80H
234 MOV AH,SET_DMA
235 INT 21H ; Set default DMA address to 80H
236 MOV AX,WORD PTR DS:[6]
237 MOV BX,AX
238 CMP AX,0FFF0H
239 PUSH CS
240 POP DS
241 JAE SAVSTK
242 MOV AX,WORD PTR DS:[6]
243 PUSH BX
244 MOV BX,OFFSET DG:DATAEND + 15
245 AND BX,0FFF0H ; Size of DEBUG in bytes (rounded up to PARA)
246 SUB AX,BX
247 POP BX
248SAVSTK:
249 PUSH BX
250 DEC AX
251 DEC AX
252 MOV BX,AX
253 MOV WORD PTR [BX],0
254 POP BX
255 MOV SPSAVE,AX
256 DEC AH
257 MOV ES:WORD PTR [6],AX
258 SUB BX,AX
259 MOV CL,4
260 SHR BX,CL
261 ADD ES:WORD PTR [8],BX
262
263 IF IBMVER
264 ; Get screen size and initialize display related variables
265 MOV AH,15
266 INT 10H
267 CMP AH,40
268 JNZ PARSCHK
269 MOV BYTE PTR DSIZ,7
270 MOV BYTE PTR NOREGL,4
271 MOV DISPB,64
272 ENDIF
273
274PARSCHK:
275; Copy rest of command line to test program's parameter area
276 MOV DI,FCB
277 MOV SI,81H
278 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
279 INT 21H
280 CALL SKIP_FILE ; Make sure si points to delimiter
281 CALL PREPNAME
282 PUSH CS
283 POP ES
284FILECHK:
285 MOV DI,80H
286 CMP BYTE PTR ES:[DI],0 ; ANY STUFF FOUND?
287 JZ COMMAND ; NOPE
288FILOOP: INC DI
289 CMP BYTE PTR ES:[DI],13 ; COMMAND LINE JUST SPACES?
290 JZ COMMAND
291 CMP BYTE PTR ES:[DI]," "
292 JZ FILOOP
293 CMP BYTE PTR ES:[DI],9
294 JZ FILOOP
295
296 CALL DEFIO ; WELL READ IT IN
297 MOV AX,CSSAVE
298 MOV WORD PTR DISADD+2,AX
299 MOV WORD PTR ASMADD+2,AX
300 MOV AX,IPSAVE
301 MOV WORD PTR DISADD,AX
302 MOV WORD PTR ASMADD,AX
303COMMAND:
304 CLD
305 MOV AX,CS
306 MOV DS,AX
307 MOV ES,AX
308 MOV SS,AX
309 MOV SP,OFFSET DG:STACK
310 STI
311 CMP [ParityFlag],0 ; did we detect a parity error?
312 JZ GoPrompt ; nope, go prompt
313 MOV [ParityFlag],0 ; reset flag
314 MOV DX,OFFSET DG:ParityMes ; message to print
315 MOV AH,STD_CON_STRING_OUTPUT; easy way out
316 INT 21h ; blam
317GoPrompt:
318 MOV AL,PROMPT
319 CALL OUT
320 CALL INBUF ; Get command line
321; From now and throughout command line processing, DI points
322; to next character in command line to be processed.
323 CALL SCANB ; Scan off leading blanks
324 JZ COMMAND ; Null command?
325 LODSB ; AL=first non-blank character
326; Prepare command letter for table lookup
327 SUB AL,"A" ; Low end range check
328 JB ERR1
329 CMP AL,"Z"-"A" ; Upper end range check
330 JA ERR1
331 SHL AL,1 ; Times two
332 CBW ; Now a 16-bit quantity
333 XCHG BX,AX ; In BX we can address with it
334 CALL CS:[BX+COMTAB] ; Execute command
335 JMP SHORT COMMAND ; Get next command
336ERR1: JMP PERR
337
338SET_TERMINATE_VECTOR:
339 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H ; Set vector 22H
340 MOV DX,OFFSET DG:TERMINATE
341 INT 21H
342 RET
343
344TERMINATE:
345 CMP BYTE PTR CS:[QFLAG],0
346 JNZ QUITING
347 MOV CS:[USER_PROC_PDB],CS
348 CMP BYTE PTR CS:[NEWEXEC],0
349 JZ NORMTERM
350 MOV AX,CS
351 MOV DS,AX
352 MOV SS,AX
353 MOV SP,OFFSET DG:STACK
354 MOV AX,[HEADSAVE]
355 JMP DEBUG_FOUND
356
357NORMTERM:
358 MOV DX,OFFSET DG:ENDMES
359 JMP SHORT RESTART
360
361QUITING:
362 MOV AX,(EXIT SHL 8)
363 INT 21H
364
365DABORT:
366 MOV DX,OFFSET DG:CARRET
367RESTART:
368 MOV AX,CS
369 MOV DS,AX
370 MOV SS,AX
371 MOV SP,OFFSET DG:STACK
372 CALL RPRBUF
373 JMP COMMAND
374
375 IF SYSVER
376SETUDEV:
377 MOV DI,OFFSET DG:CONFCB
378 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
379 INT 21H
380 CALL USERDEV
381 JMP DISPREG
382
383USERDEV:
384 MOV DX,OFFSET DG:CONFCB
385 MOV AH,FCB_OPEN
386 INT 21H
387 OR AL,AL
388 JNZ OPENERR
389 MOV SI,DX
390 TEST BYTE PTR [SI.fcb_DEVID],080H ; Device?
391 JZ OPENERR ; NO
392 LDS SI,DWORD PTR [CONFCB.fcb_FIRCLUS]
393 MOV WORD PTR CS:[CIN],SI
394 MOV WORD PTR CS:[CIN+2],DS
395 MOV WORD PTR CS:[COUT],SI
396 MOV WORD PTR CS:[COUT+2],DS
397 PUSH CS
398 POP DS
399 RET
400
401
402OPENERR:
403 MOV DX,OFFSET DG:BADDEV
404 CALL RPRBUF
405 RET
406 ENDIF
407
408; Get input line. Convert all characters NOT in quotes to upper case.
409
410INBUF:
411 CALL RBUFIN
412 MOV SI,OFFSET DG:LINEBUF
413 MOV DI,OFFSET DG:BYTEBUF
414CASECHK:
415 LODSB
416 CMP AL,'a'
417 JB NOCONV
418 CMP AL,'z'
419 JA NOCONV
420 ADD AL,"A"-"a" ; Convert to upper case
421NOCONV:
422 STOSB
423 CMP AL,13
424 JZ INDONE
425 CMP AL,'"'
426 JZ QUOTSCAN
427 CMP AL,"'"
428 JNZ CASECHK
429QUOTSCAN:
430 MOV AH,AL
431KILLSTR:
432 LODSB
433 STOSB
434 CMP AL,13
435 JZ INDONE
436 CMP AL,AH
437 JNZ KILLSTR
438 JMP SHORT CASECHK
439
440INDONE:
441 MOV SI,OFFSET DG:BYTEBUF
442
443; Output CR/LF sequence
444
445CRLF:
446 MOV AL,13
447 CALL OUT
448 MOV AL,10
449 JMP OUT
450
451; Physical backspace - blank, backspace, blank
452
453BACKUP:
454 MOV SI,OFFSET DG:BACMES
455
456; Print ASCII message. Last char has bit 7 set
457
458PRINTMES:
459 LODS CS:BYTE PTR [SI] ; Get char to print
460 CALL OUT
461 SHL AL,1 ; High bit set?
462 JNC PRINTMES
463 RET
464
465; Scan for parameters of a command
466
467SCANP:
468 CALL SCANB ; Get first non-blank
469 CMP BYTE PTR [SI],"," ; One comma between params OK
470 JNE EOLCHK ; If not comma, we found param
471 INC SI ; Skip over comma
472
473; Scan command line for next non-blank character
474
475SCANB:
476 PUSH AX
477SCANNEXT:
478 LODSB
479 CMP AL," "
480 JZ SCANNEXT
481 CMP AL,9
482 JZ SCANNEXT
483 DEC SI ; Back to first non-blank
484 POP AX
485EOLCHK:
486 CMP BYTE PTR [SI],13
487 RET
488
489; Hex addition and subtraction
490
491HEXADD:
492 MOV CX,4
493 CALL GETHEX
494 MOV DI,DX
495 MOV CX,4
496 CALL GETHEX
497 CALL GETEOL
498 PUSH DX
499 ADD DX,DI
500 CALL OUT16
501 CALL BLANK
502 CALL BLANK
503 POP DX
504 SUB DI,DX
505 MOV DX,DI
506 CALL OUT16
507 JMP SHORT CRLF
508
509; Print the hex address of DS:SI
510
511OUTSI:
512 MOV DX,DS ; Put DS where we can work with it
513 CALL OUT16 ; Display segment
514 MOV AL,":"
515 CALL OUT
516 MOV DX,SI
517 JMP SHORT OUT16 ; Output displacement
518
519; Print hex address of ES:DI
520; Same as OUTSI above
521
522OUTDI:
523 MOV DX,ES
524 CALL OUT16
525 MOV AL,":"
526 CALL OUT
527 MOV DX,DI
528
529; Print out 16-bit value in DX in hex
530
531OUT16:
532 MOV AL,DH ; High-order byte first
533 CALL HEX
534 MOV AL,DL ; Then low-order byte
535
536; Output byte in AL as two hex digits
537
538HEX:
539 MOV AH,AL ; Save for second digit
540; Shift high digit into low 4 bits
541 PUSH CX
542 MOV CL,4
543 SHR AL,CL
544 POP CX
545
546 CALL DIGIT ; Output first digit
547 MOV AL,AH ; Now do digit saved in AH
548DIGIT:
549 AND AL,0FH ; Mask to 4 bits
550; Trick 6-byte hex conversion works on 8086 too.
551 ADD AL,90H
552 DAA
553 ADC AL,40H
554 DAA
555
556; Console output of character in AL. No registers affected but bit 7
557; is reset before output.
558
559 IF SYSVER
560OUT:
561 PUSH AX
562 AND AL,7FH
563 CMP AL,7FH
564 JNZ NOTDEL
565 MOV AL,8 ; DELETE same as backspace
566NOTDEL:
567 CMP AL,9
568 JZ TABDO
569 CALL DOCONOUT
570 CMP AL,0DH
571 JZ ZEROPOS
572 CMP AL,0AH
573 JZ ZEROPOS
574 CMP AL,8
575 JNZ OOKRET
576 MOV AL," "
577 CALL DOCONOUT
578 MOV AL,8
579 CALL DOCONOUT
580 CMP BYTE PTR CS:[COLPOS],0
581 JZ NOTINC
582 DEC BYTE PTR CS:[COLPOS]
583 JMP NOTINC
584ZEROPOS:
585 MOV BYTE PTR CS:[COLPOS],0FFH
586OOKRET:
587 INC BYTE PTR CS:[COLPOS]
588NOTINC:
589 TEST BYTE PTR CS:[PFLAG],1
590 JZ POPRET
591 CALL LISTOUT
592POPRET:
593 POP AX
594 RET
595
596TABDO:
597 MOV AL,CS:[COLPOS]
598 OR AL,0F8H
599 NEG AL
600 PUSH CX
601 MOV CL,AL
602 XOR CH,CH
603 JCXZ POPTAB
604TABLP:
605 MOV AL," "
606 CALL OUT
607 LOOP TABLP
608POPTAB:
609 POP CX
610 POP AX
611 RET
612
613
614DOCONOUT:
615 PUSH DS
616 PUSH SI
617 PUSH AX
618CONOWAIT:
619 LDS SI,CS:[COUT]
620 MOV AH,10
621 CALL DEVIOCALL
622 MOV AX,CS:[IOSTAT]
623 AND AX,200H
624 JNZ CONOWAIT
625 POP AX
626 PUSH AX
627 MOV AH,8
628 CALL DEVIOCALL
629 POP AX
630 POP SI
631 POP DS
632 RET
633
634
635LISTOUT:
636 PUSH DS
637 PUSH SI
638 PUSH AX
639LISTWAIT:
640 LDS SI,CS:[POUT]
641 MOV AH,10
642 CALL DEVIOCALL
643 MOV AX,CS:[IOSTAT]
644 AND AX,200H
645 JNZ LISTWAIT
646 POP AX
647 PUSH AX
648 MOV AH,8
649 CALL DEVIOCALL
650 POP AX
651 POP SI
652 POP DS
653 RET
654
655DEVIOCALL:
656 PUSH ES
657 PUSH BX
658 PUSH CS
659 POP ES
660 MOV BX,OFFSET DG:IOCALL
661 MOV CS:[IOCOM],AH
662 MOV WORD PTR CS:[IOSTAT],0
663 MOV WORD PTR CS:[IOCNT],1
664 MOV CS:[IOBUFF],AL
665 MOV WORD PTR CS:[IOADDR+2],DS
666 MOV AX,[SI+6]
667 MOV WORD PTR CS:[IOADDR],AX
668 CALL DWORD PTR CS:[IOADDR]
669 MOV AX,[SI+8]
670 MOV WORD PTR CS:[IOADDR],AX
671 CALL DWORD PTR CS:[IOADDR]
672 MOV AL,CS:[IOBUFF]
673 POP BX
674 POP ES
675 RET
676 ELSE
677
678OUT:
679 PUSH DX
680 PUSH AX
681 AND AL,7FH
682 MOV DL,AL
683 MOV AH,2
684 INT 21H
685 POP AX
686 POP DX
687 RET
688 ENDIF
689
690
691 IF SYSVER
692RBUFIN:
693 PUSH AX
694 PUSH ES
695 PUSH DI
696 PUSH CS
697 POP ES
698 MOV BYTE PTR [LBUFFCNT],0
699 MOV DI,OFFSET DG:LINEBUF
700FILLBUF:
701 CALL IN
702 CMP AL,0DH
703 JZ BDONE
704 CMP AL,8
705 JZ ECHR
706 CMP AL,7FH
707 JZ ECHR
708 CMP BYTE PTR [LBUFFCNT],BUFLEN
709 JAE BFULL
710 STOSB
711 INC BYTE PTR [LBUFFCNT]
712 JMP SHORT FILLBUF
713
714BDONE:
715 STOSB
716 POP DI
717 POP ES
718 POP AX
719 RET
720
721BFULL:
722 MOV AL,8
723 CALL OUT
724 MOV AL,7
725 CALL OUT
726 JMP SHORT FILLBUF
727
728ECHR:
729 CMP DI,OFFSET DG:LINEBUF
730 JZ FILLBUF
731 DEC DI
732 DEC BYTE PTR [LBUFFCNT]
733 JMP SHORT FILLBUF
734 ELSE
735
736RBUFIN:
737 PUSH AX
738 PUSH DX
739 MOV AH,10
740 MOV DX,OFFSET DG:LBUFSIZ
741 INT 21H
742 POP DX
743 POP AX
744 RET
745 ENDIF
746
747
748 IF SYSVER
749RPRBUF:
750 PUSHF
751 PUSH AX
752 PUSH SI
753 MOV SI,DX
754PLOOP:
755 LODSB
756 CMP AL,"$"
757 JZ PRTDONE
758 CALL OUT
759 JMP SHORT PLOOP
760PRTDONE:
761 POP SI
762 POP AX
763 POPF
764 RET
765 ELSE
766
767RPRBUF:
768 MOV AH,9
769 INT 21H
770 RET
771 ENDIF
772
773; Output one space
774
775BLANK:
776 MOV AL," "
777 JMP OUT
778
779; Output the number of blanks in CX
780
781TAB:
782 CALL BLANK
783 LOOP TAB
784 RET
785
786; Command Table. Command letter indexes into table to get
787; address of command. PERR prints error for no such command.
788
789COMTAB DW ASSEM ; A
790 DW PERR ; B
791 DW COMPARE ; C
792 DW DUMP ; D
793 DW ENTER ; E
794 DW FILL ; F
795 DW GO ; G
796 DW HEXADD ; H
797 DW INPUT ; I
798 DW PERR ; J
799 DW PERR ; K
800 DW LOAD ; L
801 DW MOVE ; M
802 DW NAME ; N
803 DW OUTPUT ; O
804 IF ZIBO
805 DW ZTRACE
806 ELSE
807 DW PERR ; P
808 ENDIF
809 DW QUIT ; Q (QUIT)
810 DW REG ; R
811 DW SEARCH ; S
812 DW TRACE ; T
813 DW UNASSEM ; U
814 DW PERR ; V
815 DW DWRITE ; W
816 IF SYSVER
817 DW SETUDEV ; X
818 ELSE
819 DW PERR
820 ENDIF
821 DW PERR ; Y
822 DW PERR ; Z
823
824QUIT:
825 INC BYTE PTR [QFLAG]
826 MOV BX,[USER_PROC_PDB]
827FIND_DEBUG:
828IF NOT SYSVER
829 MOV AH,SET_CURRENT_PDB
830 INT 21H
831ENDIF
832 CALL ReleaseParity ; let system do normal parity stuff
833 MOV AX,(EXIT SHL 8)
834 INT 21H
835
836CODE ENDS
837 END START
838
diff --git a/v2.0/source/DEV.ASM b/v2.0/source/DEV.ASM
new file mode 100644
index 0000000..b640d55
--- /dev/null
+++ b/v2.0/source/DEV.ASM
@@ -0,0 +1,439 @@
1;
2; Device call routines for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7IFNDEF KANJI
8KANJI EQU 0 ;FALSE
9ENDIF
10
11CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14.xlist
15.xcref
16INCLUDE DOSSYM.ASM
17INCLUDE DEVSYM.ASM
18.cref
19.list
20
21TITLE DEV - Device call routines
22NAME Dev
23
24 i_need IOXAD,DWORD
25 i_need IOSCNT,WORD
26 i_need DEVIOBUF,4
27 i_need IOCALL,BYTE
28 i_need IOMED,BYTE
29 i_need IORCHR,BYTE
30 i_need CALLSCNT,WORD
31 i_need DMAAdd,DWORD
32 i_need NullDevPt,DWORD
33 i_need CallDevAd,DWORD
34 i_need Attrib,BYTE
35 i_need NULDEV,DWORD
36 i_need Name1,BYTE
37 i_need DevPt,DWORD
38 i_need DPBHead,DWORD
39 i_need NumIO,BYTE
40 i_need ThisDPB,DWORD
41 i_need DevCall,DWORD
42 i_need VerFlg,BYTE
43
44SUBTTL IOFUNC -- DO FUNCTION 1-12 I/O
45PAGE
46IOFUNC_RETRY:
47ASSUME DS:NOTHING,ES:NOTHING
48 invoke restore_world
49
50 procedure IOFUNC,NEAR
51ASSUME DS:NOTHING,ES:NOTHING
52
53; Inputs:
54; DS:SI Points to FCB
55; AH is function code
56; = 0 Input
57; = 1 Input Status
58; = 2 Output
59; = 3 Output Status
60; = 4 Flush
61; AL = character if output
62; Function:
63; Perform indicated I/O to device or file
64; Outputs:
65; AL is character if input
66; If a status call
67; zero set if not ready
68; zero reset if ready (character in AL for input status)
69; For regular files:
70; Input Status
71; Gets character but restores fcb_RR field
72; Zero set on EOF
73; Input
74; Gets character advances fcb_RR field
75; Returns ^Z on EOF
76; Output Status
77; Always ready
78; AX altered, all other registers preserved
79
80 MOV WORD PTR [IOXAD+2],SS
81 MOV WORD PTR [IOXAD],OFFSET DOSGROUP:DEVIOBUF
82 MOV WORD PTR [IOSCNT],1
83 MOV WORD PTR [DEVIOBUF],AX
84
85IOFUNC2:
86 TEST [SI.fcb_DEVID],080H
87 JNZ IOTODEV
88 JMP IOTOFILE
89
90IOTODEV:
91 invoke save_world
92 PUSH DS
93 PUSH SS
94 POP ES
95 PUSH SS
96 POP DS
97ASSUME DS:DOSGROUP
98 XOR BX,BX
99 MOV [IOCALL.REQSTAT],BX
100 MOV BYTE PTR [IOMED],BL
101
102 MOV BX,OFFSET DOSGROUP:IOCALL
103
104 MOV CX,(DEVRD SHL 8) OR DRDWRHL
105 OR AH,AH
106 JZ DCALLR
107 MOV CX,(DEVRDND SHL 8) OR DRDNDHL
108 DEC AH
109 JZ DCALLR
110 MOV CX,(DEVWRT SHL 8) OR DRDWRHL
111 DEC AH
112 JZ DCALLO
113 MOV CX,(DEVOST SHL 8) OR DSTATHL
114 DEC AH
115 JZ DCALLO
116DFLUSH:
117 MOV CX,(DEVIFL SHL 8) OR DFLSHL
118DCALLR:
119 MOV AH,86H
120DCALL:
121 MOV [IOCALL.REQLEN],CL
122 MOV [IOCALL.REQFUNC],CH
123 MOV CL,AH
124 POP DS
125ASSUME DS:NOTHING
126 CALL DEVIOCALL
127 MOV DI,[IOCALL.REQSTAT]
128 TEST DI,STERR
129 JZ OKDEVIO
130 MOV AH,CL
131 invoke CHARHARD
132 CMP AL,1
133 JZ IOFUNC_RETRY
134;Know user must have wanted ignore. Make sure device shows ready so
135;that DOS doesn't get caught in a status loop when user simply wants
136;to ignore the error.
137 AND BYTE PTR [IOCALL.REQSTAT+1], NOT (STBUI SHR 8)
138OKDEVIO:
139 PUSH SS
140 POP DS
141ASSUME DS:DOSGROUP
142 CMP CH,DEVRDND
143 JNZ DNODRD
144 MOV AL,BYTE PTR [IORCHR]
145 MOV [DEVIOBUF],AL
146
147DNODRD: MOV AH,BYTE PTR [IOCALL.REQSTAT+1]
148 NOT AH ; Zero = busy, not zero = ready
149 AND AH,STBUI SHR 8
150
151 invoke restore_world
152ASSUME DS:NOTHING
153 MOV AX,WORD PTR [DEVIOBUF]
154 return
155
156DCALLO:
157 MOV AH,87H
158 JMP SHORT DCALL
159
160IOTOFILE:
161ASSUME DS:NOTHING
162 OR AH,AH
163 JZ IOIN
164 DEC AH
165 JZ IOIST
166 DEC AH
167 JZ IOUT
168 return ; NON ZERO FLAG FOR OUTPUT STATUS
169
170IOIST:
171 PUSH WORD PTR [SI.fcb_RR] ; Save position
172 PUSH WORD PTR [SI.fcb_RR+2]
173 CALL IOIN
174 POP WORD PTR [SI.fcb_RR+2] ; Restore position
175 POP WORD PTR [SI.fcb_RR]
176 return
177
178IOUT:
179 CALL SETXADDR
180 invoke STORE
181 invoke FINNOSAV
182 CALL RESTXADDR ; If you change this into a jmp don't come
183 return ; crying to me when things don't work ARR
184
185IOIN:
186 CALL SETXADDR
187 invoke LOAD
188 PUSH CX
189 invoke FINNOSAV
190 POP CX
191 OR CX,CX ; Check EOF
192 CALL RESTXADDR
193 MOV AL,[DEVIOBUF] ; Get byte from trans addr
194 retnz
195 MOV AL,1AH ; ^Z if EOF
196 return
197
198SETXADDR:
199 POP WORD PTR [CALLSCNT] ; Return address
200 invoke save_world
201 PUSH WORD PTR [DMAADD] ; Save Disk trans addr
202 PUSH WORD PTR [DMAADD+2]
203 PUSH DS
204 PUSH SS
205 POP DS
206ASSUME DS:DOSGROUP
207 MOV CX,WORD PTR [IOXAD+2]
208 MOV WORD PTR [DMAADD+2],CX
209 MOV CX,WORD PTR [IOXAD]
210 MOV WORD PTR [DMAADD],CX ; Set byte trans addr
211 MOV CX,[IOSCNT] ; ioscnt specifies length of buffer
212 POP DS
213ASSUME DS:NOTHING
214 MOV [SI.fcb_RECSIZ],1 ; One byte per record
215 MOV DX,SI ; FCB to DS:DX
216 invoke GETRRPOS
217 JMP SHORT RESTRET ; RETURN ADDRESS
218
219RESTXADDR:
220 POP WORD PTR [CALLSCNT] ; Return address
221 POP WORD PTR [DMAADD+2] ; Restore Disk trans addr
222 POP WORD PTR [DMAADD]
223 invoke restore_world
224RESTRET:JMP WORD PTR [CALLSCNT] ; Return address
225IOFUNC ENDP
226
227SUBTTL DEVIOCALL, DEVIOCALL2 - CALL A DEVICE
228PAGE
229 procedure DEVIOCALL,NEAR
230ASSUME DS:NOTHING,ES:NOTHING
231
232; Inputs:
233; DS:SI Points to device FCB
234; ES:BX Points to request data
235; Function:
236; Call the device
237; Outputs:
238; None
239; DS:SI,AX destroyed, others preserved
240
241 LDS SI,DWORD PTR [SI.fcb_FIRCLUS]
242
243 entry DEVIOCALL2
244; As above only DS:SI points to device header on entry, and DS:SI is preserved
245 MOV AX,[SI.SDEVSTRAT]
246 MOV WORD PTR [CALLDEVAD],AX
247 MOV WORD PTR [CALLDEVAD+2],DS
248 CALL DWORD PTR [CALLDEVAD]
249 MOV AX,[SI.SDEVINT]
250 MOV WORD PTR [CALLDEVAD],AX
251 CALL DWORD PTR [CALLDEVAD]
252 return
253DEVIOCALL ENDP
254
255SUBTTL DEVNAME - LOOK FOR NAME OF DEVICE
256PAGE
257 procedure DEVNAME,NEAR
258ASSUME DS:DOSGROUP,ES:DOSGROUP
259
260; Inputs:
261; DS,ES:DOSGROUP
262; Filename in NAME1
263; Function:
264; Determine if file is in list of I/O drivers
265; Outputs:
266; Carry set if name not found
267; ELSE
268; Zero flag set
269; BH = Bit 7,6 = 1, bit 5 = 0 (cooked mode)
270; bits 0-4 set from low byte of attribute word
271; DEVPT = DWORD pointer to Device header of device
272; Registers BX destroyed
273
274 PUSH SI
275 PUSH DI
276 PUSH CX
277
278 IF KANJI
279 PUSH WORD PTR [NAME1]
280 CMP [NAME1],5
281 JNZ NOKTR
282 MOV [NAME1],0E5H
283NOKTR:
284 ENDIF
285
286 TEST BYTE PTR [ATTRIB],attr_volume_id ; If looking for VOL id don't find devs
287 JNZ RET31
288 MOV SI,OFFSET DOSGROUP:NULDEV
289LOOKIO:
290ASSUME DS:NOTHING
291 TEST [SI.SDEVATT],DEVTYP
292 JZ SKIPDEV ; Skip block devices
293 PUSH SI
294 ADD SI,SDEVNAME
295 MOV DI,OFFSET DOSGROUP:NAME1
296 MOV CX,4 ; All devices are 8 letters
297 REPE CMPSW ; Check for name in list
298 POP SI
299 JZ IOCHK ; Found it?
300SKIPDEV:
301 LDS SI,DWORD PTR [SI] ; Get address of next device
302 CMP SI,-1 ; At end of list?
303 JNZ LOOKIO
304RET31: STC ; Not found
305RETNV: PUSH SS
306 POP DS
307ASSUME DS:DOSGROUP
308
309 IF KANJI
310 POP WORD PTR [NAME1]
311 ENDIF
312
313 POP CX
314 POP DI
315 POP SI
316 RET
317
318IOCHK:
319ASSUME DS:NOTHING
320 MOV WORD PTR [DEVPT+2],DS ; Save pointer to device
321 MOV BH,BYTE PTR [SI.SDEVATT]
322 OR BH,0C0H
323 AND BH,NOT 020H ;Clears Carry
324 MOV WORD PTR [DEVPT],SI
325 JMP RETNV
326DevName ENDP
327
328 procedure GetBP,NEAR
329ASSUME DS:DOSGROUP,ES:NOTHING
330
331; Inputs:
332; AL = Logical unit number (A = 0)
333; Function:
334; Find Drive Parameter Block
335; Outputs:
336; ES:BP points to DPB
337; [THISDPB] = ES:BP
338; Carry set if unit number bad
339; No other registers altered
340
341 LES BP,[DPBHEAD] ; Just in case drive isn't valid
342 AND AL,3FH ; Mask out dirty and device bits
343 CMP AL,BYTE PTR [NUMIO]
344 CMC
345 JC GOTDPB ; Get drive A
346FNDDPB:
347 CMP AL,ES:[BP.dpb_drive]
348 JZ GOTDPB ; Carry is clear if jump executed
349 LES BP,ES:[BP.dpb_next_dpb]
350 JMP SHORT FNDDPB
351GOTDPB:
352 MOV WORD PTR [THISDPB],BP
353 MOV WORD PTR [THISDPB+2],ES
354 RET
355GetBP ENDP
356
357SUBTTL SETREAD, SETWRITE -- SET UP HEADER BLOCK
358PAGE
359 procedure SETREAD,NEAR
360ASSUME DS:NOTHING,ES:NOTHING
361
362; Inputs:
363; DS:BX = Transfer Address
364; CX = Record Count
365; DX = Starting Record
366; AH = Media Byte
367; AL = Unit Code
368; Function:
369; Set up the device call header at DEVCALL
370; Output:
371; ES:BX Points to DEVCALL
372; No other registers effected
373
374 PUSH DI
375 PUSH CX
376 PUSH AX
377 MOV CL,DEVRD
378SETCALLHEAD:
379 MOV AL,DRDWRHL
380 PUSH SS
381 POP ES
382 MOV DI,OFFSET DOSGROUP:DEVCALL
383 STOSB ; length
384 POP AX
385 STOSB ; Unit
386 PUSH AX
387 MOV AL,CL
388 STOSB ; Command code
389 XOR AX,AX
390 STOSW ; Status
391 ADD DI,8 ; Skip link fields
392 POP AX
393 XCHG AH,AL
394 STOSB ; Media byte
395 XCHG AL,AH
396 PUSH AX
397 MOV AX,BX
398 STOSW
399 MOV AX,DS
400 STOSW ; Transfer addr
401 POP CX ; Real AX
402 POP AX ; Real CX
403 STOSW ; Count
404 XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX
405 STOSW ; Start
406 XCHG AX,CX
407 XCHG DX,CX
408 POP DI
409 MOV BX,OFFSET DOSGROUP:DEVCALL
410 RET
411
412 entry SETWRITE
413ASSUME DS:NOTHING,ES:NOTHING
414
415; Inputs:
416; DS:BX = Transfer Address
417; CX = Record Count
418; DX = Starting Record
419; AH = Media Byte
420; AL = Unit Code
421; Function:
422; Set up the device call header at DEVCALL
423; Output:
424; ES:BX Points to DEVCALL
425; No other registers effected
426
427 PUSH DI
428 PUSH CX
429 PUSH AX
430 MOV CL,DEVWRT
431 ADD CL,[VERFLG]
432 JMP SHORT SETCALLHEAD
433SETREAD ENDP
434
435do_ext
436
437CODE ENDS
438 END
439
diff --git a/v2.0/source/DEVDRIV.txt b/v2.0/source/DEVDRIV.txt
new file mode 100644
index 0000000..3c82793
--- /dev/null
+++ b/v2.0/source/DEVDRIV.txt
@@ -0,0 +1,802 @@
1 MS-DOS 2.0 Device Drivers
2
3INTRODUCTION
4
5 In the past, DOS-device driver (BIOS for those who are
6familiar with CP/M) communication has been mediated with
7registers and a fixed-address jump-table. This approach
8has suffered heavily from the following two observations:
9
10 o The old jump-table ideas of the past are fixed in
11 scope and allow no extensibility.
12
13 o The past device driver interfaces have been written
14 without regard for the true power of the hardware.
15 When a multitasking system or interrupt driven
16 hardware is installed a new BIOS must be written
17 largely from scratch.
18
19 In MSDOS 2.0, the DOS-device driver interface has changed
20from the old jump-table style to one in which the device
21drivers are linked together in a list. This allows new
22drivers for optional hardware to be installed (and even
23written) in the field by other vendors or the user himself.
24This flexibility is one of the major new features of MS-DOS
252.0.
26
27 Each driver in the chain defines two entry points; the
28strategy routine and the interrupt routine. The 2.0 DOS
29does not really make use of two entry points (it simply calls
30strategy, then immediately calls interrupt). This dual entry
31point scheme is designed to facilitate future multi-tasking
32versions of MS-DOS. In multi-tasking environments I/O must
33be asynchronous, to accomplish this the strategy routine
34will be called to queue (internally) a request and return
35quickly. It is then the responsibility of the interrupt
36routine to perform the actual I/O at interrupt time by picking
37requests off the internal queue (set up by the strategy
38routine), and process them. When a request is complete,
39it is flagged as "done" by the interrupt routine. The DOS
40periodically scans the list of requests looking for ones
41flagged as done, and "wakes up" the process waiting for the
42completion of the request.
43
44 In order for requests to be queued as above it is no
45longer sufficient to pass I/O information in registers, since
46many requests may be pending at any one time. Therefore
47the new device interface uses data "packets" to pass request
48information. A device is called with a pointer to a packet,
49this packet is linked into a global chain of all pending
50I/O requests maintained by the DOS. The device then links
51the packet into its own local chain of requests for this
52particular device. The device interrupt routine picks
53requests of the local chain for processing. The DOS scans
54the global chain looking for completed requests. These
55packets are composed of two pieces, a static piece which
56has the same format for all requests (called the static
57request header), which is followed by information specific
58to the request. Thus packets have a variable size and format.
59
60 At this points it should be emphasized that MS-DOS 2.0
61does not implement most of these features, as future versions
62will. There is no global or local queue. Only one request
63is pending at any one time, and the DOS waits for this current
64request to be completed. For 2.0 it is sufficient for the
65strategy routine to simply store the address of the packet
66at a fixed location, and for the interrupt routine to then
67process this packet by doing the request and returning.
68Remember: the DOS just calls the strategy routine and then
69immediately calls the interrupt routine, it is assumed that
70the request is completed when the interrupt routine returns.
71This additional functionality is defined at this time so
72that people will be aware and thinking about the future.
73
74
75FORMAT OF A DEVICE DRIVER
76
77 A device driver is simply a relocatable memory image
78with all of the code in it to implement the device (like
79a .COM file, but not ORGed at 100 Hex). In addition it has
80a special header at the front of it which identifies it as
81a device, defines the strategy and interrupt entry points,
82and defines various attributes. It should also be noted
83that there are two basic types of devices.
84
85 The first is character devices. These are devices which
86are designed to do character I/O in a serial manner like
87CON, AUX, and PRN. These devices are named (ie. CON, AUX,
88CLOCK, etc.), and users may open channels (FCBs) to do I/O
89to them.
90
91 The second class of devices is block devices. These
92devices are the "disk drives" on the system, they can do
93random I/O in pieces called blocks (usually the physical
94sector size) and hence the name. These devices are not
95"named" as the character devices are, and therefore cannot
96be "opened" directly. Instead they are "mapped" via the
97drive letters (A,B,C, etc.).
98
99 Block devices also have units. In other words a single
100driver may be responsible for one or more disk drives. For
101instance block device driver ALPHA (please note that we cannot
102actually refer to block devices by a name!) may be
103responsible for drives A,B,C and D, this simply means that
104it has four units (0-3) defined and therefore takes up four
105drive letters. Which units correspond to which drive letters
106is determined by the position of the driver in the chain
107of all drivers: if driver ALPHA is the first block driver
108in the device chain, and it defines 4 units (0-3), then they
109will be A,B,C and D. If BETA is the second block driver
110and defines three units (0-2), then they will be E,F and
111G and so on. MS-DOS 2.0 is not limited to 16 block device
112units, as previous versions were. The theoretical limit
113is 63 (2^6 - 1), but it should be noted that after 26 the
114drive letters get a little strange (like ] \ and ^). NOTE:
115Character devices cannot define multiple units (this because
116they have only one name).
117
118
119Here is what that special device header looks like:
120
121 +--------------------------------------+
122 | DWORD Pointer to next device |
123 | (Must be set to -1) |
124 +--------------------------------------+
125 | WORD Attributes |
126 | Bit 15 = 1 if char device 0 if blk |
127 | if bit 15 is 1 |
128 | Bit 0 = 1 if Current sti device |
129 | Bit 1 = 1 if Current sto output |
130 | Bit 2 = 1 if Current NUL device |
131 | Bit 3 = 1 if Current CLOCK dev |
132 | Bit 4 = 1 if SPECIAL |
133 | Bit 14 is the IOCTL bit (see below) |
134 | Bit 13 is the NON IBM FORMAT bit |
135 +--------------------------------------+
136 | WORD Pointer to Device strategy |
137 | entry point |
138 +--------------------------------------+
139 | WORD Pointer to Device interrupt |
140 | entry point |
141 +--------------------------------------+
142 | 8-BYTE character device name field |
143 | Character devices set a device name |
144 | For block devices the first byte is |
145 | The number of units |
146 +--------------------------------------+
147
148 Note that the device entry points are words. They must
149be offsets from the same segment number used to point to
150this table. Ie. if XXX.YYY points to the start of this
151table, then XXX.strategy and XXX.interrupt are the entry
152points.
153
154 A word about the Attribute field. This field is used
155most importantly to tell the system whether this device is
156a block or character device (bit 15). Most of other bits
157are used to give selected character devices certain special
158treatment (NOTE: these bits mean nothing on a block device).
159Let's say a user has a new device driver which he wants to
160be the standard input and output. Besides just installing
161the driver he needs to tell SYSINIT (and the DOS) that he
162wishes his new driver to override the current sti and sto
163(the "CON" device). This is accomplished by setting the
164attributes to the desired characteristics, so he would set
165Bits 0 and 1 to 1 (note that they are separate!!). Similarly
166a new CLOCK device could be installed by setting that
167attribute, see the section at the end on the CLOCK device.
168NOTE: that although there is a NUL device attribute, the
169NUL device cannot be re-assigned. This attribute exists
170for the DOS so that it can tell if the NUL device is being
171used.
172
173 The NON IBM FORMAT bit applies only to block devices
174and effects the operation of the get BPB device call (see
175below).
176
177 The other bit of interest is the IOCTL bit which has
178meaning on character or block devices. This bit tells the
179DOS whether this device can handle control strings (via the
180IOCTL system call).
181
182 If a driver cannot process control strings, it should
183initially set this bit to 0. This tells the DOS to return
184an error if an attempt is made (via IOCTL system call) to
185send or receive control strings to this device. A device
186which can process control strings should initialize it to
1871. For drivers of this type, the DOS will make calls to
188the IOCTL INPUT and OUTPUT device functions to send and
189receive IOCTL strings (see IOCTL in the SYSTEM-CALLS
190document).
191
192 The IOCTL functions allow data to be sent and received
193by the device itself for its own use (to set baud rate, stop
194bits, form length etc., etc.), instead of passing data over
195the device channel as a normal read or write does. The
196interpretation of the passed information is up to the device,
197but it MUST NOT simply be treated as a normal I/O.
198
199 The SPECIAL bit applies only to character drivers and
200more particularly to CON drivers. The new 2.0 interface
201is a much more general and consistent interface than the
202old 1.25 DOS interface. It allows for a number of additional
203features of 2.0. It is also slower than 1.25 if old style
204"single byte" system calls are made. To make most efficient
205use of the interface all applications should block their
206I/O as much as possible. This means make one XENIX style
207system call to output X bytes rather than X system calls
208to output one byte each. Also putting a device channel in
209RAW mode (see IOCTL) provides a means of putting out
210characters even FASTER than 1.25. To help alleviate the
211CON output speed problem for older programs which use the
2121 - 12 system calls to output large amounts of data the
213SPECIAL bit has been implemented. If this bit is 1 it means
214the device is the CON output device, and has implemented
215an interrupt 29 Hex handler, where the 29 Hex handler is
216defined as follows:
217
218 Interrupt 29h handlers
219
220 Input:
221 Character in AL
222
223 Function:
224 output the character in al to the user
225 screen.
226 Output:
227 None
228 Registers:
229 all registers except bx must be preserved.
230 No registers except for al have a known or
231 consistent value.
232
233 If a character device implements the SPECIAL bit, it
234is the responsibility of the driver to install an address
235at the correct location in the interrupt table for interrupt
23629 Hex as part of its INIT code. IMPLICATION: There can
237be only one device driver with the SPECIAL bit set in the
238system. There is no check to insure this state.
239
240WARNING: THIS FEATURE WILL NOT BE SUPPORTED IN FUTURE VERSIONS
241 OF THE OPERATING SYSTEM. IMPLICATION: Any application
242 (not device driver) which uses INT 29H directly will
243 not work on future versions, YOU HAVE BEEN WARNED.
244
245 In order to "make" a device driver that SYSINIT can
246install, a memory image or .EXE (non-IBM only) format file
247must be created with the above header at the start. The
248link field should be initialized to -1 (SYSINIT fills it
249in). The attribute field and entry points must be set
250correctly, and if the device is a character device, the name
251field must be filled in with the name (if a block device
252SYSINIT will fill in the correct unit count). This name
253can be any 8 character "legal" file name. In fact SYSINIT
254always installs character devices at the start of the device
255list, so if you want to install a new CON device all you
256have to do is name it "CON". The new one is ahead of the
257old one in the list and thus preempts the old one as the
258search for devices stops on the first match. Be sure to
259set the sti and sto bits on a new CON device!
260
261NOTE: Since SYSINIT may install the driver anywhere, you
262 must be very careful about FAR memory references. You
263 should NOT expect that your driver will go in the same
264 place every time (The default BIOS drivers are exempted
265 from this of course).
266
267
268INSTALLATION OF DEVICE DRIVERS
269
270 Unlike past versions MS-DOS 2.0 allows new device drivers
271to be installed dynamically at boot time. This is
272accomplished by the new SYSINIT module supplied by Microsoft,
273which reads and processes the CONFIG.SYS file. This module
274is linked together with the OEM default BIOS in a similar
275manner to the way FORMAT is built.
276
277 One of the functions defined for each device is INIT.
278This routine is called once when the device is installed,
279and never again. The only thing returned by the init routine
280is a location (DS:DX) which is a pointer to the first free
281byte of memory after the device driver, (like a terminate
282and stay resident). This pointer method can be used to "throw
283away" initialization code that is only needed once, saving
284on space.
285
286 Block devices are installed the same way and also return
287a first free byte pointer as above, additional information
288is also returned:
289
290 o The number of units is returned, this determines
291 logical device names. If the current maximum logical
292 device letter is F at the time of the install call,
293 and the init routine returns 4 as the number of units,
294 then they will have logical names G, H, I and J.
295 This mapping is determined by by the position of
296 the driver in the device list and the number of units
297 on the device (stored in the first byte of the device
298 name field).
299
300 o A pointer to a BPB (Bios Parameter Block) pointer
301 array is also returned. This will be similar to
302 the INIT table used in previous versions, but will
303 have more information in it. There is one table
304 for each unit defined. These blocks will be used
305 to build a DPB (Drive Parameter Block) for each of
306 the units. The pointer passed to the DOS from the
307 driver points to an array of n word pointers to BPBs
308 where n is the number of units defined. In this
309 way if all units are the same, all of the pointers
310 can point to the same BPB, saving space. NOTE: this
311 array must be protected (below the free pointer set
312 by the return) since the DPB will be built starting
313 at the byte pointed to by the free pointer. The
314 sector size defined must be less than or equal to
315 the maximum sector size defined at default BIOS init
316 time. If it isn't the install will fail. One new
317 piece of DPB info set from this table will be a "media
318 descriptor byte". This byte means nothing to the
319 DOS, but is passed to devices so that they know what
320 form of a DPB the DOS is currently using for a
321 particular Drive-Unit.
322
323 Block devices may take several approaches; they may be
324dumb or smart. A dumb device would define a unit (and
325therefore a DPB) for each possible media drive combination.
326Unit 0 = drive 0 single side, unit 1 = drive 0 double side,
327etc. For this approach media descriptor bytes would mean
328nothing. A smart device would allow multiple media per unit,
329in this case the BPB table returned at init must define space
330large enough to accommodate the largest possible media
331supported. Smart drivers will use the "media byte" to pass
332around info about what media is currently in a unit. NOTE:
333If the DPB is a "hybrid" made to get the right sizes, it
334should give an invalid "media byte" back to the DOS.
335
336 The BOOT (default BIOS) drivers are installed pretty
337much as above. The preset device list is scanned. If block
338drivers are encountered they are installed as above (with
339the exception that the break is not moved since the drivers
340are already resident in the BIOS). Note that the logical
341drive letters are assigned in list order, thus the driver
342which is to have logical A must be the first unit of the
343first block device in the list. The order of character
344devices is also important. There must be at least 4 character
345devices defined at boot which must be the first four devices
346(of either type), the first will become standard input,
347standard output, and standard error output. The second will
348become standard auxiliary input and output, the third will
349become standard list output, and the forth will become the
350date/time (CLOCK) device. Thus the BIOS device list must
351look like this:
352
353->CON->AUX->PRN->CLOCK->any other block or character devices
354
355THE DRIVER
356
357 A device driver will define the following functions:
358
359 Command Function
360 Code
361
362 0 INIT
363 1 MEDIA CHECK (Block only, NOP for character)
364 2 BUILD BPB " " " " "
365 3 IOCTL INPUT (Only called if device has IOCTL)
366 4 INPUT (read)
367 5 NON-DESTRUCTIVE INPUT NO WAIT (Char devs only)
368 6 INPUT STATUS " " "
369 7 INPUT FLUSH " " "
370 8 OUTPUT (write)
371 9 OUTPUT (Write) with verify
372 10 OUTPUT STATUS " " "
373 11 OUTPUT FLUSH " " "
374 12 IOCTL OUTPUT (Only called if device has IOCTL)
375
376 As mentioned before, the first entry point is the strategy
377routine which is called with a pointer to a data block. This
378call does not perform the request, all it does is queue it
379(save the data block pointer). The second interrupt entry
380point is called immediately after the strategy call. The
381"interrupt" routine is called with no parameters, its primary
382function is to perform the operation based on the queued
383data block and set up any returns.
384
385 The "BUILD BPB" and "MEDIA CHECK" are the interesting
386new ones, these are explained by examining the sequence of
387events in the DOS which occurs when a drive access call (other
388than read or write) is made:
389
390 I. Turn drive letter into DPB pointer by looking
391 for DPB with correct driver-unit number.
392
393 II. Call device driver and request media check for
394 Drive-Unit. DOS passes its current Media
395 descriptor byte (from DPB). Call returns:
396
397 Media Not Changed
398 Media Changed
399 Not Sure
400 Error
401
402 Error - If an error occurs the error code should
403 be set accordingly.
404
405 Media Not changed - Current DPB and media byte
406 are OK, done.
407
408 Media Changed - Current DPB and media are wrong,
409 invalidate any buffers for this unit, and
410 goto III.
411
412 Not Sure - If there are dirty buffers for this
413 unit, assume DPB and media byte are OK and
414 done. If nothing dirty, assume media changed,
415 invalidate any buffers for unit, and goto
416 III.
417
418 NOTE: If a hybrid DPB was built at init and
419 an invalid Media byte was set, the driver
420 should return media changed when this invalid
421 media byte is encountered.
422
423 III. Call device driver to build BPB with media byte
424 and buffer.
425
426 What the driver must do at step III is determine the
427correct media that is currently in the unit, and return a
428pointer to a BPB table (same as for the install call). This
429table will be used as at init to build a correct DPB for
430the unit If the determined media descriptor byte in the table
431turns out to be the same as the one passed in, then the DOS
432will not build a new table, but rather just use the old one.
433Therefore in this case the driver doesn't have to correctly
434fill in the other entries if desired.
435
436 The build BPB call also gets a pointer to a one sector
437buffer. What this buffer contains is determined by the NON
438IBM FORMAT bit in the attribute field. If the bit is zero
439(device is IBM format compatible) then the buffer contains
440the first sector of the first FAT, in particular the FAT
441ID byte is the first byte of this buffer. NOTE: It must
442be true that the BPB is the same, as far as location of the
443FAT is concerned, for all possible media. This is because
444this first FAT sector must be read BEFORE the actual BPB
445is returned. If the NON IBM FORMAT bit is set then the
446pointer points to one sector of scratch space which may be
447used for anything.
448
449CALL FORMAT
450
451 When the DOS calls a device driver to perform a finction,
452it passes a structure (Drive Request Structure) in ES:BX
453to perform operations and does a long call to the driver's
454strategy entry point. This structure is a fixed length header
455(Static Request Header) followed by data pertinent to the
456operation being performed. NOTE: It is the drivers
457responsibility to preserve machine state.
458
459STATIC REQUEST HEADER ->
460 +-----------------------------+
461 | BYTE length of record |
462 | Length in bytes of this |
463 | Drive Request Structure |
464 +-----------------------------+
465 | BYTE unit code |
466 | The subunit the operation |
467 | is for (minor device) |
468 | (no meaning on character |
469 | devices) |
470 +-----------------------------+
471 | BYTE command code |
472 +-----------------------------+
473 | WORD Status |
474 +-----------------------------+
475 | 8 bytes reserved here for |
476 | two DWORD links. One will |
477 | be a link for the DOS queue |
478 | The other for the device |
479 | queue |
480 +-----------------------------+
481
482STATUS WORD
483
484 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
485 +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+
486 | E | | B | D | |
487 | R | RESERVED | U | O | ERROR CODE (bit 15 on)|
488 | R | | I | N | |
489 +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+
490
491 The status word is zero on entry and is set by the driver
492interrupt routine on return.
493
494 Bit 8 is the done bit, it means the operation is complete.
495For the moment the Driver just sets it to one when it exits,
496in the future this will be set by the interrupt routine to
497tell the DOS the operation is complete.
498
499 Bit 15 is the error bit, if it is set then the low 8
500bits indicate the error:
501
502 0 Write Protect violation
503 (NEW) 1 Unknown Unit
504 2 Drive not ready
505 (NEW) 3 Unknown command
506 4 CRC error
507 (NEW) 5 Bad Drive Request Structure length
508 6 Seek error
509 (NEW) 7 Unknown media
510 8 Sector not found
511 (NEW) 9 Printer out of paper
512 A Write Fault
513 (NEW) B Read Fault
514 C General Failure
515
516Bit 9 is the busy bit which is set only by status calls (see
517STATUS CALL below).
518
519
520 Here is the data block format for each function:
521
522READ or WRITE - ES:BX (Including IOCTL) ->
523 +------------------------------------+
524 | 13-BYTE Static Request Header |
525 +------------------------------------+
526 | BYTE Media descriptor from DPB |
527 +------------------------------------+
528 | DWORD transfer address |
529 +------------------------------------+
530 | WORD byte/sector Count |
531 ---+------------------------------------+---
532 | WORD starting sector number |
533 | (ignored on Char Devs) |
534 +------------------------------------+
535
536 In addition to setting the status word, the driver must
537set the Sector count to the actual number of sectors (or
538bytes) transferred. NOTE: No error check is performed on
539an IOCTL I/O call, driver MUST correctly set the return sector
540(byte) count to the actual number of bytes transferred,
541however.
542
543NOTE: THE FOLLOWING APPLIES TO BLOCK DEVICE DRIVERS.
544
545 Under certain circumstances the BIOS may be asked to
546do a write operation of 64K bytes which seems to be a "wrap
547around" of the transfer address in the BIOS I/O packet. This
548arises due to an optimization added to the write code in
549MS-DOS. It will only manifest on user WRITEs which are within
550a sector size of 64K bytes on files which are "growing" past
551the current EOF. IT IS ALLOWABLE FOR THE BIOS TO IGNORE
552THE BALANCE OF THE WRITE WHICH "WRAPS AROUND" IF IT SO
553CHOOSES. For instance a WRITE of 10000H bytes worth of
554sectors with a transfer address of XXX:1 could ignore the
555last two bytes (remember that a user program can never request
556an I/O of more than FFFFH bytes and cannot wrap around (even
557to 0) in his transfer segment, so in this case the last two
558bytes can be ignored).
559
560
561NON DESRUCTIVE READ NO WAIT - ES:BX ->
562 +------------------------------------+
563 | 13-BYTE Static Request Header |
564 +------------------------------------+
565 | BYTE read from device |
566 +------------------------------------+
567
568 This call is analogous to the console input status call
569on MS-DOS 1.25. If the character device returns Busy bit
570= 0 (characters in buffer), then the next character that
571would be read is returned. This character is NOT removed
572from the input buffer (hence the term Non Destructive Read).
573In essence this call allows the DOS to look ahead one input
574character.
575
576
577MEDIA CHECK - ES:BX ->
578 +------------------------------------+
579 | 13-BYTE Static Request Header |
580 +------------------------------------+
581 | BYTE Media Descriptor from DPB |
582 +------------------------------------+
583 | BYTE returned |
584 +------------------------------------+
585
586 In addition to setting status word, driver must set the
587return byte.
588
589 Return Byte :
590 -1 Media has been changed
591 0 Don't know if media has been changed
592 1 Media has not been changed
593
594 If the driver can return -1 or 1 (by having a door-lock
595or other interlock mechanism) the performance of MSDOS 2.0
596is enhanced as the DOS need not reread the FAT for each
597directory access.
598
599
600BUILD BPB - ES:BX ->
601 +------------------------------------+
602 | 13-BYTE Static Request Header |
603 +------------------------------------+
604 | BYTE Media Descriptor from DPB |
605 +------------------------------------+
606 | DWORD Transfer Address |
607 | (points to one sectors worth of |
608 | scratch space or first sector |
609 | of FAT depending on the value |
610 | of the NON IBM FORMAT bit) |
611 +------------------------------------+
612 | DWORD Pointer to BPB |
613 +------------------------------------+
614
615 If the NON IBM FORMAT bit of the device is set, then
616the DWORD Transfer Address points to a one sector buffer
617which can be used for any purpose. If the NON IBM FORMAT
618bit is 0, then this buffer contains the first sector of the
619FAT; in this case the driver must not alter this buffer (this
620mode is useful if all that is desired is to read the FAT
621ID byte).
622
623 If IBM compatible format is used (NON IBM FORMAT BIT
624= 0), then it must be true that the first sector of the first
625FAT is located at the same sector on all possible media.
626This is because the FAT sector will be read BEFORE the media
627is actually determined.
628
629 In addition to setting status word, driver must set the
630Pointer to the BPB on return.
631
632
633 In order to allow for many different OEMs to read each
634other's disks, the following standard is suggested: The
635information relating to the BPB for a particular piece of
636media is kept in the boot sector for the media. In
637particular, the format of the boot sector is:
638
639 +------------------------------------+
640 | 3 BYTE near JUMP to boot code |
641 +------------------------------------+
642 | 8 BYTES OEM name and version |
643 ---+------------------------------------+---
644 B | WORD bytes per sector |
645 P +------------------------------------+
646 B | BYTE sectors per allocation unit |
647 +------------------------------------+
648 | | WORD reserved sectors |
649 V +------------------------------------+
650 | BYTE number of FATs |
651 +------------------------------------+
652 | WORD number of root dir entries |
653 +------------------------------------+
654 | WORD number of sectors in logical |
655 ^ | image |
656 | +------------------------------------+
657 B | BYTE media descriptor |
658 P +------------------------------------+
659 B | WORD number of FAT sectors |
660 ---+------------------------------------+---
661 | WORD sectors per track |
662 +------------------------------------+
663 | WORD number of heads |
664 +------------------------------------+
665 | WORD number of hidden sectors |
666 +------------------------------------+
667
668 The three words at the end are optional, the DOS doesn't
669care about them (since they are not part of the BPB). They
670are intended to help the BIOS understand the media. Sectors
671per track may be redundant (could be figured out from total
672size of the disk). Number of heads is useful for supporting
673different multi-head drives which have the same storage
674capacity, but a different number of surfaces. Number of
675hidden sectors is useful for supporting drive partitioning
676schemes.
677
678
679 Currently, the media descriptor byte has been defined
680for a small range of media:
681
682 5 1/4" diskettes:
683
684 Flag bits:
685 01h - on -> 2 double sided
686
687 All other bits must be on.
688
689 8" disks:
690 FEh - IBM 3740 format, singled-sided, single-density,
691 128 bytes per sector, soft sectored, 4 sectors
692 per allocation unit, 1 reserved sector, 2 FATs,
693 68 directory entries, 77*26 sectors
694
695 FDh - 8" IBM 3740 format, singled-sided,
696 single-density, 128 bytes per sector, soft
697 sectored, 4 sectors per allocation unit, 4
698 reserved sectors, 2 FATs, 68 directory entries,
699 77*26 sectors
700
701 FEh - 8" Double-sided, double-density, 1024 bytes
702 per sector, soft sectored, 1 sector per allocation
703 unit, 1 reserved sector, 2 FATs, 192 directory
704 entries, 77*8*2 sectors
705
706
707STATUS Calls - ES:BX ->
708 +------------------------------------+
709 | 13-BYTE Static Request Header |
710 +------------------------------------+
711
712 All driver must do is set status word accordingly and
713set the busy bit as follows:
714
715 o For output on character devices: If it is 1 on
716 return, a write request (if made) would wait for
717 completion of a current request. If it is 0, there
718 is no current request and a write request (if made)
719 would start immediately.
720
721 o For input on character devices with a buffer a return
722 of 1 means, a read request (if made) would go to
723 the physical device. If it is 0 on return, then
724 there are characters in the devices buffer and a
725 read would return quickly, it also indicates that
726 the user has typed something. The DOS assumes all
727 character devices have an input type ahead buffer.
728 Devices which don't have them should always return
729 busy = 0 so that the DOS won't hang waiting for
730 something to get into a buffer which doesn't exist.
731
732
733FLUSH Calls - ES:BX ->
734 +------------------------------------+
735 | 13-BYTE Static Request Header |
736 +------------------------------------+
737
738 This call tells the driver to flush (terminate) all
739pending requests that it has knowledge of. Its primary use
740is to flush the input queue on character devices.
741
742
743INIT - ES:BX ->
744 +------------------------------------+
745 | 13-BYTE Static Request Header |
746 +------------------------------------+
747 | BYTE # of units |
748 +------------------------------------+
749 | DWORD Break Address |
750 ---+------------------------------------+---
751 | DWORD Pointer to BPB array |
752 | (not set by Character devices) |
753 +------------------------------------+
754
755 The number of units, break address, and BPB pointer are
756set by the driver.
757
758
759FORMAT OF BPB (Bios Parameter Block) -
760
761 +------------------------------------+
762 | WORD Sector size in Bytes |
763 | Must be at least 32 |
764 +------------------------------------+
765 | BYTE Sectors/Allocation unit |
766 | Must be a power of 2 |
767 +------------------------------------+
768 | WORD Number of reserved sectors |
769 | May be zero |
770 +------------------------------------+
771 | BYTE Number of FATS |
772 +------------------------------------+
773 | WORD Number of directory entries |
774 +------------------------------------+
775 | WORD Total number of sectors |
776 +------------------------------------+
777 | BYTE Media descriptor |
778 +------------------------------------+
779 | WORD Number of sectors occupied by |
780 | FAT |
781 +------------------------------------+
782
783
784THE CLOCK DEVICE
785
786 One of the most popular add on boards seems to be "Real
787Time CLOCK Boards". To allow these boards to be integrated
788into the system for TIME and DATE, there is a special device
789(determined by the attribute word) which is the CLOCK device.
790In all respects this device defines and performs functions
791like any other character device (most functions will be "set
792done bit, reset error bit, return). When a read or write
793to this device occurs, exactly 6 bytes are transferred. This
794I/O can be thought of as transferring 3 words which correspond
795exactly to the values of AX, CX and DX which were used in
796the old 1.25 DOS date and time routines. Thus the first
797two bytes are a word which is the count of days since 1-1-80.
798The third byte is minutes, the fourth hours, the fifth
799hundredths of seconds, and the sixth seconds. Reading the
800CLOCK device gets the date and time, writing to it sets the
801date and time.
802
diff --git a/v2.0/source/DEVSYM.ASM b/v2.0/source/DEVSYM.ASM
new file mode 100644
index 0000000..b648f04
--- /dev/null
+++ b/v2.0/source/DEVSYM.ASM
Binary files differ
diff --git a/v2.0/source/DIR.ASM b/v2.0/source/DIR.ASM
new file mode 100644
index 0000000..d0bb84f
--- /dev/null
+++ b/v2.0/source/DIR.ASM
@@ -0,0 +1,1084 @@
1;
2; Directory routines for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17TITLE DIR - Directory and path cracking
18NAME Dir
19
20 i_need NoSetDir,BYTE
21 i_need EntFree,WORD
22 i_need DirStart,WORD
23 i_need LastEnt,WORD
24 i_need ClusNum,WORD
25 i_need CurBuf,DWORD
26 i_need ThisFCB,DWORD
27 i_need Attrib,BYTE
28 i_need DelAll,BYTE
29 i_need VolID,BYTE
30 i_need Name1,BYTE
31 i_need ThisDPB,DWORD
32 i_need EntLast,WORD
33 i_need Creating,BYTE
34 i_need SecClusPos,BYTE
35 i_need ClusFac,BYTE
36 i_need NxtClusNum,WORD
37 i_need DirSec,WORD
38 i_need DriveSpec,BYTE
39 i_need Device_availability,BYTE
40 i_need RootStart,BYTE
41 i_need DevString,BYTE
42 i_need DevStrLen,BYTE
43
44SUBTTL BUILDDIR,NEWDIR -- ALLOCATE DIRECTORIES
45PAGE
46 procedure BUILDDIR,NEAR
47ASSUME DS:DOSGROUP,ES:NOTHING
48
49; Inputs:
50; ES:BP Points to DPB
51; [THISFCB] Set if using NEWDIR entry point
52; [LASTENT] current last valid entry number in directory if no free
53; entries
54; Function:
55; Grow directory if no free entries and not root
56; Outputs:
57; CARRY SET IF FAILURE
58; ELSE
59; AX entry number of new entry
60; If a new dir [DIRSTART],[CLUSFAC],[CLUSNUM],[DIRSEC] set
61; AX = first entry of new dir
62; GETENT should be called to set [LASTENT]
63
64 MOV AX,[ENTFREE]
65 CMP AX,-1
66 JNZ GOTRET
67 CMP [DIRSTART],0
68 JNZ NEWDIR
69 STC
70 return ; Can't grow root
71
72 entry NEWDIR
73 MOV BX,[DIRSTART]
74 OR BX,BX
75 JZ NULLDIR
76 invoke GETEOF
77NULLDIR:
78 MOV CX,1
79 invoke ALLOCATE
80 retc
81 MOV DX,[DIRSTART]
82 OR DX,DX
83 JNZ ADDINGDIR
84 call SETDIRSRCH
85 MOV [LASTENT],-1
86 JMP SHORT GOTDIRREC
87ADDINGDIR:
88 CMP [CLUSNUM],0FF8H
89 JB NOTFIRSTGROW
90 MOV [CLUSNUM],BX
91NOTFIRSTGROW:
92 MOV DX,BX
93 XOR BL,BL
94 invoke FIGREC
95GOTDIRREC:
96 MOV CL,ES:[BP.dpb_cluster_mask]
97 INC CL
98 XOR CH,CH
99ZERODIR:
100 PUSH CX
101 MOV AL,0FFH
102 invoke GETBUFFR
103 MOV CX,ES:[BP.dpb_sector_size]
104 PUSH ES
105 LES DI,[CURBUF]
106 PUSH DI
107 ADD DI,BUFINSIZ
108 XOR AX,AX
109 SHR CX,1
110 REP STOSW
111 JNC EVENZ
112 STOSB
113EVENZ:
114 POP DI
115 INC AL
116 MOV ES:[DI.BUFDIRTY],AL
117 POP ES
118 POP CX
119 INC DX
120 LOOP ZERODIR
121 MOV AX,[LASTENT]
122 INC AX
123GOTRET:
124 CLC
125 return
126
127BUILDDIR ENDP
128
129;
130; set up a . and .. directory entry for a directory
131;
132 procedure SETDOTENT,NEAR
133ASSUME DS:DOSGROUP
134 MOV CX,4
135 MOV AX,2020H
136 REP STOSW
137 STOSB
138 MOV SI,WORD PTR [THISFCB]
139 MOV AL,attr_directory
140 STOSB
141 ADD DI,10
142 MOV AX,[SI.fcb_FTIME]
143 STOSW
144 MOV AX,[SI.fcb_FDATE]
145 STOSW
146 MOV AX,DX
147 STOSW
148 XOR AX,AX
149 STOSW
150 STOSW
151 return
152SETDOTENT ENDP
153
154SUBTTL GETFILE, GETNAME, FINDNAME -- LOOK FOR A FILE
155PAGE
156 procedure SEARCH,near
157
158 entry GETFILE
159ASSUME DS:NOTHING,ES:NOTHING
160; Same as GETNAME except ES:DI points to FCB on successful return
161 invoke MOVNAME
162 retc
163 PUSH DX
164 PUSH DS
165 CALL FINDNAME
166 POP ES
167 POP DI
168 return
169
170 entry GETNAME
171ASSUME DS:NOTHING,ES:NOTHING
172
173; Inputs:
174; DS,DX point to FCB
175; Function:
176; Find file name in disk directory. First byte is
177; drive number (0=current disk). "?" matches any
178; character.
179; Outputs:
180; Carry set if file not found
181; ELSE
182; Zero set if attributes match (always except when creating)
183; AH = Device ID (bit 7 set if not disk)
184; [THISDPB] = Base of drive parameters
185; DS = DOSGROUP
186; ES = DOSGROUP
187; [CURBUF+2]:BX = Pointer into directory buffer
188; [CURBUF+2]:SI = Pointer to First Cluster field in directory entry
189; [CURBUF] has directory record with match
190; [NAME1] has file name
191; All other registers destroyed.
192
193 invoke MOVNAME
194ASSUME ES:DOSGROUP
195 retc ; Bad file name?
196
197 entry FINDNAME
198 PUSH SS
199 POP DS
200ASSUME DS:DOSGROUP
201 invoke DEVNAME
202 JC FindEntry
203 invoke BUILDFCB
204 return
205ASSUME ES:NOTHING
206
207; NOTE THE FALL THROUGH
208
209SUBTTL FINDENTRY -- LOOK FOR AN ENTRY
210PAGE
211 entry FindEntry
212ASSUME DS:DOSGROUP,ES:NOTHING
213
214; Inputs:
215; [THISDPB] set
216; [SECCLUSPOS] = 0
217; [DIRSEC] = Starting directory sector number
218; [CLUSNUM] = Next cluster of directory
219; [CLUSFAC] = Sectors/Cluster
220; [NAME1] = Name to look for
221; Function:
222; Find file name in disk directory.
223; "?" matches any character.
224; Outputs:
225; Carry set if name not found
226; ELSE
227; Zero set if attributes match (always except when creating)
228; AH = Device ID (bit 7 set if not disk)
229; [THISDPB] = Base of drive parameters
230; DS = DOSGROUP
231; ES = DOSGROUP
232; [CURBUF+2]:BX = Pointer into directory buffer
233; [CURBUF+2]:SI = Pointer to First Cluster field in directory entry
234; [CURBUF] has directory record with match
235; [NAME1] has file name
236; [LASTENT] is entry number of the entry
237; All other registers destroyed.
238
239 CALL STARTSRCH
240 CMP BYTE PTR [ATTRIB],attr_volume_id
241 ; Looking for vol ID only ?
242 JNZ NOTVOLSRCH ; No
243 CALL SETROOTSRCH ; Yes force search of root
244NOTVOLSRCH:
245 CALL GETENTRY
246 entry Srch
247 PUSH DS
248 MOV DS,WORD PTR [CURBUF+2]
249ASSUME DS:NOTHING
250 MOV AH,BYTE PTR [BX]
251 OR AH,AH ; End of directory?
252 JZ FREE
253 CMP AH,BYTE PTR [DELALL] ; Free entry?
254 JZ FREE
255 TEST BYTE PTR [BX+11],attr_volume_id
256 ; Volume ID file?
257 JZ CHKFNAM ; NO
258 INC BYTE PTR [VOLID]
259CHKFNAM:
260 MOV SI,BX
261 PUSH SS
262 POP ES
263ASSUME ES:DOSGROUP
264 MOV DI,OFFSET DOSGROUP:NAME1
265 MOV CX,11
266WILDCRD:
267 REPE CMPSB
268 JZ FOUND
269 CMP BYTE PTR ES:[DI-1],"?"
270 JZ WILDCRD
271 POP DS
272ASSUME DS:DOSGROUP
273 entry NEXTENT
274 LES BP,[THISDPB]
275ASSUME ES:NOTHING
276 CALL NEXTENTRY
277 JNC SRCH
278 JMP SHORT SETESRET
279
280FREE:
281 POP DS
282ASSUME DS:DOSGROUP
283 MOV CX,[LASTENT]
284 CMP CX,[ENTFREE]
285 JAE TSTALL
286 MOV [ENTFREE],CX
287TSTALL:
288 CMP AH,BYTE PTR [DELALL] ; At end of directory?
289 JZ NEXTENT ; No - continue search
290 MOV [ENTLAST],CX
291 STC
292 JMP SHORT SETESRET
293
294FOUND:
295;
296; We have a file with a matching name. We must now consider
297; the attributes:
298; ATTRIB Action
299; ------ ------
300; Volume_ID Is Volume_ID in test?
301; Otherwise If no create then Is ATTRIB+extra superset of test?
302; If create then Is ATTRIB equal to test?
303;
304 MOV CH,[SI] ; Attributes of file
305 POP DS
306ASSUME DS:DOSGROUP
307 MOV AH,BYTE PTR [ATTRIB] ; Attributes of search
308 TEST CH,attr_volume_id ; Volume ID file?
309 JZ check_one_volume_id ; Nope check other attributes
310 TEST AH,attr_volume_id ; Can we find Volume ID?
311 JZ NEXTENT ; Nope, (not even $FCB_CREATE)
312 XOR AH,AH ; Set zero flag for $FCB_CREATE
313 JMP SHORT RETF ; Found Volume ID
314check_one_volume_id:
315 CMP AH,attr_volume_id ; Looking only for Volume ID?
316 JZ NEXTENT ; Yes, continue search
317 ADD SI,15
318 CALL MatchAttributes
319 JZ RETF
320 TEST BYTE PTR [CREATING],-1 ; Pass back mismatch if creating
321 JZ NEXTENT ; Otherwise continue searching
322RETF:
323 LES BP,[THISDPB]
324 MOV AH,ES:[BP.dpb_drive]
325SETESRET:
326 PUSH SS
327 POP ES
328 return
329
330SUBTTL GETENTRY, NEXTENTRY, GETENT -- STEP THROUGH DIRECTORY
331PAGE
332 entry GETENTRY
333ASSUME DS:DOSGROUP,ES:NOTHING
334
335; Inputs:
336; [LASTENT] has directory entry
337; ES:BP points to drive parameters
338; Function:
339; Locates directory entry in preparation for search
340; GETENT provides entry for passing desired entry in AX
341; A valid search environment MUST exist
342; ENDENT,ENTLAST,ENTFREE
343; Outputs:
344; [CURBUF+2]:BX = Pointer to next directory entry in CURBUF
345; [CURBUF+2]:DX = Pointer to first byte after end of CURBUF
346; [LASTENT] = New directory entry number
347
348 MOV AX,[LASTENT]
349 entry GETENT
350 MOV [LASTENT],AX
351 MOV CL,4
352 SHL AX,CL
353 XOR DX,DX
354 SHL AX,1
355 RCL DX,1 ; Account for overflow in last shift
356 MOV BX,ES:[BP.dpb_sector_size]
357 AND BL,255-31 ; Must be multiple of 32
358 DIV BX
359 MOV BX,DX ; Position within sector
360 PUSH BX
361 invoke DIRREAD
362 POP BX
363SETENTRY:
364 MOV DX,WORD PTR [CURBUF]
365 ADD DX,BUFINSIZ
366 ADD BX,DX
367 ADD DX,ES:[BP.dpb_sector_size] ; Always clears carry
368 return
369
370 entry NEXTENTRY
371ASSUME DS:DOSGROUP,ES:NOTHING
372
373; Inputs:
374; Same as outputs of GETENTRY, above
375; Function:
376; Update BX, and [LASTENT] for next directory entry.
377; Carry set if no more.
378
379 MOV AX,[LASTENT]
380 CMP AX,[ENTLAST]
381 JZ NONE
382 INC AX
383 ADD BX,32
384 CMP BX,DX
385 JB HAVIT
386 MOV BL,BYTE PTR [SECCLUSPOS]
387 INC BL
388 CMP BL,BYTE PTR [CLUSFAC]
389 JB SAMECLUS
390 MOV BX,[NXTCLUSNUM]
391 CMP BX,0FF8H
392 JAE NONE
393 CMP BX,2
394 JB NONE
395 JMP GETENT
396
397NONE:
398 STC
399 return
400
401HAVIT:
402 MOV [LASTENT],AX
403 CLC
404 return
405
406SAMECLUS:
407 MOV BYTE PTR [SECCLUSPOS],BL
408 MOV [LASTENT],AX
409 PUSH DS
410 LDS DI,[CURBUF]
411ASSUME DS:NOTHING
412 MOV DX,[DI.BUFSECNO]
413 INC DX
414 POP DS
415ASSUME DS:DOSGROUP
416 invoke FIRSTCLUSTER
417 XOR BX,BX
418 JMP SETENTRY
419Search ENDP
420
421SUBTTL GETCURRDIR -- GET CURRENT DIRECTORY
422PAGE
423 procedure Dir_search,NEAR
424 entry GETCURRDIR
425ASSUME DS:NOTHING,ES:NOTHING
426
427; Inputs:
428; ES:BP Points to DPB
429; FATREAD should be called before this routine
430; Function:
431; Find current directory for drive
432; If path is bad set current directory to the root
433; Outputs:
434; DS = DOSGROUP
435; [SECCLUSPOS] = 0
436; [DIRSTART] = Cluster # of first cluster of directory ( 0 if root)
437; [DIRSEC] Set to phys sec # of first sector first cluster of directory
438; [CLUSNUM] Set to next cluster
439; [CLUSFAC] Sectors/cluster
440; Destroys all registers
441
442 MOV BX,ES:[BP.dpb_current_dir]
443 OR BX,BX
444 JZ SETROOTSRCH
445 CMP BX,0FF8H
446 JB SETDIRSRCH
447 PUSH ES
448 POP DS
449 LEA SI,[BP.dpb_dir_text]
450 CALL ROOTPATH
451ASSUME DS:DOSGROUP
452 JNC SETCURR
453 MOV ES:[BP.dpb_current_dir],0
454
455SETROOTSRCH:
456ASSUME DS:NOTHING,ES:NOTHING
457 PUSH SS
458 POP DS
459ASSUME DS:DOSGROUP
460 XOR AX,AX
461 MOV [DIRSTART],AX
462 MOV BYTE PTR [SECCLUSPOS],AL
463 DEC AX
464 MOV [CLUSNUM],AX
465 MOV AX,ES:[BP.dpb_first_sector]
466 MOV DX,ES:[BP.dpb_dir_sector]
467 SUB AX,DX
468 MOV BYTE PTR [CLUSFAC],AL
469 MOV [DIRSEC],DX
470 return
471
472SETCURR:
473ASSUME DS:DOSGROUP
474 MOV AX,[DIRSTART]
475 MOV ES:[BP.dpb_current_dir],AX
476 return
477
478 entry SETDIRSRCH
479ASSUME DS:NOTHING,ES:NOTHING
480
481; Inputs:
482; BX cluster number of start of directory
483; ES:BP Points to DPB
484; Function:
485; Set up a directory search
486; Outputs:
487; DS = DOSGROUP
488; [DIRSTART] = BX
489; [CLUSFAC],[CLUSNUM],[SECCLUSPOS],[DIRSEC] set
490; destroys AX,DX
491
492 OR BX,BX
493 JZ SETROOTSRCH
494 PUSH SS
495 POP DS
496ASSUME DS:DOSGROUP
497 MOV [DIRSTART],BX
498 MOV AL,ES:[BP.dpb_cluster_mask]
499 INC AL
500 MOV BYTE PTR [CLUSFAC],AL
501 invoke UNPACK
502 MOV [CLUSNUM],DI
503 MOV DX,BX
504 XOR BL,BL
505 MOV BYTE PTR [SECCLUSPOS],BL
506 invoke FIGREC
507 MOV [DIRSEC],DX
508 return
509Dir_search ENDP
510
511SUBTTL MAKENODE -- CREATE A NEW NODE
512PAGE
513 procedure MakeNode,NEAR
514ASSUME DS:NOTHING,ES:NOTHING
515
516; Inputs:
517; AL - attribute to create
518; DS:SI Points to asciz path
519; [THISFCB] Points to an empty FCB
520; Function:
521; Make a new node
522; Outputs:
523; DS=DOSGROUP
524; ES:BP Points to DPB
525; AX = 0 Success
526; AX = 1 A node by this name exists and is a directory
527; AX = 2 A new node could not be created error
528; AX = 3 A node by this name exists and is a file error
529; AX = 4 Bad Path error
530; AX = 5 Attribute mismatch error
531; CARRY SET IF ERROR
532; ELSE
533; [DIRSTART],[DIRSEC],[CLUSFAC],[CLUSNUM] set to directory
534; containing new node.
535; [CURBUF+2]:BX Points to entry
536; [CURBUF+2]:SI Points to entry.fcb_firclus
537; [ThisFCB] is filled in
538; If this is a new entry zero is set and
539; Attribute byte in entry is directory
540; else a file existed by this name and:
541; [NAME1] has name
542; entry is not changed in any way
543; Destroys all registers
544
545 PUSH AX
546 CALL GetPath
547 MOV DL,CL ; Save CL info
548 POP CX
549 MOV BYTE PTR [ATTRIB],CL
550 MOV CX,AX
551 JNC make_exists ; File existed
552 JNZ make_err_4 ; Path bad
553 OR DL,DL ; Check "CL" return from GETPATH
554 JNZ make_type ; Name simply not found
555make_err_4:
556 MOV AL,4 ; case 1 bad path
557make_err_ret:
558 STC
559 return
560
561make_type:
562 XOR AL,AL ; nothing exists... assume 0
563 STC
564 JMP SHORT make_save
565make_exists:
566 JZ make_exists_dir
567 MOV AL,3 ; file exists type 3
568 TEST BYTE PTR [ATTRIB],(attr_volume_id+attr_directory)
569 JNZ make_err_ret_5 ; but we wanted a volid or dir
570 OR CH,CH
571 JS make_dev ; No furthur checks if device
572 PUSH CX
573 MOV DS,WORD PTR [CURBUF+2]
574 MOV CH,[BX+dir_attr] ; Get file attributes
575 TEST CH,attr_read_only
576 JNZ make_err_ret_5P ; Cannot create on read only files
577 CALL MatchAttributes
578make_err_ret_5P:
579 POP CX
580 JZ make_dev ; Attributes ok
581make_err_ret_5:
582 MOV AL,5 ; Attribute mismatch
583 JMP SHORT make_err_ret
584
585make_dev:
586 XOR AL,AL ; Make sure zero set(atts match), carry clear(exists)
587 MOV AL,3 ; Restore correct value
588 JMP SHORT make_save
589make_exists_dir:
590 MOV AL,1 ; directory exists
591 TEST BYTE PTR [ATTRIB],attr_directory
592 JZ make_err_ret ; we didn't want a directory
593 CLC
594 return ; just return
595make_save:
596 PUSH AX
597;
598; set up for call to NewEntry - it is in the middle of FCB_CREATE
599; so we must also pre-push two registers. They will be popped off
600; by FCB_CREATE
601;
602 PUSH SS
603 POP DS
604 ASSUME DS:DOSGROUP
605 PUSHF ;Save state of flags
606 CMP BYTE PTR [NAME1],'.' ;Detect attempt to make '.' or '..'
607 JNZ NOTLDOT ; Needed because no '.' or '..' in root
608 POPF
609 MOV AL,1 ;Force type 2 error
610 JMP SHORT SET2ERR
611
612NOTLDOT:
613 POPF
614 PUSH ES
615 LES DI,[ThisFCB]
616 PUSH DS
617 PUSH DI
618 PUSH ES
619 MOV AX,CX
620 invoke NewEntry
621 POP DS
622 POP ES
623SET2ERR:
624 OR AL,AL
625 POP AX
626 JZ make_set_fcb
627 MOV AL,2 ; create failed case 2
628 STC
629 return
630make_set_fcb:
631ASSUME DS:DOSGROUP
632 PUSH ES
633 LES DI,[THISFCB]
634 INC DI
635 PUSH DS
636 PUSH SI
637 MOV DS,WORD PTR [CURBUF+2]
638ASSUME DS:NOTHING
639 MOV SI,BX
640 MOV CX,11
641 REP MOVSB
642 POP SI
643 POP DS
644ASSUME DS:DOSGROUP
645 POP ES
646 CMP AL,1
647 JA make_errors
648 OR AL,AL
649 CLC
650 return
651make_errors:
652 STC
653 return
654
655MakeNode ENDP
656
657SUBTTL GETPATH -- PARSE AN asciz PATH
658PAGE
659
660 procedure GETPATH,near
661ASSUME DS:NOTHING,ES:NOTHING
662
663; Inputs:
664; DS:SI Points to asciz path
665; Function:
666; Crack the path
667; Outputs:
668; [DRIVESPEC] is non zero if a drive was specified
669; [ROOTSTART] is non zero if a / started the path
670; [ATTRIB] set to attr_directory+attr_hidden+attr_system
671; Same as FINDPATH except if path specifies a device in which case
672; bit 7 of AH will be set and SI and BX will point DOSGROUP relative
673; Destroys all registers
674
675 XOR AX,AX
676 MOV WORD PTR [DRIVESPEC],AX
677 MOV BYTE PTR [ATTRIB],attr_directory+attr_system+attr_hidden
678 LODSB
679 invoke PATHCHRCMP
680 JZ DEFAULTROOT
681 MOV AH,AL
682 LODSB
683 CMP AL,':'
684 JZ DRVSPEC
685 DEC SI
686 DEC SI
687 PUSH DS
688 PUSH SI
689 PUSH SS
690 POP ES
691 CMP BYTE PTR [device_availability],0
692 JZ NOWDEV
693 CALL GOTPRESTRING2
694 JNC BUILDFCBJ ; If no carry then we have a device
695NOWDEV:
696 CALL DEFPATH
697GOFIND:
698 MOV AL,[NoSetDir]
699 PUSH AX
700 MOV [NoSetDir],0
701 CALL GETCURRDIR
702 POP AX
703 MOV [NoSetDir],AL
704 POP SI
705 POP DS
706 JMP FINDPATH
707
708DEFPATH:
709 XOR AL,AL
710DRVPATH:
711 invoke GETTHISDRV
712 retc ; Bad drive
713 PUSH SS
714 POP DS
715 invoke FATREAD
716 CLC
717 return
718
719DEFAULTROOT:
720 PUSH DS
721 PUSH SI
722 CALL DEFPATH
723 POP SI
724 POP DS
725ROOTSRCH:
726 INC BYTE PTR [ROOTSTART]
727 CMP BYTE PTR [SI],0
728 JZ PATHISNULL
729 PUSH DS
730 PUSH SI
731 PUSH ES ; Save pointer to DPB
732 CALL CHKDEV
733 POP ES
734 JNC BUILDFCBJ
735 POP SI
736 POP DS
737 JMP ROOTPATH
738
739BUILDFCBJ:
740 POP AX
741 POP AX
742 context es
743 invoke BUILDFCB ; Clears carry sets zero
744 INC AL ; reset zero
745 return
746
747DRVSPEC:
748 INC [DRIVESPEC]
749 MOV AL,AH
750 OR AL,20H ; Convert to lower case
751 SUB AL,60H ; Make A=1
752 PUSH DS
753 PUSH SI
754 PUSH AX
755 context es
756 CALL GotPreString2
757 ASSUME ES:NOTHING
758 POP AX
759 JNC BuildFCBJ
760 CALL DRVPATH
761 POP SI
762 POP DS
763 retc ; Bad drive
764 LODSB
765 invoke PATHCHRCMP
766 JZ ROOTSRCH
767 DEC SI
768 PUSH DS
769 PUSH SI
770 JMP GOFIND
771
772PATHISNULL:
773 CALL SETROOTSRCH
774ASSUME DS:DOSGROUP
775 XOR AL,AL ; Set zero (directory) clear carry
776 return
777
778CHKDEV:
779ASSUME DS:NOTHING
780 PUSH SS
781 POP ES
782 MOV DI,OFFSET DOSGROUP:DEVSTRING
783 XOR CX,CX
784 MOV CL,DEVSTRLEN
785CHKPRESTRING:
786 REPE CMPSB
787 JZ GOTPRESTRING
788 DEC SI
789 invoke GETLET ; Try convert to upper case
790 CMP AL,ES:[DI-1]
791 JZ CHKPRESTRING
792NOPRESTRING:
793 STC
794 return
795
796GOTPRESTRING:
797 LODSB
798 invoke PATHCHRCMP
799 JNZ NOPRESTRING
800GOTPRESTRING2:
801 MOV DI,OFFSET DOSGROUP:NAME1
802 MOV CX,9
803TESTLOOP:
804 invoke GETLET
805 CMP AL,'.'
806 JZ TESTDEVICE
807 invoke PATHCHRCMP
808 JZ NOTDEV
809 OR AL,AL
810 JZ TESTDEVICE
811 STOSB
812 LOOP TESTLOOP
813NOTDEV:
814 STC
815 return
816
817TESTDEVICE:
818 ADD CX,2
819 MOV AL,' '
820 REP STOSB
821 PUSH SS
822 POP DS
823 invoke DEVNAME
824 return
825GETPATH ENDP
826
827SUBTTL ROOTPATH, FINDPATH -- PARSE A PATH
828PAGE
829 procedure ROOTPATH,near
830
831ASSUME DS:NOTHING,ES:NOTHING
832
833; Inputs:
834; ES:BP Points to DPB
835; FATREAD should be called before this routine
836; DS:SI Points to asciz string of path which is assumed to start at
837; the root (no leading '/').
838; Function:
839; Search from root for path
840; Outputs:
841; Same as FINDPATH
842; Destroys all registers
843
844 PUSH DS
845 CALL SETROOTSRCH
846 POP DS
847
848; NOTE FALL THROUGH
849
850 entry FINDPATH
851ASSUME DS:NOTHING,ES:NOTHING
852
853; Inputs:
854; ES:BP Points to DPB
855; DS:SI Points to asciz string of path (no leading '/').
856; [SECCLUSPOS] = 0
857; [DIRSEC] = Phys sec # of first sector of directory
858; [CLUSNUM] = Cluster # of next cluster
859; [CLUSFAC] = Sectors per cluster
860; Validate_path should be called before this routine is used,
861; unless it is KNOWN the path is good.
862; Function:
863; Parse path name
864; Outputs:
865; ES:BP Points to DPB
866; Carry set if bad path
867; DS:SI Points to path element causing failure
868; Zero set
869; [DIRSTART],[DIRSEC],[CLUSNUM], and [CLUSFAC] are set up to
870; start a search on the last directory
871; CL is zero if there is a bad name in the path
872; CL is non-zero if the name was simply not found
873; [ENTFREE] may have free spot in directory
874; [NAME1] is the name.
875; CL = 81H if '*'s or '?' in name 1, 80H otherwise
876; Zero reset
877; File in middle of path or bad name in path
878; or path too long or malformed path
879; ELSE
880; DS = DOSGROUP
881; AH = device ID
882; [CURBUF] contains directory record with match
883; [CURBUF+2]:BX Points into [CURBUF] to start of entry
884; [CURBUF+2]:SI Points to fcb_FIRCLUS field for entry
885; [NAME1] Has entry name
886; If last element is a directory zero is set and:
887; [DIRSTART],[SECCLUSPOS],[DIRSEC],[CLUSNUM], and [CLUSFAC]
888; are set up to start a search on it.
889; If last element is a file zero is reset
890; Destroys all registers
891
892 PUSH ES
893 PUSH SI
894 invoke NAMETRANS
895 MOV CL,AL
896 OR CL,80H
897 POP DI
898 POP ES
899 CMP SI,DI
900 JNZ check_device
901 JMP BADPATH
902check_device:
903 PUSH DS
904 PUSH SI
905 MOV AL,BYTE PTR [SI]
906
907;
908; can we see all devices
909;
910 context DS
911 CMP BYTE PTR [device_availability],0
912 JZ FindFile
913
914;
915; check name1 to see if we have a device...
916;
917 PUSH ES
918 context ES
919 invoke DevName ; blast BX
920 POP ES
921 ASSUME ES:NOTHING
922 JC FindFile
923 OR AL,AL
924 JNZ FileInPath
925 POP SI
926 POP SI
927 context ES
928 invoke BuildFCB
929 INC AL
930 return
931
932FindFile:
933 ASSUME ES:NOTHING
934 PUSH DI ; Start of this element
935 PUSH ES
936 PUSH CX
937 CALL FINDENTRY
938 POP CX
939 POP ES
940 POP DI
941 JC BADPATHPOP
942 LDS DI,[CURBUF]
943ASSUME DS:NOTHING
944 TEST BYTE PTR [BX+dir_attr],attr_directory
945 JZ FileInPath
946
947;
948; if we are not setting the directory, then
949; check for end of string
950;
951 CMP BYTE PTR [NoSetDir],0
952 JZ SetDir
953 MOV DX,DI
954 MOV AX,DS
955 POP DI
956 POP DS
957 CMP BYTE PTR [DI],0
958 JZ SetRet
959 PUSH DS
960 PUSH DI
961 MOV DI,DX
962 MOV DS,AX
963
964SetDir:
965 MOV DX,[SI]
966 SUB BX,DI
967 SUB SI,DI
968 PUSH BX
969 PUSH AX
970 PUSH SI
971 PUSH CX
972 PUSH [DI.BUFSECNO]
973 MOV BX,DX
974 CALL SETDIRSRCH
975ASSUME DS:DOSGROUP
976 POP DX
977 XOR AL,AL
978 invoke GETBUFFR
979 POP CX
980 POP SI
981 POP AX
982 POP BX
983 MOV DI,WORD PTR [CURBUF]
984 ADD SI,DI
985 ADD BX,DI
986 POP DI
987 POP DS
988ASSUME DS:NOTHING
989 MOV AL,[DI]
990 OR AL,AL
991 JZ SETRET
992 INC DI
993 MOV SI,DI
994 invoke PATHCHRCMP
995 JNZ find_bad_name
996 JMP FINDPATH
997
998find_bad_name:
999 DEC SI
1000BADPATH:
1001 XOR CL,CL ; Set zero
1002 STC
1003 return
1004
1005FILEINPATH:
1006 POP DI
1007 POP DS
1008 MOV AL,[DI]
1009 OR AL,AL
1010 JZ INCRET
1011 MOV SI,DI ; Path too long
1012 STC
1013 return
1014
1015INCRET:
1016 INC AL ; Reset zero
1017SETRET:
1018 PUSH SS
1019 POP DS
1020 return
1021
1022BADPATHPOP:
1023 POP SI
1024 POP DS
1025 MOV AL,[SI]
1026 MOV SI,DI ; Start of bad element
1027 OR AL,AL ; zero if bad element is last, non-zero if path too long
1028 STC
1029 return
1030ROOTPATH ENDP
1031
1032SUBTTL STARTSRCH -- INITIATE DIRECTORY SEARCH
1033PAGE
1034 procedure StartSrch,NEAR
1035ASSUME DS:DOSGROUP,ES:NOTHING
1036
1037; Inputs:
1038; [THISDPB] Set
1039; Function:
1040; Set up a search for GETENTRY and NEXTENTRY
1041; Outputs:
1042; ES:BP = Drive parameters
1043; Sets up LASTENT, ENDENT, ENTFREE=ENTLAST=-1, VOLID=0
1044; Destroys all registers (via FATREAD)
1045
1046 LES BP,[THISDPB]
1047 XOR AX,AX
1048 MOV [LASTENT],AX
1049 MOV BYTE PTR [VOLID],AL ; No volume ID found
1050 DEC AX
1051 MOV [ENTFREE],AX
1052 MOV [ENTLAST],AX
1053 return
1054StartSrch ENDP
1055
1056BREAK <MatchAttributes - the final check for attribute matching>
1057
1058;
1059; Input: [Attrib] = attribute to search for
1060; CH = found attribute
1061; Output: JZ <match>
1062; JNZ <nomatch>
1063;
1064 procedure MatchAttributes,near
1065 ASSUME DS:NOTHING,ES:NOTHING
1066 PUSH AX
1067 MOV AL,[Attrib] ; AL <- SearchSet
1068 NOT AL ; AL <- SearchSet'
1069 AND AL,CH ; AL <- SearchSet' and FoundSet
1070 AND AL,attr_all ; AL <- SearchSet' and FoundSet and Important
1071;
1072; the result is non-zero if an attribute is not in the search set
1073; and in the found set and in the important set. This means that we do not
1074; have a match. Do a JNZ <nomatch> or JZ <match>
1075;
1076 POP AX
1077 return
1078MatchAttributes ENDP
1079
1080do_ext
1081
1082CODE ENDS
1083 END
1084
diff --git a/v2.0/source/DIRCALL.ASM b/v2.0/source/DIRCALL.ASM
new file mode 100644
index 0000000..db55ab8
--- /dev/null
+++ b/v2.0/source/DIRCALL.ASM
@@ -0,0 +1,507 @@
1TITLE DIRCALL - Directory manipulation internal calls
2NAME DIRCALL
3
4; $MKDIR
5; $CHDIR
6; $RMDIR
7
8.xlist
9INCLUDE DOSSEG.ASM
10
11CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14.xcref
15INCLUDE DOSSYM.ASM
16INCLUDE DEVSYM.ASM
17.cref
18.list
19
20ifndef Kanji
21Kanji equ 0
22endif
23
24 i_need AUXSTACK,BYTE
25 i_need NoSetDir,BYTE
26 i_need CURBUF, DWORD
27 i_need DIRSTART,WORD
28 i_need THISDPB,DWORD
29 i_need NAME1,BYTE
30 i_need LASTENT,WORD
31 i_need ATTRIB,BYTE
32 i_need THISFCB,DWORD
33 i_need AUXSTACK,BYTE
34 i_need CREATING,BYTE
35 i_need DRIVESPEC,BYTE
36 i_need ROOTSTART,BYTE
37 i_need SWITCH_CHARACTER,BYTE
38
39 extrn sys_ret_ok:near,sys_ret_err:near
40
41
42; XENIX CALLS
43BREAK <$MkDir - Make a directory entry>
44MKNERRJ: JMP MKNERR
45NODEEXISTSJ: JMP NODEEXISTS
46 procedure $MKDIR,NEAR
47ASSUME DS:NOTHING,ES:NOTHING
48
49; Inputs:
50; DS:DX Points to asciz name
51; Function:
52; Make a new directory
53; Returns:
54; STD XENIX Return
55; AX = mkdir_path_not_found if path bad
56; AX = mkdir_access_denied If
57; Directory cannot be created
58; Node already exists
59; Device name given
60; Disk or directory(root) full
61 invoke validate_path
62 JC MKNERRJ
63 MOV SI,DX
64 MOV WORD PTR [THISFCB+2],SS
65 MOV WORD PTR [THISFCB],OFFSET DOSGROUP:AUXSTACK-40 ; Scratch space
66 MOV AL,attr_directory
67 MOV WORD PTR [CREATING],0E500h
68 invoke MAKENODE
69ASSUME DS:DOSGROUP
70 MOV AL,mkdir_path_not_found
71 JC MKNERRJ
72 JNZ NODEEXISTSJ
73 LDS DI,[CURBUF]
74ASSUME DS:NOTHING
75 SUB SI,DI
76 PUSH SI ; Pointer to fcb_FIRCLUS
77 PUSH [DI.BUFSECNO] ; Sector of new node
78 PUSH SS
79 POP DS
80ASSUME DS:DOSGROUP
81 PUSH [DIRSTART] ; Parent for .. entry
82 XOR AX,AX
83 MOV [DIRSTART],AX ; Null directory
84 invoke NEWDIR
85 JC NODEEXISTSPOPDEL ; No room
86 invoke GETENT ; First entry
87 LES DI,[CURBUF]
88 MOV ES:[DI.BUFDIRTY],1
89 ADD DI,BUFINSIZ ; Point at buffer
90 MOV AX,202EH ; ". "
91 STOSW
92 MOV DX,[DIRSTART] ; Point at itself
93 invoke SETDOTENT
94 MOV AX,2E2EH ; ".."
95 STOSW
96 POP DX ; Parent
97 invoke SETDOTENT
98 LES BP,[THISDPB]
99 POP DX ; Entry sector
100 XOR AL,AL ; Pre read
101 invoke GETBUFFR
102 MOV DX,[DIRSTART]
103 LDS DI,[CURBUF]
104ASSUME DS:NOTHING
105ZAPENT:
106 POP SI ; fcb_Firclus pointer
107 ADD SI,DI
108 MOV [SI],DX
109 XOR DX,DX
110 MOV [SI+2],DX
111 MOV [SI+4],DX
112DIRUP:
113 MOV [DI.BUFDIRTY],1
114 PUSH SS
115 POP DS
116ASSUME DS:DOSGROUP
117 MOV AL,ES:[BP.dpb_drive]
118 invoke FLUSHBUF
119SYS_RET_OKJ:
120 JMP SYS_RET_OK
121
122NODEEXISTSPOPDEL:
123 POP DX ; Parent
124 POP DX ; Entry sector
125 LES BP,[THISDPB]
126 XOR AL,AL ; Pre read
127 invoke GETBUFFR
128 LDS DI,[CURBUF]
129ASSUME DS:NOTHING
130 POP SI ; dir_first pointer
131 ADD SI,DI
132 SUB SI,dir_first ; Point back to start of dir entry
133 MOV BYTE PTR [SI],0E5H ; Free the entry
134 CALL DIRUP
135NODEEXISTS:
136 MOV AL,mkdir_access_denied
137MKNERR:
138 JMP SYS_RET_ERR
139$MKDIR ENDP
140
141BREAK <$ChDir -- Change current directory on a drive>
142 procedure $CHDIR,NEAR
143ASSUME DS:NOTHING,ES:NOTHING
144
145; Inputs:
146; DS:DX Points to asciz name
147; Function:
148; Change current directory
149; Returns:
150; STD XENIX Return
151; AX = chdir_path_not_found if error
152
153 invoke validate_path
154 JC PathTooLong
155
156 PUSH DS
157 PUSH DX
158 MOV SI,DX
159 invoke GETPATH
160 JC PATHNOGOOD
161 JNZ PATHNOGOOD
162ASSUME DS:DOSGROUP
163 MOV AX,[DIRSTART]
164 MOV BX,AX
165 XCHG BX,ES:[BP.dpb_current_dir]
166 OR AX,AX
167 POP SI
168 POP DS
169ASSUME DS:NOTHING
170 JZ SYS_RET_OKJ
171 MOV DI,BP
172 ADD DI,dpb_dir_text
173 MOV DX,DI
174 CMP [DRIVESPEC],0
175 JZ NODRIVESPEC
176 INC SI
177 INC SI
178NODRIVESPEC:
179 MOV CX,SI
180 CMP [ROOTSTART],0
181 JZ NOTROOTPATH
182 INC SI
183 INC CX
184 JMP SHORT COPYTHESTRINGBXZ
185NOTROOTPATH:
186 OR BX,BX ; Previous path root?
187 JZ COPYTHESTRING ; Yes
188 XOR BX,BX
189ENDLOOP:
190 CMP BYTE PTR ES:[DI],0
191 JZ PATHEND
192 INC DI
193 INC BX
194 JMP SHORT ENDLOOP
195PATHEND:
196 MOV AL,'/'
197 CMP AL,[switch_character]
198 JNZ SLASHOK
199 MOV AL,'\' ; Use the alternate character
200SLASHOK:
201 STOSB
202 INC BX
203 JMP SHORT CHECK_LEN
204
205PATHNOGOOD:
206 POP AX
207 POP AX
208PATHTOOLONG:
209 error error_path_not_found
210
211ASSUME DS:NOTHING
212
213INCBXCHK:
214 INC BX
215BXCHK:
216 CMP BX,DIRSTRLEN
217 return
218
219COPYTHESTRINGBXZ:
220 XOR BX,BX
221COPYTHESTRING:
222 LODSB
223 OR AL,AL
224
225 JNZ FOOB
226 JMP CPSTDONE
227FOOB:
228 CMP AL,'.'
229 JZ SEEDOT
230 CALL COPYELEM
231CHECK_LEN:
232 CMP BX,DIRSTRLEN
233 JB COPYTHESTRING
234 MOV AL,ES:[DI-1]
235 invoke PATHCHRCMP
236 JNZ OK_DI
237 DEC DI
238OK_DI:
239 XOR AL,AL
240 STOSB ; Correctly terminate the path
241 MOV ES:[BP.dpb_current_dir],-1 ; Force re-validation
242 JMP SHORT PATHTOOLONG
243
244SEEDOT:
245 LODSB
246 OR AL,AL ; Check for null
247 JZ CPSTDONEDEC
248 CMP AL,'.'
249 JNZ COPYTHESTRING ; eat ./
250 CALL DELELMES ; have ..
251 LODSB ; eat the /
252 OR AL,AL ; Check for null
253 JZ CPSTDONEDEC
254 JMP SHORT COPYTHESTRING
255
256; Copy one element from DS:SI to ES:DI include trailing / not trailing null
257; LODSB has already been done
258COPYELEM:
259 PUSH DI ; Save in case too long
260 PUSH CX
261 MOV CX,800h ; length of filename
262 MOV AH,'.' ; char to stop on
263 CALL CopyPiece ; go for it!
264 CALL BXCHK ; did we go over?
265 JAE POPCXDI ; yep, go home
266 CMP AH,AL ; did we stop on .?
267 JZ CopyExt ; yes, go copy ext
268 OR AL,AL ; did we end on nul?
269 JZ DECSIRet ; yes, bye
270CopyPathEnd:
271 STOSB ; save the path char
272 CALL INCBXCHK ; was there room for it?
273 JAE POPCXDI ; Nope
274 INC SI ; guard against following dec
275DECSIRET:
276 DEC SI ; point back at null
277 POP CX
278 POP AX ; toss away saved DI
279 return
280POPCXDI:
281 POP CX ; restore
282 POP DI ; point back...
283 return
284CopyExt:
285 STOSB ; save the dot
286 CALL INCBXCHK ; room?
287 JAE POPCXDI ; nope.
288 LODSB ; get next char
289 XOR AH,AH ; NUL here
290 MOV CX,300h ; at most 3 chars
291 CALL CopyPiece ; go copy it
292 CALL BXCHK ; did we go over
293 JAE POPCXDI ; yep
294 OR AL,AL ; sucessful end?
295 JZ DECSIRET ; yes
296 JMP CopyPathEnd ; go stash path char
297
298DELELMES:
299; Delete one path element from ES:DI
300 DEC DI ; the '/'
301 DEC BX
302
303 IF KANJI
304 PUSH AX
305 PUSH CX
306 PUSH DI
307 PUSH DX
308 MOV CX,DI
309 MOV DI,DX
310DELLOOP:
311 CMP DI,CX
312 JZ GOTDELE
313 MOV AL,ES:[DI]
314 INC DI
315 invoke TESTKANJ
316 JZ NOTKANJ11
317 INC DI
318 JMP DELLOOP
319
320NOTKANJ11:
321 invoke PATHCHRCMP
322 JNZ DELLOOP
323 MOV DX,DI ; Point to char after '/'
324 JMP DELLOOP
325
326GOTDELE:
327 MOV DI,DX
328 POP DX
329 POP AX ; Initial DI
330 SUB AX,DI ; Distance moved
331 SUB BX,AX ; Set correct BX
332 POP CX
333 POP AX
334 return
335 ELSE
336DELLOOP:
337 CMP DI,DX
338 retz
339 PUSH AX
340 MOV AL,ES:[DI-1]
341 invoke PATHCHRCMP
342 POP AX
343 retz
344 DEC DI
345 DEC BX
346 JMP SHORT DELLOOP
347 ENDIF
348
349CPSTDONEDEC:
350 DEC DI ; Back up over trailing /
351CPSTDONE:
352 STOSB ; The NUL
353 JMP SYS_RET_OK
354
355; copy a piece CH chars max until the char in AH (or path or NUL)
356CopyPiece:
357 STOSB ; store the character
358 INC CL ; moved a byte
359 CALL INCBXCHK ; room enough?
360 JAE CopyPieceRet ; no, pop CX and DI
361 OR AL,AL ; end of string?
362 JZ CopyPieceRet ; yes, dec si and return
363
364 IF KANJI
365 CALL TestKanj ; was it kanji?
366 JZ NotKanj ; nope
367 MOVSB ; move the next byte
368 CALL INCBXCHK ; room for it?
369 JAE CopyPieceRet ; nope
370 INC CL ; moved a byte
371NotKanj:
372 ENDIF
373
374 CMP CL,CH ; move too many?
375 JBE CopyPieceNext ; nope
376
377 IF KANJI
378 CALL TestKanj ; was the last byte kanji
379 JZ NotKanj2 ; no only single byte backup
380 DEC DI ; back up a char
381 DEC BX
382NotKanj2:
383 ENDIF
384
385 DEC DI ; back up a char
386 DEC BX
387CopyPieceNext:
388 LODSB ; get next character
389 invoke PathChrCmp ; end of road?
390 JZ CopyPieceRet ; yep, return and don't dec SI
391 CMP AL,AH ; end of filename?
392 JNZ CopyPiece ; go do name
393CopyPieceRet:
394 return ; bye!
395
396$CHDIR ENDP
397
398BREAK <$RmDir -- Remove a directory>
399NOPATHJ: JMP NOPATH
400
401 procedure $RMDIR,NEAR ; System call 47
402ASSUME DS:NOTHING,ES:NOTHING
403
404; Inputs:
405; DS:DX Points to asciz name
406; Function:
407; Delete directory if empty
408; Returns:
409; STD XENIX Return
410; AX = rmdir_path_not_found If path bad
411; AX = rmdir_access_denied If
412; Directory not empty
413; Path not directory
414; Root directory specified
415; Directory malformed (. and .. not first two entries)
416; AX = rmdir_current_directory
417
418 invoke Validate_path
419 JC NoPathJ
420 MOV SI,DX
421 invoke GETPATH
422 JC NOPATHJ
423ASSUME DS:DOSGROUP
424 JNZ NOTDIRPATH
425 MOV DI,[DIRSTART]
426 OR DI,DI
427 JZ NOTDIRPATH
428 MOV CX,ES:[BP.dpb_current_dir]
429 CMP CX,-1
430 JNZ rmdir_current_dir_check
431 invoke GetCurrDir
432 invoke Get_user_stack
433 MOV DX,[SI.user_DX]
434 MOV DS,[SI.user_DS]
435 JMP $RMDIR
436
437NOTDIRPATHPOP:
438 POP AX
439 POP AX
440NOTDIRPATH:
441 error error_access_denied
442
443rmdir_current_dir_check:
444 CMP DI,CX
445 JNZ rmdir_get_buf
446 error error_current_directory
447
448rmdir_get_buf:
449 LDS DI,[CURBUF]
450ASSUME DS:NOTHING
451 SUB BX,DI
452 PUSH BX ; Save entry pointer
453 PUSH [DI.BUFSECNO] ; Save sector number
454 PUSH SS
455 POP DS
456ASSUME DS:DOSGROUP
457 PUSH SS
458 POP ES
459 MOV DI,OFFSET DOSGROUP:NAME1
460 MOV AL,'?'
461 MOV CX,11
462 REP STOSB
463 XOR AL,AL
464 STOSB
465 invoke STARTSRCH
466 invoke GETENTRY
467 MOV DS,WORD PTR [CURBUF+2]
468ASSUME DS:NOTHING
469 MOV SI,BX
470 LODSW
471 CMP AX,(' ' SHL 8) OR '.'
472 JNZ NOTDIRPATHPOP
473 ADD SI,32-2
474 LODSW
475 CMP AX,('.' SHL 8) OR '.'
476 JNZ NOTDIRPATHPOP
477 PUSH SS
478 POP DS
479ASSUME DS:DOSGROUP
480 MOV [LASTENT],2 ; Skip . and ..
481 invoke GETENTRY
482 MOV [ATTRIB],attr_directory+attr_hidden+attr_system
483 invoke SRCH
484 JNC NOTDIRPATHPOP
485 LES BP,[THISDPB]
486 MOV BX,[DIRSTART]
487 invoke RELEASE
488 POP DX
489 XOR AL,AL
490 invoke GETBUFFR
491 LDS DI,[CURBUF]
492ASSUME DS:NOTHING
493 POP BX
494 ADD BX,DI
495 MOV BYTE PTR [BX],0E5H ; Free the entry
496 JMP DIRUP
497
498NOPATH:
499 error error_path_not_found
500
501$RMDIR ENDP
502
503 do_ext
504
505CODE ENDS
506 END
507
diff --git a/v2.0/source/DISK.ASM b/v2.0/source/DISK.ASM
new file mode 100644
index 0000000..b1acd82
--- /dev/null
+++ b/v2.0/source/DISK.ASM
@@ -0,0 +1,1302 @@
1;
2; Disk routines for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17TITLE DISK - Disk utility routines
18NAME Disk
19
20 i_need COUTDSAV,BYTE
21 i_need COUTSAV,DWORD
22 i_need CINDSAV,BYTE
23 i_need CINSAV,DWORD
24 i_need CONSWAP,BYTE
25 i_need IDLEINT,BYTE
26 i_need THISFCB,DWORD
27 i_need DMAADD,DWORD
28 i_need DEVCALL,BYTE
29 i_need CALLSCNT,WORD
30 i_need CALLXAD,DWORD
31 i_need CONTPOS,WORD
32 i_need NEXTADD,WORD
33 i_need CONBUF,BYTE
34 i_need User_SS,WORD
35 i_need User_SP,WORD
36 i_need DSKStack,BYTE
37 i_need InDOS,BYTE
38 i_need NumIO,BYTE
39 i_need CurDrv,BYTE
40 i_need ThisDrv,BYTE
41 i_need ClusFac,BYTE
42 i_need SecClusPos,BYTE
43 i_need DirSec,WORD
44 i_need ClusNum,WORD
45 i_need NxtClusNum,WORD
46 i_need ReadOp,BYTE
47 i_need DskErr,BYTE
48 i_need RecCnt,WORD
49 i_need RecPos,4
50 i_need Trans,BYTE
51 i_need BytPos,4
52 i_need SecPos,WORD
53 i_need BytSecPos,WORD
54 i_need BytCnt1,WORD
55 i_need BytCnt2,WORD
56 i_need SecCnt,WORD
57 i_need ThisDPB,DWORD
58 i_need LastPos,WORD
59 i_need ValSec,WORD
60 i_need GrowCnt,DWORD
61
62SUBTTL LOAD -- MAIN READ ROUTINE AND DEVICE IN ROUTINES
63PAGE
64; * * * * Drivers for file input from devices * * * *
65
66 procedure SWAPBACK,NEAR
67ASSUME DS:DOSGROUP,ES:NOTHING
68 PUSH ES
69 PUSH DI
70 PUSH SI
71 PUSH BX
72 MOV BX,1
73 invoke get_sf_from_jfn
74 ADD DI,sf_fcb
75 MOV BL,BYTE PTR [COUTDSAV]
76 LDS SI,[COUTSAV]
77ASSUME DS:NOTHING
78 MOV WORD PTR ES:[DI.fcb_FIRCLUS],SI
79 MOV WORD PTR ES:[DI.fcb_FIRCLUS+2],DS
80 MOV ES:[DI.fcb_DEVID],BL
81 PUSH SS
82 POP DS
83ASSUME DS:DOSGROUP
84 XOR BX,BX
85 invoke get_sf_from_jfn
86 ADD DI,sf_fcb
87 MOV BL,BYTE PTR [CINDSAV]
88 LDS SI,[CINSAV]
89ASSUME DS:NOTHING
90 MOV WORD PTR ES:[DI.fcb_FIRCLUS],SI
91 MOV WORD PTR ES:[DI.fcb_FIRCLUS+2],DS
92 MOV ES:[DI.fcb_DEVID],BL
93 PUSH SS
94 POP DS
95ASSUME DS:DOSGROUP
96 MOV BYTE PTR [CONSWAP],0
97 MOV BYTE PTR [IDLEINT],1
98SWAPRET:
99 POP BX
100 POP SI
101 POP DI
102 POP ES
103 return
104SWAPBACK ENDP
105
106 procedure SWAPCON,NEAR
107ASSUME DS:DOSGROUP,ES:NOTHING
108 PUSH ES
109 PUSH DI
110 PUSH SI
111 PUSH BX
112 MOV BYTE PTR [CONSWAP],1
113 MOV BYTE PTR [IDLEINT],0
114 XOR BX,BX
115 invoke get_sf_from_jfn
116 ADD DI,sf_fcb
117 MOV BL,ES:[DI.fcb_DEVID]
118 MOV BYTE PTR [CINDSAV],BL
119 LDS SI,DWORD PTR ES:[DI.fcb_FIRCLUS]
120ASSUME DS:NOTHING
121 MOV WORD PTR [CINSAV],SI
122 MOV WORD PTR [CINSAV+2],DS
123 LDS SI,[THISFCB]
124 MOV BL,[SI.fcb_DEVID]
125 LDS SI,DWORD PTR [SI.fcb_FIRCLUS]
126 MOV ES:[DI.fcb_DEVID],BL
127 MOV WORD PTR ES:[DI.fcb_FIRCLUS],SI
128 MOV WORD PTR ES:[DI.fcb_FIRCLUS+2],DS
129 PUSH SS
130 POP DS
131ASSUME DS:DOSGROUP
132 MOV BX,1
133 invoke get_sf_from_jfn
134 ADD DI,sf_fcb
135 MOV BL,ES:[DI.fcb_DEVID]
136 MOV BYTE PTR [COUTDSAV],BL
137 LDS SI,DWORD PTR ES:[DI.fcb_FIRCLUS]
138ASSUME DS:NOTHING
139 MOV WORD PTR [COUTSAV],SI
140 MOV WORD PTR [COUTSAV+2],DS
141 LDS SI,[THISFCB]
142 MOV BL,[SI.fcb_DEVID]
143 LDS SI,DWORD PTR [SI.fcb_FIRCLUS]
144 MOV ES:[DI.fcb_DEVID],BL
145 MOV WORD PTR ES:[DI.fcb_FIRCLUS],SI
146 MOV WORD PTR ES:[DI.fcb_FIRCLUS+2],DS
147 PUSH SS
148 POP DS
149 JMP SWAPRET
150SWAPCON ENDP
151
152 procedure LOAD,NEAR
153ASSUME DS:NOTHING,ES:NOTHING
154;
155; Inputs:
156; DS:DI point to FCB
157; DX:AX = Position in file to read
158; CX = No. of records to read
159; Outputs:
160; DX:AX = Position of last record read
161; CX = No. of bytes read
162; ES:DI point to FCB
163; fcb_LSTCLUS, fcb_CLUSPOS fields in FCB set
164
165 call SETUP
166ASSUME DS:DOSGROUP
167 OR BL,BL ; Check for named device I/O
168 JS READDEV
169 call DISKREAD
170 return
171
172READDEV:
173ASSUME DS:DOSGROUP,ES:NOTHING
174 LES DI,[DMAADD]
175 TEST BL,40H ; End of file?
176 JZ ENDRDDEVJ3
177 TEST BL,ISNULL ; NUL device?
178 JZ TESTRAW ; NO
179 XOR AL,AL ; Indicate EOF
180ENDRDDEVJ3: JMP ENDRDDEVJ2
181
182DVRDRAW:
183ASSUME DS:DOSGROUP
184 PUSH ES
185 POP DS
186ASSUME DS:NOTHING
187DVRDRAWR:
188 MOV BX,DI ; DS:BX transfer addr
189 XOR DX,DX ; Start at 0
190 XOR AX,AX ; Media Byte, unit = 0
191 invoke SETREAD
192 LDS SI,[THISFCB]
193 invoke DEVIOCALL
194 MOV DX,DI ; DX is preserved by INT 24
195 MOV AH,86H ; Read error
196 MOV DI,[DEVCALL.REQSTAT]
197 TEST DI,STERR
198 JZ CRDROK ; No errors
199 invoke CHARHARD
200 MOV DI,DX
201 CMP AL,1
202 JZ DVRDRAWR ; Retry
203CRDROK:
204 MOV DI,DX
205 ADD DI,[CALLSCNT] ; Amount transferred
206 JMP SHORT ENDRDDEVJ2
207
208TESTRAW:
209 TEST BL,020H ; Raw mode?
210 JNZ DVRDRAW
211 TEST BL,ISCIN ; Is it console device?
212 JZ NOTRDCON
213 JMP READCON
214NOTRDCON:
215 MOV AX,ES
216 MOV DS,AX
217ASSUME DS:NOTHING
218 MOV BX,DI
219 XOR DX,DX
220 MOV AX,DX
221 PUSH CX
222 MOV CX,1
223 invoke SETREAD
224 POP CX
225 LDS SI,[THISFCB]
226 LDS SI,DWORD PTR [SI.fcb_FIRCLUS]
227DVRDLP:
228 invoke DSKSTATCHK
229 invoke DEVIOCALL2
230 PUSH DI
231 MOV AH,86H
232 MOV DI,[DEVCALL.REQSTAT]
233 TEST DI,STERR
234 JZ CRDOK
235 invoke CHARHARD
236 POP DI
237 MOV [CALLSCNT],1
238 CMP AL,1
239 JZ DVRDLP ;Retry
240 XOR AL,AL ;Pick some random character
241 JMP SHORT DVRDIGN
242CRDOK:
243 POP DI
244 CMP [CALLSCNT],1
245 JNZ ENDRDDEVJ2
246 PUSH DS
247 MOV DS,WORD PTR [CALLXAD+2]
248 MOV AL,BYTE PTR [DI]
249 POP DS
250DVRDIGN:
251 INC WORD PTR [CALLXAD]
252 MOV [DEVCALL.REQSTAT],0
253 INC DI
254 CMP AL,1AH ; ^Z?
255 JZ ENDRDDEVJ
256 CMP AL,c_CR ; CR?
257 LOOPNZ DVRDLP
258ENDRDDEVJ:
259 DEC DI
260ENDRDDEVJ2:
261 JMP SHORT ENDRDDEV
262
263ASSUME DS:NOTHING,ES:NOTHING
264
265TRANBUF:
266 LODSB
267 STOSB
268 CMP AL,c_CR ; Check for carriage return
269 JNZ NORMCH
270 MOV BYTE PTR [SI],c_LF
271NORMCH:
272 CMP AL,c_LF
273 LOOPNZ TRANBUF
274 JNZ ENDRDCON
275 XOR SI,SI ; Cause a new buffer to be read
276 invoke OUT ; Transmit linefeed
277 OR AL,1 ; Clear zero flag--not end of file
278ENDRDCON:
279 PUSH SS
280 POP DS
281ASSUME DS:DOSGROUP
282 CALL SWAPBACK
283 MOV [CONTPOS],SI
284ENDRDDEV:
285 PUSH SS
286 POP DS
287ASSUME DS:DOSGROUP
288 MOV [NEXTADD],DI
289 JNZ SETFCBC ; Zero set if Ctrl-Z found in input
290 LES DI,[THISFCB]
291 AND ES:BYTE PTR [DI.fcb_DEVID],0FFH-40H ; Mark as no more data available
292SETFCBC:
293 call SETFCB
294 return
295
296ASSUME DS:NOTHING,ES:NOTHING
297
298READCON:
299ASSUME DS:DOSGROUP
300 CALL SWAPCON
301 MOV SI,[CONTPOS]
302 OR SI,SI
303 JNZ TRANBUF
304 CMP BYTE PTR [CONBUF],128
305 JZ GETBUF
306 MOV WORD PTR [CONBUF],0FF80H ; Set up 128-byte buffer with no template
307GETBUF:
308 PUSH CX
309 PUSH ES
310 PUSH DI
311 MOV DX,OFFSET DOSGROUP:CONBUF
312 invoke $STD_CON_STRING_INPUT ; Get input buffer
313 POP DI
314 POP ES
315 POP CX
316 MOV SI,2 + OFFSET DOSGROUP:CONBUF
317 CMP BYTE PTR [SI],1AH ; Check for Ctrl-Z in first character
318 JNZ TRANBUF
319 MOV AL,1AH
320 STOSB
321 DEC DI
322 MOV AL,10
323 invoke OUT ; Send linefeed
324 XOR SI,SI
325 JMP SHORT ENDRDCON
326
327LOAD ENDP
328
329SUBTTL STORE -- MAIN WRITE ROUTINE AND DEVICE OUT ROUTINES
330PAGE
331ASSUME DS:NOTHING,ES:NOTHING
332 procedure STORE,NEAR
333ASSUME DS:NOTHING,ES:NOTHING
334
335; Inputs:
336; DS:DI point to FCB
337; DX:AX = Position in file of disk transfer
338; CX = Record count
339; Outputs:
340; DX:AX = Position of last record written
341; CX = No. of records written
342; ES:DI point to FCB
343; fcb_LSTCLUS, fcb_CLUSPOS fields in FCB set
344
345 call SETUP
346ASSUME DS:DOSGROUP
347 OR BL,BL
348 JS WRTDEV
349 invoke DATE16
350 MOV ES:[DI.fcb_FDATE],AX
351 MOV ES:[DI.fcb_FTIME],DX
352 call DISKWRITE
353 return
354
355WRITECON:
356 PUSH DS
357 PUSH SS
358 POP DS
359ASSUME DS:DOSGROUP
360 CALL SWAPCON
361 POP DS
362ASSUME DS:NOTHING
363 MOV SI,BX
364 PUSH CX
365WRCONLP:
366 LODSB
367 CMP AL,1AH ; ^Z?
368 JZ CONEOF
369 invoke OUT
370 LOOP WRCONLP
371CONEOF:
372 POP AX ; Count
373 SUB AX,CX ; Amount actually written
374 POP DS
375ASSUME DS:DOSGROUP
376 CALL SWAPBACK
377 JMP SHORT ENDWRDEV
378
379DVWRTRAW:
380ASSUME DS:NOTHING
381 XOR AX,AX ; Media Byte, unit = 0
382 invoke SETWRITE
383 LDS SI,[THISFCB]
384 invoke DEVIOCALL
385 MOV DX,DI
386 MOV AH,87H
387 MOV DI,[DEVCALL.REQSTAT]
388 TEST DI,STERR
389 JZ CWRTROK
390 invoke CHARHARD
391 MOV BX,DX ; Recall transfer addr
392 CMP AL,1
393 JZ DVWRTRAW ; Try again
394CWRTROK:
395 POP DS
396ASSUME DS:DOSGROUP
397 MOV AX,[CALLSCNT] ; Get actual number of bytes transferred
398ENDWRDEV:
399 LES DI,[THISFCB]
400 XOR DX,DX
401 DIV ES:[DI.fcb_RECSIZ]
402 MOV CX,AX ; Partial record is ignored
403 call ADDREC
404 return
405
406ASSUME DS:DOSGROUP
407WRTDEV:
408 OR BL,40H ; Reset EOF for input
409 XOR AX,AX
410 JCXZ ENDWRDEV ; problem of creating on a device.
411 PUSH DS
412 MOV AL,BL
413 LDS BX,[DMAADD]
414ASSUME DS:NOTHING
415 MOV DI,BX
416 XOR DX,DX ; Set starting point
417 TEST AL,020H ; Raw?
418 JNZ DVWRTRAW
419 TEST AL,ISCOUT ; Console output device?
420 JNZ WRITECON
421 TEST AL,ISNULL
422 JNZ WRTNUL
423 MOV AX,DX
424 CMP BYTE PTR [BX],1AH ; ^Z?
425 JZ WRTCOOKDONE ; Yes, transfer nothing
426 PUSH CX
427 MOV CX,1
428 invoke SETWRITE
429 POP CX
430 LDS SI,[THISFCB]
431 LDS SI,DWORD PTR [SI.fcb_FIRCLUS]
432DVWRTLP:
433 invoke DSKSTATCHK
434 invoke DEVIOCALL2
435 PUSH DI
436 MOV AH,87H
437 MOV DI,[DEVCALL.REQSTAT]
438 TEST DI,STERR
439 JZ CWROK
440 invoke CHARHARD
441 POP DI
442 MOV [CALLSCNT],1
443 CMP AL,1
444 JZ DVWRTLP
445 JMP SHORT DVWRTIGN
446CWROK:
447 POP DI
448 CMP [CALLSCNT],0
449 JZ WRTCOOKDONE
450DVWRTIGN:
451 INC DX
452 INC WORD PTR [CALLXAD]
453 INC DI
454 PUSH DS
455 MOV DS,WORD PTR [CALLXAD+2]
456 CMP BYTE PTR [DI],1AH ; ^Z?
457 POP DS
458 JZ WRTCOOKDONE
459 MOV [DEVCALL.REQSTAT],0
460 LOOP DVWRTLP
461WRTCOOKDONE:
462 MOV AX,DX
463 POP DS
464 JMP ENDWRDEV
465
466WRTNUL:
467 MOV DX,CX ;Entire transfer done
468 JMP WRTCOOKDONE
469
470STORE ENDP
471
472 procedure get_io_fcb,near
473ASSUME DS:NOTHING,ES:NOTHING
474; Convert JFN number in BX to FCB in DS:SI
475 PUSH SS
476 POP DS
477ASSUME DS:DOSGROUP
478 PUSH ES
479 PUSH DI
480 invoke get_sf_from_jfn
481 JC RET44P
482 MOV SI,DI
483 ADD SI,sf_fcb
484 PUSH ES
485 POP DS
486ASSUME DS:NOTHING
487RET44P:
488 POP DI
489 POP ES
490 return
491get_io_fcb ENDP
492
493SUBTTL GETTHISDRV -- FIND CURRENT DRIVE
494PAGE
495; Input: AL has drive identifier (1=A, 0=default)
496; Output: AL has physical drive (0=A)
497; Carry set if invalid drive (and AL is garbage anyway)
498 procedure GetThisDrv,NEAR
499ASSUME DS:NOTHING,ES:NOTHING
500 CMP BYTE PTR [NUMIO],AL
501 retc
502 DEC AL
503 JNS PHYDRV
504 MOV AL,[CURDRV]
505PHYDRV:
506 MOV BYTE PTR [THISDRV],AL
507 return
508GetThisDrv ENDP
509
510SUBTTL DIRREAD -- READ A DIRECTORY SECTOR
511PAGE
512 procedure DirRead,NEAR
513ASSUME DS:DOSGROUP,ES:NOTHING
514
515; Inputs:
516; AX = Directory block number (relative to first block of directory)
517; ES:BP = Base of drive parameters
518; [DIRSEC] = First sector of first cluster of directory
519; [CLUSNUM] = Next cluster
520; [CLUSFAC] = Sectors/Cluster
521; Function:
522; Read the directory block into [CURBUF].
523; Outputs:
524; [NXTCLUSNUM] = Next cluster (after the one skipped to)
525; [SECCLUSPOS] Set
526; ES:BP unchanged [CURBUF] Points to Buffer with dir sector
527; All other registers destroyed.
528
529 MOV CL,[CLUSFAC]
530 DIV CL ; AL # clusters to skip, AH position in cluster
531 MOV [SECCLUSPOS],AH
532 MOV CL,AL
533 XOR CH,CH
534 MOV DX,[DIRSEC]
535 ADD DL,AH
536 ADC DH,0
537 MOV BX,[CLUSNUM]
538 MOV [NXTCLUSNUM],BX
539 JCXZ FIRSTCLUSTER
540SKPCLLP:
541 invoke UNPACK
542 XCHG BX,DI
543 CMP BX,0FF8H
544 JAE HAVESKIPPED
545 LOOP SKPCLLP
546HAVESKIPPED:
547 MOV [NXTCLUSNUM],BX
548 MOV DX,DI
549 MOV BL,AH
550 invoke FIGREC
551 entry FIRSTCLUSTER
552 XOR AL,AL ; Indicate pre-read
553 MOV AH,DIRPRI
554 invoke GETBUFFR
555 ret
556DirRead ENDP
557
558SUBTTL FATSECRD -- READ A FAT SECTOR
559PAGE
560 procedure FATSecRd,NEAR
561ASSUME DS:NOTHING,ES:NOTHING
562
563; Inputs:
564; Same as DREAD
565; DS:BX = Transfer address
566; CX = Number of sectors
567; DX = Absolute record number
568; ES:BP = Base of drive parameters
569; Function:
570; Calls BIOS to perform FAT read.
571; Outputs:
572; Same as DREAD
573
574 MOV DI,CX
575 MOV CL,ES:[BP.dpb_FAT_count]
576 MOV AL,ES:[BP.dpb_FAT_size]
577 XOR AH,AH
578 MOV CH,AH
579 PUSH DX
580NXTFAT:
581 PUSH CX
582 PUSH AX
583 MOV CX,DI
584 CALL DSKREAD
585 POP AX
586 POP CX
587 JZ RET41P
588 ADD DX,AX
589 LOOP NXTFAT
590 POP DX
591 MOV CX,DI
592
593; NOTE FALL THROUGH
594
595SUBTTL DREAD -- DO A DISK READ
596PAGE
597 entry DREAD
598ASSUME DS:NOTHING,ES:NOTHING
599
600; Inputs:
601; DS:BX = Transfer address
602; CX = Number of sectors
603; DX = Absolute record number
604; ES:BP = Base of drive parameters
605; Function:
606; Calls BIOS to perform disk read. If BIOS reports
607; errors, will call HARDERR for further action.
608; DS,ES:BP preserved. All other registers destroyed.
609
610 CALL DSKREAD
611 retz
612 MOV BYTE PTR [READOP],0
613 invoke HARDERR
614 CMP AL,1 ; Check for retry
615 JZ DREAD
616 return ; Ignore otherwise
617RET41P: POP DX
618 return
619FATSecRd ENDP
620
621SUBTTL DSKREAD -- PHYSICAL DISK READ
622PAGE
623 procedure DskRead,NEAR
624ASSUME DS:NOTHING,ES:NOTHING
625
626; Inputs:
627; DS:BX = Transfer addr
628; CX = Number of sectors
629; DX = Absolute record number
630; ES:BP = Base of drive parameters
631; Function:
632; Call BIOS to perform disk read
633; Outputs:
634; DI = CX on entry
635; CX = Number of sectors unsuccessfully transfered
636; AX = Status word as returned by BIOS (error code in AL if error)
637; Zero set if OK (from BIOS)
638; Zero clear if error
639; SI Destroyed, others preserved
640
641 PUSH CX
642 MOV AH,ES:[BP.dpb_media]
643 MOV AL,ES:[BP.dpb_UNIT]
644 PUSH BX
645 PUSH ES
646 invoke SETREAD
647 JMP DODSKOP
648
649SUBTTL DWRITE -- SEE ABOUT WRITING
650PAGE
651 entry DWRITE
652ASSUME DS:NOTHING,ES:NOTHING
653
654; Inputs:
655; DS:BX = Transfer address
656; CX = Number of sectors
657; DX = Absolute record number
658; ES:BP = Base of drive parameters
659; Function:
660; Calls BIOS to perform disk write. If BIOS reports
661; errors, will call HARDERR for further action.
662; BP preserved. All other registers destroyed.
663
664 CALL DSKWRITE
665 retz
666 MOV BYTE PTR [READOP],1
667 invoke HARDERR
668 CMP AL,1 ; Check for retry
669 JZ DWRITE
670 return
671
672SUBTTL DSKWRITE -- PHYSICAL DISK WRITE
673PAGE
674 entry DSKWRITE
675ASSUME DS:NOTHING,ES:NOTHING
676
677; Inputs:
678; DS:BX = Transfer addr
679; CX = Number of sectors
680; DX = Absolute record number
681; ES:BP = Base of drive parameters
682; Function:
683; Call BIOS to perform disk read
684; Outputs:
685; DI = CX on entry
686; CX = Number of sectors unsuccessfully transfered
687; AX = Status word as returned by BIOS (error code in AL if error)
688; Zero set if OK (from BIOS)
689; Zero clear if error
690; SI Destroyed, others preserved
691
692 PUSH CX
693 MOV AH,ES:[BP.dpb_media]
694 MOV AL,ES:[BP.dpb_UNIT]
695 PUSH BX
696 PUSH ES
697 invoke SETWRITE
698DODSKOP:
699 MOV CX,DS ; Save DS
700 POP DS ; DS:BP points to DPB
701 PUSH DS
702 LDS SI,DS:[BP.dpb_driver_addr]
703 invoke DEVIOCALL2
704 MOV DS,CX ; Restore DS
705 POP ES ; Restore ES
706 POP BX
707 MOV CX,[CALLSCNT] ; Number of sectors transferred
708 POP DI
709 SUB CX,DI
710 NEG CX ; Number of sectors not transferred
711 MOV AX,[DEVCALL.REQSTAT]
712 TEST AX,STERR
713 return
714DskRead ENDP
715
716SUBTTL SETUP -- SETUP A DISK READ OR WRITE FROM USER
717PAGE
718ASSUME DS:DOSGROUP,ES:NOTHING
719
720 procedure SETUP,NEAR
721ASSUME DS:NOTHING,ES:NOTHING
722
723; Inputs:
724; DS:DI point to FCB
725; DX:AX = Record position in file of disk transfer
726; CX = Record count
727; Outputs:
728; DS = DOSGROUP
729; BL = fcb_DEVID from FCB
730; CX = No. of bytes to transfer (0 = 64K)
731; [THISDPB] = Base of drive parameters
732; [RECCNT] = Record count
733; [RECPOS] = Record position in file
734; ES:DI Points to FCB
735; [THISFCB] = ES:DI
736; [NEXTADD] = Displacement of disk transfer within segment
737; [SECPOS] = Position of first sector
738; [BYTPOS] = Byte position in file
739; [BYTSECPOS] = Byte position in first sector
740; [CLUSNUM] = First cluster
741; [SECCLUSPOS] = Sector within first cluster
742; [DSKERR] = 0 (no errors yet)
743; [TRANS] = 0 (No transfers yet)
744; [THISDRV] = Physical drive unit number
745
746 PUSH AX
747 MOV AL,[DI]
748 DEC AL
749 MOV BYTE PTR [THISDRV],AL
750 MOV AL,[DI.fcb_DEVID]
751 MOV SI,[DI.fcb_RECSIZ]
752 OR SI,SI
753 JNZ HAVRECSIZ
754 MOV SI,128
755 MOV [DI.fcb_RECSIZ],SI
756HAVRECSIZ:
757 MOV WORD PTR [THISFCB+2],DS
758 PUSH SS
759 POP DS ; Set DS to DOSGROUP
760ASSUME DS:DOSGROUP
761 MOV WORD PTR [THISFCB],DI
762 OR AL,AL ; Is it a device?
763 JNS NOTDEVICE
764 XOR AL,AL ; Fake in drive 0 so we can get BP
765NOTDEVICE:
766 invoke GETBP
767 POP AX
768 JNC CheckRecLen
769 XOR CX,CX
770 MOV BYTE PTR [DSKERR],4
771 POP BX
772 return
773
774CheckRecLen:
775 CMP SI,64 ; Check if highest byte of RECPOS is significant
776 JB SMALREC
777 XOR DH,DH ; Ignore MSB if record >= 64 bytes
778SMALREC:
779 MOV [RECCNT],CX
780 MOV WORD PTR [RECPOS],AX
781 MOV WORD PTR [RECPOS+2],DX
782 MOV BX,WORD PTR [DMAADD]
783 MOV [NEXTADD],BX
784 MOV BYTE PTR [DSKERR],0
785 MOV BYTE PTR [TRANS],0
786 MOV BX,DX
787 MUL SI
788 MOV WORD PTR [BYTPOS],AX
789 PUSH DX
790 MOV AX,BX
791 MUL SI
792 POP BX
793 ADD AX,BX
794 ADC DX,0 ; Ripple carry
795 JNZ EOFERR
796 MOV WORD PTR [BYTPOS+2],AX
797 MOV DX,AX
798 MOV AX,WORD PTR [BYTPOS]
799 MOV BX,ES:[BP.dpb_sector_size]
800 CMP DX,BX ; See if divide will overflow
801 JNC EOFERR
802 DIV BX
803 MOV [SECPOS],AX
804 MOV [BYTSECPOS],DX
805 MOV DX,AX
806 AND AL,ES:[BP.dpb_cluster_mask]
807 MOV [SECCLUSPOS],AL
808 MOV AX,CX ; Record count
809 MOV CL,ES:[BP.dpb_cluster_shift]
810 SHR DX,CL
811 MOV [CLUSNUM],DX
812 MUL SI ; Multiply by bytes per record
813 MOV CX,AX
814 ADD AX,WORD PTR [DMAADD] ; See if it will fit in one segment
815 ADC DX,0
816 JZ OK ; Must be less than 64K
817 MOV AX,WORD PTR [DMAADD]
818 NEG AX ; Amount of room left in segment
819 JNZ PARTSEG
820 DEC AX
821PARTSEG:
822 XOR DX,DX
823 DIV SI ; How many records will fit?
824 MOV [RECCNT],AX
825 MUL SI ; Translate that back into bytes
826 MOV BYTE PTR [DSKERR],2 ; Flag that trimming took place
827 MOV CX,AX
828 JCXZ NOROOM
829OK:
830 LES DI,[THISFCB]
831 MOV BL,ES:[DI.fcb_DEVID]
832 return
833
834EOFERR:
835 MOV BYTE PTR [DSKERR],1
836 XOR CX,CX
837NOROOM:
838 LES DI,[THISFCB]
839 POP BX ; Kill return address
840 return
841SETUP ENDP
842
843SUBTTL BREAKDOWN -- CUT A USER READ OR WRITE INTO PIECES
844PAGE
845 procedure BREAKDOWN,near
846ASSUME DS:DOSGROUP,ES:NOTHING
847
848; Inputs:
849; CX = Length of disk transfer in bytes
850; ES:BP = Base of drive parameters
851; [BYTSECPOS] = Byte position witin first sector
852; Outputs:
853; [BYTCNT1] = Bytes to transfer in first sector
854; [SECCNT] = No. of whole sectors to transfer
855; [BYTCNT2] = Bytes to transfer in last sector
856; AX, BX, DX destroyed. No other registers affected.
857
858 MOV AX,[BYTSECPOS]
859 MOV BX,CX
860 OR AX,AX
861 JZ SAVFIR ; Partial first sector?
862 SUB AX,ES:[BP.dpb_sector_size]
863 NEG AX ; Max number of bytes left in first sector
864 SUB BX,AX ; Subtract from total length
865 JAE SAVFIR
866 ADD AX,BX ; Don't use all of the rest of the sector
867 XOR BX,BX ; And no bytes are left
868SAVFIR:
869 MOV [BYTCNT1],AX
870 MOV AX,BX
871 XOR DX,DX
872 DIV ES:[BP.dpb_sector_size] ; How many whole sectors?
873 MOV [SECCNT],AX
874 MOV [BYTCNT2],DX ; Bytes remaining for last sector
875 OR DX,[BYTCNT1]
876 retnz ; NOT (BYTCNT1 = BYTCNT2 = 0)
877 CMP AX,1
878 retnz
879 MOV AX,ES:[BP.dpb_sector_size] ; Buffer EXACT one sector I/O
880 MOV [BYTCNT2],AX
881 MOV [SECCNT],DX ; DX = 0
882 return
883BreakDown ENDP
884
885SUBTTL DISKREAD -- PERFORM USER DISK READ
886PAGE
887 procedure DISKREAD,NEAR
888ASSUME DS:DOSGROUP,ES:NOTHING
889
890; Inputs:
891; Outputs of SETUP
892; Function:
893; Perform disk read
894; Outputs:
895; DX:AX = Position of last record read
896; CX = No. of records read
897; ES:DI point to FCB
898; fcb_LSTCLUS, fcb_CLUSPOS fields in FCB set
899
900 MOV AX,ES:WORD PTR [DI.fcb_FILSIZ]
901 MOV BX,ES:WORD PTR [DI.fcb_FILSIZ+2]
902 SUB AX,WORD PTR [BYTPOS]
903 SBB BX,WORD PTR [BYTPOS+2]
904 JB RDERR
905 JNZ ENUF
906 OR AX,AX
907 JZ RDERR
908 CMP AX,CX
909 JAE ENUF
910 MOV CX,AX
911ENUF:
912 LES BP,[THISDPB]
913 CALL BREAKDOWN
914 MOV CX,[CLUSNUM]
915 invoke FNDCLUS
916 OR CX,CX
917 JZ SHORT SKIPERR
918RDERR:
919 JMP WRTERR
920RDLASTJ:JMP RDLAST
921SETFCBJ2: JMP SETFCB
922
923SKIPERR:
924
925 MOV [LASTPOS],DX
926 MOV [CLUSNUM],BX
927 CMP [BYTCNT1],0
928 JZ RDMID
929 invoke BUFRD
930RDMID:
931 CMP [SECCNT],0
932 JZ RDLASTJ
933 invoke NEXTSEC
934 JC SETFCBJ2
935 MOV BYTE PTR [TRANS],1 ; A transfer is taking place
936ONSEC:
937 MOV DL,[SECCLUSPOS]
938 MOV CX,[SECCNT]
939 MOV BX,[CLUSNUM]
940RDLP:
941 invoke OPTIMIZE
942 PUSH DI
943 PUSH AX
944 PUSH BX
945 MOV DS,WORD PTR [DMAADD+2]
946ASSUME DS:NOTHING
947 PUSH DX
948 PUSH CX
949 CALL DREAD
950 POP BX
951 POP DX
952 ADD BX,DX ; Upper bound of read
953 MOV AL,ES:[BP.dpb_drive]
954 invoke SETVISIT
955NXTBUF: ; Must see if one of these sectors is buffered
956 MOV [DI.VISIT],1 ; Mark as visited
957 CMP AL,[DI.BUFDRV]
958 JNZ DONXTBUF ; Not for this drive
959 CMP [DI.BUFSECNO],DX
960 JC DONXTBUF ; Below first sector
961 CMP [DI.BUFSECNO],BX
962 JNC DONXTBUF ; Above last sector
963 CMP BYTE PTR [DI.BUFDIRTY],0
964 JZ CLBUFF ; Buffer is clean, so OK
965; A sector has been read in when a dirty copy of it is in a buffer
966; The buffered sector must now be read into the right place
967 POP AX ; Recall transfer address
968 PUSH AX
969 PUSH DI ; Save search environment
970 PUSH DX
971 SUB DX,[DI.BUFSECNO] ; How far into transfer?
972 NEG DX
973 MOV SI,DI
974 MOV DI,AX
975 MOV AX,DX
976 MOV CX,ES:[BP.dpb_sector_size]
977 MUL CX
978 ADD DI,AX ; Put the buffer here
979 ADD SI,BUFINSIZ
980 SHR CX,1
981 PUSH ES
982 MOV ES,WORD PTR [DMAADD+2]
983 REP MOVSW
984 JNC EVENMOV
985 MOVSB
986EVENMOV:
987 POP ES
988 POP DX
989 POP DI
990 MOV AL,ES:[BP.dpb_drive]
991CLBUFF:
992 invoke SCANPLACE
993DONXTBUF:
994 invoke SKIPVISIT
995 JNZ NXTBUF
996 PUSH SS
997 POP DS
998ASSUME DS:DOSGROUP
999 POP CX
1000 POP CX
1001 POP BX
1002 JCXZ RDLAST
1003 CMP BX,0FF8H
1004 JAE SETFCB
1005 MOV DL,0
1006 INC [LASTPOS] ; We'll be using next cluster
1007 JMP RDLP
1008
1009RDLAST:
1010 MOV AX,[BYTCNT2]
1011 OR AX,AX
1012 JZ SETFCB
1013 MOV [BYTCNT1],AX
1014 invoke NEXTSEC
1015 JC SETFCB
1016 MOV [BYTSECPOS],0
1017 invoke BUFRD
1018
1019 entry SETFCB
1020 LES SI,[THISFCB]
1021 MOV AX,[NEXTADD]
1022 MOV DI,AX
1023 SUB AX,WORD PTR [DMAADD] ; Number of bytes transfered
1024 XOR DX,DX
1025 MOV CX,ES:[SI.fcb_RECSIZ]
1026 DIV CX ; Number of records
1027 CMP AX,[RECCNT] ; Check if all records transferred
1028 JZ FULLREC
1029 MOV BYTE PTR [DSKERR],1
1030 OR DX,DX
1031 JZ FULLREC ; If remainder 0, then full record transfered
1032 MOV BYTE PTR [DSKERR],3 ; Flag partial last record
1033 SUB CX,DX ; Bytes left in last record
1034 PUSH ES
1035 MOV ES,WORD PTR [DMAADD+2]
1036 XCHG AX,BX ; Save the record count temporarily
1037 XOR AX,AX ; Fill with zeros
1038 SHR CX,1
1039 JNC EVENFIL
1040 STOSB
1041EVENFIL:
1042 REP STOSW
1043 XCHG AX,BX ; Restore record count to AX
1044 POP ES
1045 INC AX ; Add last (partial) record to total
1046FULLREC:
1047 MOV CX,AX
1048 MOV DI,SI ; ES:DI point to FCB
1049SETCLUS:
1050 TEST ES:[DI].fcb_DEVID,-1
1051 JS ADDREC ; don't set clisters if device
1052 MOV AX,[CLUSNUM]
1053 AND ES:[DI.fcb_LSTCLUS],0F000h ; fcb_lstclus is packed with dir clus
1054 OR ES:[DI.fcb_LSTCLUS],AX ; drop in the correct part of fcb_lstclus
1055 MOV AX,[LASTPOS]
1056 MOV ES:[DI.fcb_CLUSPOS],AX
1057 entry AddRec
1058 MOV AX,WORD PTR [RECPOS]
1059 MOV DX,WORD PTR [RECPOS+2]
1060 JCXZ RET28 ; If no records read, don't change position
1061 DEC CX
1062 ADD AX,CX ; Update current record position
1063 ADC DX,0
1064 INC CX
1065RET28: return
1066DISKREAD ENDP
1067
1068SUBTTL DISKWRITE -- PERFORM USER DISK WRITE
1069PAGE
1070 procedure DISKWRITE,NEAR
1071ASSUME DS:DOSGROUP,ES:NOTHING
1072
1073; Inputs:
1074; Outputs of SETUP
1075; Function:
1076; Perform disk write
1077; Outputs:
1078; DX:AX = Position of last record written
1079; CX = No. of records written
1080; ES:DI point to FCB
1081; fcb_LSTCLUS, fcb_CLUSPOS fields in FCB set
1082
1083 AND BL,3FH ; Mark file as dirty
1084 MOV ES:[DI.fcb_DEVID],BL
1085 LES BP,[THISDPB]
1086 CALL BREAKDOWN
1087 MOV AX,WORD PTR [BYTPOS]
1088 MOV DX,WORD PTR [BYTPOS+2]
1089 JCXZ WRTEOFJ
1090 ADD AX,CX
1091 ADC DX,0 ; AX:DX=last byte accessed
1092 DIV ES:[BP.dpb_sector_size] ; AX=last sector accessed
1093 MOV BX,AX ; Save last full sector
1094 OR DX,DX
1095 JNZ CALCLUS
1096 DEC AX ; AX must be zero base indexed
1097CALCLUS:
1098 MOV CL,ES:[BP.dpb_cluster_shift]
1099 SHR AX,CL ; Last cluster to be accessed
1100 PUSH AX
1101 PUSH DX ; Save the size of the "tail"
1102 PUSH ES
1103 LES DI,[THISFCB]
1104 MOV AX,ES:WORD PTR [DI.fcb_FILSIZ]
1105 MOV DX,ES:WORD PTR [DI.fcb_FILSIZ+2]
1106 POP ES
1107 DIV ES:[BP.dpb_sector_size]
1108 MOV CX,AX ; Save last full sector of current file
1109 OR DX,DX
1110 JZ NORNDUP
1111 INC AX ; Round up if any remainder
1112NORNDUP:
1113 MOV [VALSEC],AX ; Number of sectors that have been written
1114 XOR AX,AX
1115 MOV WORD PTR [GROWCNT],AX
1116 MOV WORD PTR [GROWCNT+2],AX
1117 POP AX
1118 SUB BX,CX ; Number of full sectors
1119 JB NOGROW
1120 JZ TESTTAIL
1121 MOV CX,DX
1122 XCHG AX,BX
1123 MUL ES:[BP.dpb_sector_size] ; Bytes of full sector growth
1124 SUB AX,CX ; Take off current "tail"
1125 SBB DX,0 ; 32-bit extension
1126 ADD AX,BX ; Add on new "tail"
1127 ADC DX,0 ; ripple tim's head off
1128 JMP SHORT SETGRW
1129
1130HAVSTART:
1131 MOV CX,AX
1132 invoke SKPCLP
1133 JCXZ DOWRTJ
1134 invoke ALLOCATE
1135 JNC DOWRTJ
1136WRTERR:
1137 XOR CX,CX
1138 MOV BYTE PTR [DSKERR],1
1139 MOV AX,WORD PTR [RECPOS]
1140 MOV DX,WORD PTR [RECPOS+2]
1141 LES DI,[THISFCB]
1142 return
1143
1144DOWRTJ: JMP DOWRT
1145
1146WRTEOFJ:
1147 JMP WRTEOF
1148
1149TESTTAIL:
1150 SUB AX,DX
1151 JBE NOGROW
1152 XOR DX,DX
1153SETGRW:
1154 MOV WORD PTR [GROWCNT],AX
1155 MOV WORD PTR [GROWCNT+2],DX
1156NOGROW:
1157 POP AX
1158 MOV CX,[CLUSNUM] ; First cluster accessed
1159 invoke FNDCLUS
1160 MOV [CLUSNUM],BX
1161 MOV [LASTPOS],DX
1162 SUB AX,DX ; Last cluster minus current cluster
1163 JZ DOWRT ; If we have last clus, we must have first
1164 JCXZ HAVSTART ; See if no more data
1165 PUSH CX ; No. of clusters short of first
1166 MOV CX,AX
1167 invoke ALLOCATE
1168 POP AX
1169 JC WRTERR
1170 MOV CX,AX
1171 MOV DX,[LASTPOS]
1172 INC DX
1173 DEC CX
1174 JZ NOSKIP
1175 invoke SKPCLP
1176NOSKIP:
1177 MOV [CLUSNUM],BX
1178 MOV [LASTPOS],DX
1179DOWRT:
1180 CMP [BYTCNT1],0
1181 JZ WRTMID
1182 MOV BX,[CLUSNUM]
1183 invoke BUFWRT
1184WRTMID:
1185 MOV AX,[SECCNT]
1186 OR AX,AX
1187 JZ WRTLAST
1188 ADD [SECPOS],AX
1189 invoke NEXTSEC
1190 MOV BYTE PTR [TRANS],1 ; A transfer is taking place
1191 MOV DL,[SECCLUSPOS]
1192 MOV BX,[CLUSNUM]
1193 MOV CX,[SECCNT]
1194WRTLP:
1195 invoke OPTIMIZE
1196 PUSH DI
1197 PUSH AX
1198 PUSH DX
1199 PUSH BX
1200 MOV AL,ES:[BP.dpb_drive]
1201 MOV BX,CX
1202 ADD BX,DX ; Upper bound of write
1203 invoke SETVISIT
1204ASSUME DS:NOTHING
1205NEXTBUFF: ; Search for buffers
1206 MOV [DI.VISIT],1 ; Mark as visited
1207 CMP AL,[DI.BUFDRV]
1208 JNZ DONEXTBUFF ; Not for this drive
1209 CMP [DI.BUFSECNO],DX
1210 JC DONEXTBUFF ; Buffer is not in range of write
1211 CMP [DI.BUFSECNO],BX
1212 JNC DONEXTBUFF ; Buffer is not in range of write
1213 MOV WORD PTR [DI.BUFDRV],00FFH ; Free the buffer, it is being over written
1214 invoke SCANPLACE
1215DONEXTBUFF:
1216 invoke SKIPVISIT
1217 JNZ NEXTBUFF
1218 POP BX
1219 POP DX
1220 MOV DS,WORD PTR [DMAADD+2]
1221 CALL DWRITE
1222 POP CX
1223 POP BX
1224 PUSH SS
1225 POP DS
1226ASSUME DS:DOSGROUP
1227 JCXZ WRTLAST
1228 MOV DL,0
1229 INC [LASTPOS] ; We'll be using next cluster
1230 JMP SHORT WRTLP
1231
1232WRTERRJ: JMP WRTERR
1233
1234WRTLAST:
1235 MOV AX,[BYTCNT2]
1236 OR AX,AX
1237 JZ FINWRT
1238 MOV [BYTCNT1],AX
1239 invoke NEXTSEC
1240 MOV [BYTSECPOS],0
1241 invoke BUFWRT
1242FINWRT:
1243 LES DI,[THISFCB]
1244 MOV AX,WORD PTR [GROWCNT]
1245 MOV CX,WORD PTR [GROWCNT+2]
1246 OR AX,AX
1247 JNZ UPDATE_size
1248 OR CX,CX
1249 JZ SAMSIZ
1250Update_size:
1251 ADD WORD PTR ES:[DI.fcb_FILSIZ],AX
1252 ADC WORD PTR ES:[DI.fcb_FILSIZ+2],CX
1253SAMSIZ:
1254 MOV CX,[RECCNT]
1255 JMP SETCLUS
1256
1257WRTEOF:
1258 MOV CX,AX
1259 OR CX,DX
1260 JZ KILLFIL
1261 SUB AX,1
1262 SBB DX,0
1263 DIV ES:[BP.dpb_sector_size]
1264 MOV CL,ES:[BP.dpb_cluster_shift]
1265 SHR AX,CL
1266 MOV CX,AX
1267 invoke FNDCLUS
1268 JCXZ RELFILE
1269 invoke ALLOCATE
1270 JC WRTERRJ
1271UPDATE:
1272 LES DI,[THISFCB]
1273 MOV AX,WORD PTR [BYTPOS]
1274 MOV ES:WORD PTR [DI.fcb_FILSIZ],AX
1275 MOV AX,WORD PTR [BYTPOS+2]
1276 MOV ES:WORD PTR [DI.fcb_FILSIZ+2],AX
1277 XOR CX,CX
1278 JMP ADDREC
1279
1280RELFILE:
1281 MOV DX,0FFFH
1282 invoke RELBLKS
1283 JMP SHORT UPDATE
1284
1285KILLFIL:
1286 XOR BX,BX
1287 PUSH ES
1288 LES DI,[THISFCB]
1289 MOV ES:[DI.fcb_CLUSPOS],BX
1290 XCHG BX,ES:[DI.fcb_FIRCLUS]
1291 AND ES:[DI.fcb_LSTCLUS],0F000H
1292 POP ES
1293 OR BX,BX
1294 JZ UPDATE
1295 invoke RELEASE
1296 JMP SHORT UPDATE
1297DISKWRITE ENDP
1298do_ext
1299
1300CODE ENDS
1301 END
1302
diff --git a/v2.0/source/DISKCOPY.ASM b/v2.0/source/DISKCOPY.ASM
new file mode 100644
index 0000000..56e39cb
--- /dev/null
+++ b/v2.0/source/DISKCOPY.ASM
Binary files differ
diff --git a/v2.0/source/DISKMES.ASM b/v2.0/source/DISKMES.ASM
new file mode 100644
index 0000000..d5f0226
--- /dev/null
+++ b/v2.0/source/DISKMES.ASM
Binary files differ
diff --git a/v2.0/source/DOSLINK b/v2.0/source/DOSLINK
new file mode 100644
index 0000000..9d56841
--- /dev/null
+++ b/v2.0/source/DOSLINK
@@ -0,0 +1,5 @@
1msdos mscode dosmes misc getset dircall alloc dev dir +
2disk fat rom stdbuf stdcall stdctrlc stdfcb stdproc +
3stdio time xenix xenix2;
4
5 \ No newline at end of file
diff --git a/v2.0/source/DOSMAC.ASM b/v2.0/source/DOSMAC.ASM
new file mode 100644
index 0000000..35c16f1
--- /dev/null
+++ b/v2.0/source/DOSMAC.ASM
Binary files differ
diff --git a/v2.0/source/DOSMAC_v211.ASM b/v2.0/source/DOSMAC_v211.ASM
new file mode 100644
index 0000000..3340505
--- /dev/null
+++ b/v2.0/source/DOSMAC_v211.ASM
@@ -0,0 +1,274 @@
1;
2; Macro file for MSDOS.
3;
4
5SUBTTL BREAK a listing into pages and give new subtitles
6PAGE
7BREAK MACRO subtitle
8 SUBTTL subtitle
9 PAGE
10ENDM
11
12BREAK <I_NEED: declare a variable external, if necessary, and allocate a size>
13
14;
15; declare a variable external and allocate a size
16;
17I_NEED MACRO sym,len
18 DATA SEGMENT BYTE PUBLIC 'DATA'
19 IFIDN <len>,<WORD>
20 EXTRN &sym:WORD
21 ELSE
22 IFIDN <len>,<DWORD>
23 EXTRN &sym:DWORD
24 ELSE
25 EXTRN &sym:BYTE
26 ENDIF
27 ENDIF
28 DATA ENDS
29ENDM
30
31;
32; call a procedure that may be external. The call will be short.
33;
34invoke MACRO name
35.xcref
36 IF2
37 IFNDEF name
38 EXTRN name:NEAR
39 ENDIF
40 ENDIF
41.cref
42 CALL name
43ENDM
44
45PAGE
46;
47; jump to a label that may be external. The jump will be near.
48;
49transfer MACRO name
50.xcref
51 IF2
52 IFNDEF name
53 EXTRN name:NEAR
54 ENDIF
55 ENDIF
56.cref
57 JUMP name
58ENDM
59
60;
61; get a short address in a word
62;
63short_addr MACRO name
64 IFDIF <name>,<?>
65.xcref
66 IF2
67 IFNDEF name
68 EXTRN name:NEAR
69 ENDIF
70 ENDIF
71.cref
72 DW OFFSET DOSGROUP:name
73 ELSE
74 DW ?
75 ENDIF
76ENDM
77
78;
79; get a long address in a dword
80;
81long_addr MACRO name
82.xcref
83 IF2
84 IFNDEF name
85 EXTRN name:NEAR
86 ENDIF
87.cref
88 DD name
89ENDM
90
91;
92; declare a PROC near or far but PUBLIC nonetheless
93;
94procedure MACRO name,distance
95 PUBLIC name
96name PROC distance
97ENDM
98
99PAGE
100;
101; define a data item to be public and of an appropriate size/type
102;
103I_AM MACRO name,size
104 PUBLIC name
105
106 IFIDN <size>,<WORD>
107name DW ?
108 ELSE
109 IFIDN <size>,<DWORD>
110name DD ?
111 ELSE
112 IFIDN <size>,<BYTE>
113name DB ?
114 ELSE
115name DB size DUP (?)
116 ENDIF
117 ENDIF
118 ENDIF
119ENDM
120
121PAGE
122;
123; call the macro chain
124;
125do_ext macro
126endm
127
128PAGE
129
130;
131; define an entry in a procedure
132;
133entry macro name
134 PUBLIC name
135name:
136endm
137
138BREAK <ERROR - print a message and then jump to a label>
139
140error macro code
141 local a
142.xcref
143 MOV AL,code
144 transfer SYS_RET_ERR
145.cref
146ENDM
147
148BREAK <JUMP - real jump that links up shortwise>
149;
150; given a label <lbl> either 2 byte jump to another label <lbl>_J
151; if it is near enough or 3 byte jump to <lbl>
152;
153
154jump macro lbl
155 local a
156.xcref
157 a:
158 ifndef lbl&_J ;; is this the first invocation
159 JMP lbl
160 ELSE
161 IF lbl&_J GE $
162 JMP lbl
163 ELSE
164 IF ($-lbl&_J) GT 126 ;; is the jump too far away?
165 JMP lbl
166 ELSE ;; do the short one...
167 JMP lbl&_J
168 ENDIF
169 ENDIF
170 ENDIF
171 lbl&_j = a
172.cref
173endm
174
175BREAK <RETURN - return from a function>
176
177return macro
178 local a
179.xcref
180a:
181 RET
182ret_l = a
183.cref
184endm
185
186BREAK <CONDRET - conditional return>
187
188makelab macro l,cc,ncc
189 local a
190 j&ncc a ;; j<NCC> a:
191 return ;; return
192 a: ;; a:
193 ret_&cc = ret_l ;; define ret_<CC> to be ret_l
194endm
195
196condret macro cc,ncc
197 local a,b
198 ifdef ret_l ;; if ret_l is defined
199 if (($ - ret_l) le 126) and ($ gt ret_l)
200 ;; if ret_l is near enough then
201 a: j&cc ret_l ;; a: j<CC> to ret_l
202 ret_&cc = a ;; define ret_<CC> to be a:
203 else
204 makelab a,cc,ncc
205 endif
206 else
207 ifdef ret_&cc ;; if ret_<CC> defined
208 if (($ - ret_&cc) le 126) and ($ gt ret_&cc)
209 ;; if ret_<CC> is near enough
210 a: j&cc ret_&cc ;; a: j<CC> to ret_<CC>
211 ret_&cc = a ;; define ret_<CC> to be a:
212 else
213 makelab a,cc,ncc
214 endif
215 else
216 makelab a,cc,ncc
217 endif
218 endif
219endm
220;condret macro cc,ncc
221; local a,b
222; ifdef ret_l ; if ret_l is defined
223; if (($ - ret_l) le 126) and ($ gt ret_l)
224; ; if ret_l is near enough then
225; a: j&cc ret_l ; a: j<CC> to ret_l
226; ret_&cc = a ; define ret_<CC> to be a:
227; exitm
228; endif
229; endif
230; ifdef ret_&cc ; if ret_<CC> defined
231; if (($ - ret_&cc) le 126) and ($ gt ret_&cc)
232; ; if ret_<CC> is near enough
233; a: j&cc ret_&cc ; a: j<CC> to ret_<CC>
234; ret_&cc = a ; define ret_<CC> to be a:
235; exitm
236; endif
237; endif
238; j&ncc a ; j<NCC> a:
239; return ; return
240; a: ; a:
241; ret_&cc = ret_l ; define ret_<CC> to be ret_l
242;endm
243;
244BREAK <RETZ - return if zero, links up shortwise if necessary>
245
246retz macro
247 condret z,nz
248endm
249
250BREAK <RETNZ - return if not zero, links up shortwise if necessary>
251
252retnz macro
253 condret nz,z
254endm
255
256BREAK <RETC - return if carry set, links up shortwise if necessary>
257
258retc macro
259 condret c,nc
260endm
261
262BREAK <RETNC - return if not carry, links up shortwise if necessary>
263
264retnc macro
265 condret nc,c
266endm
267
268BREAK <CONTEXT - set the DOS context to a particular register>
269
270context macro r
271 PUSH SS
272 POP r
273 ASSUME r:DOSGROUP
274endm
diff --git a/v2.0/source/DOSMES.ASM b/v2.0/source/DOSMES.ASM
new file mode 100644
index 0000000..fb3f17a
--- /dev/null
+++ b/v2.0/source/DOSMES.ASM
@@ -0,0 +1,355 @@
1 INCLUDE STDSW.ASM
2
3KANJI EQU FALSE
4
5Rainbow EQU FALSE
6
7 INCLUDE DOSSYM.ASM
8;
9; segment ordering for MSDOS
10;
11
12CONSTANTS SEGMENT BYTE PUBLIC 'CONST'
13CONSTANTS ENDS
14
15DATA SEGMENT BYTE PUBLIC 'DATA'
16DATA ENDS
17
18CODE SEGMENT BYTE PUBLIC 'CODE'
19CODE ENDS
20
21LAST SEGMENT BYTE PUBLIC 'LAST'
22LAST ENDS
23
24DOSGROUP GROUP CODE,CONSTANTS,DATA,LAST
25
26CONSTANTS SEGMENT BYTE PUBLIC 'CONST'
27
28 PUBLIC DIVMES
29DIVMES DB 13,10,"Divide overflow",13,10
30
31 PUBLIC DivMesLen
32DivMesLen DB $-DivMes ; Length of the above message in bytes
33
34
35;
36; The next variable points to the country table for the current country
37; ( the table returned by the AL=0 INTERNATIONAL call).
38;
39 PUBLIC Current_Country
40
41 IF KANJI
42Current_Country DW OFFSET DOSGROUP:JAPTABLE
43 ELSE
44Current_Country DW OFFSET DOSGROUP:USTABLE
45 ENDIF
46
47;
48; The international tabel(s).
49; This is simply a sequence of tables of the following form:
50;
51; BYTE Size of this table excluding this byte and the next
52; BYTE Country code represented by this table
53; A sequence of n bytes, where n is the number specified
54; by the first byte above and is not > internat_block_max,
55; in the correct order for being returned by the
56; INTERNATIONAL call as follows:
57; WORD Date format 0=mdy, 1=dmy, 2=ymd
58; 5 BYTE Currency symbol null terminated
59; 2 BYTE thousands separator null terminated
60; 2 BYTE Decimal point null terminated
61; 2 BYTE Date separator null terminated
62; 2 BYTE Time separator null terminated
63; 1 BYTE Bit field. Currency format.
64; Bit 0. =0 $ before # =1 $ after #
65; Bit 1. no. of spaces between # and $ (0 or 1)
66; 1 BYTE No. of significant decimal digits in currency
67; 1 BYTE Bit field. Time format.
68; Bit 0. =0 12 hour clock =1 24 hour
69; WORD Segment offset for address of case conversion routine
70; WORD RESERVED. Filled in by DOS. Segment value for above routine
71; 2 BYTE Data list separator null terminated.
72; NOTE: The segment part of the DWORD Map_call is set
73; by the INTERNATIONAL call. Do not try to initialize
74; it to anything meaningful.
75;
76; The list of tables is terminated by putting a byte of -1 after the last
77; table (a table with length -1).
78
79 PUBLIC international_table
80
81international_table LABEL BYTE
82
83 IF KANJI
84 DB SIZE internat_block ; Size in bytes of this table
85 DB 81 ; Country code
86JAPTABLE internat_block <2,'\',0,0,0,0,',',0,'.',0,'-',0,':',0,0,0,1,OFFSET DOSGROUP:MAP_DCASE , 0,',',0>
87 ENDIF
88
89 DB SIZE internat_block ; Size in bytes of this table
90 DB 1 ; Country code
91USTABLE internat_block <0,'$',0,0,0,0,',',0,'.',0,'-',0,':',0,0,2,0,OFFSET DOSGROUP:MAP_DCASE,0,',',0>
92; Tables for the IBM PC character set follow. The values
93; associated with some of the currency symbols may change with
94; other character sets. You may wish to add or delete country
95; entries. NOTE: It is not a mistake that the JAPANESE entry
96; has different currency symbols for the KANJI and
97; non-KANJI versions.
98
99IF NOT KANJI
100IF IBM
101 DB SIZE internat_block ; Size in bytes of this table
102 DB 44 ; Country code
103UKTABLE internat_block <1,9Ch,0,0,0,0,',',0,'.',0,'-',0,':',0,0,2,0,OFFSET DOSGROUP:MAP_DCASE,0,',',0>
104 DB SIZE internat_block ; Size in bytes of this table
105 DB 49 ; Country code
106GRMTABLE internat_block <1,'D','M',0,0,0,'.',0,',',0,'.',0,'.',0,3,2,1,OFFSET DOSGROUP:MAP_DCASE,0,';',0>
107 DB SIZE internat_block ; Size in bytes of this table
108 DB 33 ; Country code
109FRNTABLE internat_block <1,'F',0,0,0,0,' ',0,',',0,'/',0,':',0,3,2,1,OFFSET DOSGROUP:MAP_DCASE,0,';',0>
110 DB SIZE internat_block ; Size in bytes of this table
111 DB 81 ; Country code
112JAPTABLE internat_block <2,9DH,0,0,0,0,',',0,'.',0,'-',0,':',0,0,0,1,OFFSET DOSGROUP:MAP_DCASE , 0,',',0>
113ENDIF
114ENDIF
115 DB -1 ; End of tables
116
117CONSTANTS ENDS
118
119
120CODE SEGMENT BYTE PUBLIC 'CODE'
121ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
122
123;CASE MAPPER ROUTINE FOR 80H-FFH character range
124; ENTRY: AL = Character to map
125; EXIT: AL = The converted character
126; Alters no registers except AL and flags.
127; The routine should do nothing to chars below 80H.
128;
129; Example:
130 MAP_DCASE PROC FAR
131IF NOT KANJI
132IF IBM
133 CMP AL,80H
134 JB L_RET ;Map no chars below 80H ever
135 CMP AL,0A7H
136 JA L_RET ;This routine maps chars between 80H and A7H
137 SUB AL,80H ;Turn into index value
138 PUSH DS
139 PUSH BX
140 PUSH CS ;Move to DS
141 POP DS
142 MOV BX,OFFSET DOSGROUP:TABLE
143 XLAT ;Get upper case character
144 POP BX
145 POP DS
146ENDIF
147ENDIF
148 L_RET: RET
149 MAP_DCASE ENDP
150IF NOT KANJI
151IF IBM
152TABLE: DB 80H,9AH,"E","A",8EH,"A",8FH,80H
153 DB "E","E","E","I","I","I",8EH,8FH
154 DB 90H,92H,92H,"O",99H,"O","U","U"
155 DB "Y",99H,9AH,9BH,9CH,9DH,9EH,9FH
156 DB "A","I","O","U",0A5H,0A5H,0A6H,0A7H
157ENDIF
158ENDIF
159
160SUBTTL EDIT FUNCTION ASSIGNMENTS AND HEADERS
161PAGE
162; The following two tables implement the current buffered input editing
163; routines. The tables are pairwise associated in reverse order for ease
164; in indexing. That is; The first entry in ESCTAB corresponds to the last
165; entry in ESCFUNC, and the last entry in ESCTAB to the first entry in ESCFUNC.
166
167
168 PUBLIC ESCCHAR
169ESCCHAR DB ESCCH ;Lead-in character for escape sequences
170 IF NOT Rainbow
171ESCTAB:
172 IF NOT IBM
173 IF WANG
174 DB 0C0h ; ^Z inserter
175 DB 0C1H ; Copy one char
176 DB 0C7H ; Skip one char
177 DB 08AH ; Copy to char
178 DB 088H ; Skip to char
179 DB 09AH ; Copy line
180 DB 0CBH ; Kill line (no change in template)
181 DB 08BH ; Reedit line (new template)
182 DB 0C3H ; Backspace
183 DB 0C6H ; Enter insert mode
184 IF NOT TOGLINS
185 DB 0D6H ; Exit insert mode
186 ENDIF
187 DB 0C6H ; Escape character
188 DB 0C6H ; End of table
189 ELSE
190 ; VT52 equivalences
191 DB "Z" ; ^Z inserter
192 DB "S" ; F1 Copy one char
193 DB "V" ; F4 Skip one char
194 DB "T" ; F2 Copy to char
195 DB "W" ; F5 Skip to char
196 DB "U" ; F3 Copy line
197 DB "E" ; SHIFT ERASE Kill line (no change in template)
198 DB "J" ; ERASE Reedit line (new template)
199 DB "D" ; LEFT Backspace
200 DB "P" ; BLUE Enter insert mode
201 DB "Q" ; RED Exit insert mode
202 DB "R" ; GRAY Escape character
203 DB "R" ; End of table
204 ENDIF
205 ENDIF
206 IF IBM
207 DB 64 ; Ctrl-Z - F6
208 DB 77 ; Copy one char - -->
209 DB 59 ; Copy one char - F1
210 DB 83 ; Skip one char - DEL
211 DB 60 ; Copy to char - F2
212 DB 62 ; Skip to char - F4
213 DB 61 ; Copy line - F3
214 DB 61 ; Kill line (no change to template ) - Not used
215 DB 63 ; Reedit line (new template) - F5
216 DB 75 ; Backspace - <--
217 DB 82 ; Enter insert mode - INS (toggle)
218 DB 65 ; Escape character - F7
219 DB 65 ; End of table
220 ENDIF
221ESCEND:
222ESCTABLEN EQU ESCEND-ESCTAB
223
224ESCFUNC LABEL WORD
225 short_addr GETCH ; Ignore the escape sequence
226 short_addr TWOESC
227 IF NOT TOGLINS
228 short_addr EXITINS
229 ENDIF
230 short_addr ENTERINS
231 short_addr BACKSP
232 short_addr REEDIT
233 short_addr KILNEW
234 short_addr COPYLIN
235 short_addr SKIPSTR
236 short_addr COPYSTR
237 short_addr SKIPONE
238 short_addr COPYONE
239
240 IF IBM
241 short_addr COPYONE
242 ENDIF
243 short_addr CTRLZ
244 ENDIF
245
246;
247; OEMFunction key is expected to process a single function
248; key input from a device and dispatch to the proper
249; routines leaving all registers UNTOUCHED.
250;
251; Inputs: CS, SS are DOSGROUP
252; Outputs: None. This function is expected to JMP to onw of
253; the following labels:
254;
255; GetCh - ignore the sequence
256; TwoEsc - insert an ESCChar in the buffer
257; ExitIns - toggle insert mode
258; EnterIns - toggle insert mode
259; BackSp - move backwards one space
260; ReEdit - reedit the line with a new template
261; KilNew - discard the current line and start from scratch
262; CopyLin - copy the rest of the template into the line
263; SkipStr - read the next character and skip to it in the template
264; CopyStr - read next char and copy from template to line until char
265; SkipOne - advance position in template one character
266; CopyOne - copy next character in template into line
267; CtrlZ - place a ^Z into the template
268; Registers that are allowed to be modified by this function are:
269; AX, CX, BP
270
271 PUBLIC OEMFunctionKey
272OEMFunctionKey PROC NEAR
273 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
274 invoke $STD_CON_INPUT_NO_ECHO ; Get the second byte of the sequence
275
276 IF NOT Rainbow
277 MOV CL,ESCTABLEN ; length of table for scan
278 PUSH DI ; save DI (cannot change it!)
279 MOV DI,OFFSET DOSGROUP:ESCTAB ; offset of second byte table
280 REPNE SCASB ; Look it up in the table
281 POP DI ; restore DI
282 SHL CX,1 ; convert byte offset to word
283 MOV BP,CX ; move to indexable register
284 JMP [BP+OFFSET DOSGROUP:ESCFUNC] ; Go to the right routine
285 ENDIF
286 IF Rainbow
287
288TransferIf MACRO value,address
289 local a
290 CMP AL,value
291 JNZ a
292 transfer address
293a:
294ENDM
295
296 CMP AL,'[' ; is it second lead char
297 JZ EatParm ; yes, go walk tree
298GoGetCh:
299 transfer GetCh ; no, ignore sequence
300EatParm:
301 invoke $STD_CON_INPUT_NO_ECHO ; get argument
302 CMP AL,'A' ; is it alphabetic arg?
303 JAE EatAlpha ; yes, go snarf one up
304 XOR BP,BP ; init digit counter
305 JMP InDigit ; jump into internal eat digit routine
306EatNum:
307 invoke $STD_CON_INPUT_NO_ECHO ; get next digit
308InDigit:
309 CMP AL,'9' ; still a digit?
310 JA CheckNumEnd ; no, go check for end char
311 SUB AL,'0' ; turn into potential digit
312 JB GoGetCh ; oops, not a digit, ignore
313 MOV CX,BP ; save BP for 10 multiply
314 CBW ; make AL into AX
315 SHL BP,1 ; 2*BP
316 SHL BP,1 ; 4*BP
317 ADD BP,CX ; 5*BP
318 SHL BP,1 ; 10*BP
319 ADD BP,AX ; 10*BP + digit
320 JMP EatNum ; continue with number
321CheckNumEnd:
322 CMP AL,7Eh ; is it end char ~
323 JNZ GoGetCh ; nope, ignore key sequence
324 MOV AX,BP
325 transferIf 1,SkipStr ; FIND key
326 transferIf 2,EnterIns ; INSERT HERE key
327 transferIf 3,SkipOne ; REMOVE
328 transferIf 4,CopyStr ; SELECT
329 transferIf 17,TwoEsc ; INTERRUPT
330 transferIf 18,ReEdit ; RESUME
331 transferIf 19,KilNew ; CANCEL
332 transferIf 21,CtrlZ ; EXIT
333 transferIf 29,CopyLin ; DO
334 JMP GoGetCh
335EatAlpha:
336 CMP AL,'O' ; is it O?
337 JA GoGetCh ; no, after assume bogus
338 JZ EatPQRS ; eat the rest of the bogus key
339 transferIf 'C',CopyOne ; RIGHT
340 transferIf 'D',BackSp ; LEFT
341 JMP GoGetCh
342EatPQRS:
343 invoke $STD_CON_INPUT_NO_ECHO ; eat char after O
344 JMP GoGetCh
345 ENDIF
346
347OEMFunctionKey ENDP
348
349CODE ENDS
350
351 do_ext
352 END
353
354
355 \ No newline at end of file
diff --git a/v2.0/source/DOSSEG.ASM b/v2.0/source/DOSSEG.ASM
new file mode 100644
index 0000000..5d7e8c2
--- /dev/null
+++ b/v2.0/source/DOSSEG.ASM
@@ -0,0 +1,17 @@
1;
2; segment ordering for MSDOS
3;
4
5CONSTANTS SEGMENT BYTE PUBLIC 'CONST'
6CONSTANTS ENDS
7
8DATA SEGMENT BYTE PUBLIC 'DATA'
9DATA ENDS
10
11CODE SEGMENT BYTE PUBLIC 'CODE'
12CODE ENDS
13
14LAST SEGMENT BYTE PUBLIC 'LAST'
15LAST ENDS
16
17DOSGROUP GROUP CODE,CONSTANTS,DATA,LAST
diff --git a/v2.0/source/DOSSYM.ASM b/v2.0/source/DOSSYM.ASM
new file mode 100644
index 0000000..918ed5d
--- /dev/null
+++ b/v2.0/source/DOSSYM.ASM
@@ -0,0 +1,904 @@
1include DOSMAC.ASM
2IF2
3 %OUT DOSSYM in Pass 2
4ENDIF
5
6IFNDEF ALTVECT
7ALTVECT EQU 0 ;FALSE
8ENDIF
9
10BREAK <Control character definitions>
11
12c_DEL EQU 7Fh ; ASCII rubout or delete previous char
13c_BS EQU 08h ; ^H ASCII backspace
14c_CR EQU 0Dh ; ^M ASCII carriage return
15c_LF EQU 0Ah ; ^J ASCII linefeed
16c_ETB EQU 17h ; ^W ASCII end of transmission
17c_NAK EQU 15h ; ^U ASCII negative acknowledge
18c_ETX EQU 03h ; ^C ASCII end of text
19c_HT EQU 09h ; ^I ASCII tab
20
21BREAK <BPB Definition>
22
23
24;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
25; ;
26; C A V E A T P R O G R A M M E R ;
27; ;
28; Certain structures, constants and system calls below are private to ;
29; the DOS and are extremely version-dependent. They may change at any ;
30; time at the implementors' whim. As a result, they must not be ;
31; documented to the general public. If an extreme case arises, they ;
32; must be documented with this warning. ;
33; ;
34; Those structures and constants that are subject to the above will be ;
35; marked and bracketed with the flag: ;
36; ;
37; C A V E A T P R O G R A M M E R ;
38; ;
39;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
40
41BREAK <Bios Parameter Block>
42;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
43; C A V E A T P R O G R A M M E R ;
44; ;
45
46; Bios Parameter Block definition
47; This structure is used to build a full DPB
48
49BPBLOCK STRUC
50BPSECSZ DW ? ; Size in bytes of physical sector
51BPCLUS DB ? ; Sectors/Alloc unit
52BPRES DW ? ; Number of reserved sectors
53BPFTCNT DB ? ; Number of FATs
54BPDRCNT DW ? ; Number of directory entries
55BPSCCNT DW ? ; Total number of sectors
56BPMEDIA DB ? ; Media descriptor byte
57BPFTSEC DW ? ; Number of sectors taken up by one FAT
58BPBLOCK ENDS
59; ;
60; C A V E A T P R O G R A M M E R ;
61;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
62
63BREAK <Disk I/O Buffer Header>
64;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
65; C A V E A T P R O G R A M M E R ;
66; ;
67
68; Field definition for I/O buffer information
69
70BUFFINFO STRUC
71NEXTBUF DD ? ; Pointer to next buffer in list
72; The next two items are often refed as a word
73BUFDRV DB ? ; Logical drive # assoc with buffer FF = free
74BUFDIRTY DB ? ; Dirty flag
75BUFPRI DB ? ; Buffer selection priority (see EQUs below)
76VISIT DB ? ; Visit flag for buffer pool scans
77BUFSECNO DW ? ; Sector number of buffer
78; The next two items are often refed as a word
79BUFWRTCNT DB ? ; For FAT sectors, # times sector written out
80BUFWRTINC DB ? ; " " " , # sectors between each write
81BUFDRVDP DD ? ; Pointer to drive parameters
82BUFFINFO ENDS
83
84BUFINSIZ EQU SIZE BUFFINFO
85 ; Size of structure in bytes
86
87FREEPRI EQU 0
88LBRPRI EQU 2 ; Last byte of buffer read
89LBWPRI EQU 4 ; Last byte written
90RPRI EQU 6 ; Read but not last byte
91WPRI EQU 8 ; Written but not last byte
92DIRPRI EQU 15 ; Directory Sector
93FATPRI EQU 30 ; FAT sector
94; ;
95; C A V E A T P R O G R A M M E R ;
96;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
97
98BREAK <User stack inside of system call>
99; Location of user registers relative user stack pointer
100
101user_environ STRUC
102user_AX DW ?
103user_BX DW ?
104user_CX DW ?
105user_DX DW ?
106user_SI DW ?
107user_DI DW ?
108user_BP DW ?
109user_DS DW ?
110user_ES DW ?
111user_IP DW ?
112user_CS DW ?
113user_F DW ?
114user_environ ENDS
115
116BREAK <interrupt definitions>
117
118INTTAB EQU 20H
119INTBASE EQU 4 * inttab
120ENTRYPOINT EQU INTBASE+40H
121
122 IF ALTVECT
123ALTTAB EQU 0F0H
124ALTBASE EQU 4 * ALTTAB
125 ENDIF
126
127;
128; interrupt assignments
129;
130 IF NOT ALTVECT
131int_abort EQU INTTAB ; abort process
132int_command EQU int_abort+1 ; call MSDOS
133int_terminate EQU int_abort+2 ; int to terminate address
134int_ctrl_c EQU int_abort+3 ; ^c trapper
135int_fatal_abort EQU int_abort+4 ; hard disk error
136int_disk_read EQU int_abort+5 ; logical sector disk read
137int_disk_write EQU int_abort+6 ; logical sector disk write
138int_keep_process EQU int_abort+7 ; terminate program and stay resident
139;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
140; C A V E A T P R O G R A M M E R ;
141; ;
142int_spooler EQU int_abort+8 ; spooler call
143int_fastcon EQU int_abort+9 ; fast CON interrupt
144; ;
145; C A V E A T P R O G R A M M E R ;
146;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
147 ELSE
148int_abort EQU INTTAB ; abort process
149int_command EQU int_abort+1 ; call MSDOS
150int_terminate EQU ALTTAB ; int to terminate address
151int_ctrl_c EQU int_terminate+1 ; ^c trapper
152int_fatal_abort EQU int_terminate+2 ; hard disk error
153int_disk_read EQU int_abort+5 ; logical sector disk read
154int_disk_write EQU int_abort+6 ; logical sector disk write
155int_keep_process EQU int_abort+7 ; terminate program and stay resident
156;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
157; C A V E A T P R O G R A M M E R ;
158; ;
159int_spooler EQU int_terminate+3 ; spooler call
160int_fastcon EQU int_abort+9 ; fast CON interrupt
161; ;
162; C A V E A T P R O G R A M M E R ;
163;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
164 ENDIF
165
166addr_int_abort EQU 4 * int_abort
167addr_int_command EQU 4 * int_command
168addr_int_terminate EQU 4 * int_terminate
169addr_int_ctrl_c EQU 4 * int_ctrl_c
170addr_int_fatal_abort EQU 4 * int_fatal_abort
171addr_int_disk_read EQU 4 * int_disk_read
172addr_int_disk_write EQU 4 * int_disk_write
173addr_int_keep_process EQU 4 * int_keep_process
174;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
175; C A V E A T P R O G R A M M E R ;
176; ;
177addr_int_spooler EQU 4 * int_spooler
178addr_int_fastcon EQU 4 * int_fastcon
179; ;
180; C A V E A T P R O G R A M M E R ;
181;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
182
183BREAK <Disk map>
184; MSDOS partitions the disk into 4 sections:
185;
186; phys sector 0: +-------------------+
187; | | boot/reserved |
188; | +-------------------+
189; | | File allocation |
190; v | table(s) |
191; | (multiple copies |
192; | are kept) |
193; +-------------------+
194; | Directory |
195; +-------------------+
196; | File space |
197; +-------------------+
198; | Unaddressable |
199; | (to end of disk) |
200; +-------------------+
201;
202; All partition boundaries are sector boundaries. The size of the FAT is
203; adjusted to maximize the file space addressable.
204
205BREAK <Directory entry>
206
207;
208; +---------------------------+
209; | (12 BYTE) filename/ext | 0 0
210; +---------------------------+
211; | (BYTE) attributes | 11 B
212; +---------------------------+
213; | (10 BYTE) reserved | 12 C
214; +---------------------------+
215; | (WORD) time of last write | 22 16
216; +---------------------------+
217; | (WORD) date of last write | 24 18
218; +---------------------------+
219; | (WORD) First cluster | 26 1A
220; +---------------------------+
221; | (DWORD) file size | 28 1C
222; +---------------------------+
223;
224; First byte of filename = E5 -> free directory entry
225; = 00 -> end of allocated directory
226; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour
227; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980
228;
229dir_entry STRUC
230dir_name DB 11 DUP (?) ; file name
231dir_attr DB ? ; attribute bits
232dir_pad DB 10 DUP (?) ; reserved for expansion
233dir_time DW ? ; time of last write
234dir_date DW ? ; date of last write
235dir_first DW ? ; first allocation unit of file
236dir_size_l DW ? ; low 16 bits of file size
237dir_size_h DW ? ; high 16 bits of file size
238dir_entry ENDS
239
240attr_read_only EQU 1h
241attr_hidden EQU 2h
242attr_system EQU 4h
243attr_volume_id EQU 8h
244attr_directory EQU 10h
245attr_archive EQU 20h
246
247attr_all EQU attr_hidden+attr_system+attr_directory
248 ; OR of hard attributes for FINDENTRY
249
250attr_ignore EQU attr_read_only+attr_archive
251 ; ignore this(ese) attribute(s)
252 ; during search first/next
253
254attr_changeable EQU attr_read_only+attr_hidden+attr_system+attr_archive
255 ; changeable via CHMOD
256
257BREAK <File allocation Table information>
258;
259; The File Allocation Table uses a 12-bit entry for each allocation unit on the
260; disk. These entries are packed, two for every three bytes. The contents of
261; entry number N is found by 1) multiplying N by 1.5; 2) adding the result to
262; the base address of the Allocation Table; 3) fetching the 16-bit word at this
263; address; 4) If N was odd (so that N*1.5 was not an integer), shift the word
264; right four bits; 5) mask to 12 bits (AND with 0FFF hex). Entry number zero
265; is used as an end-of-file trap in the OS and is passed to the BIOS to help
266; determine disk format. Entry 1 is reserved for future use. The first
267; available allocation unit is assigned entry number two, and even though it is
268; the first, is called cluster 2. Entries greater than 0FF8H are end of file
269; marks; entries of zero are unallocated. Otherwise, the contents of a FAT
270; entry is the number of the next cluster in the file.
271;
272; Clusters with bad sectors are tagged with FF7H. Any non-zero number would do
273; because these clusters show as allocated, but are not part of any allocation
274; chain and thus will never be allocated to a file. A particular number is
275; selected so that disk checking programs know what to do (ie. a cluster with
276; entry FF7H which is not in a chain is not an error).
277
278BREAK <DPB structure>
279;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
280; C A V E A T P R O G R A M M E R ;
281; ;
282
283DIRSTRLEN EQU 64 ; Max length in bytes of directory strings
284
285dpb STRUC
286dpb_drive DB ? ; Logical drive # assoc with DPB (A=0,B=1,...)
287dpb_UNIT DB ? ; Driver unit number of DPB
288dpb_sector_size DW ? ; Size of physical sector in bytes
289dpb_cluster_mask DB ? ; Sectors/cluster - 1
290dpb_cluster_shift DB ? ; Log2 of sectors/cluster
291dpb_first_FAT DW ? ; Starting record of FATs
292dpb_FAT_count DB ? ; Number of FATs for this drive
293dpb_root_entries DW ? ; Number of directory entries
294dpb_first_sector DW ? ; First sector of first cluster
295dpb_max_cluster DW ? ; Number of clusters on drive + 1
296dpb_FAT_size DB ? ; Number of records occupied by FAT
297dpb_dir_sector DW ? ; Starting record of directory
298dpb_driver_addr DD ? ; Pointer to driver
299dpb_media DB ? ; Media byte
300dpb_first_access DB ? ; This is initialized to -1 to force a media
301 ; check the first time this DPB is used
302dpb_next_dpb DD ? ; Pointer to next Drive parameter block
303dpb_current_dir DW ? ; Cluster number of start of current directory
304 ; 0 indicates root, -1 indicates invalid
305 ; (disk ? changed)
306dpb_dir_text DB DIRSTRLEN DUP(?)
307 ; ASCIZ string of current directory
308dpb ENDS
309
310DPBSIZ EQU SIZE dpb ; Size of the structure in bytes
311
312DSKSIZ = dpb_max_cluster ; Size of disk (temp used during init only)
313; ;
314; C A V E A T P R O G R A M M E R ;
315;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
316
317BREAK <File Control Block definition>
318;
319; Field definition for FCBs
320; The FCB has the following structure:
321;
322; +---------------------------+
323; | Drive indicator(byte) |
324; +---------------------------+
325; | Filename (8 chars) |
326; +---------------------------+
327; | Extension (3 chars) |
328; +---------------------------+
329; | Current Extent(word) |
330; +---------------------------+
331; | Record size (word) |
332; +---------------------------+
333; | File Size (2 words) |
334; +---------------------------+
335; | Date of write |
336; +---------------------------+
337; | Time of write |
338; +---------------------------+
339;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
340; C A V E A T P R O G R A M M E R ;
341; ;
342; | Flags: |
343; | bit 7=0 file/1 device |
344; | bit 6=0 if dirty |
345; | bits 0-5 deviceid |
346; +---------------------------+
347; | first cluster in file |
348; +---------------------------+
349; | position of last cluster |
350; +---------------------------+
351; | last cluster accessed | 12 bit-+--- packed in 3 bytes
352; +---------------------------+ |
353; | parent directory | <------+
354; +---------------------------+
355; ;
356; C A V E A T P R O G R A M M E R ;
357;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
358; | next record number |
359; +---------------------------+
360; | random record number |
361; +---------------------------+
362;
363
364sys_fcb STRUC
365fcb_drive DB ?
366fcb_name DB 8 DUP (?)
367fcb_ext DB 3 DUP (?)
368fcb_EXTENT DW ?
369fcb_RECSIZ DW ? ; Size of record (user settable)
370fcb_FILSIZ DW ? ; Size of file in bytes; used with the following
371 ; word
372fcb_DRVBP DW ? ; BP for SEARCH FIRST and SEARCH NEXT
373fcb_FDATE DW ? ; Date of last writing
374fcb_FTIME DW ? ; Time of last writing
375;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
376; C A V E A T P R O G R A M M E R ;
377; ;
378fcb_DEVID DB ? ; Device ID number, bits 0-5 if file.
379 ; bit 7=0 for file, bit 7=1 for I/O device
380 ; If file, bit 6=0 if dirty
381 ; If I/O device, bit 6=0 if EOF (input)
382 ; Bit 5=1 if Raw mode
383 ; Bit 0=1 if console input device
384 ; Bit 1=1 if console output device
385 ; Bit 2=1 if null device
386 ; Bit 3=1 if clock device
387fcb_FIRCLUS DW ? ; First cluster of file
388fcb_CLUSPOS DW ? ; Position of last cluster accessed
389fcb_LSTCLUS DW ? ; Last cluster accessed and directory
390 DB ? ; pack 2 12 bit numbers into 24 bits...
391; ;
392; C A V E A T P R O G R A M M E R ;
393;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
394fcb_NR DB ? ; Next record
395fcb_RR DB 4 DUP (?) ; Random record
396sys_fcb ENDS
397
398FILDIRENT = fcb_FILSIZ ; Used only by SEARCH FIRST and
399 ; SEARCH NEXT
400
401;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
402; C A V E A T P R O G R A M M E R ;
403; ;
404devid_file_clean EQU 40h ; true if file and not written
405devid_file_mask_drive EQU 3Fh ; mask for drive number
406
407devid_device EQU 80h ; true if a device
408devid_device_EOF EQU 40h ; true if end of file reached
409devid_device_raw EQU 20h ; true if in raw mode
410devid_device_special EQU 10h ; true if special device
411devid_device_clock EQU 08h ; true if clock device
412devid_device_null EQU 04h ; true if null device
413devid_device_con_out EQU 02h ; true if console output
414devid_device_con_in EQU 01h ; true if consle input
415
416;
417; structure of devid field as returned by IOCTL is:
418;
419; BIT 7 6 5 4 3 2 1 0
420; |---|---|---|---|---|---|---|---|
421; | I | E | R | S | I | I | I | I |
422; | S | O | A | P | S | S | S | S |
423; | D | F | W | E | C | N | C | C |
424; | E | | | C | L | U | O | I |
425; | V | | | L | K | L | T | N |
426; |---|---|---|---|---|---|---|---|
427; ISDEV = 1 if this channel is a device
428; = 0 if this channel is a disk file
429;
430; If ISDEV = 1
431;
432; EOF = 0 if End Of File on input
433; RAW = 1 if this device is in Raw mode
434; = 0 if this device is cooked
435; ISCLK = 1 if this device is the clock device
436; ISNUL = 1 if this device is the null device
437; ISCOT = 1 if this device is the console output
438; ISCIN = 1 if this device is the console input
439;
440; If ISDEV = 0
441; EOF = 0 if channel has been written
442; Bits 0-5 are the block device number for
443; the channel (0 = A, 1 = B, ...)
444;
445devid_ISDEV EQU 80h
446devid_EOF EQU 40h
447devid_RAW EQU 20h
448devid_SPECIAL EQU 10H
449devid_ISCLK EQU 08h
450devid_ISNUL EQU 04h
451devid_ISCOT EQU 02h
452devid_ISCIN EQU 01h
453
454devid_block_dev EQU 1Fh ; mask for block device number
455
456;
457; find first/next buffer
458;
459find_buf STRUC
460find_buf_sattr DB ? ; attribute of search
461find_buf_drive DB ? ; drive of search
462find_buf_name DB 11 DUP (?) ; formatted name
463find_buf_LastEnt DW ? ; LastEnt
464find_buf_ThisDPB DD ? ; This DPB
465find_buf_DirStart DW ? ; DirStart
466; ;
467; C A V E A T P R O G R A M M E R ;
468;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
469
470find_buf_attr DB ? ; attribute found
471find_buf_time DW ? ; time
472find_buf_date DW ? ; date
473find_buf_size_l DW ? ; low(size)
474find_buf_size_h DW ? ; high(size)
475find_buf_pname DB 13 DUP (?) ; packed name
476find_buf ENDS
477
478BREAK <Process data block>
479;
480; Process data block (otherwise known as program header)
481;
482
483FilPerProc EQU 20
484
485Process_data_block STRUC
486PDB_Exit_Call DW ? ; INT int_abort system terminate
487PDB_block_len DW ? ; size of execution block
488 DB ?
489PDB_CPM_Call DB 5 DUP (?) ; ancient call to system
490PDB_Exit DD ? ; pointer to exit routine
491PDB_Ctrl_C DD ? ; pointer to ^C routine
492PDB_Fatal_abort DD ? ; pointer to fatal error
493;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
494; C A V E A T P R O G R A M M E R ;
495; ;
496PDB_Parent_PID DW ? ; PID of parent (terminate PID)
497PDB_JFN_Table DB FilPerProc DUP (?)
498 ; indices into system table
499; ;
500; C A V E A T P R O G R A M M E R ;
501;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
502PDB_environ DW ? ; seg addr of environment
503;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
504; C A V E A T P R O G R A M M E R ;
505; ;
506PDB_User_stack DD ? ; stack of self during system calls
507PDB_PAD1 DB 1Eh DUP (?)
508; ;
509; C A V E A T P R O G R A M M E R ;
510;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
511PDB_Call_system DB 5 DUP (?) ; portable method of system call
512;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
513; C A V E A T P R O G R A M M E R ;
514; ;
515PDB_PAD2 DB 6h DUP (?) ;
516; ;
517; C A V E A T P R O G R A M M E R ;
518;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
519Process_data_block ENDS
520
521BREAK <EXEC and EXE file structures>
522;
523; EXEC arg block - load/go program
524;
525
526;
527; The following get used as arguments to the EXEC system call. They indicate
528; whether or not the program is executed or whether or not a program header
529; gets created.
530;
531exec_func_no_execute EQU 1 ; no execute bit
532exec_func_overlay EQU 2 ; overlay bit
533
534Exec0 STRUC
535Exec0_environ DW ? ; seg addr of environment
536Exec0_com_line DD ? ; pointer to asciz command line
537Exec0_5C_FCB DD ? ; default fcb at 5C
538Exec0_6C_FCB DD ? ; default fcb at 6C
539Exec0 ENDS
540
541Exec1 STRUC
542Exec1_environ DW ? ; seg addr of environment
543Exec1_com_line DD ? ; pointer to asciz command line
544Exec1_5C_FCB DD ? ; default fcb at 5C
545Exec1_6C_FCB DD ? ; default fcb at 6C
546Exec1_SP DW ? ; stack pointer of program
547Exec1_SS DW ? ; stack seg register of program
548Exec1_IP DW ? ; entry point IP
549Exec1_CS DW ? ; entry point CS
550Exec1 ENDS
551
552Exec3 STRUC
553Exec3_load_addr DW ? ; seg address of load point
554Exec3_reloc_fac DW ? ; relocation factor
555Exec3 ENDS
556
557;
558; Exit codes in upper byte
559;
560Exit_terminate EQU 0
561Exit_abort EQU 0
562Exit_Ctrl_C EQU 1
563Exit_Hard_Error EQU 2
564Exit_Keep_process EQU 3
565
566;
567; EXE file header
568;
569
570EXE_file STRUC
571exe_signature DW ? ; must contain 4D5A (yay zibo!)
572exe_len_mod_512 DW ? ; low 9 bits of length
573exe_pages DW ? ; number of 512b pages in file
574exe_rle_count DW ? ; count of reloc entries
575exe_par_dir DW ? ; number of paragraphs before image
576exe_min_BSS DW ? ; minimum number of para of BSS
577exe_max_BSS DW ? ; max number of para of BSS
578exe_SS DW ? ; stack of image
579exe_SP DW ? ; SP of image
580exe_chksum DW ? ; checksum of file (ignored)
581exe_IP DW ? ; IP of entry
582exe_CS DW ? ; CS of entry
583exe_rle_table DW ? ; byte offset of reloc table
584exe_iov DW ? ; overlay number (0 for root)
585exe_sym_tab DD ? ; offset of symbol table in file
586EXE_file ENDS
587
588exe_valid_signature EQU 5A4Dh
589exe_valid_old_signature EQU 4D5Ah
590
591symbol_entry STRUC
592sym_value DD ?
593sym_type DW ?
594sym_len DB ?
595sym_name DB 255 dup (?)
596symbol_entry ENDS
597
598BREAK <Internal system file table format>
599;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
600; C A V E A T P R O G R A M M E R ;
601; ;
602;
603; system file table
604;
605
606sft STRUC
607sft_link DD ?
608sft_count DW ? ; number of entries
609sft_table DW ? ; beginning of array of the following
610sft ENDS
611
612;
613; system file table entry
614;
615
616sf_entry STRUC
617sf_ref_count DB ? ; number of processes sharing fcb
618sf_mode DB ? ; mode of access
619sf_attr DB ? ; attribute of file
620sf_fcb DB (SIZE sys_fcb) DUP (?)
621 ; actual FCB
622sf_entry ENDS
623
624sf_default_number EQU 5h
625; ;
626; C A V E A T P R O G R A M M E R ;
627;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
628
629BREAK <Memory arena structure>
630;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
631; C A V E A T P R O G R A M M E R ;
632; ;
633;
634; arena item
635;
636arena STRUC
637arena_signature DB ? ; 4D for valid item, 5A for last item
638arena_owner DW ? ; owner of arena item
639arena_size DW ? ; size in paragraphs of item
640arena ENDS
641
642arena_owner_system EQU 0 ; free block indication
643
644arena_signature_normal EQU 4Dh ; valid signature, not end of arena
645arena_signature_end EQU 5Ah ; valid signature, last block in arena
646; ;
647; C A V E A T P R O G R A M M E R ;
648;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
649
650BREAK <Machine instruction definitions>
651
652mi_INT EQU 0CDh
653mi_Long_JMP EQU 0EAh
654mi_Long_CALL EQU 09Ah
655mi_Long_RET EQU 0CBh
656
657BREAK <Standard I/O assignments>
658
659stdin EQU 0
660stdout EQU 1
661stderr EQU 2
662stdaux EQU 3
663stdprn EQU 4
664
665BREAK <Xenix subfunction assignments>
666
667open_for_read EQU 0
668open_for_write EQU 1
669open_for_both EQU 2
670
671BREAK <Xenix error codes>
672
673;
674; XENIX calls all return error codes through AX. If an error occurred then the
675; carry bit will be set and the error code is in AX. If no error occurred then
676; the carry bit is reset and AX contains returned info.
677;
678
679no_error_occurred EQU 0 ?
680
681error_invalid_function EQU 1
682error_file_not_found EQU 2
683error_path_not_found EQU 3
684error_too_many_open_files EQU 4
685error_access_denied EQU 5
686error_invalid_handle EQU 6
687error_arena_trashed EQU 7
688error_not_enough_memory EQU 8
689error_invalid_block EQU 9
690error_bad_environment EQU 10
691error_bad_format EQU 11
692error_invalid_access EQU 12
693error_invalid_data EQU 13
694;**** unused EQU 14
695error_invalid_drive EQU 15
696error_current_directory EQU 16
697error_not_same_device EQU 17
698error_no_more_files EQU 18
699
700alloc_not_enough_memory EQU error_not_enough_memory
701alloc_arena_trashed EQU error_arena_trashed
702
703close_invalid_handle EQU error_invalid_handle
704close_invalid_function EQU error_invalid_function
705
706chdir_path_not_found EQU error_path_not_found
707
708chmod_path_not_found EQU error_path_not_found
709chmod_access_denied EQU error_access_denied
710chmod_invalid_function EQU error_invalid_function
711
712creat_access_denied EQU error_access_denied
713creat_path_not_found EQU error_path_not_found
714creat_too_many_open_files EQU error_too_many_open_files
715
716curdir_invalid_drive EQU error_invalid_drive
717
718dealloc_invalid_block EQU error_invalid_block
719dealloc_arena_trashed EQU error_arena_trashed
720
721dup_invalid_handle EQU error_invalid_handle
722dup_too_many_open_files EQU error_too_many_open_files
723
724dup2_invalid_handle EQU error_invalid_handle
725
726exec_invalid_function EQU error_invalid_function
727exec_bad_environment EQU error_bad_environment
728exec_bad_format EQU error_bad_format
729exec_not_enough_memory EQU error_not_enough_memory
730exec_file_not_found EQU error_file_not_found
731
732filetimes_invalid_function EQU error_invalid_function
733filetimes_invalid_handle EQU error_invalid_handle
734
735findfirst_file_not_found EQU error_file_not_found
736findfirst_no_more_files EQU error_no_more_files
737findnext_no_more_files EQU error_no_more_files
738
739international_invalid_function EQU error_invalid_function
740
741ioctl_invalid_handle EQU error_invalid_handle
742ioctl_invalid_function EQU error_invalid_function
743ioctl_invalid_data EQU error_invalid_data
744
745lseek_invalid_handle EQU error_invalid_handle
746lseek_invalid_function EQU error_invalid_function
747
748mkdir_path_not_found EQU error_path_not_found
749mkdir_access_denied EQU error_access_denied
750
751open_invalid_access EQU error_invalid_access
752open_file_not_found EQU error_file_not_found
753open_access_denied EQU error_access_denied
754open_too_many_open_files EQU error_too_many_open_files
755
756read_invalid_handle EQU error_invalid_handle
757read_access_denied EQU error_access_denied
758
759rename_file_not_found EQU error_file_not_found
760rename_not_same_device EQU error_not_same_device
761rename_access_denied EQU error_access_denied
762
763rmdir_path_not_found EQU error_path_not_found
764rmdir_access_denied EQU error_access_denied
765rmdir_current_directory EQU error_current_directory
766
767setblock_invalid_block EQU error_invalid_block
768setblock_arena_trashed EQU error_arena_trashed
769setblock_not_enough_memory EQU error_not_enough_memory
770setblock_invalid_function EQU error_invalid_function
771
772unlink_file_not_found EQU error_file_not_found
773unlink_access_denied EQU error_access_denied
774
775write_invalid_handle EQU error_invalid_handle
776write_access_denied EQU error_access_denied
777
778BREAK <system call definitions>
779
780ABORT EQU 0 ; 0 0
781STD_CON_INPUT EQU 1 ; 1 1
782STD_CON_OUTPUT EQU 2 ; 2 2
783STD_AUX_INPUT EQU 3 ; 3 3
784STD_AUX_OUTPUT EQU 4 ; 4 4
785STD_PRINTER_OUTPUT EQU 5 ; 5 5
786RAW_CON_IO EQU 6 ; 6 6
787RAW_CON_INPUT EQU 7 ; 7 7
788STD_CON_INPUT_NO_ECHO EQU 8 ; 8 8
789STD_CON_STRING_OUTPUT EQU 9 ; 9 9
790STD_CON_STRING_INPUT EQU 10 ; 10 A
791STD_CON_INPUT_STATUS EQU 11 ; 11 B
792STD_CON_INPUT_FLUSH EQU 12 ; 12 C
793DISK_RESET EQU 13 ; 13 D
794SET_DEFAULT_DRIVE EQU 14 ; 14 E
795FCB_OPEN EQU 15 ; 15 F
796FCB_CLOSE EQU 16 ; 16 10
797DIR_SEARCH_FIRST EQU 17 ; 17 11
798DIR_SEARCH_NEXT EQU 18 ; 18 12
799FCB_DELETE EQU 19 ; 19 13
800FCB_SEQ_READ EQU 20 ; 20 14
801FCB_SEQ_WRITE EQU 21 ; 21 15
802FCB_CREATE EQU 22 ; 22 16
803FCB_RENAME EQU 23 ; 23 17
804GET_DEFAULT_DRIVE EQU 25 ; 25 19
805SET_DMA EQU 26 ; 26 1A
806;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
807; C A V E A T P R O G R A M M E R ;
808; ;
809GET_DEFAULT_DPB EQU 31 ; 31 1F
810; ;
811; C A V E A T P R O G R A M M E R ;
812;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
813FCB_RANDOM_READ EQU 33 ; 33 21
814FCB_RANDOM_WRITE EQU 34 ; 34 22
815GET_FCB_FILE_LENGTH EQU 35 ; 35 23
816GET_FCB_POSITION EQU 36 ; 36 24
817SET_INTERRUPT_VECTOR EQU 37 ; 37 25
818CREATE_PROCESS_DATA_BLOCK EQU 38 ; 38 26
819FCB_RANDOM_READ_BLOCK EQU 39 ; 39 27
820FCB_RANDOM_WRITE_BLOCK EQU 40 ; 40 28
821PARSE_FILE_DESCRIPTOR EQU 41 ; 41 29
822GET_DATE EQU 42 ; 42 2A
823SET_DATE EQU 43 ; 43 2B
824GET_TIME EQU 44 ; 44 2C
825SET_TIME EQU 45 ; 45 2D
826SET_VERIFY_ON_WRITE EQU 46 ; 46 2E
827; Extended functionality group
828GET_DMA EQU 47 ; 47 2F
829GET_VERSION EQU 48 ; 48 30
830KEEP_PROCESS EQU 49 ; 49 31
831;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
832; C A V E A T P R O G R A M M E R ;
833; ;
834GET_DPB EQU 50 ; 50 32
835; ;
836; C A V E A T P R O G R A M M E R ;
837;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
838SET_CTRL_C_TRAPPING EQU 51 ; 51 33
839GET_INDOS_FLAG EQU 52 ; 52 34
840GET_INTERRUPT_VECTOR EQU 53 ; 53 35
841GET_DRIVE_FREESPACE EQU 54 ; 54 36
842CHAR_OPER EQU 55 ; 55 37
843INTERNATIONAL EQU 56 ; 56 38
844; XENIX CALLS
845; Directory Group
846MKDIR EQU 57 ; 57 39
847RMDIR EQU 58 ; 58 3A
848CHDIR EQU 59 ; 59 3B
849; File Group
850CREAT EQU 60 ; 60 3C
851OPEN EQU 61 ; 61 3D
852CLOSE EQU 62 ; 62 3E
853READ EQU 63 ; 63 3F
854WRITE EQU 64 ; 64 40
855UNLINK EQU 65 ; 65 41
856LSEEK EQU 66 ; 66 42
857CHMOD EQU 67 ; 67 43
858IOCTL EQU 68 ; 68 44
859XDUP EQU 69 ; 69 45
860XDUP2 EQU 70 ; 70 46
861CURRENT_DIR EQU 71 ; 71 47
862; Memory Group
863ALLOC EQU 72 ; 72 48
864DEALLOC EQU 73 ; 73 49
865SETBLOCK EQU 74 ; 74 4A
866; Process Group
867EXEC EQU 75 ; 75 4B
868EXIT EQU 76 ; 76 4C
869WAIT EQU 77 ; 77 4D
870FIND_FIRST EQU 78 ; 78 4E
871; Special Group
872FIND_NEXT EQU 79 ; 79 4F
873; SPECIAL SYSTEM GROUP
874;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
875; C A V E A T P R O G R A M M E R ;
876; ;
877SET_CURRENT_PDB EQU 80 ; 80 50
878GET_CURRENT_PDB EQU 81 ; 81 51
879GET_IN_VARS EQU 82 ; 82 52
880SETDPB EQU 83 ; 83 53
881; ;
882; C A V E A T P R O G R A M M E R ;
883;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
884GET_VERIFY_ON_WRITE EQU 84 ; 84 54
885;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
886; C A V E A T P R O G R A M M E R ;
887; ;
888DUP_PDB EQU 85 ; 85 55
889; ;
890; C A V E A T P R O G R A M M E R ;
891;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
892RENAME EQU 86 ; 86 56
893FILE_TIMES EQU 87 ; 87 57
894
895SET_OEM_HANDLER EQU 248 ; 248 F8
896OEM_C1 EQU 249 ; 249 F9
897OEM_C2 EQU 250 ; 250 FA
898OEM_C3 EQU 251 ; 251 FB
899OEM_C4 EQU 252 ; 252 FC
900OEM_C5 EQU 253 ; 253 FD
901OEM_C6 EQU 254 ; 254 FE
902OEM_C7 EQU 255 ; 255 FF
903SUBTTL
904
diff --git a/v2.0/source/DOSSYM_v211.ASM b/v2.0/source/DOSSYM_v211.ASM
new file mode 100644
index 0000000..106e115
--- /dev/null
+++ b/v2.0/source/DOSSYM_v211.ASM
@@ -0,0 +1,963 @@
1include DOSMAC.ASM
2IF2
3 %OUT DOSSYM in Pass 2
4ENDIF
5
6IFNDEF ALTVECT
7ALTVECT EQU 0 ;FALSE
8ENDIF
9
10DOS_MAJOR_VERSION EQU 2
11DOS_MINOR_VERSION EQU 11
12
13BREAK <Control character definitions>
14
15c_DEL EQU 7Fh ; ASCII rubout or delete previous char
16c_BS EQU 08h ; ^H ASCII backspace
17c_CR EQU 0Dh ; ^M ASCII carriage return
18c_LF EQU 0Ah ; ^J ASCII linefeed
19c_ETB EQU 17h ; ^W ASCII end of transmission
20c_NAK EQU 15h ; ^U ASCII negative acknowledge
21c_ETX EQU 03h ; ^C ASCII end of text
22c_HT EQU 09h ; ^I ASCII tab
23
24BREAK <BPB Definition>
25
26
27;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
28; ;
29; C A V E A T P R O G R A M M E R ;
30; ;
31; Certain structures, constants and system calls below are private to ;
32; the DOS and are extremely version-dependent. They may change at any ;
33; time at the implementors' whim. As a result, they must not be ;
34; documented to the general public. If an extreme case arises, they ;
35; must be documented with this warning. ;
36; ;
37; Those structures and constants that are subject to the above will be ;
38; marked and bracketed with the flag: ;
39; ;
40; C A V E A T P R O G R A M M E R ;
41; ;
42;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
43
44BREAK <Bios Parameter Block>
45;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
46; C A V E A T P R O G R A M M E R ;
47; ;
48
49; Bios Parameter Block definition
50; This structure is used to build a full DPB
51
52BPBLOCK STRUC
53BPSECSZ DW ? ; Size in bytes of physical sector
54BPCLUS DB ? ; Sectors/Alloc unit
55BPRES DW ? ; Number of reserved sectors
56BPFTCNT DB ? ; Number of FATs
57BPDRCNT DW ? ; Number of directory entries
58BPSCCNT DW ? ; Total number of sectors
59BPMEDIA DB ? ; Media descriptor byte
60BPFTSEC DW ? ; Number of sectors taken up by one FAT
61BPBLOCK ENDS
62; ;
63; C A V E A T P R O G R A M M E R ;
64;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
65
66BREAK <Disk I/O Buffer Header>
67;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
68; C A V E A T P R O G R A M M E R ;
69; ;
70
71; Field definition for I/O buffer information
72
73BUFFINFO STRUC
74NEXTBUF DD ? ; Pointer to next buffer in list
75; The next two items are often refed as a word
76BUFDRV DB ? ; Logical drive # assoc with buffer FF = free
77BUFDIRTY DB ? ; Dirty flag
78BUFPRI DB ? ; Buffer selection priority (see EQUs below)
79VISIT DB ? ; Visit flag for buffer pool scans
80BUFSECNO DW ? ; Sector number of buffer
81; The next two items are often refed as a word
82BUFWRTCNT DB ? ; For FAT sectors, # times sector written out
83BUFWRTINC DB ? ; " " " , # sectors between each write
84BUFDRVDP DD ? ; Pointer to drive parameters
85BUFFINFO ENDS
86
87BUFINSIZ EQU SIZE BUFFINFO
88 ; Size of structure in bytes
89
90FREEPRI EQU 0
91LBRPRI EQU 2 ; Last byte of buffer read
92LBWPRI EQU 4 ; Last byte written
93RPRI EQU 6 ; Read but not last byte
94WPRI EQU 8 ; Written but not last byte
95DIRPRI EQU 15 ; Directory Sector
96FATPRI EQU 30 ; FAT sector
97; ;
98; C A V E A T P R O G R A M M E R ;
99;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
100
101BREAK <User stack inside of system call>
102; Location of user registers relative user stack pointer
103
104user_environ STRUC
105user_AX DW ?
106user_BX DW ?
107user_CX DW ?
108user_DX DW ?
109user_SI DW ?
110user_DI DW ?
111user_BP DW ?
112user_DS DW ?
113user_ES DW ?
114user_IP DW ?
115user_CS DW ?
116user_F DW ?
117user_environ ENDS
118
119BREAK <interrupt definitions>
120
121INTTAB EQU 20H
122INTBASE EQU 4 * inttab
123ENTRYPOINT EQU INTBASE+40H
124
125 IF ALTVECT
126ALTTAB EQU 0F0H
127ALTBASE EQU 4 * ALTTAB
128 ENDIF
129
130;
131; interrupt assignments
132;
133 IF NOT ALTVECT
134int_abort EQU INTTAB ; abort process
135int_command EQU int_abort+1 ; call MSDOS
136int_terminate EQU int_abort+2 ; int to terminate address
137int_ctrl_c EQU int_abort+3 ; ^c trapper
138int_fatal_abort EQU int_abort+4 ; hard disk error
139int_disk_read EQU int_abort+5 ; logical sector disk read
140int_disk_write EQU int_abort+6 ; logical sector disk write
141int_keep_process EQU int_abort+7 ; terminate program and stay
142 ; resident
143;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
144; C A V E A T P R O G R A M M E R ;
145; ;
146int_spooler EQU int_abort+8 ; spooler call
147int_fastcon EQU int_abort+9 ; fast CON interrupt
148; ;
149; C A V E A T P R O G R A M M E R ;
150;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
151 ELSE
152int_abort EQU INTTAB ; abort process
153int_command EQU int_abort+1 ; call MSDOS
154int_terminate EQU ALTTAB ; int to terminate address
155int_ctrl_c EQU int_terminate+1 ; ^c trapper
156int_fatal_abort EQU int_terminate+2 ; hard disk error
157int_disk_read EQU int_abort+5 ; logical sector disk read
158int_disk_write EQU int_abort+6 ; logical sector disk write
159int_keep_process EQU int_abort+7 ; terminate program and stay
160 ; resident
161;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
162; C A V E A T P R O G R A M M E R ;
163; ;
164int_spooler EQU int_terminate+3 ; spooler call
165int_fastcon EQU int_abort+9 ; fast CON interrupt
166; ;
167; C A V E A T P R O G R A M M E R ;
168;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
169 ENDIF
170
171addr_int_abort EQU 4 * int_abort
172addr_int_command EQU 4 * int_command
173addr_int_terminate EQU 4 * int_terminate
174addr_int_ctrl_c EQU 4 * int_ctrl_c
175addr_int_fatal_abort EQU 4 * int_fatal_abort
176addr_int_disk_read EQU 4 * int_disk_read
177addr_int_disk_write EQU 4 * int_disk_write
178addr_int_keep_process EQU 4 * int_keep_process
179;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
180; C A V E A T P R O G R A M M E R ;
181; ;
182addr_int_spooler EQU 4 * int_spooler
183addr_int_fastcon EQU 4 * int_fastcon
184; ;
185; C A V E A T P R O G R A M M E R ;
186;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
187
188BREAK <Disk map>
189; MSDOS partitions the disk into 4 sections:
190;
191; phys sector 0: +-------------------+
192; | | boot/reserved |
193; | +-------------------+
194; | | File allocation |
195; v | table(s) |
196; | (multiple copies |
197; | are kept) |
198; +-------------------+
199; | Directory |
200; +-------------------+
201; | File space |
202; +-------------------+
203; | Unaddressable |
204; | (to end of disk) |
205; +-------------------+
206;
207; All partition boundaries are sector boundaries. The size of the FAT is
208; adjusted to maximize the file space addressable.
209
210BREAK <Directory entry>
211
212;
213; +---------------------------+
214; | (12 BYTE) filename/ext | 0 0
215; +---------------------------+
216; | (BYTE) attributes | 11 B
217; +---------------------------+
218; | (10 BYTE) reserved | 12 C
219; +---------------------------+
220; | (WORD) time of last write | 22 16
221; +---------------------------+
222; | (WORD) date of last write | 24 18
223; +---------------------------+
224; | (WORD) First cluster | 26 1A
225; +---------------------------+
226; | (DWORD) file size | 28 1C
227; +---------------------------+
228;
229; First byte of filename = E5 -> free directory entry
230; = 00 -> end of allocated directory
231; Time: Bits 0-4=seconds/2, bits 5-10=minute, 11-15=hour
232; Date: Bits 0-4=day, bits 5-8=month, bits 9-15=year-1980
233;
234dir_entry STRUC
235dir_name DB 11 DUP (?) ; file name
236dir_attr DB ? ; attribute bits
237dir_pad DB 10 DUP (?) ; reserved for expansion
238dir_time DW ? ; time of last write
239dir_date DW ? ; date of last write
240dir_first DW ? ; first allocation unit of file
241dir_size_l DW ? ; low 16 bits of file size
242dir_size_h DW ? ; high 16 bits of file size
243dir_entry ENDS
244
245attr_read_only EQU 1h
246attr_hidden EQU 2h
247attr_system EQU 4h
248attr_volume_id EQU 8h
249attr_directory EQU 10h
250attr_archive EQU 20h
251
252attr_all EQU attr_hidden+attr_system+attr_directory
253 ; OR of hard attributes for FINDENTRY
254
255attr_ignore EQU attr_read_only+attr_archive
256 ; ignore this(ese) attribute(s) during
257 ; search first/next
258
259attr_changeable EQU attr_read_only+attr_hidden+attr_system+attr_archive
260 ; changeable via CHMOD
261
262BREAK <File allocation Table information>
263;
264; The File Allocation Table uses a 12-bit entry for each allocation unit on
265; the disk. These entries are packed, two for every three bytes. The contents
266; of entry number N is found by 1) multiplying N by 1.5; 2) adding the result
267; to the base address of the Allocation Table; 3) fetching the 16-bit word
268; at this address; 4) If N was odd (so that N*1.5 was not an integer), shift
269; the word right four bits; 5) mask to 12 bits (AND with 0FFF hex). Entry
270; number zero is used as an end-of-file trap in the OS and is passed to the
271; BIOS to help determine disk format. Entry 1 is reserved for future use.
272; The first available allocation unit is assigned entry number two, and even
273; though it is the first, is called cluster 2. Entries greater than 0FF8H
274; are end of file marks; entries of zero are unallocated. Otherwise, the
275; contents of a FAT entry is the number of the next cluster in the file.
276;
277; Clusters with bad sectors are tagged with FF7H. Any non-zero number would
278; do because these clusters show as allocated, but are not part of any
279; allocation chain and thus will never be allocated to a file. A particular
280; number is selected so that disk checking programs know what to do (ie. a
281; cluster with entry FF7H which is not in a chain is not an error).
282
283BREAK <DPB structure>
284;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
285; C A V E A T P R O G R A M M E R ;
286; ;
287
288DIRSTRLEN EQU 64 ; Max length in bytes of directory strings
289
290dpb STRUC
291dpb_drive DB ? ; Logical drive # assoc with DPB (A=0,B=1,...)
292dpb_UNIT DB ? ; Driver unit number of DPB
293dpb_sector_size DW ? ; Size of physical sector in bytes
294dpb_cluster_mask DB ? ; Sectors/cluster - 1
295dpb_cluster_shift DB ? ; Log2 of sectors/cluster
296dpb_first_FAT DW ? ; Starting record of FATs
297dpb_FAT_count DB ? ; Number of FATs for this drive
298dpb_root_entries DW ? ; Number of directory entries
299dpb_first_sector DW ? ; First sector of first cluster
300dpb_max_cluster DW ? ; Number of clusters on drive + 1
301dpb_FAT_size DB ? ; Number of records occupied by FAT
302dpb_dir_sector DW ? ; Starting record of directory
303dpb_driver_addr DD ? ; Pointer to driver
304dpb_media DB ? ; Media byte
305dpb_first_access DB ? ; This is initialized to -1 to force a media
306 ; check the first time this DPB is used
307dpb_next_dpb DD ? ; Pointer to next Drive parameter block
308dpb_current_dir DW ? ; Cluster number of start of current directory
309 ; 0 indicates root, -1 indicates invalid (disk
310 ; ? changed)
311dpb_dir_text DB DIRSTRLEN DUP(?)
312 ; ASCIZ string of current directory
313dpb ENDS
314
315DPBSIZ EQU SIZE dpb ; Size of the structure in bytes
316
317DSKSIZ = dpb_max_cluster ; Size of disk (temp used during init only)
318; ;
319; C A V E A T P R O G R A M M E R ;
320;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
321
322BREAK <File Control Block definition>
323;
324; Field definition for FCBs
325; The FCB has the following structure:
326;
327; +---------------------------+
328; | Drive indicator(byte) |
329; +---------------------------+
330; | Filename (8 chars) |
331; +---------------------------+
332; | Extension (3 chars) |
333; +---------------------------+
334; | Current Extent(word) |
335; +---------------------------+
336; | Record size (word) |
337; +---------------------------+
338; | File Size (2 words) |
339; +---------------------------+
340; | Date of write |
341; +---------------------------+
342; | Time of write |
343; +---------------------------+
344;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
345; C A V E A T P R O G R A M M E R ;
346; ;
347; | Flags: |
348; | bit 7=0 file/1 device |
349; | bit 6=0 if dirty |
350; | bits 0-5 deviceid |
351; +---------------------------+
352; | first cluster in file |
353; +---------------------------+
354; | position of last cluster |
355; +---------------------------+
356; | last cluster accessed | 12 bit-+--- packed in 3 bytes
357; +---------------------------+ |
358; | parent directory | <------+
359; +---------------------------+
360; ;
361; C A V E A T P R O G R A M M E R ;
362;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
363; | next record number |
364; +---------------------------+
365; | random record number |
366; +---------------------------+
367;
368
369sys_fcb STRUC
370fcb_drive DB ?
371fcb_name DB 8 DUP (?)
372fcb_ext DB 3 DUP (?)
373fcb_EXTENT DW ?
374fcb_RECSIZ DW ? ; Size of record (user settable)
375fcb_FILSIZ DW ? ; Size of file in bytes; used with the following
376 ; word
377fcb_DRVBP DW ? ; BP for SEARCH FIRST and SEARCH NEXT
378fcb_FDATE DW ? ; Date of last writing
379fcb_FTIME DW ? ; Time of last writing
380;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
381; C A V E A T P R O G R A M M E R ;
382; ;
383fcb_DEVID DB ? ; Device ID number, bits 0-5 if file.
384 ; bit 7=0 for file, bit 7=1 for I/O device
385 ; If file, bit 6=0 if dirty
386 ; If I/O device, bit 6=0 if EOF (input)
387 ; Bit 5=1 if Raw mode
388 ; Bit 0=1 if console input device
389 ; Bit 1=1 if console output device
390 ; Bit 2=1 if null device
391 ; Bit 3=1 if clock device
392fcb_FIRCLUS DW ? ; First cluster of file
393fcb_CLUSPOS DW ? ; Position of last cluster accessed
394fcb_LSTCLUS DW ? ; Last cluster accessed and directory pack 2 12
395 DB ? ; bit numbers into 24 bits...
396; ;
397; C A V E A T P R O G R A M M E R ;
398;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
399fcb_NR DB ? ; Next record
400fcb_RR DB 4 DUP (?) ; Random record
401sys_fcb ENDS
402
403FILDIRENT = fcb_FILSIZ ; Used only by SEARCH FIRST and SEARCH
404 ; NEXT
405
406;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
407; C A V E A T P R O G R A M M E R ;
408; ;
409devid_file_clean EQU 40h ; true if file and not written
410devid_file_mask_drive EQU 3Fh ; mask for drive number
411
412devid_device EQU 80h ; true if a device
413devid_device_EOF EQU 40h ; true if end of file reached
414devid_device_raw EQU 20h ; true if in raw mode
415devid_device_special EQU 10h ; true if special device
416devid_device_clock EQU 08h ; true if clock device
417devid_device_null EQU 04h ; true if null device
418devid_device_con_out EQU 02h ; true if console output
419devid_device_con_in EQU 01h ; true if consle input
420
421;
422; structure of devid field as returned by IOCTL is:
423;
424; BIT 7 6 5 4 3 2 1 0
425; |---|---|---|---|---|---|---|---|
426; | I | E | R | S | I | I | I | I |
427; | S | O | A | P | S | S | S | S |
428; | D | F | W | E | C | N | C | C |
429; | E | | | C | L | U | O | I |
430; | V | | | L | K | L | T | N |
431; |---|---|---|---|---|---|---|---|
432; ISDEV = 1 if this channel is a device
433; = 0 if this channel is a disk file
434;
435; If ISDEV = 1
436;
437; EOF = 0 if End Of File on input
438; RAW = 1 if this device is in Raw mode
439; = 0 if this device is cooked
440; ISCLK = 1 if this device is the clock device
441; ISNUL = 1 if this device is the null device
442; ISCOT = 1 if this device is the console output
443; ISCIN = 1 if this device is the console input
444;
445; If ISDEV = 0
446; EOF = 0 if channel has been written
447; Bits 0-5 are the block device number for
448; the channel (0 = A, 1 = B, ...)
449;
450devid_ISDEV EQU 80h
451devid_EOF EQU 40h
452devid_RAW EQU 20h
453devid_SPECIAL EQU 10H
454devid_ISCLK EQU 08h
455devid_ISNUL EQU 04h
456devid_ISCOT EQU 02h
457devid_ISCIN EQU 01h
458
459devid_block_dev EQU 1Fh ; mask for block device number
460
461;
462; find first/next buffer
463;
464find_buf STRUC
465find_buf_sattr DB ? ; attribute of search
466find_buf_drive DB ? ; drive of search
467find_buf_name DB 11 DUP (?) ; formatted name
468find_buf_LastEnt DW ? ; LastEnt
469find_buf_ThisDPB DD ? ; This DPB
470find_buf_DirStart DW ? ; DirStart
471; ;
472; C A V E A T P R O G R A M M E R ;
473;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
474
475find_buf_attr DB ? ; attribute found
476find_buf_time DW ? ; time
477find_buf_date DW ? ; date
478find_buf_size_l DW ? ; low(size)
479find_buf_size_h DW ? ; high(size)
480find_buf_pname DB 13 DUP (?) ; packed name
481find_buf ENDS
482
483BREAK <Process data block>
484;
485; Process data block (otherwise known as program header)
486;
487
488FilPerProc EQU 20
489
490Process_data_block STRUC
491PDB_Exit_Call DW ? ; INT int_abort system terminate
492PDB_block_len DW ? ; size of execution block
493 DB ?
494PDB_CPM_Call DB 5 DUP (?) ; ancient call to system
495PDB_Exit DD ? ; pointer to exit routine
496PDB_Ctrl_C DD ? ; pointer to ^C routine
497PDB_Fatal_abort DD ? ; pointer to fatal error
498;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
499; C A V E A T P R O G R A M M E R ;
500; ;
501PDB_Parent_PID DW ? ; PID of parent (terminate PID)
502PDB_JFN_Table DB FilPerProc DUP (?)
503 ; indices into system table
504; ;
505; C A V E A T P R O G R A M M E R ;
506;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
507PDB_environ DW ? ; seg addr of environment
508;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
509; C A V E A T P R O G R A M M E R ;
510; ;
511PDB_User_stack DD ? ; stack of self during system calls
512PDB_PAD1 DB 1Eh DUP (?)
513; ;
514; C A V E A T P R O G R A M M E R ;
515;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
516PDB_Call_system DB 5 DUP (?) ; portable method of system call
517;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
518; C A V E A T P R O G R A M M E R ;
519; ;
520PDB_PAD2 DB 6h DUP (?) ;
521; ;
522; C A V E A T P R O G R A M M E R ;
523;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
524Process_data_block ENDS
525
526BREAK <EXEC and EXE file structures>
527;
528; EXEC arg block - load/go program
529;
530
531;
532; The following get used as arguments to the EXEC system call. They indicate
533; whether or not the program is executed or whether or not a program header
534; gets created.
535;
536exec_func_no_execute EQU 1 ; no execute bit
537exec_func_overlay EQU 2 ; overlay bit
538
539Exec0 STRUC
540Exec0_environ DW ? ; seg addr of environment
541Exec0_com_line DD ? ; pointer to asciz command line
542Exec0_5C_FCB DD ? ; default fcb at 5C
543Exec0_6C_FCB DD ? ; default fcb at 6C
544Exec0 ENDS
545
546Exec1 STRUC
547Exec1_environ DW ? ; seg addr of environment
548Exec1_com_line DD ? ; pointer to asciz command line
549Exec1_5C_FCB DD ? ; default fcb at 5C
550Exec1_6C_FCB DD ? ; default fcb at 6C
551Exec1_SP DW ? ; stack pointer of program
552Exec1_SS DW ? ; stack seg register of program
553Exec1_IP DW ? ; entry point IP
554Exec1_CS DW ? ; entry point CS
555Exec1 ENDS
556
557Exec3 STRUC
558Exec3_load_addr DW ? ; seg address of load point
559Exec3_reloc_fac DW ? ; relocation factor
560Exec3 ENDS
561
562;
563; Exit codes in upper byte
564;
565Exit_terminate EQU 0
566Exit_abort EQU 0
567Exit_Ctrl_C EQU 1
568Exit_Hard_Error EQU 2
569Exit_Keep_process EQU 3
570
571;
572; EXE file header
573;
574
575EXE_file STRUC
576exe_signature DW ? ; must contain 4D5A (yay zibo!)
577exe_len_mod_512 DW ? ; low 9 bits of length
578exe_pages DW ? ; number of 512b pages in file
579exe_rle_count DW ? ; count of reloc entries
580exe_par_dir DW ? ; number of paragraphs before image
581exe_min_BSS DW ? ; minimum number of para of BSS
582exe_max_BSS DW ? ; max number of para of BSS
583exe_SS DW ? ; stack of image
584exe_SP DW ? ; SP of image
585exe_chksum DW ? ; checksum of file (ignored)
586exe_IP DW ? ; IP of entry
587exe_CS DW ? ; CS of entry
588exe_rle_table DW ? ; byte offset of reloc table
589exe_iov DW ? ; overlay number (0 for root)
590exe_sym_tab DD ? ; offset of symbol table in file
591EXE_file ENDS
592
593exe_valid_signature EQU 5A4Dh
594exe_valid_old_signature EQU 4D5Ah
595
596symbol_entry STRUC
597sym_value DD ?
598sym_type DW ?
599sym_len DB ?
600sym_name DB 255 dup (?)
601symbol_entry ENDS
602
603BREAK <Internal system file table format>
604;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
605; C A V E A T P R O G R A M M E R ;
606; ;
607;
608; system file table
609;
610
611sft STRUC
612sft_link DD ?
613sft_count DW ? ; number of entries
614sft_table DW ? ; beginning of array of the following
615sft ENDS
616
617;
618; system file table entry
619;
620
621sf_entry STRUC
622sf_ref_count DB ? ; number of processes sharing fcb
623sf_mode DB ? ; mode of access
624sf_attr DB ? ; attribute of file
625sf_fcb DB (SIZE sys_fcb) DUP (?)
626 ; actual FCB
627sf_entry ENDS
628
629sf_default_number EQU 5h
630; ;
631; C A V E A T P R O G R A M M E R ;
632;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
633
634BREAK <Memory arena structure>
635;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
636; C A V E A T P R O G R A M M E R ;
637; ;
638;
639; arena item
640;
641arena STRUC
642arena_signature DB ? ; 4D for valid item, 5A for last item
643arena_owner DW ? ; owner of arena item
644arena_size DW ? ; size in paragraphs of item
645arena ENDS
646
647;
648; Current structure of the data returned by the international call
649;
650
651internat_block STRUC
652Date_tim_format DW ? ; 0-USA, 1-EUR, 2-JAP
653Currency_sym DB ? ; Currency Symbol 5 bytes
654 DB ?
655 DB ?
656 DB ?
657 DB ?
658Thous_sep DB ? ; Thousands separator 2 bytes
659 DB ?
660Decimal_sep DB ? ; Decimal separator 2 bytes
661 DB ?
662Date_sep DB ? ; Date separator 2 bytes
663 DB ?
664Time_sep DB ? ; Decimal separator 2 bytes
665 DB ?
666Bit_feild DB ? ; Bit values
667 ; Bit 0 = 0 if currency symbol first
668 ; = 1 if currency symbol last
669 ; Bit 1 = 0 if No space after currency symbol
670 ; = 1 if space after currency symbol
671Currency_cents DB ? ; Number of places after currency dec point
672Time_24 DB ? ; 1 if 24 hour time, 0 if 12 hour time
673Map_call DW ? ; Address of case mapping call (DWORD)
674 DW ? ; THIS IS TWO WORDS SO IT CAN BE INITIALIZED
675 ; in pieces.
676Data_sep DB ? ; Data list separator character
677 DB ?
678internat_block ENDS
679
680;
681; Max size of the block returned by the INTERNATIONAL call
682;
683internat_block_max EQU 32
684
685;
686; CAUTION: The routines in ALLOC.ASM rely on the fact that arena_signature
687; and arena_owner_system are all equal to zero and are contained in DI. Change
688; them and change ALLOC.ASM.
689
690arena_owner_system EQU 0 ; free block indication
691
692arena_signature_normal EQU 4Dh ; valid signature, not end of arena
693arena_signature_end EQU 5Ah ; valid signature, last block in arena
694; ;
695; C A V E A T P R O G R A M M E R ;
696;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
697
698BREAK <Machine instruction definitions>
699
700mi_INT EQU 0CDh
701mi_Long_JMP EQU 0EAh
702mi_Long_CALL EQU 09Ah
703mi_Long_RET EQU 0CBh
704
705BREAK <Standard I/O assignments>
706
707stdin EQU 0
708stdout EQU 1
709stderr EQU 2
710stdaux EQU 3
711stdprn EQU 4
712
713BREAK <Xenix subfunction assignments>
714
715open_for_read EQU 0
716open_for_write EQU 1
717open_for_both EQU 2
718
719BREAK <Xenix error codes>
720
721;
722; XENIX calls all return error codes through AX. If an error occurred then
723; the carry bit will be set and the error code is in AX. If no error occurred
724; then the carry bit is reset and AX contains returned info.
725;
726
727no_error_occurred EQU 0 ?
728
729error_invalid_function EQU 1
730error_file_not_found EQU 2
731error_path_not_found EQU 3
732error_too_many_open_files EQU 4
733error_access_denied EQU 5
734error_invalid_handle EQU 6
735error_arena_trashed EQU 7
736error_not_enough_memory EQU 8
737error_invalid_block EQU 9
738error_bad_environment EQU 10
739error_bad_format EQU 11
740error_invalid_access EQU 12
741error_invalid_data EQU 13
742;**** unused EQU 14
743error_invalid_drive EQU 15
744error_current_directory EQU 16
745error_not_same_device EQU 17
746error_no_more_files EQU 18
747
748country_not_found EQU error_file_not_found
749alloc_not_enough_memory EQU error_not_enough_memory
750alloc_arena_trashed EQU error_arena_trashed
751
752close_invalid_handle EQU error_invalid_handle
753close_invalid_function EQU error_invalid_function
754
755chdir_path_not_found EQU error_path_not_found
756
757chmod_path_not_found EQU error_path_not_found
758chmod_access_denied EQU error_access_denied
759chmod_invalid_function EQU error_invalid_function
760
761creat_access_denied EQU error_access_denied
762creat_path_not_found EQU error_path_not_found
763creat_too_many_open_files EQU error_too_many_open_files
764
765curdir_invalid_drive EQU error_invalid_drive
766
767dealloc_invalid_block EQU error_invalid_block
768dealloc_arena_trashed EQU error_arena_trashed
769
770dup_invalid_handle EQU error_invalid_handle
771dup_too_many_open_files EQU error_too_many_open_files
772
773dup2_invalid_handle EQU error_invalid_handle
774
775exec_invalid_function EQU error_invalid_function
776exec_bad_environment EQU error_bad_environment
777exec_bad_format EQU error_bad_format
778exec_not_enough_memory EQU error_not_enough_memory
779exec_file_not_found EQU error_file_not_found
780
781filetimes_invalid_function EQU error_invalid_function
782filetimes_invalid_handle EQU error_invalid_handle
783
784findfirst_file_not_found EQU error_file_not_found
785findfirst_no_more_files EQU error_no_more_files
786findnext_no_more_files EQU error_no_more_files
787
788international_invalid_function EQU error_invalid_function
789
790ioctl_invalid_handle EQU error_invalid_handle
791ioctl_invalid_function EQU error_invalid_function
792ioctl_invalid_data EQU error_invalid_data
793
794lseek_invalid_handle EQU error_invalid_handle
795lseek_invalid_function EQU error_invalid_function
796
797mkdir_path_not_found EQU error_path_not_found
798mkdir_access_denied EQU error_access_denied
799
800open_invalid_access EQU error_invalid_access
801open_file_not_found EQU error_file_not_found
802open_access_denied EQU error_access_denied
803open_too_many_open_files EQU error_too_many_open_files
804
805read_invalid_handle EQU error_invalid_handle
806read_access_denied EQU error_access_denied
807
808rename_file_not_found EQU error_file_not_found
809rename_not_same_device EQU error_not_same_device
810rename_access_denied EQU error_access_denied
811
812rmdir_path_not_found EQU error_path_not_found
813rmdir_access_denied EQU error_access_denied
814rmdir_current_directory EQU error_current_directory
815
816setblock_invalid_block EQU error_invalid_block
817setblock_arena_trashed EQU error_arena_trashed
818setblock_not_enough_memory EQU error_not_enough_memory
819setblock_invalid_function EQU error_invalid_function
820
821unlink_file_not_found EQU error_file_not_found
822unlink_access_denied EQU error_access_denied
823
824write_invalid_handle EQU error_invalid_handle
825write_access_denied EQU error_access_denied
826
827BREAK <system call definitions>
828
829Abort EQU 0 ; 0 0
830Std_Con_Input EQU 1 ; 1 1
831Std_Con_Output EQU 2 ; 2 2
832Std_Aux_Input EQU 3 ; 3 3
833Std_Aux_Output EQU 4 ; 4 4
834Std_Printer_Output EQU 5 ; 5 5
835Raw_Con_IO EQU 6 ; 6 6
836Raw_Con_Input EQU 7 ; 7 7
837Std_Con_Input_No_Echo EQU 8 ; 8 8
838Std_Con_String_Output EQU 9 ; 9 9
839Std_Con_String_Input EQU 10 ; 10 A
840Std_Con_Input_Status EQU 11 ; 11 B
841Std_Con_Input_Flush EQU 12 ; 12 C
842Disk_Reset EQU 13 ; 13 D
843Set_Default_Drive EQU 14 ; 14 E
844FCB_Open EQU 15 ; 15 F
845FCB_Close EQU 16 ; 16 10
846Dir_Search_First EQU 17 ; 17 11
847Dir_Search_Next EQU 18 ; 18 12
848FCB_Delete EQU 19 ; 19 13
849FCB_Seq_Read EQU 20 ; 20 14
850FCB_Seq_Write EQU 21 ; 21 15
851FCB_Create EQU 22 ; 22 16
852FCB_Rename EQU 23 ; 23 17
853Get_Default_Drive EQU 25 ; 25 19
854Set_DMA EQU 26 ; 26 1A
855;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
856; C A V E A T P R O G R A M M E R ;
857; ;
858Get_Default_DPB EQU 31 ; 31 1F
859; ;
860; C A V E A T P R O G R A M M E R ;
861;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
862FCB_Random_Read EQU 33 ; 33 21
863FCB_Random_Write EQU 34 ; 34 22
864Get_FCB_File_Length EQU 35 ; 35 23
865Get_FCB_Position EQU 36 ; 36 24
866Set_Interrupt_Vector EQU 37 ; 37 25
867Create_Process_Data_Block EQU 38 ; 38 26
868FCB_Random_Read_Block EQU 39 ; 39 27
869FCB_Random_Write_Block EQU 40 ; 40 28
870Parse_File_Descriptor EQU 41 ; 41 29
871Get_Date EQU 42 ; 42 2A
872Set_Date EQU 43 ; 43 2B
873Get_Time EQU 44 ; 44 2C
874Set_Time EQU 45 ; 45 2D
875Set_Verify_On_Write EQU 46 ; 46 2E
876; Extended functionality group
877Get_DMA EQU 47 ; 47 2F
878Get_Version EQU 48 ; 48 30
879Keep_Process EQU 49 ; 49 31
880;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
881; C A V E A T P R O G R A M M E R ;
882; ;
883Get_DPB EQU 50 ; 50 32
884; ;
885; C A V E A T P R O G R A M M E R ;
886;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
887Set_CTRL_C_Trapping EQU 51 ; 51 33
888Get_InDOS_Flag EQU 52 ; 52 34
889Get_Interrupt_Vector EQU 53 ; 53 35
890Get_Drive_Freespace EQU 54 ; 54 36
891Char_Oper EQU 55 ; 55 37
892International EQU 56 ; 56 38
893; Directory Group
894MKDir EQU 57 ; 57 39
895RMDir EQU 58 ; 58 3A
896CHDir EQU 59 ; 59 3B
897; File Group
898Creat EQU 60 ; 60 3C
899Open EQU 61 ; 61 3D
900Close EQU 62 ; 62 3E
901Read EQU 63 ; 63 3F
902Write EQU 64 ; 64 40
903Unlink EQU 65 ; 65 41
904LSeek EQU 66 ; 66 42
905CHMod EQU 67 ; 67 43
906IOCtl EQU 68 ; 68 44
907XDup EQU 69 ; 69 45
908XDup2 EQU 70 ; 70 46
909Current_Dir EQU 71 ; 71 47
910; Memory Group
911Alloc EQU 72 ; 72 48
912Dealloc EQU 73 ; 73 49
913Setblock EQU 74 ; 74 4A
914; Process Group
915Exec EQU 75 ; 75 4B
916Exit EQU 76 ; 76 4C
917Wait EQU 77 ; 77 4D
918Find_First EQU 78 ; 78 4E
919; Special Group
920Find_Next EQU 79 ; 79 4F
921; SPECIAL SYSTEM GROUP
922;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
923; C A V E A T P R O G R A M M E R ;
924; ;
925Set_Current_PDB EQU 80 ; 80 50
926Get_Current_PDB EQU 81 ; 81 51
927Get_In_Vars EQU 82 ; 82 52
928SetDPB EQU 83 ; 83 53
929; ;
930; C A V E A T P R O G R A M M E R ;
931;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
932Get_Verify_On_Write EQU 84 ; 84 54
933;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
934; C A V E A T P R O G R A M M E R ;
935; ;
936Dup_PDB EQU 85 ; 85 55
937; ;
938; C A V E A T P R O G R A M M E R ;
939;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
940Rename EQU 86 ; 86 56
941File_Times EQU 87 ; 87 57
942AllocOper EQU 88 ; 88 58
943; Network extention system calls
944GetExtendedError EQU 89 ; 89 59
945CreateTempFile EQU 90 ; 90 5A
946CreateNewFile EQU 91 ; 91 5B
947LockOper EQU 92 ; 92 5C Lock and Unlock
948ServerCall EQU 93 ; 93 5D CommitAll, ServerDOSCall,
949 ; CloseByName, CloseUser,
950 ; CloseUserProcess,
951 ; GetOpenFileList
952UserIDOper EQU 94 ; 94 5E Get and Set
953AssignOper EQU 95 ; 95 5F On, Off, Get, Set, Cancel
954
955Set_Oem_Handler EQU 248 ; 248 F8
956OEM_C1 EQU 249 ; 249 F9
957OEM_C2 EQU 250 ; 250 FA
958OEM_C3 EQU 251 ; 251 FB
959OEM_C4 EQU 252 ; 252 FC
960OEM_C5 EQU 253 ; 253 FD
961OEM_C6 EQU 254 ; 254 FE
962OEM_C7 EQU 255 ; 255 FF
963SUBTTL
diff --git a/v2.0/source/EDLIN.ASM b/v2.0/source/EDLIN.ASM
new file mode 100644
index 0000000..f795ac4
--- /dev/null
+++ b/v2.0/source/EDLIN.ASM
@@ -0,0 +1,1846 @@
1 title EDLIN for MSDOS 2.0
2
3;-----------------------------------------------------------------------;
4; REVISION HISTORY: ;
5; ;
6; V1.02 ;
7; ;
8; V2.00 9/13/82 M.A. Ulloa ;
9; Modified to use Pathnames in command line file ;
10; specification, modified REPLACE to use an empty ;
11; string intead of the old replace string when this ;
12; is missing, and search and replace now start from ;
13; first line of buffer (like old version of EDLIN) ;
14; instead than current+1 line. Also added the U and ;
15; V commands that search (replace) starting from the ;
16; current+1 line. ;
17; ;
18; 9/15/82 M.A. Ulloa ;
19; Added the quote character (^V). ;
20; ;
21; 9/16/82 M.A. Ulloa ;
22; Corrected bug about use of quote char when going ;
23; into default insert mode. Also corrected the problem ;
24; with ^Z being the end of file marker. End of file is ;
25; reached when an attempt to read returns less chars ;
26; than requested. ;
27; ;
28; 9/17/82 M.A. Ulloa ;
29; Corrected bug about boundaries for Copy ;
30; ;
31; 10/4/82 Rev. 1 M.A. Ulloa ;
32; The IBM version now does NOT have the U and V ;
33; commands. The MSDOS version HAS the U and V commands. ;
34; Added the B switch, and modified the effect of ;
35; the quote char. ;
36; ;
37; 10/7/82 Rev. 2 M.A. Ulloa ;
38; Changed the S and R commands to start from the ;
39; current line+1 (as U and V did). Took away U and V in ;
40; all versions. ;
41; ;
42; 10/13/82 Rev. 3 M.A. Ulloa ;
43; Now if parameter1 < 1 then parameter1 = 1 ;
44; ;
45; 10/15/82 Rev. 4 M.A. Ulloa ;
46; Param4 if specified must be an absolute number that ;
47; reprecents the count. ;
48; ;
49; 10/18/82 Rev. 5 M.A. Ulloa ;
50; Fixed problem with trying to edit files with the ;
51; same name as directories. Also, if the end of file is ;
52; reached it checks that a LF is the last character, ;
53; otherwise it inserts a CRLF pair at the end. ;
54; ;
55; 10/20/82 Rev. 6 M.A.Ulloa ;
56; Changed the text of some error messages for IBM and ;
57; rewrite PAGE. ;
58; ;
59; 10/25/82 Rev. 7 M.A.Ulloa ;
60; Made all messages as in the IBM vers. ;
61; ;
62; 10/28/82 Rev. 8 M.A.Ulloa ;
63; Corrected problem with parsing for options. ;
64; ;
65; Rev. 9 Aaron Reynolds ;
66; Made error messages external. ;
67; ;
68; 12/08/82 Rev. 10 M.A. Ulloa ;
69; Corrected problem arising with having to restore ;
70; the old directory in case of a file name error. ;
71; ;
72; 12/17/82 Rev. 11 M.A. Ulloa ;
73; Added the ROPROT equate for R/O file protection. ;
74; It causes only certain operations (L,P,S,W,A, and Q) ;
75; to be allowed on read only files. ;
76; ;
77; 12/29/82 Rev. 12 M.A. Ulloa :
78; Added the creation error message. ;
79; ;
80; 4/14/83 Rev. 13 N.Panners ;
81; Fixed bug in Merge which lost char if not ^Z. ;
82; Fixed bug in Copy to correctly check ;
83; for full buffers. ;
84; ;
85; ;
86; 7/23/83 Rev. 14 N.Panners ;
87; Split EDLIN into two seperate modules to ;
88; allow assembly of sources on an IBM PC ;
89; EDLIN and EDLPROC ;
90; ;
91;-----------------------------------------------------------------------;
92
93
94FALSE EQU 0
95TRUE EQU NOT FALSE
96
97KANJI EQU FALSE
98
99roprot equ true ;set to TRUE if protection to r/o files
100 ; desired.
101FCB EQU 5CH
102
103Comand_Line_Length equ 128
104quote_char equ 16h ;quote character = ^V
105
106
107PAGE
108
109 .xlist
110 INCLUDE DOSSYM.ASM
111 .list
112
113
114SUBTTL Contants and Data areas
115PAGE
116
117PROMPT EQU "*"
118STKSIZ EQU 80H
119
120CODE SEGMENT PUBLIC
121CODE ENDS
122
123CONST SEGMENT PUBLIC WORD
124CONST ENDS
125
126DATA SEGMENT PUBLIC WORD
127DATA ENDS
128
129DG GROUP CODE,CONST,DATA
130
131CONST SEGMENT PUBLIC WORD
132
133 EXTRN BADDRV:BYTE,NDNAME:BYTE,bad_vers_err:BYTE,opt_err:BYTE
134 EXTRN NOBAK:BYTE,BADCOM:BYTE,NEWFIL:BYTE,DEST:BYTE,MRGERR:BYTE
135 EXTRN NODIR:BYTE,DSKFUL:BYTE,MEMFUL:BYTE,FILENM:BYTE
136 EXTRN NOSUCH:BYTE,TOOLNG:BYTE,EOF:BYTE,ro_err:byte,bcreat:byte
137
138 PUBLIC TXT1,TXT2,FUDGE,USERDIR,HARDCH
139
140BAK DB "BAK"
141
142make db "***MAUlloa/Microsoft/V20***"
143rev db "14"
144
145 if roprot ;***** R/O *****
146roflag db 0 ; =1 if file is r/o
147 endif
148
149fourth db 0 ;fourth parameter flag
150
151loadmod db 0 ;Load mode flag, 0 = ^Z marks the
152 ; end of a file, 1 = viceversa.
153hardch dd ?
154
155the_root db 0 ;root directory flag
156
157fudge db 0 ;directory changed flag
158user_drive db 0
159
160
161optchar db "-"
162
163dirchar db "/",0
164
165userdir db "/",0
166 db (dirstrlen) dup(0)
167
168fname_buffer db Comand_Line_Length dup(0)
169;-----------------------------------------------------------------------;
170
171TXT1 DB 0,80H DUP (?)
172TXT2 DB 0,80H DUP (?)
173DELFLG DB 0
174
175CONST ENDS
176
177DATA SEGMENT PUBLIC WORD
178
179 PUBLIC QFLG,FCB2,OLDLEN,PARAM1,PARAM2,OLDDAT,SRCHFLG
180 PUBLIC COMLINE,NEWLEN,SRCHMOD,CURRENT,LSTFND,NUMPOS
181 PUBLIC LSTNUM,SRCHCNT,POINTER,START,ENDTXT,USER_DRIVE
182
183;-----------------------------------------------------------------------;
184; Be carefull when adding parameters, they have to follow the
185; order in which they apperar here. (this is a table, ergo it
186; is indexed thru a pointer, and random additions will cause the
187; wrong item to be accessed). Also param4 is known to be the
188; count parameter, and known to be the fourth entry in the table
189; so it receives special treatment. (See GETNUM)
190
191PARAM1 DW 1 DUP (?)
192PARAM2 DW 1 DUP (?)
193PARAM3 DW 1 DUP (?)
194PARAM4 DW 1 DUP (?)
195
196;-----------------------------------------------------------------------;
197
198PTR_1 DW 1 DUP (?)
199PTR_2 DW 1 DUP (?)
200PTR_3 DW 1 DUP (?)
201COPYSIZ DW 1 DUP (?)
202OLDLEN DW 1 DUP (?)
203NEWLEN DW 1 DUP (?)
204LSTFND DW 1 DUP (?)
205LSTNUM DW 1 DUP (?)
206NUMPOS DW 1 DUP (?)
207SRCHCNT DW 1 DUP (?)
208CURRENT DW 1 DUP (?)
209POINTER DW 1 DUP (?)
210ONE4TH DW 1 DUP (?)
211THREE4TH DW 1 DUP (?)
212LAST DW 1 DUP (?)
213ENDTXT DW 1 DUP (?)
214COMLINE DW 1 DUP (?)
215LASTLIN DW 1 DUP (?)
216COMBUF DB 82H DUP (?)
217EDITBUF DB 258 DUP (?)
218EOL DB 1 DUP (?)
219FCB2 DB 37 DUP (?)
220FCB3 DB 37 DUP (?)
221fake_fcb db 37 dup (?) ;fake for size figuring
222QFLG DB 1 DUP (?)
223HAVEOF DB 1 DUP (?)
224ENDING DB 1 DUP (?)
225SRCHFLG DB 1 DUP (?)
226amnt_req dw 1 dup (?) ;ammount of bytes requested to read
227olddat db 1 dup (?) ;Used in replace and search,
228 ; replace by old data flag (1=yes)
229srchmod db 1 dup (?) ;Search mode: 1=from current+1 to
230 ; end of buffer, 0=from beg. of
231 ; buffer to the end (old way).
232MOVFLG DB 1 DUP (?)
233 DB STKSIZ DUP (?)
234
235STACK LABEL BYTE
236START LABEL WORD
237
238DATA ENDS
239
240SUBTTL Main Body
241PAGE
242
243CODE SEGMENT PUBLIC
244
245ASSUME CS:DG,DS:DG,SS:DG,ES:DG
246
247 EXTRN QUIT:NEAR,QUERY:NEAR,FNDFIRST:NEAR,FNDNEXT:NEAR
248 EXTRN UNQUOTE:NEAR,LF:NEAR,CRLF:NEAR,OUT:NEAR
249 EXTRN REST_DIR:NEAR,KILL_BL:NEAR,INT_24:NEAR
250 EXTRN FINDLIN:NEAR,SHOWNUM:NEAR,SCANLN:NEAR
251
252 if Kanji
253 EXTRN TESTKANJ:NEAR
254 endif
255
256 PUBLIC CHKRANGE
257
258 ORG 100H
259
260EDLIN:
261 JMP SIMPED
262
263edl_pad db 0e00h dup (?)
264
265HEADER DB "Vers 2.14"
266
267NONAME:
268 MOV DX,OFFSET DG:NDNAME
269ERRJ: JMP xERROR
270
271SIMPED:
272 MOV BYTE PTR [ENDING],0
273 MOV SP,OFFSET DG:STACK
274
275;Code to print header
276; PUSH AX
277; MOV DX,OFFSET DG:HEADER
278; MOV AH,STD_CON_STRING_OUTPUT
279; INT 21H
280; POP AX
281
282;----- Check Version Number --------------------------------------------;
283 push ax
284 mov ah,Get_Version
285 int 21h
286 cmp al,2
287 jae vers_ok ; version >= 2, enter editor
288 mov dx,offset dg:bad_vers_err
289 jmp short errj
290;-----------------------------------------------------------------------;
291
292vers_ok:
293
294;----- Process Pathnames -----------------------------------------------;
295
296 mov ax,(char_oper shl 8) ;get switch character
297 int 21h
298 cmp dl,"/"
299 jnz slashok ;if not / , then not PC
300 mov [dirchar],"\" ;in PC, dir separator = \
301 mov [userdir],"\"
302 mov [optchar],"/" ;in PC, option char = /
303
304slashok:
305 mov si,81h ;point to cammand line
306
307 call kill_bl
308 cmp al,13 ;A carriage return?
309 je noname ;yes, file name missing
310
311 mov di,offset dg:fname_buffer
312 xor cx,cx ;zero pathname length
313
314next_char:
315 stosb ;put patname in buffer
316 inc cx
317 lodsb
318 cmp al,' '
319 je xx1
320 cmp al,13 ; a CR ?
321 je name_copied
322 cmp al,[optchar] ; an option character?
323 je an_option
324 jmp short next_char
325
326xx1:
327 dec si
328 call kill_bl
329 cmp al,[optchar]
330 jne name_copied
331
332an_option:
333 lodsb ;get the option
334 cmp al,'B'
335 je b_opt
336 cmp al,'b'
337 je b_opt
338 mov dx,offset dg:opt_err ;bad option specified
339 jmp xerror
340
341b_opt:
342 mov [loadmod],1
343
344name_copied:
345 mov byte ptr dg:[di],0 ;nul terminate the pathname
346
347 if roprot ;***** R/O *****
348;----- Check that file is not R/O --------------------------------------;
349 push cx ;save character count
350 mov dx,offset dg:fname_buffer
351 mov al,0 ;get attributes
352 mov ah,chmod
353 int 21h
354 jc attr_are_ok
355 and cl,00000001b ;mask all but: r/o
356 jz attr_are_ok ;if all = 0 then file ok to edit,
357 mov dg:[roflag],01h ;otherwise: Error (GONG!!!)
358attr_are_ok:
359 pop cx ;restore character count
360 endif
361
362;----- Scan for directory ----------------------------------------------;
363 dec di ;adjust to the end of the pathname
364
365 IF KANJI
366 mov dx,offset dg: fname_buffer
367 PUSH DX
368 PUSH DI
369 MOV BX,DI
370 MOV DI,DX
371DELLOOP:
372 CMP DI,BX
373 Jae GOTDELE
374 MOV AL,[DI]
375 INC DI
376 CALL TESTKANJ
377 JZ NOTKANJ11
378 INC DI
379 JMP DELLOOP
380
381NOTKANJ11:
382 cmp al,dg:[dirchar]
383 JNZ DELLOOP
384 MOV DX,DI ;Point to char after '/'
385 DEC DX
386 DEC DX ;Point to char before '/'
387 JMP DELLOOP
388
389GOTDELE:
390 MOV DI,DX
391 POP AX ;Initial DI
392 POP DX
393 SUB AX,DI ;Distance moved
394 SUB CX,AX ;Set correct CX
395 CMP DX,DI
396 JB sj1 ;Found a pathsep
397 JA sj2 ;Started with a pathsep, root
398 MOV AX,[DI]
399 CALL TESTKANJ
400 JNZ same_dirj
401 XCHG AH,AL
402 cmp al,dg:[dirchar]
403 jz sj1 ;One character directory
404same_dirj:
405 ELSE
406 mov al,dg:[dirchar] ;get directory separator character
407 std ;scan backwards
408 repnz scasb ;(cx has the pathname length)
409 cld ;reset direction, just in case
410 jz sj1
411 ENDIF
412
413 jmp same_dir ;no dir separator char. found, the
414 ; file is in the current directory
415 ; of the corresponding drive. Ergo,
416 ; the FCB contains the data already.
417
418sj1:
419 jcxz sj2 ;no more chars left, it refers to root
420 cmp byte ptr [di],':' ;is the prvious character a disk def?
421 jne not_root
422sj2:
423 mov dg:[the_root],01h ;file is in the root
424not_root:
425 inc di ;point to dir separator char.
426 mov al,0
427 stosb ;nul terminate directory name
428 pop ax
429 push di ;save pointer to file name
430 mov dg:[fudge],01h ;remember that the current directory
431 ; has been changed.
432
433;----- Save current directory for exit ---------------------------------;
434 mov ah,get_default_drive ;save current drive
435 int 21h
436 mov dg:[user_drive],al
437
438 mov dl,byte ptr ds:[fcb] ;get specified drive if any
439 or dl,dl ;default disk?
440 jz same_drive
441 dec dl ;adjust to real drive (a=0,b=1,...)
442 mov ah,set_default_drive ;change disks
443 int 21h
444 cmp al,-1 ;error?
445 jne same_drive
446 mov dx,offset dg:baddrv
447 jmp xerror
448
449same_drive:
450 mov ah,get_default_dpb
451 int 21h
452
453assume ds:nothing
454
455 cmp al,-1 ;bad drive? (should always be ok)
456 jne drvisok
457 mov dx,offset dg:baddrv
458 jmp xerror
459
460drvisok:
461 cmp [bx.dpb_current_dir],0
462 je curr_is_root
463 mov si,bx
464 add si,dpb_dir_text
465 mov di,offset dg:userdir + 1
466
467dir_save_loop:
468 lodsb
469 stosb
470 or al,al
471 jnz dir_save_loop
472
473curr_is_root:
474 push cs
475 pop ds
476
477assume ds:dg
478
479
480;----- Change directories ----------------------------------------------;
481 cmp [the_root],01h
482 mov dx,offset dg:[dirchar] ;assume the root
483 je sj3
484 mov dx,offset dg:[fname_buffer]
485sj3:
486 mov ah,chdir ;change directory
487 int 21h
488 mov dx,offset dg:baddrv
489 jnc no_errors
490 jmp xerror
491no_errors:
492
493;----- Set Up int 24 intercept -----------------------------------------;
494
495 mov ax,(get_interrupt_vector shl 8) or 24h
496 int 21h
497 mov word ptr [hardch],bx
498 mov word ptr [hardch+2],es
499 mov ax,(set_interrupt_vector shl 8) or 24h
500 mov dx,offset dg:int_24
501 int 21h
502 push cs
503 pop es
504
505;----- Parse filename to FCB -------------------------------------------;
506 pop si
507 mov di,fcb
508 mov ax,(parse_file_descriptor shl 8) or 1
509 int 21h
510 push ax
511
512;-----------------------------------------------------------------------;
513
514same_dir:
515 pop ax
516 OR AL,AL
517 MOV DX,OFFSET DG:BADDRV
518 jz sj4
519 jmp xerror
520sj4:
521 CMP BYTE PTR DS:[FCB+1]," "
522 jnz sj5
523 jmp noname
524sj5:
525 MOV SI,OFFSET DG:BAK
526 MOV DI,FCB+9
527 MOV CX,3
528 ;File must not have .BAK extension
529 REPE CMPSB
530 JZ NOTBAK
531 ;Open input file
532 MOV AH,FCB_OPEN
533 MOV DX,FCB
534 INT 21H
535 MOV [HAVEOF],AL
536 OR AL,AL
537 JZ HAVFIL
538
539;----- Check that file is not a directory ------------
540 mov ah,fcb_create
541 mov dx,fcb
542 int 21h
543 or al,al
544 jz sj50 ;no error found
545 mov dx,offset dg:bcreat ;creation error
546 jmp xerror
547sj50:
548 mov ah,fcb_close ;no error, close the file
549 mov dx,fcb
550 int 21h
551 mov ah,fcb_delete ;delete the file
552 mov dx,fcb
553 int 21h
554
555;-----------------------------------------------------
556
557 MOV DX,OFFSET DG:NEWFIL
558 MOV AH,STD_CON_STRING_OUTPUT
559 INT 21H
560HAVFIL:
561 MOV SI,FCB
562 MOV DI,OFFSET DG:FCB2
563 MOV CX,9
564 REP MOVSB
565 MOV AL,"$"
566 STOSB
567 STOSB
568 STOSB
569MAKFIL:
570 ;Create .$$$ file to make sure directory has room
571 MOV DX,OFFSET DG:FCB2
572 MOV AH,FCB_CREATE
573 INT 21H
574 OR AL,AL
575 JZ SETUP
576 CMP BYTE PTR [DELFLG],0
577 JNZ NOROOM
578 CALL DELBAK
579 JMP MAKFIL
580NOROOM:
581 MOV DX,OFFSET DG:NODIR
582 JMP xERROR
583NOTBAK:
584 MOV DX,OFFSET DG:NOBAK
585 JMP xERROR
586SETUP:
587 XOR AX,AX
588 MOV WORD PTR DS:[FCB+fcb_RR],AX ;Set RR field to zero
589 MOV WORD PTR DS:[FCB+fcb_RR+2],AX
590 MOV WORD PTR [FCB2+fcb_RR],AX
591 MOV WORD PTR [FCB2+fcb_RR+2],AX
592 INC AX
593 MOV WORD PTR DS:[FCB+fcb_RECSIZ],AX ;Set record length to 1
594 MOV WORD PTR [FCB2+fcb_RECSIZ],AX
595 MOV DX,OFFSET DG:START
596 MOV DI,DX
597 MOV AH,SET_DMA
598 INT 21H
599 MOV CX,DS:[6]
600 DEC CX
601 MOV [LAST],CX
602 TEST BYTE PTR [HAVEOF],-1
603 JNZ SAVEND
604 SUB CX,OFFSET DG:START ;Available memory
605 SHR CX,1 ;1/2 of available memory
606 MOV AX,CX
607 SHR CX,1 ;1/4 of available memory
608 MOV [ONE4TH],CX ;Save amount of 1/4 full
609 ADD CX,AX ;3/4 of available memory
610 MOV DX,CX
611 ADD DX,OFFSET DG:START
612 MOV [THREE4TH],DX ;Save pointer to 3/4 full
613 ;Read in input file
614 MOV DX,FCB
615 MOV AH,FCB_RANDOM_READ_BLOCK
616 mov [amnt_req],cx ;save ammount of chars requested
617 INT 21H
618 CALL SCANEOF
619 ADD DI,CX ;Point to last byte
620SAVEND:
621 CLD
622 MOV BYTE PTR [DI],1AH
623 MOV [ENDTXT],DI
624 MOV BYTE PTR [COMBUF],128
625 MOV BYTE PTR [EDITBUF],255
626 MOV BYTE PTR [EOL],10
627 MOV [POINTER],OFFSET DG:START
628 MOV [CURRENT],1
629 MOV [PARAM1],1
630 TEST BYTE PTR [HAVEOF],-1
631 JNZ COMMAND
632 CALL APPEND
633
634COMMAND:
635 MOV SP, OFFSET DG:STACK
636 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
637 MOV DX,OFFSET DG:ABORTCOM
638 INT 21H
639 MOV AL,PROMPT
640 CALL OUT
641 MOV DX,OFFSET DG:COMBUF
642 MOV AH,STD_CON_STRING_INPUT
643 INT 21H
644 MOV [COMLINE],OFFSET DG:COMBUF + 2
645 MOV AL,10
646 CALL OUT
647PARSE:
648 MOV [PARAM2],0
649 MOV [PARAM3],0
650 MOV [PARAM4],0
651 mov [fourth],0 ;reset the fourth parameter flag
652 MOV BYTE PTR [QFLG],0
653 MOV SI,[COMLINE]
654 MOV BP,OFFSET DG:PARAM1
655 XOR DI,DI
656CHKLP:
657 CALL GETNUM
658 MOV [BP+DI],DX
659 INC DI
660 INC DI
661 CALL SKIP1
662 CMP AL,","
663 JNZ CHKNXT
664 INC SI
665CHKNXT:
666 DEC SI
667 CMP DI,8
668 JB CHKLP
669 CALL SKIP
670 CMP AL,"?"
671 JNZ DISPATCH
672 MOV [QFLG],AL
673 CALL SKIP
674DISPATCH:
675 CMP AL,5FH
676 JBE UPCASE
677 AND AL,5FH
678UPCASE:
679 MOV DI,OFFSET DG:COMTAB
680 MOV CX,NUMCOM
681 REPNE SCASB
682 JNZ COMERR
683 MOV BX,CX
684 MOV AX,[PARAM2]
685 OR AX,AX
686 JZ PARMOK
687 CMP AX,[PARAM1]
688 JB COMERR ;Param. 2 must be >= param 1
689PARMOK:
690 MOV [COMLINE],SI
691
692 if roprot ;***** R/O *****
693 cmp [roflag],01 ;file r/o?
694 jne paramok2
695 cmp byte ptr [bx+rotable],01 ;operation allowed?
696 je paramok2
697 mov dx,offset dg:ro_err ;error
698 jmp short comerr1
699paramok2:
700 endif
701
702 SHL BX,1
703 CALL [BX+TABLE]
704COMOVER:
705 MOV SI,[COMLINE]
706 CALL SKIP
707 CMP AL,0DH
708 JZ COMMANDJ
709 CMP AL,1AH
710 JZ DELIM
711 CMP AL,";"
712 JNZ NODELIM
713DELIM:
714 INC SI
715NODELIM:
716 DEC SI
717 MOV [COMLINE],SI
718 JMP PARSE
719
720COMMANDJ:
721 JMP COMMAND
722
723SKIP:
724 LODSB
725SKIP1:
726 CMP AL," "
727 JZ SKIP
728RET1: RET
729
730CHKRANGE:
731 CMP [PARAM2],0
732 JZ RET1
733 CMP BX,[PARAM2]
734 JBE RET1
735COMERR:
736 MOV DX,OFFSET DG:BADCOM
737COMERR1:
738 MOV AH,STD_CON_STRING_OUTPUT
739 INT 21H
740 JMP COMMAND
741
742
743GETNUM:
744 CALL SKIP
745 cmp di,6 ;Is this the fourth parameter?
746 jne sk1
747 mov [fourth],1 ;yes, set the flag
748sk1:
749 CMP AL,"."
750 JZ CURLIN
751 CMP AL,"#"
752 JZ MAXLIN
753 CMP AL,"+"
754 JZ FORLIN
755 CMP AL,"-"
756 JZ BACKLIN
757 MOV DX,0
758 MOV CL,0 ;Flag no parameter seen yet
759NUMLP:
760 CMP AL,"0"
761 JB NUMCHK
762 CMP AL,"9"
763 JA NUMCHK
764 CMP DX,6553 ;Max line/10
765 JAE COMERR ;Ten times this is too big
766 MOV CL,1 ;Parameter digit has been found
767 SUB AL,"0"
768 MOV BX,DX
769 SHL DX,1
770 SHL DX,1
771 ADD DX,BX
772 SHL DX,1
773 CBW
774 ADD DX,AX
775 LODSB
776 JMP SHORT NUMLP
777NUMCHK:
778 CMP CL,0
779 JZ RET1
780 OR DX,DX
781 JZ COMERR ;Don't allow zero as a parameter
782 RET
783
784CURLIN:
785 cmp [fourth],1 ;the fourth parameter?
786 je comerra ;yes, an error
787 MOV DX,[CURRENT]
788 LODSB
789 RET
790MAXLIN:
791 cmp [fourth],1 ;the fourth parameter?
792 je comerra ;yes, an error
793 MOV DX,-2
794 LODSB
795 RET
796FORLIN:
797 cmp [fourth],1 ;the fourth parameter?
798 je comerra ;yes, an error
799 CALL GETNUM
800 ADD DX,[CURRENT]
801 RET
802BACKLIN:
803 cmp [fourth],1 ;the fourth parameter?
804 je comerra ;yes, an error
805 CALL GETNUM
806 MOV BX,[CURRENT]
807 SUB BX,DX
808 jns sk2 ;if below beg of buffer then default to the
809 mov bx,1 ; beg of buffer (line1)
810sk2:
811 MOV DX,BX
812 RET
813
814comerra:
815 jmp comerr
816
817
818COMTAB DB "QTCMWASRDLPIE;",13
819
820NUMCOM EQU $-COMTAB
821
822;-----------------------------------------------------------------------;
823; Carefull changing the order of the next two tables. They are
824; linked and chnges should be be to both.
825
826TABLE DW NOCOM ;No command--edit line
827 DW NOCOM
828 DW ENDED
829 DW INSERT
830 DW PAGE
831 DW LIST
832 DW DELETE
833 dw replac_from_curr ;replace from current+1 line
834 dw search_from_curr ;search from current+1 line
835 DW APPEND
836 DW EWRITE
837 DW MOVE
838 DW COPY
839 DW MERGE
840
841 if roprot ;***** R/O *****
842 DW QUIT1
843 else
844 DW QUIT
845 endif
846
847 if roprot ;***** R/O *****
848;-----------------------------------------------------------------------;
849; If = 1 then the command can be executed with a file that
850; is r/o. If = 0 the command can not be executed, and error.
851
852ROTABLE db 0 ;NOCOM
853 db 0 ;NOCOM
854 db 0 ;ENDED
855 db 0 ;INSERT
856 db 1 ;PAGE
857 db 1 ;LIST
858 db 0 ;DELETE
859 db 0 ;replac_from_curr
860 db 1 ;search_from_curr
861 db 1 ;APPEND
862 db 1 ;EWRITE
863 db 0 ;MOVE
864 db 0 ;COPY
865 db 0 ;MERGE
866 db 1 ;QUIT
867
868;-----------------------------------------------------------------------;
869 endif
870
871 if roprot ;***** R/O *****
872quit1:
873 cmp [roflag],01 ;are we in r/o mode?
874 jne q3 ;no query....
875 MOV DX,OFFSET DG:FCB2 ;yes, quit without query.
876 MOV AH,FCB_CLOSE
877 INT 21H
878 MOV AH,FCB_DELETE
879 INT 21H
880 call rest_dir ;restore directory if needed
881 INT 20H
882q3:
883 call quit
884 endif
885
886SCANEOF:
887 cmp [loadmod],0
888 je sj52
889
890;----- Load till physical end of file
891 cmp cx,word ptr[amnt_req]
892 jb sj51
893 xor al,al
894 inc al ;reset zero flag
895 ret
896sj51:
897 jcxz sj51b
898 push di ;get rid of any ^Z at the end of the file
899 add di,cx
900 dec di ;points to last char
901 cmp byte ptr [di],1ah
902 pop di
903 jne sj51b
904 dec cx
905sj51b:
906 xor al,al ;set zero flag
907 call check_end ;check that we have a CRLF pair at the end
908 ret
909
910;----- Load till first ^Z is found
911sj52:
912 PUSH DI
913 PUSH CX
914 MOV AL,1AH
915 or cx,cx
916 jz not_found ;skip with zero flag set
917 REPNE SCASB ;Scan for end of file mark
918 jnz not_found
919 LAHF ;Save flags momentarily
920 inc cx ;include the ^Z
921 SAHF ;Restore flags
922not_found:
923 mov di,cx ;not found at the end
924 POP CX
925 LAHF ;Save flags momentarily
926 SUB CX,DI ;Reduce byte count if EOF found
927 SAHF ;Restore flags
928 POP DI
929 call check_end ;check that we have a CRLF pair at the end
930
931RET2: RET
932
933
934;-----------------------------------------------------------------------
935; If the end of file was found, then check that the last character
936; in the file is a LF. If not put a CRLF pair in.
937
938check_end:
939 jnz not_end ;end was not reached
940 pushf ;save return flag
941 push di ;save pointer to buffer
942 add di,cx ;points to one past end on text
943 dec di ;points to last character
944 cmp di,offset dg:start
945 je check_no
946 cmp byte ptr[di],0ah ;is a LF the last character?
947 je check_done ;yes, exit
948check_no:
949 mov byte ptr[di+1],0dh ;no, put a CR
950 inc cx ;one more char in text
951 mov byte ptr[di+2],0ah ;put a LF
952 inc cx ;another character at the end
953check_done:
954 pop di
955 popf
956not_end:
957 ret
958
959
960
961NOMOREJ:JMP NOMORE
962
963APPEND:
964 TEST BYTE PTR [HAVEOF],-1
965 JNZ NOMOREJ
966 MOV DX,[ENDTXT]
967 CMP [PARAM1],0 ;See if parameter is missing
968 JNZ PARMAPP
969 CMP DX,[THREE4TH] ;See if already 3/4ths full
970 JAE RET2 ;If so, then done already
971PARMAPP:
972 MOV DI,DX
973 MOV AH,SET_DMA
974 INT 21H
975 MOV CX,[LAST]
976 SUB CX,DX ;Amount of memory available
977 jnz sj53
978 jmp memerr
979sj53:
980 MOV DX,FCB
981 mov [amnt_req],cx ;save ammount of chars requested
982 MOV AH,FCB_RANDOM_READ_BLOCK
983 INT 21H ;Fill memory with file data
984 MOV [HAVEOF],AL
985 PUSH CX ;Save actual byte count
986 CALL SCANEOF
987 JNZ NOTEND
988 MOV BYTE PTR [HAVEOF],1 ;Set flag if 1AH found in file
989NOTEND:
990 XOR DX,DX
991 MOV BX,[PARAM1]
992 OR BX,BX
993 JNZ COUNTLN
994 MOV AX,DI
995 ADD AX,CX ;First byte after loaded text
996 CMP AX,[THREE4TH] ;See if we made 3/4 full
997 JBE COUNTLN
998 MOV DI,[THREE4TH]
999 MOV CX,AX
1000 SUB CX,DI ;Length remaining over 3/4
1001 MOV BX,1 ;Look for one more line
1002COUNTLN:
1003 CALL SCANLN ;Look for BX lines
1004 CMP [DI-1],AL ;Check for full line
1005 JZ FULLN
1006 STD
1007 DEC DI
1008 MOV CX,[LAST]
1009 REPNE SCASB ;Scan backwards for last line
1010 INC DI
1011 INC DI
1012 DEC DX
1013 CLD
1014FULLN:
1015 POP CX ;Actual amount read
1016 MOV WORD PTR [DI],1AH ;Place EOF after last line
1017 SUB CX,DI
1018 XCHG DI,[ENDTXT]
1019 ADD DI,CX ;Amount of file read but not used
1020 SUB WORD PTR DS:[FCB+fcb_RR],DI ;Adjust RR field in case end of file
1021 SBB WORD PTR DS:[FCB+fcb_RR+2],0 ; was not reached
1022 CMP BX,DX
1023 JNZ EOFCHK
1024 MOV BYTE PTR [HAVEOF],0
1025 RET
1026NOMORE:
1027 MOV DX,OFFSET DG:EOF
1028 MOV AH,STD_CON_STRING_OUTPUT
1029 INT 21H
1030RET3: RET
1031EOFCHK:
1032 TEST BYTE PTR [HAVEOF],-1
1033 JNZ NOMORE
1034 TEST BYTE PTR [ENDING],-1
1035 JNZ RET3 ;Suppress memory error during End
1036 JMP MEMERR
1037
1038EWRITE:
1039 MOV BX,[PARAM1]
1040 OR BX,BX
1041 JNZ WRT
1042 MOV CX,[ONE4TH]
1043 MOV DI,[ENDTXT]
1044 SUB DI,CX ;Write everything in front of here
1045 JBE RET3
1046 CMP DI,OFFSET DG:START ;See if there's anything to write
1047 JBE RET3
1048 XOR DX,DX
1049 MOV BX,1 ;Look for one more line
1050 CALL SCANLN
1051 JMP SHORT WRTADD
1052WRT:
1053 INC BX
1054 CALL FINDLIN
1055WRTADD:
1056 CMP BYTE PTR [DELFLG],0
1057 JNZ WRTADD1
1058 PUSH DI
1059 CALL DELBAK ;Want to delete the .BAK file
1060 ;as soon as the first write occurs
1061 POP DI
1062WRTADD1:
1063 MOV CX,DI
1064 MOV DX,OFFSET DG:START
1065 SUB CX,DX ;Amount to write
1066 JZ RET3
1067 MOV AH,SET_DMA
1068 INT 21H
1069 MOV DX,OFFSET DG:FCB2
1070 MOV AH,FCB_RANDOM_WRITE_BLOCK
1071 INT 21H
1072 OR AL,AL
1073 JNZ WRTERR
1074 MOV SI,DI
1075 MOV DI,OFFSET DG:START
1076 MOV [POINTER],DI
1077 MOV CX,[ENDTXT]
1078 SUB CX,SI
1079 INC CX ;Amount of text remaining
1080 REP MOVSB
1081 DEC DI ;Point to EOF
1082 MOV [ENDTXT],DI
1083 MOV [CURRENT],1
1084 RET
1085
1086WRTERR:
1087 MOV AH,FCB_CLOSE
1088 INT 21H
1089 MOV DX,OFFSET DG:DSKFUL
1090xERROR:
1091 MOV AH,STD_CON_STRING_OUTPUT
1092 INT 21H
1093;-----------------------------------------------------------------------
1094 call rest_dir ;restore to the proper directory
1095;-----------------------------------------------------------------------
1096 INT 32
1097
1098RET$5: RET
1099
1100PAGE:
1101 xor bx,bx ;get last line in the buffer
1102 call findlin
1103 mov [lastlin],dx
1104
1105 mov bx,[param1]
1106 or bx,bx ;was it specified?
1107 jnz frstok ;yes, use it
1108 mov bx,[current]
1109 cmp bx,1 ;if current line =1 start from there
1110 je frstok
1111 inc bx ;start from current+1 line
1112frstok:
1113 cmp bx,[lastlin] ;check that we are in the buffer
1114 ja ret$5 ;if not just quit
1115infile:
1116 mov dx,[param2]
1117 or dx,dx ;was param2 specified?
1118 jnz scndok ;yes,....
1119 mov dx,bx ;no, take the end line to be the
1120 add dx,22 ; start line + 23
1121scndok:
1122 inc dx
1123 cmp dx,[lastlin] ;check that we are in the buffer
1124 jbe infile2
1125 mov dx,[lastlin] ;we are not, take the last line as end
1126infile2:
1127 cmp dx,bx ;is param1 < param2 ?
1128 jbe ret$5 ;yes, no backwards listing, quit
1129 push dx ;save the end line
1130 push bx ;save start line
1131 mov bx,dx ;set the current line
1132 dec bx
1133 call findlin
1134 mov [pointer],di
1135 mov [current],dx
1136 pop bx ;restore start line
1137 call findlin ;get pointer to start line
1138 mov si,di ;save pointer
1139 pop di ;get end line
1140 sub di,bx ;number of lines
1141 jmp short display
1142
1143
1144LIST:
1145 MOV BX,[PARAM1]
1146 OR BX,BX
1147 JNZ CHKP2
1148 MOV BX,[CURRENT]
1149 SUB BX,11
1150 JA CHKP2
1151 MOV BX,1
1152CHKP2:
1153 CALL FINDLIN
1154 JNZ RET7
1155 MOV SI,DI
1156 MOV DI,[PARAM2]
1157 INC DI
1158 SUB DI,BX
1159 JA DISPLAY
1160 MOV DI,23
1161 JMP SHORT DISPLAY
1162
1163
1164DISPONE:
1165 MOV DI,1
1166
1167DISPLAY:
1168
1169; Inputs:
1170; BX = Line number
1171; SI = Pointer to text buffer
1172; DI = No. of lines
1173; Function:
1174; Ouputs specified no. of line to terminal, each
1175; with leading line number.
1176; Outputs:
1177; BX = Last line output.
1178; All registers destroyed.
1179
1180 MOV CX,[ENDTXT]
1181 SUB CX,SI
1182 JZ RET7
1183 MOV BP,[CURRENT]
1184DISPLN:
1185 PUSH CX
1186 CALL SHOWNUM
1187 POP CX
1188OUTLN:
1189 LODSB
1190 CMP AL," "
1191 JAE SEND
1192 CMP AL,10
1193 JZ SEND
1194 CMP AL,13
1195 JZ SEND
1196 CMP AL,9
1197 JZ SEND
1198 PUSH AX
1199 MOV AL,"^"
1200 CALL OUT
1201 POP AX
1202 OR AL,40H
1203SEND:
1204 CALL OUT
1205 CMP AL,10
1206 LOOPNZ OUTLN
1207 JCXZ RET7
1208 INC BX
1209 DEC DI
1210 JNZ DISPLN
1211 DEC BX
1212RET7: RET
1213
1214LOADBUF:
1215 MOV DI,2 + OFFSET DG:EDITBUF
1216 MOV CX,255
1217 MOV DX,-1
1218LOADLP:
1219 LODSB
1220 STOSB
1221 INC DX
1222 CMP AL,13
1223 LOOPNZ LOADLP
1224 MOV [EDITBUF+1],DL
1225 JZ RET7
1226TRUNCLP:
1227 LODSB
1228 INC DX
1229 CMP AL,13
1230 JNZ TRUNCLP
1231 DEC DI
1232 STOSB
1233 RET
1234
1235NOTFNDJ:JMP NOTFND
1236
1237replac_from_curr:
1238 mov byte ptr [srchmod],1 ;search from curr+1 line
1239 jmp short sj6
1240
1241REPLAC:
1242 mov byte ptr [srchmod],0 ;search from beg of buffer
1243sj6:
1244 MOV BYTE PTR [SRCHFLG],0
1245 CALL FNDFIRST
1246 JNZ NOTFNDJ
1247REPLP:
1248 MOV SI,[NUMPOS]
1249 CALL LOADBUF ;Count length of line
1250 SUB DX,[OLDLEN]
1251 MOV CX,[NEWLEN]
1252 ADD DX,CX ;Length of new line
1253 CMP DX,254
1254 JA TOOLONG
1255 MOV BX,[LSTNUM]
1256 PUSH DX
1257 CALL SHOWNUM
1258 POP DX
1259 MOV CX,[LSTFND]
1260 MOV SI,[NUMPOS]
1261 SUB CX,SI ;Get no. of char on line before change
1262 DEC CX
1263 CALL OUTCNT ;Output first part of line
1264 PUSH SI
1265 MOV SI,1+ OFFSET DG:TXT2
1266 MOV CX,[NEWLEN]
1267 CALL OUTCNT ;Output change
1268 POP SI
1269 ADD SI,[OLDLEN] ;Skip over old stuff in line
1270 MOV CX,DX ;DX=no. of char left in line
1271 ADD CX,2 ;Include CR/LF
1272 CALL OUTCNT ;Output last part of line
1273 CALL QUERY ;Check if change OK
1274 JNZ REPNXT
1275 CALL PUTCURS
1276 MOV DI,[LSTFND]
1277 DEC DI
1278 MOV SI,1+ OFFSET DG:TXT2
1279 MOV DX,[OLDLEN]
1280 MOV CX,[NEWLEN]
1281 DEC CX
1282 ADD [LSTFND],CX ;Bump pointer beyond new text
1283 INC CX
1284 DEC DX
1285 SUB [SRCHCNT],DX ;Old text will not be searched
1286 JAE SOMELEFT
1287 MOV [SRCHCNT],0
1288SOMELEFT:
1289 INC DX
1290 CALL REPLACE
1291REPNXT:
1292 CALL FNDNEXT
1293 JNZ RET8
1294 JMP REPLP
1295
1296OUTCNT:
1297 JCXZ RET8
1298OUTLP:
1299 LODSB
1300 CALL OUT
1301 DEC DX
1302 LOOP OUTLP
1303RET8: RET
1304
1305TOOLONG:
1306 MOV DX,OFFSET DG:TOOLNG
1307 JMP SHORT PERR
1308
1309search_from_curr:
1310 mov byte ptr [srchmod],1 ;search from curr+1 line
1311 jmp short sj7
1312
1313SEARCH:
1314 mov byte ptr [srchmod],0 ;search from beg of buffer
1315sj7:
1316 MOV BYTE PTR [SRCHFLG],1
1317 CALL FNDFIRST
1318 JNZ NOTFND
1319SRCH:
1320 MOV BX,[LSTNUM]
1321 MOV SI,[NUMPOS]
1322 CALL DISPONE
1323 MOV DI,[LSTFND]
1324 MOV CX,[SRCHCNT]
1325 MOV AL,10
1326 REPNE SCASB
1327 JNZ NOTFND
1328 MOV [LSTFND],DI
1329 MOV [NUMPOS],DI
1330 MOV [SRCHCNT],CX
1331 INC [LSTNUM]
1332 CALL QUERY
1333 JZ PUTCURS
1334 CALL FNDNEXT
1335 JZ SRCH
1336NOTFND:
1337 MOV DX,OFFSET DG:NOSUCH
1338PERR:
1339 MOV AH,STD_CON_STRING_OUTPUT
1340 INT 21H
1341 RET
1342
1343PUTCURS:
1344 MOV BX,[LSTNUM]
1345 DEC BX ;Current <= Last matched line
1346 CALL FINDLIN
1347 MOV [CURRENT],DX
1348 MOV [POINTER],DI
1349RET9: RET
1350
1351DELETE:
1352 MOV BX,[PARAM1]
1353 OR BX,BX
1354 JNZ DELFIN1
1355 MOV BX,[CURRENT]
1356 CALL CHKRANGE
1357DELFIN1:
1358 CALL FINDLIN
1359 JNZ RET9
1360 PUSH BX
1361 PUSH DI
1362 MOV BX,[PARAM2]
1363 OR BX,BX
1364 JNZ DELFIN2
1365 MOV BX,DX
1366DELFIN2:
1367 INC BX
1368 CALL FINDLIN
1369 MOV DX,DI
1370 POP DI
1371 SUB DX,DI
1372 JBE COMERRJ
1373 POP [CURRENT]
1374 MOV [POINTER],DI
1375 XOR CX,CX
1376 JMP SHORT REPLACE
1377
1378COMERRJ:JMP COMERR
1379
1380
1381NOCOM:
1382 DEC [COMLINE]
1383 MOV BX,[PARAM1]
1384 OR BX,BX
1385 JNZ HAVLIN
1386 MOV BX,[CURRENT]
1387 INC BX ;Default is current line plus one
1388 CALL CHKRANGE
1389HAVLIN:
1390 CALL FINDLIN
1391 MOV SI,DI
1392 MOV [CURRENT],DX
1393 MOV [POINTER],SI
1394 jz sj12
1395 ret
1396sj12:
1397 CMP SI,[ENDTXT]
1398 JZ RET12
1399 CALL LOADBUF
1400 MOV [OLDLEN],DX
1401 MOV SI,[POINTER]
1402 CALL DISPONE
1403 CALL SHOWNUM
1404 MOV AH,STD_CON_STRING_INPUT ;Get input buffer
1405 MOV DX,OFFSET DG:EDITBUF
1406 INT 21H
1407 MOV AL,10
1408 CALL OUT
1409 MOV CL,[EDITBUF+1]
1410 MOV CH,0
1411 JCXZ RET12
1412 MOV DX,[OLDLEN]
1413 MOV SI,2 + OFFSET DG:EDITBUF
1414;-----------------------------------------------------------------------
1415 call unquote ;scan for quote chars if any
1416;-----------------------------------------------------------------------
1417 MOV DI,[POINTER]
1418
1419REPLACE:
1420
1421; Inputs:
1422; CX = Length of new text
1423; DX = Length of original text
1424; SI = Pointer to new text
1425; DI = Pointer to old text in buffer
1426; Function:
1427; New text replaces old text in buffer and buffer
1428; size is adjusted. CX or DX may be zero.
1429; CX, SI, DI all destroyed. No other registers affected.
1430
1431 CMP CX,DX
1432 JZ COPYIN
1433 PUSH SI
1434 PUSH DI
1435 PUSH CX
1436 MOV SI,DI
1437 ADD SI,DX
1438 ADD DI,CX
1439 MOV AX,[ENDTXT]
1440 SUB AX,DX
1441 ADD AX,CX
1442 CMP AX,[LAST]
1443 JAE MEMERR
1444 XCHG AX,[ENDTXT]
1445 MOV CX,AX
1446 SUB CX,SI
1447 CMP SI,DI
1448 JA DOMOV
1449 ADD SI,CX
1450 ADD DI,CX
1451 STD
1452DOMOV:
1453 INC CX
1454
1455 REP MOVSB
1456 CLD
1457 POP CX
1458 POP DI
1459 POP SI
1460COPYIN:
1461 REP MOVSB
1462RET12: RET
1463
1464MEMERR:
1465 MOV DX,OFFSET DG:MEMFUL
1466 MOV AH,STD_CON_STRING_OUTPUT
1467 INT 21H
1468 JMP COMMAND
1469
1470MOVERR:
1471 MOV DX,OFFSET DG:BADCOM
1472ERRORJ:
1473 JMP COMERR
1474
1475MOVE:
1476 MOV BYTE PTR [MOVFLG],1
1477 JMP SHORT BLKMOVE
1478COPY:
1479 MOV BYTE PTR [MOVFLG],0
1480
1481BLKMOVE:
1482 MOV BX,[PARAM3] ;Third parameter must be specified
1483 OR BX,BX
1484 MOV DX,OFFSET DG:DEST
1485 JZ ERRORJ
1486 MOV BX,[PARAM1] ;Get the first parameter
1487 OR BX,BX ;Not specified?
1488 JNZ NXTARG
1489 MOV BX,[CURRENT] ;Defaults to the current line
1490 CALL CHKRANGE
1491 MOV [PARAM1],BX ;Save it since current line may change
1492 NXTARG:
1493 CALL FINDLIN ;Get a pointer to the line
1494 MOV [PTR_1],DI ;Save it
1495 MOV BX,[PARAM2] ;Get the second parameter
1496 OR BX,BX ;Not specified?
1497 JNZ HAVARGS
1498 MOV BX,[CURRENT] ;Defaults to the current line
1499 MOV [PARAM2],BX ;Save it since current line may change
1500HAVARGS:
1501 ;Parameters must not overlap
1502 MOV DX,[PARAM3]
1503 CMP DX,[PARAM1]
1504 JBE NOERROR
1505 CMP DX,[PARAM2]
1506 JBE MOVERR
1507NOERROR:
1508 INC BX ;Get pointer to line Param2+1
1509 CALL FINDLIN
1510 MOV SI,DI
1511 MOV [PTR_2],SI ;Save it
1512 MOV CX,DI
1513 MOV DI,[PTR_1] ;Restore pointer to line Param1
1514 SUB CX,DI ;Calculate number of bytes to copy
1515 MOV [COPYSIZ],CX ;Save in COPYSIZ
1516 PUSH CX ;And on the stack
1517 MOV AX,[PARAM4] ;Is count specified?
1518 OR AX,AX
1519 JZ MEM_CHECK
1520 MUL [COPYSIZ]
1521 OR DX,DX
1522 JZ COPYSIZ_OK
1523 JMP MEMERR
1524COPYSIZ_OK:
1525 MOV CX,AX
1526 MOV [COPYSIZ],CX
1527MEM_CHECK:
1528 MOV AX,[ENDTXT]
1529 MOV DI,[LAST]
1530 SUB DI,AX
1531 CMP DI,CX
1532 JAE HAV_ROOM
1533 JMP MEMERR
1534HAV_ROOM:
1535 MOV BX,[PARAM3]
1536 PUSH BX
1537 CALL FINDLIN
1538 MOV [PTR_3],DI
1539 MOV CX,[ENDTXT]
1540 SUB CX,DI
1541 INC CX
1542 MOV SI,[ENDTXT]
1543 MOV DI,SI
1544 ADD DI,[COPYSIZ]
1545 MOV [ENDTXT],DI
1546 STD
1547 REP MOVSB
1548 CLD
1549 POP BX
1550 CMP BX,[PARAM1]
1551 JB GET_PTR_2
1552 MOV SI,[PTR_1]
1553 JMP SHORT COPY_TEXT
1554GET_PTR_2:
1555 MOV SI,[PTR_2]
1556COPY_TEXT:
1557 MOV BX,[PARAM4]
1558 MOV DI,[PTR_3]
1559 POP CX
1560 MOV [COPYSIZ],CX
1561COPY_TEXT_1:
1562 REP MOVSB
1563 DEC BX
1564 CMP BX,0
1565 JLE MOV_CHK
1566 MOV [PARAM4],BX
1567 SUB SI,[COPYSIZ]
1568 MOV CX,[COPYSIZ]
1569 JMP SHORT COPY_TEXT_1
1570MOV_CHK:
1571 CMP BYTE PTR[MOVFLG],0
1572 JZ COPY_DONE
1573 MOV DI,[PTR_1]
1574 MOV SI,[PTR_2]
1575 MOV BX,[PARAM3]
1576 CMP BX,[PARAM1]
1577 JAE DEL_TEXT
1578 ADD DI,[COPYSIZ]
1579 ADD SI,[COPYSIZ]
1580DEL_TEXT:
1581 MOV CX,[ENDTXT]
1582 SUB CX,SI
1583 REP MOVSB
1584 MOV [ENDTXT],DI
1585 MOV CX,[PARAM2]
1586 SUB CX,[PARAM1]
1587 MOV BX,[PARAM3]
1588 SUB BX,CX
1589 JNC MOVE_DONE
1590COPY_DONE:
1591 MOV BX,[PARAM3]
1592MOVE_DONE:
1593 CALL FINDLIN
1594 MOV [POINTER],DI
1595 MOV [CURRENT],BX
1596 RET
1597
1598
1599MOVEFILE:
1600 MOV CX,[ENDTXT] ;Get End-of-text marker
1601 MOV SI,CX
1602 SUB CX,DI ;Calculate number of bytes to copy
1603 INC CX
1604 MOV DI,DX
1605 STD
1606 REP MOVSB ;Copy CX bytes
1607 XCHG SI,DI
1608 CLD
1609 INC DI
1610 MOV BP,SI
1611SETPTS:
1612 MOV [POINTER],DI ;Current line is first free loc
1613 MOV [CURRENT],BX ; in the file
1614 MOV [ENDTXT],BP ;End-of-text is last free loc before
1615 RET
1616
1617NAMERR:
1618 JMP COMERR1
1619
1620
1621MERGE:
1622 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 1
1623 MOV DI,OFFSET DG:FCB3
1624 INT 21H
1625 OR AL,AL
1626 MOV DX,OFFSET DG:BADDRV
1627 JNZ NAMERR
1628 MOV [COMLINE],SI
1629 MOV DX,OFFSET DG:FCB3
1630 MOV AH,FCB_OPEN
1631 INT 21H
1632 OR AL,AL
1633 MOV DX,OFFSET DG:FILENM
1634 JNZ NAMERR
1635 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
1636 MOV DX,OFFSET DG:ABORTMERGE
1637 INT 21H
1638 MOV BX,[PARAM1]
1639 OR BX,BX
1640 JNZ MRG
1641 MOV BX,[CURRENT]
1642 CALL CHKRANGE
1643MRG:
1644 CALL FINDLIN
1645 MOV BX,DX
1646 MOV DX,[LAST]
1647 CALL MOVEFILE
1648 ;Set DMA address for reading in new file
1649 MOV DX,[POINTER]
1650 MOV AH,SET_DMA
1651 INT 21H
1652 XOR AX,AX
1653 MOV WORD PTR DS:[FCB3+fcb_RR],AX
1654 MOV WORD PTR DS:[FCB3+fcb_RR+2],AX
1655 INC AX
1656 MOV WORD PTR DS:[FCB3+fcb_RECSIZ],AX
1657 MOV DX,OFFSET DG:FCB3
1658 MOV CX,[ENDTXT]
1659 SUB CX,[POINTER]
1660 MOV AH,FCB_RANDOM_READ_BLOCK
1661 INT 21H
1662 CMP AL,1
1663 JZ FILEMRG
1664 MOV DX,OFFSET DG:MRGERR
1665 MOV AH,STD_CON_STRING_OUTPUT
1666 INT 21H
1667 MOV CX,[POINTER]
1668 JMP SHORT RESTORE
1669FILEMRG:
1670 ADD CX,[POINTER]
1671 MOV SI,CX
1672 DEC SI
1673 LODSB
1674 CMP AL,1AH
1675 JNZ RESTORE
1676 DEC CX
1677RESTORE:
1678 MOV DI,CX
1679 MOV SI,[ENDTXT]
1680 INC SI
1681 MOV CX,[LAST]
1682 SUB CX,SI
1683 REP MOVSB
1684 MOV [ENDTXT],DI
1685 MOV BYTE PTR [DI],1AH
1686 MOV DX,OFFSET DG:FCB3
1687 MOV AH,FCB_CLOSE
1688 INT 21H
1689 MOV DX,OFFSET DG:START
1690 MOV AH,SET_DMA
1691 INT 21H
1692 RET
1693
1694
1695INSERT:
1696 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H ;Set vector 23H
1697 MOV DX,OFFSET DG:ABORTINS
1698 INT 21H
1699 MOV BX,[PARAM1]
1700 OR BX,BX
1701 JNZ INS
1702 MOV BX,[CURRENT]
1703 CALL CHKRANGE
1704INS:
1705 CALL FINDLIN
1706 MOV BX,DX
1707 MOV DX,[LAST]
1708 CALL MOVEFILE
1709INLP:
1710 CALL SETPTS ;Update the pointers into file
1711 CALL SHOWNUM
1712 MOV DX,OFFSET DG:EDITBUF
1713 MOV AH,STD_CON_STRING_INPUT
1714 INT 21H
1715 CALL LF
1716 MOV SI,2 + OFFSET DG:EDITBUF
1717 CMP BYTE PTR [SI],1AH
1718 JZ ENDINS
1719;-----------------------------------------------------------------------
1720 call unquote ;scan for quote chars if any
1721;-----------------------------------------------------------------------
1722 MOV CL,[SI-1]
1723 MOV CH,0
1724 MOV DX,DI
1725 INC CX
1726 ADD DX,CX
1727 JC MEMERRJ1
1728 JZ MEMERRJ1
1729 CMP DX,BP
1730 JB MEMOK
1731MEMERRJ1:
1732 CALL END_INS
1733 JMP MEMERR
1734MEMOK:
1735 REP MOVSB
1736 MOV AL,10
1737 STOSB
1738 INC BX
1739 JMP SHORT INLP
1740
1741ABORTMERGE:
1742 MOV DX,OFFSET DG:START
1743 MOV AH,SET_DMA
1744 INT 21H
1745
1746ABORTINS:
1747 MOV AX,CS ;Restore segment registers
1748 MOV DS,AX
1749 MOV ES,AX
1750 MOV SS,AX
1751 MOV SP,OFFSET DG:STACK
1752 STI
1753 CALL CRLF
1754 CALL ENDINS
1755 JMP COMOVER
1756
1757ENDINS:
1758 CALL END_INS
1759 RET
1760
1761END_INS:
1762 MOV BP,[ENDTXT]
1763 MOV DI,[POINTER]
1764 MOV SI,BP
1765 INC SI
1766 MOV CX,[LAST]
1767 SUB CX,BP
1768 REP MOVSB
1769 DEC DI
1770 MOV [ENDTXT],DI
1771 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
1772 MOV DX,OFFSET DG:ABORTCOM
1773 INT 21H
1774 RET
1775
1776FILLBUF:
1777 MOV [PARAM1],-1 ;Read in max. no of lines
1778 CALL APPEND
1779ENDED:
1780;Write text out to .$$$ file
1781 MOV BYTE PTR [ENDING],1 ;Suppress memory errors
1782 MOV BX,-1 ;Write max. no of lines
1783 CALL WRT
1784 TEST BYTE PTR [HAVEOF],-1
1785 JZ FILLBUF
1786 MOV DX,[ENDTXT]
1787 MOV AH,SET_DMA
1788 INT 21H
1789 MOV CX,1
1790 MOV DX,OFFSET DG:FCB2
1791 MOV AH,FCB_RANDOM_WRITE_BLOCK
1792 INT 21H ;Write end-of-file byte
1793;Close .$$$ file
1794 MOV AH,FCB_CLOSE
1795 INT 21H
1796 MOV SI,FCB
1797 LEA DI,[SI+fcb_FILSIZ]
1798 MOV DX,SI
1799 MOV CX,9
1800 REP MOVSB
1801 MOV SI,OFFSET DG:BAK
1802 MOVSW
1803 MOVSB
1804;Rename original file .BAK
1805 MOV AH,FCB_RENAME
1806 INT 21H
1807 MOV SI,FCB
1808 MOV DI,OFFSET DG:FCB2 + fcb_FILSIZ
1809 MOV CX,6
1810 REP MOVSW
1811;Rename .$$$ file to original name
1812 MOV DX,OFFSET DG:FCB2
1813 INT 21H
1814 call rest_dir ;restore directory if needed
1815 INT 20H
1816
1817ABORTCOM:
1818 MOV AX,CS
1819 MOV DS,AX
1820 MOV ES,AX
1821 MOV SS,AX
1822 MOV SP,OFFSET DG:STACK
1823 STI
1824 CALL CRLF
1825 JMP COMMAND
1826
1827DELBAK:
1828 MOV BYTE PTR [DELFLG],1
1829 MOV DI,9+OFFSET DG:FCB2
1830 MOV SI,OFFSET DG:BAK
1831 MOVSW
1832 MOVSB
1833 ;Delete old backup file (.BAK)
1834 MOV AH,FCB_DELETE
1835 MOV DX,OFFSET DG:FCB2
1836 INT 21H
1837 MOV DI,9+OFFSET DG:FCB2
1838 MOV AL,"$"
1839 STOSB
1840 STOSB
1841 STOSB
1842 RET
1843
1844CODE ENDS
1845 END EDLIN
1846 \ No newline at end of file
diff --git a/v2.0/source/EDLMES.ASM b/v2.0/source/EDLMES.ASM
new file mode 100644
index 0000000..f49ed96
--- /dev/null
+++ b/v2.0/source/EDLMES.ASM
Binary files differ
diff --git a/v2.0/source/EDLPROC.ASM b/v2.0/source/EDLPROC.ASM
new file mode 100644
index 0000000..0128b1d
--- /dev/null
+++ b/v2.0/source/EDLPROC.ASM
@@ -0,0 +1,531 @@
1
2
3FALSE EQU 0
4TRUE EQU NOT FALSE
5
6KANJI EQU FALSE
7
8roprot equ FALSE ;set to TRUE if protection to r/o files
9 ; desired.
10FCB EQU 5CH
11
12Comand_Line_Length equ 128
13quote_char equ 16h ;quote character = ^V
14
15
16PAGE
17
18 .xlist
19 INCLUDE DOSSYM.ASM
20 .list
21
22
23SUBTTL Contants and Data areas
24PAGE
25
26PROMPT EQU "*"
27STKSIZ EQU 80H
28
29CODE SEGMENT PUBLIC
30CODE ENDS
31
32CONST SEGMENT PUBLIC WORD
33
34 EXTRN TXT1:BYTE,TXT2:BYTE,FUDGE:BYTE,HARDCH:DWORD,USERDIR:BYTE
35
36CONST ENDS
37
38DATA SEGMENT PUBLIC WORD
39
40 EXTRN OLDLEN:WORD,OLDDAT:BYTE,SRCHFLG:BYTE,COMLINE:WORD
41 EXTRN PARAM1:WORD,PARAM2:WORD,NEWLEN:WORD,SRCHMOD:BYTE
42 EXTRN CURRENT:WORD,POINTER:WORD,START:BYTE,ENDTXT:WORD
43 EXTRN USER_DRIVE:BYTE,LSTNUM:WORD,NUMPOS:WORD,LSTFND:WORD
44 EXTRN SRCHCNT:WORD
45
46DATA ENDS
47
48DG GROUP CODE,CONST,DATA
49
50CODE SEGMENT PUBLIC
51
52ASSUME CS:DG,DS:DG,SS:DG,ES:DG
53
54 PUBLIC REST_DIR,KILL_BL,INT_24,SCANLN,FINDLIN,SHOWNUM
55 PUBLIC FNDFIRST,FNDNEXT,CRLF,LF,OUT,UNQUOTE
56
57 if kanji
58 PUBLIC TESTKANJ
59 endif
60
61 EXTRN CHKRANGE:NEAR
62
63EDLPROC:
64
65RET1: RET
66
67FNDFIRST:
68 MOV DI,1+OFFSET DG:TXT1
69 mov byte ptr[olddat],1 ;replace with old value if none new
70 CALL GETTEXT
71 OR AL,AL ;Reset zero flag in case CX is zero
72 JCXZ RET1
73 cmp al,1ah ;terminated with a ^Z ?
74 jne sj8
75 mov byte ptr[olddat],0 ;do not replace with old value
76sj8:
77 MOV [OLDLEN],CX
78 XOR CX,CX
79 CMP AL,0DH
80 JZ SETBUF
81 CMP BYTE PTR [SRCHFLG],0
82 JZ NXTBUF
83SETBUF:
84 DEC SI
85NXTBUF:
86 MOV [COMLINE],SI
87 MOV DI,1+OFFSET DG:TXT2
88 CALL GETTEXT
89 CMP BYTE PTR [SRCHFLG],0
90 JNZ NOTREPL
91 CMP AL,0DH
92 JNZ HAVCHR
93 DEC SI
94HAVCHR:
95 MOV [COMLINE],SI
96NOTREPL:
97 MOV [NEWLEN],CX
98 MOV BX,[PARAM1]
99 OR BX,BX
100 JNZ CALLER
101 cmp byte ptr[srchmod],0
102 jne sj9
103 mov bx,1 ;start from line number 1
104 jmp short sj9a
105sj9:
106 MOV BX,[CURRENT]
107 INC BX ;Default search and replace to current+1
108sj9a:
109 CALL CHKRANGE
110CALLER:
111 CALL FINDLIN
112 MOV [LSTFND],DI
113 MOV [NUMPOS],DI
114 MOV [LSTNUM],DX
115 MOV BX,[PARAM2]
116 CMP BX,1
117 SBB BX,-1 ;Decrement everything except zero
118 CALL FINDLIN
119 MOV CX,DI
120 SUB CX,[LSTFND]
121 OR AL,-1
122 JCXZ aret
123 CMP CX,[OLDLEN]
124 jae sj10
125aret: ret
126sj10:
127 MOV [SRCHCNT],CX
128
129FNDNEXT:
130
131; Inputs:
132; [TXT1+1] has string to search for
133; [OLDLEN] has length of the string
134; [LSTFND] has starting position of search in text buffer
135; [LSTNUM] has line number which has [LSTFND]
136; [SRCHCNT] has length to be searched
137; [NUMPOS] has beginning of line which has [LSTFND]
138; Outputs:
139; Zero flag set if match found
140; [LSTFND],[LSTNUM],[SRCHCNT] updated for continuing the search
141; [NUMPOS] has beginning of line in which match was made
142
143 MOV AL,[TXT1+1]
144 MOV CX,[SRCHCNT]
145 MOV DI,[LSTFND]
146SCAN:
147 OR DI,DI ;Clear zero flag in case CX=0
148 REPNE SCASB
149 JNZ RET11
150 MOV DX,CX
151 MOV BX,DI ;Save search position
152 MOV CX,[OLDLEN]
153 DEC CX
154 MOV SI,2 + OFFSET DG:TXT1
155 CMP AL,AL ;Set zero flag in case CX=0
156if kanji
157 dec si ;Want to look at the first character again
158 dec di
159kanjchar:
160 lodsb
161 call testkanj
162 jz nxt_kj_char
163 xchg ah,al
164 lodsb
165 mov bx,[di]
166 add di,2
167 cmp ax,bx
168 jnz not_kj_match
169 dec cx
170 loop kanjchar
171nxt_kj_char:
172 cmp al,byte ptr[di]
173 jnz not_kj_match
174 inc di
175 loop kanjchar
176
177not_kj_match:
178else
179 REPE CMPSB
180endif
181 MOV CX,DX
182 MOV DI,BX
183 JNZ SCAN
184 MOV [SRCHCNT],CX
185 MOV CX,DI
186 MOV [LSTFND],DI
187 MOV DI,[NUMPOS]
188 SUB CX,DI
189 MOV AL,10
190 MOV DX,[LSTNUM]
191;Determine line number of match
192GETLIN:
193 INC DX
194 MOV BX,DI
195 REPNE SCASB
196 JZ GETLIN
197 DEC DX
198 MOV [LSTNUM],DX
199 MOV [NUMPOS],BX
200 XOR AL,AL
201RET11: RET
202
203
204GETTEXT:
205
206; Inputs:
207; SI points into command line buffer
208; DI points to result buffer
209; Function:
210; Moves [SI] to [DI] until ctrl-Z (1AH) or
211; RETURN (0DH) is found. Termination char not moved.
212; Outputs:
213; AL = Termination character
214; CX = No of characters moved.
215; SI points one past termination character
216; DI points to next free location
217
218 XOR CX,CX
219
220GETIT:
221 LODSB
222;-----------------------------------------------------------------------
223 cmp al,quote_char ;a quote character?
224 jne sj101 ;no, skip....
225 lodsb ;yes, get quoted character
226 call make_cntrl
227 jmp short sj102
228;-----------------------------------------------------------------------
229sj101:
230 CMP AL,1AH
231 JZ DEFCHK
232sj102:
233 CMP AL,0DH
234 JZ DEFCHK
235 STOSB
236 INC CX
237 JMP SHORT GETIT
238
239DEFCHK:
240 OR CX,CX
241 JZ OLDTXT
242 PUSH DI
243 SUB DI,CX
244 MOV BYTE PTR [DI-1],cl
245 POP DI
246 RET
247
248OLDTXT:
249 cmp byte ptr[olddat],1 ;replace with old text?
250 je sj11 ;yes...
251 mov byte ptr[di-1],cl ;zero text buffer char count
252 ret
253
254sj11:
255 MOV CL,BYTE PTR [DI-1]
256 ADD DI,CX
257 RET
258
259
260FINDLIN:
261
262; Inputs
263; BX = Line number to be located in buffer (0 means last line)
264; Outputs:
265; DX = Actual line found
266; DI = Pointer to start of line DX
267; Zero set if BX = DX
268; AL,CX destroyed. No other registers affected.
269
270 MOV DX,[CURRENT]
271 MOV DI,[POINTER]
272 CMP BX,DX
273 JZ RET4
274 JA FINDIT
275 OR BX,BX
276 JZ FINDIT
277 MOV DX,1
278 MOV DI,OFFSET DG:START
279 CMP BX,DX
280 JZ RET4
281FINDIT:
282 MOV CX,[ENDTXT]
283 SUB CX,DI
284SCANLN:
285 MOV AL,10
286 OR AL,AL ;Clear zero flag
287FINLIN:
288 JCXZ RET4
289 REPNE SCASB
290 INC DX
291 CMP BX,DX
292 JNZ FINLIN
293RET4: RET
294
295
296SHOWNUM:
297
298; Inputs:
299; BX = Line number to be displayed
300; Function:
301; Displays line number on terminal in 8-character
302; format, suppressing leading zeros.
303; AX, CX, DX destroyed. No other registers affected.
304
305 PUSH BX
306 MOV AL," "
307 CALL OUT
308 CALL CONV10
309 MOV AL,":"
310 CALL OUT
311 MOV AL,"*"
312 POP BX
313 CMP BX,[CURRENT]
314 JZ STARLIN
315 MOV AL," "
316STARLIN:
317 JMP OUT
318
319
320CONV10:
321
322;Inputs:
323; BX = Binary number to be displayed
324; Function:
325; Ouputs binary number. Five digits with leading
326; zero suppression. Zero prints 5 blanks.
327
328 XOR AX,AX
329 MOV DL,AL
330 MOV CX,16
331CONV:
332 SHL BX,1
333 ADC AL,AL
334 DAA
335 XCHG AL,AH
336 ADC AL,AL
337 DAA
338 XCHG AL,AH
339 ADC DL,DL
340 LOOP CONV
341 MOV BL,"0"-" "
342 XCHG AX,DX
343 CALL LDIG
344 MOV AL,DH
345 CALL DIGITS
346 MOV AL,DL
347DIGITS:
348 MOV DH,AL
349 SHR AL,1
350 SHR AL,1
351 SHR AL,1
352 SHR AL,1
353 CALL LDIG
354 MOV AL,DH
355LDIG:
356 AND AL,0FH
357 JZ ZERDIG
358 MOV BL,0
359ZERDIG:
360 ADD AL,"0"
361 SUB AL,BL
362 JMP OUT
363
364RET5: RET
365
366
367CRLF:
368 MOV AL,13
369 CALL OUT
370LF:
371 MOV AL,10
372OUT:
373 PUSH DX
374 XCHG AX,DX
375 MOV AH,STD_CON_OUTPUT
376 INT 21H
377 XCHG AX,DX
378 POP DX
379 RET
380
381
382;-----------------------------------------------------------------------;
383; Will scan buffer given pointed to by SI and get rid of quote
384;characters, compressing the line and adjusting the length at the
385;begining of the line.
386; Preserves al registers except flags and AX .
387
388unquote:
389 push cx
390 push di
391 push si
392 mov di,si
393 mov cl,[si-1] ;length of buffer
394 xor ch,ch
395 mov al,quote_char
396 cld
397unq_loop:
398 jcxz unq_done ;no more chars in the buffer, exit
399 repnz scasb ;search for quote character
400 jnz unq_done ;none found, exit
401 push cx ;save chars left in buffer
402 push di ;save pointer to quoted character
403 push ax ;save quote character
404 mov al,byte ptr[di] ;get quoted character
405 call make_cntrl
406 mov byte ptr[di],al
407 pop ax ;restore quote character
408 mov si,di
409 dec di ;points to the quote character
410 inc cx ;include the carriage return also
411 rep movsb ;compact line
412 pop di ;now points to after quoted character
413 pop cx
414 jcxz sj13 ;if quote char was last of line do not adjust
415 dec cx ;one less char left in the buffer
416sj13: pop si
417 dec byte ptr[si-1] ;one less character in total buffer count also
418 push si
419 jmp short unq_loop
420
421unq_done:
422 pop si
423 pop di
424 pop cx
425 ret
426
427
428;-----------------------------------------------------------------------;
429; Convert the character in AL to the corresponding control
430; character. AL has to be between @ and _ to be converted. That is,
431; it has to be a capital letter. All other letters are left unchanged.
432
433make_cntrl:
434 push ax
435 and ax,11100000b
436 cmp ax,01000000b
437 pop ax
438 jne sj14
439 and ax,00011111b
440sj14:
441 ret
442
443
444;---- Kill spaces in buffer --------------------------------------------;
445kill_bl:
446 lodsb ;get rid of blanks
447 cmp al,' '
448 je kill_bl
449 ret
450
451
452;----- Restore INT 24 vector and old current directory -----------------;
453rest_dir:
454 cmp [fudge],0
455 je no_fudge
456
457 mov ax,(set_interrupt_vector shl 8) or 24h
458 lds dx,[hardch]
459 int 21h
460 push cs
461 pop ds
462
463 mov dx,offset dg:userdir ;restore directory
464 mov ah,chdir
465 int 21h
466 mov dl,[user_drive] ;restore old current drive
467 mov ah,set_default_drive
468 int 21h
469
470no_fudge:
471 ret
472
473;----- INT 24 Processing -----------------------------------------------;
474
475int_24_retaddr dw offset dg:int_24_back
476
477int_24 proc far
478assume ds:nothing,es:nothing,ss:nothing
479
480 pushf
481 push cs
482 push [int_24_retaddr]
483 push word ptr [hardch+2]
484 push word ptr [hardch]
485 ret
486int_24 endp
487
488int_24_back:
489 cmp al,2 ;abort?
490 jnz ireti
491 push cs
492 pop ds
493
494assume ds:dg
495
496 call rest_dir
497 int 20h
498ireti:
499 iret
500
501 IF KANJI
502TESTKANJ:
503 CMP AL,81H
504 JB NOTLEAD
505 CMP AL,9FH
506 JBE ISLEAD
507 CMP AL,0E0H
508 JB NOTLEAD
509 CMP AL,0FCH
510 JBE ISLEAD
511NOTLEAD:
512 PUSH AX
513 XOR AX,AX ;Set zero
514 POP AX
515 RET
516
517ISLEAD:
518 PUSH AX
519 XOR AX,AX ;Set zero
520 INC AX ;Reset zero
521 POP AX
522 RET
523 ENDIF
524
525;-----------------------------------------------------------------------;
526
527CODE ENDS
528 END EDLPROC
529
530
531 \ No newline at end of file
diff --git a/v2.0/source/EXE2BIN.ASM b/v2.0/source/EXE2BIN.ASM
new file mode 100644
index 0000000..80deb43
--- /dev/null
+++ b/v2.0/source/EXE2BIN.ASM
@@ -0,0 +1,514 @@
1 title LOCATE (EXE2BIN)
2
3;Loader for EXE files under 86-DOS
4
5;The following switch allows use with the "old linker", which put a version
6;number where the new linker puts the number of bytes used in the last page.
7;If enabled, this will cause a test for 0004 at this location (the old linker
8;version number), and if equal, change it to 200H so all of the last page
9;will be used.
10
11;VER. 1.5
12; 05/21/82 Added rev number
13;
14;VER. 1.6
15; 07/01/82 A little less choosy about size matches
16;
17;VER. 2.0 Rev. 1 M.A.Ulloa
18; 10/08/82 Modified to use new 2.0 system calls for file i/o
19;
20; Rev. 2 M.A.Ulloa
21; 10/27/82 Added the DOS version check
22
23FALSE EQU 0
24TRUE EQU NOT FALSE
25
26OLDLINK EQU 0 ;1 to enable, 0 to disable
27
28 .xlist
29 INCLUDE DOSSYM.ASM
30 .list
31
32
33 subttl Main Code Area
34 page
35
36
37code segment byte
38code ends
39
40DATA SEGMENT PUBLIC BYTE
41
42
43 EXTRN bad_vers_err:BYTE,NOTFND:BYTE,NOROOM:BYTE,DIRFULL:BYTE
44 EXTRN CANTFIX:BYTE,RDBAD:BYTE,FULL:BYTE,PROMPT:BYTE,CRLF:BYTE
45
46make db "MAUlloa/Microsoft/V20"
47rev db "2"
48
49file1_ext db ".EXE",00h
50file2_ext db ".BIN",00h
51
52per1 db 0
53per2 db 0
54
55file1 db 64 dup(?)
56handle1 dw 1 dup(?)
57
58file2 db 64 dup(?)
59handle2 dw 1 dup(?)
60
61
62INBUF DB 5,0
63 DB 5 DUP(?)
64
65;The following locations must be defined for storing the header:
66
67RUNVAR LABEL BYTE ;Start of RUN variables
68RELPT DW ?
69LASTP LABEL WORD
70RELSEG DW ?
71SIZ LABEL WORD ;Share these locations
72PAGES DW ?
73RELCNT DW ?
74HEADSIZ DW ?
75 DW ?
76LOADLOW DW ?
77INITSS DW ?
78INITSP DW ?
79 DW ?
80INITIP DW ?
81INITCS DW ?
82RELTAB DW ?
83RUNVARSIZ EQU $-RUNVAR
84
85DATA ENDS
86
87STACK SEGMENT WORD STACK
88 DB 80H DUP (?)
89STACK ENDS
90
91ZLOAD SEGMENT
92ZLOAD ENDS
93LOAD EQU ZLOAD
94
95CODE SEGMENT BYTE
96
97 ASSUME CS:CODE
98
99LOCATE PROC FAR
100 JMP SHORT LOCSTRT
101
102HEADER DB "Vers 2.00"
103
104LOCSTRT:
105 MOV SI,81H
106 PUSH DS
107 XOR AX,AX
108 PUSH AX ;Push return address to DS:0
109
110;Code to print header
111; PUSH DS
112; MOV DX,DATA
113; MOV DS,DX
114; MOV DX,OFFSET HEADER
115; MOV AH,STD_CON_STRING_OUTPUT
116; INT 21H
117; POP DS
118
119;----- Check Version Number --------------------------------------------;
120 mov ah,Get_Version
121 int 21h
122 cmp al,2
123 jge vers_ok ; version >= 2, enter locate
124 push ds
125 mov dx,data
126 mov ds,dx
127 mov dx,offset bad_vers_err
128 MOV AH,STD_CON_STRING_OUTPUT
129 INT 21H
130 pop ds
131 ret ;long return to DOS
132
133;-----------------------------------------------------------------------;
134vers_ok:
135
136
137 MOV BX,WORD PTR DS:2 ;Get size of memory
138 MOV DX,DATA
139 MOV ES,DX
140
141 assume es:data
142
143;-----------------------------------------------------------------------;
144
145;----- Get the first file name
146 call kill_bl
147 jnc sj01
148 mov ds,dx
149 jmp bad_file
150sj01:
151 mov di,offset file1
152sj0:
153 lodsb ;get character of file name
154 cmp al,' '
155 je sj2
156 cmp al,0dh
157 je sj2
158 cmp al,'.' ;an extension separator found?
159 jne sj1
160 mov es:[per1],-1
161sj1:
162 stosb
163 jmp short sj0
164sj2:
165 dec si
166 mov byte ptr es:[di],00h ;nul terminate the filename
167 call kill_bl
168 jc no_second
169
170;----- Get the second file name
171 mov di,offset file2
172sj3:
173 lodsb ;get character of file name
174 cmp al,' '
175 je sj5
176 cmp al,0dh
177 je sj5
178 cmp al,'.' ;an extension separator found?
179 jne sj4
180 mov es:[per2],-1
181sj4:
182 stosb
183 jmp short sj3
184sj5:
185 mov byte ptr es:[di],00h ;nul terminate
186 jmp short check_ext
187
188;----- Copy file1 to file2
189no_second:
190 mov ds,dx
191
192 assume ds:data
193
194 mov si,offset file1
195 mov di,offset file2
196sj6:
197 lodsb
198 cmp al,'.'
199 je sj7
200 cmp al,00h
201 je sj7
202 stosb
203 jmp short sj6
204sj7:
205 mov byte ptr [di],00h
206
207;----- Check that files have an extension, otherwise set default
208check_ext:
209 mov ds,dx
210
211 assume ds:data
212
213 cmp [per1],-1
214 je file1_ok
215 mov si,offset file1
216sj8:
217 lodsb
218 cmp al,00h
219 jne sj8
220 mov di,si
221 mov si,offset file1_ext
222 call put_ext
223
224file1_ok:
225 cmp [per2],-1
226 je file2_ok
227 mov si,offset file2
228sj9:
229 lodsb
230 cmp al,00h
231 jne sj9
232 mov di,si
233 mov si,offset file2_ext
234 call put_ext
235 jmp short file2_ok
236
237;----- Fill in the default extent
238put_ext proc near
239 dec di
240 mov cx,5 ;move extent: period,extent,null
241 rep movsb
242 ret
243put_ext endp
244
245;----- Find the first non-blank
246kill_bl proc near
247 cld
248sj10:
249 lodsb
250 cmp al,' '
251 je sj10
252 dec si
253 cmp al,0dh
254 clc
255 jne sj11
256 stc
257sj11:
258 ret
259kill_bl endp
260
261file2_ok:
262
263;-----------------------------------------------------------------------;
264
265 mov dx,offset file1
266 mov ah,open
267 mov al,0 ;ror reading only
268 INT 21H ;Open input file
269 jc bad_file
270 mov [handle1],ax
271 jmp exeload
272
273bad_file:
274 MOV DX,OFFSET NOTFND
275xERROR:
276 MOV AH,STD_CON_STRING_OUTPUT
277 INT 21H
278 RET ;FAR return to MS-DOS
279TOOBIG:
280 MOV DX,OFFSET NOROOM
281 JMP xERROR
282BADEXE:
283 MOV DX,OFFSET CANTFIX
284ERRORJ: JMP xERROR
285
286EXELOAD:
287 MOV DX,OFFSET RUNVAR ;Read header in here
288 MOV CX,RUNVARSIZ ;Amount of header info we need
289 push bx
290 mov bx,[handle1]
291 MOV AH,read
292 INT 21H ;Read in header
293 pop bx
294 CMP [RELPT],5A4DH ;Check signature word
295 JNZ BADEXE
296 MOV AX,[HEADSIZ] ;size of header in paragraphs
297 ADD AX,31 ;Round up first
298 CMP AX,1000H ;Must not be >=64K
299 JAE TOOBIG
300 AND AX,NOT 31
301 MOV CL,4
302 SHL AX,CL ;Header size in bytes
303
304 push dx
305 push cx
306 push ax
307 push bx
308 mov dx,ax
309 xor cx,cx
310 mov al,0
311 mov bx,[handle1]
312 mov ah,lseek
313 int 21h
314 pop bx
315 pop ax
316 pop cx
317 pop dx
318
319 XCHG AL,AH
320 SHR AX,1 ;Convert to pages
321 MOV DX,[PAGES] ;Total size of file in 512-byte pages
322 SUB DX,AX ;Size of program in pages
323 CMP DX,80H ;Fit in 64K?
324 JAE TOOBIG
325 XCHG DH,DL
326 SHL DX,1 ;Convert pages to bytes
327 MOV AX,[LASTP] ;Get count of bytes in last page
328 OR AX,AX ;If zero, use all of last page
329 JZ WHOLEP
330
331 IF OLDLINK
332 CMP AX,4 ;Produced by old linker?
333 JZ WHOLEP ;If so, use all of last page too
334 ENDIF
335
336 SUB DX,200H ;Subtract last page
337 ADD DX,AX ;Add in byte count for last page
338WHOLEP:
339 MOV [SIZ],DX
340 ADD DX,15
341 SHR DX,CL ;Convert bytes to paragraphs
342 MOV BP,LOAD
343 ADD DX,BP ;Size + start = minimum memory (paragr.)
344 CMP DX,BX ;Enough memory?
345 JA TOOBIG
346 MOV DX,OFFSET CANTFIX
347 MOV AX,[INITSS]
348 OR AX,[INITSP]
349 OR AX,[INITCS]
350ERRORNZ:
351 jz xj
352 JMP ERRORJ ;Must not have SS, SP, or CS to init.
353xj: MOV AX,[INITIP]
354 OR AX,AX ;If IP=0, do binary fix
355 JZ BINFIX
356 CMP AX,100H ;COM file must be set up for CS:100
357 JNZ ERRORNZ
358
359 push dx
360 push cx
361 push ax
362 push bx
363 mov dx,100h ;chop off first 100h
364 xor cx,cx
365 mov al,1 ;seek from current position
366 mov bx,[handle1]
367 mov ah,lseek
368 int 21h
369 pop bx
370 pop ax
371 pop cx
372 pop dx
373
374 SUB [SIZ],AX ;And count decreased size
375 CMP [RELCNT],0 ;Must have no fixups
376 JNZ ERRORNZ
377BINFIX:
378 XOR BX,BX ;Initialize fixup segment
379;See if segment fixups needed
380 CMP [RELCNT],0
381 JZ LOADEXE
382GETSEG:
383 MOV DX,OFFSET PROMPT
384 MOV AH,STD_CON_STRING_OUTPUT
385 INT 21H
386 MOV AH,STD_CON_STRING_INPUT
387 MOV DX,OFFSET INBUF
388 INT 21H ;Get user response
389 MOV DX,OFFSET CRLF
390 MOV AH,STD_CON_STRING_OUTPUT
391 INT 21H
392 MOV SI,OFFSET INBUF+2
393 MOV BYTE PTR [SI-1],0 ;Any digits?
394 JZ GETSEG
395DIGLP:
396 LODSB
397 SUB AL,"0"
398 JC DIGERR
399 CMP AL,10
400 JB HAVDIG
401 AND AL,5FH ;Convert to upper case
402 SUB AL,7
403 CMP AL,10
404 JB DIGERR
405 CMP AL,10H
406 JAE DIGERR
407HAVDIG:
408 SHL BX,1
409 SHL BX,1
410 SHL BX,1
411 SHL BX,1
412 OR BL,AL
413 JMP DIGLP
414
415DIGERR:
416 CMP BYTE PTR [SI-1],0DH ;Is last char. a CR?
417 JNZ GETSEG
418LOADEXE:
419 XCHG BX,BP ;BX has LOAD, BP has fixup
420
421 MOV CX,[SIZ]
422 MOV AH,read
423 push di
424 mov di,[handle1]
425 PUSH DS
426 MOV DS,BX
427 XOR DX,DX
428 push bx
429 mov bx,di
430 INT 21H ;Read in up to 64K
431 pop bx
432 POP DS
433 pop di
434 Jnc HAVEXE ;Did we get it all?
435 MOV DX,OFFSET RDBAD
436 jmp xERROR ;Non fatal, print warning
437HAVEXE:
438 CMP [RELCNT],0 ;Any fixups to do?
439 JZ STORE
440 MOV AX,[RELTAB] ;Get position of table
441
442 push dx
443 push cx
444 push ax
445 push bx
446 mov dx,ax
447 xor cx,cx
448 mov al,0
449 mov bx,[handle1]
450 mov ah,lseek
451 int 21h
452 pop bx
453 pop ax
454 pop cx
455 pop dx
456
457 MOV DX,OFFSET RELPT ;4-byte buffer for relocation address
458RELOC:
459 MOV DX,OFFSET RELPT ;4-byte buffer for relocation address
460 MOV CX,4
461 MOV AH,read
462 push bx
463 mov bx,[handle1]
464 INT 21H ;Read in one relocation pointer
465 pop bx
466 Jnc RDCMP
467 JMP BADEXE
468RDCMP:
469 MOV DI,[RELPT] ;Get offset of relocation pointer
470 MOV AX,[RELSEG] ;Get segment
471 ADD AX,BX ;Bias segment with actual load segment
472 MOV ES,AX
473 ADD ES:[DI],BP ;Relocate
474 DEC [RELCNT] ;Count off
475 JNZ RELOC
476STORE:
477 MOV AH,CREAT
478 MOV DX,OFFSET file2
479 xor cx,cx
480 INT 21H
481 Jc MKERR
482 mov [handle2],ax
483 MOV CX,[SIZ]
484 MOV AH,write
485 push di
486 mov di,[handle2]
487 PUSH DS
488 MOV DS,BX
489 XOR DX,DX ;Address 0 in segment
490 push bx
491 mov bx,di
492 INT 21H
493 pop bx
494 POP DS
495 pop di
496 Jc WRTERR ;Must be zero if more to come
497 MOV AH,CLOSE
498 push bx
499 mov bx,[handle2]
500 INT 21H
501 pop bx
502 RET
503
504WRTERR:
505 MOV DX,OFFSET FULL
506 JMP xERROR
507MKERR:
508 MOV DX,OFFSET DIRFULL
509 JMP xERROR
510
511LOCATE ENDP
512CODE ENDS
513 END LOCATE
514
diff --git a/v2.0/source/EXEC.ASM b/v2.0/source/EXEC.ASM
new file mode 100644
index 0000000..d41aceb
--- /dev/null
+++ b/v2.0/source/EXEC.ASM
@@ -0,0 +1,1035 @@
1SUBTTL $exec - load/go a program
2PAGE
3;
4; Assembler usage:
5; LDS DX, name
6; LES BX, blk
7; MOV AH, Exec
8; MOV AL, func
9; INT int_command
10;
11; AL Function
12; -- --------
13; 0 Load and execute the program.
14; 1 Load, create the program header but do not
15; begin execution.
16; 3 Load overlay. No header created.
17;
18; AL = 0 -> load/execute program
19;
20; +---------------------------+
21; | WORD segment address of |
22; | environment. |
23; +---------------------------+
24; | DWORD pointer to ASCIZ |
25; | command line at 80h |
26; +---------------------------+
27; | DWORD pointer to default |
28; | FCB to be passed at 5Ch |
29; +---------------------------+
30; | DWORD pointer to default |
31; | FCB to be passed at 6Ch |
32; +---------------------------+
33;
34; AL = 1 -> load program
35;
36; +---------------------------+
37; | WORD segment address of |
38; | environment. |
39; +---------------------------+
40; | DWORD pointer to ASCIZ |
41; | command line at 80h |
42; +---------------------------+
43; | DWORD pointer to default |
44; | FCB to be passed at 5Ch |
45; +---------------------------+
46; | DWORD pointer to default |
47; | FCB to be passed at 6Ch |
48; +---------------------------+
49; | DWORD returned value of |
50; | CS:IP |
51; +---------------------------+
52; | DWORD returned value of |
53; | SS:IP |
54; +---------------------------+
55;
56; AL = 3 -> load overlay
57;
58; +---------------------------+
59; | WORD segment address where|
60; | file will be loaded. |
61; +---------------------------+
62; | WORD relocation factor to |
63; | be applied to the image. |
64; +---------------------------+
65;
66; Returns:
67; AX = exec_invalid_function
68; = exec_bad_format
69; = exec_bad_environment
70; = exec_not_enough_memory
71; = exec_file_not_found
72;
73
74IF IBM
75ZEXEC_DATA SEGMENT PUBLIC BYTE
76ZERO = $
77ENDIF
78
79exec_blk DD ?
80exec_func DB ?
81exec_fh DW ?
82exec_rel_fac DW ?
83exec_res_len_para DW ?
84exec_init_IP DW ?
85exec_init_CS DW ?
86exec_init_SP DW ?
87exec_init_SS DW ?
88exec_environ DW ?
89exec_size DW ?
90exec_load_block DW ?
91
92exec_load_high DB ?
93
94exec_internal_buffer EQU $
95exec_signature DW ? ; must contain 4D5A (yay zibo!)
96exec_len_mod_512 DW ? ; low 9 bits of length
97exec_pages DW ? ; number of 512b pages in file
98exec_rle_count DW ? ; count of reloc entries
99exec_par_dir DW ? ; number of paragraphs before image
100exec_min_BSS DW ? ; minimum number of para of BSS
101exec_max_BSS DW ? ; max number of para of BSS
102exec_SS DW ? ; stack of image
103exec_SP DW ? ; SP of image
104exec_chksum DW ? ; checksum of file (ignored)
105exec_IP DW ? ; IP of entry
106exec_CS DW ? ; CS of entry
107exec_rle_table DW ? ; byte offset of reloc table
108exec_iov DW ? ; overlay number (0 for root)
109exec_dma DW ?
110exec_internal_buffer_size EQU $-exec_internal_buffer
111
112IF IBM
113exec_ctrlc DB ? ; state of users ctrlc flag
114Exec_low_seg DW ?
115CurrentPDB DW ?
116NUMIO DB ?
117ZEXECDATASIZ = $-ZERO
118ZEXECDATAEND LABEL BYTE
119 PUBLIC ZEXECDATAEND
120ZEXEC_DATA ENDS
121ZEXEC_CODE SEGMENT PUBLIC PARA
122 PUBLIC $EXEC
123ZERO = $
124 procedure $EXEC,FAR
125 ASSUME CS:EGROUP,SS:RESGROUP,ES:NOTHING,DS:NOTHING
126ENDIF
127IF NOT IBM
128 procedure $Exec,NEAR
129 ASSUME DS:NOTHING, ES:NOTHING
130ENDIF
131;
132; validate function
133;
134
135IF IBM
136 PUSH CS
137 POP DS
138 ASSUME DS:EGROUP
139
140 MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 0 ; Save current ctrl-c
141 INT int_command
142 MOV exec_ctrlc,DL
143 XOR DX,DX
144 MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 1 ; Turn it off!
145 INT int_command
146
147 MOV AH,Get_current_PDB
148 INT int_command
149 MOV [CurrentPDB],BX
150;
151; set up user return stack info
152;
153 MOV ES,BX
154 LES BX,DWORD PTR [user_sp]
155 MOV WORD PTR ES:[PDB_user_stack+2],ES
156 MOV WORD PTR ES:[PDB_user_stack],BX
157
158 MOV AH,Get_Default_Drive
159 INT int_command
160 MOV DL,AL
161 MOV AH,Set_default_drive
162 INT int_command
163 MOV [NUMIO],AL
164;
165; determine lowest seg address for overwrite problem (round DOWN)
166;
167 MOV CL,4
168 MOV AX,OFFSET ZEXEC_CODE:exec_check
169 SHR AX,CL
170 PUSH CS
171 POP BX
172 ADD AX,BX
173 MOV [exec_low_seg],AX
174
175 CALL get_user_stack
176 ASSUME DS:NOTHING
177 MOV AX,[SI.user_AX]
178 MOV BX,[SI.user_BX]
179 MOV DX,[SI.user_DX]
180 MOV ES,[SI.user_ES]
181 MOV DS,[SI.user_DS]
182ENDIF
183
184 CMP AL,3 ; only 0, 1 or 3 are allowed
185 JNA exec_check_2
186
187exec_bad_fun:
188 error error_invalid_function
189
190exec_ret_err:
191 transfer SYS_RET_ERR
192
193exec_check_2:
194 CMP AL,2
195 JZ exec_bad_fun
196
197 MOV WORD PTR [exec_blk],BX ; stash args
198 MOV WORD PTR [exec_blk+2],ES
199 MOV BYTE PTR [exec_func],AL
200 MOV BYTE PTR [exec_load_high],0
201IF IBM
202 MOV AX,(OPEN SHL 8) + 0
203 INT int_command
204ENDIF
205IF NOT IBM
206 XOR AL,AL ; open for reading
207 invoke $OPEN ; is the file there?
208ENDIF
209 JC exec_ret_err
210 MOV [exec_fh],AX
211 MOV BX,AX
212IF IBM
213 MOV AX,(ioctl SHL 8) ; get device information
214 INT int_command
215ENDIF
216IF NOT IBM
217 XOR AL,AL
218 invoke $IOCTL
219ENDIF
220 TEST DL,devid_ISDEV
221 JZ exec_check_environ
222 MOV AL,exec_file_not_found
223 transfer SYS_RET_ERR
224
225exec_check_environ:
226 MOV [exec_load_block],0
227
228 TEST BYTE PTR [exec_func],exec_func_overlay ; overlays... no environment
229 JNZ exec_read_header
230 LDS SI,DWORD PTR [exec_blk] ; get block
231 MOV AX,[SI].Exec1_environ ; address of environ
232 OR AX,AX
233 JNZ exec_scan_env
234 MOV DS,[CurrentPDB]
235 MOV AX,DS:[PDB_environ]
236 MOV [exec_environ],AX
237 OR AX,AX
238 JZ exec_read_header
239
240exec_scan_env:
241 CLD
242 MOV ES,AX
243 XOR DI,DI
244 MOV CX,07FFFh ; at most 32k of environment
245 XOR AL,AL
246
247exec_get_environ_len:
248 REPNZ SCASB ; find that nul byte
249 JZ exec_check ; CX is out... bad environment
250 MOV AL,exec_bad_environment
251 JMP exec_bomb
252
253exec_check:
254 SCASB ; is there another nul byte?
255 JNZ exec_get_environ_len ; no, scan some more
256 PUSH DI
257 MOV BX,DI ; AX <- length of environment
258 ADD BX,0Fh
259 MOV CL,4
260 SHR BX,CL ; number of paragraphs needed
261 PUSH ES
262IF IBM
263 MOV AH,ALLOC
264 INT int_command
265ENDIF
266IF NOT IBM
267 invoke $ALLOC ; can we get the space?
268ENDIF
269 POP DS
270 POP CX
271 JNC exec_save_environ
272 JMP exec_no_mem ; nope... cry and sob
273
274exec_save_environ:
275 MOV ES,AX
276 MOV [exec_environ],AX ; save him for a rainy day
277IF IBM
278 PUSH CX
279 MOV CX,ES
280 ADD CX,BX
281 CMP BX,[exec_low_seg]
282 POP CX
283 JA exec_no_mem
284ENDIF
285 XOR SI,SI
286 XOR DI,DI
287 REP MOVSB ; copy the environment
288
289exec_read_header:
290;
291; We read in the program header into the above data area and determine
292; where in this memory the image will be located.
293;
294IF IBM
295 PUSH CS
296 POP DS ; and put it in DS:DX
297 ASSUME DS:EGROUP
298ENDIF
299IF NOT IBM
300 PUSH SS
301 POP DS ; and put it in DS:DX
302 ASSUME DS:DOSGROUP
303ENDIF
304 MOV CX,exec_internal_buffer_size; header size
305 MOV BX,[exec_fh] ; from the handle
306IF IBM
307 MOV DX,OFFSET EGROUP:exec_signature
308ENDIF
309IF NOT IBM
310 MOV DX,OFFSET DOSGROUP:exec_signature
311ENDIF
312 PUSH ES
313 PUSH DS
314 CALL exec_dealloc
315IF IBM
316 MOV AH,READ
317 INT int_command
318ENDIF
319IF NOT IBM
320 invoke $READ
321ENDIF
322 CALL exec_alloc
323 POP DS
324 POP ES
325 JC exec_bad_file
326 CMP AX,exec_internal_buffer_size; did we read the right number?
327 JNZ exec_com_filej ; yep... continue
328 CMP [exec_max_BSS],0
329 JNZ exec_check_sig
330 MOV [exec_load_high],-1
331exec_check_sig:
332 MOV AX,[exec_signature]
333 CMP AX,exe_valid_signature ; zibo arises!
334 JZ exec_save_start ; assume com file if no signature
335 CMP AX,exe_valid_old_signature ; zibo arises!
336 JZ exec_save_start ; assume com file if no signature
337
338exec_com_filej:
339 JMP exec_com_file
340
341;
342; We have the program header... determine memory requirements
343;
344exec_save_start:
345 MOV AX,[exec_pages] ; get 512-byte pages
346 MOV CL,5 ; convert to paragraphs
347 SHL AX,CL
348 SUB AX,[exec_par_dir] ; AX = size in paragraphs
349 MOV [exec_res_len_para],AX
350
351;
352; Do we need to allocate memory? Yes if function is not load-overlay
353;
354 TEST BYTE PTR [exec_func],exec_func_overlay
355 JZ exec_allocate ; allocation of space
356;
357; get load address from block
358;
359 LES DI,DWORD PTR [exec_blk]
360 MOV AX,ES:[DI].exec3_load_addr
361 MOV [exec_dma],AX
362 MOV AX,ES:[DI].exec3_reloc_fac
363 MOV [exec_rel_fac],AX
364IF IBM
365 JMP exec_find_res
366ENDIF
367IF NOT IBM
368 JMP SHORT exec_find_res
369ENDIF
370
371exec_no_mem:
372 MOV AL,exec_not_enough_memory
373 JMP SHORT exec_bomb ; AX should be set by $ALLOC
374
375exec_bad_file:
376 MOV AL,exec_bad_format
377
378exec_bomb:
379 ASSUME DS:NOTHING,ES:NOTHING
380 PUSH AX
381 MOV BX,[exec_fh]
382 CALL exec_dealloc
383IF IBM
384 MOV AH,CLOSE
385 INT int_command
386ENDIF
387IF NOT IBM
388 invoke $CLOSE
389ENDIF
390 POP AX
391 transfer SYS_RET_ERR
392
393exec_allocate:
394IF IBM
395 ASSUME DS:EGROUP
396ENDIF
397IF NOT IBM
398 ASSUME DS:DOSGROUP
399ENDIF
400 PUSH AX
401 MOV BX,0FFFFh ; see how much room in arena
402 PUSH DS
403IF IBM
404 MOV AH,ALLOC
405 INT int_command
406ENDIF
407IF NOT IBM
408 invoke $ALLOC ; should have carry set and BX has max
409ENDIF
410 POP DS
411 POP AX
412 ADD AX,10h ; room for header
413 CMP BX,11h ; enough room for a header
414 JB exec_no_mem
415 CMP AX,BX ; is there enough for bare image?
416 JA exec_no_mem
417 CMP [exec_load_high],0 ; if load high, use max
418 JNZ exec_BX_max ; use max
419 ADD AX,[exec_min_BSS] ; go for min allocation
420 JC exec_no_mem ; oops! carry
421 CMP AX,BX ; enough space?
422 JA exec_no_mem ; nope...
423 SUB AX,[exec_min_BSS]
424 ADD AX,[exec_max_BSS] ; go for the MAX
425 JC exec_BX_max
426 CMP AX,BX
427 JBE exec_got_block
428
429exec_BX_max:
430 MOV AX,BX
431
432exec_got_block:
433 PUSH DS
434 MOV BX,AX
435 MOV [exec_size],BX
436IF IBM
437 MOV AH,ALLOC
438 INT int_command
439ENDIF
440IF NOT IBM
441 invoke $ALLOC ; get the space
442ENDIF
443 POP DS
444 JC exec_no_mem
445 MOV [exec_load_block],AX
446 ADD AX,10h
447 CMP [exec_load_high],0
448 JZ exec_use_ax ; use ax for load info
449 ADD AX,[exec_size] ; go to end
450 SUB AX,[exec_res_len_para] ; drop off header
451 SUB AX,10h ; drop off pdb
452exec_use_ax:
453 MOV [exec_rel_fac],AX ; new segment
454 MOV [exec_dma],AX ; beginning of dma
455IF IBM
456 CMP AX,[exec_low_seg] ; below loader
457 JA exec_no_mem_try
458 ADD AX,[exec_res_len_para] ; go to end
459 CMP Ax,[exec_low_seg] ; above loader
460 JBE exec_find_res
461exec_try_high:
462 CMP [exec_load_high],0
463 JZ exec_no_memj1
464exec_try_just_below:
465 MOV DX,AX
466 SUB DX,[exec_size] ; get beginning
467 ADD DX,[exec_res_len_para] ; no space
468 CMP DX,[exec_low_seg] ; room there?
469 JA exec_no_memj1
470 MOV AX,[exec_low_seg]
471 SUB AX,[exec_res_len_para]
472 JMP exec_use_ax
473exec_no_mem_try:
474 MOV DX,CS
475 ADD DX,(zexecdatasiz+zexeccodesize+15)/16
476 CMP AX,DX
477 JAE exec_try_high
478 JMP exec_try_just_below
479exec_no_memj1:
480 JMP exec_no_mem
481ENDIF
482
483;
484; Determine the location in the file of the beginning of the resident
485;
486exec_find_res:
487 MOV DX,[exec_par_dir]
488 PUSH DX
489 MOV CL,4
490 SHL DX,CL ; low word of location
491 POP AX
492 MOV CL,12
493 SHR AX,CL ; high word of location
494 MOV CX,AX ; CX <- high
495
496;
497; Read in the resident image (first, seek to it)
498;
499 MOV BX,[exec_fh]
500 PUSH DS
501IF IBM
502 MOV AX,(LSEEK SHL 8) + 0
503 INT int_command
504ENDIF
505IF NOT IBM
506 XOR AL,AL
507 invoke $LSEEK ; seek to resident
508ENDIF
509 POP DS
510
511exec_big_read: ; Read resident into memory
512 MOV BX,[exec_res_len_para]
513 CMP BX,1000h ; too many bytes to read?
514 JB exec_read_ok
515 MOV BX,0FE0h ; max in one chunk FE00 bytes
516
517exec_read_ok:
518 SUB [exec_res_len_para],BX ; we read (soon) this many
519 PUSH BX
520 MOV CL,4
521 SHL BX,CL ; get count in bytes from paras
522 MOV CX,BX ; count in correct register
523 MOV BX,[exec_fh] ; handle in correct register
524 PUSH DS
525 MOV DS,[exec_dma] ; Set up read buffer
526 ASSUME DS:NOTHING
527 XOR DX,DX
528 PUSH CX ; save our count
529 CALL exec_dealloc
530IF IBM
531 MOV AH,READ
532 INT int_command
533ENDIF
534IF NOT IBM
535 invoke $READ ; WOMP!
536ENDIF
537 CALL exec_alloc
538 POP CX ; get old count to verify
539 POP DS
540IF IBM
541 ASSUME DS:EGROUP
542ENDIF
543IF NOT IBM
544 ASSUME DS:DOSGROUP
545ENDIF
546 CMP CX,AX ; did we read enough?
547 POP BX ; get paragraph count back
548 JNZ exec_do_reloc ; and do reloc if no more to read
549;
550; We've read in CX bytes... bump DTA location
551;
552
553 ADD [exec_dma],BX ; bump dma address
554 CMP [exec_res_len_para],0
555 JNZ exec_big_read
556
557;
558; The image has now been read in. We must perform relocation to
559; the current location.
560;
561
562exec_do_reloc:
563 MOV CX,[exec_rel_fac]
564 MOV AX,[exec_SS] ; get initial SS
565 ADD AX,CX ; and relocate him
566 MOV [exec_init_SS],AX
567
568 MOV AX,[exec_SP] ; initial SP
569 MOV [exec_init_SP],AX
570
571 LES AX,DWORD PTR [exec_IP]
572 MOV [exec_init_IP],AX
573 MOV AX,ES
574 ADD AX,CX ; relocated...
575 MOV [exec_init_CS],AX
576
577 XOR CX,CX
578 MOV DX,[exec_rle_table]
579 MOV BX,[exec_fh]
580 PUSH DS
581IF IBM
582 MOV AX,(LSEEK SHL 8) + 0
583 INT int_command
584ENDIF
585IF NOT IBM
586 XOR AX,AX
587 invoke $LSEEK
588ENDIF
589 POP DS
590
591 JNC exec_get_entries
592exec_bad_filej:
593 JMP exec_bad_file
594
595exec_get_entries:
596 MOV DX,[exec_rle_count] ; Number of entries left
597
598exec_read_reloc:
599 ASSUME DS:NOTHING
600 PUSH DX
601IF IBM
602 MOV DX,OFFSET EGROUP:exec_signature
603ENDIF
604IF NOT IBM
605 MOV DX,OFFSET DOSGROUP:exec_signature
606ENDIF
607 MOV CX,((exec_internal_buffer_size)/4)*4
608 MOV BX,[exec_fh]
609 PUSH DS
610 CALL exec_dealloc
611IF IBM
612 MOV AH,READ
613 INT int_command
614ENDIF
615IF NOT IBM
616 invoke $READ
617ENDIF
618 CALL exec_alloc
619 POP ES
620 POP DX
621 JC exec_bad_filej
622 MOV CX,(exec_internal_buffer_size)/4
623IF IBM
624 MOV DI,OFFSET EGROUP:exec_signature ; Pointer to byte location in header
625ENDIF
626IF NOT IBM
627 MOV DI,OFFSET DOSGROUP:exec_signature ; Pointer to byte location in header
628ENDIF
629;
630; Relocate a single address
631;
632 MOV SI,[exec_rel_fac]
633
634exec_reloc_one:
635 CMP DX,0 ; Any more entries?
636 JNE exec_get_addr
637 JMP Exec_set_PDB
638
639exec_get_addr:
640 LDS BX,DWORD PTR ES:[DI] ; Get ra/sa of entry
641 MOV AX,DS ; Relocate address of item
642 ADD AX,SI
643 MOV DS,AX
644 MOV AX,WORD PTR DS:[BX] ; Relocate item
645 ADD AX,SI
646 MOV WORD PTR DS:[BX],AX
647 ADD DI,4
648 DEC DX
649 LOOP exec_reloc_one ; End of internal buffer?
650
651;
652; We've exhausted a single buffer's worth. Read in the next piece
653; of the relocation table.
654;
655
656 PUSH ES
657 POP DS
658 JMP exec_read_reloc
659
660exec_no_memj:
661 JMP exec_no_mem
662
663;
664; we have a .COM file. First, determine if we are merely loading an overlay.
665;
666exec_com_file:
667 TEST BYTE PTR [exec_func],exec_func_overlay
668 JZ exec_alloc_com_file
669 LDS SI,DWORD PTR [exec_blk] ; get arg block
670 LODSW ; get load address
671 MOV [exec_dma],AX
672 JMP SHORT exec_64k ; read it all!
673
674; We must allocate the max possible size block (ick!) and set up
675; CS=DS=ES=SS=PDB pointer, IP=100, SP=max size of block.
676;
677exec_alloc_com_file:
678 MOV BX,0FFFFh
679IF IBM
680 MOV AH,ALLOC
681 INT int_command
682ENDIF
683IF NOT IBM
684 invoke $ALLOC ; largest piece available as error
685ENDIF
686 OR BX,BX
687 JZ exec_no_memj
688 MOV [exec_size],BX ; save size of allocation block
689IF IBM
690 MOV AH,ALLOC
691 INT int_command
692ENDIF
693IF NOT IBM
694 PUSH BX
695 invoke $ALLOC ; largest piece available as error
696 POP BX ; get size of block...
697ENDIF
698 MOV [exec_load_block],AX
699 ADD AX,10h ; increment for header
700 MOV [exec_dma],AX
701 SUB BX,10h ; remember header
702IF IBM
703;
704; need to read up to exec_low_seg (at most)
705;
706 MOV CX,[exec_low_seg]
707 CMP AX,CX ; is base of allocation above spot
708 JA exec_check_64k
709 SUB CX,AX
710 CMP CX,BX
711 JA exec_check_64k
712 MOV BX,CX
713
714exec_check_64k:
715ENDIF
716 CMP BX,1000h ; 64k or more?
717 JAE exec_64k ; yes, read only 64k
718 MOV AX,BX ; convert size to bytes
719 MOV CL,4
720 SHL AX,CL
721 JMP SHORT exec_read_com
722
723exec_64k:
724 MOV AX,0FFFFh ; 64k-1 bytes
725
726exec_read_com:
727 PUSH AX ; save number to read
728 MOV BX,[exec_fh] ; of com file
729 XOR CX,CX ; but seek to 0:0
730 MOV DX,CX
731IF IBM
732 MOV AX,(LSEEK SHL 8) + 0
733 INT int_command
734ENDIF
735IF NOT IBM
736 XOR AX,AX ; seek relative to beginning
737 invoke $LSEEK ; back to beginning of file
738ENDIF
739 MOV BX,[exec_fh]
740 POP CX ; number to read
741 MOV DS,[exec_dma]
742 XOR DX,DX
743 PUSH CX
744 CALL exec_dealloc
745IF IBM
746 MOV AH,READ
747 INT int_command
748ENDIF
749IF NOT IBM
750 invoke $READ ; read in com file
751ENDIF
752 CALL exec_alloc
753 POP SI ; get number of bytes to read
754 CMP AX,SI ; did we read them all?
755IF IBM
756 JNZ exec_skip ; exactly the wrong number... no memory
757 JMP exec_no_mem
758exec_skip:
759ENDIF
760IF NOT IBM
761 JZ exec_no_memj ; exactly the wrong number... no memory
762ENDIF
763 TEST BYTE PTR [exec_func],exec_func_overlay
764 JNZ exec_set_PDB ; no starto, chumo!
765 MOV AX,[exec_DMA]
766 SUB AX,10h
767 MOV [exec_init_CS],AX
768 MOV [exec_init_IP],100h ; initial IP is 100
769 ; SI is at most FFFFh
770 DEC SI ; make room for stack
771 ; SI is at most FFFEh, room for a 0!
772 MOV [exec_init_SP],SI ; max value for read is also SP!
773 MOV [exec_init_SS],AX
774 MOV DS,AX
775 MOV WORD PTR DS:[SI],0 ; 0 for return
776
777exec_set_PDB:
778 MOV BX,[exec_fh] ; we are finished with the file.
779 CALL exec_dealloc
780IF IBM
781 MOV AH,CLOSE
782 INT int_command
783ENDIF
784IF NOT IBM
785 invoke $CLOSE ; release the jfn
786ENDIF
787 CALL exec_alloc
788 TEST BYTE PTR [exec_func],exec_func_overlay
789 JZ exec_build_header
790 transfer SYS_RET_OK ; overlay load -> done
791
792exec_build_header:
793 MOV DX,[exec_load_block]
794;
795; assign the space to the process
796;
797
798 MOV SI,arena_owner ; pointer to owner field
799
800 MOV AX,[exec_environ] ; get environ pointer
801 OR AX,AX
802 JZ NO_OWNER ; no environment
803 DEC AX ; point to header
804 MOV DS,AX
805 MOV DS:[SI],DX ; assign ownership
806NO_OWNER:
807 MOV AX,[exec_load_block] ; get load block pointer
808 DEC AX
809 MOV DS,AX ; point to header
810 MOV DS:[SI],DX ; assign ownership
811
812 PUSH DX
813IF IBM
814 MOV AH,DUP_PDB
815 INT int_command
816 MOV ES,DX
817 MOV [CurrentPDB],DX
818ENDIF
819IF NOT IBM
820 MOV BYTE PTR [CreatePDB], 0FFH ; indicate a new process
821 invoke $Dup_PDB ; ES is now PDB
822ENDIF
823 POP DX
824 PUSH [exec_environ]
825 POP ES:[PDB_environ]
826 MOV SI,[exec_size]
827 ADD SI,DX
828 MOV ES:[PDB_block_len],SI
829;
830; set up proper command line stuff
831;
832 LDS SI,DWORD PTR [exec_blk] ; get the block
833 PUSH DS ; save its location
834 PUSH SI
835 LDS SI,DS:[SI.exec0_5C_FCB] ; get the 5c fcb
836 MOV CX,12 ; copy drive, name and ext
837 PUSH CX
838 MOV DI,5Ch
839 MOV BL,DS:[SI]
840 REP MOVSB
841 XOR AX,AX ; zero extent, etc for CPM
842 STOSW
843 STOSW
844 POP CX
845 POP SI ; get block
846 POP DS
847 PUSH DS ; save (again)
848 PUSH SI
849 LDS SI,DS:[SI.exec0_6C_FCB] ; get 6C FCB
850 MOV DI,6Ch ; do same as above
851 MOV BH,DS:[SI]
852 REP MOVSB
853 STOSW
854 STOSW
855 POP SI ; get block (last time)
856 POP DS
857 LDS SI,DS:[SI.exec0_com_line] ; command line
858 MOV CX,80h
859 MOV DI,CX
860 REP MOVSB ; Wham!
861
862;
863; Process BX into default AX (validity of drive specs on args)
864;
865 DEC CL ; get 0FFh in CX
866 CMP BH,[NUMIO]
867 JBE exec_BH_good
868 MOV BH,CL
869 JMP SHORT exec_BL
870exec_BH_good:
871 XOR BH,BH
872exec_BL:
873 CMP BL,[NUMIO]
874 JBE exec_BL_good
875 MOV BL,CL
876 JMP SHORT exec_set_return
877exec_BL_good:
878 XOR BL,BL
879exec_set_return:
880 invoke get_user_stack ; get his return address
881 PUSH [SI.user_CS] ; suck out the CS and IP
882 PUSH [SI.user_IP]
883 PUSH [SI.user_CS] ; suck out the CS and IP
884 PUSH [SI.user_IP]
885 POP WORD PTR ES:[PDB_Exit]
886 POP WORD PTR ES:[PDB_Exit+2]
887 XOR AX,AX
888 MOV DS,AX
889 POP DS:[addr_int_terminate] ; save them where we can get them later
890 POP DS:[addr_int_terminate+2] ; when the child exits.
891IF NOT IBM
892 MOV WORD PTR [DMAADD],80h
893 MOV DS,[CurrentPDB]
894 MOV WORD PTR [DMAADD+2],DS
895ENDIF
896IF IBM
897 PUSH DX
898 PUSH DS
899 MOV DS,[CurrentPDB]
900 MOV DX,80h
901 MOV AH,SET_DMA
902 INT int_command
903 POP DS
904 POP DX
905ENDIF
906 TEST BYTE PTR [exec_func],exec_func_no_execute
907 JZ exec_go
908
909 LDS SI,DWORD PTR [exec_init_SP] ; get stack
910 LES DI,DWORD PTR [exec_blk] ; and block for return
911 MOV ES:[DI].exec1_SS,DS ; return SS
912
913 DEC SI ; 'push' default AX
914 DEC SI
915 MOV DS:[SI],BX ; save default AX reg
916 MOV ES:[DI].exec1_SP,SI ; return 'SP'
917
918 LDS AX,DWORD PTR [exec_init_IP]
919 MOV ES:[DI].exec1_CS,DS ; initial entry stuff
920
921 MOV ES:[DI].exec1_IP,AX
922 transfer SYS_RET_OK
923
924exec_go:
925IF IBM
926 CALL restore_ctrlc ; restore value of ctrl-c checker
927ENDIF
928 LDS SI,DWORD PTR [exec_init_IP] ; get entry point
929 CLI
930IF NOT IBM
931 MOV BYTE PTR INDOS,0
932ENDIF
933 MOV SS,[exec_init_SS] ; set up user's stack
934 ASSUME SS:NOTHING
935 MOV SP,[exec_init_SP] ; and SP
936 STI
937 PUSH DS ; fake long call to entry
938 PUSH SI
939 MOV ES,DX ; set up proper seg registers
940 MOV DS,DX
941 MOV AX,BX ; set up proper AX
942 procedure exec_long_ret,FAR
943 RET
944exec_long_ret ENDP
945
946$Exec ENDP
947
948 procedure exec_dealloc,near
949 ASSUME DS:NOTHING,ES:NOTHING
950 PUSH BX
951 MOV BX,arena_owner_system
952 CALL exec_do_change_owner
953 POP BX
954 return
955exec_dealloc ENDP
956
957 procedure exec_alloc,near
958 PUSH BX
959 MOV BX,[CurrentPDB]
960 CALL exec_do_change_owner
961 POP BX
962 return
963exec_alloc ENDP
964
965 procedure exec_do_change_owner,NEAR
966 PUSH DS
967 PUSH AX
968 MOV AX,[exec_environ]
969 OR AX,AX
970 JZ exec_alloc_try_load
971 DEC AX
972 MOV DS,AX
973 MOV DS:[arena_owner],BX
974exec_alloc_try_load:
975 MOV AX,[exec_load_block]
976 OR AX,AX
977 JZ exec_alloc_done
978 DEC AX
979 MOV DS,AX
980 MOV DS:[arena_owner],BX
981exec_alloc_done:
982 POP AX
983 POP DS
984 RET
985exec_do_change_owner ENDP
986
987IF IBM
988SYS_RET_ERR:
989 CALL get_user_stack
990 PUSH [SI.user_f]
991 XOR AH,AH
992 MOV [SI.user_AX],AX
993 POPF
994 STC
995 JMP SYS_RET
996SYS_RET_OK:
997 CALL get_user_stack
998 PUSH [SI.user_f]
999 POPF
1000 CLC
1001SYS_RET:
1002 PUSHF
1003 CALL restore_ctrlc
1004 POP [SI.user_f]
1005 JMP exec_long_ret
1006
1007;
1008; get_user_stack returns the user's stack (and hence registers) in DS:SI
1009;
1010 procedure get_user_stack,NEAR
1011 PUSH SS
1012 POP DS
1013 ASSUME DS:RESGROUP
1014 LDS SI,DWORD PTR [user_SP]
1015 RET
1016get_user_stack ENDP
1017;
1018; restore value of the ctrl-c checker
1019;
1020 procedure restore_ctrlc
1021 PUSH AX
1022 PUSH DX
1023 MOV DL,CS:[exec_ctrlc]
1024 MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 1 ; Put it back
1025 INT int_command
1026 POP DX
1027 POP AX
1028 RET
1029restore_ctrlc ENDP
1030
1031ZEXECCODESIZE EQU $-ZERO
1032ZEXECCODEEND LABEL BYTE
1033 PUBLIC ZEXECCODEEND
1034ZEXEC_CODE ENDS
1035ENDIF
diff --git a/v2.0/source/EXEMES.ASM b/v2.0/source/EXEMES.ASM
new file mode 100644
index 0000000..542ec12
--- /dev/null
+++ b/v2.0/source/EXEMES.ASM
Binary files differ
diff --git a/v2.0/source/FAT.ASM b/v2.0/source/FAT.ASM
new file mode 100644
index 0000000..b1a4863
--- /dev/null
+++ b/v2.0/source/FAT.ASM
@@ -0,0 +1,362 @@
1;
2; FAT operations for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17TITLE FAT - FAT maintenance routines
18NAME FAT
19
20 i_need CURBUF,DWORD
21 i_need CLUSSPLIT,BYTE
22 i_need CLUSSAVE,WORD
23 i_need CLUSSEC,WORD
24 i_need THISDRV,BYTE
25 i_need DEVCALL,BYTE
26 i_need CALLMED,BYTE
27 i_need CALLRBYT,BYTE
28 i_need BUFFHEAD,DWORD
29 i_need CALLXAD,DWORD
30 i_need CALLBPB,DWORD
31
32SUBTTL UNPACK -- UNPACK FAT ENTRIES
33PAGE
34
35ASSUME SS:DOSGROUP
36 procedure UNPACK,NEAR
37ASSUME DS:DOSGROUP,ES:NOTHING
38
39; Inputs:
40; BX = Cluster number
41; ES:BP = Base of drive parameters
42; Outputs:
43; DI = Contents of FAT for given cluster
44; Zero set means DI=0 (free cluster)
45; SI Destroyed, No other registers affected. Fatal error if cluster too big.
46
47 CMP BX,ES:[BP.dpb_max_cluster]
48 JA HURTFAT
49 CALL MAPCLUSTER
50ASSUME DS:NOTHING
51 MOV DI,[DI]
52 JNC HAVCLUS
53 PUSH CX
54 MOV CL,4
55 SHR DI,CL
56 POP CX
57 STC
58HAVCLUS:
59 AND DI,0FFFH
60 PUSH SS
61 POP DS
62 return
63
64HURTFAT:
65 PUSH AX
66 MOV AH,80H ; Signal Bad FAT to INT int_fatal_abort handler
67 MOV DI,0FFFH ; In case INT int_fatal_abort returns (it shouldn't)
68 invoke FATAL
69 POP AX ; Try to ignore bad FAT
70 return
71UNPACK ENDP
72
73SUBTTL PACK -- PACK FAT ENTRIES
74PAGE
75 procedure PACK,NEAR
76ASSUME DS:DOSGROUP,ES:NOTHING
77
78; Inputs:
79; BX = Cluster number
80; DX = Data
81; ES:BP = Pointer to drive DPB
82; Outputs:
83; The data is stored in the FAT at the given cluster.
84; SI,DX,DI all destroyed
85; No other registers affected
86
87 CALL MAPCLUSTER
88ASSUME DS:NOTHING
89 MOV SI,[DI]
90 JNC ALIGNED
91 PUSH CX
92 MOV CL,4
93 SHL DX,CL
94 POP CX
95 AND SI,0FH
96 JMP SHORT PACKIN
97ALIGNED:
98 AND SI,0F000H
99PACKIN:
100 OR SI,DX
101 MOV [DI],SI
102 LDS SI,[CURBUF]
103 MOV [SI.BUFDIRTY],1
104 CMP BYTE PTR [CLUSSPLIT],0
105 PUSH SS
106 POP DS
107ASSUME DS:DOSGROUP
108 retz
109 PUSH AX
110 PUSH BX
111 PUSH CX
112 MOV AX,[CLUSSAVE]
113 MOV DS,WORD PTR [CURBUF+2]
114ASSUME DS:NOTHING
115 ADD SI,BUFINSIZ
116 MOV [SI],AH
117 PUSH SS
118 POP DS
119ASSUME DS:DOSGROUP
120 PUSH AX
121 MOV DX,[CLUSSEC]
122 MOV SI,1
123 XOR AL,AL
124 invoke GETBUFFRB
125 LDS DI,[CURBUF]
126ASSUME DS:NOTHING
127 MOV [DI.BUFDIRTY],1
128 ADD DI,BUFINSIZ
129 DEC DI
130 ADD DI,ES:[BP.dpb_sector_size]
131 POP AX
132 MOV [DI],AL
133 PUSH SS
134 POP DS
135 POP CX
136 POP BX
137 POP AX
138 return
139PACK ENDP
140
141SUBTTL MAPCLUSTER - BUFFER A FAT SECTOR
142PAGE
143 procedure MAPCLUSTER,NEAR
144ASSUME DS:DOSGROUP,ES:NOTHING
145
146; Inputs:
147; ES:BP Points to DPB
148; BX Is cluster number
149; Function:
150; Get a pointer to the cluster
151; Outputs:
152; DS:DI Points to contents of FAT for given cluster
153; DS:SI Points to start of buffer
154; Carry set if cluster data is in high 12 bits of word
155; No other registers effected
156
157 MOV BYTE PTR [CLUSSPLIT],0
158 PUSH AX
159 PUSH BX
160 PUSH CX
161 PUSH DX
162 MOV AX,BX
163 SHR AX,1
164 ADD AX,BX
165 XOR DX,DX
166 MOV CX,ES:[BP.dpb_sector_size]
167 DIV CX ; AX is FAT sector # DX is sector index
168 ADD AX,ES:[BP.dpb_first_FAT]
169 DEC CX
170 PUSH AX
171 PUSH DX
172 PUSH CX
173 MOV DX,AX
174 XOR AL,AL
175 MOV SI,1
176 invoke GETBUFFRB
177 LDS SI,[CURBUF]
178ASSUME DS:NOTHING
179 LEA DI,[SI.BufInSiz]
180 POP CX
181 POP AX
182 POP DX
183 ADD DI,AX
184 CMP AX,CX
185 JNZ MAPRET
186 MOV AL,[DI]
187 PUSH SS
188 POP DS
189ASSUME DS:DOSGROUP
190 INC BYTE PTR [CLUSSPLIT]
191 MOV BYTE PTR [CLUSSAVE],AL
192 MOV [CLUSSEC],DX
193 INC DX
194 XOR AL,AL
195 MOV SI,1
196 invoke GETBUFFRB
197 LDS SI,[CURBUF]
198ASSUME DS:NOTHING
199 LEA DI,[SI.BufInSiz]
200 MOV AL,[DI]
201 PUSH SS
202 POP DS
203ASSUME DS:DOSGROUP
204 MOV BYTE PTR [CLUSSAVE+1],AL
205 MOV DI,OFFSET DOSGROUP:CLUSSAVE
206MAPRET:
207 POP DX
208 POP CX
209 POP BX
210 MOV AX,BX
211 SHR AX,1
212 POP AX
213 return
214MAPCLUSTER ENDP
215
216SUBTTL FATREAD -- CHECK DRIVE GET FAT
217PAGE
218ASSUME DS:DOSGROUP,ES:NOTHING
219
220 procedure FAT_operation,NEAR
221FATERR:
222 AND DI,STECODE ; Put error code in DI
223 MOV AH,2 ; While trying to read FAT
224 MOV AL,BYTE PTR [THISDRV] ; Tell which drive
225 invoke FATAL1
226
227 entry FATREAD
228ASSUME DS:DOSGROUP,ES:NOTHING
229
230; Function:
231; If disk may have been changed, FAT is read in and buffers are
232; flagged invalid. If not, no action is taken.
233; Outputs:
234; ES:BP = Base of drive parameters
235; All other registers destroyed
236
237 MOV AL,BYTE PTR [THISDRV]
238 invoke GETBP
239 MOV AL,DMEDHL
240 MOV AH,ES:[BP.dpb_UNIT]
241 MOV WORD PTR [DEVCALL],AX
242 MOV BYTE PTR [DEVCALL.REQFUNC],DEVMDCH
243 MOV [DEVCALL.REQSTAT],0
244 MOV AL,ES:[BP.dpb_media]
245 MOV BYTE PTR [CALLMED],AL
246 PUSH ES
247 PUSH DS
248 MOV BX,OFFSET DOSGROUP:DEVCALL
249 LDS SI,ES:[BP.dpb_driver_addr] ; DS:SI Points to device header
250ASSUME DS:NOTHING
251 POP ES ; ES:BX Points to call header
252 invoke DEVIOCALL2
253 PUSH SS
254 POP DS
255ASSUME DS:DOSGROUP
256 POP ES ; Restore ES:BP
257 MOV DI,[DEVCALL.REQSTAT]
258 TEST DI,STERR
259 JNZ FATERR
260 XOR AH,AH
261 XCHG AH,ES:[BP.dpb_first_access] ; Reset dpb_first_access
262 MOV AL,BYTE PTR [THISDRV] ; Use physical unit number
263 OR AH,BYTE PTR [CALLRBYT]
264 JS NEWDSK ; new disk or first access?
265 JZ CHKBUFFDIRT
266 return ; If Media not changed
267CHKBUFFDIRT:
268 INC AH ; Here if ?Media..Check buffers
269 LDS DI,[BUFFHEAD]
270ASSUME DS:NOTHING
271NBUFFER: ; Look for dirty buffers
272 CMP AX,WORD PTR [DI.BUFDRV]
273 retz ; There is a dirty buffer, assume Media OK
274 LDS DI,[DI.NEXTBUF]
275 CMP DI,-1
276 JNZ NBUFFER
277; If no dirty buffers, assume Media changed
278NEWDSK:
279 invoke SETVISIT
280NXBUFFER:
281 MOV [DI.VISIT],1
282 CMP AL,[DI.BUFDRV] ; For this drive?
283 JNZ SKPBUFF
284 MOV WORD PTR [DI.BUFDRV],00FFH ; Free up buffer
285 invoke SCANPLACE
286SKPBUFF:
287 invoke SKIPVISIT
288 JNZ NXBUFFER
289 LDS DI,ES:[BP.dpb_driver_addr]
290 TEST [DI.SDEVATT],ISFATBYDEV
291 JNZ GETFREEBUF
292 context DS
293 MOV BX,2
294 CALL UNPACK ; Read the first FAT sector into CURBUF
295 LDS DI,[CURBUF]
296 JMP SHORT GOTGETBUF
297GETFREEBUF:
298ASSUME DS:NOTHING
299 PUSH ES ; Get a free buffer for BIOS to use
300 PUSH BP
301 LDS DI,[BUFFHEAD]
302 invoke BUFWRITE
303 POP BP
304 POP ES
305GOTGETBUF:
306 ADD DI,BUFINSIZ
307 MOV WORD PTR [CALLXAD+2],DS
308 PUSH SS
309 POP DS
310ASSUME DS:DOSGROUP
311 MOV WORD PTR [CALLXAD],DI
312 MOV AL,DBPBHL
313 MOV AH,BYTE PTR ES:[BP.dpb_UNIT]
314 MOV WORD PTR [DEVCALL],AX
315 MOV BYTE PTR [DEVCALL.REQFUNC],DEVBPB
316 MOV [DEVCALL.REQSTAT],0
317 MOV AL,BYTE PTR ES:[BP.dpb_media]
318 MOV [CALLMED],AL
319 PUSH ES
320 PUSH DS
321 PUSH WORD PTR ES:[BP.dpb_driver_addr+2]
322 PUSH WORD PTR ES:[BP.dpb_driver_addr]
323 MOV BX,OFFSET DOSGROUP:DEVCALL
324 POP SI
325 POP DS ; DS:SI Points to device header
326ASSUME DS:NOTHING
327 POP ES ; ES:BX Points to call header
328 invoke DEVIOCALL2
329 POP ES ; Restore ES:BP
330 PUSH SS
331 POP DS
332ASSUME DS:DOSGROUP
333 MOV DI,[DEVCALL.REQSTAT]
334 TEST DI,STERR
335 JNZ FATERRJ
336 MOV AL,BYTE PTR ES:[BP.dpb_media]
337 LDS SI,[CALLBPB]
338ASSUME DS:NOTHING
339 CMP AL,BYTE PTR [SI.BPMEDIA]
340 JZ DPBOK
341 invoke $SETDPB
342 LDS DI,[CALLXAD] ; Get back buffer pointer
343 MOV AL,BYTE PTR ES:[BP.dpb_FAT_count]
344 MOV AH,BYTE PTR ES:[BP.dpb_FAT_size]
345 MOV WORD PTR [DI.BUFWRTCNT-BUFINSIZ],AX ;Correct buffer info
346DPBOK:
347 context ds
348 MOV AX,-1
349 TEST ES:[BP.dpb_current_dir],AX
350 retz ; If root, leave as root
351 MOV ES:[BP.dpb_current_dir],AX ; Path may be bad, mark invalid
352 return
353
354FATERRJ: JMP FATERR
355
356FAT_operation ENDP
357
358do_ext
359
360CODE ENDS
361 END
362
diff --git a/v2.0/source/FC.ASM b/v2.0/source/FC.ASM
new file mode 100644
index 0000000..21ed991
--- /dev/null
+++ b/v2.0/source/FC.ASM
@@ -0,0 +1,1684 @@
1 title File Compare Routine for MSDOS 2.0
2
3;-----------------------------------------------------------------------;
4; Revision History: ;
5; ;
6; V1.0 Rev. 0 10/27/82 M.A.Ulloa ;
7; ;
8; Rev. 1 10/28/82 M.A.Ulloa ;
9; Changed switch names and added binary compare using the ;
10; -b switch. ;
11; ;
12; Rev. 1 11/4/82 A.R. Reynolds ;
13; Messages in separate module ;
14; Also added header for MSVER ;
15; ;
16; Rev. 2 11/29/82 M.A. Ulloa ;
17; Corrected sysntex problem with references to [base...] ;
18; ;
19; Rev. 3 01/03/83 M.A. Ulloa ;
20; Stack is right size now. ;
21; ;
22;-----------------------------------------------------------------------;
23
24FALSE equ 0
25TRUE equ 0ffh
26
27
28buf_size equ 4096 ;buffer size
29
30
31;-----------------------------------------------------------------------;
32; Description ;
33; ;
34; FC [-# -b -w -c] <file1> <file2> ;
35; ;
36; Options: ;
37; ;
38; -# were # is a number from 1 to 9, how many lines have to ;
39; before the end of an area of difference ends. ;
40; ;
41; -b will force a binary comparation of both files. ;
42; ;
43; -w will cause all spaces and tabs to be compressed to a single ;
44; space before comparing. All leading and trailing spaces and/or tabs ;
45; in a line are ignored. ;
46; ;
47; -c will cause FC to ignore the case of the letters. ;
48; ;
49; Algorithm for text compare: (The one for binary comp. is trivial) ;
50; ;
51; The files are read into two separate buffers and the ;
52; comparation starts. If two lines are found to be different in the ;
53; two buffers, say line i of buffer A and line j of buffer B differ. ;
54; The program will try to match line i with line j+1, then with line ;
55; j+2 and so on, if the end of buffer is reached the program will ;
56; recompact the buffer and try to read more lines into the buffer, if ;
57; no more lines can be read because either the buffer is full, or the ;
58; end of file was reached, then it will revert and try to match line ;
59; j of buffer B to line i+1, i+2 and so on of buffer A. If an end of ;
60; buffer is found, it tries to refill it as before. If no matches are ;
61; found, then it will try to match line i+1 of buffer A to line j+1, ;
62; j+2, j+3, .... of buffer B, if still no matches are found, it reverts ;
63; again and tries to match line j+1 of buffer B with lines i+2, i+3,... ;
64; of buffer A. And so on till a match is found. ;
65; ;
66; Once a match is found it continues chcking pairs of lines till ;
67; the specified number are matched (option #, 3 by default), and then ;
68; it prints the differing area in both files, each followed by the ;
69; first line matched. ;
70; ;
71; If no match is found (the difference is bigger than the buffer) ;
72; a "files different" message is printed. ;
73; ;
74; If one of the files finishes before another the remaining ;
75; portion of the file (plus any ongoing difference) is printed out. ;
76; ;
77;-----------------------------------------------------------------------;
78
79
80 subttl Debug Macros
81 page
82
83m_debug macro str
84 local a,b
85 jmp short b
86a db str,0dh,0ah,"$"
87b: pushf
88 push dx
89 mov dx,offset code:a
90 push ds
91 push cs
92 pop ds
93 push ax
94 mov ah,9h
95 int 21h
96 pop ax
97 pop ds
98 pop dx
99 popf
100 endm
101
102
103m_bname macro
104 local a0,a1,a2,b1,b2
105 jmp short a0
106b1 db "------ buffer 1",0dh,0ah,"$"
107b2 db "------ buffer 2",0dh,0ah,"$"
108a0: pushf
109 push dx
110 cmp bx,offset dg:buf1
111 je a1
112 mov dx,offset code:b2
113 jmp short a2
114a1: mov dx,offset code:b1
115a2: push ds
116 push cs
117 pop ds
118 push ax
119 mov ah,9h
120 int 21h
121 pop ax
122 pop ds
123 pop dx
124 popf
125 endm
126
127
128 page
129
130 .SALL
131 .XLIST
132 include dossym.asm
133 .LIST
134
135 subttl General Definitions
136 page
137
138CR equ 0dh
139LF equ 0ah
140
141
142;-----------------------------------------------------------------------;
143; Offsets to buffer structure
144; For text comparations:
145
146fname equ 0 ;file name ptr
147fname_len equ 2 ;file name length
148handle equ 4 ;handle
149curr equ 6 ;current line ptr
150lst_curr equ 8 ;last current line ptr
151fst_sinc equ 10 ;first line towards a sinc ptr
152fst_nosinc equ 12 ;first line out of sinc ptr
153dat_end equ 14 ;ptr to last char of the buffer
154buf_end equ 16 ;pointer to the end of the buffer
155buf equ 18 ;pointer to the buffer
156
157; For binary comparations:
158
159by_read equ 6 ;bytes read into buffer
160
161;-----------------------------------------------------------------------;
162
163
164code segment word
165code ends
166
167const segment public word
168const ends
169
170data segment word
171data ends
172
173dg group code,const,data
174
175
176 subttl Constants Area
177 page
178
179const segment public word
180
181make db "MAUlloa/Microsoft/V10"
182rev db "2"
183
184;----- CAREFULL WITH PRESERVING THE ORDER OF THE TABLE -----
185opt_tbl equ $ ;option table
186
187flg_b db FALSE
188flg_c db FALSE
189flg_s db FALSE
190flg_w db FALSE
191;-----------------------------------------------------------
192
193ib_first1 db FALSE ;flags used when comparing lines
194ib_first2 db FALSE ; while in ignore white mode.
195
196m_num dw 3 ;lines that have to match before
197 ; reporting a match
198
199mtch_cntr dw 0 ;matches towards a sinc
200
201mode db FALSE ;If false then trying to match a line
202 ; from buf1 to lines in buf2. If true
203 ; then viceversa.
204
205sinc db TRUE ;Sinc flag, start IN SINC
206
207bend db 0 ;binary end of file flag, 0= none yet,
208 ; 1= file 1 ended, 2= file 2 ended
209
210base dd 0 ;base address of files for binary
211 ; comparations
212
213bhead_flg db false ;true if heading for binary comp.
214 ; has been printed already.
215
216;-----------------------------------------------------------
217bp_buf equ $ ;binary compare difference template
218
219bp_buf1 db 8 dup(' ') ;file address
220 db 3 dup(' ')
221bp_buf2 db 2 dup(' ') ;byte of file 1
222 db 3 dup(' ')
223bp_buf3 db 2 dup(' ') ;byte of file 1
224 db CR,LF
225
226bp_buf_len equ $ - bp_buf ;length of template
227;-----------------------------------------------------------
228
229 EXTRN vers_err:byte,opt_err:byte,opt_e:byte,crlf:byte,opt_err_len:byte
230 EXTRN bhead_len:byte
231 EXTRN found_err_pre:byte,found_err_pre_len:byte
232 EXTRN found_err_post:byte,found_err_post_len:byte
233 EXTRN read_err_pre:byte,read_err_pre_len:byte
234 EXTRN read_err_post:byte,read_err_post_len:byte
235 EXTRN file_err:byte,file_err_len:byte
236 EXTRN bf1ne:byte,bf1ne_len:byte,bf2ne:byte,bf2ne_len:byte,bhead:byte
237 EXTRN int_err:byte,int_err_len:byte,dif_err:byte,dif_err_len:byte
238 EXTRN args_err:byte,args_err_len:byte,fname_sep:byte,fname_sep_len:byte
239 EXTRN diff_sep:byte,diff_sep_len:byte
240
241const ends
242
243
244
245 subttl Data Area
246 page
247
248data segment word
249
250com_buf db 128 dup(?) ;command line buffer
251
252;----- Buffer structures
253buf1 dw 11 dup(?)
254buf2 dw 11 dup(?)
255
256; two extra for guard in case of need to insert a CR,LF pair
257b1 db buf_size dup(?)
258end_b1 db 2 dup(?)
259b2 db buf_size dup(?)
260end_b2 db 2 dup(?)
261
262data ends
263
264
265
266 subttl MAIN Routine
267 page
268
269code segment
270assume cs:dg,ds:nothing,es:nothing,ss:stack
271
272start:
273 jmp short FCSTRT
274;-----------------------------------------------------------------------;
275; Check version number
276
277HEADER DB "Vers 1.00"
278
279FCSTRT:
280;Code to print header
281; PUSH DS
282; push cs
283; pop ds
284; MOV DX,OFFSET DG:HEADER
285; mov ah,std_con_string_output
286; int 21h
287; POP DS
288
289 mov ah,get_version
290 int 21h
291 cmp al,2
292 jge vers_ok
293 mov dx,offset dg:vers_err
294 mov ah,std_con_string_output
295 int 21h
296 push es ;bad vers, exit a la 1.x
297 xor ax,ax
298 push ax
299
300badvex proc far
301 ret
302badvex endp
303
304
305vers_ok:
306 push cs
307 pop es
308
309assume es:dg
310
311;-----------------------------------------------------------------------;
312; Copy command line
313
314 mov si,80h ;command line address
315 cld
316 lodsb ;get char count
317 mov cl,al
318 xor ch,ch
319 inc cx ;include the CR
320 mov di,offset dg:com_buf
321 cld
322 rep movsb
323
324 push cs
325 pop ds
326
327assume ds:dg
328
329
330
331;-----------------------------------------------------------------------;
332; Initialize buffer structures
333
334 mov bx,offset dg:buf1
335 mov word ptr [bx].buf,offset dg:b1
336 mov word ptr [bx].buf_end,offset dg:end_b1
337 mov bx,offset dg:buf2
338 mov word ptr [bx].buf,offset dg:b2
339 mov word ptr [bx].buf_end,offset dg:end_b2
340
341
342;-----------------------------------------------------------------------;
343; Process options
344
345 mov ah,char_oper
346 mov al,0
347 int 21h ;get switch character
348 mov si,offset dg:com_buf
349
350cont_opt:
351 call kill_bl
352 jc bad_args ;arguments missing
353 cmp al,dl ;switch character?
354 jne get_file ;no, process file names
355 cld
356 lodsb ;get option
357 call make_caps ;capitalize option
358 mov bx,offset dg:opt_tbl
359
360 cmp al,'B'
361 je b_opt
362 cmp al,'C'
363 je c_opt
364 cmp al,'S'
365 je s_opt
366 cmp al,'W'
367 je w_opt
368 cmp al,'1' ;a number option?
369 jb bad_opt
370 cmp al,'9'
371 ja bad_opt
372 and al,0fh ;a number option, convert to binary
373 xor ah,ah ;zero high nibble
374 mov [m_num],ax
375 jmp short cont_opt
376
377bad_opt: ;a bad option:
378 push dx ; save switch character
379 mov [opt_e],al ; option in error
380 mov dx,offset dg:opt_err
381 mov cl,opt_err_len
382 call prt_err ; print error message
383 pop dx
384 jmp short cont_opt ; process rest of options
385
386b_opt:
387 mov di,0
388 jmp short opt_dispatch
389
390c_opt:
391 mov di,1
392 jmp short opt_dispatch
393
394s_opt:
395 mov di,2
396 jmp short opt_dispatch
397
398w_opt:
399 mov di,3
400
401opt_dispatch:
402 mov byte ptr dg:[bx+di],TRUE ;set the corresponding flag
403 jmp short cont_opt
404
405
406bad_args:
407 mov dx,offset dg:args_err
408 mov cl,args_err_len
409 jmp an_err
410
411
412
413;-----------------------------------------------------------------------;
414; Get the file names
415
416get_file:
417 dec si ;adjust pointer
418 call find_nonb ;find first non blank in com. buffer
419 jc bad_args ;file (or files) missing
420 mov byte ptr [di],0 ;nul terminate
421 mov dx,si ;pointer to file name
422 mov bx,offset dg:buf1
423 mov word ptr [bx].fname,dx ;save pointer to file name
424 mov word ptr [bx].fname_len,cx ;file name length
425 mov ah,open
426 mov al,0 ;open for reading
427 int 21h
428 jc bad_file
429 mov word ptr [bx].handle,ax ;save the handle
430
431 mov si,di
432 inc si ;point past the nul
433 call kill_bl ;find other file name
434 jc bad_args ;a CR found: file name missing
435 dec si ;adjust pointer
436 call find_nonb
437 mov byte ptr [di],0 ;nul terminate the file name
438 mov dx,si
439 mov bx,offset dg:buf2
440 mov word ptr [bx].fname,dx ;save pointer to file name
441 mov word ptr [bx].fname_len,cx ;file name length
442 mov ah,open
443 mov al,0 ;open for reading
444 int 21h
445 jc bad_file
446 mov word ptr [bx].handle,ax ;save the handle
447 jmp short go_compare
448
449bad_file:
450 cmp ax,error_file_not_found
451 je sj01
452 mov dx,offset dg:int_err
453 mov cl,int_err_len
454 jmp short an_err
455sj01:
456 push cx ;save file name length
457 mov dx,offset dg:found_err_pre
458 mov cl,found_err_pre_len
459 call prt_err
460 pop cx
461 mov dx,si ;pointer to file name length
462 call prt_err
463 mov dx,offset dg:found_err_post
464 mov cl,found_err_post_len
465an_err:
466 call prt_err
467 mov al,-1 ;return an error code
468 mov ah,exit
469 int 21h
470
471
472
473;-----------------------------------------------------------------------;
474; CHECK COMPARE MODE
475
476go_compare:
477 cmp [flg_b],true ;do we do a binary comparation?
478 je bin_compare
479 jmp txt_compare
480
481
482 subttl Binary Compare Routine
483 page
484
485;-----------------------------------------------------------------------;
486; COMPARE BUFFERS IN BINARY MODE
487
488bin_compare:
489
490;----- Fill in the buffers
491
492 mov bx,offset dg:buf1 ;pointer to buffer structure
493 mov dx,word ptr[bx].buf ;pointer to buffer
494 mov si,dx ;save for latter comparation
495 call read_dat ;read into buffer
496 jc bad_datj ;an error
497 mov word ptr[bx].by_read,AX ;save ammount read
498 push ax ;save for now
499
500 mov bx,offset dg:buf2 ;pointer to buffer structure
501 mov dx,word ptr[bx].buf ;pointer to buffer
502 mov di,dx ;save for comparation
503 call read_dat ;read into buffer
504bad_datj: jc bad_dat ;an error
505 mov word ptr[bx].by_read,AX ;save ammount read
506
507 pop cx ;restore byte count of buffer1
508 cmp ax,cx ;compare byte counts
509 ja morein_b2
510 jb morein_b1
511 or ax,ax ;the same ammount, is it 0?
512 jne go_bcomp ;no,compare
513 jmp go_quit ;yes, all done....
514
515morein_b2:
516 mov [bend],1 ;file 1 ended
517 jmp short go_bcomp
518
519morein_b1:
520 mov [bend],2 ;file 2 ended
521 mov cx,ax
522
523;----- Compare data in buffers
524
525go_bcomp:
526 mov ax,word ptr [base] ;load base addrs. to AX,BX pair
527 mov bx,word ptr [base+2]
528 add bx,cx ;add to base num. of bytes to
529 adc ax,0 ; compare.
530 mov word ptr [base],ax ;save total
531 mov word ptr [base+2],bx
532
533next_bcomp:
534 cld
535 jcxz end_check
536 repz cmpsb ;compare both buffers
537 jz end_check ;all bytes match
538 push cx ;save count so far
539 push ax
540 push bx
541 inc cx
542 sub bx,cx ;get file address of bytes that
543 sbb ax,0 ; are different.
544 call prt_bdif ;print difference
545 pop bx
546 pop ax
547 pop cx ;restore on-going comparation count
548 jmp short next_bcomp
549
550bnot_yet:
551 jmp bin_compare
552
553end_check:
554 cmp [bend],0 ;have any file ended yet?
555 je bnot_yet ;no, read in more data
556 cmp [bend],1 ;yes, was it file 1?
557 je bf1_ended ;yes, data left in file 2
558 mov dx,offset dg:bf1ne
559 mov cl,bf1ne_len
560 jmp short bend_mes
561
562bf1_ended:
563 mov dx,offset dg:bf2ne
564 mov cl,bf2ne_len
565
566bend_mes:
567 xor ch,ch
568 call prout
569 jmp go_quit
570
571
572
573 subttl Text Compare Routine
574 page
575
576;-----------------------------------------------------------------------;
577; Fill in the buffers
578
579bad_dat:
580 mov dx,offset dg:file_err
581 mov cl,file_err_len
582 jmp an_err
583
584
585txt_compare:
586
587 mov bx,offset dg:buf1
588 mov dx,word ptr [bx].buf
589 mov word ptr [bx].fst_nosinc,dx
590 mov word ptr [bx].curr,dx
591
592 call fill_buffer
593 jc bad_dat
594
595 mov bx,offset dg:buf2
596 mov dx,word ptr [bx].buf
597 mov word ptr [bx].fst_nosinc,dx
598 mov word ptr [bx].curr,dx
599
600 call fill_buffer
601 jc bad_dat
602
603
604;-----------------------------------------------------------------------;
605; COMPARE BUFFERS IN TEXT MODE
606
607another_line:
608 call go_match ;try to match both current lines
609 jc sj02 ;a match
610 jmp no_match ;no match, continue....
611sj02:
612 cmp byte ptr[sinc],true ;are we in SINC?
613 je sj04
614 mov ax,[mtch_cntr]
615 or ax,ax ;first line of a possible SINC?
616 jnz sj03
617 mov bx,offset dg:buf1
618 mov word ptr [bx].fst_sinc,si ;yes, save curr line buffer 1
619 mov bx,offset dg:buf2
620 mov word ptr [bx].fst_sinc,di ;save curr line buffer 2
621sj03:
622 inc ax ;increment match counter
623 mov [mtch_cntr],ax ;save number of matches
624 cmp m_num,ax ;enough lines matched for a SINC?
625 jne sj04 ;not yet, match some more
626 mov [sinc],true ;yes, flag we are now in sinc
627 call print_diff ;print mismatched lines
628
629
630
631;-----------------------------------------------------------------------;
632; Advance current line pointer in both buffers
633
634sj04:
635 mov bx,offset dg:buf1
636 call adv_b
637 jnc sj05
638 jmp no_more1
639sj05:
640 mov word ptr[bx].curr,si
641 mov bx,offset dg:buf2
642 call adv_b
643 jnc sj051
644 jmp no_more2
645sj051:
646 mov word ptr[bx].curr,si
647 jmp another_line ;continue matching
648
649
650
651;-----------------------------------------------------------------------;
652; Process a mismatch
653
654no_match:
655 cmp [sinc],true ;are we in SINC?
656 jne sj06
657 mov [sinc],false ;not any more....
658 mov bx,offset dg:buf1
659 mov word ptr [bx].fst_nosinc,si ;save current lines
660 mov word ptr [bx].lst_curr,si
661 mov bx,offset dg:buf2
662 mov word ptr [bx].fst_nosinc,di
663 mov word ptr [bx].lst_curr,di
664sj06:
665 mov [mtch_cntr],0 ;reset match counter
666 cmp [mode],true
667 je sj09
668
669;----- MODE A -----
670 mov bx,offset dg:buf2
671 call adv_b ;get next line in buffer (or file)
672 jc sj08 ;no more lines in buffer
673sj07:
674 mov word ptr [bx].curr,si
675 jmp another_line
676sj08:
677 mov [mode],true ;change mode
678 mov si,word ptr [bx].lst_curr
679 mov word ptr [bx].curr,si
680 mov bx,offset dg:buf1
681 mov si,word ptr [bx].lst_curr
682 mov word ptr [bx].curr,si
683 call adv_b ;get next line
684 jc no_more1 ;no more lines fit in buffer 1
685 mov word ptr [bx].lst_curr,si
686 jmp short sj10
687
688;----- MODE B -----
689sj09:
690 mov bx,offset dg:buf1
691 call adv_b ;get next line in buffer (or file)
692 jc sj11 ;no more lines in buffer
693sj10:
694 mov word ptr [bx].curr,si
695 jmp another_line
696
697sj11:
698 mov [mode],false
699 mov si,word ptr [bx].lst_curr
700 mov word ptr [bx].curr,si
701 mov bx,offset dg:buf2
702 mov si,word ptr [bx].lst_curr
703 mov word ptr [bx].curr,si
704 call adv_b ;get next line
705 jc no_more2 ;no more lines fit in buffer 2
706 mov word ptr [bx].lst_curr,si
707 jmp sj07
708
709
710
711;-----------------------------------------------------------------------;
712; Process end of files
713
714no_more1:
715 cmp ax,0 ;end of file reached?
716 jz xj1
717 jmp dif_files ;no, difference was too big
718xj1:
719 cmp [sinc],true ;file1 ended, are we in SINC?
720 je xj3
721 jmp no_sinc
722xj3:
723 mov bx,offset dg:buf2
724 call adv_b ;advance current line in buf2
725 jnc xj5
726 jmp go_quit ;file2 ended too, terminate prog.
727xj5:
728
729;----- File 1 ended but NOT file 2
730 mov bx,offset dg:buf1
731 call print_head
732 mov bx,offset dg:buf2
733 call print_head
734 call print_all ;print the rest of file2
735 jmp go_quit
736
737
738no_more2:
739 cmp ax,0 ;end of file reached?
740 jz xj2
741 jmp dif_files ;no, difference was too big
742xj2:
743 cmp [sinc],true ;file1 ended, are we in SINC?
744 je xj4
745 jmp no_sinc
746xj4:
747 mov bx,offset dg:buf1
748 call adv_b ;advance current line in buf2
749 jnc xj6
750 jmp go_quit ;file2 ended too, terminate prog.
751xj6:
752
753;----- File 2 ended but NOT file 1
754 mov bx,offset dg:buf1
755 call print_head
756 call print_all ;print the rest of file1
757 mov bx,offset dg:buf2
758 call print_head
759 jmp go_quit
760
761
762
763no_sinc:
764 mov bx,offset dg:buf1
765 call print_head
766 call print_all
767 mov bx,offset dg:buf2
768 call print_head
769 call print_all
770 jmp go_quit
771
772
773
774dif_files:
775 mov dx,offset dg:dif_err
776 mov cl,dif_err_len
777 jmp an_err
778
779go_quit:
780 mov al,0
781 mov ah,exit
782 int 21h
783
784
785 subttl Subroutines: make caps
786 page
787
788;-----------------------------------------------------------------------;
789; CAPIALIZES THE CHARACTER IN AL ;
790; ;
791; entry: ;
792; AL has the character to Capitalize ;
793; ;
794; exit: ;
795; AL has the capitalized character ;
796; ;
797; Called from MAIN and go_match ;
798;-----------------------------------------------------------------------;
799make_caps:
800 cmp al,'a'
801 jb sa1
802 cmp al,'z'
803 jg sa1
804 and al,0dfh
805sa1: ret
806
807
808 subttl Subroutines: kill_bl
809 page
810
811;-----------------------------------------------------------------------;
812; Get rid of blanks in command line. ;
813; ;
814; entry: ;
815; SI points to the first character on the line to scan. ;
816; ;
817; exit: ;
818; SI points to the next char after the first non-blank ;
819; char found. ;
820; Carry Set if a CR found ;
821; ;
822; modifies: ;
823; SI and AX ;
824; ;
825; Called from MAIN ;
826;-----------------------------------------------------------------------;
827kill_bl:
828 cld ;increment
829sb1: lodsb ;get rid of blanks
830 cmp al,' '
831 je sb1
832 cmp al,9
833 je sb1
834 cmp al,CR
835 clc ;assume not a CR
836 jne sb2
837 stc ;a CR found, set carry
838sb2: ret
839
840
841 subttl Subroutines: find_nonb
842 page
843
844;-----------------------------------------------------------------------;
845; Find the first non-blank in a line ;
846; ;
847; entry: ;
848; SI points to the line buffer ;
849; ;
850; exit: ;
851; DI pointer to the first blank found (incl. CR) ;
852; CX character count of non-blanks ;
853; Carry Set if a CR was found ;
854; ;
855; modifies: ;
856; AX ;
857; ;
858; Called from MAIN ;
859;-----------------------------------------------------------------------;
860find_nonb:
861 push si ;save pointer
862 xor cx,cx ;zero character count
863 cld
864sc1:
865 lodsb
866 cmp al,' '
867 je sc2
868 cmp al,9
869 je sc2
870 cmp al,CR
871 je sc2
872 inc cx ;inc character count
873 jmp short sc1
874sc2:
875 dec si
876 mov di,si
877 pop si
878 cmp al,CR
879 jne sc3
880 stc
881 ret
882sc3:
883 clc
884 ret
885
886
887 subttl Subroutines: prt_bdif
888 page
889
890;-----------------------------------------------------------------------;
891; Print a binary difference ;
892; ;
893; entry: ;
894; AX,BX file address of diference ;
895; SI pointer to one past byte in buffer1 ;
896; DI pointer to one past byte in buffer2 ;
897; ;
898; modifies: ;
899; AX, DX and CX ;
900; ;
901; called from bin_compare ;
902;-----------------------------------------------------------------------;
903prt_bdif:
904 cmp [bhead_flg],true ;have we peinted head yet?
905 je bhead_ok
906 mov [bhead_flg],true ;no, set flag
907 push ax ;print heading
908 mov dx,offset dg:bhead
909 mov cl,bhead_len
910 xor ch,ch
911 call prout
912 pop ax
913
914bhead_ok:
915 mov dx,di ;conver file address
916 mov di,offset dg:bp_buf1
917 push ax
918 mov al,ah
919 call bin2hex
920 pop ax
921 call bin2hex
922 mov al,bh
923 call bin2hex
924 mov al,bl
925 call bin2hex
926
927 mov di,offset dg:bp_buf2 ;convert byte from file 1
928 mov al, byte ptr[si-1]
929 call bin2hex
930
931 mov di,offset dg:bp_buf3 ;convert byte from file 2
932 push si
933 mov si,dx
934 mov al, byte ptr[si-1]
935 pop si
936 call bin2hex
937
938 mov di,dx ;print result
939 mov dx,offset dg:bp_buf
940 mov cx,bp_buf_len
941 call prout
942 ret
943
944
945 subttl Subroutines: bin2hex
946 page
947
948;-----------------------------------------------------------------------;
949; Binary to ASCII hex conversion ;
950; ;
951; entry: ;
952; AL byte to convert ;
953; DI pointer to were the two result ASCII bytes should go ;
954; ;
955; exit: ;
956; DI points to one past were the last result byte whent ;
957; ;
958; modifies: ;
959; AH and CL ;
960; ;
961; Called from prt_bdif ;
962;-----------------------------------------------------------------------;
963bin2hex:
964 mov cl,4
965 ror ax,cl ;get the high nibble
966 and al,0fh ;mask of high nible
967 call pt_hex
968 rol ax,cl ;get the low nibble
969 and al,0fh ;mask....
970
971pt_hex:
972 cmp al,0ah ;is it past an A ?
973 jae pasta
974 add al,30h
975 jmp short put_hex
976pasta:
977 add al,37h
978put_hex:
979 stosb ;place in buffer
980 ret
981
982
983 subttl Subroutines: go_match
984 page
985
986;-----------------------------------------------------------------------;
987; Match current lines ;
988; ;
989; exit: ;
990; Carry set if the match reset otherwise ;
991; SI Current line of buff1 ;
992; DI Current line of buff2 ;
993; ;
994; ;
995; modifies: ;
996; AX,BX,CX,DX and BP ;
997; ;
998; Called from txt_compare ;
999;-----------------------------------------------------------------------;
1000go_match:
1001 mov bx,offset dg:buf1
1002 mov si,word ptr[bx].curr
1003 push si
1004 mov bp,si ;save line pointer
1005 call find_eol
1006 mov dx,cx ;save length of line
1007 mov bx,offset dg:buf2
1008 mov si,word ptr[bx].curr
1009 push si
1010 mov di,si
1011 call find_eol
1012 cmp cx,dx ;compare lengths
1013 jne sd1 ;they do not match
1014 mov si,bp ;restore line pointer
1015 jcxz sd4 ;both length = 0, they match
1016 push cx ;save the length
1017 cld
1018 repz cmpsb ;compare strings
1019 pop cx ;restore the length
1020 jz sd4 ;they match
1021sd1:
1022 cmp [flg_w],true ;do we ignore multiple whites?
1023 je ib_compare ;yes, go compare
1024 cmp [flg_c],true ;do we ignore case differences?
1025 je ic_compare ;yes, go compare
1026sd3:
1027 clc ;they don't match
1028 jmp short sd5
1029sd4:
1030 stc
1031sd5:
1032 pop di ;curr2
1033 pop si ;curr1
1034 ret
1035
1036
1037 page
1038
1039;-----------------------------------------------------------------------;
1040; Compare ignoring case differences.
1041
1042ic_compare:
1043 pop di ;get pointer to lines
1044 pop si
1045 push si ;re-save pointers
1046 push di
1047sd8:
1048 mov al,byte ptr [si] ;get next char. of first line
1049 call make_caps
1050 mov bl,al ;save capitalized char
1051 mov al,byte ptr [di] ;get next chra. of second line
1052 call make_caps
1053 cmp al,bl
1054 jne sd3 ;they do not match....
1055 inc si ;advance pointers
1056 inc di
1057 loop sd8 ;loop for the line lengths
1058 jmp short sd4 ;they match
1059
1060
1061 page
1062
1063;-----------------------------------------------------------------------;
1064; Compare compressing whites and ignoring case differences if
1065; desired too.
1066
1067ib_compare:
1068 mov [ib_first1],true ;we start by the first char in the
1069 mov [ib_first2],true ; in the lines.
1070 pop di ;get pointer to lines
1071 pop si
1072 push si ;re-save pointers
1073 push di
1074sd9:
1075 mov al,byte ptr [si] ;get next char. of first line
1076 call isa_white ;is it a white?
1077 jnc sd12 ;no, compare....
1078sd10:
1079 mov al,byte ptr [si+1] ;peek to next,
1080 call isa_white ; it is a white too?
1081 jnc sd11
1082 inc si ; yes,
1083 jmp short sd10 ; compress all whites to a blank
1084sd11:
1085 cmp [ib_first1],true ;is this the first char. of the line?
1086 jne sd111 ;no, it stays a white
1087 inc si ;ignore the white
1088 jmp short sd12
1089sd111:
1090 cmp al,CR ;is this the last char. of the line
1091 jne sd112 ;no, it stays a white
1092 inc si ;yes, ignore the whites
1093 jmp short sd12
1094sd112:
1095 mov al,' ' ;no more whites found
1096
1097sd12:
1098 cmp [ib_first1],true ;is this the first char. of the line?
1099 jne sd121 ;no, continue
1100 mov [ib_first1],false ;yes, reset the flag
1101sd121:
1102 cmp [flg_c],true ;do we ignore case?
1103 jne sd122 ;no,....
1104 call make_caps
1105sd122:
1106 mov bl,al ;save char
1107 mov al,byte ptr [di] ;get next chra. of second line
1108 call isa_white
1109 jnc sd15
1110sd13:
1111 mov al,byte ptr [di+1] ;peek to next as before
1112 call isa_white
1113 jnc sd14
1114 inc di
1115 jmp short sd13
1116sd14:
1117 cmp [ib_first2],true ;is this the first char. of the line?
1118 jne sd141 ;no, it stays a white
1119 inc di ;ignore the white
1120 jmp short sd15
1121sd141:
1122 cmp al,CR ;is this the last char. of the line
1123 jne sd142 ;no, it stays a white
1124 inc si ;yes, ignore the whites
1125 jmp short sd15
1126sd142:
1127 mov al,' '
1128
1129sd15:
1130 cmp [ib_first2],true ;is this the first char. of the line?
1131 jne sd151 ;no, continue
1132 mov [ib_first2],false ;yes, reset the flag
1133sd151:
1134 cmp [flg_c],true ;do we ignore case?
1135 jne sd152 ;no,....
1136 call make_caps
1137sd152:
1138 cmp al,bl
1139 je sd153
1140 jmp sd3 ;they do not match....
1141sd153:
1142 cmp al,CR ;have we reached the end?
1143 jne sd154 ;no, continue....
1144 jmp sd4 ;yes, they match
1145sd154:
1146 inc si ;no, advance pointers
1147 inc di
1148 jmp sd9 ;loop for the line lengths
1149
1150
1151isa_white:
1152 cmp al,' ' ;is it a space?
1153 je sdx1
1154 cmp al,09h ;is it a tab?
1155 je sdx1
1156 clc ;if not a white return with carry clear
1157 ret
1158sdx1:
1159 stc ;is a white return with carry set
1160 ret
1161
1162
1163 page
1164
1165;-----------------------------------------------------------------------;
1166find_eol:
1167 xor cx,cx ;zero count
1168 cld
1169sd6:
1170 lodsb
1171 cmp al,CR
1172 je sd7
1173 inc cx
1174 jmp short sd6
1175sd7:
1176 ret
1177
1178
1179 subttl Subroutines: adv_b
1180 page
1181
1182;-----------------------------------------------------------------------;
1183; Get the next line in the buffer ;
1184; ;
1185; It will attempt to get the next current line from the buffer ;
1186; if it fails, it will force a refill, and if some data is read in ;
1187; then it will return the next current line. ;
1188; ;
1189; entry: ;
1190; BX pointer to buffer structure ;
1191; ;
1192; exit: ;
1193; SI pointer to next line (if any) ;
1194; Carry set if no more lines available. If carry set then: ;
1195; AX End Code: 0 = end of file reached ;
1196; 1 = no room in buffer for a line ;
1197; ;
1198; modifies: ;
1199; CX,DX and DI ;
1200; ;
1201; Called from txt_compare ;
1202;-----------------------------------------------------------------------;
1203adv_b:
1204 call get_nextl
1205 jc se1
1206 ret
1207se1:
1208 call refill
1209 jnc se0
1210 ret
1211se0:
1212 call get_nextl
1213 ret
1214
1215
1216 subttl Subroutines: get_nextl
1217 page
1218
1219;-----------------------------------------------------------------------;
1220; Returns the next line in a buffer ;
1221; (next from current or next from pointer) ;
1222; ;
1223; entry: ;
1224; BX pointer to buffer structure ;
1225; (SI pointer to line, if calling get_next) ;
1226; ;
1227; exit: ;
1228; SI pointer to next line ;
1229; Carry set if no more lines available ;
1230; ;
1231; modifies: ;
1232; DI and CX ;
1233; ;
1234; Called from adv_b and print_diff (in the case of get_next) ;
1235;-----------------------------------------------------------------------;
1236get_nextl:
1237 mov si,word ptr [bx].curr
1238get_next:
1239 mov cx,word ptr [bx].dat_end
1240 sub cx,si
1241 mov di,si
1242 mov al,LF
1243 cld
1244 repnz scasb
1245 mov si,di ;pointer to next line
1246 jnz se2 ;not found
1247 clc
1248 ret
1249se2:
1250 inc si ;point past the LF
1251 stc
1252 ret
1253
1254
1255 subttl Subroutines: refill
1256 page
1257
1258;-----------------------------------------------------------------------;
1259; Refill a buffer ;
1260; ;
1261; It will refill a buffer with data from the corresponding ;
1262; file. It will first recompact the buffer to make room for the new ;
1263; data. If in SINC then it will move the current line to the top of ;
1264; the buffer, and read the data from the end of this line till the ;
1265; end of the buffer. ;
1266; If NOT in SINC then it will recompact the buffer by moving ;
1267; all lines between the first to go out of SINC till the current line ;
1268; to the top of the buffer, and then reading data after the current ;
1269; line. ;
1270; When recompacting the buffer it relocates all pointers to ;
1271; point to the new locations of the respective lines. ;
1272; Some of the pointers may be pointing to meaningless locations ;
1273; before the relocation, and consecuently they will be pointing to ;
1274; even less meaningfull locations after relocation. ;
1275; After reading the data it normalizes the buffer to make sure ;
1276; that no partially full lines are present at the end of the buffer. If ;
1277; after recompacting and reading some character it is found that the ;
1278; characters read do not constitute a full line, then it will return ;
1279; with an error code. It will also return with an error code if it ;
1280; attempts to read past the end of file. ;
1281; ;
1282; entry: ;
1283; BX pointer to buffer structure ;
1284; ;
1285; exit: ;
1286; Carry set if no chars read into the buffer. If carry set then: ;
1287; AX End Code: 0 = end of file reached ;
1288; 1 = no room in the buffer for a line ;
1289; ;
1290; modifies: ;
1291; CX,DX,SI and DI ;
1292; ;
1293; Called from adv_b ;
1294;-----------------------------------------------------------------------;
1295refill:
1296
1297;----- Calculate ammount to move & pointer relocation factor.
1298
1299 cmp [sinc],true
1300 jne sf1
1301 mov si,word ptr [bx].curr
1302 jmp short sf2
1303sf1:
1304 mov si,word ptr [bx].fst_nosinc
1305sf2:
1306 mov di,word ptr [bx].buf
1307 mov cx,word ptr [bx].dat_end
1308
1309 mov dx,si ;calculate pointer relocation factor
1310 sub dx,di ;DX = factor
1311 jz sf3 ;no room in buffer
1312 sub cx,si ;calculate ammount of data to move
1313 inc cx ;CX = ammount
1314
1315;----- Move data
1316
1317 cld ;auto decrement
1318 rep movsb
1319
1320;----- Relocate pointers
1321
1322 sub word ptr [bx].curr,dx
1323 sub word ptr [bx].lst_curr,dx
1324 sub word ptr [bx].fst_sinc,dx
1325 sub word ptr [bx].fst_nosinc,dx
1326 sub word ptr [bx].dat_end,dx
1327
1328sf3:
1329 mov dx,word ptr [bx].dat_end
1330 inc dx ;empty part starts here
1331
1332;----- fill the buffer
1333
1334 call fill_buffer
1335 ret
1336
1337
1338 subttl Subroutines: fill_buffer
1339 page
1340
1341;-----------------------------------------------------------------------;
1342; Fill the data buffers ;
1343; ;
1344; It will fill the buffer from the pointer to the end of buffer ;
1345; and normalize the buffer. ;
1346; ;
1347; entry: ;
1348; BX pointer to buffer structure ;
1349; DX pointer to buffer (or part of buffer) ;
1350; ;
1351; exit: ;
1352; Carry set if no chars read into the buffer. If carry set then: ;
1353; AX End Code: 0 = end of file reached ;
1354; 1 = no room in the buffer for a line ;
1355; ;
1356; modifies: ;
1357; AX,CX,DX and DI ;
1358; ;
1359; Called from txt_compare and refill ;
1360;-----------------------------------------------------------------------;
1361fill_buffer:
1362 push bx
1363 call read_dat ;get data
1364 jc bad_read
1365 or ax,ax ;zero chars read?
1366 jz rd_past_eof
1367 call nor_buf
1368 mov di,cx ;save normalized char. count
1369 mov bp,dx ;save data end for now
1370
1371;----- seek for old partial line
1372
1373 or ax,ax ;is the seek value = 0 ?
1374 jz sg1 ;yes, do not seek
1375 mov dx,ax
1376 neg dx
1377 mov cx,-1
1378 mov al,1 ;seek from current position
1379 mov ah,lseek
1380 int 21h
1381 jc bad_read ;error mesage (BX already in stack)
1382
1383sg1:
1384 mov cx,di ;restore normalized char count.
1385 or cx,cx ;char count = 0 due to normalization?
1386 jz no_room
1387
1388 pop bx
1389 mov word ptr [bx].dat_end,bp
1390 clc
1391 ret
1392
1393bad_read:
1394 mov dx,offset dg:read_err_pre
1395 mov cl,read_err_pre_len
1396 call prt_err ;print error message
1397 pop bx
1398 mov dx,word ptr[bx].fname
1399 mov cx,word ptr[bx].fname_len
1400 call prt_err ;print file name
1401 mov dx,offset dg:read_err_post
1402 mov cl,read_err_post_len
1403 jmp an_err
1404
1405no_room:
1406 mov ax,1
1407 jmp short sg2
1408
1409rd_past_eof:
1410 xor ax,ax
1411sg2:
1412 pop bx
1413 stc
1414 ret
1415
1416
1417 subttl Subroutines: read_dat
1418 page
1419
1420;-----------------------------------------------------------------------;
1421; ;
1422; entry: ;
1423; DX pointer to data area (buffer or part of buffer) ;
1424; ;
1425; exit: ;
1426; AX character count or error code (from DOS read) ;
1427; Carry set if error condition ;
1428; ;
1429; modifies: ;
1430; BX and CX ;
1431; ;
1432; Called from fill_buffer, print_all and bin_compare ;
1433;-----------------------------------------------------------------------;
1434read_dat:
1435 mov cx,word ptr [bx].buf_end
1436 mov bx,word ptr [bx].handle
1437 sub cx,dx ;ammount to read to buff1
1438 mov ah,read
1439 int 21h
1440 ret
1441
1442
1443 subttl Subroutines: nor_buf
1444 page
1445
1446;-----------------------------------------------------------------------;
1447; Normalize buffers so they do not have partially full ;
1448; lines at the end. If character count is less than the buffer size ;
1449; then it checks that the last line is terminated by a CR,LF pair. ;
1450; If it is not it inserts a CR,LF at the end. It returns a seek value ;
1451; for the buffer corresponding to the number of characters in the ;
1452; incomplete line at the end of the buffer (if any). This can be used ;
1453; to start reading from the beggining of the incomplete line on next ;
1454; time the buffer is loaded. ;
1455; ;
1456; ENTRY: ;
1457; DX buffer pointer ;
1458; AX character count read ;
1459; CX character count requested ;
1460; ;
1461; EXIT: ;
1462; DX pointer to last char in buffer (normalized) ;
1463; CX character count (normalized) ;
1464; AX seek value ;
1465; ;
1466; MODIFIES: ;
1467; DI ;
1468; ;
1469; Called from fill_buffer ;
1470;-----------------------------------------------------------------------;
1471nor_buf:
1472 mov di,dx
1473 add di,ax
1474 dec di ;points to last char in buffer
1475 cmp ax,cx ;were all chars. requested read?
1476 je sm7 ;yes, buffer full
1477 cmp byte ptr[di],1ah ;terminated with a ^Z ?
1478 jne sm1
1479 dec di ;point to previous character
1480 dec ax ;decrement character count
1481sm1: cmp byte ptr[di],lf ;is last char a LF?
1482 je sm6
1483 cmp byte ptr[di],cr ;is it a CR then?
1484 je sm5
1485 add ax,2 ;two more chars in buffer
1486 inc di
1487sm2: mov byte ptr[di],cr
1488sm3: inc di
1489 mov byte ptr[di],lf
1490sm4: mov cx,ax ;new character count
1491 mov dx,di ;pointer to last char
1492 xor ax,ax ;seek = 0
1493 ret
1494
1495sm5:
1496 inc ax ;one more char in buffer
1497 jmp short sm3
1498
1499sm6:
1500 cmp byte ptr[di-1],cr ;is previous char a CR?
1501 je sm4
1502 inc ax ;no, one more char in buffer
1503 jmp short sm2
1504
1505sm7:
1506 push ax ;save char count
1507 mov cx,ax
1508 mov al,LF
1509 std
1510 repnz scasb ;search for last LF
1511 pop ax ;restore char count
1512 jnz bad_line ;none found, line too big
1513 inc di ;point to last LF
1514 mov dx,di
1515 inc cx ;ammount of chars in buffer
1516 sub ax,cx ;seek value
1517 ret
1518
1519bad_line: ;full line not possible, return
1520 mov dx,di ; with AX=count, CX=0 and DX=
1521 ret ; old last char in buffer pointer.
1522
1523
1524
1525 subttl Subroutines: print_diff
1526 page
1527
1528;-----------------------------------------------------------------------;
1529; print the difference between buffers ;
1530; ;
1531; It will print the mismatched lines. First it prints a heading ;
1532; with the first file name, then the lines that differ from file 1, ;
1533; then a heading with the second file name, and then the lines that ;
1534; differ in file 2 . ;
1535; The lines that differ are considered to start from fst_nosinc ;
1536; till fst_sinc. ;
1537; ;
1538; Called from txt_compare ;
1539;-----------------------------------------------------------------------;
1540print_diff:
1541 mov bx,offset dg:buf1
1542 call print_head ;print heading for file 1
1543 mov dx,word ptr [bx].fst_nosinc
1544 mov si,word ptr [bx].fst_sinc
1545 call get_next ;get pointer to next line
1546 mov cx,si
1547 sub cx,dx ;get character count
1548 call prout
1549 mov bx,offset dg:buf2
1550 call print_head ;print heading for file 1
1551 mov dx,word ptr [bx].fst_nosinc
1552 mov si,word ptr [bx].fst_sinc
1553 call get_next ;get pointer to next line
1554 mov cx,si
1555 sub cx,dx ;get character count
1556 call prout
1557 mov dx,offset dg:diff_sep
1558 mov cl,diff_sep_len
1559 xor ch,ch
1560 call prout ;print difference separator
1561 ret
1562
1563
1564 subttl Subroutines: print_head
1565 page
1566
1567;-----------------------------------------------------------------------;
1568; Print heading for difference ;
1569; ;
1570; entry: ;
1571; BX pointer to buffer structure ;
1572; ;
1573; modifies: ;
1574; AX,CX and DX ;
1575; ;
1576; Called from txt_compare and print_diff ;
1577;-----------------------------------------------------------------------;
1578print_head:
1579 mov dx,offset dg:fname_sep
1580 mov cl,fname_sep_len
1581 xor ch,ch
1582 call prout
1583 mov dx,word ptr [bx].fname
1584 mov cx,word ptr [bx].fname_len
1585 call prout
1586 mov dx,offset dg:CRLF
1587 mov cx,2
1588 call prout
1589 ret
1590
1591
1592 subttl Subroutines: print_all
1593 page
1594
1595;-----------------------------------------------------------------------;
1596; Print the rest of a file ;
1597; ;
1598; If in SINC it will print the file from the fst_nosinc line ;
1599; till the end of the file. If NOT in SINC then it will print from ;
1600; the current line of the buffer to the end of the file. ;
1601; ;
1602; entry: ;
1603; BX pointer to buffer structure ;
1604; ;
1605; modifies: ;
1606; AX,CX and DX ;
1607; ;
1608; Called from txt_compare ;
1609;-----------------------------------------------------------------------;
1610print_all:
1611 cmp [sinc],true ;are we in SINC?
1612 jne so1
1613 mov dx,word ptr [bx].curr
1614 jmp short so2
1615so1:
1616 mov dx,word ptr [bx].fst_nosinc
1617so2:
1618 mov cx,word ptr [bx].dat_end
1619 inc cx
1620
1621prt_again:
1622 sub cx,dx ;ammount of data to write
1623 call prout ;write it out
1624
1625;----- Read more data to the buffer
1626 push bx ;save pointer to buffer struct
1627 mov dx,word ptr [bx].buf
1628 call read_dat
1629 jnc so3
1630 jmp bad_read ;print error (BX in stack)
1631so3:
1632 or ax,ax ;zero chars read?
1633 jne so4
1634 pop bx ;all done writting
1635 ret
1636so4:
1637 pop bx
1638 mov cx,word ptr [bx].buf_end
1639 jmp short prt_again ;print next buffer full
1640
1641
1642 subttl Subroutines: prout and prt_err
1643 page
1644
1645;-----------------------------------------------------------------------;
1646; ;
1647;-----------------------------------------------------------------------;
1648prout:
1649 push bx
1650 mov bx,stdout
1651 mov ah,write
1652 int 21h
1653 pop bx
1654 ret
1655
1656
1657;-----------------------------------------------------------------------;
1658; ;
1659;-----------------------------------------------------------------------;
1660prt_err:
1661 push bx
1662 xor ch,ch
1663 jcxz retpbx
1664 mov bx,stderr
1665 mov ah,write
1666 int 21h
1667retpbx:
1668 pop bx
1669 ret
1670
1671code ends
1672
1673 page
1674
1675
1676stack segment stack
1677
1678 dw 128 dup(?)
1679
1680stack ends
1681
1682
1683 end start
1684
diff --git a/v2.0/source/FCB.ASM b/v2.0/source/FCB.ASM
new file mode 100644
index 0000000..11528f7
--- /dev/null
+++ b/v2.0/source/FCB.ASM
@@ -0,0 +1,512 @@
1;
2; FCB management routines for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7IFNDEF KANJI
8KANJI EQU 0 ;FALSE
9ENDIF
10
11CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14.xlist
15.xcref
16INCLUDE DOSSYM.ASM
17INCLUDE DEVSYM.ASM
18.cref
19.list
20
21 i_need Name1,BYTE
22 i_need NumIO,BYTE
23 i_need DevFCB,BYTE
24 i_need Creating,BYTE
25 i_need ExtFCB,BYTE
26 i_need Attrib,BYTE
27 i_need SpaceFlag,BYTE
28 i_need Current_Country,WORD
29
30 procedure MakeFcb,NEAR
31DRVBIT EQU 2
32NAMBIT EQU 4
33EXTBIT EQU 8
34 MOV BYTE PTR [SpaceFlag],0
35 XOR DL,DL ; Flag--not ambiguous file name
36 TEST AL,DRVBIT ; Use current drive field if default?
37 JNZ DEFDRV
38 MOV BYTE PTR ES:[DI],0 ; No - use default drive
39DEFDRV:
40 INC DI
41 MOV CX,8
42 TEST AL,NAMBIT ; Use current name fields as defualt?
43 XCHG AX,BX ; Save bits in BX
44 MOV AL," "
45 JZ FILLB ; If not, go fill with blanks
46 ADD DI,CX
47 XOR CX,CX ; Don't fill any
48FILLB:
49 REP STOSB
50 MOV CL,3
51 TEST BL,EXTBIT ; Use current extension as default
52 JZ FILLB2
53 ADD DI,CX
54 XOR CX,CX
55FILLB2:
56 REP STOSB
57 XCHG AX,CX ; Put zero in AX
58 STOSW
59 STOSW ; Initialize two words after to zero
60 SUB DI,16 ; Point back at start
61 TEST BL,1 ; Scan off separators if not zero
62 JZ SKPSPC
63 CALL SCANB ; Peel off blanks and tabs
64 CALL DELIM ; Is it a one-time-only delimiter?
65 JNZ NOSCAN
66 INC SI ; Skip over the delimiter
67SKPSPC:
68 CALL SCANB ; Always kill preceding blanks and tabs
69NOSCAN:
70 CALL GETLET
71 JBE NODRV ; Quit if termination character
72 CMP BYTE PTR[SI],":" ; Check for potential drive specifier
73 JNZ NODRV
74 INC SI ; Skip over colon
75 SUB AL,"@" ; Convert drive letter to binary drive number
76 JBE BADDRV ; Valid drive numbers are <= NUMIO
77 CMP AL,BYTE PTR [NUMIO]
78 JBE HAVDRV
79BADDRV:
80 MOV DL,-1
81HAVDRV:
82 STOSB ; Put drive specifier in first byte
83 INC SI
84 DEC DI ; Counteract next two instructions
85NODRV:
86 DEC SI ; Back up
87 INC DI ; Skip drive byte
88NORMSCAN:
89 MOV CX,8
90 CALL GETWORD ; Get 8-letter file name
91 CMP BYTE PTR [SI],"."
92 JNZ NODOT
93 INC SI ; Skip over dot if present
94 MOV CX,3 ; Get 3-letter extension
95 CALL MUSTGETWORD
96NODOT:
97 MOV AL,DL
98 return
99
100NONAM:
101 ADD DI,CX
102 DEC SI
103 return
104
105GETWORD:
106 CALL GETLET
107 JBE NONAM ; Exit if invalid character
108 DEC SI
109;
110; UGH!!! Horrible bug here that should be fixed at some point:
111; If the name we are scanning is longer than CX, we keep on reading!
112;
113MUSTGETWORD:
114 CALL GETLET
115;
116; If spaceFlag is set then we allow spaces in a pathname
117;
118 JB FILLNAM
119 JNZ MustCheckCX
120 TEST BYTE PTR [SpaceFlag],0FFh
121 JZ FILLNAM
122 CMP AL," "
123 JNZ FILLNAM
124
125MustCheckCX:
126 JCXZ MUSTGETWORD
127 DEC CX
128 CMP AL,"*" ; Check for ambiguous file specifier
129 JNZ NOSTAR
130 MOV AL,"?"
131 REP STOSB
132NOSTAR:
133 STOSB
134
135 IF KANJI
136 CALL TESTKANJ
137 JZ NOTDUAL3
138 JCXZ BNDERR ; Attempt to straddle boundry
139 MOVSB ; Transfer second byte
140 DEC CX
141 JMP SHORT NOTDUAL3
142BNDERR:
143 MOV BYTE PTR ES:[DI-1]," " ; patch up that space
144 JMP MustGetWord ; go back and scan until delim
145
146NOTDUAL3:
147 ENDIF
148
149 CMP AL,"?"
150 JNZ MUSTGETWORD
151 OR DL,1 ; Flag ambiguous file name
152 JMP MUSTGETWORD
153FILLNAM:
154 MOV AL," "
155 REP STOSB
156 DEC SI
157 return
158
159SCANB:
160 LODSB
161 CALL SPCHK
162 JZ SCANB
163 DEC SI
164 return
165MakeFCB ENDP
166
167;
168; NameTrans is used by FindPath to scan off an element
169; of a path. We must allow spaces in pathnames
170; Inputs: SS - DOSGROUP
171; DS:SI name
172; Outputs: DS:SI advanced over spot
173; ES:DI point to after Name1
174; registers modified: AX, BX, CX, DX
175procedure NameTrans,near
176 MOV BYTE PTR [SpaceFlag],1
177 PUSH SS
178 POP ES
179 MOV DI,OFFSET DOSGROUP:NAME1
180 PUSH DI
181 MOV AL,' '
182 MOV CX,11
183 REP STOSB
184 XOR AL,AL
185 MOV DL,AL
186 STOSB
187 POP DI
188 CMP BYTE PTR [SI],'.'
189
190 IF KANJI
191 JZ FOOBAR
192 CALL NORMSCAN
193 CMP [NAME1],0E5H
194 retnz
195 MOV [NAME1],5
196 return
197FOOBAR:
198 ELSE
199 JNZ NORMSCAN
200 ENDIF
201
202 MOVSB
203 LODSB
204 CALL PATHCHRCMP
205 JZ GOTDOTNAME
206 OR AL,AL
207 JZ GOTDOTNAME
208 CMP AL,'.'
209 JNZ BADDOTS
210 STOSB
211 LODSB
212 CALL PATHCHRCMP
213 JZ GOTDOTNAME
214 OR AL,AL
215 JZ GOTDOTNAME
216 DEC SI
217BADDOTS:
218 DEC SI
219GOTDOTNAME:
220 DEC SI
221 XOR AL,AL
222 return
223nametrans ENDP
224
225SUBTTL BUILDFCB -- MAKE A BLANK FCB FOR A DEVICE
226PAGE
227 procedure BuildFCB,near
228ASSUME DS:DOSGROUP,ES:DOSGROUP
229
230; Function:
231; Build a blank FCB for I/O to a device
232; Outputs:
233; Same as GETNAME
234
235 MOV AX," "
236 MOV DI,OFFSET DOSGROUP:DEVFCB+8 ; Point to extent field
237 STOSW
238 STOSB ; Blank out extent field
239 XOR AX,AX
240 MOV CX,10
241 REP STOSW ; Fill FCB with zeros
242 STOSB
243 invoke DATE16
244 MOV DI,OFFSET DOSGROUP:DEVFCB+22
245 XCHG AX,DX
246 STOSW
247 XCHG AX,DX
248 STOSW
249 XCHG AX,BX ; But device number in AH
250 MOV BX,OFFSET DOSGROUP:DEVFCB
251 MOV SI,DI
252 XOR AL,AL ; Set zero, clear carry
253 return
254BuildFCB ENDP
255
256SUBTTL MOVENAME, LODNAME -- EXAMINE FCB AND SETUP
257PAGE
258 procedure FCB_move,NEAR
259
260 entry MOVNAMENOSET
261 MOV DI,1
262 JMP SHORT MOVSTART
263
264 entry MOVNAME
265ASSUME DS:NOTHING,ES:NOTHING
266
267; Inputs:
268; DS, DX point to FCB or extended FCB
269; Outputs:
270; DS:DX point to normal FCB
271; DS:SI point after end of NAME/EXT in FCB
272; ES = DOSGROUP
273; If file name OK:
274; [NAME1] has name in upper case
275; All registers destroyed
276; Carry set if bad file name or drive
277
278 XOR DI,DI
279MOVSTART:
280 MOV WORD PTR [CREATING],0E500H ; Not creating, not DEL *.*
281 MOV SI,DX
282 LODSB
283 MOV [EXTFCB],AL ; Set flag if extended FCB in use
284 XOR AH,AH ; Set default attributes
285 CMP AL,-1 ; Is it an extended FCB?
286 JNZ HAVATTRB
287 ADD DX,7 ; Adjust to point to normal FCB
288 ADD SI,6
289 MOV AH,[SI-1] ; Attribute byte
290 LODSB ; Get drive select byte
291HAVATTRB:
292 invoke GETTHISDRV
293 retc
294 PUSH DS
295 PUSH DX
296 PUSH SI
297 PUSH AX
298;
299; DS:DX is pointer to good FCB
300; DS:SI is same
301;
302; Move the file into Name1 and UCASE it
303;
304 PUSH DI
305 context ES
306 MOV DI,OFFSET DOSGROUP:NAME1
307 CALL LodName
308 POP DI
309 JC DrvNoSet
310
311;
312; are we setting current dir info?
313;
314 OR DI,DI
315 JNZ DrvNoSet ; do not set dir info
316
317;
318; check for device name first, eliminating drive hits on devices
319;
320 context DS
321 invoke DEVNAME
322 JNC DrvNoSet ; we have a device
323
324;
325; make sure that everything is current
326;
327 invoke FATREAD
328 ASSUME DS:NOTHING,ES:NOTHING
329 MOV BYTE PTR [ATTRIB],attr_directory+attr_hidden+attr_system
330 invoke GETCURRDIR
331DrvNoSet:
332 POP AX
333 MOV BYTE PTR [ATTRIB],AH
334
335 POP SI
336 POP DX
337 POP DS
338 context ES
339 MOV DI,OFFSET DOSGROUP:NAME1
340
341 entry LODNAME
342; Inputs: DS:SI point to an FCB
343; ES:DI point to an FCB
344; Outputs: DS:SI point to after FCB
345; ES:DI point to after FCB
346; FCB from DS:SI copied and ucased to ES:DI
347; Carry set if there was an error.
348; Destroys AX,CX
349 CMP BYTE PTR [SI]," " ; Don't allow blank as first letter
350 STC ; In case of error
351 retz
352
353 IF KANJI
354 MOV CX,8
355 CMP BYTE PTR [SI],0E5H
356 JNZ MOVCHK
357 INC SI
358 MOV AL,5
359 STOSB
360 MOVSB
361 MOV CX,6
362MOVCHK:
363 CALL GETLET
364 JB RET6
365 JNZ STOLET ; Is it a delimiter?
366 CMP AL," " ; This is the only delimiter allowed
367 STC ; In case of error
368 JNZ RET6
369STOLET:
370 STOSB
371 CALL TESTKANJ
372 JZ MOVLP ;No
373 LODSB ;Get second byte
374 DEC CX
375 JZ BOUNDERR ;Attempt to cross boundry
376 STOSB
377MOVLP:
378 LOOP MOVCHK
379 MOV CX,3
380MOVCHK2:
381 CALL GETLET
382 JB RET6
383 JNZ STOLET2 ; Is it a delimiter?
384 CMP AL," " ; This is the only delimiter allowed
385 STC ; In case of error
386 retnz
387STOLET2:
388 STOSB
389 CALL TESTKANJ
390 JZ MOVLP2 ;No
391 LODSB ;Get second byte
392 DEC CX
393 JNZ DOSTORE
394BOUNDERR: ;Attempt to cross boundry
395 STC
396 return
397
398DOSTORE:
399 STOSB
400MOVLP2:
401 LOOP MOVCHK2
402 ELSE
403 MOV CX,11
404MOVCHK:
405 CALL GETLET
406 JB RET6
407 JNZ STOLET ; Is it a delimiter?
408 CMP AL," " ; This is the only delimiter allowed
409 STC ; In case of error
410 retnz
411STOLET:
412 STOSB
413 LOOP MOVCHK
414 ENDIF
415
416 CLC ; Got through whole name - no error
417RET6: return
418FCB_Move ENDP
419
420SUBTTL GETLET, DELIM -- CHECK CHARACTERS AND CONVERT
421PAGE
422 procedure GetLet,NEAR
423; Get a byte from [SI], convert it to upper case, and compare for delimiter.
424; ZF set if a delimiter, CY set if a control character (other than TAB).
425 LODSB
426
427 CMP AL,"a"
428 JB CHK1
429 CMP AL,"z"
430 JA CHK1
431 SUB AL,20H ; Convert to upper case
432CHK1:
433 PUSH SI
434 MOV SI,[Current_Country]
435 ADD SI,Map_call
436 PUSH CS ; CS for long return
437 CALL WORD PTR CS:[SI]
438 POP SI
439 entry CHK
440 CMP AL,"."
441 retz
442 CMP AL,'"'
443 retz
444 CALL PATHCHRCMP
445 retz
446 CMP AL,"["
447 retz
448 CMP AL,"]"
449 retz
450
451DELIM:
452 CMP AL,":" ; Allow ":" as separator in IBM version
453 retz
454
455 CMP AL,"<"
456 retz
457 CMP AL,"|"
458 retz
459 CMP AL,">"
460 retz
461
462 CMP AL,"+"
463 retz
464 CMP AL,"="
465 retz
466 CMP AL,";"
467 retz
468 CMP AL,","
469 retz
470SPCHK:
471 CMP AL,9 ; Filter out tabs too
472 retz
473; WARNING! " " MUST be the last compare
474 CMP AL," "
475 return
476GetLet ENDP
477
478 procedure PATHCHRCMP,NEAR
479 CMP AL,'/'
480 retz
481 CMP AL,'\'
482 return
483PathChrCMP ENDP
484
485 IF KANJI
486 procedure TESTKANJ,NEAR
487 CMP AL,81H
488 JB NOTLEAD
489 CMP AL,9FH
490 JBE ISLEAD
491 CMP AL,0E0H
492 JB NOTLEAD
493 CMP AL,0FCH
494 JBE ISLEAD
495NOTLEAD:
496 PUSH AX
497 XOR AX,AX ;Set zero
498 POP AX
499 return
500
501ISLEAD:
502 PUSH AX
503 XOR AX,AX ;Set zero
504 INC AX ;Reset zero
505 POP AX
506 return
507TESTKANJ ENDP
508 ENDIF
509do_ext
510
511CODE ENDS
512 END
diff --git a/v2.0/source/FCMES.ASM b/v2.0/source/FCMES.ASM
new file mode 100644
index 0000000..1fc52cb
--- /dev/null
+++ b/v2.0/source/FCMES.ASM
Binary files differ
diff --git a/v2.0/source/FIND.ASM b/v2.0/source/FIND.ASM
new file mode 100644
index 0000000..7c82768
--- /dev/null
+++ b/v2.0/source/FIND.ASM
@@ -0,0 +1,932 @@
1 title MSDOS V2.0 FIND
2
3;--------------------------------------------------------------------;
4; Revision History: ;
5; ;
6; V1.1 8/23/82 M.A.Ulloa ;
7; ;
8; V1.2 9/22/82 M.A.Ulloa ;
9; Added the -c and -n options ;
10; ;
11; 9/23/82 M.A.Ulloa ;
12; Added DOS version number control ;
13; ;
14; 10/07/82 Rev.2 M.A.Ulloa ;
15; Changed quote for double quotes, and added ;
16; file name printing ;
17; ;
18; 10/20/82 Rev.3 M.A.Ulloa ;
19; Modified IBM name to FIND, and changed the text ;
20; of some messages. ;
21; ;
22; 10/25/82 Rev.4 M.A.Ulloa ;
23; Changed name to FIND and all messages to the ;
24; IBM form. ;
25; ;
26; 10/27/82 Rev.5 M.A.Ulloa ;
27; Made the correct exit on version check in case ;
28; of a 1.x DOS. ;
29; ;
30; 11/4/82 Rev. 5 A.R. Reynolds ;
31; Messages moved to external module ;
32; ;
33; 11/10/82 Rev. 6 M.A. Ulloa ;
34; Corrected problem with line numbers, and a problem ;
35; with seeking for 0 chars. ;
36; ;
37; 03/30/83 Rev. 7 M.A. Ulloa ;
38; Added patch area for bug fixing. ;
39; ;
40; 04/14/83 Rev. 8 M.A. Ulloa ;
41; Made changes for Kanji characters. (uhg!) ;
42; ;
43;--------------------------------------------------------------------;
44
45FALSE equ 0
46TRUE equ NOT FALSE
47
48KANJI equ FALSE ;set to true is kanji vers.
49
50;--------------------------------------------------------------------;
51; FIND program following the standart UNIX operation. ;
52; ;
53; FORMAT: ;
54; find {option} string {filename {filename} {...}} ;
55; ;
56; NOTES: ;
57; 1) String arguments HAVE to be enclosed ;
58; in double quotes. (Two double quotes if a ;
59; doble quote is to be included). Only ONE ;
60; string argument is presently allowed. ;
61; ;
62; 2) Options are available: ;
63; v All lines but those matching are considered ;
64; c Only print a count of matching lines ;
65; n Each line is preceded by its relative ;
66; line number in the file. ;
67; ;
68; - Options can be Upper or lower case. ;
69; - Format: The switch character followed by an options ;
70; character. I.e.: In the IBM PC: /v ;
71; ;
72; 3) The program returns: ;
73; 0 - OK, and some matches ;
74; 2 - Some Error ;
75; ;
76; 4) The maximum line size is determined by ;
77; buffer size. Bigger lines will bomb the program. ;
78; ;
79; 5) If no file name is given then it will asssume ;
80; the input is comming from the Standart Input. NO ;
81; errors are reported when reading from Standart Input. ;
82;--------------------------------------------------------------------;
83
84code segment public
85assume cs:code,ss:code,ds:nothing,es:nothing
86
87
88CR equ 0dh ;A Carriage Return
89LF equ 0ah ;A Line Feed
90quote_char equ 22h ;A double quote character
91
92
93buffer_size equ 4096 ;file buffer size
94st_buf_size equ 128 ;string arg. buffer size
95fname_buf_size equ 64 ;file name buffer size
96
97
98;----- DOS EQUATES --------------------------------------------------;
99std_in equ 0 ;STD input handle
100std_out equ 1 ;STD output handle
101std_err equ 2 ;STD error handle
102dos_ent equ 21h ;DOS entry point
103
104std_con_string_output equ 9
105get_version equ 48
106char_oper equ 55 ;get configuration parameters
107open equ 61 ;DOS std open code
108close equ 62 ;DOS std close code
109read equ 63 ;DOS std read code
110write equ 64 ;DOS std write code
111lseek equ 66 ;DOS file seek
112exit equ 76 ;DOS process exit code
113
114
115;----- Misc Data -----------------------------------------------;
116make db "***MAUlloa/Microsoft/V12***"
117rev db "8"
118
119
120colon db ": "
121n1_buf db "["
122n2_buf db 8 dup(0) ;buffer for number conversion
123
124
125
126;----- OPTION FLAGS -------------------------------------------------;
127; If a flag is set (0ffh) then the option has been selected, if
128;reset (0) then it has been not. All options are reset initially.
129; NOTE: the order of this table has to remain consistent with the
130;options dispatch code. If any changes are made they have to
131;correspond with the code.
132
133opt_tbl:
134
135v_flg db 0
136c_flg db 0
137n_flg db 0
138x_flg db 0 ;not used
139l_flg db 0 ;not used
140
141
142;----- LINE COUNTERS ------------------------------------------------;
143mtch_cntr dw 0 ;matched lines counter
144line_cntr dw 0 ;line counter
145
146
147;----- MAIN ROUTINE -------------------------------------------------;
148start:
149
150;----- CHECK VERSION NUMBER -----------------------------------------;
151
152 mov ah,get_version
153 int 21h
154 cmp al,2
155 jge vers_ok
156 push cs
157 pop ds
158 mov dx,offset bad_vers
159 mov ah,std_con_string_output
160 int 21h
161 push es ;bad vers, exit a la 1.x
162 xor ax,ax
163 push ax
164
165badfart proc far ;(what a hack!!)
166 ret
167badfart endp
168
169vers_ok:
170
171 push cs ;load ES to the right area,
172 pop es ; for use with DI register
173
174assume es:code
175
176;--------------------------------------------------------------------;
177
178 mov si,81h ;Start addrss. of commad line buf.
179
180 call kill_bl ;Get rid of blanks
181 or bx,bx ;A CR found?
182 jz find_opt ;no, first find the options
183args_missing:
184 mov dx,offset errmsg1 ;empty command line, no args: error.
185 mov cl,cs:errlen1
186 call prt_err
187 mov al,2 ;error code for exit
188 jmp done
189
190
191;----- FIND THE OPTION IF ANY ---------------------------------------;
192find_opt:
193 mov ah,char_oper ;get the dos switch char.
194 mov al,0
195 int dos_ent ;switch char in DL
196 push dx
197another_opt:
198 lodsb ;get the first char of command line
199 cmp al,' ' ;a blank?
200 je cont_scan
201 cmp al,CR ;a Carriage Return
202 je args_missing
203 pop dx ;get switch character
204 cmp al,dl ;is it the switch char?
205 jne find_str ;no, no options: get the string
206 push dx ;save for another round
207
208 lodsb ;get the option character
209 cmp al,' ' ;a blank?
210 je cont_scan ;yes, ignore and continue
211 cmp al,CR ;a CR?
212 je args_missing ;yes, error...
213 call make_caps ;Capitalize the character
214 mov bx,offset opt_tbl ;pointer to option flag table
215
216 cmp al,'V' ;the v option?
217 je opt_v
218 cmp al,'C' ;the c option?
219 je opt_c
220 cmp al,'N' ;the n option?
221 je opt_n
222
223 mov cs:errmsg5_opt,al ;save the option
224 mov dx,offset errmsg5 ;unknown option: error
225 mov cl,cs:errlen5
226 call prt_err
227 mov dx,offset crlf ;print a CRLF
228 mov cx,2
229 call prt_err
230 jmp another_opt ;process next option
231
232opt_v:
233 mov di,0
234 jmp short opt_dispatch
235
236opt_c:
237 mov di,1
238 jmp short opt_dispatch
239
240opt_n:
241 mov di,2
242
243opt_dispatch:
244 mov es:byte ptr[bx+di],0ffh ;set the corresponding flag
245 jmp another_opt ;process the rest of the options
246
247cont_scan:
248 dec si ;adjust SI
249 call kill_bl ;get rid of blanks
250 or bx,bx ;A CR found?
251 jz another_opt ;no, test for other options
252 jmp args_missing ;yes, error...
253
254
255;----- FIND STRING ARGUMENT -----------------------------------------;
256find_str:
257 cmp al,quote_char ;string should start with a
258 jnz bad_str_err ; quote character, if not: error.
259 mov di,offset st_buffer ;String argument buffer addrss.
260 xor cx,cx ;Clear to keep string length.
261
262move_str:
263 lodsb
264 cmp al,CR ;if a CR is found in the string
265 jnz str_ok ; then it's a bad string
266bad_str_err:
267 mov dx,offset errmsg2 ;bad string error message
268 mov cl,cs:errlen2
269 call prt_err ;print the error.
270 mov al,2
271 jmp done
272
273str_ok:
274 cmp al,quote_char ;look for a quote character
275 jnz move_char ;not an apost., move to buffer
276 lodsb ;an apost., check next char.
277 cmp al,quote_char ;another quote character?
278 je move_char ;yes, move it to the buffer
279 dec si ;no, adjust the pointer
280 mov es:st_length,cx ;store the string length
281 or cx,cx ;Is the string empty?
282 jnz other_args ;no: get the rest of the args.
283 mov al,1 ;empty: no matches(!?)
284 jmp done
285move_char:
286 stosb ;put in buffer
287 inc cx ;increment string length
288 jmp move_str
289
290
291;----- FIND THE FILE ARGUMENTS --------------------------------------;
292other_args: ;Process the rest of the command
293 ; line arguments.
294 call kill_bl ;get rid of leading blanks
295 or bx,bx ;At least one argument necessary,
296 jz further_args ; if a CR not found: ok.
297
298;----- USE STD IN FOR INPUT -----------------------------------------;
299 push cs
300 pop ds
301 mov ax,std_in ;handle
302 jmp fill
303
304further_args:
305 call clr_cntrs ;set all counters to zero
306 mov di,offset file_name_buf ;Set pointer to the name buffer
307 xor cx,cx ;zero file name length
308move_fname:
309 lodsb
310 cmp al,' ' ;A blank: end of file name,
311 je done_move
312 cmp al,CR ;A CR: idem.
313 je done_move
314 stosb ;store in name buffer
315 inc cx ;increment file name length
316 jmp move_fname
317done_move:
318 dec si ;Adjust pointer for next round.
319 mov es:byte ptr[di],00h ;File names are null terminated
320 push si ;Save SI to continue com. line scan.
321 push ds ;Save DS register contents for
322 ; later because it points to the
323 ; rest of the arguments.
324 mov es:file_name_len,cx ;save the name length
325
326;----- OPEN FILE FOR READING ----------------------------------------;
327 push cs ;Load new DS with CS
328 pop ds
329 mov dx,offset file_name_buf ;addrss. of the file name
330 mov ah,open
331 mov al,0 ;file open for reading
332 int dos_ent ;call the DOS
333 jnc say_name ;if no carry then no errors
334 jmp open_error
335
336;----- PRINT FILE NAME ----------------------------------------------;
337say_name:
338 push ax ;save file handle
339 mov dx,offset heading
340 mov cl,cs:heading_len
341 xor ch,ch
342 call prout
343
344 mov dx,offset file_name_buf
345 mov cx,ds:file_name_len
346 call prout
347
348 cmp ds:c_flg,0ffh ;count only flag set?
349 je xx1
350
351 mov dx,offset crlf
352 mov cx,2
353 call prout
354
355xx1:
356 pop ax
357
358;----- Fill Buffer for Matching -------------------------------------;
359fill:
360 mov bx,ax ;retrieve handle
361refill:
362 mov dx,offset buffer ;data buffer addrss.
363 mov cx,buffer_size
364 mov ah,read
365 int dos_ent
366 jnc no_read_error ;if carry then read error
367 jmp read_error
368no_read_error:
369 or ax,ax ;if ax=0 then all done
370 jnz go_match
371 cmp ds:c_flg,0ffh ;count only flag set?
372 jne sj2
373 call print_count
374sj2:
375 cmp bx,std_in ;Using STD IN?
376 jnz regular
377 jmp foo ;if so: all done, exit
378regular:
379 mov ah,close ;otherwise close the file
380 int dos_ent
381 jmp scan_rest ;get another file
382
383;----- MATCH ROUTINE ------------------------------------------------;
384;Note: If input is being taken from a file the stack contains
385; (from top to bottom):
386; - Pointer to the next command in the command line
387; - Pointer to the program segment prefix (to be loaded into
388; DS to access the command line.
389; if the imput is from the standart input then NONE of it will be
390; in the stack.
391
392go_match:
393 push bx ;save the file handle
394 mov bp,offset buffer ;ptr to first line of file
395 mov di,ax ;dispalcement from beg of buffer
396
397 cmp ax,buffer_size-1 ;last line of the file?
398 jg no_last_line ;if yes, add a CRLF just in case
399 mov bx,bp
400 cmp byte ptr[bx+di-1],LF ;finished with a LF?
401 je no_last_line ;yes, it's an OK line.
402 mov byte ptr[bx+di],CR ;put a CR at the end of the data
403 inc di
404 mov byte ptr[bx+di],LF ;put a LF ...
405 inc di
406
407no_last_line:
408 push di ;save the # of chars. in the buffer
409 push bp
410 mov dx,ds:st_length ;length of the string arg.
411 dec dx ;adjust for later use
412 jmp short try_again
413
414
415more_stuff_o:
416 jmp more_stuff
417
418
419
420;----- SCAN LINES IN THE BUFFER FOR A MATCH -------------------------;
421;Note: at this point the stack contains (from top to bottom):
422; - Stuff mentioned before
423; - File Handle
424; - Number of chars. left in the buffer from the next line.
425; - Addrs. of the next line in the buffer.
426;
427; plus, DX has the adjusted length of the string argument.
428
429try_again:
430 inc ds:line_cntr ;increment line counter
431 pop bp ;addrs. of next line in the buffer
432 mov di,bp ;points to beg. of a line
433 pop cx ;get # of chars left in the buffer
434 mov bx,cx ;save in case a non-complete line
435 mov al,LF ;search for a Line Feed
436 jcxz more_stuff_o ;no chars left in buffer
437 repnz scasb
438 jnz more_stuff_o ;no full line left in buffer
439
440 push cx ;save chars left in buffer
441 push di ;points to beg. of next line
442 mov cx,di
443 sub cx,bp ;length of the current line
444 mov bx,cx ;save in case it has a match
445 dec cx
446 dec cx ;CRLF characters discounted
447 jcxz try_again_opt ;if line empty go to next line
448 mov di,bp ;pointer to the beg. of current line
449another_char:
450;
451; On entry:
452; BX line length
453; CX adjusted line length
454; DX adjusted string argument length
455; DI points to beg. of line
456;
457
458IF KANJI
459
460 push dx ;save for next line
461lop:
462 pop dx
463 push dx
464 inc dx ;different algorithm!
465 mov si,offset st_buffer ;pointer to beg. of string argument
466
467comp_next_char:
468 push di
469 mov di,si
470 call is_prefix ;check for a prefix char
471 pop di
472 jnc nopre
473 lodsw
474 cmp cx,1 ; Can not compare a two byte char
475 jz try_again_opt1 ; if there is only one available
476 cmp ax,word ptr [di]
477 jz kmatch1
478 call next_kchar ;no match, advance di to next kanji
479 jc try_again_opt1 ;not enough chars left in line
480 jmp short lop ;try another char in line
481
482nopre:
483 lodsb
484 cmp al,byte ptr [di]
485 jz kmatch
486 call next_kchar ;no match, advance di to next kanji
487 jc try_again_opt1 ;not enough chars left in line
488 jmp short lop ;try another char in line
489
490try_again_opt1:
491 pop dx
492 jmp try_again_opt
493
494
495kmatch1:
496 dec dx ;last char had prefix so it was
497 ; long.
498kmatch:
499 dec dx
500 jz a_matchk ; no chars left: a match!
501 call next_kchar
502 jc try_again_opt1
503 jmp comp_next_char ; loop if chars left in arg.
504
505a_matchk:
506 pop dx
507
508ELSE
509
510 mov si,offset st_buffer ;pointer to beg. of string argument
511 lodsb ;get first character of the str. arg.
512 repnz scasb ;search for a match in current line
513 jnz try_again_opt ;no match, try the next line
514 cmp cx,dx ;compare lengths, a full match is not
515 jb try_again_opt ; possible if CX < DX.
516 push di ;save addrs. of next char. in the line
517 push cx ;save the # of chars. left in the line
518 mov cx,dx ;get the adjusted string arg. length
519 jcxz a_match ;if a single char string, then match!
520 repz cmpsb ;compare string with line
521 jz a_match ;a match found, hurrah!
522 pop cx ;no match, get # of chars remaining
523 ; in the line.
524 pop di ;position of the next char. in the line
525 jmp another_char
526
527
528;----- A MATCH: CHECK FOR THE v OPTION ------------------------------;
529a_match:
530 pop ax ;adjust stack
531 pop ax
532ENDIF
533
534 cmp ds:v_flg,0ffh ;is flag set?
535 jne prt_line ;no, print the line
536 jmp try_again
537
538;----- NO MATCH: CHECK FOR THE v OPTION -----------------------------;
539try_again_opt:
540 cmp ds:v_flg,0ffh ;is flag set?
541 jne try_again ;no goto next line
542
543;----- PRINT THE LINE WITH THE MATCH --------------------------------;
544;Note: at this point the stack contains (top to bottom)
545; - Stuff mentioned before
546;
547; plus, BP points to begginig of the current line, BX has the length
548;of the current line including the CRLF, and DX the adjusted length of
549;the string argument.
550
551prt_line:
552 cmp ds:c_flg,0ffh ;is count only flag set?
553 jne no_c_flg
554 inc ds:mtch_cntr ;yes, increment counter
555 jmp try_again
556
557no_c_flg:
558 push dx ;save the adjusted string arg. length
559 cmp ds:n_flg,0ffh ;is line number flag set?
560 jne no_n_flg
561 call prt_lcntr
562no_n_flg:
563 mov dx,bp
564 mov cx,bx
565 call prout
566 pop dx ;restore
567 jmp try_again
568
569;----- READ MORE TEXT LINES INTO THE BUFFER -------------------------;
570; The scanning routines have detected that the buffer does not
571;contain a full line any more. More lines have to be read into the
572;buffer. But first perform a seek on the file in order to re-read
573;the non-complete line into the begining of the buffer.
574; Uppon entry BP contains points to the begining of the non-complete
575;line, and BX has the number of characters left in the buffer.
576; The Stack contains (top to bottom):
577; - Pointer to the next command in the command line
578; - Pointer to the program segment prefix (to be loaded into
579; DS to access the command line).
580; - File handle.
581
582more_stuff:
583 mov dx,bx ;get chars left in buffer
584 pop bx ;get the handle
585 or dx,dx ;are there 0 left?
586 jz no_seek ;yes, do not seek
587 neg dx ;form two's complement
588 mov cx,-1
589 mov al,1 ;seek from the current position
590 mov ah,lseek ;seek on file
591 int dos_ent
592 jc read_error
593no_seek:
594 jmp refill ;no errors: refill the buffer
595read_error:
596 cmp bx,std_in ;Using STD IN?
597 je foo ;if so: all done, exit
598 mov ah,close ;close the file
599 int dos_ent
600 mov dx,offset errmsg4_pre ;read error
601 mov cl,cs:errlen4_pre
602 call prt_file_name ;print the file name in error
603 mov dx,offset errmsg4_post ;read error
604 mov cl,cs:errlen4_post
605 jmp r_error
606
607;----- PRINT ERRORS -------------------------------------------------;
608open_error:
609 mov dx,offset errmsg3_pre ;error in open operation
610 mov cl,cs:errlen3_pre
611 call prt_err_2 ;print error message
612 call prt_file_name ;print the file name in error
613 mov dx,offset errmsg3_post ;error in open operation
614 mov cl,cs:errlen3_post
615r_error:
616 call prt_err_2 ;print error message
617
618;----- SCAN THE REST OF THE COMMAND LINE ----------------------------;
619scan_rest:
620 pop ds ;restore pointer to comm. line
621 pop si ;restore pointer to next comm.
622 call kill_bl ;look for further args.
623 or bx,bx ;test for a CR
624 jnz foo
625 jmp further_args
626foo:
627 mov al,0 ;Proper code
628done:
629 mov ah,exit ;All done, exit with proper code.
630 int dos_ent
631
632
633;--------------------------------------------------------------------;
634; Get rid of blanks in command line. ;
635; Advances the SI reg till the next non-blank character, if the ;
636; character is a CR (0dh) then returns with BX non-zero, otherwise ;
637; BX is zero. ;
638; ;
639; entry: ;
640; SI points to the first character on the line to scan. ;
641; ;
642; exit: ;
643; SI points to the first non-blank character found. ;
644; BX contains 0D hex if the first non-blank found is ;
645; a Carriage Return, otherwise it is 0. ;
646; ;
647; modifies: ;
648; BX, SI, and AX ;
649; ;
650;--------------------------------------------------------------------;
651kill_bl:
652 cld ;increment
653 xor bx,bx ;zero bx to start: no CR found
654no_bl:
655 lodsb ;get rid of blanks
656 cmp al,' '
657 je no_bl
658 cmp al,CR
659 jnz no_cr
660 mov bx,ax ;make bx non-zero (actually 0dh)
661no_cr:
662 dec si ;adjust pointer
663 ret
664
665
666;--------------------------------------------------------------------;
667; Clear Counters ;
668;--------------------------------------------------------------------;
669clr_cntrs:
670 mov byte ptr es:mtch_cntr,0
671 mov byte ptr es:line_cntr,0
672 ret
673
674;--------------------------------------------------------------------;
675; Print Count of Matched lines ;
676; ;
677; Modifies: AX,CX,DX and DI ;
678;--------------------------------------------------------------------;
679print_count:
680 push bx ;save handle
681 cmp bx,std_in ;using std_in?
682 jz sj3 ;if so do not print file name
683
684 mov dx,offset colon
685 mov cx,2
686 call prout ;print colon
687sj3:
688 mov ax,ds:mtch_cntr
689 mov di,offset n2_buf ;buffer for characters
690 call bin2asc ;convert to ascii
691 mov dx,offset n2_buf
692 call prout ;print the number
693 mov dx,offset crlf
694 mov cx,2
695 call prout ;print an end of line
696 pop bx
697 ret
698
699
700;--------------------------------------------------------------------;
701; Print relative line number ;
702; ;
703; Modifies: AX,CX and DI ;
704;--------------------------------------------------------------------;
705prt_lcntr:
706 push bx
707 push dx
708 mov ax,ds:line_cntr
709 mov di,offset n2_buf
710 call bin2asc
711 mov byte ptr[di],"]"
712 inc cx
713 inc cx
714 mov dx,offset n1_buf
715 call prout
716 pop dx
717 pop bx
718 ret
719
720;--------------------------------------------------------------------;
721; Print string to STD_OUT ;
722;--------------------------------------------------------------------;
723prout:
724 mov bx,std_out
725 mov ah,write
726 int dos_ent
727 ret
728
729
730;--------------------------------------------------------------------;
731; Binary to Ascii conversion routine ;
732; ;
733; Entry: ;
734; AX Binary number ;
735; DI Points to one past the last char in the ;
736; result buffer. ;
737; ;
738; Exit: ;
739; Result in the buffer MSD first ;
740; CX Digit count ;
741; ;
742; Modifies: ;
743; AX,BX,CX,DX and DI ;
744; ;
745;--------------------------------------------------------------------;
746bin2asc:
747 mov bx,0ah
748 xor cx,cx
749go_div:
750 inc cx
751 cmp ax,bx
752 jb div_done
753 xor dx,dx
754 div bx
755 add dl,'0' ;convert to ASCII
756 push dx
757 jmp short go_div
758
759div_done:
760 add al,'0'
761 push ax
762 mov bx,cx
763deposit:
764 pop ax
765 stosb
766 loop deposit
767 mov cx,bx
768 ret
769
770
771;--------------------------------------------------------------------;
772; Print the current file name ;
773; ;
774; modifies: ;
775; DX, CX, BX and AX ;
776;--------------------------------------------------------------------;
777prt_file_name:
778 mov dx,offset file_name_buf ;print the file name
779 mov cx,ds:file_name_len ;retrive file name length
780 jmp short prt_err_2
781
782
783;--------------------------------------------------------------------;
784; Print an error message to the Standart error ;
785; ;
786; entry: ;
787; DX has the pointer to the message ;
788; CX has the length of the message ;
789; ;
790; modifies: ;
791; BX and AX ;
792;--------------------------------------------------------------------;
793prt_err:
794 push ds ;Save the current DS
795 push cs ;Make DS point to the right
796 pop ds ; place, for DOS use.
797 call prt_err_2
798 pop ds
799 ret
800
801prt_err_2:
802 xor ch,ch
803 mov bx,std_err
804 mov ah,write
805 int dos_ent ;write error message
806 ret
807
808
809;--------------------------------------------------------------------;
810; CAPIALIZES THE CHARACTER IN AL ;
811; ;
812; entry: ;
813; AL has the character to Capitalize ;
814; ;
815; exit: ;
816; AL has the capitalized character ;
817; ;
818; modifies: ;
819; AL ;
820;--------------------------------------------------------------------;
821make_caps:
822 cmp al,'a'
823 jb no_cap
824 cmp al,'z'
825 jg no_cap
826 and al,0dfh
827no_cap:
828 ret
829
830
831
832IF KANJI
833
834;--------------------------------------------------------------------;
835; ADVANCE POINTER TO NEXT KANJI CHARACTER ;
836; ;
837; entry: DI points to a Kanji string ;
838; CX length in bytes of the string ;
839; ;
840; exit: DI points to next Kanji char ;
841; CX has number of bytes left ;
842; ;
843; modifies: AX ;
844; ;
845;--------------------------------------------------------------------;
846next_kchar:
847 jcxz no_kleft
848 call is_prefix
849 jnc no_p
850 inc di
851 dec cx
852 jcxz no_kleft ; for insurance
853no_p:
854 inc di
855 dec cx
856 clc
857 ret
858
859no_kleft:
860 stc
861 ret
862
863
864;--------------------------------------------------------------------;
865; FIND OUT IS THE BYTE IS A KANJI PREFIX ;
866; ;
867; entry: DI points to a kanji string ;
868; ;
869; exit: Carry set if it is a kanji prefix ;
870; ;
871; modifies: AX ;
872; ;
873;--------------------------------------------------------------------;
874is_prefix:
875 mov al,byte ptr [di]
876 cmp al,81h
877 jb nok
878 cmp al,0a0h
879 jb isk
880 cmp al,0e0h
881 jb nok
882 cmp al,0fdh
883 jb isk
884nok:
885 clc
886 ret
887isk:
888 stc
889 ret
890
891ENDIF
892
893
894;----- PATCH AREA ---------------------------------------------------;
895
896patch_area dw 100h dup(?)
897
898
899
900;----- BUFFER AREA --------------------------------------------------;
901st_length dw 0 ;String argumnet length
902st_buffer db st_buf_size dup(?) ;String argument buffer
903
904file_name_len dw 0 ;File name length
905file_name_buf db fname_buf_size+1 dup(?) ;File name buffer,(allow for
906 ; null at the end).
907
908buffer db buffer_size+1 dup(?) ;file buffer, the last byte is
909 ;a guard in case of forced insertion
910 ;of a CRLF pair.
911
912;----- ERROR MESSAGES -----------------------------------------------;
913 EXTRN bad_vers:byte,crlf:byte,errmsg1:byte,errlen1:byte,errmsg2:byte
914 EXTRN errmsg3_pre:byte,errlen3_pre:byte
915 EXTRN errmsg3_post:byte,errlen3_post:byte
916 EXTRN errmsg4_pre:byte,errlen4_pre:byte
917 EXTRN errmsg4_post:byte,errlen4_post:byte
918 EXTRN heading:byte,heading_len:byte,errlen2:byte
919 EXTRN errmsg5:byte,errmsg5_opt:byte,errlen5:byte
920code ends
921
922
923;----- STACK AREA ---------------------------------------------------;
924stack segment stack
925
926 dw 64 dup(?,?)
927stack_top equ $
928
929stack ends
930
931 end start
932
diff --git a/v2.0/source/FINDMES.ASM b/v2.0/source/FINDMES.ASM
new file mode 100644
index 0000000..cb120db
--- /dev/null
+++ b/v2.0/source/FINDMES.ASM
Binary files differ
diff --git a/v2.0/source/FORMAT.ASM b/v2.0/source/FORMAT.ASM
new file mode 100644
index 0000000..694857b
--- /dev/null
+++ b/v2.0/source/FORMAT.ASM
@@ -0,0 +1,1627 @@
1;***************************************************************
2;
3; 86-DOS FORMAT DISK UTILITY
4;
5; This routine formats a new disk,clears the FAT and DIRECTORY
6; then optionally copies the SYSTEM and COMMAND.COM to this
7; new disk
8;
9; SYNTAX: FORMAT [drive][/switch1][/switch2]...[/switch16]
10;
11; Regardless of the drive designator , the user will be
12; prompted to insert the diskette to be formatted.
13;
14;***************************************************************
15
16;Mod to ask for volume ID ARR 5/12/82
17; 05/19/82 Fixed rounding bug in CLUSCAL: ARR
18;REV 1.5
19; Added rev number message
20; Added dir attribute to DELALL FCB
21;REV 2.00
22; Redone for 2.0
23;REV 2.10
24; 5/1/83 ARR Re-do to transfer system on small memory systems
25
26FALSE EQU 0
27TRUE EQU NOT FALSE
28
29IBMJAPVER EQU FALSE ; SET ONLY ONE SWITCH TO TRUE!
30IBMVER EQU FALSE
31MSVER EQU TRUE
32
33KANJI EQU FALSE
34
35 .xlist
36 INCLUDE DOSSYM.ASM
37 .list
38
39
40;FORMAT Pre-defined switches
41SYSSW EQU 1 ; System transfer
42VOLSW EQU 2 ; Volume ID prompt
43OLDSW EQU 4 ; E5 dir terminator
44
45
46DRNUM EQU 5CH
47
48RECLEN EQU fcb_RECSIZ+7
49RR EQU fcb_RR+7
50
51;Per system file data structure
52
53FILESTRUC STRUC
54FILE_HANDLE DW ? ; Source handle
55FILE_SIZEP DW ? ; File size in para
56FILE_SIZEB DD ? ; File size in bytes
57FILE_OFFSET DD ? ; Offset in file (partial)
58FILE_START DW ? ; Para number of start in buffer
59FILE_DATE DW ? ; Date of file
60FILE_TIME DW ? ; Time of file
61FILE_NAME DB ? ; Start of name
62FILESTRUC ENDS
63
64CODE SEGMENT PUBLIC 'CODE'
65
66 ASSUME CS:CODE,DS:CODE,ES:CODE
67
68 ORG 100H
69
70;For OEM module
71 PUBLIC SWITCHMAP,DRIVE
72 EXTRN HARDFLAG:BYTE ;0 = REMOVABLE MEDIA
73 EXTRN SWITCHLIST:BYTE,FATID:BYTE,FATSPACE:WORD
74 EXTRN STARTSECTOR:WORD,FREESPACE:WORD,INIT:NEAR
75 EXTRN DISKFORMAT:NEAR,BADSECTOR:NEAR,DONE:NEAR
76 EXTRN WRTFAT:NEAR
77
78;For FORMES module
79 EXTRN WAITYN:NEAR,REPORT:NEAR
80 PUBLIC PRINT,CRLF,DISP32BITS,UNSCALE,FDSKSIZ,SECSIZ,CLUSSIZ
81 PUBLIC SYSSIZ,BADSIZ
82
83START:
84 JMP SHORT FSTRT
85
86HEADER DB "Vers 2.10"
87
88FSTRT:
89 MOV SP,OFFSET STACK ;Use internal stack
90
91;Code to print header
92; PUSH AX
93; MOV DX,OFFSET HEADER
94; CALL PRINT
95; POP AX
96
97DOSVER_HIGH EQU 020BH ;2.11 in hex
98 PUSH AX ;Save DRIVE validity info
99 MOV AH,GET_VERSION
100 INT 21H
101 XCHG AH,AL ;Turn it around to AH.AL
102 CMP AX,DOSVER_HIGH
103 JAE OKDOS
104GOTBADDOS:
105 MOV DX,OFFSET BADVER
106 MOV AH,STD_CON_STRING_OUTPUT
107 INT 21H
108 INT 20H
109
110OKDOS:
111
112 IF IBMVER ; IBM WANTS TO CHECK FOR ASSIGN.COM
113 XOR AX,AX
114 MOV ES,AX
115 MOV BX,ES:[4*21H]
116 MOV ES,ES:[4*21H+2]
117 CMP BX,122H
118 JNZ NO_ASSIGN
119 CMP ES:[109H],0807H
120 JNZ NO_ASSIGN
121 CMP ES:[103H],0201H
122 JNZ RE_ASSIGN
123 CMP ES:[105H],0403H
124 JNZ RE_ASSIGN
125 CMP ES:[107H],0605H
126 JZ NO_ASSIGN
127RE_ASSIGN:
128 MOV DX,OFFSET ASGERR
129 CALL PRINT
130 JMP FEXIT2
131NO_ASSIGN:
132 PUSH CS
133 POP ES
134 ENDIF
135
136 POP AX
137
138 CMP AL,0FFH ;See if invalid drive specified
139 JNZ DRVGD ;If not proceed
140 MOV DX,OFFSET INVDRV ;Invalid drive message
141 CALL PRINT ;Print the message
142 JMP FEXIT2 ;Exit
143DRVGD:
144 MOV AH,GET_DEFAULT_DRIVE ;Must get the default drive
145 INT 21H ;Default now in AL
146 MOV DEFALT,AL ;Save for later
147 ADD AL,"A"
148 MOV [BIODRV],AL
149 MOV [DOSDRV],AL
150 MOV [SYSDRV],AL
151 MOV [COMDRV],AL
152 MOV SI,DRNUM ;So we can get our parameters
153 LODSB ;Fetch drive designation
154 OR AL,AL ;See if specified
155 JNZ DRVSPEC ;If specfied proceed
156 MOV AL,DEFALT
157 INC AL
158DRVSPEC:
159 DEC AL ;Drive designator now correct
160 MOV BYTE PTR DS:[DRNUM],AL ;And updated
161 MOV DRIVE,AL ;Save copy
162 MOV DX,OFFSET INT_23
163 MOV AH,SET_INTERRUPT_VECTOR
164 MOV AL,23H
165 INT 21H ;Set ^C vector
166 ;Get all the swith information from the command line
167 XOR AX,AX
168 MOV AH,CHAR_OPER ;GET SWITCH CHARACTER
169 INT 21H ;CALL THE DOS
170 MOV [SWTCH],DL
171
172 XOR BX,BX ;Store switch information in BX
173 MOV SI,81H ;Point to the command line buffer
174NXTSWT:
175 CALL SCANOFF
176 LODSB
177 CMP AL,[SWTCH]
178 JZ GETPARM
179 CMP AL,13
180 JZ SAVSWT
181 LODSB ;Get next character
182 CMP AL,":" ;Is it a drive specifier?
183 JNZ INVALID ;No -- invalid parameter
184 CMP BYTE PTR DBLFLG,0 ;Is is the only drive specifier we've seen
185 JNZ INVALID ;No -- invalid parameter
186 INC BYTE PTR DBLFLG ;Yes -- set the flag
187 JMP SHORT NXTSWT
188GETPARM:
189 LODSB
190 ;Convert any lower case input into upper case
191 CMP AL,41H
192 JL GETCHR ;Switch is a digit don't try to convert it
193 AND AL,0DFH
194GETCHR:
195 MOV CL,SWITCHLIST ;Number of legal switches
196 OR CL,CL ;If it's none we shouldn't be here
197 JZ INVALID ;Report the error
198 MOV CH,0
199 MOV DI,1+OFFSET SWITCHLIST ;Point to the legal switch characters
200 REPNE SCASB
201 JNZ INVALID
202 MOV AX,1
203 SHL AX,CL
204 OR BX,AX ;Set the appropriate bit in SWITCHMAP
205 JMP SHORT NXTSWT ;See if there are anymore
206
207INVALID:
208 MOV DX,OFFSET INVPAR
209 CALL PRINT
210 JMP FEXIT
211
212SCANOFF:
213 LODSB
214 CMP AL,20H
215 JZ SCANOFF
216 CMP AL,9
217 JZ SCANOFF
218 DEC SI
219 RET
220
221MEMERR:
222 MOV DX,OFFSET MEMEX
223 CALL PRINT
224 JMP FEXIT
225
226
227SAVSWT:
228
229 IF IBMVER ;/B SWITCH TURNS /8 ON AND /S OFF
230 TEST BX,00100000B
231 JZ NOT_SW_B
232 AND BX,NOT SYSSW ;TURN OFF /S
233 OR BX,00010000B ;TURN ON /8
234NOT_SW_B:
235 ENDIF
236
237 MOV SWITCHMAP,BX
238 TEST SWITCHMAP,SYSSW
239 JZ INITCALL
240 CALL SAVUDIRS
241 MOV BX,[FREESPACE]
242 ADD BX,15
243 MOV CL,4
244 SHR BX,CL
245 PUSH CS
246 POP ES
247 MOV AH,SETBLOCK
248 INT 21H
249 MOV BX,0FFFFH
250 MOV AH,ALLOC
251 INT 21H
252 OR BX,BX
253 JZ MEMERR ;No memory
254 MOV [MSIZE],BX
255 MOV AH,ALLOC
256 INT 21H
257 JC MEMERR ;No memory
258 MOV [MSTART],AX
259 MOV DX,OFFSET SWTCH
260 MOV AH,CHDIR
261 INT 21H ;Go to root on default drive (source)
262
263RDFRST:
264 CALL READDOS ;Read BIOS and DOS
265 JNC INITCALL ;OK -- read next file
266NEEDSYS:
267 CALL SYSPRM ;Prompt for system disk
268 JMP RDFRST ;Try again
269
270INITCALL:
271 CALL INIT ;Let OEM read any files before disk is changed
272 JNC SWITCHCHK
273 MOV DX,OFFSET FRMTERR
274 CALL PRINT
275 JMP FEXIT
276
277SWITCHCHK:
278 MOV DX,SWITCHMAP
279 MOV SWITCHCOPY,DX
280
281SYSLOOP:
282 MOV WORD PTR BADSIZ,0 ;Must intialize for each iteration
283 MOV WORD PTR BADSIZ+2,0
284 MOV WORD PTR SYSSIZ,0
285 MOV WORD PTR SYSSIZ+2,0
286 MOV BYTE PTR DBLFLG,0
287 MOV BYTE PTR CLEARFLG,0
288 MOV DX,SWITCHCOPY
289 MOV SWITCHMAP,DX ;Restore original Switches
290 MOV AL,DRIVE ;Fetch drive
291 ADD AL,"A" ;(AL)= ASCII designation
292 MOV BYTE PTR SNGDRV,AL ;Fill out the message
293 MOV BYTE PTR TARGDRV,AL
294 MOV BYTE PTR HRDDRV,AL
295 CALL DSKPRM ;Prompt for new disk
296 CALL DISKFORMAT ;Format the disk
297 JNC GETTRK
298FRMTPROB:
299 MOV DX,OFFSET FRMTERR
300 CALL PRINT
301 JMP SHORT SYSLOOP
302
303 ;Mark any bad sectors in the FATs
304 ;And keep track of how many bytes there are in bad sectors
305
306GETTRK:
307 CALL BADSECTOR ;Do bad track fix-up
308 JC FRMTPROB ;Had an error in Formatting - can't recover
309 CMP AX,0 ;Are we finished?
310 JNZ TRKFND ;No - check error conditions
311 JMP DRTFAT ;Yes
312TRKFND:
313 CMP BX,STARTSECTOR ;Are any sectors in the system area bad?
314 JGE CLRTEST
315 MOV DX,OFFSET NOUSE ;Can't build FATs of Directory
316 CALL PRINT
317 JMP FRMTPROB ;Bad disk -- try again
318CLRTEST:
319 MOV SECTORS,AX ;Save the number of sectors on the track
320 CMP BYTE PTR CLEARFLG,0 ;Have we already cleared the FAT and DIR?
321 JNZ SYSTEST ;Yes - all set
322 INC CLEARFLG ;Set the flag
323 PUSH BX
324 CALL CLEAR ;Fix-up fat and directory
325 POP BX
326SYSTEST:
327 TEST SWITCHMAP,SYSSW ;If system requested calculate size
328 JZ BAD100
329 CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space?
330 JNZ CMPTRKS ;Yes -- all ready for the compare
331 INC BYTE PTR DBLFLG ;No -- set the flag
332 CALL GETSIZE ;Calculate the system size
333 MOV DX,WORD PTR SYSSIZ+2
334 MOV AX,WORD PTR SYSSIZ
335 DIV SECSIZ
336 ADD AX,STARTSECTOR
337 MOV SYSTRKS,AX ;Space FAT,Dir,and system files require
338CMPTRKS:
339 CMP BX,SYSTRKS
340 JG BAD100
341 MOV DX,OFFSET NOTSYS ;Can't transfer a system
342 CALL PRINT
343 AND SWITCHMAP,NOT SYSSW ;Turn off system transfer switch
344 MOV WORD PTR SYSSIZ+2,0 ;No system to transfer
345 MOV WORD PTR SYSSIZ,0 ;No system to transfer
346BAD100:
347; BX is the first bad sector #, SECTORS is the number of bad sectors starting
348; at BX. This needs to be converted to clusters. The start sector number may
349; need to be rounded down to a cluster boundry, the end sector may need to be
350; rounded up to a cluster boundry. Know BX >= STARTSECTOR
351 SUB BX,STARTSECTOR ; BX is now DATA area relative
352 MOV CX,BX
353 ADD CX,SECTORS
354 DEC CX ; CX is now the last bad sector #
355 MOV AX,BX
356 XOR DX,DX
357 DIV CLUSSIZ
358 MOV BX,AX ; BX is rounded down and converted
359 ; to a cluster #. Where cluster 0 =
360 ; first cluster of data. First bad
361 ; Sector is in cluster BX.
362 MOV AX,CX
363 XOR DX,DX
364 DIV CLUSSIZ
365 MOV CX,AX ; CX is rounded up and converted to a
366 ; to a cluster #. Where cluster 0 =
367 ; first cluster of data. Last bad
368 ; Sector is in cluster CX.
369 SUB CX,BX
370 INC CX ; CX is number of clusters to mark bad
371 ADD BX,2 ; Bias start by correct amount since
372 ; first cluster of data is really
373 ; cluster 2.
374 MOV AX,CLUSSIZ ; Sectors/Cluster
375 MUL SECSIZ ; Times Bytes/Sector
376 MOV BP,AX ; = Bytes/Cluster
377
378; Mark CX clusters bad starting at cluster BX
379PACKIT:
380 MOV DX,0FF7H ;0FF7H indicates a bad sector
381 CALL PACK ;Put it in the allocation map
382 CMP DX,DI ;Have we already marked it bad?
383 JZ BAD150 ;if so, don't add it in
384 ADD WORD PTR BADSIZ,BP ;Add in number of bad bytes
385 JNB BAD150
386 INC WORD PTR BADSIZ+2
387BAD150:
388 INC BX ;Next cluster
389 LOOP PACKIT ;Continue for # of clusters
390 JMP GETTRK
391
392; Inputs:
393 ;BX = Cluster number
394 ;DX = Data
395; Outputs:
396 ;The data is stored in the FAT at the given cluster.
397 ;SI is destroyed
398 ;DI contains the former contents
399 ;No other registers affected
400PACK:
401 PUSH BX
402 PUSH CX
403 PUSH DX
404 MOV SI,BX
405 SHR BX,1
406 ADD BX,FATSPACE
407 ADD BX,SI
408 SHR SI,1
409 MOV SI,WORD PTR [BX]
410 MOV DI,SI
411 JNB ALIGNED
412 MOV CL,4
413 SHL DX,CL
414 SHR DI,CL
415 AND SI,15
416 JMP SHORT PACKIN
417
418ALIGNED:
419 AND SI,0F000H
420PACKIN:
421 AND DI,00FFFH ;DI CONTAINS FORMER CONTENTS
422 OR SI,DX
423 MOV WORD PTR[BX],SI
424 POP DX
425 POP CX
426 POP BX
427 RET
428
429DRTFAT:
430 CMP BYTE PTR CLEARFLG,0
431 JNZ CLEARED
432 CALL CLEAR ;Clear the FAT and Dir
433 TEST SWITCHMAP,SYSSW ;If system requested, calculate size
434 JZ CLEARED
435 CMP BYTE PTR DBLFLG,0 ;Have we already calculated System space?
436 JNZ CLEARED ;Yes
437 INC BYTE PTR DBLFLG ;No -- set the flag
438 CALL GETSIZE ;Calculate the system size
439CLEARED:
440 CALL WRTFAT
441 JNC FATWRT
442 MOV DX,OFFSET NOUSE
443 CALL PRINT
444 JMP FRMTPROB
445
446FATWRT:
447
448 TEST SWITCHMAP,SYSSW ;System desired
449 JZ STATUS
450 CALL WRITEDOS ;Write the BIOS & DOS
451 JNC SYSOK
452 MOV DX,OFFSET NOTSYS ;Can't transfer a system
453 CALL PRINT
454 MOV WORD PTR SYSSIZ+2,0 ;No system transfered
455 MOV WORD PTR SYSSIZ,0 ;No system transfered
456 JMP SHORT STATUS
457
458SYSOK:
459 MOV DX,OFFSET SYSTRAN
460 CALL PRINT
461STATUS:
462 CALL CRLF
463 CALL VOLID
464 MOV AH,DISK_RESET
465 INT 21H
466 CALL DONE ;Final call to OEM module
467 JNC REPORTC
468 JMP FRMTPROB ;Report an error
469
470REPORTC:
471 CALL REPORT
472
473 CALL MORE ;See if more disks to format
474 JMP SYSLOOP ;If we returned from MORE then continue
475
476DISP32BITS:
477 PUSH BX
478 XOR AX,AX
479 MOV BX,AX
480 MOV BP,AX
481 MOV CX,32
482CONVLP:
483 SHL SI,1
484 RCL DI,1
485 XCHG AX,BP
486 CALL CONVWRD
487 XCHG AX,BP
488 XCHG AX,BX
489 CALL CONVWRD
490 XCHG AX,BX
491 ADC AL,0
492 LOOP CONVLP
493 ; Conversion complete. Print 8-digit number with 2 leading blanks.
494 MOV CX,1810H
495 XCHG DX,AX
496 CALL DIGIT
497 XCHG AX,BX
498 CALL OUTWORD
499 XCHG AX,BP
500 CALL OUTWORD
501 POP DX
502 CMP DX,0
503 JZ RET3
504 CALL PRINT
505RET3: RET
506
507OUTWORD:
508 PUSH AX
509 MOV DL,AH
510 CALL OUTBYTE
511 POP DX
512OUTBYTE:
513 MOV DH,DL
514 SHR DL,1
515 SHR DL,1
516 SHR DL,1
517 SHR DL,1
518 CALL DIGIT
519 MOV DL,DH
520DIGIT:
521 AND DL,0FH
522 JZ BLANKZER
523 MOV CL,0
524BLANKZER:
525 DEC CH
526 AND CL,CH
527 OR DL,30H
528 SUB DL,CL
529 MOV AH,STD_CON_OUTPUT
530 INT 21H
531 RET
532
533CONVWRD:
534 ADC AL,AL
535 DAA
536 XCHG AL,AH
537 ADC AL,AL
538 DAA
539 XCHG AL,AH
540RET2: RET
541
542UNSCALE:
543 SHR CX,1
544 JC RET2
545 SHL AX,1
546 RCL DX,1
547 JMP SHORT UNSCALE
548
549
550;******************************************
551; Calculate the size in bytes of the system rounded up to sector and
552; cluster boundries, Answer in SYSSIZ
553
554GETSIZE:
555 MOV AX,WORD PTR BIOSSIZB ;And calculate the system size
556 MOV DX,WORD PTR BIOSSIZB+2
557 CALL FNDSIZ
558 MOV AX,WORD PTR DOSSIZB
559 MOV DX,WORD PTR DOSSIZB+2
560 CALL FNDSIZ
561 MOV AX,WORD PTR COMSIZB
562 MOV DX,WORD PTR COMSIZB+2
563
564;Calculate the number of sectors used for the system
565FNDSIZ:
566 DIV SECSIZ
567 OR DX,DX
568 JZ FNDSIZ0
569 INC AX ; Round up to next sector
570FNDSIZ0:
571 PUSH AX
572 XOR DX,DX
573 DIV CLUSSIZ
574 POP AX
575 OR DX,DX
576 JZ ONCLUS
577 SUB DX,CLUSSIZ
578 NEG DX
579 ADD AX,DX ; Round up sector count to cluster
580 ; boundry
581ONCLUS:
582 MUL SECSIZ ; Turn it back into bytes
583 ADD WORD PTR SYSSIZ,AX
584 ADC WORD PTR SYSSIZ+2,DX
585 RET
586
587PRINT: MOV AH,STD_CON_STRING_OUTPUT ;Print msg pointed to by DX
588 INT 21H
589 RET
590
591MORE: CMP BYTE PTR [HARDFLAG],0 ;Check if removable media
592 JNZ FEXIT
593 CALL WAITYN ;Get yes or no response
594 JB FEXIT ;Exit if CF=1
595 CALL CRLF
596CRLF:
597 MOV DX,OFFSET CRLFMSG
598 CALL PRINT
599 RET
600
601PERROR: CALL PRINT ;Print message and exit
602FEXIT:
603 CALL RESTUDIR ;Restore users dirs
604FEXIT2:
605 INT 20H
606
607 ;Prompt the user for a system diskette in the default drive
608SYSPRM:
609 MOV AH,GET_DEFAULT_DRIVE ;Will find out the default drive
610 INT 21H ;Default now in AL
611 IF IBMVER OR IBMJAPVER
612 MOV BX,AX
613 ENDIF
614 ADD AL,41H ;Now in Ascii
615 MOV SYSDRV,AL ;Text now ok
616
617 IF IBMVER OR IBMJAPVER
618 INT 11H ;Make sure drive has insertable media
619 AND AL,11000000B
620 ROL AL,1
621 ROL AL,1
622 OR AL,AL
623 JNZ NOTONEDRV
624 INC AL
625NOTONEDRV:
626 CMP BL,AL
627 JBE ISFLOPPY
628 MOV AL,"A"
629 MOV BYTE PTR [SYSDRV],AL
630 MOV [BIODRV],AL
631 MOV [DOSDRV],AL
632 MOV [COMDRV],AL
633ISFLOPPY:
634 ENDIF
635
636 MOV DX,OFFSET SYSMSG
637 CALL PRINT ;Print first line
638 CALL WAITKY ;Wait for a key
639 CALL CRLF
640 RET
641
642TARGPRM:
643 MOV DX,OFFSET TARGMSG
644 CALL PRINT ;Print first line
645 CALL WAITKY ;Wait for a key
646 CALL CRLF
647 RET
648
649DSKPRM:
650 MOV DX,OFFSET SNGMSG ;Point to the message
651 CMP BYTE PTR [HARDFLAG],0 ;Check if removable media
652 JZ GOPRNIT
653 MOV DX,OFFSET HRDMSG
654GOPRNIT:
655 CALL PRINT ;Print the message
656 CALL WAITKY ;Wait for space bar
657 CALL CRLF
658 CALL CRLF
659 RET
660
661 ;Will wait for any key to be depressed.
662WAITKY:
663 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_INPUT_NO_ECHO
664 INT 21H
665 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
666 INT 21H
667
668 return
669
670FDPB: MOV DL,DRIVE
671 INC DL
672 MOV AH,GET_DPB
673 PUSH DS
674 INT 21H
675 INC AL
676 JZ DRVERR
677 MOV DX,WORD PTR [BX+13]
678 DEC DX
679 MOV AL,BYTE PTR [BX+4]
680 INC AL
681 MOV CX,WORD PTR [BX+2]
682 POP DS
683 RET
684DRVERR:
685 POP DS
686 MOV DX,OFFSET INVDRV
687 JMP PERROR
688
689 ;Clear the FAT and directory and set Dirty byte in the FAT
690CLEAR:
691 MOV AL,FATID
692 OR AL,0F8H ;Make sure it's a legal value
693 MOV AH,0FFH
694 MOV DI,FATSPACE
695 MOV WORD PTR[DI],AX
696 MOV BYTE PTR[DI+2],AH
697 MOV AH,DISK_RESET
698 INT 21H
699 CALL WRTFAT
700
701 IF IBMJAPVER
702 PUSH DS
703 MOV DL,[DRIVE] ;GET THE DRIVE PARAMETER
704 INC DL
705 MOV AH,32H
706 INT 21H
707
708 MOV DPB_FIRST_ACCESS[BX],-1 ;FORCE MEDIA CHANGE
709 POP DS
710 ENDIF
711
712 CALL FDPB
713 MOV WORD PTR FDSKSIZ,DX
714 MOV SECSIZ,CX
715 MOV AH,0
716 MOV CLUSSIZ,AX
717 SHR DX,1
718 JNC ROUNDED
719 INC DX
720ROUNDED:
721 ADD DX,WORD PTR FDSKSIZ
722 XOR AX,AX
723 MOV CX,DX
724 MOV DI,FATSPACE
725 ADD DI,3
726 REP STOSB
727 MOV AH,DISK_RESET
728 INT 21H
729 CALL WRTFAT
730 MOV DL,[DRIVE]
731 ADD DL,'A'
732 MOV [ROOTSTR],DL
733 MOV DX,OFFSET ROOTSTR
734 MOV AH,CHDIR
735 INT 21H ;Go to root on target drive
736 MOV AL,DRIVE
737 INC AL
738 MOV ALLDRV,AL
739 MOV AH,FCB_DELETE
740 MOV DX,OFFSET ALLFILE
741 INT 21H
742
743 TEST SWITCHMAP,OLDSW ;See if E5 terminated DIR requested
744 JZ RET25
745 MOV AL,DRIVE
746 INC AL
747 MOV BYTE PTR CLEANFILE,AL ;Get the drive
748 MOV DX,OFFSET CLEANFILE
749 MOV AH,FCB_CREATE
750MAKE_NEXT:
751 INT 21H
752 OR AL,AL
753 JNZ DELETE_THEM
754 INC BYTE PTR CLNNAM
755 CMP BYTE PTR CLNNAM,"Z" + 1
756 JNZ MAKE_NEXT
757 MOV BYTE PTR CLNNAM,"A"
758 INC BYTE PTR CLNNAM + 1
759 CMP BYTE PTR CLNNAM + 1,"Z" + 1
760 JNZ MAKE_NEXT
761 MOV BYTE PTR CLNNAM + 1,"A"
762 INC BYTE PTR CLNNAM + 2
763 JMP MAKE_NEXT
764
765DELETE_THEM:
766 MOV WORD PTR CLNNAM,"??"
767 MOV BYTE PTR CLNNAM + 2,"?"
768 MOV AH,FCB_DELETE
769 INT 21H
770RET25:
771 RET ;And return
772
773
774;*****************************************
775; Process V switch if set
776
777VOLID:
778 TEST [SWITCHMAP],VOLSW
779 JNZ DOVOL
780VRET: CLC
781 RET
782
783DOVOL:
784 PUSH CX
785 PUSH SI
786 PUSH DI
787 PUSH ES
788 PUSH DS
789 POP ES
790VOL_LOOP:
791 MOV AL,DRIVE
792 INC AL
793 MOV DS:BYTE PTR[VOLFCB+7],AL
794 MOV DX,OFFSET LABPRMT
795 CALL PRINT
796 MOV DX,OFFSET INBUFF
797 MOV AH,STD_CON_STRING_INPUT
798 INT 21H
799 MOV DX,OFFSET CRLFMSG
800 CALL PRINT
801 MOV DX,OFFSET CRLFMSG
802 CALL PRINT
803 MOV CL,[INBUFF+1]
804 OR CL,CL
805 JZ VOLRET
806 XOR CH,CH
807 MOV SI,OFFSET INBUFF+2
808 MOV DI,SI
809 ADD DI,CX
810 MOV CX,11
811 MOV AL,' '
812 REP STOSB
813 MOV CX,5
814 MOV DI,OFFSET VOLNAM
815 REP MOVSW
816 MOVSB
817 MOV DX,OFFSET VOLFCB
818 MOV AH,FCB_CREATE
819 INT 21H
820 OR AL,AL
821 JZ GOOD_CREATE
822 MOV DX,OFFSET INVCHR ;PRINT INVALID CHARS MESSAGE
823 CALL PRINT
824 JMP VOL_LOOP
825GOOD_CREATE:
826 MOV DX,OFFSET VOLFCB
827 MOV AH,FCB_CLOSE
828 INT 21H
829 CALL CRLF
830VOLRET:
831 POP ES
832 POP DI
833 POP SI
834 POP CX
835 RET
836
837;****************************************
838;Copy IO.SYS, MSDOS.SYS and COMMAND.COM into data area.
839; Carry set if problems
840
841READDOS:
842 CALL TESTSYSDISK
843 JNC RDFILS
844 RET
845
846RDFILS:
847 MOV BYTE PTR [FILSTAT],0
848 MOV BX,[BIOSHandle]
849 MOV AX,[MSTART]
850 MOV DX,AX
851 ADD DX,[MSIZE] ; CX first bad para
852 MOV [BIOSSTRT],AX
853 MOV CX,[BIOSSIZP]
854 ADD AX,CX
855 CMP AX,DX
856 JBE GOTBIOS
857 MOV BYTE PTR [FILSTAT],00000001B ; Got part of BIOS
858 MOV SI,[MSIZE]
859 XOR DI,DI
860 CALL DISIX4
861 MOV DS,[BIOSSTRT]
862ASSUME DS:NOTHING
863 CALL READFILE
864ASSUME DS:CODE
865 JC CLSALL
866 XOR DX,DX
867 MOV CX,DX
868 MOV AX,(LSEEK SHL 8) OR 1
869 INT 21H
870 MOV WORD PTR [BIOSOFFS],AX
871 MOV WORD PTR [BIOSOFFS+2],DX
872FILESDONE:
873 CLC
874CLSALL:
875 PUSHF
876 CALL COMCLS
877 POPF
878 RET
879
880GOTBIOS:
881 MOV BYTE PTR [FILSTAT],00000010B ; Got all of BIOS
882 LES SI,[BIOSSIZB]
883 MOV DI,ES
884 MOV DS,[BIOSSTRT]
885ASSUME DS:NOTHING
886 CALL READFILE
887ASSUME DS:CODE
888 JC CLSALL
889 MOV BX,[DOSHandle]
890 MOV [DOSSTRT],AX
891 CMP AX,DX ; No room left?
892 JZ CLSALL ; Yes
893 MOV CX,[DOSSIZP]
894 ADD AX,CX
895 CMP AX,DX
896 JBE GOTDOS
897 OR BYTE PTR [FILSTAT],00000100B ; Got part of DOS
898 SUB DX,[DOSSTRT]
899 MOV SI,DX
900 XOR DI,DI
901 CALL DISIX4
902 MOV DS,[DOSSTRT]
903ASSUME DS:NOTHING
904 CALL READFILE
905ASSUME DS:CODE
906 JC CLSALL
907 XOR DX,DX
908 MOV CX,DX
909 MOV AX,(LSEEK SHL 8) OR 1
910 INT 21H
911 MOV WORD PTR [DOSOFFS],AX
912 MOV WORD PTR [DOSOFFS+2],DX
913 JMP FILESDONE
914
915GOTDOS:
916 OR BYTE PTR [FILSTAT],00001000B ; Got all of DOS
917 LES SI,[DOSSIZB]
918 MOV DI,ES
919 MOV DS,[DOSSTRT]
920ASSUME DS:NOTHING
921 CALL READFILE
922ASSUME DS:CODE
923CLSALLJ: JC CLSALL
924 MOV BX,[COMHandle]
925 MOV [COMSTRT],AX
926 CMP AX,DX ; No room left?
927 JZ CLSALL ; Yes
928 MOV CX,[COMSIZP]
929 ADD AX,CX
930 CMP AX,DX
931 JBE GOTCOM
932 OR BYTE PTR [FILSTAT],00010000B ; Got part of COMMAND
933 SUB DX,[COMSTRT]
934 MOV SI,DX
935 XOR DI,DI
936 CALL DISIX4
937 MOV DS,[COMSTRT]
938ASSUME DS:NOTHING
939 CALL READFILE
940ASSUME DS:CODE
941 JC CLSALLJ
942 XOR DX,DX
943 MOV CX,DX
944 MOV AX,(LSEEK SHL 8) OR 1
945 INT 21H
946 MOV WORD PTR [COMOFFS],AX
947 MOV WORD PTR [COMOFFS+2],DX
948 JMP FILESDONE
949
950GOTCOM:
951 OR BYTE PTR [FILSTAT],00100000B ; Got all of COMMAND
952 LES SI,[COMSIZB]
953 MOV DI,ES
954 MOV DS,[COMSTRT]
955ASSUME DS:NOTHING
956 CALL READFILE
957ASSUME DS:CODE
958 JMP CLSALL
959
960;**************************************************
961;Write BIOS DOS COMMAND to the newly formatted disk.
962
963WRITEDOS:
964 MOV CX,BIOSATT
965 MOV DX,OFFSET BIOSFIL
966 LES SI,[BIOSSIZB]
967 MOV DI,ES
968 CALL MAKEFIL
969 JNC GOTNBIO
970RET34: RET
971
972GOTNBIO:
973 MOV [TempHandle],BX
974 TEST BYTE PTR FILSTAT,00000010B
975 JNZ GOTALLBIO
976 LES SI,[BIOSOFFS]
977 MOV DI,ES
978 MOV WORD PTR [IOCNT],SI
979 MOV WORD PTR [IOCNT+2],DI
980 MOV BP,OFFSET BIOSData
981 CALL GOTTARG
982 JC RET34
983 JMP SHORT BIOSDONE
984
985GOTALLBIO:
986 LES SI,[BIOSSIZB]
987 MOV DI,ES
988 MOV DS,[BIOSSTRT]
989ASSUME DS:NOTHING
990 CALL WRITEFILE
991ASSUME DS:CODE
992BIOSDONE:
993 MOV BX,[TempHandle]
994 MOV CX,BTIME
995 MOV DX,BDATE
996 CALL CLOSETARG
997 MOV CX,DOSATT
998 MOV DX,OFFSET DOSFIL
999 LES SI,[DOSSIZB]
1000 MOV DI,ES
1001 CALL MAKEFIL
1002 JC RET34
1003
1004GOTNDOS:
1005 MOV [TempHandle],BX
1006 TEST BYTE PTR FILSTAT,00001000B
1007 JNZ GOTALLDOS
1008 MOV BP,OFFSET DOSData
1009 TEST BYTE PTR FILSTAT,00000100B
1010 JNZ PARTDOS
1011 MOV WORD PTR [DOSOFFS],0
1012 MOV WORD PTR [DOSOFFS+2],0
1013 CALL GETSYS3
1014RET34J: JC RET34
1015 JMP SHORT DOSDONE
1016
1017PARTDOS:
1018 LES SI,[DOSOFFS]
1019 MOV DI,ES
1020 MOV WORD PTR [IOCNT],SI
1021 MOV WORD PTR [IOCNT+2],DI
1022 CALL GOTTARG
1023 JC RET34J
1024 JMP SHORT DOSDONE
1025
1026GOTALLDOS:
1027 LES SI,[DOSSIZB]
1028 MOV DI,ES
1029 MOV DS,[DOSSTRT]
1030ASSUME DS:NOTHING
1031 CALL WRITEFILE
1032ASSUME DS:CODE
1033DOSDONE:
1034 MOV BX,[TempHandle]
1035 MOV CX,DTIME
1036 MOV DX,DDATE
1037 CALL CLOSETARG
1038 MOV CX,COMATT
1039 MOV DX,OFFSET COMFIL
1040 LES SI,[COMSIZB]
1041 MOV DI,ES
1042 CALL MAKEFIL
1043 JNC GOTNCOM
1044RET35: RET
1045
1046GOTNCOM:
1047 MOV [TempHandle],BX
1048 TEST BYTE PTR FILSTAT,00100000B
1049 JNZ GOTALLCOM
1050 MOV BP,OFFSET COMData
1051 TEST BYTE PTR FILSTAT,00010000B
1052 JNZ PARTCOM
1053 MOV WORD PTR [COMOFFS],0
1054 MOV WORD PTR [COMOFFS+2],0
1055 CALL GETSYS3
1056 JC RET35
1057 JMP SHORT COMDONE
1058
1059PARTCOM:
1060 LES SI,[COMOFFS]
1061 MOV DI,ES
1062 MOV WORD PTR [IOCNT],SI
1063 MOV WORD PTR [IOCNT+2],DI
1064 CALL GOTTARG
1065 JC RET35
1066 JMP SHORT COMDONE
1067
1068GOTALLCOM:
1069 LES SI,[COMSIZB]
1070 MOV DI,ES
1071 MOV DS,[COMSTRT]
1072ASSUME DS:NOTHING
1073 CALL WRITEFILE
1074ASSUME DS:CODE
1075COMDONE:
1076 MOV BX,[TempHandle]
1077 MOV CX,CTIME
1078 MOV DX,CDATE
1079 CALL CLOSETARG
1080 CMP BYTE PTR [FILSTAT],00101010B
1081 JZ NOREDOS
1082RDFRST2:
1083 CALL READDOS ; Start back with BIOS
1084 JNC NOREDOS
1085 CALL SYSPRM ;Prompt for system disk
1086 JMP RDFRST2 ;Try again
1087NOREDOS:
1088 CLC
1089 RET
1090
1091;*********************************************
1092; Create a file on target disk
1093; CX = attributes, DX points to name
1094; DI:SI is size file is to have
1095;
1096; There is a bug in DOS 2.00 and 2.01 having to do with writes
1097; from the end of memory. In order to circumvent it this routine
1098; must create files with the length in DI:SI
1099;
1100; On return BX is handle, carry set if problem
1101
1102MAKEFIL:
1103 MOV BX,DX
1104 PUSH WORD PTR [BX]
1105 MOV AL,TARGDRV
1106 MOV [BX],AL
1107 MOV AH,CREAT
1108 INT 21H
1109 POP WORD PTR [BX]
1110 MOV BX,AX
1111 JC RET50
1112 MOV CX,DI
1113 MOV DX,SI
1114 MOV AX,LSEEK SHL 8
1115 INT 21H ; Seek to eventual EOF
1116 XOR CX,CX
1117 MOV AH,WRITE
1118 INT 21H ; Set size of file to position
1119 XOR CX,CX
1120 MOV DX,CX
1121 MOV AX,LSEEK SHL 8
1122 INT 21H ; Seek back to start
1123RET50:
1124 RET
1125
1126;*********************************************
1127; Close a file on the target disk
1128; CX/DX is time/date, BX is handle
1129
1130CLOSETARG:
1131 MOV AX,(FILE_TIMES SHL 8) OR 1
1132 INT 21H
1133 MOV AH,CLOSE
1134 INT 21H
1135 RET
1136
1137SAVUDIRS:
1138 XOR DL,DL
1139 MOV SI,OFFSET USERDIRS
1140 MOV BYTE PTR [SI],'\'
1141 INC SI
1142 MOV AH,CURRENT_DIR
1143 INT 21H
1144RET43: RET
1145
1146
1147RESTUDIR:
1148 TEST SWITCHMAP,SYSSW
1149 JZ RET43
1150 MOV DX,OFFSET USERDIRS
1151 MOV AH,CHDIR
1152 INT 21H ; Restore users DIR
1153 RET
1154
1155INT_23:
1156 PUSH CS
1157 POP DS
1158 JMP FEXIT
1159
1160;****************************************
1161; Transfer system files
1162; BP points to data structure for file involved
1163; offset is set to current amount read in
1164; Start set to start of file in buffer
1165; TempHandle is handle to write to on target
1166
1167IOLOOP:
1168 MOV AL,[SYSDRV]
1169 CMP AL,[TARGDRV]
1170 JNZ GOTTARG
1171 MOV AH,DISK_RESET
1172 INT 21H
1173 CALL TARGPRM ;Get target disk
1174
1175GOTTARG:
1176;Enter here if some of file is already in buffer, IOCNT must be set
1177; to size already in buffer.
1178 MOV BX,[TempHandle]
1179 MOV SI,WORD PTR [IOCNT]
1180 MOV DI,WORD PTR [IOCNT+2]
1181 MOV DS,[BP.FILE_START]
1182ASSUME DS:NOTHING
1183 CALL WRITEFILE ; Write next part
1184ASSUME DS:CODE
1185 JNC TESTDONE
1186 RET
1187
1188TESTDONE:
1189 LES AX,[BP.FILE_OFFSET]
1190 CMP AX,WORD PTR [BP.FILE_SIZEB]
1191 JNZ GETSYS3
1192 MOV AX,ES
1193 CMP AX,WORD PTR [BP.FILE_SIZEB+2]
1194 JNZ GETSYS3
1195 RET ; Carry clear from CMP
1196
1197GETSYS3:
1198;Enter here if none of file is in buffer
1199 MOV AX,[MSTART] ; Furthur IO done starting here
1200 MOV [BP.FILE_START],AX
1201 MOV AL,[SYSDRV]
1202 CMP AL,[TARGDRV]
1203 JNZ TESTSYS
1204 MOV AH,DISK_RESET
1205 INT 21H
1206GSYS:
1207 CALL SYSPRM ;Prompt for system disk
1208TESTSYS:
1209 CALL TESTSYSDISK
1210 JC GSYS
1211 MOV BX,[BP.FILE_HANDLE]
1212 LES DX,[BP.FILE_OFFSET]
1213 PUSH DX
1214 MOV CX,ES
1215 MOV AX,LSEEK SHL 8
1216 INT 21H
1217 POP DX
1218 LES SI,[BP.FILE_SIZEB]
1219 MOV DI,ES
1220 SUB SI,DX
1221 SBB DI,CX ; DI:SI is #bytes to go
1222 PUSH DI
1223 PUSH SI
1224 ADD SI,15
1225 ADC DI,0
1226 CALL DISID4
1227 MOV AX,SI
1228 POP SI
1229 POP DI
1230 CMP AX,[MSIZE]
1231 JBE GOTSIZ2
1232 MOV SI,[MSIZE]
1233 XOR DI,DI
1234 CALL DISIX4
1235GOTSIZ2:
1236 MOV WORD PTR [IOCNT],SI
1237 MOV WORD PTR [IOCNT+2],DI
1238 MOV DS,[MSTART]
1239ASSUME DS:NOTHING
1240 CALL READFILE
1241ASSUME DS:CODE
1242 JNC GETOFFS
1243 CALL CLSALL
1244 JMP GSYS
1245GETOFFS:
1246 XOR DX,DX
1247 MOV CX,DX
1248 MOV AX,(LSEEK SHL 8) OR 1
1249 INT 21H
1250 MOV WORD PTR [BP.FILE_OFFSET],AX
1251 MOV WORD PTR [BP.FILE_OFFSET+2],DX
1252 CALL CLSALL
1253 JMP IOLOOP
1254
1255;*************************************************
1256; Test to see if correct system disk. Open handles
1257
1258TESTSYSDISK:
1259 MOV AX,OPEN SHL 8
1260 MOV DX,OFFSET BIOSFIL
1261 INT 21H
1262 JNC SETBIOS
1263CRET12: STC
1264RET12: RET
1265
1266SETBIOS:
1267 MOV [BIOSHandle],AX
1268 MOV BX,AX
1269 CALL GETFSIZ
1270 CMP [BIOSSIZP],0
1271 JZ SETBIOSSIZ
1272 CMP [BIOSSIZP],AX
1273 JZ SETBIOSSIZ
1274BIOSCLS:
1275 MOV AH,CLOSE
1276 MOV BX,[BIOSHandle]
1277 INT 21H
1278 JMP CRET12
1279
1280SETBIOSSIZ:
1281 MOV [BIOSSIZP],AX
1282 MOV WORD PTR [BIOSSIZB],SI
1283 MOV WORD PTR [BIOSSIZB+2],DI
1284 MOV [BDATE],DX
1285 MOV [BTIME],CX
1286 MOV AX,OPEN SHL 8
1287 MOV DX,OFFSET DOSFIL
1288 INT 21H
1289 JNC DOSOPNOK
1290 JMP BIOSCLS
1291
1292DOSOPNOK:
1293 MOV [DOSHandle],AX
1294 MOV BX,AX
1295 CALL GETFSIZ
1296 CMP [DOSSIZP],0
1297 JZ SETDOSSIZ
1298 CMP [DOSSIZP],AX
1299 JZ SETDOSSIZ
1300DOSCLS:
1301 MOV AH,CLOSE
1302 MOV BX,[DOSHandle]
1303 INT 21H
1304 JMP BIOSCLS
1305
1306SETDOSSIZ:
1307 MOV [DOSSIZP],AX
1308 MOV WORD PTR [DOSSIZB],SI
1309 MOV WORD PTR [DOSSIZB+2],DI
1310 MOV [DDATE],DX
1311 MOV [DTIME],CX
1312 MOV AX,OPEN SHL 8
1313 MOV DX,OFFSET COMFIL
1314 INT 21H
1315 JC DOSCLS
1316 MOV [COMHandle],AX
1317 MOV BX,AX
1318 CALL GETFSIZ
1319 CMP [COMSIZP],0
1320 JZ SETCOMSIZ
1321 CMP [COMSIZP],AX
1322 JZ SETCOMSIZ
1323COMCLS:
1324 MOV AH,CLOSE
1325 MOV BX,[COMHandle]
1326 INT 21H
1327 JMP DOSCLS
1328
1329SETCOMSIZ:
1330 MOV [COMSIZP],AX
1331 MOV WORD PTR [COMSIZB],SI
1332 MOV WORD PTR [COMSIZB+2],DI
1333 MOV [CDATE],DX
1334 MOV [CTIME],CX
1335 CLC
1336 RET
1337
1338;*******************************************
1339; Handle in BX, return file size in para in AX
1340; File size in bytes DI:SI, file date in DX, file
1341; time in CX.
1342
1343GETFSIZ:
1344 MOV AX,(LSEEK SHL 8) OR 2
1345 XOR CX,CX
1346 MOV DX,CX
1347 INT 21H
1348 MOV SI,AX
1349 MOV DI,DX
1350 ADD AX,15 ; Para round up
1351 ADC DX,0
1352 AND DX,0FH ; If the file is larger than this
1353 ; it is bigger than the 8086 address space!
1354 MOV CL,12
1355 SHL DX,CL
1356 MOV CL,4
1357 SHR AX,CL
1358 OR AX,DX
1359 PUSH AX
1360 MOV AX,LSEEK SHL 8
1361 XOR CX,CX
1362 MOV DX,CX
1363 INT 21H
1364 MOV AX,FILE_TIMES SHL 8
1365 INT 21H
1366 POP AX
1367 RET
1368
1369;********************************************
1370; Read/Write file
1371; DS:0 is Xaddr
1372; DI:SI is byte count to I/O
1373; BX is handle
1374; Carry set if screw up
1375;
1376; I/O SI bytes
1377; I/O 64K - 1 bytes DI times
1378; I/O DI bytes
1379; DS=CS on output
1380
1381
1382READFILE:
1383; Must preserve AX,DX
1384 PUSH AX
1385 PUSH DX
1386 PUSH BP
1387 MOV BP,READ SHL 8
1388 CALL FILIO
1389 POP BP
1390 POP DX
1391 POP AX
1392 PUSH CS
1393 POP DS
1394 RET
1395
1396WRITEFILE:
1397 PUSH BP
1398 MOV BP,WRITE SHL 8
1399 CALL FILIO
1400 POP BP
1401 PUSH CS
1402 POP DS
1403 RET
1404
1405FILIO:
1406 XOR DX,DX
1407 MOV CX,SI
1408 JCXZ K64IO
1409 MOV AX,BP
1410 INT 21H
1411 JC IORET
1412 ADD DX,AX
1413 CMP AX,CX ; If not =, AX<CX, carry set.
1414 JNZ IORET
1415 CALL NORMALIZE
1416K64IO:
1417 CLC
1418 MOV CX,DI
1419 JCXZ IORET
1420 MOV AX,BP
1421 INT 21H
1422 JC IORET
1423 ADD DX,AX
1424 CMP AX,CX ; If not =, AX<CX, carry set.
1425 JNZ IORET
1426 CALL NORMALIZE
1427 MOV CX,DI
1428K64M1:
1429 PUSH CX
1430 XOR AX,AX
1431 OR DX,DX
1432 JZ NORMIO
1433 MOV CX,10H
1434 SUB CX,DX
1435 MOV AX,BP
1436 INT 21H
1437 JC IORETP
1438 ADD DX,AX
1439 CMP AX,CX ; If not =, AX<CX, carry set.
1440 JNZ IORETP
1441 CALL NORMALIZE
1442NORMIO:
1443 MOV CX,0FFFFH
1444 SUB CX,AX
1445 MOV AX,BP
1446 INT 21H
1447 JC IORETP
1448 ADD DX,AX
1449 CMP AX,CX ; If not =, AX<CX, carry set.
1450 JNZ IORETP
1451 CALL NORMALIZE ; Clears carry
1452 POP CX
1453 LOOP K64M1
1454 PUSH CX
1455IORETP:
1456 POP CX
1457IORET:
1458 RET
1459
1460
1461;*********************************
1462; Shift DI:SI left 4 bits
1463DISIX4:
1464 MOV CX,4
1465SH32:
1466 SHL SI,1
1467 RCL DI,1
1468 LOOP SH32
1469 RET
1470
1471;*********************************
1472; Shift DI:SI right 4 bits
1473DISID4:
1474 MOV CX,4
1475SH32B:
1476 SHR DI,1
1477 RCR SI,1
1478 LOOP SH32B
1479 RET
1480
1481;********************************
1482; Normalize DS:DX
1483
1484NORMALIZE:
1485 PUSH DX
1486 PUSH AX
1487 SHR DX,1
1488 SHR DX,1
1489 SHR DX,1
1490 SHR DX,1
1491 MOV AX,DS
1492 ADD AX,DX
1493 MOV DS,AX
1494 POP AX
1495 POP DX
1496 AND DX,0FH ; Clears carry
1497 RET
1498
1499
1500ROOTSTR DB ?
1501 DB ":"
1502SWTCH DB "/",0
1503DBLFLG DB 0 ;Initialize flags to zero
1504CLEARFLG DB 0
1505DRIVE DB 0
1506DEFALT DB 0 ;Default drive
1507IOCNT DD ?
1508MSTART DW ? ; Start of sys file buffer (para#)
1509MSIZE DW ? ; Size of above in paragraphs
1510TempHandle DW ?
1511FILSTAT DB ? ; In memory status of files
1512 ; XXXXXX00B BIOS not in
1513 ; XXXXXX01B BIOS partly in
1514 ; XXXXXX10B BIOS all in
1515 ; XXXX00XXB DOS not in
1516 ; XXXX01XXB DOS partly in
1517 ; XXXX10XXB DOS all in
1518 ; XX00XXXXB COMMAND not in
1519 ; XX01XXXXB COMMAND partly in
1520 ; XX10XXXXB COMMAND all in
1521
1522USERDIRS DB DIRSTRLEN+3 DUP(?) ; Storage for users current directory
1523
1524BIOSData LABEL BYTE
1525BIOSHandle DW 0
1526BIOSSIZP DW 0
1527BIOSSIZB DD ?
1528BIOSOFFS DD ?
1529BIOSSTRT DW ?
1530BDATE DW 0 ;IO system date stored here
1531BTIME DW 0 ;IO system time stored here
1532
1533BIOSATT EQU attr_hidden + attr_system + attr_read_only
1534BIOSFIL LABEL BYTE
1535BIODRV LABEL BYTE
1536 DB "X:\"
1537 IF IBMVER OR IBMJAPVER
1538 DB "IBMBIO.COM"
1539 ENDIF
1540 IF MSVER
1541 DB "IO.SYS"
1542 ENDIF
1543 DB 0
1544
1545DOSData LABEL BYTE
1546DOSHandle DW 0
1547DOSSIZP DW 0
1548DOSSIZB DD ?
1549DOSOFFS DD ?
1550DOSSTRT DW ?
1551DDATE DW 0 ;DOS date stored here
1552DTIME DW 0 ;DOS time
1553
1554DOSATT EQU attr_hidden + attr_system + attr_read_only
1555DOSFIL LABEL BYTE
1556DOSDRV LABEL BYTE
1557 DB "X:\"
1558 IF IBMVER OR IBMJAPVER
1559 DB "IBMDOS.COM"
1560 ENDIF
1561 IF MSVER
1562 DB "MSDOS.SYS"
1563 ENDIF
1564 DB 0
1565
1566COMData LABEL BYTE
1567COMHandle DW 0
1568COMSIZP DW 0
1569COMSIZB DD ?
1570COMOFFS DD ?
1571COMSTRT DW ?
1572CDATE DW 0 ;Date of COMMAND
1573CTIME DW 0 ;Time of COMMAND
1574
1575COMATT EQU 0
1576COMFIL LABEL BYTE
1577COMDRV LABEL BYTE
1578 DB "X:\COMMAND.COM",0
1579
1580VOLFCB DB -1,0,0,0,0,0,8
1581 DB 0
1582VOLNAM DB " "
1583 DB 8
1584 DB 26 DUP(?)
1585
1586ALLFILE DB -1,0,0,0,0,0,0FFH
1587ALLDRV DB 0,"???????????"
1588 DB 26 DUP(?)
1589
1590CLEANFILE DB 0
1591CLNNAM DB "AAAFFFFFFOR"
1592 DB 26 DUP(?)
1593
1594SWITCHMAP DW ?
1595SWITCHCOPY DW ?
1596FAT DW ?
1597 DW ?
1598CLUSSIZ DW ?
1599SECSIZ DW ?
1600SYSSIZ DD ?
1601FDSKSIZ DD ?
1602BADSIZ DD ?
1603SYSTRKS DW ?
1604SECTORS DW ?
1605INBUFF DB 80,0
1606 DB 80 DUP(?)
1607
1608 DB 100H DUP(?)
1609
1610STACK LABEL BYTE
1611
1612;For FORMES module
1613
1614 EXTRN BADVER:BYTE,SNGMSG:BYTE,SNGDRV:BYTE,HRDMSG:BYTE,HRDDRV:BYTE
1615 EXTRN LABPRMT:BYTE,TARGMSG:BYTE,TARGDRV:BYTE
1616 EXTRN SYSTRAN:BYTE,CRLFMSG:BYTE,INVCHR:BYTE,INVDRV:BYTE
1617 EXTRN SYSMSG:BYTE,SYSDRV:BYTE,FRMTERR:BYTE,NOTSYS:BYTE
1618 EXTRN NOUSE:BYTE,MEMEX:BYTE,INVPAR:BYTE
1619
1620 IF IBMVER
1621 EXTRN ASGERR:BYTE
1622 ENDIF
1623
1624CODE ENDS
1625
1626 END START
1627 \ No newline at end of file
diff --git a/v2.0/source/FORMAT.txt b/v2.0/source/FORMAT.txt
new file mode 100644
index 0000000..ab47f54
--- /dev/null
+++ b/v2.0/source/FORMAT.txt
@@ -0,0 +1,393 @@
1FORMAT - formats a new disk, clears the FAT and DIRECTORY
2and optionally copies the SYSTEM and COMMAND.COM to this
3new disk.
4
5Command syntax:
6
7 FORMAT [drive:][/switch1][/switch2]...[/switch16]
8
9 Where "drive:" is a legal drive specification and if
10 omitted indicates that the default drive will be used.
11 There may be up to 16 legal switches included in the
12 command line.
13
14
15 The OEM must supply five (NEAR) routines to the program
16along with 6 data items. The names of the routines are INIT,
17DISKFORMAT, BADSECTOR, WRTFAT and DONE, and their flow of
18control (by the Microsoft module) is like this:
19
20 |
21 +---------+
22 | INIT |
23 +---------+
24 |
25 |<------------------------------+
26+------------+ |
27| DISKFORMAT | |
28+------------+ |
29 |<-------+ |
30+-----------+ |-This loop is done |- This loop done
31| BADSECTOR | | for each group of | once for each disk
32+-----------+ | bad sectors | to be formatted.
33 |----->--+ | If variable HARDFLAG
34 | | is set then the loop
35+----------+ | is only performed
36| | | once.
37| WRTFAT | |
38+----------+ |
39 | |
40 +------+ |
41 | DONE | |
42 +------+ |
43 +---->--------------------------+
44
45 The INIT, DISKFORMAT, and BADSECTOR routines are free
46to use any MS-DOS system calls, except for calls that cause
47disk accesses on the disk being formatted. DONE may use
48ANY calls, since by the time it is called the new disk has
49been formatted.
50
51The following data must be declared PUBLIC in a module
52provided by the OEM:
53
54 SWITCHLIST - A string of bytes. The first byte is count
55 N, followed by N characters which are the switches to
56 be accepted by the command line scanner. Alphabetic
57 characters must be in upper case (the numeric
58 characters 0-9 are allowed). The last three switches,
59 normally "O", "V" and "S", have pre-defined meanings.
60
61 The "S" switch is the switch which causes the
62 system files IO.SYS, MSDOS.SYS, and COMMAND.COM to be
63 transfered to the disk after it is formatted thus
64 making a "S"ystem disk. The switch can be some letter
65 other than "S", but the last switch in the list is
66 assumed to have the meaning "transfer system",
67 regardles of what the particular letter is.
68
69 The second to the last switch, "V", causes FORMAT
70 to prompt the user for a volume label after the disk
71 is formatted. Again, as with "S", the particular
72 letter is not important but rather the position in the
73 list.
74
75 The third to the last switch, "O", causes FORMAT to
76 produce an IBM Personal Computer DOS version 1.X
77 compatible disk. Normally FORMAT causes a 0 byte to
78 be placed in the first byte of each directory entry
79 instead of the 0E5 Hex free entry designator. This
80 results in a very marked directory search performance
81 increase due to an optimization in the DOS. Disks
82 made this way cause trouble on IBM PC DOS 1.X
83 versions, however, which did not have this
84 optimization. The 0 byte fools IBM 1.X versions into
85 thinking these entries are allocated instead of free,
86 NOTE that IBM Personnal Computer DOS version 2.00 and
87 MS-DOS version 1.25 will have no trouble with these
88 disks, since they have the same optimization. The "O"
89 switch causes FORMAT to re-do the directory with a 0E5
90 Hex byte at the start of each entry so that the disk
91 may be used with 1.X versions of IBM PC DOS, as well
92 as MS-DOS 1.25/2.00 and IBM PC DOS 2.00. This switch
93 should only be given when needed because it takes a
94 fair amount of time for FORMAT to perform the
95 conversion, and it noticably decreases 1.25 and 2.00
96 performance on disks with few directory entries.
97
98 Up to 16 switches are permitted. Normally a "C"
99 switch is specified for "Clear". This switch should
100 cause the formatting operation to be bypassed (within
101 DISKFORMAT or BADSECTOR). This is provided as a
102 time-saving convenience to the user, who may wish
103 to "start fresh" on a previosly formatted and used
104 disk.
105
106 HARDFLAG - BYTE location which specifies whether the
107 OEM routine is formatting a fixed disk or a a drive
108 with removable media. A zero indicates removable
109 media, any other value indicates a fixed disk. The
110 status of this byte only effect the messages printed
111 by the main format module. This value should be
112 set or reset by the OEM supplied INIT routine.
113
114 FATID - BYTE location containing the value to be used
115 in the first byte of the FAT. Must be in the range
116 F8 hex to FF hex.
117
118 STARTSECTOR - WORD location containing the sector number
119 of the first sector of the data area.
120
121 FATSPACE - WORD location containing the address of the
122 start of the FAT area. A FAT built in this area
123 will be written to disk using the OEM supplied WRTFAT
124 subroutine. 6k is sufficient to store any FAT. This
125 area must not overlap the FREESPACE area.
126
127 FREESPACE - WORD location which contains the address
128 of the start of free memory space. This is where
129 the system will be loaded, by the Microsoft module,
130 for transferring to the newly formatted disk. Memory
131 should be available from this address to the end
132 of memory, so it is typically the address of the
133 end of the OEM module.
134
135The following routines must be declared PUBLIC in the
136OEM-supplied module:
137
138 INIT - An initialization routine. This routine is called
139 once at the start of the FORMAT run after the switches
140 have been processed. This routine should perform
141 any functions that only need to be done once per
142 FORMAT run. An example of what this routine might
143 do is read the boot sector into a buffer so that
144 it can be transferred to the new disks by DISKFORMAT.
145 If this routine returns with the CARRY flag set it
146 indicates an error, and FORMAT will print "Format
147 failure" and quit. This feature can be used to detect
148 conflicting switches (like specifying both single
149 and double density) and cause FORMAT to quit without
150 doing anything.
151
152 DISKFORMAT - Formats the disk according to the options
153 indicated by the switches and the value of FATID
154 must be defined when it returns (although INIT may
155 have already done it). This routine is called once
156 for EACH disk to be formatted. If neccessary it
157 must transfer the Bootstrap loader. If any error
158 conditions are detected, set the CARRY flag and return
159 to FORMAT. FORMAT will report a 'Format failure'
160 and prompt for another disk. (If you only require
161 a clear directory and FAT then simply setting the
162 appropriate FATID, if not done by INIT, will be all
163 that DISKFORMAT must do.)
164
165 BADSECTOR - Reports the sector number of any bad sectors
166 that may have been found during the formatting of
167 the disk. This routine is called at least once for
168 EACH disk to be formatted, and is called repeatedly
169 until AX is zero or the carry flag is set. The carry
170 flag is used just as in DISKFORMAT to indicate an
171 error, and FORMAT handles it in the same way. The
172 first sector in the data area must be in STARTSECTOR
173 for the returns from this routine to be interpreted
174 correctly. If there are bad sectors, BADSECTOR must
175 return a sector number in in register BX, the number
176 of consecutive bad sectors in register AX, and carry
177 clear. FORMAT will then process the bad sectors
178 and call BADSECTOR again. When BADSECTOR returns
179 with AX = 0 this means there are no more bad sectors;
180 FORMAT clears the directory and goes on to DONE,
181 so for this last return BX need not contain anything
182 meaningful.
183
184 FORMAT processes bad sectors by determining their
185 corresponding allocation unit and marking that unit
186 with an FF7 hex in the File Allocation Table. CHKDSK
187 understands the FF7 mark as a flag for bad sectors
188 and accordingly reports the number of bytes marked
189 in this way.
190
191 NOTE: Actual formatting of the disk can be done in
192 BADSECTOR instead of DISKFORMAT on a "report as you
193 go" basis. Formatting goes until a group of bad
194 sectors is encountered, BADSECTOR then reports them
195 by returning with AX and BX set. FORMAT will then
196 call BADSECTOR again and formatting can continue.
197
198 WRTFAT - This routine is called after the disk is
199 formatted and bad sectors have been reported. Its
200 purpose is to write all copies of the FAT from the
201 area of memory referenced by FATSPACE to the drive
202 just formatted. It may be possible to use INT 26H
203 to perform the write, or a direct BIOS call. Whether
204 this is possible depends on whether the FAT ID byte
205 is used by the BIOS to determine the media in the
206 drive. If it is, these methods will probably fail
207 because there is no FAT ID byte on the disk yet (in
208 this case WRTFATs primary job is to get the FAT ID
209 byte out on the disk and thus solve the chicken and
210 egg problem).
211
212 DONE - This routine is called after the formatting is
213 complete, the disk directory has been initialized,
214 and the system has been transferred. It is called
215 once for EACH disk to be formatted. This gives the
216 chance for any finishing-up operations, if needed.
217 If the OEM desires certain extra files to be put
218 on the diskette by default, or according to a switch,
219 this could be done in DONE. Again, as in BADSECTOR
220 and DISKFORMAT, carry flag set on return means an
221 error has occurred: 'Format failure' will be printed
222 and FORMAT will prompt for another disk.
223
224
225The following data is declared PUBLIC in Microsoft's FORMAT
226module:
227
228 SWITCHMAP - A word with a bit vector indicating what
229 switches have been included in the command line. The
230 correspondence of the bits to the switches is
231 determined by SWITCHLIST. The right-most
232 (highest-addressed) switch in SWITCHLIST (which must
233 be the system transfer switch, normally "S")
234 corresponds to bit 0, the second from the right,
235 normally "V" to bit 1, etc. For example, if
236 SWITCHLIST is the string "7,'AGI2OVS'", and the user
237 specifies "/G/S" on the command line, then bit 6 will
238 be 0 (A not specified), bit 5 will be 1 (G specified),
239 bits 4,3,2 and 1 will be 0 (neither I,2,O or V
240 specified), and bit 0 will be 1 (S specified).
241
242 Bits 0,1 and 2 are the only switches used in
243 Microsoft's FORMAT module. These switches are used 1)
244 after INIT has been called, to determine if it is
245 necessary to load the system; 2) after the last
246 BADSECTOR call, to determine if the system is to be
247 written, E5 directory conversion is to be done, and/or
248 a volume label is to be asked for. INIT may force
249 these bits set or reset if desired (for example, some
250 drives may never be used as system disk, such as hard
251 disks). After INIT, the "S" bit may be turned off
252 (but not on, since the system was never read) if
253 something happens that means the system should not be
254 transferred.
255
256 After INIT, a second copy of SWITCHMAP is made
257 internally which is used to restore SWITCHMAP for
258 each disk to be formatted. FORMAT itself will turn
259 off the system bit if bad sectors are reported in
260 the system area; DISKFORMAT and BADSECTOR are also
261 allowed to change the map. However, these changes
262 affect only the current disk being formatted, since
263 SWITCHMAP is restored after each disk. (Changes
264 made to SWITCHMAP by INIT do affect ALL disks.)
265
266 DRIVE - A byte containing the drive specified in the
267 command line. 0=A, 1=B, etc.
268
269Once the OEM-supplied module has been prepared, it must linked
270with Microsoft's FORMAT.OBJ module and the FORMES.OBJ module.
271If the OEM-supplied module is called OEMFOR.OBJ, then the
272following linker command will do:
273
274 LINK FORMAT FORMES OEMFOR;
275
276This command will produce a file called FORMAT.EXE. FORMAT
277has been designed to run under MS-DOS as a simple binary
278.COM file. This conversion is performed by LOCATE (EXE2BIN)
279with the command
280
281 LOCATE FORMAT.EXE FORMAT.COM
282
283which will produce the file FORMAT.COM.
284
285;*****************************************
286;
287; A Sample OEM module
288;
289;*****************************************
290
291CODE SEGMENT BYTE PUBLIC 'CODE'
292; This segment must be
293; named CODE, it must be
294; PUBLIC, and it's
295; classname must be 'CODE'
296
297
298 ASSUME CS:CODE,DS:CODE,ES:CODE
299
300; Must declare data and routines PUBLIC
301
302PUBLIC FATID,STARTSECTOR,SWITCHLIST,FREESPACE
303PUBLIC INIT,DISKFORMAT,BADSECTOR,DONE,WRTFAT
304PUBLIC FATSPACE,HARDFLAG
305
306; This data defined in Microsoft-supplied module
307
308 EXTRN SWITCHMAP:WORD,DRIVE:BYTE
309
310INIT:
311
312; Read the boot sector into memory
313 CALL READBOOT
314 ...
315; Set FATID to double sided if "D" switch specified
316 TEST SWITCHMAP,10H
317 JNZ SETDBLSIDE
318 ...
319 RET
320
321DISKFORMAT:
322 ...
323
324; Use the bit map in SWITCHMAP to determine
325; what switches are set
326
327 TEST SWITCHMAP,8 ;Is there a "/C"?
328 JNZ CLEAR ; Yes -- clear operation
329 ; requested jump around the
330 ; format code
331 < format the disk >
332CLEAR:
333 ...
334; Transfer the boot from memory to the new disk
335 CALL TRANSBOOT
336 ...
337 RET
338
339; Error return - set carry
340
341ERRET:
342 STC
343 RET
344
345BADSECTOR:
346 ...
347 RET
348
349
350WRTFAT:
351 ...
352
353WRTFATLOOP:
354 < Set up call to write out a fat to disk>
355 ...
356 MOV BX,[FATSPACE]
357
358 < Write out one fat to disk>
359 JC ERRET
360 ...
361 < Decrement fat counter >
362 JNZ WRTFATLOOP
363 CLC ;Good return
364 RET
365
366
367DONE:
368 ...
369 RET
370
371; Default Single sided
372FATID DB 0FEH
373
374HARDFLAG DB 0
375
376STARTSECTOR DW 9
377
378SWITCHLIST DB 5,"DCOVS" ; "OVS" must be the last
379 ; switches in the list
380
381FATSPACE DW FATBUF
382
383FREESPACE DW ENDBOOT
384
385BOOT DB BOOTSIZE DUP(?) ; Buffer for the
386 ; boot sector
387
388FATBUF DB 6 * 1024 DUP(?) ; Fat buffer
389ENDBOOT LABEL BYTE
390
391CODE ENDS
392 END
393
diff --git a/v2.0/source/FORMES.ASM b/v2.0/source/FORMES.ASM
new file mode 100644
index 0000000..eedae27
--- /dev/null
+++ b/v2.0/source/FORMES.ASM
Binary files differ
diff --git a/v2.0/source/GENFOR.ASM b/v2.0/source/GENFOR.ASM
new file mode 100644
index 0000000..a108593
--- /dev/null
+++ b/v2.0/source/GENFOR.ASM
Binary files differ
diff --git a/v2.0/source/GETSET.ASM b/v2.0/source/GETSET.ASM
new file mode 100644
index 0000000..289f4c8
--- /dev/null
+++ b/v2.0/source/GETSET.ASM
@@ -0,0 +1,627 @@
1TITLE GETSET - GETting and SETting MS-DOS system calls
2NAME GETSET
3;
4; System Calls which get and set various things
5;
6; $GET_VERSION
7; $GET_VERIFY_ON_WRITE
8; $SET_VERIFY_ON_WRITE
9; $SET_CTRL_C_TRAPPING
10; $INTERNATIONAL
11; $GET_DRIVE_FREESPACE
12; $GET_DMA
13; $SET_DMA
14; $GET_DEFAULT_DRIVE
15; $SET_DEFAULT_DRIVE
16; $GET_INTERRUPT_VECTOR
17; $SET_INTERRUPT_VECTOR
18; RECSET
19; $CHAR_OPER
20;
21.xlist
22;
23; get the appropriate segment definitions
24;
25INCLUDE DOSSEG.ASM
26
27IFNDEF ALTVECT
28ALTVECT EQU 0 ; FALSE
29ENDIF
30
31IFNDEF IBM
32IBM EQU 0
33ENDIF
34
35CODE SEGMENT BYTE PUBLIC 'CODE'
36 ASSUME SS:DOSGROUP,CS:DOSGROUP
37
38.xcref
39INCLUDE DOSSYM.ASM
40INCLUDE DEVSYM.ASM
41.cref
42.list
43
44
45 i_need VERFLG,BYTE
46 i_need CNTCFLAG,BYTE
47 i_need DMAADD,DWORD
48 i_need CURDRV,BYTE
49 i_need Current_Country,WORD
50 i_need international_table,BYTE
51 i_need INDOS,BYTE
52 i_need SYSINITVAR,WORD
53 i_need NUMIO,BYTE
54 i_need SWITCH_CHARACTER,BYTE
55 i_need DEVICE_AVAILABILITY,BYTE
56
57USERNUM DW ? ; 24 bit user number
58 DB ?
59 IF IBM
60OEMNUM DB 0 ; 8 bit OEM number
61 ELSE
62OEMNUM DB 0FFH ; 8 bit OEM number
63 ENDIF
64
65MSVERS EQU THIS WORD ; MS-DOS version in hex for $GET_VERSION
66MSMAJOR DB DOS_MAJOR_VERSION
67MSMINOR DB DOS_MINOR_VERSION
68
69
70BREAK <$Get_Version -- Return MSDOS version number>
71 procedure $GET_VERSION,NEAR
72ASSUME DS:NOTHING,ES:NOTHING
73
74; Inputs:
75; None
76; Function:
77; Return MS-DOS version number
78; Outputs:
79; OEM number in BH
80; User number in BL:CX (24 bits)
81; Version number as AL.AH in binary
82; NOTE: On pre 1.28 DOSs AL will be zero
83
84 PUSH SS
85 POP DS
86ASSUME DS:DOSGROUP
87 MOV BX,[USERNUM + 2]
88 MOV CX,[USERNUM]
89 MOV AX,[MSVERS]
90 invoke get_user_stack
91ASSUME DS:NOTHING
92 MOV [SI.user_BX],BX
93 MOV [SI.user_CX],CX
94 MOV [SI.user_AX],AX ; Really only sets AH
95 return
96$GET_VERSION ENDP
97
98BREAK <$International - return country-dependent information>
99;
100; Inputs:
101; DS:DX point to a block
102; Function:
103; give users an idea of what country the application is running
104; Outputs:
105; AX = number of bytes transferred
106; DS:DX ->+---------------------------------+
107; | WORD Date/time format |
108; +---------------------------------+
109; | BYTE ASCIZ currency symbol |
110; +---------------------------------+
111; | BYTE ASCIZ thousands separator |
112; +---------------------------------+
113; | BYTE ASCIZ decimal separator |
114; +---------------------------------+
115
116 procedure $INTERNATIONAL,NEAR
117ASSUME DS:NOTHING,ES:NOTHING
118 MOV BL,AL
119 PUSH DS
120 POP ES
121 PUSH DX
122 POP DI
123 PUSH SS
124 POP DS
125ASSUME DS:DOSGROUP
126 CMP DI,-1
127 JZ international_set
128 OR BL,BL
129 JNZ international_find
130 MOV SI,[Current_Country]
131 MOV AX,WORD PTR [SI-2] ; Get size in AL, country code in AH
132 MOV BL,AH ; Set country code
133 JMP SHORT international_copy
134
135international_find:
136 CALL international_get
137 JNC international_copy
138 error country_not_found
139
140international_get:
141 MOV SI,OFFSET DOSGROUP:international_table
142international_next:
143 LODSW ; Get size in AL, country code in AH
144 CMP AL,-1
145 JNZ check_code
146 STC
147RET35:
148 RET
149
150check_code:
151 CMP BL,AH
152 JZ RET35 ; Carry clear
153 XOR AH,AH
154 ADD SI,AX
155 JMP international_next
156
157international_copy:
158 MOV CL,AL
159 XOR CH,CH
160 PUSH DI
161 REP MOVSB
162 POP DI
163 MOV WORD PTR ES:[DI.MAP_CALL + 2],CS ; Set segment for case map call
164international_ok:
165 XOR AX,AX
166 MOV AL,BL ; Return country code in AX
167 transfer SYS_RET_OK
168
169international_set:
170 CALL international_get
171 JNC international_store
172 error country_not_found
173
174international_store:
175 MOV [Current_Country],SI
176 JMP international_ok
177
178$INTERNATIONAL ENDP
179
180BREAK <$Get_Verify_on_Write - return verify-after-write flag>
181 procedure $GET_VERIFY_ON_WRITE,NEAR
182ASSUME DS:NOTHING,ES:NOTHING
183
184; Inputs:
185; none.
186; Function:
187; returns flag
188; Returns:
189; AL = value of VERIFY flag
190
191 MOV AL,[VERFLG]
192 return
193$GET_VERIFY_ON_WRITE ENDP
194
195BREAK <$Set_Verify_on_Write - Toggle verify-after-write flag>
196 procedure $SET_VERIFY_ON_WRITE,NEAR
197ASSUME DS:NOTHING,ES:NOTHING
198
199; Inputs:
200; AL = desired value of VERIFY flag
201; Function:
202; Sets flag
203; Returns:
204; None
205
206 AND AL,1
207 MOV [VERFLG],AL
208 return
209$SET_VERIFY_ON_WRITE ENDP
210
211BREAK <$Set_CTRL_C_Trapping -- En/Disable ^C check in dispatcher>
212 procedure $SET_CTRL_C_TRAPPING,NEAR
213ASSUME DS:NOTHING,ES:NOTHING
214
215; Inputs:
216; AL = 0 read ^C status
217; AL = 1 Set ^C status, DL = 0/1 for ^C off/on
218; Function:
219; Enable disable ^C checking in dispatcher
220; Outputs:
221; If AL = 0 then DL = 0/1 for ^C off/on
222
223 OR AL,AL
224 JNZ CTRL_C_set
225 invoke get_user_stack
226 MOV AL,[CNTCFLAG]
227 MOV BYTE PTR [SI.user_DX],AL
228 return
229CTRL_C_set:
230 DEC AL
231 JNZ bad_val
232 AND DL,01h
233 MOV [CNTCFLAG],DL
234 return
235bad_val:
236 MOV AL,0FFH
237 return
238$SET_CTRL_C_TRAPPING ENDP
239
240BREAK <$Get_INDOS_Flag -- Return location of DOS critical-section flag>
241 procedure $GET_INDOS_FLAG,NEAR
242ASSUME DS:NOTHING,ES:NOTHING
243
244; Inputs:
245; None
246; Function:
247; Returns location of DOS status for interrupt routines
248; Returns:
249; Flag location in ES:BX
250
251 invoke get_user_stack
252 MOV [SI.user_BX],OFFSET DOSGROUP:INDOS
253 MOV [SI.user_ES],SS
254 return
255$GET_INDOS_FLAG ENDP
256
257;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
258; C A V E A T P R O G R A M M E R ;
259; ;
260 procedure $GET_IN_VARS,NEAR
261; Return a pointer to interesting DOS variables This call is version
262; dependent and is subject to change without notice in future versions.
263; Use at risk.
264 invoke get_user_stack
265 MOV [SI.user_BX],OFFSET DOSGROUP:SYSINITVAR
266 MOV [SI.user_ES],SS
267 return
268$GET_IN_VARS ENDP
269; ;
270; C A V E A T P R O G R A M M E R ;
271;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
272
273BREAK <$Get_Drive_Freespace -- Return bytes of free disk space on a drive>
274 procedure $GET_DRIVE_FREESPACE,NEAR
275ASSUME DS:NOTHING,ES:NOTHING
276
277; Inputs:
278; DL = Drive number
279; Function:
280; Return number of free allocation units on drive
281; Outputs:
282; BX = Number of free allocation units
283; DX = Total Number of allocation units on disk
284; CX = Sector size
285; AX = Sectors per allocation unit
286; = -1 if bad drive specified
287; This call returns the same info in the same registers (except for FAT pointer)
288; as the old FAT pointer calls
289
290 PUSH SS
291 POP DS
292ASSUME DS:DOSGROUP
293 MOV AL,DL
294 invoke GETTHISDRV
295 MOV AX,-1
296 JC BADFRDRIVE
297 invoke FATREAD
298 XOR DX,DX
299 MOV BX,2
300 MOV CX,ES:[BP.dpb_max_cluster]
301 DEC CX
302 PUSH CX ; Save Total
303SCANFREE:
304 invoke UNPACK
305 JNZ NOTFREECLUS
306 INC DX
307NOTFREECLUS:
308 INC BX
309 LOOP SCANFREE
310 POP BX ; Remember Total
311 MOV AL,ES:[BP.dpb_cluster_mask]
312 INC AL
313 XOR AH,AH
314 MOV CX,ES:[BP.dpb_sector_size]
315BADFRDRIVE:
316 invoke get_user_stack
317ASSUME DS:NOTHING
318 MOV [SI. user_CX],CX
319 MOV [SI.user_DX],BX
320 MOV [SI.user_BX],DX
321 MOV [SI.user_AX],AX
322 return
323
324$GET_DRIVE_FREESPACE ENDP
325
326BREAK <$Get_DMA, $Set_DMA -- Get/Set current DMA address>
327 procedure $GET_DMA,NEAR
328ASSUME DS:NOTHING,ES:NOTHING
329
330; Inputs:
331; None
332; Function:
333; Get DISK TRANSFER ADDRESS
334; Returns:
335; ES:BX is current transfer address
336
337 MOV BX,WORD PTR [DMAADD]
338 MOV CX,WORD PTR [DMAADD+2]
339 invoke get_user_stack
340 MOV [SI.user_BX],BX
341 MOV [SI.user_ES],CX
342 return
343$GET_DMA ENDP
344
345 procedure $SET_DMA,NEAR ; System call 26
346ASSUME DS:NOTHING,ES:NOTHING
347
348; Inputs:
349; DS:DX is desired new disk transfer address
350; Function:
351; Set DISK TRANSFER ADDRESS
352; Returns:
353; None
354
355 MOV WORD PTR [DMAADD],DX
356 MOV WORD PTR [DMAADD+2],DS
357 return
358$SET_DMA ENDP
359
360BREAK <$Get_Default_DPB,$Get_DPB -- Return pointer to DPB>
361;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
362; C A V E A T P R O G R A M M E R ;
363; ;
364 procedure $GET_DEFAULT_DPB,NEAR
365ASSUME DS:NOTHING,ES:NOTHING
366
367; Inputs:
368; DL = Drive number (always default drive for call 31)
369; Function:
370; Return pointer to drive parameter table for default drive
371; Returns:
372; DS:BX points to the DPB
373; AL = 0 If OK, = -1 if bad drive (call 50 only)
374
375 MOV DL,0
376 entry $GET_DPB
377 PUSH SS
378 POP DS
379ASSUME DS:DOSGROUP
380 MOV AL,DL
381 invoke GETTHISDRV
382 JC ISNODRV
383 invoke FATREAD
384 invoke get_user_stack
385ASSUME DS:NOTHING
386 MOV [SI.user_BX],BP
387 MOV [SI.user_DS],ES
388 XOR AL,AL
389 return
390
391ISNODRV:
392 MOV AL,-1
393 return
394$GET_Default_dpb ENDP
395; ;
396; C A V E A T P R O G R A M M E R ;
397;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
398
399
400BREAK <$Get_Default_Drive, $Set_Default_Drive -- Set/Get default drive>
401 procedure $GET_DEFAULT_DRIVE,NEAR
402ASSUME DS:NOTHING,ES:NOTHING
403
404; Inputs:
405; None
406; Function:
407; Return current drive number
408; Returns:
409; AL = drive number
410
411 MOV AL,[CURDRV]
412 return
413$GET_DEFAULT_DRIVE ENDP
414
415 procedure $SET_DEFAULT_DRIVE,NEAR
416ASSUME DS:NOTHING,ES:NOTHING
417
418; Inputs:
419; DL = Drive number for new default drive
420; Function:
421; Set the default drive
422; Returns:
423; AL = Number of drives, NO ERROR RETURN IF DRIVE NUMBER BAD
424
425 MOV AL,[NUMIO]
426 CMP DL,AL
427 JNB RET17
428 MOV [CURDRV],DL
429RET17: return
430$SET_DEFAULT_DRIVE ENDP
431
432
433BREAK <$Get_Interrupt_Vector - Get/Set interrupt vectors>
434 procedure $GET_INTERRUPT_VECTOR,NEAR
435ASSUME DS:NOTHING,ES:NOTHING
436
437; Inputs:
438; AL = interrupt number
439; Function:
440; Get the interrupt vector
441; Returns:
442; ES:BX is current interrupt vector
443
444 CALL RECSET
445 LES BX,DWORD PTR ES:[BX]
446 invoke get_user_stack
447 MOV [SI.user_BX],BX
448 MOV [SI.user_ES],ES
449 return
450$GET_INTERRUPT_VECTOR ENDP
451
452 procedure $SET_INTERRUPT_VECTOR,NEAR ; System call 37
453ASSUME DS:NOTHING,ES:NOTHING
454
455; Inputs:
456; AL = interrupt number
457; DS:DX is desired new interrupt vector
458; Function:
459; Set the interrupt vector
460; Returns:
461; None
462
463 CALL RECSET
464 MOV ES:[BX],DX
465 MOV ES:[BX+2],DS
466 return
467$SET_INTERRUPT_VECTOR ENDP
468
469 IF ALTVECT
470VECIN: ; INPUT VECTORS
471 DB 22H ; Terminate
472 DB 23H ; ^C
473 DB 24H ; Hard error
474 DB 28H ; Spooler
475LSTVEC DB ? ; ALL OTHER
476
477VECOUT: ; GET MAPPED VECTOR
478 DB int_terminate
479 DB int_ctrl_c
480 DB int_fatal_abort
481 DB int_spooler
482LSTVEC2 DB ? ; Map to itself
483
484NUMVEC = VECOUT-VECIN
485 ENDIF
486
487procedure RECSET,NEAR
488
489 IF ALTVECT
490 PUSH SS
491 POP ES
492 MOV [LSTVEC],AL ; Terminate list with real vector
493 MOV [LSTVEC2],AL ; Terminate list with real vector
494 MOV CX,NUMVEC ; Number of possible translations
495 MOV DI,OFFSET DOSGROUP:VECIN ; Point to vectors
496 REPNE SCASB
497 MOV AL,ES:[DI+NUMVEC-1] ; Get translation
498 ENDIF
499
500 XOR BX,BX
501 MOV ES,BX
502 MOV BL,AL
503 SHL BX,1
504 SHL BX,1
505 return
506recset ENDP
507
508BREAK <$Char_Oper - hack on paths, switches so that xenix can look like PCDOS>
509;
510; input: AL = function:
511; 0 - read switch char
512; 1 - set switch char (char in DL)
513; 2 - read device availability
514; 3 - set device availability (0/FF in DL)
515; DL = 0 means /DEV/ must preceed device names
516; DL = Non0 means /DEV/ need not preeceed
517; output: (get) DL - character/flag
518;
519 procedure $CHAR_OPER,NEAR
520 ASSUME DS:NOTHING,ES:NOTHING
521 PUSH SS
522 POP DS
523ASSUME DS:DOSGROUP
524 OR AL,AL
525 JNZ char_oper_set_switch
526 MOV DL,[switch_character]
527 JMP SHORT char_oper_ret
528char_oper_set_switch:
529 DEC AL
530 JNZ char_oper_read_avail
531 MOV [switch_character],DL
532 return
533char_oper_read_avail:
534 DEC AL
535 JNZ char_oper_set_avail
536 MOV DL,[device_availability]
537 JMP SHORT char_oper_ret
538char_oper_set_avail:
539 DEC AL
540 JNZ char_oper_bad_ret
541 MOV [device_availability],DL
542 return
543char_oper_bad_ret:
544 MOV AL,0FFh
545 return
546char_oper_ret:
547 invoke get_user_stack
548 MOV [SI.user_DX],DX
549 return
550$CHAR_OPER ENDP
551
552BREAK <$SetDPB - Create a valid DPB from a user-specified BPB>
553 procedure $SETDPB,NEAR
554ASSUME DS:NOTHING,ES:NOTHING
555
556; Inputs:
557; ES:BP Points to DPB
558; DS:SI Points to BPB
559; Function:
560; Build a correct DPB from the BPB
561; Outputs:
562; ES:BP and DS preserved all others destroyed
563
564 MOV DI,BP
565 ADD DI,2 ; Skip over dpb_drive and dpb_UNIT
566 LODSW
567 STOSW ; dpb_sector_size
568 MOV DX,AX
569 LODSB
570 DEC AL
571 STOSB ; dpb_cluster_mask
572 INC AL
573 XOR AH,AH
574LOG2LOOP:
575 TEST AL,1
576 JNZ SAVLOG
577 INC AH
578 SHR AL,1
579 JMP SHORT LOG2LOOP
580SAVLOG:
581 MOV AL,AH
582 STOSB ; dpb_cluster_shift
583 MOV BL,AL
584 MOVSW ; dpb_first_FAT Start of FAT (# of reserved sectors)
585 LODSB
586 STOSB ; dpb_FAT_count Number of FATs
587 MOV BH,AL
588 LODSW
589 STOSW ; dpb_root_entries Number of directory entries
590 MOV CL,5
591 SHR DX,CL ; Directory entries per sector
592 DEC AX
593 ADD AX,DX ; Cause Round Up
594 MOV CX,DX
595 XOR DX,DX
596 DIV CX
597 MOV CX,AX ; Number of directory sectors
598 INC DI
599 INC DI ; Skip dpb_first_sector
600 MOVSW ; Total number of sectors in DSKSIZ (temp as dpb_max_cluster)
601 LODSB
602 MOV ES:[BP.dpb_media],AL ; Media byte
603 LODSW ; Number of sectors in a FAT
604 STOSB ; dpb_FAT_size
605 MUL BH ; Space occupied by all FATs
606 ADD AX,ES:[BP.dpb_first_FAT]
607 STOSW ; dpb_dir_sector
608 ADD AX,CX ; Add number of directory sectors
609 MOV ES:[BP.dpb_first_sector],AX
610 SUB AX,ES:[BP.DSKSIZ]
611 NEG AX ; Sectors in data area
612 MOV CL,BL ; dpb_cluster_shift
613 SHR AX,CL ; Div by sectors/cluster
614 INC AX
615 MOV ES:[BP.dpb_max_cluster],AX
616 MOV ES:[BP.dpb_current_dir],0 ; Current directory is root
617 return
618$SETDPB ENDP
619; ;
620; C A V E A T P R O G R A M M E R ;
621;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
622
623 do_ext
624
625CODE ENDS
626 END
627
diff --git a/v2.0/source/HRDDRV.ASM b/v2.0/source/HRDDRV.ASM
new file mode 100644
index 0000000..672b99d
--- /dev/null
+++ b/v2.0/source/HRDDRV.ASM
@@ -0,0 +1,501 @@
1 TITLE HRDDRV.SYS for the ALTOS ACS-86C.
2
3; Hard Disk Drive for Version 2.x of MSDOS.
4
5; Constants for commands in Altos ROM.
6
7ROM_CONSTA EQU 01 ;Return status AL of console selected in CX.
8ROM_CONIN EQU 02 ;Get char. from console in CX to AL
9ROM_CONOUT EQU 03 ;Write char. in DL to console in CX.
10ROM_PMSG EQU 07 ;Write string ES:DX to console in CX.
11ROM_DISKIO EQU 08 ;Perform disk I/O from IOPB in ES:CX.
12ROM_INIT EQU 10 ;Returns boot console and top memory ES:DX.
13
14
15CODE SEGMENT
16ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
17
18 ORG 0 ;Starts at an offset of zero.
19
20 PAGE
21 SUBTTL Device driver tables.
22
23;-----------------------------------------------+
24; DWORD pointer to next device | 1 word offset.
25; (-1,-1 if last device) | 1 word segement.
26;-----------------------------------------------+
27; Device attribute WORD ; 1 word.
28; Bit 15 = 1 for chacter devices. ;
29; 0 for Block devices. ;
30; ;
31; Charcter devices. (Bit 15=1) ;
32; Bit 0 = 1 current sti device. ;
33; Bit 1 = 1 current sto device. ;
34; Bit 2 = 1 current NUL device. ;
35; Bit 3 = 1 current Clock device. ;
36; ;
37; Bit 13 = 1 for non IBM machines. ;
38; 0 for IBM machines only. ;
39; Bit 14 = 1 IOCTL control bit. ;
40;-----------------------------------------------+
41; Device strategy pointer. ; 1 word offset.
42;-----------------------------------------------+
43; Device interrupt pointer. ; 1 word offset.
44;-----------------------------------------------+
45; Device name field. ; 8 bytes.
46; Character devices are any valid name ;
47; left justified, in a space filled ;
48; field. ;
49; Block devices contain # of units in ;
50; the first byte. ;
51;-----------------------------------------------+
52
53DSKDEV: ;Header for hard disk driver.
54 DW -1,-1 ;Last device
55 DW 2000H ;Is a block device
56 DW STRATEGY
57 DW DSK_INT
58MEMMAX DB 1 ;Number of Units
59
60 PAGE
61 SUBTTL Dispatch tables for each device.
62
63DSK_TBL:DW DSK_INI ;0 - Initialize Driver.
64 DW MEDIAC ;1 - Return current media code.
65 DW GET_BPB ;2 - Get Bios Parameter Block.
66 DW CMDERR ;3 - Reserved. (currently returns error)
67 DW DSK_RED ;4 - Block read.
68 DW BUS_EXIT ;5 - (Not used, return busy flag)
69 DW EXIT ;6 - Return status. (Not used)
70 DW EXIT ;7 - Flush input buffer. (Not used.)
71 DW DSK_WRT ;8 - Block write.
72 DW DSK_WRV ;9 - Block write with verify.
73 DW EXIT ;10 - Return output status.
74 DW EXIT ;11 - Flush output buffer. (Not used.)
75 DW EXIT ;12 - IO Control.
76
77 PAGE
78 SUBTTL Strategy and Software Interrupt routines.
79
80;Define offsets for io data packet
81
82IODAT STRUC
83CMDLEN DB ? ;LENGTH OF THIS COMMAND
84UNIT DB ? ;SUB UNIT SPECIFIER
85CMD DB ? ;COMMAND CODE
86STATUS DW ? ;STATUS
87 DB 8 DUP (?)
88MEDIA DB ? ;MEDIA DESCRIPTOR
89TRANS DD ? ;TRANSFER ADDRESS
90COUNT DW ? ;COUNT OF BLOCKS OR CHARACTERS
91START DW ? ;FIRST BLOCK TO TRANSFER
92IODAT ENDS
93
94PTRSAV DD 0 ;Strategy pointer save.
95
96;
97; Simplistic Strategy routine for non-multi-Tasking system.
98;
99; Currently just saves I/O packet pointers in PTRSAV for
100; later processing by the individual interrupt routines.
101;
102
103STRATP PROC FAR
104
105STRATEGY:
106 MOV WORD PTR CS:[PTRSAV],BX
107 MOV WORD PTR CS:[PTRSAV+2],ES
108 RET
109
110STRATP ENDP
111
112
113;
114; Ram memory driver interrupt routine for processing I/O packets.
115;
116
117DSK_INT:
118 PUSH SI ;Save SI from caller.
119 MOV SI,OFFSET DSK_TBL
120
121;
122; Common program for handling the simplistic I/O packet
123; processing scheme in MSDOS 2.0
124;
125
126ENTRY: PUSH AX ;Save all nessacary registers.
127 PUSH CX
128 PUSH DX
129 PUSH DI
130 PUSH BP
131 PUSH DS
132 PUSH ES
133 PUSH BX
134
135 LDS BX,CS:[PTRSAV] ;Retrieve pointer to I/O Packet.
136
137 MOV AL,[BX.UNIT] ;AL = Unit code.
138 MOV AH,[BX.MEDIA] ;AH = Media descriptor.
139 MOV CX,[BX.COUNT] ;CX = Contains byte/sector count.
140 MOV DX,[BX.START] ;DX = Starting Logical sector.
141 XCHG DI,AX ;Save Unit and Media Temporarily.
142 MOV AL,[BX.CMD] ;Retrieve Command type. (1 => 11)
143 XOR AH,AH ;Clear upper half of AX for calculation.
144 ADD SI,AX ;Compute entry pointer in dispatch table.
145 ADD SI,AX
146 CMP AL,11 ;Verify that not more than 11 commands.
147 JA CMDERR ;Ah, well, error out.
148 XCHG AX,DI
149 LES DI,[BX.TRANS] ;DI contains addess of Transfer address.
150 ;ES contains segment.
151 PUSH CS
152 POP DS ;Data segment same as Code segment.
153 JMP [SI] ;Perform I/O packet command.
154
155 PAGE
156 SUBTTL Common error and exit points.
157
158BUS_EXIT: ;Device busy exit.
159 MOV AH,00000011B ;Set busy and done bits.
160 JMP SHORT EXIT1
161
162CMDERR: MOV AL,3 ;Set unknown command error #.
163
164;
165; Common error processing routine.
166; AL contains actual error code.
167;
168; Error # 0 = Write Protect violation.
169; 1 = Unkown unit.
170; 2 = Drive not ready.
171; 3 = Unknown command in I/O packet.
172; 4 = CRC error.
173; 5 = Bad drive request structure length.
174; 6 = Seek error.
175; 7 = Unknown media discovered.
176; 8 = Sector not found.
177; 9 = Printer out of paper.
178; 10 = Write fault.
179; 11 = Read fault.
180; 12 = General failure.
181;
182
183ERR_EXIT:
184 MOV AH,10000001B ;Set error and done bits.
185 STC ;Set carry bit also.
186 JMP SHORT EXIT1 ;Quick way out.
187
188EXITP PROC FAR ;Normal exit for device drivers.
189
190EXIT: MOV AH,00000001B ;Set done bit for MSDOS.
191EXIT1: LDS BX,CS:[PTRSAV]
192 MOV [BX.STATUS],AX ;Save operation compete and status.
193
194 POP BX ;Restore registers.
195 POP ES
196 POP DS
197 POP BP
198 POP DI
199 POP DX
200 POP CX
201 POP AX
202 POP SI
203 RET ;RESTORE REGS AND RETURN
204EXITP ENDP
205
206 PAGE
207
208 subttl Hard Disk drive control.
209
210;
211; Read command = 09 hex.
212; Write command = 02 hex.
213; Seek command = 10 hex.
214; Recal command = 20 hex.
215; Rezero command = 40 hex.
216; Reset command = 80 hex.
217;
218; Busy = 01 hex.
219; Operation Complete = 02 hex.
220; Bad Sector = 04 hex.
221; Record Not found = 08 hex.
222; CRC error = 10 hex.
223; (not used) = 20 hex.
224; Write fault = 40 hex.
225; Drive Ready = 80 hex.
226;
227
228hd_read equ 09h
229hd_writ equ 02h
230hd_wmsk equ 5dh
231hd_rmsk equ 9ch
232 page
233
234 SUBTTL Altos monitor ram and 8089 IOPB structures.
235
236;
237; Structure to reference 8089 and ROM command table.
238;
239
240SIOPB STRUC
241 DB 4 DUP (?) ;Monitor Use Only
242OPCODE DB ? ;I/O operation code.
243DRIVE DB ? ;Logical drive spec.
244TRACK DW ? ;Logical track number.
245HEAD DB ? ;Logical head number.
246SECTOR DB ? ;Logical sector to start with.
247SCOUNT DB ? ;Number of logical sectors in buffer.
248RETCODE DB ? ;Error code after masking.
249RETMASK DB ? ;Error mask.
250RETRIES DB ? ;Number of retries before error exit.
251DMAOFF DW ? ;Buffer offset address.
252DMASEG DW ? ;Buffer segment.
253SECLENG DW ? ;Sector Length.
254 DB 6 DUP (?) ;8089 use only.
255SIOPB ENDS
256
257IOPB SIOPB <,0,0,0,0,0,0,0,0,0,0,0,0,>
258
259 PAGE
260 SUBTTL Common Drive parameter block definitions on Altos.
261
262DBP STRUC
263
264JMPNEAR DB 3 DUP (?) ;Jmp Near xxxx for boot.
265NAMEVER DB 8 DUP (?) ;Name / Version of OS.
266
267;------- Start of Drive Parameter Block.
268
269SECSIZE DW ? ;Sector size in bytes. (dpb)
270ALLOC DB ? ;Number of sectors per alloc. block. (dpb)
271RESSEC DW ? ;Reserved sectors. (dpb)
272FATS DB ? ;Number of FAT's. (dpb)
273MAXDIR DW ? ;Number of root directory entries. (dpb)
274SECTORS DW ? ;Number of sectors per diskette. (dpb)
275MEDIAID DB ? ;Media byte ID. (dpb)
276FATSEC DW ? ;Number of FAT Sectors. (dpb)
277
278;------- End of Drive Parameter Block.
279
280SECTRK DW ? ;Number of Sectors per track.
281HEADS DW ? ;Number of heads per cylinder.
282HIDDEN DW ? ;Number of hidden sectors.
283
284DBP ENDS
285
286HDDRIVE DBP <,,512,4,0,2,256,4000,0F5H,3,12,4,0>
287
288
289INI_TAB DW OFFSET HDDRIVE.SECSIZE
290
291 PAGE
292 SUBTTL Media check routine
293
294;
295; Media check routine.
296; On entry:
297; AL = memory driver unit number.
298; AH = media byte
299; On exit:
300;
301; [MEDIA FLAG] = -1 (FF hex) if disk is changed.
302; [MEDIA FLAG] = 0 if don't know.
303; [MEDIA FLAG] = 1 if not changed.
304;
305
306MEDIAC: LDS BX,CS:[PTRSAV]
307 MOV BYTE PTR [BX.TRANS],1
308 JMP EXIT
309
310 PAGE
311 SUBTTL Build and return Bios Parameter Block for a diskette.
312
313;
314; Build Bios Parameter Blocks.
315;
316; On entry: ES:BX contains the address of a scratch sector buffer.
317; AL = Unit number.
318; AH = Current media byte.
319;
320; On exit: Return a DWORD pointer to the associated BPB
321; in the Request packet.
322;
323
324GET_BPB:
325 MOV SI,OFFSET HDDRIVE+11
326 LDS BX,CS:[PTRSAV]
327 MOV WORD PTR [BX.COUNT],SI
328 MOV WORD PTR [BX.COUNT+2],CS
329 JMP EXIT
330
331 PAGE
332 SUBTTL MSDOS 2.x Disk I/O drivers.
333
334;
335; Disk READ/WRITE functions.
336;
337; On entry:
338; AL = Disk I/O driver number
339; AH = Media byte.
340; ES = Disk transfer segment.
341; DI = Disk transfer offset in ES.
342; CX = Number of sectors to transfer
343; DX = Logical starting sector.
344;
345; On exit:
346; Normal exit through common exit routine.
347;
348; Abnormal exit through common error routine.
349;
350
351DSK_RED:
352 MOV AH,HD_READ
353 JMP SHORT DSK_COM
354DSK_WRV:
355DSK_WRT:
356 MOV AH,HD_WRIT
357DSK_COM:
358 MOV SI,OFFSET HDDRIVE ;Keeps code size down.
359 MOV [IOPB.DMASEG],ES
360 MOV [IOPB.DMAOFF],DI
361 MOV DI,[SI.SECSIZE]
362 MOV [IOPB.SECLENG],DI
363 MOV [IOPB.RETRIES],1
364 MOV [IOPB.RETMASK],05DH ;Error return mask.
365 MOV [IOPB.OPCODE],AH
366 MOV [IOPB.DRIVE],4 ;Drive 4 is only available.
367 ADD DX,[SI.HIDDEN] ;Account for invisible sectors.
368 MOV BP,CX ;Save number of sectors to R/W
369DSK_IO1:
370 PUSH DX ;Save starting sector.
371 MOV AX,DX
372 MOV DX,0 ;32 bit divide coming up.
373 MOV CX,[SI.SECTRK]
374 DIV CX ;Get track+head and start sector.
375 MOV [IOPB.SECTOR],DL ;Starting sector.
376 MOV BL,DL ;Save starting sector for later.
377 MOV DX,0
378 MOV CX,[SI.HEADS]
379 DIV CX ;Compute head we are on.
380 MOV [IOPB.HEAD],DL
381 MOV [IOPB.TRACK],AX ;Track to read/write.
382 MOV AX,[SI.SECTRK] ;Now see how many sectors
383 INC AL ; we can burst read.
384 SUB AL,BL ;BL is the starting sector.
385 MOV AH,0
386 POP DX ;Retrieve logical sector start.
387 CMP AX,BP ;See if on last partial track+head.
388 JG DSK_IO2 ;Yes, on last track+head.
389 SUB BP,AX ;No, update number of sectors left.
390 ADD DX,AX ;Update next starting sector.
391 JMP SHORT DSK_IO3
392DSK_IO2:MOV AX,BP ;Only read enough of sector
393 MOV BP,0 ;to finish buffer and clear # left.
394DSK_IO3:MOV [IOPB.SCOUNT],AL
395 MOV DI,AX ;Save number sectors for later.
396 MOV BX,ROM_DISKIO
397 MOV CX,OFFSET IOPB
398 PUSH CS
399 POP ES
400 CALL ROM_CALL ;Do disk operation.
401 MOV AL,[IOPB.RETCODE] ;Get error code.
402 OR AL,AL
403 JNZ DERROR
404 MOV AX,DI ;Retrieve number of sectors read.
405 MOV CX,[SI.SECSIZE] ;Number of bytes per sector.
406 PUSH DX
407 MUL CX
408 POP DX
409 TEST AL,0FH ;Make sure no strange sizes.
410 JNZ SERR1
411 MOV CL,4
412 SHR AX,CL ;Convert number of bytes to para.
413 ADD AX,[IOPB.DMASEG]
414 MOV [IOPB.DMASEG],AX
415 OR BP,BP
416 JNZ DSK_IO1 ;Still more to do.
417 MOV AL,0
418 JMP EXIT ;All done.
419SERR1: MOV AL,12
420 JMP ERR_EXIT
421
422 PAGE
423 SUBTTL Disk Error processing.
424
425;
426; Disk error routine.
427;
428
429DERROR:
430 LDS BX,CS:[PTRSAV]
431 MOV [BX.COUNT],0
432 PUSH CS
433 POP DS
434
435 MOV BL,-1
436 MOV AH,AL
437 MOV BH,14 ;Lenght of table.
438 MOV SI,OFFSET DERRTAB
439DERROR2:INC BL ;Increment to next error code.
440 LODS BYTE PTR CS:[SI]
441 CMP AH,AL ;See if error code matches disk status.
442 JZ DERROR3 ;Got the right error, exit.
443 DEC BH
444 JNZ DERROR2 ;Keep checking table.
445 MOV BL,12 ;Set general type of error.
446DERROR3:MOV AL,BL ;Now we've got the code.
447 JMP ERR_EXIT
448
449DERRTAB DB 00H ; 0. Write protect error
450 DB 00H ; 1. Unknown unit.
451 DB 00H ; 2. Not ready error.
452 DB 00H ; 3. Unknown command.
453 DB 10H ; 4. CRC error
454 DB 00H ; 5. Bad drive request.
455 DB 00H ; 6. Seek error
456 DB 00H ; 7. Unknown media.
457 DB 08H ; 8. Sector not found
458 DB 00H ; 9. (Not used.)
459 DB 40H ;10. Write fault.
460 DB 04H ;11. Read fault.
461 DB 01H ;12. General type of failure.
462
463 PAGE
464 SUBTTL Common ROM call routine.
465
466;
467; Save all registers except CX, BX and AX.
468
469ROMRTN DD 0FE000000H ;Main ROM entry point.
470
471ROM_CALL:
472 PUSH DI
473 PUSH SI
474 PUSH BP
475 PUSH DX
476 PUSH ES
477 CALL CS:DWORD PTR [ROMRTN]
478 POP ES
479 POP DX
480 POP BP
481 POP SI
482 POP DI
483 RET
484
485
486 PAGE
487 SUBTTL Hard Disk Drive initalization routine.
488
489DSK_INI:
490 LDS BX,CS:[PTRSAV]
491 MOV BYTE PTR [BX.MEDIA],1
492 MOV WORD PTR [BX.TRANS],OFFSET DSK_INI
493 MOV WORD PTR [BX.TRANS+2],CS
494 MOV WORD PTR [BX.COUNT],OFFSET INI_TAB
495 MOV WORD PTR [BX.COUNT+2],CS
496 JMP EXIT
497
498CODE ENDS
499
500 END
501
diff --git a/v2.0/source/IFEQU.ASM b/v2.0/source/IFEQU.ASM
new file mode 100644
index 0000000..ff5f581
--- /dev/null
+++ b/v2.0/source/IFEQU.ASM
@@ -0,0 +1,18 @@
1;*************************************
2; COMMAND EQUs which are switch dependant
3
4IF1
5 IF IBM
6 %OUT IBM version
7 ELSE
8 %OUT Normal version
9 ENDIF
10
11 IF HIGHMEM
12 %OUT Highmem version
13 ENDIF
14
15 IF KANJI
16 %OUT Kanji version
17 ENDIF
18ENDIF
diff --git a/v2.0/source/INCOMP.txt b/v2.0/source/INCOMP.txt
new file mode 100644
index 0000000..6c187b6
--- /dev/null
+++ b/v2.0/source/INCOMP.txt
Binary files differ
diff --git a/v2.0/source/INIT.ASM b/v2.0/source/INIT.ASM
new file mode 100644
index 0000000..0ea86f5
--- /dev/null
+++ b/v2.0/source/INIT.ASM
@@ -0,0 +1,939 @@
1TITLE COMMAND Initialization
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15ENVIRONSIZ EQU 0A0H ;Must agree with values in EVIRONMENT segment
16ENVIRONSIZ2 EQU 092H
17
18CODERES SEGMENT PUBLIC
19 EXTRN RSTACK:WORD,SETVECT:NEAR,LODCOM:NEAR,CONTC:NEAR,INT_2E:NEAR
20 EXTRN LOADCOM:NEAR,CHKSUM:NEAR
21
22 IF IBMVER
23 EXTRN EXECHK:NEAR,SYSCALL:NEAR
24 ENDIF
25
26CODERES ENDS
27
28DATARES SEGMENT PUBLIC
29 EXTRN DATARESEND:BYTE,LTPA:WORD,MYSEG:WORD,MYSEG1:WORD,MYSEG2:WORD
30 EXTRN MEMSIZ:WORD,TRNSEG:WORD,ENVIRSEG:WORD,RSWITCHAR:BYTE
31 EXTRN COMDRV:BYTE,COMLET:BYTE,PERMCOM:BYTE,SINGLECOM:WORD
32 EXTRN PARENT:WORD,IO_SAVE:WORD,COM_PTR:DWORD,COM_FCB1:DWORD
33 EXTRN COM_FCB2:DWORD,SUM:WORD,BATCH:WORD,COMSPEC:BYTE
34
35 IF IBMVER
36 EXTRN SYS_CALL:DWORD,EXESEG:WORD,EXESUM:WORD
37 ENDIF
38
39DATARES ENDS
40
41ENVIRONMENT SEGMENT PUBLIC
42 EXTRN ENVIREND:BYTE,PATHSTRING:BYTE,ECOMSPEC:BYTE
43ENVIRONMENT ENDS
44
45TRANCODE SEGMENT PUBLIC
46 EXTRN DATINIT:FAR
47TRANCODE ENDS
48
49TRANSPACE SEGMENT PUBLIC
50 EXTRN TRANSPACEEND:BYTE
51TRANSPACE ENDS
52
53ZEXEC_DATA SEGMENT PUBLIC
54 IF IBM
55 EXTRN ZEXECDATAEND:BYTE
56 ENDIF
57ZEXEC_DATA ENDS
58
59; *******************************************************************
60; START OF INIT PORTION
61; This code is overlayed the first time the TPA is used.
62
63INIT SEGMENT PUBLIC PARA
64
65 EXTRN HEADER:BYTE
66 EXTRN BADCOMLKMES:BYTE
67
68 PUBLIC CONPROC
69
70ASSUME CS:RESGROUP,DS:RESGROUP,ES:RESGROUP,SS:RESGROUP
71
72 ORG 0
73ZERO = $
74
75CONPROC:
76 MOV SP,OFFSET RESGROUP:RSTACK
77
78 IF HIGHMEM
79 MOV BX,WORD PTR DS:[PDB_block_len]
80 MOV AX,OFFSET RESGROUP:ENVIREND + 15
81 MOV CL,4
82 SHR AX,CL
83 PUSH AX ; Save size to alloc
84 INC AX ; Plus one for arena
85 SUB BX,AX ; Subtract size of resident
86 MOV WORD PTR DS:[PDB_block_len],BX
87 MOV AX,CS
88 SUB BX,AX
89 MOV AH,SETBLOCK
90 INT 21H
91 POP BX ; Get back size to alloc
92 MOV AH,ALLOC
93 INT 21H
94 MOV [REALRES],AX
95 MOV ES,AX
96 XOR SI,SI
97 MOV DI,SI
98 MOV CX,OFFSET RESGROUP:ENVIREND
99 SHR CX,1 ; Length of resident and environment in words
100 ; Last byte doesn't matter
101 REP MOVSW ; Move to end of memory
102 MOV DS,AX
103 MOV BX,AX
104 MOV AH,SET_CURRENT_PDB
105 INT 21H
106 MOV AX,BX
107 MOV BX,OFFSET RESGROUP:DATARESEND + 15
108 MOV CL,4
109 SHR BX,CL ; BX is size for SETBLOCK
110 MOV WORD PTR DS:[PDB_block_len],BX
111 ADD WORD PTR DS:[PDB_block_len],AX
112 MOV [LTPA],CS
113 MOV AH,SETBLOCK
114 INT 21H ;Shrink to not include environment
115 MOV BX,(ENVIRONSIZ + 15) / 16
116 MOV AH,ALLOC
117 INT 21H ;Allocate the environment
118 MOV [ENVIRSEG],AX
119 MOV CS:[ENVIRSEGSAV],AX
120 MOV ES,AX
121ASSUME ES:ENVIRONMENT
122 XOR DI,DI
123 MOV SI,OFFSET RESGROUP:PATHSTRING
124 MOV CX,ENVIRONSIZ
125 REP MOVSB
126 MOV AX,WORD PTR CS:[PDB_block_len]
127 ENDIF
128
129 IF NOT HIGHMEM
130 MOV AX,OFFSET RESGROUP:ENVIREND + 15
131 MOV CL,4
132 SHR AX,CL
133 MOV CX,CS
134 ADD AX,CX ; Compute segment of TPA
135 MOV [LTPA],AX ; Good enough for the moment
136 MOV AX,WORD PTR DS:[PDB_block_len]
137 ENDIF
138
139 MOV [MYSEG1],DS
140 MOV [MYSEG2],DS
141 MOV [MYSEG],DS
142 MOV [MEMSIZ],AX
143
144 MOV DX,OFFSET TRANGROUP:TRANSPACEEND + 15
145 MOV CL,4
146 SHR DX,CL
147
148 IF IBM
149 PUSH DX
150 MOV DX,OFFSET EGROUP:ZEXECDATAEND + 15
151 MOV CL,4
152 SHR DX,CL
153 POP CX
154 ADD DX,CX
155 ENDIF
156
157 SUB AX,DX
158 MOV [TRNSEG],AX ; Read it in here
159 MOV AX,DS:[PDB_environ]
160 OR AX,AX
161 JZ BUILDENV ; Need to make an environment
162
163 IF HIGHMEM
164 INC BYTE PTR CS:[CHUCKENV] ; Flag no ENVIRONSEG
165 ELSE
166 INC BYTE PTR [CHUCKENV] ; Flag no ENVIRONSEG
167 ENDIF
168
169 JMP SHORT ENVIRONPASSED
170
171BUILDENV:
172
173 IF NOT HIGHMEM
174 MOV AX,OFFSET RESGROUP:PATHSTRING ; Figure environment pointer
175 MOV CL,4
176 SHR AX,CL
177 MOV DX,DS
178 ADD AX,DX
179 ELSE
180 JMP SHORT GOTTHEENVIR
181 ENDIF
182
183ENVIRONPASSED:
184 MOV [ENVIRSEG],AX
185
186 IF HIGHMEM
187 DEC AX
188 MOV ES,AX
189 INC AX
190 MOV ES:[arena_owner],DS ; Adjust owner of passed envir
191 ENDIF
192
193 MOV ES,AX
194ASSUME ES:ENVIRONMENT
195
196GOTTHEENVIR:
197 MOV AX,CHAR_OPER SHL 8
198 INT int_command
199 MOV [RSWITCHAR],DL
200
201 CMP DL,'/'
202 JNZ IUSESLASH
203
204 IF HIGHMEM
205 MOV CS:[COMSPECT],'\'
206 ELSE
207 MOV [COMSPECT],'\'
208 ENDIF
209
210 IF HIGHMEM
211 CMP BYTE PTR CS:[CHUCKENV],0
212 ELSE
213 CMP BYTE PTR [CHUCKENV],0
214 ENDIF
215
216 JNZ IUSESLASH
217
218 MOV ES:[ECOMSPEC-10H],'\'
219IUSESLASH:
220
221IF IBMVER
222 PUSH ES
223 MOV AX,(Get_interrupt_vector SHL 8) + int_command
224 INT int_command
225 MOV WORD PTR [SYS_CALL],BX
226 MOV WORD PTR [SYS_CALL+2],ES
227 MOV DX,OFFSET RESGROUP:SYSCALL
228 MOV AX,(Set_interrupt_vector SHL 8) + int_command
229 INT int_command
230 POP ES
231ENDIF
232
233 MOV AL,BYTE PTR DS:[FCB] ; get drive spec for default
234 MOV AH,DRVCHAR
235 MOV [COMDRV],AL
236 ADD AL,40H ; Convert to letter
237 CMP AL,40H
238 JZ NOCOMDRV
239 STD
240 IF HIGHMEM
241 CMP BYTE PTR CS:[CHUCKENV],0
242 ELSE
243 CMP BYTE PTR [CHUCKENV],0
244 ENDIF
245
246 JNZ NOTWIDENV
247
248 PUSH DS
249 PUSH ES
250 POP DS
251 MOV DI,OFFSET ENVIRONMENT:ECOMSPEC + ENVIRONSIZ2 - 1 - 10H
252 MOV SI,OFFSET ENVIRONMENT:ECOMSPEC + ENVIRONSIZ2 - 3 - 10H
253 MOV CX,ENVIRONSIZ2 - 2
254 REP MOVSB
255
256 POP DS
257 MOV WORD PTR ES:[ECOMSPEC-10H],AX
258
259NOTWIDENV:
260 CLD
261 IF HIGHMEM
262 MOV WORD PTR CS:[AUTOBAT],AX
263 ELSE
264 MOV WORD PTR [AUTOBAT],AX
265 ENDIF
266
267 MOV [COMLET],AL
268NOCOMDRV:
269 CALL SETVECT ; Set the vectors
270
271 MOV SI,80H
272 LODSB
273 MOV CL,AL
274 XOR CH,CH
275 JCXZ COMRETURNSJ ; No parameters
276 MOV SI,81H ; Start of parms
277CHKARG:
278 LODSB
279 CMP AL,' '
280 JZ NEXTCH
281 CMP AL,9 ; Tab only other delimiter
282 JZ NEXTCH
283 CMP AL,[RSWITCHAR] ; Switch?
284 JNZ CHKOTHERARGS ; No
285 DEC CX
286 JCXZ ARGSDONEJ ; oops
287 LODSB
288 OR AL,20H ; Lower case
289 CMP AL,'p' ; PERMCOM switch
290 JNZ NEXTCH
291 JMP SETPERM
292
293NEXTCH:
294 CMP AL,'d'
295 JNZ NEXTCH3
296
297 IF HIGHMEM
298 MOV BYTE PTR CS:[PRDATTM],1 ; User explicitly says no date time
299 ELSE
300 MOV BYTE PTR [PRDATTM],1 ; User explicitly says no date time
301 ENDIF
302
303 LOOP CHKARG
304 JMP SHORT ARGSDONEJ
305NEXTCH3:
306 CMP AL,'c'
307 JNZ NEXTCH2 ; SINGLECOM switch 2
308 MOV [SINGLECOM],SI ; Point to the rest of the command line
309 MOV [PERMCOM],0 ; A SINGLECOM must not be a PERMCOM
310
311 IF HIGHMEM
312 MOV BYTE PTR CS:[PRDATTM],1 ; No date or time either, explicit
313 ELSE
314 MOV BYTE PTR [PRDATTM],1 ; No date or time either, explicit
315 ENDIF
316
317ARGSDONEJ:
318 JMP ARGSDONE
319
320NEXTCH2:
321 LOOP CHKARG
322
323COMRETURNSJ:
324 JMP COMRETURNS
325
326CHKOTHERARGS:
327 DEC SI
328 MOV DX,SI
329 PUSH CX
330 PUSH SI
331CONTRLOOP:
332 LODSB
333 DEC CX
334 CMP AL,' '
335 JZ SETCDEV
336 CMP AL,9
337 JZ SETCDEV
338 JCXZ SETCDEVA
339 JMP SHORT CONTRLOOP
340
341SETCDEVA:
342 INC SI
343SETCDEV:
344 MOV BYTE PTR [SI-1],0
345 MOV AX,(OPEN SHL 8) OR 2 ; Read and write
346 INT int_command
347 JC CHKSRCHSPEC ; Wasn't a file
348 MOV BX,AX
349 MOV AX,IOCTL SHL 8
350 INT int_command
351 TEST DL,80H
352 JNZ ISADEVICE
353 MOV AH,CLOSE ; Close initial handle, wasn't a device
354 INT int_command
355 JMP CHKSRCHSPEC
356
357ISADEVICE:
358 XOR DH,DH
359 OR DL,3 ; Make sure has CON attributes
360 MOV AX,(IOCTL SHL 8) OR 1
361 INT int_command
362 MOV DX,BX ; Save new handle
363 POP BX ; Throw away saved SI
364 POP BX ; Throw away saved CX
365 PUSH CX
366 MOV CX,3
367 XOR BX,BX
368RCCLLOOP: ; Close 0,1 and 2
369 MOV AH,CLOSE
370 INT int_command
371 INC BX
372 LOOP RCCLLOOP
373 MOV BX,DX ; New device handle
374 MOV AH,XDUP
375 INT int_command ; Dup to 0
376 MOV AH,XDUP
377 INT int_command ; Dup to 1
378 MOV AH,XDUP
379 INT int_command ; Dup to 2
380 MOV AH,CLOSE
381 INT int_command ; Close initial handle
382 POP CX
383 JCXZ ARGSDONEJ2
384 JMP CHKARG
385
386CHKSRCHSPEC: ; Not a device, so must be directory spec
387
388 IF HIGHMEM
389 MOV BYTE PTR CS:[CHUCKENV],0 ; If search specified -- no inheritance
390 MOV AX,CS:[ENVIRSEGSAV]
391 MOV [ENVIRSEG],AX
392 ELSE
393 MOV BYTE PTR [CHUCKENV],0 ; If search specified -- no inheritance
394 MOV AX,OFFSET RESGROUP:PATHSTRING ; Figure environment pointer
395 MOV CL,4
396 SHR AX,CL
397 MOV DX,DS
398 ADD AX,DX
399 MOV [ENVIRSEG],AX
400 ENDIF
401
402 MOV ES,AX
403 MOV BYTE PTR [SI-1],' '
404 POP SI ; Remember location
405 POP CX ; and count
406
407 IF HIGHMEM
408 MOV DI,CS:[ECOMLOC]
409 ELSE
410 MOV DI,[ECOMLOC]
411 ENDIF
412
413COMTRLOOP:
414 LODSB
415 DEC CX
416 CMP AL,' '
417 JZ SETCOMSR
418 CMP AL,9
419 JZ SETCOMSR
420 STOSB
421
422 IF KANJI
423 XOR AH,AH
424 ENDIF
425
426 JCXZ SETCOMSR
427
428 IF KANJI
429 CALL ITESTKANJ
430 JZ COMTRLOOP
431 DEC CX
432 MOVSB
433 INC AH
434 JCXZ SETCOMSR
435 ENDIF
436
437 JMP SHORT COMTRLOOP
438
439SETCOMSR:
440 PUSH SI
441 PUSH CX
442
443 PUSH DS
444
445 IF HIGHMEM
446 PUSH CS
447 POP DS
448 ENDIF
449
450 MOV SI,OFFSET RESGROUP:COMSPECT
451 MOV CX,14
452
453 MOV AL,ES:[DI-1]
454
455 IF KANJI
456 OR AH,AH
457 JNZ INOTROOT ; Last char was KANJI second byte, might be '\'
458 ENDIF
459
460 CALL PATHCHRCMPR
461 JNZ INOTROOT
462 INC SI ; Don't make a double /
463 DEC CX
464INOTROOT:
465 REP MOVSB
466
467 MOV DX,[ECOMLOC] ; Now lets make sure its good!
468 PUSH ES
469 POP DS
470
471 MOV AX,OPEN SHL 8
472 INT int_command ; Open COMMAND.COM
473 POP DS
474 JC SETCOMSRBAD ; No COMMAND.COM here
475 MOV BX,AX ; Handle
476 MOV AH,CLOSE
477 INT int_command ; Close COMMAND.COM
478SETCOMSRRET:
479 POP CX
480 POP SI
481ARGSDONEJ2:
482 JCXZ ARGSDONE
483 JMP CHKARG
484
485SETCOMSRBAD:
486
487 IF HIGHMEM
488 PUSH DS
489 PUSH CS
490 POP DS
491 ENDIF
492
493 MOV DX,OFFSET RESGROUP:BADCOMLKMES
494 MOV AH,STD_CON_STRING_OUTPUT
495 INT int_command
496 MOV SI,OFFSET RESGROUP:COMSPECT
497 MOV DI,[ECOMLOC]
498 MOV CX,14
499 REP MOVSB ; Get my default back
500
501 IF HIGHMEM
502 POP DS
503 ENDIF
504
505 JMP SHORT SETCOMSRRET
506
507CHKARGJ:
508 JMP CHKARG
509
510SETPERM:
511 INC [PERMCOM]
512
513 IF HIGHMEM
514 CMP BYTE PTR CS:[PRDATTM],-1
515 ELSE
516 CMP BYTE PTR [PRDATTM],-1
517 ENDIF
518
519 JNZ LOOPIT
520
521 IF HIGHMEM
522 MOV BYTE PTR CS:[PRDATTM],0 ; If not set explicit, set to prompt
523 ELSE
524 MOV BYTE PTR [PRDATTM],0 ; If not set explicit, set to prompt
525 ENDIF
526
527LOOPIT:
528 LOOP CHKARGJ
529ARGSDONE:
530 CMP [PERMCOM],0
531 JZ COMRETURNS
532 PUSH ES ; Save environment pointer
533 MOV AH,SET_CURRENT_PDB
534 MOV BX,DS
535 MOV ES,BX
536 INT int_command ; Current process is me
537 MOV DI,PDB_Exit ; Diddle the addresses in my header
538 MOV AX,OFFSET RESGROUP:LODCOM
539 STOSW
540 MOV AX,DS
541 STOSW
542 MOV AX,OFFSET RESGROUP:CONTC
543 STOSW
544 MOV AX,DS
545 STOSW
546 MOV WORD PTR DS:[PDB_Parent_PID],DS ; Parent is me forever
547 MOV DX,OFFSET RESGROUP:INT_2E
548 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 02EH
549 INT int_command ;Set magic interrupt
550 POP ES ;Remember environment
551COMRETURNS:
552 MOV AX,WORD PTR DS:[PDB_Parent_PID]
553 MOV [PARENT],AX ; Save parent
554 MOV WORD PTR DS:[PDB_Parent_PID],DS ; Parent is me
555 MOV AX,WORD PTR DS:[PDB_JFN_Table]
556 MOV [IO_SAVE],AX ; Get the default stdin and out
557 MOV WORD PTR [COM_PTR+2],DS ; Set all these to resident
558 MOV WORD PTR [COM_FCB1+2],DS
559 MOV WORD PTR [COM_FCB2+2],DS
560 MOV DI,OFFSET RESGROUP:COMSPEC
561
562 IF HIGHMEM
563 MOV SI,CS:[ECOMLOC]
564 CMP BYTE PTR CS:[CHUCKENV],0
565 ELSE
566 MOV SI,[ECOMLOC]
567 CMP BYTE PTR [CHUCKENV],0
568 ENDIF
569
570 MOV AX,DS ; XCHG ES,DS
571 PUSH ES
572 POP DS
573 MOV ES,AX
574
575 JZ COPYCOMSP ; All set up for copy
576
577 PUSH CS
578 POP DS
579
580 MOV SI,OFFSET RESGROUP:COMSPSTRING
581 PUSH ES
582 PUSH DI
583 CALL IFINDE
584 MOV SI,DI
585 PUSH ES
586 POP DS
587 POP DI
588 POP ES
589 JNC COPYCOMSP
590COMSPECNOFND:
591
592 IF HIGHMEM
593 MOV DS,CS:[ENVIRSEG]
594 MOV SI,CS:[ECOMLOC]
595 ELSE
596 MOV SI,[ECOMLOC]
597 ADD SI,OFFSET RESGROUP:PATHSTRING
598 PUSH CS
599 POP DS
600 ENDIF
601
602COPYCOMSP:
603 LODSB
604 STOSB
605 OR AL,AL
606 JNZ COPYCOMSP
607
608 IF HIGHMEM
609 MOV DS,CS:[REALRES]
610 PUSH CS
611 POP ES
612 MOV AH,DEALLOC
613 INT 21H
614 CMP BYTE PTR CS:[CHUCKENV],0
615 JZ GOTENVIR ; Environment is ok
616 MOV ES,CS:[ENVIRSEGSAV]
617 MOV AH,DEALLOC
618 INT 21H
619 ELSE
620 PUSH CS
621 POP DS
622 MOV BX,OFFSET RESGROUP:DATARESEND + 15
623 MOV CL,4
624 SHR BX,CL
625 MOV AH,SETBLOCK
626 INT int_command ; Shrink me to the resident only
627 CMP BYTE PTR [CHUCKENV],0
628 JNZ GOTENVIR ; Environment was passed
629 MOV BX,(ENVIRONSIZ + 15) /16
630 MOV AH,ALLOC
631 INT int_command ; "ALLOCATE" the environment
632 MOV DS,[ENVIRSEG]
633 MOV [ENVIRSEG],AX
634 MOV ES,AX
635 XOR SI,SI
636 MOV DI,SI
637 MOV CX,ENVIRONSIZ
638 REP MOVSB
639 PUSH CS
640 POP DS
641 ENDIF
642
643GOTENVIR:
644 CALL LOADCOM ; Load the transient in the right place
645 CALL CHKSUM ; Compute the checksum
646 MOV [SUM],DX ; Save it
647IF IBM
648 MOV AX,[MEMSIZ]
649 MOV DX,OFFSET EGROUP:ZEXECDATAEND + 15
650 MOV CL,4
651 SHR DX,CL
652 SUB AX,DX
653 MOV [EXESEG],AX
654 CALL EXECHK
655 MOV [EXESUM],DX
656ENDIF
657 IF MSVER
658 CMP [SINGLECOM],0
659 JNZ NOPHEAD ; Don't print header if SINGLECOM
660 IF HIGHMEM
661 PUSH DS
662 PUSH CS
663 POP DS
664 ENDIF
665 MOV DX,OFFSET RESGROUP:HEADER
666 MOV AH,STD_CON_STRING_OUTPUT
667 INT int_command
668 IF HIGHMEM
669 POP DS
670 ENDIF
671NOPHEAD:
672 ENDIF
673
674 IF HIGHMEM
675 CMP BYTE PTR CS:[PRDATTM],0
676 ELSE
677 CMP BYTE PTR [PRDATTM],0
678 ENDIF
679
680 JNZ NODTTM ; Don't do AUTOEXEC or date time
681 MOV BX,3 ; 48 BYTES ENOUGH
682 MOV AH,ALLOC
683 INT int_command
684 JC DODTTM ; PRETEND NO BATCH
685 MOV [BATCH],AX
686 MOV ES,AX
687 XOR DI,DI
688
689 IF HIGHMEM
690 CMP BYTE PTR CS:[AUTOBAT],0
691 ELSE
692 CMP BYTE PTR [AUTOBAT],0
693 ENDIF
694
695 JNZ NOAUTSET
696 MOV AH,GET_DEFAULT_DRIVE
697 INT int_command
698 ADD AL,'A'
699
700 IF HIGHMEM
701 MOV CS:[AUTOBAT],AL
702 ELSE
703 MOV [AUTOBAT],AL
704 ENDIF
705
706NOAUTSET:
707
708 IF HIGHMEM
709 PUSH DS
710 PUSH CS
711 POP DS
712 ENDIF
713
714 MOV SI,OFFSET RESGROUP:AUTOBAT
715 MOV CX,8
716 REP MOVSW ; NAME
717 MOV AX,-1
718 MOV CL,10
719 REP STOSW ; PARMS
720 MOV DX,OFFSET RESGROUP:AUTOBAT
721 MOV AX,OPEN SHL 8
722 INT int_command ; See if AUTOEXEC.BAT exists
723 JC NOABAT
724 MOV BX,AX
725 MOV AH,CLOSE
726 INT int_command
727
728 IF HIGHMEM
729 POP DS
730 ENDIF
731
732 JMP SHORT DRV0
733
734NOABAT:
735
736 IF HIGHMEM
737 POP DS
738 ENDIF
739
740 MOV ES,[BATCH] ; Not found--turn off batch job
741 MOV AH,DEALLOC
742 INT int_command
743 MOV [BATCH],0 ; AFTER DEALLOC in case of ^C
744DODTTM:
745
746 IF HIGHMEM
747 MOV AX,OFFSET TRANGROUP:DATINIT
748 MOV WORD PTR CS:[INITADD],AX
749 MOV AX,[TRNSEG]
750 MOV WORD PTR CS:[INITADD+2],AX
751 CALL DWORD PTR CS:[INITADD]
752 ELSE
753 MOV AX,OFFSET TRANGROUP:DATINIT
754 MOV WORD PTR[INITADD],AX
755 MOV AX,[TRNSEG]
756 MOV WORD PTR[INITADD+2],AX
757 CALL DWORD PTR [INITADD]
758 ENDIF
759
760NODTTM:
761
762 IF IBMVER
763 CMP [SINGLECOM],0
764 JNZ DRV0 ; Don't print header if SINGLECOM
765 MOV DX,OFFSET RESGROUP:HEADER
766 MOV AH,STD_CON_STRING_OUTPUT
767 INT int_command
768 ENDIF
769
770DRV0:
771 IF HIGHMEM
772 PUSH DS
773 MOV AX,OFFSET RESGROUP:LODCOM
774 PUSH AX
775MQQ PROC FAR
776 RET
777MQQ ENDP
778 ELSE
779 JMP LODCOM ; Allocate the transient
780 ENDIF
781
782PATHCHRCMPR:
783 CMP [RSWITCHAR],'/'
784 JZ RNOSLASHT
785 CMP AL,'/'
786 JZ RET41
787RNOSLASHT:
788 CMP AL,'\'
789RET41:
790 RET
791
792
793IFINDE:
794 CALL IFIND ; FIND THE NAME
795 JC IFIND2 ; CARRY MEANS NOT FOUND
796 JMP ISCASB1 ; SCAN FOR = SIGN
797;
798; On return of FIND1, ES:DI points to beginning of name
799;
800IFIND:
801 CLD
802
803 CALL ICOUNT0 ; CX = LENGTH OF NAME
804
805 IF HIGHMEM
806 MOV ES,CS:[REALRES]
807ASSUME ES:RESGROUP
808 MOV ES,ES:[ENVIRSEG]
809ASSUME ES:NOTHING
810 ELSE
811 MOV ES,[ENVIRSEG]
812 ENDIF
813
814 XOR DI,DI
815IFIND1:
816 PUSH CX
817 PUSH SI
818 PUSH DI
819IFIND11:
820 LODSB
821
822 IF KANJI
823 CALL ITESTKANJ
824 JZ NOTKANJ4
825 DEC SI
826 LODSW
827 INC DI
828 INC DI
829 CMP AX,ES:[DI-2]
830 JNZ IFIND12
831 DEC CX
832 LOOP IFIND11
833 JMP SHORT IFIND12
834
835NOTKANJ4:
836 ENDIF
837
838 CALL IUPCONV
839 INC DI
840 CMP AL,ES:[DI-1]
841 JNZ IFIND12
842 LOOP IFIND11
843IFIND12:
844 POP DI
845 POP SI
846 POP CX
847 JZ IFIND2
848 PUSH CX
849 CALL ISCASB2 ; SCAN FOR A NUL
850 POP CX
851 CMP BYTE PTR ES:[DI],0
852 JNZ IFIND1
853 STC ; INDICATE NOT FOUND
854IFIND2:
855 RET
856
857ICOUNT0:
858 PUSH DS
859 POP ES
860 MOV DI,SI
861
862 PUSH DI ; COUNT NUMBER OF CHARS UNTIL "="
863 CALL ISCASB1
864 JMP SHORT ICOUNTX
865 PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL
866 CALL ISCASB2
867ICOUNTX:
868 POP CX
869 SUB DI,CX
870 XCHG DI,CX
871 RET
872
873ISCASB1:
874 MOV AL,"=" ; SCAN FOR AN =
875 JMP SHORT ISCASBX
876ISCASB2:
877 XOR AL,AL ; SCAN FOR A NUL
878ISCASBX:
879 MOV CX,100H
880 REPNZ SCASB
881 RET
882
883 IF KANJI
884ITESTKANJ:
885 CMP AL,81H
886 JB NOTLEAD
887 CMP AL,9FH
888 JBE ISLEAD
889 CMP AL,0E0H
890 JB NOTLEAD
891 CMP AL,0FCH
892 JBE ISLEAD
893NOTLEAD:
894 PUSH AX
895 XOR AX,AX ;Set zero
896 POP AX
897 RET
898
899ISLEAD:
900 PUSH AX
901 XOR AX,AX ;Set zero
902 INC AX ;Reset zero
903 POP AX
904 RET
905 ENDIF
906
907IUPCONV:
908 CMP AL,"a"
909 JB IRET22
910 CMP AL,"z"
911 JA IRET22
912 SUB AL,20H ; Lower-case changed to upper-case
913IRET22:
914 RET
915
916ICONDEV LABEL BYTE
917 DB "/DEV/"
918 DB "CON",0,0,0,0,0,0 ; Room for 8 char device
919BADCSPFL DB 0
920COMSPECT DB "/COMMAND.COM",0,0
921AUTOBAT DB 0,":\AUTOEXEC.BAT",0
922
923PRDATTM DB -1 ;Init not to prompt for date time
924INITADD DD ?
925CHUCKENV DB 0
926ECOMLOC DW OFFSET ENVIRONMENT:ECOMSPEC-10H
927
928 IF HIGHMEM
929REALRES DW ?
930ENVIRSEGSAV DW ?
931 ENDIF
932
933COMSPSTRING DB "COMSPEC="
934
935
936INIT ENDS
937
938 END
939
diff --git a/v2.0/source/INT24.txt b/v2.0/source/INT24.txt
new file mode 100644
index 0000000..d38d6fa
--- /dev/null
+++ b/v2.0/source/INT24.txt
Binary files differ
diff --git a/v2.0/source/MISC.ASM b/v2.0/source/MISC.ASM
new file mode 100644
index 0000000..e0a5cee
--- /dev/null
+++ b/v2.0/source/MISC.ASM
@@ -0,0 +1,648 @@
1TITLE MISC - Miscellanious routines for MS-DOS
2NAME MISC
3;
4; Miscellaneous system calls most of which are CAVEAT
5;
6; $SLEAZEFUNC
7; $SLEAZEFUNCDL
8; $GET_INDOS_FLAG
9; $GET_IN_VARS
10; $GET_DEFAULT_DPB
11; $GET_DPB
12; $DISK_RESET
13; $SETDPB
14; $Dup_PDB
15; $CREATE_PROCESS_DATA_BLOCK
16; SETMEM
17;
18.xlist
19;
20; get the appropriate segment definitions
21;
22INCLUDE DOSSEG.ASM
23
24CODE SEGMENT BYTE PUBLIC 'CODE'
25 ASSUME SS:DOSGROUP,CS:DOSGROUP
26
27.xcref
28INCLUDE DOSSYM.ASM
29INCLUDE DEVSYM.ASM
30.cref
31.list
32
33
34ifndef Kanji
35Kanji equ 0
36endif
37
38ENTRYPOINTSEG EQU 0CH
39MAXDIF EQU 0FFFH
40SAVEXIT EQU 10
41
42 i_need LASTBUFFER,DWORD
43 i_need INDOS,BYTE
44 i_need SYSINITVAR,BYTE
45 i_need CurrentPDB,WORD
46 i_need CreatePDB,BYTE
47 i_need EXIT_TYPE,BYTE
48 i_need EXIT_CODE,WORD
49 i_need LASTENT,WORD
50 i_need THISDPB,DWORD
51 i_need ATTRIB,BYTE
52 i_need EXTFCB,BYTE
53 i_need DMAADD,DWORD
54 i_need DIRSTART,WORD
55 i_need CURBUF,DWORD
56 i_need USER_SP,WORD
57 i_need ENTLAST,WORD
58 i_need THISDRV,BYTE
59
60ASSUME SS:DOSGROUP
61
62BREAK <SleazeFunc -- get a pointer to media byte>
63
64;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
65; C A V E A T P R O G R A M M E R ;
66; ;
67 procedure $SLEAZEFUNC,NEAR
68ASSUME DS:NOTHING,ES:NOTHING
69
70; Inputs:
71; None
72; Function:
73; Return Stuff sort of like old get fat call
74; Outputs:
75; DS:BX = Points to FAT ID byte (IBM only)
76; GOD help anyone who tries to do ANYTHING except
77; READ this ONE byte.
78; DX = Total Number of allocation units on disk
79; CX = Sector size
80; AL = Sectors per allocation unit
81; = -1 if bad drive specified
82
83 MOV DL,0
84 entry $SLEAZEFUNCDL
85 PUSH SS
86 POP DS
87ASSUME DS:DOSGROUP
88 MOV AL,DL
89 invoke GETTHISDRV
90 MOV AL,-1
91 JC BADSLDRIVE
92 invoke FATREAD
93 MOV DX,ES:[BP.dpb_max_cluster]
94 DEC DX
95 MOV AL,ES:[BP.dpb_cluster_mask]
96 INC AL
97 MOV CX,ES:[BP.dpb_sector_size]
98 ADD BP,dpb_media
99BADSLDRIVE:
100 invoke get_user_stack
101ASSUME DS:NOTHING
102 MOV [SI.user_CX],CX
103 MOV [SI.user_DX],DX
104 MOV [SI.user_BX],BP
105 MOV [SI.user_DS],ES
106 return
107$SLEAZEFUNC ENDP
108; ;
109; C A V E A T P R O G R A M M E R ;
110;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
111
112
113
114BREAK <$ABORT -- Terminate a process>
115 procedure $ABORT,NEAR
116ASSUME DS:NOTHING,ES:NOTHING
117
118; Inputs:
119; CS:00 must point to valid program header block
120; Function:
121; Restore terminate and Cntrl-C addresses, flush buffers
122; and transfer to the terminate address
123; Returns:
124; TO THE TERMINATE ADDRESS
125
126 XOR AL,AL
127 MOV [exit_type],exit_abort
128
129;
130; abort_inner must have AL set as the exit code!
131;
132 entry abort_inner
133 MOV AH,[exit_type]
134 MOV [exit_code],AX
135 invoke Get_user_stack
136 MOV DS,[SI.user_CS] ; set up old interrupts
137 XOR AX,AX
138 MOV ES,AX
139 MOV SI,SAVEXIT
140 MOV DI,addr_int_terminate
141 MOVSW
142 MOVSW
143 MOVSW
144 MOVSW
145 MOVSW
146 MOVSW
147 transfer reset_environment
148$ABORT ENDP
149
150BREAK <$Dir_Search_First -- Start a directory search>
151 procedure $DIR_SEARCH_FIRST,NEAR
152ASSUME DS:NOTHING,ES:NOTHING
153
154; Inputs:
155; DS:DX Points to unopenned FCB
156; Function:
157; Directory is searched for first matching entry and the directory
158; entry is loaded at the disk transfer address
159; Returns:
160; AL = -1 if no entries matched, otherwise 0
161
162 invoke GETFILE
163ASSUME DS:DOSGROUP
164SAVPLCE:
165; Search-for-next enters here to save place and report
166; findings.
167 MOV DL,0 ; Do not XOR!!!
168 JC KILLSRCH
169 OR AH,AH ; Is it I/O device?
170 JS KILLIT ; If so, sign bit will end search
171 MOV AX,[LASTENT]
172 INC DL
173KILLIT:
174 MOV ES:[DI.FILDIRENT],AX
175 MOV AX,WORD PTR [THISDPB]
176 MOV ES:[DI.fcb_DRVBP],AX
177 MOV AX,WORD PTR [THISDPB+2]
178 MOV ES:[DI.fcb_DRVBP+2],AX
179 MOV AX,[DIRSTART]
180 MOV ES:[DI.fcb_DRVBP+4],AX
181; Information in directory entry must be copied into the first
182; 33 bytes starting at the disk transfer address.
183 MOV SI,BX
184 LES DI,[DMAADD]
185 MOV AX,00FFH
186 CMP AL,[EXTFCB]
187 JNZ NORMFCB
188 STOSW
189 INC AL
190 STOSW
191 STOSW
192 MOV AL,[ATTRIB]
193 STOSB
194NORMFCB:
195 MOV AL,[THISDRV]
196 INC AL
197 STOSB ; Set drive number
198 OR DL,DL
199 JZ DOSRELATIVE
200 MOV DS,WORD PTR [CURBUF+2]
201ASSUME DS:NOTHING
202DOSRELATIVE:
203
204 IF KANJI
205 MOVSW
206 CMP BYTE PTR ES:[DI-2],5
207 JNZ NOTKTRAN
208 MOV BYTE PTR ES:[DI-2],0E5H
209NOTKTRAN:
210 MOV CX,15
211 ELSE
212 MOV CX,16
213 ENDIF
214
215 REP MOVSW ; Copy 32 bytes of directory entry
216 XOR AL,AL
217 return
218
219ASSUME DS:NOTHING
220KILLSRCH1:
221 PUSH DS
222 POP ES ; Make ES:DI point to the FCB
223KILLSRCH:
224 MOV AX,-1
225 MOV WORD PTR ES:[DI.FILDIRENT],AX
226 return
227$DIR_SEARCH_FIRST ENDP
228
229BREAK <$Dir_Search_Next -- Find next matching directory entry>
230 procedure $DIR_SEARCH_NEXT,NEAR
231ASSUME DS:NOTHING,ES:NOTHING
232
233; Inputs:
234; DS:DX points to unopenned FCB returned by $DIR_SEARCH_FIRST
235; Function:
236; Directory is searched for the next matching entry and the directory
237; entry is loaded at the disk transfer address
238; Returns:
239; AL = -1 if no entries matched, otherwise 0
240
241 invoke MOVNAMENOSET
242ASSUME ES:DOSGROUP
243 MOV DI,DX
244 JC NEAR PTR KILLSRCH1
245 MOV AX,[DI.FILDIRENT]
246 LES BP,DWORD PTR [DI.fcb_DRVBP]
247 OR AX,AX
248 JS NEAR PTR KILLSRCH1
249 MOV BX,[DI.fcb_DRVBP+4]
250 PUSH DX
251 PUSH DS
252 PUSH AX
253 MOV WORD PTR [THISDPB],BP
254 MOV WORD PTR [THISDPB+2],ES
255 invoke SetDirSrch
256 ASSUME DS:DOSGROUP
257 POP AX
258 MOV [ENTLAST],-1
259 invoke GetEnt
260 invoke NextEnt
261 POP ES
262 ASSUME ES:NOTHING
263 POP DI
264 JMP SAVPLCE
265$DIR_SEARCH_NEXT ENDP
266
267BREAK <$Get_FCB_File_Length -- Return size of file in current records>
268 procedure $GET_FCB_FILE_LENGTH,NEAR
269ASSUME DS:NOTHING,ES:NOTHING
270
271; Inputs:
272; DS:DX points to unopenned FCB
273; Function:
274; Set random record field to size of file
275; Returns:
276; AL = -1 if no entries matched, otherwise 0
277
278 invoke GETFILE
279ASSUME DS:DOSGROUP
280 MOV AL,-1
281 retc
282 ADD DI,fcb_RR ; Write size in RR field
283 MOV CX,WORD PTR ES:[DI.fcb_RECSIZ-fcb_RR]
284 OR CX,CX
285 JNZ RECOK
286 MOV CX,128
287RECOK:
288 XOR DX,DX ; Intialize size to zero
289 INC SI
290 INC SI ; Point to length field
291 MOV DS,WORD PTR [CURBUF+2]
292ASSUME DS:NOTHING
293 MOV AX,[SI+2] ; Get high word of size
294 DIV CX
295 PUSH AX ; Save high part of result
296 LODSW ; Get low word of size
297 DIV CX
298 OR DX,DX ; Check for zero remainder
299 POP DX
300 JZ DEVSIZ
301 INC AX ; Round up for partial record
302 JNZ DEVSIZ ; Propagate carry?
303 INC DX
304DEVSIZ:
305 STOSW
306 MOV AX,DX
307 STOSB
308 MOV AL,0
309 CMP CX,64
310 JAE RET14 ; Only 3-byte field if fcb_RECSIZ >= 64
311 MOV ES:[DI],AH
312RET14: return
313$GET_FCB_FILE_LENGTH ENDP
314
315BREAK <$Get_Fcb_Position -- Set random record field to current position>
316 procedure $GET_FCB_POSITION,NEAR
317ASSUME DS:NOTHING,ES:NOTHING
318
319; Inputs:
320; DS:DX points to openned FCB
321; Function:
322; Sets random record field to be same as current record fields
323; Returns:
324; None
325
326 invoke GETREC
327 MOV WORD PTR [DI+fcb_RR],AX
328 MOV [DI+fcb_RR+2],DL
329 CMP [DI.fcb_RECSIZ],64
330 JAE RET16
331 MOV [DI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64
332RET16: return
333$GET_FCB_POSITION ENDP
334
335BREAK <$Disk_Reset -- Flush out all dirty buffers>
336 procedure $DISK_RESET,NEAR
337ASSUME DS:NOTHING,ES:NOTHING
338
339; Inputs:
340; None
341; Function:
342; Flush and invalidate all buffers
343; Returns:
344; Nothing
345
346 PUSH SS
347 POP DS
348ASSUME DS:DOSGROUP
349 MOV AL,-1
350 invoke FLUSHBUF
351 MOV WORD PTR [LASTBUFFER+2],-1
352 MOV WORD PTR [LASTBUFFER],-1
353 invoke SETVISIT
354ASSUME DS:NOTHING
355NBFFR: ; Free ALL buffers
356 MOV [DI.VISIT],1 ; Mark as visited
357 CMP BYTE PTR [DI.BUFDRV],-1
358 JZ SKPBF ; Save a call to PLACEBUF
359 MOV WORD PTR [DI.BUFDRV],00FFH
360 invoke SCANPLACE
361SKPBF:
362 invoke SKIPVISIT
363 JNZ NBFFR
364 return
365$DISK_RESET ENDP
366
367 procedure $RAW_CON_IO,NEAR ; System call 6
368ASSUME DS:NOTHING,ES:NOTHING
369
370; Inputs:
371; DL = -1 if input
372; else DL is output character
373; Function:
374; Input or output raw character from console, no echo
375; Returns:
376; AL = character
377
378 MOV AL,DL
379 CMP AL,-1
380 JNZ RAWOUT
381 LES DI,DWORD PTR [user_SP] ; Get pointer to register save area
382 XOR BX,BX
383 invoke GET_IO_FCB
384 retc
385 MOV AH,1
386 invoke IOFUNC
387 JNZ RESFLG
388 invoke SPOOLINT
389 OR BYTE PTR ES:[DI.user_F],40H ; Set user's zero flag
390 XOR AL,AL
391 return
392
393RESFLG:
394 AND BYTE PTR ES:[DI.user_F],0FFH-40H ; Reset user's zero flag
395
396RILP:
397 invoke SPOOLINT
398 entry $RAW_CON_INPUT ; System call 7
399
400; Inputs:
401; None
402; Function:
403; Input raw character from console, no echo
404; Returns:
405; AL = character
406
407 XOR BX,BX
408 invoke GET_IO_FCB
409 retc
410 MOV AH,1
411 invoke IOFUNC
412 JZ RILP
413 XOR AH,AH
414 invoke IOFUNC
415 return
416;
417; Output the character in AL to stdout
418;
419entry RAWOUT
420
421 PUSH BX
422 MOV BX,1
423
424 invoke GET_IO_FCB
425 JC RAWRET1
426
427 TEST [SI.fcb_DEVID],080H ; output to file?
428 JZ RAWNORM ; if so, do normally
429 PUSH DS
430 PUSH SI
431 LDS SI,DWORD PTR [SI.fcb_FIRCLUS] ; output to special?
432 TEST BYTE PTR [SI+SDEVATT],ISSPEC
433 POP SI
434 POP DS
435 JZ RAWNORM ; if not, do normally
436 INT int_fastcon ; quickly output the char
437 JMP SHORT RAWRET
438RAWNORM:
439
440 CALL RAWOUT3
441RAWRET: CLC
442RAWRET1:
443 POP BX
444 return
445
446;
447; Output the character in AL to handle in BX
448;
449entry RAWOUT2
450
451 invoke GET_IO_FCB
452 retc
453RAWOUT3:
454 PUSH AX
455 JMP SHORT RAWOSTRT
456ROLP:
457 invoke SPOOLINT
458RAWOSTRT:
459 MOV AH,3
460 CALL IOFUNC
461 JZ ROLP
462 POP AX
463 MOV AH,2
464 CALL IOFUNC
465 CLC ; Clear carry indicating successful
466 return
467$RAW_CON_IO ENDP
468
469ASSUME DS:NOTHING,ES:NOTHING
470; This routine is called at DOS init
471
472 procedure OUTMES,NEAR ; String output for internal messages
473 LODS CS:BYTE PTR [SI]
474 CMP AL,"$"
475 retz
476 invoke OUT
477 JMP SHORT OUTMES
478 return
479OutMes ENDP
480 ASSUME SS:DOSGROUP
481
482BREAK <$Parse_File_Descriptor -- Parse an arbitrary string into an FCB>
483 procedure $PARSE_FILE_DESCRIPTOR,NEAR
484ASSUME DS:NOTHING,ES:NOTHING
485
486; Inputs:
487; DS:SI Points to a command line
488; ES:DI Points to an empty FCB
489; Bit 0 of AL = 1 At most one leading separator scanned off
490; = 0 Parse stops if separator encountered
491; Bit 1 of AL = 1 If drive field blank in command line - leave FCB
492; = 0 " " " " " " - put 0 in FCB
493; Bit 2 of AL = 1 If filename field blank - leave FCB
494; = 0 " " " - put blanks in FCB
495; Bit 3 of AL = 1 If extension field blank - leave FCB
496; = 0 " " " - put blanks in FCB
497; Function:
498; Parse command line into FCB
499; Returns:
500; AL = 1 if '*' or '?' in filename or extension, 0 otherwise
501; DS:SI points to first character after filename
502
503 invoke MAKEFCB
504 PUSH SI
505 invoke get_user_stack
506 POP [SI.user_SI]
507 return
508$PARSE_FILE_DESCRIPTOR ENDP
509
510BREAK <$Create_Process_Data_Block,SetMem -- Set up process data block>
511;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
512; C A V E A T P R O G R A M M E R ;
513; ;
514 procedure $Dup_PDB,NEAR
515ASSUME DS:NOTHING,ES:NOTHING
516 MOV BYTE PTR [CreatePDB], 0FFH ; indicate a new process
517$Dup_PDB ENDP
518
519
520 procedure $CREATE_PROCESS_DATA_BLOCK,NEAR
521ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
522
523; Inputs:
524; DX = Segment number of new base
525; Function:
526; Set up program base and copy term and ^C from int area
527; Returns:
528; None
529; Called at DOS init
530
531 MOV ES,DX
532 TEST BYTE PTR [CreatePDB],0FFh
533 JZ create_PDB_old
534 MOV DS,[CurrentPDB]
535 JMP SHORT Create_copy
536
537Create_PDB_old:
538 invoke get_user_stack
539 MOV DS,[SI.user_CS]
540
541Create_copy:
542 XOR SI,SI ; copy all 80h bytes
543 MOV DI,SI
544 MOV CX,80H
545 REP MOVSW
546
547 TEST BYTE PTR [CreatePDB],0FFh ; Shall we create a process?
548 JZ Create_PDB_cont ; nope, old style call
549;
550; Here we set up for a new process...
551;
552
553 PUSH CS
554 POP DS
555 ASSUME DS:DOSGROUP
556 XOR BX,BX ; dup all jfns
557 MOV CX,FilPerProc
558
559Create_dup_jfn:
560 PUSH ES ; save new PDB
561 invoke get_jfn_pointer ; ES:DI is jfn
562 JC create_skip ; not a valid jfn
563 PUSH ES ; save him
564 PUSH DI
565 invoke get_sf_from_jfn ; get sf pointer
566 JC create_no_inc
567 INC ES:[DI].sf_ref_count ; new fh
568
569create_no_inc:
570 POP DI
571 POP ES ; get old jfn
572 MOV AL,ES:[DI] ; get sfn
573 POP ES
574 PUSH ES
575 MOV AL,ES:[BX] ; copy into new place!
576
577create_skip:
578 POP ES
579 INC BX ; next jfn...
580 LOOP create_dup_jfn
581
582 PUSH [CurrentPDB] ; get current process
583 POP BX
584 PUSH BX
585 POP ES:[PDB_Parent_PID] ; stash in child
586 MOV [CurrentPDB],ES
587 ASSUME DS:NOTHING
588 MOV DS,BX
589;
590; end of new process create
591;
592Create_PDB_cont:
593 MOV BYTE PTR [CreatePDB],0h ; reset flag
594 MOV AX,DS:[2] ; set up size for fall through
595
596entry SETMEM
597ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
598
599; Inputs:
600; AX = Size of memory in paragraphs
601; DX = Segment
602; Function:
603; Completely prepares a program base at the
604; specified segment.
605; Called at DOS init
606; Outputs:
607; DS = DX
608; ES = DX
609; [0] has INT int_abort
610; [2] = First unavailable segment ([ENDMEM])
611; [5] to [9] form a long call to the entry point
612; [10] to [13] have exit address (from int_terminate)
613; [14] to [17] have ctrl-C exit address (from int_ctrl_c)
614; [18] to [21] have fatal error address (from int_fatal_abort)
615; DX,BP unchanged. All other registers destroyed.
616
617 XOR CX,CX
618 MOV DS,CX
619 MOV ES,DX
620 MOV SI,addr_int_terminate
621 MOV DI,SAVEXIT
622 MOV CX,6
623 REP MOVSW
624 MOV ES:[2],AX
625 SUB AX,DX
626 CMP AX,MAXDIF
627 JBE HAVDIF
628 MOV AX,MAXDIF
629HAVDIF:
630 MOV BX,ENTRYPOINTSEG
631 SUB BX,AX
632 MOV CL,4
633 SHL AX,CL
634 MOV DS,DX
635 MOV WORD PTR DS:[PDB_CPM_Call+1],AX
636 MOV WORD PTR DS:[PDB_CPM_Call+3],BX
637 MOV DS:[PDB_Exit_Call],(int_abort SHL 8) + mi_INT
638 MOV BYTE PTR DS:[PDB_CPM_Call],mi_Long_CALL
639 MOV WORD PTR DS:[PDB_Call_System],(int_command SHL 8) + mi_INT
640 MOV BYTE PTR DS:[PDB_Call_System+2],mi_Long_RET
641 return
642
643$CREATE_PROCESS_DATA_BLOCK ENDP
644 do_ext
645
646 CODE ENDS
647 END
648
diff --git a/v2.0/source/MORE.ASM b/v2.0/source/MORE.ASM
new file mode 100644
index 0000000..6c9bf95
--- /dev/null
+++ b/v2.0/source/MORE.ASM
Binary files differ
diff --git a/v2.0/source/MOREMES.ASM b/v2.0/source/MOREMES.ASM
new file mode 100644
index 0000000..57c28d1
--- /dev/null
+++ b/v2.0/source/MOREMES.ASM
@@ -0,0 +1,17 @@
1TITLE MORE Messages
2
3CODE SEGMENT PUBLIC
4 PUBLIC MORETXT,BADVER,CRLFTXT,BUFFER
5
6MORETXT DB 13,"-- More --$"
7BADVER DB "MORE: Incorrect DOS version"
8CRLFTXT DB 13,10,"$"
9;
10; THIS VARIABLE MUST BE DEFINED LAST!
11;
12BUFFER DB 4098 DUP (?)
13
14CODE ENDS
15 END
16
17 \ No newline at end of file
diff --git a/v2.0/source/MSCODE.ASM b/v2.0/source/MSCODE.ASM
new file mode 100644
index 0000000..c4b58bc
--- /dev/null
+++ b/v2.0/source/MSCODE.ASM
@@ -0,0 +1,615 @@
1;
2; MSCODE.ASM -- MSDOS code
3;
4
5INCLUDE DOSSEG.ASM
6INCLUDE STDSW.ASM
7
8CODE SEGMENT BYTE PUBLIC 'CODE'
9ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
10
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17IFNDEF KANJI
18KANJI EQU 0 ; FALSE
19ENDIF
20
21IFNDEF IBM
22IBM EQU 0
23ENDIF
24
25IFNDEF HIGHMEM
26HIGHMEM EQU 0
27ENDIF
28
29
30 i_need USER_SP,WORD
31 i_need USER_SS,WORD
32 i_need SAVEDS,WORD
33 i_need SAVEBX,WORD
34 i_need INDOS,BYTE
35 i_need NSP,WORD
36 i_need NSS,WORD
37 i_need CURRENTPDB,WORD
38 i_need AUXSTACK,BYTE
39 i_need CONSWAP,BYTE
40 i_need IDLEINT,BYTE
41 i_need NOSETDIR,BYTE
42 i_need ERRORMODE,BYTE
43 i_need IOSTACK,BYTE
44 i_need WPERR,BYTE
45 i_need DSKSTACK,BYTE
46 i_need CNTCFLAG,BYTE
47 i_need LEAVEADDR,WORD
48 i_need NULLDEVPT,DWORD
49
50 IF NOT IBM
51 i_need OEM_HANDLER,DWORD
52 ENDIF
53
54 EXTRN DSKSTATCHK:NEAR,GETBP:NEAR,DSKREAD:NEAR,DSKWRITE:NEAR
55
56
57BREAK <Copyright notice and version>
58
59CODSTRT EQU $
60
61 IF NOT IBM
62 IF NOT KANJI
63 PUBLIC HEADER
64HEADER DB 13,10,"Microsoft MS-DOS version "
65 DB DOS_MAJOR_VERSION + "0"
66 DB "."
67 DB (DOS_MINOR_VERSION / 10) + "0"
68 DB (DOS_MINOR_VERSION MOD 10) + "0"
69 IF HIGHMEM
70 DB "H"
71 ENDIF
72 ENDIF
73 IF KANJI
74 PUBLIC HEADER
75HEADER DB 13,10,82h,"M"+1fh,82h,"i"+20h,82h,"c"+20h,82h,"r"+20h,82h,"o"+20h
76 DB 82h,"s"+20h,82h,"o"+20h,82h,"f"+20h,82h,"t"+20h
77 DB 81h,40h,82h,"M"+1fh,82h,"S"+1fh,81h,5dh+1fh
78 DB 82h,"D"+1fh,82h,"O"+1fh,82h,"S"+1fh,81h,40h
79 DB 82h,DOS_MAJOR_VERSION+"0"+1fh
80 DB 81h,25h+1fh
81 DB 82h,(DOS_MINOR_VERSION / 10)+"0"+1fh
82 DB 82h,(DOS_MINOR_VERSION MOD 10)+"0"+1fh
83 DB 94h,0c5h
84 ENDIF
85 DB 13,10
86 DB "Copyright 1981,82,83 Microsoft Corp.",13,10,"$"
87 ENDIF
88BREAK <System call entry points and dispatcher>
89ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
90
91 procedure SYSTEM_CALL,NEAR
92entry QUIT ; INT 20H entry point
93 MOV AH,0
94 JMP SHORT SAVREGS
95
96entry COMMAND ; Interrupt call entry point (INT 21H)
97
98 IF NOT IBM
99 CMP AH,SET_OEM_HANDLER
100 JB NOTOEM
101 JMP $SET_OEM_HANDLER
102NOTOEM:
103 ENDIF
104
105 CMP AH,MAXCOM
106 JBE SAVREGS
107BADCALL:
108 MOV AL,0
109entry IRET
110 IRET
111
112entry CALL_ENTRY ; System call entry point and dispatcher
113 POP AX ; IP from the long call at 5
114 POP AX ; Segment from the long call at 5
115 POP [User_SP] ; IP from the CALL 5
116 PUSHF ; Start re-ordering the stack
117 CLI
118 PUSH AX ; Save segment
119 PUSH [User_SP] ; Stack now ordered as if INT had been used
120 CMP CL,MAXCALL ; This entry point doesn't get as many calls
121 JA BADCALL
122 MOV AH,CL
123SAVREGS:
124 CALL save_world
125 MOV [SaveDS],DS
126 MOV [SaveBX],BX
127 MOV BX,CS
128 MOV DS,BX
129ASSUME DS:DOSGROUP
130 INC [INDOS] ; Flag that we're in the DOS
131 MOV AX,[user_SP]
132 MOV [NSP],AX
133 MOV AX,[user_SS]
134 MOV [NSS],AX
135 POP AX
136 PUSH AX
137 MOV [user_SP],SP
138 MOV [user_SS],SS
139;
140; save user stack in his area for later returns (possibly from EXEC)
141; Here comes multitasking!!!
142;
143 MOV DS,[CurrentPDB]
144 MOV WORD PTR DS:[PDB_User_stack],SP
145 MOV WORD PTR DS:[PDB_User_stack+2],SS
146
147 MOV BX,CS ; no holes here.
148 MOV SS,BX
149ASSUME SS:DOSGROUP
150
151 entry REDISP
152 MOV SP,OFFSET DOSGROUP:AUXSTACK ; Enough stack for interrupts
153 STI ; Stack OK now
154 PUSH CS
155 POP DS
156 XOR BH,BH
157 MOV [CONSWAP],BH
158 MOV [IDLEINT],1
159 MOV BYTE PTR [NoSetDir],0 ; set directories on search
160 MOV BL,AH
161 SHL BX,1
162 CLD
163 OR AH,AH
164 JZ DSKROUT ; ABORT
165 CMP AH,12
166 JBE IOROUT ; Character I/O
167 CMP AH,GET_CURRENT_PDB ; INT 24 needs GET,SET PDB
168 JZ IOROUT
169 CMP AH,SET_CURRENT_PDB
170 JNZ DSKROUT
171IOROUT:
172 CMP [ERRORMODE],0
173 JNZ DISPCALL ; Stay on AUXSTACK if INT 24
174 MOV SP,OFFSET DOSGROUP:IOSTACK
175 JMP SHORT DISPCALL
176
177DSKROUT:
178 MOV [ERRORMODE],0 ; Cannot make non 1-12 calls in
179 MOV [WPERR],-1 ; error mode, so good place to
180 ; make sure flags are reset
181 MOV SP,OFFSET DOSGROUP:DSKSTACK
182 TEST [CNTCFLAG],-1
183 JZ DISPCALL
184 PUSH AX
185 invoke DSKSTATCHK
186 POP AX
187DISPCALL:
188 PUSH [LEAVEADDR]
189 PUSH CS:[BX+DISPATCH]
190 MOV BX,[SaveBX]
191 MOV DS,[SaveDS]
192ASSUME DS:NOTHING
193 return
194
195 entry LEAVE
196ASSUME SS:NOTHING ; User routines may misbehave
197 CLI
198 DEC [INDOS]
199 MOV SP,[user_SP]
200 MOV SS,[user_SS]
201 MOV BP,SP
202 MOV BYTE PTR [BP.user_AX],AL
203 MOV AX,[NSP]
204 MOV [user_SP],AX
205 MOV AX,[NSS]
206 MOV [user_SS],AX
207 CALL restore_world
208
209 IRET
210SYSTEM_CALL ENDP
211
212;
213; restore_world restores all registers ('cept SS:SP, CS:IP, flags) from
214; the stack prior to giving the user control
215;
216 ASSUME DS:NOTHING,ES:NOTHING
217restore_tmp DW ?
218 procedure restore_world,NEAR
219 POP restore_tmp ; POP restore_tmp
220 POP AX ; PUSH ES
221 POP BX ; PUSH DS
222 POP CX ; PUSH BP
223 POP DX ; PUSH DI
224 POP SI ; PUSH SI
225 POP DI ; PUSH DX
226 POP BP ; PUSH CX
227 POP DS ; PUSH BX
228 POP ES ; PUSH AX
229world_ret:
230 PUSH restore_tmp ; PUSH restore_tmp
231 return
232restore_world ENDP
233
234;
235; save_world saves complete registers on the stack
236;
237 procedure save_world,NEAR
238 POP restore_tmp
239 PUSH ES
240 PUSH DS
241 PUSH BP
242 PUSH DI
243 PUSH SI
244 PUSH DX
245 PUSH CX
246 PUSH BX
247 PUSH AX
248 JMP SHORT world_ret
249save_world ENDP
250
251;
252; get_user_stack returns the user's stack (and hence registers) in DS:SI
253;
254 procedure get_user_stack,NEAR
255 LDS SI,DWORD PTR [user_SP]
256 return
257get_user_stack ENDP
258
259; Standard Functions
260DISPATCH LABEL WORD
261.lall
262 short_addr $ABORT ; 0 0
263.xall
264 short_addr $STD_CON_INPUT ; 1 1
265 short_addr $STD_CON_OUTPUT ; 2 2
266 short_addr $STD_AUX_INPUT ; 3 3
267 short_addr $STD_AUX_OUTPUT ; 4 4
268 short_addr $STD_PRINTER_OUTPUT ; 5 5
269 short_addr $RAW_CON_IO ; 6 6
270 short_addr $RAW_CON_INPUT ; 7 7
271 short_addr $STD_CON_INPUT_NO_ECHO ; 8 8
272 short_addr $STD_CON_STRING_OUTPUT ; 9 9
273 short_addr $STD_CON_STRING_INPUT ; 10 A
274 short_addr $STD_CON_INPUT_STATUS ; 11 B
275 short_addr $STD_CON_INPUT_FLUSH ; 12 C
276 short_addr $DISK_RESET ; 13 D
277 short_addr $SET_DEFAULT_DRIVE ; 14 E
278 short_addr $FCB_OPEN ; 15 F
279 short_addr $FCB_CLOSE ; 16 10
280 short_addr $DIR_SEARCH_FIRST ; 17 11
281 short_addr $DIR_SEARCH_NEXT ; 18 12
282 short_addr $FCB_DELETE ; 19 13
283 short_addr $FCB_SEQ_READ ; 20 14
284 short_addr $FCB_SEQ_WRITE ; 21 15
285 short_addr $FCB_CREATE ; 22 16
286 short_addr $FCB_RENAME ; 23 17
287 short_addr CPMFUNC ; 24 18
288 short_addr $GET_DEFAULT_DRIVE ; 25 19
289 short_addr $SET_DMA ; 26 1A
290
291;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
292; C A V E A T P R O G R A M M E R ;
293; ;
294 short_addr $SLEAZEFUNC ; 27 1B
295 short_addr $SLEAZEFUNCDL ; 28 1C
296; ;
297; C A V E A T P R O G R A M M E R ;
298;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
299
300 short_addr CPMFUNC ; 29 1D
301 short_addr CPMFUNC ; 30 1E
302;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
303; C A V E A T P R O G R A M M E R ;
304; ;
305 short_addr $GET_DEFAULT_DPB ; 31 1F
306; ;
307; C A V E A T P R O G R A M M E R ;
308;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
309 short_addr CPMFUNC ; 32 20
310 short_addr $FCB_RANDOM_READ ; 33 21
311 short_addr $FCB_RANDOM_WRITE ; 34 22
312 short_addr $GET_FCB_FILE_LENGTH ; 35 23
313 short_addr $GET_FCB_POSITION ; 36 24
314MAXCALL = ($-DISPATCH)/2 - 1
315
316; Extended Functions
317 short_addr $SET_INTERRUPT_VECTOR ; 37 25
318;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
319; C A V E A T P R O G R A M M E R ;
320; ;
321 short_addr $CREATE_PROCESS_DATA_BLOCK ; 38 26
322; ;
323; C A V E A T P R O G R A M M E R ;
324;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
325 short_addr $FCB_RANDOM_READ_BLOCK ; 39 27
326 short_addr $FCB_RANDOM_WRITE_BLOCK ; 40 28
327 short_addr $PARSE_FILE_DESCRIPTOR ; 41 29
328 short_addr $GET_DATE ; 42 2A
329 short_addr $SET_DATE ; 43 2B
330 short_addr $GET_TIME ; 44 2C
331 short_addr $SET_TIME ; 45 2D
332 short_addr $SET_VERIFY_ON_WRITE ; 46 2E
333
334; Extended functionality group
335 short_addr $GET_DMA ; 47 2F
336 short_addr $GET_VERSION ; 48 30
337 short_addr $Keep_Process ; 49 31
338;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
339; C A V E A T P R O G R A M M E R ;
340; ;
341 short_addr $GET_DPB ; 50 32
342; ;
343; C A V E A T P R O G R A M M E R ;
344;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
345 short_addr $SET_CTRL_C_TRAPPING ; 51 33
346 short_addr $GET_INDOS_FLAG ; 52 34
347 short_addr $GET_INTERRUPT_VECTOR ; 53 35
348 short_addr $GET_DRIVE_FREESPACE ; 54 36
349 short_addr $CHAR_OPER ; 55 37
350 short_addr $INTERNATIONAL ; 56 38
351; XENIX CALLS
352; Directory Group
353 short_addr $MKDIR ; 57 39
354 short_addr $RMDIR ; 58 3A
355 short_addr $CHDIR ; 59 3B
356; File Group
357 short_addr $CREAT ; 60 3C
358 short_addr $OPEN ; 61 3D
359 short_addr $CLOSE ; 62 3E
360 short_addr $READ ; 63 3F
361 short_addr $WRITE ; 64 40
362 short_addr $UNLINK ; 65 41
363 short_addr $LSEEK ; 66 42
364 short_addr $CHMOD ; 67 43
365 short_addr $IOCTL ; 68 44
366 short_addr $DUP ; 69 45
367 short_addr $DUP2 ; 70 46
368 short_addr $CURRENT_DIR ; 71 47
369; Memory Group
370 short_addr $ALLOC ; 72 48
371 short_addr $DEALLOC ; 73 49
372 short_addr $SETBLOCK ; 74 4A
373; Process Group
374 short_addr $EXEC ; 75 4B
375 short_addr $EXIT ; 76 4C
376 short_addr $WAIT ; 77 4D
377 short_addr $FIND_FIRST ; 78 4E
378; Special Group
379 short_addr $FIND_NEXT ; 79 4F
380; SPECIAL SYSTEM GROUP
381;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
382; C A V E A T P R O G R A M M E R ;
383; ;
384 short_addr $SET_CURRENT_PDB ; 80 50
385 short_addr $GET_CURRENT_PDB ; 81 51
386 short_addr $GET_IN_VARS ; 82 52
387 short_addr $SETDPB ; 83 53
388; ;
389; C A V E A T P R O G R A M M E R ;
390;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
391 short_addr $GET_VERIFY_ON_WRITE ; 84 54
392;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
393; C A V E A T P R O G R A M M E R ;
394; ;
395 short_addr $DUP_PDB ; 85 55
396; ;
397; C A V E A T P R O G R A M M E R ;
398;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
399 short_addr $RENAME ; 86 56
400 short_addr $FILE_TIMES ; 87 57
401 short_addr $AllocOper ; 88 58
402
403MAXCOM = ($-DISPATCH)/2 - 1
404
405CPMFUNC:
406 XOR AL,AL
407 return
408
409 IF NOT IBM
410BREAK <Set_OEM_Handler -- Set OEM sys call address and handle OEM Calls>
411
412$SET_OEM_HANDLER:
413ASSUME DS:NOTHING,ES:NOTHING
414
415; Inputs:
416; User registers, User Stack, INTS disabled
417; If CALL F8, DS:DX is new handler address
418; Function:
419; Process OEM INT 21 extensions
420; Outputs:
421; Jumps to OEM_HANDLER if appropriate
422
423 JNE DO_OEM_FUNC ; If above F8 try to jump to handler
424 MOV WORD PTR [OEM_HANDLER],DX ; Set Handler
425 MOV WORD PTR [OEM_HANDLER+2],DS
426 IRET ; Quick return, Have altered no registers
427
428DO_OEM_FUNC:
429 CMP WORD PTR [OEM_HANDLER],-1
430 JNZ OEM_JMP
431 JMP BADCALL ; Handler not initialized
432
433OEM_JMP:
434 JMP [OEM_HANDLER]
435
436 ENDIF
437
438
439ASSUME SS:DOSGROUP
440
441;
442; $Set_current_PDB takes BX and sets it to be the current process
443; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! ***
444;
445 procedure $SET_CURRENT_PDB,NEAR
446 ASSUME DS:NOTHING,SS:NOTHING
447 MOV [CurrentPDB],BX
448 return
449$SET_CURRENT_PDB ENDP
450
451;
452; $get_current_PDB returns in BX the current process
453; *** THIS FUNCTION CALL IS SUBJECT TO CHANGE!!! ***
454;
455 procedure $GET_CURRENT_PDB,NEAR
456 ASSUME DS:NOTHING,SS:NOTHING
457 invoke get_user_stack
458 PUSH [CurrentPDB]
459 POP [SI.user_BX]
460 return
461$GET_CURRENT_PDB ENDP
462; ;
463; C A V E A T P R O G R A M M E R ;
464;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
465
466BREAK <NullDev -- Driver for null device>
467 procedure SNULDEV,FAR
468ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
469 MOV WORD PTR [NULLDEVPT],BX
470 MOV WORD PTR [NULLDEVPT+2],ES
471 return
472SNULDEV ENDP
473
474 procedure INULDEV,FAR
475 PUSH ES
476 PUSH BX
477 LES BX,[NULLDEVPT]
478 OR ES:[BX.REQSTAT],STDON ; Set done bit
479 POP BX
480 POP ES
481 return
482
483INULDEV ENDP
484
485
486BREAK <AbsDRD, AbsDWRT -- INT int_disk_read, int_disk_write handlers>>
487
488
489 IF IBM
490ERRIN: ; Codes returned by BIOS
491 DB 2 ; NO RESPONSE
492 DB 6 ; SEEK FAILURE
493 DB 12 ; GENERAL ERROR
494 DB 4 ; BAD CRC
495 DB 8 ; SECTOR NOT FOUND
496 DB 0 ; WRITE ATTEMPT ON WRITE-PROTECT DISK
497ERROUT: ; DISK ERRORS RETURNED FROM INT 25 and 26
498 DB 80H ; NO RESPONSE
499 DB 40H ; Seek failure
500 DB 2 ; Address Mark not found
501 DB 8 ; DMA OVERRUN
502 DB 4 ; SECTOR NOT FOUND
503 DB 3 ; WRITE ATTEMPT TO WRITE-PROTECT DISK
504
505NUMERR EQU $-ERROUT
506 ENDIF
507
508 procedure ABSDRD,FAR
509ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
510
511 CLI
512 MOV [user_SS],SS
513 MOV [user_SP],SP
514 PUSH CS
515 POP SS
516ASSUME SS:DOSGROUP
517 MOV SP,OFFSET DOSGROUP:DSKSTACK
518 INC BYTE PTR [INDOS]
519 STI
520 CLD
521 PUSH ES
522 PUSH DS
523 PUSH SS
524 POP DS
525ASSUME DS:DOSGROUP
526 invoke GETBP
527 POP DS
528ASSUME DS:NOTHING
529 JC ILEAVE
530 invoke DSKREAD
531TLEAVE:
532 JZ ILEAVE
533
534 IF IBM
535; Translate the error code to ancient 1.1 codes
536 PUSH ES
537 PUSH CS
538 POP ES
539 XOR AH,AH ; Nul error code
540 MOV CX,NUMERR ; Number of possible error conditions
541 MOV DI,OFFSET DOSGROUP:ERRIN ; Point to error conditions
542 REPNE SCASB
543 JNZ LEAVECODE ; Not found
544 MOV AH,ES:[DI+NUMERR-1] ; Get translation
545LEAVECODE:
546 POP ES
547 ENDIF
548
549 STC
550ILEAVE:
551 POP ES
552 CLI
553 DEC BYTE PTR [INDOS]
554 MOV SP,[user_SP]
555 MOV SS,[user_SS]
556ASSUME SS:NOTHING
557 STI
558 return
559ABSDRD ENDP
560
561 procedure ABSDWRT,FAR
562ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
563
564 CLI
565 MOV [user_SS],SS
566 MOV [user_SP],SP
567 PUSH CS
568 POP SS
569ASSUME SS:DOSGROUP
570 MOV SP,OFFSET DOSGROUP:DSKSTACK
571 INC BYTE PTR [INDOS]
572 STI
573 CLD
574 PUSH ES
575 PUSH DS
576 PUSH SS
577 POP DS
578ASSUME DS:DOSGROUP
579 invoke GETBP
580 POP DS
581ASSUME DS:NOTHING
582 JC ILEAVE
583 invoke DSKWRITE
584 JMP TLEAVE
585ABSDWRT ENDP
586
587
588
589 procedure SYS_RETURN,NEAR
590 ASSUME DS:NOTHING,ES:NOTHING
591 entry SYS_RET_OK
592 call get_user_stack
593 PUSH [SI.user_F]
594 POPF
595 CLC
596 JMP SHORT DO_RET
597
598 entry SYS_RET_ERR
599 XOR AH,AH ; hack to allow for smaller error rets
600 call get_user_stack
601 PUSH [SI.user_F]
602 POPF
603 STC
604DO_RET:
605 MOV [SI.user_AX],AX ; Really only sets AH
606 PUSHF
607 POP [SI.user_F] ; dump on his flags
608 return
609SYS_RETURN ENDP
610
611do_ext
612
613CODE ENDS
614 END
615 \ No newline at end of file
diff --git a/v2.0/source/MSDATA.ASM b/v2.0/source/MSDATA.ASM
new file mode 100644
index 0000000..ed524e8
--- /dev/null
+++ b/v2.0/source/MSDATA.ASM
@@ -0,0 +1,342 @@
1SUBTTL Initialized data and data used at DOS initialization
2PAGE
3; DATA AREA for MS-DOS
4
5IFNDEF KANJI
6KANJI EQU 0 ;FALSE
7ENDIF
8
9CONSTANTS SEGMENT BYTE PUBLIC 'CONST'
10 EXTRN international_table:BYTE
11 EXTRN Current_Country:WORD
12
13
14 ORG 0
15CONSTRT EQU $ ; Start of constants segment
16
17 PUBLIC DevStrLen
18DEVSTRLEN DB 3 ; Size of below
19 PUBLIC DevString
20DEVSTRING DB "DEV" ; Dummy device directory
21
22;
23; Table of routines for assignable devices
24;
25; MSDOS allows assignment if the following standard devices:
26; stdin (usually CON input)
27; stdout (usually CON output)
28; auxin (usually AUX input)
29; auxout (usually AUX output)
30; stdlpt (usually PRN output)
31;
32; SPECIAL NOTE:
33; Status of a file is a strange idea. We choose to handle it in this manner:
34; If we're not at end-of-file, then we always say that we have a character.
35; Otherwise, we return ^Z as the character and set the ZERO flag. In this
36; manner we can support program written under the old DOS (they use ^Z as EOF
37; on devices) and programs written under the new DOS (they use the ZERO flag
38; as EOF).
39
40; Default FCBs for boot up
41
42sftabl LABEL DWORD ; file table
43 DW -1
44 DW -1
45 DW sf_default_number ; Number of entries in table
46 DB sf_default_number DUP ( (SIZE sf_entry) DUP (0))
47
48 I_AM NoSetDir,BYTE ; true -> do not set directory
49 I_am DidCTRLC,BYTE ; true -> we did a ^C exit
50 I_am SpaceFlag,BYTE ; true -> embedded spaces are allowed
51 ; in FCB
52; the next two variables relate to the position of the logical stdout/stdin
53; cursor. They are only meaningful when stdin/stdout are assigned to the
54; console.
55
56 i_am CARPOS,BYTE ; cursor position in stdin
57 i_am STARTPOS,BYTE ; position of cursor at beginning
58 ; of buffered input call
59 I_AM PFLAG,BYTE
60 I_AM VERFLG,BYTE ; Initialize with verify off
61 I_AM CONTPOS,WORD
62 PUBLIC CHARCO
63CHARCO DB 00000011B ; Allows statchks every 4 chars...
64
65 I_AM DMAADD,DWORD ; User's disk transfer address
66 ; (disp/seg)
67 ORG $-CONSTRT-4
68 DW 80H
69 DW ?
70
71ENDMEM DW ?
72
73 PUBLIC switch_character
74switch_character DB '/'
75
76 PUBLIC device_availability
77device_availability DB 0FFH
78
79 I_AM FirstArena,WORD ; first free block found
80 I_AM BestArena,WORD ; best free block found
81 I_AM LastArena,WORD ; last free block found
82 I_AM AllocMethod,BYTE ; how to alloc first(best)last
83 I_AM arena_head,WORD
84
85; The following block of data is used by SYSINIT. Do not change the order or
86; size of this block
87
88 PUBLIC SYSINITVAR
89SYSINITVAR LABEL WORD
90 I_AM DPBHEAD,DWORD ; Pointer to head of DPB-FAT list
91 I_AM sft_addr,DWORD ; Pointer to first FCB table
92 ORG $-CONSTRT-4
93 short_addr sftabl
94 DW ? ; DOS segment set at INIT
95
96; The following address points to the CLOCK device
97 i_am BCLOCK,DWORD
98; The following address is used by DISKSTATCHK it is always points to the
99; console input device header
100 I_AM BCON,DWORD ; Console device entry points
101 i_am NUMIO,BYTE ; Number of disk tables
102MAXSEC DW 0 ; Maximum allowed sector size
103 I_AM BUFFHEAD,DWORD ; Pointer to head of buffer queue
104DEVHEAD LABEL DWORD
105 I_AM NULDEV,DWORD ; Set to list start passed by
106 ; BIOS at DOS Init
107
108 DW DEVTYP OR ISNULL
109 short_addr SNULDEV
110 short_addr INULDEV
111 DB "NUL "
112
113
114 i_am DAY,BYTE
115 i_am MONTH,BYTE
116 i_am YEAR,WORD
117 i_am DAYCNT,WORD
118 i_am WEEKDAY,BYTE
119 ORG $-CONSTRT-7
120 DB 0,0
121 DW 0,-1
122 DB 0
123
124 I_AM CURDRV,BYTE ; Default to drive A
125 I_AM LASTENT,WORD
126 i_am INDOS,BYTE ; DOS status for interrupt processing
127 ORG $-CONSTRT-1
128 DB 0
129 I_AM ErrorMode,BYTE ; Flag for INT 24 processing
130 PUBLIC WPErr
131WPERR DB -1 ; Write protect error flag
132 I_AM CONSWAP,BYTE
133 PUBLIC IDLEINT
134IDLEINT DB 1
135 PUBLIC CNTCFLAG
136CNTCFLAG DB 0 ; ^C check in dispatch disabled
137
138 PUBLIC LastBuffer
139LASTBUFFER LABEL DWORD ; Buffer queue recency pointer
140 DW -1
141 DW -1
142
143; Combination of all device call parameters
144
145 PUBLIC DEVCALL
146DEVCALL SRHEAD <>
147CALLUNIT LABEL BYTE
148CALLFLSH LABEL WORD
149 I_AM CALLMED,BYTE
150CALLBR LABEL DWORD
151 PUBLIC CALLXAD
152CALLXAD LABEL DWORD
153 I_AM CALLRBYT,BYTE
154 DB 3 DUP(?)
155 PUBLIC CallBPB
156CALLBPB LABEL DWORD
157 I_AM CALLSCNT,WORD
158CALLSSEC DW ?
159
160 I_AM CALLDEVAD,DWORD ; stash for device entry point
161
162; Same as above for I/O calls
163
164 PUBLIC IOCall
165IOCALL SRHEAD <>
166IOFLSH LABEL WORD
167 PUBLIC IORCHR
168IORCHR LABEL BYTE
169 I_AM IOMED,BYTE
170 I_AM IOXAD,DWORD
171 I_AM IOSCNT,WORD
172 I_AM IOSSEC,WORD
173
174; Call struct for DSKSTATCHK
175 PUBLIC DSKSTCALL
176DSKSTCALL DB DRDNDHL
177 DB 0
178 PUBLIC DSKSTCOM
179DSKSTCOM DB DEVRDND
180 I_AM DSKSTST,WORD
181 DB 8 DUP (0)
182 I_AM DSKCHRET,BYTE
183 short_addr DEVIOBUF
184 DW ? ; DOS segment set at Init
185 PUBLIC DSKSTCNT
186DSKSTCNT DW 1
187 DW 0
188
189; Days in year
190 i_am YRTAB,8
191 ORG $-CONSTRT-8
192 DB 200,166 ; Leap year
193 DB 200,165
194 DB 200,165
195 DB 200,165
196
197; Days of each month
198 i_am MONTAB,12
199 ORG $-CONSTRT-12
200 DB 31 ; January
201 DB 28 ; February--reset each
202 ; time year changes
203 DB 31 ; March
204 DB 30 ; April
205 DB 31 ; May
206 DB 30 ; June
207 DB 31 ; July
208 DB 31 ; August
209 DB 30 ; September
210 DB 31 ; October
211 DB 30 ; November
212 DB 31 ; December
213
214 IF NOT IBM
215 PUBLIC OEM_HANDLER
216OEM_HANDLER DD -1
217 ENDIF
218
219;WARNING For HIGHMEM version, these two vars must be at the end of the
220; Constants segment to prevent them getting overwritten.
221 I_AM CurrentPDB,WORD
222 i_am CreatePDB,BYTE ; flag for creating a process
223
224 PUBLIC LEAVEADDR
225LEAVEADDR LABEL WORD
226 short_addr LEAVE
227
228CONSTANTS ENDS
229
230SUBTTL Uninitialized data overlayed by initialization code
231PAGE
232DATA SEGMENT WORD PUBLIC 'DATA'
233; Init code overlaps with data area below
234
235 ORG 0
236 i_am INBUF,128
237 I_AM CONBUF,131 ; The rest of INBUF and console buffer
238 i_am TIMEBUF,6
239 I_AM DEVIOBUF,2 ; Buffer for I/O under file assignment
240 I_AM EXITHOLD,DWORD
241
242 PUBLIC DevFCB
243DEVFCB LABEL BYTE ; Uses NAME1, NAME2, NAME3 combined
244; WARNING.. do not alter size or relative location of the following 4 items
245; without first examining FCB_RENAME
246 I_AM NAME1,12 ; File name buffer
247 I_AM ATTRIB,BYTE
248 I_AM NAME2,13
249 I_AM NAME3,14
250
251 I_AM EXTFCB,BYTE
252
253; WARNING - the following two items are accessed as a word
254 I_AM CREATING,BYTE
255 I_AM DELALL,BYTE
256
257 I_AM FoundDel,BYTE
258
259 I_AM user_SP,WORD
260 I_AM user_SS,WORD
261 I_AM CONTSTK,WORD
262 I_AM SECCLUSPOS,BYTE ; Position of first sector
263 ; within cluster
264 I_AM DSKERR,BYTE
265 I_AM TRANS,BYTE
266 I_AM READOP,BYTE
267 I_AM THISDRV,BYTE
268 I_AM THISDPB,DWORD
269 I_AM CLUSFAC,BYTE
270
271; WARNING - the following two items are accessed as a word
272 I_AM DRIVESPEC,BYTE
273 I_AM ROOTSTART,BYTE
274
275 I_AM CLUSSPLIT,BYTE
276 i_am INSMODE,BYTE
277 I_AM CLUSSAVE,WORD
278 I_AM CLUSSEC,WORD
279 I_AM PREREAD,WORD ; 0 means preread; 1 means optional
280 I_AM FATBYT,WORD
281 I_AM DEVPT,DWORD
282 I_AM THISFCB,DWORD ; Address of user FCB
283
284 I_AM NEXTADD,WORD
285 I_AM RECPOS,4
286 I_AM RECCNT,WORD
287 I_AM LASTPOS,WORD
288 I_AM CLUSNUM,WORD
289 I_AM DIRSEC,WORD
290 I_AM DIRSTART,WORD
291 I_AM SECPOS,WORD ; Position of first sector accessed
292 I_AM VALSEC,WORD ; Number of valid (previously written)
293 ; sectors
294 I_AM BYTSECPOS,WORD ; Position of first byte within sector
295 I_AM BYTPOS,4 ; Byte position in file of access
296 I_AM BYTCNT1,WORD ; No. of bytes in first sector
297 I_AM BYTCNT2,WORD ; No. of bytes in last sector
298 I_AM SECCNT,WORD ; No. of whole sectors
299 I_AM ENTFREE,WORD
300 I_AM ENTLAST,WORD
301 I_AM NXTCLUSNUM,WORD
302 I_AM GROWCNT,DWORD
303 I_AM CURBUF,DWORD
304 I_AM VOLID,BYTE
305 I_AM NULLDEVPT,DWORD
306 I_AM CINSAV,DWORD
307 I_AM CINDSAV,BYTE
308 I_AM COUTDSAV,BYTE
309 I_AM COUTSAV,DWORD
310 PUBLIC SaveBX
311SaveBX DW ?
312 PUBLIC SaveDS
313SaveDS DW ?
314 I_AM ConC_spsave,WORD
315
316 I_AM exit_code,WORD ; exit code of last proc.
317 I_am exit_type,BYTE ; type of exit...
318
319 IF IBM
320;For 2.00 this pads the DOS so that on a 2 disk IBM PC with no
321;CONFIG.SYS file the space taken up by BIOS, DOS, res COMMAND is
322;about 24K
323IBMPAD DB 540h DUP(?)
324 ENDIF
325
326; make those pushes fast!!!
327EVEN
328 DB 0A0H DUP (?)
329 I_am AuxStack,0A0h
330 I_AM DSKSTACK,0A0h ; Stack space
331 PUBLIC IOSTACK
332IOSTACK LABEL BYTE
333
334 PUBLIC NSS
335NSS DW ?
336 PUBLIC NSP
337NSP DW ?
338
339PAGE
340 INCLUDE MSINIT.ASM
341
342 \ No newline at end of file
diff --git a/v2.0/source/MSDOS.ASM b/v2.0/source/MSDOS.ASM
new file mode 100644
index 0000000..1d43531
--- /dev/null
+++ b/v2.0/source/MSDOS.ASM
@@ -0,0 +1,12 @@
1TITLE Standard MSDOS
2NAME MSDOS_2
3
4; Number of disk I/O buffers
5
6 INCLUDE STDSW.ASM
7 INCLUDE MSHEAD.ASM
8 INCLUDE MSDATA.ASM
9
10 END
11
12 \ No newline at end of file
diff --git a/v2.0/source/MSHEAD.ASM b/v2.0/source/MSHEAD.ASM
new file mode 100644
index 0000000..108197d
--- /dev/null
+++ b/v2.0/source/MSHEAD.ASM
@@ -0,0 +1,198 @@
1; TITLE MSHEAD.ASM -- MS-DOS DEFINITIONS
2PAGE
3; MS-DOS High-performance operating system for the 8086 version 1.28
4; by Microsoft MSDOS development group:
5; Tim Paterson (Ret.)
6; Aaron Reynolds
7; Nancy Panners (Parenting)
8; Mark Zbikowski
9; Chris Peters (BIOS) (ret.)
10
11; ****************** Revision History *************************
12; >> EVERY change must noted below!! <<
13;
14; 0.34 12/29/80 General release, updating all past customers
15; 0.42 02/25/81 32-byte directory entries added
16; 0.56 03/23/81 Variable record and sector sizes
17; 0.60 03/27/81 Ctrl-C exit changes, including register save on user stack
18; 0.74 04/15/81 Recognize I/O devices with file names
19; 0.75 04/17/81 Improve and correct buffer handling
20; 0.76 04/23/81 Correct directory size when not 2^N entries
21; 0.80 04/27/81 Add console input without echo, Functions 7 & 8
22; 1.00 04/28/81 Renumber for general release
23; 1.01 05/12/81 Fix bug in `STORE'
24; 1.10 07/21/81 Fatal error trapping, NUL device, hidden files, date & time,
25; RENAME fix, general cleanup
26; 1.11 09/03/81 Don't set CURRENT BLOCK to 0 on open; fix SET FILE SIZE
27; 1.12 10/09/81 Zero high half of CURRENT BLOCK after all (CP/M programs don't)
28; 1.13 10/29/81 Fix classic "no write-through" error in buffer handling
29; 1.20 12/31/81 Add time to FCB; separate FAT from DPT; Kill SMALLDIR; Add
30; FLUSH and MAPDEV calls; allow disk mapping in DSKCHG; Lots
31; of smaller improvements
32; 1.21 01/06/82 HIGHMEM switch to run DOS in high memory
33; 1.22 01/12/82 Add VERIFY system call to enable/disable verify after write
34; 1.23 02/11/82 Add defaulting to parser; use variable escape character Don't
35; zero extent field in IBM version (back to 1.01!)
36; 1.24 03/01/82 Restore fcn. 27 to 1.0 level; add fcn. 28
37; 1.25 03/03/82 Put marker (00) at end of directory to speed searches
38; 1.26 03/03/82 Directory buffers searched as a circular queue, current buffer
39; is searched first when possible to minimize I/O
40; 03/03/82 STORE routine optimized to tack on partial sector tail as
41; full sector write when file is growing
42; 03/09/82 Multiple I/O buffers
43; 03/29/82 Two bugs: Delete all case resets search to start at beginning
44; of directory (infinite loop possible otherwise), DSKRESET
45; must invalidate all buffers (disk and directory).
46; 1.27 03/31/82 Installable device drivers
47; Function call 47 - Get pointer to device table list
48; Function call 48 - Assign CON AUX LIST
49; 04/01/82 Spooler interrupt (INT 28) added.
50; 1.28 04/15/82 DOS retructured to use ASSUMEs and PROC labels around system
51; call entries. Most CS relative references changed to SS
52; relative with an eye toward putting a portion of the DOS in
53; ROM. DOS source also broken into header, data and code pieces
54; 04/15/82 GETDMA and GETVECT calls added as 24 and 32. These calls
55; return the current values.
56; 04/15/82 INDOS flag implemented for interrupt processing along with
57; call to return flag location (call 29)
58; 04/15/82 Volume ID attribute added
59; 04/17/82 Changed ABORT return to user to a long ret from a long jump to
60; avoid a CS relative reference.
61; 04/17/82 Put call to STATCHK in dispatcher to catch ^C more often
62; 04/20/82 Added INT int_upooler into loop ^S wait
63; 04/22/82 Dynamic disk I/O buffer allocation and call to manage them
64; call 49.
65; 04/23/82 Added GETDSKPTDL as call 50, similar to GETFATPT(DL), returns
66; address of DPB
67; 04/29/82 Mod to WRTDEV to look for ^C or ^S at console input when
68; writting to console device via file I/O. Added a console
69; output attribute to devices.
70; 04/30/82 Call to en/dis able ^C check in dispatcher Call 51
71; 04/30/82 Code to allow assignment of func 1-12 to disk files as well
72; as devices.... pipes, redirection now possible
73; 04/30/82 Expanded GETLIST call to 2.0 standard
74; 05/04/82 Change to INT int_fatal_abort callout int HARDERR. DOS SS
75; (data segment) stashed in ES, INT int_fatal_abort routines must
76; preserve ES. This mod so HARDERR can be ROMed.
77; 1.29 06/01/82 Installable block and character devices as per 2.0 spec
78; 06/04/82 Fixed Bug in CLOSE regarding call to CHKFATWRT. It got left
79; out back about 1.27 or so (oops). ARR
80; 1.30 06/07/82 Directory sector buffering added to main DOS buffer queue
81; 1.40 06/15/82 Tree structured directories. XENIX Path Parser MKDIR CHDIR
82; RMDIR Xenix calls
83; 1.41 06/13/82 Made GETBUFFR call PLACEBUF
84; 1.50 06/17/82 FATs cached in buffer pool, get FAT pointer calls disappear
85; Frees up lots of memory.
86; 1.51 06/24/82 BREAKDOWN modified to do EXACT one sector read/write through
87; system buffers
88; 1.52 06/30/82 OPEN, CLOSE, READ, WRITE, DUP, DUP2, LSEEK implemented
89; 1.53 07/01/82 OPEN CLOSE mod for Xenix calls, saves and gets remote dir
90; 1.54 07/11/82 Function calls 1-12 make use of new 2.0 PDB. Init code
91; changed to set file handle environment.
92; 2.00 08/01/82 Number for IBM release
93; 01/19/83 No environ bug in EXEC
94; 01/19/83 MS-DOS OEM INT 21 extensions (SET_OEM_HANDLER)
95; 01/19/83 Performance bug fix in cooked write to NUL
96; 01/27/83 Growcnt fixed for 32-bits
97; 01/27/83 Find-first problem after create
98; 2.01 02/17/83 International DOS
99; 2.11 08/12/83 Dos split into several more modules for assembly on
100; an IBM PC
101;
102; *************************************************************
103
104
105SUBTTL EQUATES
106PAGE
107; Interrupt Entry Points:
108
109; INTBASE: ABORT
110; INTBASE+4: COMMAND
111; INTBASE+8: BASE EXIT ADDRESS
112; INTBASE+C: CONTROL-C ABORT
113; INTBASE+10H: FATAL ERROR ABORT
114; INTBASE+14H: BIOS DISK READ
115; INTBASE+18H: BIOS DISK WRITE
116; INTBASE+1CH: END BUT STAY RESIDENT (NOT SET BY DOS)
117; INTBASE+20H: SPOOLER INTERRUPT
118; INTBASE+40H: Long jump to CALL entry point
119
120ENTRYPOINTSEG EQU 0CH
121MAXDIF EQU 0FFFH
122SAVEXIT EQU 10
123
124 INCLUDE DOSSYM.ASM
125 INCLUDE DEVSYM.ASM
126
127SUBTTL ^C, terminate/abort/exit and Hard error actions
128PAGE
129;
130; There are three kinds of context resets that can occur during normal DOS
131; functioning: ^C trap, terminate/abort/exit, and Hard-disk error. These must
132; be handles in a clean fashion that allows nested executions along with the
133; ability to trap one's own errors.
134;
135; ^C trap - A process may elect to catch his own ^Cs. This is achieved by
136; using the $GET_INTERRUPT_VECTOR and $SET_INTERRUPT_VECTOR as
137; follows:
138;
139; $GET_INTERRUPT_VECTOR for INT int_ctrl_c
140; Save it in static memory.
141; $SET_INTERRUPT_VECTOR for INT int_ctrl_c
142;
143; The interrupt service routine must preserve all registers and
144; return carry set iff the operation is to be aborted (via abort
145; system call), otherwise, carry is reset and the operation is
146; restarted. ANY DEVIATION FROM THIS WILL LEAD TO UNRELIABLE
147; RESULTS.
148;
149; To restore original ^C processing (done on terminate/abort/exit),
150; restore INT int_ctrl_c from the saved vector.
151;
152; Hard-disk error -- The interrupt service routine for INT int_fatal_abort must
153; also preserve registers and return one of three values in AL: 0 and
154; 1 imply retry and ignore (???) and 2 indicates an abort. The user
155; himself is not to issue the abort, rather, the dos will do it for
156; him by simulating a normal abort/exit system call. ANY DEVIATION
157; FROM THIS WILL LEAD TO UNRELIABLE RESULTS.
158;
159; terminate/abort/exit -- The user may not, under any circumstances trap an
160; abort call. This is reserved for knowledgeable system programs.
161; ANY DEVIATION FROM THIS WILL LEAD TO UNRELIABLE RESULTS.
162
163SUBTTL SEGMENT DECLARATIONS
164PAGE
165
166; The following are all of the segments used. They are declared in the order
167; that they should be placed in the executable
168
169;
170; segment ordering for MSDOS
171;
172
173START SEGMENT BYTE PUBLIC 'START'
174START ENDS
175
176CONSTANTS SEGMENT BYTE PUBLIC 'CONST'
177CONSTANTS ENDS
178
179DATA SEGMENT WORD PUBLIC 'DATA'
180DATA ENDS
181
182CODE SEGMENT BYTE PUBLIC 'CODE'
183CODE ENDS
184
185LAST SEGMENT BYTE PUBLIC 'LAST'
186LAST ENDS
187
188DOSGROUP GROUP CODE,CONSTANTS,DATA,LAST
189
190; The following segment is defined such that the data/const classes appear
191; before the code class for ROMification
192
193START SEGMENT BYTE PUBLIC 'START'
194 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
195 JMP DOSINIT
196START ENDS
197
198 \ No newline at end of file
diff --git a/v2.0/source/MSINIT.ASM b/v2.0/source/MSINIT.ASM
new file mode 100644
index 0000000..36edf9f
--- /dev/null
+++ b/v2.0/source/MSINIT.ASM
@@ -0,0 +1,408 @@
1; TITLE MSINIT.ASM -- MS-DOS INITIALIZATION CODE
2
3 ORG 0 ; reset to beginning of data segment
4; Init code below overlaps with data area
5
6INITBLOCK DB 110H DUP(0) ; Allow for segment round up
7
8INITSP DW ?
9INITSS DW ?
10BUFFSTRT DW ?
11
12ASSUME CS:DOSGROUP,DS:DOSGROUP,ES:DOSGROUP,SS:NOTHING
13
14 EXTRN QUIT:NEAR,IRET:NEAR,ABSDRD:FAR,ABSDWRT:FAR
15 EXTRN COMMAND:NEAR,CALL_ENTRY:NEAR
16 IF NOT IBM
17 EXTRN HEADER:BYTE
18 ENDIF
19
20MOVDPB:
21; This section of code is safe from being overwritten by block move
22 MOV SP,CS:[INITSP]
23 MOV SS,CS:[INITSS]
24 REP MOVS BYTE PTR [DI],[SI]
25 CLD
26 MOV WORD PTR ES:[DMAADD+2],DX
27 MOV SI,WORD PTR [DPBHEAD] ; Address of first DPB
28 MOV WORD PTR ES:[DPBHEAD+2],ES
29 MOV WORD PTR ES:[sft_addr+2],ES
30 MOV CL,[NUMIO] ; Number of DPBs
31 XOR CH,CH
32SETFINDPB:
33 MOV WORD PTR ES:[SI.dpb_next_dpb+2],ES
34 MOV ES:[SI.dpb_first_access],-1 ; Never accessed before
35 ADD SI,DPBSIZ ; Point to next DPB
36 LOOP SETFINDPB
37 SUB SI,DPBSIZ
38 MOV WORD PTR ES:[SI.dpb_next_dpb+2],-1
39 MOV DI,[BUFFSTRT] ; Set up one default buffer
40 MOV WORD PTR ES:[BUFFHEAD+2],ES
41 MOV WORD PTR ES:[BUFFHEAD],DI
42 MOV WORD PTR ES:[DI.BUFDRV],00FFH
43 MOV ES:[DI.BUFPRI],FREEPRI
44 MOV WORD PTR ES:[DI.NEXTBUF],-1
45 MOV WORD PTR ES:[DI.NEXTBUF+2],-1
46 PUSH ES
47 INC DX ; Leave enough room for the ARENA
48 MOV BYTE PTR [CreatePDB],0FFh ; create jfns and set CurrentPDB
49 invoke $CREATE_PROCESS_DATA_BLOCK ; Set up segment
50ASSUME DS:NOTHING,ES:NOTHING
51 POP ES
52ASSUME ES:DOSGROUP
53
54;
55; set up memory arena
56;SPECIAL NOTE FOR HIGHMEM VERSION
57; At this point a process header has been built where the start of the
58; CONSTANTS segment as refed by CS is. From this point until the return
59; below be careful about references off of CS.
60;
61 PUSH AX
62 MOV AX,[CurrentPDB]
63 MOV ES:[CurrentPDB],AX ; Put it in the REAL location
64 MOV BYTE PTR ES:[CreatePDB],0h ; reset flag in REAL location
65 DEC AX
66 MOV ES:[arena_head],AX
67 PUSH DS
68 MOV DS,AX
69 MOV DS:[arena_signature],arena_signature_end
70 MOV DS:[arena_owner],arena_owner_system
71 SUB AX,ES:[ENDMEM]
72 NEG AX
73 DEC AX
74 MOV DS:[arena_size],AX
75 POP DS
76 POP AX
77
78 MOV DI,OFFSET DOSGROUP:sftabl + sft_table ; Point to sft 0
79 MOV AL,3
80 STOSB ; Adjust Refcount
81 MOV DI,OFFSET DOSGROUP:SYSINITVAR
82
83XXX PROC FAR
84 RET
85XXX ENDP
86DATA ENDS
87
88; the next segment defines a new class that MUST appear last in the link map.
89; This defines several important locations for the initialization process that
90; must be the first available locations of free memory.
91
92LAST SEGMENT BYTE PUBLIC 'LAST'
93 PUBLIC SYSBUF
94 PUBLIC MEMSTRT
95
96SYSBUF LABEL WORD
97ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
98
99DOSINIT:
100 CLI
101 CLD
102 MOV [ENDMEM],DX
103 MOV [INITSP],SP
104 MOV [INITSS],SS
105 MOV SP,OFFSET DOSGROUP:INITSTACK
106 MOV AX,CS
107 MOV SS,AX
108ASSUME SS:DOSGROUP
109 MOV WORD PTR [DEVHEAD+2],DS
110 MOV WORD PTR [DEVHEAD],SI ; DS:SI Points to CONSOLE Device
111 CALL CHARINIT
112 PUSH SI
113 ADD SI,SDEVNAME ; Point to name
114 PUSH CS
115 POP ES
116ASSUME ES:DOSGROUP
117 MOV DI,OFFSET DOSGROUP:sftabl + sft_table ; Point to sft 0
118 MOV AL,3
119 STOSB ; Refcount
120 DEC AL
121 STOSB ; Access rd/wr
122 XOR AL,AL
123 STOSB ; Drive byte
124 STOSB ; attribute
125 MOV CX,4
126 REP MOVSW ; Name
127 MOV CL,3
128 MOV AL," "
129 REP STOSB ; Extension
130 ADD DI,12 ; Skip
131 MOV AL,0C0H OR ISCIN OR ISCOUT
132 STOSB
133 POP SI
134 MOV AX,SI
135 STOSW ; Device pointer in FIRCLUS
136 MOV AX,DS
137 STOSW
138 OR BYTE PTR [SI.SDEVATT],ISCIN OR ISCOUT
139 MOV WORD PTR [BCON],SI
140 MOV WORD PTR [BCON+2],DS
141CHAR_INIT_LOOP:
142 LDS SI,DWORD PTR [SI] ; AUX device
143 CALL CHARINIT
144 TEST BYTE PTR [SI.SDEVATT],ISCLOCK
145 JZ CHAR_INIT_LOOP
146 MOV WORD PTR [BCLOCK],SI
147 MOV WORD PTR [BCLOCK+2],DS
148 MOV BP,OFFSET DOSGROUP:MEMSTRT ; ES:BP points to DPB
149PERDRV:
150 LDS SI,DWORD PTR [SI] ; Next device
151 CMP SI,-1
152 JZ CONTINIT
153 CALL CHARINIT
154 TEST [SI.SDEVATT],DEVTYP
155 JNZ PERDRV ; Skip any other character devs
156 MOV CL,[CALLUNIT]
157 XOR CH,CH
158 MOV [SI.SDEVNAME],CL ; Number of units in name field
159 MOV DL,[NUMIO]
160 XOR DH,DH
161 ADD [NUMIO],CL
162 PUSH DS
163 PUSH SI
164 LDS BX,[CALLBPB]
165PERUNIT:
166 MOV SI,[BX] ; DS:SI Points to BPB
167 INC BX
168 INC BX ; On to next BPB
169 MOV ES:[BP.dpb_drive],DL
170 MOV ES:[BP.dpb_UNIT],DH
171 PUSH BX
172 PUSH CX
173 PUSH DX
174 invoke $SETDPB
175 MOV AX,ES:[BP.dpb_sector_size]
176 CMP AX,[MAXSEC]
177 JBE NOTMAX
178 MOV [MAXSEC],AX
179NOTMAX:
180 POP DX
181 POP CX
182 POP BX
183 MOV AX,DS ; Save DS
184 POP SI
185 POP DS
186 MOV WORD PTR ES:[BP.dpb_driver_addr],SI
187 MOV WORD PTR ES:[BP.dpb_driver_addr+2],DS
188 PUSH DS
189 PUSH SI
190 INC DH
191 INC DL
192 MOV DS,AX
193 ADD BP,DPBSIZ
194 LOOP PERUNIT
195 POP SI
196 POP DS
197 JMP PERDRV
198
199CONTINIT:
200 PUSH CS
201 POP DS
202ASSUME DS:DOSGROUP
203; Calculate true address of buffers, FATs, free space
204 MOV DI,BP ; First byte after current DPBs
205 MOV BP,[MAXSEC]
206 MOV AX,OFFSET DOSGROUP:SYSBUF
207 MOV [BUFFSTRT],AX
208 ADD AX,BP ; One I/O buffer
209 ADD AX,BUFINSIZ
210 MOV WORD PTR [DPBHEAD],AX ; True start of DPBs
211 MOV DX,AX
212 SUB DX,OFFSET DOSGROUP:SYSBUF
213 MOV BP,DX
214 ADD BP,DI ; Allocate buffer space
215 SUB BP,ADJFAC ; True address of free memory
216 PUSH BP
217 MOV DI,OFFSET DOSGROUP:MEMSTRT ; Current start of DPBs
218 ADD DI,dpb_next_dpb ; Point at dpb_next_dpb field
219 MOV CL,[NUMIO]
220 XOR CH,CH
221TRUEDPBAD:
222 ADD AX,DPBSIZ ; Compute address of next DPB
223 STOSW ; Set the link to next DPB
224 ADD DI,DPBSIZ-2 ; Point at next address
225 LOOP TRUEDPBAD
226 SUB DI,DPBSIZ ; Point at last dpb_next_dpb field
227 MOV AX,-1
228 STOSW ; End of list
229 ADD BP,15 ;True start of free space (round up to segment)
230 MOV CL,4
231 SHR BP,CL ; Number of segments for DOS resources
232 MOV DX,CS
233 ADD DX,BP ; First free segment
234 MOV BX,0FH
235 MOV CX,[ENDMEM]
236
237 IF HIGHMEM
238 SUB CX,BP
239 MOV BP,CX ; Segment of DOS
240 MOV DX,CS ; Program segment
241 ENDIF
242
243 IF NOT HIGHMEM
244 MOV BP,CS
245 ENDIF
246
247; BP has segment of DOS (whether to load high or run in place)
248; DX has program segment (whether after DOS or overlaying DOS)
249; CX has size of memory in paragraphs (reduced by DOS size if HIGHMEM)
250 MOV [ENDMEM],CX
251 MOV ES,BP
252ASSUME ES:DOSGROUP
253
254 IF HIGHMEM
255 XOR SI,SI
256 MOV DI,SI
257 MOV CX,OFFSET DOSGROUP:SYSBUF ;# bytes to move
258 SHR CX,1 ;# words to move (carry set if odd)
259 REP MOVSW ; Move DOS to high memory
260 JNC NOTODD
261 MOVSB
262NOTODD:
263 ENDIF
264
265 MOV WORD PTR ES:[DSKCHRET+3],ES
266 XOR AX,AX
267 MOV DS,AX
268 MOV ES,AX
269ASSUME DS:NOTHING,ES:NOTHING
270 MOV DI,INTBASE+2
271 MOV AX,BP
272 MOV BYTE PTR DS:[ENTRYPOINT],mi_Long_JMP
273 MOV WORD PTR DS:[ENTRYPOINT+1],OFFSET DOSGROUP:CALL_ENTRY
274 MOV WORD PTR DS:[ENTRYPOINT+3],AX
275 EXTRN DIVOV:near
276 MOV WORD PTR DS:[0],OFFSET DOSGROUP:DIVOV ; Set default divide
277 ; trap address
278 MOV DS:[2],AX
279 MOV CX,17
280 REP STOSW ; Set 9 segments (skip 2 between each)
281
282 IF ALTVECT
283 MOV DI,ALTBASE+2
284 MOV CX,15
285 REP STOSW ; Set 8 segments (skip 2 between each)
286 ENDIF
287
288 MOV WORD PTR DS:[addr_int_abort],OFFSET DOSGROUP:QUIT
289 MOV WORD PTR DS:[addr_int_command],OFFSET DOSGROUP:COMMAND
290 MOV WORD PTR DS:[addr_int_terminate],100H
291 MOV WORD PTR DS:[addr_int_terminate+2],DX
292 MOV WORD PTR DS:[addr_int_ctrl_c],OFFSET DOSGROUP:IRET
293 ; Ctrl-C exit
294 MOV WORD PTR DS:[addr_int_fatal_abort],OFFSET DOSGROUP:IRET
295 ; Fatal error exit
296 MOV WORD PTR DS:[addr_int_disk_read],OFFSET DOSGROUP:ABSDRD
297 ; INT 25
298 MOV WORD PTR DS:[addr_int_disk_write],OFFSET DOSGROUP:ABSDWRT
299 ; INT 26
300 EXTRN Stay_resident:NEAR
301 MOV WORD PTR DS:[addr_int_keep_process],OFFSET DOSGROUP:Stay_resident
302 MOV WORD PTR DS:[addr_int_spooler],OFFSET DOSGROUP:IRET ; Spooler
303
304 IF NOT ALTVECT
305 MOV CX,12
306 XOR AX,AX
307 MOV DI,2AH*4
308 REP STOSW ;Zero interrupt locs for ints 2AH-2FH
309 ENDIF
310
311 PUSH CS
312 POP DS
313 PUSH CS
314 POP ES
315ASSUME DS:DOSGROUP,ES:DOSGROUP
316 MOV AX,OFFSET DOSGROUP:INITBLOCK
317 ADD AX,0Fh ; round to a paragraph
318 MOV CL,4
319 SHR AX,CL
320 MOV DI,DS
321 ADD DI,AX
322 INC DI
323 MOV [CurrentPDB],DI
324 PUSH BP
325 PUSH DX ; Save COMMAND address
326 MOV AX,[ENDMEM]
327 MOV DX,DI
328
329 invoke SETMEM ; Basic Header
330ASSUME DS:NOTHING,ES:NOTHING
331 PUSH CS
332 POP DS
333ASSUME DS:DOSGROUP
334 MOV DI,PDB_JFN_Table
335 XOR AX,AX
336 STOSW
337 STOSB ; 0,1 and 2 are CON device
338 MOV AL,0FFH
339 MOV CX,FilPerProc - 3
340 REP STOSB ; Rest are unused
341 PUSH CS
342 POP ES
343ASSUME ES:DOSGROUP
344 MOV WORD PTR [sft_addr+2],DS ; Must be set to print messages
345
346; After this points the char device functions for CON will work for
347; printing messages
348
349 IF NOT IBM
350 IF NOT ALTVECT
351 MOV SI,OFFSET DOSGROUP:HEADER
352 invoke OUTMES
353 PUSH CS ; Outmes stomps on segments
354 POP DS
355 PUSH CS
356 POP ES
357 ENDIF
358 ENDIF
359
360; Move the FATs into position
361 POP DX ; Restore COMMAND address
362 POP BP
363 POP CX ; True address of free memory
364 MOV SI,OFFSET DOSGROUP:MEMSTRT ; Place to move DPBs from
365 MOV DI,WORD PTR [DPBHEAD] ; Place to move DPBs to
366 SUB CX,DI ; Total length of DPBs
367 CMP DI,SI
368 JBE MOVJMP ; Are we moving to higher or
369 ; lower memory?
370 DEC CX ; Move backwards to higher memory
371 ADD DI,CX
372 ADD SI,CX
373 INC CX
374 STD
375MOVJMP:
376 MOV ES,BP
377ASSUME ES:DOSGROUP
378 JMP MOVDPB
379
380CHARINIT:
381ASSUME DS:NOTHING,ES:NOTHING
382; DS:SI Points to device header
383 MOV [DEVCALL.REQLEN],DINITHL
384 MOV [DEVCALL.REQUNIT],0
385 MOV [DEVCALL.REQFUNC],DEVINIT
386 MOV [DEVCALL.REQSTAT],0
387 PUSH ES
388 PUSH BX
389 PUSH AX
390 MOV BX,OFFSET DOSGROUP:DEVCALL
391 PUSH CS
392 POP ES
393 invoke DEVIOCALL2
394 POP AX
395 POP BX
396 POP ES
397 RET
398
399 DB 80H DUP(?)
400INITSTACK LABEL BYTE
401 DW ?
402
403MEMSTRT LABEL WORD
404ADJFAC EQU MEMSTRT-SYSBUF
405
406 do_ext
407LAST ENDS
408 \ No newline at end of file
diff --git a/v2.0/source/PCLOCK.ASM b/v2.0/source/PCLOCK.ASM
new file mode 100644
index 0000000..6018bfd
--- /dev/null
+++ b/v2.0/source/PCLOCK.ASM
Binary files differ
diff --git a/v2.0/source/PRINT.ASM b/v2.0/source/PRINT.ASM
new file mode 100644
index 0000000..dd58735
--- /dev/null
+++ b/v2.0/source/PRINT.ASM
@@ -0,0 +1,1645 @@
1;MS-DOS PRINT program for background printing of text files to the list
2; device. INT 28H is a software interrupt generated by the DOS
3; in its I/O wait loops. This spooler can be assembled for
4; operation using only this interrupt which is portable from
5; system to system. It may also be assembled to use a hardware
6; timer interrupt in addition to the software INT 28H. The
7; purpose of using hardware interrupts is to allow printing to
8; continue during programs which do not enter the system and
9; therefore causes the INT 28H to go away. A timer interrupt is
10; chosen in preference to a "printer buffer empty" interrupt
11; because PRINT in the timer form is generic. It can be given
12; the name of any currently installed character device as the
13; "printer", this makes it portable to devices which are
14; installed by the user even in the hardware case. It could be
15; modified to use a buffer empty interrupt (no code is given for
16; this case), if this is done the PROMPT and BADMES messages and
17; their associated code should be removed as PRINT will then be
18; device specific.
19;
20; VERSION 1.00 07/03/82
21
22
23FALSE EQU 0
24TRUE EQU NOT FALSE
25
26IBM EQU FALSE
27IBMVER EQU IBM
28MSVER EQU TRUE
29
30 IF MSVER
31HARDINT EQU FALSE ;No hardware ints
32AINT EQU FALSE ;No need to do interrupt acknowledge
33 ENDIF
34
35 IF IBM
36HARDINT EQU TRUE
37INTLOC EQU 1CH ;Hardware interrupt location (Timer)
38AINT EQU TRUE ;Acknowledge interrupts
39EOI EQU 20H ;End Of Interrupt "instruction"
40AKPORT EQU 20H ;Interrupt Acknowledge port
41 ENDIF
42
43;The following values have to do with the ERRCNT variable and the
44; CNTMES message. The values define levels at wich it is assumed
45; an off-line error exists. ERRCNT1 defines the value of ERRCNT above
46; which the CNTMES message is printed by the transient. ERRCNT2
47; defines the value of ERRCNT above which the resident will give up
48; trying to print messages on the printer, it is much greater than
49; ERRCNT1 because a much tighter loop is involved. The bounding event
50; which determines the correct value is the time required to do a
51; form feed.
52
53 IF IBM
54ERRCNT1 EQU 1000
55ERRCNT2 EQU 20000
56 ELSE
57ERRCNT1 EQU 1000
58ERRCNT2 EQU 20000
59 ENDIF
60
61 IF HARDINT
62TIMESLICE EQU 8 ;The PRINT scheduling time slice. PRINT
63 ; lets this many "ticks" go by before
64 ; using a time slice to pump out characters.
65 ; Setting this to 3 for instance means PRINT
66 ; Will skip 3 slices, then take the fourth.
67 ; Thus using up 1/4 of the CPU. Setting it
68 ; to one gives PRINT 1/2 of the CPU.
69 ; The above examples assume MAXTICK is
70 ; 1. The actual PRINT CPU percentage is
71 ; (MAXTICK/(1+TIMESLICE))*100
72
73MAXTICK EQU 2 ;The PRINT in timeslice. PRINT will pump
74 ; out characters for this many clock ticks
75 ; and then exit. The selection of a value
76 ; for this is dependent on the timer rate.
77
78BUSYTICK EQU 1 ;If PRINT sits in a wait loop waiting for
79 ; output device to come ready for this
80 ; many ticks, it gives up its time slice.
81 ; Setting it greater than or equal to
82 ; MAXTICK causes it to be ignored.
83
84;User gets TIMESLICE ticks and then PRINT takes MAXTICK ticks unless BUSYTICK
85; ticks go by without getting a character out.
86 ENDIF
87
88
89;WARNING DANGER WARNING:
90; PRINT is a systems utility. It is clearly understood that it may have
91; to be entirely re-written for future versions of MS-DOS. The following
92; TWO vectors are version specific, they may not exist at all in future
93; versions. If they do exist, they may function differently.
94; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS
95; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM.
96; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON
97; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS.
98SOFTINT EQU 28H ;Software interrupt generated by DOS
99COMINT EQU 2FH ;Communications interrupt used by PRINT
100 ; This vector number is DOS reserved. It
101 ; is not generally available to programs
102 ; other than PRINT.
103
104BLKSIZ EQU 512 ;Size of the PRINT I/O block in bytes
105FCBSIZ EQU 40 ;Size of an FCB
106
107 INCLUDE DOST:DOSSYM.ASM
108
109FCB EQU 5CH
110PARMS EQU 80H
111
112DG GROUP CODE,DATA
113
114CODE SEGMENT
115ASSUME CS:DG
116
117 ORG 100H
118START:
119 JMP TRANSIENT
120
121HEADER DB "Vers 1.00"
122
123 DB 128 DUP (?)
124ISTACK LABEL WORD ;Stack starts here and grows down
125
126;Resident data
127
128 IF HARDINT
129INDOS DD ? ;DOS buisy flag
130NEXTINT DD ? ;Chain for int
131BUSY DB 0 ;Internal ME flag
132SOFINT DB 0 ;Internal ME flag
133TICKCNT DB 0 ;Tick counter
134TICKSUB DB 0 ;Tick miss counter
135SLICECNT DB TIMESLICE ;Time slice counter
136 ENDIF
137
138CBUSY DB 0 ;ME on com interrupt
139SPNEXT DD ? ;Chain location for INT 28
140PCANMES DB 0 ;Cancel message flag
141SSsave DW ? ;Stack save area for INT 24
142SPsave DW ?
143DMAADDR DD ? ;Place to save DMA address
144HERRINT DD ? ;Place to save Hard error interrupt
145LISTDEV DD ? ;Pointer to Device
146COLPOS DB 0 ;Column position for TAB processing
147NXTCHR DW OFFSET DG:BUFFER + BLKSIZ ;Buffer pointer
148CURRFIL DW OFFSET DG:SPLFCB ;Current file being printed
149
150LASTFCB DW ? ;Back pointer
151LASTFCB2 DW ? ;Another back pointer
152PABORT DB 0 ;Abort flag
153
154;Resident messages
155
156ERRMES DB 13,10,13,10,"**********",13,10,"$"
157ERRMEST DB " error reading file",13,10
158EMFILNAM DB " : . "
159BELMES DB 13,0CH,7,"$"
160
161CANMES DB 13,10,13,10
162CANFILNAM DB " : . "
163 DB " Canceled by operator$"
164
165ALLCAN DB 13,10,13,10,"All files canceled by operator$"
166
167MESBAS DW OFFSET DG:ERR0
168 DW OFFSET DG:ERR1
169 DW OFFSET DG:ERR2
170 DW OFFSET DG:ERR3
171 DW OFFSET DG:ERR4
172 DW OFFSET DG:ERR5
173 DW OFFSET DG:ERR6
174 DW OFFSET DG:ERR7
175 DW OFFSET DG:ERR8
176 DW OFFSET DG:ERR9
177 DW OFFSET DG:ERR10
178 DW OFFSET DG:ERR11
179 DW OFFSET DG:ERR12
180
181;INT 24 messages A La COMMAND
182
183ERR0 DB "Write protect$"
184ERR1 DB "Bad unit$"
185ERR2 DB "Not ready$"
186ERR3 DB "Bad command$"
187ERR4 DB "Data$"
188ERR5 DB "Bad call format$"
189ERR6 DB "Seek$"
190ERR7 DB "Non-DOS disk$"
191ERR8 DB "Sector not found$"
192ERR9 DB "No paper$"
193ERR10 DB "Write fault$"
194ERR11 DB "Read fault$"
195ERR12 DB "Disk$"
196
197FATMES DB "File allocation table bad drive "
198BADDRVM DB "A.",13,10,"$"
199
200;The DATA buffer
201BUFFER DB BLKSIZ DUP(0)
202 DB ?
203CODE ENDS
204
205;Transient data
206
207DATA SEGMENT BYTE
208 ORG 0
209SWITCHAR DB ? ;User switch character
210FULLFLAG DB 0 ;Flag for printing queue full message
211MAKERES DB 0 ;Flag to indicate presence of resident
212ARGSETUP DB 0 ;Flag to indicate a formatted FCB exists at 5C
213DEFDRV DB 0 ;Default drive
214CANFLG DB 0 ;Flag to indicate cancel
215FILCNT DB 0 ;Number of files
216SPLIST DD ? ;Pointer to FCBs in resident
217CURFILE DD ? ;Pointer to current FCB
218SRCHFCB DB 38 DUP (0) ;SEARCH-FIRST/NEXT FCB
219ENDRES DW OFFSET DG:DEF_ENDRES ;Term-Res location
220
221;Messages
222
223NOFILS DB "PRINT queue is empty",13,10,"$"
224CURMES DB 13,10," "
225CURFNAM DB " : . is currently being printed",13,10,"$"
226FILMES DB " "
227FILFNAM DB " : . is in queue"
228CRLF DB 13,10,"$"
229OPMES DB "Cannot open "
230OPFILNAM DB " : . ",13,10,"$"
231FULLMES DB "PRINT queue is full",13,10,"$"
232SRCHMES LABEL BYTE
233SRCHFNAM DB " : . "," File not found",13,10,"$"
234BADMES DB "List output is not assigned to a device",13,10,"$"
235GOODMES DB "Resident part of PRINT installed",13,10,"$"
236PROMPT DB "Name of list device [PRN]: $"
237CNTMES DB "Errors on list device indicate that it",13,10
238 DB "may be off-line. Please check it.",13,10,13,10,"$"
239BADSWT DB "Invalid parameter",13,10,"$"
240
241
242BADVER DB "Incorrect DOS version",13,10,"$"
243
244 IF IBM
245;Reserved names for parallel card
246INT_17_HITLIST LABEL BYTE
247 DB 8,"PRN ",0
248 DB 8,"LPT1 ",0
249 DB 8,"LPT2 ",1
250 DB 8,"LPT3 ",2
251 DB 0
252;Reserved names for Async adaptor
253INT_14_HITLIST LABEL BYTE
254 DB 8,"AUX ",0
255 DB 8,"COM1 ",0
256 DB 8,"COM2 ",1
257 DB 0
258 ENDIF
259
260COMBUF DB 14,0 ;Device name buffer
261 DB 14 DUP (?)
262LISTFCB DB 0,"PRN " ;Device name FCB
263 DB 25 DUP (0)
264PARSEBUF DB 80 DUP (?) ;Parsing space
265
266DATA ENDS
267
268CODE SEGMENT
269ASSUME CS:DG,DS:DG,ES:DG,SS:DG
270
271
272;Interrupt routines
273ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:NOTHING
274 IF HARDINT
275HDSPINT: ;Hardware interrupt entry point
276 INC [TICKCNT] ;Tick
277 INC [TICKSUB] ;Tick
278 CMP [SLICECNT],0
279 JZ TIMENOW
280 DEC [SLICECNT] ;Count down
281 JMP SHORT CHAININT ;Not time yet
282TIMENOW:
283 CMP [BUSY],0 ;See if interrupting ourself
284 JNZ CHAININT
285 PUSH DS
286 PUSH SI
287 LDS SI,[INDOS] ;Check for making DOS calls
288 CMP BYTE PTR [SI],0
289 POP SI
290 POP DS
291 JNZ CHAININT ;DOS is Buisy
292 INC [BUSY] ;Exclude furthur interrupts
293 MOV [TICKCNT],0 ;Reset tick counter
294 MOV [TICKSUB],0 ;Reset tick counter
295 STI ;Keep things rolling
296
297 IF AINT
298 MOV AL,EOI ;Acknowledge interrupt
299 OUT AKPORT,AL
300 ENDIF
301
302 CALL DOINT
303 CLI
304 MOV [SLICECNT],TIMESLICE ;Either soft or hard int resets time slice
305 MOV [BUSY],0 ;Done, let others in
306CHAININT:
307 JMP [NEXTINT] ;Chain to next clock routine
308 ENDIF
309
310
311SPINT: ;INT 28H entry point
312 IF HARDINT
313 CMP [BUSY],0
314 JNZ NXTSP
315 INC [BUSY] ;Exclude hardware interrupt
316 INC [SOFINT] ;Indicate a software int in progress
317 ENDIF
318
319 STI ;Hardware interrupts ok on INT 28H entry
320 CALL DOINT
321
322 IF HARDINT
323 CLI
324 MOV [SOFINT],0 ;Indicate INT done
325 MOV [SLICECNT],TIMESLICE ;Either soft or hard int resets time slice
326 MOV [BUSY],0
327 ENDIF
328
329NXTSP: JMP [SPNEXT] ;Chain to next INT 28
330
331DOINT:
332 PUSH SI
333 MOV SI,[CURRFIL]
334 INC SI
335 INC SI
336 CMP BYTE PTR CS:[SI],-1
337 POP SI
338 JNZ GOAHEAD
339 JMP SPRET ;Nothing to do
340GOAHEAD:
341 PUSH AX ;Need a working register
342 MOV [SSsave],SS
343 MOV [SPsave],SP
344 MOV AX,CS
345 CLI
346;Go to internal stack to prevent INT 24 overflowing system stack
347 MOV SS,AX
348 MOV SP,OFFSET DG:ISTACK
349 STI
350 PUSH ES
351 PUSH DS
352 PUSH BX
353 PUSH CX
354 PUSH DX
355 PUSH SI
356 PUSH DI
357 PUSH CS
358 POP DS
359ASSUME DS:DG
360
361 MOV BX,[NXTCHR]
362 CMP BX,OFFSET DG:BUFFER + BLKSIZ
363 JNZ PLOOP
364 JMP READBUFF ;Buffer empty
365
366PLOOP:
367 IF HARDINT
368 MOV BX,[NXTCHR]
369 CMP BX,OFFSET DG:BUFFER + BLKSIZ
370 JZ DONEJMP ;Buffer has become empty
371 CMP [SOFINT],0
372 JNZ STATCHK
373 CMP [TICKCNT],MAXTICK ;Check our time slice
374 JAE DONEJMP
375STATCHK:
376 ENDIF
377
378 CALL PSTAT
379
380 IF HARDINT
381 JZ DOCHAR ;Printer ready
382 CMP [SOFINT],0
383 ENDIF
384
385 JNZ DONEJMP ;If soft int give up
386
387 IF HARDINT
388 CMP [TICKSUB],BUSYTICK ;Check our busy timeout
389 JAE DONEJMP
390 JMP PLOOP
391 ENDIF
392
393DOCHAR:
394 MOV AL,BYTE PTR [BX]
395 CMP AL,1AH ;^Z?
396 JZ FILEOFJ ;CPM EOF
397 CMP AL,0DH ;CR?
398 JNZ NOTCR
399 MOV [COLPOS],0
400NOTCR:
401 CMP AL,9 ;TAB?
402 JNZ NOTABDO
403 MOV CL,[COLPOS]
404 OR CL,0F8H
405 NEG CL
406 XOR CH,CH
407 JCXZ TABDONE
408TABLP:
409 MOV AL," "
410 INC [COLPOS]
411 PUSH CX
412 CALL POUT
413 POP CX
414 LOOP TABLP
415 JMP TABDONE
416
417NOTABDO:
418 CMP AL,8 ;Back space?
419 JNZ NOTBACK
420 DEC [COLPOS]
421NOTBACK:
422 CMP AL,20H ;Non Printing char?
423 JB NOCHAR
424 INC [COLPOS] ;Printing char
425NOCHAR:
426 CALL POUT ;Print it
427TABDONE:
428 INC [NXTCHR] ;Next char
429
430 IF HARDINT
431 MOV [TICKSUB],0 ;Got a character out, Reset counter
432 CMP [SOFINT],0 ;Soft int does one char at a time
433 JZ PLOOP
434 ENDIF
435
436DONEJMP:
437 POP DI
438 POP SI
439 POP DX
440 POP CX
441 POP BX
442 POP DS
443 POP ES
444ASSUME DS:NOTHING,ES:NOTHING
445 CLI
446 MOV SS,[SSsave] ;Restore Entry Stack
447 MOV SP,[SPsave]
448 STI
449 POP AX
450SPRET:
451 RET
452
453FILEOFJ: JMP FILEOF
454
455READBUFF:
456ASSUME DS:DG,ES:NOTHING
457
458 MOV AL,24H
459 MOV AH,GET_INTERRUPT_VECTOR
460 INT 21H
461 MOV WORD PTR [HERRINT+2],ES ;Save current vector
462 MOV WORD PTR [HERRINT],BX
463 MOV DX,OFFSET DG:DSKERR
464 MOV AL,24H
465 MOV AH,SET_INTERRUPT_VECTOR ;Install our own
466 INT 21H ;Spooler must catch its errors
467 MOV AH,GET_DMA
468 INT 21H
469 MOV WORD PTR [DMAADDR+2],ES ;Save DMA address
470 MOV WORD PTR [DMAADDR],BX
471 MOV DX,OFFSET DG:BUFFER
472 MOV AH,SET_DMA
473 INT 21H ;New DMA address
474 MOV [PABORT],0 ;No abort
475 MOV DX,[CURRFIL] ;Read
476 INC DX
477 INC DX ;Skip over pointer
478 MOV AH,FCB_SEQ_READ
479 INT 21H
480 PUSH AX
481 LDS DX,[DMAADDR]
482ASSUME DS:NOTHING
483 MOV AH,SET_DMA
484 INT 21H ;Restore DMA
485 LDS DX,[HERRINT]
486 MOV AL,24H
487 MOV AH,SET_INTERRUPT_VECTOR
488 INT 21H ;Restore Error INT
489 POP AX
490 PUSH CS
491 POP DS
492ASSUME DS:DG
493 CMP [PABORT],0
494 JNZ TONEXTFIL ;Barf on this file, got INT 24
495 CMP AL,01
496 JZ FILEOF ;Read EOF?
497 MOV BX,OFFSET DG:BUFFER ;Buffer full
498 MOV [NXTCHR],BX
499 JMP DONEJMP
500
501FILEOF:
502 MOV AL,0CH ;Form feed
503 CALL LOUT
504TONEXTFIL:
505 CALL NEXTFIL
506 JMP DONEJMP
507
508;INT 24 handler
509
510DSKERR:
511ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
512 STI
513 CMP [PABORT],0
514 JNZ IGNRET
515 PUSH BX
516 PUSH CX
517 PUSH DX
518 PUSH DI
519 PUSH SI
520 PUSH BP
521 PUSH ES
522 PUSH DS
523 PUSH CS
524 POP DS
525 PUSH CS
526 POP ES
527ASSUME DS:DG,ES:DG
528 ADD [BADDRVM],AL ;Set correct drive letter
529 MOV SI,OFFSET DG:ERRMES
530 CALL LISTMES
531 TEST AH,080H
532 JNZ FATERR
533 AND DI,0FFH
534 CMP DI,12
535 JBE HAVCOD
536 MOV DI,12
537HAVCOD:
538 SHL DI,1
539 MOV DI,WORD PTR [DI+MESBAS] ; Get pointer to error message
540 MOV SI,DI
541 CALL LISTMES ; Print error type
542 MOV DI,OFFSET DG:EMFILNAM
543 MOV SI,[CURRFIL]
544 ADD SI,2 ;Get to file name
545 LODSB
546 ADD AL,'@'
547 STOSB
548 INC DI
549 MOV CX,4
550 REP MOVSW
551 INC DI
552 MOVSW
553 MOVSB
554 MOV SI,OFFSET DG:ERRMEST
555 CALL LISTMES
556SETABORT:
557 INC [PABORT] ;Indicate abort
558 POP DS
559 POP ES
560 POP BP
561 POP SI
562 POP DI
563 POP DX
564 POP CX
565 POP BX
566IGNRET:
567 XOR AL,AL ;Ignore
568 IRET
569
570FATERR:
571 MOV SI,OFFSET DG:FATMES
572 CALL LISTMES
573 JMP SHORT SETABORT
574
575ADDFILJ: JMP ADDFIL
576
577COMBUSY:
578 MOV AX,-1
579 IRET
580
581;Communications interrupt
582SPCOMINT:
583ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
584 CMP [CBUSY],0
585 JNZ COMBUSY
586 INC [CBUSY] ;Exclude
587 STI ;Turn ints back on
588 PUSH SI
589 PUSH DI
590 PUSH CX
591 PUSH DS
592 PUSH CS
593 POP DS
594ASSUME DS:DG
595 MOV [PCANMES],0 ;Havn't printed cancel message
596 OR AH,AH
597 JZ ADDFILJ ;Add file
598 CMP AH,1
599 JZ CANFIL ;Cancel File(s)
600 XOR AL,AL
601SETCOUNT:
602 PUSH AX ;Save AL return code
603 XOR AH,AH
604 MOV SI,OFFSET DG:SPLFCB
605 MOV CX,[NUMFCBS]
606CNTFILS:
607 CMP BYTE PTR [SI+2],-1 ;Valid?
608 JZ LNEXT
609 INC AH
610LNEXT:
611 ADD SI,FCBSIZ
612 LOOP CNTFILS
613COMRET:
614 MOV BX,OFFSET DG:SPLFCB
615 MOV DX,[CURRFIL]
616 PUSH DS
617 POP ES
618ASSUME ES:NOTHING
619 MOV CH,AH
620 POP AX ;Get AL return
621 MOV AH,CH
622
623 IF HARDINT
624BWAIT3:
625 CMP [BUSY],0
626 JNZ BWAIT3
627 INC [BUSY]
628 ENDIF
629
630 CALL PSTAT ; Tweek error counter
631
632 IF HARDINT
633 MOV [BUSY],0
634 ENDIF
635
636 POP DS
637ASSUME DS:NOTHING
638 POP CX
639 POP DI
640 POP SI
641 MOV [CBUSY],0
642 IRET
643
644DELALLJ: JMP DELALL
645
646CANFIL:
647ASSUME DS:DG,ES:NOTHING
648 MOV CX,[NUMFCBS]
649
650 IF HARDINT
651BWAIT:
652 CMP [BUSY],0
653 JNZ BWAIT
654 INC [BUSY]
655 ENDIF
656
657 MOV SI,[CURRFIL]
658 CMP DX,-1
659 JZ DELALLJ
660 MOV BX,[SI]
661 PUSH BX
662LOOKEND: ;Set initial pointer values
663 CMP BX,SI
664 JZ GOTLAST
665 POP AX
666 PUSH BX
667 MOV BX,[BX]
668 JMP SHORT LOOKEND
669
670GOTLAST:
671 POP BX
672 MOV [LASTFCB],BX
673 MOV [LASTFCB2],BX
674 POP ES
675 PUSH ES
676 MOV BX,SI
677LOOKMATCH:
678 MOV DI,DX
679 ADD SI,2 ;Skip pointer
680 CMP BYTE PTR [SI],-1
681 JZ CANTERMJ ;No more
682 CMPSB
683 JNZ SKIPFIL ;DRIVE
684 PUSH CX
685 MOV CX,11
686NXTCHAR:
687 MOV AL,ES:[DI]
688 INC DI
689 CALL UPCONV
690 MOV AH,AL
691 LODSB
692 CALL UPCONV
693 CMP AH,"?" ;Wild card?
694 JZ NXTCHRLP ;Yes
695 CMP AH,AL
696 JNZ SKIPFILC
697NXTCHRLP:
698 LOOP NXTCHAR
699MATCH:
700 POP CX
701 MOV AH,-1
702 XCHG AH,[BX+2] ;Zap it
703 CMP BX,[CURRFIL] ;Is current file?
704 JNZ REQUEUE ;No
705 MOV AL,1
706 XCHG AL,[PCANMES]
707 OR AL,AL
708 JNZ DIDCMES ;Only print cancel message once
709 PUSH ES
710 PUSH CS
711 POP ES
712 MOV DI,OFFSET DG:CANFILNAM
713 MOV SI,BX
714 ADD SI,3 ;Get to file name
715 MOV AL,AH
716 ADD AL,'@'
717 STOSB
718 INC DI
719 MOV CX,4
720 REP MOVSW
721 INC DI
722 MOVSW
723 MOVSB
724 POP ES
725 MOV SI,OFFSET DG:CANMES
726 CALL LISTMES
727 MOV SI,OFFSET DG:BELMES
728 CALL LISTMES
729DIDCMES:
730 PUSH CX
731 CALL NEXTFIL
732SKIPFILC:
733 POP CX
734SKIPFIL:
735 MOV [LASTFCB2],BX
736 MOV BX,[BX]
737NEXTFC:
738 MOV SI,BX
739 LOOP LOOKMATCH
740CANTERMJ: JMP SHORT CANTERM
741
742REQUEUE:
743 MOV AX,[BX]
744 CMP AX,[CURRFIL] ;Is last FCB?
745 JZ SKIPFIL ;Yes, is in right place
746 MOV SI,[LASTFCB2]
747 MOV [SI],AX ;Unlink FCB
748 MOV SI,[CURRFIL]
749 MOV [BX],SI
750 MOV SI,[LASTFCB]
751 MOV [SI],BX ;Link FCB at end
752 MOV [LASTFCB],BX ;New end
753 MOV BX,AX ;Process what it pointed to
754 JMP SHORT NEXTFC
755
756DELALL:
757 CMP BYTE PTR CS:[SI+2],-1 ;Examine current file
758DELALL2:
759 MOV BYTE PTR [SI+2],-1 ;Zap it
760 MOV SI,[SI]
761 LOOP DELALL2
762 JZ CANTERM1 ;No message if nothing was in progress
763 MOV SI,OFFSET DG:ALLCAN
764 CALL LISTMES
765 MOV SI,OFFSET DG:BELMES
766 CALL LISTMES
767CANTERM1:
768 MOV [NXTCHR],OFFSET DG:BUFFER + BLKSIZ ;Buffer empty
769CANTERM:
770
771 IF HARDINT
772 MOV [BUSY],0
773 ENDIF
774
775 XOR AX,AX
776 JMP SETCOUNT
777
778UPCONV:
779 CMP AL,'a'
780 JB NOCONV
781 CMP AL,'z'
782 JA NOCONV
783 SUB AL,20H
784NOCONV:
785 RET
786
787ADDFIL:
788ASSUME DS:DG,ES:NOTHING
789 MOV SI,[CURRFIL]
790 MOV CX,[NUMFCBS]
791
792 IF HARDINT
793BWAIT2:
794 CMP [BUSY],0
795 JNZ BWAIT2
796 INC [BUSY]
797 ENDIF
798
799LOOKSPOT:
800 CMP BYTE PTR [SI+2],-1
801 JZ GOTSPOT
802 MOV SI,[SI]
803 LOOP LOOKSPOT
804
805 IF HARDINT
806 MOV [BUSY],0
807 ENDIF
808
809 MOV AL,1
810 JMP SETCOUNT
811
812GOTSPOT:
813 PUSH DS
814 POP ES
815 POP DS
816 PUSH DS
817ASSUME DS:NOTHING
818 PUSH SI
819 MOV DI,SI
820 ADD DI,2
821 MOV SI,DX
822 MOV CX,19
823 REP MOVSW ;Copy in and set FCB
824 POP SI
825 PUSH ES
826 POP DS
827ASSUME DS:DG
828 MOV WORD PTR [SI+2+fcb_EXTENT],0
829 MOV BYTE PTR [SI+2+fcb_NR],0
830 MOV WORD PTR [SI+2+fcb_RECSIZ],BLKSIZ
831
832 IF HARDINT
833 MOV [BUSY],0
834 ENDIF
835
836 XOR AL,AL
837 JMP SETCOUNT
838
839NEXTFIL:
840ASSUME DS:DG,ES:NOTHING
841 MOV SI,[CURRFIL]
842 MOV BYTE PTR [SI+2],-1 ;Done with current file
843 MOV SI,[SI]
844 MOV [CURRFIL],SI
845 MOV [NXTCHR],OFFSET DG:BUFFER + BLKSIZ ;Buffer empty
846 MOV [COLPOS],0 ;Start of line
847 RET
848
849LISTMES:
850ASSUME DS:DG,ES:NOTHING
851 LODSB
852 CMP AL,"$"
853 JZ LMESDONE
854 CALL LOUT
855 JMP LISTMES
856
857LMESDONE:
858 RET
859
860LOUT:
861 PUSH BX
862LWAIT:
863 CALL PSTAT
864 JZ PREADY
865 CMP [ERRCNT],ERRCNT2
866 JA POPRET ;Don't get stuck
867 JMP SHORT LWAIT
868PREADY:
869 CALL POUT
870POPRET:
871 POP BX
872 RET
873
874;Stuff for BIOS interface
875IOBUSY EQU 0200H
876IOERROR EQU 8000H
877
878BYTEBUF DB ?
879
880CALLAD DD ?
881
882IOCALL DB 22
883 DB 0
884IOREQ DB ?
885IOSTAT DW 0
886 DB 8 DUP(?)
887 DB 0
888 DW OFFSET DG:BYTEBUF
889INTSEG DW ?
890IOCNT DW 1
891 DW 0
892
893PSTAT:
894ASSUME DS:DG
895 PUSH BX
896 INC [ERRCNT]
897 MOV BL,10
898 CALL DOCALL
899 TEST [IOSTAT],IOERROR
900 JZ NOSTATERR
901 OR [IOSTAT],IOBUSY ;If error, show buisy
902NOSTATERR:
903 TEST [IOSTAT],IOBUSY
904 JNZ RET13P ;Shows buisy
905 MOV [ERRCNT],0
906RET13P:
907 POP BX
908 RET
909
910POUT:
911ASSUME DS:DG
912 MOV [BYTEBUF],AL
913 MOV BL,8
914DOCALL:
915 PUSH ES
916 MOV [IOREQ],BL
917 MOV BX,CS
918 MOV ES,BX
919 MOV BX,OFFSET DG:IOCALL
920 MOV [IOSTAT],0
921 MOV [IOCNT],1
922 PUSH DS
923 PUSH SI
924 PUSH AX
925 LDS SI,[LISTDEV]
926ASSUME DS:NOTHING
927 MOV AX,[SI+6]
928 MOV WORD PTR [CALLAD],AX
929 CALL [CALLAD]
930 MOV AX,[SI+8]
931 MOV WORD PTR [CALLAD],AX
932 CALL [CALLAD]
933 POP AX
934 POP SI
935 POP DS
936ASSUME DS:DG
937 POP ES
938 RET
939
940 IF IBM
941REAL_INT_13 DD ?
942INT_13_RETADDR DW OFFSET DG:INT_13_BACK
943
944INT_13 PROC FAR
945ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
946 PUSHF
947 INC [BUSY] ;Exclude if dumb program call ROM
948 PUSH CS
949 PUSH [INT_13_RETADDR]
950 PUSH WORD PTR [REAL_INT_13+2]
951 PUSH WORD PTR [REAL_INT_13]
952 RET
953INT_13 ENDP
954
955INT_13_BACK PROC FAR
956 PUSHF
957 DEC [BUSY]
958 POPF
959 RET 2 ;Chuck saved flags
960INT_13_BACK ENDP
961 ENDIF
962
963
964 IF IBM
965
966REAL_INT_5 DD ?
967REAL_INT_17 DD ?
968INT_17_NUM DW 0
969
970INT_17:
971ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
972 PUSH SI
973 MOV SI,[CURRFIL]
974 INC SI
975 INC SI
976 CMP BYTE PTR CS:[SI],-1
977 POP SI
978 JZ DO_INT_17 ;Nothing pending, so OK
979 CMP DX,[INT_17_NUM]
980 JNZ DO_INT_17 ;Not my unit
981 CMP [BUSY],0
982 JNZ DO_INT_17 ;You are me
983 STI
984 MOV AH,0A1H ;You are bad, get out of paper
985 IRET
986
987DO_INT_17:
988 JMP [REAL_INT_17] ;Do a 17
989
990REAL_INT_14 DD ?
991INT_14_NUM DW 0
992
993INT_14:
994ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
995 PUSH SI
996 MOV SI,[CURRFIL]
997 INC SI
998 INC SI
999 CMP BYTE PTR CS:[SI],-1
1000 POP SI
1001 JZ DO_INT_14 ;Nothing pending, so OK
1002 CMP DX,[INT_14_NUM]
1003 JNZ DO_INT_14 ;Not my unit
1004 CMP [BUSY],0
1005 JNZ DO_INT_14 ;You are me
1006 STI
1007 OR AH,AH
1008 JZ SET14_AX
1009 CMP AH,2
1010 JBE SET14_AH
1011SET14_AX:
1012 MOV AL,0
1013SET14_AH:
1014 MOV AH,80H ;Time out
1015 IRET
1016
1017DO_INT_14:
1018 JMP [REAL_INT_14] ;Do a 14
1019
1020INT_5:
1021ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
1022 PUSH SI
1023 MOV SI,[CURRFIL]
1024 INC SI
1025 INC SI
1026 CMP BYTE PTR CS:[SI],-1
1027 POP SI
1028 JZ DO_INT_5 ;Nothing pending, so OK
1029 CMP [INT_17_NUM],0
1030 JNZ DO_INT_5 ;Only care about unit 0
1031 IRET ;Pretend it worked
1032
1033DO_INT_5:
1034 JMP [REAL_INT_5] ;Do a 5
1035 ENDIF
1036
1037
1038;The following data is order and position dependant
1039NUMFCBS DW 10
1040ERRCNT DW 0
1041
1042SPLFCB DW OFFSET DG:FC1
1043 DB (FCBSIZ - 2) DUP (-1)
1044FC1 DW OFFSET DG:FC2
1045 DB (FCBSIZ - 2) DUP (-1)
1046FC2 DW OFFSET DG:FC3
1047 DB (FCBSIZ - 2) DUP (-1)
1048FC3 DW OFFSET DG:FC4
1049 DB (FCBSIZ - 2) DUP (-1)
1050FC4 DW OFFSET DG:FC5
1051 DB (FCBSIZ - 2) DUP (-1)
1052FC5 DW OFFSET DG:FC6
1053 DB (FCBSIZ - 2) DUP (-1)
1054FC6 DW OFFSET DG:FC7
1055 DB (FCBSIZ - 2) DUP (-1)
1056FC7 DW OFFSET DG:FC8
1057 DB (FCBSIZ - 2) DUP (-1)
1058FC8 DW OFFSET DG:FC9
1059 DB (FCBSIZ - 2) DUP (-1)
1060FC9 DW OFFSET DG:SPLFCB
1061 DB (FCBSIZ - 2) DUP (-1)
1062
1063DEF_ENDRES LABEL BYTE
1064
1065ASSUME CS:DG,DS:DG,ES:DG,SS:DG
1066
1067BADSPOOL:
1068 MOV DX,OFFSET DG:BADMES
1069 MOV AH,STD_CON_STRING_OUTPUT
1070 INT 21H
1071 INT 20H
1072
1073SETUP:
1074;Called once to install resident
1075 CLD
1076 MOV [INTSEG],CS
1077 MOV DX,OFFSET DG:PROMPT
1078 MOV AH,STD_CON_STRING_OUTPUT
1079 INT 21H
1080 MOV DX,OFFSET DG:COMBUF
1081 MOV AH,STD_CON_STRING_INPUT
1082 INT 21H ;Get device name
1083 MOV DX,OFFSET DG:CRLF
1084 MOV AH,STD_CON_STRING_OUTPUT
1085 INT 21H
1086 MOV CL,[COMBUF+1]
1087 OR CL,CL
1088 JZ DEFSPOOL ;User didn't specify one
1089 XOR CH,CH
1090 MOV DI,OFFSET DG:LISTFCB + 1
1091 MOV SI,OFFSET DG:COMBUF + 2
1092 REP MOVSB
1093DEFSPOOL:
1094 MOV DX,OFFSET DG:LISTFCB
1095 MOV AH,FCB_OPEN
1096 INT 21H
1097 OR AL,AL
1098 JNZ BADSPOOL ;Bad
1099 TEST BYTE PTR [LISTFCB.fcb_DEVID],080H
1100 JZ BADSPOOL ;Must be a device
1101 LDS SI,DWORD PTR [LISTFCB.fcb_FIRCLUS]
1102ASSUME DS:NOTHING
1103 MOV WORD PTR [CALLAD+2],DS ;Get I/O routines
1104 MOV WORD PTR [LISTDEV+2],DS ;Get I/O routines
1105 MOV WORD PTR [LISTDEV],SI
1106 PUSH CS
1107 POP DS
1108ASSUME DS:DG
1109 MOV DX,OFFSET DG:SPINT
1110 MOV AL,SOFTINT
1111 MOV AH,GET_INTERRUPT_VECTOR
1112 INT 21H ;Get soft vector
1113 MOV WORD PTR [SPNEXT+2],ES
1114 MOV WORD PTR [SPNEXT],BX
1115 MOV AL,SOFTINT
1116 MOV AH,SET_INTERRUPT_VECTOR
1117 INT 21H ;Set soft vector
1118 MOV DX,OFFSET DG:SPCOMINT
1119 MOV AL,COMINT
1120 MOV AH,SET_INTERRUPT_VECTOR ;Set communication vector
1121 INT 21H
1122
1123 IF IBM
1124 MOV AL,13H
1125 MOV AH,GET_INTERRUPT_VECTOR
1126 INT 21H
1127 MOV WORD PTR [REAL_INT_13+2],ES
1128 MOV WORD PTR [REAL_INT_13],BX
1129 MOV DX,OFFSET DG:INT_13
1130 MOV AL,13H
1131 MOV AH,SET_INTERRUPT_VECTOR
1132 INT 21H ;Set diskI/O interrupt
1133 MOV AL,17H
1134 MOV AH,GET_INTERRUPT_VECTOR
1135 INT 21H
1136 MOV WORD PTR [REAL_INT_17+2],ES
1137 MOV WORD PTR [REAL_INT_17],BX
1138 MOV AL,14H
1139 MOV AH,GET_INTERRUPT_VECTOR
1140 INT 21H
1141 MOV WORD PTR [REAL_INT_14+2],ES
1142 MOV WORD PTR [REAL_INT_14],BX
1143 MOV AL,5H
1144 MOV AH,GET_INTERRUPT_VECTOR
1145 INT 21H
1146 MOV WORD PTR [REAL_INT_5+2],ES
1147 MOV WORD PTR [REAL_INT_5],BX
1148 PUSH CS
1149 POP ES
1150 MOV BP,OFFSET DG:LISTFCB + 1
1151 MOV SI,BP
1152 MOV CX,8
1153CONLP: ;Make sure device name in upper case
1154 LODSB
1155 CMP AL,'a'
1156 JB DOCONLP
1157 CMP AL,'z'
1158 JA DOCONLP
1159 SUB BYTE PTR [SI-1],20H
1160DOCONLP:
1161 LOOP CONLP
1162 MOV DI,OFFSET DG:INT_17_HITLIST
1163CHKHIT:
1164 MOV SI,BP
1165 MOV CL,[DI]
1166 INC DI
1167 JCXZ NOTONHITLIST
1168 REPE CMPSB
1169 LAHF
1170 ADD DI,CX ;Bump to next position without affecting flags
1171 MOV BL,[DI] ;Get device number
1172 INC DI
1173 SAHF
1174 JNZ CHKHIT
1175 XOR BH,BH
1176 MOV [INT_17_NUM],BX
1177 MOV DX,OFFSET DG:INT_17
1178 MOV AL,17H
1179 MOV AH,SET_INTERRUPT_VECTOR
1180 INT 21H ;Set printer interrupt
1181 MOV DX,OFFSET DG:INT_5
1182 MOV AL,5H
1183 MOV AH,SET_INTERRUPT_VECTOR
1184 INT 21H ;Set print screen interrupt
1185 JMP SHORT ALLSET
1186NOTONHITLIST:
1187 MOV DI,OFFSET DG:INT_14_HITLIST
1188CHKHIT2:
1189 MOV SI,BP
1190 MOV CL,[DI]
1191 INC DI
1192 JCXZ ALLSET
1193 REPE CMPSB
1194 LAHF
1195 ADD DI,CX ;Bump to next position without affecting flags
1196 MOV BL,[DI] ;Get device number
1197 INC DI
1198 SAHF
1199 JNZ CHKHIT2
1200 XOR BH,BH
1201 MOV [INT_14_NUM],BX
1202 MOV DX,OFFSET DG:INT_14
1203 MOV AL,14H
1204 MOV AH,SET_INTERRUPT_VECTOR
1205 INT 21H ;Set RS232 port interrupt
1206ALLSET:
1207 ENDIF
1208
1209 IF HARDINT
1210 MOV AH,GET_INDOS_FLAG
1211 INT 21H
1212 MOV WORD PTR [INDOS+2],ES ;Get indos flag location
1213 MOV WORD PTR [INDOS],BX
1214 MOV AL,INTLOC
1215 MOV AH,GET_INTERRUPT_VECTOR
1216 INT 21H
1217 MOV WORD PTR [NEXTINT+2],ES
1218 MOV WORD PTR [NEXTINT],BX
1219 MOV DX,OFFSET DG:HDSPINT
1220 MOV AL,INTLOC
1221 MOV AH,SET_INTERRUPT_VECTOR
1222 INT 21H ;Set hardware interrupt
1223 ENDIF
1224
1225 MOV [MAKERES],1 ;Indicate to do a terminate stay resident
1226 MOV DX,OFFSET DG:GOODMES
1227 MOV AH,STD_CON_STRING_OUTPUT
1228 INT 21H
1229 RET
1230
1231ASSUME CS:DG,DS:DG,ES:DG,SS:DG
1232
1233TRANSIENT:
1234;User interface
1235 CLD
1236
1237;Code to print header
1238; MOV DX,OFFSET DG:HEADER
1239; MOV AH,STD_CON_STRING_OUTPUT
1240; INT 21H
1241
1242DOSVER_LOW EQU 0136H ;1.54 in hex
1243DOSVER_HIGH EQU 0200H ;2.00 in hex
1244 MOV AH,GET_VERSION
1245 INT 21H
1246 XCHG AH,AL ;Turn it around to AH.AL
1247 CMP AX,DOSVER_LOW
1248 JB GOTBADDOS
1249 CMP AX,DOSVER_HIGH
1250 JBE OKDOS
1251GOTBADDOS:
1252 PUSH CS
1253 POP DS
1254 MOV DX,OFFSET DG:BADVER
1255 MOV AH,STD_CON_STRING_OUTPUT
1256 INT 21H
1257 INT 20H
1258OKDOS:
1259 MOV AX,CHAR_OPER SHL 8
1260 INT 21H
1261 MOV [SWITCHAR],DL ;Get user switch character
1262 MOV AH,GET_INTERRUPT_VECTOR
1263 MOV AL,COMINT
1264 INT 21H
1265ASSUME ES:NOTHING
1266 MOV DI,BX
1267 MOV SI,OFFSET DG:SPCOMINT
1268 MOV CX,13
1269 REPE CMPSB
1270 JZ GOTRES ;Signature matched
1271 PUSH CS
1272 POP ES
1273 CALL SETUP
1274GOTRES:
1275 PUSH CS
1276 POP ES
1277 MOV AH,GET_DEFAULT_DRIVE
1278 INT 21H
1279 MOV [DEFDRV],AL
1280 MOV SI,PARMS
1281 LODSB
1282 OR AL,AL
1283 JNZ GOTPARMS
1284TRANEXIT:
1285 CALL GETSPLIST
1286 CMP [MAKERES],0
1287 JNZ SETRES
1288 INT 20H
1289
1290SETRES:
1291 MOV DX,[ENDRES]
1292 INT 27H
1293
1294ARGSDONE:
1295 CMP [ARGSETUP],0
1296 JZ TRANEXIT
1297 CALL PROCESS
1298 JMP SHORT TRANEXIT
1299
1300GOTPARMS:
1301PARSE:
1302 MOV DI,OFFSET DG:PARSEBUF
1303 CALL CPARSE
1304 JC ARGSDONE
1305 CMP AX,4 ;Switch?
1306 JNZ GOTNORMARG
1307 MOV AL,[DI] ;Get the switch character
1308 CMP AL,'C'
1309 JZ SETCAN
1310 CMP AL,'c'
1311 JNZ CHKSPL
1312SETCAN:
1313 MOV [CANFLG],1
1314 JMP SHORT PARSE
1315CHKSPL:
1316 CMP AL,'P'
1317 JZ RESETCAN
1318 CMP AL,'p'
1319 JNZ CHKTERM
1320RESETCAN:
1321 MOV [CANFLG],0
1322 JMP SHORT PARSE
1323CHKTERM:
1324 CMP AL,'T'
1325 JZ SETTERM
1326 CMP AL,'t'
1327 JZ SETTERM
1328 MOV DX,OFFSET DG:BADSWT
1329 MOV AH,STD_CON_STRING_OUTPUT
1330 INT 21H
1331 JMP SHORT PARSE
1332
1333SETTERM:
1334 CALL TERMPROCESS
1335 JMP TRANEXIT ; Ignore everything after T switch
1336
1337GOTNORMARG:
1338 XOR AL,AL
1339 XCHG AL,[ARGSETUP]
1340 OR AL,AL
1341 JZ PARSEARG
1342 CALL NORMPROC ;Don't test ARGSETUP, it just got zeroed
1343PARSEARG:
1344 PUSH SI
1345 MOV SI,DI
1346 MOV DI,FCB
1347 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 1
1348 INT 21H ;Parse the arg
1349 CMP BYTE PTR [DI],0
1350 JNZ DRVOK
1351 MOV DL,[DEFDRV]
1352 INC DL
1353 MOV BYTE PTR [DI],DL ;Set the default drive
1354DRVOK:
1355 POP SI
1356 INC [ARGSETUP]
1357 JMP SHORT PARSE
1358
1359TERMPROCESS:
1360 MOV DX,-1
1361PROCRET:
1362 MOV AH,1
1363 CALL DOSET
1364PROCRETNFUNC:
1365 MOV [ARGSETUP],0
1366 PUSH CS
1367 POP ES
1368RET14: RET
1369
1370PROCESS:
1371 CMP [ARGSETUP],0
1372 JZ RET14 ;Nothing to process
1373NORMPROC:
1374 MOV AL,BYTE PTR DS:[FCB+1]
1375 CMP AL," "
1376 JZ SRCHBADJ
1377 MOV DX,FCB
1378 MOV AH,[CANFLG]
1379 CMP AH,0
1380 JNZ PROCRET
1381 MOV DX,OFFSET DG:SRCHFCB
1382 MOV AH,SET_DMA
1383 INT 21H
1384 MOV DX,FCB
1385 MOV AH,DIR_SEARCH_FIRST
1386 INT 21H
1387 OR AL,AL
1388 JNZ SRCHBADJ
1389SRCHLOOP:
1390 MOV DX,OFFSET DG:SRCHFCB
1391 MOV AH,FCB_OPEN
1392 INT 21H
1393 OR AL,AL
1394 JZ OPENOK
1395 CALL OPENERR
1396 JMP SHORT NEXTSEARCH
1397SRCHBADJ: JMP SRCHBAD
1398OPENOK:
1399 MOV DX,OFFSET DG:SRCHFCB
1400 MOV AH,0
1401 CALL DOSET
1402 OR AL,AL
1403 JZ NEXTSEARCH
1404 XCHG AL,[FULLFLAG] ;Know AL non-zero
1405 OR AL,AL
1406 JNZ NEXTSEARCH ;Only print message once
1407 MOV DX,OFFSET DG:FULLMES ;Queue full
1408 MOV AH,STD_CON_STRING_OUTPUT
1409 INT 21H
1410NEXTSEARCH:
1411 MOV DX,OFFSET DG:SRCHFCB
1412 MOV AH,SET_DMA
1413 INT 21H
1414 MOV DX,FCB
1415 MOV AH,DIR_SEARCH_NEXT
1416 INT 21H
1417 OR AL,AL
1418 JNZ PROCRETNFUNC
1419 JMP SRCHLOOP
1420
1421DOSET:
1422 INT COMINT
1423 MOV [FILCNT],AH ;Suck up return info
1424 MOV WORD PTR [SPLIST+2],ES
1425 MOV WORD PTR [CURFILE+2],ES
1426 MOV WORD PTR [SPLIST],BX
1427 MOV WORD PTR [CURFILE],DX
1428 RET
1429
1430OPENERR:
1431 PUSH SI
1432 PUSH DI
1433 MOV SI,OFFSET DG:OPFILNAM
1434 PUSH DS
1435 POP ES
1436 MOV DI,OFFSET DG:SRCHFCB
1437 CALL MVFNAM
1438 MOV DX,OFFSET DG:OPMES
1439 MOV AH,STD_CON_STRING_OUTPUT
1440 INT 21H
1441 POP DI
1442 POP SI
1443 RET
1444
1445SRCHBAD:
1446 PUSH SI
1447 PUSH DI
1448 MOV SI,OFFSET DG:SRCHFNAM
1449 PUSH DS
1450 POP ES
1451 MOV DI,FCB
1452 CALL MVFNAM
1453 MOV DX,OFFSET DG:SRCHMES
1454 MOV AH,STD_CON_STRING_OUTPUT
1455 INT 21H
1456 POP DI
1457 POP SI
1458 JMP PROCRETNFUNC
1459
1460GETSPLIST:
1461 MOV AH,0FFH
1462 CALL DOSET
1463 PUSH DS
1464 LDS DI,[SPLIST]
1465 MOV DI,[DI-2] ;Get the error count
1466 POP DS
1467 CMP DI,ERRCNT1
1468 JB CNTOK
1469 MOV DX,OFFSET DG:CNTMES
1470 MOV AH,STD_CON_STRING_OUTPUT
1471 INT 21H
1472CNTOK:
1473 MOV CL,[FILCNT]
1474 OR CL,CL
1475 JZ NOFILES
1476 XOR CH,CH
1477 LES DI,[CURFILE]
1478 PUSH DI
1479 INC DI
1480 INC DI
1481 MOV SI,OFFSET DG:CURFNAM
1482 CALL MVFNAM
1483 POP DI
1484 MOV DX,OFFSET DG:CURMES
1485 MOV AH,STD_CON_STRING_OUTPUT
1486 INT 21H
1487 DEC CX
1488 JCXZ RET12
1489FILOOP:
1490 MOV DI,ES:[DI]
1491 PUSH DI
1492 INC DI
1493 INC DI
1494 MOV SI,OFFSET DG:FILFNAM
1495 CALL MVFNAM
1496 POP DI
1497 MOV DX,OFFSET DG:FILMES
1498 MOV AH,STD_CON_STRING_OUTPUT
1499 INT 21H
1500 LOOP FILOOP
1501RET12: RET
1502
1503NOFILES:
1504 MOV DX,OFFSET DG:NOFILS
1505 MOV AH,STD_CON_STRING_OUTPUT
1506 INT 21H
1507 RET
1508
1509;Make a message with the file name
1510MVFNAM:
1511ASSUME DS:NOTHING,ES:NOTHING
1512 PUSH SI
1513 PUSH DI
1514 PUSH CX
1515 MOV AX,ES
1516 PUSH DS
1517 POP ES
1518 MOV DS,AX
1519 XCHG SI,DI
1520 LODSB
1521 ADD AL,"@"
1522 CMP AL,"@"
1523 JNZ STCHR
1524 MOV AL,[DEFDRV]
1525 ADD AL,"A"
1526STCHR:
1527 STOSB
1528 INC DI
1529 MOV CX,4
1530 REP MOVSW
1531 INC DI
1532 MOVSW
1533 MOVSB
1534 MOV AX,ES
1535 PUSH DS
1536 POP ES
1537 MOV DS,AX
1538 POP CX
1539 POP DI
1540 POP SI
1541 RET
1542
1543;-----------------------------------------------------------------------;
1544; ENTRY: ;
1545; DS:SI Points input buffer ;
1546; ES:DI Points to the token buffer ;
1547; ;
1548; EXIT: ;
1549; DS:SI Points to next char in the input buffer ;
1550; ES:DI Points to the token buffer ;
1551; CX Character count ;
1552; AX Condition Code ;
1553; =1 same as carry set ;
1554; =2 normal token ;
1555; =4 switch character, char in token buffer ;
1556; Carry Flag Set if a CR was found, Reset otherwise ;
1557; ;
1558; MODIFIES: ;
1559; CX, SI, AX and the Carry Flag ;
1560; ;
1561;-----------------------------------------------------------------------;
1562
1563TAB equ 09h
1564CR equ 0dh
1565
1566CPARSE:
1567ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
1568 pushf ;save flags
1569 push di ;save the token buffer addrss
1570 xor cx,cx ;no chars in token buffer
1571 call kill_bl
1572
1573 cmp al,CR ;a CR?
1574 jne sj2 ;no, skip
1575sj1:
1576 mov ax,1 ;condition code
1577 dec si ;adjust the pointer
1578 pop di ;retrive token buffer address
1579 popf ;restore flags
1580 stc ;set the carry bit
1581 ret
1582
1583sj2:
1584 mov dl,[SWITCHAR]
1585 cmp al,dl ;is the char the switch char?
1586 jne anum_char ;no, process...
1587 call kill_bl
1588 cmp al,CR ;a CR?
1589 je sj1 ;yes, error exit
1590 call move_char ;Put the switch char in the token buffer
1591 mov ax,4 ;Flag switch
1592 jmp short x_done2
1593
1594anum_char:
1595 call move_char ;just an alphanum string
1596 lodsb
1597 cmp al,' '
1598 je x_done
1599 cmp al,tab
1600 je x_done
1601 cmp al,CR
1602 je x_done
1603 cmp al,','
1604 je x_done
1605 cmp al,'='
1606 je x_done
1607 cmp al,dl ;Switch character
1608 jne anum_char
1609x_done:
1610 dec si ;adjust for next round
1611 mov ax,2 ;normal token
1612x_done2:
1613 push ax ;save condition code
1614 mov al,0
1615 stosb ;null at the end
1616 pop ax
1617 pop di ;restore token buffer pointer
1618 popf
1619 clc ;clear carry flag
1620 ret
1621
1622
1623kill_bl proc near
1624 lodsb
1625 cmp al,' '
1626 je kill_bl
1627 cmp al,tab
1628 je kill_bl
1629 cmp al,',' ;a comma?
1630 je kill_bl
1631 cmp al,'='
1632 je kill_bl
1633 ret
1634kill_bl endp
1635
1636
1637move_char proc near
1638 stosb ;store char in token buffer
1639 inc cx ;increment char count
1640 ret
1641move_char endp
1642
1643CODE ENDS
1644 END START
1645
diff --git a/v2.0/source/PRINT_v211.ASM b/v2.0/source/PRINT_v211.ASM
new file mode 100644
index 0000000..4585af7
--- /dev/null
+++ b/v2.0/source/PRINT_v211.ASM
@@ -0,0 +1,1645 @@
1;MS-DOS PRINT program for background printing of text files to the list
2; device. INT 28H is a software interrupt generated by the DOS
3; in its I/O wait loops. This spooler can be assembled for
4; operation using only this interrupt which is portable from
5; system to system. It may also be assembled to use a hardware
6; timer interrupt in addition to the software INT 28H. The
7; purpose of using hardware interrupts is to allow printing to
8; continue during programs which do not enter the system and
9; therefore causes the INT 28H to go away. A timer interrupt is
10; chosen in preference to a "printer buffer empty" interrupt
11; because PRINT in the timer form is generic. It can be given
12; the name of any currently installed character device as the
13; "printer", this makes it portable to devices which are
14; installed by the user even in the hardware case. It could be
15; modified to use a buffer empty interrupt (no code is given for
16; this case), if this is done the PROMPT and BADMES messages and
17; their associated code should be removed as PRINT will then be
18; device specific.
19;
20; VERSION 1.00 07/03/82
21
22
23FALSE EQU 0
24TRUE EQU NOT FALSE
25
26IBM EQU TRUE
27IBMVER EQU IBM
28MSVER EQU FALSE
29
30 IF MSVER
31HARDINT EQU FALSE ;No hardware ints
32AINT EQU FALSE ;No need to do interrupt acknowledge
33 ENDIF
34
35 IF IBM
36HARDINT EQU TRUE
37INTLOC EQU 1CH ;Hardware interrupt location (Timer)
38AINT EQU TRUE ;Acknowledge interrupts
39EOI EQU 20H ;End Of Interrupt "instruction"
40AKPORT EQU 20H ;Interrupt Acknowledge port
41 ENDIF
42
43;The following values have to do with the ERRCNT variable and the
44; CNTMES message. The values define levels at wich it is assumed
45; an off-line error exists. ERRCNT1 defines the value of ERRCNT above
46; which the CNTMES message is printed by the transient. ERRCNT2
47; defines the value of ERRCNT above which the resident will give up
48; trying to print messages on the printer, it is much greater than
49; ERRCNT1 because a much tighter loop is involved. The bounding event
50; which determines the correct value is the time required to do a
51; form feed.
52
53 IF IBM
54ERRCNT1 EQU 1000
55ERRCNT2 EQU 20000
56 ELSE
57ERRCNT1 EQU 1000
58ERRCNT2 EQU 20000
59 ENDIF
60
61 IF HARDINT
62TIMESLICE EQU 8 ;The PRINT scheduling time slice. PRINT
63 ; lets this many "ticks" go by before
64 ; using a time slice to pump out characters.
65 ; Setting this to 3 for instance means PRINT
66 ; Will skip 3 slices, then take the fourth.
67 ; Thus using up 1/4 of the CPU. Setting it
68 ; to one gives PRINT 1/2 of the CPU.
69 ; The above examples assume MAXTICK is
70 ; 1. The actual PRINT CPU percentage is
71 ; (MAXTICK/(1+TIMESLICE))*100
72
73MAXTICK EQU 2 ;The PRINT in timeslice. PRINT will pump
74 ; out characters for this many clock ticks
75 ; and then exit. The selection of a value
76 ; for this is dependent on the timer rate.
77
78BUSYTICK EQU 1 ;If PRINT sits in a wait loop waiting for
79 ; output device to come ready for this
80 ; many ticks, it gives up its time slice.
81 ; Setting it greater than or equal to
82 ; MAXTICK causes it to be ignored.
83
84;User gets TIMESLICE ticks and then PRINT takes MAXTICK ticks unless BUSYTICK
85; ticks go by without getting a character out.
86 ENDIF
87
88
89;WARNING DANGER WARNING:
90; PRINT is a systems utility. It is clearly understood that it may have
91; to be entirely re-written for future versions of MS-DOS. The following
92; TWO vectors are version specific, they may not exist at all in future
93; versions. If they do exist, they may function differently.
94; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS
95; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM.
96; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON
97; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS.
98SOFTINT EQU 28H ;Software interrupt generated by DOS
99COMINT EQU 2FH ;Communications interrupt used by PRINT
100 ; This vector number is DOS reserved. It
101 ; is not generally available to programs
102 ; other than PRINT.
103
104BLKSIZ EQU 512 ;Size of the PRINT I/O block in bytes
105FCBSIZ EQU 40 ;Size of an FCB
106
107 INCLUDE DOSSYM.ASM
108
109FCB EQU 5CH
110PARMS EQU 80H
111
112DG GROUP CODE,DATA
113
114CODE SEGMENT
115ASSUME CS:DG
116
117 ORG 100H
118START:
119 JMP TRANSIENT
120
121HEADER DB "Vers 1.00"
122
123 DB 128 DUP (?)
124ISTACK LABEL WORD ;Stack starts here and grows down
125
126;Resident data
127
128 IF HARDINT
129INDOS DD ? ;DOS buisy flag
130NEXTINT DD ? ;Chain for int
131BUSY DB 0 ;Internal ME flag
132SOFINT DB 0 ;Internal ME flag
133TICKCNT DB 0 ;Tick counter
134TICKSUB DB 0 ;Tick miss counter
135SLICECNT DB TIMESLICE ;Time slice counter
136 ENDIF
137
138CBUSY DB 0 ;ME on com interrupt
139SPNEXT DD ? ;Chain location for INT 28
140PCANMES DB 0 ;Cancel message flag
141SSsave DW ? ;Stack save area for INT 24
142SPsave DW ?
143DMAADDR DD ? ;Place to save DMA address
144HERRINT DD ? ;Place to save Hard error interrupt
145LISTDEV DD ? ;Pointer to Device
146COLPOS DB 0 ;Column position for TAB processing
147NXTCHR DW OFFSET DG:BUFFER + BLKSIZ ;Buffer pointer
148CURRFIL DW OFFSET DG:SPLFCB ;Current file being printed
149
150LASTFCB DW ? ;Back pointer
151LASTFCB2 DW ? ;Another back pointer
152PABORT DB 0 ;Abort flag
153
154;Resident messages
155
156ERRMES DB 13,10,13,10,"**********",13,10,"$"
157ERRMEST DB " error reading file",13,10
158EMFILNAM DB " : . "
159BELMES DB 13,0CH,7,"$"
160
161CANMES DB 13,10,13,10
162CANFILNAM DB " : . "
163 DB " Canceled by operator$"
164
165ALLCAN DB 13,10,13,10,"All files canceled by operator$"
166
167MESBAS DW OFFSET DG:ERR0
168 DW OFFSET DG:ERR1
169 DW OFFSET DG:ERR2
170 DW OFFSET DG:ERR3
171 DW OFFSET DG:ERR4
172 DW OFFSET DG:ERR5
173 DW OFFSET DG:ERR6
174 DW OFFSET DG:ERR7
175 DW OFFSET DG:ERR8
176 DW OFFSET DG:ERR9
177 DW OFFSET DG:ERR10
178 DW OFFSET DG:ERR11
179 DW OFFSET DG:ERR12
180
181;INT 24 messages A La COMMAND
182
183ERR0 DB "Write protect$"
184ERR1 DB "Bad unit$"
185ERR2 DB "Not ready$"
186ERR3 DB "Bad command$"
187ERR4 DB "Data$"
188ERR5 DB "Bad call format$"
189ERR6 DB "Seek$"
190ERR7 DB "Non-DOS disk$"
191ERR8 DB "Sector not found$"
192ERR9 DB "No paper$"
193ERR10 DB "Write fault$"
194ERR11 DB "Read fault$"
195ERR12 DB "Disk$"
196
197FATMES DB "File allocation table bad drive "
198BADDRVM DB "A.",13,10,"$"
199
200;The DATA buffer
201BUFFER DB BLKSIZ DUP(0)
202 DB ?
203CODE ENDS
204
205;Transient data
206
207DATA SEGMENT BYTE
208 ORG 0
209SWITCHAR DB ? ;User switch character
210FULLFLAG DB 0 ;Flag for printing queue full message
211MAKERES DB 0 ;Flag to indicate presence of resident
212ARGSETUP DB 0 ;Flag to indicate a formatted FCB exists at 5C
213DEFDRV DB 0 ;Default drive
214CANFLG DB 0 ;Flag to indicate cancel
215FILCNT DB 0 ;Number of files
216SPLIST DD ? ;Pointer to FCBs in resident
217CURFILE DD ? ;Pointer to current FCB
218SRCHFCB DB 38 DUP (0) ;SEARCH-FIRST/NEXT FCB
219ENDRES DW OFFSET DG:DEF_ENDRES ;Term-Res location
220
221;Messages
222
223NOFILS DB "PRINT queue is empty",13,10,"$"
224CURMES DB 13,10," "
225CURFNAM DB " : . is currently being printed",13,10,"$"
226FILMES DB " "
227FILFNAM DB " : . is in queue"
228CRLF DB 13,10,"$"
229OPMES DB "Cannot open "
230OPFILNAM DB " : . ",13,10,"$"
231FULLMES DB "PRINT queue is full",13,10,"$"
232SRCHMES LABEL BYTE
233SRCHFNAM DB " : . "," File not found",13,10,"$"
234BADMES DB "List output is not assigned to a device",13,10,"$"
235GOODMES DB "Resident part of PRINT installed",13,10,"$"
236PROMPT DB "Name of list device [PRN]: $"
237CNTMES DB "Errors on list device indicate that it",13,10
238 DB "may be off-line. Please check it.",13,10,13,10,"$"
239BADSWT DB "Invalid parameter",13,10,"$"
240
241
242BADVER DB "Incorrect DOS version",13,10,"$"
243
244 IF IBM
245;Reserved names for parallel card
246INT_17_HITLIST LABEL BYTE
247 DB 8,"PRN ",0
248 DB 8,"LPT1 ",0
249 DB 8,"LPT2 ",1
250 DB 8,"LPT3 ",2
251 DB 0
252;Reserved names for Async adaptor
253INT_14_HITLIST LABEL BYTE
254 DB 8,"AUX ",0
255 DB 8,"COM1 ",0
256 DB 8,"COM2 ",1
257 DB 0
258 ENDIF
259
260COMBUF DB 14,0 ;Device name buffer
261 DB 14 DUP (?)
262LISTFCB DB 0,"PRN " ;Device name FCB
263 DB 25 DUP (0)
264PARSEBUF DB 80 DUP (?) ;Parsing space
265
266DATA ENDS
267
268CODE SEGMENT
269ASSUME CS:DG,DS:DG,ES:DG,SS:DG
270
271
272;Interrupt routines
273ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:NOTHING
274 IF HARDINT
275HDSPINT: ;Hardware interrupt entry point
276 INC [TICKCNT] ;Tick
277 INC [TICKSUB] ;Tick
278 CMP [SLICECNT],0
279 JZ TIMENOW
280 DEC [SLICECNT] ;Count down
281 JMP SHORT CHAININT ;Not time yet
282TIMENOW:
283 CMP [BUSY],0 ;See if interrupting ourself
284 JNZ CHAININT
285 PUSH DS
286 PUSH SI
287 LDS SI,[INDOS] ;Check for making DOS calls
288 CMP BYTE PTR [SI],0
289 POP SI
290 POP DS
291 JNZ CHAININT ;DOS is Buisy
292 INC [BUSY] ;Exclude furthur interrupts
293 MOV [TICKCNT],0 ;Reset tick counter
294 MOV [TICKSUB],0 ;Reset tick counter
295 STI ;Keep things rolling
296
297 IF AINT
298 MOV AL,EOI ;Acknowledge interrupt
299 OUT AKPORT,AL
300 ENDIF
301
302 CALL DOINT
303 CLI
304 MOV [SLICECNT],TIMESLICE ;Either soft or hard int resets time slice
305 MOV [BUSY],0 ;Done, let others in
306CHAININT:
307 JMP [NEXTINT] ;Chain to next clock routine
308 ENDIF
309
310
311SPINT: ;INT 28H entry point
312 IF HARDINT
313 CMP [BUSY],0
314 JNZ NXTSP
315 INC [BUSY] ;Exclude hardware interrupt
316 INC [SOFINT] ;Indicate a software int in progress
317 ENDIF
318
319 STI ;Hardware interrupts ok on INT 28H entry
320 CALL DOINT
321
322 IF HARDINT
323 CLI
324 MOV [SOFINT],0 ;Indicate INT done
325 MOV [SLICECNT],TIMESLICE ;Either soft or hard int resets time slice
326 MOV [BUSY],0
327 ENDIF
328
329NXTSP: JMP [SPNEXT] ;Chain to next INT 28
330
331DOINT:
332 PUSH SI
333 MOV SI,[CURRFIL]
334 INC SI
335 INC SI
336 CMP BYTE PTR CS:[SI],-1
337 POP SI
338 JNZ GOAHEAD
339 JMP SPRET ;Nothing to do
340GOAHEAD:
341 PUSH AX ;Need a working register
342 MOV [SSsave],SS
343 MOV [SPsave],SP
344 MOV AX,CS
345 CLI
346;Go to internal stack to prevent INT 24 overflowing system stack
347 MOV SS,AX
348 MOV SP,OFFSET DG:ISTACK
349 STI
350 PUSH ES
351 PUSH DS
352 PUSH BX
353 PUSH CX
354 PUSH DX
355 PUSH SI
356 PUSH DI
357 PUSH CS
358 POP DS
359ASSUME DS:DG
360
361 MOV BX,[NXTCHR]
362 CMP BX,OFFSET DG:BUFFER + BLKSIZ
363 JNZ PLOOP
364 JMP READBUFF ;Buffer empty
365
366PLOOP:
367 IF HARDINT
368 MOV BX,[NXTCHR]
369 CMP BX,OFFSET DG:BUFFER + BLKSIZ
370 JZ DONEJMP ;Buffer has become empty
371 CMP [SOFINT],0
372 JNZ STATCHK
373 CMP [TICKCNT],MAXTICK ;Check our time slice
374 JAE DONEJMP
375STATCHK:
376 ENDIF
377
378 CALL PSTAT
379
380 IF HARDINT
381 JZ DOCHAR ;Printer ready
382 CMP [SOFINT],0
383 ENDIF
384
385 JNZ DONEJMP ;If soft int give up
386
387 IF HARDINT
388 CMP [TICKSUB],BUSYTICK ;Check our busy timeout
389 JAE DONEJMP
390 JMP PLOOP
391 ENDIF
392
393DOCHAR:
394 MOV AL,BYTE PTR [BX]
395 CMP AL,1AH ;^Z?
396 JZ FILEOFJ ;CPM EOF
397 CMP AL,0DH ;CR?
398 JNZ NOTCR
399 MOV [COLPOS],0
400NOTCR:
401 CMP AL,9 ;TAB?
402 JNZ NOTABDO
403 MOV CL,[COLPOS]
404 OR CL,0F8H
405 NEG CL
406 XOR CH,CH
407 JCXZ TABDONE
408TABLP:
409 MOV AL," "
410 INC [COLPOS]
411 PUSH CX
412 CALL POUT
413 POP CX
414 LOOP TABLP
415 JMP TABDONE
416
417NOTABDO:
418 CMP AL,8 ;Back space?
419 JNZ NOTBACK
420 DEC [COLPOS]
421NOTBACK:
422 CMP AL,20H ;Non Printing char?
423 JB NOCHAR
424 INC [COLPOS] ;Printing char
425NOCHAR:
426 CALL POUT ;Print it
427TABDONE:
428 INC [NXTCHR] ;Next char
429
430 IF HARDINT
431 MOV [TICKSUB],0 ;Got a character out, Reset counter
432 CMP [SOFINT],0 ;Soft int does one char at a time
433 JZ PLOOP
434 ENDIF
435
436DONEJMP:
437 POP DI
438 POP SI
439 POP DX
440 POP CX
441 POP BX
442 POP DS
443 POP ES
444ASSUME DS:NOTHING,ES:NOTHING
445 CLI
446 MOV SS,[SSsave] ;Restore Entry Stack
447 MOV SP,[SPsave]
448 STI
449 POP AX
450SPRET:
451 RET
452
453FILEOFJ: JMP FILEOF
454
455READBUFF:
456ASSUME DS:DG,ES:NOTHING
457
458 MOV AL,24H
459 MOV AH,GET_INTERRUPT_VECTOR
460 INT 21H
461 MOV WORD PTR [HERRINT+2],ES ;Save current vector
462 MOV WORD PTR [HERRINT],BX
463 MOV DX,OFFSET DG:DSKERR
464 MOV AL,24H
465 MOV AH,SET_INTERRUPT_VECTOR ;Install our own
466 INT 21H ;Spooler must catch its errors
467 MOV AH,GET_DMA
468 INT 21H
469 MOV WORD PTR [DMAADDR+2],ES ;Save DMA address
470 MOV WORD PTR [DMAADDR],BX
471 MOV DX,OFFSET DG:BUFFER
472 MOV AH,SET_DMA
473 INT 21H ;New DMA address
474 MOV [PABORT],0 ;No abort
475 MOV DX,[CURRFIL] ;Read
476 INC DX
477 INC DX ;Skip over pointer
478 MOV AH,FCB_SEQ_READ
479 INT 21H
480 PUSH AX
481 LDS DX,[DMAADDR]
482ASSUME DS:NOTHING
483 MOV AH,SET_DMA
484 INT 21H ;Restore DMA
485 LDS DX,[HERRINT]
486 MOV AL,24H
487 MOV AH,SET_INTERRUPT_VECTOR
488 INT 21H ;Restore Error INT
489 POP AX
490 PUSH CS
491 POP DS
492ASSUME DS:DG
493 CMP [PABORT],0
494 JNZ TONEXTFIL ;Barf on this file, got INT 24
495 CMP AL,01
496 JZ FILEOF ;Read EOF?
497 MOV BX,OFFSET DG:BUFFER ;Buffer full
498 MOV [NXTCHR],BX
499 JMP DONEJMP
500
501FILEOF:
502 MOV AL,0CH ;Form feed
503 CALL LOUT
504TONEXTFIL:
505 CALL NEXTFIL
506 JMP DONEJMP
507
508;INT 24 handler
509
510DSKERR:
511ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
512 STI
513 CMP [PABORT],0
514 JNZ IGNRET
515 PUSH BX
516 PUSH CX
517 PUSH DX
518 PUSH DI
519 PUSH SI
520 PUSH BP
521 PUSH ES
522 PUSH DS
523 PUSH CS
524 POP DS
525 PUSH CS
526 POP ES
527ASSUME DS:DG,ES:DG
528 ADD [BADDRVM],AL ;Set correct drive letter
529 MOV SI,OFFSET DG:ERRMES
530 CALL LISTMES
531 TEST AH,080H
532 JNZ FATERR
533 AND DI,0FFH
534 CMP DI,12
535 JBE HAVCOD
536 MOV DI,12
537HAVCOD:
538 SHL DI,1
539 MOV DI,WORD PTR [DI+MESBAS] ; Get pointer to error message
540 MOV SI,DI
541 CALL LISTMES ; Print error type
542 MOV DI,OFFSET DG:EMFILNAM
543 MOV SI,[CURRFIL]
544 ADD SI,2 ;Get to file name
545 LODSB
546 ADD AL,'@'
547 STOSB
548 INC DI
549 MOV CX,4
550 REP MOVSW
551 INC DI
552 MOVSW
553 MOVSB
554 MOV SI,OFFSET DG:ERRMEST
555 CALL LISTMES
556SETABORT:
557 INC [PABORT] ;Indicate abort
558 POP DS
559 POP ES
560 POP BP
561 POP SI
562 POP DI
563 POP DX
564 POP CX
565 POP BX
566IGNRET:
567 XOR AL,AL ;Ignore
568 IRET
569
570FATERR:
571 MOV SI,OFFSET DG:FATMES
572 CALL LISTMES
573 JMP SHORT SETABORT
574
575ADDFILJ: JMP ADDFIL
576
577COMBUSY:
578 MOV AX,-1
579 IRET
580
581;Communications interrupt
582SPCOMINT:
583ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
584 CMP [CBUSY],0
585 JNZ COMBUSY
586 INC [CBUSY] ;Exclude
587 STI ;Turn ints back on
588 PUSH SI
589 PUSH DI
590 PUSH CX
591 PUSH DS
592 PUSH CS
593 POP DS
594ASSUME DS:DG
595 MOV [PCANMES],0 ;Havn't printed cancel message
596 OR AH,AH
597 JZ ADDFILJ ;Add file
598 CMP AH,1
599 JZ CANFIL ;Cancel File(s)
600 XOR AL,AL
601SETCOUNT:
602 PUSH AX ;Save AL return code
603 XOR AH,AH
604 MOV SI,OFFSET DG:SPLFCB
605 MOV CX,[NUMFCBS]
606CNTFILS:
607 CMP BYTE PTR [SI+2],-1 ;Valid?
608 JZ LNEXT
609 INC AH
610LNEXT:
611 ADD SI,FCBSIZ
612 LOOP CNTFILS
613COMRET:
614 MOV BX,OFFSET DG:SPLFCB
615 MOV DX,[CURRFIL]
616 PUSH DS
617 POP ES
618ASSUME ES:NOTHING
619 MOV CH,AH
620 POP AX ;Get AL return
621 MOV AH,CH
622
623 IF HARDINT
624BWAIT3:
625 CMP [BUSY],0
626 JNZ BWAIT3
627 INC [BUSY]
628 ENDIF
629
630 CALL PSTAT ; Tweek error counter
631
632 IF HARDINT
633 MOV [BUSY],0
634 ENDIF
635
636 POP DS
637ASSUME DS:NOTHING
638 POP CX
639 POP DI
640 POP SI
641 MOV [CBUSY],0
642 IRET
643
644DELALLJ: JMP DELALL
645
646CANFIL:
647ASSUME DS:DG,ES:NOTHING
648 MOV CX,[NUMFCBS]
649
650 IF HARDINT
651BWAIT:
652 CMP [BUSY],0
653 JNZ BWAIT
654 INC [BUSY]
655 ENDIF
656
657 MOV SI,[CURRFIL]
658 CMP DX,-1
659 JZ DELALLJ
660 MOV BX,[SI]
661 PUSH BX
662LOOKEND: ;Set initial pointer values
663 CMP BX,SI
664 JZ GOTLAST
665 POP AX
666 PUSH BX
667 MOV BX,[BX]
668 JMP SHORT LOOKEND
669
670GOTLAST:
671 POP BX
672 MOV [LASTFCB],BX
673 MOV [LASTFCB2],BX
674 POP ES
675 PUSH ES
676 MOV BX,SI
677LOOKMATCH:
678 MOV DI,DX
679 ADD SI,2 ;Skip pointer
680 CMP BYTE PTR [SI],-1
681 JZ CANTERMJ ;No more
682 CMPSB
683 JNZ SKIPFIL ;DRIVE
684 PUSH CX
685 MOV CX,11
686NXTCHAR:
687 MOV AL,ES:[DI]
688 INC DI
689 CALL UPCONV
690 MOV AH,AL
691 LODSB
692 CALL UPCONV
693 CMP AH,"?" ;Wild card?
694 JZ NXTCHRLP ;Yes
695 CMP AH,AL
696 JNZ SKIPFILC
697NXTCHRLP:
698 LOOP NXTCHAR
699MATCH:
700 POP CX
701 MOV AH,-1
702 XCHG AH,[BX+2] ;Zap it
703 CMP BX,[CURRFIL] ;Is current file?
704 JNZ REQUEUE ;No
705 MOV AL,1
706 XCHG AL,[PCANMES]
707 OR AL,AL
708 JNZ DIDCMES ;Only print cancel message once
709 PUSH ES
710 PUSH CS
711 POP ES
712 MOV DI,OFFSET DG:CANFILNAM
713 MOV SI,BX
714 ADD SI,3 ;Get to file name
715 MOV AL,AH
716 ADD AL,'@'
717 STOSB
718 INC DI
719 MOV CX,4
720 REP MOVSW
721 INC DI
722 MOVSW
723 MOVSB
724 POP ES
725 MOV SI,OFFSET DG:CANMES
726 CALL LISTMES
727 MOV SI,OFFSET DG:BELMES
728 CALL LISTMES
729DIDCMES:
730 PUSH CX
731 CALL NEXTFIL
732SKIPFILC:
733 POP CX
734SKIPFIL:
735 MOV [LASTFCB2],BX
736 MOV BX,[BX]
737NEXTFC:
738 MOV SI,BX
739 LOOP LOOKMATCH
740CANTERMJ: JMP SHORT CANTERM
741
742REQUEUE:
743 MOV AX,[BX]
744 CMP AX,[CURRFIL] ;Is last FCB?
745 JZ SKIPFIL ;Yes, is in right place
746 MOV SI,[LASTFCB2]
747 MOV [SI],AX ;Unlink FCB
748 MOV SI,[CURRFIL]
749 MOV [BX],SI
750 MOV SI,[LASTFCB]
751 MOV [SI],BX ;Link FCB at end
752 MOV [LASTFCB],BX ;New end
753 MOV BX,AX ;Process what it pointed to
754 JMP SHORT NEXTFC
755
756DELALL:
757 CMP BYTE PTR CS:[SI+2],-1 ;Examine current file
758DELALL2:
759 MOV BYTE PTR [SI+2],-1 ;Zap it
760 MOV SI,[SI]
761 LOOP DELALL2
762 JZ CANTERM1 ;No message if nothing was in progress
763 MOV SI,OFFSET DG:ALLCAN
764 CALL LISTMES
765 MOV SI,OFFSET DG:BELMES
766 CALL LISTMES
767CANTERM1:
768 MOV [NXTCHR],OFFSET DG:BUFFER + BLKSIZ ;Buffer empty
769CANTERM:
770
771 IF HARDINT
772 MOV [BUSY],0
773 ENDIF
774
775 XOR AX,AX
776 JMP SETCOUNT
777
778UPCONV:
779 CMP AL,'a'
780 JB NOCONV
781 CMP AL,'z'
782 JA NOCONV
783 SUB AL,20H
784NOCONV:
785 RET
786
787ADDFIL:
788ASSUME DS:DG,ES:NOTHING
789 MOV SI,[CURRFIL]
790 MOV CX,[NUMFCBS]
791
792 IF HARDINT
793BWAIT2:
794 CMP [BUSY],0
795 JNZ BWAIT2
796 INC [BUSY]
797 ENDIF
798
799LOOKSPOT:
800 CMP BYTE PTR [SI+2],-1
801 JZ GOTSPOT
802 MOV SI,[SI]
803 LOOP LOOKSPOT
804
805 IF HARDINT
806 MOV [BUSY],0
807 ENDIF
808
809 MOV AL,1
810 JMP SETCOUNT
811
812GOTSPOT:
813 PUSH DS
814 POP ES
815 POP DS
816 PUSH DS
817ASSUME DS:NOTHING
818 PUSH SI
819 MOV DI,SI
820 ADD DI,2
821 MOV SI,DX
822 MOV CX,19
823 REP MOVSW ;Copy in and set FCB
824 POP SI
825 PUSH ES
826 POP DS
827ASSUME DS:DG
828 MOV WORD PTR [SI+2+fcb_EXTENT],0
829 MOV BYTE PTR [SI+2+fcb_NR],0
830 MOV WORD PTR [SI+2+fcb_RECSIZ],BLKSIZ
831
832 IF HARDINT
833 MOV [BUSY],0
834 ENDIF
835
836 XOR AL,AL
837 JMP SETCOUNT
838
839NEXTFIL:
840ASSUME DS:DG,ES:NOTHING
841 MOV SI,[CURRFIL]
842 MOV BYTE PTR [SI+2],-1 ;Done with current file
843 MOV SI,[SI]
844 MOV [CURRFIL],SI
845 MOV [NXTCHR],OFFSET DG:BUFFER + BLKSIZ ;Buffer empty
846 MOV [COLPOS],0 ;Start of line
847 RET
848
849LISTMES:
850ASSUME DS:DG,ES:NOTHING
851 LODSB
852 CMP AL,"$"
853 JZ LMESDONE
854 CALL LOUT
855 JMP LISTMES
856
857LMESDONE:
858 RET
859
860LOUT:
861 PUSH BX
862LWAIT:
863 CALL PSTAT
864 JZ PREADY
865 CMP [ERRCNT],ERRCNT2
866 JA POPRET ;Don't get stuck
867 JMP SHORT LWAIT
868PREADY:
869 CALL POUT
870POPRET:
871 POP BX
872 RET
873
874;Stuff for BIOS interface
875IOBUSY EQU 0200H
876IOERROR EQU 8000H
877
878BYTEBUF DB ?
879
880CALLAD DD ?
881
882IOCALL DB 22
883 DB 0
884IOREQ DB ?
885IOSTAT DW 0
886 DB 8 DUP(?)
887 DB 0
888 DW OFFSET DG:BYTEBUF
889INTSEG DW ?
890IOCNT DW 1
891 DW 0
892
893PSTAT:
894ASSUME DS:DG
895 PUSH BX
896 INC [ERRCNT]
897 MOV BL,10
898 CALL DOCALL
899 TEST [IOSTAT],IOERROR
900 JZ NOSTATERR
901 OR [IOSTAT],IOBUSY ;If error, show buisy
902NOSTATERR:
903 TEST [IOSTAT],IOBUSY
904 JNZ RET13P ;Shows buisy
905 MOV [ERRCNT],0
906RET13P:
907 POP BX
908 RET
909
910POUT:
911ASSUME DS:DG
912 MOV [BYTEBUF],AL
913 MOV BL,8
914DOCALL:
915 PUSH ES
916 MOV [IOREQ],BL
917 MOV BX,CS
918 MOV ES,BX
919 MOV BX,OFFSET DG:IOCALL
920 MOV [IOSTAT],0
921 MOV [IOCNT],1
922 PUSH DS
923 PUSH SI
924 PUSH AX
925 LDS SI,[LISTDEV]
926ASSUME DS:NOTHING
927 MOV AX,[SI+6]
928 MOV WORD PTR [CALLAD],AX
929 CALL [CALLAD]
930 MOV AX,[SI+8]
931 MOV WORD PTR [CALLAD],AX
932 CALL [CALLAD]
933 POP AX
934 POP SI
935 POP DS
936ASSUME DS:DG
937 POP ES
938 RET
939
940 IF IBM
941REAL_INT_13 DD ?
942INT_13_RETADDR DW OFFSET DG:INT_13_BACK
943
944INT_13 PROC FAR
945ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
946 PUSHF
947 INC [BUSY] ;Exclude if dumb program call ROM
948 PUSH CS
949 PUSH [INT_13_RETADDR]
950 PUSH WORD PTR [REAL_INT_13+2]
951 PUSH WORD PTR [REAL_INT_13]
952 RET
953INT_13 ENDP
954
955INT_13_BACK PROC FAR
956 PUSHF
957 DEC [BUSY]
958 POPF
959 RET 2 ;Chuck saved flags
960INT_13_BACK ENDP
961 ENDIF
962
963
964 IF IBM
965
966REAL_INT_5 DD ?
967REAL_INT_17 DD ?
968INT_17_NUM DW 0
969
970INT_17:
971ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
972 PUSH SI
973 MOV SI,[CURRFIL]
974 INC SI
975 INC SI
976 CMP BYTE PTR CS:[SI],-1
977 POP SI
978 JZ DO_INT_17 ;Nothing pending, so OK
979 CMP DX,[INT_17_NUM]
980 JNZ DO_INT_17 ;Not my unit
981 CMP [BUSY],0
982 JNZ DO_INT_17 ;You are me
983 STI
984 MOV AH,0A1H ;You are bad, get out of paper
985 IRET
986
987DO_INT_17:
988 JMP [REAL_INT_17] ;Do a 17
989
990REAL_INT_14 DD ?
991INT_14_NUM DW 0
992
993INT_14:
994ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
995 PUSH SI
996 MOV SI,[CURRFIL]
997 INC SI
998 INC SI
999 CMP BYTE PTR CS:[SI],-1
1000 POP SI
1001 JZ DO_INT_14 ;Nothing pending, so OK
1002 CMP DX,[INT_14_NUM]
1003 JNZ DO_INT_14 ;Not my unit
1004 CMP [BUSY],0
1005 JNZ DO_INT_14 ;You are me
1006 STI
1007 OR AH,AH
1008 JZ SET14_AX
1009 CMP AH,2
1010 JBE SET14_AH
1011SET14_AX:
1012 MOV AL,0
1013SET14_AH:
1014 MOV AH,80H ;Time out
1015 IRET
1016
1017DO_INT_14:
1018 JMP [REAL_INT_14] ;Do a 14
1019
1020INT_5:
1021ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
1022 PUSH SI
1023 MOV SI,[CURRFIL]
1024 INC SI
1025 INC SI
1026 CMP BYTE PTR CS:[SI],-1
1027 POP SI
1028 JZ DO_INT_5 ;Nothing pending, so OK
1029 CMP [INT_17_NUM],0
1030 JNZ DO_INT_5 ;Only care about unit 0
1031 IRET ;Pretend it worked
1032
1033DO_INT_5:
1034 JMP [REAL_INT_5] ;Do a 5
1035 ENDIF
1036
1037
1038;The following data is order and position dependant
1039NUMFCBS DW 10
1040ERRCNT DW 0
1041
1042SPLFCB DW OFFSET DG:FC1
1043 DB (FCBSIZ - 2) DUP (-1)
1044FC1 DW OFFSET DG:FC2
1045 DB (FCBSIZ - 2) DUP (-1)
1046FC2 DW OFFSET DG:FC3
1047 DB (FCBSIZ - 2) DUP (-1)
1048FC3 DW OFFSET DG:FC4
1049 DB (FCBSIZ - 2) DUP (-1)
1050FC4 DW OFFSET DG:FC5
1051 DB (FCBSIZ - 2) DUP (-1)
1052FC5 DW OFFSET DG:FC6
1053 DB (FCBSIZ - 2) DUP (-1)
1054FC6 DW OFFSET DG:FC7
1055 DB (FCBSIZ - 2) DUP (-1)
1056FC7 DW OFFSET DG:FC8
1057 DB (FCBSIZ - 2) DUP (-1)
1058FC8 DW OFFSET DG:FC9
1059 DB (FCBSIZ - 2) DUP (-1)
1060FC9 DW OFFSET DG:SPLFCB
1061 DB (FCBSIZ - 2) DUP (-1)
1062
1063DEF_ENDRES LABEL BYTE
1064
1065ASSUME CS:DG,DS:DG,ES:DG,SS:DG
1066
1067BADSPOOL:
1068 MOV DX,OFFSET DG:BADMES
1069 MOV AH,STD_CON_STRING_OUTPUT
1070 INT 21H
1071 INT 20H
1072
1073SETUP:
1074;Called once to install resident
1075 CLD
1076 MOV [INTSEG],CS
1077 MOV DX,OFFSET DG:PROMPT
1078 MOV AH,STD_CON_STRING_OUTPUT
1079 INT 21H
1080 MOV DX,OFFSET DG:COMBUF
1081 MOV AH,STD_CON_STRING_INPUT
1082 INT 21H ;Get device name
1083 MOV DX,OFFSET DG:CRLF
1084 MOV AH,STD_CON_STRING_OUTPUT
1085 INT 21H
1086 MOV CL,[COMBUF+1]
1087 OR CL,CL
1088 JZ DEFSPOOL ;User didn't specify one
1089 XOR CH,CH
1090 MOV DI,OFFSET DG:LISTFCB + 1
1091 MOV SI,OFFSET DG:COMBUF + 2
1092 REP MOVSB
1093DEFSPOOL:
1094 MOV DX,OFFSET DG:LISTFCB
1095 MOV AH,FCB_OPEN
1096 INT 21H
1097 OR AL,AL
1098 JNZ BADSPOOL ;Bad
1099 TEST BYTE PTR [LISTFCB.fcb_DEVID],080H
1100 JZ BADSPOOL ;Must be a device
1101 LDS SI,DWORD PTR [LISTFCB.fcb_FIRCLUS]
1102ASSUME DS:NOTHING
1103 MOV WORD PTR [CALLAD+2],DS ;Get I/O routines
1104 MOV WORD PTR [LISTDEV+2],DS ;Get I/O routines
1105 MOV WORD PTR [LISTDEV],SI
1106 PUSH CS
1107 POP DS
1108ASSUME DS:DG
1109 MOV DX,OFFSET DG:SPINT
1110 MOV AL,SOFTINT
1111 MOV AH,GET_INTERRUPT_VECTOR
1112 INT 21H ;Get soft vector
1113 MOV WORD PTR [SPNEXT+2],ES
1114 MOV WORD PTR [SPNEXT],BX
1115 MOV AL,SOFTINT
1116 MOV AH,SET_INTERRUPT_VECTOR
1117 INT 21H ;Set soft vector
1118 MOV DX,OFFSET DG:SPCOMINT
1119 MOV AL,COMINT
1120 MOV AH,SET_INTERRUPT_VECTOR ;Set communication vector
1121 INT 21H
1122
1123 IF IBM
1124 MOV AL,13H
1125 MOV AH,GET_INTERRUPT_VECTOR
1126 INT 21H
1127 MOV WORD PTR [REAL_INT_13+2],ES
1128 MOV WORD PTR [REAL_INT_13],BX
1129 MOV DX,OFFSET DG:INT_13
1130 MOV AL,13H
1131 MOV AH,SET_INTERRUPT_VECTOR
1132 INT 21H ;Set diskI/O interrupt
1133 MOV AL,17H
1134 MOV AH,GET_INTERRUPT_VECTOR
1135 INT 21H
1136 MOV WORD PTR [REAL_INT_17+2],ES
1137 MOV WORD PTR [REAL_INT_17],BX
1138 MOV AL,14H
1139 MOV AH,GET_INTERRUPT_VECTOR
1140 INT 21H
1141 MOV WORD PTR [REAL_INT_14+2],ES
1142 MOV WORD PTR [REAL_INT_14],BX
1143 MOV AL,5H
1144 MOV AH,GET_INTERRUPT_VECTOR
1145 INT 21H
1146 MOV WORD PTR [REAL_INT_5+2],ES
1147 MOV WORD PTR [REAL_INT_5],BX
1148 PUSH CS
1149 POP ES
1150 MOV BP,OFFSET DG:LISTFCB + 1
1151 MOV SI,BP
1152 MOV CX,8
1153CONLP: ;Make sure device name in upper case
1154 LODSB
1155 CMP AL,'a'
1156 JB DOCONLP
1157 CMP AL,'z'
1158 JA DOCONLP
1159 SUB BYTE PTR [SI-1],20H
1160DOCONLP:
1161 LOOP CONLP
1162 MOV DI,OFFSET DG:INT_17_HITLIST
1163CHKHIT:
1164 MOV SI,BP
1165 MOV CL,[DI]
1166 INC DI
1167 JCXZ NOTONHITLIST
1168 REPE CMPSB
1169 LAHF
1170 ADD DI,CX ;Bump to next position without affecting flags
1171 MOV BL,[DI] ;Get device number
1172 INC DI
1173 SAHF
1174 JNZ CHKHIT
1175 XOR BH,BH
1176 MOV [INT_17_NUM],BX
1177 MOV DX,OFFSET DG:INT_17
1178 MOV AL,17H
1179 MOV AH,SET_INTERRUPT_VECTOR
1180 INT 21H ;Set printer interrupt
1181 MOV DX,OFFSET DG:INT_5
1182 MOV AL,5H
1183 MOV AH,SET_INTERRUPT_VECTOR
1184 INT 21H ;Set print screen interrupt
1185 JMP SHORT ALLSET
1186NOTONHITLIST:
1187 MOV DI,OFFSET DG:INT_14_HITLIST
1188CHKHIT2:
1189 MOV SI,BP
1190 MOV CL,[DI]
1191 INC DI
1192 JCXZ ALLSET
1193 REPE CMPSB
1194 LAHF
1195 ADD DI,CX ;Bump to next position without affecting flags
1196 MOV BL,[DI] ;Get device number
1197 INC DI
1198 SAHF
1199 JNZ CHKHIT2
1200 XOR BH,BH
1201 MOV [INT_14_NUM],BX
1202 MOV DX,OFFSET DG:INT_14
1203 MOV AL,14H
1204 MOV AH,SET_INTERRUPT_VECTOR
1205 INT 21H ;Set RS232 port interrupt
1206ALLSET:
1207 ENDIF
1208
1209 IF HARDINT
1210 MOV AH,GET_INDOS_FLAG
1211 INT 21H
1212 MOV WORD PTR [INDOS+2],ES ;Get indos flag location
1213 MOV WORD PTR [INDOS],BX
1214 MOV AL,INTLOC
1215 MOV AH,GET_INTERRUPT_VECTOR
1216 INT 21H
1217 MOV WORD PTR [NEXTINT+2],ES
1218 MOV WORD PTR [NEXTINT],BX
1219 MOV DX,OFFSET DG:HDSPINT
1220 MOV AL,INTLOC
1221 MOV AH,SET_INTERRUPT_VECTOR
1222 INT 21H ;Set hardware interrupt
1223 ENDIF
1224
1225 MOV [MAKERES],1 ;Indicate to do a terminate stay resident
1226 MOV DX,OFFSET DG:GOODMES
1227 MOV AH,STD_CON_STRING_OUTPUT
1228 INT 21H
1229 RET
1230
1231ASSUME CS:DG,DS:DG,ES:DG,SS:DG
1232
1233TRANSIENT:
1234;User interface
1235 CLD
1236
1237;Code to print header
1238; MOV DX,OFFSET DG:HEADER
1239; MOV AH,STD_CON_STRING_OUTPUT
1240; INT 21H
1241
1242DOSVER_LOW EQU 0136H ;1.54 in hex
1243DOSVER_HIGH EQU 020BH ;2.11 in hex
1244 MOV AH,GET_VERSION
1245 INT 21H
1246 XCHG AH,AL ;Turn it around to AH.AL
1247 CMP AX,DOSVER_LOW
1248 JB GOTBADDOS
1249 CMP AX,DOSVER_HIGH
1250 JBE OKDOS
1251GOTBADDOS:
1252 PUSH CS
1253 POP DS
1254 MOV DX,OFFSET DG:BADVER
1255 MOV AH,STD_CON_STRING_OUTPUT
1256 INT 21H
1257 INT 20H
1258OKDOS:
1259 MOV AX,CHAR_OPER SHL 8
1260 INT 21H
1261 MOV [SWITCHAR],DL ;Get user switch character
1262 MOV AH,GET_INTERRUPT_VECTOR
1263 MOV AL,COMINT
1264 INT 21H
1265ASSUME ES:NOTHING
1266 MOV DI,BX
1267 MOV SI,OFFSET DG:SPCOMINT
1268 MOV CX,13
1269 REPE CMPSB
1270 JZ GOTRES ;Signature matched
1271 PUSH CS
1272 POP ES
1273 CALL SETUP
1274GOTRES:
1275 PUSH CS
1276 POP ES
1277 MOV AH,GET_DEFAULT_DRIVE
1278 INT 21H
1279 MOV [DEFDRV],AL
1280 MOV SI,PARMS
1281 LODSB
1282 OR AL,AL
1283 JNZ GOTPARMS
1284TRANEXIT:
1285 CALL GETSPLIST
1286 CMP [MAKERES],0
1287 JNZ SETRES
1288 INT 20H
1289
1290SETRES:
1291 MOV DX,[ENDRES]
1292 INT 27H
1293
1294ARGSDONE:
1295 CMP [ARGSETUP],0
1296 JZ TRANEXIT
1297 CALL PROCESS
1298 JMP SHORT TRANEXIT
1299
1300GOTPARMS:
1301PARSE:
1302 MOV DI,OFFSET DG:PARSEBUF
1303 CALL CPARSE
1304 JC ARGSDONE
1305 CMP AX,4 ;Switch?
1306 JNZ GOTNORMARG
1307 MOV AL,[DI] ;Get the switch character
1308 CMP AL,'C'
1309 JZ SETCAN
1310 CMP AL,'c'
1311 JNZ CHKSPL
1312SETCAN:
1313 MOV [CANFLG],1
1314 JMP SHORT PARSE
1315CHKSPL:
1316 CMP AL,'P'
1317 JZ RESETCAN
1318 CMP AL,'p'
1319 JNZ CHKTERM
1320RESETCAN:
1321 MOV [CANFLG],0
1322 JMP SHORT PARSE
1323CHKTERM:
1324 CMP AL,'T'
1325 JZ SETTERM
1326 CMP AL,'t'
1327 JZ SETTERM
1328 MOV DX,OFFSET DG:BADSWT
1329 MOV AH,STD_CON_STRING_OUTPUT
1330 INT 21H
1331 JMP SHORT PARSE
1332
1333SETTERM:
1334 CALL TERMPROCESS
1335 JMP TRANEXIT ; Ignore everything after T switch
1336
1337GOTNORMARG:
1338 XOR AL,AL
1339 XCHG AL,[ARGSETUP]
1340 OR AL,AL
1341 JZ PARSEARG
1342 CALL NORMPROC ;Don't test ARGSETUP, it just got zeroed
1343PARSEARG:
1344 PUSH SI
1345 MOV SI,DI
1346 MOV DI,FCB
1347 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 1
1348 INT 21H ;Parse the arg
1349 CMP BYTE PTR [DI],0
1350 JNZ DRVOK
1351 MOV DL,[DEFDRV]
1352 INC DL
1353 MOV BYTE PTR [DI],DL ;Set the default drive
1354DRVOK:
1355 POP SI
1356 INC [ARGSETUP]
1357 JMP SHORT PARSE
1358
1359TERMPROCESS:
1360 MOV DX,-1
1361PROCRET:
1362 MOV AH,1
1363 CALL DOSET
1364PROCRETNFUNC:
1365 MOV [ARGSETUP],0
1366 PUSH CS
1367 POP ES
1368RET14: RET
1369
1370PROCESS:
1371 CMP [ARGSETUP],0
1372 JZ RET14 ;Nothing to process
1373NORMPROC:
1374 MOV AL,BYTE PTR DS:[FCB+1]
1375 CMP AL," "
1376 JZ SRCHBADJ
1377 MOV DX,FCB
1378 MOV AH,[CANFLG]
1379 CMP AH,0
1380 JNZ PROCRET
1381 MOV DX,OFFSET DG:SRCHFCB
1382 MOV AH,SET_DMA
1383 INT 21H
1384 MOV DX,FCB
1385 MOV AH,DIR_SEARCH_FIRST
1386 INT 21H
1387 OR AL,AL
1388 JNZ SRCHBADJ
1389SRCHLOOP:
1390 MOV DX,OFFSET DG:SRCHFCB
1391 MOV AH,FCB_OPEN
1392 INT 21H
1393 OR AL,AL
1394 JZ OPENOK
1395 CALL OPENERR
1396 JMP SHORT NEXTSEARCH
1397SRCHBADJ: JMP SRCHBAD
1398OPENOK:
1399 MOV DX,OFFSET DG:SRCHFCB
1400 MOV AH,0
1401 CALL DOSET
1402 OR AL,AL
1403 JZ NEXTSEARCH
1404 XCHG AL,[FULLFLAG] ;Know AL non-zero
1405 OR AL,AL
1406 JNZ NEXTSEARCH ;Only print message once
1407 MOV DX,OFFSET DG:FULLMES ;Queue full
1408 MOV AH,STD_CON_STRING_OUTPUT
1409 INT 21H
1410NEXTSEARCH:
1411 MOV DX,OFFSET DG:SRCHFCB
1412 MOV AH,SET_DMA
1413 INT 21H
1414 MOV DX,FCB
1415 MOV AH,DIR_SEARCH_NEXT
1416 INT 21H
1417 OR AL,AL
1418 JNZ PROCRETNFUNC
1419 JMP SRCHLOOP
1420
1421DOSET:
1422 INT COMINT
1423 MOV [FILCNT],AH ;Suck up return info
1424 MOV WORD PTR [SPLIST+2],ES
1425 MOV WORD PTR [CURFILE+2],ES
1426 MOV WORD PTR [SPLIST],BX
1427 MOV WORD PTR [CURFILE],DX
1428 RET
1429
1430OPENERR:
1431 PUSH SI
1432 PUSH DI
1433 MOV SI,OFFSET DG:OPFILNAM
1434 PUSH DS
1435 POP ES
1436 MOV DI,OFFSET DG:SRCHFCB
1437 CALL MVFNAM
1438 MOV DX,OFFSET DG:OPMES
1439 MOV AH,STD_CON_STRING_OUTPUT
1440 INT 21H
1441 POP DI
1442 POP SI
1443 RET
1444
1445SRCHBAD:
1446 PUSH SI
1447 PUSH DI
1448 MOV SI,OFFSET DG:SRCHFNAM
1449 PUSH DS
1450 POP ES
1451 MOV DI,FCB
1452 CALL MVFNAM
1453 MOV DX,OFFSET DG:SRCHMES
1454 MOV AH,STD_CON_STRING_OUTPUT
1455 INT 21H
1456 POP DI
1457 POP SI
1458 JMP PROCRETNFUNC
1459
1460GETSPLIST:
1461 MOV AH,0FFH
1462 CALL DOSET
1463 PUSH DS
1464 LDS DI,[SPLIST]
1465 MOV DI,[DI-2] ;Get the error count
1466 POP DS
1467 CMP DI,ERRCNT1
1468 JB CNTOK
1469 MOV DX,OFFSET DG:CNTMES
1470 MOV AH,STD_CON_STRING_OUTPUT
1471 INT 21H
1472CNTOK:
1473 MOV CL,[FILCNT]
1474 OR CL,CL
1475 JZ NOFILES
1476 XOR CH,CH
1477 LES DI,[CURFILE]
1478 PUSH DI
1479 INC DI
1480 INC DI
1481 MOV SI,OFFSET DG:CURFNAM
1482 CALL MVFNAM
1483 POP DI
1484 MOV DX,OFFSET DG:CURMES
1485 MOV AH,STD_CON_STRING_OUTPUT
1486 INT 21H
1487 DEC CX
1488 JCXZ RET12
1489FILOOP:
1490 MOV DI,ES:[DI]
1491 PUSH DI
1492 INC DI
1493 INC DI
1494 MOV SI,OFFSET DG:FILFNAM
1495 CALL MVFNAM
1496 POP DI
1497 MOV DX,OFFSET DG:FILMES
1498 MOV AH,STD_CON_STRING_OUTPUT
1499 INT 21H
1500 LOOP FILOOP
1501RET12: RET
1502
1503NOFILES:
1504 MOV DX,OFFSET DG:NOFILS
1505 MOV AH,STD_CON_STRING_OUTPUT
1506 INT 21H
1507 RET
1508
1509;Make a message with the file name
1510MVFNAM:
1511ASSUME DS:NOTHING,ES:NOTHING
1512 PUSH SI
1513 PUSH DI
1514 PUSH CX
1515 MOV AX,ES
1516 PUSH DS
1517 POP ES
1518 MOV DS,AX
1519 XCHG SI,DI
1520 LODSB
1521 ADD AL,"@"
1522 CMP AL,"@"
1523 JNZ STCHR
1524 MOV AL,[DEFDRV]
1525 ADD AL,"A"
1526STCHR:
1527 STOSB
1528 INC DI
1529 MOV CX,4
1530 REP MOVSW
1531 INC DI
1532 MOVSW
1533 MOVSB
1534 MOV AX,ES
1535 PUSH DS
1536 POP ES
1537 MOV DS,AX
1538 POP CX
1539 POP DI
1540 POP SI
1541 RET
1542
1543;-----------------------------------------------------------------------;
1544; ENTRY: ;
1545; DS:SI Points input buffer ;
1546; ES:DI Points to the token buffer ;
1547; ;
1548; EXIT: ;
1549; DS:SI Points to next char in the input buffer ;
1550; ES:DI Points to the token buffer ;
1551; CX Character count ;
1552; AX Condition Code ;
1553; =1 same as carry set ;
1554; =2 normal token ;
1555; =4 switch character, char in token buffer ;
1556; Carry Flag Set if a CR was found, Reset otherwise ;
1557; ;
1558; MODIFIES: ;
1559; CX, SI, AX and the Carry Flag ;
1560; ;
1561;-----------------------------------------------------------------------;
1562
1563TAB equ 09h
1564CR equ 0dh
1565
1566CPARSE:
1567ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
1568 pushf ;save flags
1569 push di ;save the token buffer addrss
1570 xor cx,cx ;no chars in token buffer
1571 call kill_bl
1572
1573 cmp al,CR ;a CR?
1574 jne sj2 ;no, skip
1575sj1:
1576 mov ax,1 ;condition code
1577 dec si ;adjust the pointer
1578 pop di ;retrive token buffer address
1579 popf ;restore flags
1580 stc ;set the carry bit
1581 ret
1582
1583sj2:
1584 mov dl,[SWITCHAR]
1585 cmp al,dl ;is the char the switch char?
1586 jne anum_char ;no, process...
1587 call kill_bl
1588 cmp al,CR ;a CR?
1589 je sj1 ;yes, error exit
1590 call move_char ;Put the switch char in the token buffer
1591 mov ax,4 ;Flag switch
1592 jmp short x_done2
1593
1594anum_char:
1595 call move_char ;just an alphanum string
1596 lodsb
1597 cmp al,' '
1598 je x_done
1599 cmp al,tab
1600 je x_done
1601 cmp al,CR
1602 je x_done
1603 cmp al,','
1604 je x_done
1605 cmp al,'='
1606 je x_done
1607 cmp al,dl ;Switch character
1608 jne anum_char
1609x_done:
1610 dec si ;adjust for next round
1611 mov ax,2 ;normal token
1612x_done2:
1613 push ax ;save condition code
1614 mov al,0
1615 stosb ;null at the end
1616 pop ax
1617 pop di ;restore token buffer pointer
1618 popf
1619 clc ;clear carry flag
1620 ret
1621
1622
1623kill_bl proc near
1624 lodsb
1625 cmp al,' '
1626 je kill_bl
1627 cmp al,tab
1628 je kill_bl
1629 cmp al,',' ;a comma?
1630 je kill_bl
1631 cmp al,'='
1632 je kill_bl
1633 ret
1634kill_bl endp
1635
1636
1637move_char proc near
1638 stosb ;store char in token buffer
1639 inc cx ;increment char count
1640 ret
1641move_char endp
1642
1643CODE ENDS
1644 END START
1645 \ No newline at end of file
diff --git a/v2.0/source/PROC.ASM b/v2.0/source/PROC.ASM
new file mode 100644
index 0000000..abc6f9c
--- /dev/null
+++ b/v2.0/source/PROC.ASM
@@ -0,0 +1,130 @@
1;
2; process control system calls for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17 i_need CurrentPDB,WORD
18 i_need CreatePDB,BYTE
19 i_need NUMIO,BYTE
20 i_need Exit_type,BYTE
21 i_need INDOS,BYTE
22 i_need DMAADD,DWORD
23 i_need DidCTRLC,BYTE
24
25SUBTTL $WAIT - return previous process error code
26PAGE
27;
28; process control data
29;
30 i_need exit_code,WORD ; code of exit
31
32;
33; Assembler usage:
34; MOV AH, Wait
35; INT int_command
36; AX has the exit code
37 procedure $WAIT,NEAR
38 ASSUME DS:NOTHING,ES:NOTHING
39 MOV AX,[exit_code]
40 XOR DX,DX
41 MOV [exit_code],DX
42 transfer SYS_RET_OK
43$WAIT ENDP
44
45IF IBM
46 procedure $EXEC,NEAR
47 error error_invalid_function
48$EXEC ENDP
49ENDIF
50IF NOT IBM
51INCLUDE EXEC.ASM
52ENDIF
53
54SUBTTL Terminate and stay resident handler
55PAGE
56;
57; Input: DX is an offset from CurrentPDB at which to
58; truncate the current block.
59;
60; output: The current block is truncated (expanded) to be [DX+15]/16
61; paragraphs long. An exit is simulated via resetting CurrentPDB
62; and restoring the vectors.
63;
64 procedure $Keep_process,NEAR
65 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
66
67 PUSH AX ; keep exit code around
68 MOV BYTE PTR [Exit_type],Exit_keep_process
69 MOV ES,[CurrentPDB]
70 CMP DX,6h ; keep enough space around for system
71 JAE Keep_shrink ; info
72 MOV DX,6h
73keep_shrink:
74 MOV BX,DX
75 PUSH BX
76 PUSH ES
77 invoke $SETBLOCK ; ignore return codes.
78 POP DS
79 POP BX
80 JC keep_done ; failed on modification
81 MOV AX,DS
82 ADD AX,BX
83 MOV DS:[PDB_block_len],AX
84
85keep_done:
86 POP AX
87 JMP SHORT exit_inner ; and let abort take care of the rest
88
89$Keep_process ENDP
90
91 procedure Stay_resident,NEAR
92 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
93 MOV AX,(Keep_process SHL 8) + 0 ; Lower part is return code
94 ADD DX,15
95 MOV CL,4
96 SHR DX,CL
97
98 transfer COMMAND
99Stay_resident ENDP
100
101SUBTTL $EXIT - return to parent process
102PAGE
103;
104; Assembler usage:
105; MOV AL, code
106; MOV AH, Exit
107; INT int_command
108; Error return:
109; None.
110;
111 procedure $EXIT,NEAR
112 ASSUME DS:NOTHING,ES:NOTHING,SS:DOSGROUP
113 XOR AH,AH
114 XCHG AH,BYTE PTR [DidCTRLC]
115 OR AH,AH
116 MOV BYTE PTR [Exit_type],exit_terminate
117 JZ exit_inner
118 MOV BYTE PTR [Exit_type],exit_ctrl_c
119
120Exit_inner:
121 invoke get_user_stack
122 PUSH [CurrentPDB]
123 POP [SI.user_CS]
124 transfer abort_inner
125$EXIT ENDP
126
127do_ext
128
129CODE ENDS
130 END
diff --git a/v2.0/source/PROFIL.ASM b/v2.0/source/PROFIL.ASM
new file mode 100644
index 0000000..08a5ada
--- /dev/null
+++ b/v2.0/source/PROFIL.ASM
@@ -0,0 +1,705 @@
1 TITLE PROFIL - MS-DOS Profile program
2
3;Profiler for MS-DOS 1.25 2.00
4;
5; Lots of stuff stolen from debug.
6; User provides # of paragraphs per bucket, program is cut up accordingly.
7; User also specifies clock interval
8
9
10;System calls
11PRINTBUF EQU 9
12SETDMA EQU 26
13CREATE EQU 22
14OPEN EQU 15
15CLOSE EQU 16
16GETBUF EQU 10
17BLKWRT EQU 40
18BLKRD EQU 39
19OUTCH EQU 2
20SETBASE EQU 38
21
22FCB EQU 5CH
23BUFLEN EQU 80
24
25; FCB offsets
26RR EQU 33
27RECLEN EQU 14
28FILELEN EQU 16
29
30
31;Segments in load order
32
33CODE SEGMENT PUBLIC
34CODE ENDS
35
36DATA SEGMENT BYTE
37DATA ENDS
38
39INIT SEGMENT BYTE
40INIT ENDS
41
42DG GROUP CODE,DATA,INIT
43
44;The data segment
45
46DATA SEGMENT BYTE
47 ORG 0
48ENDMES DB 13,10,"Program terminated normally",13,10,"$"
49ABORTMES DB 13,10,"Program aborted",13,10,"$"
50TOOBIG DB "Program too big",13,10,"$"
51EXEBAD DB "EXE file bad",13,10,"$"
52
53OUT_FCB LABEL WORD
54 DB 0
55OUTNAME DB " PRF"
56 DB 30 DUP(0)
57
58 DB 80H DUP(?)
59STACK LABEL WORD
60
61BYTEBUF DB BUFLEN DUP(?) ;Processed input queue
62AXSAVE DW ? ;See interrupt routine
63BXSAVE DW ? ; " " "
64PROG_AREA DW ? ;Segment of program start
65
66;EXE file header
67RUNVAR LABEL WORD
68RELPT DW ?
69LASTP LABEL WORD
70RELSEG DW ?
71PSIZE LABEL WORD
72PAGES DW ?
73RELCNT DW ?
74HEADSIZ DW ?
75 DW ?
76LOADLOW DW ?
77PROG_SS LABEL WORD ;Program stack seg
78INITSS DW ?
79PROG_SP LABEL WORD ;Program SP
80INITSP DW ?
81 DW ?
82PROG_ENTRY EQU THIS DWORD
83PROG_RA LABEL WORD ;Program start offset
84INITIP DW ?
85PROG_SA LABEL WORD ;Program start segment (may be different from PROG_AREA)
86INITCS DW ?
87RELTAB DW ?
88RUNVARSIZ EQU $-RUNVAR
89
90EXEFILE DB 0 ;Flag to indicate EXE file
91DRV_VALID DW ? ;Init for AX register
92OUTPUT_DATA LABEL WORD ;Start of the profile data
93CLOCK_GRAIN DW ? ;Clock interval micro-seconds
94BUCKET_NUM DW ? ;Number of buckets
95BUCKET_SIZE DW ? ;Paragraphs per bucket
96PROG_LOW_PA DW ? ;Start of program (PARA #)
97PROG_HIGH_PA DW ? ;End of program (PARA #)
98DOS_PA DW ? ;IO-DOS PARA boundry
99HIT_IO DW 0 ;IO bucket
100HIT_DOS DW 0 ;DOS bucket
101HIT_HIGH DW 0 ;Above Program bucket
102NUM_DATA_WORDS EQU ($-OUTPUT_DATA)/2 ;Number of word items
103BUCKET LABEL WORD ;Bucket count area
104
105;The following data will be overwritten when the buckets are initialized
106LINEBUF DB BUFLEN,1,0DH ;Raw input buffer
107 DB BUFLEN DUP(?)
108
109NOFILE DB "File not found",13,10,"$"
110OUTERR DB "Cannot open output file",13,10,"$"
111GRAIN_PROMPT DB "Sample time (micro-sec) >= 60 ? ","$"
112SIZE_PROMPT DB "Number of paragraphs (16 bytes) per bucket? ","$"
113PARAM_PROMPT DB "Parameters to program? ","$"
114DATA ENDS
115
116;The resident code portion
117CODE SEGMENT PUBLIC
118ASSUME CS:DG,DS:DG,ES:DG,SS:DG
119
120;The clock interrupt routine
121 PUBLIC CLK_INTER
122
123;Stuff provided by external clock handler routine
124 EXTRN CLOCKON:NEAR,CLOCKOFF:NEAR,LEAVE_INT:NEAR
125
126 ORG 100H
127START:
128 CLD
129 MOV SP,OFFSET DG:STACK ;Use internal stack
130 CALL SETUP
131;The following setup stuff cannot be done in SETUP because we're probably
132; overwritting the INIT area
133 MOV DX,[PROG_AREA]
134 MOV AH,SETBASE
135 INT 21H ;Set base for program
136 MOV ES,[PROG_AREA]
137 PUSH SI ;Points to BYTEBUF
138 MOV DI,81H ;Set unformatted params
139COMTAIL:
140 LODSB
141 STOSB
142 CMP AL,13
143 JNZ COMTAIL
144 SUB DI,82H ;Figure length
145 XCHG AX,DI
146 MOV BYTE PTR ES:[80H],AL
147 POP SI
148 MOV DI,FCB ;First param
149 MOV AX,2901H
150 INT 21H
151 MOV BYTE PTR [DRV_VALID],AL
152 MOV AX,2901H
153 MOV DI,6CH ;Second param
154 INT 21H
155 MOV BYTE PTR [DRV_VALID+1],AL
156
157 MOV AX,ES ;Prog segment to AX
158 MOV DX,[PROG_RA] ;Offset
159 CMP [EXEFILE],1
160 JZ EXELOAD ;EXE file
161 JMP BINFIL ;Regular file (.COM)
162
163EXELOAD:
164 MOV AX,[HEADSIZ] ;Size of header in paragraphs
165 ADD AX,31
166 MOV CL,4
167 ROL AX,CL ;Size in bytes
168 MOV BX,AX
169 AND AX,0FE00H
170 AND BX,0FH
171 MOV WORD PTR DS:[FCB+RR],AX ;Position in file of program
172 MOV WORD PTR DS:[FCB+RR+2],BX ;Record size
173 MOV DX,[PAGES] ;Size in 512 byte blocks
174 DEC DX
175 XCHG DH,DL
176 ROL DX,1
177 MOV DI,DX
178 MOV SI,DX
179 AND DI,0FE00H
180 AND SI,1FFH
181 SUB DI,AX
182 SBB SI,BX
183 MOV AX,[LASTP]
184 OR AX,AX
185 JNZ PARTP
186 MOV AX,200H
187PARTP:
188 ADD DI,AX
189 ADC SI,0
190 MOV AX,DI
191 ADD AX,15
192 AND AL,0F0H
193 OR AX,SI
194 MOV CL,4
195 ROR AX,CL
196 XCHG AX,CX
197 MOV BX,[PROG_AREA]
198 ADD BX,10H
199 MOV AX,WORD PTR DS:[2]
200 SUB AX,CX
201 MOV DX,OFFSET DG:TOOBIG
202 JB ERROR
203 CMP BX,AX
204 JA ERROR
205 CMP [LOADLOW],-1
206 JNZ LOADEXE
207 XCHG AX,BX
208LOADEXE:
209 MOV BP,AX
210 XOR DX,DX
211 CALL READ
212 JC HAVEXE
213BADEXE:
214 MOV DX,OFFSET DG:EXEBAD
215
216ERROR:
217 MOV AH,PRINTBUF ;Print the message in DX
218 INT 21H
219 INT 20H ;Exit
220
221HAVEXE:
222 MOV AX,[RELTAB] ;Get position of relocation table
223 MOV WORD PTR DS:[FCB+RR],AX
224 MOV WORD PTR DS:[FCB+RR+2],0
225 MOV DX,OFFSET DG:RELPT ;Four byte buffer
226 MOV AH,SETDMA
227 INT 21H
228 CMP [RELCNT],0
229 JZ NOREL
230RELOC:
231 MOV AH,BLKRD
232 MOV DX,FCB
233 MOV CX,4
234 INT 21H ;Read in one relocation pointer
235 OR AL,AL
236 JNZ BADEXE
237 MOV DI,[RELPT] ;Pointer offset
238 MOV AX,[RELSEG] ;pointer segment
239 ADD AX,BP ;Bias with actual load segment
240 MOV ES,AX
241 ADD ES:[DI],BP ;Relocate
242 DEC [RELCNT]
243 JNZ RELOC
244
245NOREL:
246 ADD [INITSS],BP
247 ADD [INITCS],BP
248 JMP SHORT PROGGO
249
250BINFIL:
251 MOV WORD PTR DS:[FCB+RECLEN],1
252 MOV SI,-1
253 MOV DI,SI
254 CALL READ
255 MOV ES,[PROG_SA] ;Prog segment to ES
256 MOV AX,WORD PTR ES:[6]
257 MOV [PROG_SP],AX ;Default SP for non EXE files
258 DEC AH
259 MOV WORD PTR ES:[6],AX ;Fix size
260
261PROGGO:
262 PUSH DS
263 MOV AX,[PROG_AREA]
264 MOV DS,AX
265 MOV DX,80H
266 MOV AH,SETDMA
267 INT 21H ;Set default disk transfer address
268 POP DS
269 MOV BX,[BUCKET_NUM]
270 SHL BX,1 ;Mult by 2 to get #bytes in bucket area
271CLEAR:
272 MOV BUCKET[BX],0 ;Zero counts
273 SUB BX,2
274 JGE CLEAR
275 MOV DX,[CLOCK_GRAIN]
276 PUSH DS
277 POP ES
278 CLI ;Don't collect data yet
279 CALL CLOCKON ;Set the interrupt
280 MOV SI,[PROG_RA]
281 MOV DI,[PROG_AREA]
282 MOV BX,[PROG_SS]
283 MOV CX,[PROG_SP]
284 MOV AX,[DRV_VALID]
285 MOV DX,[PROG_SA]
286 MOV SS,BX
287 MOV SP,CX
288 XOR CX,CX
289 PUSH CX ;0 on prog stack
290 PUSH DX
291 PUSH SI
292 MOV DS,DI ;Set up segments
293 MOV ES,DI
294 STI ;Start collecting data
295XXX PROC FAR
296 RET ;Hop to program
297XXX ENDP
298
299READ:
300; AX:DX is disk transfer address (segment:offset)
301; SI:DI is 32 bit length
302
303RDLOOP:
304 MOV BX,DX
305 AND DX,000FH
306 MOV CL,4
307 SHR BX,CL
308 ADD AX,BX
309 PUSH AX
310 PUSH DX
311 PUSH DS
312 MOV DS,AX
313 MOV AH,SETDMA
314 INT 21H
315 POP DS
316 MOV DX,FCB
317 MOV CX,0FFF0H ;Keep request in segment
318 OR SI,SI ;Need > 64K?
319 JNZ BIGRD
320 MOV CX,DI ;Limit to amount requested
321BIGRD:
322 MOV AH,BLKRD
323 INT 21H
324 SUB DI,CX ;Subtract off amount done
325 SBB SI,0 ;Ripple carry
326 CMP AL,1 ;EOF?
327 POP DX
328 POP AX ;Restore transfer address
329 JZ RET10
330 ADD DX,CX ;Bump transfer address by last read
331 MOV BX,SI
332 OR BX,DI ;Finished with request
333 JNZ RDLOOP
334RET10: STC
335 RET
336
337
338;Return here on termination or abort
339
340TERMINATE:
341 CLI ;Stop collecting data
342 MOV DX,OFFSET DG:ENDMES
343 JMP SHORT WRITEOUT
344ABORT:
345 CLI ;Stop collecting data
346 MOV DX,OFFSET DG:ABORTMES
347WRITEOUT:
348 MOV AX,CS
349 MOV DS,AX
350 MOV SS,AX
351 MOV SP,OFFSET DG:STACK ;Use internal stack
352 PUSH DX
353 CALL CLOCKOFF ;Restore original clock routine
354 STI ;Back to normal clock
355 POP DX
356 MOV AH,PRINTBUF
357 INT 21H ;Apropriate termination message
358 MOV [OUT_FCB+14],2 ;Word size records
359 MOV DX,OFFSET DG:OUTPUT_DATA
360 MOV AH,SETDMA
361 INT 21H ;Set the transfer address
362 MOV CX,NUM_DATA_WORDS
363 ADD CX,[BUCKET_NUM]
364 MOV DX,OFFSET DG:OUT_FCB
365 MOV AH,BLKWRT
366 INT 21H ;Write out data
367 MOV DX,OFFSET DG:OUT_FCB
368 MOV AH,CLOSE
369 INT 21H
370 INT 20H ;Exit
371
372
373;The clock interrupt routine
374CLK_INTER PROC NEAR
375 CLI
376 PUSH DS
377 PUSH CS
378 POP DS ;Get profile segment
379 MOV [AXSAVE],AX
380 MOV [BXSAVE],BX
381 POP AX ;old DS
382 MOV BX,OFFSET DG:LEAVE_INT
383 PUSH BX
384 PUSH AX
385 PUSH ES
386 PUSH [AXSAVE]
387 PUSH [BXSAVE]
388 PUSH CX
389 PUSH DX
390
391
392;Stack looks like this
393;
394; +18 OLDFLAGS
395; +16 OLDCS
396; +14 OLDIP
397; +12 RETURN TO LEAVE_INT
398; +10 OLDDS
399; +8 OLDES
400; +6 OLDAX
401; +4 OLDBX
402; +2 OLDCX
403;SP-> OLDDX
404
405 MOV BX,SP
406 LES BX,DWORD PTR SS:[BX+14] ;Get CS:IP
407 MOV AX,BX
408 MOV CL,4
409 SHR AX,CL
410 MOV CX,ES
411 ADD AX,CX ;Paragraph of CS:IP
412 CMP AX,[DOS_PA] ;Below DOS?
413 JB IOHIT
414 CMP AX,[PROG_LOW_PA] ;Below program?
415 JB DOSHIT
416 CMP AX,[PROG_HIGH_PA] ;Above program?
417 JAE MISSH
418
419 SUB AX,[PROG_LOW_PA] ;Paragraph offset
420 XOR DX,DX
421
422 DIV [BUCKET_SIZE]
423 MOV BX,AX
424 SHL BX,1 ;Mult by 2 to get byte offset
425 INC BUCKET[BX]
426 JMP SHORT DONE
427
428IOHIT:
429 INC [HIT_IO]
430 JMP SHORT DONE
431
432DOSHIT:
433 INC [HIT_DOS]
434 JMP SHORT DONE
435
436MISSH:
437 INC [HIT_HIGH]
438
439DONE:
440 POP DX
441 POP CX
442 POP BX
443 POP AX
444 POP ES
445 POP DS
446 STI
447 RET ;To LEAVE_INT
448
449CLK_INTER ENDP
450
451CODE ENDS
452
453;The init segment contains code to process input parameters
454; It will be blasted as soon as the program to be run is read in
455; And/or the bucket area is initialized
456
457INIT SEGMENT BYTE
458 ORG 0
459
460SETUP:
461 MOV DX,FCB
462 MOV AH,OPEN
463 INT 21H ;Open program file
464 AND AL,AL
465 JZ OPENOK
466 MOV DX,OFFSET DG:NOFILE
467 JMP ERROR
468
469OPENOK:
470 XOR BX,BX
471 MOV WORD PTR DS:[FCB+RR],BX
472 MOV WORD PTR DS:[FCB+RR+2],BX ;RR to 0
473 MOV SI,FCB
474 MOV DI,OFFSET DG:OUT_FCB
475 MOV CX,4
476 REP MOVSW
477 MOVSB ;Transfer drive spec and file to output
478 MOV DX,OFFSET DG:OUT_FCB
479 MOV AH,CREATE
480 INT 21H ;Try to create the output file
481 AND AL,AL
482 JZ GETSIZE
483 MOV DX,OFFSET DG:OUTERR
484 JMP ERROR
485
486GETSIZE: ;Get bucket size
487 MOV DX,OFFSET DG:SIZE_PROMPT
488 MOV AH,PRINTBUF
489 INT 21H
490 CALL INBUF
491 CALL SCANB
492 JZ GETSIZE ;SCANB went to CR
493 XOR BX,BX
494 INC BX ;Size >=1
495 CALL GETNUM
496 JC GETSIZE ;Bad number
497 MOV [BUCKET_SIZE],DX
498
499 CMP WORD PTR DS:[FCB+9],5800H+"E" ;"EX"
500 JNZ NOTEXE
501 CMP BYTE PTR DS:[FCB+11],"E"
502 JNZ NOTEXE
503
504LOADEXEHEAD: ;Load the EXE header
505 MOV [EXEFILE],1
506 MOV DX,OFFSET DG:RUNVAR ;Read header in here
507 MOV AH,SETDMA
508 INT 21H
509 MOV CX,RUNVARSIZ
510 MOV DX,FCB
511 MOV WORD PTR DS:[FCB+RECLEN],1
512 OR AL,AL
513 MOV AH,BLKRD
514 INT 21H
515 CMP [RELPT],5A4DH ;Magic number
516 JZ EXEOK
517 JMP BADEXE
518EXEOK:
519 MOV AX,[PAGES] ;Size of file in 512 byte blocks
520 MOV CL,5
521 SHL AX,CL ;Size in paragraphs
522 JMP SHORT SETBUCKET
523
524NOTEXE:
525 MOV AX,WORD PTR DS:[FCB+FILELEN]
526 MOV DX,WORD PTR DS:[FCB+FILELEN+2] ;Size of file in bytes DX:AX
527 ADD AX,15
528 ADC DX,0 ;Round to PARA
529 MOV CL,4
530 SHR AX,CL
531 AND AX,0FFFH
532 MOV CL,12
533 SHL DX,CL
534 AND DX,0F000H
535 OR AX,DX ;Size in paragraphs to AX
536 MOV [PROG_RA],100H ;Default offset
537
538SETBUCKET:
539 PUSH AX ;Save size
540 XOR DX,DX
541 DIV [BUCKET_SIZE]
542 INC AX ;Round up
543 MOV [BUCKET_NUM],AX
544 MOV BX,OFFSET DG:BUCKET
545 SHL AX,1 ;Number of bytes in bucket area
546 ADD AX,BX ;Size of profil in bytes
547 ADD AX,15 ;Round up to PARA boundry
548 MOV CL,4
549 SHR AX,CL ;Number of paragraphs in profil
550 INC AX ;Insurance
551 MOV BX,CS
552 ADD AX,BX
553 MOV [PROG_AREA],AX
554
555 CMP [EXEFILE],1
556 JZ SETBOUNDS
557 MOV AX,[PROG_AREA] ;Set up .COM segments
558 MOV [PROG_SS],AX
559 MOV [PROG_SA],AX
560
561SETBOUNDS: ;Set the sample window
562 MOV BX,10H ;Get start offset
563 ADD BX,[PROG_AREA] ;PARA # of start
564 MOV [PROG_LOW_PA],BX
565 POP AX ;Recall size of PROG in paragraphs
566 ADD BX,AX
567 MOV [PROG_HIGH_PA],BX
568
569SETDOS:
570 XOR DX,DX
571 MOV ES,DX ;look in interrupt area
572 MOV DX,WORD PTR ES:[82H] ;From int #20
573 MOV [DOS_PA],DX
574 PUSH DS
575 POP ES
576
577GETGRAIN: ;Get sample interval
578 MOV DX,OFFSET DG:GRAIN_PROMPT
579 MOV AH,PRINTBUF
580 INT 21H
581 CALL INBUF
582 CALL SCANB
583 JZ GETGRAIN ;SCANB went to CR
584 MOV BX,60 ;Grain >=60
585 CALL GETNUM
586 JC GETGRAIN ;Bad number
587 MOV [CLOCK_GRAIN],DX
588
589 MOV DX,OFFSET DG:PARAM_PROMPT
590 MOV AH,PRINTBUF
591 INT 21H
592 CALL INBUF ;Get program parameters
593
594 MOV AX,2522H ;Set vector 22H
595 MOV DX,OFFSET DG:TERMINATE
596 INT 21H
597 MOV AL,23H ;Set vector 23H
598 MOV DX,OFFSET DG:ABORT
599 INT 21H
600 RET ;Back to resident code
601
602GETNUM: ;Get a number, DS:SI points to buffer, carry set if bad
603 XOR DX,DX
604 MOV CL,0
605 LODSB
606NUMLP:
607 SUB AL,"0"
608 JB NUMCHK
609 CMP AL,9
610 JA NUMCHK
611 CMP DX,6553
612 JAE BADNUM
613 MOV CL,1
614 PUSH BX
615 MOV BX,DX
616 SHL DX,1
617 SHL DX,1
618 ADD DX,BX
619 SHL DX,1
620 CBW
621 POP BX
622 ADD DX,AX
623 LODSB
624 JMP NUMLP
625NUMCHK:
626 CMP CL,0
627 JZ BADNUM
628 CMP BX,DX
629 JA BADNUM
630 CLC
631 RET
632BADNUM:
633 STC
634 RET
635
636INBUF: ;Read in from console, SI points to start on exit
637 MOV AH,GETBUF
638 MOV DX,OFFSET DG:LINEBUF
639 INT 21H
640 MOV SI,2 + OFFSET DG:LINEBUF
641 MOV DI,OFFSET DG:BYTEBUF
642CASECHK:
643 LODSB
644 CMP AL,'a'
645 JB NOCONV
646 CMP AL,'z'
647 JA NOCONV
648 ADD AL,"A"-"a" ;Convert to upper case
649NOCONV:
650 STOSB
651 CMP AL,13
652 JZ INDONE
653 CMP AL,'"'
654 JNZ QUOTSCAN
655 CMP AL,"'"
656 JNZ CASECHK
657QUOTSCAN:
658 MOV AH,AL
659KILLSTR:
660 LODSB
661 STOSB
662 CMP AL,13
663 JZ INDONE
664 CMP AL,AH
665 JNZ KILLSTR
666 JMP SHORT CASECHK
667
668INDONE:
669 MOV SI,OFFSET DG:BYTEBUF
670
671;Output CR/LF
672
673CRLF:
674 MOV AL,13
675 CALL OUT
676 MOV AL,10
677
678OUT:
679 PUSH AX
680 PUSH DX
681 AND AL,7FH
682 XCHG AX,DX
683 MOV AH,OUTCH
684 INT 21H
685 POP DX
686 POP AX
687 RET
688
689SCANB: ;Scan to first non-blank
690 PUSH AX
691SCANNEXT:
692 LODSB
693 CMP AL," "
694 JZ SCANNEXT
695 CMP AL,9
696 JZ SCANNEXT
697 DEC SI
698 POP AX
699EOLCHK:
700 CMP BYTE PTR[SI],13
701 RET
702
703INIT ENDS
704 END START
705
diff --git a/v2.0/source/PROFILE.txt b/v2.0/source/PROFILE.txt
new file mode 100644
index 0000000..2d50631
--- /dev/null
+++ b/v2.0/source/PROFILE.txt
Binary files differ
diff --git a/v2.0/source/PROHST.HLP b/v2.0/source/PROHST.HLP
new file mode 100644
index 0000000..13880e5
--- /dev/null
+++ b/v2.0/source/PROHST.HLP
@@ -0,0 +1,35 @@
1PROHST is a preliminary version of a utility to process the profile
2file produced by the PROFIL utility of MSDOS.
3Those of you familiar with MS-Pascal or MS-Fortran will have little
4difficulty in understanding how the parameters work. There are three,
5the .PRF filename, an optional histogram file (default extension .HST,
6default name same as the .PRF file) and an optional link map. If the
7link map was produced with the line number options PROHST will try
8and relate buckets to line numbers. Otherwise, it will relate it to
9module offsets. If you specify no map file (the default), addresses
10relative to the start of the program will be used. The default extension
11for the map file is .MAP.
12
13a:prohst f;
14
15this will produce a histogram for the file f.prf in f.hst and no map file
16will be assumed.
17
18a:prohst f,,;
19
20this will produce a histogram for f.prf in f.hst and expects a f.map file.
21
22a:prohst f,g,k
23
24this produces a histogram for f.prf in g.hst and expects a map file k.map.
25
26Note that if you select the map option with line numbers, the program will
27appear to be looping. Never fear, go and have lunch or some other time
28consuming pastime, and you will be suprised how long it took to produce
29such a small file. Also, some of the line number/bucket correspondances are
30not what they might be. Future version shoudl fix this. If you make a better
31version, be sure to let me have a copy.
32
33David Jones.
34
35 \ No newline at end of file
diff --git a/v2.0/source/QUICK.txt b/v2.0/source/QUICK.txt
new file mode 100644
index 0000000..d443b8e
--- /dev/null
+++ b/v2.0/source/QUICK.txt
Binary files differ
diff --git a/v2.0/source/RDATA.ASM b/v2.0/source/RDATA.ASM
new file mode 100644
index 0000000..7a9b368
--- /dev/null
+++ b/v2.0/source/RDATA.ASM
Binary files differ
diff --git a/v2.0/source/README.txt b/v2.0/source/README.txt
new file mode 100644
index 0000000..c5bbf25
--- /dev/null
+++ b/v2.0/source/README.txt
@@ -0,0 +1,177 @@
1 MSDOS 2.0 RELEASE
2
3
4The 2.0 Release of MSDOS includes five 5 1/4 double density single sided
5diskettes or three 8 iinch CP/M 80 format diskettes.
6
7The software/documentation on the five inch diskettes is arranged
8as follows:
9
101. DOS distribution diskette. This diskette contains files which
11 should be distriibuted to all users. This allows the DOS distri-
12 bution diskette to meet the requirements of users of high level
13 language compilers as well as users running only applications.
14 Many compilers marketed independently through the retail channel
15 (including those of Microsoft) assume LINK comes with the DOS, as
16 in the case of IBM. How you choose to distrubute BASIC (contracted
17 for separately) is up to you.
18
192. Assembly Language Development System diskette. This diskette
20 contains files of interest to assembly language programmers.
21 High level language programmers do not need these programs unless
22 they are writing assembly language subroutines. IBM chose to
23 unbundle this package from the DOS distribution diskette (except
24 for DEBUG), but you do not have to do so.
25
263. PRINT and FORMAT diskette. This diskette contains .ASM source
27 files which are necessary to assemble the print spooler, which you
28 may wish to customize for greater performance. .OBJ files are also
29 included for the FORMAT utility.
30
314. Skeltal BIOS and documentation diskette. This diskette contains
32 the skeltal BIOS source code and the SYSINIT and SYSIMES object
33 modules which must be linked with your BIOS module. The proper
34 sequence for linking is BIOS - SYSINIT - SYSIMES.
35 A profiler utiliity is also included on the diskette, but this
36 is not intended for end-users. This is distributed for use by
37 your development staff only and is not supported by Microsoft
38 If you do decide to distribute it, it is at your own risk!
39
40
415. Documentation. Features of 2.0 are documented on this disk.
42
43The user manual contains some significant errors. Most of these are
44due to last minute changes to achieve a greater degree of compatibility
45with IBM's implementation of MS-DOS (PC DOS). This includes the use
46of "\" instead of "/" as the path separator, and "/" instead of "-"
47as the switch character. For transporting of batch files across
48machines, Microsoft encourages the use of "\" and "/" respectively
49in the U.S. market. (See DOSPATCH.TXT for how you can overide this.
50The user guide explains how the end-user can override this in CONFIG.SYS).
51Both the printer echo keys and insert mode keys have now been made to
52toggle. The default prompt (this may also be changed by the user
53with the PROMPT command) has been changed from "A:" to "A>".
54We apologize for any inconveniences these changes may have caused
55your technical publications staff.
56
57
58Here is what you need to do to MSDOS 2.0 to create a shipable product:
59(see "Making a Bootable Diskette" below)
60
611. BIOS. If you have developed a BIOS for the Beta Test 2.0 version
62 You should link your BIOS module to SYSINIT.OBJ and SYSIMES.OBJ.
63 You must modify your BIOS to accomodate the call back to the BIOS
64 at the end of SYSINIT. If you have no need for this call, simply
65 find a far RET and label it RE_INIT and declare it public.
66 An example of this can be found in the skeletal BIOS. In addition
67 please add support for the new fast console output routine as
68 described in the device drivers document. We strongly recommend
69 that you adapt the standard boot sector format also described in
70 device drivers. Once again, please refer to the skeletal BIOS.
71 If you have not yet implemented version 2.0 please read the device
72 drivers document. Microsoft strongly recommends that machines
73 incorporating integrated display devices with memory mapped video
74 RAM implement some sort of terminal emulations through the use of
75 escape sequences. The skeletal BIOS includes a sample ANSI
76 terminal driver.
77
782. Please refer to DOSPATCH.TXT for possible changes you might wish
79 to make. We strongly recommend that you not patch the switch
80 characters for the U.S. market. Your one byte serial number
81 will be issued upon signing the license agreement. Please patch
82 the DOS accordingly. If you wish to serialize the DOS, this is
83 described in DOSPATCH.TXT. Please patch the editing template
84 definitions. Please note the addition of the Control-Z entry
85 at the beginning of the table. Also note that the insert switches
86 have now both been made to toggle.
87
883. Utilities. FORMAT must be configured for each specific system.
89 GENFOR is a generic example of a system independent format module,
90 but it is not recommended that this be distributed to your customers.
91 Link in the following order: FORMAT, FORMES, (your format module).
92 The print spooler is distributed as an executable file, which only
93 prints during wait for keyboard input. If you wish with your
94 implementation to steal some compute time when printing as well,
95 you will need to customize it and reassemble. Please note that
96 you can use a printer-ready or timer interrupt. The former is more
97 efficient, but ties the user to a specific device. Sample code
98 is conditionaled out for the IBM PC timer interrupt.
99
100The following problems are known to exist:
101
1021. Macro assembler does not support the initialization of 10-byte
103 floating point constants in 8087 emulation mode - the last two bytes
104 are zero filled.
105
1062. LIB has not been provided. The version which incorporates support
107 for 2.0 path names will be completed in a couple of weeks. The
108 1.x version should work fine if you cannot wait. Because the library
109 manager acts as a counterpart to the linker, we recommend that it
110 be distributed with the DOS distribution diskette as opposed to the
111 assembly language development system.
112
1133. International (French, German, Japanese, and U.K.) versions will be
114 available in several months.
115
1164. COMMAND.ASM is currently too large to assemble on a micro. It is
117 being broken down into separate modules so it can be asembled on
118 a machine. Source licensees should realize that the resultant
119 binaries from the new version will not correspond exactly to the
120 old version.
121
1225. If you have any further questions regarding the MSDOS 2.0 distribution
123 please contact Don Immerwahr (OEM technical support (206) 828-8086).
124
125
126 Sincerely yours,
127
128
129 Chris Larson
130 MS-DOS Product Marketing Manager
131 (206) 828-8080
132
133
134
135 BUILDING A BOOTABLE (MSDOS FORMAT) DISKETTE
136
137
1381. In implementing MSDOS on a new machine, it is highly recommended
139 that an MSDOS machine be available for the development.
140 Please note that utilities shipped with MSDOS 2.0 use MSDOS 2.0
141 system calls and WILL NOT not run under MSDOS 1.25.
142
1432. Use your MSDOS development machine and EDLIN or a word processor
144 package to write BOOT.ASM, your bootstrap loader BIOS.ASM and
145 your Format module.
146
1473. Use MASM, the Microsoft Macro-86 Assembler, to assemble these
148 modules. LINK is then used to link together the .OBJ modules in
149 the order specified.
150
1514. Link creates .EXE format files which are not memory image files
152 and contain relocation information in their headers. Since your
153 BIOS and BOOT routines will not be loaded by the EXE loader in
154 MSDOS, they must first be turned into memory image files by
155 using the EXE2BIN utility.
156
1575. The easiest thing to do is to (using your development machine)
158 FORMAT a single sided diskette without the system. Use DEBUG
159 to load and write your BOOT.COM bootstrap loader to the BOOT
160 sector of that diskette. You may decide to have your bootstrap
161 load BIOS and let the BIOS load MSDOS or it may load both. Note that
162 the Bootstrap loader will have to know physically where to go on
163 the disk to get the BIOS and the DOS. COMMAND.COM is loaded
164 by the SYSINIT module.
165
1666. Use the COPY command to copy your IO.SYS file (what the
167 BIOS-SYSINIT-SYSIMES module is usually called) onto the disk
168 followed by MSDOS.SYS and COMMAND.COM. You may use DEBUG
169 to change the directory attribute bytes to make these files hidden.
170
171CAUTION:
172
173At all times, the BIOS writer should be careful to preserve the state
174of the DOS - including the flags. You should be also be cautioned that
175the MSDOS stack is not deep. You should not count on more than one or
176two pushes of the registers.
177
diff --git a/v2.0/source/RECMES.ASM b/v2.0/source/RECMES.ASM
new file mode 100644
index 0000000..0723208
--- /dev/null
+++ b/v2.0/source/RECMES.ASM
Binary files differ
diff --git a/v2.0/source/RECOVER.ASM b/v2.0/source/RECOVER.ASM
new file mode 100644
index 0000000..05d27f9
--- /dev/null
+++ b/v2.0/source/RECOVER.ASM
@@ -0,0 +1,876 @@
1TITLE RECOVER MS-DOS File/Disk Recovery Utility
2;----------------------------------------------------------
3;
4; Recover - Program to rebuild an ms.dos directory
5;
6; Copyright 1982 by Microsoft Corporation
7; Written by Chris Peters, April 1982
8;
9;-----------------------------------------------------------
10;
11;REV 1.5 added header message ARR
12;
13
14FALSE EQU 0
15TRUE EQU NOT FALSE
16
17
18IBMVER EQU true
19KANJI EQU FALSE
20
21bdos equ 21h
22boot equ 20h
23aread equ 25h
24awrite equ 26h
25
26 INCLUDE DOSSYM.ASM
27
28;
29cr equ 0dh
30lf equ 0ah
31;
32fcb equ 5ch
33
34code segment public
35code ends
36
37const segment public byte
38const ends
39
40data segment public byte
41data ends
42
43
44dg group code,const,data
45
46code segment public
47 assume cs:dg,ds:dg,es:dg,ss:dg
48
49 PUBLIC PCRLF,PRINT,INT_23,convert
50 EXTRN dskwrt:NEAR,dskrd:NEAR,DSKERR:NEAR,report:NEAR
51
52 org 100h
53
54recover:jmp rec_start
55
56HEADER DB "Vers 1.50"
57
58;-----------------------------------------------------------------------;
59hardch dd ?
60
61the_root db 0 ;root directory flag
62
63fudge db 0 ;directory changed flag
64user_drive db 0
65drive db 0
66
67
68dirchar db "/",0
69
70
71userdir db "/",0
72 db (dirstrlen) dup(0)
73
74fname_buffer db 128 dup(0)
75;-----------------------------------------------------------------------;
76
77pcrlf: mov dx,offset dg: crlf
78print: mov ah,STD_CON_STRING_OUTPUT
79 int bdos
80pret: ret
81;
82convert:push bx
83 xor ax,ax
84 mov bx,ax
85 mov bp,ax
86 mov cx,32
87convlp: shl si,1
88 rcl di,1
89 xchg ax,bp
90 call convwrd
91 xchg ax,bp
92 xchg ax,bx
93 call convwrd
94 xchg ax,bx
95 adc al,0
96 loop convlp
97
98 mov cx,1810h
99 xchg dx,ax
100 call digit
101 xchg ax,bx
102 call outword
103 mov ax,bp
104 call outword
105 pop dx
106 call print
107ret2: ret
108;
109outword:push ax
110 mov dl,ah
111 call outbyte
112 pop dx
113outbyte:mov dh,dl
114 shr dl,1
115 shr dl,1
116 shr dl,1
117 shr dl,1
118 call digit
119 mov dl,dh
120digit: and dl,0fh
121 jz blankzer
122 xor cl,cl
123blankzer:
124 dec ch
125 and cl,ch
126 or dl,30h
127 sub dl,cl
128 cmp dl,30h
129 jl ret2
130 mov ah,STD_CON_OUTPUT
131 int bdos
132 ret
133;
134convwrd:adc al,al
135 daa
136 xchg al,ah
137 adc al,al
138 daa
139 xchg al,ah
140 ret
141;
142; bx = fat[ax]
143;
144getfat: mov bx,offset dg: fattbl
145 push ax
146 mov si,ax
147 sar ax,1
148 pushf
149 add si,ax
150 mov bx,word ptr [bx][si]
151 popf
152 jnc getfat1
153 mov cl,4
154 shr bx,cl
155getfat1:and bh,00001111b
156 pop ax
157 mov cx,secsiz
158 ret
159;
160; fat[ax] = dx
161;
162setfat: mov bx,offset dg: fattbl
163 push ax
164 push dx
165 mov si,ax
166 sar ax,1
167 pushf
168 add si,ax
169 mov ax,word ptr [bx][si]
170 popf
171 jnc setfat2
172 and ax,000fh
173 mov cl,4
174 shl dx,cl
175setfat1:or ax,dx
176 mov word ptr [bx][si],ax
177 pop dx
178 pop ax
179 ret
180
181setfat2:and ax,0f000h
182 jmp setfat1
183
184load: mov dx,firfat
185 mov al,byte ptr fatnum
186 mov byte ptr fatcnt,al
187 mov al,byte ptr drive
188 mov cx,fatsiz
189 mov bx,offset dg: fattbl
190ret66: ret
191
192readft: call load
193readit: call dskrd
194 cmp [fndfat],0 ;save location of readable fat sector
195 jnz fdfat
196 mov [fndfat],dx
197fdfat: cmp word ptr [bx+1],-1
198 jz ret66
199
200 add dx,cx ;try to read the other fats
201 dec byte ptr fatcnt
202 jnz readit
203
204 mov dx,[fndfat] ;see if any readable at all
205 or dx,dx
206 jz readft ;if not disk is blown, keep trying
207 call dskrd
208 ret
209
210wrtfat: call load
211wrtit: push ax
212 push bx
213 push cx
214 push dx
215 call dskwrt
216 pop dx
217 pop cx
218 pop bx
219 pop ax
220
221wrtok: add dx,cx
222 dec byte ptr fatcnt
223 jnz wrtit
224 ret
225
226printerr:
227 call print
228 jmp rabort
229
230
231rec_start:
232
233;Code to print header
234; PUSH AX
235; MOV DX,OFFSET DG:HEADER
236; CALL print
237; POP AX
238
239DOSVER_HIGH EQU 0200H ;2.00 in hex
240 PUSH AX ;Save DRIVE validity info
241 MOV AH,GET_VERSION
242 INT 21H
243 XCHG AH,AL ;Turn it around to AH.AL
244 CMP AX,DOSVER_HIGH
245 JAE OKDOS
246GOTBADDOS:
247 MOV DX,OFFSET DG:BADVER
248 CALL PRINT
249 INT 20H
250
251OKDOS: POP AX
252
253 cmp al,0ffH
254 JZ BADDRVSPECJ
255 mov si,80h
256 lodsb
257 or al,al
258 jz noparm
259look: lodsb
260 cmp al," "
261 jz look
262 cmp al,9
263 jz look
264 cmp al,13
265 jnz gotparm
266noparm:
267 jmp noname
268
269BADDRVSPECJ: JMP BADDRVSPEC
270
271gotparm:
272 mov ah,DISK_RESET
273 int bdos ;empty buffer queue
274
275 mov ah,get_default_drive ;save current drive
276 int 21h
277 mov [user_drive],al
278
279 mov bx,fcb ;determine input command
280 mov al,[bx]
281 dec al
282 cmp al,-1
283 jnz drvok1
284 mov al,[user_drive]
285drvok1:
286 mov [drive],al
287 add [drvlet],al
288 add [drvlet1],al
289 mov dx,offset dg: askmsg
290 call print
291 mov ah,STD_CON_INPUT_FLUSH
292 mov al,1 ;wait for a key
293 int bdos
294
295 cmp al,17h
296 jnz drvok2
297 mov dx,offset dg: egomes
298 jmp printerr
299egomes: db "Chris Peters helped with the new dos!",cr,lf
300 db "Microsoft rules ok$"
301
302drvok2:
303 IF IBMVER
304 MOV AL,DRIVE ;This is for ibm's single drive sys
305 PUSH DS
306 MOV BX,50H
307 MOV DS,BX
308 MOV DS:(BYTE PTR 4),AL ;Indicate drive changed
309 POP DS
310 ENDIF
311
312;----- Process Pathnames -----------------------------------------------;
313 mov ax,(char_oper shl 8) ;get switch character
314 int 21h
315 cmp dl,"/"
316 jnz slashok ;if not / , then not PC
317 mov [dirchar],"\" ;in PC, dir separator = \
318 mov [userdir],"\"
319
320slashok:
321 mov si,81h ;point to cammand line
322 mov di,offset dg: fname_buffer
323 xor cx,cx ;zero pathname length
324
325kill_bl:
326 lodsb ;get rid of blanks
327 cmp al,9
328 je kill_bl
329 cmp al,' '
330 je kill_bl
331 cmp al,13 ;A carriage return?
332 jne next_char
333 jmp noname ;yes, file name missing
334
335next_char:
336 stosb ;put patname in buffer
337 inc cx
338 lodsb
339 cmp al,' '
340 je name_copied
341 cmp al,9
342 je name_copied
343 cmp al,13 ; a CR ?
344 jne next_char
345
346name_copied:
347 mov byte ptr [di],0 ;nul terminate the pathname
348 dec di ;adjust to the end of the pathname
349
350;----- Scan for directory ----------------------------------------------;
351
352 IF KANJI
353 mov dx,offset dg: [fname_buffer]
354 PUSH DX
355 PUSH DI
356 MOV BX,DI
357 MOV DI,DX
358DELLOOP:
359 CMP DI,BX
360 JZ GOTDELE
361 MOV AL,[DI]
362 INC DI
363 CALL TESTKANJ
364 JZ NOTKANJ11
365 INC DI
366 JMP DELLOOP
367
368NOTKANJ11:
369 cmp al,[dirchar]
370 JNZ DELLOOP
371 MOV DX,DI ;Point to char after '/'
372 DEC DX
373 DEC DX ;Point to char before '/'
374 JMP DELLOOP
375
376GOTDELE:
377 MOV DI,DX
378 POP AX ;Initial DI
379 POP DX
380 SUB AX,DI ;Distance moved
381 SUB CX,AX ;Set correct CX
382 CMP DX,DI
383 JB sja ;Found a pathsep
384 JA sjb ;Started with a pathsep, root
385 MOV AX,[DI]
386 CALL TESTKANJ
387 JNZ same_dirj
388 XCHG AH,AL
389 cmp al,[dirchar]
390 jz sja ;One character directory
391same_dirj:
392 ELSE
393 mov al,[dirchar] ;get directory separator character
394 std ;scan backwards
395 repnz scasb ;(cx has the pathname length)
396 cld ;reset direction, just in case
397 jz sja
398 ENDIF
399
400 jmp same_dir ;no dir separator char. found, the
401 ; file is in the current directory
402 ; of the corresponding drive. Ergo,
403 ; the FCB contains the data already.
404
405sja:
406 jcxz sjb ;no more chars left, it refers to root
407 cmp byte ptr [di],':' ;is the prvious character a disk def?
408 jne not_root
409sjb:
410 mov [the_root],01h ;file is in the root
411not_root:
412 inc di ;point to dir separator char.
413 mov al,0
414 stosb ;nul terminate directory name
415 pop ax
416 push di ;save pointer to file name
417 mov [fudge],01h ;remember that the current directory
418 ; has been changed.
419
420;----- Save current directory for exit ---------------------------------;
421 mov dl,byte ptr ds:[fcb] ;get specified drive if any
422 or dl,dl ;default disk?
423 jz same_drive
424 dec dl ;adjust to real drive (a=0,b=1,...)
425 mov ah,set_default_drive ;change disks
426 int 21h
427 cmp al,-1 ;error?
428 jne same_drive
429BADDRVSPEC:
430 mov dx,offset dg: baddrv
431 jmp printerr
432
433same_drive:
434 mov ah,get_default_dpb
435 int 21h
436
437assume ds:nothing
438
439 cmp al,-1 ;bad drive? (should always be ok)
440 jne drvisok
441 mov dx,offset dg: baddrv
442 jmp printerr
443
444drvisok:
445 cmp [bx.dpb_current_dir],0
446 je curr_is_root
447 mov si,bx
448 add si,dpb_dir_text
449 mov di,offset dg: userdir + 1
450
451dir_save_loop:
452 lodsb
453 stosb
454 or al,al
455 jnz dir_save_loop
456
457curr_is_root:
458 push cs
459 pop ds
460
461assume ds:dg
462
463
464;----- Change directories ----------------------------------------------;
465 cmp [the_root],01h
466 mov dx,offset dg: [dirchar] ;assume the root
467 je sj1
468 mov dx,offset dg: [fname_buffer]
469sj1:
470 mov ah,chdir ;change directory
471 int 21h
472 mov dx,offset dg: baddrv
473 jnc no_errors
474 jmp printerr
475no_errors:
476
477;----- Set Up int 24 intercept -----------------------------------------;
478
479 mov ax,(get_interrupt_vector shl 8) or 24h
480 int 21h
481 mov word ptr [hardch],bx
482 mov word ptr [hardch+2],es
483 mov ax,(set_interrupt_vector shl 8) or 23h
484 mov dx,offset dg: int_23
485 int 21h
486 mov ax,(set_interrupt_vector shl 8) or 24h
487 mov dx,offset dg: int_24
488 int 21h
489 push cs
490 pop es
491
492;----- Parse filename to FCB -------------------------------------------;
493 pop si
494 mov di,fcb
495 mov ax,(parse_file_descriptor shl 8) or 1
496 int 21h
497 push ax
498;-----------------------------------------------------------------------;
499same_dir:
500 pop ax
501
502 mov bx,fcb
503 cmp byte ptr [bx+1],' ' ;must specify file name
504 jnz drvok
505 cmp byte ptr [bx],0 ;or drive specifier
506 jnz drvok
507noname: mov dx,offset dg: drverr
508 call print
509 jmp int_23
510
511drvok: push ds
512 mov dl,drive
513 inc dl
514 mov ah,GET_DPB
515 int bdos
516 mov ax,word ptr [bx+2] ;get physical sector size
517 mov cl,byte ptr [bx+4] ;get sectors/cluster - 1
518 xor ch,ch
519 inc cx
520 mov cs:secall,cx ;save sectors per cluster
521 mul cx ;ax = bytes per cluster
522 mov bp,word ptr [bx+11] ;get record of first sector
523 mov dx,word ptr [bx+16] ;get record of first directory entry
524 mov si,word ptr [bx+6] ;get record of first fat
525 mov cl,byte ptr [bx+15] ;get size of fat
526 mov di,word ptr [bx+13] ;get number of clusters
527 mov ch,byte ptr [bx+8] ;get number of fats on drive
528 mov bx,word ptr [bx+9] ;get max number of dir entries
529 pop ds
530
531 mov maxent,bx
532 mov firfat,si
533 mov firrec,bp
534 mov firdir,dx
535 mov byte ptr fatsiz,cl
536 mov lastfat,di ;number of fat entries
537 mov byte ptr fatnum,ch ;save number of fats on disk
538
539 mov secsiz,ax
540
541 mov di,table ;di points into constructed directory
542 mov ax,0e5e5h ;deleted file magic number
543 shl bx,1 ;16 words in a dir entry
544 shl bx,1
545 shl bx,1
546 shl bx,1
547 mov cx,bx
548 rep stosw
549
550 call readft
551 mov bx,fcb
552 cmp byte ptr [bx+1],' '
553 jz recdsk
554 jmp recfil
555
556recdsk: mov di,table
557 mov fatptr,2
558 mov ax,fatptr
559step1: call getfat
560 cmp bx,0fffh
561 jz step1a
562 jmp step6
563step1a: mov filsiz,0
564 mov word ptr filsiz+2,0
565 mov dx,lastfat
566 mov target,ax
567step2: mov ax,2
568 add filsiz,cx
569 adc word ptr filsiz+2,0
570step3: call getfat
571 cmp bx,target
572 jne step4
573 mov target,ax
574 jmp step2
575step4: inc ax
576 cmp ax,dx
577 jle step3
578;
579; at this point target = head of list, filsiz = file size
580;
581 inc filcnt ;increment file count
582 mov ax,maxent
583 cmp filcnt,ax ;compare with max number of entries
584 ja direrr
585
586 mov si,(offset dg: dirent)+7
587nam0: inc byte ptr [si] ;increment file name
588 cmp byte ptr [si],'9'
589 jle nam1
590 mov byte ptr [si],'0'
591 dec si
592 jmp nam0
593
594nam1: mov ah,GET_DATE
595 int bdos ;set the date
596 sub cx,1980
597 add dh,dh
598 add dh,dh
599 add dh,dh
600 add dh,dh
601 add dh,dh
602 rcl cl,1
603 or dh,dl
604 mov byte ptr dirent+24,dh
605 mov byte ptr dirent+25,cl
606 mov ah,GET_TIME
607 int bdos ;set the time
608 shr dh,1
609 add cl,cl
610 add cl,cl
611 add cl,cl
612 rcl ch,1
613 add cl,cl
614 rcl ch,1
615 add cl,cl
616 rcl ch,1
617 or dh,cl
618 mov byte ptr dirent+22,dh
619 mov byte ptr dirent+23,ch
620
621 mov ax,filsiz ;set file size
622 mov word ptr dirent+28,ax
623 mov ax,word ptr filsiz+2
624 mov word ptr dirent+30,ax
625 mov ax,target ;set first cluster location
626 mov word ptr dirent+26,ax
627
628 mov si,offset dg: dirent ;copy in new dir entry
629 mov cx,32
630 rep movsb
631
632step6: inc fatptr ;keep looking for eof's
633 mov ax,fatptr
634 cmp ax,lastfat
635 jg step7
636 jmp step1
637
638direrr: dec filcnt
639 mov dx,offset dg: dirmsg
640 call print
641
642step7:
643 mov al,drive
644 mov dx,firdir ;write out constructed directory
645 mov cx,firrec
646 sub cx,dx
647 mov bx,table
648 call dskwrt
649 call pcrlf
650 mov dx,offset dg: recmsg_pre
651 call print
652 mov bx,offset dg: recmsg_post
653 mov si,filcnt
654 xor di,di ;output number of files created
655 call convert
656 jmp rexit
657recfil: mov dx,fcb
658 mov ah,FCB_OPEN
659 int bdos
660 inc al
661 jnz recfil0
662 mov dx,offset dg: opnerr
663 call print
664 jmp rexit
665
666recfil0:mov lastfat,1 ;indicate location of list head
667 mov di,fcb
668 mov ax,[di+16] ;get file size
669 mov filsiz,ax
670 mov siztmp,ax
671 mov ax,[di+18]
672 mov filsiz+2,ax
673 mov siztmp+2,ax
674 mov ax,[di+25] ;get list head
675 or ax,ax
676 mov fatptr,ax
677 jnz recfil1
678recvec: jmp recfil6
679
680recfil1:cmp fatptr,0fffh
681 jz recvec ;terminate loop at e-o-f
682
683 mov cx,secall
684 mov ax,fatptr
685 dec ax
686 dec ax
687 mul cx
688 add ax,firrec
689 mov dx,ax
690 mov bx,table
691 mov al,drive
692 int aread
693 pop di ;restore stack pointer
694 mov di,fcb ;restore pointer to fcb
695 jnc recfil4 ;if no error continue reading
696
697 mov ax,fatptr
698 call getfat
699 cmp lastfat,1
700 jnz recfil2
701
702 cmp bx,0fffh
703 jnz noteof
704 xor bx,bx
705noteof: mov word ptr [di+25],bx
706 jmp recfil3
707
708recfil2:mov dx,bx ;jump around bad sector
709 mov ax,lastfat
710 call setfat
711
712recfil3:mov ax,fatptr ;mark sector bad
713 mov dx,0ff7h
714 call setfat
715 mov ax,secsiz ;prepare to dec filsiz by secsiz
716 cmp siztmp+2,0
717 jnz recfilx
718 cmp siztmp,ax
719 ja recfilx
720 mov ax,siztmp
721
722recfilx:sub word ptr [di+16],ax
723 sbb word ptr [di+18],0
724 sub siztmp,ax
725 sbb siztmp,0
726
727 and byte ptr [di+24],10111111b ;mark file dirty
728
729 mov ax,lastfat ;point to next sector to check
730 jmp recfil5
731
732recfil4:
733 mov ax,secsiz ;set bytes remaining to be read
734 sub siztmp,ax
735 sbb siztmp+2,0
736 jnc recok
737 xor ax,ax ;if < 0, then set to zero
738 mov siztmp,ax
739 mov siztmp+2,ax
740
741recok: mov ax,fatptr ;get next sector to test
742 mov lastfat,ax
743recfil5:call getfat
744 mov fatptr,bx
745 jmp recfil1
746
747recfil6: ;all done
748 mov dx,fcb
749 mov ah,FCB_CLOSE
750 int bdos ;close the file
751 call pcrlf
752 call report
753
754;
755rexit: mov ah,DISK_RESET
756 int bdos
757 call wrtfat ;save the fat
758int_23: call rest_dir
759rabort: int boot ;home, james...
760
761;----- Restore INT 24 vector and old current directory -----------------;
762rest_dir:
763 cmp [fudge],0
764 je no_fudge
765
766 mov ax,(set_interrupt_vector shl 8) or 24h
767 lds dx,[hardch]
768 int 21h
769 push cs
770 pop ds
771
772 mov dx,offset dg: userdir ;restore directory
773 mov ah,chdir
774 int 21h
775 mov dl,[user_drive] ;restore old current drive
776 mov ah,set_default_drive
777 int 21h
778
779no_fudge:
780 ret
781
782;----- INT 24 Processing -----------------------------------------------;
783
784int_24_retaddr dw int_24_back
785
786int_24 proc far
787assume ds:nothing,es:nothing,ss:nothing
788
789 pushf
790 push cs
791 push [int_24_retaddr]
792 push word ptr [hardch+2]
793 push word ptr [hardch]
794 ret
795int_24 endp
796
797int_24_back:
798 cmp al,2 ;abort?
799 jnz ireti
800 push cs
801 pop ds
802
803assume ds:dg
804
805 call rest_dir
806 int 20h
807ireti:
808 iret
809
810 IF KANJI
811TESTKANJ:
812 CMP AL,81H
813 JB NOTLEAD
814 CMP AL,9FH
815 JBE ISLEAD
816 CMP AL,0E0H
817 JB NOTLEAD
818 CMP AL,0FCH
819 JBE ISLEAD
820NOTLEAD:
821 PUSH AX
822 XOR AX,AX ;Set zero
823 POP AX
824 RET
825
826ISLEAD:
827 PUSH AX
828 XOR AX,AX ;Set zero
829 INC AX ;Reset zero
830 POP AX
831 RET
832 ENDIF
833
834code ends
835
836const segment public byte
837
838 EXTRN BADVER:BYTE,askmsg:BYTE,drvlet:BYTE,dirmsg:BYTE
839 EXTRN recmsg_pre:BYTE,DRVLET1:BYTE,recmsg_post:BYTE
840 EXTRN crlf:BYTE,drverr:BYTE,baddrv:BYTE,opnerr:BYTE
841
842const ends
843
844data segment byte
845
846 PUBLIC filsiz
847
848dirent db 'FILE0000REC'
849 db 21 dup (00)
850
851fndfat dw 0000 ;sector of first good fat
852filcnt dw 0000
853fatcnt db 00
854fatnum db 00
855fatsiz dw 0000
856firfat dw 0000
857fatptr dw 0000
858secall dw 0000 ;sectors per cluster
859target dw 0000
860maxent dw 0000
861firrec dw 0000
862firdir dw 0000
863secsiz dw 0000
864siztmp dw 0000
865 dw 0000
866filsiz dw 0000
867 dw 0000
868lastfat dw 0000
869;
870table dw offset dg:fattbl + 6 * 1024
871fattbl db 0
872
873data ends
874
875 end recover
876
diff --git a/v2.0/source/ROM.ASM b/v2.0/source/ROM.ASM
new file mode 100644
index 0000000..f668986
--- /dev/null
+++ b/v2.0/source/ROM.ASM
@@ -0,0 +1,530 @@
1;
2; Disk utilities of MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.XLIST
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17TITLE ROM - miscellaneous routines
18NAME ROM
19
20 i_need CLUSNUM,WORD
21 i_need NEXTADD,WORD
22 i_need LASTPOS,WORD
23 i_need SECCLUSPOS,BYTE
24 i_need FATBYT,WORD
25 i_need RECPOS,4
26 i_need THISFCB,DWORD
27 i_need TRANS,BYTE
28 i_need BYTCNT1,WORD
29 i_need CURBUF,DWORD
30 i_need BYTSECPOS,WORD
31 i_need DMAADD,WORD
32 i_need SECPOS,WORD
33 i_need VALSEC,WORD
34
35 procedure GET_random_record,NEAR
36 entry GETRRPOS1
37 MOV CX,1
38 entry GetRRPos
39 MOV DI,DX
40 CMP BYTE PTR [DI],-1
41 JNZ NORMFCB1
42 ADD DI,7
43NORMFCB1:
44 MOV AX,WORD PTR [DI.fcb_RR]
45 MOV DX,WORD PTR [DI.fcb_RR+2]
46 return
47GET_random_record ENDP
48
49SUBTTL FNDCLUS -- Skip over allocation units
50PAGE
51 procedure FNDCLUS,NEAR
52ASSUME DS:DOSGROUP,ES:NOTHING
53
54; Inputs:
55; CX = No. of clusters to skip
56; ES:BP = Base of drive parameters
57; [THISFCB] point to FCB
58; Outputs:
59; BX = Last cluster skipped to
60; CX = No. of clusters remaining (0 unless EOF)
61; DX = Position of last cluster
62; DI destroyed. No other registers affected.
63
64 PUSH ES
65 LES DI,[THISFCB]
66 MOV BX,ES:[DI.fcb_LSTCLUS] ; fcb_lstclus is packed with dir clus
67 AND BX,0FFFh ; get rid of dir nibble
68 MOV DX,ES:[DI.fcb_CLUSPOS]
69 OR BX,BX
70 JZ NOCLUS
71 SUB CX,DX
72 JNB FINDIT
73 ADD CX,DX
74 XOR DX,DX
75 MOV BX,ES:[DI.fcb_FIRCLUS]
76FINDIT:
77 POP ES
78 JCXZ RET10
79entry SKPCLP
80 invoke UNPACK
81 CMP DI,0FF8H
82 JAE RET10
83 XCHG BX,DI
84 INC DX
85 LOOP SKPCLP
86RET10: return
87
88NOCLUS:
89 POP ES
90 INC CX
91 DEC DX
92 return
93FNDCLUS ENDP
94
95SUBTTL BUFSEC -- BUFFER A SECTOR AND SET UP A TRANSFER
96PAGE
97 procedure BUFSEC,NEAR
98ASSUME DS:DOSGROUP,ES:NOTHING
99
100; Inputs:
101; AH = priority of buffer
102; AL = 0 if buffer must be read, 1 if no pre-read needed
103; ES:BP = Base of drive parameters
104; [CLUSNUM] = Physical cluster number
105; [SECCLUSPOS] = Sector position of transfer within cluster
106; [BYTCNT1] = Size of transfer
107; Function:
108; Insure specified sector is in buffer, flushing buffer before
109; read if necessary.
110; Outputs:
111; ES:DI = Pointer to buffer
112; SI = Pointer to transfer address
113; CX = Number of bytes
114; [NEXTADD] updated
115; [TRANS] set to indicate a transfer will occur
116
117 MOV DX,[CLUSNUM]
118 MOV BL,[SECCLUSPOS]
119 CALL FIGREC
120 invoke GETBUFFR
121 MOV BYTE PTR [TRANS],1 ; A transfer is taking place
122 MOV SI,[NEXTADD]
123 MOV DI,SI
124 MOV CX,[BYTCNT1]
125 ADD DI,CX
126 MOV [NEXTADD],DI
127 LES DI,[CURBUF]
128 ADD DI,BUFINSIZ ; Point to buffer
129 ADD DI,[BYTSECPOS]
130 return
131BUFSEC ENDP
132
133SUBTTL BUFRD, BUFWRT -- PERFORM BUFFERED READ AND WRITE
134PAGE
135 procedure BUFRD,NEAR
136ASSUME DS:DOSGROUP,ES:NOTHING
137
138; Do a partial sector read via one of the system buffers
139; ES:BP Points to DPB
140
141 PUSH ES
142 MOV AX,LBRPRI SHL 8 ; Assume last byte read
143 CALL BUFSEC
144 MOV BX,ES
145 MOV ES,[DMAADD+2]
146 MOV DS,BX
147ASSUME DS:NOTHING
148 XCHG DI,SI
149 SHR CX,1
150 JNC EVENRD
151 MOVSB
152EVENRD:
153 REP MOVSW
154 POP ES
155 LDS DI,[CURBUF]
156 LEA BX,[DI.BufInSiz]
157 SUB SI,BX ; Position in buffer
158 invoke PLACEBUF
159 CMP SI,ES:[BP.dpb_sector_size]
160 JB RBUFPLACED
161 invoke PLACEHEAD
162RBUFPLACED:
163 PUSH SS
164 POP DS
165 return
166BUFRD ENDP
167
168 procedure BUFWRT,NEAR
169ASSUME DS:DOSGROUP,ES:NOTHING
170
171; Do a partial sector write via one of the system buffers
172; ES:BP Points to DPB
173
174 MOV AX,[SECPOS]
175 INC AX ; Set for next sector
176 MOV [SECPOS],AX
177 CMP AX,[VALSEC] ; Has sector been written before?
178 MOV AL,1
179 JA NOREAD ; Skip preread if SECPOS>VALSEC
180 XOR AL,AL
181NOREAD:
182 PUSH ES
183 CALL BUFSEC
184 MOV DS,[DMAADD+2]
185ASSUME DS:NOTHING
186 SHR CX,1
187 JNC EVENWRT
188 MOVSB
189EVENWRT:
190 REP MOVSW
191 POP ES
192 LDS BX,[CURBUF]
193 MOV BYTE PTR [BX.BUFDIRTY],1
194 LEA SI,[BX.BufInSiz]
195 SUB DI,SI ; Position in buffer
196 MOV SI,DI
197 MOV DI,BX
198 invoke PLACEBUF
199 CMP SI,ES:[BP.dpb_sector_size]
200 JB WBUFPLACED
201 invoke PLACEHEAD
202WBUFPLACED:
203 PUSH SS
204 POP DS
205 return
206BUFWRT ENDP
207
208SUBTTL NEXTSEC -- Compute next sector to read or write
209PAGE
210 procedure NEXTSEC,NEAR
211ASSUME DS:DOSGROUP,ES:NOTHING
212
213; Compute the next sector to read or write
214; ES:BP Points to DPB
215
216 TEST BYTE PTR [TRANS],-1
217 JZ CLRET
218 MOV AL,[SECCLUSPOS]
219 INC AL
220 CMP AL,ES:[BP.dpb_cluster_mask]
221 JBE SAVPOS
222 MOV BX,[CLUSNUM]
223 CMP BX,0FF8H
224 JAE NONEXT
225 invoke UNPACK
226 MOV [CLUSNUM],DI
227 INC [LASTPOS]
228 MOV AL,0
229SAVPOS:
230 MOV [SECCLUSPOS],AL
231CLRET:
232 CLC
233 return
234NONEXT:
235 STC
236 return
237NEXTSEC ENDP
238
239SUBTTL OPTIMIZE -- DO A USER DISK REQUEST WELL
240PAGE
241 procedure OPTIMIZE,NEAR
242ASSUME DS:DOSGROUP,ES:NOTHING
243
244; Inputs:
245; BX = Physical cluster
246; CX = No. of records
247; DL = sector within cluster
248; ES:BP = Base of drives parameters
249; [NEXTADD] = transfer address
250; Outputs:
251; AX = No. of records remaining
252; BX = Transfer address
253; CX = No. or records to be transferred
254; DX = Physical sector address
255; DI = Next cluster
256; [CLUSNUM] = Last cluster accessed
257; [NEXTADD] updated
258; ES:BP unchanged. Note that segment of transfer not set.
259
260 PUSH DX
261 PUSH BX
262 MOV AL,ES:[BP.dpb_cluster_mask]
263 INC AL ; Number of sectors per cluster
264 MOV AH,AL
265 SUB AL,DL ; AL = Number of sectors left in first cluster
266 MOV DX,CX
267 MOV CX,0
268OPTCLUS:
269; AL has number of sectors available in current cluster
270; AH has number of sectors available in next cluster
271; BX has current physical cluster
272; CX has number of sequential sectors found so far
273; DX has number of sectors left to transfer
274; ES:BP Points to DPB
275; ES:SI has FAT pointer
276 invoke UNPACK
277 ADD CL,AL
278 ADC CH,0
279 CMP CX,DX
280 JAE BLKDON
281 MOV AL,AH
282 INC BX
283 CMP DI,BX
284 JZ OPTCLUS
285 DEC BX
286FINCLUS:
287 MOV [CLUSNUM],BX ; Last cluster accessed
288 SUB DX,CX ; Number of sectors still needed
289 PUSH DX
290 MOV AX,CX
291 MUL ES:[BP.dpb_sector_size] ; Number of sectors times sector size
292 MOV SI,[NEXTADD]
293 ADD AX,SI ; Adjust by size of transfer
294 MOV [NEXTADD],AX
295 POP AX ; Number of sectors still needed
296 POP DX ; Starting cluster
297 SUB BX,DX ; Number of new clusters accessed
298 ADD [LASTPOS],BX
299 POP BX ; BL = sector postion within cluster
300 invoke FIGREC
301 MOV BX,SI
302 return
303BLKDON:
304 SUB CX,DX ; Number of sectors in cluster we don't want
305 SUB AH,CL ; Number of sectors in cluster we accepted
306 DEC AH ; Adjust to mean position within cluster
307 MOV [SECCLUSPOS],AH
308 MOV CX,DX ; Anyway, make the total equal to the request
309 JMP SHORT FINCLUS
310OPTIMIZE ENDP
311
312SUBTTL FIGREC -- Figure sector in allocation unit
313PAGE
314 procedure FIGREC,NEAR
315ASSUME DS:NOTHING,ES:NOTHING
316
317; Inputs:
318; DX = Physical cluster number
319; BL = Sector postion within cluster
320; ES:BP = Base of drive parameters
321; Outputs:
322; DX = physical sector number
323; No other registers affected.
324
325 PUSH CX
326 MOV CL,ES:[BP.dpb_cluster_shift]
327 DEC DX
328 DEC DX
329 SHL DX,CL
330 OR DL,BL
331 ADD DX,ES:[BP.dpb_first_sector]
332 POP CX
333 return
334FIGREC ENDP
335
336SUBTTL GETREC -- Figure record in file from fcb
337PAGE
338 procedure GETREC,NEAR
339ASSUME DS:NOTHING,ES:NOTHING
340
341; Inputs:
342; DS:DX point to FCB
343; Outputs:
344; CX = 1
345; DX:AX = Record number determined by fcb_EXTENT and fcb_NR fields
346; DS:DI point to FCB
347; No other registers affected.
348
349 MOV DI,DX
350 CMP BYTE PTR [DI],-1 ; Check for extended FCB
351 JNZ NORMFCB2
352 ADD DI,7
353NORMFCB2:
354 MOV CX,1
355 MOV AL,[DI.fcb_NR]
356 MOV DX,[DI.fcb_EXTENT]
357 SHL AL,1
358 SHR DX,1
359 RCR AL,1
360 MOV AH,DL
361 MOV DL,DH
362 MOV DH,0
363 return
364GETREC ENDP
365
366SUBTTL ALLOCATE -- Assign disk space
367PAGE
368 procedure ALLOCATE,NEAR
369ASSUME DS:DOSGROUP,ES:NOTHING
370
371; Inputs:
372; BX = Last cluster of file (0 if null file)
373; CX = No. of clusters to allocate
374; DX = Position of cluster BX
375; ES:BP = Base of drive parameters
376; [THISFCB] = Points to FCB
377; Outputs:
378; IF insufficient space
379; THEN
380; Carry set
381; CX = max. no. of records that could be added to file
382; ELSE
383; Carry clear
384; BX = First cluster allocated
385; FAT is fully updated including dirty bit
386; fcb_FIRCLUS field of FCB set if file was null
387; SI,BP unchanged. All other registers destroyed.
388
389 PUSH BX ; save the fat byte
390 XOR BX,BX
391 invoke UNPACK
392 MOV [FATBYT],DI
393 POP BX
394
395 PUSH DX
396 PUSH CX
397 PUSH BX
398 MOV AX,BX
399CLUSALLOC:
400 MOV DX,BX
401FINDFRE:
402 INC BX
403 CMP BX,ES:[BP.dpb_max_cluster]
404 JLE TRYOUT
405 CMP AX,1
406 JG TRYIN
407 POP BX
408 MOV DX,0FFFH
409 invoke RELBLKS
410 POP AX ; No. of clusters requested
411 SUB AX,CX ; AX=No. of clusters allocated
412 POP DX
413 invoke RESTFATBYT
414 INC DX ; Position of first cluster allocated
415 ADD AX,DX ; AX=max no. of cluster in file
416 MOV DL,ES:[BP.dpb_cluster_mask]
417 MOV DH,0
418 INC DX ; DX=records/cluster
419 MUL DX ; AX=max no. of records in file
420 MOV CX,AX
421 SUB CX,WORD PTR [RECPOS] ; CX=max no. of records that could be written
422 JA MAXREC
423 XOR CX,CX ; If CX was negative, zero it
424MAXREC:
425 STC
426 return
427
428TRYOUT:
429 invoke UNPACK
430 JZ HAVFRE
431TRYIN:
432 DEC AX
433 JLE FINDFRE
434 XCHG AX,BX
435 invoke UNPACK
436 JZ HAVFRE
437 XCHG AX,BX
438 JMP SHORT FINDFRE
439HAVFRE:
440 XCHG BX,DX
441 MOV AX,DX
442 invoke PACK
443 MOV BX,AX
444 LOOP CLUSALLOC
445 MOV DX,0FFFH
446 invoke PACK
447 POP BX
448 POP CX ; Don't need this stuff since we're successful
449 POP DX
450 invoke UNPACK
451 invoke RESTFATBYT
452 XCHG BX,DI
453 OR DI,DI
454 retnz
455 PUSH ES
456 LES DI,[THISFCB]
457 AND BX,0FFFh
458 MOV ES:[DI.fcb_FIRCLUS],BX
459 AND ES:[DI.fcb_LSTCLUS],0F000h ; clear out old lstclus
460 OR ES:[DI.fcb_LSTCLUS],BX ; or the new guy in...
461 POP ES
462 return
463ALLOCATE ENDP
464
465 procedure RESTFATBYT,NEAR
466ASSUME DS:DOSGROUP,ES:NOTHING
467
468 PUSH BX
469 PUSH DX
470 PUSH DI
471 XOR BX,BX
472 MOV DX,[FATBYT]
473 invoke PACK
474 POP DI
475 POP DX
476 POP BX
477 return
478RESTFATBYT ENDP
479
480SUBTTL RELEASE -- DEASSIGN DISK SPACE
481PAGE
482 procedure RELEASE,NEAR
483ASSUME DS:DOSGROUP,ES:NOTHING
484
485; Inputs:
486; BX = Cluster in file
487; ES:BP = Base of drive parameters
488; Function:
489; Frees cluster chain starting with [BX]
490; AX,BX,DX,DI all destroyed. Other registers unchanged.
491
492 XOR DX,DX
493entry RELBLKS
494; Enter here with DX=0FFFH to put an end-of-file mark
495; in the first cluster and free the rest in the chain.
496 invoke UNPACK
497 retz
498 MOV AX,DI
499 invoke PACK
500 CMP AX,0FF8H
501 MOV BX,AX
502 JB RELEASE
503RET12: return
504RELEASE ENDP
505
506SUBTTL GETEOF -- Find the end of a file
507PAGE
508 procedure GETEOF,NEAR
509ASSUME DS:DOSGROUP,ES:NOTHING
510
511; Inputs:
512; ES:BP Points to DPB
513; BX = Cluster in a file
514; DS = CS
515; Outputs:
516; BX = Last cluster in the file
517; DI destroyed. No other registers affected.
518
519 invoke UNPACK
520 CMP DI,0FF8H
521 JAE RET12
522 MOV BX,DI
523 JMP SHORT GETEOF
524GETEOF ENDP
525
526do_ext
527
528CODE ENDS
529 END
530
diff --git a/v2.0/source/RUCODE.ASM b/v2.0/source/RUCODE.ASM
new file mode 100644
index 0000000..927a559
--- /dev/null
+++ b/v2.0/source/RUCODE.ASM
Binary files differ
diff --git a/v2.0/source/SKELIO.ASM b/v2.0/source/SKELIO.ASM
new file mode 100644
index 0000000..b2ff8e3
--- /dev/null
+++ b/v2.0/source/SKELIO.ASM
@@ -0,0 +1,1377 @@
1 TITLE IO.SYS for the ALTOS ACS-86C.
2
3; I/O system for Version 2.x of MSDOS.
4
5;This BIOS designed to be linked with the SYSINIT module provided by
6;Microsoft
7
8BIOSIZ EQU 4096 ;Size of BIOS in bytes.
9BIOSIZS EQU 100H ;Size of BIOS in Paragraphs.
10ANSI EQU 0 ;Ansi switch.
11
12;Additional Information for the ALTOS machine.
13
14QSIZE EQU 100 ;Input queue size.
15BIOSSEG EQU 0C0H ;I/O system segment.
16MAX_MEM EQU 4000H ;Memory size in paragraphs.
17
18; Constants for commands in Altos ROM.
19
20ROM_CONSTA EQU 01 ;Return status AL of console selected in CX.
21ROM_CONIN EQU 02 ;Get char. from console in CX to AL
22ROM_CONOUT EQU 03 ;Write char. in DL to console in CX.
23ROM_PMSG EQU 07 ;Write string ES:DX to console in CX.
24ROM_DISKIO EQU 08 ;Perform disk I/O from IOPB in ES:CX.
25ROM_INIT EQU 10 ;Returns boot console and top memory ES:DX.
26
27;Things needed to communicate with SYSINIT
28
29EXTRN SYSINIT:FAR ;The entry point of SYSINIT
30EXTRN CURRENT_DOS_LOCATION:WORD ;Where the DOS is when SYSINIT called
31EXTRN FINAL_DOS_LOCATION:WORD ;Where I want SYSINIT to put the DOS
32EXTRN DEVICE_LIST:DWORD ;Pointer to the DEVICE list.
33EXTRN MEMORY_SIZE:WORD ;Size in paragraphs of Physical memory.
34EXTRN DEFAULT_DRIVE:BYTE ;Default Drive to use when system booted
35EXTRN BUFFERS:BYTE ;Number of default buffers.
36 ; Leave as is and SYSINIT uses only 2.
37
38CODE SEGMENT
39ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
40
41 ORG 0 ;Starts at an offset of zero.
42
43INIT: JMP HWINIT
44
45 PAGE
46
47 SUBTTL Device driver tables.
48
49;-----------------------------------------------+
50; DWORD pointer to next device | 1 word offset.
51; (-1,-1 if last device) | 1 word segement.
52;-----------------------------------------------+
53; Device attribute WORD ; 1 word.
54; Bit 15 = 1 for chacter devices. ;
55; 0 for Block devices. ;
56; ;
57; Charcter devices. (Bit 15=1) ;
58; Bit 0 = 1 current sti device. ;
59; Bit 1 = 1 current sto device. ;
60; Bit 2 = 1 current NUL device. ;
61; Bit 3 = 1 current Clock device. ;
62; ;
63; Bit 13 = 1 for non IBM machines. ;
64; 0 for IBM machines only. ;
65; Bit 14 = 1 IOCTL control bit. ;
66;-----------------------------------------------+
67; Device strategy pointer. ; 1 word offset.
68;-----------------------------------------------+
69; Device interrupt pointer. ; 1 word offset.
70;-----------------------------------------------+
71; Device name field. ; 8 bytes.
72; Character devices are any valid name ;
73; left justified, in a space filled ;
74; field. ;
75; Block devices contain # of units in ;
76; the first byte. ;
77;-----------------------------------------------+
78
79DEVSTART LABEL WORD
80CONDEV: ;Header for device CON
81 DW AUXDEV,BIOSSEG ;Link to next device
82 DW 8003H ;Attributes - console input, output device
83 DW STRATEGY ;Srategy entry point
84 DW CON_INT ;Interrupt entry point
85 DB "CON " ;Device name
86
87AUXDEV: ;Header for device AUX
88 DW PRNDEV,BIOSSEG
89 DW 8000H
90 DW STRATEGY
91 DW AUX_INT
92 DB "AUX "
93
94PRNDEV: ;Header for device PRN
95 DW TIMDEV,BIOSSEG
96 DW 8000H
97 DW STRATEGY
98 DW PRN_INT
99 DB "PRN "
100
101TIMDEV: ;Header for device CLOCK
102 DW DSKDEV,BIOSSEG
103 DW 8008H
104 DW STRATEGY
105 DW TIM_INT
106 DB "CLOCK "
107
108DSKDEV: ;Header for disk devices
109 DW -1,-1 ;Last device
110 DW 2000H ;Is a block device
111 DW STRATEGY
112 DW DSK_INT
113DRVMAX DB 1 ;Number of Units
114 DB 7 DUP (?)
115
116 PAGE
117 SUBTTL Dispatch tables for each device.
118
119DSKTBL: DW DSK_INIT ;0 - Initialize Driver.
120 DW MEDIAC ;1 - Return current media code.
121 DW GET_BPB ;2 - Get Bios Parameter Block.
122 DW CMDERR ;3 - Reserved. (currently returns error)
123 DW DSK_RED ;4 - Block read.
124 DW BUS_EXIT ;5 - (Not used, return busy flag)
125 DW EXIT ;6 - Return status. (Not used)
126 DW EXIT ;7 - Flush input buffer. (Not used.)
127 DW DSK_WRT ;8 - Block write.
128 DW DSK_WRV ;9 - Block write with verify.
129 DW EXIT ;10 - Return output status.
130 DW EXIT ;11 - Flush output buffer. (Not used.)
131 DW EXIT ;12 - IO Control.
132
133CONTBL: DW EXIT ;0 - Init. (Not used)
134 DW EXIT ;1 - Media check (Not used)
135 DW EXIT ;2 - Get Bios Parameter Block (Not used)
136 DW CMDERR ;3 - Reserved. (Currently returns error)
137 DW CON_READ ;4 - Character read. (Destructive)
138 DW CON_RDND ;5 - Character read. (Non-destructive)
139 DW EXIT ;6 - Return status. (Not used)
140 DW CON_FLSH ;7 - Flush Input buffer.
141 DW CON_WRIT ;8 - Character write.
142 DW CON_WRIT ;9 - Character write with Verify.
143 DW CON_WRST ;10 - Character write status.
144 DW EXIT ;11 - Flush output buffer. (Not used.)
145 DW EXIT ;12 - IO Control.
146
147AUXTBL: DW EXIT ;0 - Init. (Not used)
148 DW EXIT ;1 - Media check (Not used)
149 DW EXIT ;2 - Get Bios Parameter Block (Not used)
150 DW CMDERR ;3 - Reserved. (Returns an error)
151 DW AUX_READ ;4 - Character read. (Destructive)
152 DW AUX_RDND ;5 - Character read. (Non-destructive)
153 DW EXIT ;6 - Return status. (Not used)
154 DW AUX_CLR ;7 - Flush Input buffer.
155 DW AUX_WRIT ;8 - Character write.
156 DW AUX_WRIT ;9 - Character write with verify.
157 DW AUX_WRST ;10 - Character write status.
158 DW EXIT ;11 - Flush output buffer. (Not used.)
159 DW EXIT ;12 - IO Control.
160
161TIMTBL: DW EXIT ;0 - Init. (Not used)
162 DW EXIT ;1 - Media check (Not used)
163 DW EXIT ;2 - Get Bios Parameter Block (Not used)
164 DW CMDERR ;3 - Reserved. (Currently returns an error)
165 DW TIM_RED ;4 - Character read. (Destructive)
166 DW BUS_EXIT ;5 - (Not used, returns busy flag.)
167 DW EXIT ;6 - Return status. (Not used)
168 DW EXIT ;7 - Flush Input buffer. (Not used)
169 DW TIM_WRT ;8 - Character write.
170 DW TIM_WRT ;9 - Character write with verify.
171 DW EXIT ;10 - Character write status. (Not used)
172 DW EXIT ;11 - Flush output buffer. (Not used)
173 DW EXIT ;12 - IO Control.
174
175PRNTBL: DW EXIT ;0 - (Not used)
176 DW EXIT ;1 - (Not used)
177 DW EXIT ;2 - Block (Not used)
178 DW CMDERR ;3 - Reserved. (currently returns error)
179 DW EXIT ;4 - (Not used)
180 DW BUS_EXIT ;5 - (Not used, returns busy flag.)
181 DW EXIT ;6 - (Not used)
182 DW EXIT ;7 - (Not used)
183 DW PRN_WRT ;8 - Character write.
184 DW PRN_WRT ;9 - Character write with verify.
185 DW PRN_STA ;10 - Character write status.
186 DW EXIT ;11 - (Not used.)
187 DW EXIT ;12 - IO Control.
188
189 PAGE
190 SUBTTL Strategy and Software Interrupt routines.
191
192;Define offsets for io data packet
193
194IODAT STRUC
195CMDLEN DB ? ;LENGTH OF THIS COMMAND
196UNIT DB ? ;SUB UNIT SPECIFIER
197CMD DB ? ;COMMAND CODE
198STATUS DW ? ;STATUS
199 DB 8 DUP (?)
200MEDIA DB ? ;MEDIA DESCRIPTOR
201TRANS DD ? ;TRANSFER ADDRESS
202COUNT DW ? ;COUNT OF BLOCKS OR CHARACTERS
203START DW ? ;FIRST BLOCK TO TRANSFER
204IODAT ENDS
205
206PTRSAV DD 0 ;Strategy pointer save.
207
208;
209; Simplistic Strategy routine for non-multi-Tasking system.
210;
211; Currently just saves I/O packet pointers in PTRSAV for
212; later processing by the individual interrupt routines.
213;
214
215STRATP PROC FAR
216
217STRATEGY:
218 MOV WORD PTR CS:[PTRSAV],BX
219 MOV WORD PTR CS:[PTRSAV+2],ES
220 RET
221
222STRATP ENDP
223
224;
225; Console interrupt routine for processing I/O packets.
226;
227
228CON_INT:
229 PUSH SI
230 MOV SI,OFFSET CONTBL
231 JMP SHORT ENTRY
232
233;
234; Auxilary interrupt routine for processing I/O packets.
235;
236
237AUX_INT:
238 PUSH SI
239 MOV SI,OFFSET AUXTBL
240 JMP SHORT ENTRY
241
242;
243; Printer interrupt routine for processing I/O packets.
244;
245
246PRN_INT:
247 PUSH SI
248 MOV SI,OFFSET PRNTBL
249 JMP SHORT ENTRY
250
251;
252; Clock interrupt routine for processing I/O packets.
253;
254
255TIM_INT:
256 PUSH SI
257 MOV SI,OFFSET TIMTBL
258 JMP SHORT ENTRY
259
260;
261; Disk interrupt routine for processing I/O packets.
262;
263
264DSK_INT:
265 PUSH SI
266 MOV SI,OFFSET DSKTBL
267
268;
269; Common program for handling the simplistic I/O packet
270; processing scheme in MSDOS 2.0
271;
272
273ENTRY: PUSH AX ;Save all nessacary registers.
274 PUSH CX
275 PUSH DX
276 PUSH DI
277 PUSH BP
278 PUSH DS
279 PUSH ES
280 PUSH BX
281
282 LDS BX,CS:[PTRSAV] ;Retrieve pointer to I/O Packet.
283
284 MOV AL,[BX.UNIT] ;AL = Unit code.
285 MOV AH,[BX.MEDIA] ;AH = Media descriptor.
286 MOV CX,[BX.COUNT] ;CX = Contains byte/sector count.
287 MOV DX,[BX.START] ;DX = Starting Logical sector.
288
289 XCHG DI,AX ;Move Unit & Media into DI temporarily.
290 MOV AL,[BX.CMD] ;Retrieve Command type. (1 => 11)
291 XOR AH,AH ;Clear upper half of AX for calculation.
292 ADD SI,AX ;Compute entry pointer in dispatch table.
293 ADD SI,AX
294 CMP AL,11 ;Verify that not more than 11 commands.
295 JA CMDERR ;Ah, well, error out.
296 XCHG AX,DI ;Move Unit & Media back where they belong.
297 LES DI,[BX.TRANS] ;DI contains addess of Transfer address.
298 ;ES contains segment.
299 PUSH CS
300 POP DS ;Data segment same as Code segment.
301 JMP [SI] ;Perform I/O packet command.
302
303 PAGE
304 SUBTTL Common error and exit points.
305
306BUS_EXIT: ;Device busy exit.
307 MOV AH,00000011B ;Set busy and done bits.
308 JMP SHORT EXIT1
309
310CMDERR: MOV AL,3 ;Set unknown command error #.
311
312;
313; Common error processing routine.
314; AL contains actual error code.
315;
316; Error # 0 = Write Protect violation.
317; 1 = Unkown unit.
318; 2 = Drive not ready.
319; 3 = Unknown command in I/O packet.
320; 4 = CRC error.
321; 5 = Bad drive request structure length.
322; 6 = Seek error.
323; 7 = Unknown media discovered.
324; 8 = Sector not found.
325; 9 = Printer out of paper.
326; 10 = Write fault.
327; 11 = Read fault.
328; 12 = General failure.
329;
330
331ERR_EXIT:
332 MOV AH,10000001B ;Set error and done bits.
333 STC ;Set carry bit also.
334 JMP SHORT EXIT1 ;Quick way out.
335
336EXITP PROC FAR ;Normal exit for device drivers.
337
338EXIT: MOV AH,00000001B ;Set done bit for MSDOS.
339EXIT1: LDS BX,CS:[PTRSAV]
340 MOV [BX.STATUS],AX ;Save operation compete and status.
341
342 POP BX ;Restore registers.
343 POP ES
344 POP DS
345 POP BP
346 POP DI
347 POP DX
348 POP CX
349 POP AX
350 POP SI
351 RET ;RESTORE REGS AND RETURN
352EXITP ENDP
353
354 PAGE
355 SUBTTL Main console I/O section.
356
357MCON DW 0001H
358PCON DW 0002H
359ACON DW 0003H
360
361CHAR DB ? ;Small typeahead buffer for now.
362
363;
364; Console keyboard handler.
365;
366
367CISTAT: PUSH CX ;Save CX pair.
368 MOV AL,[CHAR]
369 OR AL,AL
370 JNZ CISTA9 ;Character still in buffer.
371CISTA1: MOV BX,ROM_CONSTA
372 MOV CX,[MCON]
373 CALL ROM_CALL ;See if character waiting.
374 TEST AL,AL
375 JZ CISTA9
376 MOV BX,ROM_CONIN
377 MOV CX,[MCON]
378 CALL ROM_CALL ;Get character from Rom.
379 OR AL,AL
380 JZ CISTA1 ;Got a null character.
381 MOV [CHAR],AL
382CISTA9: POP CX ;Can't lose CX pair.
383 RET
384
385;
386; Get a character from the buffer queue.
387;
388
389CINP: CALL CISTAT ;Check for character ready in queue.
390 JZ CINP ;Cycle until one ready.
391 MOV [CHAR],0 ;We have character in AL, clear type a head.
392 RET
393
394;
395; Console read non-destructive.
396;
397
398CON_RDND:
399 CALL CISTAT ;See if character ready.
400 JZ CON_RDN2 ;No, return busy signal.
401CON_RDN1:
402 LDS BX,CS:[PTRSAV]
403 MOV [BX.MEDIA],AL
404 JMP EXIT
405CON_RDN2:
406 JMP BUS_EXIT
407
408;
409; Console destructive read.
410;
411
412CON_READ:
413 CALL CINP ;Get character.
414 STOSB ;Save it in users buffer.
415 LOOP CON_READ ;Loop until CX is exhausted.
416 JMP EXIT
417
418;
419; Console flush routine. (ctrl-c, ctrl-f, or ctrl-s inspired)
420;
421
422CON_FLSH:
423 MOV [CHAR],0 ;Clear small type a head buffer.
424 JMP EXIT
425
426;
427; Console output status routine.
428;
429
430CON_WRST:
431 JMP EXIT ;Yes, normal exit.
432
433;
434; Console output routine.
435;
436
437CON_WRIT:
438 MOV SI,DI ;Get destination to source.
439CON_WRI1:
440 LODS BYTE PTR ES:[SI]
441 PUSH CX
442IF ANSI
443 CALL CONOUT ;Call ansi driver.
444 ENDIF
445IFE ANSI
446 CALL OUTCHR
447 ENDIF
448 POP CX
449 LOOP CON_WRI1 ;Keep going until user buffer through.
450 JMP EXIT
451
452;
453; Console character output routine.
454;
455
456OUTCHR: MOV BX,ROM_CONOUT
457 MOV CX,[MCON] ;Get current console port.
458 MOV DL,AL
459 CALL ROM_CALL
460 RET
461
462 PAGE
463
464IF ANSI
465
466 SUBTTL ANSI interface section.
467
468;
469;ANSI Info and routines. ANSI driver implemented as a finite state automata
470;This ANSI driver translates the ANSI standard escape sequences into the
471; Zenith Escape sequences used on the Zenith(Heath) Z(H)-19 terminal.
472;This is not a full implementation of ANSI, but rather a minimal implementation
473; which implements all of the necessary ANSI functions.
474;
475
476ESC EQU 1BH ;Escape character used in this implementation.
477STATE DW ST1 ;Current ANSI character state.
478PRMPNT DW PARMS ;Current parameter pointer.
479PARMS DB 0,0,0,0,0,0,0 ;Allow for up to eight parameters.
480LASTPRM DB 0 ;With this being the eight one.
481
482CMDTABL DB 'A' ;Cursor up. "esc","[",#,"A"
483 DW CUU
484 DB 'B' ;Cursor down. "esc","[",#,"B"
485 DW CUD
486 DB 'C' ;Cursor forward. "esc","[",#,"C"
487 DW CUF
488 DB 'D' ;Cursor back. "esc","[",#,"D"
489 DW CUB
490 DB 'H' ;Direct cursor posit. "esc","[",x,y,"H"
491 DW CUP
492 DB 'J' ;Erase. "esc","[",code,"J"
493 DW ED
494 DB 'K' ;Erase in line. "esc","[",code,"K"
495 DW EL
496 DB 'f' ;Direct cursor posit. "esc","[",x,y,"f"
497 DW CUP
498 DB 'm' ;Special video mode. "esc","[",code,"m"
499 DW SGR
500 DB 's' ;Save cursor posit. "esc","[","s"
501 DW PSCP
502 DB 'u' ;Move cursor to saved. "esc","[","u"
503 DW PRCP
504 DB 00 ;End of table.
505
506;
507; ANSI console output driver.
508;
509
510CONOUT: MOV DI,OFFSET STATE ;Retrieve current ansi state.
511 JMP [DI] ;Jump to it.
512
513;
514; State one (1).
515; Looks for an Escape character.
516;
517
518ST1: CMP AL,ESC ;See if this the first character is ESC.
519 JNZ OUTCHR ;No, treat as regular character output.
520 MOV WORD PTR [DI],OFFSET ST2 ;Yes, setup state two.
521 RET
522
523;
524; State two (2).
525; Looks for the "[" character.
526;
527
528ST2: CMP AL,'[' ;See if a valide state two.
529 JNZ OUTCHR ;No, treat as regular charcter
530 MOV BX,OFFSET PARMS ;Yes, get parameter pointer.
531 MOV WORD PTR [PRMPNT],BX ;Setup in pointer index.
532 MOV WORD PTR [BX],0 ;Clear first entry.
533 MOV WORD PTR [DI],OFFSET ST3;Setup for state three.
534 RET
535
536;
537; State three (3).
538; Entered one or more times for parameter passing.
539;
540
541ST3: CMP AL,';' ;Look for decimal # seperator.
542 JNZ ST3A ;No check phase A.
543 INC WORD PTR [PRMPNT] ;Yes, incr. pointer to next param.
544 MOV AX,OFFSET LASTPRM ;Check for outside parameter list.
545 CMP [PRMPNT],AX
546 JBE RETST3 ;Yes, proceed with next parameter.
547 MOV [PRMPNT],AX ;No, treat as extentsion to old.
548RETST3: MOV DI,[PRMPNT] ;Setup for next parameter.
549 MOV BYTE PTR [DI],0 ;Pre-Initialize it to zero.
550 RET
551
552;
553; State three A (3A).
554; Check for a ascii digit.
555;
556
557ST3A: CMP AL,'0' ;Check for ASCII digit.
558 JB ST3B ;No, check for seconday command character.
559 CMP AL,'9' ;Still checking for ASCII digit.
560 JA ST3B ;No, it must be a secondary.
561 SUB AL,'0' ;Convert to binary.
562 MOV DI,[PRMPNT] ;Get the current parameter pointer.
563 XCHG [DI],AL ;Get existing #.
564 MOV AH,10 ;Scale by 10.
565 MUL AH
566 ADD [DI],AL ;Add to new digit.
567 RET
568
569;
570; State three B (3B).
571; Wasn't a ascii digit, so check for secondary command.
572;
573
574ST3B: MOV [DI],OFFSET ST1 ;Preset STATE to state 1 just in case.
575 MOV DI,OFFSET PARMS-1 ;Get pointer to start of parameters.
576 MOV [PRMPNT],DI ;Save it in Parameter pointer.
577 MOV DI,OFFSET CMDTABL-3 ;Get start of Secondary command table.
578
579ST3B1: ADD DI,3 ;Update Command table pointer.
580 CMP BYTE PTR [DI],0 ;Check for end of table.
581 JNZ ST3B2 ;No, continue processing.
582 JMP OUTCHR ;Yes, treat as regular character.
583ST3B2: CMP AL,[DI] ;Check for valid. command.
584 JNZ ST3B1 ;No, keep checking.
585 JMP [DI+1] ;Yes, transfer to that secondary command.
586
587;
588; Get binary parameter from storage and return a one if = 0
589;
590
591GETONE: CALL GETPARM ;Get parameter form list.
592 OR AL,AL ;Verify for non-zero.
593 JNZ GETRET ;Good, then return to caller.
594 INC AL ;Bad, make it at least a one.
595GETRET: CBW ;Sign extend AL.
596 MOV CX,AX ;Copy of it to CX.
597 RET
598
599GETPARM:INC WORD PTR [PRMPNT] ;Increment parameter pointer.
600GOTPARM:MOV DI,[PRMPNT] ;Get parameter pointer.
601 MOV AL,[DI] ;Get parameter value.
602 RET
603
604;
605; Send escape, character sequence.
606;
607
608OUTESC: MOV AL,ESC ;Send escape character.
609 CALL OUTCHR
610 MOV AL,BL ;Send follow character.
611 JMP OUTCHR
612
613;
614; Cursor Positioning routines.
615;
616
617CUU: MOV BL,'A' ;Cursor up.
618 JMP SHORT CURPOS
619CUD: MOV BL,'B' ;Cursor down.
620 JMP SHORT CURPOS
621CUF: MOV BL,'C' ;Cursor forward.
622 JMP SHORT CURPOS
623CUB: MOV BL,'D' ;Cursor back.
624
625CURPOS: CALL GETONE ;Get number of positions to move into CX.
626MOVCUR: CALL OUTESC ;Send escape, command characters.
627 LOOP MOVCUR ;Keep moving until done.
628 RET
629
630;
631; Direct cursor positioning routine.
632;
633
634CUP: CALL GETONE ;Get X position.
635 MOV DX,AX ;Save in DX.
636 CALL GETONE ;Get Y position.
637 MOV BL,'Y'
638 CALL OUTESC ;Send escape, "Y" sequence.
639 MOV AL,DL
640 ADD AL,' '-1 ;Convert binary to Character.
641 CALL OUTCHR ;Send X posit.
642 MOV AL,CL
643 ADD AL,' '-1 ;Convert binary to Character.
644 JMP OUTCHR ;Send Y posit.
645
646;
647; Erase all/part of screen.
648;
649
650ED: CALL GETPARM ;Get trinary command type.
651 MOV BL,'b'
652 DEC AL ;See if erase from begining of screen.
653 JZ ED1 ;Yes, perform ZDS function.
654 MOV BL,'E'
655 DEC AL ;See if erase from end of screen.
656 JZ ED1 ;Yes, perform ZDS function.
657 MOV BL,'J' ;Now we assume erase whole screen.
658ED1: JMP OUTESC
659
660;
661; Erase all/part of a line.
662;
663
664EL: CALL GETPARM ;Get trinary command type.
665 MOV BL,'o'
666 DEC AL ;See if erase from begining of line.
667 JZ EL1 ;Yes, perform ZDS function.
668 MOV BL,'l'
669 DEC AL ;See if erase whole line.
670 JZ EL1 ;Yes, perform ZDS function.
671 MOV BL,'K' ;Now we assume erase to end of line.
672EL1: JMP OUTESC
673
674;
675; Special video modes.
676;
677
678SGR: CALL GETPARM ;Get trinary command type.
679 MOV BL,'p'
680 CMP AL,7 ;See if enter reverse video mode.
681 JZ SGR2 ;Yes, perform ZDS function.
682 MOV BL,'q'
683 OR AL,AL ;See if exit reverse video mode.
684 JNZ SGR3 ;No, ignore.
685SGR2: CALL OUTESC
686SGR3: RET
687
688;
689; Save / restore cursor position.
690;
691
692PSCP: MOV BL,'j' ;Set save cursor posit. mode.
693 JMP OUTESC
694
695PRCP: MOV BL,'k' ;Restore last cursor save.
696 JMP OUTESC
697
698 ENDIF
699
700
701 PAGE
702 SUBTTL Printer buffer handler.
703
704;
705; Printer status routine.
706;
707
708PRN_STA:
709 JMP EXIT
710
711;
712; Printer write routine.
713;
714
715PRN_WRT:MOV SI,DI ;Set source = destination index.
716
717PRN_WR1:LODS BYTE PTR ES:[SI];Get a data byte.
718 PUSH CX
719 MOV CX,[PCON]
720 MOV BX,ROM_CONOUT
721 MOV DL,AL
722 CALL ROM_CALL
723 POP CX
724 LOOP PRN_WR1
725 RET
726
727 PAGE
728 SUBTTL Auxilary I/O routines.
729
730AUXCHAR DB 0 ;Temporary AUX ahead storage.
731
732;
733; Status routine for Auxilary port.
734;
735
736AISTAT: MOV AL,[AUXCHAR]
737 TEST AL,AL
738 JNZ AISTA9 ;Character already waiting.
739 MOV CX,[ACON]
740 MOV BX,ROM_CONSTA
741 CALL ROM_CALL
742 TEST AL,AL
743 JZ AISTA9 ;Still none waiting.
744 MOV CX,[ACON]
745 MOV BX,ROM_CONIN
746 CALL ROM_CALL
747AISTA9: MOV [AUXCHAR],AL
748 RET
749
750;
751; Auxilary port read.
752;
753
754AIN: CALL AISTAT ;Get status and/or char.
755 JZ AIN ;Cycle until one is ready.
756 MOV [AUXCHAR],0
757 RET
758
759;
760; Write routine for Auxilary port.
761;
762
763AOUT: MOV CX,[ACON]
764 MOV BX,ROM_CONOUT
765 MOV DL,AL
766 CALL ROM_CALL
767 RET
768
769;
770; Non-Destructive Auxilary read routine.
771;
772
773AUX_RDND:
774 CALL AISTAT ;Get status and copy of char. waiting if any.
775 JZ AUX_RDN2 ;No character waiting, exit.
776 JMP CON_RDN1
777AUX_RDN2:
778 JMP BUS_EXIT
779
780;
781; Destructive Auxilary read routine.
782;
783
784AUX_READ:
785 CALL AIN ;Get data character.
786 STOSB ;Save it through DI.
787 LOOP AUX_READ ;Cycle until user buffer full.
788 JMP EXIT
789
790;
791; Auxilary clear type a head.
792;
793
794AUX_CLR:
795 MOV [AUXCHAR],0
796 JMP EXIT
797
798;
799; Auxilary write port status.
800;
801
802AUX_WRST:
803 JMP EXIT
804
805;
806; Auxilary write.
807;
808
809AUX_WRIT:
810 MOV SI,DI
811AUX_WRI1:
812 LODS BYTE PTR ES:[SI] ;Get char. from users buffer.
813 CALL AOUT ;Send it to device.
814 LOOP AUX_WRI1 ;Cycle until all done.
815 JMP EXIT
816
817 PAGE
818 SUBTTL Date/Time Routines.
819
820TIM_DAYS: DB 2 DUP (?) ;Number of days since 1-1-80.
821TIM_MINS: DB ? ;Minutes.
822TIM_HRS: DB ? ;Hours.
823TIM_HSEC: DB ? ;Hundreths of a second.
824TIM_SECS: DB ? ;Seconds.
825
826;
827; Time write routine.
828;
829
830TIM_WRT:
831 MOV SI,OFFSET TIM_DAYS
832 XCHG SI,DI
833 PUSH ES
834 MOV AX,DS
835 POP DS
836 MOV ES,AX
837 MOV CX,6
838 REP MOVSB
839 MOV AL,0
840 JMP EXIT
841
842;
843; Time read routine.
844;
845
846TIM_RED:
847 MOV SI,OFFSET TIM_DAYS
848 MOV CX,6
849 REP MOVSB
850 MOV AL,0
851 JMP EXIT
852
853 PAGE
854 SUBTTL 8089 Monitor structure.
855
856;
857; Structure to reference 8089 and ROM command table.
858;
859
860SIOPB STRUC
861 DB 4 DUP (?) ;Monitor Use Only
862OPCODE DB ? ;I/O operation code.
863DRIVE DB ? ;Logical drive spec.
864TRACK DW ? ;Logical track number.
865HEAD DB ? ;Logical head number.
866SECTOR DB ? ;Logical sector to start with.
867SCOUNT DB ? ;Number of logical sectors in buffer.
868RETCODE DB ? ;Error code after masking.
869RETMASK DB ? ;Error mask.
870RETRIES DB ? ;Number of retries before error exit.
871DMAOFF DW ? ;Buffer offset address.
872DMASEG DW ? ;Buffer segment.
873SECLENG DW ? ;Sector Length.
874 DB 6 DUP (?) ;8089 use only.
875SIOPB ENDS
876
877IOPB SIOPB <,00H,0,0,0,0,0,0,000H,0,0,0,0,>
878
879 PAGE
880 SUBTTL Drive Tables.
881
882
883;
884; MSDOS drive initialization tables and other what not.
885;
886; Drive 0 is:
887; Single sided, Single density, 77 track with 26
888; 128 byte sectors per track. One sector for
889; boot and header. (256,128 bytes free, old style).
890; or
891; Single sided, Single density, 77 track with 26
892; 128 byte sectors per track. Four sectors for
893; boot and header. (255,744 bytes free).
894; or
895; Single sided, Double Density, 75 track with 12
896; 512 byte sectors per track.
897; (460,800 bytes)
898; Two hidden single density tracks.
899;
900
901DBP STRUC
902
903JMPNEAR DB 3 DUP (?) ;Jmp Near xxxx for boot.
904NAMEVER DB 8 DUP (?) ;Name / Version of OS.
905
906;------- Start of Drive Parameter Block.
907
908SECSIZE DW ? ;Sector size in bytes. (dpb)
909ALLOC DB ? ;Number of sectors per alloc. block. (dpb)
910RESSEC DW ? ;Reserved sectors. (dpb)
911FATS DB ? ;Number of FAT's. (dpb)
912MAXDIR DW ? ;Number of root directory entries. (dpb)
913SECTORS DW ? ;Number of sectors per diskette. (dpb)
914MEDIAID DB ? ;Media byte ID. (dpb)
915FATSEC DW ? ;Number of FAT Sectors. (dpb)
916
917;------- End of Drive Parameter Block.
918
919SECTRK DW ? ;Number of Sectors per track.
920
921DBP ENDS
922
923LSDRIV1 DBP <,,128,4,1,2,68,2002,0FEH,6,26>
924
925LSDRIV2 DBP <,,128,4,4,2,68,2002,0FDH,6,26>
926
927LDDRIV1 DBP <,,512,1,24,2,128,924,0F8H,3,12>
928
929LDDRIV2 DBP <,,1024,1,16,2,128,616,0F9H,1,8>
930
931DSK_INIT:
932 MOV AX,1
933 MOV SI,OFFSET INITTAB
934 JMP GET_BP5
935
936INITTAB:
937 DW LDDRIV2.SECSIZE
938
939DSTAT EQU 41H ;1793 status port.
940DTRACK EQU 43H ;1793 track port.
941DSECTOR EQU 45H ;1793 sector port.
942DDATA EQU 47H ;1793 data I/O port.
943
944DDENS EQU 55H ;Density select port.
945DDBIT EQU 04H ;Density select bit.
946DSELECT EQU 53H ;Drive select port.
947
948CURDRV DB 0
949DRVTAB DB 0EH,0DH,0BH,07H
950TRKPT DB 0,1,2,3
951TRKTAB DB -1,-1,-1,-1
952PREDENS DB 0,0,0,0
953
954 PAGE
955 SUBTTL Media check routine
956
957;
958; Media check routine.
959; On entry:
960; AL = disk unit number.
961; AH = media byte
962; On exit:
963;
964; [MEDIA FLAG] = -1 (FF hex) if disk is changed.
965; [MEDIA FLAG] = 0 if don't know.
966; [MEDIA FLAG] = 1 if not changed.
967;
968; [MEDIA] = 0FEH for Standard single density.
969; [MEDIA] = 0FDH for Altos single density.
970; [MEDIA] = 0F4H for Altos double density.
971;
972
973MEDIAS STRUC
974 DB 13 DUP(?) ;Static request header.
975MEDIAS1 DB ? ;Media byte.
976MEDIAS2 DB ? ;Media status byte flag.
977MEDIAS ENDS
978
979MEDIAC:
980 AND AL,03H ;Clear any extraneous bits.
981 PUSH AX ;Save drive number requested.
982 MOV AL,0D0H ;Terminate with no interrupt.
983 CALL DCOM
984 AND AL,20H ;See if head load bit set.
985 POP AX
986 JZ MEDIA2 ;Head not loaded, so see if media changed.
987 MOV AH,1 ; AH = 1, disk not changed.
988 JMP SHORT MEDIA1
989
990MEDIA1A:MOV [PREDENS],DL ;Save last density used for read.
991
992MEDIA1: LDS BX,[PTRSAV] ;Udate media section of data block.
993 MOV [BX.MEDIAS2],AH
994 MOV AL,0
995 JMP EXIT
996
997MEDIA2: CALL MEDIA4 ;Unload head if selecting new drive.
998 MOV CX,2 ;Try each density once.
999 MOV BX,OFFSET DRVTAB
1000 XLAT ;Convert from drive # to select code.
1001 OUT DSELECT,AL ;Select disk
1002 MOV AH,0 ;Assume that we don't know.
1003 MOV DL,[PREDENS] ;Get last density.
1004 AND DL,DDBIT ;Be sure only Density bit set/clr.
1005MEDIA3: IN AL,DDENS
1006 AND AL,0FBH ;Clear density bit.
1007 OR AL,DL ;Set/clear density bit.
1008 OUT DDENS,AL ;Select density.
1009 MOV AL,0C4H ;READ ADDRESS command
1010 CALL DCOM
1011 AND AL,98H
1012 IN AL,DDATA ;Eat last byte to reset DRQ
1013 JZ MEDIA1A ;Jump if no error in reading address.
1014 MOV AH,0FFH ; AH = -1 (disk changed) if new density works.
1015 XOR DL,DDBIT ;Flip density bit.
1016 LOOP MEDIA3
1017 MOV AX,2 ;Couldn't read disk at all, AH = 0 for don't
1018 JMP ERR_EXIT ; know if disk changed, AL = error code 2 -
1019
1020MEDIA4: MOV AH,AL ;Save disk drive number in AH.
1021 XCHG AL,[CURDRV] ;make new drive current, AL = previous
1022 CMP AL,AH ;Changing drives?
1023 JZ MEDIA5 ;No, return to caller.
1024;
1025; If changing drives, unload head so the head load delay one-shot
1026; will fire again. Do it by seeking to same track with the H bit reset.
1027;
1028 IN AL,DTRACK ;Get current track number
1029 OUT DDATA,AL ;Make it the track to seek to
1030 MOV AL,10H ;Seek and unload head
1031 CALL DCOM
1032 MOV AL,AH ;Restore current drive number
1033MEDIA5: RET
1034
1035;
1036; Short routine to send a command to 1793 diskette controller chip and
1037; wait for 1793 to complete the command.
1038;
1039
1040DCOM: OUT 41H,AL ;Send command to 1793.
1041 MOV CX,10H
1042DCOM1: LOOP DCOM1 ;Wait a short time for 1793 to digest it.
1043
1044DCOM2: IN AL,41H ;Get 1793's status.
1045 AND AL,1 ;See if busy.
1046 JNZ DCOM2 ;Yes, keep checking.
1047 IN AL,41H ;Get 1793's status for return
1048 RET
1049
1050 PAGE
1051 SUBTTL Build and return Bios Parameter Block for a diskette.
1052
1053;
1054; Build Bios Parameter Blocks.
1055;
1056; On entry: ES:DI contains the address of a scratch sector buffer.
1057; AL = Unit number.
1058; AH = Current media byte.
1059;
1060; On exit: Return a DWORD pointer to the associated BPB
1061; in the Request packet.
1062;
1063
1064BPBS STRUC
1065 DB 13 DUP(?) ;Static request header.
1066BPB1 DB ? ;Media byte.
1067BPB2 DW ? ;DWORD transfer address.
1068 DW ?
1069BPB3 DW ? ;DWORD pointer to BPB
1070 DW ?
1071BPBS ENDS
1072
1073GET_BPB:
1074 PUSH ES
1075 PUSH DI
1076 MOV [IOPB.DMASEG],ES
1077 MOV [IOPB.DMAOFF],DI
1078 MOV BYTE PTR[IOPB.SECTOR],1
1079 MOV BYTE PTR[IOPB.SCOUNT],1
1080 MOV BYTE PTR[IOPB.OPCODE],088H
1081 MOV BYTE PTR[IOPB.RETRIES],1
1082 MOV BYTE PTR[IOPB.DRIVE],0
1083 MOV [IOPB.TRACK],0
1084 MOV BYTE PTR[IOPB.HEAD],1
1085 MOV BYTE PTR[IOPB.RETMASK],0DCH
1086 MOV [IOPB.SECLENG],128
1087 MOV BX,ROM_DISKIO
1088 MOV CX,OFFSET IOPB
1089 PUSH CS
1090 POP ES
1091 CALL ROM_CALL ;Read sector zero for information.
1092 PUSH CS
1093 POP DS
1094 POP DI
1095 POP ES
1096 MOV AH,[IOPB.RETCODE]
1097 OR AH,AH
1098 JNZ GET_BP3 ;Disk error, assume old single density.
1099
1100GET_BP1:MOV AL,ES:[DI.MEDIAID] ;Get diskettes media ID.
1101 MOV SI,OFFSET LSDRIV2
1102 CMP AL,[SI.MEDIAID]
1103 JZ GET_BP4
1104 MOV SI,OFFSET LDDRIV1
1105 CMP AL,[SI.MEDIAID]
1106 JZ GET_BP4
1107 MOV SI,OFFSET LDDRIV2
1108 CMP AL,[SI.MEDIAID]
1109 JZ GET_BP4
1110
1111GET_BP3:MOV SI,OFFSET LSDRIV1 ;No compares, assume old style for now.
1112
1113GET_BP4:MOV AL,[SI.MEDIAID]
1114 ADD SI,11 ;Convert to DPB pointer
1115
1116GET_BP5:LDS BX,[PTRSAV] ;Update I/O data packet.
1117 MOV [BX.BPB1],AL ;Media byte.
1118 MOV [BX.BPB3],SI ;DPB pointer.
1119 MOV [BX.BPB3+2],CS ;Code segment.
1120 OR AH,AH
1121 JNZ GET_BP6
1122 MOV AL,0
1123 JMP EXIT
1124GET_BP6:MOV AX,7
1125 JMP ERR_EXIT
1126
1127 PAGE
1128
1129 SUBTTL Disk I/O equates.
1130
1131; Floppy drives
1132
1133; --------------------------
1134; Hardware command def.
1135; --------------------------
1136;
1137; Read command = 88 hex.
1138; Write command = A8 hex.
1139; Format command = F0 hex.
1140; Seek command = 1E hex.
1141; Recal command = 0A hex.
1142; Set DD mode = 80 hex.
1143;
1144; --------------------------
1145; Status bits:
1146; --------------------------
1147;
1148; Busy = 01 hex.
1149; (not used) = 02 hex.
1150; TK0(seek) = 04 hex.
1151; Lost Data = 04 hex.
1152; CRC error = 08 hex.
1153; Seek error = 10 hex.
1154; Not found = 10 hex.
1155; Write fault = 20 hex.
1156; Write protect = 40 hex.
1157; Not ready = 80 hex.
1158;
1159; --------------------------
1160
1161F_READ EQU 088H ;Floppy read command.
1162F_WRIT EQU 0A8H ;Floppy write command.
1163F_FMT EQU 0F0H ;Floppy format command.
1164F_SEEK EQU 01EH ;Floppy seek command.
1165F_RECAL EQU 00AH ;Floppy recal. command.
1166F_DD EQU 080H ;Set Drive double density bit.
1167
1168 PAGE
1169 SUBTTL MSDOS 2.x Disk I/O drivers.
1170
1171;
1172; Disk READ/WRITE functions.
1173;
1174; On entry:
1175; AL = Disk I/O driver number
1176; AH = Media byte.
1177; ES = Disk transfer segment.
1178; DI = Disk transfer offset in ES.
1179; CX = Number of sectors to transfer
1180; DX = Logical starting sector.
1181;
1182; On exit:
1183; Normal exit through common exit routine.
1184;
1185; Abnormal exit through common error routine.
1186;
1187
1188DSK_RED:
1189 MOV BX,0DC88H ;Set read mode and Error mask.
1190 JMP SHORT DSK_COM
1191DSK_WRV:
1192DSK_WRT:MOV BX,0FCA8H ;Set write mode and Error mask.
1193
1194DSK_COM:MOV SI,OFFSET LSDRIV1
1195 CMP AH,[SI.MEDIAID]
1196 JE DSK_CO3
1197 MOV SI,OFFSET LSDRIV2
1198 CMP AH,[SI.MEDIAID]
1199 JE DSK_CO3
1200 MOV SI,OFFSET LDDRIV1
1201 CMP AH,[SI.MEDIAID]
1202 JE DSK_CO2
1203 MOV SI,OFFSET LDDRIV2
1204 CMP AH,[SI.MEDIAID]
1205 JE DSK_CO2
1206 MOV AL,7
1207 JMP ERR_EXIT
1208
1209DSK_CO2:OR AL,F_DD ;Set double density mode.
1210
1211DSK_CO3:MOV [IOPB.DMASEG],ES ;Setup Buffer segment.
1212 MOV [IOPB.DMAOFF],DI ;Setup buffer offset.
1213 MOV DI,[SI.SECSIZE] ;Get sector size.
1214 MOV [IOPB.SECLENG],DI
1215 MOV [IOPB.RETRIES],1 ;Setup number of retries.
1216 MOV [IOPB.RETMASK],BH ;Operation error mask.
1217 MOV [IOPB.OPCODE],BL ;R/W opcode.
1218 MOV [IOPB.DRIVE],AL ;Drive with density select.
1219 MOV [IOPB.HEAD],1 ;Only one head on floppy drive.
1220 MOV BP,CX ;Save number of sectors to R/W
1221DSK_CO4:PUSH DX ;Save starting sector.
1222 MOV AX,DX
1223 MOV DX,0 ;32 bit divide coming up.
1224 MOV CX,[SI.SECTRK]
1225 DIV CX ;Get track+head and start sector.
1226 INC DL
1227 MOV [IOPB.SECTOR],DL ;Starting sector.
1228 MOV BL,DL ;Save starting sector for later.
1229 MOV [IOPB.TRACK],AX ;Track to read/write.
1230 MOV AX,[SI.SECTRK] ;Now see how many sectors
1231 INC AL ; we can burst read.
1232 SUB AL,BL ;BL is the starting sector.
1233 MOV AH,0
1234 POP DX ;Retrieve logical sector start.
1235 CMP AX,BP ;See if on last partial track+head.
1236 JG DSK_CO5 ;Yes, on last track+head.
1237 SUB BP,AX ;No, update number of sectors left.
1238 ADD DX,AX ;Update next starting sector.
1239 JMP SHORT DSK_CO6
1240DSK_CO5:MOV AX,BP ;Only read enough of sector
1241 MOV BP,0 ;to finish buffer and clear # left.
1242DSK_CO6:MOV [IOPB.SCOUNT],AL
1243 MOV DI,AX ;Save number sectors for later.
1244 MOV BX,ROM_DISKIO
1245 MOV CX,OFFSET IOPB
1246 PUSH CS
1247 POP ES
1248 CALL ROM_CALL ;Do disk operation.
1249 MOV AL,[IOPB.RETCODE] ;Get error code.
1250 OR AL,AL
1251 JNZ DERROR
1252 MOV AX,DI ;Retrieve number of sectors read.
1253 MOV CX,[SI.SECSIZE] ;Number of bytes per sector.
1254 PUSH DX
1255 MUL CX
1256 POP DX
1257 TEST AL,0FH ;Make sure no strange sizes.
1258 JNZ DSK_CO7 ;Illegal sector size found.
1259 MOV CL,4
1260 SHR AX,CL ;Convert number of bytes to para.
1261 ADD AX,[IOPB.DMASEG]
1262 MOV [IOPB.DMASEG],AX
1263 OR BP,BP
1264 JNZ DSK_CO4 ;Still more to do.
1265 MOV AL,0
1266 JMP EXIT ;All done.
1267DSK_CO7:MOV AL,12
1268 JMP ERR_EXIT
1269
1270 PAGE
1271 SUBTTL Disk Error processing.
1272
1273;
1274; Disk error routine.
1275;
1276
1277DERROR: LDS BX,CS:[PTRSAV]
1278 MOV [BX.COUNT],0
1279 PUSH CS
1280 POP DS
1281
1282 MOV BL,-1
1283 MOV AH,AL
1284 MOV BH,14 ;Lenght of table.
1285 MOV SI,OFFSET DERRTAB
1286DERROR2:INC BL ;Increment to next error code.
1287 LODS BYTE PTR CS:[SI]
1288 CMP AH,AL ;See if error code matches disk status.
1289 JZ DERROR3 ;Got the right error, exit.
1290 DEC BH
1291 JNZ DERROR2 ;Keep checking table.
1292 MOV BL,12 ;Set general type of error.
1293DERROR3:MOV AL,BL ;Now we've got the code.
1294 RET
1295
1296DERRTAB DB 40H ; 0. Write protect error
1297 DB 00H ; 1. Unknown unit.
1298 DB 80H ; 2. Not ready error.
1299 DB 0FFH ; 3. Unknown command.
1300 DB 08H ; 4. CRC error
1301 DB 00H ; 5. Bad drive request.
1302 DB 02H ; 6. Seek error
1303 DB 00H ; 7. Unknown media.
1304 DB 10H ; 8. Sector not found
1305 DB 00H ; 9. (Not used.)
1306 DB 20H ;10. Write fault.
1307 DB 04H ;11. Read fault.
1308 DB 07H ;12. General type of failure.
1309
1310 PAGE
1311 SUBTTL Common ROM call routine.
1312
1313;
1314; Save all registers except CX, BX and AX.
1315
1316ROMRTN DD 0FE000000H ;Main ROM entry point.
1317
1318ROM_CALL:
1319 PUSH DI
1320 PUSH SI
1321 PUSH BP
1322 PUSH DX
1323 PUSH ES
1324 CALL CS:DWORD PTR [ROMRTN]
1325 POP ES
1326 POP DX
1327 POP BP
1328 POP SI
1329 POP DI
1330 RET
1331
1332 PAGE
1333 SUBTTL Initalization code and temporary work areas.
1334
1335;
1336; Overlayed by MSDOS by SYSINIT.
1337;
1338
1339WRKSTK LABEL WORD
1340 DB 100 DUP (?)
1341
1342
1343HWINIT: XOR BP,BP
1344 MOV SS,BP
1345 MOV SP,OFFSET WRKSTK+98 ;Some nice area for stack.
1346
1347 PUSH CS
1348 POP ES
1349
1350 MOV BX,ROM_INIT
1351 CALL ROM_CALL
1352 MOV AH,0
1353 MOV MCON,AX
1354
1355 MOV AX,SEG SYSINIT
1356 MOV DS,AX
1357
1358ASSUME DS:SEG SYSINIT
1359
1360 MOV AX,CS
1361 ADD AX,BIOSIZS
1362 MOV DS:[CURRENT_DOS_LOCATION],AX
1363 MOV DS:[MEMORY_SIZE],MAX_MEM
1364 MOV AX,CS
1365 MOV WORD PTR DS:[DEVICE_LIST+2],AX
1366 MOV WORD PTR DS:[DEVICE_LIST],OFFSET DEVSTART
1367 MOV AX,CS
1368 ADD AX,((OFFSET WRKSTK - OFFSET INIT)+50) /16
1369 MOV DS:[FINAL_DOS_LOCATION],AX
1370 JMP SYSINIT
1371
1372DOSSPOT LABEL WORD
1373
1374CODE ENDS
1375
1376 END
1377
diff --git a/v2.0/source/SORT.ASM b/v2.0/source/SORT.ASM
new file mode 100644
index 0000000..a4f39e8
--- /dev/null
+++ b/v2.0/source/SORT.ASM
@@ -0,0 +1,420 @@
1TITLE SORT FILTER FOR MS-DOS
2;
3; Sort /R /+n
4; /R -> reverse sort
5; /+n -> sort on column n
6;
7; Written by: Chris Peters
8;
9; Modification History:
10; 3-18-83 MZ Fix CR-LF at end of buffer
11; Fix small file sorting
12; Fix CR-LF line termination bug
13; Comment the Damn source
14;
15FALSE EQU 0
16TRUE EQU NOT FALSE
17
18;NOTE: "internat" must be false if KANJI version
19internat equ true
20;NOTE: see above
21
22.xlist
23.xcref
24 INCLUDE DOSSYM.ASM
25.cref
26.list
27
28sys MACRO name ; system call macro
29 MOV AH,name
30 INT 21h
31 ENDM
32save MACRO reglist ; push those registers
33IRP reg,<reglist>
34 PUSH reg
35ENDM
36ENDM
37restore MACRO reglist ; pop those registers
38IRP reg,<reglist>
39 POP reg
40ENDM
41ENDM
42
43MAXREC EQU 256 ; MAXIMUM NUL RECORD SIZE
44
45SPACE EQU 0 ; Offset zero in the allocated block
46BUFFER EQU MAXREC ; Offset MAXREC in the allocated block
47
48SUBTTL Segments used in load order
49
50
51CODE SEGMENT
52CODE ENDS
53
54CONST SEGMENT PUBLIC BYTE
55CONST ENDS
56
57CSTACK SEGMENT STACK
58 DB 128 DUP (0) ; initial stack to be clear
59CSTACK ENDS
60
61DG GROUP CODE,CONST,CSTACK
62
63CODE SEGMENT
64ASSUME CS:DG,DS:NOTHING,ES:NOTHING,SS:CSTACK
65
66COLUMN DW 0 ; COLUMN TO USE FOR KEY + 1
67SWITCH DB '/'
68
69SORT:
70;
71; check for proper version number of system
72;
73 sys GET_VERSION
74 XCHG AH,AL ; Turn it around to AH.AL
75 CMP AX,200H ; Version 2.00 only
76 JAE OKDOS ; Success
77 MOV DX,OFFSET DG:BADVER ; Get error message
78 PUSH CS ; Get DS addressability
79 POP DS
80 sys STD_CON_STRING_OUTPUT ; Send to STDOUT
81 PUSH ES ; long segment
82 PUSH COLUMN ; offset zero
83LONG_RET PROC FAR
84 RET ; long return to OS
85LONG_RET ENDP
86;
87; get proper switch character
88;
89OKDOS:
90 MOV AL,0 ; Get current switch character
91 sys CHAR_OPER
92 MOV SWITCH,DL
93;
94; parse command line
95;
96 MOV SI,80H ; pointer to command line
97 CLD ; go left to right
98 XOR CX,CX
99 LODSB
100 MOV CL,AL ; CX = length of command line
101SWITCH_LOOP:
102 CALL GET_CHAR ; get a character
103 CMP AL,SWITCH ; beginning of switch?
104 JNZ SWITCH_LOOP ; No, get next character
105 CALL GET_CHAR ; get 1st char of switch
106 CMP AL,'+' ; Column to sort?
107 JZ SWITCH_NUMBER ; Yes, parse a number
108 OR AL,20h ; convert to lower case
109 CMP AL,'r' ; Reverse sort?
110 JNZ SWITCH_LOOP ; No, get next switch
111 MOV CS:CODE_PATCH,72h ; sleaze JAE into JB
112 JMP SWITCH_LOOP ; get next switch
113SWITCH_NUMBER:
114 MOV COLUMN,0 ; start off at 0
115SWITCH_NEXT_NUMBER:
116 CALL GET_CHAR ; get supposed digit
117 SUB AL,'0' ; convert to number
118 JB SWITCH_LOOP ; less than '0'
119 CMP AL,9 ; is it a valid digit?
120 JA SWITCH_LOOP ; nope, get next switch
121 CBW ; make it a full word
122 MOV BX,AX ; save byte away
123 MOV AX,10 ; decimal number system
124 MUL COLUMN ; take previous result
125 ADD AX,BX ; add in low order digit
126 MOV COLUMN,AX ; save away value
127 JMP SWITCH_NEXT_NUMBER ; get next character
128GET_CHAR:
129 JCXZ END_GET ; End of line
130 DEC CX ; dec char count
131 LODSB ; get the character
132 RET ; return
133END_GET:
134 POP AX ; nuke return on stack
135;
136; set up column for proper sort offset
137;
138END_SWITCH:
139 ADD COLUMN,2
140 CMP COLUMN,2
141 JZ GOT_COL
142 DEC COLUMN
143
144;
145; Get sorting area, no more than 64K
146;
147GOT_COL:
148 MOV BX,1000H ; 64K worth of paragraphs
149GET_MEM:
150 sys ALLOC ; allocate them from somewhere
151 JNC GOT_MEM ; if error, BX has amount free, try to get it
152 OR BX,BX ; but, is BX = 0?
153 JNZ GET_MEM ; nope, try to allocate it
154 JMP SIZERR ; complain
155
156GOT_MEM:
157 MOV DS,AX ; Point DS to buffer
158 MOV ES,AX ; and point ES to buffer
159 MOV CL,4 ; 2^4 bytes per paragraph
160 SHL BX,CL ; Find out how many bytes we have
161
162;
163; clear out temporary record area
164;
165 MOV CX,MAXREC/2 ; Size of temporary buffer (words)
166 MOV AX,' ' ; Character to fill with
167 MOV DI,SPACE ; Beginning of temp buffer
168 REP STOSW ; Blam.
169;
170; read in file from standard input
171;
172 MOV DX,BUFFER + 2 ; DX = place to begin reading
173 MOV CX,BX ; CX is the max number to read
174 SUB CX,MAXREC + 2 ; remember offset of temp buffer
175SORTL:
176 XOR BX,BX ; Standard input
177 sys READ ; Read it in
178 ADD DX,AX ; Bump pointer by count read
179 SUB CX,AX ; subtract from remaining the count read
180 JZ SIZERR ; if buffer is full then error
181 OR AX,AX ; no chars read -> end of file
182 JNZ SORTL ; there were chars read. go read again
183 JMP SHORT SIZOK ; trim last ^Z terminated record
184SIZERR:
185 MOV SI,OFFSET DG:ERRMSG ; not enough memory error
186ERROR_EXIT:
187 PUSH CS ; DS addressability
188 POP DS
189 LODSW ; get length
190 MOV CX,AX ; put into appropriate register
191 MOV DX,SI ; get output destination
192 MOV BX,2 ; output to standard error
193 sys WRITE ; and write it out
194 MOV AL,1 ; return an error code
195 sys EXIT
196
197;
198; Look for a ^Z. Terminate buffer at 1st ^Z.
199;
200SIZOK:
201 MOV BX,DX ; save end pointer
202 MOV CX,DX ; get pointer to end of text
203 SUB CX,BUFFER+2 ; dif in pointers is count
204 MOV AL,1AH ; char is ^Z
205 MOV DI,BUFFER+2 ; point to beginning of text
206 REPNZ SCASB ; find one
207 JNZ NoBack ; nope, try to find CRLF
208 DEC BX ; pretend that we didn't see ^Z
209NoBack:
210 SUB BX,CX ; sub from endpointer the number left
211 SUB BX,2 ; Hope for a CR LF at end
212 CMP WORD PTR [BX],0A0Dh ; Was there one there?
213 JZ GOTEND ; yep, here is the end
214 ADD BX,2 ; nope, bump back to SCASB spot
215 CMP BYTE PTR [BX],AL ; Was there ^Z there?
216 JZ GOTEND ; yep, chop it
217 INC BX ; Nope, skip last char
218GOTEND:
219 MOV BP,BX ; BP = filesize-2(CRLF)+temp buffer+2
220 MOV WORD PTR DS:[BP],0 ; 0 at end of the file
221;
222; We now turn the entire buffer into a linked list of chains by
223; replacing CRLFs with the length of the following line (with 2 for CRLF)
224;
225 MOV BX,BUFFER ; pointer to line head (length)
226 MOV DI,BUFFER+2 ; pointer to line text
227REPLACE_LOOP:
228 MOV AL,13 ; char to look for is CR
229 MOV CX,BP ; count = end pointer
230 SUB CX,DI ; chop off start point to get length
231 INC CX ; add 1???
232REPLACE_SCAN:
233 REPNZ SCASB ; look for CR
234 JNZ REPLACE_SKIP ; count exhausted
235 CMP BYTE PTR [DI],10 ; LF there?
236 JNZ REPLACE_SCAN ; nope, continue scanning
237REPLACE_SKIP:
238 MOV AX,DI ; AX to point after CR
239 DEC AX ; AX to point to CR
240 save <AX> ; save pointer
241 SUB AX,BX ; AX is length of line found
242 MOV [BX],AX ; stuff it in previous link
243 restore <BX> ; get pointer to next
244 INC DI ; skip LF???
245 JCXZ END_REPLACE_LOOP ; no more to scan -> go sort
246 JMP REPLACE_LOOP ; look for next
247
248END_REPLACE_LOOP:
249 MOV WORD PTR [BX],0 ; terminate file with nul
250 LEA BP,[BX+2] ; remember the null line at end
251 MOV DI,BUFFER ; DI is start of unsorted section
252
253;
254; begin sort. Outer loop steps over all unsorted lines
255;
256OUTER_SORT_LOOP:
257 MOV BX,DI ; BX is start of unsorted section
258 MOV SI,BX ; SI is scanning place link
259 CMP WORD PTR [BX],0 ; are we at the end of the buffer?
260 JNZ INNER_SORT_LOOP ; No, do inner process
261 JMP END_OUTER_SORT_LOOP ; yes, go dump out
262
263;
264; BX points to best guy found so far. We scan through the sorted section
265; to find an appropriate insertion point
266;
267INNER_SORT_LOOP:
268 ADD SI,[SI] ; link to next fellow
269 MOV AX,[SI] ; get length of comparison guy
270 OR AX,AX ; test for end of buffer
271 JZ END_INNER_SORT_LOOP ; if zero then figure out insertion
272 save <SI,DI> ; save SI,DI
273 MOV DI,BX ; DI = pointer to tester link
274 SUB AX,COLUMN ; adjust length for column
275 JA AXOK ; more chars in tester than column?
276 MOV SI,SPACE ; point SI to blank area
277 MOV AX,MAXREC ; make AX be max length
278AXOK:
279 MOV DX,[DI] ; get length of best guy
280 SUB DX,COLUMN ; adjust length for column
281 JA DXOK ; there are more chars after column
282 MOV DI,SPACE ; point air to a space
283 MOV DX,MAXREC ; really big record
284DXOK:
285 MOV CX,AX ; AX is shortest record
286 CMP AX,DX ; perhaps DX is shorter
287 JB SMALL ; nope, leace CX alone
288 MOV CX,DX ; DX is shorter, put length in CX
289SMALL:
290 ADD DI,COLUMN ; offset into record
291 ADD SI,COLUMN ; offset into other record
292if not internat
293 REPZ CMPSB ; compare every one
294 endif
295if internat
296 push bx
297 push ax
298 mov bx,offset dg:table
299tloop: lodsb
300 xlat byte ptr cs:[bx]
301 mov ah,al
302 mov al,es:[di]
303 inc di
304 xlat byte ptr cs:[bx]
305 cmp ah,al
306 loopz tloop
307 pop ax
308 pop bx
309 endif
310 restore <DI,SI> ; get head pointers back
311 JNZ TESTED_NOT_EQUAL ; didn't exhaust counter, conditions set
312 CMP AX,DX ; check string lengths
313TESTED_NOT_EQUAL:
314;
315; note! jae is patched to a jbe if file is to be sorted in reverse!
316;
317CODE_PATCH LABEL BYTE
318 JAE INNER_SORT_LOOP ; if this one wasn't better then go again
319 MOV BX,SI ; it was better, save header
320 JMP INNER_SORT_LOOP ; and scan again
321
322END_INNER_SORT_LOOP:
323 MOV SI,BX ; SI is now the best person
324 CMP SI,DI ; check best for current
325 JZ END_INSERT ; best equals current, all done
326
327;
328; SI points to best line found so far
329; DI points to a place to insert this line
330; DI is guaranteed to be < SI
331; make room for line at destination
332;
333 MOV DX,[SI] ; get length of line
334 save <SI,DI> ; save positions of people
335 STD ; go right to left
336 MOV CX,BP ; get end of file pointer
337 SUB CX,DI ; get length from destination to end
338 MOV SI,BP ; start from end
339 DEC SI ; SI points to end of file
340 MOV DI,SI ; destination is end of file
341 ADD DI,DX ; DI points to new end of file
342 REP MOVSB ; blam. Move every one up
343 CLD ; back left to right
344 restore <DI,SI> ; get old source and destination
345;
346; MOVE NEW LINE INTO PLACE
347;
348 save <DI> ; save destination
349 ADD SI,DX ; adjust for previous movement
350 save <SI> ; save this value
351 MOV CX,DX ; get number to move
352 REP MOVSB ; blam. move the new line in
353 restore <SI,DI> ; get back destination and new source
354;
355; DELETE LINE FROM OLD PLACE
356;
357 save <DI> ; save destination
358 MOV CX,BP ; pointer to end
359 ADD CX,DX ; remember bump
360 SUB CX,SI ; get count of bytes to move
361 INC CX ; turn it into a word
362 SHR CX,1 ; or a count of words
363 MOV DI,SI ; new destination of move
364 ADD SI,DX ; offset of block
365 REP MOVSW ; blam, squeeze out the space
366 restore <DI> ; get back original destination
367 MOV WORD PTR DS:[BP-2],0 ; remake the end of file mark
368
369END_INSERT:
370 ADD DI,[DI] ; link to next guy
371 JMP OUTER_SORT_LOOP ; and continue
372;
373; PUT BACK IN THE CR-LF
374;
375END_OUTER_SORT_LOOP:
376 MOV DI,BUFFER ; start at beginning (where else)
377 MOV CX,[DI] ; count of butes
378
379INSERT_LOOP:
380 ADD DI,CX ; point to next length
381 MOV CX,[DI] ; get length
382 MOV WORD PTR [DI],0A0DH ; replace length with CRLF
383 CMP CX,0 ; check for end of file
384 JNZ INSERT_LOOP ; nope, try again
385
386WRITE_FILE:
387 MOV DX,BUFFER+2 ; get starting point
388 MOV CX,BP ; pointer to end of buffer
389 SUB CX,DX ; dif in pointers is number of bytes
390 MOV BX,1 ; to standard output
391 sys WRITE ; write 'em out
392 JC BADWRT ; some bizarre error -> flag it
393 CMP AX,CX ; did we write what was expected?
394 JZ WRTOK ; yes, say bye bye
395BADWRT:
396 MOV SI,OFFSET dg:ERRMSG2 ; strange write error
397 JMP ERROR_EXIT ; bye bye
398WRTOK:
399 XOR AL,AL ; perfect return (by convention)
400 sys EXIT ; bye!
401
402CODE ENDS
403
404CONST SEGMENT PUBLIC BYTE
405 EXTRN BADVER:BYTE,ERRMSG:BYTE,ERRMSG2:BYTE
406if internat
407 extrn table:byte
408 endif
409CONST ENDS
410
411SUBTTL Initialized Data
412PAGE
413CSTACK SEGMENT STACK
414 DB 96 dup (0)
415CSTACK ENDS
416
417 END SORT
418
419
420 \ No newline at end of file
diff --git a/v2.0/source/SORTMES.ASM b/v2.0/source/SORTMES.ASM
new file mode 100644
index 0000000..4fb6556
--- /dev/null
+++ b/v2.0/source/SORTMES.ASM
Binary files differ
diff --git a/v2.0/source/STDBUF.ASM b/v2.0/source/STDBUF.ASM
new file mode 100644
index 0000000..400280a
--- /dev/null
+++ b/v2.0/source/STDBUF.ASM
Binary files differ
diff --git a/v2.0/source/STDCALL.ASM b/v2.0/source/STDCALL.ASM
new file mode 100644
index 0000000..5d9d926
--- /dev/null
+++ b/v2.0/source/STDCALL.ASM
Binary files differ
diff --git a/v2.0/source/STDCTRLC.ASM b/v2.0/source/STDCTRLC.ASM
new file mode 100644
index 0000000..a02d90d
--- /dev/null
+++ b/v2.0/source/STDCTRLC.ASM
Binary files differ
diff --git a/v2.0/source/STDFCB.ASM b/v2.0/source/STDFCB.ASM
new file mode 100644
index 0000000..17cf4e9
--- /dev/null
+++ b/v2.0/source/STDFCB.ASM
@@ -0,0 +1,16 @@
1;
2; Standard FCB calls for MSDOS (first 12 function calls)
3;
4
5.xlist
6.xcref
7INCLUDE STDSW.ASM
8.cref
9.list
10
11TITLE STDFCB - FCB calls for MSDOS
12NAME STDFCB
13
14INCLUDE FCB.ASM
15
16 \ No newline at end of file
diff --git a/v2.0/source/STDIO.ASM b/v2.0/source/STDIO.ASM
new file mode 100644
index 0000000..c14c98a
--- /dev/null
+++ b/v2.0/source/STDIO.ASM
@@ -0,0 +1,17 @@
1;
2; Standard device IO for MSDOS (first 12 function calls)
3;
4
5.xlist
6.xcref
7INCLUDE STDSW.ASM
8INCLUDE DOSSEG.ASM
9.cref
10.list
11
12TITLE STDIO - device IO for MSDOS
13NAME STDIO
14
15INCLUDE IO.ASM
16
17 \ No newline at end of file
diff --git a/v2.0/source/STDPROC.ASM b/v2.0/source/STDPROC.ASM
new file mode 100644
index 0000000..3d44849
--- /dev/null
+++ b/v2.0/source/STDPROC.ASM
@@ -0,0 +1,16 @@
1;
2; Pseudo EXEC system call for MSDOS
3;
4
5.xlist
6.xcref
7INCLUDE STDSW.ASM
8.cref
9.list
10
11TITLE STDPROC - process maintenance for MSDOS
12NAME STDPROC
13
14INCLUDE PROC.ASM
15
16 \ No newline at end of file
diff --git a/v2.0/source/STDSW.ASM b/v2.0/source/STDSW.ASM
new file mode 100644
index 0000000..30a8a16
--- /dev/null
+++ b/v2.0/source/STDSW.ASM
@@ -0,0 +1,34 @@
1TRUE EQU 0FFFFH
2FALSE EQU NOT TRUE
3
4; Use the switches below to produce the standard Microsoft version or the IBM
5; version of the operating system
6MSVER EQU false
7IBM EQU true
8WANG EQU FALSE
9ALTVECT EQU FALSE
10
11; Set this switch to cause DOS to move itself to the end of memory
12HIGHMEM EQU FALSE
13
14 IF IBM
15ESCCH EQU 0 ; character to begin escape seq.
16CANCEL EQU 27
17TOGLINS EQU TRUE ;One key toggles insert mode
18TOGLPRN EQU TRUE ;One key toggles printer echo
19ZEROEXT EQU TRUE
20 ELSE
21 IF WANG ;Are we assembling for WANG?
22ESCCH EQU 1FH ;Yes. Use 1FH for escape character
23 ELSE
24ESCCH EQU 1BH
25 ENDIF
26CANCEL EQU "X"-"@" ;Cancel with Ctrl-X
27TOGLINS EQU WANG ;Separate keys for insert mode on
28 ;and off if not WANG
29TOGLPRN EQU FALSE ;Separate keys for printer echo on
30 ;and off
31ZEROEXT EQU TRUE
32 ENDIF
33
34 \ No newline at end of file
diff --git a/v2.0/source/STRIN.ASM b/v2.0/source/STRIN.ASM
new file mode 100644
index 0000000..2bc58fb
--- /dev/null
+++ b/v2.0/source/STRIN.ASM
@@ -0,0 +1,292 @@
1 procedure $STD_CON_STRING_INPUT,NEAR ;System call 10
2ASSUME DS:NOTHING,ES:NOTHING
3
4; Inputs:
5; DS:DX Point to an input buffer
6; Function:
7; Fill buffer from console input until CR
8; Returns:
9; None
10
11 MOV AX,SS
12 MOV ES,AX
13 MOV SI,DX
14 XOR CH,CH
15 LODSW
16 OR AL,AL
17 retz ;Buffer is 0 length!!?
18 MOV BL,AH ;Init template counter
19 MOV BH,CH ;Init template counter
20 CMP AL,BL
21 JBE NOEDIT ;If length of buffer inconsistent with contents
22 CMP BYTE PTR [BX+SI],c_CR
23 JZ EDITON ;If CR correctly placed EDIT is OK
24NOEDIT:
25 MOV BL,CH ;Reset buffer
26EDITON:
27 MOV DL,AL
28 DEC DX ;DL is # of bytes we can put in the buffer
29NEWLIN:
30 MOV AL,[CARPOS]
31 MOV [STARTPOS],AL ;Remember position in raw buffer
32 PUSH SI
33 MOV DI,OFFSET DOSGROUP:INBUF ;Build the new line here
34 MOV [INSMODE],CH ;Insert mode off
35 MOV BH,CH ;No chars from template yet
36 MOV DH,CH ;No chars to new line yet
37 invoke $STD_CON_INPUT_NO_ECHO ;Get first char
38 CMP AL,c_LF ;Linefeed
39 JNZ GOTCH ;Filter out LF so < works
40 entry GETCH
41 invoke $STD_CON_INPUT_NO_ECHO
42GOTCH:
43 CMP AL,"F"-"@" ;Ignore ^F
44 JZ GETCH
45 CMP AL,[ESCCHAR]
46 JZ ESC
47 CMP AL,c_DEL
48 JZ BACKSPJ
49 CMP AL,c_BS
50 JZ BACKSPJ
51 CMP AL,c_CR
52 JZ ENDLIN
53 CMP AL,c_LF
54 JZ PHYCRLF
55 CMP AL,CANCEL
56 JZ KILNEW
57SAVCH:
58 CMP DH,DL
59 JAE BUFFUL ;No room
60 STOSB
61 INC DH ;Got a char
62 invoke BUFOUT ;Print control chars nicely
63 CMP BYTE PTR [INSMODE],0
64 JNZ GETCH ;In insert mode, get more chars
65 CMP BH,BL
66 JAE GETCH ;We are out of chars in template
67 INC SI ;Skip to next char in template
68 INC BH
69 JMP SHORT GETCH
70
71BACKSPJ: JMP SHORT BACKSP
72
73BUFFUL:
74 MOV AL,7 ;Bell
75 invoke OUT
76 JMP SHORT GETCH
77
78ESC:
79 transfer OEMFunctionKey
80
81ENDLIN:
82 STOSB ;Put the CR in the buffer
83 invoke OUT ;Echo it
84 POP DI ;Get start of buffer
85 MOV [DI-1],DH ;Tell user how many bytes
86 INC DH ;DH is length including CR
87COPYNEW:
88 MOV BP,ES ;XCHG ES,DS
89 MOV BX,DS
90 MOV ES,BX
91 MOV DS,BP
92 MOV SI,OFFSET DOSGROUP:INBUF
93 MOV CL,DH
94 REP MOVSB ;Copy final line to user buffer
95 return ;All done
96
97;Output a CRLF
98 entry CRLF
99 MOV AL,c_CR
100 invoke OUT
101 MOV AL,c_LF
102 JMP OUT
103
104;Output a CRLF which is not terminate buffer
105PHYCRLF:
106 invoke CRLF
107 JMP GETCH
108
109;Zap the line without zapping the template
110 entry KILNEW
111 MOV AL,"\"
112 invoke OUT ;Print the CANCEL indicator
113 POP SI ;Remember start of edit buffer
114PUTNEW:
115 invoke CRLF ;Go to next line on screen
116 MOV AL,[STARTPOS]
117 invoke TAB ;Tab over
118 JMP NEWLIN ;Start over again
119
120;Back up one char
121 entry BACKSP
122 OR DH,DH
123 JZ OLDBAK ;No chars in line, do nothing to line
124 CALL BACKUP ;Do the backup
125 MOV AL,ES:[DI] ;Get the deleted char
126 CMP AL," "
127 JAE OLDBAK ;Was a normal char
128 CMP AL,c_HT
129 JZ BAKTAB ;Was a tab, fix up users display
130 CALL BACKMES ;Was a control char, zap the '^'
131OLDBAK:
132 CMP BYTE PTR [INSMODE],0
133 JNZ GETCH1 ;In insert mode, get more chars
134 OR BH,BH
135 JZ GETCH1 ;Not advanced in template, stay where we are
136 DEC BH ;Go back in template
137 DEC SI
138GETCH1:
139 JMP GETCH
140
141BAKTAB:
142 PUSH DI
143 DEC DI ;Back up one char
144 STD ;Go backward
145 MOV CL,DH ;Number of chars currently in line
146 MOV AL," "
147 PUSH BX
148 MOV BL,7 ;Max
149 JCXZ FIGTAB ;At start, do nothing
150FNDPOS:
151 SCASB ;Look back
152 JNA CHKCNT
153 CMP BYTE PTR ES:[DI+1],9
154 JZ HAVTAB ;Found a tab
155 DEC BL ;Back one char if non tab control char
156CHKCNT:
157 LOOP FNDPOS
158FIGTAB:
159 SUB BL,[STARTPOS]
160HAVTAB:
161 SUB BL,DH
162 ADD CL,BL
163 AND CL,7 ;CX has correct number to erase
164 CLD ;Back to normal
165 POP BX
166 POP DI
167 JZ OLDBAK ;Nothing to erase
168TABBAK:
169 invoke BACKMES
170 LOOP TABBAK ;Erase correct number of chars
171 JMP SHORT OLDBAK
172
173BACKUP:
174 DEC DH ;Back up in line
175 DEC DI
176BACKMES:
177 MOV AL,c_BS ;Backspace
178 invoke OUT
179 MOV AL," " ;Erase
180 invoke OUT
181 MOV AL,c_BS ;Backspace
182 JMP OUT ;Done
183
184;User really wants an ESC character in his line
185 entry TwoEsc
186 MOV AL,[ESCCHAR]
187 JMP SAVCH
188
189;Copy the rest of the template
190 entry COPYLIN
191 MOV CL,BL ;Total size of template
192 SUB CL,BH ;Minus position in template, is number to move
193 JMP SHORT COPYEACH
194
195 entry CopyStr
196 invoke FINDOLD ;Find the char
197 JMP SHORT COPYEACH ;Copy up to it
198
199;Copy one char from template to line
200 entry COPYONE
201 MOV CL,1
202;Copy CX chars from template to line
203COPYEACH:
204 MOV BYTE PTR [INSMODE],0 ;All copies turn off insert mode
205 CMP DH,DL
206 JZ GETCH2 ;At end of line, can't do anything
207 CMP BH,BL
208 JZ GETCH2 ;At end of template, can't do anything
209 LODSB
210 STOSB
211 invoke BUFOUT
212 INC BH ;Ahead in template
213 INC DH ;Ahead in line
214 LOOP COPYEACH
215GETCH2:
216 JMP GETCH
217
218;Skip one char in template
219 entry SKIPONE
220 CMP BH,BL
221 JZ GETCH2 ;At end of template
222 INC BH ;Ahead in template
223 INC SI
224 JMP GETCH
225
226 entry SKIPSTR
227 invoke FINDOLD ;Find out how far to go
228 ADD SI,CX ;Go there
229 ADD BH,CL
230 JMP GETCH
231
232;Get the next user char, and look ahead in template for a match
233;CX indicates how many chars to skip to get there on output
234;NOTE: WARNING: If the operation cannot be done, the return
235; address is popped off and a jump to GETCH is taken.
236; Make sure nothing extra on stack when this routine
237; is called!!! (no PUSHes before calling it).
238FINDOLD:
239 invoke $STD_CON_INPUT_NO_ECHO
240 CMP AL,[ESCCHAR] ; did he type a function key?
241 JNZ FindSetup ; no, set up for scan
242 invoke $STD_CON_INPUT_NO_ECHO ; eat next char
243 JMP NotFnd ; go try again
244FindSetup:
245 MOV CL,BL
246 SUB CL,BH ;CX is number of chars to end of template
247 JZ NOTFND ;At end of template
248 DEC CX ;Cannot point past end, limit search
249 JZ NOTFND ;If only one char in template, forget it
250 PUSH ES
251 PUSH DS
252 POP ES
253 PUSH DI
254 MOV DI,SI ;Template to ES:DI
255 INC DI
256 REPNE SCASB ;Look
257 POP DI
258 POP ES
259 JNZ NOTFND ;Didn't find the char
260 NOT CL ;Turn how far to go into how far we went
261 ADD CL,BL ;Add size of template
262 SUB CL,BH ;Subtract current pos, result distance to skip
263 return
264
265NOTFND:
266 POP BP ;Chuck return address
267 JMP GETCH
268
269 entry REEDIT
270 MOV AL,"@" ;Output re-edit character
271 invoke OUT
272 POP DI
273 PUSH DI
274 PUSH ES
275 PUSH DS
276 invoke COPYNEW ;Copy current line into template
277 POP DS
278 POP ES
279 POP SI
280 MOV BL,DH ;Size of line is new size template
281 JMP PUTNEW ;Start over again
282
283 entry EXITINS
284 entry ENTERINS
285 NOT BYTE PTR [INSMODE]
286 JMP GETCH
287
288;Put a real live ^Z in the buffer (embedded)
289 entry CTRLZ
290 MOV AL,"Z"-"@"
291 JMP SAVCH
292$STD_CON_STRING_INPUT ENDP
diff --git a/v2.0/source/SYS.ASM b/v2.0/source/SYS.ASM
new file mode 100644
index 0000000..e15758e
--- /dev/null
+++ b/v2.0/source/SYS.ASM
@@ -0,0 +1,587 @@
1TITLE MS-DOS SYS Program
2; SYS - Copies system programs IBMBIO.COM/IO.SYS and IBMDOS.COM/MSDOS.SYS
3; 1.6 05/21/82 Added rev number message
4; 1.61 06/04/82 Allow SYS to blank disk TimP at SCP
5; 1.70 06/30/82 NON contiguous DOS allowed on 2.00 IBM. Allows SYS to
6; 1.0 1.1 disks.
7; 1.71 07/02/82 Put in CHDIRs to make sure everything done in root dir.
8; 1.80 04/26/83 MZ make sys work in small machines; use full 2.0 system
9; calls
10; 1.81 07/22/83 ARR Added check in IBM version for valid FAT ID on
11; destination because of IBM problem with SYSing to
12; unformatted disks which are really formatted.
13; Prints NoDest message for ridic IBM reasons, should
14; have a better message.
15
16FALSE EQU 0
17TRUE EQU NOT FALSE
18
19IBMJAPVER EQU FALSE
20IBMVER EQU FALSE
21MSVER EQU TRUE
22
23.xlist
24.xcref
25 INCLUDE DOSSYM.ASM
26.cref
27.list
28
29
30DOSVER_LOW EQU 0136H ; Lowest acceptable DOS version number
31DOSVER_HIGH EQU 020BH ; Highest acceptable DOS version
32
33CODE SEGMENT WORD PUBLIC
34CODE ENDS
35
36CONST SEGMENT BYTE PUBLIC
37CONST ENDS
38
39DATA SEGMENT BYTE PUBLIC
40DATA ENDS
41
42DG GROUP CODE,DATA,CONST
43
44DATA SEGMENT PUBLIC BYTE
45
46 EXTRN BADDRV:BYTE, BADDRVLen:WORD
47 EXTRN BADPARM:BYTE, BADPARMLen:WORD
48 EXTRN GETSYS:BYTE, GETSYSLen:WORD
49 EXTRN SYSDRV:BYTE
50 EXTRN NODEST:BYTE, NODESTLen:WORD
51 EXTRN BADSIZ:BYTE, BADSIZLen:WORD
52 EXTRN DONE:BYTE, DONELen:WORD
53 EXTRN BADVER:BYTE
54
55 IF IBMJAPVER
56 EXTRN BADDISK:BYTE, BADDISKLen:WORD
57 ENDIF
58
59DEFALT DB 0
60 IF MSVER
61BIOSName DB "A:\IO.SYS",0
62DOSName DB "A:\MSDOS.SYS",0
63 ENDIF
64 IF IBMVER OR IBMJAPVER
65BIOSName DB "A:\IBMBIO.COM",0
66DOSName DB "A:\IBMDOS.COM",0
67 ENDIF
68
69BIOSInFH DW ? ; file handle of source BIOS
70BIOSLenLow DW 2 DUP (?) ; 32-bit length of BIOS
71BIOSLenHigh DW 2 DUP (?) ; 32-bit length of BIOS
72BIOSTime DW 2 DUP (?) ; place to store time of BIOS write
73BIOSOutFH DW ? ; fh of BIOS destination
74
75DOSInFH DW ? ; file handle of source DOS
76DOSLenLow DW 2 DUP (?) ; 32-bit length of DOS
77DOSLenHigh DW 2 DUP (?) ; 32-bit length of DOS
78DOSTime DW 2 DUP (?) ; place to store time of DOS write
79DOSOutFH DW ? ; fh of DOS destination
80
81AllName DB "A:\*.*",0
82
83cbBuf DW ? ; number of bytes in buffer
84pDOS DW ? ; offset of beginning of DOS in buffer
85pDOSEnd DW ? ; offset of end of DOS in buffer
86
87 IF IBMVER OR IBMJAPVER
88BOOT DW 256 DUP (0)
89 IF IBMJAPVER
90LLISTBUF DW 256 DUP (0)
91 ENDIF
92 ENDIF
93
94 IF IBMJAPVER
95RELOC DW 1 DUP(?)
96STARTSECTOR DW 1 DUP(?)
97 ENDIF
98
99BUF LABEL BYTE ; beginning of area for file reads
100
101DATA ENDS
102
103CODE SEGMENT PUBLIC
104
105 ASSUME CS:DG,DS:DG,ES:DG,SS:DG
106
107 ORG 100H
108
109Start:
110 JMP SHORT CheckVersion
111
112 IF IBMVER
113 DW OFFSET DG:BOOT
114 ENDIF
115HEADER DB "Vers 1.81"
116CheckVersion:
117 PUSH AX ; save drive letter validity
118 MOV AH,GET_VERSION
119 INT 21H ; get dos version
120 XCHG AH,AL ; Turn it around to AH.AL
121 CMP AX,DOSVER_LOW ; is it too low?
122 JB GOTBADDOS ; yes, error
123 CMP AX,DOSVER_HIGH ; too high?
124 JBE OKDOS ; yes, go check drive letter
125GOTBADDOS:
126 MOV DX,OFFSET DG:BADVER ; message to dump
127 MOV AH,STD_CON_STRING_OUTPUT ; standard output device
128 INT 21H
129 INT 20H ; old style exit for compatability
130
131OKDOS: POP AX ; get drive validity
132 JMP SHORT SYS ; go process
133
134ERR0: MOV DX,OFFSET DG:BADPARM ; no drive letter
135 MOV CX,BadParmLen
136 JMP DisplayError
137
138ERR1: MOV DX,OFFSET DG:BADDRV ; drive letter invalid
139 MOV CX,BadDrvLen
140 JMP DisplayError
141
142ERR2: MOV AL,DEFALT ; get default drive number
143 ADD AL,'A'-1 ; turn into letter
144 MOV SYSDRV,AL ; place into middle of message
145 MOV DX,OFFSET DG:GETSYS
146 MOV CX,GETSYSLen ; length for output
147 MOV BX,stderr ; use stderr
148 MOV AH,Write ; Ask for system disk
149 INT 21H
150 CALL GetKeystroke ; wait for him to type simething
151 XOR AL,AL ; valid drive spec now...
152SYS:
153 CMP DS:(BYTE PTR 5DH)," " ; Was file specified?
154 JNZ ERR0 ; yes, no files are allowed -> error
155 CMP AL,-1 ; Invalid drive spec?
156 JZ ERR1 ; yes, must have valid drive -> error
157 CMP DS:(BYTE PTR 5CH),0 ; No drive specified?
158 JZ ERR1 ; yes, cannot sys to default drive error
159 MOV AH,GET_DEFAULT_DRIVE ; Get default drive
160 INT 21H
161 INC AL ; turn from phys drive to logical drive
162 MOV DEFALT,AL ; save it for possible printing
163 CMP DS:(BYTE PTR 5CH),AL ; did he specify the default drive?
164 JZ ERR1 ; yes, default drive not allowed
165
166 IF IBMVER ; Check for "valid" destination
167 PUSH AX
168 MOV AL,BYTE PTR DS:[5Ch]
169 DEC AL
170 MOV BX,OFFSET DG:BUF ; Temp space
171 MOV DX,1 ; Sector 1 (first sec of FAT)
172 MOV CX,DX ; One sector
173 INT 25H ; Read Fat sector
174 POP AX ; Flags
175 POP AX ; Real AX
176 JC OKFAT ; Don't error here, let a CREATE or
177 ; some other call to the dest
178 ; generate a more useful INT 24H
179 ; error
180 CMP BYTE PTR [BUF],0F8H
181 JAE OKFAT
182 JMP ERR3
183OKFAT:
184 ENDIF
185
186 ADD AL,'A'-1 ; turn into letter
187 MOV BIOSName,AL ; twiddle source name
188 MOV DOSName,AL ; twiddle source name
189 CLD
190 MOV DX,OFFSET DG:BIOSName ; source name
191 MOV DI,OFFSET DG:BIOSInFH ; pointer to block of data
192 CALL OpenFile
193 JC Err2 ; not found, go and try again
194 MOV DX,OFFSET DG:DOSName ; source of DOS
195 MOV DI,OFFSET DG:DOSInFH ; pointer to block of data
196 CALL OpenFile ; Look for DOS
197 JC ERR2 ; not there, go ask for a system disk
198 MOV CX,SP ; get lowest available spot
199 SUB CX,0200h+(OFFSET DG:BUF); leave room for all sorts of things
200 MOV cbBuf,CX ; store length away
201 CALL FillMem ; load up memory with files
202
203 IF IBMJAPVER
204 CALL READ_BOOT ; need to copy boot sector too
205 ENDIF
206
207 MOV AL,DS:(BYTE PTR 5CH) ; get drive of destination
208
209 IF IBMJAPVER
210 CALL CHECK_TRAN ; check for bootable device
211 JZ DOSWRT ; ok to boot
212 MOV DX,OFFSET DG:BADDISK ; incorrect format to boot
213 MOV CX,BadDiskLen
214 JMP DisplayError ; go error and quit
215DOSWRT:
216 ENDIF
217
218 ADD AL,'A'-1 ; convert to letter
219 MOV BIOSName,AL ; point names at destination drive
220 MOV DOSName,AL
221 MOV AllName,AL ; look for any files
222
223 MOV AH,Find_First ; look for files
224 MOV DX,OFFSET DG:AllName ; path of where to look
225 MOV CX,Attr_Hidden+Attr_System ; attributes to find
226 INT 21H
227 JC PutSys ; no files - go and copy
228
229 IF MSVER
230 MOV DL,DS:(BYTE PTR 5CH) ; get drive number
231 MOV AH,GET_DRIVE_FREESPACE ; get free space available
232 INT 21H
233 MUL CX ; Compute size of cluster (secsiz*secperclus)
234 XCHG CX,AX ; move it to correct spot
235 MOV DX,OFFSET DG:BIOSName ; who to open
236 MOV AX,BIOSLenLow+2 ; get low part of size
237 MOV BX,BIOSLenHigh+2 ; get high size
238 CALL CHKLEN ; open and snoop size
239 JNZ ERR4 ; Must fit exact so MSDOS is in right place
240 MOV DX,OFFSET DG:DOSName ; other guy to open
241 MOV AX,DOSLenLow+2 ; get low part of size
242 MOV BX,DOSLenHigh+2 ; get high size
243 CALL CHKLEN ; open and snoop second size
244 JA ERR4 ; Must be enough (or too much) space
245 ENDIF
246
247 IF IBMVER OR IBMJAPVER
248 MOV DX,OFFSET DG:BIOSName ; open BIOS
249 MOV CX,7 ; attributes
250 MOV AH,Find_First
251 INT 21H
252 JNC FindDos
253Err3J: JMP Err3 ; not found, go and complain
254FindDos:
255 MOV DX,OFFSET DG:DOSName ; open DOS
256 MOV AH,Find_First
257 INT 21H
258 JC Err3J ; Not found, go complain
259 ENDIF
260
261PUTSYS:
262 MOV DX,OFFSET DG:BIOSName ; who to change mode
263 MOV CX,0 ; undo attributes
264 MOV AX,(ChMod SHL 8) + 1 ; set the attributes
265 INT 21h
266 MOV DX,OFFSET DG:DOSName ; who to change mode
267 MOV CX,0 ; undo attributes
268 MOV AX,(ChMod SHL 8) + 1 ; set the attributes
269 INT 21h
270 MOV DX,OFFSET DG:BIOSName ; destination of BIOS
271 MOV CX,7 ; fancy attributes
272 MOV AH,Creat ; make a new one
273 INT 21h
274 MOV BIOSOutFH,AX ; save handle
275 MOV DX,OFFSET DG:DOSName ; destination of DOS
276 MOV AH,Creat ; make a new one
277 INT 21h
278 MOV DOSOutFH,AX ; save handle
279Copy:
280 CALL DumpMem ; flush out memory
281 MOV AX,DOSLenHigh ; more DOS?
282 OR AX,DOSLenLow ; more low dos
283 OR AX,BIOSLenHigh ; more high BIOS
284 OR AX,BIOSLenLow ; more low BIOS
285 JZ AllDone ; nope, all done
286 CALL FillMem ; reload world
287 JMP Copy
288ERR4:
289 MOV DX,OFFSET DG:BADSIZ
290 MOV CX,BadSizLen
291 JMP DisplayError
292AllDone:
293 MOV CX,BIOSTime ; get time and date
294 MOV DX,BIOSTime+2
295 MOV BX,BIOSOutFH ; where to stuff the time
296 MOV AX,(File_Times SHL 8) + 1
297 INT 21h
298 MOV AH,Close
299 INT 21h
300
301 MOV CX,DOSTime ; get time and date
302 MOV DX,DOSTime+2
303 MOV BX,DOSOutFH ; where to stuff the time
304 MOV AX,(File_Times SHL 8) + 1
305 INT 21h
306 MOV AH,Close
307 INT 21h
308
309 IF IBMVER OR IBMJAPVER
310 CALL PUTBOOT ; copy the boot sector also
311 ENDIF
312
313 MOV DX,OFFSET DG:DONE ; all finished message
314 MOV CX,DoneLen
315 XOR AL,AL ; ok error code
316SERROR:
317 PUSH AX
318 MOV BX,stderr
319 MOV AH,Write ; convenient place to display message
320 INT 21H
321 POP AX
322ErrorExit:
323 MOV AH,EXIT ; bye and return error code
324 INT 21h
325
326DisplayError:
327 MOV AL,1
328 JMP SERROR
329FillMem:
330 MOV CX,cbBuf ; get length of buffer
331 MOV BX,BIOSInFH ; get bios source handle
332 MOV DX,OFFSET DG:BUF ; point to beginning of buffer
333 PUSH CX ; save away total length
334 CMP BIOSLenHigh,0 ; > 64K to read?
335 JA UseCX ; use CX
336 CMP BIOSLenLow,CX ; more left to read?
337 JA UseCX ; use CX
338 MOV CX,BIOSLenLow ; move new
339UseCX:
340 MOV AH,Read
341 INT 21h ; read in what we can
342 ADD DX,AX ; update pointer for DOS Read
343 MOV pDOS,DX ; point to beginning of DOS
344 SUB BIOSLenLow,AX ; decrement remaining
345 SBB BIOSLenHigh,0 ; do 32 bit
346 POP CX ; get original length
347 SUB CX,AX ; this much is left
348
349 MOV BX,DOSInFH ; get bios source handle
350 CMP DOSLenHigh,0 ; > 64K to read?
351 JA UseCXDOS ; use CX
352 CMP DOSLenLow,CX ; more left to read?
353 JA UseCXDOS ; use CX
354 MOV CX,DOSLenLow ; move new
355UseCXDOS:
356 MOV AH,Read
357 INT 21h ; read in what we can
358 ADD DX,AX ; update pointer for DOS Read
359 MOV pDOSEnd,DX ; point to End of dos DOS
360 SUB DOSLenLow,AX ; decrement remaining
361 SBB DOSLenHigh,0 ; do 32 bit arithmetic
362 return
363
364OpenFile:
365 MOV AX,(OPEN SHL 8) + 0 ; open for reading only
366 INT 21H ; Look for BIOS
367 retc ; not found, go and try again
368 STOSW ; stash away handle
369 MOV BX,AX ; get ready for seeks
370 MOV AX,(LSeek SHL 8) + 2 ; seek relative to eof
371 XOR CX,CX ; zero offset
372 XOR DX,DX ; zero offset
373 INT 21h ; get offsets
374 STOSW ; save low part of size
375 STOSW ; save low part of size
376 MOV AX,DX
377 STOSW ; save high part of size
378 STOSW ; save high part of size
379 XOR DX,DX ; zero offset
380 MOV AX,(LSeek SHL 8) + 0 ; seek relative to beginning
381 INT 21h
382 MOV AX,(File_Times SHL 8) + 0
383 INT 21h ; get last write times
384 MOV AX,CX
385 STOSW ; save time
386 MOV AX,DX
387 STOSW ; save date
388 return
389
390ERR3:
391 MOV DX,OFFSET DG:NODEST
392 MOV CX,NoDestLen
393 JMP DisplayError
394
395DumpMem:
396 MOV DX,OFFSET DG:BUF ; get offset of bios start
397 MOV CX,pDOS ; beginning of next guy
398 SUB CX,DX ; difference is length
399 JZ DumpDos ; no bios to move
400 MOV BX,BIOSOutFH ; where to output
401 MOV AH,Write
402 INT 21h ; wham
403DumpDos:
404 MOV DX,pDOS ; beginning of dos
405 MOV CX,pDOSEnd ; end of dos
406 SUB CX,DX ; difference is length
407 retz ; if zero no write
408 MOV BX,DOSOutFH ; where to output
409 MOV AH,Write
410 INT 21h ; wham
411 ret
412
413 IF MSVER
414CHKLEN:
415; CX has size of cluster, DX has pointer to file name
416; Returns with flags set on (size of file) - (size of hole)
417 PUSH AX ; old size low
418 PUSH BX ; old size high
419 PUSH CX ; old cluster size
420 MOV AH,Find_First
421 MOV CX,7 ; attributes to search for
422 INT 21H
423 JC ERR3 ; cannot find file, error
424 POP CX ; get cluster size back
425 MOV DX,DS:[80h+find_buf_size_h] ; get destination size high
426 MOV AX,DS:[80h+find_buf_size_l] ; get size low
427 ADD AX,CX ; add cluster size
428 ADC DX,0 ; 32 bit add
429 SUB AX,1 ; adding CLUSSIZE-1
430 SBB DX,0 ; 32 bit dec
431 DIV CX ; compute new cluster size
432 POP DX ; get old high
433 POP BX ; get old low
434 PUSH AX ; save away dividend
435 MOV AX,BX ; put into correct register
436 ADD AX,CX ; do the same as above (+CLUSSIZE-1)/CLUSSIZE
437 ADC DX,0 ; 32 bit add
438 SUB AX,1 ; adding CLUSSIZE-1
439 SBB DX,0 ; 32 bit dec
440 DIV CX ; compute old cluster size
441 POP DX ; get new size
442 CMP AX,DX ; is old >= new?
443 return
444 ENDIF
445
446 IF IBMJAPVER
447PUTBOOT:
448 CALL READ_LLIST ; Get the list sector and set new boot sector
449 MOV AL,DS:(BYTE PTR 5CH)
450 DEC AL ; A=0
451 MOV CX,1
452 XOR DX,DX
453 MOV BX,OFFSET DG:BOOT
454 INT 26H ; Write out new boot sector
455 POPF
456 CALL WRITE_LLIST ; Make and write out new list sector
457 RET
458 ENDIF
459
460 IF IBMVER
461PUTBOOT:
462 MOV AH,GET_DPB
463 MOV DL,BYTE PTR DS:[5Ch] ; Target drive
464 INT 21H
465ASSUME DS:NOTHING
466 MOV AL,[BX+16H] ; Media byte
467 PUSH CS
468 POP DS
469ASSUME DS:DG
470 CMP AL,0FEH
471 JB RET1
472 TEST AL,1
473 JZ GOTBOOT
474 MOV BX,OFFSET DG:BOOT
475 MOV WORD PTR [BX+17],112 ; Set number of dir entries
476 MOV WORD PTR [BX+19],2*8*40 ; Set number of sectors
477 INC BYTE PTR [BX+21] ; Media = ff
478 INC WORD PTR [BX+26] ; Number of heads = 2
479
480GOTBOOT:
481 MOV AL,BYTE PTR DS:[5Ch]
482 DEC AL
483 MOV BX,OFFSET DG:BOOT ; Boot sector
484 XOR DX,DX ; Sector 0
485 MOV CX,DX
486 INC CX ; One sector
487 INT 26H ; Write out 8 sector boot sector
488 POP AX ; Flags
489RET1: RET
490 ENDIF
491
492 IF IBMJAPVER
493READ_BOOT:
494 MOV AL,[DEFALT]
495 DEC AL ; A=0
496 MOV CX,1
497 XOR DX,DX
498 MOV BX,OFFSET DG:BOOT
499 INT 25H
500 POPF
501 MOV AX,[BOOT+108H] ; Get old first sector of data
502 MOV [RELOC],AX
503 RET
504
505READ_LLIST:
506 MOV AL,DS:(BYTE PTR 5CH)
507 DEC AL ; A=0
508 MOV CX,1
509 MOV DX,[STARTSECTOR]
510 MOV BX,OFFSET DG:LLISTBUF
511 INT 25H
512 POPF
513 RET
514
515WRITE_LLIST:
516 MOV AX,[STARTSECTOR]
517 MOV DX,AX
518 SUB AX,[RELOC] ; True reloc factor
519 MOV CL,BYTE PTR [LLISTBUF+0CH] ; Number of entries needing reloc
520 XOR CH,CH
521 JCXZ NO_RELOCS
522 MOV BX,OFFSET DG:LLISTBUF + 10H
523RELLOOP:
524 ADD WORD PTR [BX+2],AX
525 ADD BX,10H
526 LOOP RELLOOP
527NO_RELOCS:
528 MOV AL,DS:(BYTE PTR 5CH)
529 DEC AL ; A=0
530 MOV CX,1
531 MOV BX,OFFSET DG:LLISTBUF
532 INT 26H
533 POPF
534 RET
535
536CHECK_TRAN:
537; All registers preserved. Returns zero if SYS OK, NZ if SYS FAIL
538; AL is drive (1=A,...) AL=0 is not valid
539
540 PUSH BX
541 PUSH AX
542 PUSH DS
543 MOV DL,AL
544 MOV AH,GET_DPB
545 INT 21H
546 MOV AX,[BX.dpb_first_sector] ; Get new first sector of data
547 MOV BH,[BX.dpb_media]
548 POP DS
549 MOV [STARTSECTOR],AX
550 MOV [BOOT+108H],AX ; Set new start of data in boot
551 POP AX
552 PUSH AX
553 MOV BL,AL
554 INT 11H ; IBM EQUIP CALL
555 ROL AL,1
556 ROL AL,1
557 AND AL,3
558 JNZ NOT_SINGLE
559 INC AL
560NOT_SINGLE:
561 INC AL ; AL is now MAX floppy #
562 CMP BL,AL
563 POP AX
564 JBE CHECK_FLOP ; Is a floppy
565 XOR BL,BL ; Is Hard file
566 POP BX
567 RET
568
569CHECK_FLOP:
570 CMP BH,0FBH ; Only floppy that boots
571 POP BX
572 RET
573 ENDIF
574
575GetKeystroke:
576 MOV AX,(Std_CON_Input_Flush SHL 8) + Std_CON_Input_No_Echo
577 INT 21H
578 MOV AX,(Std_CON_Input_Flush SHL 8) + 0
579 INT 21H
580
581 return
582
583CODE ENDS
584 END START
585
586
587 \ No newline at end of file
diff --git a/v2.0/source/SYSCALL.ASM b/v2.0/source/SYSCALL.ASM
new file mode 100644
index 0000000..02d38d8
--- /dev/null
+++ b/v2.0/source/SYSCALL.ASM
@@ -0,0 +1,749 @@
1;
2; system call entry points MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17
18 i_need YEAR,WORD
19 i_need DAY,BYTE
20 i_need WeekDay,BYTE
21 i_need TimeBuf,6
22 i_need BCLOCK,DWORD
23 i_need DskErr,BYTE
24 i_need Attrib,BYTE
25 i_need Name1,BYTE
26 i_need Name2,BYTE
27 i_need Name3,BYTE
28 i_need DelAll,BYTE
29 i_need ThisDPB,DWORD
30 i_need CurBuf,DWORD
31 i_need LastEnt,WORD
32 i_need ThisDrv,BYTE
33 i_need DirStart,WORD
34 i_need DevPt,DWORD
35 i_need Creating,BYTE
36 i_need VolID,BYTE
37 i_need FoundDel,BYTE
38
39SUBTTL DATE AND TIME - SYSTEM CALLS 42,43,44,45; S/G DATE,TIME
40PAGE
41 procedure $GET_DATE,NEAR ;System call 42
42ASSUME DS:NOTHING,ES:NOTHING
43
44; Inputs:
45; None
46; Function:
47; Return current date
48; Returns:
49; Date in CX:DX
50
51 PUSH SS
52 POP DS
53ASSUME DS:DOSGROUP
54 invoke READTIME ;Check for rollover to next day
55 MOV AX,[YEAR]
56 MOV BX,WORD PTR [DAY]
57 invoke get_user_stack ;Get pointer to user registers
58ASSUME DS:NOTHING
59 MOV [SI.user_DX],BX ;DH=month, DL=day
60 ADD AX,1980 ;Put bias back
61 MOV [SI.user_CX],AX ;CX=year
62 MOV AL,BYTE PTR [WEEKDAY]
63 RET
64$GET_DATE ENDP
65
66 procedure $SET_DATE,NEAR ;System call 43
67ASSUME DS:NOTHING,ES:NOTHING
68
69; Inputs:
70; CX:DX valid date
71; Function:
72; Set current date
73; Returns:
74; AL = -1 date bad, = 0 OK
75
76 MOV AL,-1 ;Be ready to flag error
77 SUB CX,1980 ;Fix bias in year
78 JC RET24 ;Error if not big enough
79 CMP CX,119 ;Year must be less than 2100
80 JA RET24
81 OR DH,DH
82 JZ RET24
83 OR DL,DL
84 JZ RET24 ;Error if either month or day is 0
85 CMP DH,12 ;Check against max. month
86 JA RET24
87 PUSH SS
88 POP DS
89ASSUME DS:DOSGROUP
90 invoke DODATE
91RET24: RET
92$SET_DATE ENDP
93
94 procedure $GET_TIME,NEAR ;System call 44
95ASSUME DS:NOTHING,ES:NOTHING
96
97; Inputs:
98; None
99; Function:
100; Get current time
101; Returns:
102; Time in CX:DX
103
104 PUSH SS
105 POP DS
106ASSUME DS:DOSGROUP
107 invoke READTIME
108 invoke get_user_stack ;Get pointer to user registers
109 MOV [SI.user_DX],DX
110 MOV [SI.user_CX],CX
111 XOR AL,AL
112RET26: RET
113$GET_TIME ENDP
114
115 procedure $SET_TIME,NEAR ;System call 45
116;Time is in CX:DX in hours, minutes, seconds, 1/100 sec.
117ASSUME DS:NOTHING,ES:NOTHING
118
119; Inputs:
120; CX:DX = Time
121; Function:
122; Set time
123; Returns:
124; AL = -1 time bad, = 0 OK
125
126 MOV AL,-1 ;Flag in case of error
127 CMP CH,24 ;Check hours
128 JAE RET26
129 CMP CL,60 ;Check minutes
130 JAE RET26
131 CMP DH,60 ;Check seconds
132 JAE RET26
133 CMP DL,100 ;Check 1/100's
134 JAE RET26
135 PUSH CX
136 PUSH DX
137 PUSH SS
138 POP DS
139ASSUME DS:DOSGROUP
140 MOV BX,OFFSET DOSGROUP:TIMEBUF
141 MOV CX,6
142 XOR DX,DX
143 MOV AX,DX
144 PUSH BX
145 invoke SETREAD
146ASSUME ES:DOSGROUP
147 PUSH DS
148 LDS SI,[BCLOCK]
149ASSUME DS:NOTHING
150 invoke DEVIOCALL2 ;Get correct day count
151 POP DS
152ASSUME DS:DOSGROUP
153 POP BX
154 invoke SETWRITE
155 POP WORD PTR [TIMEBUF+4]
156 POP WORD PTR [TIMEBUF+2]
157 LDS SI,[BCLOCK]
158ASSUME DS:NOTHING
159 invoke DEVIOCALL2 ;Set the time
160 XOR AL,AL
161 RET
162$SET_TIME ENDP
163
164SUBTTL DISK R/W ROUTINES
165PAGE
166 procedure $FCB_SEQ_READ,NEAR ; System call 20
167ASSUME DS:NOTHING,ES:NOTHING
168
169; Inputs:
170; DS:DX Points to openned FCB
171; Function:
172; Read next record from file to disk transfer address
173; Returns:
174; AL = 1 EOF record is empty
175; AL = 3 EOF record is partial zero filled
176; AL = 2 No room at disk transfer address
177; AL = 0 All OK
178
179 invoke GETREC
180 invoke LOAD
181 JMP SHORT FINSEQ
182
183 entry $FCB_SEQ_WRITE ; System call 21
184ASSUME DS:NOTHING,ES:NOTHING
185
186; Inputs:
187; DS:DX Points to openned FCB
188; Function:
189; Write next record to file from disk transfer address
190; Returns:
191; AL = 1 Disk full
192; AL = 2 No room in disk transfer segment
193; AL = 0 All OK
194
195 invoke GETREC
196 invoke STORE
197FINSEQ:
198 JCXZ SETNREX
199 ADD AX,1
200 ADC DX,0
201 JMP SHORT SETNREX
202
203 entry $FCB_RANDOM_READ ; System call 33
204ASSUME DS:NOTHING,ES:NOTHING
205
206; Inputs:
207; DS:DX Points to openned FCB
208; Function:
209; Read record addressed by random record field from file to
210; disk transfer address
211; Returns:
212; AL = 1 EOF record is empty
213; AL = 3 EOF record is partial zero filled
214; AL = 2 No room at disk transfer address
215; AL = 0 All OK
216
217 invoke GETRRPOS1
218 invoke LOAD
219 JMP SHORT FINRND
220
221 entry $FCB_RANDOM_WRITE ; System call 34
222ASSUME DS:NOTHING,ES:NOTHING
223
224; Inputs:
225; DS:DX Points to openned FCB
226; Function:
227; Write record addressed by random record field to file from
228; disk transfer address
229; Returns:
230; AL = 1 Disk full
231; AL = 2 No room in disk transfer segment
232; AL = 0 All OK
233
234 invoke GETRRPOS1
235 invoke STORE
236 JMP SHORT FINRND
237
238 entry $FCB_RANDOM_READ_BLOCK ; System call 39
239ASSUME DS:NOTHING,ES:NOTHING
240
241; Inputs:
242; DS:DX Points to openned FCB
243; CX = Record count
244; Function:
245; Read CX records starting at random record field from file
246; to disk transfer address
247; Returns:
248; AL = 1 EOF record is empty
249; AL = 3 EOF record is partial zero filled
250; AL = 2 No room at disk transfer address
251; AL = 0 All OK
252; CX = Actual number of records read
253
254 invoke GETRRPOS
255 invoke LOAD
256 JMP SHORT FINBLK
257
258 entry $FCB_RANDOM_WRITE_BLOCK ; System call 40
259ASSUME DS:NOTHING,ES:NOTHING
260
261; Inputs:
262; DS:DX Points to openned FCB
263; CX = Record count
264; Function:
265; Write CX records starting at random record field to file
266; from disk transfer address
267; If CX = 0 File is set to length determined from random record field
268; Returns:
269; AL = 1 Disk full
270; AL = 2 No room in disk transfer segment
271; AL = 0 All OK
272; CX = Actual number of records written
273
274 invoke GETRRPOS
275 invoke STORE
276FINBLK:
277 invoke get_user_stack
278 MOV [SI.user_CX],CX
279 entry FINNOSAV
280 JCXZ FINRND
281 ADD AX,1
282 ADC DX,0
283FINRND:
284 MOV WORD PTR ES:[DI.fcb_RR],AX
285 MOV ES:[DI.fcb_RR+2],DL
286 OR DH,DH
287 JZ SETNREX
288 MOV ES:[DI.fcb_RR+3],DH ; Save 4 byte of RECPOS only if significant
289SETNREX:
290 MOV CX,AX
291 AND AL,7FH
292 MOV ES:[DI.fcb_NR],AL
293 AND CL,80H
294 SHL CX,1
295 RCL DX,1
296 MOV AL,CH
297 MOV AH,DL
298 MOV ES:[DI.fcb_EXTENT],AX
299 MOV AL,BYTE PTR [DSKERR]
300RET4:
301 RET
302$FCB_SEQ_READ ENDP
303
304SUBTTL $FCB_DELETE -- SYSTEM CALL 19
305PAGE
306 procedure $FCB_DELETE,NEAR ; System call 19
307ASSUME DS:NOTHING,ES:NOTHING
308
309; Inputs:
310; DS:DX point to unopened FCB
311; Function:
312; Delete all matching entries
313; Returns:
314; AL = -1 if no entries matched, otherwise 0
315
316 invoke MOVNAME
317ASSUME ES:DOSGROUP
318 MOV AL,-1
319 MOV BYTE PTR [FoundDel],AL
320 JC RET4
321 MOV AL,BYTE PTR [ATTRIB]
322 AND AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only
323 ; Look only at hidden bits
324 CMP AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only
325 ; All must be set
326 JNZ NOTALL
327 MOV CX,11
328 MOV AL,"?"
329 MOV DI,OFFSET DOSGROUP:NAME1
330 REPE SCASB ; See if name is *.*
331 JNZ NOTALL
332 MOV BYTE PTR [DELALL],0 ; DEL *.* - flag deleting all
333NOTALL:
334 invoke FINDNAME
335ASSUME DS:DOSGROUP
336 MOV AL,-1
337 JC RET4
338 OR AH,AH ; Check if device name
339 JS RET4 ; Can't delete I/O devices
340DELFILE:
341 LES BP,[THISDPB]
342 MOV AH,BYTE PTR [DELALL]
343 PUSH DS
344 LDS DI,[CURBUF]
345ASSUME DS:NOTHING
346 TEST [Attrib],attr_read_only ; are we deleting RO files too?
347 JNZ DoDelete ; yes
348 TEST DS:[BX.dir_attr],attr_read_only
349 JZ DoDelete ; not read only
350 POP DS
351 JMP SHORT DelNxt
352DoDelete:
353 MOV BYTE PTR [FoundDel],0
354 MOV [DI.BUFDIRTY],1
355 MOV BYTE PTR [BX],AH
356 MOV BX,[SI]
357 POP DS
358ASSUME DS:DOSGROUP
359 OR BX,BX
360 JZ DELNXT
361 CMP BX,ES:[BP.dpb_max_cluster]
362 JA DELNXT
363 invoke RELEASE
364DELNXT:
365 invoke GETENTRY ; Registers need to be reset
366 invoke NEXTENT
367 JNC DELFILE
368 CALL FLUSHRET1
369 MOV AL,BYTE PTR [FoundDel]
370 RET
371
372$FCB_DELETE ENDP
373
374SUBTTL $FCB_RENAME -- SYSTEM CALL 23; RENAME FILES
375PAGE
376ERRETJ: JMP ERRET
377
378 procedure $FCB_RENAME,NEAR ; System call 23
379ASSUME DS:NOTHING,ES:NOTHING
380
381; Inputs:
382; DS:DX point to a modified FCB (DS:DX+11H points to destination
383; name)
384; Function:
385; Rename all matching entries to indicated name
386; Returns:
387; AL = -1 if no entries matched, otherwise 0
388
389 invoke MOVNAME
390ASSUME ES:DOSGROUP
391 JC ERRETJ
392 ADD SI,5
393 MOV DI,OFFSET DOSGROUP:NAME2
394 invoke LODNAME
395 JC ERRETJ ; Report error if second name invalid
396 invoke FINDNAME
397ASSUME DS:DOSGROUP
398 JC ERRETJ
399 OR AH,AH ; Check if I/O device name
400 JS ERRETJ ; If so, can't rename it
401 MOV SI,OFFSET DOSGROUP:NAME1
402 MOV DI,OFFSET DOSGROUP:NAME3
403 MOV CX,13
404 REP MOVSB ; Copy name to search for --include attribute byte
405RENFIL:
406 MOV DI,OFFSET DOSGROUP:NAME1
407 MOV SI,OFFSET DOSGROUP:NAME2
408 MOV CX,11
409NEWNAM:
410 LODSB
411 CMP AL,"?"
412 JNZ NOCHG
413 PUSH DS
414 MOV DS,WORD PTR [CURBUF+2]
415 MOV AL,[BX]
416 POP DS
417NOCHG:
418 STOSB
419 INC BX
420 LOOP NEWNAM
421 INC DI
422 MOV BYTE PTR [DI],attr_all ;Sets ATTRIB
423 ; Stop duplicates with any attributes
424 invoke DEVNAME ; Check if giving it a device name
425 JNC RENERR
426 XOR AX,AX
427 PUSH [LASTENT]
428 invoke FINDENTRY ; See if new name already exists
429 POP AX
430 JNC RENERR ; Error if found
431 LES BP,[THISDPB]
432 invoke GETENT ; Re-read matching entry
433 MOV DI,BX ; Leave BX,DX until call to NEXTENT
434 MOV ES,WORD PTR [CURBUF+2]
435 MOV SI,OFFSET DOSGROUP:NAME1
436 MOV CX,11
437 REP MOVSB ; Replace old name with new one
438 MOV DI,WORD PTR [CURBUF]
439 MOV ES:[DI.BUFDIRTY],1 ; Directory changed
440 PUSH SS
441 POP ES
442 MOV SI,OFFSET DOSGROUP:NAME3
443 MOV DI,OFFSET DOSGROUP:NAME1
444 MOV CX,13 ; Include attribute byte
445 REP MOVSB ; Copy name back into search buffer
446 invoke NEXTENT
447 JNC RENFIL
448 JMP FLUSHRET1
449
450RENERR:
451 CALL FLUSHRET1
452ERRET:
453 MOV AL,-1
454 RET
455$FCB_RENAME ENDP
456
457SUBTTL $FCB_OPEN -- SYSTEM CALL 15; OPEN A FILE
458PAGE
459 procedure $FCB_OPEN,NEAR ; System call 15
460ASSUME DS:NOTHING,ES:NOTHING
461
462; Inputs:
463; DS:DX point to an unopened FCB
464; Function:
465; Open indicated file and fill in FCB
466; Returns:
467; AL = -1 if no entries matched, otherwise 0
468; FOR INTERNAL USE
469; [CURBUF+2]:SI and [CURBUF+2]:BX Preserved
470
471 invoke GETFILE
472ASSUME DS:DOSGROUP,ES:NOTHING
473
474 entry DOOPEN
475
476; Enter here to perform $FCB_OPEN on file already found
477; in directory. AH=device ID number, DS=CS, BX points to directory
478; entry in [CURBUF], SI points to First Cluster field, and
479; ES:DI point to the FCB to be opened. This entry point
480; is used by $FCB_CREATE.
481 JC ERRET
482 PUSH SI
483 PUSH AX ; Save I/O driver number
484 XOR AL,AL
485 OR AH,AH
486 JS OPENDEV
487 MOV AL,[THISDRV]
488 MOV DS,WORD PTR [CURBUF+2]
489ASSUME DS:NOTHING
490 INC AX
491OPENDEV:
492 STOSB
493 XOR AX,AX
494IF ZEROEXT
495 ADD DI,11
496 STOSW ; Zero low byte of extent field if ZERPEXT only
497ELSE
498 ADD DI,12 ; Point to high half of CURRENT BLOCK field
499 STOSB ; Set it to zero (CP/M programs set low byte)
500ENDIF
501 MOV AL,128 ; Default record size
502 STOSW ; Set record size
503 LODSW ; Get starting cluster
504 MOV DX,AX ; Save it for the moment
505 MOVSW ; Transfer size to FCB
506 MOVSW
507 MOV AX,[SI-8] ; Get date
508 STOSW ; Save date in FCB
509 MOV AX,[SI-10] ; Get time
510 STOSW ; Save it in FCB
511 POP AX ; Restore I/O driver number
512 POP SI
513 MOV AL,AH
514 OR AL,40H ; Not dirty
515 STOSB
516 JS SAVDEVPT ; If device, go save pointer to it
517 MOV AX,DX ; Restore starting cluster
518 STOSW ; first cluster
519 PUSH AX ; save cluster
520 XOR AX,AX
521 STOSW ; clus pos
522 POP AX ; last cluster
523 STOSB
524 MOV AL,AH
525 MOV AH,BYTE PTR [DIRSTART]
526 PUSH CX
527 MOV CL,4
528 SHL AH,CL
529 OR AL,AH
530 STOSB
531 MOV AX,[DIRSTART]
532 MOV CL,4
533 SHL AX,CL
534 POP CX
535 MOV AL,AH
536 STOSB
537OPEN_RET:
538 XOR AX,AX
539 RET
540
541SAVDEVPT:
542ASSUME DS:DOSGROUP
543 LDS AX,[DEVPT]
544ASSUME DS:NOTHING
545 STOSW
546 MOV ES:[DI],DS
547 JMP SHORT OPEN_RET
548$FCB_OPEN ENDP
549
550SUBTTL $FCB_CLOSE -- SYSTEM CALL 16; CLOSE FILE
551PAGE
552 procedure $FCB_CLOSE,NEAR ; System call 16
553ASSUME DS:NOTHING,ES:NOTHING
554
555; Inputs:
556; DS:DX point to an opened FCB
557; Function:
558; Close the indicated file
559; Returns:
560; AL = -1 if disk has been changed, otherwise 0
561
562 MOV DI,DX
563 CMP BYTE PTR [DI],-1 ; Check for extended FCB
564 JNZ NORMFCB3
565 ADD DI,7
566NORMFCB3:
567 TEST [DI.fcb_DEVID],devid_file_clean+devid_device
568 ; Allow only dirty files
569 JNZ OKRET1 ; can't close I/O device or not written
570 invoke MOVNAMENOSET
571 JC BADCLOSE ; Bad file name
572 entry FCB_CLOSE_INNER
573 PUSH DX
574 PUSH DS
575 MOV SI,DX
576 MOV BX,[SI.fcb_LSTCLUS+1]
577 MOV CL,4
578 SHR BX,CL
579 PUSH BX
580 PUSH SS
581 POP DS
582ASSUME DS:DOSGROUP
583 invoke FATREAD
584 POP BX
585 invoke SETDIRSRCH
586 invoke FINDENTRY
587 POP ES
588 POP DI
589 JC BADCLOSE
590 LDS BX,[CURBUF]
591ASSUME DS:NOTHING
592
593 ; note that SI points to dir_first...
594
595 OR BYTE PTR [SI-dir_first+dir_attr],attr_archive
596 MOV CX,ES:[DI.fcb_FIRCLUS]
597 MOV [SI-dir_first+dir_first],CX
598 MOV DX,ES:WORD PTR [DI.fcb_FILSIZ]
599 MOV [SI-dir_first+dir_size_l],DX
600 MOV DX,ES:WORD PTR [DI.fcb_FILSIZ+2]
601 MOV [SI-dir_first+dir_size_h],DX
602 MOV DX,ES:[DI.fcb_FDATE]
603 MOV [SI-dir_first+dir_date],DX
604 MOV DX,ES:[DI.fcb_FTIME]
605 MOV [SI-dir_first+dir_time],DX
606 MOV [BX.BUFDIRTY],1
607 PUSH SS
608 POP DS
609ASSUME DS:DOSGROUP
610FLUSHRET1:
611 LES BP,[THISDPB]
612 MOV AL,ES:[BP.dpb_drive]
613 invoke FLUSHBUF
614OKRET1:
615 XOR AL,AL
616 RET
617
618BADCLOSE:
619 MOV AL,-1
620 RET
621$FCB_CLOSE ENDP
622
623SUBTTL $FCB_CREATE -- SYSTEM CALL 22; MAKE AND OPEN A NEW FILE
624PAGE
625 procedure $FCB_CREATE,NEAR ; System call 22
626ASSUME DS:NOTHING,ES:NOTHING
627
628; Inputs:
629; DS:DX point to an unopened FCB
630; Function:
631; If file does not exist, create it and open it
632; If file exists, free up its contents and open the file
633; Returns:
634; AL = -1 if file cannot be created, otherwise 0
635
636 invoke MOVNAME
637ASSUME ES:DOSGROUP
638 JC ERRET3
639 MOV DI,OFFSET DOSGROUP:NAME1
640 MOV CX,11
641 MOV AL,"?"
642 REPNE SCASB
643 JZ ERRET3
644 MOV BYTE PTR [CREATING],-1
645 PUSH DX
646 PUSH DS
647 invoke FINDNAME
648ASSUME DS:DOSGROUP
649NWENTY:
650 LES BP,[THISDPB]
651ASSUME ES:NOTHING
652 JNC EXISTENT
653 invoke BUILDDIR
654 JC ERRPOP
655 invoke GETENT ; Point at that free entry
656 JMP SHORT FREESPOT
657ERRPOP:
658 POP DS
659 POP DX
660ASSUME DS:NOTHING
661ERRET3:
662 JMP SHORT BADCLOSE
663
664 entry NEWENTRY
665 POP DX ; Return address
666 POP ES ; ES
667 POP CX ; DI
668 PUSH DX
669 PUSH CX
670 PUSH ES
671 JMP NWENTY
672
673EXISTENT:
674ASSUME DS:DOSGROUP
675 JNZ ERRPOP ; Error if attributes don't match
676 OR AH,AH ; Check if file is I/O device
677 JS OPENJMP ; If so, no action
678 PUSH DS
679 LDS DI,[CURBUF]
680ASSUME DS:NOTHING
681 MOV CX,[SI] ; Get pointer to clusters
682 MOV SI,[DI.BUFSECNO]
683 POP DS
684ASSUME DS:DOSGROUP
685 JCXZ FREESPOT
686 CMP CX,ES:[BP.dpb_max_cluster]
687 JA FREESPOT
688 SUB BX,DI
689 PUSH BX
690 PUSH SI ; Save sector number
691 MOV BX,CX
692 invoke RELEASE ; Free any data already allocated
693 POP DX
694 XOR AL,AL
695 invoke GETBUFFR
696 POP BX
697 ADD BX,WORD PTR [CURBUF]
698FREESPOT:
699 TEST BYTE PTR [ATTRIB],attr_volume_id
700 JZ NOTVOLID
701 CMP BYTE PTR [VOLID],0
702 JNZ ERRPOP ; Can't create a second volume ID
703NOTVOLID:
704 MOV ES,WORD PTR [CURBUF+2]
705 MOV DI,BX
706 MOV SI,OFFSET DOSGROUP:NAME1
707 MOV CX,5
708 MOVSB
709 REP MOVSW
710 MOV AL,[ATTRIB]
711 STOSB
712 MOV CL,5
713 XOR AX,AX
714 REP STOSW
715 invoke DATE16
716 XCHG AX,DX
717 STOSW
718 XCHG AX,DX
719 STOSW
720 XOR AX,AX
721 PUSH DI
722 STOSW
723 STOSW
724 STOSW
725 MOV SI,WORD PTR [CURBUF]
726 MOV ES:[SI.BUFDIRTY],1
727 LES BP,[THISDPB]
728 MOV AL,ES:[BP.dpb_drive]
729 PUSH AX
730 PUSH BX
731 invoke FLUSHBUF
732 POP BX
733 POP AX
734 POP SI
735 MOV AH,AL ; Get I/O driver number back
736OPENJMP:
737 CLC ; Clear carry so OPEN won't fail
738 POP ES
739 POP DI
740ASSUME ES:NOTHING
741 JMP DOOPEN
742$FCB_CREATE ENDP
743
744do_ext
745
746CODE ENDS
747 END
748
749 \ No newline at end of file
diff --git a/v2.0/source/SYSCALL.txt b/v2.0/source/SYSCALL.txt
new file mode 100644
index 0000000..26d4729
--- /dev/null
+++ b/v2.0/source/SYSCALL.txt
@@ -0,0 +1,1657 @@
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 MS-DOS 2.0
20
21 System Calls Reference
22
23
24
25
26
27
28
29
30
31
32
33
34+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
35| |
36| C A V E A T P R O G R A M M E R |
37| |
38| Certain structures, constants and system calls below |
39| are private to the DOS and are extremely |
40| version-dependent. They may change at any time at the |
41| implementors' whim. As a result, they must not be |
42| documented to the general public. If an extreme case |
43| arises, they must be documented with this warning. |
44| |
45| Those structures and constants that are subject to the |
46| above will be marked and bracketed with the flag: |
47| |
48| C A V E A T P R O G R A M M E R |
49| |
50+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 Section 1
70
71 Extensions to existing call structure
72
73
74 Name: * Alloc - allocate memory
75
76 Assembler usage:
77 MOV BX,size
78 MOV AH,Alloc
79 INT 21h
80 ; AX:0 is pointer to allocated memory
81 ; if alloc fails, BX is the largest block available
82
83 Description:
84 Alloc returns a pointer to a free block of memory
85 that has the requested size in paragraphs.
86
87 Error return:
88 AX = error_not_enough_memory
89 The largest available free block is smaller
90 than that requested or there is no free block.
91 = error_arena_trashed
92 The internal consistency of the memory arena
93 has been destroyed. This is due to a user
94 program changing memory that does not belong
95 to it.
96
97
98 Name: * CharOper - change incompatible configuration
99 parameters
100
101 Assembler usage:
102 MOV AH, CharOper
103 MOV AL, func
104 MOV DL, data
105 INT 21h
106 ; on read functions, data is returned in DL
107
108 Description:
109 CharOper allows a program to change system
110 parameters to allow for switch indicators and whether
111 devices are available at every level of the directory
112 tree.
113
114 A function code is passed in AL:
115
116 AL Function
117 -- --------
118 0 DL, on return, will contain the DOS switch
119 character. On most systems this will default to
120 '-'.
121 1 Set the switch character to the character in DL.
122 2 Read the device availability byte into DL. If
123 this byte is 0, then devices must be accessed in
124 file I/O calls by /dev/device. If this byte is
125 non-zero, then the devices are available at every
126 node of the directory tree (i.e. CON is the
127 console device not the file CON). This byte is
128 generally 0.
129 3 Set the device availability byte to the value in
130 DL.
131
132 Error returns:
133 AL = FF
134 The function code specified in AL is not in
135 the range 0:3
136
137
138 Name: * CurrentDir - return text of current directory
139
140 Assembler usage:
141 MOV AH,CurrentDir
142 LDS SI,area
143 MOV DL,drive
144 INT 21h
145 ; DS:SI is a pointer to 64 byte area that contains
146 ; drive current directory.
147
148 Description:
149 CurrentDir returns the current directory for a
150 particular drive. The directory is root-relative and
151 does not contain the drive specifier. The drive code
152 passed in DL is 0=default, 1=A, 2=B, etc.
153
154 Error returns:
155 AX = error_invalid_drive
156 The drive specified in DL was invalid.
157
158
159 Name: * Dealloc - free allocated memory
160
161 Assembler usage:
162 MOV ES,block
163 MOV AH,dealloc
164 INT 21h
165
166 Description:
167 Dealloc returns a piece of memory to the system
168 pool that was allocated by alloc.
169
170 Error return:
171 AX = error_invalid_block
172 The block passed in ES is not one allocated
173 via Alloc.
174 = error_arena_trashed
175 The internal consistency of the memory arena
176 has been destroyed. This is due to a user
177 program changing memory that does not belong
178 to it.
179
180
181 Name: * FileTimes - get/set the write times of a
182 handle
183
184 Assembler usage:
185 MOV AH, FileTimes
186 MOV AL, func
187 MOV BX, handle
188 ; if AL = 1 then then next two are mandatory
189 MOV CX, time
190 MOV DX, date
191 INT 21h
192 ; if AL = 0 then CX/DX has the last write time/date
193 ; for the handle.
194
195 Description:
196 FileTimes returns or sets the last-write time for
197 a handle. These times are not recorded until the file
198 is closed.
199
200 A function code is passed in AL:
201
202 AL Function
203 -- --------
204 0 Return the time/date of the handle in CX/DX
205 1 Set the time/date of the handle to CX/DX
206
207 Error returns:
208 AX = error_invalid_function
209 The function passed in AL was not in the range
210 0:1.
211 = error_invalid_handle
212 The handle passed in BX was not currently
213 open.
214
215
216 Name: * FindFirst - find matching file
217
218 Assembler usage:
219 MOV AH, FindFirst
220 LDS DX, pathname
221 MOV CX, attr
222 INT 21h
223 ; DMA address has datablock
224
225 Description:
226 FindFirst takes a pathname with wildcards in the
227 last component (passed in DS:DX), a set of attributes
228 (passed in CX) and attempts to find all files that
229 match the pathname and have a subset of the required
230 attributes. A datablock at the current DMA is written
231 that contains information in the following form:
232
233 find_buf STRUC
234+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
235| C A V E A T P R O G R A M M E R |
236| |
237 find_buf_sattr DB ? ; attribute of search
238 find_buf_drive DB ? ; drive of search
239 find_buf_name DB 11 DUP (?); search name
240 find_buf_LastEnt DW ? ; LastEnt
241 find_buf_ThisDPB DD ? ; This DPB
242 find_buf_DirStart DW ? ; DirStart
243| |
244| C A V E A T P R O G R A M M E R |
245+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
246
247 find_buf_attr DB ? ; attribute found
248 find_buf_time DW ? ; time
249 find_buf_date DW ? ; date
250 find_buf_size_l DW ? ; low(size)
251 find_buf_size_h DW ? ; high(size)
252 find_buf_pname DB 13 DUP (?) ; packed name
253 find_buf ENDS
254
255 To obtain the subsequent matches of the pathname,
256 see the description of FindNext
257
258 Error Returns:
259 AX = error_file_not_found
260 The path specified in DS:DX was an invalid
261 path.
262 = error_no_more_files
263 There were no files matching this
264 specification.
265
266
267 Name: * FindNext - step through a directory matching
268 files
269
270 Assembler usage:
271 ; DMA points at area returned by find_first
272 MOV AH, findnext
273 INT 21h
274 ; next entry is at dma
275
276 Description:
277 FindNext finds the next matching entry in a
278 directory. The current DMA address must point at a
279 block returned by FindFirst (see FindFirst).
280
281 Error Returns:
282 AX = error_no_more_files
283 There are no more files matching this pattern.
284
285
286 Name: * GetDMA - get current DMA transfer address
287
288 Assembler usage:
289 MOV AH,GetDMA
290 INT 21h
291 ; ES:BX has current DMA transfer address
292
293 Description:
294 Return DMA transfer address.
295
296 Error returns:
297 None.
298
299+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
300| C A V E A T P R O G R A M M E R |
301| |
302
303 Name: * GetDSKPT(DL) - get pointer to drive parameter
304 block
305
306 Assembler usage:
307 MOV AH,GetDSKPT
308 INT 21h
309 ; DS:BX has address of drive parameter block
310
311 Description:
312 Return pointer to default drive parameter block.
313
314 Error returns:
315 None.
316
317 Assembler usage:
318 MOV DL,DrvNUM
319 MOV AH,GetDSKPTDL
320 INT 21h
321 ; DS:BX has address of drive parameter block
322
323 Description:
324 Return pointer to drive parameter block for drive
325 designated in DL (0=Default, A=1, B=2 ...)
326
327 Error returns:
328 AL = FF
329 The drive given in DL is invalid.
330| |
331| C A V E A T P R O G R A M M E R |
332+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
333
334
335 Name: * GetFreespace - get Disk free space
336
337 Assembler usage:
338 MOV AH,GetFreespace
339 MOV DL,Drive ;0 = default, A = 1
340 INT 21h
341 ; BX = Number of free allocation units on drive
342 ; DX = Total number of allocation units on drive
343 ; CX = Bytes per sector
344 ; AX = Sectors per allocation unit
345
346 Description:
347 Return Free space on disk along with additional
348 information about the disk.
349
350 Error returns:
351 AX = FFFF
352 The drive number given in DL was invalid.
353
354 NOTE: This call returns the same information in the same
355 registers (except for the FAT pointer) as the get FAT
356 pointer calls did in previous versions of the DOS.
357
358
359 Name: * GetInDOSF - get DOS critical-section flag
360
361 Assembler usage:
362 MOV AH,GetInDOSF
363 INT 21h
364 ; ES:BX has location of the flag
365 MOV CritSEG, ES
366 MOV CritOFF, BX
367 ...
368 IntVec:
369 MOV AX, DWORD PTR Crit
370 CMP AX,0
371 JZ DoFunc
372 IRET
373 DoFunc: ...
374
375 Description:
376 Return location of indos flag. On return ES:BX is
377 the address of a byte memory cell inside the DOS. If
378 used in an interrupt service routine, it indicates
379 whether or not the DOS was interrupted in a critical
380 section. If the cell was zero, then the DOS was not
381 in a critical section and thus can be called by the
382 interrupt routine. If the cell was non-zero, the DOS
383 should be considered to be in an uninterruptable state
384 and for reliability, no DOS calls should be given.
385
386 Error returns:
387 None.
388
389
390 Name: * GetVector - get interrupt vector
391
392 Assembler usage:
393 MOV AH,GetVector
394 MOV AL,interrupt
395 INT 21h
396 ; ES:BX now has long pointer to interrupt routine
397
398 Description:
399 Return interrupt vector associated with an
400 interrupt.
401
402 Error returns:
403 None.
404
405
406 Name: * GetVerifyFlag - return current setting of the
407 verify after write flag.
408
409 Assembler usage:
410 MOV AH,GetVerifyFlag
411 INT 21h
412 ; AL is the current verify flag value
413
414 Description:
415 The current value of the verify flag is returned
416 in AL.
417
418 Error returns:
419 None.
420
421
422 Name: * GetVersion - get DOS version number
423
424 Assembler usage:
425 MOV AH,GetVersion
426 INT 21h
427 ; AL is the major version number
428 ; AH is the minor version number
429 ; BH is the OEM number
430 ; BL:CX is the (24 bit) user number
431
432 Description:
433 Return MS-DOS version number. On return AL.AH
434 will be the two part version designation, ie. for
435 MS-DOS 1.28 AL would be 1 and AH would be 28. For pre
436 1.28 DOS AL = 0. Note that version 1.1 is the same as
437 1.10, not the same as 1.01.
438
439 Error returns:
440 None.
441
442
443 Name: * International - return country dependent
444 information
445
446 Assembler usage:
447 LDS DX, blk
448 MOV AH, International
449 MOV AL, func
450 INT 21h
451
452 Description:
453 This call returns in the block of memory pointed
454 to by DS:DX, the following information pertinent to
455 international applications:
456
457 +---------------------------+
458 | WORD Date/time format |
459 +---------------------------+
460 | BYTE ASCIZ string |
461 | currency symbol |
462 +---------------------------+
463 | BYTE ASCIZ string |
464 | thousands separator |
465 +---------------------------+
466 | BYTE ASCIZ string decimal |
467 | separator |
468 +---------------------------+
469
470 The date/time format has the following values and
471 meanings:
472
473 0 - USA standard h:m:s m/d/y
474 1 - Europe standard h:m:s d/m/y
475 2 - Japan standard y/m/d h:m:s
476
477 The value passed in AL is either 0 (for current
478 country) or a country code (to be defined later.
479 Currently the country code must be zero).
480
481 Error returns:
482 AX = error_invalid_function
483 The function passed in AL was not 0
484 (currently).
485
486
487 Name: * KeepProcess - terminate process and remain
488 resident
489
490 Assembler usage:
491 MOV AL, exitcode
492 MOV DX, parasize
493 MOV AH, KeepProcess
494 INT 21h
495
496 Description:
497 This call terminates the current process and
498 attempts to set the initial allocation block to a
499 specific size in paragraphs. It will not free up any
500 other allocation blocks belonging to that process.
501 The exit code passed in AX is retrievable by the
502 parent via Wait.
503
504 Error Returns:
505 None.
506
507
508 Name: * Rename - move a directory entry
509
510 Assembler usage:
511 LDS DX, source
512 LES DI, dest
513 MOV AH, Rename
514 INT 21h
515
516 Description:
517 Rename will attempt to rename a file into another
518 path. The paths must be on the same device.
519
520 Error returns:
521 AX = error_file_not_found
522 The file name specifed by DS:DX was not found.
523 = error_not_same_device
524 The source and destination are on different
525 drives.
526 = error_access_denied
527 The path specified in DS:DX was a directory or
528 the file specified by ES:DI exists or the
529 destination directory entry could not be
530 created.
531
532
533 Name: * SetBlock - modify allocated blocks
534
535 Assembler usage:
536 MOV ES,block
537 MOV BX,newsize
538 MOV AH,setblock
539 INT 21h
540 ; if setblock fails for growing, BX will have the
541 ; maximum size possible
542
543 Description:
544 Setblock will attempt to grow/shrink an allocated
545 block of memory.
546
547 Error return:
548 AX = error_invalid_block
549 The block passed in ES is not one allocated
550 via Alloc.
551 = error_arena_trashed
552 The internal consistency of the memory arena
553 has been destroyed. This is due to a user
554 program changing memory that does not belong
555 to it.
556 = error_not_enough_memory
557 There was not enough free memory after the
558 specified block to satisfy the grow request.
559
560
561 Name: * SetCtrlCTrapping - turn on/off broad ^C
562 checking
563
564 Assembler usage:
565 MOV DL,val
566 MOV AH,SetCtrlCTrapping
567 MOV AL,func
568 INT 21h
569 ; If AL was 0, then DL has the current value of the
570 ; ^C check
571
572 Description:
573 MSDOS ordinarily checks for a ^C on the
574 controlling device only when doing a function 1-12
575 operation to that device. SetCtrlCTrapping allows the
576 user to expand this checking to include any system
577 call. For example, with the ^C trapping off, all disk
578 I/O will proceed without interruption while with ^C
579 trapping on, the ^C interrupt is given at the system
580 call that initiates the disk operation.
581
582 Error return:
583 AL = FF
584 The function passed in AL was not in the range
585 0:1.
586
587+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
588| C A V E A T P R O G R A M M E R |
589| |
590
591 Name: * Set_OEM_Handler - set handler for OEM
592 specific INT 21H calls.
593
594 Assembler usage:
595 LDS DX,handler_address
596 MOV AH,Set_OEM_Handler
597 INT 21H
598
599 Description:
600 Set handler address for 0F9H-0FFH INT 21H system
601 calls to DS:DX. To return the 0F9H-0FFH calls to
602 the uninitialized state, give DS=DX=-1.
603
604 Error returns:
605 None.
606
607 Handler entry:
608 All registers as user set them when INT 21H
609 issued (including SS:SP). INT 21 return is on
610 stack, so the correct method for the OEM handler
611 to return to the user is to give an IRET. The
612 OEM handler is free to make any INT 21H system
613 call (including the 0F9H- 0FFH group if the OEM
614 handler is re-entrant).
615
616
617 The AH INT 21H function codes 0F8H through 0FFH are
618 reserved for OEM extensions to the INT 21H calling
619 convention. These calls have two states, initialized
620 and uninitialized. There will be one handler for all 7
621 (0F9-0FFH) functions. When the DOS is first
622 initialized, these calls are uninitialized. The AH=0F8H
623 call is the call which will set the handler address for
624 the 0F9-0FFH calls. If the 0F9-0FFH calls are
625 uninitialized, an attempt to call them results in the
626 normal invalid system call number return.
627 OEMs should NOT document the 0F8 call.
628| |
629| C A V E A T P R O G R A M M E R |
630+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649 Section 2
650
651 XENIX-compatible system calls
652
653
654
655 Previous to version 2.0, MSDOS had a simple single
656 directory structure that sufficed for small (160k to 320K)
657 diskettes. As the need for hard disk support grows, and
658 as MSDOS 2.0 will support a wide variety of hard disks,
659 the need for better disk organization also grows. Merely
660 expanding the directory is not an effective solution;
661 doing a 'DIR' on a directory with 1000 files is not a
662 user-friendly characteristic.
663
664 People, by nature, think in hierarchical terms:
665 organization charts and family trees, for example. It
666 would be nice to allow users to organize their files on
667 disk in a similar manner. Consider the following:
668
669 In a particular business, both sales and accounting
670 share a computer with a large disk and the individual
671 employees use it for preparation of reports and
672 maintaining accounting information. One would naturally
673 view the organization of files on the disk in this
674 fashion:
675
676 +-disk-+
677 / \
678 / \
679 / \
680 sales accounting
681 / | | \
682 / | | \
683 / | | \
684 John Mary Steve Sue
685 / | (A) | | | \
686 / | | | | \
687 / | | | | \
688 report accts. report accts. report report
689 receiv. receiv
690
691 In MSDOS 2.0 the user can arrange his files in such a
692 manner that files that are not part of his current task do
693 not interfere with that task. Pre-2.0 versions of MSDOS
694 has a single directory that contains files. MSDOS extends
695 this concept to allow a directory to contain both files
696 and directories and to introduce the notion of the
697 'current' directory.
698
699 To specify a filename, the user could use one of two
700 methods, either specify a path from the root node to the
701 file, or specify a path from the current node to the file.
702 A path is a series of directory names separated by '/' and
703 ending with a filename. A path that starts at the root
704 begins with a '/'.
705
706 There is a special directory entry in each directory,
707 denoted by '..' that is the parent of the directory. The
708 root directory's parent is itself (who created God?).
709
710 Using a directory structure like the hierarchy above,
711 and assuming that the current directory is at point (D),
712 to reference the report under John, the following are all
713 equivalent:
714
715 report
716 /sales/John/report
717 ../John/report
718
719 To refer to the report under Mary, the following are
720 all equivalent:
721
722 ../Mary/report
723 /sales/Mary/report
724
725 To refer to the report under Sue, the following are
726 all equivalent.
727
728 ../../accounting/Sue/report
729 /accounting/Sue/report
730
731 There is no restriction in MSDOS 2.0 on the depth of a
732 tree (the length of the longest path from root to leaf)
733 except in the number of allocation units available. The
734 root directory will have a fixed number of entries, 64 for
735 the single sided diskettes to XXX for a large hard disk.
736 For non-root directories, there is no limit to the number
737 of files per directory excepting in the number of
738 allocation units available.
739
740 Old (pre-2.0) disks will appear to MSDOS 2.0 as having
741 only a root directory with files in it and no
742 subdirectories whatever.
743
744 Implementation of the tree-structure is simple. The
745 root directory is the pre-2.0 directory. Subdirectories
746 of the root have a special attribute set indicating that
747 they are directories. The subdirectories themselves are
748 files, linked through the FAT as usual. Their contents
749 are identical in character to the contents of the root
750 directory.
751
752 Pre-2.0 programs that use system calls not described
753 below will not be able to make use of files in other
754 directories. They will only be able to access files in
755 the current directory. This is no great loss of
756 functionality as users will aggregate their files into
757 sub-directories on basis of functionality; the files that
758 are being used will be found in the current directory.
759 Those that are not necessary for the current task will be
760 placed in other directories. Out of sight, out of mind.
761
762 There are also new attributes in 2.0. These and the
763 old attributes apply to the tree structured directories in
764 the following manner:
765
766 Attribute Meaning/Function Meaning/Function
767 for files for directories
768
769 volume_id Present at the root. Meaningless.
770 Only one file may have
771 this set.
772
773 directory Meaningless. Indicates that the
774 directory entry is a
775 directory. Cannot be
776 changed with ChMod.
777
778 read_only Old fcb-create, new Meaningless.
779 Creat, new open (for
780 write or read/write)
781 will fail.
782
783 archive Set when file is Meaningless.
784 written. Set/reset via
785 ChMod.
786
787 hidden/ Prevents file from Prevents directory
788 system being found in search entry from being
789 first/search next. found. ChDir to
790 New open will fail. directory will still
791 work.
792
793
794 Name: * ChDir - Change the current directory
795
796 Assembler usage:
797 LDS DX, name
798 MOV AH, ChDir
799 INT 21h
800
801 Description:
802 ChDir is given the ASCIZ name of the directory
803 which is to become the current directory. If any
804 member of the specified pathname does not exist, then
805 the current directory is unchanged. Otherwise, the
806 current directory is set to the string.
807
808 Error returns:
809 AX = error_path_not_found
810 The path specified in DS:DX either indicated a
811 file or the path was invalid.
812
813
814 Name: * ChMod - change write protection
815
816 Assembler usage:
817 LDS DX, name
818 MOV CX, attribute
819 MOV AL, func
820 MOV AH, ChMod
821 INT 21h
822
823 Description:
824 Given an ASCIZ name, ChMod will set/get the
825 attributes of the file to those given in CX.
826
827 A function code is passed in AL:
828
829 AL Function
830 -- --------
831 0 Return the attributes of the file in CX
832 1 Set the attributes of the file to those in CX
833
834 Error returns:
835 AX = error_path_not_found
836 The path specified was invalid.
837 = error_access_denied
838 The attributes specified in CX contained one
839 that could not be changed (directory, volume
840 ID).
841 = error_invalid_function
842 The function passed in AL was not in the range
843 0:1.
844
845
846 Name: * Close - close a file handle
847
848 Assembler usage:
849 MOV BX, handle
850 MOV AH, Close
851 INT 21h
852
853 Description:
854 In BX is passed a file handle (like that returned
855 by Open, Creat or Dup); the Close call will close the
856 associated file. Internal buffers are flushed.
857
858 Error return:
859 AX = error_invalid_handle
860 The handle passed in BX was not currently
861 open.
862
863
864 Name: * Creat - create a file
865
866 Assembler usage:
867 LDS DX, name
868 MOV AH, Creat
869 MOV CX, attribute
870 INT 21h
871 ; AX now has the handle
872
873 Description:
874 Creat creates a new file or truncates an old file
875 to zero length in preparation for writing. If the
876 file did not exist, then the file is created in the
877 appropriate directory and the file is given the
878 read/write protection code of access.
879
880 CX contains the default attributes to be set for
881 the file. Currently, the read-only bit must be off.
882
883 Error returns:
884 AX = error_access_denied
885 The attributes specified in CX contained one
886 that could not be created (directory, volume
887 ID), a file already existed with a more
888 inclusive set of attributes, or a directory
889 existed with the same name.
890 = error_path_not_found
891 The path specified was invalid.
892 = error_too_many_open_files
893 The file was created with the specified
894 attributes, but there were no free handles
895 available for the process or that the internal
896 system tables were full.
897
898
899 Name: * Dup - duplicate a file handle
900
901 Assembler usage:
902 MOV BX, fh
903 MOV AH, Dup
904 INT 21h
905 ; AX has the returned handle
906
907 Description:
908 Dup takes an already opened file handle and
909 returns a new handle that refers to the same file at
910 the same position.
911
912 Error returns:
913 AX = error_invalid_handle
914 The handle passed in BX was not currently
915 open.
916 = error_too_many_open_files
917 There were no free handles available in the
918 current process or the internal system tables
919 were full.
920
921
922 Name: * Dup2 - force a duplicate of a handle
923
924 Assembler usage:
925 MOV BX, fh
926 MOV CX, newfh
927 MOV AH, Dup2
928 INT 21h
929
930 Description:
931 Dup2 will cause newfh to refer to the same stream
932 as fh. If there was an open file on newfh, then it is
933 closed first.
934
935 Error returns:
936 AX = error_invalid_handle
937 The handle passed in BX was not currently
938 open.
939
940
941 Name: * Exec - load / execute a program
942
943 Assembler usage:
944 LDS DX, name
945 LES BX, blk
946 MOV AH, Exec
947 MOV AL, func
948 INT 21h
949
950 Description:
951 This call allows a program to load another program
952 into memory and (default) begin execution of it.
953 DS:DX points to the ASCIZ name of the file to be
954 loaded. ES:BX points to a parameter block for the
955 load.
956
957 A function code is passed in AL:
958
959 AL Function
960 -- --------
961 0 Load and execute the program. A program header is
962 established for the program and the terminate and
963 ^C addresses are set to the instruction after the
964 EXEC system call.
965
966 NOTE: When control is returned, via a ^C or
967 terminate, from the program being EXECed ALL
968 registers are altered including the stack.
969 This is because control is returned from the
970 EXECed program, not the system. To regain
971 your stack, store an SS:SP value in a data
972 location reachable from your CS.
973
974+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
975| C A V E A T P R O G R A M M E R |
976| |
977 1 Load, create the program header but do not begin
978 execution. The CS:IP/SS:SP of the program are
979 returned in the area provided by the user.
980| |
981| C A V E A T P R O G R A M M E R |
982+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
983
984 3 Load, do not create the program header, and do not
985 begin execution. This is useful in loading
986 program overlays.
987
988 For each value of AL, the block has the following
989 format:
990
991 AL = 0 -> load/execute program
992
993 +---------------------------+
994 | WORD segment address of |
995 | environment. |
996 +---------------------------+
997 | DWORD pointer to command |
998 | line at 80h |
999 +---------------------------+
1000 | DWORD pointer to default |
1001 | FCB to be passed at 5Ch |
1002 +---------------------------+
1003 | DWORD pointer to default |
1004 | FCB to be passed at 6Ch |
1005 +---------------------------+
1006
1007+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1008| C A V E A T P R O G R A M M E R |
1009| |
1010 AL = 1 -> load program
1011
1012 +---------------------------+
1013 | WORD segment address of |
1014 | environment. |
1015 +---------------------------+
1016 | DWORD pointer to command |
1017 | line at 80h |
1018 +---------------------------+
1019 | DWORD pointer to default |
1020 | FCB to be passed at 5Ch |
1021 +---------------------------+
1022 | DWORD pointer to default |
1023 | FCB to be passed at 6Ch |
1024 +---------------------------+
1025 | DWORD returned value of |
1026 | SS:SP |
1027 +---------------------------+
1028 | DWORD returned value of |
1029 | CS:IP |
1030 +---------------------------+
1031| |
1032| C A V E A T P R O G R A M M E R |
1033+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1034
1035 AL = 3 -> load overlay
1036
1037 +---------------------------+
1038 | WORD segment address where|
1039 | file will be loaded. |
1040 +---------------------------+
1041 | WORD relocation factor to |
1042 | be applied to the image. |
1043 +---------------------------+
1044
1045 Note that all open files of a process are
1046 duplicated in the child process after an Exec. This
1047 is extremely powerful; the parent process has control
1048 over the meanings of stdin, stdout, stderr, stdaux and
1049 stdprn. The parent could, for example, write a series
1050 of records to a file, open the file as standard input,
1051 open a listing file as standard output and then Exec a
1052 sort program that takes its input from stdin and
1053 writes to stdout.
1054
1055 Also inherited (or passed from the parent) is an
1056 'environment'. This is a block of text strings (less
1057 than 32K bytes total) that convey various
1058 configurations parameters. The format of the
1059 environment is as follows:
1060
1061 (paragraph boundary)
1062 +---------------------------+
1063 | BYTE asciz string 1 |
1064 +---------------------------+
1065 | BYTE asciz string 2 |
1066 +---------------------------+
1067 | ... |
1068 +---------------------------+
1069 | BYTE asciz string n |
1070 +---------------------------+
1071 | BYTE of zero |
1072 +---------------------------+
1073
1074 Typically the environment strings have the form:
1075
1076 parameter=value
1077
1078 for example, COMMAND.COM always passes its execution
1079 search path as:
1080
1081 PATH=A:/BIN;B:/BASIC/LIB
1082
1083 A zero value of the environment address will cause the
1084 child process to inherit the parent's environment
1085 unchanged.
1086
1087 Note that on a successful return from EXEC, all
1088 registers, except for CS:IP, are changed.
1089
1090 Error return:
1091 AX = error_invalid_function
1092 The function passed in AL was not 0, 1 or 3.
1093 = error_bad_environment
1094 The environment was larger than 32Kb.
1095 = error_bad_format
1096 The file pointed to by DS:DX was an EXE format
1097 file and contained information that was
1098 internally inconsistent.
1099 = error_not_enough_memory
1100 There was not enough memory for the process to
1101 be created.
1102 = error_file_not_found
1103 The path specified was invalid or not found.
1104
1105
1106 Name: * Exit - terminate a process
1107
1108 Assembler usage:
1109 MOV AL, code
1110 MOV AH, Exit
1111 INT 21h
1112
1113 Description:
1114 Exit will terminate the current process,
1115 transferring control to the invoking process. In
1116 addition, a return code may be sent. All files open
1117 at the time are closed.
1118
1119 Error returns:
1120 None.
1121
1122
1123 Name: * Ioctl - I/O control for devices
1124
1125 Assembler usage:
1126 MOV BX, Handle
1127
1128 (or MOV BL, drive for calls AL=4,5
1129 0=default,A=1...)
1130
1131 MOV DX, Data
1132
1133 (or LDS DX, buf and
1134 MOV CX, count for calls AL=2,3,4,5)
1135
1136 MOV AH, Ioctl
1137 MOV AL, func
1138 INT 21h
1139 ; For calls AL=2,3,4,5 AX is the number of bytes
1140 ; transferred (same as READ and WRITE).
1141 ; For calls AL=6,7 AL is status returned, AL=0 if
1142 ; status is not ready, AL=0FFH otherwise.
1143
1144 Description:
1145 Set or Get device information associated with open
1146 Handle, or send/receive control string to device
1147 Handle or device.
1148
1149 The following values are allowed for func:
1150
1151 Request Function
1152 ------ --------
1153 0 Get device information (returned in DX)
1154 1 Set device information (as determined by DX)
1155 2 Read CX number of bytes into DS:DX from device
1156 control channel.
1157 3 Write CX number of bytes from DS:DX to device
1158 control channel.
1159 4 Same as 2 only drive number in BL
1160 0=default,A=1,B=2,...
1161 5 Same as 3 only drive number in BL
1162 0=default,A=1,B=2,...
1163 6 Get input status
1164 7 Get output status
1165
1166 Ioctl can be used to get information about device
1167 channels. It is ok to make Ioctl calls on regular
1168 files but only calls 0,6 and 7 are defined in that
1169 case (AL=0,6,7), all other calls return an
1170 error_invalid_function error.
1171
1172 CALLS AL=0 and AL=1
1173
1174 The bits of DX are defined as follows for calls
1175 AL=0 and AL=1. Note that the upper byte MUST be zero
1176 on a set call.
1177
1178 |
1179 15 14 13 12 11 10 9 8|7 6 5 4 3 2 1 0
1180 +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+
1181 | R| C| |I|E|R|S|I|I|I|I|
1182 | e| T| |S|O|A|P|S|S|S|S|
1183 | s| R| Reserved |D|F|W|E|C|N|C|C|
1184 | | L| |E| | |C|L|U|O|I|
1185 | | | |V| | |L|K|L|T|N|
1186 +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+
1187 |
1188
1189 ISDEV = 1 if this channel is a device
1190 = 0 if this channel is a disk file (Bits 8-15 =
1191 0 in this case)
1192
1193 If ISDEV = 1
1194
1195 EOF = 0 if End Of File on input
1196 RAW = 1 if this device is in Raw mode
1197 = 0 if this device is cooked
1198 ISCLK = 1 if this device is the clock device
1199 ISNUL = 1 if this device is the null device
1200 ISCOT = 1 if this device is the console output
1201 ISCIN = 1 if this device is the console input
1202 SPECL = 1 if this device is special
1203
1204 CTRL = 0 if this device can NOT do control strings
1205 via calls AL=2 and AL=3.
1206 CTRL = 1 if this device can process control
1207 strings via calls AL=2 and AL=3.
1208 NOTE that this bit cannot be set.
1209
1210 If ISDEV = 0
1211 EOF = 0 if channel has been written
1212 Bits 0-5 are the block device number for the
1213 channel (0 = A, 1 = B, ...)
1214
1215 Bits 15,8-13,4 are reserved and should not be altered.
1216
1217 Calls 2..5:
1218 These four calls allow arbitrary control strings to be
1219 sent or received from a device. The Call syntax is
1220 the same as the READ and WRITE calls, except for 4 and
1221 5 which take a drive number in BL instead of a handle
1222 in BX.
1223
1224 An error_invalid_function error is returned if the
1225 CTRL bit (see above) is 0.
1226
1227 An error_access_denied is returned by calls AL=4,5 if
1228 the drive number is invalid.
1229
1230 Calls 6,7:
1231 These two calls allow the user to check if a file
1232 handle is ready for input or output. Status of
1233 handles open to a device is the intended use of these
1234 calls, but status of a handle open to a disk file is
1235 OK and is defined as follows:
1236
1237 Input:
1238 Always ready (AL=FF) until EOF reached, then
1239 always not ready (AL=0) unless current
1240 position changed via LSEEK.
1241 Output:
1242 Always ready (even if disk full).
1243
1244 IMPORTANT NOTE:
1245 The status is defined at the time the system is
1246 CALLED. On future versions, by the time control is
1247 returned to the user from the system, the status
1248 returned may NOT correctly reflect the true current
1249 state of the device or file.
1250
1251 Error returns:
1252 AX = error_invalid_handle
1253 The handle passed in BX was not currently
1254 open.
1255 = error_invalid_function
1256 The function passed in AL was not in the range
1257 0:7.
1258 = error_invalid_data
1259 = error_access_denied (calls AL=4..7)
1260
1261
1262 Name: * LSeek - move file read/write pointer
1263
1264 Assembler usage:
1265 MOV DX, offsetlow
1266 MOV CX, offsethigh
1267 MOV AL, method
1268 MOV BX, handle
1269 MOV AH, LSeek
1270 INT 21h
1271 ; DX:AX has the new location of the pointer
1272
1273 Description:
1274 LSeek moves the read/write pointer according to
1275 method:
1276
1277 Method Function
1278 ------ --------
1279 0 The pointer is moved to offset bytes from the
1280 beginning of the file.
1281 1 The pointer is moved to the current location
1282 plus offset.
1283 2 The pointer is moved to the end of file plus
1284 offset.
1285
1286 Offset should be regarded as a 32-bit integer with
1287 CX occupying the most significant 16 bits.
1288
1289 Error returns:
1290 AX = error_invalid_handle
1291 The handle passed in BX was not currently
1292 open.
1293 = error_invalid_function
1294 The function passed in AL was not in the range
1295 0:2.
1296
1297
1298 Name: * MkDir - Create a directory entry
1299
1300 Assembler usage:
1301 LDS DX, name
1302 MOV AH, MkDir
1303 INT 21h
1304
1305 Description:
1306 Given a pointer to an ASCIZ name, create a new
1307 directory entry at the end.
1308
1309 Error returns:
1310 AX = error_path_not_found
1311 The path specified was invalid or not found.
1312 = error_access_denied
1313 The directory could not be created (no room in
1314 parent directory), the directory/file already
1315 existed or a device name was specified.
1316
1317
1318 Name: * Open - access a file
1319
1320 Assembler usage:
1321 LDS DX, name
1322 MOV AH, Open
1323 MOV AL, access
1324 INT 21h
1325 ; AX has error or file handle
1326 ; If successful open
1327
1328 Description:
1329 Open associates a 16-bit file handle with a file.
1330
1331 The following values are allowed for access:
1332
1333 ACCESS Function
1334 ------ --------
1335 0 file is opened for reading
1336 1 file is opened for writing
1337 2 file is opened for both reading and writing.
1338
1339 DS:DX point to an ASCIZ name of the file to be
1340 opened.
1341
1342 The read/write pointer is set at the first byte of
1343 the file and the record size of the file is 1 byte.
1344 The returned file handle must be used for subsequent
1345 I/O to the file.
1346
1347 The DOS, on initialization, will have a maximum
1348 number of files. See the configuration file document
1349 for information on changing this default.
1350
1351 Error returns:
1352 AX = error_invalid_access
1353 The access specified in AL was not in the
1354 range 0:2.
1355 = error_file_not_found
1356 The path specified was invalid or not found.
1357 = error_access_denied
1358 The user attempted to open a directory or
1359 volume-id, or open a read-only file for
1360 writing.
1361 = error_too_many_open_files
1362 There were no free handles available in the
1363 current process or the internal system tables
1364 were full.
1365
1366
1367 Name: * Read - Do file/device I/O
1368
1369 Assembler usage:
1370 LDS DX, buf
1371 MOV CX, count
1372 MOV BX, handle
1373 MOV AH, Read
1374 INT 21h
1375 ; AX has number of bytes read
1376
1377 Description:
1378 Read transfers count bytes from a file into a
1379 buffer location. It is not guaranteed that all count
1380 bytes will be read; for example, reading from the
1381 keyboard will read at most one line of text. If the
1382 returned value is zero, then the program has tried to
1383 read from the end of file.
1384
1385 All I/O is done using normalized pointers; no
1386 segment wraparound will occur.
1387
1388 Error returns:
1389 AX = error_invalid_handle
1390 The handle passed in BX was not currently
1391 open.
1392 = error_access_denied
1393 The handle passed in BX was opened in a mode
1394 that did not allow reading.
1395
1396
1397 Name: * RmDir - Remove a directory entry
1398
1399 Assembler usage:
1400 LDS DX, name
1401 MOV AH, RmDir
1402 INT 21h
1403
1404 Description:
1405 RmDir is given an asciz name of a directory. That
1406 directory is removed from its parent
1407
1408 Error returns:
1409 AX = error_path_not_found
1410 The path specified was invalid or not found.
1411 = error_access_denied
1412 The path specified was not empty, not a
1413 directory, the root directory or contained
1414 invalid information.
1415 = error_current_directory
1416 The path specified was the current directory
1417 on a drive.
1418
1419
1420 Name: * Unlink - delete a directory entry
1421
1422 Assembler usage:
1423 LDS DX, name
1424 MOV AH, Unlink
1425 INT 21h
1426
1427 Description:
1428 Unlink removes a directory entry associated with a
1429 filename. If the file is currently open on another
1430 handle, then no removal will take place.
1431
1432 Error returns:
1433 AX = error_file_not_found
1434 The path specified was invalid or not found.
1435 = error_access_denied
1436 The path specified was a directory or
1437 read-only.
1438
1439
1440 Name: * Wait - retrieve the return code of a child
1441
1442 Assembler usage:
1443 MOV AH, Wait
1444 INT 21h
1445 ; AX has the exit code
1446
1447 Description:
1448 Wait will return the Exit code specified by a
1449 child process. It will return this Exit code only
1450 once. The low byte of this code is that sent by the
1451 Exit routine. The high byte is one of the following:
1452
1453 0 - terminate/abort
1454 1 - ^C
1455 2 - Hard error
1456 3 - Terminate and stay resident
1457
1458 Error returns:
1459 None.
1460
1461
1462 Name: * Write - write to a file
1463
1464 Assembler usage:
1465 LDS DX, buf
1466 MOV CX, count
1467 MOV BX, handle
1468 MOV AH, Write
1469 INT 21h
1470 ; AX has number of bytes written
1471
1472 Description:
1473 Write transfers count bytes from a buffer into
1474 a file. It should be regarded as an error if the
1475 number of bytes written is not the same as the number
1476 requested.
1477
1478 It is important to note that the write system
1479 call with a count of zero (CX = 0) will truncate
1480 the file at the current position.
1481
1482 All I/O is done using normalized pointers; no
1483 segment wraparound will occur.
1484
1485 Error Returns:
1486 AX = error_invalid_handle
1487 The handle passed in BX was not currently
1488 open.
1489 = error_access_denied
1490 The handle was not opened in a mode that
1491 allowed writing.
1492
1493
1494The following XENIX convention is followed for the new 2.0
1495system calls:
1496
1497 o If no error occurred, then the carry flag will be
1498 reset and register AX will contain the appropriate
1499 information.
1500
1501 o If an error occurred, then the carry flag will be
1502 set and register AX will contain the error code.
1503
1504The following code sample illustrates the recommended method
1505of detecting these errors:
1506
1507 ...
1508 MOV errno,0
1509 INT 21h
1510 JNC continue
1511 MOV errno,AX
1512continue:
1513 ...
1514
1515The word variable errno will now have the correct error code
1516for that system call.
1517
1518The current equates for the error codes are:
1519
1520no_error_occurred EQU 0
1521
1522error_invalid_function EQU 1
1523error_file_not_found EQU 2
1524error_path_not_found EQU 3
1525error_too_many_open_files EQU 4
1526error_access_denied EQU 5
1527error_invalid_handle EQU 6
1528error_arena_trashed EQU 7
1529error_not_enough_memory EQU 8
1530error_invalid_block EQU 9
1531error_bad_environment EQU 10
1532error_bad_format EQU 11
1533error_invalid_access EQU 12
1534error_invalid_data EQU 13
1535error_invalid_drive EQU 15
1536error_current_directory EQU 16
1537error_not_same_device EQU 17
1538error_no_more_files EQU 18
1539
1540
1541System call assignments:
1542
1543ABORT EQU 0 ; 0 0
1544STD_CON_INPUT EQU 1 ; 1 1
1545STD_CON_OUTPUT EQU 2 ; 2 2
1546STD_AUX_INPUT EQU 3 ; 3 3
1547STD_AUX_OUTPUT EQU 4 ; 4 4
1548STD_PRINTER_OUTPUT EQU 5 ; 5 5
1549RAW_CON_IO EQU 6 ; 6 6
1550RAW_CON_INPUT EQU 7 ; 7 7
1551STD_CON_INPUT_NO_ECHO EQU 8 ; 8 8
1552STD_CON_STRING_OUTPUT EQU 9 ; 9 9
1553STD_CON_STRING_INPUT EQU 10 ; 10 A
1554STD_CON_INPUT_STATUS EQU 11 ; 11 B
1555STD_CON_INPUT_FLUSH EQU 12 ; 12 C
1556DISK_RESET EQU 13 ; 13 D
1557SET_DEFAULT_DRIVE EQU 14 ; 14 E
1558FCB_OPEN EQU 15 ; 15 F
1559FCB_CLOSE EQU 16 ; 16 10
1560DIR_SEARCH_FIRST EQU 17 ; 17 11
1561DIR_SEARCH_NEXT EQU 18 ; 18 12
1562FCB_DELETE EQU 19 ; 19 13
1563FCB_SEQ_READ EQU 20 ; 20 14
1564FCB_SEQ_WRITE EQU 21 ; 21 15
1565FCB_CREATE EQU 22 ; 22 16
1566FCB_RENAME EQU 23 ; 23 17
1567GET_DEFAULT_DRIVE EQU 25 ; 25 19
1568SET_DMA EQU 26 ; 26 1A
1569+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1570| C A V E A T P R O G R A M M E R |
1571| |
1572GET_DEFAULT_DPB EQU 31 ; 31 1F
1573| |
1574| C A V E A T P R O G R A M M E R |
1575+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1576FCB_RANDOM_READ EQU 33 ; 33 21
1577FCB_RANDOM_WRITE EQU 34 ; 34 22
1578GET_FCB_FILE_LENGTH EQU 35 ; 35 23
1579GET_FCB_POSITION EQU 36 ; 36 24
1580SET_INTERRUPT_VECTOR EQU 37 ; 37 25
1581CREATE_PROCESS_DATA_BLOCK EQU 38 ; 38 26
1582FCB_RANDOM_READ_BLOCK EQU 39 ; 39 27
1583FCB_RANDOM_WRITE_BLOCK EQU 40 ; 40 28
1584PARSE_FILE_DESCRIPTOR EQU 41 ; 41 29
1585GET_DATE EQU 42 ; 42 2A
1586SET_DATE EQU 43 ; 43 2B
1587GET_TIME EQU 44 ; 44 2C
1588SET_TIME EQU 45 ; 45 2D
1589SET_VERIFY_ON_WRITE EQU 46 ; 46 2E
1590; Extended functionality group
1591GET_DMA EQU 47 ; 47 2F
1592GET_VERSION EQU 48 ; 48 30
1593KEEP_PROCESS EQU 49 ; 49 31
1594+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1595| C A V E A T P R O G R A M M E R |
1596| |
1597GET_DPB EQU 50 ; 50 32
1598| |
1599| C A V E A T P R O G R A M M E R |
1600+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1601SET_CTRL_C_TRAPPING EQU 51 ; 51 33
1602GET_INDOS_FLAG EQU 52 ; 52 34
1603GET_INTERRUPT_VECTOR EQU 53 ; 53 35
1604GET_DRIVE_FREESPACE EQU 54 ; 54 36
1605CHAR_OPER EQU 55 ; 55 37
1606INTERNATIONAL EQU 56 ; 56 38
1607; XENIX CALLS
1608; Directory Group
1609MKDIR EQU 57 ; 57 39
1610RMDIR EQU 58 ; 58 3A
1611CHDIR EQU 59 ; 59 3B
1612; File Group
1613CREAT EQU 60 ; 60 3C
1614OPEN EQU 61 ; 61 3D
1615CLOSE EQU 62 ; 62 3E
1616READ EQU 63 ; 63 3F
1617WRITE EQU 64 ; 64 40
1618UNLINK EQU 65 ; 65 41
1619LSEEK EQU 66 ; 66 42
1620CHMOD EQU 67 ; 67 43
1621IOCTL EQU 68 ; 68 44
1622XDUP EQU 69 ; 69 45
1623XDUP2 EQU 70 ; 70 46
1624CURRENT_DIR EQU 71 ; 71 47
1625; Memory Group
1626ALLOC EQU 72 ; 72 48
1627DEALLOC EQU 73 ; 73 49
1628SETBLOCK EQU 74 ; 74 4A
1629; Process Group
1630EXEC EQU 75 ; 75 4B
1631EXIT EQU 76 ; 76 4C
1632WAIT EQU 77 ; 77 4D
1633FIND_FIRST EQU 78 ; 78 4E
1634; Special Group
1635FIND_NEXT EQU 79 ; 79 4F
1636; SPECIAL SYSTEM GROUP
1637+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1638| C A V E A T P R O G R A M M E R |
1639| |
1640SET_CURRENT_PDB EQU 80 ; 80 50
1641GET_CURRENT_PDB EQU 81 ; 81 51
1642GET_IN_VARS EQU 82 ; 82 52
1643SETDPB EQU 83 ; 83 53
1644| |
1645| C A V E A T P R O G R A M M E R |
1646+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1647GET_VERIFY_ON_WRITE EQU 84 ; 84 54
1648+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1649| C A V E A T P R O G R A M M E R |
1650| |
1651DUP_PDB EQU 85 ; 85 55
1652| |
1653| C A V E A T P R O G R A M M E R |
1654+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1655RENAME EQU 86 ; 86 56
1656FILE_TIMES EQU 87 ; 87 57
1657
diff --git a/v2.0/source/SYSIMES.ASM b/v2.0/source/SYSIMES.ASM
new file mode 100644
index 0000000..1ff4f0d
--- /dev/null
+++ b/v2.0/source/SYSIMES.ASM
Binary files differ
diff --git a/v2.0/source/SYSINIT.ASM b/v2.0/source/SYSINIT.ASM
new file mode 100644
index 0000000..0c198b1
--- /dev/null
+++ b/v2.0/source/SYSINIT.ASM
@@ -0,0 +1,1424 @@
1TITLE BIOS SYSTEM INITIALIZATION
2
3FALSE EQU 0
4TRUE EQU NOT FALSE
5
6IBMVER EQU FALSE
7IBM EQU IBMVER
8IBMJAPVER EQU FALSE ; If TRUE set KANJI true also
9MSVER EQU TRUE
10ALTVECT EQU FALSE ; Switch to build ALTVECT version
11HIGHMEM EQU FALSE
12KANJI EQU FALSE
13
14 IF IBMVER OR IBMJAPVER
15NOEXEC EQU TRUE
16 ELSE
17NOEXEC EQU FALSE
18 ENDIF
19
20; Set to agree with those in DOST:MSHEAD.ASM, ALTVECT version only
21MAJOR_VERSION EQU 2
22MINOR_VERSION EQU 0B ;2.11
23
24DOSSIZE EQU 5000H
25
26; Internal DOS data returned by DOSINIT
27
28SYSINITVAR STRUC
29DPBHEAD DD ? ; Pointer to head of DPB-FAT list
30sft_addr DD ? ; Pointer to first FCB table
31; The following address points to the CLOCK device
32BCLOCK DD ?
33; The following address is used by DISKSTATCHK it is always
34; points to the console input device header
35BCON DD ? ; Console device entry points
36NUMIO DB 0 ; Number of disk tables
37MAXSEC DW 0 ; Maximum allowed sector size
38BUFFHEAD DD ? ; Head of buffer queue
39DEVHEAD DD ?
40SYSINITVAR ENDS
41
42 INCLUDE DOSSYM.ASM
43 INCLUDE DEVSYM.ASM
44
45 IF NOT IBM
46 IF NOT IBMJAPVER
47 EXTRN RE_INIT:FAR
48 ENDIF
49 ENDIF
50
51SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT'
52
53ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
54
55 EXTRN BADOPM:BYTE,CRLFM:BYTE,BADCOM:BYTE
56 EXTRN BADSIZ_PRE:BYTE,BADLD_PRE:BYTE
57 EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE
58 EXTRN SYSSIZE:BYTE,BADCOUNTRY:BYTE
59
60 PUBLIC CURRENT_DOS_LOCATION
61 PUBLIC FINAL_DOS_LOCATION
62 PUBLIC DEVICE_LIST
63 PUBLIC MEMORY_SIZE
64 PUBLIC DEFAULT_DRIVE
65 PUBLIC BUFFERS
66 PUBLIC FILES
67 PUBLIC SYSINIT
68
69 IF HIGHMEM
70 PUBLIC DPBBUF_SIZ
71 ENDIF
72
73SYSINIT:
74 JMP GOINIT
75
76DOSINFO LABEL DWORD
77 DW 0000
78CURRENT_DOS_LOCATION DW 0000
79
80MSDOS LABEL DWORD
81ENTRY_POINT LABEL DWORD
82 DW 0000
83FINAL_DOS_LOCATION DW 0000
84DEVICE_LIST DD 00000000
85
86 IF HIGHMEM
87DPBBUF_SIZ DW (4472 + 15) / 16
88 ENDIF
89
90MEMORY_SIZE DW 0001
91DEFAULT_DRIVE DB 00
92BUFFERS DB 2
93FILES DB 8
94COMMAND_LINE DB 2,0,"P" ; Default Command.com Args
95 DB 29 DUP (0)
96ZERO DB 0
97
98 IF NOT NOEXEC
99COMEXE EXEC0 <0,COMMAND_LINE,DEFAULT_DRIVE,ZERO>
100 ENDIF
101
102COUNT DW 0000
103CHRPTR DW 0000
104
105BUFPTR LABEL DWORD ; LEAVE THIS STUFF IN ORDER!
106MEMLO DW 0
107PRMBLK LABEL WORD
108MEMHI DW 0
109LDOFF DW 0
110AREA DW 0
111
112PACKET DB 22
113 DB 0
114 DB 0 ; INITIALIZE CODE
115 DW 0
116 DB 8 DUP (?)
117UNITCOUNT DB 0
118BREAK_ADDR DD 0
119BPB_ADDR DD 0
120
121GOINIT:
122 CLD
123 XOR SI,SI
124 MOV DI,SI
125
126 IF MSVER
127 MOV CX,[MEMORY_SIZE]
128 CMP CX,1
129 JNZ NOSCAN
130 MOV CX,2048 ; START SCANNING AT 32K BOUNDARY
131 XOR BX,BX
132
133MEMSCAN:INC CX
134 JZ SETEND
135 MOV DS,CX
136 MOV AL,[BX]
137 NOT AL
138 MOV [BX],AL
139 CMP AL,[BX]
140 NOT AL
141 MOV [BX],AL
142 JZ MEMSCAN
143SETEND:
144 MOV [MEMORY_SIZE],CX
145 ENDIF
146
147 IF IBMVER OR IBMJAPVER
148 MOV CX,[MEMORY_SIZE]
149 ENDIF
150
151NOSCAN:
152 MOV AX,CS
153 MOV DS,AX
154ASSUME DS:SYSINITSEG
155
156 IF HIGHMEM
157 SUB CX,(DOSSIZE / 16) ; Leave room for DOS
158 SUB CX,CS:[DPBBUF_SIZ] ; Allow OEM to tune
159 ENDIF
160
161 MOV AX,OFFSET SYSSIZE + 15
162 SHR AX,1 ; Divide by 16 for paras
163 SHR AX,1
164 SHR AX,1
165 SHR AX,1
166 SUB CX,AX
167 MOV ES,CX
168 MOV CX,OFFSET SYSSIZE + 1
169 SHR CX,1 ; Divide by 2 to get words
170 REP MOVSW ; RELOCATE SYSINIT
171
172 ASSUME ES:SYSINITSEG
173
174 PUSH ES
175 MOV AX,OFFSET SYSIN
176 PUSH AX
177
178AAA PROC FAR
179 RET
180AAA ENDP
181;
182; MOVE THE DOS TO ITS PROPER LOCATION
183;
184SYSIN:
185
186 ASSUME DS:NOTHING,ES:SYSINITSEG,SS:NOTHING
187
188 MOV AX,[CURRENT_DOS_LOCATION]
189 MOV DS,AX
190 MOV AX,[FINAL_DOS_LOCATION]
191 MOV ES,AX
192
193 ASSUME ES:NOTHING
194
195 XOR SI,SI
196 MOV DI,SI
197 MOV CX,DOSSIZE/2
198 REP MOVSW
199
200 LDS SI,[DEVICE_LIST]
201 MOV DX,[MEMORY_SIZE]
202
203 CLI
204 MOV AX,CS
205 MOV SS,AX
206 MOV SP,OFFSET LOCSTACK
207
208 ASSUME SS:SYSINITSEG
209
210 IF NOT ALTVECT
211 STI ; Leave INTs disabled for ALTVECT
212 ENDIF
213LOCSTACK LABEL BYTE
214
215 CALL MSDOS
216 MOV WORD PTR [DOSINFO+2],ES ; SAVE POINTER TO DOS INFO
217 MOV WORD PTR [DOSINFO],DI
218
219 IF NOT IBM
220 IF NOT IBMJAPVER
221 CALL RE_INIT ; Re-call the BIOS
222 ENDIF
223 ENDIF
224
225 STI
226 CLD
227
228 IF HIGHMEM
229 PUSH DS
230 MOV BX,DS
231 ADD BX,10H
232 MOV ES,BX
233 PUSH CS
234 POP DS
235 XOR SI,SI
236 MOV DI,SI
237 MOV CX,OFFSET SYSSIZE + 1
238 SHR CX,1 ; Divide by 2 to get words
239 REP MOVSW
240 POP DS
241 PUSH ES
242 MOV AX,OFFSET SECONDRELOC
243 PUSH AX
244BBB PROC FAR
245 RET
246BBB ENDP
247
248SECONDRELOC:
249 MOV AX,CS
250 CLI
251 MOV SS,AX
252 MOV SP,OFFSET LOCSTACK
253 STI
254 ELSE
255 MOV BX,CS
256 SUB BX,10H
257 MOV ES,BX
258 XOR SI,SI
259 MOV DI,SI
260 MOV CX,80H
261 REP MOVSW
262 MOV AH,SET_CURRENT_PDB
263 INT 21H
264 ENDIF
265
266 PUSH DS
267 PUSH CS
268 POP DS
269 MOV DX,OFFSET INT24 ; SET UP INT 24 HANDLER
270 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H
271 INT 21H
272
273 IF ALTVECT
274 MOV DX,OFFSET BOOTMES
275 CALL PRINT ; Print message DOSINIT couldn't
276 ENDIF
277
278 POP DS
279
280 MOV DL,[DEFAULT_DRIVE]
281 OR DL,DL
282 JZ NODRVSET
283 DEC DL ; A = 0
284 MOV AH,SET_DEFAULT_DRIVE
285 INT 21H ; SELECT THE DISK
286NODRVSET:
287
288 CALL DOCONF ; DO THE CONFIG STUFF
289
290 IF HIGHMEM
291 PUSH DS
292 MOV AX,OFFSET SYSSIZE + 15
293 MOV CL,4
294 SHR AX,CL ; Divide by 16 to get para
295 MOV CX,ES
296 SUB CX,AX
297 MOV ES,CX
298 PUSH CS
299 POP DS
300 XOR SI,SI
301 MOV DI,SI
302 MOV CX,OFFSET SYSSIZE + 1
303 SHR CX,1 ; Divide by 2 to get words
304 REP MOVSW
305 POP DS
306 PUSH ES
307 MOV AX,OFFSET THIRDRELOC
308 PUSH AX
309CCC PROC FAR
310 RET
311CCC ENDP
312
313THIRDRELOC:
314 MOV AX,CS
315 CLI
316 MOV SS,AX
317 MOV SP,OFFSET LOCSTACK
318 STI
319 ENDIF
320
321 IF NOEXEC
322 MOV BP,DS ; SAVE COMMAND.COM SEGMENT
323
324 PUSH DS
325 POP ES
326
327 MOV BX,CS
328 SUB BX,10H
329 MOV DS,BX
330 XOR SI,SI
331 MOV DI,SI
332 MOV CX,80H
333 REP MOVSW
334 MOV BX,ES
335 MOV AH,SET_CURRENT_PDB
336 INT 21H
337
338 MOV ES:[PDB_PARENT_PID],ES ; WE ARE THE ROOT
339 ENDIF
340
341 PUSH CS
342 POP DS
343ASSUME DS:SYSINITSEG
344 MOV AL,[FILES]
345 CBW
346 MOV CX,AX
347 XOR BX,BX ; Close standard input
348 MOV AH,CLOSE
349 INT 21H
350 MOV BX,2
351RCCLLOOP: ; Close everybody but standard output
352 MOV AH,CLOSE
353 INT 21H
354 INC BX
355 LOOP RCCLLOOP
356
357 MOV DX,OFFSET CONDEV
358 MOV AL,2
359 MOV AH,OPEN ; OPEN CON FOR READ/WRITE
360 STC
361 INT 21H
362 JNC GOAUX
363 CALL BADFIL
364 JMP SHORT GOAUX2
365
366GOAUX: PUSH AX
367 MOV BX,1 ; close standard output
368 MOV AH,CLOSE
369 INT 21H
370 POP AX
371
372 MOV BX,AX ; New device handle
373 MOV AH,XDUP
374 INT 21H ; Dup to 1, STDOUT
375 MOV AH,XDUP
376 INT 21H ; Dup to 2, STDERR
377
378GOAUX2: MOV DX,OFFSET AUXDEV
379 MOV AL,2 ; READ/WRITE ACCESS
380 CALL OPEN_DEV
381
382 MOV DX,OFFSET PRNDEV
383 MOV AL,1 ; WRITE ONLY
384 CALL OPEN_DEV
385;
386; SET UP THE PARAMETERS FOR COMMAND
387;
388GOSET:
389 MOV SI,OFFSET COMMAND_LINE+1
390
391 IF NOEXEC
392 MOV DI,81H
393 ELSE
394 PUSH DS
395 POP ES
396 MOV DI,SI
397 ENDIF
398
399 MOV CL,-1
400COMTRANLP: ; FIND LENGTH OF COMMAND LINE
401 INC CL
402 LODSB
403 STOSB ; COPY COMMAND LINE IN
404 OR AL,AL
405 JNZ COMTRANLP
406 DEC DI
407 MOV AL,0DH
408 STOSB
409
410 IF NOEXEC
411 MOV ES:[80H],CL
412 MOV AL,[DEFAULT_DRIVE]
413 MOV ES:[5CH],AL
414 ELSE
415 MOV [COMMAND_LINE],CL ; Count
416 ENDIF
417
418 PUSH CS
419 POP ES
420
421 ASSUME ES:SYSINITSEG
422
423 MOV DX,OFFSET COMMND ; NOW POINTING TO FILE DESCRIPTION
424
425 IF NOEXEC
426 MOV ES,BP ; SET LOAD ADDRESS
427 MOV BX,100H
428 CALL LDFIL ; READ IN COMMAND
429 JC COMERR
430 MOV DS,BP
431 CLI
432 MOV DX,80H
433 MOV SS,BP
434 MOV SP,DX
435 STI
436
437 XOR AX,AX ; PUSH A WORD OF ZEROS
438 PUSH AX
439 MOV AH,SET_DMA ; SET DISK TRANFER ADDRESS
440 INT 21H
441 PUSH BP ; SET HIGH PART OF JUMP ADDRESS
442 MOV AX,100H
443 PUSH AX ; SET LOW PART OF JUMP ADDRESS
444CCC PROC FAR
445 RET ; CRANK UP COMMAND!
446CCC ENDP
447
448 ELSE
449 MOV BX,OFFSET COMEXE
450 MOV WORD PTR [BX.EXEC0_COM_LINE+2],CS
451 MOV WORD PTR [BX.EXEC0_5C_FCB+2],CS
452 MOV WORD PTR [BX.EXEC0_6C_FCB+2],CS
453
454 XOR AX,AX
455 MOV AH,EXEC
456 STC ; IN CASE OF INT 24
457 INT 21H ; GO START UP COMMAND
458 ENDIF
459
460COMERR:
461 MOV DX,OFFSET BADCOM ; WANT TO PRINT COMMAND ERROR
462 CALL BADFIL
463STALL: JMP STALL
464
465DOCONF:
466 PUSH CS
467 POP DS
468
469 ASSUME DS:SYSINITSEG
470
471 MOV BX,0FFFFH
472 MOV AH,ALLOC
473 INT 21H ; FIRST TIME FAILS
474 MOV AH,ALLOC
475 INT 21H ; SECOND TIME GETS IT
476 MOV [AREA],AX
477
478 IF HIGHMEM
479 ADD AX,BX
480 ENDIF
481
482 MOV [MEMHI],AX
483
484 MOV AX,(CHAR_OPER SHL 8) ; GET SWITCH CHARACTER
485 INT 21H
486 MOV [COMMAND_LINE+1],DL
487
488 MOV DX,OFFSET CONFIG ; NOW POINTING TO FILE DESCRIPTION
489 MOV AX,OPEN SHL 8 ; OPEN FILE "CONFIG.SYS"
490 STC ; IN CASE OF INT 24
491 INT 21H ; FUNCTION REQUEST
492 JC ENDFILE
493 JMP NOPROB ; PROBLEM WITH OPEN
494
495ENDFILE:
496 PUSH CS
497 POP DS
498 CALL ROUND
499 MOV AL,[FILES]
500 SUB AL,5
501 JBE DOBUFF
502 CBW
503
504 IF HIGHMEM
505 PUSH AX
506 MOV BL,SIZE SF_ENTRY
507 MUL BL
508 ADD AX,15+6
509 MOV CL,4
510 SHR AX,CL
511 SUB [MEMHI],AX
512 POP AX
513 ENDIF
514
515 MOV BX,[MEMLO]
516 MOV DX,[MEMHI]
517 LDS DI,[DOSINFO] ; GET POINTER TO DOS DATA
518 LDS DI,[DI+SFT_ADDR] ; DS:BP POINTS TO SFT
519 MOV WORD PTR [DI+SFT_LINK],BX
520 MOV WORD PTR [DI+SFT_LINK+2],DX ; SET POINTER TO NEW SFT
521 PUSH CS
522 POP DS
523 LES DI,DWORD PTR [MEMLO] ; POINT TO NEW SFT
524 MOV WORD PTR ES:[DI+SFT_LINK],-1
525 MOV ES:[DI+SFT_COUNT],AX
526 MOV BL,SIZE SF_ENTRY
527 MUL BL ; AX = NUMBER OF BYTES TO CLEAR
528 MOV CX,AX
529
530 IF HIGHMEM
531 MOV AX,6
532 ELSE
533 ADD [MEMLO],AX ; ALLOCATE MEMORY
534 MOV AX,6
535 ADD [MEMLO],AX ; REMEMBER THE HEADER TOO
536 ENDIF
537
538 ADD DI,AX
539 XOR AX,AX
540 REP STOSB ; CLEAN OUT THE STUFF
541
542DOBUFF: CALL ROUND
543
544 DEC [BUFFERS]
545 JZ BUF1
546
547 PUSH DS
548 LES DI,BUFPTR
549 LDS BX,DOSINFO
550
551 IF HIGHMEM
552 MOV AX,[BX.MAXSEC]
553 ADD AX,BUFINSIZ + 15
554 MOV CL,4
555 SHR AX,CL
556 SUB CS:[MEMHI],AX
557 MOV ES,CS:[MEMHI]
558 ENDIF
559
560 MOV AX,WORD PTR [BX.BUFFHEAD]
561 MOV WORD PTR ES:[DI.NEXTBUF],AX
562 MOV AX,WORD PTR [BX.BUFFHEAD+2]
563 MOV WORD PTR ES:[DI.NEXTBUF+2],AX
564
565 MOV WORD PTR [BX.BUFFHEAD],DI
566 MOV WORD PTR [BX.BUFFHEAD+2],ES
567
568 MOV WORD PTR ES:[DI.BUFDRV],00FFH ; NEW BUFFER FREE
569 MOV BX,[BX.MAXSEC]
570 POP DS
571
572 IF NOT HIGHMEM
573 ADD BX,BUFINSIZ
574 ADD [MEMLO],BX
575 ENDIF
576
577 JMP DOBUFF
578
579BUF1: CALL ROUND
580 MOV BX,[MEMHI]
581 MOV AX,[AREA]
582 MOV ES,AX ; CALC WHAT WE NEEDED
583 SUB BX,AX
584
585 IF HIGHMEM
586 DEC BX ; Arena
587 PUSH BX
588 ENDIF
589
590 MOV AH,SETBLOCK
591 INT 21H ; GIVE THE REST BACK
592
593 IF NOT HIGHMEM
594 PUSH ES
595 MOV AX,ES
596 DEC AX
597 MOV ES,AX
598 MOV ES:[arena_owner],8 ; Set impossible owner
599 POP ES
600 ENDIF
601
602 IF HIGHMEM
603 MOV BX,0FFFFH
604 MOV AH,ALLOC
605 INT 21H
606 MOV AH,ALLOC
607 INT 21H
608
609 PUSH ES
610 DEC AX
611 MOV ES,AX
612 MOV ES:[arena_owner],8 ; Set impossible owner
613 POP ES
614
615 IF NOT NOEXEC
616 MOV ES,[AREA]
617 MOV AH,DEALLOC
618 INT 21H
619 ENDIF
620
621 POP BX
622 MOV AX,[AREA]
623 MOV DS,AX
624 ADD AX,BX
625 MOV ES,AX
626 ELSE
627 IF NOEXEC
628 MOV BX,0FFFFH ; ALLOCATE THE REST OF MEM FOR COMMAND
629 MOV AH,ALLOC
630 INT 21H
631 MOV AH,ALLOC
632 INT 21H
633 MOV DS,AX
634 ENDIF
635 ENDIF
636
637 RET
638
639BADOP: MOV DX,OFFSET BADOPM ; WANT TO PRINT COMMAND ERROR
640 CALL PRINT
641 JMP COFF
642
643NOPROB: ; GET FILE SIZE (NOTE < 64K!!)
644 MOV BX,AX
645 XOR CX,CX
646 XOR DX,DX
647 MOV AX,(LSEEK SHL 8) OR 2
648 INT 21H
649 MOV [COUNT],AX
650 XOR DX,DX
651 MOV AX,LSEEK SHL 8 ; Reset pointer to beginning of file
652 INT 21H
653 MOV DX,CS
654
655 IF HIGHMEM
656 MOV AX,OFFSET SYSSIZE + 15
657 MOV CL,4
658 SHR AX,CL
659 ADD DX,AX
660 ELSE
661 MOV AX,[COUNT]
662 ADD AX,15
663 MOV CL,4
664 SHR AX,CL ; NUMBER OF SEGMENTS
665 SUB DX,AX
666 SUB DX,11H ; ROOM FOR HEADER
667 ENDIF
668
669 MOV DS,DX
670 MOV ES,DX
671ASSUME DS:NOTHING,ES:NOTHING
672 XOR DX,DX
673 MOV CX,[COUNT]
674 MOV AH,READ
675 STC ; IN CASE OF INT 24
676 INT 21H ; Function request
677 PUSHF
678 PUSH CS
679 POP DS
680ASSUME DS:SYSINITSEG
681 PUSH AX
682 MOV AH,CLOSE
683 INT 21H
684 POP AX
685 POPF
686 JC CONFERR ; IF NOT WE'VE GOT A PROBLEM
687 CMP CX,AX
688 JZ GETCOM ; COULDN'T READ THE FILE
689CONFERR:
690 MOV DX,OFFSET CONFIG ; WANT TO PRINT CONFIG ERROR
691 CALL BADFIL
692ENDFILV:JMP ENDFILE
693
694GETCOM:
695 CALL ORGANIZE ; ORGANIZE THE FILE
696 CALL GETCHR
697
698CONFLP: JC ENDFILV
699 MOV AH,AL
700 CALL GETCHR
701
702 CMP AH,'B' ; BUFFER COMMAND?
703 JNZ TRYC
704 CALL GETNUM
705 JZ COFF
706 CMP AX,100
707 JAE badop
708 MOV [BUFFERS],AL
709 JMP SHORT COFF
710
711TRYC: CMP AH,'C'
712 JZ GOTC
713 JMP TRYD
714GOTC:
715 CMP AL,'O' ; FIRST LETTER OF "ON"
716 JNZ COFF
717 CALL GETCHR
718 JC ENDFILV
719 CMP AL,'N' ; SECOND LETTER OF "ON"
720 JNZ COFF
721 MOV AH,SET_CTRL_C_TRAPPING ; TURN ON CONTROL-C CHECK
722 MOV AL,1
723 MOV DL,AL
724 INT 21H
725
726COFF: PUSH CS
727 POP DS
728 CALL NEWLINE
729 JMP CONFLP
730
731TRYD: CMP AH,'D'
732 JZ GOTD
733 JMP TRYF
734GOTD: MOV BX,CS
735 MOV DS,BX
736
737 MOV WORD PTR [BPB_ADDR],SI
738 MOV WORD PTR [BPB_ADDR+2],ES
739
740 CALL ROUND
741
742 IF HIGHMEM
743 PUSH DS
744 PUSH ES
745 POP DS
746 MOV DX,SI
747 MOV AX,OPEN SHL 8
748 STC ; In case INT 24H
749 INT 21H
750 POP DS
751 JC BADBRK
752 MOV BX,AX
753 XOR DX,DX
754 MOV CX,DX
755 MOV AX,(LSEEK SHL 8) OR 2
756 INT 21H
757 PUSH AX
758 MOV AH,CLOSE
759 INT 21H
760 POP AX ; DX:AX is size of file
761 ADD AX,15
762 ADC DX,0
763 MOV CL,4
764 SHR AX,CL
765 MOV CL,12
766 SHL DX,CL
767 OR AX,DX ; AX is size in PARA
768 MOV CX,[MEMHI]
769 SUB [MEMHI],AX
770 JNC SIZEOK
771 MOV [MEMHI],CX ; Not enough memory
772 JMP SHORT BADBRK
773SIZEOK:
774 MOV BX,CS
775 ENDIF
776
777 XOR AX,AX
778 MOV WORD PTR [ENTRY_POINT],AX
779 MOV AX,[MEMHI]
780 MOV WORD PTR [ENTRY_POINT+2],AX ; SET ENTRY POINT
781
782
783 IF NOT NOEXEC
784 MOV [LDOFF],AX ; SET LOAD OFFSET
785 ENDIF
786
787 PUSH ES
788 POP DS
789 MOV DX,SI ; DS:DX POINTS TO FILE NAME
790
791 IF NOEXEC
792 LES BX,DWORD PTR CS:[MEMLO]
793 CALL LDFIL ; LOAD IN THE DEVICE DRIVER
794 ELSE
795 MOV ES,BX
796 MOV BX,OFFSET PRMBLK ; ES:BX POINTS TO PARAMETERS
797 MOV AL,3
798 MOV AH,EXEC
799 STC ; IN CASE OF INT 24
800 INT 21H ; LOAD IN THE DEVICE DRIVER
801 ENDIF
802
803 PUSH DS
804 POP ES ; ES:SI BACK TO CONFIG.SYS
805 PUSH CS
806 POP DS ; DS BACK TO SYSINIT
807 JNC GOODLD
808BADBRK: CALL BADLOAD
809 JMP COFF
810
811GOODLD: PUSH ES ; INITIALIZE THE DEVICE
812 PUSH SI
813
814 PUSH CS
815 POP ES
816 MOV BX,SDEVSTRAT
817 CALL CALLDEV
818 MOV BX,SDEVINT
819 CALL CALLDEV
820
821 PUSH CS
822 POP DS
823
824 IF NOT HIGHMEM
825 MOV AX,WORD PTR [BREAK_ADDR+2] ; REMOVE THE INIT CODE
826 CMP AX,[MEMORY_SIZE]
827 JB BREAKOK
828 POP SI
829 POP ES
830 JMP BADBRK
831BREAKOK:
832
833 MOV [MEMHI],AX
834 MOV AX,WORD PTR [BREAK_ADDR]; REMOVE THE INIT CODE
835 MOV [MEMLO],AX
836 ENDIF
837
838 LDS DX,[ENTRY_POINT] ; SET DS:DX TO HEADER
839 MOV SI,DX
840 ADD SI,SDEVATT ; DS:SI POINTS TO ATTRIBUTES
841 LES DI,CS:[DOSINFO] ; ES:DI POINT TO DOS INFO
842 MOV AX,DS:[SI] ; GET ATTRIBUTES
843 TEST AX,DEVTYP ; TEST IF BLOCK DEV
844 JZ ISBLOCK
845
846 TEST AX,ISCIN ; IS IT A CONSOLE IN?
847 JZ TRYCLK
848 MOV WORD PTR ES:[DI.BCON],DX
849 MOV WORD PTR ES:[DI.BCON+2],DS
850
851TRYCLK: TEST AX,ISCLOCK ; IS IT A CLOCK DEVICE?
852 JZ GOLINK
853 MOV WORD PTR ES:[DI+BCLOCK],DX
854 MOV WORD PTR ES:[DI+BCLOCK+2],DS
855GOLINK: JMP LINKIT
856
857ISBLOCK:
858 MOV AL,CS:[UNITCOUNT] ; IF NO UNITS FOUND....
859 OR AL,AL
860 JNZ PERDRV
861
862 IF NOT HIGHMEM
863 MOV CS:[MEMLO],0 ; ...ERASE THE DEVICE
864 ENDIF
865
866 MOV AX,-1
867 JMP ENDDEV
868
869PERDRV:
870 CBW
871 MOV CX,AX
872 MOV DH,AH
873 MOV DL,ES:[DI.NUMIO] ; GET NUMBER OF DEVICES
874 ADD ES:[DI.NUMIO],AL ; UPDATE THE AMOUNT
875
876 LDS BX,CS:[BPB_ADDR] ; POINT TO BPB ARRAY
877PERUNIT:
878 LES BP,CS:[DOSINFO]
879 LES BP,DWORD PTR ES:[BP.DPBHEAD]; GET FIRST DPB
880
881SCANDPB:CMP WORD PTR ES:[BP.DPB_NEXT_DPB],-1
882 JZ FOUNDPB
883 LES BP,ES:[BP.DPB_NEXT_DPB]
884 JMP SCANDPB
885FOUNDPB:
886 MOV AX,CS:[MEMLO]
887 MOV WORD PTR ES:[BP.DPB_NEXT_DPB],AX
888
889 IF HIGHMEM
890 MOV AX,(DPBSIZ + 15) / 16
891 SUB CS:[MEMHI],AX
892 ENDIF
893
894 MOV AX,CS:[MEMHI]
895 MOV WORD PTR ES:[BP.DPB_NEXT_DPB+2],AX
896 LES BP,DWORD PTR CS:[MEMLO]
897
898 IF NOT HIGHMEM
899 ADD WORD PTR CS:[MEMLO],DPBSIZ
900 ENDIF
901
902 MOV WORD PTR ES:[BP.DPB_NEXT_DPB],-1
903 MOV ES:[BP.DPB_FIRST_ACCESS],-1
904
905 MOV SI,[BX] ; DS:SI POINTS TO BPB
906 INC BX
907 INC BX ; POINT TO NEXT GUY
908 MOV WORD PTR ES:[BP.DPB_DRIVE],DX
909 MOV AH,SETDPB ; HIDDEN SYSTEM CALL
910 INT 21H
911 MOV AX,ES:[BP.DPB_SECTOR_SIZE]
912 PUSH ES
913 LES DI,CS:[DOSINFO] ; ES:DI POINT TO DOS INFO
914 CMP AX,ES:[DI.MAXSEC]
915 POP ES
916 JBE NOTMAX
917 POP SI
918 POP ES
919 MOV DX,OFFSET BADSIZ_PRE
920 MOV BX,OFFSET BADSIZ_POST
921 CALL PRNERR
922 JMP COFF
923
924NOTMAX: PUSH DS
925 PUSH DX
926 LDS DX,CS:[ENTRY_POINT]
927 MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR],DX
928 MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR+2],DS
929 POP DX
930 POP DS
931 INC DX
932 INC DH
933 LOOP PERUNIT
934
935LINKIT:
936 LES DI,CS:[DOSINFO] ; ES:DI = DOS TABLE
937 MOV CX,WORD PTR ES:[DI.DEVHEAD] ; DX:CX = HEAD OF LIST
938 MOV DX,WORD PTR ES:[DI.DEVHEAD+2]
939
940 LDS SI,CS:[ENTRY_POINT] ; DS:SI = DEVICE LOCATION
941 MOV WORD PTR ES:[DI.DEVHEAD],SI ; SET HEAD OF LIST IN DOS
942 MOV WORD PTR ES:[DI.DEVHEAD+2],DS
943 MOV AX,DS:[SI] ; GET POINTER TO NEXT DEVICE
944 MOV WORD PTR CS:[ENTRY_POINT],AX; AND SAVE IT
945
946 MOV WORD PTR DS:[SI],CX ; LINK IN THE DRIVER
947 MOV WORD PTR DS:[SI+2],DX
948ENDDEV:
949 POP SI
950 POP ES
951 INC AX ; AX = FFFF?
952 JZ COFFV
953 JMP GOODLD ; OTHERWISE PRETEND WE LOADED IT IN
954COFFV: JMP COFF
955
956TRYQ:
957 CMP AH,'Q'
958 JNZ TRYW
959 CALL GETNUM
960 JZ COFFV
961 OR AH,AH
962 JNZ COFFV
963 MOV AH,INTERNATIONAL ; AL is country code
964 MOV DX,-1 ; Set country
965 INT 21H
966 JNC COFFV
967 MOV DX,OFFSET BADCOUNTRY
968 CALL PRINT
969 JMP COFFV
970
971TRYF:
972 CMP AH,'F'
973 JNZ TRYQ
974 CALL GETNUM
975 JZ COFFV
976 CMP AX,100
977 JAE TryX
978 MOV [FILES],AL
979 JMP COFFV
980TRYW:
981 CMP AH,'W'
982 JNZ TRYA
983 MOV DL,AL
984 MOV AX,(CHAR_OPER SHL 8) OR 1 ; SET SWITCH CHARACTER
985 MOV [COMMAND_LINE+1],DL
986 INT 21H
987 JMP COFF
988
989TRYA:
990 CMP AH,'A'
991 JNZ TRYS
992 CMP AL,'F' ; FIRST LETTER OF "FALSE"
993 JNZ COFFJ
994 MOV AX,(CHAR_OPER SHL 8) OR 3 ; TURN ON "/DEV" PREFIX
995 XOR DL,DL
996 INT 21H
997COFFJ: JMP COFF
998
999TRYS:
1000 CMP AH,'S'
1001 JNZ TRYX
1002 MOV [COMMAND_LINE+1],0
1003 MOV DI,OFFSET COMMND + 1
1004 MOV [DI-1],AL
1005STORESHELL:
1006 CALL GETCHR
1007 OR AL,AL
1008 JZ GETSHPARMS
1009 CMP AL," "
1010 JB ENDSH
1011 MOV [DI],AL
1012 INC DI
1013 JMP STORESHELL
1014
1015ENDSH:
1016 MOV BYTE PTR [DI],0
1017 CALL GETCHR
1018 CMP AL,10
1019 JNZ CONV
1020 CALL GETCHR
1021CONV: JMP CONFLP
1022
1023TRYX:
1024 JMP BADOP
1025
1026GETSHPARMS:
1027 MOV BYTE PTR [DI],0
1028 MOV DI,OFFSET COMMAND_LINE+1
1029PARMLOOP:
1030 CALL GETCHR
1031 CMP AL," "
1032 JB ENDSH
1033 MOV [DI],AL
1034 INC DI
1035 JMP PARMLOOP
1036
1037GETCHR: MOV CX,COUNT
1038 JCXZ NOCHAR
1039 MOV SI,CHRPTR
1040 MOV AL,ES:[SI]
1041 DEC COUNT
1042 INC CHRPTR
1043 CLC
1044 RET
1045NOCHAR: STC
1046 RET
1047
1048ORGANIZE:
1049 MOV CX,[COUNT]
1050 JCXZ NOCHAR
1051 CALL MAPCASE
1052 XOR SI,SI
1053 MOV DI,SI
1054
1055ORG1: CALL GET ; SKIP LEADING CONTROL CHARACTERS
1056 CMP AL,' '
1057 JB ORG1
1058
1059 PUSH CX
1060 PUSH SI
1061 PUSH DI
1062 MOV BP,SI
1063 DEC BP
1064 MOV SI,OFFSET COMTAB ; Prepare to search command table
1065 MOV CH,0
1066FINDCOM:
1067 MOV DI,BP
1068 MOV CL,[SI]
1069 INC SI
1070 JCXZ NOCOM
1071 REPE CMPSB
1072 LAHF
1073 ADD SI,CX ; Bump to next position without affecting flags
1074 SAHF
1075 LODSB ; Get indicator letter
1076 JNZ FINDCOM
1077 POP DI
1078 POP SI
1079 POP CX
1080 JMP SHORT GOTCOM
1081
1082NOCOM:
1083 POP DI
1084 POP SI
1085 POP CX
1086 MOV AL,'Z'
1087GOTCOM: STOSB ; SAVE INDICATOR CHAR IN BUFFER
1088
1089ORG2: CALL GET2 ; SKIP NAME UNTIL DELIMETER
1090 CALL DELIM ;
1091 JNZ ORG2
1092
1093 CALL GET ; GET CHARS TO RIGHT OF EQUALS SIGN
1094 STOSB
1095
1096ORG4: CALL GET2
1097 STOSB
1098 CMP AL,' '
1099 JA ORG4
1100 CMP AL,10
1101 JZ ORG1
1102
1103 MOV BYTE PTR ES:[DI-1],0
1104ORG5: CALL GET2
1105 STOSB
1106 CMP AL,10
1107 JNZ ORG5
1108 JMP ORG1
1109
1110GET2:
1111 JCXZ NOGET
1112 MOV AL,ES:[SI]
1113 INC SI
1114 DEC CX
1115 RET
1116
1117GET: JCXZ NOGET
1118 MOV AL,ES:[SI]
1119 INC SI
1120 DEC CX
1121 CALL DELIM
1122 JZ GET
1123GRET: RET
1124
1125
1126DELIM: CMP AL,' '
1127 JZ GRET
1128 CMP AL,9
1129 JZ GRET
1130 CMP AL,'='
1131 JZ GRET
1132 CMP AL,','
1133 JZ GRET
1134 CMP AL,';'
1135 RET
1136
1137
1138NOGET: POP CX
1139 MOV COUNT,DI
1140 XOR SI,SI
1141 MOV CHRPTR,SI
1142 RET
1143;
1144; NEWLINE RETURNS WITH FIRST CHARACTER OF NEXT LINE
1145;
1146NEWLINE:CALL GETCHR ; SKIP NON-CONTROL CHARACTERS
1147 JC NONEW
1148 CMP AL,10 ; LOOK FOR LINE FEED
1149 JNZ NEWLINE
1150 CALL GETCHR
1151NONEW: RET
1152
1153MAPCASE:
1154 PUSH CX
1155 PUSH SI
1156 PUSH DS
1157 PUSH ES
1158 POP DS
1159 XOR SI,SI
1160CONVLOOP:
1161 LODSB
1162
1163 IF KANJI
1164 CALL TESTKANJ
1165 JZ NORMCONV
1166 INC SI ; Skip next char
1167 DEC CX
1168 JCXZ CONVDONE ; Just ignore 1/2 kanji error
1169; Fall through, know AL is not in 'a'-'z' range
1170NORMCONV:
1171 ENDIF
1172
1173 CMP AL,'a'
1174 JB NOCONV
1175 CMP AL,'z'
1176 JA NOCONV
1177 SUB AL,20H
1178 MOV [SI-1],AL
1179NOCONV:
1180 LOOP CONVLOOP
1181CONVDONE:
1182 POP DS
1183 POP SI
1184 POP CX
1185 RET
1186
1187 IF KANJI
1188TESTKANJ:
1189 CMP AL,81H
1190 JB NOTLEAD
1191 CMP AL,9FH
1192 JBE ISLEAD
1193 CMP AL,0E0H
1194 JB NOTLEAD
1195 CMP AL,0FCH
1196 JBE ISLEAD
1197NOTLEAD:
1198 PUSH AX
1199 XOR AX,AX ; Set zero
1200 POP AX
1201 RET
1202
1203ISLEAD:
1204 PUSH AX
1205 XOR AX,AX ; Set zero
1206 INC AX ; Reset zero
1207 POP AX
1208 RET
1209 ENDIF
1210
1211ASSUME DS:NOTHING
1212
1213ROUND: MOV AX,[MEMLO]
1214
1215 IF NOT HIGHMEM
1216 ADD AX,15
1217 ENDIF
1218
1219 SHR AX,1
1220 SHR AX,1
1221 SHR AX,1
1222 SHR AX,1
1223 ADD [MEMHI],AX
1224 XOR AX,AX
1225 MOV [MEMLO],AX
1226 RET
1227
1228CALLDEV:MOV DS,WORD PTR CS:[ENTRY_POINT+2]
1229 ADD BX,WORD PTR CS:[ENTRY_POINT]; Do a little relocation
1230 MOV AX,DS:[BX]
1231 PUSH WORD PTR CS:[ENTRY_POINT]
1232 MOV WORD PTR CS:[ENTRY_POINT],AX
1233 MOV BX,OFFSET PACKET
1234 CALL [ENTRY_POINT]
1235 POP WORD PTR CS:[ENTRY_POINT]
1236 RET
1237
1238BADNUM: POP AX ; POP RETURN ADDRESS
1239 JMP BADOP
1240
1241ToDigit:
1242 SUB AL,'0'
1243 JB NotDig
1244 CMP AL,9
1245 JA NotDig
1246 CLC
1247 RET
1248NotDig: STC
1249 RET
1250
1251GETNUM: XOR BX,BX ; running count is zero
1252B2: CALL ToDigit ; do we have a digit
1253 JC BadNum ; no, bomb
1254 XCHG AX,BX ; put total in AX
1255 PUSH BX ; save digit
1256 MOV BX,10 ; base of arithmetic
1257 MUL BX ; shift by one decimal digit
1258 POP BX ; get back digit
1259 ADD AL,BL ; get total
1260 ADC AH,0 ; make that 16 bits
1261 JC BADNUM ; too big a number
1262 XCHG AX,BX ; stash total
1263 CALL GETCHR ; GET NEXT DIGIT
1264 JC B1 ; no more characters
1265 OR AL,AL ; end of line separator?
1266 JNZ B2 ; no, try as a valid character
1267 INC COUNT ; one more character to scan
1268 DEC CHRPTR ; back up over separator
1269B1: MOV AX,BX ; get proper count
1270 OR AX,AX
1271 RET
1272;
1273; ES:SI POINTS TO FILE NAME (NUL TERMINATED)
1274; DS:DX POINTS TO STRING TO OUTPUT IN FRONT OF NAME ($ TERM)
1275;
1276BADFIL:
1277 PUSH CS
1278 POP ES
1279 MOV SI,DX
1280BADLOAD:
1281 MOV DX,OFFSET BADLD_PRE ; WANT TO PRINT CONFIG ERROR
1282 MOV BX,OFFSET BADLD_POST
1283PRNERR:
1284 PUSH CS
1285 POP DS
1286 MOV AH,STD_CON_STRING_OUTPUT
1287 INT 21H
1288PRN1: MOV DL,ES:[SI]
1289 OR DL,DL
1290 JZ PRN2
1291 MOV AH,STD_CON_OUTPUT
1292 INT 21H
1293 INC SI
1294 JMP PRN1
1295PRN2: MOV DX,BX
1296PRINT: MOV AH,STD_CON_STRING_OUTPUT
1297 INT 21H
1298 RET
1299;
1300; LOAD FILE CALLED [DS:DX] AT MEMORY LOCATION ES:BX
1301;
1302LDFIL:
1303 PUSH AX
1304 PUSH BX
1305 PUSH CX
1306 PUSH DX
1307 PUSH SI
1308 PUSH DS
1309 PUSH BX
1310
1311 XOR AX,AX ; OPEN THE FILE
1312 MOV AH,OPEN
1313 STC ; IN CASE OF INT 24
1314 INT 21H
1315 POP DX ; Trans addr is DS:DX
1316 JC LDRET
1317
1318 PUSH ES ; READ THE FILE IN
1319 POP DS
1320 MOV BX,AX ; Handle in BX
1321 MOV CX,0FF00H
1322 MOV AH,READ
1323 STC ; IN CASE OF INT 24
1324 INT 21H
1325 JC LDRET
1326 MOV SI,DX ; CHECK FOR EXE FILE
1327 CMP WORD PTR [SI],"ZM"
1328 JNZ LDCLS
1329LDERR: STC
1330 JMP SHORT LDRET
1331
1332LDCLS: MOV AH,CLOSE ; CLOSE THE FILE
1333 STC
1334 INT 21H
1335
1336LDRET: POP DS
1337 POP SI
1338 POP DX
1339 POP CX
1340 POP BX
1341 POP AX
1342 RET
1343;
1344; OPEN DEVICE POINTED TO BY DX, AL HAS ACCESS CODE
1345; IF UNABLE TO OPEN DO A DEVICE OPEN NULL DEVICE INSTEAD
1346;
1347OPEN_DEV:
1348 CALL OPEN_FILE
1349 JNC OPEN_DEV3
1350OPEN_DEV1:
1351 MOV DX,OFFSET NULDEV
1352 CALL OPEN_FILE
1353OPEN_DEV2:
1354 RET
1355OPEN_DEV3:
1356 XOR AX,AX ; GET DEVICE INFO
1357 MOV AH,IOCTL
1358 INT 21H
1359 TEST DL,10000000B
1360 JNZ OPEN_DEV2
1361 MOV AH,CLOSE
1362 INT 21H
1363 JMP OPEN_DEV1
1364
1365OPEN_FILE:
1366 MOV AH,OPEN
1367 STC
1368 INT 21H
1369 RET
1370
1371INT24: ADD SP,6 ; RESTORE MACHINE STATE
1372 POP AX
1373 POP BX
1374 POP CX
1375 POP DX
1376 POP SI
1377 POP DI
1378 POP BP
1379 POP DS
1380 POP ES
1381 PUSH AX
1382 MOV AH,GET_DEFAULT_DRIVE ; INITIALIZE DOS
1383 INT 21H
1384 POP AX
1385 IRET ; BACK TO USER
1386
1387 IF ALTVECT
1388BOOTMES DB 13
1389TEN: DB 10
1390 DB "MS-DOS version "
1391 DB MAJOR_VERSION + "0"
1392 DB "."
1393 DB (MINOR_VERSION / 10) + "0"
1394 DB (MINOR_VERSION MOD 10) + "0"
1395 DB 13,10
1396 DB "Copyright 1981,82 Microsoft Corp.",13,10,"$"
1397 ENDIF
1398
1399NULDEV DB "\DEV\NUL",0
1400CONDEV DB "\DEV\CON",0
1401AUXDEV DB "\DEV\AUX",0
1402PRNDEV DB "\DEV\PRN",0
1403
1404CONFIG DB "\CONFIG.SYS",0
1405
1406COMMND DB "\COMMAND.COM",0
1407
1408COMTAB LABEL BYTE
1409 DB 7,"BUFFERS",'B'
1410 DB 5,"BREAK",'C'
1411 DB 5,"SHELL",'S'
1412 DB 6,"DEVICE",'D'
1413 DB 5,"FILES",'F'
1414 DB 8,"SWITCHAR",'W'
1415 DB 8,"AVAILDEV",'A'
1416 DB 7,"COUNTRY",'Q'
1417 DB 0
1418
1419
1420SYSINITSEG ENDS
1421 END
1422
1423
1424 \ No newline at end of file
diff --git a/v2.0/source/SYSINIT.txt b/v2.0/source/SYSINIT.txt
new file mode 100644
index 0000000..fa20d08
--- /dev/null
+++ b/v2.0/source/SYSINIT.txt
Binary files differ
diff --git a/v2.0/source/SYSMES.ASM b/v2.0/source/SYSMES.ASM
new file mode 100644
index 0000000..c7dea6d
--- /dev/null
+++ b/v2.0/source/SYSMES.ASM
@@ -0,0 +1,51 @@
1 TITLE Message file for MS-DOS SYS Program
2
3FALSE EQU 0
4TRUE EQU NOT FALSE
5
6 INCLUDE DOSSYM.ASM
7
8Message MACRO label,text
9 PUBLIC label,label&Len
10label DB text
11label&Len DW $-label
12ENDM
13
14
15IBMJAPVER EQU FALSE
16
17CONST SEGMENT PUBLIC BYTE
18
19; only this message must be terminated with a $
20 PUBLIC BadVer
21BADVER DB "Incorrect DOS version",13,10,"$"
22
23 IF IBMJAPVER
24 Message BadDisk,<"Destination disk cannot be booted">
25 ENDIF
26
27 Message BadDrv,<"Invalid drive specification">
28 Message BadParm,<"Invalid parameter">
29 Message NoDest,<"No room for system on destination disk">
30 Message BadSiz,<"Incompatible system size">
31 Message Done,<"System transferred">
32
33 PUBLIC GetSys,SysDrv,GetSysLen
34GETSYS DB "Insert system disk in drive "
35SYSDRV DB "A",13,10
36 DB "and strike any key when ready",13,10
37GetSysLen DW GetSysLen-GetSys
38
39CONST ENDS
40
41DATA SEGMENT BYTE PUBLIC
42DATA ENDS
43
44CODE SEGMENT
45DG GROUP CODE,CONST,DATA
46 ASSUME CS:DG,DS:DG,ES:DG,SS:DG
47
48CODE ENDS
49 END
50
51 \ No newline at end of file
diff --git a/v2.0/source/TCODE.ASM b/v2.0/source/TCODE.ASM
new file mode 100644
index 0000000..dfe6ca5
--- /dev/null
+++ b/v2.0/source/TCODE.ASM
@@ -0,0 +1,1088 @@
1TITLE PART1 - COMMAND Transient routines.
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15
16DATARES SEGMENT PUBLIC
17 EXTRN BATCH:WORD,BATLOC:DWORD,PARMBUF:BYTE
18 EXTRN RESTDIR:BYTE,EXTCOM:BYTE,ECHOFLAG:BYTE
19 EXTRN SINGLECOM:WORD,VERVAL:WORD,FORFLAG:BYTE
20 EXTRN RE_INSTR:BYTE,RE_OUT_APP:BYTE,PIPE1:BYTE,PIPE2:BYTE
21 EXTRN RE_OUTSTR:BYTE,PIPEFLAG:BYTE,PIPEFILES:BYTE,PIPEPTR:WORD
22 EXTRN INPIPEPTR:WORD,OUTPIPEPTR:WORD,EXEC_BLOCK:BYTE,ENVIRSEG:WORD
23DATARES ENDS
24
25TRANDATA SEGMENT PUBLIC
26 EXTRN BADBAT:BYTE,NEEDBAT:BYTE,BADNAM:BYTE
27 EXTRN SYNTMES:BYTE,BADDRV:BYTE,BYTMES_POST:BYTE
28 EXTRN DIRMES_PRE:BYTE,DIRMES_POST:BYTE,BYTMES_PRE:BYTE
29 EXTRN NOTFND:BYTE,PIPEEMES:BYTE,BADPMES:BYTE,COMTAB:BYTE
30TRANDATA ENDS
31
32TRANSPACE SEGMENT PUBLIC
33 EXTRN UCOMBUF:BYTE,COMBUF:BYTE,USERDIR1:BYTE,EXECPATH:BYTE
34 EXTRN DIRCHAR:BYTE,EXEC_ADDR:DWORD,RCH_ADDR:DWORD,CHKDRV:BYTE
35 EXTRN CURDRV:BYTE,PARM1:BYTE,PARM2:BYTE,COMSW:WORD,ARG1S:WORD
36 EXTRN ARG2S:WORD,ARGTS:WORD,SPECDRV:BYTE,BYTCNT:WORD,IDLEN:BYTE
37 EXTRN DIRBUF:BYTE,ID:BYTE,COM:BYTE,LINCNT:BYTE,INTERNATVARS:BYTE
38 EXTRN HEADCALL:DWORD,RESSEG:WORD,TPA:WORD,SWITCHAR:BYTE
39 EXTRN STACK:WORD,FILTYP:BYTE,FILECNT:WORD,LINLEN:BYTE
40
41
42 IF KANJI
43 EXTRN KPARSE:BYTE
44 ENDIF
45TRANSPACE ENDS
46
47; ********************************************************************
48; START OF TRANSIENT PORTION
49; This code is loaded at the end of memory and may be overwritten by
50; memory-intensive user programs.
51
52TRANCODE SEGMENT PUBLIC PARA
53ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
54
55
56 EXTRN SCANOFF:NEAR,DELIM:NEAR,SAVUDIR:NEAR,SAVUDIR1:NEAR
57 EXTRN PATHCHRCMP:NEAR,PRINT:NEAR,RESTUDIR:NEAR
58 EXTRN CRLF2:NEAR,PRINT_PROMPT:NEAR,GETBATBYT:NEAR,PRESCAN:NEAR
59 EXTRN CRPRINT:NEAR,DISP32BITS:NEAR,FCB_TO_ASCZ:NEAR
60 EXTRN ERROR_PRINT:NEAR,FREE_TPA:NEAR,ALLOC_TPA:NEAR
61 EXTRN $EXIT:NEAR,FORPROC:NEAR,FIND_NAME_IN_ENVIRONMENT:NEAR
62 EXTRN UPCONV:NEAR,BATOPEN:NEAR,BATCLOSE:NEAR,IOSET:NEAR,FIND_PATH:NEAR
63 EXTRN TESTDOREIN:NEAR,TESTDOREOUT:NEAR
64
65 PUBLIC SWLIST,CERROR,SETREST1,DOCOM,DOCOM1,DRVBAD,NOTFNDERR
66 PUBLIC COMMAND,TCOMMAND,SWITCH,PIPEERRSYN,GETKEYSTROKE,SETREST
67 PUBLIC CHKCNT
68
69
70 IF KANJI
71 EXTRN TESTKANJ:NEAR
72 ENDIF
73
74 ORG 0
75ZERO = $
76
77 ORG 100H ; Allow for 100H parameter area
78
79SETDRV:
80 MOV AH,SET_DEFAULT_DRIVE
81 INT int_command
82TCOMMAND:
83 MOV DS,[RESSEG]
84ASSUME DS:RESGROUP
85 MOV AX,-1
86 XCHG AX,[VERVAL]
87 CMP AX,-1
88 JZ NOSETVER2
89 MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
90 INT int_command
91NOSETVER2:
92 CALL [HEADCALL] ; Make sure header fixed
93 XOR BP,BP ; Flag transient not read
94 CMP [SINGLECOM],-1
95 JNZ COMMAND
96$EXITPREP:
97 PUSH CS
98 POP DS
99 JMP $EXIT ; Have finished the single command
100ASSUME DS:NOTHING
101COMMAND:
102 CLD
103 MOV AX,CS
104 MOV SS,AX
105ASSUME SS:TRANGROUP
106 MOV SP,OFFSET TRANGROUP:STACK
107 MOV ES,AX
108ASSUME ES:TRANGROUP
109 MOV DS,[RESSEG]
110ASSUME DS:RESGROUP
111 STI
112
113 MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF
114 MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE)
115 OR BP,BP ; See if just read
116 JZ TESTRDIR ; Not read, check user directory
117 MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer
118 JMP SHORT NOSETBUF
119TESTRDIR:
120 CMP [RESTDIR],0
121 JZ NOSETBUF ; User directory OK
122 PUSH DS
123 PUSH CS
124 POP DS
125ASSUME DS:TRANGROUP
126 MOV DX,OFFSET TRANGROUP:USERDIR1
127 MOV AH,CHDIR
128 INT int_command ; Restore users directory
129 POP DS
130ASSUME DS:RESGROUP
131NOSETBUF:
132 CMP [PIPEFILES],0
133 JZ NOPCLOSE ; Don't bother if they don't exist
134 CMP [PIPEFLAG],0
135 JNZ NOPCLOSE ; Don't del if still piping
136 CALL PIPEDEL
137NOPCLOSE:
138 MOV [EXTCOM],0 ; Flag internal command
139 MOV [RESTDIR],0 ; Flag users dirs OK
140 MOV AX,CS ; Get segment we're in
141 MOV DS,AX
142ASSUME DS:TRANGROUP
143 PUSH AX
144 MOV DX,OFFSET TRANGROUP:INTERNATVARS
145 MOV AX,INTERNATIONAL SHL 8
146 INT 21H
147 POP AX
148 SUB AX,[TPA] ; AX=size of TPA in paragraphs
149 MOV DX,16
150 MUL DX ; DX:AX=size of TPA in bytes
151 OR DX,DX ; See if over 64K
152 JZ SAVSIZ ; OK if not
153 MOV AX,-1 ; If so, limit to 65535 bytes
154SAVSIZ:
155 MOV [BYTCNT],AX ; Max no. of bytes that can be buffered
156 MOV DS,[RESSEG] ; All batch work must use resident seg.
157ASSUME DS:RESGROUP
158 TEST [ECHOFLAG],-1
159 JZ GETCOM ; Don't do the CRLF
160 CALL SINGLETEST
161 JB GETCOM
162 CALL CRLF2
163GETCOM:
164 MOV AH,GET_DEFAULT_DRIVE
165 INT int_command
166 MOV [CURDRV],AL
167 TEST [ECHOFLAG],-1
168 JZ NOPDRV ; No prompt if echo off
169 CALL SINGLETEST
170 JB NOPDRV
171 CALL PRINT_PROMPT ; Prompt the user
172NOPDRV:
173 TEST [PIPEFLAG],-1 ; Pipe has highest presedence
174 JZ NOPIPE
175 JMP PIPEPROC ; Continue the pipeline
176NOPIPE:
177 TEST [FORFLAG],-1 ; FOR has next highest precedence
178 JZ TESTFORBAT
179 JMP FORPROC ; Continue the FOR
180TESTFORBAT:
181 MOV [RE_INSTR],0 ; Turn redirection back off
182 MOV [RE_OUTSTR],0
183 MOV [RE_OUT_APP],0
184 TEST [BATCH],-1 ; Batch has lowest precedence
185 JZ ISNOBAT
186 JMP READBAT ; Continue BATCH
187
188ISNOBAT:
189 CMP [SINGLECOM],0
190 JZ REGCOM
191 MOV SI,-1
192 XCHG SI,[SINGLECOM]
193 MOV DI,OFFSET TRANGROUP:COMBUF + 2
194 XOR CX,CX
195SINGLELOOP:
196 LODSB
197 STOSB
198 INC CX
199 CMP AL,0DH
200 JNZ SINGLELOOP
201 DEC CX
202 PUSH CS
203 POP DS
204ASSUME DS:TRANGROUP
205 MOV [COMBUF + 1],CL
206 JMP DOCOM
207
208REGCOM:
209 PUSH CS
210 POP DS ; Need local segment to point to buffer
211 MOV DX,OFFSET TRANGROUP:UCOMBUF
212 MOV AH,STD_CON_STRING_INPUT
213 INT int_command ; Get a command
214 MOV CL,[UCOMBUF]
215 XOR CH,CH
216 ADD CX,3
217 MOV SI,OFFSET TRANGROUP:UCOMBUF
218 MOV DI,OFFSET TRANGROUP:COMBUF
219 REP MOVSB ; Transfer it to the cooked buffer
220 JMP DOCOM
221
222; All batch proccessing has DS set to segment of resident portion
223ASSUME DS:RESGROUP,ES:TRANGROUP
224
225NEEDENV:
226 PUSH DS
227 PUSH SI
228 PUSH DI
229
230 MOV DI,OFFSET TRANGROUP:ID
231 ADD AL,"0"
232 STOSB
233GETENV1:
234 CALL GETBATBYT
235 STOSB
236 CMP AL,13
237 JZ GETENV2
238 CMP AL,"%"
239 JNZ GETENV1
240 MOV BYTE PTR ES:[DI-1],"="
241GETENV2:
242 MOV SI,OFFSET TRANGROUP:ID
243 PUSH CS
244 POP DS ; DS:SI POINTS TO NAME
245ASSUME DS:TRANGROUP,ES:RESGROUP
246 CALL FIND_NAME_IN_environment
247 PUSH ES
248 POP DS
249 PUSH CS
250 POP ES
251ASSUME DS:RESGROUP,ES:TRANGROUP
252 MOV SI,DI
253 POP DI ; get back pointer to command line
254 JNC GETENV4
255
256GETENV3: ; Parameter not found
257 PUSH CS
258 POP DS
259 MOV SI,OFFSET TRANGROUP:ID
260
261GETENV4:
262 LODSB ; From resident segment
263 OR AL,AL ; Check for end of parameter
264 JZ GETENV6
265 CMP AL,13
266 JZ GETENV6
267 CMP AL,"="
268 JZ GETENVX
269 STOSB
270 JMP GETENV4
271
272GETENVX:
273 MOV AL,"%"
274 STOSB
275GETENV6:
276 POP SI
277 POP DS
278 CMP AL,13
279 JZ SAVBATBYTJ
280 JMP RDBAT
281
282NEEDPARM:
283 CALL GETBATBYT
284 CMP AL,"%" ; Check for two consecutive %
285 JZ SAVBATBYTJ
286 CMP AL,13 ; Check for end-of-line
287 JNZ PAROK
288SAVBATBYTJ:
289 JMP SAVBATBYT
290PAROK:
291 SUB AL,"0"
292 JB NEEDENV ; look for parameter in the environment
293 CMP AL,9
294 JA NEEDENV
295
296 CBW
297 MOV SI,AX
298 SHL SI,1 ; Two bytes per entry
299 PUSH ES
300 PUSH DI
301 MOV ES,[BATCH]
302 XOR CX,CX
303 MOV AX,CX
304 MOV DI,CX
305 DEC CX
306 REPNZ SCASB
307 ADD DI,SI
308 MOV SI,ES:[DI]
309 POP DI
310 POP ES
311 CMP SI,-1 ; Check if parameter exists
312 JZ RDBAT ; Ignore if it doesn't
313RDPARM:
314 LODSB ; From resident segment
315 CMP AL,0DH ; Check for end of parameter
316 JZ RDBAT
317 STOSB
318 JMP RDPARM
319
320PROMPTBAT:
321 MOV DX,OFFSET TRANGROUP:NEEDBAT
322 CALL [RCH_ADDR]
323 JZ AskForBat ; Media is removable
324NoAskForBat:
325 MOV ES,[BATCH] ; Turn off batch
326 MOV AH,DEALLOC
327 INT int_command ; free up the batch piece
328 MOV [BATCH],0 ; AFTER DEALLOC in case of ^C
329 MOV [FORFLAG],0 ; Turn off for processing
330 MOV [PIPEFLAG],0 ; Turn off any pipe
331 PUSH CS
332 POP DS
333 MOV DX,OFFSET TRANGROUP:BADBAT
334 CALL ERROR_PRINT ; Tell user no batch file
335 JMP TCOMMAND
336
337ASKFORBAT:
338 PUSH CS
339 POP DS
340 CALL ERROR_PRINT ; Prompt for batch file
341 CALL GetKeystroke
342 JMP TCOMMAND
343;**************************************************************************
344; read the next keystroke
345
346GetKeystroke:
347 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_INPUT_no_echo
348 INT int_command ; Get character with KB buffer flush
349 MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
350 INT int_command
351 return
352
353READBAT:
354 CALL BATOPEN
355 JC PROMPTBAT
356 MOV DI,OFFSET TRANGROUP:COMBUF+2
357TESTNOP:
358 CALL GETBATBYT
359 CMP AL,':' ; Label/Comment?
360 JNZ NOTLABEL
361NOPLINE: ; Consume the line
362 CALL GETBATBYT
363 CMP AL,0DH
364 JNZ NOPLINE
365 CALL GETBATBYT ; Eat Linefeed
366 TEST [BATCH],-1
367 JNZ TESTNOP
368 JMP TCOMMAND ; Hit EOF
369
370RDBAT:
371 CALL GETBATBYT
372NOTLABEL:
373 CMP AL,"%" ; Check for parameter
374 JNZ SAVBATBYT
375 JMP NEEDPARM
376SAVBATBYT:
377 STOSB
378 CMP AL,0DH
379 JNZ RDBAT
380 SUB DI,OFFSET TRANGROUP:COMBUF+3
381 MOV AX,DI
382 MOV ES:[COMBUF+1],AL ; Set length of line
383 CALL GETBATBYT ; Eat linefeed
384 CALL BATCLOSE
385 TEST [ECHOFLAG],-1
386 PUSH CS
387 POP DS ; Go back to local segment
388 JZ NOECHO2
389ASSUME DS:TRANGROUP
390 MOV DX,OFFSET TRANGROUP:COMBUF+2
391 CALL CRPRINT
392DOCOM:
393; All segments are local for command line processing
394 CALL CRLF2
395DOCOM1:
396
397NOECHO2:
398 CALL PRESCAN ; Cook the input buffer
399 JZ NOPIPEPROC
400 JMP PIPEPROCSTRT ; Fire up the pipe
401NOPIPEPROC:
402 MOV SI,OFFSET TRANGROUP:COMBUF+2
403 MOV DI,OFFSET TRANGROUP:IDLEN
404 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off
405 INT int_command
406 CMP AL,1 ; Check for ambiguous command name
407 JZ BADCOMJ1 ; Ambiguous commands not allowed
408 CMP AL,-1
409 JNZ DRVGD
410 JMP DRVBAD
411
412BADCOMJ1:
413 JMP BADCOM
414
415DRVGD:
416 MOV AL,[DI]
417 MOV [SPECDRV],AL
418 MOV AL," "
419 MOV CX,9
420 INC DI
421 REPNE SCASB ; Count no. of letters in command name
422 MOV AL,9
423 SUB AL,CL
424 MOV [IDLEN],AL
425 MOV DI,81H
426 XOR CX,CX
427 PUSH SI
428COMTAIL:
429 LODSB
430 STOSB ; Move command tail to 80H
431 CMP AL,13
432 LOOPNZ COMTAIL
433 NOT CL
434 MOV BYTE PTR DS:[80H],CL
435 POP SI
436; If the command has 0 parameters must check here for
437; any switches that might be present.
438; SI -> first character after the command.
439 CALL SWITCH ; Is the next character a SWITCHAR
440 MOV [COMSW],AX
441 MOV DI,FCB
442 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
443 INT int_command
444 MOV [PARM1],AL ; Save result of parse
445
446PRBEG:
447 LODSB
448 CMP AL,[SWITCHAR]
449 JZ PRFIN
450 CMP AL,13
451 JZ PRFIN
452 CALL DELIM
453 JNZ PRBEG
454PRFIN:
455 DEC SI
456 CALL SWITCH
457 MOV [ARG1S],AX
458 MOV DI,FCB+10H
459 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
460 INT int_command ; Parse file name
461 MOV [PARM2],AL ; Save result
462 CALL SWITCH
463 MOV [ARG2S],AX
464 OR AX,[ARG1S]
465 MOV [ARGTS],AX
466SWTLP: ; Find any remaining switches
467 CMP BYTE PTR [SI],0DH
468 JZ GOTALLSW
469 INC SI
470 CALL SWITCH
471 OR [ARGTS],AX
472 JMP SHORT SWTLP
473
474GOTALLSW:
475 MOV AL,[IDLEN]
476 MOV DL,[SPECDRV]
477 OR DL,DL ; Check if drive was specified
478 JZ OK
479 JMP DRVCHK
480OK:
481 DEC AL ; Check for null command
482 JNZ FNDCOM
483 MOV DS,[RESSEG]
484ASSUME DS:RESGROUP
485 CMP [SINGLECOM],-1
486 JZ EXITJ
487 JMP GETCOM
488
489EXITJ:
490 JMP $EXITPREP
491ASSUME DS:TRANGROUP
492
493RETSW:
494 XCHG AX,BX ; Put switches in AX
495 return
496
497SWITCH:
498 XOR BX,BX ; Initialize - no switches set
499SWLOOP:
500 CALL SCANOFF ; Skip any delimiters
501 CMP AL,[SWITCHAR] ; Is it a switch specifier?
502 JNZ RETSW ; No -- we're finished
503 OR BX,GOTSWITCH ; Indicate there is a switch specified
504 INC SI ; Skip over the switch character
505 CALL SCANOFF
506 CMP AL,0DH
507 JZ RETSW ; Oops
508 INC SI
509; Convert lower case input to upper case
510 CALL UPCONV
511 MOV DI,OFFSET TRANGROUP:SWLIST
512 MOV CX,SWCOUNT
513 REPNE SCASB ; Look for matching switch
514 JNZ BADSW
515 MOV AX,1
516 SHL AX,CL ; Set a bit for the switch
517 OR BX,AX
518 JMP SHORT SWLOOP
519
520BADSW:
521 JMP SHORT SWLOOP
522
523SWLIST DB "VBAPW"
524SWCOUNT EQU $-SWLIST
525
526DRVBAD:
527 MOV DX,OFFSET TRANGROUP:BADDRV
528 JMP CERROR
529
530FNDCOM:
531 MOV SI,OFFSET TRANGROUP:COMTAB ; Prepare to search command table
532 MOV CH,0
533FINDCOM:
534 MOV DI,OFFSET TRANGROUP:IDLEN
535 MOV CL,[SI]
536 JCXZ EXTERNAL
537 REPE CMPSB
538 LAHF
539 ADD SI,CX ; Bump to next position without affecting flags
540 SAHF
541 LODSB ; Get flag for drive check
542 MOV [CHKDRV],AL
543 LODSW ; Get address of command
544 JNZ FINDCOM
545 MOV DX,AX
546 CMP [CHKDRV],0
547 JZ NOCHECK
548 MOV AL,[PARM1]
549 OR AL,[PARM2] ; Check if either parm. had invalid drive
550 CMP AL,-1
551 JZ DRVBAD
552NOCHECK:
553 CALL IOSET
554 CALL DX ; Call the internal
555COMJMP:
556 JMP TCOMMAND
557
558SETDRV1:
559 JMP SETDRV
560
561DRVCHK:
562 DEC DL ; Adjust for correct drive number
563 DEC AL ; Check if anything else is on line
564 JZ SETDRV1
565EXTERNAL:
566 MOV [FILTYP],0
567 MOV DL,[SPECDRV]
568 MOV [IDLEN],DL
569 CALL SAVUDIR ; Drive letter already checked
570 MOV AL,'?'
571 MOV DI,OFFSET TRANGROUP:COM
572 STOSB ; Look for any extension
573 STOSB
574 STOSB
575 MOV DX,OFFSET TRANGROUP:DIRBUF ; Command will end up here
576 MOV AH,SET_DMA
577 INT int_command
578 PUSH ES
579 CALL FIND_PATH
580 MOV SI,DI
581 POP ES
582
583 MOV DI,OFFSET TRANGROUP:EXECPATH
584 MOV BYTE PTR [DI],0 ; Initialize to current directory
585RESEARCH:
586 MOV AH,DIR_SEARCH_FIRST
587COMSRCH:
588 PUSH CS
589 POP DS
590 MOV DX,OFFSET TRANGROUP:IDLEN
591 INT int_command
592 OR AL,AL
593 MOV AH,DIR_SEARCH_NEXT ; Do search-next next
594 JNZ PATHCHK
595 CMP WORD PTR [DIRBUF+9],4F00H + "C"
596 JNZ CHKEXE
597 CMP [DIRBUF+11],"M"
598 JNZ CHKEXE
599 OR [FILTYP],4
600 JMP EXECUTE ; If we find a COM were done
601
602CHKEXE:
603 CMP WORD PTR [DIRBUF+9],5800H + "E"
604 JNZ CHKBAT
605 CMP [DIRBUF+11],"E"
606 JNZ CHKBAT
607 OR [FILTYP],1 ; Flag an EXE found
608 JMP COMSRCH ; Continue search
609
610CHKBAT:
611 CMP WORD PTR [DIRBUF+9],4100H + "B"
612 JNZ COMSRCH
613 CMP [DIRBUF+11],"T"
614 JNZ COMSRCH
615 OR [FILTYP],2 ; Flag BAT found
616 JMP COMSRCH ; Continue search
617
618PATHCHK:
619 TEST [FILTYP],1
620 JZ TESTBAT
621 MOV WORD PTR [DIRBUF+9],5800H+"E"
622 MOV [DIRBUF+11],"E"
623 JMP EXECUTE ; Found EXE
624
625TESTBAT:
626 TEST [FILTYP],2
627 JZ NEXTPATH ; Found nothing, try next path
628 MOV WORD PTR [DIRBUF+9],4100H+"B"
629 MOV [DIRBUF+11],"T"
630 MOV DX,OFFSET TRANGROUP:DIRBUF ; Found BAT
631 MOV AH,FCB_OPEN
632 INT int_command
633 OR AL,AL
634 JZ BATCOMJ ; Bat exists
635 CALL RESTUDIR
636 JMP BADCOM
637
638BATCOMJ:
639 JMP BATCOM
640
641NEXTPATH:
642 MOV DX,OFFSET TRANGROUP:USERDIR1 ; Restore users dir
643 MOV AH,CHDIR
644 INT int_command
645 MOV DS,[RESSEG]
646ASSUME DS:RESGROUP
647 MOV [RESTDIR],0
648BADPATHEL:
649 MOV DI,OFFSET TRANGROUP:EXECPATH ; Build a full path here
650 MOV DX,SI
651 MOV DS,[ENVIRSEG] ; Point into environment
652ASSUME DS:NOTHING
653 LODSB
654
655 IF KANJI
656 MOV [KPARSE],0
657 ENDIF
658
659 OR AL,AL
660 JZ BADCOMJ ; NUL, command not found
661 XOR BL,BL ; Make BL a NUL
662PSKIPLP: ; Get the path
663 STOSB
664 OR AL,AL
665 JZ LASTPATH
666 CMP AL,';'
667 JZ GOTNEXTPATH
668 CMP DI,15+DirStrLen+(OFFSET TRANGROUP:EXECPATH)
669 JB OKPath
670SKIPPathElem:
671 LODSB ; scan to end of path element
672 OR AL,AL
673 JZ BadPathEl
674 CMP AL,';'
675 JZ BadPathEl
676 JMP SkipPathElem
677
678OKPath:
679 IF KANJI
680 MOV [KPARSE],0
681 CALL TESTKANJ
682 JZ NXTPTCHR
683 INC [KPARSE]
684 MOVSB
685NXTPTCHR:
686 ENDIF
687
688 LODSB
689 JMP SHORT PSKIPLP
690
691BADCOMJ:
692 JMP BADCOM
693
694LASTPATH:
695 MOV BYTE PTR ES:[DI-1],';' ; Fix up the NUL in EXECPATH
696 DEC SI ; Point to the NUL in PATHSTRING
697 MOV BL,[SI-1] ; Change substi char to char before NUL
698
699GOTNEXTPATH:
700 DEC DI ; Point to the end of the dir
701 PUSH BX
702 PUSH SI
703 PUSH DX
704 MOV SI,DX
705 XOR DL,DL
706 CMP BYTE PTR [SI+1],DRVCHAR
707 JNZ DEFDRVPATH ; No drive spec
708 MOV DL,[SI]
709 SUB DL,'@'
710DEFDRVPATH:
711 PUSH DS
712 PUSH CS
713 POP DS
714ASSUME DS:TRANGROUP
715 MOV [IDLEN],DL ; New drive
716 PUSH DI
717 CALL SAVUDIR ; Save the users dir
718 POP DI
719 JNC PATHTRY
720 MOV DX,OFFSET TRANGROUP:BADPMES ; Tell the user bad stuff in path
721 CALL PRINT
722PATHTRY:
723 POP DS
724ASSUME DS:NOTHING
725 POP DX
726 POP SI
727 POP BX
728 XCHG BL,[SI-1] ; Stick in NUL, or same thing if LASTPATH
729CDPATH:
730 MOV AH,CHDIR
731 INT int_command
732 MOV [SI-1],BL ; Fix the path string back up
733 MOV DS,[RESSEG]
734ASSUME DS:RESGROUP
735 INC [RESTDIR] ; Say users dir needs restoring
736 JNC ResearchJ
737 JMP BADPATHEL ; Ignore a directory which doesn't exist
738ResearchJ:
739 JMP RESEARCH ; Try looking in this one
740
741BATCOM:
742ASSUME DS:TRANGROUP
743; Batch parameters are read with ES set to segment of resident part
744 CALL IOSET ; Set up any redirection
745 MOV ES,[RESSEG]
746ASSUME ES:RESGROUP
747;Since BATCH has lower precedence than PIPE or FOR. If a new BATCH file
748;is being started it MUST be true that no FOR or PIPE is currently in
749;progress.
750 MOV [FORFLAG],0 ; Turn off for processing
751 MOV [PIPEFLAG],0 ; Turn off any pipe
752 TEST [BATCH],-1
753 JNZ CHAINBAT ; Don't need allocation if chaining
754 CALL FREE_TPA
755ASSUME ES:RESGROUP
756 MOV BX,6 ; 64 + 32 bytes
757 MOV AH,ALLOC
758 INT int_command ; Suck up a little piece for batch processing
759 MOV [BATCH],AX
760 CALL ALLOC_TPA
761CHAINBAT:
762 PUSH ES
763 MOV ES,[BATCH]
764ASSUME ES:NOTHING
765 MOV DL,[DIRBUF]
766 XOR DI,DI
767 CALL SAVUDIR1 ; ES:DI set up, get dir containing Batch file
768 XOR AX,AX
769 MOV CX,AX
770 DEC CX
771 REPNZ SCASB ; Find the NUL
772 DEC DI ; Point at the NUL
773 MOV AL,[DIRCHAR]
774 CMP AL,ES:[DI-1]
775 JZ NOPUTSLASH
776 STOSB
777NOPUTSLASH:
778 MOV SI,OFFSET TRANGROUP:DIRBUF+1
779 CALL FCB_TO_ASCZ ; Tack on batch file name
780 MOV AX,-1
781 MOV BX,DI
782 MOV CX,10
783 REP STOSW ; Init Parmtab to no parms
784 POP ES
785ASSUME ES:RESGROUP
786 CALL RESTUDIR
787 MOV SI,OFFSET TRANGROUP:COMBUF+2
788 MOV DI,OFFSET RESGROUP:PARMBUF
789 MOV CX,10
790EACHPARM:
791 CALL SCANOFF
792 CMP AL,0DH
793 JZ HAVPARM
794 JCXZ MOVPARM ; Only first 10 parms get pointers
795 PUSH ES
796 MOV ES,[BATCH]
797 MOV ES:[BX],DI ; Set pointer table to point to actual parameter
798 POP ES
799 INC BX
800 INC BX
801MOVPARM:
802 LODSB
803 CALL DELIM
804 JZ ENDPARM ; Check for end of parameter
805 STOSB
806 CMP AL,0DH
807 JZ HAVPARM
808 JMP SHORT MOVPARM
809ENDPARM:
810 MOV AL,0DH
811 STOSB ; End-of-parameter marker
812 JCXZ EACHPARM
813 DEC CX
814 JMP SHORT EACHPARM
815HAVPARM:
816 XOR AL,AL
817 STOSB ; Nul terminate the parms
818 XOR AX,AX
819 PUSH ES
820 POP DS ; Simply batch FCB setup
821ASSUME DS:RESGROUP
822 MOV WORD PTR [BATLOC],AX ; Start at beginning of file
823 MOV WORD PTR [BATLOC+2],AX
824 CMP [SINGLECOM],-1
825 JNZ NOBATSING
826 MOV [SINGLECOM],0FFF0H ; Flag single command BATCH job
827NOBATSING:
828 JMP TCOMMAND
829ASSUME DS:TRANGROUP,ES:TRANGROUP
830
831EXECUTE:
832 CALL RESTUDIR
833NeoExecute:
834 CMP BYTE PTR [DI],0 ; Command in current directory
835 JZ NNSLSH
836 MOV AL,[DI-1]
837
838 IF KANJI
839 CMP [KPARSE],0
840 JNZ StuffPath ; Last char is second KANJI byte, might be '\'
841 ENDIF
842
843 CALL PATHCHRCMP
844 JZ HAVEXP ; Don't double slash
845StuffPath:
846 MOV AL,[DIRCHAR]
847 STOSB
848 JMP SHORT HAVEXP
849
850NNSLSH:
851 MOV AL,[DIRBUF] ; Specify a drive
852 ADD AL,'@'
853 STOSB
854 MOV AL,DRVCHAR
855 STOSB
856HAVEXP:
857 MOV SI,OFFSET TRANGROUP:DIRBUF+1
858 CALL FCB_TO_ASCZ ; Tack on the filename
859 CALL IOSET
860 MOV ES,[TPA]
861 MOV AH,DEALLOC
862 INT int_command ; Now running in "free" space
863 MOV ES,[RESSEG]
864ASSUME ES:RESGROUP
865 INC [EXTCOM] ; Indicate external command
866 MOV [RESTDIR],0 ; Since USERDIR1 is in transient, insure
867 ; this flag value for re-entry to COMMAND
868 MOV DI,FCB
869 MOV SI,DI
870 MOV CX,052H
871 REP MOVSW ; Transfer parameters to resident header
872 MOV DX,OFFSET TRANGROUP:EXECPATH
873 MOV BX,OFFSET RESGROUP:EXEC_BLOCK
874 MOV AX,EXEC SHL 8
875 JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident
876
877BADCOM:
878 PUSH CS
879 POP DS
880 MOV DX,OFFSET TRANGROUP:BADNAM
881CERROR:
882 CALL ERROR_PRINT
883 JMP TCOMMAND
884
885SINGLETEST:
886ASSUME DS:RESGROUP
887 CMP [SINGLECOM],0
888 JZ RET5
889 CMP [SINGLECOM],0EFFFH
890 return
891
892
893ASSUME DS:TRANGROUP
894SETREST1:
895 MOV AL,1
896SETREST:
897 PUSH DS
898 MOV DS,[RESSEG]
899ASSUME DS:RESGROUP
900 MOV [RESTDIR],AL
901 POP DS
902ASSUME DS:TRANGROUP
903RET5:
904 return
905
906CHKCNT:
907 TEST [FILECNT],-1
908 JNZ ENDDIR
909NOTFNDERR:
910 MOV DX,OFFSET TRANGROUP:NOTFND
911 JMP CERROR
912
913ENDDIR:
914; Make sure last line ends with CR/LF
915 MOV AL,[LINLEN]
916 CMP AL,[LINCNT] ; Will be equal if just had CR/LF
917 JZ MESSAGE
918 CALL CRLF2
919MESSAGE:
920 MOV DX,OFFSET TRANGROUP:DIRMES_PRE
921 CALL PRINT
922 MOV SI,[FILECNT]
923 XOR DI,DI
924 CALL DISP32BITS
925 MOV DX,OFFSET TRANGROUP:DIRMES_POST
926 CALL PRINT
927 MOV AH,GET_DRIVE_FREESPACE
928 MOV DL,BYTE PTR DS:[FCB]
929 INT int_command
930 CMP AX,-1
931 retz
932 MOV DX,OFFSET TRANGROUP:BYTMES_PRE
933 CALL PRINT
934 MUL CX ; AX is bytes per cluster
935 MUL BX
936 MOV DI,DX
937 MOV SI,AX
938 CALL DISP32BITS
939 MOV DX,OFFSET TRANGROUP:BYTMES_POST
940 JMP PRINT
941
942ASSUME DS:RESGROUP
943
944PIPEDEL:
945 PUSH DX
946 MOV DX,OFFSET RESGROUP:PIPE1 ; Clean up in case ^C
947 MOV AH,UNLINK
948 INT int_command
949 MOV DX,OFFSET RESGROUP:PIPE2
950 MOV AH,UNLINK
951 INT int_command
952 XOR AX,AX
953 MOV WORD PTR [PIPEFLAG],AX ; Pipe files and pipe gone
954 MOV [ECHOFLAG],1 ; Make sure ^C to pipe doesn't leave ECHO OFF
955 POP DX
956 return
957
958PIPEERRSYN:
959 MOV DX,OFFSET TRANGROUP:SYNTMES
960 JMP SHORT PIPPERR
961PIPEERR:
962 MOV DX,OFFSET TRANGROUP:PIPEEMES
963PIPPERR:
964 CALL PIPEDEL
965 PUSH CS
966 POP DS
967 JMP CERROR
968
969PIPEPROCSTRT:
970ASSUME DS:TRANGROUP,ES:TRANGROUP
971 MOV DS,[RESSEG]
972ASSUME DS:RESGROUP
973 INC [PIPEFILES] ; Flag that the pipe files exist
974 MOV AH,19H ; Get current drive
975 INT int_command
976 ADD AL,'A'
977 MOV [PIPE2],AL ; Make pipe files in root of def drv
978 MOV BX,OFFSET RESGROUP:PIPE1
979 MOV [BX],AL
980 MOV DX,BX
981 XOR CX,CX
982 MOV AH,CREAT
983 INT int_command
984 JC PIPEERR ; Couldn't create
985 MOV BX,AX
986 MOV AH,CLOSE ; Don't proliferate handles
987 INT int_command
988 MOV DX,OFFSET RESGROUP:PIPE2
989 MOV AH,CREAT
990 INT int_command
991 JC PIPEERR
992 MOV BX,AX
993 MOV AH,CLOSE
994 INT int_command
995 CALL TESTDOREIN ; Set up a redirection if specified
996 MOV [ECHOFLAG],0 ; No echo on pipes
997 MOV SI,[PIPEPTR]
998 CMP [SINGLECOM],-1
999 JNZ NOSINGP
1000 MOV [SINGLECOM],0F000H ; Flag single command pipe
1001NOSINGP:
1002 JMP SHORT FIRSTPIPE
1003
1004PIPEPROC:
1005ASSUME DS:RESGROUP
1006 MOV [ECHOFLAG],0 ; No echo on pipes
1007 MOV SI,[PIPEPTR]
1008 LODSB
1009 CMP AL,'|'
1010 JNZ PIPEEND ; Pipe done
1011 MOV DX,[INPIPEPTR] ; Get the input file name
1012 MOV AX,(OPEN SHL 8)
1013 INT int_command
1014PIPEERRJ:
1015 JC PIPEERR ; Lost the pipe file
1016 MOV BX,AX
1017 MOV AL,0FFH
1018 XCHG AL,[BX.PDB_JFN_Table]
1019 MOV DS:[PDB_JFN_Table],AL ; Redirect
1020FIRSTPIPE:
1021 MOV DI,OFFSET TRANGROUP:COMBUF + 2
1022 XOR CX,CX
1023 CMP BYTE PTR [SI],0DH ; '|<CR>'
1024 JNZ PIPEOK1
1025PIPEERRSYNJ:
1026 JMP PIPEERRSYN
1027PIPEOK1:
1028 CMP BYTE PTR [SI],'|' ; '||'
1029 JZ PIPEERRSYNJ
1030PIPECOMLP:
1031 LODSB
1032 STOSB
1033
1034 IF KANJI
1035 CALL TESTKANJ
1036 JZ NOTKANJ5
1037 MOVSB
1038 JMP PIPECOMLP
1039
1040NOTKANJ5:
1041 ENDIF
1042
1043 CMP AL,0DH
1044 JZ LASTPIPE
1045 INC CX
1046 CMP AL,'|'
1047 JNZ PIPECOMLP
1048 MOV BYTE PTR ES:[DI-1],0DH
1049 DEC CX
1050 MOV [COMBUF+1],CL
1051 DEC SI
1052 MOV [PIPEPTR],SI ; On to next pipe element
1053 MOV DX,[OUTPIPEPTR]
1054 PUSH CX
1055 XOR CX,CX
1056 MOV AX,(CREAT SHL 8)
1057 INT int_command
1058 POP CX
1059 JC PIPEERRJ ; Lost the file
1060 MOV BX,AX
1061 MOV AL,0FFH
1062 XCHG AL,[BX.PDB_JFN_Table]
1063 MOV DS:[PDB_JFN_Table+1],AL
1064 XCHG DX,[INPIPEPTR] ; Swap for next element of pipe
1065 MOV [OUTPIPEPTR],DX
1066 JMP SHORT PIPECOM
1067
1068LASTPIPE:
1069 MOV [COMBUF+1],CL
1070 DEC SI
1071 MOV [PIPEPTR],SI ; Point at the CR (anything not '|' will do)
1072 CALL TESTDOREOUT ; Set up the redirection if specified
1073PIPECOM:
1074 PUSH CS
1075 POP DS
1076 JMP NOPIPEPROC ; Process the pipe element
1077
1078PIPEEND:
1079 CALL PIPEDEL
1080 CMP [SINGLECOM],0F000H
1081 JNZ NOSINGP2
1082 MOV [SINGLECOM],-1 ; Make it return
1083NOSINGP2:
1084 JMP TCOMMAND
1085
1086TRANCODE ENDS
1087 END
1088
diff --git a/v2.0/source/TCODE2.ASM b/v2.0/source/TCODE2.ASM
new file mode 100644
index 0000000..bc2742d
--- /dev/null
+++ b/v2.0/source/TCODE2.ASM
@@ -0,0 +1,522 @@
1TITLE PART2 - COMMAND Transient routines.
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15CODERES SEGMENT PUBLIC
16 EXTRN LODCOM1:NEAR
17CODERES ENDS
18
19DATARES SEGMENT PUBLIC
20 EXTRN PARENT:WORD,IO_SAVE:WORD,PERMCOM:BYTE
21 EXTRN PIPEFLAG:BYTE,ENVIRSEG:WORD
22 if ibmver
23 EXTRN SYS_CALL:DWORD
24 endif
25DATARES ENDS
26
27TRANDATA SEGMENT PUBLIC
28
29 EXTRN PATH_TEXT:BYTE,PROMPT_TEXT:BYTE
30 EXTRN BADDEV:BYTE,SYNTMES:BYTE,ENVERR:BYTE
31TRANDATA ENDS
32
33TRANSPACE SEGMENT PUBLIC
34
35 EXTRN CURDRV:BYTE,DIRCHAR:BYTE,PWDBUF:BYTE
36 EXTRN INTERNATVARS:BYTE,RESSEG:WORD,TPA:WORD
37
38TRANSPACE ENDS
39
40
41TRANCODE SEGMENT PUBLIC BYTE
42ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
43
44 EXTRN CERROR:NEAR,ZPRINT:NEAR
45 EXTRN CRLF2:NEAR,SCANOFF:NEAR,FREE_TPA:NEAR,ALLOC_TPA:NEAR
46 EXTRN OUT:NEAR,DRVBAD:NEAR,SETPATH:NEAR,PRINT:NEAR
47 EXTRN FCB_TO_ASCZ:NEAR
48
49 PUBLIC PRINT_DRIVE,$EXIT,MOVE_NAME
50 PUBLIC UPCONV,ADD_PROMPT,CTTY,PRINT_DEFAULT_DIRECTORY
51 PUBLIC ADD_NAME_TO_ENVIRONMENT,PWD,SCAN_DOUBLE_NULL
52 PUBLIC FIND_NAME_IN_ENVIRONMENT,STORE_CHAR
53 PUBLIC FIND_PATH,DELETE_PATH,FIND_PROMPT
54 PUBLIC SCASB2
55
56 IF KANJI
57 PUBLIC TESTKANJ
58 ENDIF
59
60BREAK <Environment utilities>
61ASSUME DS:TRANGROUP
62
63ADD_PROMPT:
64 CALL DELETE_PROMPT ; DELETE ANY EXISTING PROMPT
65 CALL SCAN_DOUBLE_NULL
66ADD_PROMPT2:
67 PUSH SI
68 CALL GETARG
69 POP SI
70 retz ; PRE SCAN FOR ARGUMENTS
71 CALL MOVE_NAME ; MOVE IN NAME
72 CALL GETARG
73 JMP SHORT ADD_NAME
74;
75; Input: DS:SI points to a CR terminated string
76; Output: carry flag is set if no room
77; otherwise name is added to environment
78;
79ADD_NAME_TO_ENVIRONMENT:
80 CALL GETARG
81 JZ DISP_ENV
82;
83; check if line contains exactly one equals sign
84;
85 XOR BX,BX ;= COUNT IS 0
86 PUSH SI ;SAVE POINTER TO BEGINNING OF LINE
87EQLP:
88 LODSB ;GET A CHAR
89 CMP AL,13 ;IF CR WE'RE ALL DONE
90 JZ QUEQ
91 CMP AL,"=" ;LOOK FOR = SIGN
92 JNZ EQLP ;NOT THERE, GET NEXT CHAR
93 INC BL ;OTHERWISE INCREMENT EQ COUNT
94 CMP BYTE PTR [SI],13 ;LOOK FOR CR FOLLOWING = SIGN
95 JNZ EQLP
96 INC BH ;SET BH=1 MEANS NO PARAMETERS
97 JMP EQLP ;AND LOOK FOR MORE
98QUEQ:
99 POP SI ;RESTORE BEGINNING OF LINE
100 DEC BL ;ZERO FLAG MEANS ONLY ONE EQ
101 JZ ONEQ ;GOOD LINE
102 MOV DX,OFFSET TRANGROUP:SYNTMES
103 JMP CERROR
104
105ONEQ:
106 PUSH BX
107 CALL DELETE_NAME_IN_ENVIRONMENT
108 POP BX
109 DEC BH
110 retz
111
112 CALL SCAN_DOUBLE_NULL
113 CALL MOVE_NAME
114ADD_NAME:
115 LODSB
116 CMP AL,13
117 retz
118 CALL STORE_CHAR
119 JMP ADD_NAME
120
121DISP_ENV:
122 MOV DS,[RESSEG]
123ASSUME DS:RESGROUP
124 MOV DS,[ENVIRSEG]
125ASSUME DS:NOTHING
126 XOR SI,SI
127PENVLP:
128 CMP BYTE PTR [SI],0
129 retz
130
131 MOV DX,SI
132 CALL ZPRINT
133 CALL CRLF2
134PENVLP2:
135 LODSB
136 OR AL,AL
137 JNZ PENVLP2
138 JMP PENVLP
139
140ASSUME DS:TRANGROUP
141DELETE_PATH:
142 MOV SI,OFFSET TRANGROUP:PATH_TEXT
143 JMP SHORT DELETE_NAME_IN_environment
144
145DELETE_PROMPT:
146 MOV SI,OFFSET TRANGROUP:PROMPT_TEXT
147
148DELETE_NAME_IN_environment:
149;
150; Input: DS:SI points to a "=" terminated string
151; Output: carry flag is set if name not found
152; otherwise name is deleted
153;
154 PUSH SI
155 PUSH DS
156 CALL FIND ; ES:DI POINTS TO NAME
157 JC DEL1
158 MOV SI,DI ; SAVE IT
159 CALL SCASB2 ; SCAN FOR THE NUL
160 XCHG SI,DI
161 CALL GETENVSIZ
162 SUB CX,SI
163 PUSH ES
164 POP DS ; ES:DI POINTS TO NAME, DS:SI POINTS TO NEXT NAME
165 REP MOVSB ; DELETE THE NAME
166DEL1:
167 POP DS
168 POP SI
169 return
170
171FIND_PATH:
172 MOV SI,OFFSET TRANGROUP:PATH_TEXT
173 JMP SHORT FIND_NAME_IN_environment
174
175FIND_PROMPT:
176 MOV SI,OFFSET TRANGROUP:PROMPT_TEXT
177
178FIND_NAME_IN_environment:
179;
180; Input: DS:SI points to a "=" terminated string
181; Output: ES:DI points to the arguments in the environment
182; zero is set if name not found
183; carry flag is set if name not valid format
184;
185 CALL FIND ; FIND THE NAME
186 retc ; CARRY MEANS NOT FOUND
187 JMP SCASB1 ; SCAN FOR = SIGN
188;
189; On return of FIND1, ES:DI points to beginning of name
190;
191FIND:
192 CLD
193 CALL COUNT0 ; CX = LENGTH OF NAME
194 MOV ES,[RESSEG]
195ASSUME ES:RESGROUP
196 MOV ES,[ENVIRSEG]
197ASSUME ES:NOTHING
198 XOR DI,DI
199FIND1:
200 PUSH CX
201 PUSH SI
202 PUSH DI
203FIND11:
204 LODSB
205
206 IF KANJI
207 CALL TESTKANJ
208 JZ NOTKANJ3
209 DEC SI
210 LODSW
211 INC DI
212 INC DI
213 CMP AX,ES:[DI-2]
214 JNZ FIND12
215 DEC CX
216 LOOP FIND11
217 JMP SHORT FIND12
218
219NOTKANJ3:
220 ENDIF
221
222 CALL UPCONV
223 INC DI
224 CMP AL,ES:[DI-1]
225 JNZ FIND12
226 LOOP FIND11
227FIND12:
228 POP DI
229 POP SI
230 POP CX
231 retz
232 PUSH CX
233 CALL SCASB2 ; SCAN FOR A NUL
234 POP CX
235 CMP BYTE PTR ES:[DI],0
236 JNZ FIND1
237 STC ; INDICATE NOT FOUND
238 return
239
240COUNT0:
241 PUSH DS
242 POP ES
243 MOV DI,SI
244
245COUNT1:
246 PUSH DI ; COUNT NUMBER OF CHARS UNTIL "="
247 CALL SCASB1
248 JMP SHORT COUNTX
249COUNT2:
250 PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL
251 CALL SCASB2
252COUNTX:
253 POP CX
254 SUB DI,CX
255 XCHG DI,CX
256 return
257
258MOVE_NAME:
259 CMP BYTE PTR DS:[SI],13
260 retz
261 LODSB
262
263 IF KANJI
264 CALL TESTKANJ
265 JZ NOTKANJ1
266 CALL STORE_CHAR
267 LODSB
268 CALL STORE_CHAR
269 JMP SHORT MOVE_NAME
270
271NOTKANJ1:
272 ENDIF
273
274 CALL UPCONV
275 CALL STORE_CHAR
276 CMP AL,"="
277 JNZ MOVE_NAME
278 return
279
280GETARG:
281 MOV SI,80H
282 LODSB
283 OR AL,AL
284 retz
285 CALL SCANOFF
286 CMP AL,13
287 return
288
289SCAN_DOUBLE_NULL:
290 MOV ES,[RESSEG]
291ASSUME ES:RESGROUP
292 MOV ES,[ENVIRSEG]
293ASSUME ES:NOTHING
294 XOR DI,DI
295SDN1:
296 CALL SCASB2
297 CMP BYTE PTR ES:[DI],0
298 JNZ SDN1
299 return
300
301SCASB1:
302 MOV AL,"=" ; SCAN FOR AN =
303 JMP SHORT SCASBX
304SCASB2:
305 XOR AL,AL ; SCAN FOR A NUL
306SCASBX:
307 MOV CX,100H
308 REPNZ SCASB
309 return
310
311 IF KANJI
312TESTKANJ:
313 CMP AL,81H
314 JB NOTLEAD
315 CMP AL,9FH
316 JBE ISLEAD
317 CMP AL,0E0H
318 JB NOTLEAD
319 CMP AL,0FCH
320 JBE ISLEAD
321NOTLEAD:
322 PUSH AX
323 XOR AX,AX ;Set zero
324 POP AX
325 return
326
327ISLEAD:
328 PUSH AX
329 XOR AX,AX ;Set zero
330 INC AX ;Reset zero
331 POP AX
332 return
333 ENDIF
334
335UPCONV:
336 CMP AL,"a"
337 JB RET22C
338 CMP AL,"z"
339 JA RET22C
340 SUB AL,20H ; Lower-case changed to upper-case
341RET22C:
342 CALL DWORD PTR CS:[INTERNATVARS.Map_call]
343 return
344;
345; STORE A CHAR IN environment, GROWING IT IF NECESSARY
346;
347STORE_CHAR:
348 PUSH CX
349 PUSH BX
350 CALL GETENVSIZ
351 MOV BX,CX
352 SUB BX,2 ; SAVE ROOM FOR DOUBLE NULL
353 CMP DI,BX
354 JB STORE1
355
356 PUSH AX
357 PUSH CX
358 PUSH BX ; Save Size of environment
359 CALL FREE_TPA
360 POP BX
361 ADD BX,2 ; Recover true environment size
362 MOV CL,4
363 SHR BX,CL ; Convert back to paragraphs
364 INC BX ; Try to grow environment by one para
365 MOV AH,SETBLOCK
366 INT int_command
367 PUSHF
368 PUSH ES
369 MOV ES,[RESSEG]
370 CALL ALLOC_TPA
371 POP ES
372 POPF
373 POP CX
374 POP AX
375 JNC STORE1
376 MOV DX,OFFSET TRANGROUP:ENVERR
377 JMP CERROR
378STORE1:
379 STOSB
380 MOV WORD PTR ES:[DI],0 ; NULL IS AT END
381 POP BX
382 POP CX
383 return
384
385GETENVSIZ:
386;Get size of environment in bytes, rounded up to paragraph boundry
387;ES has environment segment
388;Size returned in CX, all other registers preserved
389
390 PUSH ES
391 PUSH AX
392 MOV AX,ES
393 DEC AX ;Point at arena
394 MOV ES,AX
395 MOV AX,ES:[arena_size]
396 MOV CL,4
397 SHL AX,CL ;Convert to bytes
398 MOV CX,AX
399 POP AX
400 POP ES
401 return
402
403PRINT_DRIVE:
404 MOV AH,GET_DEFAULT_DRIVE
405 INT int_command
406 ADD AL,"A"
407 JMP OUT
408
409ASSUME DS:TRANGROUP,ES:TRANGROUP
410PWD:
411 CALL PRINT_DIRECTORY
412 CALL CRLF2
413 return
414
415PRINT_DEFAULT_DIRECTORY:
416 MOV BYTE PTR DS:[FCB],0
417PRINT_DIRECTORY:
418 MOV DL,DS:[FCB]
419 MOV AL,DL
420 ADD AL,'@'
421 CMP AL,'@'
422 JNZ GOTDRIVE
423 ADD AL,[CURDRV]
424 INC AL
425GOTDRIVE:
426 PUSH AX
427 MOV SI,OFFSET TRANGROUP:PWDBUF+3
428 MOV AH,CURRENT_DIR
429 INT int_command
430 JNC DPBISOK
431 PUSH CS
432 POP DS
433 JMP DRVBAD
434DPBISOK:
435 MOV DI,OFFSET TRANGROUP:PWDBUF
436 MOV DX,DI
437 POP AX
438 MOV AH,DRVCHAR
439 STOSW
440 MOV AL,[DIRCHAR]
441 STOSB
442 JMP ZPRINT
443
444$EXIT:
445 PUSH ES
446 MOV ES,[RESSEG]
447ASSUME ES:RESGROUP
448 MOV AX,[PARENT]
449 MOV WORD PTR ES:[PDB_Parent_PID],AX
450
451IF IBM
452 CMP [PERMCOM],0
453 JNZ NORESETVEC ;Don't reset the vector if a PERMCOM
454 LDS DX,DWORD PTR ES:[SYS_CALL]
455ASSUME DS:NOTHING
456 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) + INT_COMMAND
457 INT int_command
458NORESETVEC:
459ENDIF
460
461 POP ES
462ASSUME ES:TRANGROUP
463 MOV ES,[TPA]
464 MOV AH,DEALLOC
465 INT int_command ; Now running in "free" space
466 MOV AX,(EXIT SHL 8)
467 INT int_command
468
469CTTY:
470 CALL SETPATH ; Get spec
471 MOV AX,(OPEN SHL 8) OR 2 ; Read and write
472 INT int_command ; Open new device
473 JC ISBADDEV
474 MOV BX,AX
475 MOV AX,IOCTL SHL 8
476 INT int_command
477 TEST DL,80H
478 JNZ DEVISOK
479 MOV AH,CLOSE ; Close initial handle
480 INT int_command
481ISBADDEV:
482 MOV DX,OFFSET TRANGROUP:BADDEV
483 CALL PRINT
484 JMP RESRET
485
486DEVISOK:
487 XOR DH,DH
488 OR DL,3 ; Make sure has CON attributes
489 MOV AX,(IOCTL SHL 8) OR 1
490 INT int_command
491 PUSH BX ; Save handle
492 MOV CX,3
493 XOR BX,BX
494ICLLOOP: ; Close basic handles
495 MOV AH,CLOSE
496 INT int_command
497 INC BX
498 LOOP ICLLOOP
499 POP BX ; Get handle
500 MOV AH,XDUP
501 INT int_command ; Dup it to 0
502 MOV AH,XDUP
503 INT int_command ; Dup to 1
504 MOV AH,XDUP
505 INT int_command ; Dup to 2
506 MOV AH,CLOSE ; Close initial handle
507 INT int_command
508RESRET:
509 MOV DS,[RESSEG]
510ASSUME DS:RESGROUP
511 PUSH DS
512 MOV AX,WORD PTR DS:[PDB_JFN_Table] ; Get new 0 and 1
513 MOV [IO_SAVE],AX
514 MOV AX,OFFSET RESGROUP:LODCOM1
515 PUSH AX
516ZMMMM PROC FAR
517 RET ; Force header to be checked
518ZMMMM ENDP
519
520TRANCODE ENDS
521 END
522
diff --git a/v2.0/source/TCODE3.ASM b/v2.0/source/TCODE3.ASM
new file mode 100644
index 0000000..547c937
--- /dev/null
+++ b/v2.0/source/TCODE3.ASM
@@ -0,0 +1,677 @@
1TITLE PART3 - COMMAND Transient routines.
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15
16DATARES SEGMENT PUBLIC
17 EXTRN BATCH:WORD,BATLOC:DWORD
18 EXTRN RETCODE:WORD,ECHOFLAG:BYTE
19 EXTRN SINGLECOM:WORD,FORFLAG:BYTE,UFORDRV:BYTE
20 EXTRN FORSET:BYTE,FORCOM:BYTE,FORVAR:BYTE,FORPTR:WORD
21 EXTRN FORUFCB:BYTE,FORFCB:BYTE,RE_INSTR:BYTE,RE_OUT_APP:BYTE
22 EXTRN RE_OUTSTR:BYTE,PIPEFLAG:BYTE
23
24DATARES ENDS
25
26TRANDATA SEGMENT PUBLIC
27
28 EXTRN BADLAB:BYTE,SYNTMES:BYTE,FORNESTMES:BYTE
29 EXTRN NOTFND:BYTE,FULDIR:BYTE,IFTAB:BYTE
30TRANDATA ENDS
31
32TRANSPACE SEGMENT PUBLIC
33
34 EXTRN BATHAND:WORD,RESSEG:WORD,DIRBUF:BYTE,COMBUF:BYTE
35 EXTRN GOTOLEN:WORD,IFNOTFLAG:BYTE
36
37TRANSPACE ENDS
38
39
40TRANCODE SEGMENT PUBLIC BYTE
41ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
42
43 EXTRN SCANOFF:NEAR,DOCOM:NEAR,DOCOM1:NEAR,CERROR:NEAR
44 EXTRN PRINT:NEAR,TCOMMAND:NEAR,DELIM:NEAR,GETBATBYT:NEAR
45 EXTRN FCB_TO_ASCZ:NEAR
46
47 PUBLIC GOTO,$IF,IFERLEV,SHIFT,IFEXISTS
48 PUBLIC STRCOMP,MesTran,$FOR,IFNOT
49 PUBLIC FORPROC,BATOPEN,BATCLOSE
50 PUBLIC IOSET,TESTDOREIN,TESTDOREOUT
51
52 ASSUME DS:RESGROUP
53FORTERM:
54 MOV [FORFLAG],0
55 CMP [SINGLECOM],0FF00H
56 JNZ NOFORP2
57 MOV [SINGLECOM],-1 ; Cause a terminate
58NOFORP2:
59 JMP TCOMMAND
60
61FORPROC:
62ASSUME DS:RESGROUP
63 CMP [FORUFCB],-1
64 JZ NORMFOR
65 MOV DX,OFFSET TRANGROUP:DIRBUF
66 PUSH DS
67 PUSH CS
68 POP DS
69ASSUME DS:TRANGROUP
70 MOV AH,SET_DMA
71 INT int_command
72 POP DS
73ASSUME DS:RESGROUP
74 MOV DX,OFFSET RESGROUP:FORFCB
75 MOV AH,DIR_SEARCH_NEXT
76 CMP [FORUFCB],0
77 JZ DOFORSRCH
78 MOV AH,DIR_SEARCH_FIRST
79 MOV [FORUFCB],0
80DOFORSRCH:
81 INT int_command
82 OR AL,AL
83 JNZ FORTERM
84 PUSH DS
85 POP ES
86ASSUME ES:RESGROUP
87 PUSH CS
88 POP DS
89ASSUME DS:TRANGROUP
90 MOV SI,OFFSET TRANGROUP:DIRBUF
91 MOV DI,OFFSET RESGROUP:FORSET
92 MOV [FORPTR],DI
93 LODSB ;Get drive spec
94 ADD AL,'@'
95 CMP AL,'@'
96 JZ NDRV8
97 CMP [UFORDRV],0
98 JZ NDRV8
99 MOV AH,':'
100 STOSW
101NDRV8:
102 CALL FCB_TO_ASCZ
103 MOV BYTE PTR ES:[DI-1],0DH
104 PUSH ES
105 POP DS
106ASSUME DS:RESGROUP
107NORMFOR:
108 PUSH CS
109 POP ES
110ASSUME ES:TRANGROUP
111 MOV BX,[FORPTR]
112 CMP BYTE PTR [BX],0
113 JZ FORTERM
114 MOV SI,BX
115PARMSUB0:
116 LODSB
117 CMP AL,0DH
118 JNZ PARMSUB0
119 MOV DX,SI ; DX points to next parm
120 MOV SI,OFFSET RESGROUP:FORCOM
121 MOV DI,OFFSET TRANGROUP:COMBUF+2
122 XOR CX,CX
123TFORCOM:
124 LODSB
125 CMP AL,'%'
126 JNZ NOFORPARM
127 MOV AH,[FORVAR]
128 CMP AH,[SI]
129 JNZ NOFORPARM
130 INC SI
131 PUSH SI
132 MOV SI,BX
133PARMSUB:
134 LODSB
135 CMP AL,0DH
136 JZ PARMSUBDONE
137 INC CX
138 STOSB
139 JMP SHORT PARMSUB
140PARMSUBDONE:
141 POP SI ; Get back command line pointer
142 JMP TFORCOM
143NOFORPARM:
144 STOSB
145 INC CX
146 CMP AL,0DH
147 JNZ TFORCOM
148 DEC CX
149 MOV [COMBUF+1],CL
150 MOV [FORPTR],DX ; Point to next set element
151 TEST [ECHOFLAG],-1
152 PUSH CS
153 POP DS
154ASSUME DS:TRANGROUP
155 JZ NOECHO3
156 MOV BYTE PTR ES:[DI-1],'$'
157 MOV DX,OFFSET TRANGROUP:COMBUF+2
158 CALL PRINT
159 MOV BYTE PTR ES:[DI-1],0DH
160 JMP DOCOM
161NOECHO3:
162 JMP DOCOM1
163
164ASSUME DS:TRANGROUP,ES:TRANGROUP
165
166FORNESTERR:
167 PUSH DS
168 MOV DS,[RESSEG]
169ASSUME DS:RESGROUP
170 MOV DX,OFFSET TRANGROUP:FORNESTMES
171 CMP [SINGLECOM],0FF00H
172 JNZ NOFORP3
173 MOV [SINGLECOM],-1 ; Cause termination
174NOFORP3:
175 POP DS
176ASSUME DS:TRANGROUP
177 JMP CERROR
178
179$FOR:
180 MOV SI,81H
181 XOR CX,CX
182 MOV ES,[RESSEG]
183ASSUME ES:RESGROUP
184 MOV DI,OFFSET RESGROUP:FORSET
185 XOR AL,AL
186 MOV [UFORDRV],AL
187 XCHG AL,[FORFLAG]
188 OR AL,AL
189 JNZ FORNESTERR
190 MOV [FORPTR],DI
191 MOV [FORUFCB],-1
192 CALL SCANOFF
193 LODSW
194 CMP AL,'%'
195 JNZ FORERRORJ
196 MOV [FORVAR],AH
197 CALL SCANOFF
198 CMP AL,0DH
199 JZ FORERRORJ2
200 LODSW
201 CMP AX,('N' SHL 8) OR 'I'
202 JZ FOROK1
203 CMP AX,('n' SHL 8) OR 'i'
204 JNZ FORERRORJ
205FOROK1:
206 CALL SCANOFF
207 LODSB
208 CMP AL,'('
209 JNZ FORERRORJ
210 CALL SCANOFF
211 CMP AL,')' ; Special check for null set
212 JNZ FORSETLP
213 MOV DS,[RESSEG]
214 JMP FORTERM
215FORSETLP:
216 LODSB
217 CMP AL,0DH
218FORERRORJ2:
219 JZ FORERRORJ3
220 CMP AL,')'
221 JZ FORSETEND
222 STOSB
223 CMP AL,'*'
224 JZ SETFORSCAN
225 CMP AL,'?'
226 JNZ NOFORSCAN
227SETFORSCAN:
228 MOV [FORUFCB],1
229NOFORSCAN:
230 CALL DELIM
231 JNZ FORSETLP
232 MOV BYTE PTR ES:[DI-1],0DH
233 CALL SCANOFF
234 JMP FORSETLP
235
236FORSETEND:
237 MOV AX,000DH
238 CMP BYTE PTR ES:[DI-1],0DH
239 JNZ FORSETTERM
240 XOR AX,AX
241FORSETTERM:
242 STOSW
243 CALL SCANOFF
244 LODSW
245 CMP AX,('O' SHL 8) OR 'D'
246 JZ FOROK2
247 CMP AX,('o' SHL 8) OR 'd'
248FORERRORJ:
249 JNZ FORERROR
250FOROK2:
251 CALL SCANOFF
252 CMP AL,0DH
253FORERRORJ3:
254 JZ FORERROR
255 MOV DI,OFFSET RESGROUP:FORCOM
256FORCOMLP:
257 LODSB
258 STOSB
259 CMP AL,0DH
260 JNZ FORCOMLP
261 INC [FORFLAG]
262 CMP [SINGLECOM],-1
263 JNZ NOFORP
264 MOV [SINGLECOM],0FF00H ; Flag single command for
265NOFORP:
266 CMP [FORUFCB],1
267 retnz
268 PUSH ES
269 POP DS
270ASSUME DS:RESGROUP
271 MOV DI,OFFSET RESGROUP:FORFCB
272 MOV SI,OFFSET RESGROUP:FORSET
273 CMP BYTE PTR [SI+1],':'
274 JNZ NOSETUDRV
275 INC [UFORDRV]
276NOSETUDRV:
277 MOV AX,PARSE_FILE_DESCRIPTOR SHL 8
278 INT int_command
279 return
280
281
282ASSUME DS:TRANGROUP,ES:TRANGROUP
283
284IFERRORP:
285 POP AX
286IFERROR:
287FORERROR:
288 MOV DX,OFFSET TRANGROUP:SYNTMES
289 JMP CERROR
290
291$IF:
292 MOV [IFNOTFLAG],0
293 MOV SI,81H
294IFREENT:
295 CALL SCANOFF
296 CMP AL,0DH
297 JZ IFERROR
298 MOV BP,SI
299 MOV DI,OFFSET TRANGROUP:IFTAB ; Prepare to search if table
300 MOV CH,0
301IFINDCOM:
302 MOV SI,BP
303 MOV CL,[DI]
304 INC DI
305 JCXZ IFSTRING
306 JMP SHORT FIRSTCOMP
307IFCOMP:
308 JNZ IFDIF
309FIRSTCOMP:
310 LODSB
311 MOV AH,ES:[DI]
312 INC DI
313 CMP AL,AH
314 JZ IFLP
315 OR AH,20H ; Try lower case
316 CMP AL,AH
317IFLP:
318 LOOP IFCOMP
319IFDIF:
320 LAHF
321 ADD DI,CX ; Bump to next position without affecting flags
322 MOV BX,[DI] ; Get handler address
323 INC DI
324 INC DI
325 SAHF
326 JNZ IFINDCOM
327 LODSB
328 CMP AL,0DH
329IFERRORJ:
330 JZ IFERROR
331 CALL DELIM
332 JNZ IFINDCOM
333 CALL SCANOFF
334 JMP BX
335
336IFNOT:
337 NOT [IFNOTFLAG]
338 JMP IFREENT
339
340
341IFSTRING:
342 PUSH SI
343 XOR CX,CX
344FIRST_STRING:
345 LODSB
346 CMP AL,0DH
347 JZ IFERRORP
348 CALL DELIM
349 JZ EQUAL_CHECK
350 INC CX
351 JMP SHORT FIRST_STRING
352EQUAL_CHECK:
353 CMP AL,'='
354 JZ EQUAL_CHECK2
355 CMP AL,0DH
356 JZ IFERRORP
357 LODSB
358 JMP SHORT EQUAL_CHECK
359EQUAL_CHECK2:
360 LODSB
361 CMP AL,'='
362 JNZ IFERRORP
363 CALL SCANOFF
364 CMP AL,0DH
365 JZ IFERRORP
366 POP DI
367 REPE CMPSB
368 JZ MATCH
369 CMP BYTE PTR [SI-1],0DH
370 JZ IFERRORJ
371SKIPSTRINGEND:
372 LODSB
373NOTMATCH:
374 CMP AL,0DH
375IFERRORJ2:
376 JZ IFERRORJ
377 CALL DELIM
378 JNZ SKIPSTRINGEND
379 MOV AL,-1
380 JMP SHORT IFRET
381MATCH:
382 LODSB
383 CALL DELIM
384 JNZ NOTMATCH
385 XOR AL,AL
386 JMP SHORT IFRET
387
388IFEXISTS:
389 MOV DI,OFFSET TRANGROUP:DIRBUF
390 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
391 INT int_command
392 MOV AH,FCB_OPEN
393 MOV DX,DI
394 INT int_command
395IFRET:
396 TEST [IFNOTFLAG],-1
397 JZ REALTEST
398 NOT AL
399REALTEST:
400 OR AL,AL
401 JZ IFTRUE
402 JMP TCOMMAND
403IFTRUE:
404 CALL SCANOFF
405 MOV CX,SI
406 SUB CX,81H
407 SUB DS:[80H],CL
408 MOV CL,DS:[80H]
409 MOV [COMBUF+1],CL
410 MOV DI,OFFSET TRANGROUP:COMBUF+2
411 REP MOVSB
412 MOV AL,0DH
413 STOSB
414 JMP DOCOM1
415
416IFERLEV:
417 MOV BH,10
418 XOR BL,BL
419GETNUMLP:
420 LODSB
421 CMP AL,0DH
422 JZ IFERRORJ2
423 CALL DELIM
424 JZ GOTNUM
425 SUB AL,'0'
426 XCHG AL,BL
427 MUL BH
428 ADD AL,BL
429 XCHG AL,BL
430 JMP SHORT GETNUMLP
431GOTNUM:
432 PUSH DS
433 MOV DS,[RESSEG]
434ASSUME DS:RESGROUP
435 MOV AH,BYTE PTR [RETCODE]
436 POP DS
437ASSUME DS:TRANGROUP
438 XOR AL,AL
439 CMP AH,BL
440 JAE IFRET
441 DEC AL
442 JMP SHORT IFRET
443
444ASSUME DS:TRANGROUP
445
446SHIFT:
447 MOV DS,[RESSEG]
448ASSUME DS:RESGROUP
449 MOV AX,[BATCH]
450 TEST AX,-1
451 retz
452 MOV ES,AX
453 MOV DS,AX
454ASSUME DS:NOTHING,ES:NOTHING
455 XOR CX,CX
456 MOV AX,CX
457 MOV DI,CX
458 DEC CX
459 REPNZ SCASB
460 MOV SI,DI
461 INC SI
462 INC SI
463 MOV CX,9
464 REP MOVSW ; Perform shift of existing parms
465 CMP WORD PTR [DI],-1
466 retz ; No new parm
467 MOV SI,[DI]
468 MOV WORD PTR [DI],-1 ; Assume no parm
469 MOV DS,[RESSEG]
470ASSUME DS:RESGROUP
471SKIPCRLP:
472 LODSB
473 CMP AL,0DH
474 JNZ SKIPCRLP
475 CMP BYTE PTR [SI],0
476 retz ; End of parms
477 MOV ES:[DI],SI ; Pointer to next parm as %9
478 return
479
480
481ASSUME DS:TRANGROUP,ES:TRANGROUP
482GOTO:
483 MOV DS,[RESSEG]
484ASSUME DS:RESGROUP
485 TEST [BATCH],-1
486 retz ; If not in batch mode, a nop
487 XOR DX,DX
488 MOV WORD PTR [BATLOC],DX ; Back to start
489 MOV WORD PTR [BATLOC+2],DX
490 CALL BATOPEN ; Find the batch file
491 MOV DI,FCB+1 ; Get the label
492 MOV CX,11
493 MOV AL,' '
494 REPNE SCASB
495 JNZ NOINC
496 INC CX
497NOINC:
498 SUB CX,11
499 NEG CX
500 MOV [GOTOLEN],CX
501 CALL GETBATBYT
502 CMP AL,':'
503 JZ CHKLABEL
504LABLKLP: ; Look for the label
505 CALL GETBATBYT
506 CMP AL,0AH
507 JNZ LABLKTST
508 CALL GETBATBYT
509 CMP AL,':'
510 JZ CHKLABEL
511LABLKTST:
512 TEST [BATCH],-1
513 JNZ LABLKLP
514 CALL BATCLOSE
515 PUSH CS
516 POP DS
517 MOV DX,OFFSET TRANGROUP:BADLAB
518 JMP CERROR
519
520CHKLABEL:
521 MOV DI,FCB+1
522 MOV CX,[GOTOLEN]
523NEXTCHRLP:
524 PUSH CX
525 CALL GETBATBYT
526 POP CX
527 OR AL,20H
528 CMP AL,ES:[DI]
529 JNZ TRYUPPER
530 JMP SHORT NEXTLABCHR
531TRYUPPER:
532 SUB AL,20H
533 CMP AL,ES:[DI]
534 JNZ LABLKTST
535NEXTLABCHR:
536 INC DI
537 LOOP NEXTCHRLP
538 CALL GETBATBYT
539 CMP AL,' '
540 JA LABLKTST
541 CMP AL,0DH
542 JZ SKIPLFEED
543TONEXTBATLIN:
544 CALL GETBATBYT
545 CMP AL,0DH
546 JNZ TONEXTBATLIN
547SKIPLFEED:
548 CALL GETBATBYT
549BATCLOSE:
550 MOV BX,CS:[BATHAND]
551 MOV AH,CLOSE
552 INT int_command
553 return
554
555BATOPEN:
556;Open the BATCH file, If open fails, AL is drive of batch file (A=1)
557ASSUME DS:RESGROUP,ES:TRANGROUP
558 PUSH DS
559 MOV DS,[BATCH]
560ASSUME DS:NOTHING
561 XOR DX,DX
562 MOV AX,OPEN SHL 8
563 INT int_command ; Open the batch file
564 JC SETERRDL
565 POP DS
566ASSUME DS:RESGROUP
567 MOV [BATHAND],AX
568 MOV BX,AX
569 MOV DX,WORD PTR [BATLOC]
570 MOV CX,WORD PTR [BATLOC+2]
571 MOV AX,LSEEK SHL 8 ; Go to the right spot
572 INT int_command
573 return
574
575SETERRDL:
576 MOV BX,DX
577 MOV AL,[BX] ; Get drive spec
578 SUB AL,'@' ; A = 1
579 POP DS
580 STC ; SUB mucked over carry
581 return
582
583MESTRAN:
584ASSUME DS:NOTHING,ES:NOTHING
585 LODSB
586 CMP AL,"$"
587 retz
588 STOSB
589 JMP MESTRAN
590IOSET:
591; ALL REGISTERS PRESERVED
592ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
593 PUSH DS
594 PUSH DX
595 PUSH AX
596 PUSH BX
597 PUSH CX
598 MOV DS,[RESSEG]
599ASSUME DS:RESGROUP
600 CMP [PIPEFLAG],0
601 JNZ NOREDIR ; Don't muck up the pipe
602 CALL TESTDOREIN
603 CALL TESTDOREOUT
604NOREDIR:
605 POP CX
606 POP BX
607 POP AX
608 POP DX
609 POP DS
610ASSUME DS:NOTHING
611 return
612
613TESTDOREIN:
614ASSUME DS:RESGROUP
615 CMP [RE_INSTR],0
616 retz
617 MOV DX,OFFSET RESGROUP:RE_INSTR
618 MOV AX,(OPEN SHL 8)
619 INT int_command
620 MOV DX,OFFSET TRANGROUP:NOTFND
621 JC REDIRERR
622 MOV BX,AX
623 MOV AL,0FFH
624 XCHG AL,[BX.PDB_JFN_Table]
625 MOV DS:[PDB_JFN_Table],AL
626 return
627
628REDIRERR:
629 PUSH CS
630 POP DS
631 JMP CERROR
632
633TESTDOREOUT:
634ASSUME DS:RESGROUP
635 CMP [RE_OUTSTR],0
636 JZ NOREOUT
637 CMP [RE_OUT_APP],0
638 JZ REOUTCRT
639 MOV DX,OFFSET RESGROUP:RE_OUTSTR
640 MOV AX,(OPEN SHL 8) OR 1
641 INT int_command
642 JC REOUTCRT
643 XOR DX,DX
644 XOR CX,CX
645 MOV BX,AX
646 MOV AX,(LSEEK SHL 8) OR 2
647 INT int_command
648 JMP SHORT SET_REOUT
649REOUTCRT:
650 MOV DX,OFFSET RESGROUP:RE_OUTSTR
651 XOR CX,CX
652 MOV AH,CREAT
653 INT int_command
654 MOV DX,OFFSET TRANGROUP:FULDIR
655 JC REDIRERR
656 MOV BX,AX
657SET_REOUT:
658 MOV AL,0FFH
659 XCHG AL,[BX.PDB_JFN_Table]
660 MOV DS:[PDB_JFN_Table+1],AL
661NOREOUT:
662 return
663
664STRCOMP:
665; Compare ASCIZ DS:SI with ES:DI.
666; SI,DI destroyed.
667 CMPSB
668 retnz ; Strings not equal
669 cmp byte ptr [SI-1],0 ; Hit NUL terminator?
670 retz ; Yes, strings equal
671 jmp short STRCOMP ; Equal so far, keep going
672
673
674
675TRANCODE ENDS
676 END
677
diff --git a/v2.0/source/TCODE4.ASM b/v2.0/source/TCODE4.ASM
new file mode 100644
index 0000000..a8c44a6
--- /dev/null
+++ b/v2.0/source/TCODE4.ASM
@@ -0,0 +1,1002 @@
1TITLE PART4 - COMMAND Transient routines.
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15
16DATARES SEGMENT PUBLIC
17 EXTRN RESTDIR:BYTE
18DATARES ENDS
19
20TRANDATA SEGMENT PUBLIC
21 EXTRN BADDRV:BYTE,BADSWT:BYTE
22 EXTRN BADDAT:BYTE,NEWDAT:BYTE,BADTIM:BYTE
23 EXTRN DMES:BYTE,CURDAT_PRE:BYTE,CURDAT_MID:BYTE,CURDAT_POST:BYTE
24 EXTRN RENERR:BYTE,VERMES_PRE:BYTE,VERMES_POST:BYTE
25 EXTRN DIRHEAD_PRE:BYTE,DIRHEAD_POST:BYTE
26 EXTRN ACRLF:BYTE,BADARGS:BYTE,NOTFND:BYTE
27 EXTRN NEWTIM:BYTE,BADCD:BYTE,BADMKD:BYTE,CLSSTRING:BYTE
28 EXTRN CURTIM_PRE:BYTE,CURTIM_POST:BYTE,PauseMes:BYTE
29 EXTRN BADRMD:BYTE
30TRANDATA ENDS
31
32TRANSPACE SEGMENT PUBLIC
33 EXTRN COMBUF:BYTE,DIRCHAR:BYTE,USERDIR1:BYTE
34 EXTRN BYTCNT:WORD,CURDRV:BYTE,COMSW:WORD,ARGTS:WORD
35 EXTRN LINCNT:BYTE,LINLEN:BYTE,FILECNT:WORD,CHARBUF:BYTE
36 EXTRN DIRBUF:BYTE,BITS:WORD,PATHPOS:WORD
37 EXTRN DESTISDIR:BYTE,DESTTAIL:WORD,DESTINFO:BYTE,FULLSCR:WORD
38 EXTRN INTERNATVARS:BYTE,RESSEG:WORD,TPA:WORD
39TRANSPACE ENDS
40
41
42TRANCODE SEGMENT PUBLIC BYTE
43ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
44
45 EXTRN NOTEST2:NEAR,PRINTVOL:NEAR,Print_Date:NEAR
46 EXTRN CERROR:NEAR,SWITCH:NEAR,PWD:NEAR,SETREST:NEAR,MESTRAN:NEAR
47 EXTRN NOTFNDERR:NEAR,CHKCNT:NEAR,GETKEYSTROKE:NEAR
48 EXTRN SETPATH:NEAR,PATHCRUNCH:NEAR,PRINT:NEAR,ZPRINT:NEAR
49 EXTRN DISPSIZE:NEAR,OUT:NEAR,OUT2:NEAR,ERROR_PRINT:NEAR
50 EXTRN SCANOFF:NEAR,OUTBYTE:NEAR,GETNUM:NEAR,ERROR_OUTPUT:NEAR
51
52
53 PUBLIC PRINT_TIME,CATALOG
54 PUBLIC BADCDERR,PRINT_VERSION,CLS,SAVUDIR,SAVUDIR1
55 PUBLIC TYPEFIL,CRENAME,$RMDIR
56 PUBLIC CTIME,$CHDIR,ONESPC,DATINIT
57 PUBLIC $MKDIR,VERSION,RESTUDIR1
58 PUBLIC RESTUDIR,CRLF2,ERASE
59 PUBLIC volume,date,P_date,PAUSE
60
61
62CATALOG:
63 CALL OKVOLARG
64 MOV AL,"?" ; *.* is default file spec.
65 MOV DI,5DH
66 MOV CX,11
67 REP STOSB
68 MOV SI,81H
69 CALL SWITCH
70 MOV DI,FCB
71 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 0DH ; Parse with default name and extension
72 INT int_command
73
74; Begin by processing any switches that may have been specified.
75; BITS will contain any information about switches that was
76; found when the command line was parsed.
77
78SETSWT:
79 MOV AX,[COMSW] ; Get switches from command
80 OR AX,[ARGTS] ; OR in switches from all of tail
81 MOV [BITS],AX
82 MOV BYTE PTR[FULLSCR],LINPERPAG
83 TEST AL,1 ; Look for W switch
84 MOV AL,NORMPERLIN
85 JZ DIR
86 MOV AL,WIDEPERLIN
87DIR:
88 MOV [LINLEN],AL ; Set number of entries per line
89 MOV [LINCNT],AL
90 MOV [FILECNT],0 ; Keep track of how many files found
91 MOV DX,OFFSET TRANGROUP:DIRBUF ; Set Disk transfer address
92 MOV AH,SET_DMA
93 INT int_command
94 CALL PATHCRUNCH ; Get where we're going
95 PUSHF
96 JNC NOTEST
97 CMP [DESTISDIR],0 ; No CHDIRs worked
98 JZ NOTEST ; see if they should have
99 JMP BADCDERR
100
101NOTEST:
102 MOV SI,FCB
103 MOV DI,OFFSET TRANGROUP:DIRBUF
104 MOV DX,DI
105 MOV CX,12
106 REP MOVSB
107 MOV AH,FCB_OPEN
108 INT int_command
109 MOV DX,OFFSET TRANGROUP:DIRHEAD_PRE ; Print "Directory of"
110 PUSH AX ; save return code
111 CALL PRINT
112 CALL PWD ; print the path
113 MOV DX,OFFSET TRANGROUP:DIRHEAD_POST
114 CALL PRINT
115 POP AX
116 OR AL,AL
117 JNZ OKDODIR ; Go ahead and dir if open fail
118 TEST [DIRBUF+fcb_DEVID],devid_device
119 JZ OKDODIR
120 JMP NOTFNDERR ; Can't DIR a device
121OKDODIR:
122 MOV AH,DIR_SEARCH_FIRST
123 MOV BYTE PTR DS:[FCB-7],0FFH
124 MOV BYTE PTR DS:[FCB-1],010H
125 POPF
126 JC SHOWDIR ; Current dir
127 JZ DOFIRST ; FCB is *.*
128 MOV AL,"?"
129 MOV DI,5DH
130 MOV CX,11
131 REP STOSB ; Remake default FCB
132 MOV SI,[DESTTAIL]
133 MOV DI,FCB
134 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 0EH ; Parse with default drive, name and extension
135 INT int_command
136 MOV AH,DIR_SEARCH_FIRST
137DOFIRST:
138 MOV DX,FCB-7
139 INT int_command
140 PUSH AX
141 CALL RESTUDIR
142 POP AX
143 JMP SHORT DIRSTART
144
145SHOWDIR:
146 MOV DX,FCB-7 ; DX -> Unopened FCB
147 INT int_command ; Search for a file to match FCB
148DIRSTART:
149 INC AL ; FF = file not found
150 JNZ AGAIN ; Either an error or we are finished
151 JMP CHKCNT
152NEXENTJ:
153 JMP NEXENT
154AGAIN:
155 INC [FILECNT] ; Keep track of how many we find
156 MOV SI,OFFSET TRANGROUP:DIRBUF+8 ; SI -> information returned by sys call
157 CALL SHONAME
158 TEST BYTE PTR[BITS],WSWITCH ; W switch set?
159 JNZ NEXENTJ ; If so, no size, date, or time
160 MOV SI,OFFSET TRANGROUP:DIRBUF+8+dir_attr
161 TEST BYTE PTR [SI],attr_directory
162 JZ FILEENT
163 MOV DX,OFFSET TRANGROUP:DMES
164 CALL PRINT
165 JMP SHORT NOFSIZ
166FILEENT:
167 CALL DISPSIZE ; Print size of file
168NOFSIZ:
169 MOV AX,WORD PTR [DIRBUF+8+dir_date] ; Get date
170 OR AX,AX
171 JZ NEXENT ; Skip if no date
172 MOV DI,OFFSET TRANGROUP:CHARBUF
173 PUSH AX
174 MOV AX," "
175 STOSW
176 POP AX
177 MOV BX,AX
178 AND AX,1FH ; get day
179 MOV DL,AL
180 MOV AX,BX
181 MOV CL,5
182 SHR AX,CL ; Align month
183 AND AL,0FH ; Get month
184 MOV DH,AL
185 MOV CL,BH
186 SHR CL,1 ; Align year
187 XOR CH,CH
188 ADD CX,80 ; Relative 1980
189 CMP CL,100
190 JB MILLENIUM
191 SUB CL,100
192MILLENIUM:
193 CALL DATE_CXDX
194 MOV CX,WORD PTR[DIRBUF+8+dir_time] ; Get time
195 JCXZ PRBUF ; Time field present?
196 MOV AX," "
197 STOSW
198 SHR CX,1
199 SHR CX,1
200 SHR CX,1
201 SHR CL,1
202 SHR CL,1 ; Hours in CH, minutes in CL
203 MOV BL,[INTERNATVARS.Time_24]
204 OR BL,80H ; Tell P_TIME called from DIR
205 CALL P_TIME ; Don't care about DX, never used with DIR
206PRBUF:
207 XOR AX,AX
208 STOSB
209 MOV DX,OFFSET TRANGROUP:CHARBUF
210 CALL ZPRINT
211NEXENT:
212 DEC [LINCNT]
213 JNZ SAMLIN
214NEXLIN:
215 MOV AL,[LINLEN]
216 MOV [LINCNT],AL
217 CALL CRLF2
218 TEST BYTE PTR[BITS],PSWITCH ; P switch present?
219 JZ SCROLL ; If not, just continue
220 DEC BYTE PTR[FULLSCR]
221 JNZ SCROLL
222 MOV BYTE PTR[FULLSCR],LINPERPAG
223 MOV DX,OFFSET TRANGROUP:PAUSEMES
224 CALL PRINT
225 CALL GetKeystroke
226 CALL CRLF2
227SCROLL:
228 MOV AH,DIR_SEARCH_NEXT
229 JMP SHOWDIR
230
231SAMLIN:
232 MOV AL,9 ; Output a tab
233 CALL OUT
234 JMP SHORT SCROLL
235
236SHONAME:
237 MOV DI,OFFSET TRANGROUP:CHARBUF
238 MOV CX,8
239 REP MOVSB
240 MOV AL," "
241 STOSB
242 MOV CX,3
243 REP MOVSB
244 XOR AX,AX
245 STOSB
246 PUSH DX
247 MOV DX,OFFSET TRANGROUP:CHARBUF
248 CALL ZPRINT
249 POP DX
250 return
251
252ONESPC:
253 MOV AL," "
254 JMP OUT
255
256CRLF2:
257 PUSH DX
258 MOV DX,OFFSET TRANGROUP:ACRLF
259PR:
260 PUSH DS
261 PUSH CS
262 POP DS
263 CALL PRINT
264 POP DS
265 POP DX
266 return
267
268PAUSE:
269 MOV DX,OFFSET TRANGROUP:PAUSEMES
270 CALL ERROR_PRINT
271 CALL GetKeystroke
272 CALL CRLF2
273 return
274
275ERASE:
276 MOV DX,OFFSET TRANGROUP:BADARGS
277 MOV SI,80H
278 LODSB
279 OR AL,AL
280 JZ ERRJ2
281 CALL SCANOFF
282 CMP AL,13 ; RETURN KEY?
283 JZ ERRJ2 ; IF SO NO PARAMETERS SPECIFIED
284
285ERA1:
286 CALL PATHCRUNCH
287 JNC NOTEST2J
288 CMP [DESTISDIR],0 ; No CHDIRs worked
289 JZ NOTEST2J ; see if they should have
290BADCDERR:
291 MOV DX,OFFSET TRANGROUP:BADCD
292ERRJ2:
293 JMP CERROR
294
295NOTEST2J:
296 JMP NOTEST2
297
298CRENAME:
299 CALL PATHCRUNCH
300 JNC NOTEST3
301 CMP [DESTISDIR],0 ; No CHDIRs worked
302 JZ NOTEST3 ; see if they should have
303 JMP BADCDERR
304
305NOTEST3:
306 MOV SI,[PATHPOS]
307 MOV DI,FCB+10H
308 CALL SCANOFF
309 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
310 INT int_command
311 CMP BYTE PTR DS:[FCB+10H+1]," " ; Check if parameter exists
312 MOV DX,OFFSET TRANGROUP:BADARGS
313 JZ ERRJ ; Error if missing parameter
314 MOV AH,FCB_RENAME
315 MOV DX,FCB
316 INT int_command
317 PUSH AX
318 CALL RESTUDIR
319 POP AX
320 MOV DX,OFFSET TRANGROUP:RENERR
321 INC AL
322 retnz
323ERRJ:
324 JMP CERROR
325
326ASSUME DS:TRANGROUP,ES:TRANGROUP
327TYPEFIL:
328 mov si,81H
329 call SCANOFF ; Skip to first non-delim
330 cmp al,0DH
331 jnz GOTTARG
332 jmp NOARGERR ; No args
333GOTTARG:
334 CALL SETPATH
335 MOV AX,OPEN SHL 8
336 INT int_command
337 MOV DX,OFFSET TRANGROUP:NOTFND
338 JC ERRJ
339 MOV BX,AX ; Handle
340 MOV DS,[TPA]
341 XOR DX,DX
342ASSUME DS:NOTHING
343TYPELP:
344 MOV CX,[BYTCNT]
345 MOV AH,READ
346 INT int_command
347 MOV CX,AX
348 JCXZ RET56
349 PUSH BX
350 MOV BX,1
351 MOV AH,WRITE
352 INT int_command
353 POP BX
354 JC ERROR_OUTPUTJ
355 CMP AX,CX
356 JZ TYPELP
357 DEC CX
358 CMP AX,CX
359 retz ; One less byte OK (^Z)
360ERROR_OUTPUTJ:
361 MOV BX,1
362 MOV AX,IOCTL SHL 8
363 INT int_command
364 TEST DL,devid_ISDEV
365 retnz ; If device, no error message
366 JMP ERROR_OUTPUT
367
368RESTUDIR1:
369 PUSH DS
370 MOV DS,[RESSEG]
371ASSUME DS:RESGROUP
372 CMP [RESTDIR],0
373 POP DS
374ASSUME DS:TRANGROUP
375 retz
376RESTUDIR:
377 MOV DX,OFFSET TRANGROUP:USERDIR1
378 MOV AH,CHDIR
379 INT int_command ; Restore users DIR
380 XOR AL,AL
381 CALL SETREST
382RET56:
383 return
384
385
386VOLUME:
387 mov si,81H
388 call SCANOFF ; Skip to first non-delim
389 CMP BYTE PTR DS:[FCB],0 ;Default drive?
390 JZ CHECKNOARG ;Yes
391 INC SI
392 INC SI ;Skip over d:
393 MOV BX,SI
394 CALL SCANOFF
395 CMP BX,SI
396 JNZ OKVOLARG ; If we skipped some delims at this point, OK
397CHECKNOARG:
398 cmp al,0DH
399 JZ OKVOLARG
400BADVOLARG:
401 MOV DX,OFFSET TRANGROUP:BADDRV
402 JMP CERROR
403
404OKVOLARG:
405 CALL CRLF2
406 PUSH DS
407 POP ES
408 MOV DI,FCB-7 ; Set up extended FCB
409 MOV AX,-1
410 STOSB
411 XOR AX,AX
412 STOSW
413 STOSW
414 STOSB
415 MOV AL,8 ; Look for volume label
416 STOSB
417 INC DI ; Skip drive byte
418 MOV CX,11
419 MOV AL,'?'
420 REP STOSB
421 MOV DX,OFFSET TRANGROUP:DIRBUF
422 MOV AH,SET_DMA
423 INT int_command
424 MOV DX,FCB-7
425 MOV AH,DIR_SEARCH_FIRST
426 INT int_command
427 JMP PRINTVOL
428
429VERSION:
430 CALL CRLF2
431 CALL PRINT_VERSION
432 JMP CRLF2
433
434PRINT_VERSION:
435 MOV DI,OFFSET TRANGROUP:CHARBUF
436 MOV SI,OFFSET TRANGROUP:VERMES_PRE
437 CALL MESTRAN
438 MOV AH,GET_VERSION
439 INT int_command
440 PUSH AX
441 XOR AH,AH
442 MOV CL,10
443 DIV CL
444 MOV CL,4
445 SHL AL,CL
446 OR AL,AH
447 MOV CX,1110H
448 MOV DL,AL
449 CALL OUTBYTE
450 MOV AL,'.'
451 STOSB
452 POP AX
453 MOV AL,AH
454 XOR AH,AH
455 MOV CL,10
456 DIV CL
457 MOV CL,4
458 SHL AL,CL
459 OR AL,AH
460 MOV CX,1010H
461 MOV DL,AL
462 CALL OUTBYTE
463 MOV SI,OFFSET TRANGROUP:VERMES_POST
464 CALL MESTRAN
465 XOR AX,AX
466 STOSB
467 MOV DX,OFFSET TRANGROUP:CHARBUF
468 JMP ZPRINT
469
470ASSUME DS:TRANGROUP
471
472CLS:
473 IF IBMVER
474 MOV BX,1
475 MOV AX,IOCTL SHL 8
476 INT int_command
477 TEST DL,devid_ISDEV
478 JZ ANSICLS ; If a file put out ANSI
479 TEST DL,devid_SPECIAL
480 JZ ANSICLS ; If not special CON, do ANSI
481 MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 29H
482 INT int_command
483 MOV DX,ES
484 MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 20H
485 INT int_command
486 MOV AX,ES
487 CMP DX,AX
488 JA ANSICLS ; If not default driver, do ANSI
489 MOV AH,11 ; Set overscan to black
490 XOR BX,BX
491 INT 16
492 MOV AH,15
493 INT 16
494 MOV DL,AH
495 DEC DL
496
497 IF KANJI
498 MOV DH,23
499 ELSE
500 MOV DH,25
501 ENDIF
502
503 XOR AX,AX
504 MOV CX,AX
505
506 IF KANJI
507 MOV BH,0
508 ELSE
509 MOV BH,7
510 ENDIF
511
512 MOV AH,6
513 INT 16
514 XOR DX,DX
515 MOV BH,0
516 MOV AH,2
517 INT 16
518 return
519
520ANSICLS:
521 ENDIF
522
523 MOV SI,OFFSET TRANGROUP:CLSSTRING
524 LODSB
525 MOV CL,AL
526 XOR CH,CH
527 MOV AH,RAW_CON_IO
528CLRLOOP:
529 LODSB
530 MOV DL,AL
531 INT int_command
532 LOOP CLRLOOP
533 return
534
535$CHDIR:
536 MOV AX,[COMSW]
537 OR AX,[ARGTS]
538 MOV DX,OFFSET TRANGROUP:BADSWT
539 JNZ CERRORJ3
540 mov si,81H
541 call SCANOFF ; Skip to first non-delim
542 cmp al,0DH
543 jz PWDJ ; No args
544 inc si ; Skip first char
545 lodsw
546 cmp ax,(0DH SHL 8) OR ':' ; d:<CR> ?
547 jnz REALCD ; no
548PWDJ:
549 jmp PWD ; Drive only specified
550REALCD:
551 CALL SETPATH
552 TEST [DESTINFO],2
553 JNZ BADCDERRJ
554 MOV AH,CHDIR
555 INT int_command
556 retnc
557BADCDERRJ:
558 JMP BADCDERR
559
560$MKDIR:
561 CALL SETRMMK
562 JNZ BADMDERR
563 MOV AH,MKDIR
564 INT int_command
565 retnc
566BADMDERR:
567 MOV DX,OFFSET TRANGROUP:BADMKD
568CERRORJ3:
569 JMP CERROR
570
571NOARGERR:
572 MOV DX,OFFSET TRANGROUP:BADARGS
573 JMP SHORT CERRORJ3
574
575SETRMMK:
576 mov si,81H
577 call SCANOFF ; Skip to first non-delim
578 cmp al,0DH
579 jz NOARGERR ; No args
580 MOV AX,[COMSW]
581 OR AX,[ARGTS]
582 MOV DX,OFFSET TRANGROUP:BADSWT
583 JNZ CERRORJ3
584 CALL SETPATH
585 TEST [DESTINFO],2
586 return
587
588$RMDIR:
589 CALL SETRMMK
590 JNZ BADRDERR
591 MOV AH,RMDIR
592 INT int_command
593 retnc
594BADRDERR:
595 MOV DX,OFFSET TRANGROUP:BADRMD
596 JMP CERROR
597
598SAVUDIR:
599; DL is drive number A=1
600 MOV DI,OFFSET TRANGROUP:USERDIR1
601SAVUDIR1:
602 MOV AL,DL
603 ADD AL,'@'
604 CMP AL,'@'
605 JNZ GOTUDRV
606 ADD AL,[CURDRV]
607 INC AL ; A = 1
608GOTUDRV:
609 STOSB
610 MOV AH,[DIRCHAR]
611 MOV AL,DRVCHAR
612 STOSW
613 PUSH ES
614 POP DS
615ASSUME DS:NOTHING
616 MOV SI,DI
617 MOV AH,CURRENT_DIR ; Get the Directory Text
618 INT int_command
619 retc
620 PUSH CS
621 POP DS
622ASSUME DS:TRANGROUP
623 return
624
625ASSUME DS:TRANGROUP,ES:TRANGROUP
626
627; Date and time are set during initialization and use
628; this routines since they need to do a long return
629
630DATINIT PROC FAR
631 PUSH ES
632 PUSH DS ; Going to use the previous stack
633 MOV AX,CS ; Set up the appropriate segment registers
634 MOV ES,AX
635 MOV DS,AX
636 MOV DX,OFFSET TRANGROUP:INTERNATVARS ;Set up internat vars
637 MOV AX,INTERNATIONAL SHL 8
638 INT 21H
639 MOV WORD PTR DS:[81H],13 ; Want to prompt for date during initialization
640 MOV [COMBUF],COMBUFLEN ; Init COMBUF
641 MOV WORD PTR [COMBUF+1],0D01H
642 CALL DATE
643 CALL CTIME
644 POP DS
645 POP ES
646 RET
647DATINIT ENDP
648
649; DATE - Gets and sets the time
650
651DATE_CXDX:
652 MOV BX,CX
653P_DATE:
654 MOV AX,BX
655 MOV CX,DX
656 MOV DL,100
657 DIV DL
658 XCHG AL,AH
659 XCHG AX,DX
660 MOV BH,"0"-" " ; Enable leading zero suppression
661 MOV AX,WORD PTR [INTERNATVARS.Date_tim_format]
662 OR AX,AX
663 JZ USPDAT
664 DEC AX
665 JZ EUPDAT
666 MOV BH,0 ; Disable leading zero suppression
667 CALL P_YR
668 CALL P_DSEP
669 CALL P_MON
670 CALL P_DSEP
671 CALL P_DAY
672 return
673
674USPDAT:
675 CALL P_MON
676 CALL P_DSEP
677 CALL P_DAY
678PLST:
679 CALL P_DSEP
680 CALL P_YR
681 return
682
683EUPDAT:
684 CALL P_DAY
685 CALL P_DSEP
686 CALL P_MON
687 JMP PLST
688
689P_MON:
690 MOV AL,CH
691 CALL OUT2
692 return
693
694P_DSEP:
695 MOV AL,BYTE PTR [INTERNATVARS.Date_sep]
696 STOSB
697 return
698
699P_DAY:
700 MOV AL,CL
701 CALL OUT2
702 return
703
704P_YR:
705 MOV AL,DH
706 OR AL,AL
707 JZ TWODIGYR ; Two instead of 4 digit year
708 CALL OUT2
709TWODIGYR:
710 MOV AL,DL
711 CALL OUT2
712 return
713
714DATE:
715 MOV SI,81H ; Accepting argument for date inline
716 CALL SCANOFF
717 CMP AL,13
718 JZ PRMTDAT
719 JMP COMDAT
720
721PRMTDAT:
722 MOV DX,OFFSET TRANGROUP:CURDAT_PRE
723 CALL PRINT ; Print "Current date is "
724 CALL PRINT_DATE
725 MOV DX,OFFSET TRANGROUP:CURDAT_POST
726 CALL PRINT
727GETDAT:
728 MOV DX,OFFSET TRANGROUP:NEWDAT
729 CALL ERROR_PRINT ; Print "Enter new date: "
730 MOV AH,STD_CON_STRING_INPUT
731 MOV DX,OFFSET TRANGROUP:COMBUF
732 INT int_command ; Get input line
733 CALL CRLF2
734 MOV SI,OFFSET TRANGROUP:COMBUF+2
735 CMP BYTE PTR[SI],13 ; Check if new date entered
736 retz
737COMDAT:
738 MOV AX,WORD PTR [INTERNATVARS.Date_tim_format]
739 OR AX,AX
740 JZ USSDAT
741 DEC AX
742 JZ EUSDAT
743 CALL GET_YR
744 JC DATERRJ
745 CALL GET_DSEP
746 JC DATERRJ
747 CALL GET_MON
748 JC DATERRJ
749 CALL GET_DSEP
750 JC DATERRJ
751 CALL GET_DAY
752DAT_SET:
753 JC DATERR
754 LODSB
755 CMP AL,13
756 JNZ DATERR
757 MOV AH,SET_DATE
758 INT int_command
759 OR AL,AL
760 JNZ DATERR
761 return
762
763USSDAT:
764 CALL GET_MON
765 JC DATERR
766 CALL GET_DSEP
767DATERRJ:
768 JC DATERR
769 CALL GET_DAY
770TGET:
771 JC DATERR
772 CALL GET_DSEP
773 JC DATERR
774 CALL GET_YR
775 JMP DAT_SET
776
777EUSDAT:
778 CALL GET_DAY
779 JC DATERR
780 CALL GET_DSEP
781 JC DATERR
782 CALL GET_MON
783 JMP TGET
784
785GET_MON:
786 CALL GETNUM ; Get one or two digit number
787 retc
788 MOV DH,AH ; Put in position
789 return
790
791GET_DAY:
792 CALL GETNUM
793 MOV DL,AH ; Put in position
794 return
795
796GET_YR:
797 CALL GETNUM
798 retc
799 MOV CX,1900
800 CALL GET_DSEP
801 PUSHF
802 DEC SI
803 POPF
804 JZ BIAS
805 CMP BYTE PTR[SI],13
806 JZ BIAS
807 MOV AL,100
808 MUL AH
809 MOV CX,AX
810 CALL GETNUM
811 retc
812BIAS:
813 MOV AL,AH
814 MOV AH,0
815 ADD CX,AX
816
817 IF IBM AND KANJI
818;
819; Gross hack for PC-J machine: CMOS clock cannot handle years after 2079
820;
821 CMP CX,2080
822 JB YearOk
823 STC
824 return
825YearOk: CLC
826 ENDIF
827 return
828
829DATERR:
830 MOV DX,OFFSET TRANGROUP:BADDAT
831 CALL PRINT
832 JMP GETDAT
833
834GET_DSEP:
835 LODSB
836 CMP AL,'/'
837 retz
838 CMP AL,'.'
839 retz
840 CMP AL,'-'
841 retz
842 STC
843 return
844
845; TIME gets and sets the time
846
847CTIME:
848 MOV SI,81H ; Accepting argument for time inline
849 CALL SCANOFF
850 CMP AL,13
851 JZ PRMTTIM
852 MOV BX,".:"
853 CALL INLINE
854 JMP COMTIM
855
856PRINT_TIME:
857 MOV AH,GET_TIME
858 INT int_command ; Get time in CX:DX
859 PUSH DI
860 PUSH ES
861 PUSH CS
862 POP ES
863 MOV DI,OFFSET TRANGROUP:CHARBUF
864 MOV BL,1 ; Always 24 hour time
865 CALL P_TIME
866 XOR AX,AX
867 STOSB
868 MOV DX,OFFSET TRANGROUP:CHARBUF
869 CALL ZPRINT
870 POP ES
871 POP DI
872 return
873
874P_TIME:
875 MOV AL,CH
876 TEST BL,07FH ; Ignore high bit
877 JNZ T24 ; 24 hr time?
878 MOV BH,"a" ; Assume A.M.
879 CMP AL,12 ; In the afternoon?
880 JB MORN
881 MOV BH,"p"
882 JE MORN
883 SUB AL,12 ; Keep it to 12 hours or less
884MORN:
885 OR AL,AL ; Before 1 am?
886 JNZ T24
887 MOV AL,12
888T24:
889 PUSH BX
890 MOV BH,"0"-" " ; Enable leading zero suppression
891 CALL OUT2
892 CALL P_TSEP
893 MOV AL,CL
894 CALL OUT2
895 POP BX
896 PUSH BX
897 TEST BL,80H
898 JNZ PAP ; If from DIR, go directly to am pm
899 MOV BH,0 ; Disable leading zero suppression
900 CALL P_TSEP
901 MOV AL,DH
902 CALL OUT2
903 IF NOT IBMJAPAN
904 MOV AL,"."
905 STOSB
906 MOV AL,DL
907 CALL OUT2
908 ENDIF
909PAP:
910 POP BX
911 TEST BL,07FH ; Ignore high bit
912 retnz ; 24 hour time, no am pm
913 MOV AL,BH
914 STOSB ; Store 'a' or 'p'
915 return
916
917P_TSEP:
918 MOV AL,[INTERNATVARS.Time_sep]
919 STOSB
920 return
921
922
923PRMTTIM:
924 MOV DX,OFFSET TRANGROUP:CURTIM_PRE
925 CALL PRINT ; Print "Current time is "
926 CALL PRINT_TIME
927 MOV DX,OFFSET TRANGROUP:CURTIM_POST
928 CALL PRINT
929GETTIM:
930 XOR CX,CX ; Initialize hours and minutes to zero
931 MOV DX,OFFSET TRANGROUP:NEWTIM
932 MOV BX,".:"
933 CALL GETBUF
934COMTIM:
935 retz ; If no time present, don't change it
936 JC TIMERR
937 MOV CX,DX
938 XOR DX,DX
939 LODSB
940 CMP AL,13
941 JZ SAVTIM
942 CMP AL,BL
943 JZ GOTSEC
944 CMP AL,BH
945 JNZ TIMERR
946GOTSEC:
947 CALL GETNUM
948 JC TIMERR
949 MOV DH,AH ; Position seconds
950 LODSB
951 CMP AL,13
952 JZ SAVTIM
953 CMP AL,"."
954 JNZ TIMERR
955 CALL GETNUM
956 JC TIMERR
957 MOV DL,AH
958 LODSB
959 CMP AL,13
960 JNZ TIMERR
961SAVTIM:
962 MOV AH,SET_TIME
963 INT int_command
964 OR AL,AL
965 retz ; Error in time?
966TIMERR:
967 MOV DX,OFFSET TRANGROUP:BADTIM
968 CALL PRINT ; Print error message
969 JMP GETTIM ; Try again
970
971GETBUF:
972 CALL ERROR_PRINT ; Print "Enter new time: "
973 MOV AH,STD_CON_STRING_INPUT
974 MOV DX,OFFSET TRANGROUP:COMBUF
975 INT int_command ; Get input line
976 CALL CRLF2
977 MOV SI,OFFSET TRANGROUP:COMBUF+2
978 CMP BYTE PTR[SI],13 ; Check if new time entered
979 retz
980INLINE:
981 CALL GETNUM ; Get one or two digit number
982 retc
983 MOV DH,AH ; Put in position
984 LODSB
985 CMP AL,BL
986 JZ NEXT
987 CMP AL,BH
988 JZ NEXT
989 DEC SI ; Clears zero flag
990 CLC
991 MOV DL,0
992 return ; Time may have only an hour specified
993
994NEXT:
995 CALL GETNUM
996 MOV DL,AH ; Put in position
997 return
998
999
1000TRANCODE ENDS
1001 END
1002
diff --git a/v2.0/source/TCODE5.ASM b/v2.0/source/TCODE5.ASM
new file mode 100644
index 0000000..63fb3cf
--- /dev/null
+++ b/v2.0/source/TCODE5.ASM
@@ -0,0 +1,953 @@
1TITLE PART5 - COMMAND Transient routines.
2
3 INCLUDE COMSW.ASM
4
5.xlist
6.xcref
7 INCLUDE DOSSYM.ASM
8 INCLUDE DEVSYM.ASM
9 INCLUDE COMSEG.ASM
10.list
11.cref
12
13 INCLUDE COMEQU.ASM
14
15CODERES SEGMENT PUBLIC
16
17 IF IBMVER
18 EXTRN EXEC_WAIT:NEAR
19 ENDIF
20
21CODERES ENDS
22
23
24DATARES SEGMENT PUBLIC
25 EXTRN BATCH:WORD,BATLOC:DWORD,BATBYT:BYTE,ECHOFLAG:BYTE
26 EXTRN SINGLECOM:WORD,RE_OUTSTR:BYTE,PIPEFLAG:BYTE,PIPEPTR:WORD
27 EXTRN RE_INSTR:BYTE,RE_OUT_APP:BYTE,PARMBUF:BYTE,PIPESTR:BYTE
28 EXTRN LTPA:WORD,ENVIRSEG:WORD
29DATARES ENDS
30
31TRANDATA SEGMENT PUBLIC
32 EXTRN PIPEEMES:BYTE,NULPATH:BYTE,NOSPACE:BYTE
33 EXTRN DBACK:BYTE,PROMPT_TABLE:BYTE
34TRANDATA ENDS
35
36TRANSPACE SEGMENT PUBLIC
37 EXTRN PATHCNT:WORD,PATHPOS:WORD,PATHSW:WORD
38 EXTRN DESTISDIR:BYTE,DESTTAIL:WORD,DESTINFO:BYTE
39 EXTRN BATHAND:WORD,RESSEG:WORD,TPA:WORD,SWITCHAR:BYTE
40 EXTRN BYTCNT:WORD,COMBUF:BYTE,DIRBUF:BYTE,CHARBUF:BYTE
41
42
43 IF KANJI
44 EXTRN KPARSE:BYTE
45 ENDIF
46
47TRANSPACE ENDS
48
49
50TRANCODE SEGMENT PUBLIC BYTE
51ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
52
53 IF KANJI
54 EXTRN TESTKANJ:NEAR
55 ENDIF
56
57 EXTRN CERROR:NEAR,UPCONV:NEAR,PIPEERRSYN:NEAR,SETREST1:NEAR
58 EXTRN SWITCH:NEAR,SETREST1:NEAR,BATCLOSE:NEAR,MOVE_NAME:NEAR
59 EXTRN FIND_PROMPT:NEAR,FIND_PATH:NEAR,DELETE_PATH:NEAR
60 EXTRN STORE_CHAR:NEAR,SCAN_DOUBLE_NULL:NEAR,SCASB2:NEAR
61 EXTRN PRINT_DRIVE:NEAR,SAVUDIR:NEAR,CRLF2:NEAR,PAUSE:NEAR
62
63 PUBLIC PRINT_B,PRINT_G,DISPSIZE,GETNUM,OUTBYTE
64 PUBLIC DELIM,OUT,OUT2,SETPATH,PATHCRUNCH
65 PUBLIC CRPRINT,SCANOFF,FCB_TO_ASCZ
66 PUBLIC PRINT_L,PATH,PATHCHRCMP,PRINT_ESC,PRINT_BACK
67 PUBLIC PRINT_EQ,PRINT,ZPRINT,PRINT_PROMPT
68 PUBLIC DISP32BITS,ERROR_PRINT,ERROR_OUTPUT
69 PUBLIC FREE_TPA,ALLOC_TPA,PRESCAN,GETBATBYT
70
71
72FREE_TPA:
73ASSUME DS:TRANGROUP,ES:NOTHING
74 PUSH ES
75 MOV ES,[TPA]
76 MOV AH,DEALLOC
77 INT int_command ; Make lots of free memory
78 POP ES
79 return
80
81ALLOC_TPA:
82ASSUME DS:TRANGROUP,ES:RESGROUP
83 MOV BX,0FFFFH ; Re-allocate the transient
84 MOV AH,ALLOC
85 INT int_command
86 MOV AH,ALLOC
87 INT int_command
88 MOV [LTPA],AX ; Re-compute evrything
89 MOV [TPA],AX
90 MOV BX,AX
91 MOV AX,CS
92 SUB AX,BX
93 MOV DX,16
94 MUL DX
95 OR DX,DX
96 JZ SAVSIZ2
97 MOV AX,-1
98SAVSIZ2:
99 MOV [BYTCNT],AX
100 return
101
102
103PRESCAN: ; Cook the input buffer
104ASSUME DS:TRANGROUP,ES:TRANGROUP
105 XOR CX,CX
106 MOV ES,[RESSEG]
107ASSUME ES:RESGROUP
108 MOV SI,OFFSET TRANGROUP:COMBUF+2
109 MOV DI,SI
110
111CountQuotes:
112 LODSB ; get a byte
113 CMP AL,22h ; is it a quote?
114 JNZ CountEnd ; no, try for end of road
115 INC CH ; bump count
116 JMP CountQuotes ; go get next char
117CountEnd:
118 CMP AL,13 ; end of road?
119 JNZ CountQuotes ; no, go back for next char
120
121 IF KANJI
122 PUSH CX ; save count
123 MOV SI,DI ; get back beginning of buffer
124KanjiScan:
125 LODSB ; get a byte
126 CALL TestKanj ; is it a leadin byte
127 JZ KanjiQuote ; no, check for quotes
128 MOV AH,AL ; save leadin
129 LODSB ; get trailing byte
130 CMP AX,8140h ; is it Kanji space
131 JNZ KanjiScan ; no, go get next
132 MOV [SI-2],2020h ; replace with spaces
133 JMP KanjiScan ; go get next char
134KanjiQuote:
135 CMP AL,22h ; beginning of quoted string
136 JNZ KanjiEnd ; no, check for end
137 DEC CH ; drop count
138 JZ KanjiScan ; if count is zero, no quoting
139KanjiQuoteLoop:
140 LODSB ; get next byte
141 CMP AL,22h ; is it another quote
142 JNZ KanjiQuoteLoop ; no, get another
143 DEC CH ; yes, drop count
144 JMP KanjiScan ; go get next char
145KanjiEnd:
146 CMP AL,13 ; end of line character?
147 JNZ KanjiScan ; go back to beginning
148 POP CX ; get back original count
149 ENDIF
150
151 MOV SI,DI ; restore pointer to begining
152PRESCANLP:
153 LODSB
154
155 IF KANJI
156 CALL TESTKANJ
157 JZ NOTKANJ6
158 MOV [DI],AL
159 INC DI ; fake STOSB into DS
160 LODSB ; grab second byte
161 MOV [DI],AL ; fake stosb into DS
162 INC DI
163 INC CL
164 INC CL
165 JMP PRESCANLP
166NOTKANJ6:
167 ENDIF
168
169 CMP AL,22H ; " character
170 JNZ TRYGREATER
171 DEC CH
172 JZ TRYGREATER
173QLOOP:
174 MOV [DI],AL
175 INC DI
176 INC CL
177 LODSB
178 CMP AL,22H ; " character
179 JNZ QLOOP
180 DEC CH
181
182TRYGREATER:
183 CMP AL,'>'
184 JNZ NOOUT
185 CMP BYTE PTR [SI],'>'
186 JNZ NOAPPND
187 LODSB
188 INC [RE_OUT_APP] ; Flag >>
189NOAPPND:
190 CALL SCANOFF
191 CMP AL,0DH
192 JNZ GOTREOFIL
193 MOV WORD PTR [RE_OUTSTR],09H ; Cause an error later
194 JMP SHORT PRESCANEND
195GOTREOFIL:
196 PUSH DI
197 MOV DI,OFFSET RESGROUP:RE_OUTSTR
198SETREOUTSTR: ; Get the output redirection name
199 LODSB
200 CMP AL,0DH
201 JZ GOTRESTR
202 CALL DELIM
203 JZ GOTRESTR
204 CMP AL,[SWITCHAR]
205 JZ GOTRESTR
206 STOSB ; store it into resgroup
207 JMP SHORT SETREOUTSTR
208
209NOOUT:
210 CMP AL,'<'
211 JNZ CHKPIPE
212 CALL SCANOFF
213 CMP AL,0DH
214 JNZ GOTREIFIL
215 MOV WORD PTR [RE_INSTR],09H ; Cause an error later
216 JMP SHORT PRESCANEND
217GOTREIFIL:
218 PUSH DI
219 MOV DI,OFFSET RESGROUP:RE_INSTR
220 JMP SHORT SETREOUTSTR ; Get the input redirection name
221
222CHKPIPE:
223 MOV AH,AL
224 CMP AH,'|'
225 JNZ CONTPRESCAN
226 INC [PIPEFLAG]
227 CALL SCANOFF
228 CMP AL,0DH
229 JZ PIPEERRSYNJ5
230 CMP AL,'|' ; Double '|'?
231 JNZ CONTPRESCAN
232PIPEERRSYNJ5:
233 PUSH ES
234 POP DS ; DS->RESGROUP
235 JMP PIPEERRSYN
236
237GOTRESTR:
238 XCHG AH,AL
239 CMP BYTE PTR ES:[DI-1],':' ; Trailing ':' OK on devices
240 JNZ NOTTRAILCOL
241 DEC DI ; Back up over trailing ':'
242NOTTRAILCOL:
243 XOR AL,AL
244 STOSB ; NUL terminate the string
245 POP DI ; Remember the start
246CONTPRESCAN:
247 MOV [DI],AH ; "delete" the redirection string
248 INC DI
249 CMP AH,0DH
250 JZ PRESCANEND
251 INC CL
252 JMP PRESCANLP
253PRESCANEND:
254 CMP [PIPEFLAG],0
255 JZ ISNOPIPE
256 MOV DI,OFFSET RESGROUP:PIPESTR
257 MOV [PIPEPTR],DI
258 MOV SI,OFFSET TRANGROUP:COMBUF+2
259 CALL SCANOFF
260PIPESETLP: ; Transfer the pipe into the resident pipe buffer
261 LODSB
262 STOSB
263 CMP AL,0DH
264 JNZ PIPESETLP
265ISNOPIPE:
266 MOV [COMBUF+1],CL
267 CMP [PIPEFLAG],0
268 PUSH CS
269 POP ES
270 return
271
272ASSUME DS:TRANGROUP,ES:TRANGROUP
273
274PATHCHRCMP:
275 CMP [SWITCHAR],'/'
276 JZ NOSLASHT
277 CMP AL,'/'
278 retz
279NOSLASHT:
280 CMP AL,'\'
281 return
282
283PATHCRUNCH:
284; Drive taken from FCB
285; DI = Dirsave pointer
286;
287; Zero set if path dir, CHDIR to this dir, FCB filled with ?
288; NZ set if path/file, CHDIR to file, FCB has file (parsed fill ' ')
289; [DESTTAIL] points to parse point
290; Carry set if no CHDIRs worked, FCB not altered.
291; DESTISDIR set non zero if PATHCHRs in path (via SETPATH)
292
293 MOV DL,DS:[FCB]
294 CALL SAVUDIR
295 CALL SETPATH
296 TEST [DESTINFO],2
297 JNZ TRYPEEL ; If ? or * cannot be pure dir
298 MOV AH,CHDIR
299 INT int_command
300 JC TRYPEEL
301 CALL SETREST1
302 MOV AL,"?" ; *.* is default file spec if pure dir
303 MOV DI,5DH
304 MOV CX,11
305 REP STOSB
306 XOR AL,AL ; Set zero
307 return
308
309TRYPEEL:
310 MOV SI,[PATHPOS]
311 DEC SI ; Point at NUL
312 MOV AL,[SI-1]
313
314 IF KANJI
315 CMP [KPARSE],0
316 JNZ DELSTRT ; Last char is second KANJI byte, might be '\'
317 ENDIF
318
319 CALL PATHCHRCMP
320 JZ PEELFAIL ; Trailing '/'
321
322 IF KANJI
323DELSTRT:
324 MOV CX,SI
325 MOV SI,DX
326 PUSH DX
327DELLOOP:
328 CMP SI,CX
329 JZ GOTDELE
330 LODSB
331 CALL TESTKANJ
332 JZ NOTKANJ8
333 INC SI
334 JMP DELLOOP
335
336NOTKANJ8:
337 CALL PATHCHRCMP
338 JNZ DELLOOP
339 MOV DX,SI
340 DEC DX
341 JMP DELLOOP
342
343GOTDELE:
344 MOV SI,DX
345 POP DX
346 CMP SI,DX
347 JZ BADRET
348 MOV CX,SI
349 MOV SI,DX
350DELLOOP2: ; Set value of KPARSE
351 CMP SI,CX
352 JZ KSET
353 MOV [KPARSE],0
354 LODSB
355 CALL TESTKANJ
356 JZ DELLOOP2
357 INC SI
358 INC [KPARSE]
359 JMP DELLOOP2
360
361KSET:
362 ELSE
363DELLOOP:
364 CMP SI,DX
365 JZ BADRET
366 MOV AL,[SI]
367 CALL PATHCHRCMP
368 JZ TRYCD
369 DEC SI
370 JMP SHORT DELLOOP
371 ENDIF
372
373TRYCD:
374 CMP BYTE PTR [SI+1],'.'
375 JZ PEELFAIL ; If . or .., pure cd should have worked
376 mov al,[si-1]
377 CMP al,DRVCHAR ; Special case dDRVCHAR,DIRCHARfile
378 JZ BADRET
379
380 IF KANJI
381 CMP [KPARSE],0
382 JNZ NOTDOUBLESL ; Last char is second KANJI byte, might be '\'
383 ENDIF
384
385 CALL PATHCHRCMP
386 JNZ NOTDOUBLESL
387PEELFAIL:
388 STC ; //
389 return
390NOTDOUBLESL:
391 MOV BYTE PTR [SI],0
392 MOV AH,CHDIR
393 INT int_command
394 JNC CDSUCC
395 return
396
397BADRET:
398 MOV AL,[SI]
399 CALL PATHCHRCMP ; Special case 'DIRCHAR'file
400 STC
401 retnz
402 XOR BL,BL
403 XCHG BL,[SI+1]
404 MOV AH,CHDIR
405 INT int_command
406 retc
407 MOV [SI+1],BL
408CDSUCC:
409 CALL SETREST1
410 INC SI ; Reset zero
411 MOV [DESTTAIL],SI
412 MOV DI,FCB
413 MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 02H ; Parse with default drive
414 INT int_command
415 return
416
417
418DISPSIZE:
419 MOV SI,WORD PTR[DIRBUF+29+7]
420 MOV DI,WORD PTR[DIRBUF+31+7]
421
422DISP32BITS:
423; Prints the 32-bit number DI:SI on the console in decimal. Uses a total
424; of 9 digit positions with leading blanks.
425 XOR AX,AX
426 MOV BX,AX
427 MOV BP,AX
428 MOV CX,32
429CONVLP:
430 SHL SI,1
431 RCL DI,1
432 XCHG AX,BP
433 CALL CONVWRD
434 XCHG AX,BP
435 XCHG AX,BX
436 CALL CONVWRD
437 XCHG AX,BX
438 ADC AL,0
439 LOOP CONVLP
440
441; Conversion complete. Print 9-digit number.
442
443 MOV DI,OFFSET TRANGROUP:CHARBUF
444 MOV CX,1810H ; Allow leading zero blanking for 8 digits
445 XCHG DX,AX
446 CALL DIGIT
447 XCHG AX,BX
448 CALL OUTWORD
449 XCHG AX,BP
450 CALL OUTWORD
451 XOR AX,AX
452 STOSB
453 MOV DX,OFFSET TRANGROUP:CHARBUF
454 JMP ZPRINT
455
456OUTWORD:
457 PUSH AX
458 MOV DL,AH
459 CALL OUTBYTE
460 POP DX
461OUTBYTE:
462 MOV DH,DL
463 SHR DL,1
464 SHR DL,1
465 SHR DL,1
466 SHR DL,1
467 CALL DIGIT
468 MOV DL,DH
469DIGIT:
470 AND DL,0FH
471 JZ BLANKZER
472 MOV CL,0
473BLANKZER:
474 DEC CH
475 AND CL,CH
476 OR DL,30H
477 SUB DL,CL
478 MOV AL,DL
479 STOSB
480 return
481
482CONVWRD:
483 ADC AL,AL
484 DAA
485 XCHG AL,AH
486 ADC AL,AL
487 DAA
488 XCHG AL,AH
489 return
490
491
492GETBATBYT:
493; Get one byte from the batch file and return it in AL. End-of-file
494; returns <CR> and ends batch mode. DS must be set to resident segment.
495; AH, CX, DX destroyed.
496ASSUME DS:RESGROUP
497 ADD WORD PTR [BATLOC],1 ; Add one to file location
498 ADC WORD PTR [BATLOC+2],0
499 PUSH BX
500 MOV DX,OFFSET RESGROUP:BATBYT
501 MOV BX,[BATHAND]
502 MOV AH,READ
503 MOV CX,1
504 INT int_command ; Get one more byte from batch file
505 POP BX
506 MOV CX,AX
507 JC BATEOF
508 JCXZ BATEOF
509 MOV AL,[BATBYT]
510 CMP AL,1AH
511 retnz
512BATEOF:
513 PUSH ES
514 MOV ES,[BATCH] ; Turn off batch
515 MOV AH,DEALLOC
516 INT int_command ; free up the batch piece
517 POP ES
518 MOV [BATCH],0 ; AFTER DEALLOC in case of ^C
519 CALL BATCLOSE
520 MOV AL,0DH ; If end-of-file, then end of line
521 CMP [SINGLECOM],0FFF0H ; See if we need to set SINGLECOM
522 JNZ NOSETSING2
523 MOV [SINGLECOM],-1 ; Cause termination
524NOSETSING2:
525 MOV [ECHOFLAG],1
526 return
527ASSUME DS:TRANGROUP
528
529SCANOFF:
530 LODSB
531 CALL DELIM
532 JZ SCANOFF
533 DEC SI ; Point to first non-delimiter
534 return
535
536DELIM:
537 CMP AL," "
538 retz
539 CMP AL,"="
540 retz
541 CMP AL,","
542 retz
543 CMP AL,";"
544 retz
545 CMP AL,9 ; Check for TAB character
546 return
547
548
549PRINT_PROMPT:
550 PUSH DS
551 PUSH CS
552 POP DS ; MAKE SURE DS IS IN TRANGROUP
553
554 PUSH ES
555 CALL FIND_PROMPT ; LOOK FOR PROMPT STRING
556 JC PP0 ; CAN'T FIND ONE
557 CMP BYTE PTR ES:[DI],0
558 JNZ PP1
559PP0:
560 CALL PRINT_DRIVE ; USE DEFAULT PROMPT
561 MOV AL,SYM
562 CALL OUT
563 JMP SHORT PP5
564
565PP1:
566 MOV AL,ES:[DI] ; GET A CHAR
567 INC DI
568 OR AL,AL
569 JZ PP5 ; NUL TERMINATED
570 CMP AL,"$" ; META CHARACTER?
571 JZ PP2 ; NOPE
572PPP1:
573 CALL OUT
574 JMP PP1
575
576PP2:
577 MOV AL,ES:[DI]
578 INC DI
579 MOV BX,OFFSET TRANGROUP:PROMPT_TABLE-3
580 OR AL,AL
581 JZ PP5
582
583PP3:
584 ADD BX,3
585 CALL UPCONV
586 CMP AL,[BX]
587 JZ PP4
588 CMP BYTE PTR [BX],0
589 JNZ PP3
590 JMP PP1
591
592PP4:
593 PUSH ES
594 PUSH DI
595 PUSH CS
596 POP ES
597 CALL [BX+1]
598 POP DI
599 POP ES
600 JMP PP1
601
602PP5:
603 POP ES ; RESTORE SEGMENTS
604 POP DS
605 return
606
607PRINT_BACK:
608 MOV DX,OFFSET TRANGROUP:DBACK
609 JMP ZPRINT
610
611PRINT_EQ:
612 MOV AL,"="
613 JMP SHORT OUTV
614PRINT_ESC:
615 MOV AL,1BH
616 JMP SHORT OUTV
617PRINT_G:
618 MOV AL,">"
619 JMP SHORT OUTV
620PRINT_L:
621 MOV AL,"<"
622 JMP SHORT OUTV
623PRINT_B:
624 MOV AL,"|"
625OUTV:
626 JMP OUT
627
628SETPATH:
629; Get an ASCIZ argument from the unformatted parms
630; DESTISDIR set if pathchars in string
631; DESTINFO set if ? or * in string
632 MOV SI,80H
633 LODSB
634 XOR AH,AH
635 MOV [PATHCNT],AX
636 MOV [PATHPOS],SI
637GETPATH:
638 MOV [DESTINFO],0
639 MOV [DESTISDIR],0
640 MOV SI,[PATHPOS]
641 MOV CX,[PATHCNT]
642 MOV DX,SI
643 JCXZ PATHDONE
644 PUSH CX
645 PUSH SI
646 CALL SWITCH
647 MOV [PATHSW],AX
648 POP BX
649 SUB BX,SI
650 POP CX
651 ADD CX,BX
652 MOV DX,SI
653SKIPPATH:
654
655 IF KANJI
656 MOV [KPARSE],0
657SKIPPATH2:
658 ENDIF
659
660 JCXZ PATHDONE
661 DEC CX
662 LODSB
663
664 IF KANJI
665 CALL TESTKANJ
666 JZ TESTPPSEP
667 DEC CX
668 INC SI
669 INC [KPARSE]
670 JMP SKIPPATH2
671
672TESTPPSEP:
673 ENDIF
674
675 CALL PATHCHRCMP
676 JNZ TESTPMETA
677 INC [DESTISDIR]
678TESTPMETA:
679 CMP AL,'?'
680 JNZ TESTPSTAR
681 OR [DESTINFO],2
682TESTPSTAR:
683 CMP AL,'*'
684 JNZ TESTPDELIM
685 OR [DESTINFO],2
686TESTPDELIM:
687 CALL DELIM
688 JZ PATHDONEDEC
689 CMP AL,[SWITCHAR]
690 JNZ SKIPPATH
691PATHDONEDEC:
692 DEC SI
693PATHDONE:
694 XOR AL,AL
695 XCHG AL,[SI]
696 INC SI
697 CMP AL,0DH
698 JNZ NOPSTORE
699 MOV [SI],AL ;Don't loose the CR
700NOPSTORE:
701 MOV [PATHPOS],SI
702 MOV [PATHCNT],CX
703 return
704
705PGETARG:
706 MOV SI,80H
707 LODSB
708 OR AL,AL
709 retz
710 CALL PSCANOFF
711 CMP AL,13
712 return
713
714PSCANOFF:
715 LODSB
716 CALL DELIM
717 JNZ PSCANOFFD
718 CMP AL,';'
719 JNZ PSCANOFF ; ';' is not a delimiter
720PSCANOFFD:
721 DEC SI ; Point to first non-delimiter
722 return
723
724PATH:
725 CALL FIND_PATH
726 CALL PGETARG ; Pre scan for arguments
727 JZ DISPPATH ; Print the current path
728 CALL DELETE_PATH ; DELETE ANY OFFENDING NAME
729 CALL SCAN_DOUBLE_NULL
730 CALL MOVE_NAME ; MOVE IN PATH=
731 CALL PGETARG
732 CMP AL,';' ; NUL path argument?
733 JZ GOTPATHS
734PATHSLP: ; Get the user specified path
735 LODSB
736 CMP AL,0DH
737 JZ GOTPATHS
738
739 IF KANJI
740 CALL TESTKANJ
741 JZ NOTKANJ2
742 CALL STORE_CHAR
743 LODSB
744 CALL STORE_CHAR
745 JMP SHORT PATHSLP
746
747NOTKANJ2:
748 ENDIF
749
750 CALL UPCONV
751 CMP AL,';' ; ';' not a delimiter on PATH
752 JZ NOTDELIM
753 CALL DELIM
754 JZ GOTPATHS
755NOTDELIM:
756 CALL STORE_CHAR
757 JMP SHORT PATHSLP
758
759GOTPATHS:
760 XOR AX,AX
761 STOSW
762 return
763
764DISPPATH:
765 CALL PRINT_PATH
766 CALL CRLF2
767 return
768
769PRINT_PATH:
770 CMP BYTE PTR ES:[DI],0
771 JNZ PATH1
772PATH0:
773 MOV DX,OFFSET TRANGROUP:NULPATH
774 PUSH CS
775 POP DS
776 JMP PRINT
777PATH1:
778 PUSH ES
779 POP DS
780 SUB DI,5
781 MOV DX,DI
782ASSUME DS:RESGROUP
783 CALL SCASB2 ; LOOK FOR NUL
784 CMP CX,0FFH
785 JZ PATH0
786 JMP ZPRINT
787
788FCB_TO_ASCZ: ; Convert DS:SI to ASCIZ ES:DI
789 MOV CX,8
790MAINNAME:
791 LODSB
792 CMP AL,' '
793 JZ SKIPSPC
794 STOSB
795SKIPSPC:
796 LOOP MAINNAME
797 LODSB
798 CMP AL,' '
799 JZ GOTNAME
800 MOV AH,AL
801 MOV AL,'.'
802 STOSB
803 XCHG AL,AH
804 STOSB
805 MOV CL,2
806EXTNAME:
807 LODSB
808 CMP AL,' '
809 JZ GOTNAME
810 STOSB
811 LOOP EXTNAME
812
813GOTNAME:
814 XOR AL,AL
815 STOSB
816 return
817
818GETNUM:
819 CALL INDIG
820 retc
821 MOV AH,AL ; Save first digit
822 CALL INDIG ; Another digit?
823 JC OKRET
824 AAD ; Convert unpacked BCD to decimal
825 MOV AH,AL
826OKRET:
827 OR AL,1
828 return
829
830INDIG:
831 MOV AL,BYTE PTR[SI]
832 SUB AL,"0"
833 retc
834 CMP AL,10
835 CMC
836 retc
837 INC SI
838 return
839
840
841OUT2: ; Output binary number as two ASCII digits
842 AAM ; Convert binary to unpacked BCD
843 XCHG AL,AH
844 OR AX,3030H ; Add "0" bias to both digits
845 CMP AL,"0" ; Is MSD zero?
846 JNZ NOSUP
847 SUB AL,BH ; Suppress leading zero if enabled
848NOSUP:
849 MOV BH,0 ; Disable zero suppression
850 STOSW
851 return
852
853OUT:
854; Print char in AL without affecting registers
855 XCHG AX,DX
856 PUSH AX
857 CALL OUT_CHAR
858 POP AX
859 XCHG AX,DX
860 return
861
862OUT_CHAR:
863 PUSH DS
864 PUSH DX
865 PUSH CX
866 PUSH BX
867 PUSH AX
868 PUSH CS
869 POP DS
870 MOV BX,OFFSET TRANGROUP:CHARBUF
871 MOV [BX],DL
872 MOV DX,BX
873 MOV BX,1
874 MOV CX,BX
875 MOV AH,WRITE
876 INT int_command
877 POP AX
878 POP BX
879 POP CX
880 POP DX
881 POP DS
882 return
883
884
885ERROR_PRINT:
886 PUSH AX
887 PUSH BX
888 MOV AL,"$"
889 MOV BX,2 ;STD ERROR
890 JMP SHORT STRING_OUT
891
892CRPRINT:
893 PUSH AX
894 MOV AL,13
895 JMP SHORT Z$PRINT
896PRINT: ;$ TERMINATED STRING
897 PUSH AX
898 MOV AL,"$"
899 JMP SHORT Z$PRINT
900ZPRINT:
901 PUSH AX
902 XOR AX,AX ;NUL TERMINATED STRING
903Z$PRINT:
904 PUSH BX
905 MOV BX,1 ;STD CON OUT
906;
907; output string terminated by AL to handle BX, DS:DX points to string
908;
909STRING_OUT:
910 PUSH CX
911 PUSH DI
912 MOV DI,DX
913 MOV CX,-1
914 PUSH ES
915 PUSH DS
916 POP ES
917 REPNZ SCASB ; LOOK FOR TERMINATOR
918 POP ES
919 NEG CX
920 DEC CX
921 DEC CX
922;
923; WRITE CHARS AT DS:DX TO HANDLE IN BX, COUNT IN CX
924;
925 MOV AH,WRITE
926 INT int_command
927 JC ERROR_OUTPUT
928 CMP AX,CX
929 JNZ ERROR_OUTPUT
930 POP DI
931 POP CX
932 POP BX
933 POP AX
934 return
935
936ERROR_OUTPUT:
937 PUSH CS
938 POP DS
939ASSUME DS:TRANGROUP
940 MOV ES,[RESSEG]
941ASSUME ES:RESGROUP
942 MOV DX,OFFSET TRANGROUP:NOSPACE
943 CMP [PIPEFLAG],0
944 JZ GO_TO_ERROR
945 MOV [PIPEFLAG],0
946 MOV DX,OFFSET TRANGROUP:PIPEEMES
947GO_TO_ERROR:
948 JMP CERROR
949
950
951TRANCODE ENDS
952 END
953
diff --git a/v2.0/source/TDATA.ASM b/v2.0/source/TDATA.ASM
new file mode 100644
index 0000000..9a4af2e
--- /dev/null
+++ b/v2.0/source/TDATA.ASM
@@ -0,0 +1,243 @@
1TITLE COMMAND Transient Initialized DATA
2
3 INCLUDE COMSW.ASM
4.xlist
5.xcref
6 INCLUDE COMSEG.ASM
7.list
8.cref
9
10 INCLUDE IFEQU.ASM
11
12TRANCODE SEGMENT PUBLIC
13 EXTRN PRINT_DATE:NEAR,PRINT_TIME:NEAR,PRINT_DEFAULT_DIRECTORY:NEAR
14 EXTRN PRINT_DRIVE:NEAR,PRINT_VERSION:NEAR,PRINT_G:NEAR
15 EXTRN PRINT_L:NEAR,PRINT_B:NEAR,CRLF2:NEAR,OUT:NEAR,PRINT_ESC:NEAR
16 EXTRN PRINT_BACK:NEAR,PRINT_EQ:NEAR
17
18 EXTRN IFNOT:NEAR,IFERLEV:NEAR,IFEXISTS:NEAR
19
20 EXTRN CATALOG:NEAR,CRENAME:NEAR,ERASE:NEAR,TYPEFIL:NEAR
21 EXTRN TCOMMAND:NEAR,COPY:NEAR,PAUSE:NEAR,DATE:NEAR,CTIME:NEAR
22 EXTRN VERSION:NEAR,VOLUME:NEAR,$CHDIR:NEAR,$MKDIR:NEAR,$RMDIR:NEAR
23 EXTRN CNTRLC:NEAR,VERIFY:NEAR,ADD_NAME_TO_ENVIRONMENT:NEAR
24 EXTRN ADD_PROMPT:NEAR,PATH:NEAR,$EXIT:NEAR,CTTY:NEAR,ECHO:NEAR
25 EXTRN GOTO:NEAR,SHIFT:NEAR,$IF:NEAR,$FOR:NEAR,CLS:NEAR
26TRANCODE ENDS
27
28; Data for transient portion
29
30TRANDATA SEGMENT PUBLIC BYTE
31
32 PUBLIC BADBAT,NEEDBAT,BADNAM,RENERR,NOTFND,NOSPACE,ENVERR,FULDIR
33 PUBLIC OVERWR,LOSTERR,DIRMES_PRE,DIRMES_POST,BADDRV,PAUSEMES,BADSWT
34 PUBLIC COPIED_PRE,COPIED_POST,BYTMES_PRE,BYTMES_POST
35 PUBLIC WEEKTAB,BADDAT,NEWDAT,BADTIM,NEWTIM,SUREMES,CURDAT_MID
36 PUBLIC CURDAT_PRE,CURDAT_POST,CURTIM_PRE,CURTIM_POST,VERMES_POST
37 PUBLIC DMES,VERMES_PRE,VOLMES,GOTVOL,NOVOL,BADCD,BADMKD,BADRMD
38 PUBLIC BAD_ON_OFF,NULPATH,PATH_TEXT,PROMPT_TEXT,BADPMES
39 PUBLIC BADDEV,BADLAB,SYNTMES,FORNESTMES,PIPEEMES,INBDEV,OFFMES
40 PUBLIC ONMES,CTRLCMES,VERIMES,ECHOMES,BADCPMES,BADARGS,DEVWMES
41 PUBLIC ACRLF,DBACK,CLSSTRING,PROMPT_TABLE,IFTAB,COMTAB
42 PUBLIC TRANDATAEND,DIRHEAD_PRE,DIRHEAD_POST
43
44 ORG 0
45ZERO = $
46BADBAT DB 13,10,"Batch file missing",13,10,"$"
47NEEDBAT DB 13,10,"Insert disk with batch file"
48 DB 13,10,"and press any key when ready",13,10,"$"
49BADNAM DB "Bad command or file name",13,10,"$"
50RENERR DB "Duplicate file name or "
51NOTFND DB "File not found",13,10,"$"
52NOSPACE DB "Insufficient disk space",13,10,"$"
53ENVERR DB "Out of environment space",13,10,"$"
54FULDIR DB "File creation error",13,10,"$"
55OVERWR DB "File cannot be copied onto itself",13,10,"$"
56LOSTERR DB "Content of destination lost before copy",13,10,"$"
57
58;"COPIED_PRE<# files copied>COPIED_POST"
59COPIED_POST DB " File(s) copied",13,10 ŠCOPIED_PRE DB "$"
60
61;"DIRMES_PRE<# files in dir>DIRMES_POST"
62DIRMES_POST DB " File(s) "
63DIRMES_PRE DB "$"
64
65;"BYTMES_PRE<# free bytes>BYTMES_POST"
66BYTMES_POST DB " bytes free",13,10
67BYTMES_PRE DB "$"
68
69BADDRV DB "Invalid drive specification",13,10,"$"
70PAUSEMES DB "Strike a key when ready . . . $"
71BADSWT DB "Invalid parameter",13,10,"$"
72WEEKTAB DB "SunMonTueWedThuFriSat"
73BADDAT DB 13,10,"Invalid date$"
74
75;"CURDAT_PRE<day of week>CURDAT_MID<MO,DAY,YR>CURDAT_POST"
76;Note: CURDAT_MID also appears in the date printed via PROMPT command
77CURDAT_PRE DB "Current date is "
78CURDAT_MID LABEL BYTE
79CURDAT_POST DB "$"
80
81NEWDAT DB 13,10,"Enter new date: $"
82BADTIM DB 13,10,"Invalid time$"
83
84;"CURTIM_PRE<HR,MIN,SEC,HSEC>CURTIM_POST"
85CURTIM_PRE DB "Current time is "
86CURTIM_POST DB "$"
87
88NEWTIM DB 13,10,"Enter new time: $"
89SUREMES DB "Are you sure (Y/N)? $"
90DMES DB " <DIR> $"
91
92;"VERMES_PRE<version #>VERMES_POST"
93 IF IBMVER
94VERMES_PRE DB "TeleVideo Personal Computer DOS Version "
95 ENDIF
96 IF MSVER
97VERMES_PRE DB "MS-DOS Version "
98 ENDIF
99VERMES_POST DB "$"
100
101VOLMES DB " Volume in drive $"
102GOTVOL DB " is $"
103NOVOL DB " has no label$"
104
105BADCD DB "Invalid directory",13,10,"$"
106BADMKD DB "Unable to create directory",13,10,"$"
107BADRMD DB "Invalid path, not directory,",13,10
108 DB "or directory not empty",13,10,"$"
109BAD_ON_OFF DB "Must specify ON or OFF" ;Note Run over to next message
110
111;"DIRHEAD_PRE<path of dir>DIRHEAD_POST"
112DIRHEAD_POST DB 13,10,"$"
113DIRHEAD_PRE DB " Directory of $" Š
114NULPATH DB "No Path $"
115PATH_TEXT DB "PATH="
116PROMPT_TEXT DB "PROMPT="
117BADPMES DB "Invalid drive in search path",13,10,"$"
118BADDEV DB "Invalid device",13,10,"$"
119BADLAB DB "Label not found",13,10,"$"
120SYNTMES DB "Syntax error",13,10,"$"
121FORNESTMES DB 13,"FOR cannot be nested",13,10,"$"
122PIPEEMES DB "Intermediate file error during pipe",13,10,"$"
123INBDEV DB "Cannot do binary reads from a device",13,10,"$"
124OFFMES DB "off",13,10,"$"
125ONMES DB "on",13,10,"$"
126CTRLCMES DB "BREAK is $"
127VERIMES DB "VERIFY is $"
128ECHOMES DB "ECHO is $"
129BADCPMES DB "Invalid path or file name",13,10,"$"
130BADARGS DB "Invalid number of parameters",13,10,"$"
131DEVWMES DB "Error writing to device"
132ACRLF DB 13,10,"$"
133DBACK DB 8," ",8,0 ; DESTRUCTIVE BACK SPACE
134
135CLSSTRING DB 4,01BH,"[2J" ; ANSI Clear screen
136
137PROMPT_TABLE LABEL BYTE
138 DB "D"
139 DW OFFSET TRANGROUP:PRINT_DATE
140 DB "T"
141 DW OFFSET TRANGROUP:PRINT_TIME
142 DB "P"
143 DW OFFSET TRANGROUP:PRINT_DEFAULT_DIRECTORY
144 DB "N"
145 DW OFFSET TRANGROUP:PRINT_DRIVE
146 DB "V"
147 DW OFFSET TRANGROUP:PRINT_VERSION
148 DB "G"
149 DW OFFSET TRANGROUP:PRINT_G
150 DB "L"
151 DW OFFSET TRANGROUP:PRINT_L
152 DB "B"
153 DW OFFSET TRANGROUP:PRINT_B
154 DB "_"
155 DW OFFSET TRANGROUP:CRLF2
156 DB "$"
157 DW OFFSET TRANGROUP:OUT
158 DB "E"
159 DW OFFSET TRANGROUP:PRINT_ESC
160 DB "H"
161 DW OFFSET TRANGROUP:PRINT_BACK
162 DB "Q"
163 DW OFFSET TRANGROUP:PRINT_EQ
164 DB 0 ; NUL TERMINATED
165
166IFTAB LABEL BYTE ; Table of IF conditionals
167 DB 3,"NOT" ; First byte is count Š DW OFFSET TRANGROUP:IFNOT
168 DB 10,"ERRORLEVEL"
169 DW OFFSET TRANGROUP:IFERLEV
170 DB 5,"EXIST"
171 DW OFFSET TRANGROUP:IFEXISTS
172 DB 0
173
174COMTAB DB 4,"DIR",1 ; Table for internal command names
175 DW OFFSET TRANGROUP:CATALOG
176 DB 7,"RENAME",1
177 DW OFFSET TRANGROUP:CRENAME
178 DB 4,"REN",1
179 DW OFFSET TRANGROUP:CRENAME
180 DB 6,"ERASE",1
181 DW OFFSET TRANGROUP:ERASE
182 DB 4,"DEL",1
183 DW OFFSET TRANGROUP:ERASE
184 DB 5,"TYPE",1
185 DW OFFSET TRANGROUP:TYPEFIL
186 DB 4,"REM",0
187 DW OFFSET TRANGROUP:TCOMMAND
188 DB 5,"COPY",1
189 DW OFFSET TRANGROUP:COPY
190 DB 6,"PAUSE",0
191 DW OFFSET TRANGROUP:PAUSE
192 DB 5,"DATE",0
193 DW OFFSET TRANGROUP:DATE
194 DB 5,"TIME",0
195 DW OFFSET TRANGROUP:CTIME
196 DB 4,"VER",0
197 DW OFFSET TRANGROUP:VERSION
198 DB 4,"VOL",1
199 DW OFFSET TRANGROUP:VOLUME
200 DB 3,"CD",1
201 DW OFFSET TRANGROUP:$CHDIR
202 DB 6,"CHDIR",1
203 DW OFFSET TRANGROUP:$CHDIR
204 DB 3,"MD",1
205 DW OFFSET TRANGROUP:$MKDIR
206 DB 6,"MKDIR",1
207 DW OFFSET TRANGROUP:$MKDIR
208 DB 3,"RD",1
209 DW OFFSET TRANGROUP:$RMDIR
210 DB 6,"RMDIR",1
211 DW OFFSET TRANGROUP:$RMDIR
212 DB 6,"BREAK",0
213 DW OFFSET TRANGROUP:CNTRLC
214 DB 7,"VERIFY",0
215 DW OFFSET TRANGROUP:VERIFY
216 DB 4,"SET",0
217 DW OFFSET TRANGROUP:ADD_NAME_TO_ENVIRONMENT
218 DB 7,"PROMPT",0
219 DW OFFSET TRANGROUP:ADD_PROMPT
220 DB 5,"PATH",0
221 DW OFFSET TRANGROUP:PATH Š DB 5,"EXIT",0
222 DW OFFSET TRANGROUP:$EXIT
223 DB 5,"CTTY",1
224 DW OFFSET TRANGROUP:CTTY
225 DB 5,"ECHO",0
226 DW OFFSET TRANGROUP:ECHO
227 DB 5,"GOTO",0
228 DW OFFSET TRANGROUP:GOTO
229 DB 6,"SHIFT",0
230 DW OFFSET TRANGROUP:SHIFT
231 DB 3,"IF",0
232 DW OFFSET TRANGROUP:$IF
233 DB 4,"FOR",0
234 DW OFFSET TRANGROUP:$FOR
235 DB 4,"CLS",0
236 DW OFFSET TRANGROUP:CLS
237 DB 0 ; Terminate command table
238
239TRANDATAEND LABEL BYTE
240
241TRANDATA ENDS
242 END
243
diff --git a/v2.0/source/TIME.ASM b/v2.0/source/TIME.ASM
new file mode 100644
index 0000000..f1e4a1c
--- /dev/null
+++ b/v2.0/source/TIME.ASM
Binary files differ
diff --git a/v2.0/source/TSPC.ASM b/v2.0/source/TSPC.ASM
new file mode 100644
index 0000000..85f02e7
--- /dev/null
+++ b/v2.0/source/TSPC.ASM
Binary files differ
diff --git a/v2.0/source/TUCODE.ASM b/v2.0/source/TUCODE.ASM
new file mode 100644
index 0000000..1a69b77
--- /dev/null
+++ b/v2.0/source/TUCODE.ASM
Binary files differ
diff --git a/v2.0/source/UINIT.ASM b/v2.0/source/UINIT.ASM
new file mode 100644
index 0000000..2e6bc77
--- /dev/null
+++ b/v2.0/source/UINIT.ASM
Binary files differ
diff --git a/v2.0/source/UTILITY.txt b/v2.0/source/UTILITY.txt
new file mode 100644
index 0000000..a63793c
--- /dev/null
+++ b/v2.0/source/UTILITY.txt
@@ -0,0 +1,813 @@
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 MS-DOS 2.0
20
21 Utility Extensions
22
23
24
25
26
27
28
29
30 The following notation is used below:
31
32 [item] item is optional.
33 item* item is repeated 0 or more times.
34 item+ item is repeated 1 or more times.
35 {item1 | item2}
36 item1 is present or item 2 is present but
37 not both.
38 <object> indicates a syntactic variable.
39
40
41COMMAND invokation
42
43COMMAND [[<drive>:]<path>] [<cttydev>] [-D] [-P] [-C <string>]
44
45 -P If present COMMAND will be permanent, otherwise
46 this is a transient command.
47
48 -D If present COMMAND will not prompt for DATE and
49 TIME when it comes up.
50
51 d: Specifies device where command will look for
52 COMMAND.COM current default drive if absent.
53
54 <Path> Specifies a directory on device d: root
55 directory if absent.
56
57 <cttydev> Name of the CTTY device. /DEV/CON if absent
58 and command is permanent. The /DEV/ may be left
59 off if AVAILDEV is TRUE (see sysinit doc).
60
61 -C <string> If present -C must be the last switch.
62 This causes COMMAND to try to execute the string
63 as if the user had typed it at the standard input.
64 COMMAND executes this single command string and
65 then exits. If the -P switch is present it is
66 ignored (can't have a single command, permanent
67 COMMAND). NOTE: ALL of the text on the command
68 line after the -C is just passed on. It is not
69 processed for more arguments, this is why -C must
70 be last.
71
72COMMAND extensions
73
74IF <condition> <command>
75
76 where <condition> is one of the following:
77
78 ERRORLEVEL <number>
79 true if and only if the previous program EXECed by
80 COMMAND had an exit code of <number> or higher.
81
82 <string1> == <string2>
83 true if and only if <string1> and <string2> are
84 identical after parameter substitution. Strings
85 may not have embedded delimiters.
86
87 EXIST <filename>
88 true if and only if <filename> exists.
89
90 NOT <condition>
91 true if and only if <condition> is false.
92
93 The IF statement allows conditional execution of commands.
94 When the <condition> is true, then the <command> is
95 executed otherwise, the <command> is skipped.
96
97 Examples:
98
99 IF not exist /tmp/foo ECHO Can't find file /tmp/foo
100
101 IF $1x == x ECHO Need at least one parameter
102
103 IF NOT ERRORLEVEL 3 LINK $1,,;
104
105
106FOR %%<c> IN <set> DO <command>
107
108 <c> can be any character but 0,1,2,3,..,9 (so there is no
109 confusion with the %0 - %9 batch parameters).
110
111 <set> is ( <item>* )
112
113 The %%<c> variable is sequentially set to each member of
114 <set> and then <command> is evaluated. If a member of
115 <set> is an expression involving * and/or ?, then the
116 variable is set to each matching pattern from disk. In
117 this case only one such <item> may be in the set, any
118 <item>s after the first are ignored.
119
120 Example:
121
122 FOR %%f IN ( *.ASM ) DO MASM %%f;
123
124 for %%f in (FOO BAR BLECH) do REM %%f to you
125
126 NOTE: The '%%' is needed so that after Batch parameter
127 (%0 - %9) processing is done, there is one '%' left.
128 If only '%f' were there, the batch parameter processor
129 would see the '%' then look at 'f', decide that '%f'
130 was an error (bad parameter reference) and throw out
131 the '%f' so that FOR would never see it. If the FOR
132 is NOT in a batch file, then only ONE '%' should be
133 used.
134
135
136SHIFT
137
138 Currently, command files are limited to handling 10
139 parameters: %0 through %9. To allow access to more than
140 these, the command SHIFT will perform a 'pop' of the
141 command line parameters:
142
143 if %0 = "foo"
144 %1 = "bar"
145 %2 = "blech"
146 %3...%9 are empty
147
148 then a SHIFT will result in the following:
149
150 %0 = "bar"
151 %1 = "blech"
152 %2...%9 are empty
153
154 If there are more than 10 parameters given on a command
155 line, then the those that appear after the 10th (%9) will
156 be shifted one at a time into %9 by successive shifts.
157
158:<label>
159
160 This is essentially a no-op. It defines a label in the
161 batch file for a subsequent GOTO. It may also be used to
162 put comment lines in batch files since all lines that
163 start with ':' are ignored.
164
165GOTO <label>
166
167 Causes commands to be taken from the batch file beginning
168 with the line after the <label> definition. If no label
169 has been defined, the current batch file will terminate.
170
171 Example:
172
173 :foo
174 REM looping...
175 GOTO foo
176
177 will produce a infinite sequence of messages:
178 'REM looping...'
179
180 NOTE: Labels are case insensitive, :FOO == :foo == :Foo
181
182
183ECHO [{ON | OFF | <message>}]
184
185 Normally, commands in a BATCH file are echoed onto the
186 standard output as they are seen by COMMAND. ECHO OFF
187 turns off this feature. ECHO ON turns echoing back on.
188 If ON or OFF is not specified and there is text following
189 the command, that text (a message) is echoed to standard
190 output. If there are no arguments at all, the current
191 setting of echo (on or off) is echoed to the standard
192 output in the form:
193
194 ECHO is xxx
195
196 Where xxx is "on" or "off".
197
198Redirection of standard input/standard output.
199
200 Programs that read from the keyboard and write to the
201 screen are said to be doing I/O to the standard input and
202 standard output. Using any of the following will result
203 in I/O to these standard devices:
204
205 Writing to default handles 1 / read from default
206 handle 0.
207
208 Doing byte I/O using system calls 1, 2, 6-12.
209
210 These standard devices may be redirected to/from files by
211 the following in command line arguments:
212
213 > <filename>
214 causes <filename> to be created (or truncated to
215 zero length) and then assigns standard output to
216 that file. All output from the command will be
217 placed in the file.
218
219 < <filename>
220 causes standard input to be assigned to
221 <filename>. All input to the command will come
222 from this file. If end-of-file is reached, then
223 system calls 1, 2, 6-12 will return ^Z , while
224 reading from handle 0 will return zero characters.
225
226 >> <filename>
227 causes <filename> to be opened (created if
228 necessary) and positions the write pointer at the
229 end of the file so that all output will be
230 appended to the file.
231
232 Note that the above will not appear in the command line
233 that the program being invoked sees.
234
235 Examples:
236
237 DIR *.ASM > FOO.LST
238 Sends the output of the dir command to the file
239 FOO.LST.
240
241
242 FOR %0 IN (*.ASM) DO MASM %0; >>ERRS.LST
243 Sends all error output from assembling every .ASM file
244 into the file ERRS.LST.
245
246Piping of standard I/O
247
248 It is often useful for the output of one program to be
249 sent as input to another program. A typical case is a
250 program that produces columnar output that must later be
251 sorted.
252
253 The pipe feature allows this to occur naturally is the
254 programs do all of their I/O to the standard devices.
255
256 For example, if we had a program SORT that read all of
257 it's standard input, sorted it and then wrote it to the
258 standard output, then we could get a sorted directory
259 listing as follows:
260
261 DIR | SORT
262
263 The | would cause all standard output generated by the
264 left-hand command to be sent to the standard input of the
265 right-hand command.
266
267 If we wanted the sorted directory to be sent to a file, we
268 type:
269
270 DIR | SORT >FILE
271
272 and away it goes.
273
274 The piping feature is implemented as sequential execution
275 of the procedures with redirection to and from temporary
276 files. In the example above, the following would be an
277 exact equivalent:
278
279 DIR >/tmp/std1
280 SORT </tmp/std1 >FILE
281
282
283
284 The pipe is not a real pipe but rather a quasi-pipe
285 that uses temporary files to hold the input and output as
286 it sequentially executes the elements of the pipe. These
287 files are created in the current directory, of the current
288 drive and have the form %PIPEx%.$$$, where x will be 1 or
289 2. This means that any program that runs in the pipe must
290 be sure to restore the current directory and drive if it
291 has changed them, otherwise the pipe files will be lost.
292
293
294VER
295 Prints DOS version number.
296
297VOL [<drive>:]
298 Prints the volume ID of the disk in drive d:. No d: does
299 default drive.
300
301CHDIR [{<drive>: | <path>}]
302 Change directory, or print current. directory.If no
303 argument is given, the current directory on the default
304 drive is printed. If d: alone is given, the durrent
305 directory of drive d is printed. Otherwise the current
306 directory is set to path.
307
308 NOTE:"CD" is accepted as an abbreviation.
309
310MKDIR <path> - Make a directory.
311 "MD" is accepted as an abbreviation.
312
313RMDIR <path> - Remove a directory.
314 "RD" is accepted as an abbreviation.
315 The directory must be empty except for
316 '.' and '..'.
317
318 <path> - A standard XENIX style path with the optional
319 addition of a drive spec:
320
321 A:/FOO/BAR Full path
322 /FOO/BAR Full path, current drive
323 FOO/BAR Current dir relative
324 A:FOO/BAR " " "
325
326VERIFY [{ON | OFF}]
327 Select/deselect verify after write mode. This supliments
328 the V switch to the COPY command. Once turned ON, it
329 stays on until some program changes it (via the set verify
330 system call) or the VERIFY OFF command is given. If no
331 argument is given, the current setting of VERIFY is
332 printed to the standard output in the form:
333
334 VERIFY is xxx
335
336 Where xxx is "on" or "off".
337
338PATH [<path>{;<path>}*]
339 Set command search paths. This allows users to set
340 directories that should be searched for external commands
341 after a search of the current directory is made. The
342 default value is /bin. In addition there are two special
343 cases: PATH all by itself with no arguments will print
344 the current path. Path with the single argument ';' (ie.
345 "PATH ;") will set the NUL path (no directories other than
346 the current one searched). If no argument is given, the
347 current value of PATH is printed to the standard output in
348 the form:
349
350 PATH=text of path
351 or
352 No path
353
354 NOTE: On IBM systems, the default value of path is No
355 path.
356
357EXIT
358 For COMMANDs run without the P switch, this causes COMMAND
359 to return. For a normal COMMAND it causes a return to
360 itself.
361
362BREAK [{ON | OFF}]
363 Like in CONFIG.SYS, "BREAK ON" turns on the Control C
364 check in the DOS function dispatcher. "BREAK OFF" turns
365 it off. If no argument is given the setting of BREAK is
366 printed to the standard output in the form:
367
368 BREAK is xxx
369
370 Where xxx is "on" or "off".
371
372PROMPT [<prompt-text>]
373 Set the system prompt. MS-DOS prompts are now user
374 settable, all of the text on the command line is taken to
375 be the new prompt. If no text is present the prompt is
376 set to the default prompt. There are meta strings for
377 various special prompts. These are of the form '$c' where
378 c is one of the following:
379
380 $ - The '$' character.
381 t - The time.
382 d - The date.
383 p - The current directory of the default drive.
384 v - The version number.
385 n - The default drive.
386 g - The '>' character.
387 l - The '<' character.
388 b - The '|' character.
389 s - The ' ' character.
390 e - The ESC character.
391 _ - A CR LF sequence.
392
393 EXAMPLE:
394 PROMPT $n:
395 Would set the normal MS-DOS prompt.
396 PROMPT $n>
397 Would det the normal PC-DOS prompt.
398 PROMPT Time = $t$_Date = $d
399 Would set a two line prompt which printed
400 Time = (current time)
401 Date = (current date)
402
403 NOTE: For '$c' sequences, lower case = upper case, and
404 any character not on the above list is mapped to
405 nothing.
406
407SET (ENVNAME)=(ENVTEXT)
408 Set environment strings. This command inserts strings in
409 COMMAND's environment. For instance:
410
411 SET PROMPT=$n>
412 Duplicates the function of the PROMPT command.
413 SET PATH=p1;p2
414 Duplicates the function of the PATH command.
415 SET foo=bar
416 Puts the string FOO=bar into the environment (note the
417 case mapping of (ENVNAME)).
418
419 NOTE: Environments are very flexible, almost anything can
420 be put into the environment with the SET command; the
421 only requirement is that a single '=' be present in
422 the string.
423
424CLS
425 Clear screen, causes the ANSI escape sequence ESC[2J to be
426 sent to standard output.
427
428CTTY /DEV/dev - Change console TTY. For instance:
429
430 CTTY /DEV/AUX
431
432 Would move all command I/O to the AUX port.
433
434 CTTY /DEV/CON
435
436 Would move it back to the normal device. The
437 /dev/ prefix may be left off if AVAILDEV is
438 TRUE (see configuration-file doc).
439
440COMMAND internal commands take path arguments.
441
442 DIR <path>
443
444 COPY <path> <path>
445
446 DEL(ERASE) <path>
447 If the path is a dir, all files in that dir
448 are deleted.
449 NOTE: The "Are you sure (Y/N)" prompt for DEL and
450 ERASE now uses buffered standard input, so
451 users must type a return after their answer.
452 This gives them the chance to correct if they
453 type 'y' by mistake.
454
455 TYPE <path> (must specify a file)
456
457
458
459
460FILCOM - compare two files
461
462 The FILCOM program compares two files and produces a log
463 of differences between them. The comparison may be made
464 in two fashions; either on a line-by-line basis, or on a
465 byte-by-byte basis.
466
467 The line-by-line compare will isolate blocks of lines that
468 are different between the two files and will print the
469 blocks from each file. The line-by-line compare is the
470 default when neither of the two files being compared has
471 the extension .EXE, .COM, or .OBJ.
472
473 The byte-by-byte compare will display exactly which bytes
474 are different between the two files. If either file being
475 compared has extension .EXE, .COM, or .OBJ then the files
476 will be compared in byte-by-byte mode.
477
478
479
480RECOVER - recover files from a trashed disk.
481
482 If a sector on a disk goes bad, you can recover either the
483 file that contained that sector (without the sector) or
484 the entire disk (if the bad sector was in the directory).
485
486 To recover a particular file:
487
488 RECOVER <file-to-recover>
489
490 This will cause the file to be read sector by sector and
491 to be have the bad sector skipped. Note that this implies
492 that the allocation unit containing the bad sector will be
493 read as much as possible. When such a bad sector is
494 found, its containing allocation unit is marked as bad,
495 thus preventing future allocations of that bad sector.
496
497 To recover a particular disk:
498
499 RECOVER <drive-letter>:
500
501 This will cause a scan to be made of the drive's FAT for
502 chains of allocation units (files). A new root directory
503 is then written that has entries of the form FILEnnnn.
504 Each FILEnnnn will point to the head of one of the
505 allocation unit chains.
506
507 If there are more chains than directory entries in the
508 root, RECOVER prints a message and leaves the un-RECOVERED
509 chains in the FAT so that RECOVER can be run again once
510 some room has been made in the ROOT.
511
512
513
514DEBUG ON MS-DOS 2.0
515
516
517 When 2.0 DEBUG is invoked it sets up a program header
518atoffset 0 in its program work area. On previous versions it
519was OK to overwrite this header with impunity: this is true
520of the default header set up if no <filespec> is given to
521DEBUG. If DEBUGging a .COM or .EXE file, however, you must be
522careful not to tamper with the header of the program below
523address 5CH, to do this will probably result in a crash. It
524is also important that an attempt is not made to "restart" a
525program once the "program terminated normally" message is
526given. The program must be reloaded with the N and L commands
527in order for it to run properly.
528
529NEW FEATURES
530
531The A (Assemble) Command
532
533FORMAT: A [<address>]
534
535PURPOSE: To assemble 8086/8087/8088 mnemonics directly into
536 memory.
537
538o If a syntax error is encountered, DEBUG responds with
539
540 ^ Error
541
542 and redisplays the current assembly address.
543
544o All numeric values are hexadecimal and may be entered
545 as 1-4 characters.
546
547o Prefix mnemonics must be entered in front of the opcode
548 to which they refer. They may also be entered on a
549 separate line.
550
551o The segment override mnemonics are CS:, DS:, ES:, and
552 SS:
553
554o String manipulation mnemonics must explictly state the
555 string size. For example, the MOVSW must be used to
556 move word strings and MOVSB must be used to move byte
557 strings.
558
559
560o The mnemonic for the far return is RETF.
561
562o The assembler will automatically assemble short, near
563 or far jumps and calls depending on byte displacement
564 to the destination address. These may be overridden
565 with the NEAR or FAR prefix. For example:
566
567 0100:0500 JMP 502 ; a 2 byte short jump
568 0100:0502 JMP NEAR 505 ; a 3 byte near jump
569 0100:0505 JMP FAR 50A ; a 5 byte far jump
570
571 The NEAR prefix may be abbreviated to NE but the FAR
572 prefix cannot be abbreviated.
573
574o DEBUG cannot tell whether some operands refer to a word
575 memory location or a byte memroy location. In this case
576 the data type must be explicity stated with the prefix
577 "WORD PTR" or "BYTE PTR". DEBUG will also except the
578 abbreviations "WO" and "BY". For example:
579
580 NEG BYTE PTR [128]
581 DEC WO [SI]
582
583o DEBUG also cannot tell whether an operand refers to a
584 memory location or to an immediate operand. DEBUG uses
585 the common convention that operands enclosed in square
586 brackets refer to memory. For example:
587
588 MOV AX,21 ;Load AX with 21H
589 MOV AX,[21] ;Load AX with the contents
590 ;of memory location 21H
591
592o Two popular pseudo-instructions have also been included.
593 The DB opcode will assemble byte values directly into
594 memory. The DW opcode will assemble word values directly
595 into memory. For example:
596
597 DB 1,2,3,4,"THIS IS AN EXAMPLE"
598 DB 'THIS IS A QUOTE: "'
599 DB "THIS IS A QUOTE: '"
600
601 DW 1000,2000,3000,"BACH"
602
603
604o All forms of the register indirect commands are supported.
605 For example:
606
607 ADD BX,34[BP+2].[SI-1]
608 POP [BP+DI]
609 PUSH [SI]
610
611o All opcode synonyms are supported, For example:
612
613 LOOPZ 100
614 LOOPE 100
615
616 JA 200
617 JNBE 200
618
619o For 8087 opcodes the WAIT or FWAIT prefix must be
620 explictly specified. For example:
621
622 FWAIT FADD ST,ST(3) ; This lines will assemble
623 ; a FWAIT prefix
624
625 FLD TBYTE PTR [BX] ; This line will not
626
627
628
629FORMAT enhancements
630
631 FORMAT will now install volume id's during the format
632 process. DIR and CHKDSK will display these volume id's.
633
634 User programs can read the volume id on a particular drive
635 by doing a 'search next' with the volume id attribute. It
636 is impossible, using normal DOS calls, to delete a volume
637 id or to create another one. The only way to create a
638 volume id is to reformat the disk.
639
640 NOTE: On IBM systems the V switch must be given to FORMAT
641 to have it do Volume IDs.
642
643
644
645
646CHKDSK FOR MS-DOS 2.0
647
648
649 MS-DOS 2.0 has a tree structured directory scheme which
650did not exist on previous versions of MS-DOS. As a result
651CHKDSK is a much more complex program than in previous
652versions since it must perform a tree traversal to find all of
653the files on a given disk. It employes a depth first
654traversal in order to accomplish this.
655
656 Previous versions of CHKDSK automatically "fixed"
657disks (regardless of whether it was appropriate). CHKDSK 2.00
658run normally will not alter the disk in any way, it simply
659reports on any inconsistencies found. To actually "fix" a
660disk CHKDSK must be run with the F switch (Fix). This allows
661you to perhaps take some alternate (to CHKDSK repairs) action
662before letting CHKDSK loose on your disk.
663
664 CHKDSK 2.00 will report on non-contiguous allocation units
665(extents) for specified files. This is handy for gaging how
666"fragmented" a disk volume has become. This is done by simply
667giving a filespec:
668
669 CHKDSK B:*.*
670
671This would report extents for all files in the current
672directory for drive B after doing a normal consistency check
673on drive B. Files which have many extents can be copied and
674renamed to restore them to a contiguous state, thus improving
675I/O performance to the files.
676
677 Previous versions of CHKDSK would simply free
678allocation units which were marked as used, but were not
679actually part of any file. CHKDSK 2.00 will recover these
680"orphan" allocation units if specified. If orphan allocation
681units are found, CHKDSK prompts for free or recover. Free
682just frees the orphans as previous versions did, recover will
683employ allocation chain analysis to create "orphan files" in
684the root directory of the disk. These files will have the
685form "%ORPHAN%.l$$" where l will take on some ASCII value
686greater than '@'. These files may then be inspected to see if
687valuable data was contained in them. If there is not enough
688room to make all of the "orphan" files, CHKDSK leaves the
689unrecovered chains in the FAT so that CHKDSK can be run again
690(once some entries in the ROOT have been deleted). NOTE:
691Making ORPHAN files is a SLOW process.
692
693 Verbose mode. CHKDSK 2.00 may be run with the V switch
694which causes a trace of the files and directories being
695processed to be printed as CHKDSK runs.
696
697
698FILTERS FOR MS-DOS 2.0
699
700 A filter is a utility that reads from standard input,
701modifies the information in some way, then writes the result
702to standard output. In this way the data is said to have been
703"filtered" by the program. Since different filters can be
704piped together in many different ways a few filters can take
705the place of a large number of specific purpose programs. The
706following describes the filters that are provided with MS-DOS
7072.0:
708
709CIPHER <key word>
710
711 Cipher reads a program from standard input, encrypts it
712using the key word provided by the user, then writes the
713result to standard output. To decrypt the file simply run
714CIPHER again using the same keyword. For example:
715
716A>CIPHER MYSTERY <NSA.CIA >SECRET.FIL
717
718 This command line will read file NSA.CIA, encrypt it using
719the key word "MYSTERY", then write the result to file
720SECRET.FIL To view the original file the following command
721line could be used:
722
723A>CIPHER MYSTERY <SECRET.FIL
724
725 This will read file SECRET.FIL, decrypt the file using the
726key word "MYSTERY", then write the result to standard output,
727which in this case is the console.
728
729FGREP
730
731 This filter takes as arguments a string and optionally a
732series of file names. It will send to standard output all
733lines from the files specified in the command line that
734contain the string.
735
736 If no files are specified FGREP will take the input from
737standard in. The format for the command line invocation of
738FGREP is:
739
740FGREP [<option>] <string> <filename>*
741
742 The options available are:
743
744 /v Will cause FGREP to output all lines NOT
745 containing the specified string.
746
747 /c Will cause FGREP to only print the count of
748 lines matched in each of the files.
749
750 /n Each line matched is preceded by its relative
751 line number in the file.
752
753 The string argument should be enclosed in double quotes.
754Two double quotes in succession are taken as a single double
755quote. So,
756
757A>FGREP "Fool""s Paradise" book1.txt book2.txt bible
758
759will output all lines from the book1.txt, book2.txt and bible
760(in that order that contain the string: Fool"s Paradise .
761And,
762
763A>dir b: | fgrep /v "DAT"
764
765will output all names of the files in disk b: which do not
766contain the string DAT .
767
768MORE
769
770 The filter MORE reads from standard input, sends one
771screen full of information to standard output and then pauses
772with message:
773
774-- More --
775
776 Pressing the RETURN key will cause another screen full of
777information to be written to standard output. This process
778continues until all the input data is read.
779
780SORT [/R] [/+n]
781
782 Sort reads from standard input, sorts the data, the writes
783the information to standard output. The sort is done using
784the ASCII collating sequence. There are switches which allow
785the user to select various options:
786
787 R - Reverse the sort, that is make "Z" come before "A"
788
789 +n - Sort starting with column "n" where n is some integer.
790 The default is start the comparisons with column 1,
791 this switch allows the user to start in any column.
792
793example:
794
795A>SORT /R <UNSORT.TXT >SORT.TXT
796
797This command line will read the file UNSORT.TXT, do a reverse
798sort, then write the output to file SORT.TXT
799
800A>DIR | SORT /+14
801
802 This command line will cause the output of the directory
803command to be piped to the sort filter, the sort filter will
804sort starting with column 14 (This is the column the file size
805starts), then send the output to the console. Thus a
806directory sorted by file size will be the result. To get real
807fancy:
808
809A>DIR | SORT /+14 | MORE
810
811will do the same thing except that MORE will give you a chance
812to read the directory before it scrolls off the screen.
813
diff --git a/v2.0/source/WSBAUD.BAS b/v2.0/source/WSBAUD.BAS
new file mode 100644
index 0000000..cc5426c
--- /dev/null
+++ b/v2.0/source/WSBAUD.BAS
Binary files differ
diff --git a/v2.0/source/WSMSGS.OVR b/v2.0/source/WSMSGS.OVR
new file mode 100644
index 0000000..714ecbf
--- /dev/null
+++ b/v2.0/source/WSMSGS.OVR
Binary files differ
diff --git a/v2.0/source/WSOVLY1.OVR b/v2.0/source/WSOVLY1.OVR
new file mode 100644
index 0000000..123b56e
--- /dev/null
+++ b/v2.0/source/WSOVLY1.OVR
Binary files differ
diff --git a/v2.0/source/XENIX.ASM b/v2.0/source/XENIX.ASM
new file mode 100644
index 0000000..dd20b50
--- /dev/null
+++ b/v2.0/source/XENIX.ASM
@@ -0,0 +1,907 @@
1;
2; xenix file calls for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7IFNDEF KANJI
8KANJI EQU 0 ;FALSE
9ENDIF
10
11CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14.xlist
15.xcref
16INCLUDE DOSSYM.ASM
17INCLUDE DEVSYM.ASM
18.cref
19.list
20
21TITLE XENIX - IO system to mimic UNIX
22NAME XENIX
23
24 i_need NoSetDir,BYTE
25 i_need CURDRV,BYTE
26 i_need IOCALL,BYTE
27 i_need IOMED,BYTE
28 i_need IOSCNT,WORD
29 i_need IOXAD,DWORD
30 i_need DIRSTART,WORD
31 i_need ATTRIB,BYTE
32 i_need THISFCB,DWORD
33 i_need AuxStack,BYTE
34 i_need Creating,BYTE
35 i_need ThisDRV,BYTE
36 i_need NAME1,BYTE
37 i_need LastEnt,WORD
38 i_need ThisDPB,DWORD
39 i_need EntLast,WORD
40 i_need CurrentPDB,WORD
41 i_need sft_addr,DWORD ; pointer to head of table
42 i_need CURBUF,DWORD ; pointer to current buffer
43 i_need DMAADD,DWORD ; pointer to current dma address
44
45BREAK <Local data>
46
47CODE ENDS
48DATA SEGMENT BYTE PUBLIC 'DATA'
49
50open_name DW ?
51 DW ?
52open_access DB ?
53open_jfn DW ? ; accessed as DD
54open_jfn_b DW ? ; accessed as DD with above
55open_sfn DW ?
56open_sfoff DW ? ; accessed as DD
57open_sfn_b DW ? ; accessed as DD with above
58open_devid DB ?
59Cr_read_only DB ?
60rename_source DD ?
61rename_dest DD ?
62
63DATA ENDS
64CODE SEGMENT BYTE PUBLIC 'CODE'
65
66BREAK <Validate_path - check to see if there are meta characters in path>
67
68;
69; Input: DS:DX is an ASCIZ path
70; Output: Carry set if meta-characters present or path malformed and
71; Zero is set if the only problem is that meta-characters
72; are present in the last element of the path
73procedure Validate_path,near
74 ASSUME DS:NOTHING,ES:NOTHING
75 PUSH AX
76 PUSH CX
77 PUSH SI
78 MOV SI,DX
79 MOV CX,0FFH ;No path seps yet
80 MOV AX,[SI] ; Get first two bytes
81 OR AL,AL
82 JZ validate_malformed ; NUL path
83 CMP AH,':'
84 JNZ validate_loop ; OK so far
85 CMP BYTE PTR [SI+2],0
86 JZ validate_malformed ; NUL path (just d:)
87validate_loop:
88 LODSB
89validate_loop1:
90
91 IF KANJI
92 invoke TESTKANJ
93 JZ NOTKANJ6
94 INC SI
95 JMP validate_loop
96
97NOTKANJ6:
98 ENDIF
99
100 OR AL,AL
101 JZ validate_end
102 CMP AL,"?"
103 JZ validate_error
104 CMP AL,"*"
105 JZ validate_error
106 invoke PathChrCmp
107 JNZ validate_loop
108 JCXZ validate_malformed ;If path sep, cannot have meta yet
109 LODSB ;Look ahead one char
110 OR AL,AL
111 JZ validate_checktslsh ;Trailing path sep
112 invoke PathChrCmp
113 JNZ validate_loop1 ;Double path sep?
114validate_malformed:
115 INC CX
116 OR CX,CX ;Reset zero
117 JMP SHORT validate_set_carry
118
119validate_error:
120 XOR CX,CX ;Flag metas found
121 JMP validate_loop
122
123validate_checktslsh:
124;A bizarre case, "/" is OK, "d:/" is OK, anything else is an error
125 SUB SI,DX
126 CMP SI,2
127 JZ validate_end ;Two chars, the '/' and the NUL
128 CMP SI,4
129 JNZ validate_malformed ;Four chars, "D:/<NUL>"
130 MOV SI,DX
131 CMP BYTE PTR [SI+1],':'
132 JNZ validate_malformed ;Second char must be a ':'
133
134validate_end:
135 OR CX,CX ;Clears carry
136 JNZ validate_ok ;No metas found, leave carry clear
137validate_set_carry:
138 STC
139validate_ok:
140 POP SI
141 POP CX
142 POP AX
143 return
144validate_path ENDP
145
146BREAK <Access_path - determine if file found>
147
148;
149; Input: DS:DX point to a path
150; Output: Carry reset - outputs of GetPath
151; carry set - AL has error code
152;
153 procedure Access_path,NEAR
154 ASSUME DS:NOTHING,ES:NOTHING
155 CALL Validate_path
156 JC access_no_path
157 MOV SI,DX
158 invoke GetPath
159 retnc
160 MOV AL,error_file_not_found
161 OR CL,CL
162 JNZ access_ret
163access_no_path:
164 MOV AL,error_path_not_found
165access_ret:
166 STC
167 return
168access_path ENDP
169
170BREAK <Find_free_jfn - return a free jfn in users PDB>
171;
172; system file table data
173;
174
175;
176; The system file table is two linear tables. The first table is the
177; DOS initialization table containing a default number of FCBs. The
178; first word in the table is a link to the second table, which
179; SYSINIT sets up, the second word is the number of FCBs in the table.
180;
181
182;
183; find_free_jfn
184; input: none
185; output: JNC <found>
186; ES:DI is pointer to free JFN
187; JC <no free jfns>
188; ES,DI indeterminate
189;
190 procedure Find_free_jfn,NEAR
191 ASSUME DS:NOTHING,ES:NOTHING
192 PUSH AX
193 PUSH CX
194 MOV AL,0FFh
195 MOV ES,[CurrentPDB]
196 MOV DI,PDB_JFN_Table
197 MOV CX,FilPerProc
198 REPNE SCASB
199 STC
200 JNZ Find_jfn_ret
201 DEC DI
202 CLC
203Find_jfn_ret:
204 POP CX
205 POP AX
206 return
207Find_free_jfn ENDP
208
209BREAK <find_free_sfn - return a free sfn and sf pointer>
210;
211; find_free_sfn
212; input: none
213; output: JNC <found>
214; ES:DI is free sf entry
215; SI is sfn
216; JC <not found>
217; ES,DI,SI indeterminate
218;
219; sft_addr --> (link) count (fcbs)
220; links = -1 means end of list
221;
222 procedure Find_free_sfn,NEAR
223 ASSUME DS:NOTHING,ES:NOTHING
224 PUSH BX
225 PUSH CX
226 LES BX,sft_addr ; head of chain of tables
227 XOR SI,SI ; count of sfn
228
229 ; ES:BX points to table... search through table
230Find_sfn_in_table:
231 CMP BX,-1 ; end of chain
232 JZ Find_no_free_sfns
233 MOV DI,sft_table ; offset to sf entry
234 MOV CX,ES:[BX].sft_count ; count of fcbs in table
235
236Find_sfn:
237 CMP ES:BYTE PTR [BX+DI].sf_ref_count,0h
238 JZ Find_got_sfn ; ref count is 0 -> free entry
239 ADD DI,SIZE sf_entry ; look to next entry
240 INC SI ; bump sfn
241 LOOP Find_sfn
242 LES BX,ES:[BX].sft_link ; link to next
243 JMP SHORT Find_sfn_in_table ; look for more
244
245Find_no_free_sfns:
246 STC
247 JMP SHORT find_ret
248Find_got_sfn:
249 ADD DI,BX
250 CLC
251Find_ret:
252 POP CX
253 POP BX
254 RET
255Find_free_sfn ENDP
256
257BREAK <$Open - open a file handle>
258;
259; Assembler usage:
260; LDS DX, Name
261; MOV AH, Open
262; MOV AL, access
263; INT int_command
264;
265; ACCESS Function
266; ------ --------
267; open_for_read file is opened for reading
268; open_for_write file is opened for writing
269; open_for_both file is opened for both reading and writing.
270;
271; Error returns:
272; AX = error_invalid_access
273; = error_file_not_found
274; = error_access_denied
275; = error_too_many_open_files
276;
277
278 procedure $Open,NEAR
279 ASSUME DS:NOTHING,ES:NOTHING
280 MOV [Cr_read_only],0
281Open_create:
282 CMP AL,open_for_both ; validate access
283 JBE OPEN_get_jfn
284 error error_invalid_access
285
286OPEN_get_jfn:
287 MOV [open_name+2],DS
288 context DS
289 MOV open_name,DX
290 MOV open_access,AL
291
292 invoke Find_free_jfn ; scan through user's area
293 ; ES:DI is the jfn entry
294 JNC OPEN_get_sfn
295OPEN_too_many:
296 error error_too_many_open_files
297
298OPEN_get_sfn:
299 MOV OPEN_jfn_b,ES
300 MOV OPEN_jfn,DI
301 invoke Find_free_sfn ; get a free sft entry
302 ; ES:DI is the SFT entry that's free, SI is the sfn
303 JC OPEN_too_many
304
305OPEN_file:
306 MOV OPEN_sfn,SI
307 MOV OPEN_sfoff,DI
308 MOV OPEN_sfn_b,ES
309;
310; open the file
311;
312 PUSH DS
313 LDS DX,DWORD PTR [open_name]
314 ASSUME DS:NOTHING
315 CALL access_path
316 POP DS
317 ASSUME DS:DOSGROUP
318 JNC open_check_access ; carry set -> error
319 transfer SYS_RET_ERR
320
321open_check_access:
322 MOV ES,WORD PTR [CURBUF+2] ; get buffer location
323 MOV open_devid,AH
324 TEST AH,080h
325 JNZ open_set_FCB_dev ;is a device
326 MOV AL,ES:[BX].dir_attr
327 TEST AL,attr_directory ; can't open directories
328 JZ open_try_volid
329
330open_bad_access:
331 error error_access_denied
332
333open_try_volid:
334 TEST AL,attr_volume_id ; can't open volume ids
335 JNZ open_bad_access
336 TEST AL,attr_read_only ; check write on read only
337 JZ open_set_FCB
338 CMP [Cr_read_only],0
339 JNZ open_set_FCB ; ok if creating read only file
340 CMP open_access, open_for_read
341 JNZ open_bad_access ; writing on a read only file
342 JMP SHORT open_set_FCB
343
344open_set_FCB_dev:
345 PUSH SS
346 POP ES ;Device opens are DOSGROUP relative
347
348open_set_FCB:
349 MOV CX,11 ; copy name into FCB...
350 PUSH SI ; ES:BX is source, must change
351 MOV SI,BX ; ES:SI is source
352 MOV DI,open_sfoff ; ??:DI is dest
353 PUSH DS
354 PUSH ES
355 MOV ES,open_sfn_b ; ES:DI is dest
356 POP DS ; DS:SI is source
357 ASSUME DS:NOTHING
358;
359; need to save attribute for the close operation
360;
361 MOV AH,DS:[BX.dir_attr] ; save attribute for close
362 MOV ES:[DI.sf_attr],AH
363
364 ADD DI,sf_fcb+1 ; point to name
365
366 IF KANJI
367 MOVSB
368 CMP BYTE PTR ES:[DI-1],5
369 JNZ NOTKTRAN
370 MOV BYTE PTR ES:[DI-1],0E5H
371NOTKTRAN:
372 DEC CX
373 ENDIF
374
375 REP MOVSB ; move in parsed name
376 POP DS
377 ASSUME DS:DOSGROUP
378 POP SI
379 LES DI,DWORD PTR [open_sfoff]
380 ADD DI,sf_fcb ; offset on fcb in sf entry
381 MOV AH,open_devid
382 invoke DOOPEN ; let open code fill in blanks
383 context DS
384 LES DI,DWORD PTR [open_sfoff]
385 INC ES:[DI].sf_ref_count ; reference this FCB
386 MOV AL,open_access ; stash the access
387 MOV ES:BYTE PTR [DI].sf_mode,AL
388 XOR AX,AX
389 MOV ES:WORD PTR [DI.sf_FCB.fcb_RR],AX ; beginning of file
390 MOV ES:WORD PTR [DI.sf_FCB.fcb_RR+2],AX
391 INC AX
392 MOV ES:WORD PTR [DI.sf_FCB.fcb_RECSIZ],AX ; byte io only
393 LES DI,DWORD PTR [open_jfn]
394 MOV AX,open_sfn
395 MOV ES:BYTE PTR [DI],AL ; stash sfn in PDB
396 SUB DI,PDB_jfn_table ; get jfn for user
397 MOV AX,DI
398 transfer SYS_RET_OK
399$Open ENDP
400
401
402BREAK <$UNLINK - delete a file entry>
403;
404; Assembler usage:
405; LDS DX, name
406; MOV AH, Unlink
407; INT 21h
408;
409; Error returns:
410; AX = error_file_not_found
411; = error_access_denied
412;
413 procedure $UNLINK,NEAR
414 ASSUME DS:NOTHING,ES:NOTHING
415 CALL access_path
416 JNC unlink_check_attr
417 transfer SYS_RET_ERR
418
419unlink_check_attr:
420 JZ unlink_dir
421 LDS DI,DWORD PTR [CURBUF] ; get directory entry
422 TEST DS:[BX.dir_attr],attr_read_only
423 JZ unlink_doit
424
425unlink_dir:
426 error error_access_denied
427
428unlink_doit:
429 MOV BYTE PTR DS:[BX.dir_name],0E5h ; delete dir entry
430 MOV BYTE PTR DS:[DI.BUFDIRTY],1 ; dirty the buffer
431 LODSW
432 MOV BX,AX
433 AND BX,0FFFh
434 context DS
435 JZ unlink_flush
436 invoke RELEASE
437unlink_flush:
438 MOV AL,BYTE PTR ES:[BP.DPB_drive]
439 invoke FLUSHBUF
440 transfer SYS_RET_OK
441$UNLINK ENDP
442
443BREAK <$CREAT - creat a new file and open him for input>
444;
445; Assembler usage:
446; LDS DX, name
447; MOV AH, Creat
448; MOV CX, access
449; INT 21h
450; ; AX now has the handle
451;
452; Error returns:
453; AX = error_access_denied
454; = error_path_not_found
455; = error_too_many_open_files
456;
457
458
459 procedure $CREAT,NEAR
460 ASSUME DS:NOTHING,ES:NOTHING
461 CALL Validate_path
462 JNC unlink_do_make
463 error error_path_not_found
464unlink_do_make:
465 PUSH DX
466 PUSH DS
467 context DS
468 MOV WORD PTR [CREATING],0E5FFh
469 MOV WORD PTR [ThisFCB+2],SS
470 MOV WORD PTR [ThisFCB],OFFSET DOSGROUP:AUXSTACK-40
471 MOV SI,DX
472 MOV AL,CL
473 AND CL,attr_read_only
474 MOV [Cr_read_only],CL
475 POP DS
476 PUSH DS
477ASSUME DS:NOTHING
478 invoke MakeNode
479 POP DS
480 POP DX
481 OR AL,AL
482 JZ creat_open
483 CMP AL,3
484 JZ creat_open
485creat_no_access:
486 error error_access_denied
487creat_open:
488 MOV AL,open_for_both
489 JMP Open_create
490
491$CREAT ENDP
492
493
494BREAK <$DUP - duplicate a jfn>
495;
496; Assembler usage:
497; MOV BX, fh
498; MOV AH, Dup
499; INT int_command
500; AX has the returned handle
501; Errors:
502; AX = dup_invalid_handle
503; = dup_too_many_open_files
504 procedure $DUP,NEAR
505 ASSUME DS:NOTHING,ES:NOTHING
506 context DS
507 invoke Find_free_jfn
508 JC dup_no_free_handles
509
510dup_force:
511 PUSH ES
512 PUSH DI
513 invoke Get_sf_from_jfn
514 POP SI
515 POP DS
516 JC dup_bad_handle
517 ; ES:DI is pointer to sf entry
518 ; DS:DI is pointer to jfn
519 INC ES:[DI].sf_ref_count ; another jfn reference...
520 MOV AL,[BX].PDB_JFN_table ; get old sfn
521 MOV [SI],AL ; store in new place
522 SUB SI,PDB_JFN_table ; get jfn
523 MOV AX,SI
524 transfer SYS_RET_OK
525
526dup_no_free_handles:
527 error error_too_many_open_files
528
529dup_bad_handle:
530 error error_invalid_handle
531$DUP ENDP
532
533BREAK <$DUP2 - force a dup on a particular jfn>
534;
535; Assembler usage:
536; MOV BX, fh
537; MOV CX, newfh
538; MOV AH, Dup2
539; INT int_command
540; Error returns:
541; AX = error_invalid_handle
542;
543 procedure $DUP2,NEAR
544 ASSUME DS:NOTHING,ES:NOTHING
545 XCHG BX,CX ; BX < destination jfn
546 PUSH BX
547 PUSH CX
548 invoke $CLOSE ; close BX
549 context DS
550 POP CX
551 POP BX
552 invoke Get_jfn_pointer
553 XCHG BX,CX
554 JNC dup_force
555lseek_bad_handle:
556 error error_invalid_handle
557$DUP2 ENDP
558
559
560BREAK <$CHMOD - change file attributes>
561;
562; Assembler usage:
563; LDS DX, name
564; MOV CX, attributes
565; INT 21h
566; Error returns:
567; AX = error_path_not_found
568; AX = error_access_denied
569;
570 procedure $CHMOD,NEAR
571 ASSUME DS:NOTHING,ES:NOTHING
572 CMP AL,1
573 JBE chmod_save
574 error error_invalid_function
575chmod_save:
576 JB chmod_try_file
577 MOV BX,CX
578 AND BX,NOT attr_changeable
579 JZ chmod_try_file
580
581chmod_bad:
582 error error_access_denied
583
584chmod_bye:
585 transfer SYS_RET_ERR
586chmod_try_file:
587 PUSH CX
588 PUSH AX
589 CALL access_path
590 POP DX
591 POP CX
592 JC chmod_bye
593 LES DI,[CURBUF]
594 context DS
595 OR DL,DL
596 JZ chmod_fetch
597 AND BYTE PTR ES:[BX].dir_attr,NOT attr_changeable
598 OR BYTE PTR ES:[BX].dir_attr,CL
599 MOV ES:[DI.BUFDIRTY],1
600 MOV AL,-1
601 invoke FlushBuf
602 transfer SYS_RET_OK
603chmod_fetch:
604 XOR CX,CX
605 MOV CL,BYTE PTR ES:[BX].dir_attr
606 invoke Get_user_stack
607 MOV [SI.user_CX],CX
608 transfer SYS_RET_OK
609$chmod ENDP
610
611BREAK <$CURRENT_DIR - dump the current directory into user space>
612;
613; Assembler usage:
614; LDS SI,area
615; MOV DL,drive
616; INT 21h
617; ; DS:SI is a pointer to 64 byte area that contains drive
618; ; current directory.
619; Error returns:
620; AX = error_invalid_drive
621;
622procedure $CURRENT_DIR,NEAR
623 ASSUME DS:NOTHING,ES:NOTHING
624 PUSH DS
625 PUSH BX
626 PUSH SI
627 invoke $get_DPB
628;
629; ES:BP points to DPB. DS:SI points to user stack, unless error
630;
631 CMP AL,0FFh
632 JNZ current_copy
633 POP AX ; Clean Stack
634 POP AX
635 POP AX
636 error error_invalid_drive
637
638current_copy:
639 POP DI ; where to move to
640 POP [SI.user_BX] ; restore old BX
641 POP BX
642 MOV [SI.user_DS],BX ; and restore old DS
643;
644; ES:BP is pointer to DPB. BX:DI is pointer to destination
645;
646 CMP ES:[BP.dpb_current_dir],-1
647 JNZ current_ok
648 PUSH BX
649 PUSH DI
650 MOV [ATTRIB],attr_all
651 invoke GETCURRDIR
652 POP DI
653 POP BX
654current_ok:
655 MOV SI,BP ; ES:SI is source
656 PUSH ES
657 POP DS ; DS:SI is source
658 MOV ES,BX ; ES:DI is destination
659 CMP [SI.dpb_current_dir],0
660 JNZ current_move
661 MOV BYTE PTR [SI.dpb_dir_text],0
662
663current_move:
664 ADD SI,dpb_dir_text
665 MOV CX,DIRSTRLEN
666current_loop:
667 LODSB
668 STOSB
669 OR AL,AL
670 LOOPNZ current_loop
671 transfer SYS_RET_OK
672$CURRENT_DIR ENDP
673
674
675BREAK <$RENAME - move directory entries around>
676;
677; Assembler usage:
678; LDS DX, source
679; LES DI, dest
680; MOV AH, Rename
681; INT 21h
682;
683; Error returns:
684; AX = error_file_not_found
685; = error_not_same_device
686; = error_access_denied
687procedure $RENAME,near
688
689 MOV WORD PTR [rename_source],DX
690 MOV WORD PTR [rename_source+2],DS
691 MOV WORD PTR [rename_dest],DI
692 MOV WORD PTR [rename_dest+2],ES
693 CALL Access_path
694 JNC rename_check_dir
695 transfer SYS_RET_ERR
696
697rename_check_dir:
698 JZ rename_no_access
699 MOV DS,WORD PTR [CurBuf+2]
700 PUSH [BX.dir_date]
701 PUSH [BX.dir_first]
702 PUSH [BX.dir_size_h]
703 PUSH [BX.dir_size_l]
704 PUSH [BX.dir_time]
705 PUSH WORD PTR [BX.dir_attr]
706 PUSH WORD PTR [ThisDrv]
707 LDS SI,[rename_dest]
708 invoke GetPath
709 POP AX
710 JC rename_check_drives
711rename_bad_access:
712 ADD SP,12
713rename_no_access:
714 error error_access_denied
715rename_check_drives:
716 CMP AL,[ThisDrv]
717 JZ rename_create
718 ADD SP,12
719 error error_not_same_device
720rename_create:
721 LDS SI,[rename_dest]
722 POP AX
723 PUSH AX
724 MOV WORD PTR [Creating],0E5FFh
725 MOV WORD PTR [ThisFCB+2],SS
726 MOV WORD PTR [ThisFCB],OFFSET DOSGROUP:AUXStack-40
727 invoke MakeNode
728 JC rename_bad_access
729 LDS SI,[CurBuf]
730 POP AX
731 MOV [BX.dir_attr],AL
732 POP [BX.dir_time]
733 POP [BX.dir_size_l]
734 POP [BX.dir_size_h]
735 POP [BX.dir_first]
736 POP [BX.dir_date]
737 MOV [SI.BUFDIRTY],1
738 LDS SI,[rename_source]
739 invoke GetPath
740 LDS SI,[CurBuf]
741 MOV BYTE PTR [BX],0E5h
742 MOV [SI.BUFDIRTY],1
743 context DS
744 MOV AL,0FFh
745 invoke FlushBuf
746 transfer SYS_RET_OK
747
748$RENAME ENDP
749
750BREAK <$FIND_FIRST - find first matching xenix filename>
751;
752; Assembler usage:
753; MOV AH, FindFirst
754; LDS DX, name
755; MOV CX, attr
756; INT 21h
757; ; DMA address has datablock
758;
759; Error Returns:
760; AX = error_file_not_found
761; = error_no_more_files
762;
763procedure $FIND_FIRST,near
764 ASSUME DS:NOTHING,ES:NOTHING
765 CALL Validate_path
766 JNC find_get
767 JZ find_get
768 error error_file_not_found
769find_get:
770 MOV SI,DX
771 PUSH CX
772 INC BYTE PTR [NoSetDir] ; if we find a dir, don't change to it
773 MOV WORD PTR [Creating],0E500h
774 CALL GetPath
775 POP CX
776 MOV [Attrib],CL
777find_check:
778 JNC find_check_attr
779find_no_more:
780 error error_no_more_files
781find_check_attr:
782 MOV DS,WORD PTR [CURBUF+2]
783 MOV CH,[BX.dir_attr]
784 invoke MatchAttributes
785 JZ found_it
786 PUSH [LastEnt]
787 MOV BX,[DirStart]
788 JMP find_it_next
789found_it:
790 LES DI,[DMAADD]
791 MOV AL,[Attrib]
792 STOSB ; find_buf 0 = attribute in search
793 MOV AL,[ThisDrv]
794 STOSB ; find_buf 1 = drive
795 MOV CX,11
796 PUSH BX
797 MOV SI,OFFSET DOSGROUP:NAME1; find_buf 2 = formatted name
798 PUSH DS
799 PUSH SS
800 POP DS
801
802 IF KANJI
803 MOVSB
804 CMP BYTE PTR ES:[DI-1],5
805 JNZ NOTKANJB
806 MOV BYTE PTR ES:[DI-1],0E5H
807NOTKANJB:
808 DEC CX
809 ENDIF
810
811 REP MOVSB
812 POP DS
813 MOV AX,[LastEnt]
814 STOSW ; find_buf 13 = LastEnt
815 MOV AX,WORD PTR [ThisDPB]
816 STOSW ; find_buf 15 = ThisDPB
817 MOV AX,WORD PTR [ThisDPB+2]
818 STOSW
819 MOV AX,[DirStart]
820 STOSW ; find_buf 19 = DirStart
821 MOV AL,[BX].dir_attr
822 STOSB ; find_buf 21 = attribute found
823 MOV AX,[BX].dir_time
824 STOSW ; find_buf 22 = time
825 MOV AX,[BX].dir_date
826 STOSW ; find_buf 24 = date
827 MOV AX,[BX].dir_size_l
828 STOSW ; find_buf 26 = low(size)
829 MOV AX,[BX].dir_size_h
830 STOSW ; find_buf 28 = high(size)
831 POP SI
832 MOV CX,8 ; find_buf 30 = packed name
833find_loop_name:
834 LODSB
835 STOSB
836 CMP AL," "
837 LOOPNZ find_loop_name
838 JNZ find_check_dot
839 DEC DI
840find_check_dot:
841 ADD SI,CX
842 CMP BYTE PTR [SI]," "
843 JZ find_done
844 MOV AL,"."
845 STOSB
846 MOV CX,3
847find_loop_ext:
848 LODSB
849 STOSB
850 CMP AL," "
851 LOOPNZ find_loop_ext
852 JNZ find_done
853 DEC DI
854find_done:
855 XOR AL,AL
856 STOSB
857 transfer SYS_RET_OK
858$FIND_FIRST ENDP
859
860BREAK <$FIND_NEXT - scan for match in directory>
861;
862; Assembler usage:
863; ; dma points at area returned by find_first
864; MOV AH, findnext
865; INT 21h
866; ; next entry is at dma
867;
868; Error Returns:
869; AX = error_no_more_files
870;
871procedure $FIND_NEXT,near
872 ASSUME DS:NOTHING,ES:NOTHING
873 LDS SI,[DMAADD]
874 MOV DX,SI
875 INC DX
876 PUSH SI
877 invoke MOVNAMENOSET
878 POP SI
879 JNC find_load
880findnext_no_more:
881 error error_no_more_files
882find_load:
883 MOV AX,[SI.find_buf_LastEnt]
884 LES BP,[SI.find_buf_ThisDPB]
885 OR AX,AX
886 JS findnext_no_more
887 MOV BX,[SI.find_buf_DirStart]
888 MOV DL,[SI.find_buf_sattr]
889 MOV [Attrib],DL
890 PUSH AX
891 MOV WORD PTR [ThisDPB],BP
892 MOV WORD PTR [ThisDPB+2],ES
893find_it_next:
894 invoke SetDirSrch
895 ASSUME DS:DOSGROUP
896 POP AX
897 MOV [ENTLAST],-1
898 invoke GetEnt
899 invoke NextEnt
900 JMP find_check
901$find_next ENDP
902
903do_ext
904
905CODE ENDS
906 END
907
diff --git a/v2.0/source/XENIX2.ASM b/v2.0/source/XENIX2.ASM
new file mode 100644
index 0000000..1535dbb
--- /dev/null
+++ b/v2.0/source/XENIX2.ASM
@@ -0,0 +1,626 @@
1;
2; xenix file calls for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7IFNDEF KANJI
8KANJI EQU 0 ;FALSE
9ENDIF
10
11CODE SEGMENT BYTE PUBLIC 'CODE'
12 ASSUME SS:DOSGROUP,CS:DOSGROUP
13
14.xlist
15.xcref
16INCLUDE DOSSYM.ASM
17INCLUDE DEVSYM.ASM
18.cref
19.list
20
21TITLE XENIX - IO system to mimic UNIX
22NAME XENIX
23
24 i_need NoSetDir,BYTE
25 i_need CURDRV,BYTE
26 i_need IOCALL,BYTE
27 i_need IOMED,BYTE
28 i_need IOSCNT,WORD
29 i_need IOXAD,DWORD
30 i_need DIRSTART,WORD
31 i_need ATTRIB,BYTE
32 i_need THISFCB,DWORD
33 i_need AuxStack,BYTE
34 i_need Creating,BYTE
35 i_need ThisDRV,BYTE
36 i_need NAME1,BYTE
37 i_need LastEnt,WORD
38 i_need ThisDPB,DWORD
39 i_need EntLast,WORD
40 i_need CurrentPDB,WORD
41 i_need sft_addr,DWORD ; pointer to head of table
42 i_need CURBUF,DWORD ; pointer to current buffer
43 i_need DMAADD,DWORD ; pointer to current dma address
44
45BREAK <Local data>
46
47CODE ENDS
48DATA SEGMENT BYTE PUBLIC 'DATA'
49
50
51PushSave DW ?
52PushES DW ?
53PushBX DW ?
54
55xenix_count DW ?
56
57DATA ENDS
58CODE SEGMENT BYTE PUBLIC 'CODE'
59
60
61BREAK <get_sf_from_sfn - translate a sfn into sf pointer>
62;
63; get_sf_from_sfn
64; input: AX has sfn (0 based)
65; DS is DOSGROUP
66; output: JNC <found>
67; ES:DI is sf entry
68; JC <error>
69; ES,DI indeterminate
70;
71 procedure get_sf_from_sfn,NEAR
72 ASSUME DS:DOSGROUP,ES:NOTHING
73 PUSH AX ; we trash AX in process
74 LES DI,[sft_addr]
75
76get_sfn_loop:
77 CMP DI,-1 ; end of chain of tables?
78 JZ get_sf_invalid ; I guess so...
79 SUB AX,ES:[DI].sft_count ; chop number of entries in this table
80 JL get_sf_gotten ; sfn is in this table
81 LES DI,ES:[DI].sft_link ; step to next table
82 JMP get_sfn_loop
83
84get_sf_gotten:
85 ADD AX,ES:[DI].sft_count ; reset to index in this table
86 PUSH BX
87 MOV BX,SIZE sf_entry
88 MUL BL ; number of bytes offset into table
89 POP BX
90 ADD AX,sft_table ; offset into sf table structure
91 ADD DI,AX ; offset into memory
92 CLC
93 JMP SHORT get_sf_ret
94
95get_sf_jfn_invalid:
96get_sf_invalid:
97 STC
98
99get_sf_jfn_ret:
100get_sf_ret:
101 POP AX ; remember him?
102 RET
103get_sf_from_sfn ENDP
104
105BREAK <get_sf_from_jfn - translate a jfn into sf pointer>
106;
107; get_sf_from_jfn
108; input: BX is jfn 0 based
109; DS is DOSGROUP
110; output: JNC <found>
111; ES:DI is sf entry
112; JC <error>
113; ES,DI is indeterminate
114;
115 procedure get_sf_from_jfn,NEAR
116 ASSUME DS:DOSGROUP,ES:NOTHING
117 PUSH AX ; save him
118 invoke get_jfn_pointer
119 JC get_sf_jfn_invalid
120 MOV AL,ES:[DI] ; get sfn
121 CMP AL,0FFh ; is it free?
122 JZ get_sf_jfn_invalid ; yep... error
123 XOR AH,AH
124 invoke get_sf_from_sfn ; check this sfn out...
125 JMP SHORT get_sf_jfn_ret ; condition codes are properly set
126
127get_sf_from_jfn ENDP
128
129BREAK <get_jfn_pointer - map a jfn into a pointer to jfn>
130;
131; get_jfn_pointer
132; input: BX is jfn
133; DS is DOSGROUP
134; output: JNC <found>
135; ES:DI is pointer to jfn
136; JC <bad jfn>
137;
138 procedure Get_jfn_pointer,NEAR
139 ASSUME DS:DOSGROUP,ES:NOTHING
140 CMP BX,FilPerProc
141 JAE get_jfn_bad
142 MOV ES,[CurrentPDB]
143 MOV DI,BX
144 ADD DI,PDB_JFN_Table
145 CLC
146 RET
147
148get_jfn_bad:
149 STC
150 RET
151get_jfn_pointer ENDP
152
153
154BREAK <$Close - release a handle>
155;
156; Assembler usage:
157; MOV BX, handle
158; MOV AH, Close
159; INT int_command
160;
161; Error return:
162; AX = error_invalid_handle
163;
164 procedure $Close,NEAR
165 ASSUME DS:NOTHING,ES:NOTHING
166
167 context DS
168
169 invoke get_jfn_pointer ; get jfn loc
170 JNC close_jfn
171close_bad_handle:
172 error error_invalid_handle
173
174close_jfn:
175 MOV AL,BYTE PTR ES:[DI]
176 CMP AL,0FFh
177 JE close_bad_handle
178 MOV BYTE PTR ES:[DI],0FFh;
179 XOR AH,AH
180 invoke get_sf_from_sfn
181 JC close_bad_handle
182 PUSH ES
183 POP DS
184 ASSUME DS:NOTHING
185 DEC [DI].sf_ref_count ; no more reference
186 LEA DX,[DI].sf_fcb
187;
188; need to restuff Attrib if we are closing a protected file
189;
190 TEST [DI.sf_fcb.fcb_DevID],devid_file_clean+devid_device
191 JNZ close_ok
192 PUSH WORD PTR [DI].sf_attr
193 invoke MOVNAMENOSET
194 POP BX
195 MOV [Attrib],BL
196 invoke FCB_CLOSE_INNER
197 CMP AL,0FFh ; file not found error?
198 JNZ close_ok
199 error error_file_not_found
200close_ok:
201 transfer SYS_RET_OK
202
203$Close ENDP
204
205
206BREAK <PushDMA, PopDMA, ptr_normalize - set up local dma and save old>
207; PushDMA
208; input: DS:DX is DMA
209; output: DS:DX is normalized , ES:BX destroyed
210; [DMAADD] is now set up to DS:DX
211; old DMA is pushed
212
213 procedure PushDMA,NEAR
214 ASSUME DS:NOTHING,ES:NOTHING
215
216 MOV PushES,ES
217 MOV PushBX,BX
218 POP PushSave
219 LES BX,DWORD PTR [DMAADD] ; get old dma
220 PUSH ES
221 PUSH BX
222 PUSH PushSave
223 invoke ptr_normalize ; get new dma
224 MOV WORD PTR [DMAADD],DX ; save IT!
225 MOV WORD PTR [DMAADD+2],DS
226 MOV ES,PushES
227 MOV BX,PushBX
228 RET
229PushDMA ENDP
230
231; PopDMA
232; input: old DMA under ret address on stack
233; output: [DMAADD] set to old version and stack popped
234 procedure PopDMA,NEAR
235 ASSUME DS:NOTHING,ES:NOTHING
236
237 POP PushSave
238 POP WORD PTR [DMAADD]
239 POP WORD PTR [DMAADD+2]
240 PUSH PushSave
241 RET
242PopDMA ENDP
243
244; ptr_normalize
245; input: DS:DX is a pointer
246; output: DS:DX is normalized (DX < 10h)
247 procedure ptr_normalize,NEAR
248 PUSH CX ; T1 = CX
249 PUSH DX ; T2 = DX
250 MOV CL,4
251 SHR DX,CL ; DX = (DX >> 4) (using CX)
252 MOV CX,DS
253 ADD CX,DX
254 MOV DS,CX ; DS = DS + DX (using CX)
255 POP DX
256 AND DX,0Fh ; DX = T2 & 0Fh
257 POP CX ; CX = T1
258
259; PUSH AX
260; PUSH DX
261; MOV AX,DS
262; PUSH CX
263; MOV CL,4
264; SHR DX,CL ; get upper part of dx
265; POP CX
266; ADD AX,DX ; add into seg address
267; MOV DS,AX
268; POP DX
269; AND DX,0Fh ; save low part
270; POP AX
271
272 RET
273ptr_normalize ENDP
274
275BREAK <$Read - Do file/device I/O>
276;
277; Assembler usage:
278; LDS DX, buf
279; MOV CX, count
280; MOV BX, handle
281; MOV AH, Read
282; INT int_command
283; AX has number of bytes read
284; Errors:
285; AX = read_invalid_handle
286; = read_access_denied
287;
288
289 procedure $Read,NEAR
290 ASSUME DS:NOTHING,ES:NOTHING
291
292 invoke PushDMA
293 CALL IO_setup
294 JC IO_err
295 CMP ES:[DI].sf_mode,open_for_write
296 JNE read_setup
297IO_bad_mode:
298 MOV AL,read_access_denied
299IO_err:
300 invoke PopDMA
301 transfer SYS_RET_ERR
302
303read_setup:
304 invoke $FCB_RANDOM_READ_BLOCK ; do read
305IO_done:
306 invoke get_user_stack ; get old frame
307 MOV AX,[SI].user_CX ; get returned CX
308 MOV CX,xenix_count
309 MOV [SI].user_CX,CX ; stash our CX
310 invoke PopDMA ; get old DMA
311 transfer SYS_RET_OK
312$Read ENDP
313
314BREAK <$Write - Do file/device I/O>
315;
316; Assembler usage:
317; LDS DX, buf
318; MOV CX, count
319; MOV BX, handle
320; MOV AH, Write
321; INT int_command
322; AX has number of bytes written
323; Errors:
324; AX = write_invalid_handle
325; = write_access_denied
326;
327
328 procedure $Write,NEAR
329 ASSUME DS:NOTHING,ES:NOTHING
330
331 invoke PushDMA
332 CALL IO_setup
333 JC IO_err
334 CMP ES:[DI].sf_mode,open_for_read
335 JE IO_bad_mode
336 invoke $FCB_RANDOM_WRITE_BLOCK ; do write
337 JMP IO_done
338
339$write ENDP
340
341IO_setup:
342 ASSUME DS:NOTHING,ES:NOTHING
343 context DS
344 MOV xenix_count,CX
345 invoke Get_sf_from_jfn
346 ; ES:DI is sf pointer
347 MOV AL,read_invalid_handle ;Assume an error
348 MOV CX,xenix_count
349 LEA DX,[DI].sf_fcb
350 PUSH ES
351 POP DS
352 ASSUME DS:NOTHING
353 RET
354
355BREAK <$LSEEK - set random record field>
356;
357; Assembler usage:
358; MOV DX, offsetlow
359; MOV CX, offsethigh
360; MOV BX, handle
361; MOV AL, method
362; MOV AH, LSeek
363; INT int_command
364; DX:AX has the new location of the pointer
365; Error returns:
366; AX = error_invalid_handle
367; = error_invalid_function
368 procedure $LSEEK,NEAR
369 ASSUME DS:NOTHING,ES:NOTHING
370 CMP AL,3
371 JB lseek_get_sf
372 error error_invalid_function
373
374lseek_get_sf:
375 context DS
376 invoke get_sf_from_jfn
377 PUSH ES
378 POP DS
379 ASSUME DS:NOTHING
380 JC lseek_bad
381;
382; don't seek device
383;
384 TEST [DI.sf_fcb+fcb_devid],devid_device
385 JZ lseek_dispatch
386 XOR AX,AX
387 XOR DX,DX
388 JMP SHORT lseek_ret
389lseek_dispatch:
390 DEC AL
391 JL lseek_beginning
392 DEC AL
393 JL lseek_current
394; move from end of file
395; first, get end of file
396 XCHG AX,DX ; AX <- low
397 XCHG DX,CX ; DX <- high
398 ASSUME DS:NOTHING
399 ADD AX,[DI+sf_fcb+fcb_FILSIZ]
400 ADC DX,[DI+sf_fcb+fcb_FILSIZ+2]
401 JMP SHORT lseek_ret
402
403lseek_beginning:
404 XCHG AX,DX ; AX <- low
405 XCHG DX,CX ; DX <- high
406
407lseek_ret:
408 MOV WORD PTR [DI+sf_fcb+fcb_RR],AX
409 MOV WORD PTR [DI+sf_fcb+fcb_RR+2],DX
410 invoke get_user_stack
411 MOV [SI.user_DX],DX
412 MOV [SI.user_AX],AX
413 transfer SYS_RET_OK
414
415lseek_current:
416; ES:DI is pointer to sf... need to invoke set random record for place
417 XCHG AX,DX ; AX <- low
418 XCHG DX,CX ; DX <- high
419 ADD AX,WORD PTR [DI+sf_fcb+fcb_RR]
420 ADC DX,WORD PTR [DI+sf_fcb+fcb_RR+2]
421 JMP lseek_ret
422
423lseek_bad:
424 error error_invalid_handle
425$lseek ENDP
426
427
428BREAK <$IOCTL - return/set device dependent stuff>
429;
430; Assembler usage:
431; MOV BX, Handle
432; MOV DX, Data
433;
434; (or LDS DX,BUF
435; MOV CX,COUNT)
436;
437; MOV AH, Ioctl
438; MOV AL, Request
439; INT 21h
440;
441; Error returns:
442; AX = error_invalid_handle
443; = error_invalid_function
444; = error_invalid_data
445
446 procedure $IOCTL,NEAR
447 ASSUME DS:NOTHING,ES:NOTHING
448 MOV SI,DS ;Stash DS for calls 2,3,4 and 5
449 context DS
450 CMP AL,3
451 JA ioctl_check_block ;Block device
452 PUSH DX
453 invoke get_sf_from_jfn
454 POP DX ;Restore DATA
455 JNC ioctl_check_permissions ; have valid handle
456 error error_invalid_handle
457
458ioctl_check_permissions:
459 CMP AL,2
460 JAE ioctl_control_string
461 CMP AL,0
462 MOV AL,BYTE PTR ES:[DI+sf_fcb+fcb_devid]
463 JZ ioctl_read ; read the byte
464 OR DH,DH
465 JZ ioctl_check_device ; can I set with this data?
466 error error_invalid_data ; no DH <> 0
467
468ioctl_check_device:
469 TEST AL,devid_ISDEV ; can I set this handle?
470 JZ ioctl_bad_fun ; no, it is a file.
471 MOV BYTE PTR ES:[DI+sf_fcb+fcb_devid],DL
472 transfer SYS_RET_OK
473
474ioctl_read:
475 XOR AH,AH
476 TEST AL,devid_ISDEV ; Should I set high byte
477 JZ ioctl_no_high ; no
478 LES DI,DWORD PTR ES:[DI+sf_fcb+fcb_FIRCLUS] ;Get device pointer
479 MOV AH,BYTE PTR ES:[DI.SDEVATT+1] ;Get high byte
480ioctl_no_high:
481 invoke get_user_stack
482 MOV DX,AX
483 MOV [SI.user_DX],DX
484 transfer SYS_RET_OK
485
486ioctl_control_string:
487 TEST BYTE PTR ES:[DI+sf_fcb+fcb_devid],devid_ISDEV ; can I?
488 JZ ioctl_bad_fun ; no, it is a file.
489 LES DI,DWORD PTR ES:[DI+sf_fcb+fcb_FIRCLUS] ;Get device pointer
490 XOR BL,BL ; Unit number of char dev = 0
491 JMP SHORT ioctl_do_string
492
493ioctl_check_block:
494 DEC AL
495 DEC AL ;4=2,5=3,6=4,7=5
496 CMP AL,3
497 JBE ioctl_get_dev
498
499 MOV AH,1
500 SUB AL,4 ;6=0,7=1
501 JZ ioctl_get_status
502 MOV AH,3
503 DEC AL
504 JNZ ioctl_bad_fun
505
506ioctl_get_status:
507 PUSH AX
508 invoke GET_IO_FCB
509 POP AX
510 JC ioctl_acc_err
511 invoke IOFUNC
512 MOV AH,AL
513 MOV AL,0FFH
514 JNZ ioctl_status_ret
515 INC AL
516ioctl_status_ret:
517 transfer SYS_RET_OK
518
519ioctl_bad_fun:
520 error error_invalid_function
521
522ioctl_acc_err:
523 error error_access_denied
524
525ioctl_get_dev:
526 PUSH CX
527 PUSH DX
528 PUSH AX
529 PUSH SI ;DS in disguise
530 MOV AL,BL ;Drive
531 invoke GETTHISDRV
532 JC ioctl_bad_drv
533 invoke FATREAD ;"get" the drive
534 MOV BL,ES:[BP.dpb_UNIT] ; Unit number
535 LES DI,ES:[BP.dpb_driver_addr]
536 CLC ;Make sure error jump not taken
537ioctl_bad_drv:
538 POP SI
539 POP AX
540 POP DX
541 POP CX
542 JC ioctl_acc_err
543ioctl_do_string:
544 TEST ES:[DI.SDEVATT],DEVIOCTL ;See if device accepts control
545 JZ ioctl_bad_fun ;NO
546 DEC AL
547 DEC AL
548 JZ ioctl_control_read
549 MOV [IOCALL.REQFUNC],DEVWRIOCTL
550 JMP SHORT ioctl_control_call
551ioctl_control_read:
552 MOV [IOCALL.REQFUNC],DEVRDIOCTL
553ioctl_control_call:
554 MOV AL,DRDWRHL
555 MOV AH,BL ;Unit number
556 MOV WORD PTR [IOCALL.REQLEN],AX
557 XOR AX,AX
558 MOV [IOCALL.REQSTAT],AX
559 MOV [IOMED],AL
560 MOV [IOSCNT],CX
561 MOV WORD PTR [IOXAD],DX
562 MOV WORD PTR [IOXAD+2],SI
563 PUSH ES
564 POP DS
565ASSUME DS:NOTHING
566 MOV SI,DI ;DS:SI -> driver
567 PUSH SS
568 POP ES
569 MOV BX,OFFSET DOSGROUP:IOCALL ;ES:BX -> Call header
570 invoke DEVIOCALL2
571 MOV AX,[IOSCNT] ;Get actual bytes transferred
572 transfer SYS_RET_OK
573
574$IOCTL ENDP
575
576BREAK <File_Times - modify write times on a handle>
577;
578; Assembler usage:
579; MOV AH, FileTimes
580; MOV AL, func
581; MOV BX, handle
582; ; if AL = 1 then then next two are mandatory
583; MOV CX, time
584; MOV DX, date
585; INT 21h
586; ; if AL = 0 then CX/DX has the last write time/date
587; ; for the handle.
588;
589; Error returns:
590; AX = error_invalid_function
591; = error_invalid_handle
592;
593procedure $File_times,near
594 CMP AL,2
595 JB filetimes_ok
596 error error_invalid_function
597
598filetimes_ok:
599 PUSH SS
600 POP DS
601 CALL Get_sf_from_jfn
602 JNC filetimes_disp
603 error error_invalid_handle
604
605filetimes_disp:
606 OR AL,AL
607 JNZ filetimes_set
608 MOV CX,ES:[DI.sf_fcb.fcb_FTIME]
609 MOV DX,ES:[DI.sf_fcb.fcb_FDATE]
610 invoke Get_user_stack
611 MOV [SI.user_CX],CX
612 MOV [SI.user_DX],DX
613 transfer SYS_RET_OK
614
615filetimes_set:
616 MOV ES:[DI.sf_fcb.fcb_FTIME],CX
617 MOV ES:[DI.sf_fcb.fcb_FDATE],DX
618 AND ES:[DI.sf_fcb.fcb_DEVID],NOT devid_file_clean
619 transfer SYS_RET_OK
620$file_times ENDP
621
622do_ext
623
624CODE ENDS
625 END
626