summaryrefslogtreecommitdiff
path: root/v2.0/source/PRINT_v211.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/PRINT_v211.ASM')
-rw-r--r--v2.0/source/PRINT_v211.ASM1645
1 files changed, 1645 insertions, 0 deletions
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