home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / DIR / DIRNO120.ZIP / DIRNOTES.ASM next >
Encoding:
Assembly Source File  |  1990-09-05  |  48.1 KB  |  1,086 lines

  1. ;          Dirnotes.asm ;  FORMAT: DIRNOTES [d][path][directory] 
  2.  
  3. ; *A  10-15-89 WCL ... Chg'd Home,End key defs to ^Home,^End respectively
  4. ;     rev 1.10         Added new Home,End,Tab,Sh-Tab,Ins,Del,^T,^Left,^Right 
  5. ;                      KEY DEFS.
  6. ;                      Reassembled with TASM 1.0, Linked with TLINK 2.0.
  7.  
  8. ; *B  09-04-90 EFP ... Chg'd the display to include leading zeros in the date, 
  9. ;     rev 1.20         Eliminated the time field to allow for a larger comment
  10. ;                      field, Added conversion code to reformat the filenames 
  11. ;                      (added in the DIRNOTES listing via an RBBS Upload) from 
  12. ;                      XXXXXXXX.XXX to XXXXXXXX XXX.  Added Alt-C to jump to 
  13. ;                      the last 3 of the comment field (used for category code 
  14. ;                      in RBBS FMS directories). 
  15.  
  16. ;                      Reassembled with MASM 4.0, Linked with LINK 3.51.
  17.  
  18. CODE SEGMENT                           ;*************************;
  19. ASSUME CS:CODE,DS:CODE                 ;*                       *;
  20. ORG 100H                               ;*  REMEMBER TO EXE2BIN  *;
  21.                                        ;*                       *;
  22. START:         JMP    BEGINNING        ;*************************;
  23.  
  24. ;              DATA AREA
  25. ;              ---------
  26. COPYRIGHT      DB  'Copyright 1987 Ziff-Davis Publishing Co. - Rev 1.10',10,13
  27. PROGRAMMER     DB  'Michael J. Mefford - Updated 10-15-89 by WCL, 09-05-90 by EFP',1AH
  28. DIRNOTES       DB  'DIRN----.DAT',0
  29. STAR_DOT_STAR  DB  '*.*',0
  30. DOTS           DB  '............'
  31.  
  32. CURRENT_DISK   DB  ?
  33. STATUS_REG     DW  ?
  34. VIDEO_SEG      DW  0B000H
  35. NORMAL         DB  07H
  36. INVERSE        DB  70H
  37.  
  38. CURSOR_ORG     DW  ?              ;*A    CH & CL registers: cursor height
  39. CURS_POS       DW  ?              ; row,col
  40. CUR_OFFSET     DW  OFFSET BUFFER
  41. END_OFFSET     DW  ?
  42. PAGE_END       DW  183H+21*160    ;*B
  43. COUNT          DW  1
  44. LINE           DW  183H           ;*B
  45.  
  46. EOF_FLAG       DB  0
  47. UPDATE_FLAG    DB  0
  48. INS_FLAG       DB  1              ;*A    1 = insert mode
  49.  
  50. NOT_ENOUGH     DB  'Not enough memory$'
  51. INVALID        DB  'Invalid directory$'
  52. TOO_MANY       DB  'Too many files$'
  53. LOADING        DB  'Loading and sorting directory notes.',0
  54. DIRECTORY      DB  'Directory of ',0
  55. FILES          DB  '    Files',0
  56. STATUS_LINE    DB  'Press Esc to exit',0
  57. SAVING         DB  'Saving ',0
  58.  
  59. ;----------------------------------------------------------------------------;
  60. ; Some housekeeping first. Since we will be changing the default drive       ;
  61. ; and directory to the requested drive and directory, we need to save the    ;
  62. ; current defaults, so they can be restored.  If less than 64K, exit.        ;
  63. ;----------------------------------------------------------------------------;
  64.  
  65. ;              CODE AREA
  66. ;              ---------
  67. BEGINNING:     CLD
  68.  
  69.  
  70.                MOV    AH,19H                 ;Get current drive.
  71.                INT    21H
  72.                MOV    CURRENT_DISK,AL        ;And save.
  73.  
  74.                MOV    SI,OFFSET CURRENT_DIR  ;Get current directory.
  75.                CALL   GET_DIR
  76.  
  77.                CMP    SP,65500               ;Do we have 64K?
  78.                MOV    DX,OFFSET NOT_ENOUGH
  79.                JA     PARSE
  80.                JMP    ERROR_EXIT             ;If no, exit.
  81.  
  82. ;-----------------------------------------------------------;
  83. ; Parse the command line for parameters and append the      ;
  84. ; DIRNOTES filename with the characters of directory name.  ;
  85. ;-----------------------------------------------------------;
  86.  
  87. PARSE:         CMP    BYTE PTR DS:[80H],0    ;Any parameters?
  88.                JZ     APPEND                 ;If no, skip parse.
  89.  
  90.                MOV    SI,81H                 ;Else, point to first character.
  91. NEXT_PARSE:    LODSB
  92.                CMP    AL,13                  ;Carriage return?
  93.                JZ     APPEND                 ;If yes, done here.
  94.                CMP    AL,32                  ;Leading space?
  95.                JBE    NEXT_PARSE             ;If yes, get next byte.
  96.                PUSH   SI                     ;Save start.
  97.  
  98. NEXT_PARA:     LODSB
  99.                CMP    AL,13                  ;End of parameter?
  100.                JZ     END_PARA               ;If yes, done here.
  101.                CMP    AL,':'                 ;Drive request?
  102.                JNZ    NEXT_PARA              ;If no, get next byte.
  103.                MOV    DL,BYTE PTR [SI-2]     ;Else, retrieve request.
  104.                AND    DL,5FH                 ;Capitalize.
  105.                SUB    DL,'A'                 ;Convert to DOS format.
  106.                MOV    AH,0EH                 ;And change drive.
  107.                INT    21H
  108.                JMP    SHORT NEXT_PARA        ;Find end of parameter.
  109.  
  110. END_PARA:      MOV    BYTE PTR DS:[SI-1],0   ;Convert parameter to ASCIIZ.
  111.                POP    DX                     ;Retrieve start.
  112.                DEC    DX                     ;Adjust.
  113.                MOV    AH,3BH                 ;Change directory.
  114.                INT    21H
  115.                MOV    DX,OFFSET INVALID      ;Exit if invalid parameter.
  116.                JNC    APPEND
  117.                JMP    ERROR_EXIT
  118.  
  119. APPEND:        MOV    SI,80H                 ;Get default directory.
  120.                CALL   GET_DIR
  121.                CLD
  122. NEXT_END:      LODSB                         ;Find end.
  123.                CMP    AL,0
  124.                JNZ    NEXT_END
  125.                DEC    SI
  126.                STD                           ;Reverse direction.
  127. NEXT_START:    AND    BYTE PTR [SI],5FH      ;Capitalize.
  128.                LODSB
  129.                CMP    AL,'\'                 ;Look for last path.
  130.                JNZ    NEXT_START
  131.                CLD                           ;Back to forward direction.
  132.                INC    SI
  133.                INC    SI
  134.                MOV    DI,OFFSET DIRNOTES+5   ;Insert three characters of path
  135.                MOV    CX,3                   ; into filename, DIRN----.DAT
  136. STORE_PATH:    CMP    BYTE PTR [SI],0
  137.                JZ     DISPLAY
  138.                MOVSB
  139.                LOOP   STORE_PATH
  140.  
  141. ;---------------------------------------------------------------------;
  142. ; More housekeeping. We will be writing directly to the screen buffer ;
  143. ; so we need the display card address and the status register.        ;
  144. ;---------------------------------------------------------------------;
  145.  
  146. DISPLAY:       MOV    AX,40H           ;Point to the ROM BIOS data area
  147.                MOV    DS,AX            ; and get base address of active
  148.                MOV    AX,DS:[63H]      ; display card.
  149.                ADD    AX,6             ;Add six to get status register
  150.                PUSH   CS               ;Done there, so restore data segment.
  151.                POP    DS
  152.                MOV    STATUS_REG,AX    ;Store status register.
  153.                CMP    AX,3BAH          ;Status port of MONO card is 3BAh.
  154.                JZ     MESSAGE          ;If that's what we got, it's MONO
  155.                MOV    VIDEO_SEG,0B800H       ; else COLOR so add 800h.
  156.                XOR    BH,BH                  ;Get current attribute
  157.                MOV    AH,8                   ; of display page zero.
  158.                INT    10H
  159.                MOV    NORMAL,AH              ;Store it.
  160.                XOR    AH,1110111B            ;Flip color bits.
  161.                MOV    INVERSE,AH             ;Save it.
  162.  
  163. MESSAGE:       CALL   CLS
  164.                MOV    SI,OFFSET LOADING      ;Display loading message.
  165.                MOV    DX,0C15H
  166.                CALL   DISPLAY_TEXT
  167.  
  168.                MOV    DI,OFFSET BUFFER       ;Fill buffer with spaces.
  169.                MOV    CX,30000
  170.                MOV    AX,2020H
  171.                REP    STOSW
  172.  
  173. ;------------------------------------------------------------------;
  174. ; Read all the directory filenames and store as records in buffer. ;
  175. ;------------------------------------------------------------------;
  176.  
  177. READ_DIR:      MOV    DX,OFFSET STAR_DOT_STAR
  178.                MOV    CX,6
  179.                MOV    AH,4EH                 ;Find first matching.
  180.                INT    21H
  181.                JNC    STORE_NAME
  182.                JMP    EXIT                   ;If empty directory, exit.
  183.  
  184. STORE_NAME:    MOV    DI,OFFSET BUFFER       ;Set up pointers and store
  185.                MOV    BP,60000               ; first filename.
  186.                CALL   BUFFER_NAME
  187.  
  188. FIND_NEXT:     MOV    AH,4FH                 ;Find next matching.
  189.                INT    21H
  190.                JC     STORE_COUNT            ;If carry, no more names.
  191.                INC    COUNT                  ;Inc count of names.
  192.                CALL   BUFFER_NAME
  193.                CMP    DI,BP                  ;Are we encroaching stack?
  194.                JB     FIND_NEXT              ;If no, find next.
  195.                MOV    DX,OFFSET TOO_MANY     ;Else, exit with message.
  196.                JMP    ERROR_EXIT
  197.  
  198. ;---------------------------------------------;
  199. ; Store buffer end address and page end,      ;
  200. ; number of files then alphabetize filenames. ;
  201. ;---------------------------------------------;
  202.  
  203. STORE_COUNT:   MOV    END_OFFSET,DI          ;Store ending offset.
  204.                MOV    BX,COUNT
  205.  
  206.                MOV    AX,BX
  207.                MOV    CL,10                  ;Convert to decimal.
  208.                STD                           ;Reverse direction.
  209.                MOV    DI,OFFSET FILES+2      ;Point to storage.
  210. NEXT_COUNT:    DIV    CL
  211.                XCHG   AL,AH
  212.                ADD    AL,'0'                 ;Convert to ASCII.
  213.                STOSB                         ;Store the remainder.
  214.                XCHG   AL,AH
  215.                XOR    AH,AH
  216.                CMP    AX,0                   ;Are we done?
  217.                JNZ    NEXT_COUNT
  218.  
  219.                CLD                           ;Back to forward direction.
  220.                CMP    BX,20                  ;Enough to file one page?
  221.                JA     SORT                   ;If yes, use default setting.
  222.                MOV    AX,160                 ;Else, calculate last record.
  223.                MUL    BL
  224.                ADD    AX,183H                ;*B Add bar offset.
  225.                MOV    PAGE_END,AX
  226.                CMP    BX,1                   ;Skip sort if only one filename.
  227.                JZ     OPEN_FILE
  228.  
  229. SORT:          MOV    DX,END_OFFSET          ;End of filenames in DX.
  230.                SUB    DX,81
  231. NEXT_PASS:     MOV    BP,0
  232.                MOV    BX,OFFSET BUFFER       ;Point to start of buffer.
  233.  
  234. NEXT_SORT:     MOV    SI,BX                  ;Put in source and destination
  235.                MOV    DI,BX                  ; registers.
  236.                ADD    DI,81
  237.                MOV    CX,12
  238.                REPZ   CMPSB                  ;Compare filenames.
  239.                JBE    END_SORT               ;If already in order, skip.
  240.  
  241.                MOV    SI,BX                  ;Else, recover pointers.
  242.                MOV    DI,BX
  243.                ADD    DI,81
  244.                MOV    CX,40                  ;Exchange the records.
  245. NEXT_SWAP:     MOV    AX,[DI]
  246.                MOVSW
  247.                MOV    [SI-2],AX
  248.                LOOP   NEXT_SWAP
  249.                MOV    BP,1                   ;Flag that exchange was made.
  250.  
  251. END_SORT:      ADD    BX,81                  ;Point to next record.
  252.                CMP    BX,DX                  ;End of top?
  253.                JB     NEXT_SORT              ;If no, bubble sort next.
  254.                CMP    BP,0                   ;Was there exchange made?
  255.                JZ     OPEN_FILE              ;If no, done here.
  256.                SUB    DX,81                  ;Else, move top down one record.
  257.                JMP    SHORT NEXT_PASS
  258.  
  259. ;-------------------------------;
  260. ; Attempt to read old dirnotes. ;
  261. ;-------------------------------;
  262.  
  263. OPEN_FILE:     MOV    DX,OFFSET DIRNOTES     ;Open DIRNOTES
  264.                MOV    AX,3D00H               ; for reading.
  265.                INT    21H
  266.                JC     READY                  ;If not found, skip to display.
  267.  
  268.                MOV    BX,AX
  269.                PUSH   BX                     ;Save filehandle.
  270. READ_FILE:     POP    BX
  271.                PUSH   BX
  272.                MOV    DX,60000               ;Point above directory listing.
  273.                MOV    CX,37*81               ;Read up to 37 records at a time.
  274.                MOV    AH,3FH
  275.                INT    21H
  276.  
  277.                CMP    AX,0                   ;End of file?
  278.                JZ     CLOSE_FILE             ;If yes, done here.
  279.                ADD    DX,AX
  280.                MOV    DI,DX                  ;Else, point to end and tack
  281.                MOV    BYTE PTR [DI],1AH      ; on Ctrl Z as end signature.
  282.                CMP    AX,37*81               ;Was it a full read?
  283.                JZ     FORM_NAME              ;If yes, reformat filename.
  284.                MOV    EOF_FLAG,1             ;Else, flag as end of file.
  285.                                              ;B*
  286. FORM_NAME:     CALL   RBBS_DIRN              ;B* reformat filename.
  287.  
  288. ;-------------------------------------------------------;
  289. ; Here we will match old DIRNOTES with new directory    ;
  290. ; listing. Notes for deleted files will not find match. ;
  291. ;-------------------------------------------------------;
  292.  
  293. COMPARE:       MOV    BP,OFFSET BUFFER       ;Point to first record.
  294. NEXT_FILE:     MOV    BX,60000               ;Point to read buffer.
  295. NEXT_MATCH:    MOV    SI,BX                  ;Set up source and destination.
  296.                MOV    DI,BP
  297.                MOV    CX,6                   ;Filename with extension.
  298.                REPZ   CMPSW                  ;Compare all 12 characters.
  299.                JNZ    END_NOTE               ;Skip if no match.
  300.                ADD    SI,20                  ;B*  else point to note.
  301.                ADD    DI,20                  ;B*
  302.                MOV    CX,24                  ;B*
  303.                REP    MOVSW                  ;Store note.
  304.  
  305.                SUB    SI,67
  306.                SUB    DI,67
  307.                MOV    CX,9                   ;B*
  308.                REPZ   CMPSW                  ;Has size or date changed?
  309.                JNZ    END_MATCH
  310.                MOV    BYTE PTR [BP+31],32    ;B* If yes, remove "U".
  311.                JMP    SHORT END_MATCH        ;Skip rest and go to next record.
  312.  
  313. END_NOTE:      ADD    BX,81                  ;Point to next record.
  314.                CMP    BYTE PTR DS:[BX],1AH   ;Are we at the end?
  315.                JNZ    NEXT_MATCH             ;If no, compare.
  316. END_MATCH:     ADD    BP,81                  ;Point to next record.
  317.                CMP    BYTE PTR DS:[BP],32    ;End of directory listing?
  318.                JNZ    NEXT_FILE              ;If no, check for matches.
  319.                CMP    EOF_FLAG,1             ;Else, end of file?
  320.                JNZ    READ_FILE              ;If no, read more.
  321.  
  322. CLOSE_FILE:    POP    BX
  323.                MOV    AH,3EH                 ;Close file.
  324.                INT    21H
  325.  
  326. ;--------------------------------------------;
  327. ; Now, we are ready to initialize the screen ;
  328. ;--------------------------------------------;
  329.  
  330. READY:         MOV    AX,VIDEO_SEG           ;Initialize video segment.
  331.                MOV    ES,AX
  332.                MOV    DX,4                   ;Row 0; column 3.
  333.                MOV    SI,OFFSET DIRECTORY    ;Display "Directory ".
  334.                CALL   DISPLAY_TEXT
  335.                MOV    AH,19H
  336.                INT    21H                    ;Get drive.
  337.                ADD    AL,'A'                 ;Convert to ASCII.
  338.                CALL   WRITE_TEXT             ;Display it.
  339.                MOV    AL,':'                 ;Add colon.
  340.                CALL   WRITE_TEXT
  341.                MOV    SI,80H                 ;Get directory.
  342.                CALL   GET_DIR
  343.                DEC    SI
  344.                CALL   GET_TEXT               ;Write it as well.
  345.                MOV    DX,180EH               ;Row 24; column 13.
  346.                MOV    SI,OFFSET FILES        ;Display file count.
  347.                CALL   DISPLAY_TEXT
  348.                MOV    DX,1833H               ;Row 24; column 50.
  349.                MOV    SI,OFFSET STATUS_LINE  ;Display "Press Esc to exit".
  350.                CALL   DISPLAY_TEXT
  351.                MOV    LINE,183H              ;B* Initialize cursor position.
  352.                MOV    BL,INVERSE             ;Put up cursor bar.
  353.                CALL   BAR
  354.                CALL   UPDATE_SCREEN          ;Display directory listing.
  355.                MOV    CURS_POS,221H          ;B* Initialize cursor position.
  356.                MOV    AH,03                  ;*A
  357.                MOV    BH,0                   ;*A
  358.                INT    10H                    ;*A Get original cursor size
  359.                MOV    CURSOR_ORG,CX          ;*A
  360.                CALL   SET_CUR_SIZE           ;*A Set cursor size
  361.  
  362. ;-----------------------------------------;
  363. ; We are ready for business now. We will  ;
  364. ; loop here, waiting for user keystrokes. ;
  365. ;-----------------------------------------;
  366.  
  367. GET_KEY:       CALL   SET_CURSOR             ;Update cursor position.
  368.                MOV    AH,0                   ;Wait for
  369.                INT    16H                    ;keystroke.
  370.  
  371. ASCII:         CMP    AL,32                  ;Is it space or above?
  372.                JB     CR                     ;If no, skip.
  373.                CMP    BYTE PTR CURS_POS,79   ;End of line?  Line: 42-79 physical
  374.                JZ     GET_KEY                ;If yes, skip.       41-78 logical
  375.                CMP    INS_FLAG, 1            ;Insert mode on?          *A
  376.                JNZ    WRT_ASCII              ;Jmp if not               *A
  377.                CALL   PUSHEM_OUT             ;Else push out characters *A
  378. WRT_ASCII:     CALL   STORE_CHAR             ;Else, store the ASCII character.
  379.                INC    BYTE PTR CURS_POS      ;Update cursor (points to next loc).
  380.                JMP    SHORT GET_KEY
  381.  
  382. CR:            CMP    AH,1CH                 ;Is it carriage return?
  383.                JNZ    BS
  384.                MOV    BYTE PTR CURS_POS,33   ;B* Cursor to beginning of line.
  385.                JMP    SCROLL_DOWN      ; and scroll down.
  386.  
  387. BS:            CMP    AH,0EH                 ;Backspace?
  388.                JNZ    TAB
  389.                CMP    BYTE PTR CURS_POS,33   ;B* Are we already at beginning?
  390.                JZ     GET_KEY                ;If yes, skip.
  391.                DEC    BYTE PTR CURS_POS      ;Else, cursor left one.
  392.                MOV    AL,32                  ;And replace with space.
  393.                CALL   STORE_CHAR
  394.                JMP    SHORT GET_KEY
  395.  
  396. TAB:           CMP    AH,0FH                 ;Tab?  *A
  397.                JNZ    LEFT_ARROW
  398.                CMP    AL,00H
  399.                JZ     SHFT_TAB
  400.                CMP    BYTE PTR CURS_POS,79   ;Are we already end of line?
  401.                JZ     GET_KEY
  402.                ADD    BYTE PTR CURS_POS,5    ;Cursor right.
  403.                CMP    BYTE PTR CURS_POS,79   ;Are we past end of line?
  404.                JBE    EXIT_TAB
  405.                MOV    BYTE PTR CURS_POS,79
  406. EXIT_TAB:      JMP    SHORT GET_KEY
  407.  
  408. SHFT_TAB:                                    ;Sh-Tab?  *A
  409.                CMP    BYTE PTR CURS_POS,33   ;B* Are we already start of line?
  410.                JZ     GET_KEY
  411.                SUB    BYTE PTR CURS_POS,5    ;Cursor left.
  412.                CMP    BYTE PTR CURS_POS,33   ;B* Are we before start of line?
  413.                JAE    EXIT_SH_TAB            ;Jump if not
  414.                MOV    BYTE PTR CURS_POS, 33  ;B*
  415. EXIT_SH_TAB:   JMP    GET_KEY
  416.  
  417. LEFT_ARROW:    CMP    AH,4BH                 ;Left arrow?
  418.                JNZ    RIGHT_ARROW
  419.                CMP    BYTE PTR CURS_POS,33   ;B* Are we already home position?
  420.                JZ     LEFT_EXIT
  421.                DEC    BYTE PTR CURS_POS      ;If no, back cursor up one.
  422. LEFT_EXIT:     JMP    GET_KEY
  423.  
  424. RIGHT_ARROW:   CMP    AH,4DH                 ;Right arrow?
  425.                JNZ    CTL_LFT_ARR
  426.                CMP    BYTE PTR CURS_POS,79   ;Are we already end of line?
  427.                JZ     SKIP_CHK
  428.                INC    BYTE PTR CURS_POS      ;Cursor right one.
  429. SKIP_CHK:      JMP    GET_KEY
  430.  
  431. CTL_LFT_ARR:   CMP    AH,73H                 ;^Left arrow?
  432.                JNZ    CTL_RT_ARR
  433.                INC    BYTE PTR CURS_POS
  434. CHAR_L:        CALL   LOOPER_LEFT
  435.                JAE    CHAR_L
  436. NON_CHAR_L:    CALL   LOOPER_LEFT
  437.                JB     NON_CHAR_L
  438. CHAR_L2:       CALL   LOOPER_LEFT
  439.                JAE    CHAR_L2
  440.                INC    BYTE PTR CURS_POS
  441. EXIT_CTL_L:    JMP    GET_KEY
  442.  
  443. LOOPER_LEFT:
  444.                CMP    BYTE PTR CURS_POS,33   ;B*
  445.                JZ     EXIT_CTL_L
  446.                DEC    BYTE PTR CURS_POS
  447.                CALL   GET_CHAR
  448.                CMP    BL,48
  449.                RET
  450.  
  451. CTL_RT_ARR:    CMP    AH,74H                 ;^Right arrow? *A
  452.                JNZ    UP_ARROW
  453.                DEC    BYTE PTR CURS_POS
  454. CHAR_R:        CALL   LOOPER_RT
  455.                JAE    CHAR_R
  456.                MOV    BH,BYTE PTR CURS_POS   ;Location of last non_char (space)
  457. NON_CHAR_R:    CALL   LOOPER_RT
  458.                JB     NON_CHAR_R
  459. CHK_END:       CMP    BYTE PTR CURS_POS,79
  460.                JB     EXIT_CTL_R1
  461.                DEC    BYTE PTR CURS_POS      ;Point to last logical char
  462.                CALL   GET_CHAR
  463.                CMP    BL,32
  464.                JNZ    EXIT_CTL_R0
  465.                INC    BH
  466.                MOV    BYTE PTR CURS_POS,BH
  467. FIND_CHAR:     CALL   LOOPIT_LEFT
  468.                JZ     FIND_CHAR
  469. EXIT_CTL_R0:   INC    BYTE PTR CURS_POS
  470. EXIT_CTL_R1:   JMP    GET_KEY
  471.  
  472. LOOPER_RT:     CMP    BYTE PTR CURS_POS,79
  473.                JZ     CHK_END
  474.                INC    BYTE PTR CURS_POS
  475.                CALL   GET_CHAR
  476.                CMP    BL,48
  477.                RET
  478.  
  479. LOOPIT_LEFT:
  480.                CMP    BYTE PTR CURS_POS,33   ;B*
  481.                JZ     EXIT_CTL_R1
  482.                DEC    BYTE PTR CURS_POS
  483.                CALL   GET_CHAR
  484.                CMP    BL,32
  485.                RET
  486.  
  487. UP_ARROW:      CMP    AH,48H                 ;Up arrow?
  488.                JNZ    DN_ARROW
  489.                MOV    BP,-160                ;If yes, move bar up one line.
  490.                MOV    DX,0FF00H              ;And also the cursor.
  491.                CALL   SCROLL_BAR
  492.                JMP    GET_KEY
  493.  
  494. DN_ARROW:      CMP    AH,50H                 ;Down arrow?
  495.                JNZ    HOME
  496. SCROLL_DOWN:   MOV    BP,160                 ;If yes, move cursor and bar down.
  497.                MOV    DX,100H
  498.                CALL   SCROLL_BAR
  499.                JMP    GET_KEY
  500.  
  501. HOME:          CMP    AH,47H                 ;Home key?  *A
  502.                JNZ    END_KEY
  503. SET_MIN_POS:   MOV    BYTE PTR CURS_POS, 33  ;B*
  504.                JMP    GET_KEY
  505.  
  506. END_KEY:       CMP    AH,4FH                 ;End key?   *A
  507.                JNZ    PG_UP
  508. SET_END_POS:   MOV    BYTE PTR CURS_POS, 79
  509. LOOP_END_POS:  CMP    BYTE PTR CURS_POS, 33  ;B*
  510.                JZ     EXIT_END_POS
  511.                DEC    BYTE PTR CURS_POS
  512.                CALL   GET_CHAR
  513.                CMP    BL,32
  514.                JZ     LOOP_END_POS
  515.                INC    BYTE PTR CURS_POS
  516. EXIT_END_POS:  JMP    GET_KEY
  517.  
  518. PG_UP:         CMP    AH,49H                 ;Page up?
  519.                JNZ    PG_DN
  520.                MOV    BP,-81*21              ;If yes, move up 21 lines.
  521.                CALL   SCROLL
  522.                JMP    SHORT BOTTOM_BAR       ;And move bar to bottom.
  523.  
  524. PG_DN:         CMP    AH,51H                 ;Page down?
  525.                JNZ    CTRL_PG_UP
  526.                MOV    BP,81*21               ;If yes, move down 21 lines.
  527.                CALL   SCROLL
  528.                JMP    SHORT TOP_BAR          ;And move bar to top.
  529.  
  530. CTRL_PG_UP:    CMP    AH,84H                 ;Ctrl PgUp?
  531.                JNZ    CTRL_PG_DN
  532. TOP_BAR:       MOV    SI,183H                ;B* If yes, move bar to top.
  533.                MOV    CURS_POS,221H          ;B*
  534.                JMP    SHORT UPDATE_BAR
  535.  
  536. CTRL_PG_DN:    CMP    AH,76H                 ;Ctrl PgDn?
  537.                JNZ    CTRL_HOME
  538. BOTTOM_BAR:    MOV    SI,PAGE_END            ;If yes, move bar to bottom.
  539.                MOV    AX,SI                  ;Divide page end by 160
  540.                SUB    SI,160                 ; to get cursor row position.
  541.                SUB    AX,183H-160            ;B*
  542.                XOR    DX,DX
  543.                MOV    BX,160
  544.                DIV    BX
  545.                MOV    DH,AL
  546.                MOV    DL,21H                 ;B*
  547.                MOV    CURS_POS,DX
  548. UPDATE_BAR:    CALL   MOVE_BAR               ;Display updates.
  549.                CALL   SET_CURSOR
  550.                CALL   UPDATE_SCREEN
  551.                JMP    NEXT_KEY
  552.  
  553. CTRL_HOME:     CMP    AH,77H                     ;^Home?  *A
  554.                JNZ    CTRL_END
  555.                MOV    CUR_OFFSET,OFFSET BUFFER   ;If yes, move listing and
  556.                JMP    SHORT TOP_BAR              ; bar to top.
  557.  
  558. CTRL_END:      CMP    AH,75H                 ;^End? *A
  559.                JNZ    INS_KEY
  560.                MOV    BX,END_OFFSET          ;If yes, move listing and
  561.                SUB    BX,81*21               ; bar to bottom.
  562.                CMP    BX,OFFSET BUFFER
  563.                JBE    BOTTOM_BAR
  564.                MOV    CUR_OFFSET,BX
  565.                JMP    SHORT BOTTOM_BAR
  566.  
  567. INS_KEY:       CMP    AH,52H                 ;Insert?  *A
  568.                JNZ    DEL
  569.                XOR    BYTE PTR INS_FLAG,1
  570.                CALL   SET_CUR_SIZE
  571.                JMP    GET_KEY
  572.  
  573. DEL:           CMP    AH,53H                 ;Del?  *A
  574.                JNZ    CTRL_T
  575.                CALL   DEL_CHAR
  576.                JMP    GET_KEY
  577.  
  578. CTRL_T:        CMP    AH,14H                 ;Ctrl T? *A
  579.                JNZ    CTRL_Y
  580.                MOV    BH,80
  581.                SUB    BH,BYTE PTR CURS_POS
  582.                CALL   GET_CHAR
  583.                CMP    BL,32
  584.                JZ     DEL_A_SPACE
  585. DEL_A_CHAR:    DEC    BH
  586.                CMP    BH,0
  587.                JZ     EXIT_T
  588.                CALL   DEL_CHAR
  589.                CALL   GET_CHAR
  590.                CMP    BL,32
  591.                JNZ    DEL_A_CHAR
  592. DEL_A_SPACE:   DEC    BH
  593.                CMP    BH,0
  594.                JZ     EXIT_T
  595.                CALL   DEL_CHAR
  596.                CALL   GET_CHAR
  597.                CMP    BL,32
  598.                JZ     DEL_A_SPACE
  599. EXIT_T:        JMP    GET_KEY
  600.  
  601. CTRL_Y:        CMP    AH,15H                 ;Ctrl-Y?  *A
  602.                JNZ    ALT_C
  603.                MOV    BYTE PTR CURS_POS,33   ;B*
  604.                MOV    BH, 39
  605. EXIT_DEL_CHR:  CALL   DEL_CHAR
  606.                DEC    BH
  607.                CMP    BH,0
  608.                JNZ    EXIT_DEL_CHR
  609.                JMP    GET_KEY
  610.  
  611. ALT_C:         CMP    AH,2EH                 ;Alt-C?  *B
  612.                JNZ    ESC
  613. SET_CAT_POS:   MOV    BYTE PTR CURS_POS, 76
  614.                JMP    GET_KEY
  615.  
  616. ESC:           CMP    AH,1                   ;Esc?
  617.                JNZ    NEXT_KEY
  618.                JMP    EXIT                   ;If yes, exit.
  619.  
  620. NEXT_KEY:      JMP    GET_KEY
  621.  
  622.                 ;*************;
  623.                 ; SUBROUTINES ;
  624.                 ;*************;
  625.  
  626. ;--------------------------------------;
  627. ; This subroutine sets the cursor size ;
  628. ;--------------------------------------;
  629.  
  630. SET_CUR_SIZE:
  631.                CMP    BYTE PTR INS_FLAG,1
  632.                JZ     INSERT_ON
  633.                MOV    CX,CURSOR_ORG
  634.                JMP    DO_TEN
  635. INSERT_ON:     MOV    CX,080CH
  636. DO_TEN:        MOV    AH,01H
  637.                INT    10H
  638.                RET
  639.  
  640. ;-------------------------------------;
  641. ; This subroutine scrolls the screen. ;
  642. ;-------------------------------------;
  643.  
  644. SCROLL:        MOV    SI,CUR_OFFSET          ;Get current offset.
  645.                ADD    SI,BP                  ;Add requested direction.
  646.                JNS    CK_LOWER               ;If signed and PgUp request
  647.                CMP    BP,-81*21              ; then below start.
  648.                JZ     LOWER_LIMIT
  649. CK_LOWER:      CMP    SI,OFFSET BUFFER       ;If above start check upper limit.
  650.                JAE    UPPER_LIMIT
  651. LOWER_LIMIT:   MOV    CUR_OFFSET,OFFSET BUFFER    ;Else, make it start.
  652.                JMP    SHORT UPDATE                ;And update screen.
  653.  
  654. UPPER_LIMIT:   MOV    BX,END_OFFSET               ;See if beyond end of
  655.                CMP    BX,OFFSET BUFFER+21*81      ; directory listing as well.
  656.                JA     CK_UPPER
  657.                MOV    CUR_OFFSET,OFFSET BUFFER
  658.                JMP    SHORT UPDATE
  659.  
  660. CK_UPPER:      SUB    BX,21*81
  661.                CMP    SI,BX
  662.                JBE    END_SCROLL
  663.                MOV    SI,BX
  664.  
  665. END_SCROLL:    MOV    CUR_OFFSET,SI          ;Update current offset.
  666. UPDATE:        CALL   UPDATE_SCREEN
  667.                RET
  668.  
  669. ;--------------------------------------------------;
  670. ; This subroutine scrolls the bar if between start ;
  671. ; and end of page. Otherwise the page is scrolled. ;
  672. ;--------------------------------------------------;
  673.  
  674. SCROLL_BAR:    MOV    SI,LINE                ;Get current line.
  675.                ADD    SI,BP                  ;Add requested line.
  676.                MOV    BP,-81                 ;Assume below beginning.
  677.                CMP    SI,183H                ;B* Is it?
  678.                JB     SCROLL_PAGE            ;If yes, scroll page instead.
  679.                MOV    BP,81                  ;Do the same for end of page.
  680.                CMP    SI,PAGE_END
  681.                JAE    SCROLL_PAGE
  682.                ADD    CURS_POS,DX            ;If in range, update cursor
  683.                CALL   MOVE_BAR               ; and bar position.
  684.                RET
  685.  
  686. SCROLL_PAGE:   CALL   SCROLL
  687.                RET
  688.  
  689. ;----------------------------------------------------;
  690. ; This subroutine does the actual moving of the bar. ;
  691. ;----------------------------------------------------;
  692.  
  693. MOVE_BAR:      MOV    BL,NORMAL              ;Remove old bar.
  694.                CALL   BAR
  695.                MOV    LINE,SI                ;And move bar to new line.
  696.                MOV    BL,INVERSE
  697.                CALL   BAR
  698.                RET
  699.  
  700. BAR:           MOV    DI,LINE                ;Retrieve line.
  701.                MOV    BH,46                  ;B* Bar length 47.
  702.                MOV    DX,STATUS_REG
  703. NEXT_BAR:      MOV    CX,1                   ;Write one character at a time.
  704.                CALL   HORZ_RET
  705.                DEC    BH
  706.                JNZ    NEXT_BAR
  707.                RET
  708.  
  709. ;----------------------------------------------;
  710. ; This subroutine stores the ASCII characters. ;
  711. ;    AL = character to store                   ;
  712. ;----------------------------------------------;
  713.  
  714. STORE_CHAR:
  715.                CALL   GET_CHAR_LOC           ;*A
  716.                MOV    [SI],AL                ;Store it.
  717.                MOV    CX,1                   ;Write one character
  718.                CALL   WRITE_SCREEN           ;Display by updating screen.
  719.                MOV    UPDATE_FLAG,1          ;Flag as updated so file will
  720.                RET                           ; be written upon Esc.
  721.  
  722. ;------------------------------------------------;
  723. ; This subroutine retrieves the ASCII character. ;
  724. ;    BL = character to retrieve                  ;
  725. ;------------------------------------------------;
  726.  
  727. GET_CHAR:      CALL   GET_CHAR_LOC           ;*A
  728.                MOV    BL,DS:[SI]             ;Retrieve it.
  729.                RET                           ;
  730.  
  731. ;------------------------------------------------;
  732. ; This subroutine deletes an ASCII character.    ; *A
  733. ;------------------------------------------------;
  734.  
  735. DEL_CHAR:
  736.                CMP    BYTE PTR CURS_POS,79       ; Past last char?
  737.                JAE    EXIT_DEL_CHAR              ; Skip del if so, else
  738.                MOV    AX, CURS_POS               ;
  739.                PUSH   AX                         ; Save cursor position
  740. NEXTDEL:       INC    BYTE PTR CURS_POS          ; Point to next position
  741.                CMP    BYTE PTR CURS_POS,79       ; Is it past the last char?
  742.                JB     GETIT                      ; Jump if not
  743.                MOV    AL,32                      ; else fill last char with a space
  744.                JMP    MOVIT
  745. GETIT:         CALL   GET_CHAR                   ; Get char at next location
  746.                MOV    AL,BL                      ; mov it into AL
  747. MOVIT:         DEC    BYTE PTR CURS_POS          ; Point to current del char
  748.                CALL   STORE_CHAR                 ; Put new char there and show it
  749.                INC    BYTE PTR CURS_POS          ; Point to next del position
  750.                CMP    BYTE PTR CURS_POS,79       ; Past the last char yet?
  751.                JB     NEXTDEL                    ; No, continue processing
  752.                POP    AX                         ; Yes, restore old cursor position
  753.                MOV    CURS_POS,AX
  754. EXIT_DEL_CHAR: RET
  755.  
  756. ;------------------------------------------------;
  757. ; This subroutine push out trailing characters   ; *A
  758. ;------------------------------------------------;
  759.  
  760. PUSHEM_OUT:
  761.                CMP    BYTE PTR CURS_POS,78       ; At or past last valid char?
  762.                JAE    PUSH_RET                   ; Yes, Can't push any further
  763.                PUSH   AX                         ; Save current charcter
  764.                MOV    AX, CURS_POS               ;
  765.                PUSH   AX                         ; Save cursor position
  766.                MOV    BYTE PTR CURS_POS,78       ;
  767. NEXTADD:
  768.                POP    AX                         ; Restore cursor postion
  769.                DEC    BYTE PTR CURS_POS          ; Backup one character
  770.                CMP    BYTE PTR CURS_POS,AL       ; Is it prior to start loc?
  771.                PUSH   AX
  772.                JB     PUSH_RESTORE               ; Jump if not
  773.                CALL   GET_CHAR                   ; and get char at that location
  774.                MOV    AL,BL                      ; mov it into AL
  775.                INC    BYTE PTR CURS_POS          ; Point to next char
  776.                CALL   STORE_CHAR                 ; Put previous char there and show it
  777.                DEC    BYTE PTR CURS_POS          ; Backup one character
  778.                JMP    NEXTADD
  779. PUSH_RESTORE:
  780.                POP    AX
  781.                MOV    CURS_POS,AX
  782.                POP    AX
  783. PUSH_RET:      RET
  784.  
  785.  
  786. ;----------------------------------------------------------------; *A
  787. ; This subroutine causes [SI] to point to the current character  ;
  788. ;   Destroyed: CX,DL                                             ;
  789. ;----------------------------------------------------------------;
  790.  
  791. GET_CHAR_LOC:                                ;
  792.                PUSH   AX                     ;Save AX.
  793.                MOV    SI,CUR_OFFSET          ;Retrieve current starting offset.
  794.                MOV    AX,CURS_POS            ;Retrieve cursor position.
  795.                MOV    CX,AX                  ;Save it.
  796.                MOV    AL,AH
  797.                XOR    AH,AH                  ;Isolate row.
  798.                DEC    AX                     ;Adjust for offset.
  799.                DEC    AX
  800.                ADD    SI,AX                  ;Add to source.
  801.                MOV    DL,80                  ;Multiply by 80.
  802.                MUL    DL
  803.                ADD    SI,AX                  ;Add to source.
  804.                MOV    DI,AX                  ;DI is screen offset.
  805.                SHL    DI,1                   ;Adjust for attribute.
  806.                ADD    DI,2*160               ;Adjust for starting in row 3.
  807.                XOR    CH,CH                  ;Isolate column.
  808.                ADD    SI,CX                  ;Add column to offset.
  809.                SHL    CX,1                   ;Double for screen offset.
  810.                ADD    DI,CX                  ;Add it.  = screen offset
  811.                POP    AX                     ;Retrieve AX.
  812.                RET
  813.  
  814.  
  815. ;---------------------------------------------------;
  816. ; This subroutine writes the listing to the screen. ;
  817. ;---------------------------------------------------;
  818.  
  819. UPDATE_SCREEN: MOV    SI,CUR_OFFSET          ;Retrieve starting offset.
  820.                MOV    DI,2*160               ;Point to row three of screen.
  821.                MOV    BH,21                  ;21 lines to write.
  822. NEXT_WRITE:    MOV    CX,79                  ;79 characters per line.
  823.                CALL   WRITE_SCREEN           ;Write them.
  824.                ADD    SI,2                   ;Bump pointer past cr/lf.
  825.                ADD    DI,2                   ;Bump pointer to next line.
  826.                DEC    BH                     ;Do all 21 lines.
  827.                JNZ    NEXT_WRITE
  828.                RET
  829.  
  830. ;------------------------------------------------------------;
  831. ; This subroutine displays the directory by writing directly ;
  832. ; to the screen buffer. To avoid screen noise (snow) on the  ;
  833. ; color card, the horizontal retrace has to be monitored.    ;
  834. ;   CX = number of characters to write (79 max)              ;
  835. ;   DI = screen position                                     ;
  836. ;  Destroyed: BL, AL, DI                                     ;
  837. ;------------------------------------------------------------;
  838.  
  839. WRITE_SCREEN:
  840.                MOV    DX,STATUS_REG          ;Get status register.
  841. NEXT_BYTE:     LODSB                         ;Get a byte.
  842.                MOV    BL,AL                  ;Save it in BL.
  843.  
  844. HORZ_RET:      IN     AL,DX                  ;Get status.
  845.                TEST   AL,1                   ;Is it low?
  846.                JNZ    HORZ_RET               ;If not, wait until it
  847.                CLI                           ;No more interrupts.
  848.  
  849. WAIT:          IN     AL,DX                  ;Get status.
  850.                TEST   AL,1                   ;Is it high?
  851.                JZ     WAIT                   ;If no, wait until it is.
  852.                MOV    AL,BL                  ;Retrieve character; now it's OK
  853.                STOSB                         ; to write to screen buffer.
  854.                STI                           ;Interrupts back on.
  855.                INC    DI                     ;Bump pointer past attribute.
  856.                LOOP   NEXT_BYTE              ;Get next byte.
  857.                RET                           ;Return
  858.  
  859. ;------------------------------------;
  860. ; This subroutine clears the screen. ;
  861. ;------------------------------------;
  862.  
  863. CLS:           MOV    BH,NORMAL              ;Clear with original attribute.
  864.                XOR    CX,CX
  865.                MOV    DX,184FH               ;Entire screen.
  866.                MOV    AX,600H                ;Scroll active page.
  867.                INT    10H
  868.                RET                           ;Return.
  869.  
  870. ;-----------------------------------------;
  871. ; These subroutines display the messages. ;
  872. ;-----------------------------------------;
  873.  
  874. DISPLAY_TEXT:  MOV    CURS_POS,DX            ;Store requested cursor position.
  875.                CALL   SET_CURSOR             ;Move cursor.
  876. GET_TEXT:      LODSB
  877.                CMP    AL,0                   ;Zero marks end of string.
  878.                JZ     END_TEXT
  879.                CALL   WRITE_TEXT
  880.                JMP    SHORT GET_TEXT
  881. END_TEXT:      RET
  882.  
  883. WRITE_TEXT:    PUSH   SI                     ;BIOS does not save SI.
  884.                MOV    AH,0EH                 ;Write teletype
  885.                INT    10H
  886.                POP    SI
  887.                RET
  888.  
  889. ;----------------------------------------------------------------------;
  890. ; These two subroutines move the cursor and get the current directory. ;
  891. ;----------------------------------------------------------------------;
  892.  
  893. SET_CURSOR:    PUSH   SI                     ;Save SI pointer; BIOS doesn't.
  894.                MOV    DX,CURS_POS            ;Get requested cursor position.
  895.                XOR    BH,BH                  ;Page zero.
  896.                MOV    AH,2
  897.                INT    10H
  898.                POP    SI
  899.                RET
  900.  
  901. GET_DIR:       MOV    BYTE PTR [SI],'\'      ;DOS doesn't preface directory
  902.                INC    SI                     ; with slash so we must.
  903.                XOR    DL,DL
  904.                MOV    AH,47H                 ;Retrieve default directory.
  905.                INT    21H
  906.                RET
  907.  
  908. ;--------------------------------------------------;
  909. ; This long subroutine stores the filename in DIR  ;
  910. ; format. That is, filename, bytes, date and time. ;
  911. ;--------------------------------------------------;
  912.  
  913. BUFFER_NAME:   MOV    SI,158                 ;Point to filename.
  914.                MOV    CX,12                  ;Store 12 bytes of filename.
  915. NEXT_STORE:    LODSB                         ;Get a byte.
  916.                CMP    AL,0                   ;End of filename?
  917.                JZ     END_STORE              ;If yes, finish with blanks.
  918.                CMP    AL,'.'                 ;Is it the period?
  919.                JNZ    STORE_BYTE             ;If no, store.
  920.                SUB    CX,3                   ;Else store 3 spaces.
  921.                MOV    AL,32
  922.                REP    STOSB
  923.                ADD    CX,3
  924.                JMP    SHORT NEXT_STORE       ;Get next byte.
  925.  
  926. STORE_BYTE:    STOSB                         ;Store byte.
  927.                LOOP   NEXT_STORE             ;Get next byte.
  928. END_STORE:     MOV    AL,32                  ;Pad balance with spaces.
  929.                REP    STOSB
  930.  
  931. FILE_SIZE:     PUSH   DI                     ;Save pointer.
  932.                ADD    DI,8                   ;Move to end of bytes field.
  933.                MOV    DX,DS:[154]            ;Retrieve high and low words
  934.                MOV    AX,DS:[156]            ; of bytes.
  935.                MOV    BX,10                  ;Convert to decimal; divide by 10.
  936.                STD                           ;Reverse direction.
  937.  
  938. NEXT_SIZE:     MOV    CX,DX                  ;Low word in CX.
  939.                XOR    DX,DX                  ;Zero in high half.
  940.                DIV    BX                     ;Convert to decimal.
  941.                XCHG   AX,CX                  ;Retrieve low word.
  942.                DIV    BX
  943.                XCHG   AX,DX                  ;Retrieve remainder.
  944.                ADD    AL,'0'                 ;Convert to ASCII.
  945.                STOSB                         ;Store it.
  946.                MOV    AX,CX                  ;Are we done?
  947.                OR     CX,DX
  948.                JNZ    NEXT_SIZE              ;If no, divide again.
  949.  
  950.                CLD                           ;Back to forward direction.
  951.                POP    DI                     ;Retrieve pointer.
  952.                ADD    DI,11                  ;Move to date field.
  953. DATE:          MOV    DX,DS:[152]            ;Retrieve date.
  954.                MOV    AX,DX
  955.                MOV    CL,5                   ;Shift to lowest bits.
  956.                ROR    AX,CL
  957.                AND    AX,0FH                 ;Mask off all but month.
  958.                MOV    CL,0                   ;Flag include leading zeros.
  959.                MOV    CH,'-'                 ;Delimiting character.
  960.                CALL   STORE_WORD             ;Store it.
  961.  
  962.                MOV    AX,DX                  ;Retrieve date.
  963.                AND    AX,1FH                 ;Mask off all but day.
  964.                MOV    CL,0                   ;Flag include leading zeros.
  965.                MOV    CH,'-'
  966.                CALL   STORE_WORD             ;Store it.
  967.  
  968.                MOV    AX,DX                  ;Retrieve date for last time.
  969.                MOV    CL,9
  970.                ROR    AX,CL
  971.                AND    AX,7FH                 ;Mask off all but year.
  972.                ADD    AX,80                  ;Adjust to ASCII.
  973.                CMP    AX,100                 ;Past year 2000?
  974.                JB     DISPLAY_DATE           ;If no, display. Else, adjust for
  975.                SUB    AX,100                 ; next century. (Planning ahead!)
  976. DISPLAY_DATE:  MOV    CL,0                   ;Display leading zeros.
  977.                MOV    CH,'U'                 ;B* Assume for now all are updated
  978.                CALL   STORE_WORD             ;Store it.
  979.  
  980.                MOV    BYTE PTR [DI+47],13    ;Tack on carriage return linefeed.
  981.                MOV    BYTE PTR [DI+48],10
  982.                ADD    DI,49                  ;B* Move pointer past note field
  983.                RET                           ; to start of next record.
  984.  
  985. STORE_WORD:    DIV    BL                     ;Divide by ten.
  986.                ADD    AX,'00'                ;Convert to ASCII.
  987.                CMP    CL,0                   ;Are we to display leading zero?
  988.                JZ     STORE_IT               ;If yes, store as is.
  989.                CMP    AL,'0'                 ;Is it a leading zero?
  990.                JNZ    STORE_IT               ;If no, store it.
  991.                MOV    AL,32                  ;Else, store a space.
  992. STORE_IT:      STOSW
  993.                MOV    AL,CH                  ;Store delimiter character also.
  994.                STOSB
  995.                RET
  996.  
  997. ;---------------------------------------------------------;
  998. ; Here we will reformat the Filenames in the old DIRNOTES ;
  999. ; listing that have been added via an RBBS Upload.  The   ;
  1000. ; format change is from XXXXXXXX.XXX to XXXXXXXX XXX.     ;
  1001. ;---------------------------------------------------------;
  1002.                                              ;B*
  1003. RBBS_DIRN:     MOV    BX,60000               ;Point to read buffer.
  1004. NEXT_RBBS:     MOV    SI,BX                  ;Set up source and destination.
  1005.                CMP    BYTE PTR [SI+8],'.'
  1006.                JNE    CHECK_ALL              ;Skip if match.
  1007.                MOV    BYTE PTR [SI+8],32     ;Blank out the ".".
  1008.                JMP    END_RBBS
  1009. CHECK_ALL:     MOV    DI,OFFSET DOTS
  1010.                MOV    CX,12                  ;Filename with extension.
  1011.                REPNE  CMPSB                  ;Compare all 12 characters.
  1012.                JNE    END_RBBS               ;Skip if match.
  1013.  
  1014.                MOV    DI,BX                  ;Set up source and destination.
  1015.                MOV    BYTE PTR [SI-1],32     ;Blank out the ".".
  1016.                MOV    AL, BYTE PTR [SI+2]    ;Move the last 3 chars of the   
  1017.                MOV    BYTE PTR [DI+11], AL   ; qualifier to the end of the name 
  1018.                MOV    BYTE PTR [SI+2],32     ; field and blank the source
  1019.                MOV    AL, BYTE PTR [SI+1]
  1020.                MOV    BYTE PTR [DI+10], AL
  1021.                MOV    BYTE PTR [SI+1],32
  1022.                MOV    AL, BYTE PTR [SI]
  1023.                MOV    BYTE PTR [DI+9], AL
  1024.                MOV    BYTE PTR [SI],32
  1025.  
  1026. END_RBBS:      ADD    BX,81                  ;Point to next record.
  1027.                CMP    BYTE PTR DS:[BX],1AH   ;Are we at the end?
  1028.                JNZ    NEXT_RBBS              ;If no, compare.
  1029.                RET
  1030.  
  1031. ;-----------------------------------------------------------------;
  1032. ; This is the exit routines. Check if notes have been updated.    ;
  1033. ; If yes, write the file. Return to original drive and directory. ;
  1034. ;-----------------------------------------------------------------;
  1035.  
  1036. ERROR_EXIT:    MOV    AH,9                   ;Display error message.
  1037.                INT    21H
  1038.                CALL   RESTORE_PATH           ;Restore path.
  1039.                INT    20H                    ;Exit.
  1040.  
  1041. EXIT:          MOV    CURS_POS,1700H         ;Row 22; column 0.
  1042.                CALL   SET_CURSOR
  1043.                MOV    CX,CURSOR_ORG          ;*A
  1044.                MOV    AH,01H                 ;*A
  1045.                INT    10H                    ;*A
  1046.                CMP    BYTE PTR UPDATE_FLAG,1 ;Did we update notes?
  1047.                JNZ    NO_WRITE               ;If no, skip write
  1048.                MOV    SI,OFFSET SAVING       ;Display "Saving DIRN----.DAT.
  1049.                CALL   GET_TEXT
  1050.                MOV    SI,OFFSET DIRNOTES
  1051.                CALL   GET_TEXT
  1052.                MOV    DX,OFFSET DIRNOTES     ; else point to DIRNOTES
  1053.                MOV    CX,20H                 ; create the file.
  1054.                MOV    AH,3CH
  1055.                INT    21H
  1056.                MOV    BX,AX                  ;Filehandle.
  1057.                MOV    DX,OFFSET BUFFER       ;Point to the buffer
  1058.                MOV    CX,END_OFFSET
  1059.                SUB    CX,DX                  ;File size.
  1060.                MOV    AH,40H                 ;Write it.
  1061.                INT    21H
  1062.  
  1063. NO_WRITE:      CALL   RESTORE_PATH           ;Restore default directory.
  1064.                MOV    CURS_POS,0             ;Home the cursor.
  1065.                CALL   SET_CURSOR
  1066.                CALL   CLS                    ;Clear the screen.
  1067.                INT    20H                    ; and exit.
  1068.  
  1069. RESTORE_PATH:  MOV    DL,CURRENT_DISK        ;Reset the drive.
  1070.                MOV    AH,0EH
  1071.                INT    21H
  1072.                MOV    DX,OFFSET CURRENT_DIR  ;Reset the directory.
  1073.                MOV    AH,3BH
  1074.                INT    21H
  1075.                RET
  1076.  
  1077. ;-------------------------------------------------;
  1078. ; Approximate 700 filename buffer at end of code. ;
  1079. ;-------------------------------------------------;
  1080.  
  1081. CURRENT_DIR:
  1082. BUFFER         EQU    CURRENT_DIR+66
  1083.  
  1084. CODE ENDS
  1085. END  START
  1086.