ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



КАК ЧИТАТЬ ПОСЛЕДОВАТЕЛЬНО ( ФУНКЦИЯ 14Н )
     

     Вызов:           АН = 14Н
                      DS:DX - указатель на открытый FCB

     Возвращает:      AL - 00H = прочитано успешно
                           01Н = конец файла
                           02Н = мало места в буфере диска
                           03Н = конец файла, неполная запись

     Комментарий:
     Функция  14Н читает запись из указанного файла. DX должен
содержать смещение (сегментный адрес в DS) открытого FCB.  Эта
функция  загружает  запись,  адресуемую  полями  Текущий  блок
(смещение 0СН) и Текущая запись (смещение 20Н) в буфер  обмена
с диском, после чего производит инкремент этих полей.
     Длина записи берется из поля Размер записи (смещение 0ЕН).
     Значение возвращаемого кода:

     Код      Значение
     __________________________________________________________
     0        Прочитано успешно
     1        Конец файла; нет данных в записи
     2        Мало места в буфере обмена с диском для чтения
              одной записи; чтение отменяется
     3        Конец файла; прочитана неполная запись и
              дополнена справа нулями до полной длины записи
     __________________________________________________________

     Макроопределение:

     read-seq macro fcb
              mov   dx,offset fcb
              mov   ah,14H
              int   21H
              endm

     Пример:
     Следующая  программа  выводит  на  экран  файл  с  именем
textfile.asc на диске В. Ее функция аналогична функции команды
MS-DOS TYPE. Если в буфере окажется неполная  запись  в  конце
файла, то она выводится до символа признака конца файла (ASCII
26 или CONTROL+Z).

     fcb        db    2,"TEXTFILEASC"
                db    26 dup (?)
     buffer     db    128 dup (?)
     ;
     begin:     set-dta buffer      ; См. функцию 1АН
                open  fcb           ; См. функцию 0FH
     read-line: read-seq fcb        ; Наша функция
                cmp   al,02H        ; Буфер диска мал?
                je    all-done      ; Да
                cmp   al,00H        ; Конец файла?
                jg    check-more    ; Да
                display buffer      ; См. функцию 09Н
                jmp   read-line     ; Получить след. запись
     check-more: cmp  al,03H        ; Неполная запись?
                jne   all-done      ; Нет, возврат

                             - 52 -


                xor   si,si         ; Сброс индекса
     find-eof:  cmp   buffer[si],26 ; Это признак конца файла?
                je    all-done      ; Да, больше не отображать
                display-char buffer[si] ; См. функцию 02Н
                inc   si            ; Инкремент счетчика
                jmp   find-eof      ; Проверить след. символ
     all-done:  close fcb           ; См. функцию 10Н



     ЗАПИСАТЬ ПОСЛЕДОВАТЕЛЬНО ( ФУНКЦИЯ 15Н )

     Вызов:           АН = 15Н
                      DS:DX - указатель на открытый FCB

     Возвращает:      AL - 00H = записано успешно
                           01Н = диск заполнен
                           02Н = мал буфер диска

     Комментарий:
     Функция  15Н  помещает запись в указанный файл. DX должен
содержать смещение (сегментный  адрес  в  DS)  открытого  FCB.
Запись адресуется полями Текущий блок (смещение 0СН) и Текущая
запись  (смещение  20Н).  После  записи производится инкремент
этих полей.
     Размер записи берется из  поля  Размер  записи  (смещение
0ЕН).  Если размер записи меньше размера сектора, то данные из
буфера обмена с диском записываются в буфер MS-DOS, откуда они
записываются на диск при заполнении буфера до размера сектора,
при закрытии файла или при вызове функции 0DH ( Сброс диска ).
     Значения возвращаемого кода:

     Код в AL         Значение
     __________________________________________________________
     0                Записано успешно
     1                Диск заполнен; запись отменяется
     2                Мало места в буфере обмена с диском для
                      одной записи; запись отменяется
     __________________________________________________________

     Макроопределение:

     write-seq macro fcb
              mov     dx,offset fcb
              mov     ah,15H
              int     21H
              endm

     Пример:
     Следующая программа создает на  диске  В  файл  с  именем
dir.tmp,  содержащий  номера  дисководов  (0=А,  1=В и т.д.) и
имена файлов из каждого каталогового входа.

     record-size equ  0EH ; Смещение поля Размер записи в FCB
     fcb1        db   2,"DIR     TMP"
                 db   26 dup (?)
     fcb2        db   2,"???????????"
                 db   26 dup (?)
     buffer      db   128 dup (?)
     ;

                             - 53 -


     begin:   set-dta buffer     ; См. функцию 1АН
              search-first fcb2  ; См. функцию 11Н
              cmp     al,0FFH    ; Каталоговый вход найден?
              je      all-done   ; Нет, нет файлов на диске
              create  fcb1       ; См. функцию 16Н
              mov     fcb1[record-size],12 ; Установить размер
                                 ; записи равным 12
     write-it: write-seq fcb1    ; Наша функция
              cmp     al,0       ; Записано успешно?
              jne     all-done   ; Нет, возврат
              search-next fcb2   ; См. функцию 12Н
              cmp     al,0FFH    ; Каталоговый вход найден
              je      all-done   ; Нет, возврат
              jmp     write-it   ; Да, записать
     all-done: close  fcb1       ; См. функцию 10Н




     СОЗДАТЬ ФАЙЛ ( ФУНКЦИЯ 16Н )

     Вызов:           АН = 16Н
                      DS:DX - указатель на неоткрытый FCB

     Возвращает:      AL - 00H = свободный вход найден
                           FFH = нет свободных входов

     Комментарий:
     Функция 16Н создает файл. DX  должен  содержать  смещение
(сегментный  адрес  в  DS)  неоткрытого  FCB.  MS-DOS  ищет  в
каталоге  соответствующий  вход,  а  если  такового  нет,   то
свободный вход.
     Если  система находит соответствующий вход, она открывает
файл и сбрасывает его длину в ноль ( другими словами, если  вы
пытаетесь  создать  уже  существуюший  файл, то он стирается и
создается  новый  пустой  файл).  Если  система   не   находит
подходящий  вход,  но  нашла  свободный,  она открывает файл и
устанавливает его  длину  равной  нулю.  В  обоих  случаях  AL
возвращает 0, иначе - FFH.
     Устанавливая  байт атрибута в расширенном FCB , вы можете
присвоить файлу соответствующий атрибут (  см.  Раздел  1.9.1,
"Расширенный FCB").

     Макроопределение:

     create macro fcb
              mov     dx,offset fcb
              mov     ah,16H
              int     21H
              endm

     Пример:
     Следующая программа создает на  диске  В  файл  с  именем
dir.tmp,  содержащий  номера  дисководов  (0=А,  1=В и т.д.) и
имена файлов из каждого каталогового входа.

     record-size equ  0EH ; Смещение поля Размер записи в FCB
     fcb1        db   2,"DIR     TMP"
                 db   26 dup (?)
     fcb2        db   2,"???????????"

                             - 54 -


                 db   26 dup (?)
     buffer      db   128 dup (?)
     ;
     begin:   set-dta buffer     ; См. функцию 1АН
              search-first fcb2  ; См. функцию 11Н
              cmp     al,0FFH    ; Каталоговый вход найден?
              je      all-done   ; Нет, нет файлов на диске
              create  fcb1       ; Наша функция
              mov     fcb1[record-size],12 ; Установить размер
                                 ; записи равным 12
     write-it: write-seq fcb1    ; См. функцию 15Н
              cmp     al,0       ; Записано успешно?
              jne     all-done   ; Нет, возврат
              search-next fcb2   ; См. функцию 12Н
              cmp     al,0FFH    ; Каталоговый вход найден
              je      all-done   ; Нет, возврат
              jmp     write-it   ; Да, записать
     all-done: close  fcb1       ; См. функцию 10Н



     ПЕРЕИМЕНОВАТЬ ФАЙЛ ( ФУНКЦИЯ 17Н )

     Вызов:           АН = 17Н
                      DS:DX - указатель на модифицированный
                              FCB со следующим нестандартным
                              форматом:

                              Байт(ы)   Содержание
                              _________________________________
                              00Н       Номер дисковода
                              01Н-08Н   Старое имя файла (при
                                        необходимости , допол-
                                        ненное справа пробелами)
                              09Н-0ВН   Старое расширение ( при
                                        необходимости, допол-
                                        ненное справа пробелами)
                              0СН-10Н   Обнулено
                              11Н-18Н   Новое имя файла ( при
                                        необходимости допол-
                                        ненное справа пробелами)
                              19Н-1ВН   Новое расширение ( при
                                        необходимости допол-
                                        ненное справа пробелами)
                              1СН-24Н   Обнулено
                              _________________________________

     Возвращает:      AL - 00H = каталоговый вход найден
                           FFH = каталоговый вход не найден или
                                 файл  с   новым   именем   уже
                                 существует

     Комментарий:
     Функция 17Н переименовывает существующий файл. DX  должен
содержать    смещение    (сегментный    адрес    в   DS)   FCB
модифицированного  формата.  MS-DOS  ищет  в  каталоге   вход,
удовлетворяющий первому имени, которое может содержать символы
заполнители.
     Если  система  находит  соответствующий вход и не находит
входа, удовлетворяющего второму имени, она заменяет имя  файла

                             - 55 -


в  каталоговом  входе на второе имя файла из модифицированного
FCB, при этом  AL  возвращает  0.  Если  второе  имя  содержит
символы  заполнители,  то  система  не  меняет соответствующие
символы в имени файла в каталоговом входе.
     Эта функция не может быть использована для переименования
скрытых, системных файлов  и  подкаталогов.  Если  система  не
находит  соответствующего  входа  или находит вход для второго
имени файла, то AL возвращает FFH.

     Макроопределение:

     rename macro fcb,newname
              mov     dx,offset fcb
              mov     ah,17H
              int     21H
              endm

     Пример:
     Следующая программа запрашивает старое и новое имя файла,
а затем переименовывает файл.

     fcb      db      37 dup (?)
     prompt1  db      "Имя файла: $"
     prompt2  db      "Новое имя: $"
     reply    db      15 dup (?)
     crlf     db      0DH,0AH,"$"
     ;
     begin:   display prompt1      ; См. функцию 09Н
              get-string 15,reply  ; См. функцию 0АН
              display crlf         ; См. функцию 09Н
              parse   reply[2],fcb ; См. функцию 29Н
              display prompt2      ; См. функцию 09Н
              get-string 15,reply  ; См. функцию 0АН
              display crlf         ; См. функцию 09Н
              parse   reply[2],fc4b[16] ; См. функцию 29Н
              rename  fcb          ; Наша функция



     ПОЛУЧИТЬ ТЕКУЩИЙ ДИСК ( ФУНКЦИЯ 19Н )

     Вызов:           АН = 19Н

     Возвращает:      AL - текущий дисковод (0=А, 1=В и т.д.)

     Комментарий:
     Функция возвращает код текущего дисковода.

     Макроопределение:

     current-disk macro
                  mov ah,19H
                  int 21H
                  endm

     Пример:
     Следующая программа отображает на экране текущий дисковод
в системе с двумя дисководами.

     message  db   "Текущий диск - $"

                             - 56 -


     crlf     db   0DH,0AH,"$"
     ;
     begin:   display message  ; См. функцию 09Н
              current-disk     ; Наша функция
              cmp     al,00H   ; Это диск А?
              jne     disk-b   ; Нет, это диск В
              display-char "A" ; См. функцию 02Н
              jmp     all-done
     disk-b:  display-char "B" ; См. функцию 02Н
     all-done: display crlf    ; См. функцию 09Н



     УСТАНОВИТЬ БУФЕР ОБМЕНА С ДИСКОМ ( ФУНКЦИЯ 1АН )

     Вызов:           АН = 1АН
                      DS:DX - буфер обмена с диском

     Возвращает:      --

     Комментарий:
     DX должен содержать  смещение  (сегментный  адрес  в  DS)
Буфера  обмена  с  диском. Буфер не должен заходить за границы
сегмента.
     Если вы не установите свой буфер, то система по умолчанию
создаст его со смещением 80Н в PSP (Префикс  сегмента  кодов).
Узнать адрес текущего буфера можно с помощью функции 2FH.

     Макроопределение:

     set-dta macro buffer
             mov      dx,offset buffer
             mov      ah,1AH
             int      21H
             endm

      Пример:
     Следующая   программа   запрашивает   букву,  преобразует
введенную букву в ее порядковый номер в алфавите, затем читает
и выводит на экран соответствующую запись из  файла  с  именем
alphabet.dat,  находящегося  на  диске  В.  Файл  содержит  26
записей, каждая длиной 28 байт.

     record-size     equ 0EH ; Смещение поля Размер записи в FCB
     relative-record equ 21H ; Смещение поля Относительная
                               запись в FCB
     ;
     fcb      db  2,"ALPHABETDAT"
              db  26 dup (?)
     buffer   db  28 dup (?),"$"
     prompt   db  "Введите букву: $"
     crlf     db  0DH,0AH,"$"
     ;
     begin:   set-dta buffer     ; Наша функция
              open    fcb        ; См. функцию 0FH
              mov fcb[record-size],28 ; Установить размер
                                        записи
     get-char: display prompt    ; См. функцию 09Н
              read-kbd-and-echo  ; См. функцию 01Н
              cmp     al,0DH     ; Это ВК

                             - 57 -


              je      all-done   ; Да, возврат
              sub     al,41H     ; Преобразовать код ASCII
                                   в номер записи
              mov     fcb[relative-record],al ; Установить
                                 ; относительную запись
              display crlf       ; См. функцию 09Н
              read-ran fcb       ; См. функцию 21Н
              display buffer     ; См. функцию 09Н
              display crlf       ; См. функцию 09Н
              jmp     get-char   ; Получить следующий символ
     all-done: close  fcb        ; См. функцию 10Н





     ПОЛУЧИТЬ ДАННЫЕ ТЕКУЩЕГО ДИСКА ( ФУНКЦИЯ 1ВН )

     Вызов:           АН = 1ВН

     Возвращает:           количество
                      AL - секторов на кластер
                      СХ - байт на сектор
                      DX - кластеров на диск

                      DS:BX - указатель на байт FAT ID
                              ( таблица размещения файла )

     Комментарий:
     Функция возвращает данные о диске в текущем дисководе. BX
возвращает смещение (сегментный  адрес  в  DS)  первого  байта
Таблицы  размещения  файла  (FAT),  который идентифицирует тип
диска :

     Значение Тип диска
     __________________________________________________________
     FF       Двусторонний, 8 секторов на одной дорожке,
              40 дорожек на одной стороне
     FE       Односторонний, 8 секторов на одной дорожке,
              40 дорожек на одной стороне
     FD       Двусторонний, 9 секторов на одной дорожке,
              40 дорожек на одной стороне
     FC       Односторонний, 9 секторов на одной дорожке,
              40 дорожек на одной стороне
     F9       Двусторонний, 15 секторов на одной дорожке,
              40 дорожек на одной стороне
     F9       Двусторонний, 9 секторов на одной дорожке,
              80 дорожек на одной стороне
     F8       Жесткий диск
     __________________________________________________________

     Эта функция аналогична функции 36Н ( Получить  свободное
пространство  диска  ),  за  исключением  того,  что  в BX она
возвращает адрес байта FAT ID, а  не  количество  имеющихся
кластеров.  Она  также  схожа с функцией 1СН ( Получить данные
диска),  но  возвращает  данные  диска  только   из   текущего
дисковода. Подробнее, о том, как MS-DOS хранит данные на диске
и о Таблице размещения файла, см. Главу 3, "MS-DOS Техническая
информация".

                             - 58 -


     __________________________________________________________
     Предостережение
                    Байт  FAT ID  больше  не  отвечает за
                    идентификацию  типа  используемого  диска.
                    Подробнее,  см.  Главу 2, "MS-DOS Драйверы
                    устройств".
     __________________________________________________________

     Макроопределение:

     def-drive-data macro
              push    ds
              mov     ah,1BH
              int     21H
              mov     al,byte ptr[bx]
              pop     ds
              endm

     Пример:
     Следующая  программа  сообщает,   является   ли   текущий
диск флоппи-диском , или же текущим является жесткий диск.

     stdout   equ     1
     ;
     msg      db      "Текущий диск -    "
     dskt     db      "Дискета."
     fixed    db      "Жесткий."
     crlf     db      0DH,0AH
     ;
     begin:   write-handle stdout,msg,17  ; См. функцию 40Н
              jc      write-error         ; Метка не показана
              def-drive-data              ; Наша функция
              cmp     byte ptr [bx],0F8H  ; Проверить байт
                                          ; FAT ID
              jne     disk                ; Это жесткий диск?
              write-handle stdout,fixed,8 ; См. функцию 40Н
              jc      write-error         ; Метка не показана
              jmp short all-done          ; Возврат
     disk:    write-handle stdout,dskt,8  ; См. функцию 40Н
     all-done: write-handle stdout,crlf,2 ; См. функцию 40Н
              jc      write-error         ; Метка не показана




     ПОЛУЧИТЬ ДАННЫЕ ДИСКА ( ФУНКЦИЯ 1СН )

     Вызов:           АН = 1СН
                      DL - дисковод (0=текущий, 1=А и т.д.)

     Возвращает:      AL - FFH, если несуществующий дисковод,
                                в противном случае количество
                                секторов в кластере
                      СХ - количество байт в секторе
                      DX - количество кластеров на диске
                      DS:BX - указатель на байт FAT ID

     Комментарий:
     Функция возвращает данные диска из указанного в DL дисковода.
BX возвращает смещение (сегментный  адрес  в  DS)  первого  байта

                             - 59 -


Таблицы  размещения  файла  (FAT),  который идентифицирует тип
диска :

     Значение Тип диска
     __________________________________________________________
     FF       Двусторонний, 8 секторов на одной дорожке,
              40 дорожек на одной стороне
     FE       Односторонний, 8 секторов на одной дорожке,
              40 дорожек на одной стороне
     FD       Двусторонний, 9 секторов на одной дорожке,
              40 дорожек на одной стороне
     FC       Односторонний, 9 секторов на одной дорожке,
              40 дорожек на одной стороне
     F9       Двусторонний, 15 секторов на одной дорожке,
              40 дорожек на одной стороне
     F9       Двусторонний, 9 секторов на одной дорожке,
              80 дорожек на одной стороне
     F8       Жесткий диск
     __________________________________________________________

     Если в DL несуществующий номер, то AL возвращает FFH.
     Эта функция аналогична функции 36Н ( Получить  свободное
пространство  диска  ),  за  исключением  того,  что  в BX она
возвращает адрес байта FAT ID, а  не  количество  имеющихся
кластеров.  Она  также  схожа с функцией 1ВН ( Получить данные
текущего диска),  но  возвращает  данные  диска , указанного в
DL .    Подробнее, о том, как MS-DOS хранит данные на диске
и о Таблице размещения файла, см. Главу 3, "MS-DOS Техническая
информация".
     __________________________________________________________
     Предостережение
                    Байт  FAT ID  больше  не  отвечает за
                    идентификацию  типа  используемого  диска.
                    Подробнее,  см.  Главу 2, "MS-DOS Драйверы
                    устройств".
     __________________________________________________________

     Макроопределение:

    drive-data macro drive
              push    ds
              mov     dl,drive
              mov     ah,1CH
              int     21H
              mov     al,byte ptr[bx]
              pop     ds
              endm

     Пример:
     Следующая  программа  сообщает,   является   ли   текущий
диск флоппи-диском , или же текущим является жесткий диск.

     stdout   equ     1
     ;
     msg      db      "Текущий диск -    "
     dskt     db      "Дискета."
     fixed    db      "Жесткий."
     crlf     db      0DH,0AH
     ;
     begin:   write-handle stdout,msg,17  ; См. функцию 40Н

                             - 60 -


              jc      write-error         ; Метка не показана
              drive-data 2                ; Наша функция
              cmp     byte ptr [bx],0F8H  ; Проверить байт
                                          ; FAT ID
              jne     disk                ; Это жесткий диск?
              write-handle stdout,fixed,8 ; См. функцию 40Н
              jc      write-error         ; Метка не показана
              jmp short all-done          ; Возврат
     disk:    write-handle stdout,dskt,8  ; См. функцию 40Н
     all-done: write-handle stdout,crlf,2 ; См. функцию 40Н
              jc      write-error         ; Метка не показана




     ЧИТАТЬ ВЫБОРОЧНО ( ФУНКЦИЯ 21Н )

     Вызов:           АН = 21Н
                      DS:DX - указатель на открытый FCB

     Возвращает:      AL - 0 = прочитано успешно
                           1 = конец файла, пустая запись
                           2 = мало места в DTA
                           3 = конец файла, неполная запись

     Комментарий:
     Функция  21Н  читает  (в  буфер  обмена с диском) запись,
адресуемую полем Относительная запись (смещение 21Н) в FCB. DX
должен содержать смещение (сегментный адрес  в  DS)  открытого
FCB.  Поля  Текущий  блок  (смещение  0СН)  и  Текущая  запись
(смещение  20Н)  устанавливаются  в   соответствии   с   полем
Относительная  запись.  Длина  записи  берется  из поля Размер
записи (смещение 0ЕН) в FCB.
     AL возвращает код результата:

     Код      Значение
     __________________________________________________________
     0        Прочитано успешно
     1        Конец файла; нет данных в записи
     2        Мало места в Буфере обмена с диском (DTA) для
              чтения одной записи; чтение отменяется
     3        Конец файла; прочитана неполная запись и
              дополнена справа нулями до длины полной записи.
     __________________________________________________________

     Макроопределение:

     read-ran macro fcb
              mov   dx,offset fcb
              mov   ah,21H
              int   21h
              endm

     Пример:
     Следующая   программа   запрашивает   букву,  преобразует
введенную букву в ее порядковый номер в алфавите, затем читает
и выводит на экран соответствующую запись из  файла  с  именем
alphabet.dat,  находящегося  на  диске  В.  Файл  содержит  26
записей, каждая длиной 28 байт.


                             - 61 -


     record-size     equ 0EH ; Смещение поля Размер записи в FCB
     relative-record equ 21H ; Смещение поля Относительная
                               запись в FCB
     ;
     fcb      db  2,"ALPHABETDAT"
              db  26 dup (?)
     buffer   db  28 dup (?),"$"
     prompt   db  "Введите букву: $"
     crlf     db  0DH,0AH,"$"
     ;
     begin:   set-dta buffer     ; См. функцию 1АН
              open    fcb        ; См. функцию 0FH
              mov fcb[record-size],28 ; Установить размер
                                        записи
     get-char: display prompt    ; См. функцию 09Н
              read-kbd-and-echo  ; См. функцию 01Н
              cmp     al,0DH     ; Это ВК
              je      all-done   ; Да, возврат
              sub     al,41H     ; Преобразовать код ASCII
                                   в номер записи
              mov     fcb[relative-record],al ; Установить
                                 ; относительную запись
              display crlf       ; См. функцию 09Н
              read-ran fcb       ; Наша функция
              display buffer     ; См. функцию 09Н
              display crlf       ; См. функцию 09Н
              jmp     get-char   ; Получить следующий символ
     all-done: close  fcb        ; См. функцию 10Н



     ЗАПИСАТЬ ВЫБОРОЧНО ( ФУНКЦИЯ 22Н )

     Вызов:           АН = 22Н
                      DS:DX - указатель на открытый FCB

     Возвращает:      AL - 0 = записано успешно
                           1 = диск заполнен
                           2 = мало места в DTA

     Комментарий:
     Функция записывает из Блока обмена с диском (DTA) запись,
адресуемую полем Относительная запись (смещение 21Н) в FCB. DX
должен содержать смещение (сегментный адрес  в  DS)  открытого
FCB.   Поля   Текущий   блок   и   Текущая   запись  (смещения
соответственно 0СН и 20Н ) устанавливаются  в  зависимости  от
Относительной записи. После этого происходит запись с DTA.
     Размер  записи  берется из поля Размер записи в FCB. Если
размер  записи  меньше  размера  сектора,  то  данные  из  DTA
записываются  в  системный буфер, который записывается на диск
при заполнении его до размера сектора, при закрытии файла  или
при вызове функции 0DH (Сброс диска).
     AL возвращает код результата операции:

     Код      Значение
     __________________________________________________________
     0        Записано успешно
     1        Диск заполнен
     2        Мало места в Буфере обмена с диском для одной
              записи; запись отменяется
     __________________________________________________________

                             - 62 -



     Макроопределение:

     write-ran macro fcb
              mov     dx,offset fcb
              mov     ah,22H
              int     21H
              endm

     Пример:
     Следующая   программа   запрашивает   букву,  преобразует
введенную букву в ее порядковый номер в алфавите, затем читает
и выводит на экран соответствующую запись из  файла  с  именем
alphabet.dat,  находящегося  на диске В. После вывода на экран
этой записи, программа  запрашивает  ввод  измененной  записи.
Если  вы  введете  измененную  запись, то она будет записана в
файл. Если вы просто  нажмете  ВВОД,  то  запись  заменена  не
будет.  Файл  содержит  26 записей, каждая длиной 28 байт.

     record-size     equ 0EH ; Смещение поля Размер записи в FCB
     relative-record equ 21H ; Смещение поля Относительная
                               запись в FCB
     ;
     fcb      db  2,"ALPHABETDAT"
              db  26 dup (?)
     buffer   db  28 dup (?),"$"
     prompt1  db  "Введите букву: $"
     prompt2  db  "Новая запись (ВВОД если нет изменений): $"
     crlf     db  0DH,0AH,"$"
     reply    db  28 dup (32)
     blanks   db  26 dup (32)
     ;
     begin:   set-dta buffer     ; См. функцию 1АН
              open    fcb        ; См. функцию 0FH
              mov fcb[record-size],28 ; Установить размер
                                        записи
     get-char: display prompt1   ; См. функцию 09Н
              read-kbd-and-echo  ; См. функцию 01Н
              cmp     al,0DH     ; Это ВК
              je      all-done   ; Да, возврат
              sub     al,41H     ; Преобразовать код ASCII
                                   в номер записи
              mov     fcb[relative-record],al ; Установить
                                 ; относительную запись
              display crlf       ; См. функцию 09Н
              read-ran fcb       ; Наша функция
              display buffer     ; См. функцию 09Н
              display crlf       ; См. функцию 09Н
              display prompt2    ; См. функцию 09Н
              get-string 27,reply ; См. функцию 0АН
              display crlf       ; См. функцию 09Н
              cmp     reply[1],0 ; Что-нибудь введено,кроме ВК?
              je      get-char   ; Нет, другой символ
              xor     bx,bx      ; Сброс
              mov     bl,reply[1] ; Длину reply в качестве
                                    счетчика
              mov-string blanks,buffer,26 ; См. конец главы
              mov-string replay[2],buffer,bx ; См. конец главы
              write-ran fcb      ; Наша функция
              jmp     get-char   ; Получить следующий символ
     all-done: close  fcb        ; См. функцию 10Н

                             - 63 -



     ПОЛУЧИТЬ РАЗМЕР ФАЙЛА ( ФУНКЦИЯ 23Н )

     Вызов:           АН = 23Н
                      DS:DX - указатель на неоткрытый FCB

     Возвращает:      AL - 00H = каталоговый вход найден
                           FFH = каталоговый вход не найден

     Комментарий:
     Функция 23Н возвращает размер указанного файла. DX должен
содержать смещение (сегментный адрес в DS) неоткрытого FCB.
     Если  каталоговый  вход  найден, то MS-DOS делит значение
поля  Размер  файла  (смещение  10Н)  каталогового  входа   на
значение  поля  Размер  записи  (смещение  0ЕН) FCB. Результат
помещается в поле Относительная запись (смещение 21Н)  FCB,  а
AL возвращает 0.
     Вам  неоходимо  выставить  поле  Размер  записи  в  блоке
управления файлом  (FCB)  перед  вызовом  этой  функции.  Если
размер   записи   не  является  делителем  размера  файла,  то
результат округляется в сторону увеличения.
     Если вход не найден, AL возвращает FFH.

     Макроопределение:

     file-size macro fcb
              mov     dx,offset fcb
              mov     ah,23H
              int     21H
              endm

     Пример:
     Следующая программа запрашивает имя файла, открывает  его
для  заполнения поля Размер записи в FCB, вызывает функцию 23Н
и выводит на экран длину записи и количество записей.

     fcb      db      37 dup (?)
     prompt   db      "Имя файла: $"
     msg1     db      "Длина записи:     ",0DH,0AH,"$"
     msg2     db      "Записей:      ",0DH,0AH,"$"
     crlf     db      0DH,0AH,"$"
     reply    db      17 dup (?)
     ;
     begin:   display prompt         ; См. функцию 09Н
              get-string 17,reply    ; См. функцию 0АН
              cmp     reply[1],0     ; Это ВК?
              jne     get-length     ; Нет, продолжать
              jmp     all-done       ; Да, возврат
     get-length: display crlf        ; См. фунуцию 09Н
              parse   reply[2],fcb   ; См. функцию 29Н
              open    fcb            ; См. функцию 0FH
              file-size fcb          ; Наша функция
              mov     ax,word ptr fcb[33] ; Получить длину
                                            записи
              convert ax,10,msg2[9]  ; См. конец главы
              mov     ax,word ptr fcb[14] ; Получить количество
                                            записей
              convert ax,10,msg1[15] ; См. конец главы
              display msg1           ; См. функцию 09Н
              display msg2           ; См. функцию 09Н
     all-done: close  fcb            ; См. функцию 10Н

                             - 64 -



     УСТАНОВИТЬ ОТНОСИТЕЛЬНУЮ ЗАПИСЬ ( ФУНКЦИЯ 24Н )

     Вызов:           АН = 24Н
                      DS:DX - указатель на открытый FCB

     Возвращает:      --
                      AL = 00H - поле относительной записи
                                 в FCB изменено.

     Комментарий:
     Функция  устанавливает  поле   Относительная   запись
(смещение  21Н) в соответствие с полями Текущий блок (смещение
0СН) и Текущая запись  (смещение  20Н).  DX  должен  содержать
смещение  (сегментный  адрес  в DS) открытого FCB. Пользуйтесь
этой функцией перед выборочными чтением и  записью   ( функции
21Н, 22Н, 27Н или 28Н).

     Макроопределение:

     set-relative-record macro fcb
              mov     dx,offset fcb
              mov     ah,24H
              int     21H
              endm

     Пример:
     Следующая  программа копирует файл, используя функции 27Н
и 28Н. Копирование значительно ускорено путем установки  длины
записи   равной   длине   файла,   счетчика   записей  -  1  и
использованием буфера в 32К. Указатель  файла  позиционируется
установкой  поля  Текущая  запись в 1 и использованием функции
24Н  (Установить  относительную  запись)  .   Таким   образом,
указатель   файла   адресует  ту же  запись  в  файле,  что  и
комбинация полей Текущий блок и Текущая запись.

     current-record   equ 20H ; Смещение поля Текущая запись
                                в FCB
     file-size        equ 10H ; Смещение поля Размер файла
                                в FCB
     ;
     fcb      db      37 dup (?)
     filename db      17 dup (?)
     prompt1  db      "Копировать файл: $" ; Об'яснение симво-
     prompt2  db      "Имя копии: $" ; ла $ дается в описании
                                     ; функции 09Н
     crlf     db      0DH,0AH,"$"
     file-length dw   ?
     buffer db        32767 dup (?)
     ;
     begin:   set-dta buffer            ; См. функцию 1АН
              display prompt1           ; См. функцию 09Н
              get-string 15,filename    ; См. функцию 0АН
              display crlf              ; См. функцию 09Н
              parse   filename[2],fcb   ; См. функцию 29Н
              open    fcb               ; См. функцию 0FH
              mov     fcb[current-record],0 ; Установка поля
                                        ; Текущая запись
              set-relative-record fcb   ; Наша функция
              mov     ax,word ptr fcb[file-size] ; Получить

                             - 65 -


                                        ; размер файла
              mov     file-length,ax    ; Сохранить его
                                        ; для выборочной
                                        ; записи
              ran-block-read fcb,1,ax   ; См. функцию 27Н
              display prompt2           ; См. функцию 09Н
              get-string 15,filename    ; См. функцию 0АН
              display crlf              ; См. функцию 09Н
              parse   filename[2],fcb   ; См. функцию 29Н
              create  fcb               ; См. функцию 16Н
              mov     fcb[current-record],0 ; Установка поля
                                        ; Текущая запись
              set-relative-record fcb   ; Наша функция
              mov     ax,file-length    ; Восстановить размер
              ran-block-write fcb,1,ax  ; См. функцию 28Н
              close   fcb               ; См. фунуцию 10Н

                             - 66 -




     УСТАНОВИТЬ ВЕКТОР ПРЕРЫВАНИЯ ( ФУНКЦИЯ 25Н )

     Вызов:           АН = 25Н
                      AL - номер прерывания
                      DS:DX - указатель на процедуру
                              обслуживания прерывания

     Возвращает:      --

     Комментарий:
     Функция  25Н  устанавливает  адрес  прерывания  в таблице
векторов для указанного прерывания.
     AL должен  содержать  номер  прерывания.  DX  -  смещение
(сегментный адрес в DS) процедуры обслуживания прерывания.
     Для  избежания  проблем совместимости , программы никогда
не  должны  напрямую  устанавливать  вектор  или  использовать
Прерывание  25Н  для  прямого  чтения из памяти. Для получения
вектора используйте функцию 35Н ( Получить вектор прерывания),
а для установки - Функцию 25Н, если необязательно, чтобы  ваши
программы были совместимы с версиями системы до 2.0.

     Макроопределение:

     set-vector macro interrupt,handler-start
              mov     al,interrupt
              mov     dx,offset handler-start
              mov     ah,25H
              int     21H
              endm

     Пример:
     Так  как  прерывания  обычно  имеют  специфику конкретной
машины, пример не показан.



     СОЗДАТЬ НОВЫЙ PSP ( ФУНКЦИЯ 26Н )

     Вызов:           АН = 26Н
                      DX - сегментный адрес нового PSP

     Возвращает:      --

     Комментарий:
     Эта  функция  была  заменена.  Используйте  функцию   4ВН
(Загрузить  и  выполнить  программу  или наложить) для запуска
дочерних программ,  если  нет  необходимости  в  совместимости
ваших программ с версиями системы до 2.0.
     Функция  создает  новый Префикс сегмента кодов (PSP). Его
сегментный адрес должен быть загружен в DX.

     Макроопределение:

     create-psp macro seg-addr
              mov     dx,seg-addr
              mov     ah,26H
              int     21H
              endm

                             - 67 -



     Пример:
     Так как эта функция была  заменена  на  функции  4В00Н  и
4В03Н, пример не показан.




     ЧИТАТЬ БЛОК ВЫБОРОЧНО ( ФУНКЦИЯ 27Н )

     Вызов:           АН = 27Н
                      СХ - количество блоков для чтения
                      DS:DX - указатель на открытый FCB

     Возвращает :     AL - 0 = прочитано успешно
                           1 = конец файла, пустая запись
                           2 = мало места в DTA
                           3 = конец файла, неполная запись
                      СХ - количество прочитанных блоков

     Комментарий:
     Функция   27Н   читает  одну  или  несколько  записей  из
указанного файла в Буфер обмена  с  диском  (DTA).  DX  должен
содержать  смещение  (сегментный адрес в DS) открытого FCB. СХ
должен содержать количество записей, которое нужно  прочитать.
Чтение  начинается  с  записи,  адресуемой полем Относительная
запись (смещение 21Н). Это  поле  необходимо  выставить  перед
вызовом этой функции.
     MS-DOS  подсчитывает  количество  байт  для  чтения путем
умножения значения СХ на значение поля Размер записи (смещение
0ЕН) FCB.
     СХ  возвращает  количество  прочитанных   записей.   Поля
Текущий  блок  (смещение  0СН),  Текущая запись (смещение 20Н)
и Относительная запись теперь адресуют следующую запись.
     При  вызове  этой  функции  с  СХ,  равным  0,  не  будет
прочитано ни одной записи.
     AL возвращает код результата операции:

     Код      Значение
     __________________________________________________________
     0        Прочитано успешно
     1        Конец файла; нет данных в записи
     2        Мало места в Буфере обмена с диском для чтения
              одной записи; чтение отменяется
     3        Конец файла; прочитана неполная запись и допол-
              нена справа нулями до полной длины.
     __________________________________________________________

     Макроопределение:

     ran-block-read macro fcb,count,rec-size
              mov     dx,offset fcb
              mov     cx,count
              mov     word ptr fcb[14],rec-size
              mov     ah,27H
              int     21H
              endm


                             - 68 -



     Пример:
     Следующая  программа копирует файл, используя функции 27Н
и 28Н. Копирование значительно ускорено путем установки  длины
записи   равной   длине   файла,   счетчика   записей  -  1  и
использованием буфера в 32К. Файл читается как одна запись
(  сравните  с  примером  функции 28Н, где длина записи = 1, а
счетчик записей = размеру файла).

     current-record   equ 20H ; Смещение поля Текущая запись
                                в FCB
     file-size        equ 10H ; Смещение поля Размер файла
                                в FCB
     ;
     fcb      db      37 dup (?)
     filename db      17 dup (?)
     prompt1  db      "Копировать файл: $" ; Об'яснение симво-
     prompt2  db      "Имя копии: $" ; ла $ дается в описании
                                     ; функции 09Н
     crlf     db      0DH,0AH,"$"
     file-length dw   ?
     buffer db        32767 dup (?)
     ;
     begin:   set-dta buffer            ; См. функцию 1АН
              display prompt1           ; См. функцию 09Н
              get-string 15,filename    ; См. функцию 0АН
              display crlf              ; См. функцию 09Н
              parse   filename[2],fcb   ; См. функцию 29Н
              open    fcb               ; См. функцию 0FH
              mov     fcb[current-record],0 ; Установка поля
                                        ; Текущая запись
              set-relative-record fcb   ; См. функцию 24Н
              mov     ax,word ptr fcb[file-size] ; Получить
                                        ; размер файла
              mov     file-length,ax    ; Сохранить его
                                        ; для выборочной
                                        ; записи
              ran-block-read fcb,1,ax   ; Наша функция
              display prompt2           ; См. функцию 09Н
              get-string 15,filename    ; См. функцию 0АН
              display crlf              ; См. функцию 09Н
              parse   filename[2],fcb   ; См. функцию 29Н
              create  fcb               ; См. функцию 16Н
              mov     fcb[current-record],0 ; Установка поля
                                        ; Текущая запись
              set-relative-record fcb   ; См. функцию 24Н
              mov     ax,file-length    ; Восстановить размер
              ran-block-write fcb,1,ax  ; См. функцию 28Н
              close   fcb               ; См. фунуцию 10Н



                             - 69 -




     ЗАПИСАТЬ БЛОК ВЫБОРОЧНО ( ФУНКЦИЯ 28Н )

     Вызов:           АН = 28Н
                      СХ - количество блоков для чтения
                           ( 0 - установка поля Размер файла)
                      DS:DX - указатель на открытый FCB

     Возвращает:      AL - 0 = записано успешно
                           1 = диск заполнен
                           2 = конец сегмента
                      СХ - количество прочитанных блоков

     Комментарий:
     Функция записывает одну или несколько записей в указанный
файл из Буфера обмена с  диском  (DTA).  DX  должен  содержать
смещение  (сегментный  адрес  в DS) открытого FCB. В СХ должно
быть либо количество записей для чтения, либо 0.
     Если  СХ  не  ноль,  то  указанное   количество   записей
записывается  в  файл,  начиная  с  записи,  адресуемой  полем
Относительная запись (смещение 21Н)  FCB.  Если  СХ  -  0,  то
ничего  не  записывается  , а MS-DOS устанавливает поле размер
файла (смещение 10Н) в каталоговом входе равным значению  поля
Относительная  запись  (смещение  21Н) в FCB. В соответствии с
новым размером файла , дисковые кластеры либо выделяются, либо
освобождаются.
     MS-DOS подсчитывает  количество  байт  для  записи  путем
умножения  содержимого  СХ  на  значение  поля  Размер  записи
(смещение  0ЕН)  FCB.  СХ  возвращает  количество   записанных
блоков.  Поля  Текущий  блок  (смещение  0СН),  Текущая запись
(смещение 20Н) и Относительная запись (смещение 21Н)  адресуют
теперь следующую запись.
     AL возвращает код результата операции:

     Код      Значение
     __________________________________________________________
     0        Записано успешно
     1        Диск заполнен. Ничего не записано
     2        Мало места в Буфере обмена с диском для одной
              записи. Запись отменяется
     __________________________________________________________

     Макроопределение:

     ran-block-write macro fcb,count,rec-size
              mov     dx,offset fcb
              mov     cx,count
              mov     word ptr fcb[14],rec-size
              mov     ah,28H
              int     21H
              endm

     Пример:
     Следующая  программа копирует файл, используя функции 27Н
и 28Н. Копирование значительно ускорено путем установки  длины
записи   равной  1 , а счетчика   записей  -  размеру файла и
использованием буфера в 32К. Чтение и запись осуществляются за
один доступ к диску.
(  Сравните с примером функции 27Н, где длина записи = размеру
размеру файла, счетчик записей = 1).

                             - 70 -



     current-record   equ 20H ; Смещение поля Текущая запись
                                в FCB
     file-size        equ 10H ; Смещение поля Размер файла
                                в FCB
     ;
     fcb      db      37 dup (?)
     filename db      17 dup (?)
     prompt1  db      "Копировать файл: $" ; Об'яснение симво-
     prompt2  db      "Имя копии: $" ; ла $ дается в описании
                                     ; функции 09Н
     crlf     db      0DH,0AH,"$"

     buffer db        32767 dup (?)
     num-recs    dw   ?
     ;
     begin:   set-dta buffer            ; См. функцию 1АН
              display prompt1           ; См. функцию 09Н
              get-string 15,filename    ; См. функцию 0АН
              display crlf              ; См. функцию 09Н
              parse   filename[2],fcb   ; См. функцию 29Н
              open    fcb               ; См. функцию 0FH
              mov     fcb[current-record],0 ; Установка поля
                                        ; Текущая запись
              set-relative-record fcb   ; См. функцию 24Н
              mov     ax,word ptr fcb[file-size] ; Получить
                                        ; размер файла
              mov     num-recs,ax       ; Сохранить его
                                        ; для выборочной
                                        ; записи
              ran-block-read fcb,num-recs,1 ; См. функцию 27Н
              display prompt2           ; См. функцию 09Н
              get-string 15,filename    ; См. функцию 0АН
              display crlf              ; См. функцию 09Н
              parse   filename[2],fcb   ; См. функцию 29Н
              create  fcb               ; См. функцию 16Н
              mov     fcb[current-record],0 ; Установка поля
                                        ; Текущая запись
              set-relative-record fcb   ; См. функцию 24Н

              ran-block-write fcb,num-recs,1 ; Наша функция
              close   fcb               ; См. фунуцию 10Н




     РАЗОБРАТЬ ИМЯ ФАЙЛА ( ФУНКЦИЯ 29Н )

     Вызов:           АН = 29Н
                      AL - управляет разбором
                      DS:SI - указатель на разбираемую строку
                      ES:DI - указатель на буфер для
                              неоткрытого FCB

     Возвращает:      AL - 00H = нет символов заполнителей
                           01Н = есть символы заполнители
                           FFH = несуществующее имя дисковода
                      DS:SI - указатель на первый байт после
                              разобранной строки
                      ES:DI - указатель на неоткрытый FCB

                             - 71 -



     Комментарий:
     Функция 29Н производит анализ  строки  на  имя  файла  по
принципу  - дисковод:имя_файла.расширение. SI должен содержать
смещение (сегментный адрес в DS) разбираемой строки. DI должен
содержать смещение (сегментный адрес в ES) достаточно большого
участка памяти  для  неоткрытого  FCB.  Если  строка  содержит
разрешенное  имя  файла,  то  система  создает соответствующий
неоткрытый FCB по ES:DI.
     AL контролирует разбор. Биты 4-7 должны  быть  нулями,  а
биты 0-3 имеют следующий смысл:

     Таблица 1.20
     __________________________________________________________
     Бит      Действие
     __________________________________________________________
     0   0    Останавливает разбор, если встречает разделитель
         1    Игнорирует лидирующие разделители
     1   0    Если строка не содержит номер дисковода, то в FCB
              он выставляется в 0 (текущий)
         1    Оставляет номер дисковода в FCB неизменным, если
              строка не содержит номер дисковода
     2   0    Вставляет в имя файла в FCB 8 пробелов, если
              строка не содержит имени файла
         1    Оставляет имя файла неизменным в FCB, если строка
              не содержит имени файла
     3   0    Вставляет 3 пробела в расширение имени в FCB,
              если строка не содержит расширения
         1    Оставляет расширение имени в FCB неизменным, если
              строка не содержит расширения
     __________________________________________________________
     Если  строка  содержит  имя  файла  или  его расширение с
с символом (*), то все остальные символы имени или  расширения
заменяются на символ (?).

     Разделители имени файла:

     : ; . , = + / " [ ] \ < > | таб

     Если строка содержит разрешенное имя файла, то:

     - AL возвращает 0, если в имени или расширении есть
       символы заполнители, и 1, если их нет в спецификации.
     - DS:SI адресуют символ, следующий за разобранной строкой.
     - ES:DI адресуют первый байт неоткрытого FCB.

     Если имя дисковода не существует, то AL возвращает FFH.
     Если строка не содержит разрешенное имя файла, то ES:DI+1
адресуют пробел.

     Макроопределение:

     parse macro string,fcb
              mov     si,offset string
              mov     di,offset fcb
              push    es
              push    ds
              pop     es
              mov     al,0FH ; Биты 0-3 в 1
              mov     ah,29H

                             - 72 -


              int     21H
              pop     es
              endm

     Пример:
     Следующая  программа  проверяет  существование файла, имя
которого вы вводите на запрос.

     fcb      db      37 dup (?)
     prompt   db      "Имя файла: $"
     reply    db      17 dup (?)
     yes      db      "Файл существует",0DH,0AH,"$"
     no       db      "Файл не существует",0DH,0AH,"$"
     crlf     db      0DH,0AH,"$"
     ;
     begin:   display prompt       ; См. функцию 09Н
              get-string 15,reply  ; См. функцию 0АН
              parse   reply[2],fcb ; Наша функция
              display crlf         ; См. функцию 09Н
              search-first fcb     ; См. функцию 11Н
              cmp     al,0FFH      ; Каталоговый вход найден?
              je      not-there    ; Нет
              display yes          ; См. функцию 09Н
              jmp     return       ; Метка не показана
     not-there: display no         ; См. функцию 09Н




     ПОЛУЧИТЬ ДАТУ ( ФУНКЦИЯ 2АН )

     Вызов:           АН = 2АН

     Возвращает:      СХ - год ( 1980-2099 )
                      DH - месяц ( 1-12 )
                      DL - число ( 1-31 )
                      AL - день недели ( 0=Вс., 6=Сб. и т.д. )

     Комментарий:
     Функция 2АН возвращает текущую дату операционной системы.

     Макроопределение:

     get-date macro
              mov     ah,2AH
              int     21H
              endm

     Пример:
     Следующая программа получает дату,  производит  инкремент
дня, а если нужно, то и месяца, после чего устанавливает новую
дату.

     month    db      31,28,31,30,31,30,31,31,30,31,30,31
     ;
     begin:   get-date            ; Наша функция
              inc     dl          ; Инкремент дня
              xor     bx,bx       ; BL в качестве индекса
              mov     bl,dh       ; Месяца в индекс
              dec     bx          ; Отсчет в таблице

                             - 73 -


                                    месяцев с нуля
              cmp     dl,month[bx] ; Месяц прошел?
              jle     month-ok    ; Нет, установить дату
              mov     dl,1        ; Да, сброс дней в 1
              inc     dh          ; и инкремент месяцев
              cmp     dh,12       ; Год закончился?
              jle     month-ok    ; Нет, установить дату
              mov     dh,1        ; Да, сброс месяцев в 1
              inc     cx          ; и инкремент года
     month-ok: set-date cx,dh,dl  ; См. функцию 2АН



     УСТАНОВИТЬ ДАТУ ( ФУНКЦИЯ 2ВН )

     Вызов:           АН = 2ВН
                      СХ - год ( 1980-2099 )
                      DH - месяц ( 1-12 )
                      DL - день ( 1-31 )

     Возвращает:      AL - 00H = разрешенная дата
                           FFH = несуществующая дата

     Комментарий:
     Функция устанавливает дату операционной системы. Регистры
DX и CX должны содержать разрешенную дату в двоичном коде.

     Макроопределение:

     set-date macro year,month,day
              mov     cx,year
              mov     dh,month
              mov     dl,day
              mov     ah,2BH
              int     21H
              endm

     Пример:
     Следующая программа получает дату,  производит  инкремент
дня, а если нужно, то и месяца, после чего устанавливает новую
дату.

     month    db      31,28,31,30,31,30,31,31,30,31,30,31
     ;
     begin:   get-date            ; См. функцию 2АН
              inc     dl          ; Инкремент дня
              xor     bx,bx       ; BL в качестве индекса
              mov     bl,dh       ; Месяца в индекс
              dec     bx          ; Отсчет в таблице
                                    месяцев с нуля
              cmp     dl,month[bx] ; Месяц прошел?
              jle     month-ok    ; Нет, установить дату
              mov     dl,1        ; Да, сброс дней в 1
              inc     dh          ; и инкремент месяцев
              cmp     dh,12       ; Год закончился?
              jle     month-ok    ; Нет, установить дату
              mov     dh,1        ; Да, сброс месяцев в 1
              inc     cx          ; и инкремент года
     month-ok: set-date cx,dh,dl  ; Наша функция


                             - 74 -



     ПОЛУЧИТЬ ВРЕМЯ ( ФУНКЦИЯ 2СН )

     Вызов:           АН = 2СН

     Возвращает:      СН - часы ( 0-23 )
                      CL - минуты ( 0-59 )
                      DH - секунды ( 0-59 )
                      DL - сотые доли секунды ( 0-99 )

     Комментарий:
     Функция  2СН  возвращает  время  операционной  системы  в
регистрах CX и DX в двоичном коде.
     В зависимости от аппаратной  реализации  отсчета  времени,
некоторые поля  регистров  не используются . Например, многие
чипы с часами не  выделяют  долей  секунды.  В  таких  случаях
значение DL, скорее всего, будет всегда равно 0.

     Макроопределение:

     get-time macro
              mov     ah,2ch
              int     21h
              endm

     Пример:
     Следующая   программа   непрерывно  отображает  время  до
нажатия любой клавиши:

     time   db   "00:00:00.00",0DH,0AH,"$"
            .
            .
     begin: get-time                ; Наша функция
            byte-to-dec ch,time     ; См. конец главы
            byte-to-dec cl,time[3]  ; См. конец главы
            byte-to dec dh,time[6]  ; См. конец главы
            byte-to dec dl,time[9]  ; См. конец главы
            display time            ; См. функцию 09Н
            check-kbd-status        ; См. функцию 0ВН
            cmp     al,0FFH         ; Есть символы?
            je      return          ; Да, возврат
            jmp     begin           ; Нет, продолжать
                                    ; индикацию времени




     УСТАНОВИТЬ ВРЕМЯ ( ФУНКЦИЯ 2DH )

     Вызов:           АН = 2DH
                      СН - часы ( 0-23 )
                      CL - минуты ( 0-59 )
                      DH - секунды ( 0-59 )
                      DL - сотые доли секунды ( 0-99 )

     Возвращает:      AL - 00H - разрешенное время
                           FFH - несуществующее время

                             - 75 -



     Комментарий:
     Функция  2СН  возвращает  время  операционной  системы  в
регистрах CX и DX в двоичном коде.

     В зависимости от аппаратной  реализации  отсчета  времени,
некоторые поля  регистров  не используются . Например, многие
чипы с часами не  выделяют  долей  секунды.  В  таких  случаях
значение DL не будет использоваться.

     Макроопределение:

     set-time macro hour,minutes,seconds,hundredths
              mov     ch,hour
              mov     cl,minutes
              mov     dh,seconds
              mov     dl,hundredths
              mov     ah,2DH
              int     21H
              endm

     Пример:
     Следующая  программа  сбрасывает  системные часы в ноль и
отображает время непрерывно. При вводе символа экран замирает.
При вводе следующего символа,  часы  сбрасываются  в  ноль,  а
индикация времени продолжается.

     time   db   "00:00:00.00",0DH,0AH,"$"
            .
            .
     begin: set-time 0,0,0,0        ; Наша функция
     read-clock: get-time           ; См. функцию 2СН
            byte-to-dec ch,time     ; См. конец главы
            byte-to-dec cl,time[3]  ; См. конец главы
            byte-to dec dh,time[6]  ; См. конец главы
            byte-to dec dl,time[9]  ; См. конец главы
            display time            ; См. функцию 09Н
            dir-console-io 0FFH     ; См. функцию 06Н
            cmp     al,00H          ; Есть символы?
            jne     stop            ; Да, стоп таймер
            jmp     read-clock      ; Нет, продолжать
                                    ; индикацию времени
     stop:  read-kbd                ; См. функцию 08Н
            jmp     begin           ; Продолжить



     УТАНОВИТЬ/СБРОСИТЬ ФЛАГ ПРОВЕРКИ ( ФУНКЦИЯ 2ЕН )

     Вызов:           АН = 2ЕН
                      AL - 0 = не проверять
                           1 = проверять

     Возвращает:      --

     Комментарий:
     Функция  2ЕН  сообщает  системе, проверять или нет каждую
запись на диск. Если AL = 1, то проверять ; если AL = 0 ,то не
проверять. В свою очередь, система проверяет этот  флаг  перед
каждой операцией записи на диск.
     В  нормальном  положении  флаг  сброшен.  Вы  можете  его

                             - 76 -


установить , если записываются очень важные данные.  Установка
флага  снижает  скорость записи. Вы можете проверить установку
флага  с  помощью  функции  54Н   ( Получить  состояние  флага
проверки).

     Макроопределение:

     verify macro switch
              mov     al,switch
              mov     ah,2EH
              int     21H
              endm

     Пример:
     Следующая  программа  копирует  содержимое одностороннего
диска  А  на  диск  В,  проверяя  каждую   запись.   Программа
использует буфер в 32К.

     on       equ     1
     off      equ     0
     ;
     prompt   db      "Источник в А, адресат в В",0DH,0AH
              db      "Нажмите любую клавишу. $"
     first    dw      0
     buffer   db      60 dup (512 dup (?)) ; 60 секторов
     ;
     begin:   display prompt   ; См. функцию 09Н
              read-kbd         ; См. функцию 08Н
              verify  on       ; Наша функция
              mov     cx,6     ; Копировать 60 секторов
                               ; 6 раз
     copy:    push    cx       ; Сохранить счетчик
              abs-disk-read 0,buffer,60,first ; См. преры-
                               ; вание 25Н
              abs-disk-write 1,buffer,64,first ; См. преры-
                               ; вание 26Н
              add     first,60 ; Следующие 60 секторов
              pop     cx       ; Восстановить счетчик
              loop    copy     ; Еще раз
              verify  off      ; Наша функция

           endm
               mov    ah,59H
               int    21H
               endm


© KOAP Open Portal 2000



?????? ???????????