;             Copyright (c) 1990 by Gurtjak D. ( Donetsk, USSR )
;                             All right reserved.
main	segment	para public;
	assume	cs:main,ds:main
	org	100h

start:  jmp	Install

runflag		db	0
filename	db	30 dup ( 0 )
Flag		db	0
SegDos		dw	0
OfsDos		dw	0
Bf		db	82 dup ( 0 )	; буфер - 1 строка
Col		dw	80

Beep	PROC	NEAR
	cli
	mov	dx,200
lp3:	in	al,61h
	and	al,0feh
ncc:	or	al,2
	out	61h,al
	mov	cx,300
fhl:	loop	fhl
	and	al,0fdh
	out	61h,al
	mov	cx,300
scl:	loop	scl
	dec	dx
	jnz	lp3
	mov	cx,30000
lp2:	loop	lp2
	sti
	ret
Beep	ENDP

WriteFile	PROC	NEAR
;	пишем в файл 1 строку
	push	ax
	push	cx
	push	dx
	push	ds
	push	cs
	pop	ds
	mov	ah,40h
	mov	dx,offset Bf
	int	21h
	pop	ds
	pop	dx
	pop	cx
	pop	ax
	ret
WriteFile	ENDP

;██████████████████████████████████████████████████████
WriteScr	PROC 	NEAR
	mov	ax,40h
	mov	es,ax
	mov	al,es:49h
	and	al,7eh
	cmp	al,3
	jbe	Bp1
	cmp	al,7
	je	Bp1
exit:	ret

Bp1:

;	ОПЕРАЦИИ ЗАПИСИ В ФАЙЛ С ИМЕНЕМ [filename]
;       открываем файл

	cmp	runflag,1
	jne	exit

        mov     ah,3dh
	mov	dx,offset filename
        mov     al,2
	int	21h
        jnc     OkWrt
        mov     ah,3ch
        mov     dx,offset filename
        mov     cx,20h
        int     21h
	jc	exit
OkWrt:
	mov	bx,ax
        mov     ax,4202h                ; в конец файла
        xor     cx,cx
        mov     dx,cx
        int     21h
        jc      Exit

	call	Beep

	call	PushBuf
	call	Beep

CloseFile:
;	закрываем файл
	mov	ah,3eh
	int	21h
	call	Beep

;	модификация имени файла
;        push    di
;        push    es
;        push    cs
;        pop     es
;        mov     di,offset filename
;        mov     al,0
;        cld
;lp111:  scasb
;        jnz     lp111
;        sub     di,2
;l122:   mov     al,es:[di]
;        inc     al
;        cmp     al,'/'          ; '.'+1
;        jne     Extn
;        dec     di
;        jmp     short l122

;Extn:   cmp     al,'Z'
;        ja      Zero
;        cmp     al,'A'
;        jge     No_Zero
;Zero:   mov     al,'A'
;No_Zero:
;        stosb
;        pop     es
;        pop     di

	mov	runflag,0
	ret
WriteScr	ENDP
;████████████████████████████████████████████████████████████
; Пишем экран в буфер

PushBuf		PROC	NEAR
	push	si
	push	di
	push	cx
	push	es
	push	ds

	mov	ax,40h
	mov	es,ax

	mov	ax,0b800h
	cmp	byte ptr es:49h,7
	jne	No_Mono
Mono:	mov	ax,0b000h
No_Mono:
;	Вычисления сегмента видимой страницы
	mov	ds,ax

	mov	dx,es:63h
	mov	al,12
	out	dx,al
	inc	dx
	in	al,dx
	mov	ah,al
	dec	dx
	mov	al,13
	out	dx,al
	inc	dx
	in	al,dx
	mov	cl,4
	shr	ax,cl

	push	ds			; в ds - сегмент видимой страницы
	pop	cx
	add	cx,ax
	mov	ds,cx

	mov	ax,es:4ah
	mov	cs:Col,ax		; число текстов. колонок
	mov	cx,25			; число строк в странице
	mov	al,es:87h
	cmp	al,0
	je	No_EGA			; проверка на EGA
	test	al,8
	jne	No_EGA
;       вычисляем число строк на странице -> cx
	mov	cl,es:84h
	inc	cl

No_EGA:
	mov	si,0
	push	cs
	pop	es
loops:
	mov	di,offset Bf		; si указывает на нач. строки
	push	cx			; сохраняем cx
	push	si			; сохраняем si
	mov	ax,cs:Col
	add	si,ax			; si на конец строки
	add	si,ax
	sub	si,2

	mov	cx,ax
loopc:	dec	cx
	mov	al,[si]
	cmp	al,' '			; идем влево до 1-го не ' ' или 0
	je	space
	cmp	al,0
	jne	No_Space
space:	dec	si
	dec	si
	or	cx,cx
	jne	loopc

	pop	si			; символов в стороке нет
	push    si			; сохраняем si и пишем в буфер
	jmp	short LFCR		; 13,10

No_Space:
					; в cl номер посл. символа в строке
	pop	si			; восст. si - начало строки
	push	si
	cld
	inc	cx
	push	cx
lpmv:					; цикл - копируем строку в буфер
	movsb
	inc	si
	dec	cx
	jnz	lpmv

	pop	cx
	xor	ch,ch

LFCR:	mov	al,13			; пишем 13,10
	stosb
	mov	al,10
	stosb
	add	cx,2
	call	WriteFile

	pop	si
	pop	cx			; восстанавливаем счетчик строк
	add	si,160			; si на следующую сточку
	dec	cx
	jnz	loops

	pop	ds
	pop	es
	pop	cx
	pop	di
	pop	si
	ret


PushBuf		ENDP
;███████████████████████████ INT 09h ██████████████████████████

Int09h		PROC FAR

	pushf
	push	ax
	push	es
	push	ds

	push	cs
	pop	ds

	in	al,60h
	cmp	al,55			; скэн код клавиши
	jne	Oldvec
	cmp	runflag,0
	jne	Oldvec
	mov	ax,40h			; проверяем флаги клавиатуры
	mov	es,ax
	mov	al,es:17h
	test	al,4
	jnz	Init

Oldvec:
	pop	ds
	pop	es
	pop	ax
	popf
	db	0eah			; jump oldvector
OfsOld	dw	0
SegOld	dw	0

	iret

Init:   cli
	in	al,61h
	mov	ah,al
	or	al,80h
	out	61h,al
	xchg	ah,al
	out	61h,al
	mov	al,20h
	out	20h,al

;	сбрасываем экран в буфер

	mov	cs:runflag,1
	sti

the_end:
	pop	ds
	pop	es
	pop	ax
	popf
	iret
Int09h		ENDP
;██████████████████████████ INT 08h ████████████████████████████

Int08h		PROC 	NEAR
		pushf
		db	9ah				; call oldvector
ofs08		dw	0
seg08		dw	0

;		Проверяем статус реентерабельности ДОС
	pushf
	push	ax
	push	bx
	push	cx
	push	dx
	push	ds
	push	es

	push	cs
	pop	ds
	cmp	runflag,0
	je	No_call
	cmp	flag,1
	je	No_call

        sti
	mov	es,segdos	; es:bx -> byte DOS status
	mov	bx,ofsdos
	cmp	byte ptr es:[bx],0
	jne	No_call
	mov	flag,1
	sti
	call	WriteScr
	mov	flag,0
no_call:
	pop	es
	pop	ds
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	popf
	iret
Int08h		ENDP

;█████████████████████████████ INT 28h █████████████████████████████

Int28h		PROC  NEAR
	pushf
	cmp	cs:flag,1
	je	old28h
	cmp	cs:runflag,1
	je	Ok28

Old28h:	popf
	db	0eah		; jump oldvector
Ofs28	dw	0
Seg28	dw	0

Ok28:
	push	ds
	push	es
	push	ax
	push	bx
	push	cx
	push	dx

	push	cs
	pop	ds
	mov	flag,1
	sti
	call	WriteScr
	mov	flag,0
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	pop	es
	pop	ds
	jmp	short	old28h
Int28h		ENDP

;█████████████████████████████ INT 2Fh █████████████████████████
Int2Fh		PROC	NEAR
;Мультиплексорное прерывание ДОС
;Если в ah=90h возвращает
;al=0ffh если программа есть в памяти, es:di - адрес filename
	cmp	ah,90h
	je 	My_Int
	db	0eah		; jump oldvector
Ofs2F	dw	0
Seg2F	dw	0

My_Int:	push	cs
	pop	es
	mov	di,offset filename
	mov	al,0ffh
	iret
Int2Fh		ENDP


;███████████████████████████████████████████████████████████████

install:
	push	cs
	pop	ds
        mov     si,offset Titl
        mov     bp,offset Titl1

        xor     bl,bl
unc1:	lodsb
	add	bl,al
        cmp     si,bp
	jbe	unc1

ContrS  equ     045h

        cmp     bl,ContrS

	je	OkCmp
	int	20h
OkCmp:
        mov     ax,9000h
	int	2fh
	cmp	al,0ffh
	je	Olr_Inst

	mov	runflag,0
	mov	flag,0
	mov	ah,34h
	int	21h
	mov	segdos,es
	mov	ofsdos,bx
	mov	ax,3509h
	int	21h
	mov	SegOld,es
	mov	OfsOld,bx
	mov	ax,2509h
	mov	dx,offset Int09h
	int	21h

	mov	ax,3508h
	int	21h
	mov	Seg08,es
	mov	Ofs08,bx
	mov	ax,2508h
	mov	dx,offset Int08h
	int	21h

	mov	ax,3528h
	int	21h
	mov	Seg28,es
	mov	Ofs28,bx
	mov	ax,2528h
	mov	dx,offset Int28h
	int	21h

	mov	ax,352Fh
	int	21h
	mov	Seg2F,es
	mov	Ofs2F,bx
	mov	ax,252Fh
	mov	dx,offset Int2Fh
	int	21h

	push	cs
	pop	es

	mov	di,offset filename
	call	ReadPar

	mov	ah,9
	mov	dx,offset titl
	int	21h

	lea	dx,Install
	int	27h

Olr_Inst:			; программа уже сидит в памяти
	call	ReadPar
	mov	ah,9
	mov	dx,offset titl1
	int	21h

	int	20h

ReadPar		PROC	NEAR

;	очередной параметр из ком.строки (bx) -> es:di
;	оканчивается 0.
	mov	bx,81h
	push	di
scan1:	mov	cx,bx
	sub	cx,81h
	mov	bp,80h
	cmp	cl,[bp]
	jge	exit_sc
	mov	al,[bx]
	inc	bx
	cmp	al,' '
	jz	scan1
	cmp	al,'\'
	jbe	BigChar
	sub	al,'a'-'A'

BigChar:
	stosb
	jmp	short scan1
exit_sc:
	xor	al,al
	stosb
	pop	di
	cmp	byte ptr es:[di],0
	jne	Pr_File
No_File:
	mov	cx,11
	mov	di,offset filename
	mov	si,offset file
	repe	movsb

Pr_File:
	ret

ReadPar		ENDP


File	db	'SCREEN.TXT',0

titl	db	13,10
	db	' Программа копирования экрана в файл.',13,10
	db	' Имя файла указывается в командной строке',13,10
        db      ' ( по умолчанию - файл SCREEN.TXT в текущем каталоге )',13,10
	db	' Инициализация программы : <Ctrl> + PrtScr',13,10,13,10
        db      ' Версия 1.1  от  29 августа 1990 года.',13,10
        db      ' Автор :  Гуртяк Д. ( г. Донецк )',13,10
	db	'$'
titl1	db	13,10,' Программа копирования экрана'
	db	' в файл уже есть в памяти',13,10
	db	' Текущее имя файла изменено',13,10,'$'


main	ENDS
	end	start