.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