]>
wirehaze git hosting - MS-DOS.git/blob - v2.0/source/PRINT_v211.ASM
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
20 ; VERSION 1.00 07/03/82
31 HARDINT EQU FALSE
;No hardware ints
32 AINT EQU FALSE
;No need to do interrupt acknowledge
37 INTLOC EQU 1
CH ;Hardware interrupt location (Timer)
38 AINT EQU TRUE
;Acknowledge interrupts
39 EOI EQU 20H
;End Of Interrupt "instruction"
40 AKPORT EQU 20H
;Interrupt Acknowledge port
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
62 TIMESLICE 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
73 MAXTICK 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.
78 BUSYTICK 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.
84 ;User gets TIMESLICE ticks and then PRINT takes MAXTICK ticks unless BUSYTICK
85 ; ticks go by without getting a character out.
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.
98 SOFTINT EQU 28H
;Software interrupt generated by DOS
99 COMINT EQU 2FH
;Communications interrupt used by PRINT
100 ; This vector number is DOS reserved. It
101 ; is not generally available to programs
104 BLKSIZ EQU
512 ;Size of the PRINT I/O block in bytes
105 FCBSIZ EQU
40 ;Size of an FCB
121 HEADER
DB "Vers 1.00"
124 ISTACK
LABEL WORD ;Stack starts here and grows down
129 INDOS
DD ?
;DOS buisy flag
130 NEXTINT
DD ?
;Chain for int
131 BUSY
DB 0 ;Internal ME flag
132 SOFINT
DB 0 ;Internal ME flag
133 TICKCNT
DB 0 ;Tick counter
134 TICKSUB
DB 0 ;Tick miss counter
135 SLICECNT
DB TIMESLICE
;Time slice counter
138 CBUSY
DB 0 ;ME on com interrupt
139 SPNEXT
DD ?
;Chain location for INT 28
140 PCANMES
DB 0 ;Cancel message flag
141 SSsave
DW ?
;Stack save area for INT 24
143 DMAADDR
DD ?
;Place to save DMA address
144 HERRINT
DD ?
;Place to save Hard error interrupt
145 LISTDEV
DD ?
;Pointer to Device
146 COLPOS
DB 0 ;Column position for TAB processing
147 NXTCHR
DW OFFSET DG
:BUFFER
+ BLKSIZ
;Buffer pointer
148 CURRFIL
DW OFFSET DG
:SPLFCB
;Current file being printed
150 LASTFCB
DW ?
;Back pointer
151 LASTFCB2
DW ?
;Another back pointer
152 PABORT
DB 0 ;Abort flag
156 ERRMES
DB 13,10,13,10,"**********",13,10,"$"
157 ERRMEST
DB " error reading file",13,10
159 BELMES
DB 13,0CH,7,"$"
161 CANMES
DB 13,10,13,10
163 DB " Canceled by operator$"
165 ALLCAN
DB 13,10,13,10,"All files canceled by operator$"
167 MESBAS
DW OFFSET DG
:ERR0
181 ;INT 24 messages A La COMMAND
183 ERR0
DB "Write protect$"
186 ERR3
DB "Bad command$"
188 ERR5
DB "Bad call format$"
190 ERR7
DB "Non-DOS disk$"
191 ERR8
DB "Sector not found$"
193 ERR10
DB "Write fault$"
194 ERR11
DB "Read fault$"
197 FATMES
DB "File allocation table bad drive "
198 BADDRVM
DB "A.",13,10,"$"
201 BUFFER
DB BLKSIZ
DUP(0)
209 SWITCHAR
DB ?
;User switch character
210 FULLFLAG
DB 0 ;Flag for printing queue full message
211 MAKERES
DB 0 ;Flag to indicate presence of resident
212 ARGSETUP
DB 0 ;Flag to indicate a formatted FCB exists at 5C
213 DEFDRV
DB 0 ;Default drive
214 CANFLG
DB 0 ;Flag to indicate cancel
215 FILCNT
DB 0 ;Number of files
216 SPLIST
DD ?
;Pointer to FCBs in resident
217 CURFILE
DD ?
;Pointer to current FCB
218 SRCHFCB
DB 38 DUP (0) ;SEARCH-FIRST/NEXT FCB
219 ENDRES
DW OFFSET DG
:DEF_ENDRES
;Term-Res location
223 NOFILS
DB "PRINT queue is empty",13,10,"$"
225 CURFNAM
DB " : . is currently being printed",13,10,"$"
227 FILFNAM
DB " : . is in queue"
229 OPMES
DB "Cannot open "
230 OPFILNAM
DB " : . ",13,10,"$"
231 FULLMES
DB "PRINT queue is full",13,10,"$"
233 SRCHFNAM
DB " : . "," File not found",13,10,"$"
234 BADMES
DB "List output is not assigned to a device",13,10,"$"
235 GOODMES
DB "Resident part of PRINT installed",13,10,"$"
236 PROMPT
DB "Name of list device [PRN]: $"
237 CNTMES
DB "Errors on list device indicate that it",13,10
238 DB "may be off-line. Please check it.",13,10,13,10,"$"
239 BADSWT
DB "Invalid parameter",13,10,"$"
242 BADVER
DB "Incorrect DOS version",13,10,"$"
245 ;Reserved names for parallel card
246 INT_17_HITLIST
LABEL BYTE
252 ;Reserved names for Async adaptor
253 INT_14_HITLIST
LABEL BYTE
260 COMBUF
DB 14,0 ;Device name buffer
262 LISTFCB
DB 0,"PRN " ;Device name FCB
264 PARSEBUF
DB 80 DUP (?
) ;Parsing space
269 ASSUME
CS:DG
,DS:DG
,ES:DG
,SS:DG
273 ASSUME
CS:DG
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
275 HDSPINT: ;Hardware interrupt entry point
280 DEC [SLICECNT
] ;Count down
281 JMP SHORT CHAININT
;Not time yet
283 CMP [BUSY
],0 ;See if interrupting ourself
287 LDS SI,[INDOS
] ;Check for making DOS calls
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
298 MOV AL,EOI
;Acknowledge interrupt
304 MOV [SLICECNT
],TIMESLICE
;Either soft or hard int resets time slice
305 MOV [BUSY
],0 ;Done, let others in
307 JMP [NEXTINT
] ;Chain to next clock routine
311 SPINT: ;INT 28H entry point
315 INC [BUSY
] ;Exclude hardware interrupt
316 INC [SOFINT
] ;Indicate a software int in progress
319 STI ;Hardware interrupts ok on INT 28H entry
324 MOV [SOFINT
],0 ;Indicate INT done
325 MOV [SLICECNT
],TIMESLICE
;Either soft or hard int resets time slice
329 NXTSP: JMP [SPNEXT
] ;Chain to next INT 28
336 CMP BYTE PTR CS:[SI],-1
339 JMP SPRET
;Nothing to do
341 PUSH AX ;Need a working register
346 ;Go to internal stack to prevent INT 24 overflowing system stack
348 MOV SP,OFFSET DG
:ISTACK
362 CMP BX,OFFSET DG
:BUFFER
+ BLKSIZ
364 JMP READBUFF
;Buffer empty
369 CMP BX,OFFSET DG
:BUFFER
+ BLKSIZ
370 JZ DONEJMP
;Buffer has become empty
373 CMP [TICKCNT
],MAXTICK
;Check our time slice
381 JZ DOCHAR
;Printer ready
385 JNZ DONEJMP
;If soft int give up
388 CMP [TICKSUB
],BUSYTICK
;Check our busy timeout
418 CMP AL,8 ;Back space?
422 CMP AL,20H
;Non Printing char?
424 INC [COLPOS
] ;Printing char
428 INC [NXTCHR
] ;Next char
431 MOV [TICKSUB
],0 ;Got a character out, Reset counter
432 CMP [SOFINT
],0 ;Soft int does one char at a time
444 ASSUME
DS:NOTHING
,ES:NOTHING
446 MOV SS,[SSsave
] ;Restore Entry Stack
456 ASSUME
DS:DG
,ES:NOTHING
459 MOV AH,GET_INTERRUPT_VECTOR
461 MOV WORD PTR [HERRINT
+2],ES ;Save current vector
462 MOV WORD PTR [HERRINT
],BX
463 MOV DX,OFFSET DG
:DSKERR
465 MOV AH,SET_INTERRUPT_VECTOR
;Install our own
466 INT 21H
;Spooler must catch its errors
469 MOV WORD PTR [DMAADDR
+2],ES ;Save DMA address
470 MOV WORD PTR [DMAADDR
],BX
471 MOV DX,OFFSET DG
:BUFFER
473 INT 21H
;New DMA address
474 MOV [PABORT
],0 ;No abort
475 MOV DX,[CURRFIL
] ;Read
477 INC DX ;Skip over pointer
487 MOV AH,SET_INTERRUPT_VECTOR
488 INT 21H
;Restore Error INT
494 JNZ TONEXTFIL
;Barf on this file, got INT 24
497 MOV BX,OFFSET DG
:BUFFER
;Buffer full
502 MOV AL,0CH ;Form feed
511 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
528 ADD [BADDRVM
],AL ;Set correct drive letter
529 MOV SI,OFFSET DG
:ERRMES
539 MOV DI,WORD PTR [DI+MESBAS
] ; Get pointer to error message
541 CALL LISTMES
; Print error type
542 MOV DI,OFFSET DG
:EMFILNAM
544 ADD SI,2 ;Get to file name
554 MOV SI,OFFSET DG
:ERRMEST
557 INC [PABORT
] ;Indicate abort
571 MOV SI,OFFSET DG
:FATMES
581 ;Communications interrupt
583 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
587 STI ;Turn ints back on
595 MOV [PCANMES
],0 ;Havn't printed cancel message
599 JZ CANFIL
;Cancel File(s)
602 PUSH AX ;Save AL return code
604 MOV SI,OFFSET DG
:SPLFCB
607 CMP BYTE PTR [SI+2],-1 ;Valid?
614 MOV BX,OFFSET DG
:SPLFCB
620 POP AX ;Get AL return
630 CALL PSTAT
; Tweek error counter
647 ASSUME
DS:DG
,ES:NOTHING
662 LOOKEND: ;Set initial pointer values
679 ADD SI,2 ;Skip pointer
693 CMP AH,"?" ;Wild card?
702 XCHG AH,[BX+2] ;Zap it
703 CMP BX,[CURRFIL
] ;Is current file?
708 JNZ DIDCMES
;Only print cancel message once
712 MOV DI,OFFSET DG
:CANFILNAM
714 ADD SI,3 ;Get to file name
725 MOV SI,OFFSET DG
:CANMES
727 MOV SI,OFFSET DG
:BELMES
740 CANTERMJ: JMP SHORT CANTERM
744 CMP AX,[CURRFIL
] ;Is last FCB?
745 JZ SKIPFIL
;Yes, is in right place
747 MOV [SI],AX ;Unlink FCB
751 MOV [SI],BX ;Link FCB at end
752 MOV [LASTFCB
],BX ;New end
753 MOV BX,AX ;Process what it pointed to
757 CMP BYTE PTR CS:[SI+2],-1 ;Examine current file
759 MOV BYTE PTR [SI+2],-1 ;Zap it
762 JZ CANTERM1
;No message if nothing was in progress
763 MOV SI,OFFSET DG
:ALLCAN
765 MOV SI,OFFSET DG
:BELMES
768 MOV [NXTCHR
],OFFSET DG
:BUFFER
+ BLKSIZ
;Buffer empty
788 ASSUME
DS:DG
,ES:NOTHING
800 CMP BYTE PTR [SI+2],-1
823 REP MOVSW ;Copy in and set FCB
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
840 ASSUME
DS:DG
,ES:NOTHING
842 MOV BYTE PTR [SI+2],-1 ;Done with current file
845 MOV [NXTCHR
],OFFSET DG
:BUFFER
+ BLKSIZ
;Buffer empty
846 MOV [COLPOS
],0 ;Start of line
850 ASSUME
DS:DG
,ES:NOTHING
866 JA POPRET
;Don't get stuck
874 ;Stuff for BIOS interface
899 TEST [IOSTAT
],IOERROR
901 OR [IOSTAT
],IOBUSY
;If error, show buisy
904 JNZ RET13P
;Shows buisy
919 MOV BX,OFFSET DG
:IOCALL
928 MOV WORD PTR [CALLAD
],AX
931 MOV WORD PTR [CALLAD
],AX
942 INT_13_RETADDR
DW OFFSET DG
:INT_13_BACK
945 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
947 INC [BUSY
] ;Exclude if dumb program call ROM
949 PUSH [INT_13_RETADDR
]
950 PUSH WORD PTR [REAL_INT_13
+2]
951 PUSH WORD PTR [REAL_INT_13
]
959 RET 2 ;Chuck saved flags
971 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
976 CMP BYTE PTR CS:[SI],-1
978 JZ DO_INT_17
;Nothing pending, so OK
980 JNZ DO_INT_17
;Not my unit
982 JNZ DO_INT_17
;You are me
984 MOV AH,0A1H ;You are bad, get out of paper
988 JMP [REAL_INT_17
] ;Do a 17
994 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
999 CMP BYTE PTR CS:[SI],-1
1001 JZ DO_INT_14
;Nothing pending, so OK
1003 JNZ DO_INT_14
;Not my unit
1005 JNZ DO_INT_14
;You are me
1014 MOV AH,80H
;Time out
1018 JMP [REAL_INT_14
] ;Do a 14
1021 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
1026 CMP BYTE PTR CS:[SI],-1
1028 JZ DO_INT_5
;Nothing pending, so OK
1030 JNZ DO_INT_5
;Only care about unit 0
1031 IRET ;Pretend it worked
1034 JMP [REAL_INT_5
] ;Do a 5
1038 ;The following data is order and position dependant
1042 SPLFCB
DW OFFSET DG
:FC1
1043 DB (FCBSIZ
- 2) DUP (-1)
1044 FC1
DW OFFSET DG
:FC2
1045 DB (FCBSIZ
- 2) DUP (-1)
1046 FC2
DW OFFSET DG
:FC3
1047 DB (FCBSIZ
- 2) DUP (-1)
1048 FC3
DW OFFSET DG
:FC4
1049 DB (FCBSIZ
- 2) DUP (-1)
1050 FC4
DW OFFSET DG
:FC5
1051 DB (FCBSIZ
- 2) DUP (-1)
1052 FC5
DW OFFSET DG
:FC6
1053 DB (FCBSIZ
- 2) DUP (-1)
1054 FC6
DW OFFSET DG
:FC7
1055 DB (FCBSIZ
- 2) DUP (-1)
1056 FC7
DW OFFSET DG
:FC8
1057 DB (FCBSIZ
- 2) DUP (-1)
1058 FC8
DW OFFSET DG
:FC9
1059 DB (FCBSIZ
- 2) DUP (-1)
1060 FC9
DW OFFSET DG
:SPLFCB
1061 DB (FCBSIZ
- 2) DUP (-1)
1063 DEF_ENDRES
LABEL BYTE
1065 ASSUME
CS:DG
,DS:DG
,ES:DG
,SS:DG
1068 MOV DX,OFFSET DG
:BADMES
1069 MOV AH,STD_CON_STRING_OUTPUT
1074 ;Called once to install resident
1077 MOV DX,OFFSET DG
:PROMPT
1078 MOV AH,STD_CON_STRING_OUTPUT
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
1088 JZ DEFSPOOL
;User didn't specify one
1090 MOV DI,OFFSET DG
:LISTFCB
+ 1
1091 MOV SI,OFFSET DG
:COMBUF
+ 2
1094 MOV DX,OFFSET DG
:LISTFCB
1099 TEST BYTE PTR [LISTFCB
.fcb_DEVID
],080H
1100 JZ BADSPOOL
;Must be a device
1101 LDS SI,DWORD PTR [LISTFCB
.fcb_FIRCLUS
]
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
1109 MOV DX,OFFSET DG
:SPINT
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
1116 MOV AH,SET_INTERRUPT_VECTOR
1117 INT 21H
;Set soft vector
1118 MOV DX,OFFSET DG
:SPCOMINT
1120 MOV AH,SET_INTERRUPT_VECTOR
;Set communication vector
1125 MOV AH,GET_INTERRUPT_VECTOR
1127 MOV WORD PTR [REAL_INT_13
+2],ES
1128 MOV WORD PTR [REAL_INT_13
],BX
1129 MOV DX,OFFSET DG
:INT_13
1131 MOV AH,SET_INTERRUPT_VECTOR
1132 INT 21H
;Set diskI/O interrupt
1134 MOV AH,GET_INTERRUPT_VECTOR
1136 MOV WORD PTR [REAL_INT_17
+2],ES
1137 MOV WORD PTR [REAL_INT_17
],BX
1139 MOV AH,GET_INTERRUPT_VECTOR
1141 MOV WORD PTR [REAL_INT_14
+2],ES
1142 MOV WORD PTR [REAL_INT_14
],BX
1144 MOV AH,GET_INTERRUPT_VECTOR
1146 MOV WORD PTR [REAL_INT_5
+2],ES
1147 MOV WORD PTR [REAL_INT_5
],BX
1150 MOV BP,OFFSET DG
:LISTFCB
+ 1
1153 CONLP: ;Make sure device name in upper case
1159 SUB BYTE PTR [SI-1],20H
1162 MOV DI,OFFSET DG
:INT_17_HITLIST
1170 ADD DI,CX ;Bump to next position without affecting flags
1171 MOV BL,[DI] ;Get device number
1177 MOV DX,OFFSET DG
:INT_17
1179 MOV AH,SET_INTERRUPT_VECTOR
1180 INT 21H
;Set printer interrupt
1181 MOV DX,OFFSET DG
:INT_5
1183 MOV AH,SET_INTERRUPT_VECTOR
1184 INT 21H
;Set print screen interrupt
1187 MOV DI,OFFSET DG
:INT_14_HITLIST
1195 ADD DI,CX ;Bump to next position without affecting flags
1196 MOV BL,[DI] ;Get device number
1202 MOV DX,OFFSET DG
:INT_14
1204 MOV AH,SET_INTERRUPT_VECTOR
1205 INT 21H
;Set RS232 port interrupt
1210 MOV AH,GET_INDOS_FLAG
1212 MOV WORD PTR [INDOS
+2],ES ;Get indos flag location
1213 MOV WORD PTR [INDOS
],BX
1215 MOV AH,GET_INTERRUPT_VECTOR
1217 MOV WORD PTR [NEXTINT
+2],ES
1218 MOV WORD PTR [NEXTINT
],BX
1219 MOV DX,OFFSET DG
:HDSPINT
1221 MOV AH,SET_INTERRUPT_VECTOR
1222 INT 21H
;Set hardware interrupt
1225 MOV [MAKERES
],1 ;Indicate to do a terminate stay resident
1226 MOV DX,OFFSET DG
:GOODMES
1227 MOV AH,STD_CON_STRING_OUTPUT
1231 ASSUME
CS:DG
,DS:DG
,ES:DG
,SS:DG
1237 ;Code to print header
1238 ; MOV DX,OFFSET DG:HEADER
1239 ; MOV AH,STD_CON_STRING_OUTPUT
1242 DOSVER_LOW EQU
0136H ;1.54 in hex
1243 DOSVER_HIGH EQU
020BH ;2.11 in hex
1246 XCHG AH,AL ;Turn it around to AH.AL
1254 MOV DX,OFFSET DG
:BADVER
1255 MOV AH,STD_CON_STRING_OUTPUT
1259 MOV AX,CHAR_OPER
SHL 8
1261 MOV [SWITCHAR
],DL ;Get user switch character
1262 MOV AH,GET_INTERRUPT_VECTOR
1267 MOV SI,OFFSET DG
:SPCOMINT
1270 JZ GOTRES
;Signature matched
1277 MOV AH,GET_DEFAULT_DRIVE
1302 MOV DI,OFFSET DG
:PARSEBUF
1307 MOV AL,[DI] ;Get the switch character
1328 MOV DX,OFFSET DG
:BADSWT
1329 MOV AH,STD_CON_STRING_OUTPUT
1335 JMP TRANEXIT
; Ignore everything after T switch
1342 CALL NORMPROC
;Don't test ARGSETUP, it just got zeroed
1347 MOV AX,(PARSE_FILE_DESCRIPTOR
SHL 8) OR 1
1348 INT 21H
;Parse the arg
1353 MOV BYTE PTR [DI],DL ;Set the default drive
1372 JZ RET14
;Nothing to process
1374 MOV AL,BYTE PTR DS:[FCB
+1]
1381 MOV DX,OFFSET DG
:SRCHFCB
1385 MOV AH,DIR_SEARCH_FIRST
1390 MOV DX,OFFSET DG
:SRCHFCB
1396 JMP SHORT NEXTSEARCH
1397 SRCHBADJ: JMP SRCHBAD
1399 MOV DX,OFFSET DG
:SRCHFCB
1404 XCHG AL,[FULLFLAG
] ;Know AL non-zero
1406 JNZ NEXTSEARCH
;Only print message once
1407 MOV DX,OFFSET DG
:FULLMES
;Queue full
1408 MOV AH,STD_CON_STRING_OUTPUT
1411 MOV DX,OFFSET DG
:SRCHFCB
1415 MOV AH,DIR_SEARCH_NEXT
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
1433 MOV SI,OFFSET DG
:OPFILNAM
1436 MOV DI,OFFSET DG
:SRCHFCB
1438 MOV DX,OFFSET DG
:OPMES
1439 MOV AH,STD_CON_STRING_OUTPUT
1448 MOV SI,OFFSET DG
:SRCHFNAM
1453 MOV DX,OFFSET DG
:SRCHMES
1454 MOV AH,STD_CON_STRING_OUTPUT
1465 MOV DI,[DI-2] ;Get the error count
1469 MOV DX,OFFSET DG
:CNTMES
1470 MOV AH,STD_CON_STRING_OUTPUT
1481 MOV SI,OFFSET DG
:CURFNAM
1484 MOV DX,OFFSET DG
:CURMES
1485 MOV AH,STD_CON_STRING_OUTPUT
1494 MOV SI,OFFSET DG
:FILFNAM
1497 MOV DX,OFFSET DG
:FILMES
1498 MOV AH,STD_CON_STRING_OUTPUT
1504 MOV DX,OFFSET DG
:NOFILS
1505 MOV AH,STD_CON_STRING_OUTPUT
1509 ;Make a message with the file name
1511 ASSUME
DS:NOTHING
,ES:NOTHING
1543 ;-----------------------------------------------------------------------;
1545 ; DS:SI Points input buffer ;
1546 ; ES:DI Points to the token buffer ;
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 ;
1555 ; =4 switch character, char in token buffer ;
1556 ; Carry Flag Set if a CR was found, Reset otherwise ;
1559 ; CX, SI, AX and the Carry Flag ;
1561 ;-----------------------------------------------------------------------;
1567 ASSUME
DS:NOTHING
,ES:NOTHING
,SS:NOTHING
1569 push di ;save the token buffer addrss
1570 xor cx,cx ;no chars in token buffer
1576 mov ax,1 ;condition code
1577 dec si ;adjust the pointer
1578 pop di ;retrive token buffer address
1580 stc ;set the carry bit
1585 cmp al,dl ;is the char the switch char?
1586 jne anum_char
;no, process...
1589 je sj1
;yes, error exit
1590 call move_char
;Put the switch char in the token buffer
1591 mov ax,4 ;Flag switch
1595 call move_char
;just an alphanum string
1607 cmp al,dl ;Switch character
1610 dec si ;adjust for next round
1611 mov ax,2 ;normal token
1613 push ax ;save condition code
1615 stosb ;null at the end
1617 pop di ;restore token buffer pointer
1619 clc ;clear carry flag
1629 cmp al,',' ;a comma?
1638 stosb ;store char in token buffer
1639 inc cx ;increment char count
1645 \1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a\1a