CODE SEGMENT
ASSUME CS:CODE

	org 80h
	cmd_lenght db ?
	cmd_line   db ?
	org 100h
	start1:

	


jmp InitPart

;Процедура обработчик 21h прерывания
;Входные параметры: ah - номер функции
;Выходные значения: flags
;Изменяемые регистры: flags
Int21hProc proc FAR
	pushf		;так как комманда iret востановит флаги из стека 
	
	cmp ah, 0Bh	; Проверка принадлежности фунукции к определенной группе
	jb Good
	inc byte ptr cs:[busy21h]
	jmp notGood
Good:	
	db 9ah 
	OldInt21h dw ?,?
	retf 2
	
notGood:	
	call dword ptr cs:[OldInt21h]
	pushf
	dec byte ptr cs:[busy21h]
	
	cmp byte ptr cs:[FlagVizov], 0
	je ExitWithoutVizov
	jmp DoRealSaving	
ExitWithoutVizov:
	popf
	retf 2
	
	
busy21h db 0	
Int21hProc ENDP

;Процедура обработчик 09h прерывания
;Входные параметры: нет
;Выходные значения: нет
;Изменяемые регистры: нет

Int09hProc PROC FAR		; Начало резедентной части 

	push ax
	push bx
	push cx
	push dx	
	push ds
	push es
	push si
	push di
	push bp
	
	
	
	

	

	mov ax, 40h
	mov es, ax
	mov di, es:[1Ch]
	pushf 
	call dword ptr cs:[OldInt09h]
	
	cmp di, es:[1Ch]
	jz TempLabel
	cmp byte ptr es:[di+1], 20h
	jnz TempLabel
	mov al, es:[17h]
	and al, 0Fh
	cmp al, 00000100b
	jnz TempLabel
	mov es:[1Ch], di
	

	

	
	
	
	
	mov ah, cs:byte ptr FlagWork	; Проверка флага выполнения действий
	cmp ah, 0 
	je DoSaving
	jmp EndOfProg
	

	
TempLabel:
	jmp EndOfProg

DoSaving:	
	mov ah, cs: byte ptr Flag21h	; Проверка флага занятости 21h прерывания
	cmp ah, 0
	je DoRealSaving
	inc cs: byte ptr FlagVizov	; Установка флага отложеного вызова
	jmp EndOfProg
	
	
DoRealSaving:	
	inc cs:byte ptr FlagWork	
	
	
	mov ah, 3Ch		; Создание файла
	mov cx, 0
	push cs
	pop ds
	mov dx, offset FileName
	int 21h
	
	mov bx, ax		; В bx - идентификатор файла
	
	
	

	
	
	
	
	
	
	
	
	
	
	
	call WindowSaveProc
	call WindowDrawProc
	call MessagesDrawProc

	push ax
	push bx
	push dx
	
	mov ah, 02h		; Установка курсора на 1 строку окна
 	mov bh, 0
 	mov dl, 44
 	mov dh, 11
 	int 10h
 	
 	pop dx
 	pop bx
 	pop ax
 	
 		
	call NewInputAddresProc	; получить первый адресс (ds:si)
	cmp ax, 0
	je EscEndOfProg
	push di
	push es

	push ax
	push bx
	push dx
	
	mov ah, 02h		; Установка курсора на 3 строку окна
 	mov bh, 0
 	mov dl, 44
 	mov dh, 13
 	int 10h	
	
 	pop dx
 	pop bx
 	pop ax
	
	call NewInputAddresProc      ; получить второй адресс (es:di)
	pop ds
	pop si
	cmp ax, 0
	je EscEndOfProg
	
	call TestAdressProc		; Проверка корректности ввода адресов
	cmp ax, 1
	jne GoodAdreses
	;mov ah, 09
	;mov dx, offset MesBadAdr
	;push ds
	;push cs
	;pop ds
	;int 21h
	;pop ds
	jmp EscEndOfProg		; Неправильный ввод адрессов
	
GoodAdreses:	

	call ZapisProc
	
EscEndOfProg:			; Восстановление старого обработчика прерывания
	call WindowRestoreProc
EndOfProgWithFlag:	
	dec cs:byte ptr FlagWork
EndOfProg:


	
	pop bp
	pop di
	pop si
	pop es
	pop ds
	pop dx
	pop cx
	pop bx
	pop ax
	iret
	
FlagWork db 0		; Флаг действий
MesBadAdr db "Bad Address$"	
Flag21h db 0		; Флаг занятости прерывания 21h
FlagVizov db 0		; Флаг отложеного вызова

Int09hProc ENDP	













;Процедура сохранения области экрана под нашим окном размером 3Х30
;в переменные OldMes1, OldMes2 и OldMes3 
;Входные параметры: нет
;Выходные значения: сохраненые строки в указанных переменных
;Изменяемые регистры: нет

WindowSaveProc PROC ;FAR
	push ax
	push bx
	push cx
	push dx
	push di
	push si
	 

mov di, offset OldMes1
mov si, 0
mov dl, 20
mov dh, 11
	mov cx, 0

SaveLoop:
	mov ah, 02h
	mov bh, 0
	int 10h

	mov ah, 08h
	mov bh, 0
	int 10h

	mov byte ptr cs:[di], al
	inc di
	mov byte ptr cs:[di], ah
	inc di
	inc dl
	inc si
	cmp si, 30
	jne SaveLoop
	inc cx
	
	mov di, offset OldMes2
	mov dl, 20
	mov si, 0
	inc dh
	cmp cx, 1
	je SaveLoop
	mov di, offset OldMes3
	cmp cx, 2
	je SaveLoop
	
	pop si
	pop di
	pop dx
	pop cx
	pop bx
	pop ax
	ret 

WindowSaveProc ENDP


	




	

;Процедура вывода на экран окна
;Входные параметры: нет
;Выходные значения: нет
;Изменяемые регистры: нет

WindowDrawProc PROC ;FAR

	push ax
	push bx
	push cx
	push dx
	
	
	
	mov dh, 11
Window:
 	mov ah, 02h
 	mov bh, 0
 	mov dl, 20
 	int 10h	
	mov ah, 9h
	mov al, 32
	mov bl, 00011111b
	mov cx, 30
	int 10h
	inc dh
	cmp dh, 14
	jne Window
	
	pop dx
	pop cx
	pop bx
	pop ax
	ret 
WindowDrawProc ENDP	
	
	
	
	
;Процедура вывода в окно на строки 1 и 2 сообщений из пременых
;message1, message2
;Входные параметры: нет
;Выходные значения: нет
;Изменяемые регистры: нет	
	
MessagesDrawProc PROC ;FAR
	push ax
	push bx
	push cx
	push dx
	push bp
	push es
	
	push cs
	pop es
	mov ah, 13h
	mov al, 0
	mov cx, 21
	mov bl, 00011111b
	mov dh, 11
	mov dl, 21
	mov bp, offset message1
	int 10h
		
	mov ah, 13h
	mov al, 0
	mov cx, 21
	mov bl, 00011111b
	mov dh, 13
	mov dl, 21
	mov bp, offset message2
	int 10h
	
	pop es
	pop bp	 
	pop dx
	pop cx
	pop bx
	pop ax
	ret
MessagesDrawProc ENDP


;Процедура восстановления области экрана 
;использованой для вывода окна
;Входные параметры: нет
;Выходные значения: нет
;Изменяемые регистры: нет	

WindowRestoreProc PROC ;FAR
	push bp
	push es
	push ax
	push cx
	push dx
	push es
	 
	mov dh, 11
	mov bp, offset Oldmes1
	push cs
	pop es
	mov ah, 13h
	mov al, 00000010b
	mov cx, 30
	mov dl, 20
	int 10h
	
	mov dh, 12
	mov bp, offset Oldmes2
	push cs
	pop es
	mov ah, 13h
	mov al, 00000010b
	mov cx, 30
	mov dl, 20
	int 10h
	
	mov dh, 13
	mov bp, offset Oldmes3
	push cs
	pop es
	mov ah, 13h
	mov al, 00000010b
	mov cx, 30
	mov dl, 20
	int 10h
	
	pop es
	pop dx
	pop cx
	pop ax
	pop es
	pop bp
	ret

WindowRestoreProc ENDP


;Процедура вывода в окно на строки 1 и 2 сообщений из пременых
;message1, message2
;Входные параметры: нет
;Выходные значения: нет
;Изменяемые регистры: нет	
NewInputAddresProc PROC ;FAR

	push bx
	push cx
	push dx
	push ds
	push si

	
	mov di, 0   ; Здесь лежит адресс
	mov si, 0   ; Кол-во введенных символов
	mov cx, 16
	
	push cs
	pop ds
	
newSymbolNEW:
	
	cmp si, 4
	jne SavedOffsetNEW

	push di
	pop es
	mov di,0
SavedOffsetNEW:	
	cmp si, 5	
	je TempLabel1
	
	mov ah, 10h
	int 16h
	cmp ah, 01h
	je TempLabel2
		;	al - ASCII считаный символ
		;	ah - скан-код клавиши
	
	cmp al, '0'
	jb newSymbolNEW       ;- ?????? ????
	cmp al, '9'
	ja NumeralNEW
	sub al, '0'        ;- ???? ?????
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	mov ah, 0
	add di, ax
	add al, '0'
OutPutNEW:
	mov dl, al
	mov ah, 02h
	int 21h
	inc si

	

	jmp newSymbolNEW
	
TempLabel1:
	jmp EndScanNEW		
TempLabel2:
	jmp ESCExit		
	;??????? ?? ?????	
	 
	
	
	
	
NumeralNEW:
	cmp ah, 1Eh	;A
	je A
	
	cmp ah, 30h	;B
	je B
	
	cmp ah, 3Eh	;C
	je C
	
	cmp ah, 20h	;D
	je D
	
	cmp ah, 12h	;E
	je E
	
	cmp ah, 21h	;F
	je F
	
	jmp newSymbolNew
	
A:
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	add di, 0Ah
	mov al, 41h
	jmp OutPutNEW
	
B:
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	add di, 0Bh
	mov al, 42h
	jmp OutPutNEW

C:
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	add di, 0Ch
	mov al, 43h
	jmp OutPutNEW

D:
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	add di, 0Dh
	mov al, 44h
	jmp OutPutNEW

E:
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	add di, 0Eh
	mov al, 45h
	jmp OutPutNEW

F:
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	add di, 0Fh
	mov al, 46h
	jmp OutPutNEW
	
ESCExit:
	mov ax, 0

	
EndScanNEW:

	pop si
	pop ds
	pop dx
	pop cx
	pop bx
	ret



NewInputAddresProc ENDP


 ;возврашает в es:di
InputAddresProc PROC ;FAR




	push ax
	push bx
	push cx
	push dx
	push ds
	push si
	
	
	
	
	
	

	
	mov di, 0   ; ????? ????? ??????
	mov si, 0   ; ???-?? ????????? ????????
	mov cx, 16
	
	push cs
	pop ds
	;mov dx, offset Message1
	;mov ah, 9
	;int 21h
newSymbol:
	
	cmp si, 4
	jne SavedOffset

	push di
	pop es
	mov di,0
SavedOffset:	
	cmp si, 5	
	je EndScan
	mov ah, 07h
	int 21h
	
;	al -------- считаный символ??????
	
	cmp al, '0'
	jb newSymbol       ;- ?????? ????
	cmp al, '9'
	ja Numeral
	sub al, '0'        ;- ???? ?????
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	mov ah, 0
	add di, ax
	add al, '0'
OutPut:
	mov dl, al
	mov ah, 02h
	int 21h
	inc si

	

	jmp newSymbol
		
	
	;??????? ?? ?????	
	 
	
	
	
	
Numeral:
	cmp al, 'A'	
	jb newSymbol
	cmp al, 'F'
	ja NewSymbol
	
	sub al, '7'       ;- ???? ?????
	push ax
	mov ax, di
	mul cx
	mov di, ax
	pop ax
	mov ah, 0
	add di, ax
	add al, '7'
	jmp OutPut
	
EndScan:
	pop si
	pop ds
	pop dx
	pop cx
	pop bx
	pop ax


	
	
	ret
InputAddresProc ENDP


TestAdressProc PROC  ;FAR
	push cx
		
	mov ax, ds
	mov cx, es
	
	cmp ax, cx
	ja ErrorAdress
	je TestOffset
	jb GoodAdress
	
	
TestOffset:
	cmp si, di
	ja ErrorAdress
	
GoodAdress:
	pop cx
	ret
ErrorAdress:
	mov ax, 1
	pop cx
	ret
	
TestAdressProc ENDP



ZapisProc PROC  ;FAR




	mov cx, ds	;ds:si -1  cx
	mov dx, es	;es:di -2  dx
	
	
	cmp cx, dx
	je OneSegment
	
	
nextChar1:	
	mov al, ds:[si]
	mov byte ptr cs:[Buffer], al
	
	mov dx, offset Buffer
	push ds
	push cs
	pop  ds
	mov ah, 40h
	mov cx, 1
	int 21h
	pop ds
	
	inc si
	cmp si, 10h
	jne SameSegment
	mov si, 0 
	push bx
	mov bx, ds
	inc bx
	mov ds, bx
	pop bx
	mov cx, ds
	mov dx, es
	cmp cx, dx
	je LastSegment
	jmp nextChar1
	
	
SameSegment:
	jmp nextChar1
		
LastSegment:
	cmp si, di	
	ja EndOfZapis
	
	mov al, ds:[si]
	mov byte ptr cs:[Buffer], al
	
	mov dx, offset Buffer
	push ds
	push cs
	pop  ds
	mov ah, 40h
	mov cx, 1
	int 21h
	pop ds
	inc si
	jmp LastSegment


OneSegment:
	sub di, si
	push bx
	mov bx, cs; ds - no
	mov ds, bx
	pop bx
	
nextChar:
	mov al, es:[si]
	mov byte ptr cs:[Buffer], al
	inc si
	;push si

	mov dx, offset Buffer
	
	mov ah, 40h
	mov cx, 1
	int 21h
	;pop si
	dec di
	cmp di, -1
	je endOfZapis
	jmp nextChar

endOfZapis:
	
	
	
	mov ah, 3Eh; ??????? ????
	int 21h
	
	
	
	
	ret
	
	;mov ax, 4c00h ; ????? ?????
	;int 21h
	
	

	
	
ZapisProc ENDP

OldInt09h DW ?,?
ComLineMes db "Command line error$"	
message1 db "Input first address: $"
message2 db "Input second address: $"
FileName    db  20 dup(?)
OldMes1 db  60 dup(?),"$"
OldMes2 db  60 dup(?),'$'
OldMes3 db  60 dup(?),'$'

Buffer label byte

int09Flag dw 0

Int2FhProc PROC FAR
	cmp 	ax, ChisloA
	jne 	@@Exit2
	cmp 	dx, ChisloB
	jne 	@@Exit2
	mov 	ax, ChisloC
	mov 	dx, ChisloD
	iret
@@Exit2:
	
	pushf
	call 	dword ptr cs:[OldInt2Fh]
	iret
OldInt2Fh DW ?,?;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Int2FhProc ENDP


ChisloA 	EQU 99AAh
ChisloB 	EQU 0BBCCh
ChisloC 	EQU 0DDEEh
ChisloD 	EQU 0FF00h








;Главная нерезидентная часть программы: InitPart
;Входные параметры: нет
;Выходные значения: нет



InitPart:

;проверка загружена или нет программа	
	mov		ax, ChisloA
	mov		dx, ChisloB
	int		2Fh
	cmp		ax, ChisloC
	jne		FileOperations
	cmp		dx, ChisloD
	jne		FileOperations
	mov		ah, 9
	mov		dx, offset AlreadyResident
	push		cs
	pop		ds
	int		21h
	mov		ax, 4C01h
	int		21h



FileOperations: 			; Разбор командной строки

	mov		cl, cmd_lenght
	cmp		cl, 1		; Нет параметра
	jle		ComLineError
	;mov si, offset FileName
	push		cs
	pop		ds
	;ПО МОЕМУ mov es,ds
	mov		di, offset cmd_line
FindParam:
	mov		al, ' '   	; Ищем первый не пробел
	repz		scasb		; т.е. ищем начало параметра
	dec 		di 		
	push 		di
			
ScanParam:				; выделяем параметр
	inc 		di
	;mov 		si, di
	mov 		al, es:[di]
	;mov byte ptr 		ds:[si], al
	;inc si
	cmp 		al, 0Dh         	; Возврат каретки - конец командной строки
	je 		ParamsEnded
	cmp 		al, 20h		; Если пробел - значит несколько параметров
	je 		ComLineError	; Значит вкралась ошибка
	jmp 		ScanParam
ParamsEnded:
	mov 		byte ptr es:[di], 0 ; Для работы с файлами нужна ASCIZ - строка
	mov 		ax, di		; В AX конец параметра
	
	mov 		si, offset FileName
	push 		cs
	pop 		ds
	pop 		di		;в DI начало параметра
	
FNameSAveLoop:

	mov 		bl, byte ptr es:[di]
	mov 		byte ptr ds:[si], bl
	inc 		si
	inc 		di	
	cmp 		di, ax
	jle 		FNameSAveLoop
	
	
	
		
	
	;mov ah, 3Ch	; Создать новый файл ( или перезаписать имеющийся)
	;mov CX, 0
	;pop di
	;mov dx, di 
	;int 21h
	;mov bx, ax	; bx - идентификатор файла
	
	
	
	
	jmp 		NoResident
	
	
	
	
ComLineError:
	push 		cs
	pop		ds
	mov 		ah, 09h
	mov 		dx, offset ComLineMes
	int 		21h 
	mov 		ax, 4c00h	; Конец программы из-за ошибки командной строки
	int 		21h		
	


	


NoResident:		; Загрузка обработчиков прерываний
	MOV		ax, 0
	mov 		es, ax
	mov 		ax, es:[09h*4]
	mov 		OldInt09h, ax
	mov 		ax, es:[09h*4 + 2]	
	mov 		OldInt09h + 2, ax

	mov 		ax, es:[2Fh*4]
	mov 		OldInt2Fh, ax
	mov 		ax, es:[2Fh*4+2]
	mov 		OldInt2Fh + 2, ax
	
	mov 		ax, es:[21h*4]
	mov 		OldInt21h, ax
	mov 		ax, es:[21h*4+2]
	mov 		OldInt21h + 2, ax

	
	
	cli
	mov 		word ptr es:[09h*4], offset Int09hProc
	mov 		word ptr es:[09h*4+2], cs
		
	mov 		WORD PTR es:[2Fh*4], offset Int2FhProc
	mov 		WORD PTR es:[2Fh*4+2], cs
	
	mov 		WORD PTR es:[21h*4], offset Int21hProc
	mov 		WORD PTR es:[21h*4+2], cs
	sti
	

	
	mov 		ah, 09h
	mov 		dx, offset StayResident
	push		cs
	pop 		ds
	int 		21h

	mov 		dx, offset InitPart
	int 		27h




	
	
		
	


StayResident db "Program loaded now$"
AlreadyResident db "Program already loaded$"
CODE ENDS
	end start1
;ошибки в 25 35 139 140 141 158 178 184 198 201 766 801 824 949 1026		
 