Authorization

.model small
.stack
.data
;const's
F_READ  EQU 0
F_WRITE EQU 1
F_RDWR  EQU 2

;messages
dos_    db 'Введите имя DOS-файла: $'
win_    db 'Введите имя WIN-файла: $'
_info   db 10,13,'"DOS-to-WINDOWS" text file converter v1.1',10,13
        db 'Written by Serg Lisin, Russia, 8 September 2002$'
;errormessages
doserr  db 'DOS-файл не найден!$'
ERRlen  db 10,13, 'Длина DOS-файла больше 65535 байт!$'

;variables
DOSfile db 128 dup (?)
WINfile db 128 dup (?)
READbuf db 00
DOShnd  dw ?
WINhnd  dw ?
Fileptr dw 0000
DOSlen  dw 0000
;codepage
cp866   db  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207
        db  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223
        db  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239
        db  32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32
        db  32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32
        db  32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32
        db  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
        db  32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32

.code
start:
main    PROC near
        mov ax,@data
        mov ds,ax
        mov es,ax
        mov ah,03h
        int 10h

        call begdos     ;спросим имя DOS-файла
        mov al,F_READ   ;al -accsess type code "read only"
        call _FDOSopen  ;откроем файл для чтения
        mov [DOShnd],ax ;сохраним дескриптор файла

        mov bx,ax
        call _Flen      ;вычислим длину DOS-файла

        call begwin     ;спросим имя WIN-файла
        mov al,F_WRITE  ;al -access type code "write only"
        call _FWINopen  ;откроем файл для записи
        mov [WINhnd],ax ; и сохраним дескриптор файла

_lop:
        call _FDOSread   ;прочитаем байт,
        call _Convert    ;перекодируем и
        call _FWINwrite  ;запишем байт

        mov  bx,[DOShnd] ;переместим
        mov  dx,[Fileptr];указатель
        call _Fseek      ;на одну позицию в DOS-файле,

        mov  bx,WINhnd   ;и в WIN-файле
        mov  dx,[Fileptr];тоже
        call _Fseek      ;передвинемся

        mov ax,[Fileptr] ;ax -указатель
        mov dx,[DOSlen]  ;dx -длина DOS-файла
        cmp ax,dx        ;сравним
        jz short _exx_   ;если равно тогда выходим в DOS
        inc ax           ;если нет увеличим указатель на 1
        mov [Fileptr],ax ;и поместим его на место
        jmp short _lop   ;уходим на след. виток

_exx_:
        call prtinfo
        mov ah,4Ch
        int 21h

main    ENDP

;---------------------------------------------
;процедуры ввода имен файлов
;---------------------------------------------
begdos  PROC near
        lea dx,dos_    ;Запрос имени DOS-файла
        mov ah,09
        int 21h        ;печать по функции 09h
        lea dx,DOSfile ;dx на буфер
        mov bx,1       ;bx-дескриптор устройства(1-стандартный ввод)
        mov cx,80      ;cx-длина
        mov ah,3Fh     ;3F - DOS service "read from file or device"
        mov al,00
        int 21h        ;call DOS service

        lea di,DOSfile
        mov cx,80
        cld
        mov al,13
        repnz scasb
        mov byte ptr es:[di],00   ;затрем нулями код возврата каретки
        mov byte ptr es:[di-1],00 ;и перевода строки
        ret
begdos  ENDP

begwin  PROC near
        lea dx,win_
        mov ax,0900h
        int 21h
        lea dx,WINfile
        mov bx,1
        mov cx,80
        mov ah,3Fh
        mov al,0
        int 21h
        lea di,WINfile
        mov cx,80
        cld
        mov al,13
        repnz scasb
        mov byte ptr es:[di],00
        mov byte ptr es:[di-1],00
        ret
begwin  ENDP

_FDOSopen PROC near   ;процедура открытия файла
; На входе: al = access type code, DS:DX указывает на имя файла
; На выходе: if CF set we have failed, else ax == Дескриптору файла
         lea dx,ds:[DOSfile]   ; point DS:DX to file name string
         mov ah,3Dh            ; select "open file" DOS service
         int 21h               ; call DOS service
         jnc short fopendone   ; if CF set we have failed

         lea dx,doserr         ;покажем
         mov ah,09h            ;сообщение
         int 21h               ;об ошибке,
         call beep             ;свистнем
         mov ah,4Ch            ;и выйдем в DOS
         int 21h
fopendone:
         ret                   ;если все ОК то вернемся без проблем
_FDOSopen ENDP

_FWINopen PROC near           ;процедура открытия файла
        lea dx,ds:[WINfile]   ;DS:DX на имя файла
        mov ah,3Dh            ;3Dh-"open file" DOS service
        int 21h               ;call DOS service
        jnc short fopendone   ;if CF=1 файл не найден
creatfile:                    ;создадим нов. файл
        mov ah,3Ch            ;3Ch-"create file" DOS service
        mov cx,0              ;
        int 21h               ;call DOS service
        ret
_FWINopen ENDP

_FDOSread PROC near  ;процедура чтения из файла
        lea dx,es:[READbuf]   ;ES:DX на буфер
        mov bx,DOShnd         ;bx- дескриптор файла
        mov cx,1              ;кол-во читаемых байт
        mov ah,3Fh            ;3Fh - "read from file or device" DOS service
        int 21h               ;call DOS service
        ret
_FDOSread ENDP

_Convert PROC near
        xor ax,ax
        mov al,ds:[READbuf]  ;al -код символа (1251)
        push ax
        pop  dx           ;закинем код в bx
        cmp dx,127        ;проверим
        jg  _work         ;если код > 127, тогда обработаем
        ret               ;если меньше, тогда выйдем
_work:
        sub dx,128
        push dx
        pop ax
        lea bx,cp866
        xlatb
        mov ds:[READbuf],al
        ret
_Convert ENDP

_FWINwrite PROC near ;процедура записи в файл
        lea dx,es:[READbuf]   ;ES:DX на буфер
        mov bx,WINhnd         ;bx- дескриптор файла
        mov cx,1              ;число записываемых байт
        mov ah,40h            ;40h -"write file" DOS service
        int 21h               ;call DOS service
        ret
_FWINwrite ENDP

_Fseek  PROC near  ;процедура перемещения указателя чтения/записи
;на входе:  bx= дескриптору файла, al= режиму установки указателя
;           dx= указателю
;на выходе: dx= смещению, куда реально установился указатель

        mov ah,42h
        mov al,0         ;"from start of file" method
        xor cx,cx
        mov dx,Fileptr
        int 21h
        cmp dx,cx
        jz  short thatsok
        call beep
        mov ah,4Ch
        int 21h
thatsok:
        ret
_Fseek  ENDP

_Flen   PROC near  ;процедура определения длины файла
        mov ah,42h ;"move file ptr" DOS service
        mov al,2   ;"from end of file" method
        xor cx,cx  ;cx обнулим
        xor dx,dx   ; и dx тоже
        int 21h
        cmp dx,00
        jnz short _errlen
        mov ds:[DOSlen],ax
        jmp short filelendone
_errlen:
        lea dx,ERRlen
        mov ah,09h
        int 21h
        call beep
        mov ah,4Ch
        int 21h

filelendone:
        mov ah,42h
        mov al,0
        mov dx,Fileptr
        xor cx,cx
        int 21h
        ret
_Flen   ENDP
;---------------------------
beep    PROC near
        mov ax,0E07h
        int 10h
        ret
beep    ENDP
prtinfo PROC near
        lea dx,_info
        mov ah,09h
        int 21h
        ret
prtinfo ENDP
END     start