summaryrefslogtreecommitdiff
path: root/v2.0/source/COPY.ASM
blob: 0456a4f9d57a695190ec0a42f4a2b1dfa51ead9c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
TITLE   COMMAND COPY routines.

        INCLUDE COMSW.ASM

.xlist
.xcref
        INCLUDE DOSSYM.ASM
        INCLUDE DEVSYM.ASM
        INCLUDE COMSEG.ASM
.list
.cref

        INCLUDE COMEQU.ASM

DATARES SEGMENT PUBLIC
        EXTRN   VERVAL:WORD
DATARES ENDS

TRANDATA        SEGMENT PUBLIC
        EXTRN   BADARGS:BYTE,BADCD:BYTE,BADSWT:BYTE,COPIED_PRE:BYTE
        EXTRN   COPIED_POST:BYTE
        EXTRN   INBDEV:BYTE,OVERWR:BYTE,FULDIR:BYTE,LOSTERR:BYTE
        EXTRN   NOSPACE:BYTE,DEVWMES:BYTE,NOTFND:BYTE
TRANDATA        ENDS

TRANSPACE       SEGMENT PUBLIC
        EXTRN   MELCOPY:BYTE,SRCPT:WORD,MELSTART:WORD,SCANBUF:BYTE
        EXTRN   DESTFCB2:BYTE,SDIRBUF:BYTE,SRCTAIL:WORD,CFLAG:BYTE
        EXTRN   NXTADD:WORD,DESTCLOSED:BYTE,ALLSWITCH:WORD,ARGC:BYTE
        EXTRN   PLUS:BYTE,BINARY:BYTE,ASCII:BYTE,FILECNT:WORD
        EXTRN   WRITTEN:BYTE,CONCAT:BYTE,DESTBUF:BYTE,SRCBUF:BYTE
        EXTRN   SDIRBUF:BYTE,DIRBUF:BYTE,DESTFCB:BYTE,FRSTSRCH:BYTE
        EXTRN   FIRSTDEST:BYTE,DESTISDIR:BYTE,DESTSWITCH:WORD,STARTEL:WORD
        EXTRN   DESTTAIL:WORD,DESTSIZ:BYTE,DESTINFO:BYTE,INEXACT:BYTE
        EXTRN   CURDRV:BYTE,DESTVARS:BYTE,RESSEG:WORD,SRCSIZ:BYTE
        EXTRN   SRCINFO:BYTE,SRCVARS:BYTE,USERDIR1:BYTE,NOWRITE:BYTE
        EXTRN   RDEOF:BYTE,SRCHAND:WORD,CPDATE:WORD,CPTIME:WORD
        EXTRN   SRCISDEV:BYTE,BYTCNT:WORD,TPA:WORD,TERMREAD:BYTE
        EXTRN   DESTHAND:WORD,DESTISDEV:BYTE,DIRCHAR:BYTE
TRANSPACE       ENDS


; **************************************************
; COPY CODE
;

TRANCODE        SEGMENT PUBLIC BYTE

        EXTRN   RESTUDIR:NEAR,CERROR:NEAR,SWITCH:NEAR,DISP32BITS:NEAR
        EXTRN   PRINT:NEAR,TCOMMAND:NEAR,ZPRINT:NEAR,ONESPC:NEAR
        EXTRN   RESTUDIR1:NEAR,FCB_TO_ASCZ:NEAR,CRLF2:NEAR,SAVUDIR1:NEAR
        EXTRN   SETREST1:NEAR,BADCDERR:NEAR,STRCOMP:NEAR,DELIM:NEAR
        EXTRN   UPCONV:NEAR,PATHCHRCMP:NEAR,SCANOFF:NEAR

        EXTRN   CPARSE:NEAR

        EXTRN   SEARCH:NEAR,SEARCHNEXT:NEAR,DOCOPY:NEAR,CLOSEDEST:NEAR
        EXTRN   FLSHFIL:NEAR,SETASC:NEAR,BUILDNAME:NEAR,COPERR:NEAR

        PUBLIC  COPY,BUILDPATH,COMPNAME,ENDCOPY


ASSUME  CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING

DOMELCOPY:
        cmp     [MELCOPY],0FFH
        jz      CONTMEL
        mov     SI,[SRCPT]
        mov     [MELSTART],si
        mov     [MELCOPY],0FFH
CONTMEL:
        xor     BP,BP
        mov     si,[SRCPT]
        mov     bl,'+'
SCANSRC2:
        mov     di,OFFSET TRANGROUP:SCANBUF
        call    CPARSE
        test    bh,80H
        jz      NEXTMEL                 ; Go back to start
        test    bh,1                    ; Switch ?
        jnz     SCANSRC2                ; Yes
        call    SOURCEPROC
        call    RESTUDIR1
        mov     di,OFFSET TRANGROUP:DESTFCB2
        mov     ax,PARSE_FILE_DESCRIPTOR SHL 8
        INT     int_command
        mov     bx,OFFSET TRANGROUP:SDIRBUF + 1
        mov     si,OFFSET TRANGROUP:DESTFCB2 + 1
        mov     di,[SRCTAIL]
        call    BUILDNAME
        jmp     MELDO


NEXTMEL:
        call    CLOSEDEST
        xor     ax,ax
        mov     [CFLAG],al
        mov     [NXTADD],ax
        mov     [DESTCLOSED],al
        mov     si,[MELSTART]
        mov     [SRCPT],si
        call    SEARCHNEXT
        jz      SETNMELJ
        jmp     ENDCOPY2
SETNMELJ:
        jmp     SETNMEL

COPY:
; First order of buisness is to find out about the destination
ASSUME  DS:TRANGROUP,ES:TRANGROUP
        xor     ax,ax
        mov     [ALLSWITCH],AX          ; no switches
        mov     [ARGC],al               ; no arguments
        mov     [PLUS],al               ; no concatination
        mov     [BINARY],al             ; Binary not specifically specified
        mov     [ASCII],al              ; ASCII not specifically specified
        mov     [FILECNT],ax            ; No files yet
        mov     [WRITTEN],al            ; Nothing written yet
        mov     [CONCAT],al             ; No concatination
        mov     [MELCOPY],al            ; Not a Mel Hallerman copy
        mov     word ptr [SCANBUF],ax   ; Init buffer
        mov     word ptr [DESTBUF],ax   ; Init buffer
        mov     word ptr [SRCBUF],ax    ; Init buffer
        mov     word ptr [SDIRBUF],ax   ; Init buffer
        mov     word ptr [DIRBUF],ax    ; Init buffer
        mov     word ptr [DESTFCB],ax   ; Init buffer
        dec     ax
        mov     [FRSTSRCH],al           ; First search call
        mov     [FIRSTDEST],al          ; First time
        mov     [DESTISDIR],al          ; Don't know about dest
        mov     si,81H
        mov     bl,'+'                  ; include '+' as a delimiter
DESTSCAN:
        xor     bp,bp                   ; no switches
        mov     di,offset trangroup:SCANBUF
        call    CPARSE
        PUSHF                           ; save flags
        test    bh,80H                  ; A '+' argument?
        jz      NOPLUS                  ; no
        mov     [PLUS],1                ; yes
NOPLUS:
        POPF                            ; get flags back
        jc      CHECKDONE               ; Hit CR?
        test    bh,1                    ; Switch?
        jz      TESTP2                  ; no
        or      [DESTSWITCH],BP         ; Yes, assume destination
        or      [ALLSWITCH],BP          ; keep tabs on all switches
        jmp     short DESTSCAN

TESTP2:
        test    bh,80H                  ; Plus?
        jnz     GOTPLUS                 ; Yes, not a separate arg
        inc     [ARGC]                  ; found a real arg
GOTPLUS:
        push    SI
        mov     ax,[STARTEL]
        mov     SI,offset trangroup:SCANBUF ; Adjust to copy
        sub     ax,SI
        mov     DI,offset trangroup:DESTBUF
        add     ax,DI
        mov     [DESTTAIL],AX
        mov     [DESTSIZ],cl            ; Save its size
        inc     cx                      ; Include the NUL
        rep     movsb                   ; Save potential destination
        mov     [DESTINFO],bh           ; Save info about it
        mov     [DESTSWITCH],0          ; reset switches
        pop     SI
        jmp     short DESTSCAN          ; keep going

CHECKDONE:
        mov     al,[PLUS]
        mov     [CONCAT],al             ; PLUS -> Concatination
        shl     al,1
        shl     al,1
        mov     [INEXACT],al            ; CONCAT -> inexact copy
        mov     dx,offset trangroup:BADARGS
        mov     al,[ARGC]
        or      al,al                   ; Good number of args?
        jz      CERROR4J                ; no, not enough
        cmp     al,2
        jbe     ACOUNTOK
CERROR4J:
        jmp    CERROR                   ; no, too many
ACOUNTOK:
        mov     bp,offset trangroup:DESTVARS
        cmp     al,1
        jnz     GOT2ARGS
        mov     al,[CURDRV]             ; Dest is default drive:*.*
        add     al,'A'
        mov     ah,':'
        mov     [bp.SIZ],2
        mov     di,offset trangroup:DESTBUF
        stosw
        mov     [DESTSWITCH],0          ; no switches on dest
        mov     [bp.INFO],2             ; Flag dest is ambig
        mov     [bp.ISDIR],0            ; Know destination specs file
        call    SETSTARS
GOT2ARGS:
        cmp     [bp.SIZ],2
        jnz     NOTSHORTDEST
        cmp     [DESTBUF+1],':'
        jnz     NOTSHORTDEST            ; Two char file name
        or      [bp.INFO],2             ; Know dest is d:
        mov     di,offset trangroup:DESTBUF + 2
        mov     [bp.ISDIR],0            ; Know destination specs file
        call    SETSTARS
NOTSHORTDEST:
        mov     di,[bp.TTAIL]
        cmp     byte ptr [DI],0
        jnz     CHKSWTCHES
        mov     dx,offset trangroup:BADCD
        cmp     byte ptr [DI-2],':'
        jnz     CERROR4J               ; Trailing '/' error
        mov     [bp.ISDIR],2           ; Know destination is d:/
        or      [bp.INFO],6
        call    SETSTARS
CHKSWTCHES:
        mov     dx,offset trangroup:BADSWT
        mov     ax,[ALLSWITCH]
        cmp     ax,GOTSWITCH
        jz      CERROR4J                ; Switch specified which is not known

; Now know most of the information needed about the destination

        TEST    AX,VSWITCH              ; Verify requested?
        JZ      NOVERIF                 ; No
        MOV     AH,GET_VERIFY_ON_WRITE
        INT     int_command             ; Get current setting
        PUSH    DS
        MOV     DS,[RESSEG]
ASSUME  DS:RESGROUP
        XOR     AH,AH
        MOV     [VERVAL],AX             ; Save current setting
        POP     DS
ASSUME  DS:TRANGROUP
        MOV     AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1 ; Set verify
        INT     int_command
NOVERIF:
        xor     bp,bp                   ; no switches
        mov     si,81H
        mov     bl,'+'                  ; include '+' as a delimiter
SCANFSRC:
        mov     di,offset trangroup:SCANBUF
        call    CPARSE                  ; Parse first source name
        test    bh,1                    ; Switch?
        jnz     SCANFSRC                ; Yes, try again
        or      [DESTSWITCH],bp         ; Include copy wide switches on DEST
        test    bp,BSWITCH
        jnz     NOSETCASC               ; Binary explicit
        cmp     [CONCAT],0
        JZ      NOSETCASC               ; Not Concat
        mov     [ASCII],ASWITCH         ; Concat -> ASCII copy if no B switch
NOSETCASC:
        push    SI
        mov     ax,[STARTEL]
        mov     SI,offset trangroup:SCANBUF ; Adjust to copy
        sub     ax,SI
        mov     DI,offset trangroup:SRCBUF
        add     ax,DI
        mov     [SRCTAIL],AX
        mov     [SRCSIZ],cl             ; Save its size
        inc     cx                      ; Include the NUL
        rep     movsb                   ; Save this source
        mov     [SRCINFO],bh            ; Save info about it
        pop     SI
        mov     ax,bp                   ; Switches so far
        call    SETASC                  ; Set A,B switches accordingly
        call    SWITCH                  ; Get any more switches on this arg
        call    SETASC                  ; Set
        call    FRSTSRC
        jmp     FIRSTENT

ENDCOPY:
        CALL    CLOSEDEST
ENDCOPY2:
        MOV     DX,OFFSET TRANGROUP:COPIED_PRE
        CALL    PRINT
        MOV     SI,[FILECNT]
        XOR     DI,DI
        CALL    DISP32BITS
        MOV     DX,OFFSET TRANGROUP:COPIED_POST
        CALL    PRINT
        JMP     TCOMMAND                ; Stack could be messed up

SRCNONEXIST:
        cmp     [CONCAT],0
        jnz     NEXTSRC                 ; If in concat mode, ignore error
        mov     dx,offset trangroup:SRCBUF
        call    zprint
        CALL    ONESPC
        mov     dx,offset trangroup:NOTFND
        jmp     COPERR

SOURCEPROC:
        push    SI
        mov     ax,[STARTEL]
        mov     SI,offset trangroup:SCANBUF ; Adjust to copy
        sub     ax,SI
        mov     DI,offset trangroup:SRCBUF
        add     ax,DI
        mov     [SRCTAIL],AX
        mov     [SRCSIZ],cl             ; Save its size
        inc     cx                      ; Include the NUL
        rep     movsb                   ; Save this sorce
        mov     [SRCINFO],bh            ; Save info about it
        pop     SI
        mov     ax,bp                   ; Switches so far
        call    SETASC                  ; Set A,B switches accordingly
        call    SWITCH                  ; Get any more switches on this arg
        call    SETASC                  ; Set
        cmp     [CONCAT],0
        jnz     LEAVECFLAG              ; Leave CFLAG if concatination
FRSTSRC:
        xor     ax,ax
        mov     [CFLAG],al              ; Flag destination not created
        mov     [NXTADD],ax             ; Zero out buffer
        mov     [DESTCLOSED],al         ; Not created -> not closed
LEAVECFLAG:
        mov     [SRCPT],SI              ; remember where we are
        mov     di,offset trangroup:USERDIR1
        mov     bp,offset trangroup:SRCVARS
        call    BUILDPATH               ; Figure out everything about the source
        mov     si,[SRCTAIL]            ; Create the search FCB
        return

NEXTSRC:
        cmp     [PLUS],0
        jnz     MORECP
ENDCOPYJ2:
        jmp     ENDCOPY                 ; Done
MORECP:
        xor     bp,bp                   ; no switches
        mov     si,[SRCPT]
        mov     bl,'+'                  ; include '+' as a delimiter
SCANSRC:
        mov     di,offset trangroup:SCANBUF
        call    CPARSE                  ; Parse first source name
        JC      EndCopyJ2               ; if error, then end (trailing + case)
        test    bh,80H
        jz      ENDCOPYJ2               ; If no '+' we're done
        test    bh,1                    ; Switch?
        jnz     SCANSRC                 ; Yes, try again
        call    SOURCEPROC
FIRSTENT:
        mov     di,FCB
        mov     ax,PARSE_FILE_DESCRIPTOR SHL 8
        INT     int_command
        mov     ax,word ptr [SRCBUF]    ; Get drive
        cmp     ah,':'
        jz      DRVSPEC1
        mov     al,'@'
DRVSPEC1:
        sub     al,'@'
        mov     ds:[FCB],al
        mov     ah,DIR_SEARCH_FIRST
        call    SEARCH
        pushf                           ; Save result of search
        call    RESTUDIR1               ; Restore users dir
        popf
        jz      NEXTAMBIG0
        jmp     SRCNONEXIST             ; Failed
NEXTAMBIG0:
        xor     al,al
        xchg    al,[FRSTSRCH]
        or      al,al
        jz      NEXTAMBIG
SETNMEL:
        mov     cx,12
        mov     di,OFFSET TRANGROUP:SDIRBUF
        mov     si,OFFSET TRANGROUP:DIRBUF
        rep     movsb                   ; Save very first source name
NEXTAMBIG:
        xor     al,al
        mov     [NOWRITE],al            ; Turn off NOWRITE
        mov     di,[SRCTAIL]
        mov     si,offset trangroup:DIRBUF + 1
        call    FCB_TO_ASCZ             ; SRCBUF has complete name
MELDO:
        cmp     [CONCAT],0
        jnz     SHOWCPNAM               ; Show name if concat
        test    [SRCINFO],2             ; Show name if multi
        jz      DOREAD
SHOWCPNAM:
        mov     dx,offset trangroup:SRCBUF
        call    ZPRINT
        call    CRLF2
DOREAD:
        call    DOCOPY
        cmp     [CONCAT],0
        jnz     NODCLOSE                ; If concat, do not close
        call    CLOSEDEST               ; else close current destination
        jc      NODCLOSE                ; Concat flag got set, close didn't really happen
        mov     [CFLAG],0               ; Flag destination not created
NODCLOSE:
        cmp     [CONCAT],0              ; Check CONCAT again
        jz      NOFLUSH
        CALL    FLSHFIL                 ; Flush output between source files on CONCAT
                                        ;  so LOSTERR stuff works correctly
        TEST    [MELCOPY],0FFH
        jz      NOFLUSH
        jmp     DOMELCOPY

NOFLUSH:
        call    SEARCHNEXT              ; Try next match
        jnz     NEXTSRCJ                ; Finished with this source spec
        mov     [DESTCLOSED],0          ; Not created or concat -> not closed
        jmp     NEXTAMBIG               ; Do next ambig

NEXTSRCJ:
        jmp   NEXTSRC



BUILDPATH:
        test    [BP.INFO],2
        jnz     NOTPFILE                ; If ambig don't bother with open
        mov     dx,bp
        add     dx,BUF                  ; Set DX to spec
        mov     ax,OPEN SHL 8
        INT     int_command
        jc      NOTPFILE
        mov     bx,ax                   ; Is pure file
        mov     ax,IOCTL SHL 8
        INT     int_command
        mov     ah,CLOSE
        INT     int_command
        test    dl,devid_ISDEV
        jnz     ISADEV                  ; If device, done
        test    [BP.INFO],4
        jz      ISSIMPFILE              ; If no path seps, done
NOTPFILE:
        mov     dx,word ptr [BP.BUF]
        cmp     dh,':'
        jz      DRVSPEC5
        mov     dl,'@'
DRVSPEC5:
        sub     dl,'@'                  ; A = 1
        call    SAVUDIR1
        mov     dx,bp
        add     dx,BUF                  ; Set DX for upcomming CHDIRs
        mov     bh,[BP.INFO]
        and     bh,6
        cmp     bh,6                    ; Ambig and path ?
        jnz     CHECKAMB                ; jmp if no
        mov     si,[BP.TTAIL]
        cmp     byte ptr [si-2],':'
        jnz     KNOWNOTSPEC
        mov     [BP.ISDIR],2            ; Know is d:/file
        jmp     short DOPCDJ

KNOWNOTSPEC:
        mov     [BP.ISDIR],1            ; Know is path/file
        dec     si                      ; Point to the /
DOPCDJ:
        jmp     short DOPCD

CHECKAMB:
        cmp     bh,2
        jnz     CHECKCD
ISSIMPFILE:
ISADEV:
        mov     [BP.ISDIR],0            ; Know is file since ambig but no path
        return

CHECKCD:
        call    SETREST1
        mov     ah,CHDIR
        INT     int_command
        jc      NOTPDIR
        mov     di,dx
        xor     ax,ax
        mov     cx,ax
        dec     cx
        repne   scasb
        dec     di
        mov     al,[DIRCHAR]
        mov     [bp.ISDIR],2            ; assume d:/file
        cmp     al,[di-1]
        jz      GOTSRCSLSH
        stosb
        mov     [bp.ISDIR],1            ; know path/file
GOTSRCSLSH:
        or      [bp.INFO],6
        call    SETSTARS
        return


NOTPDIR:
        mov     [bp.ISDIR],0            ; assume pure file
        mov     bh,[bp.INFO]
        test    bh,4
        retz                            ; Know pure file, no path seps
        mov     [bp.ISDIR],2            ; assume d:/file
        mov     si,[bp.TTAIL]
        cmp     byte ptr [si],0
        jz      BADCDERRJ2              ; Trailing '/'
        cmp     byte ptr [si],'.'
        jz      BADCDERRJ2              ; If . or .. pure cd should have worked
        cmp     byte ptr [si-2],':'
        jz      DOPCD                   ; Know d:/file
        mov     [bp.ISDIR],1            ; Know path/file
        dec     si                      ; Point at last '/'
DOPCD:
        xor     bl,bl
        xchg    bl,[SI]                 ; Stick in a NUL
        call    SETREST1
        mov     ah,CHDIR
        INT     int_command
        xchg    bl,[SI]
        retnc
BADCDERRJ2:
        JMP     BADCDERR

SETSTARS:
        mov     [bp.TTAIL],DI
        add     [bp.SIZ],12
        mov     ax,('.' SHL 8) OR '?'
        mov     cx,8
        rep     stosb
        xchg    al,ah
        stosb
        xchg    al,ah
        mov     cl,3
        rep     stosb
        xor     al,al
        stosb
        return


COMPNAME:
        PUSH    CX
        PUSH    AX
        MOV     si,offset trangroup:SRCBUF
        MOV     di,offset trangroup:DESTBUF
        MOV     CL,[CURDRV]
        MOV     CH,CL
        CMP     BYTE PTR [SI+1],':'
        JNZ     NOSRCDRV
        LODSW
        SUB     AL,'A'
        MOV     CL,AL
NOSRCDRV:
        CMP     BYTE PTR [DI+1],':'
        JNZ     NODSTDRV
        MOV     AL,[DI]
        INC     DI
        INC     DI
        SUB     AL,'A'
        MOV     CH,AL
NODSTDRV:
        CMP     CH,CL
        jnz     RET81P
        call    STRCOMP
        jz      RET81P
        mov     ax,[si-1]
        mov     cx,[di-1]
        push    ax
        and     al,cl
        pop     ax
        jnz     RET81P                  ; Niether of the mismatch chars was a NUL
; Know one of the mismatch chars is a NUL
; Check for ".NUL" compared with NUL
        cmp     al,'.'
        jnz     CHECKCL
        or      ah,ah
        jmp     short RET81P            ; If NUL return match, else no match
CHECKCL:
        cmp     cl,'.'
        jnz     RET81P                  ; Mismatch
        or      ch,ch                   ; If NUL return match, else no match
RET81P:
        POP     AX
        POP     CX
        return

TRANCODE        ENDS

        END