home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / sampler0 / dirnotes.asm < prev    next >
Assembly Source File  |  1990-03-02  |  39KB  |  1,064 lines

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