ORG 0100
START:         JMP    BEGINNING
COPYRIGHT      DB     "STEP2.COM  Copyright (c) 1993 Robert Wallingford, P.E.",0D,0A
               DB     "                              2338 N. McVicker Avenue",0D,0A
               DB     "                              Chicago, IL  60639-2216",0D,0A
               DB     "                              Phone  (312)-889-1115",0D,0A,024
SUBBUF:        DW     SUBBUFF
NUMB:          DW   0FFFF          ;Line count for NUMBUF
ITEMS:         DW   0000           ;Line count for MISSBUF
COUNT:         DW   0000           ;Sorting counter and pointer
DRIVE          DB     ?
FILE_START     DW     ?
FILENAME_END   DW     ?
ARGUMENTS      DW     ?
SYNTAX  DB  0D,0A,"Syntax:  STEP2  FILE1  FILE2"
        DB  0D,0A,"     FILE1 is the file to be disassembled."
        DB  0D,0A,"     FILE2 is the file derived from DEBUG.COM"
        DB  0D,0A,"     LABLFILE.REP is the file of projected replacements."
        DB  0D,0A,"     DEBUG.COM must exist in the default dir."
        DB  0D,0A,"     INPUT  (from STEP1)  must be in this dir."
        DB  0D,0A,"     MISSING.NBR  may also be generated."
CR_LF   DB  0D,0A,"$"
FAIL           DB     0D,0A,"Can't find $"
FAIL1          DB     " in default directory.",0D,0A,024
INPUTNF        DB     0D,0A,"Can't find INPUT in default directory.$"
DBGNF          DB     0D,0A,"Can't find DEBUG.COM in default directory.$"
DELIMITERS     DB     9,0D,020,"/"
DBG            DB     "DEBUG.COM ",0
DBGF:          DB     "DEBUG.COM",0
TARGET:        DB     13 DUP 0
INPUTF:        DB     "INPUT",0
OUTPUTF:       DB     "TEMPFILE.OUT",0
HANDLE1        DW     0000                   ;Handle of INPUTF file
HANDLE2        DW     0000                   ;Handle of OUTPUTF file
HANDLE3        DW     0000                   ;Handle of TARGET file (CHANGED)
HANDLE4:       DW     0000                   ;Handle of OUTPUT file
STACK_SEG      DW     ?
STACK_PTR      DW     ?
LENGTH:  DW   0000           ;Length of deleted strings
BUFEND:  DW   0000           ;End of buffer for SUBR09
FLAG1:   DB   00             ;1 means 4 hex digits pass ok
MOREFLAG:DB   00             ;If 1, there is more left in file
FILE2A:  DB   "OUTPUT2.B00"  ;Default output filename
ADD2B:   DB   00,0D,0A,024   ;For displaying default output filename
FILE2:   DB   13 DUP 00      ;Output filename buffer
SIZEFILE:DW   0000           ;Size of target file
LABL:    DB   "LABLFILE.REP",0
MISSING: DB   "MISSING.NBR",00
MISBUF:  DW   0000           ;PTR to start of "MISSING.NBR" buffer
MSGFNF1: DB   "Target file not found.",0D,0A,024
MSGFTB:  DB   "Target file is too big.",0D,0A,024
MSGDSO:  DB   "Defaulting to standard output filename.",0D,0A,024
MSGTMO:  DB   "Too many output files, terminating program.",0D,0A,024
MSGNOF:  DB   "New output file will be ",024
MSGTMI:  DB   "There are too many items to sort and process.",0D,0A,024
PARAMETER_BLOCK  LABEL  WORD
ENVIRONMENT    DW     0
COM_LINE_PTR   DW     PARAMETER,?
FCB_1ST        DW     FCB_5CH,  ?
FCB_2ND        DW     FCB_6CH,  ?
;----------------------------------------------------------------------------;
; Some housekeeping first.                                                   ;
;                                                                            ;
;                                             Change the default DTA.        ;
; Move the stack and deallocate memory so we have room to spawn the program. ;
;----------------------------------------------------------------------------;
BEGINNING:
               MOV    AH,9                   ;Display
               MOV    DX,OFFSET COPYRIGHT    ;Copyright message
               INT    021                    ;Using DOS
               MOV    SI,080                 ;Point to command line parameters.
               LODSB
               CMP    AL,0                   ;Are there any?
               JZ     SYN_EXIT               ;If no, exit.
               CALL   SUBR01
               CALL   SUBR02
               CLD                           ;String moves forward.
               MOV    DX,OFFSET DTA          ;Move the disk transfer address
               MOV    AH,01A                 ; to the end of code to protect
               INT    021                    ; command line parameters at 80h.
               MOV    SP,OFFSET CODE_END     ;Move the stack down to the
               MOV    BX,SP                  ; end of code segment.
               ADD    BX,0F                  ;Round up paragraph size.
               MOV    CL,4
               SHR    BX,CL
               MOV    AH,04A                 ;Deallocate rest of memory.
               INT    021                    ;Using DOS
;--------------------------------------------------;
; Parse the command line parameters.  Start by     ;
; scanning off spaces.                             ;
;--------------------------------------------------;
               MOV    SI,080                 ;Point to command line parameters.
               LODSB                         ;Parameter length in AL
               XOR    AH,AH                  ;AX = AL
               MOV    CX,AX                  ;Bytes to move
               ADD    AX,081                 ;Parameter end
               MOV    SI,AX                  ;Set SI
               ADD    AX,0A                  ;Add 10
               MOV    DI,AX                  ;Set DI
MAKEROOM:      LODSB                         ;Move the
               STOSB                         ; parameters
               DEC    SI
               DEC    SI
               DEC    DI
               DEC    DI
               LOOP   MAKEROOM
               MOV    DI,082                 ;Set DI
               MOV    SI,OFFSET DBG          ;Set SI
               MOV    CX,0A                  ;Move 10 bytes
               REP    MOVSB                  ;Insert "DEBUG.COM "
               ADD    B[080],0A              ;Correct new length
               MOV    SI,081                 ;Set SI
NEXT_LEADCHAR: LODSB                         ;Get a byte.
               CMP    AL,0D                  ;Is it carriage return?
               JNZ    CK_LEADING             ;If yes, bad syntax.
SYN_EXIT:      JMP    SYNTAX_EXIT            ;Error exit
CK_LEADING:    CMP    AL,020                 ;Is it a space or tab?
               JBE    NEXT_LEADCHAR          ;If yes, get next character.
               DEC    SI                     ;Else, adjust pointer back one.
               PUSH   SI                     ;Save as possible path request.
               MOV    FILE_START,SI          ;Save as possible start of filename
;----------------------------------------------------;
; We now have the start of the run file.  Next scan  ;
; to the end of filename looking for a path request. ;
;----------------------------------------------------;
NEXT_PATHCHAR: LODSB                         ;Get a byte.
               MOV    DI,OFFSET DELIMITERS   ;Check for tab, carriage return,
               MOV    CX,4                   ; space, switch, or redirection
               REPNZ  SCASB                  ; characters as filename end.
               JNZ    NEXT_PATHCHAR          ;Continue until found.
               DEC    SI                     ;Else, adjust pointer back one.
               MOV    ARGUMENTS,SI           ;Save as start of arguments.
;--------------------------------------------------;
; Parse the arguments for two file control blocks. ;
;--------------------------------------------------;
               MOV    DI,OFFSET FCB_5CH      ;Point to first FCB storage.
               MOV    AX,02901               ;Parse and scan off leading
               INT    021                    ; separators.
               MOV    DI,OFFSET FCB_6CH      ;Same for second FCB
               MOV    AX,02901               ; even though it is
               INT    021                    ; not used in this program
;----------------------------------------------------;
; Store run filename stripping extension in process. ;
;----------------------------------------------------;
               MOV    AH,19H                 ;Get current drive
               INT    021                    ;Using DOS
               MOV    DRIVE,AL               ;Store current drive
               MOV    SI,OFFSET CURRENT_DIR  ;Store current directory.
               MOV    B[SI],"\"              ;DOS doesn't preface directory
               INC    SI                     ; with slash so we must.
               XOR    DL,DL                  ;Use default drive to
               MOV    AH,47H                 ;Retrieve default directory.
               INT    021                    ;Using DOS
               MOV    SI,FILE_START          ;Store the run filename.
               MOV    DI,OFFSET FILENAME     ;Set DI
NEXT_FILECHAR: LODSB                         ;Get a byte.
               PUSH   DI                     ;Save DI to stack
               MOV    DI,OFFSET DELIMITERS   ;Are we at the end of filename
               MOV    CX,4                   ;Check 4 possibles
               REPNZ  SCASB                  ;Scan them
               POP    DI                     ;Recover DI from stack
               JZ     STORE_DOT              ;If yes, done here.
               STOSB                         ;Write byte
               JMP    NEXT_FILECHAR          ;Loop back
STORE_DOT:     MOV    AL,0                   ;Make it
               STOSB                         ; ASCIIZ
               DEC    DI                     ;Step back one
               MOV    FILENAME_END,DI        ;Store end of filename.
               POP    DX                     ;Retrieve filespec start.
RUN_IT:        CALL   EXEC                   ;If found, execute it.
               JMP    DO_MORE                ;Continue after EXEC
;------------------------------------------------------;
; Close all open files before exit or error messages.  ;
;------------------------------------------------------;
CLOSE:         PUSH   AX                     ;Save error code.
               MOV    AH,03E                 ;Close file
               MOV    BX,HANDLE1             ;File handle
               INT    021                    ;Using DOS
               MOV    AH,03E                 ;Close file
               MOV    BX,HANDLE2             ;File handle
               INT    021                    ;Using DOS
               POP    AX                     ;Retrieve error code.
               RET                           ;Return
;------------------------------------------------------;
; This is the exit routine. Also close all open files. ;
;------------------------------------------------------;
SYNTAX_EXIT:   CALL   CLOSE                  ;Close any open files
               MOV    DX,OFFSET SYNTAX       ;Display
               MOV    AH,9                   ; syntax.
               INT    021                    ;Using DOS
               MOV    AX,04C00               ;Exit
               INT    021                    ;Using DOS
DO_MORE:       CALL   SUBR03                 ;Clean up DEBUG output
               CALL   SUBR08                 ;Overwrite duplicates
               CALL   SUBR09                 ;Remove overwrites, sequence
               CALL   SUBR12                 ;Build a file of missing line numbers
               MOV    AH,04C                 ;Exit.
               INT    021                    ;Using DOS
;----------------------------------------------------------;
; This subroutine executes the file using the 4Bh routine. ;
;----------------------------------------------------------;
EXEC:          CALL   REDIR                  ;Redirect input and output
               PUSH   DS                     ;Save segment registers.
               PUSH   ES
               CLI
               MOV    STACK_SEG,SS           ;Save stack segment and pointer.
               MOV    STACK_PTR,SP
               STI
               MOV    COM_LINE_PTR + 2,DS    ;Point to command line.
               MOV    FCB_1ST + 2,DS         ;Point to file control blocks.
               MOV    FCB_2ND + 2,DS
EXECUTE:       CALL   MAKE_FILESPEC          ;Construct filespec.
               CALL   ADD_PARAMETER          ;Construct arguments.
               MOV    DX,OFFSET FILESPEC     ;Set DX
EXEC_FILE:     MOV    BX,OFFSET PARAMETER_BLOCK  ;Point to parameter block.
               MOV    AX,04B00                   ;Execute.
               INT    021                    ;Using DOS
               CLI
               MOV    SP,CS:STACK_PTR        ;Restore stack segment and pointer.
               MOV    SS,CS:STACK_SEG
               STI
               POP    ES                     ;Restore segment registers.
               POP    DS
               RET                           ;Return
;---------------------------;
MAKE_FILESPEC: MOV    DI,OFFSET FILESPEC     ;Set DI
               MOV    AL,DRIVE               ;Add working drive.
               ADD    AL,"A"                 ;Make it a letter
               STOSB                         ;Store it
               MOV    AL,":"                 ;Insert a
               STOSB                         ; colon
               MOV    SI,DI                  ;Add working directory.
               MOV    B[SI],"\"              ;DOS doesn't preface directory
               INC    SI                     ; with slash so we must.
               XOR    DL,DL                  ;Set DL to zero
               MOV    AH,47H                 ;Retrieve default directory.
               INT    021                    ;Using DOS
               MOV    DI,SI                  ;Set DI
               CMP    B[DI],0                ;If root, ready for filename.
               JZ     ADD_FILENAME
FIND_END:      INC    DI                     ;Else, find end of path.
               CMP    B[DI],0                ;End ?
               JNZ    FIND_END
               MOV    AL,"\"                 ;Tack on "\" path delimiter.
               STOSB
ADD_FILENAME:  MOV    SI,OFFSET FILENAME     ;Add on filename.
NEXT_CHAR:     LODSB
               STOSB
               CMP    AL,0                   ;End ?
               JNZ    NEXT_CHAR
               RET                           ;Return
;---------------------------;
ADD_PARAMETER: MOV    DI,OFFSET PARAMETER + 1;Set DI
               MOV    SI,ARGUMENTS           ;Add on arguments.
GET_PARAMETER: LODSB
               STOSB
               CMP    AL,0D                  ;CR ?
               JNZ    GET_PARAMETER
               XOR    CL,CL                     ;Zero in counter.
               MOV    SI,OFFSET PARAMETER + 1
CNT_PARAMETER: LODSB                         ;Count parameters
               CMP    AL,0D                  ;CR ?
               JZ     END_PARAMETER
               INC    CL                     ;Count parameter length.
               JMP    CNT_PARAMETER
END_PARAMETER: MOV    PARAMETER,CL           ;Store as first byte of parameter.
               RET                           ;Return
;--------------------------------------------------;
; This section handles redirected input and output ;
;--------------------------------------------------;
REDIR:         MOV    AX,03D00
               MOV    DX,OFFSET INPUTF       ;Open INPUT for reading
               INT    021                    ;Using DOS
               MOV    W[HANDLE1],AX          ;Save handle
               MOV    AH,045                 ;Duplicate file handle
               XOR    BX,BX                  ; of Standard input = 0
               INT    021                    ;Using DOS
               MOV    BX,W[HANDLE1]          ;Get handle
               MOV    AH,046                 ;Make it redirected input
               XOR    CX,CX                  ;Set CX to zero
               INT    021                    ;Using DOS
               MOV    AX,03C00               ;Create file for overwrite
               MOV    DX,OFFSET OUTPUTF      ; as redirected output
               INT    021                    ;Using DOS
               MOV    W[HANDLE2],AX          ;Save handle
               MOV    AH,045                 ;Duplicate file handle
               MOV    BX,1                   ; of Standard output = 1
               INT    021                    ;Using DOS
               MOV    BX,W[HANDLE2]          ;Get handle
               MOV    AH,046                 ;Make it redirected output
               MOV    CX,1
               INT    021                    ;Using DOS
               RET                           ;Return
;---------------------------;
SKIPSP:                                      ;SKIPS SPACES IN PARAMETER STRING
               INC    SI                     ;Next byte
               DEC    CX
               CMP    B[SI],020              ;Space?
               JE     SKIPSP                 ;Loop back
               RET                           ;Return
;---------------------------;
SUBR01:                                      ;READ PARAMETERS, OPEN, CREATE FILES
               CLD                           ;Forward
               MOV    SI,0080                ;Parameters
               XOR    CX,CX                  ;Set CX to zero
               LODSB
               MOV    CL,AL                  ;CX is parameter length
SUB100:        MOV    DI,OFFSET TARGET
               DEC    SI
               INC    CX
               CALL   SKIPSP                 ;Skip leading spaces and adjust CX
SUB101:        LODSB
               CMP    AL,":"                 ;Colon ?
               JE     SUB100
               CMP    AL,"\"                 ;Backslash ?
               JE     SUB100
               CMP    AL,020                 ;Space ?
               JE     SUB102                 ;End of first filename
               STOSB
               LOOP   SUB101                 ;Enter first filename
SUB102:        XOR    AL,AL
               STOSB                         ;Make first filename ASCIIZ
SUB103:        MOV    DI,OFFSET FILE2
               DEC    SI
               INC    CX
               CALL   SKIPSP                 ;Skip spaces
               CMP    B[SI],0D               ;CR?
               JNE    SUB104                 ;No filename
               JMP    SUB110
SUB104:        LODSB
               CMP    AL,0D                  ;CR ?
               JE     SUB105
               CMP    AL,":"                 ;Colon ?
               JE     SUB103
               CMP    AL,"\"                 ;Backslash ?
               JE     SUB103
               CMP    B[SI],020              ;Space?
               JE     SUB105                 ;End of filename
               STOSB
               LOOP   SUB104                 ;Loop back
SUB105:        MOV    B[DI],0                ;Make filename ASCIIZ
               JMP    SUB109                 ;Continue, no output file named
SUB107:        MOV    DI,FILE2               ;Output filename address
               MOV    CX,0D                  ;Max. filename length
SUB108:        CMP    B[SI],0D               ;CR ?
               JE     SUB109                 ;Continue
               CMP    B[SI],020              ;Space ?
               JE     SUB109                 ;Continue
               LODSB                         ;Get char. from para. string
               STOSB                         ;Put it in filename
               LOOP   SUB108                 ;Loop back
SUB109:        MOV    DX,FILE2               ;ASCII filename address
               MOV    CX,0                   ;Normal attributes
               MOV    AX,05B00               ;Create file
               INT    021                    ;Using DOS
               MOV    W[HANDLE4],AX          ;Store handle
               JNC    SUB113
SUB110:        MOV    DX,MSGDSO              ;Message address
               MOV    AH,9                   ;Ouput message
               INT    021                    ;Using DOS
               MOV    SI,FILE2A              ;Standard output f.n. address
               ADD    SI,0A                  ;First ext. index
SUB111:        INC    B[SI]                  ;Increment index
               CMP    B[SI],03A              ;Not bigger than ASCII 9
               JE     SUB112
               MOV    DX,OFFSET FILE2A       ;ASCII filename address
               MOV    CX,0                   ;Normal attributes
               MOV    AX,05B00               ;Create file
               INT    021                    ;Using DOS
               MOV    W[HANDLE4],AX          ;Store handle
               JC     SUB111                 ;Repeat loop if creation failed
               MOV    DX,MSGNOF              ;New output file message address
               MOV    AH,9                   ;Display it
               INT    021                    ;Using DOS
               MOV    B[ADD2B],020           ;Make ASCIIZ a space for display
               MOV    DX,FILE2A              ;Address of default filename
               MOV    AH,9                   ;Display it
               INT    021                    ;Using DOS
               JMP    SUB113                 ;Continue
SUB112:        MOV    B[SI],02F              ;Reinitialize filename index
               INC    B[SI - 1]              ;Increment second index
               CMP    B[SI - 1],03A          ;Check second index (99 files maximum)
               JB     SUB111
               MOV    DX,MSGTMO              ;Too many output files message
               JMP    SUB115                 ;Exit with message
SUB113:        MOV    DX,TARGET              ;ASCIIZ filename
               MOV    AX,03D00               ;Open file
               INT    021                    ;Using DOS
               JB     RET                    ;Exit (Let SUR202 catch it)
               MOV    BX,AX                  ;Move file handle
               MOV    AX,04202               ;Move pointer to end
               XOR    CX,CX                  ;Zero offset from end
               XOR    DX,DX                  ;Zero offset from end
               INT    021                    ;Using DOS
               JC     SUB114                 ;Carry flag, error
               CMP    DX,0000                ;Smaller than 64K
               JNE    SUB114                 ;File too big
               CMP    AX,0F000               ;Less than 61,440 bytes
               JAE    SUB114                 ;File too big
               MOV    W[SIZEFILE],AX         ;Save size of file
               MOV    AX,04200               ;Move pointer to beginning
               XOR    CX,CX                  ;Zero offset from start
               XOR    DX,DX                  ;Zero offset from start
               INT    021                    ;Using DOS
               MOV    AH,03E                 ;Close file
               INT    021                    ;Using DOS
               RET                           ;Return
SUB114:        MOV    DX,MSGFTB              ;File is too big
SUB115:        MOV    AH,9                   ;Display message
               INT    021                    ;Using DOS
               MOV    AX,04C00               ;Exit program
               INT    021                    ;Using DOS
               RET                           ;Return
;---------------------------;
SUBR02:        MOV    AH,01A                 ;Set the
               MOV    DX,OFFSET DTA          ;  DTA
               INT    021                    ;Using DOS
               MOV    DX,INPUTF              ;Filename address
               MOV    AH,04E                 ;Does it exist ?
               INT    021                    ;Using DOS
               JNC    SUB201
               MOV    DX,OFFSET INPUTNF
               MOV    AH,09                  ;Display message
               INT    021                    ;Using DOS
               MOV    AX,04C04               ;Exit
               INT    021                    ;Using DOS
SUB201:        MOV    DX,DBGF                ;Filename address
               MOV    AH,04E                 ;Does it exist ?
               INT    021                    ;Using DOS
               JNC    SUB202
               MOV    DX,OFFSET DBGNF
               MOV    AH,09                  ;Display message
               INT    021                    ;Using DOS
               MOV    AX,04C05               ;Exit
               INT    021                    ;Using DOS
SUB202:        MOV    DX,TARGET              ;Filename address
               MOV    AH,04E                 ;Does it exist ?
               INT    021                    ;Using DOS
               JNC    SUB204
               MOV    DX,OFFSET FAIL
               MOV    AH,09                  ;Display message
               INT    021                    ;Using DOS
               MOV    SI,OFFSET TARGET       ;Set SI
SUB203:        LODSB
               CMP    AL,0
               JNE    SUB203
               MOV    B[SI-1],024            ;Insert "$"
               MOV    DX,OFFSET TARGET
               MOV    AH,09                  ;Display message
               INT    021                    ;Using DOS
               MOV    DX,OFFSET FAIL1
               MOV    AH,09                  ;Display message
               INT    021                    ;Using DOS
               MOV    AX,04C06               ;Exit
               INT    021                    ;Using DOS
SUB204:        RET                           ;Return
;---------------------------;
SUBR03:                                      ;CLEAN UP OUTPUT FILE
               MOV    AX,04200               ;Set pointer
               MOV    BX,W[HANDLE2]          ; of this file
               XOR    CX,CX                  ; to start
               XOR    DX,DX                  ; of file
               INT    021                    ;Using DOS
SUB300:        MOV    BX,W[HANDLE2]          ;Get handle
               MOV    DX,OFFSET BUFFERSM     ;Copy of original file
               MOV    W[BUFEND],DX
               MOV    CX,2                   ;Max. bytes to read
               MOV    BP,DX
               MOV    AH,03F                 ;Read file
               INT    021                    ;Using DOS
               CMP    AX,CX
               JNE    RET
               INC    BP
               INC    BP
SUB301:        CMP    W[BP - 2],0A0D         ;Read max?
               JE     SUB302                 ;Then file is too big
               CALL   SUBSUB31               ;Read one more byte
               CMP    B[MOREFLAG],0          ;End ?
               JE     SUB301
SUB302:        MOV    SI,OFFSET BUFFERSM     ;Set SI
               MOV    DI,SI                  ;Set DI
               CMP    B[SI],02D              ;Line start with hyphen ?
               JNE    SUB303
               JMP    SUB300
SUB303:        MOV    CX,W[BUFEND]
               SUB    CX,SI
               CALL   SUBSUB32               ;Clean up the line
               CALL   SUBR04                 ;Process the data
               MOV    DX,OFFSET BUFFERSM
               MOV    CX,W[BUFEND]
               SUB    CX,DX                  ;Line length
               MOV    BX,W[HANDLE4]          ;File handle
               MOV    AH,040                 ;Write line
               INT    021                    ;Using DOS
               CMP    B[MOREFLAG],0          ;End ?
               JE     SUB300
               MOV    AX,03E00               ;Close file
               MOV    BX,W[HANDLE4]          ;File handle
               INT    021                    ;Using DOS
               MOV    AX,03E00               ;Close file
               MOV    BX,W[HANDLE2]          ;File handle
               INT    021                    ;Using DOS
               RET                           ;Return
;---------------------------;
SUBSUB31:      MOV    B[MOREFLAG],1          ;Set flag
               MOV    CX,1                   ;Read one more byte
               MOV    BX,W[HANDLE2]          ;File handle
               MOV    AH,03F                 ;Read file
               MOV    DX,BP                  ;Address to read to
               INT    021                    ;Using DOS
               CMP    AX,1                   ;Successful ?
               JNE    SSUB311
               MOV    B[MOREFLAG],0          ;Reset flag
               INC    BP                     ;Step address
               INC    B[BUFEND]              ;Increase length counter
SSUB311:       RET                           ;Return
;---------------------------;
SUBSUB32:      CMP    B[SI + 4],03A          ;Are next 5 bytes segment: ?
                ;This should skip edited lines with DB statements.
               JNE    SSUB321                 ;Continue if not
               ADD    SI,5                   ;Skip segment:
               SUB    CX,6                   ;Adjust CX for SEG. & LINE #
               LODSB                         ;Load and store
               STOSB                         ; the 1st digit
               LODSB                         ;Load and store
               STOSB                         ; the 2nd digit
               LODSB                         ;Load and store
               STOSB                         ; the 3rd digit
               LODSB                         ;Load and store
               STOSB                         ; the 4th digit
               ADD    SI,15                  ;Skip 15 code & spaces
               SUB    CX,15                  ;Adjust CX for this skip
               MOV    AL,020                 ;Load space in AL
               STOSB                         ;And put
               STOSB
               STOSB                         ;   in five
               STOSB
               STOSB                         ;      of them
SSUB321:
               STOSB                         ;Save byte to BUFFERSM
               CMP    B[SI],020
               JNE    SSUB323
               CMP    B[SI + 1],020          ;Check for 2 spaces
               JNE    SSUB323
SSUB322:       INC    SI                     ;Adjust SI
               DEC    CX                     ;Adjust CX
               CMP    B[SI],0D               ;CR ?
               JNE    SSUB322
               CMP    B[SI + 1],0A           ;Line feed ?
               JNE    SSUB322
               SUB    CX,2                   ;Adjust CX
               LODSW                         ;Move the CR LF pair
               STOSW
               MOV    W[BUFEND],DI           ;New line end
               RET                           ;Return
SSUB323:       LODSB                         ;Loop back through BUFFERSM
               LOOP   SSUB321                ;Loop back
               MOV    W[BUFEND],DI           ;New line end
               RET                           ;Return
;---------------------------;
SUBR04:            ;SWEEP OF ENTIRE FILE
               MOV    DI,OFFSET MISSBUF      ;Initialize DI
               MOV    AX,W[ITEMS]            ;Set AX
               XOR    CX,CX                  ;Set CX to zero
               MOV    CL,0F                  ;15 characters per line
               MUL    CL                     ;Multiply by line length
               ADD    DI,AX                  ;Add offset
               MOV    SI,OFFSET BUFFERSM     ;Initialize SI
               PUSH   SI                     ;Save SI
               PUSH   DI                     ; and DI
               INC    W[NUMB]                ;Increment counter
               MOV    AX,W[NUMB]             ;Set AX
               MOV    CL,02
               SHL    AX,CL
               ADD    AX,W[NUMB]
               MOV    DI,OFFSET NUMBUF       ;Set DI
               ADD    DI,AX
               MOV    SI,OFFSET BUFFERSM     ;Set SI
               XOR    CX,CX
               MOV    CL,4
               REP    MOVSB                  ;Move 4 bytes
               MOV    AL,020
               STOSB                         ;Insert space
               POP    DI
               POP    SI
SUB401:        LODSB                         ;Get byte from BUFFER
               CMP    AL,0D
               JE     RET
               CMP    AL,04A                 ;Check it for "J"
               JNE    SUB402                 ;Exit loop if match
               CALL   SUBR05                 ;Check end space string
SUB402:        CMP    AL,04C                 ;Check it for "L"
               JNE    SUB403                 ;Exit loop if match
               CALL   SUBR07                 ;Check end space string
SUB403:        CMP    AL,043                 ;Check it for "C"
               JNE    SUB404                 ;Exit loop if match
               CALL   SUBR11                 ;Check end space string
SUB404:        CMP    AL,05B                 ;Check it for "["
               JNE    SUB405                 ;Exit loop if match
               CALL   SUBR13                 ;Check end space string
SUB405:        CMP    AL,053                 ;Check it for "S"
               JNE    SUB406                 ;Exit loop if match
               CMP    B[SI],049              ;Check it for "I"
               JNE    SUB406                 ;Exit loop if match
               CMP    B[SI+1],02C            ;Check it for comma
               JNE    SUB406                 ;Exit loop if match
               ADD    SI,2                   ;Adjust SI and CX
               CALL   SUBR06                 ;Are next 4 char. hex digits
               CMP    B[FLAG1],0             ;Check flag
               JE     SUB406                 ;Equal, digits not OK
               CALL   SUBR10                 ;Enter a data line
               JMP    SUB406                 ;Loop too long
LONGLOOP:      JMP    SUB401                 ;This will fix it
SUB406:        CMP    AL,044                 ;Check it for "D"
               JNE    SUB408                 ;Exit loop if match
               CMP    B[SI],049              ;Check it for "I"
               JNE    SUB407                 ;Exit loop if match
               CMP    B[SI+1],02C            ;Check it for comma
               JNE    SUB408                 ;Exit loop if match
               ADD    SI,2                   ;Adjust SI and CX
               CALL   SUBR06                 ;Are next 4 char. hex digits
               CMP    B[FLAG1],0             ;Check flag
               JE     SUB408                 ;Equal, digits not OK
               CALL   SUBR10                 ;Enter a data line
SUB407:        CMP    B[SI],058              ;Check it for "X"
               JNE    SUB408                 ;Exit loop if match
               CMP    B[SI+1],02C            ;Check it for comma
               JNE    SUB408                 ;Exit loop if match
               ADD    SI,2                   ;Adjust SI and CX
               CALL   SUBR06                 ;Are next 4 char. hex digits
               CMP    B[FLAG1],0             ;Check flag
               JE     SUB408                 ;Equal, digits not OK
               CALL   SUBR10                 ;Enter a data line
SUB408:        JMP    SUB401                 ;Loop back through BUFFER
               RET                           ;Return
SUBR05:               ;SEEK (J)???TAB(HEX NUMBER)
               LODSB                         ;At least one letter after J
               LODSB                         ;Get byte in AL
               CMP    AL,09                  ;Is it tab ?
               JE     SUB501                 ;If yes, get numbers
               LODSB                         ;Get byte in AL
               CMP    AL,09                  ;Is it tab ?
               JE     SUB501                 ;If not, return
               LODSB                         ;Get byte in AL
               CMP    AL,09                  ;Is it tab ?
               JE     SUB501                 ;If not, return
               JMP    SUB506                 ;Return
SUB501:        CMP    W[SI],04146            ;Is it "FA"
               JNE    SUB502
               CMP    W[SI+2],02052          ;   "R "
               JNE    SUB502                 ;No, not FAR
               ADD    SI,4                   ;Yes, adjust
SUB502:        CMP    B[SI],05B              ;Possible indirect call
               JNE    SUB503                 ;If no, check digits
               INC    SI                     ;If yes, adjust
SUB503:        CALL   SUBR06                 ;Are next 4 char. hex digits
               CMP    B[FLAG1],0             ;Check flag
               JNE    SUB504                 ;Not equal, digits OK
               LODSB                         ;Get byte in AL
SUB504:        INC    W[ITEMS]               ;Increase line count
               MOV    CX,4                   ;Reset to 4
SUB505:        LODSB                         ;Get byte in AL
               STOSB                         ;Store it in new file buffer
               LOOP   SUB505                 ;Repeat loop 3 more times
               MOV    AL,020                 ;Set AL to space
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               MOV    AL,057                 ;Set AL to W
               STOSB                         ;Store it in new file buffer
               MOV    AL,04A                 ;Set AL to J
               STOSB                         ;Store it in new file buffer
               MOV    AL,020                 ;Set AL to space
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               MOV    AL,":"                 ;Set AL to ":"
               STOSB                         ;Store it in new file buffer
               MOV    AL,0D                  ;Set al to CR
               STOSB                         ;Store it in new file buffer
               MOV    AL,0A                  ;Set AL to LF
               STOSB                         ;Store it in new file buffer
               MOV    AL,020                 ;Set AL to space
SUB506:        RET                           ;Return
SUBR06:            ;CHECK FOR 4 HEX DIGITS
               MOV    B[FLAG1],0             ;Reset flag
               CMP    B[SI],030              ;Possible HEX digit ?
               JB     SUB601                 ;If not, return
               CMP    B[SI],046              ;Possible HEX digit ?
               JA     SUB601                 ;If not, return
               CMP    B[SI+1],030            ;Possible HEX digit ?
               JB     SUB601                 ;If not, return
               CMP    B[SI+1],046            ;Possible HEX digit ?
               JA     SUB601                 ;If not, return
               CMP    B[SI+2],030            ;Possible HEX digit ?
               JB     SUB601                 ;If not, return
               CMP    B[SI+2],046            ;Possible HEX digit ?
               JA     SUB601                 ;If not, return
               CMP    B[SI+3],030            ;Possible HEX digit ?
               JB     SUB601                 ;If not, return
               CMP    B[SI+3],046            ;Possible HEX digit ?
               JA     SUB601                 ;If not, return
               MOV    B[FLAG1],1             ;4 hex digits pass ok
SUB601:        RET
SUBR07:            ;SEEK (L)OOP???TAB(HEX NUMBER)
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,04F                 ;Is it O ?
               JNE    RET                    ;If not, return
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,04F                 ;Is it O ?
               JNE    RET                    ;If not, return
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,050                 ;Is it P ?
               JNE    RET                    ;If not, return
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,09                  ;Is it tab ?
               JE     SUB701                 ;If yes, get next
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,09                  ;Is it tab ?
               JE     SUB701                 ;If not, return
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,09                  ;Is it tab ?
               JE     SUB701                 ;If not, return
               JMP    SUB703
SUB701:        INC    W[ITEMS]               ;Increase line count
               SUB    CX,4                   ;Adjust for  + 4
               PUSH   CX                     ;Save counter in stack
               MOV    CX,4                   ;Reset to 4
SUB702:        LODSB                         ;Get byte in AL
               STOSB                         ;Store it in new file buffer
               LOOP   SUB702                 ;Repeat loop 3 more times
               MOV    AL,020                 ;Set AL to space
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               MOV    AL,057                 ;Set AL to W
               STOSB                         ;Store it in new file buffer
               MOV    AL,04A                 ;Set AL to J
               STOSB                         ;Store it in new file buffer
               MOV    AL,020                 ;Set AL to space
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               MOV    AL,":"                 ;Set AL to ":"
               STOSB                         ;Store it in new file buffer
               MOV    AL,0D                  ;Set al to CR
               STOSB                         ;Store it in new file buffer
               MOV    AL,0A                  ;Set AL to LF
               STOSB                         ;Store it in new file buffer
               POP    CX                     ;Recover CX from stack
SUB703:        RET                           ;Return
SUBR08:            ;MARKS DUPLICATE LINES IN OUTPUT FILE
               MOV    AX,W[SIZEFILE]         ;Adjust file
               ADD    AX,0100                ; size for
               MOV    W[SIZEFILE],AX         ; PSP
               MOV    SI,OFFSET PASSWORD     ;Start with file password
               MOV    DI,W[SUBBUF]           ;Destination address
               MOV    CX,0F                  ;Password size
               REP    MOVSB                  ;Move it
               MOV    W[COUNT],0             ;Initialize outer loop counter
               MOV    BX,W[SUBBUF]           ;Initialize BX as line pointer
SUB801:        INC    W[COUNT]               ;Increment outer loop counter
               MOV    AX,W[ITEMS]            ;Load upper counter limit in AX
               CMP    W[COUNT],AX            ;Check outer loop counter
               JAE    RET                    ;Exit if equal or above
               MOV    CX,W[ITEMS]
               SUB    CX,W[COUNT]            ;Set counter to lines left
               ADD    BX,0F                  ;New base line
               MOV    SI,BX                  ;Set SI to match
               INC    SI                     ;Simulate lodsw
               INC    SI                     ; in inner loop
               CMP    W[BX],03030
               JNE    SUB802
               MOV    AX,02A2A               ;Load ** into AX
               MOV    DI,BX                  ;Set write pointer
               STOSW                         ;Write **
               STOSW                         ;Write **
               JMP    SUB801
SUB802:        PUSH   BX
               PUSH   CX
               PUSH   DX
               MOV    AX,W[BX]               ;Convert
               XCHG   AH,AL
               MOV    BX,W[BX + 2]           ; to
               XCHG   BH,BL
               SUB    AX,03030               ; ASCII
               SUB    BX,03030
               CMP    AH,9                   ;>9 ?
               JB     SUB803
               SUB    AH,7                   ;Extra adjustment
SUB803:        CMP    AL,9                   ;>9 ?
               JB     SUB804
               SUB    AL,7                   ;Extra adjustment
SUB804:        CMP    BH,9                   ;>9 ?
               JB     SUB805
               SUB    BH,7                   ;Extra adjustment
SUB805:        CMP    BL,9                   ;>9 ?
               JB     SUB806
               SUB    BL,7                   ;Extra adjustment
SUB806:        MOV    CX,4
               XOR    DX,DX                  ;Set DX to zero
               MOV    DL,AH                  ;Move byte
               SHL    DX,CL                  ;Multiply by 16
               ADD    DL,AL                  ;Combine them
               SHL    DX,CL                  ;Multiply by 16
               ADD    DL,BH                  ;Combine them
               SHL    DX,CL                  ;Multiply by 16
               ADD    DL,BL                  ;Combine them
               MOV    BX,W[SIZEFILE]
               CMP    BX,DX                  ;Too big for a line number ?
               JNB    SUB807
               MOV    AX,02A2A               ;Ready to overwrite
SUB807:        POP    DX
               POP    CX
               POP    BX
               CMP    AX,02A2A               ;Overwrite it ?
               JNE    SUB808
               MOV    DI,BX
               STOSW                         ;Do the
               STOSW                         ; overwrite
               JMP    SUB801
SUB808:            ;Inner loop, checks all lines after (count)
               ADD    SI,0D                  ;Adjust SI, less 2 for lodsw
               LODSW                         ;Loads 1st & 2nd digits into AX
               CMP    W[BX],AX               ;Check them
               JNE    SUB810                 ;If not eq. skip second 2 digits
               PUSH   AX                     ;Save AX in stack
               PUSH   SI                     ;Save SI in stack
               LODSW                         ;Load 3rd & 4th digits into AX
               CMP    W[BX+2],AX             ;Check for a match
               JNE    SUB809                 ;No, skip write
               MOV    AX,02A2A               ;Load ** into AX
               MOV    DI,BX                  ;Set write pointer
               STOSW                         ;Write **
               STOSW                         ;Write **
SUB809:        POP    SI                     ;Get SI back from stack
               POP    AX                     ;Get AX back from stack
SUB810:        LOOP   SUB808                 ;Repeat inner loop
               JMP    SUB801                 ;Repeat outer loop
               RET                           ;Return
SUBR09:               ;REMOVE OVERWRITES AND PUT IN SEQUENCE
               MOV    CX,W[ITEMS]            ;Lines to check
               CMP    CX,0168                ;Too many ?
               JB     SUB901                 ;OK ?  Skip message
               MOV    DX,MSGTMI              ;Message address
               MOV    AH,9                   ;Display message
               INT    021                    ;Using DOS
               MOV    AX,04C00               ;Exit program
               INT    021                    ;Using DOS
               RET                           ;Return
SUB901:               ;REMOVE MARKED LINES, ADD NUMBERS
               MOV    AX,0F                  ;15 character per line
               MUL    CX                     ; times lines
               MOV    BX,OFFSET MISSBUF      ;First line after password
               ADD    AX,BX                  ;Sum for end of file
               MOV    W[BUFEND],AX           ;Save it
SUB902:        CMP    B[BX],02A              ;Check first char. for *
               JNE    SUB904                 ;No, then skip
               DEC    W[ITEMS]               ;One less items
               PUSH   CX                     ;Save it in stack
               MOV    CX,W[BUFEND]           ;Set new counter to move string
               SUB    CX,BX                  ;Minus current position
               SUB    CX,0F                  ;Minus one line length
               MOV    SI,BX
               ADD    SI,0F                  ;Set SI to start of next line
               MOV    DI,BX                  ;Set DI to start of current line
SUB903:        LODSB
               STOSB
               LOOP   SUB903                 ;Move rest of file back one line
               POP    CX                     ;Get old counter from stack
               SUB    W[BUFEND],0F           ;Adjust BUFEND
               SUB    BX,0F                  ;Compensate for comming ADD
SUB904:        ADD    BX,0F                  ;Set BX for next line
               LOOP   SUB902                 ;Sweep buffer area
               MOV    W[COUNT],0             ;Initialize count
               MOV    BX,OFFSET MISSBUF      ;Initialize BX
               MOV    CX,W[ITEMS]            ;Set loop counter
SUB905:            ;Convert ASCII to HEX for ordering
               PUSH   CX                     ;Save counter in stack
               MOV    CL,4                   ;Set for shift left
               MOV    SI,BX                  ;Set SI
               MOV    DI,SI
               ADD    DI,0A                  ;Set DI
               LODSW                         ;Load first two digits
               SUB    AH,030                 ;Convert to hex
               CMP    AH,0A                  ;Alpha check
               JB     SUB906                 ;Skip if not alpha
               SUB    AH,07                  ;Alpha conversion
SUB906:        SUB    AL,030                 ;Convert to hex
               CMP    AL,0A                  ;Alpha check
               JB     SUB907                 ;Skip if not alpha
               SUB    AL,07                  ;Alpha conversion
SUB907:        SHL    AL,CL                  ;Shift first digit
               ADD    AL,AH                  ;Combine them
               STOSB                         ;Store first two digits as hex
               LODSW                         ;Load second two digits
               SUB    AH,030                 ;Convert to hex
               CMP    AH,0A                  ;Alpha check
               JB     SUB908                 ;Skip if not alpha
               SUB    AH,07                  ;Alpha conversion
SUB908:        SUB    AL,030                 ;Convert to hex
               CMP    AL,0A                  ;Alpha check
               JB     SUB909                 ;Skip if not alpha
               SUB    AL,07                  ;Alpha conversion
SUB909:        SHL    AL,CL                  ;Shift first digit
               ADD    AL,AH                  ;Combine them
               STOSB                         ;Store second two digits as hex
               ADD    BX,0F                  ;Set BX for next line
               POP    CX                     ;Recover counter from stack
               LOOP   SUB905                 ;Sweep buffer
               MOV    CX,W[ITEMS]            ;Initialize loop counter
               MOV    BX,OFFSET MISSBUF      ;Set BX
               MOV    SI,BX
               SUB    SI,3                   ;Set SI
               MOV    DI,BX
               SUB    DI,3                   ;Set DI
SUB910:        ADD    SI,0D                  ;Next line
               ADD    DI,0D                  ;Next line
               LODSB                         ;Read byte
               MOV    AH,AL                  ;Shift it
               LODSB                         ;Read byte
               STOSW                         ;Replace rotated word
               LOOP   SUB910                 ;Sweep buffer
               MOV    CX,W[ITEMS]            ;Initialize loop counter
               MOV    BX,OFFSET MISSBUF      ;Set BX
               MOV    SI,BX
               SUB    SI,3                   ;Set SI
               MOV    DI,BX
               SUB    DI,7                   ;Set DI
SUB911:        MOV    DX,03030               ;Initialize ASCII count
               ADD    SI,0D                  ;Update SI
               ADD    DI,0D                  ;Update DI
               MOV    BX,0                   ;Set BX to 0
               LODSW                         ;Load word in AX
               PUSH   DX                     ;Save DX to stack
               PUSH   CX                     ;Save CX to stack
               PUSH   SI                     ;Save SI to stack
               MOV    SI,OFFSET MISSBUF      ;Reinitialize SI
               SUB    SI,5                   ;Update SI
               MOV    CX,W[ITEMS]            ;Initialize counter
SUB912:        ADD    SI,0F                  ;Update SI
               CMP    AX,W[SI]               ;Compare them (no duplicates)
               JL     SUB913                 ;Only count if not less
               INC    BX                     ;Increase count
SUB913:        LOOP   SUB912                 ;Sweep buffer
               POP    SI                     ;Recover SI from stack
               POP    CX                     ;Recover CX from stack
SUB914:        CMP    BX,0                   ;Loop escape
               JE     SUB917                 ; if equal
SUB915:        DEC    BX                     ;Decrease count
               INC    DH                     ;Adjust ASCII count
               CMP    DH,03A                 ;Non-number
               JB     SUB916
               INC    DL                     ;Step other digit
               MOV    DH,030                 ;reset first digit
               CMP    DL,03A                 ;Check second digit
               JNE    SUB916                 ;If greater than 99
               MOV    DL,041                 ; make MSD a capital letter
SUB916:        JMP    SUB914                 ;Repeat loop
SUB917:        MOV    AX,DX                  ;Reset AX for write
               STOSW                         ;Write it in center gap
               POP    DX                     ;Recover DX from stack
               LOOP   SUB911                 ;Sweep buffer
               MOV    CX,W[ITEMS]            ;Reset loop counter
               MOV    BX,W[SUBBUF]           ;Initialize BX
               MOV    DX,02020               ;For restoring gap
SUB918:        ADD    BX,0F                  ;Update BX
               MOV    SI,BX                  ;Update SI
               MOV    DI,BX                  ;Update DI
               ADD    SI,6                   ;Update SI
               ADD    DI,0A                  ;Update DI
               LODSW                         ;Load word
               STOSW                         ; and write it
               SUB    DI,6                   ;Update DI
               MOV    AX,DX                  ;Load two spaces
               STOSW                         ;Write them
               LOOP   SUB918                 ;Sweep buffer
               RET                           ;Return
SUBR10:            ;ENTER DATA LINE
               INC    W[ITEMS]               ;Increase line count
               SUB    CX,4                   ;Adjust for  4 characters
               PUSH   CX                     ;Save counter in stack
               MOV    CX,4                   ;Reset to 4
SUBA01:        LODSB                         ;Get byte in AL
               STOSB                         ;Store it in new file buffer
               LOOP   SUBA01                 ;Repeat loop 3 more times
               MOV    AL,020                 ;Set AL to space
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               MOV    AL,057                 ;Set AL to W
               STOSB                         ;Store it in new file buffer
               MOV    AL,044                 ;Set AL to D
               STOSB                         ;Store it in new file buffer
               MOV    AL,020                 ;Set AL to space
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               MOV    AL,":"                 ;Set AL to ":"
               STOSB                         ;Store it in new file buffer
               MOV    AL,0D                  ;Set al to CR
               STOSB                         ;Store it in new file buffer
               MOV    AL,0A                  ;Set AL to LF
               STOSB                         ;Store it in new file buffer
               POP    CX                     ;Recover CX from stack
               RET                           ;Return
SUBR11:               ;CHECK FOR "CALL"
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,041                 ;Is it A ?
               JNE    SUBB05                 ;If yes, get next
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,04C                 ;Is it L ?
               JNE    SUBB05                 ;If not, return
               LODSB                         ;Get byte in AL
               DEC    CX                     ;Adjust counter
               CMP    AL,04C                 ;Is it L ?
               JNE    SUBB05                 ;If not, return
               PUSH   CX                     ;Save CX to stack
               MOV    CX,5                   ;Skip possible "FAR"
SUBB01:        LODSB                         ;Load next byte in AL
               CMP    AL,9                   ;Is it a tab
               JE     SUBB02                 ;Exit loop
               CMP    AL,05B                 ;Check for indirect CALL
               JE     SUBB02                 ;Exit loop
               LOOP   SUBB01                 ;Repeat loop max 5 bytes
SUBB02:        MOV    AX,6                   ;Pop CX
               SUB    AX,CX                  ;  and adjust
               POP    CX                     ;  for loop
               SUB    CX,AX                  ;  count
               CMP    B[SI],05B              ;Check for indirect CALL
               JNE    SUBB03                 ;Continue if not "["
               INC    SI                     ;If equal, skip it
               DEC    CX                     ;  by adjusting SI and CX
SUBB03:        CALL   SUBR06                 ;Check for hex digits
               CMP    B[FLAG1],0             ;Check flag
               JE     SUBB05                 ;Equal, digits not OK
               INC    W[ITEMS]               ;Increase line count
               SUB    CX,4                   ;Adjust for tab + 4
               PUSH   CX                     ;Save counter in stack
               MOV    CX,4                   ;Reset to 4
SUBB04:        LODSB                         ;Get byte in AL
               STOSB                         ;Store it in new file buffer
               LOOP   SUBB04                 ;Repeat loop 3 more times
               MOV    AL,020                 ;Set AL to space
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               MOV    AL,057                 ;Set AL to W
               STOSB                         ;Store it in new file buffer
               MOV    AL,053                 ;Set AL to S
               STOSB                         ;Store it in new file buffer
               MOV    AL,020                 ;Set AL to space
               STOSB                         ;Store it in new file buffer
               STOSB                         ;Store it in new file buffer
               MOV    AL,":"                 ;Set AL to ":"
               STOSB                         ;Store it in new file buffer
               MOV    AL,0D                  ;Set AL to CR
               STOSB                         ;Store it in new file buffer
               MOV    AL,0A                  ;Set AL to LF
               STOSB                         ;Store it in new file buffer
               POP    CX                     ;Recover CX from stack
SUBB05:        RET                           ;Return
SUBR12:            ;GET MISSING LINE NUMBERS
               MOV    AX,03C00               ;Create file
               MOV    DX,OFFSET LABL         ;File name address
               XOR    CX,CX                  ;Normal attribute
               INT    021                    ;Using DOS
               MOV    W[HANDLE4],AX          ;Save handle
               MOV    BX,W[HANDLE4]          ;Load output file handle
               MOV    DX,W[SUBBUF]           ;New file is here
               INC    B[ITEMS]               ;For password
               MOV    AL,0F                  ;Lines are 15 characters including CR & LF
               MUL    B[ITEMS]               ;Multiply lines by 11
               MOV    CX,AX                  ;Set length of write function
               MOV    AX,04000               ;Write buffer to file
               INT    021                    ;Using DOS
               MOV    AH,03E                 ;Close file
               INT    021                    ;Using DOS
               MOV    DI,W[SUBBUF]
               MOV    W[MISBUF],DI           ;New buffer start (overwriting)
               MOV    SI,OFFSET ROBERT       ;Put in a
               MOV    CX,0F                  ;  close
SUBC04:                                      ;  but
               LODSB                         ;  wrong
               STOSB                         ;  password
               LOOP   SUBC04                 ;  0.WALLINGFORD CR LF
               MOV    BP,W[SUBBUF]           ;Pointer in first set
               MOV    CX,W[ITEMS]            ;Count in first set
               MOV    W[ITEMS],0             ;Items will now count for new file
SUBC05:        PUSH   CX                     ;Save count in stack
               ADD    BP,0F                  ;Items are 15 bytes long
               MOV    BX,OFFSET NUMBUF       ;Pointer in
               MOV    CX,W[NUMB]             ;Count in second set
SUBC06:        PUSH   CX                     ;Compare a linenumber at
               PUSH   DI                     ;  BX and one at BP
               MOV    CX,4                   ;         "
               MOV    SI,BP                  ;         "
               MOV    DI,BX                  ;         "
               REPE   CMPSB                  ;         "
               POP    DI                     ;         "
               POP    CX                     ;         "
               JE     SUBC08                 ;If match, step outer loop
               ADD    BX,5                   ;No match, next BX and
               LOOP   SUBC06                 ;  step inner loop
               INC    W[ITEMS]               ;If inner loop completed without
               MOV    DI,W[MISBUF]           ;  a match, add an item, and reset
               MOV    CX,W[ITEMS]            ;  DI to original value plus 10 times
SUBC07:                                      ;  the number of items. This is the
               ADD    DI,0F                  ;  current end of the buffer that
               LOOP   SUBC07                 ;  will be the file MISSING.NBR
               MOV    SI,BP                  ;Reset SI
               LODSW                         ;Copy the whole line number 
               STOSW                         ;         "
               LODSW                         ;         "
               STOSW                         ;         "
               MOV    AX,02020               ;Put in 4 spaces
               STOSW                         ;         "
               STOSW                         ;         "
               ADD    SI,4                   ;Add the ID characters
               LODSW                         ;         "
               STOSW                         ;         "
               PUSH   DI                     ;Copy the
               MOV    AL,B[DI-1]             ;  second ID
               SUB    DI,4                   ;  character
               STOSB                         ;  to the
               POP    DI                     ;  Gap space
               DEC    DI                     ;And replace
               MOV    AL,04D                 ;  it with
               STOSB                         ;  an "M"
               MOV    AX,W[ITEMS]            ;Missing line count (hex)
               MOV    DL,0A                  ;Convert
               DIV    DL                     ;  it to
               ADD    AL,030                 ;  modified
               ADD    AH,030                 ;  decimal
               STOSW                         ;Store it
               ADD    SI,2                   ;Skip input numbers
               LODSB                         ;Put in a colon
               STOSB                         ;         "
               LODSW                         ;Add the CR  LF  pair
               STOSW                         ;         "
SUBC08:        POP    CX                     ;Recover outer loop counter
               LOOP   SUBC05                 ;Step outer loop
               MOV    AH,03C                 ;Create (or truncate) file
               MOV    CX,0                   ;Normal attributes
               MOV    DX,MISSING             ;Address of filename
               INT    021                    ;Using DOS
               MOV    BX,AX                  ;Move file handle
               MOV    AX,W[ITEMS]            ;Number of lines
               INC    AX                     ;To include pseudo password
               MOV    CL,0F                  ;Characters per line
               MUL    CL                     ;Multiply them
               MOV    CX,AX                  ;Bytes to write to file
               MOV    AH,040                 ;Write buffer to file
               MOV    DX,W[MISBUF]           ;Address of write buffer
               INT    021                    ;Using DOS
               MOV    AH,03E                 ;Close file
               INT    021                    ;Using DOS
               RET                           ;Return
SUBR13:        CMP    B[SI+4],05D            ;Check for "]" after 4 characters
               JNE    SUBD01                 ;If not, return
               CALL   SUBR06                 ;Check for 4 hex digits
               CMP    B[FLAG1],0
               JE     SUBD01                 ;Equal, digits not OK
               CALL   SUBR10                 ;Enter a data line
SUBD01:        RET                           ;Return
PASSWORD:      DB     "R.WALLINGFORD",0D,0A
ROBERT:        DB     "0.WALLINGFORD",0D,0A,024
;---------------------------;
PARAMETER      LABEL  BYTE
FCB_5CH        EQU    PARAMETER + 2
FCB_6CH        EQU    FCB_5CH + 16
CURRENT_DIR    EQU    FCB_6CH + 16
FILENAME       EQU    CURRENT_DIR + 65
FILESPEC       EQU    FILENAME + 13
DTA            EQU    FILESPEC + 80
BUFFERSM       EQU    DTA + 43
SUBBUFF        EQU    BUFFERSM + 85
MISSBUF        EQU    SUBBUFF + 15
NUMBUF         EQU    MISSBUF + 5400
CODE_END       EQU    NUMBUF + 04000 + 256  ;256 is for stack
CODE ENDS
END  START
