;	DISPLAY "Low-print-2."
;==============================================================
;
;	Программа LOW PRINT for Sprinter-97.
;
;==============================================================

;=============================================================
;	Функции Bios Sprinter-97.
;	Рабочая версия 29.05.97
;=============================================================
; LP_OPEN_WIN 	Открытие окна
; point 3D13h C=80h	Вход:	B - код окна.
;	B=0 - Spectrum 32x24	B=1 - Spectrum 64x24
;	B=2 - Spectrum 40x24	B=3 - Spectrum 80x24
;			Выход: DE - размер окна
;=============================================================
; LP_PRINT_ALL 	Вывод символов на экран с текущего знакоместа
; point 3D13h C=81h	Вход:	A - символ,
;				B - число выводимых символов,
;				Е - атрибут символа
;=============================================================
; LP_PRINT_SYM 	Вывод символов на экран с текущего знакоместа
;		без атрибута
; point 3D13h C=82h	Вход:	A - символ,
;				B - число выводимых символов,
;=============================================================
; LP_PRINT_ATR 	Вывод атрибутов на экран с текущего знакоместа
; point 3D13h C=83h	Вход:	B - число выводимых символов,
;				Е - атрибут символа
;=============================================================
; LP_SET_PLACE 	Установка текущего знакоместа
; point 3D13h C=84h	Вход:	E - знакоместо по горизонтали
;				D - знакоместо по вертикали
;=============================================================
; LP_PRINT_LN	Вывод строки символов на экран с текущего
;		знакоместа
; point 3D13h C=85h	Вход:	HL - адрес строки
;				B - число выводимых символов,
;				Е - атрибут символов
;=============================================================
; LP_PRINT_LN2 	Вывод строки символов на экран с текущего
;		знакоместа без атрибутов
; point 3D13h C=86h	Вход:	HL - адрес строки
;				B - число выводимых символов,
;=============================================================
; LP_PRINT_LN3	Вывод строки символов на экран с текущего
;		знакоместа
; point 3D13h C=87h	Вход:	HL - адрес строки
;				B - число выводимых символов,
;				D - разделитель
;				Е - атрибут символов
;=============================================================
; LP_PRINT_LN4	Вывод строки символов на экран с текущего
;		знакоместа без атрибутов
; point 3D13h C=88h	Вход:	HL - адрес строки
;				B - число выводимых символов,
;				D - разделитель
;=============================================================
; LP_CLS_WIN	Очистка окна экрана
; point 3D13h C=89h	Вход:	DE - положение окна
;				B - атрибут очистки
;				H - высота, L - ширина
;=============================================================
 MACRO TEST_40
	;[x] включил 31/10/23, чисто на Хэллоууууииин
	 EX AF,AF'
	 JR C,.LLL
	 INC D	; режим 40
.LLL:	 EX AF,AF'
	;
 ENDM

 MACRO DJ_NEXT_HL
	; DEC B
	; CALL Z,LP_NEXT_HL
	DJNZ .LLL
	CALL LP_NEXT_HL
.LLL:
 ENDM



 MACRO LP_OPEN_PG
	IN A,(SLOT3)
	LD C,A
	LD A,SYS_PAGE
	OUT (SLOT3),A

	LD A,C
	LD (SYS_PAGE.COPY_SLOT3),A
	IN A,(PORT_Y)
	LD (SYS_PAGE.COPY_RGADR),A
 ENDM

 MACRO LP_CLOSE_PG
        LD A,(SYS_PAGE.COPY_RGADR)
        OUT (PORT_Y),A
        LD A,(SYS_PAGE.COPY_SLOT3)
        OUT (SLOT3),A
 ENDM


;*********************************
;*      LOW LEVEL PRINTER        *
;*      DE' - ZG                 *
;*      HL' - PLACE ON SCR       *
;*       C' - ATTRIBUTES         *
;*       B' - COUNT SYMBS        *
;*      ZF  - inverse            *
;*      AF' - страница и mode    *
;*********************************

 MACRO LP_BEG_PM
        EX AF,AF'
        EXX
        IN A,(SLOT3)
        LD C,A
        IN A,(PORT_Y)
        LD B,A

        LD A,SYS_PAGE
        OUT (SLOT3),A
        LD (SYS_SP),SP
        LD SP,SYS_SP
        PUSH BC

        LD HL,(WIN_ID_0.HL)
        LD DE,(WIN_ID_0.DE)
        LD BC,(WIN_ID_0.BC)

        LD A,E
        AND A
        RRA
	OUT (PORT_Y),A
        EXX
        EX AF,AF'
 ENDM

 MACRO LP_END_PM
        EX AF,AF'
        EXX
        RLA
        LD E,A
        LD (WIN_ID_0.HL),HL	; место печати
        LD (WIN_ID_0.DE),DE
        LD (WIN_ID_0.BC),BC

        POP BC
        LD A,B
        OUT (PORT_Y),A
        LD A,C
        OUT (SLOT3),A

        LD SP,SYS_SP
        EXX
        EX AF,AF'    
        RET
 ENDM

;
;------------------------------------------------------------------[#81]
LP_PRINT_ALL:
	CALL LP_BEG_P
	EXX
	 LD C,A
	EXX
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	LD A,D
	OUT (PORT_Y),A
	INC D
.cont:	LD (HL),C
	EXX
	LD A,E
	EXX
	INC L
	LD (HL),A
	DEC L
	 TEST_40	;[x] включил 31/10/23, чисто на Хэллоууууииин
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

	JP	LP_END_P
;------------------------------------------------------------------[#81]
;

;
;------------------------------------------------------------------[#82]
LP_PRINT_SYM:
	CALL LP_BEG_P
	EXX
	 LD C,A
	EXX
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	LD A,D
	OUT (PORT_Y),A
.cont:	LD (HL),C
	INC D
	 TEST_40
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

	JP	LP_END_P
;------------------------------------------------------------------[#82]
;

;
;------------------------------------------------------------------[#83]
LP_PRINT_ATR:
	CALL LP_BEG_P
	LD A,E
	EXX
	 LD C,A
	EXX
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	LD A,D
	OUT (PORT_Y),A
	INC D
	INC L
	LD (HL),C
	DEC L
	 TEST_40
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

	;LD A,SYS_PAGE
	;OUT (SLOT3),A
	JP	LP_END_P
;------------------------------------------------------------------[#83]
;

;
;------------------------------------------------------------------[#85]
LP_PRINT_LINE:
	CALL LP_BEG_P
	EXX
	 LD C,PORT_Y
	EXX
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	OUT (C),D
	INC D
	EXX
	LD A,(HL)
	INC HL
	EXX
	LD (HL),A
	EXX
	LD A,E
	EXX
	INC L
	LD (HL),A
	DEC L
	 TEST_40
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

	;LD A,SYS_PAGE
	;OUT (SLOT3),A
	JP	LP_END_P
;------------------------------------------------------------------[#85]
;

;
;------------------------------------------------------------------[#86]
LP_PRINT_LINE2:
	CALL LP_BEG_P
	EXX
	 LD C,PORT_Y
	EXX
	LD A,#50
	OUT (SLOT3),A

.loop:	LD A,(HL)
	INC HL
	EXX
	OUT (C),D
	INC D
	LD (HL),A
	 TEST_40
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

	;LD A,SYS_PAGE
	;OUT (SLOT3),A
	JP	LP_END_P
;------------------------------------------------------------------[#86]
;

;
;------------------------------------------------------------------[#87]
LP_PRINT_LINE3:
	CALL LP_BEG_P
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	LD A,D
	OUT (PORT_Y),A
	INC D
	EXX
	LD A,(HL)
	INC HL
	CP D
	JR NZ,.NoEnd
	DEC HL
	;!TEST
	 ;LD A,' '
	 EXX
	 LD	C,' '
	 JP	LP_PRINT_ALL.cont
	;
.NoEnd:	EXX
	LD (HL),A
	EXX
	LD A,E
	EXX
	INC L
	LD (HL),A
	DEC L
	 TEST_40
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

	JP	LP_END_P
;------------------------------------------------------------------[#87]
;

;
;------------------------------------------------------------------[#88]
LP_PRINT_LINE4:
	CALL LP_BEG_P
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	LD A,D
	OUT (PORT_Y),A
	EXX
	LD A,(HL)
	INC HL
	CP D
	JR NZ,.NoEnd
	DEC HL
	;!TEST
	 ;LD A,' '
	 EXX
	 LD	C,' '	 
	 JP	LP_PRINT_SYM.cont
	;
.NoEnd:	EXX
	LD (HL),A
	INC D
	 TEST_40
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

	JP	LP_END_P
;------------------------------------------------------------------[#88]
;

;
;------------------------------------------------------------------[#8B]
LP_PRINT_LINE5:
	CALL LP_BEG_P
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	LD A,D
	OUT (PORT_Y),A
	EXX
	LD A,(HL)
	INC HL
	CP D
	;!TEST
	 ;JR Z,.exit
	 JR Z,LP_END_P
	;
	EXX
	LD (HL),A
	EXX
	LD A,E
	EXX
	INC L
	LD (HL),A
	DEC L
	INC D
	 TEST_40
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

.exit:	;JP	LP_END_P
;------------------------------------------------------------------[#8B]
LP_END_P:		; !!!!! ожидается, что портятся только альтернативные регистры и те, что как параметры на входе
	LD A,SYS_PAGE
	OUT (SLOT3),A
.SYS_PAGE:	
        EX AF,AF'
        EXX
         RLA
         LD E,A
	 LD (WIN_ID_0.reg_HL),HL	; место печати
	 LD (WIN_ID_0.reg_DE),DE
	 LD (WIN_ID_0.reg_BC),BC
	 LP_CLOSE_PG
        EXX
        EX AF,AF'
	AND A
        RET
.short:	EX AF,AF'
        EXX
	LP_CLOSE_PG
        EXX
        EX AF,AF'
	AND A
        RET
;

;
;------------------------------------------------------------------[#8C]
LP_PRINT_LINE6:
	CALL LP_BEG_P
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	LD A,D
	OUT (PORT_Y),A
	EXX
	LD A,(HL)
	INC HL
	CP D
	;!TEST
	 ;JR Z,.exit
	 JR Z,LP_END_P
	;
	EXX
	LD (HL),A
	INC D
	 TEST_40
	 DJ_NEXT_HL
	EXX
	DJNZ .loop

.exit:	JP	LP_END_P
;------------------------------------------------------------------[#8C]
;






;
;------------------------------------------------------------------[#84]
LP_SET_PLACE: ; портятся только альтернативные регистры и те, что как параметры на входе
	CALL	LP_BEG_P
	CALL	LP_AT_D
	CALL	LP_TAB_E
	JP	LP_END_P.SYS_PAGE
;------------------------------------------------------------------[#84]
;

;
;------------------------------------------------------------------[#8E]
LP_GET_PLACE:
	CALL LP_BEG_P

	LD A,(WIN_ID_0.H_BEG)
	NEG
	EXX
	 ADD A,D
	EXX
	LD E,A

	LD A,(WIN_ID_0.V_BEG)
	NEG
	EXX
	 ADD A,L
	 DEC A
	EXX
	RRCA
	RRCA
	AND %0011'1111
	LD D,A
	
	JP LP_END_P.short
;------------------------------------------------------------------[#8E]
;

;
;-------------------------------------------------------------[#89, #8D]
;--------------------------------------------------------[#89]
LP_CLS_WIN:
	LD	C,' '
	JR	CLS_WIN
;--------------------------------------------------------[#89]
;--------------------------------------------------------[#8D]
LP_CLS_WIN2:
	LD	C,A
	;JR	CLS_WIN
;--------------------------------------------------------[#8D]
CLS_WIN: CALL	LP_BEG_P
	LD	(SYS_PAGE.SYS_WORK1),BC	; сохранить цвет
	PUSH	DE

.loop1:	CALL	LP_AT_D
        CALL	LP_TAB_E
	PUSH	DE
	EXX
	 LD	BC,(SYS_PAGE.SYS_WORK1)
	EXX
	LD	B,L
	LD	A,#50
	OUT	(SLOT3),A

.loop2:	EXX
	 LD	A,D
	 OUT	(PORT_Y),A
	 LD	(HL),C
	 INC	L
	 LD	(HL),B
	 DEC	L
	 INC	D
 	EXX
	DJNZ	.loop2

	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	POP	DE
	INC	D
	DEC	H
	JR	NZ,.loop1

	POP	DE
        CALL	LP_AT_D
        CALL	LP_TAB_E
	JP	LP_END_P.SYS_PAGE
;-------------------------------------------------------------[#89, #8D]
;

;
;------------------------------------------------------------------[#B8]
WIN_GET_ZG:	; DE - адрес куда переслать фонт
	LD HL,ZG_ADDRESS
	LD BC,#0800
	LDIR
	AND A
	RET
;------------------------------------------------------------------[#B8]
;

;
;------------------------------------------------------------------[#B6]
WIN_SET_ZG:								; LP_SET_ZG:
	EX	AF,AF'
	EXX
	  LP_OPEN_PG
   	 CALL	.SET		;LP_SET_ZG1
	  LP_CLOSE_PG
	EXX
	EX	AF,AF'
	AND	A
	RET
.SET:	IN	A,(SLOT1)
	LD	(SYS_PAGE.COPY_SLOT1),A
	LD	A,SHARED_PAGE
	OUT	(SLOT1),A
	EXX
	 LD	BC,Port_All_Mode
	 IN	A,(C)
	 LD	(SYS_PAGE.SYS_WORK1),A
	 AND	#FE			; Spectrum Screen on, accelerator and keyboard interrupt off
	 OUT	(C),A
	 EX	AF,AF'
	 LD	B,A
	 AND	#0F
	 ADD	A,A
	 OUT	(PORT_Y),A
	 LD	A,B
	 RRCA
	 RRCA
	 RRCA
	 AND	#18
	 OR	#40
	 LD	H,A
	 LD	L,0
	 LD	BC,#0800	;!HARDCODE
	 EX	DE,HL
	 ;!TEST 11/02/2024 установка шрифта более гибкая без заплётов
	  LD	A,H
	  SUB	#C0
	  JR	NC,.change
	 ;
	 LDIR
.cont:	 EX	DE,HL
	 LD	A,H
	 RRCA
	 RRCA
	 RRCA
	 DEC	A
	 AND	3
	 ADD	A,#58
	 LD	H,A

.loop:	 LD	(HL),L
	 INC	L
	 JR	NZ,.loop

	 LD	A,(SYS_PAGE.SYS_WORK1)
	 LD	BC,Port_All_Mode	
	 OUT     (C),A
	EXX

	EX	AF,AF'
	LD	A,(SYS_PAGE.COPY_SLOT1)
	OUT	(SLOT1),A
	RET
;!TEST 11/02/2024 установка шрифта более гибкая без заплётов
.change:
	LD	A,(SYS_PAGE.COPY_SLOT3)
	OUT	(SLOT3),A
	LDIR
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	JR	.cont
;------------------------------------------------------------------[#B6]
;

;*******************************************************
;
;	WIN_MAP_SC - карта экрана
;       0 - hor size
;	1 - ver size
;	2 - hor place
;	3 - ver place
LP_SIZE:                   ; определение size
	LP_OPEN_PG
	LD DE,(WIN_ID_0.USER.SIZE_H)
	LD A,(WIN_ID_0.USER.MODE)
	BIT 5,A
	LP_CLOSE_PG
	RET NZ
	LD A,E
	ADD A,A
	LD E,A
        RET
;


LP_AT_D:		; !!!!! ожидается, что портятся только альтернативные регистры и те, что как параметры на входе
	LD A,(WIN_ID_0.USER.SIZE_V)
	EXX
	 LD L,A
	EXX
	LD A,D
	EXX
.loop:	 SUB L
	 JR NC,.loop

	 ADD A,L
	 ADD A,A
	 ADD A,A
	 LD L,A
	 LD A,(WIN_ID_0.V_BEG)
	 ADD A,L
	 LD L,A
	 INC L
	 LD H,#C3
	EXX
	RET
;


; !!!!! ожидается, что портятся только альтернативные регистры и те, что как параметры на входе
LP_TAB_E:
	LD A,(WIN_ID_0.SIZE_REL)
	EXX
	 LD D,A
	EXX
	LD A,E
	EXX
.loop:	 SUB D
	 JR NC,.loop
	 JR Z,.loop

	 NEG
	 LD B,A	; сохранить сколько осталось символов в строке
	 NEG
	 ADD A,D
	 LD D,A
	 LD A,(WIN_ID_0.USER.MODE)
	 AND %0010'0000
	 JR Z,.skip_Dx2
	 LD A,D
	 ADD A,A
	 LD D,A
.skip_Dx2:
	 LD A,(WIN_ID_0.H_BEG)
	 ADD A,D
	 LD D,A
	EXX
	RET
;*************************************************************

; вычисление нового места
LP_NEXT_HL:
	LD A,SYS_PAGE
	OUT (SLOT3),A
	INC L
	INC L
	INC L
	INC L
	LD A,(WIN_ID_0.V_END)
	CP L
	JR NC,LP_NEXT_HL1
	LD HL,(WIN_ID_0.V_BEG)
	;LD A,(WIN_ID_0.V_BEG)
	;LD L,A
	INC L
	LD H,#C3	;!HARDCODE
LP_NEXT_HL1:
	LD A,(WIN_ID_0.H_BEG)
	LD D,A
	LD A,(WIN_ID_0.SIZE_REL)
	LD B,A

	LD A,#50
	OUT (SLOT3),A
	RET

; !!!!! ожидается, что портятся только альтернативные регистры и те, что как параметры на входе
LP_BEG_P:
	EX AF,AF'
        EXX
	  LP_OPEN_PG
         LD HL,(WIN_ID_0.reg_HL)
         LD DE,(WIN_ID_0.reg_DE)
         LD BC,(WIN_ID_0.reg_BC)
         LD A,E
         AND A
         RRA
	 OUT (PORT_Y),A
        EXX
        EX AF,AF'
        RET

LP_INI_P:
	EX AF,AF'
	EXX
	 LP_OPEN_PG
	LD A,(WIN_ID_0.USER.MODE)
	CP #C0
	JR NC,LP_INI_NO_ZG			; открытие бордера...
	LD A,(WIN_ID_0.USER.MODE_S)
	BIT 0,A
	JR NZ,LP_INI_NO_ZG			; открытие Spectrum-Screen

	LD A,(WIN_ID_0.USER.MODE)
	BIT 4,A
	JR Z,LP_INI_NO_ZG			; открытие графического экрана
	LD DE,(SYS_PAGE.WIN_ZG)			; знакогенератор

	EXX
	EX AF,AF'
	CALL WIN_SET_ZG.SET	;LP_SET_ZG1
	EXX
	EX AF,AF'

LP_INI_NO_ZG:
	LD A,(WIN_ID_0.H_BEG)
	LD D,A
	LD A,(WIN_ID_0.V_BEG)
	LD L,A
	INC L
	LD H,#C3

	AND A
	LD A,(WIN_ID_0.USER.MODE)
	BIT 5,A
	LD A,(WIN_ID_0.USER.SIZE_H)
	JR NZ,LP_INI_40
	ADD A,A
	SCF
	;!TODO что-то тут подвыпиленно 
LP_INI_40:
	LD B,A
	LD (WIN_ID_0.SIZE_REL),A

	; LD DE,(SYS_PAGE.WIN_MODE_SC)	; место по горизонтали и страница моды
	; LD HL,(SYS_PAGE.WIN_MODE_SH)	; место по вертикали с адресом
	; INC HL
	; LD B,0
	; CALL LP_TAB_H2

	EX AF,AF'
        EXX
	JP LP_END_P
;********************************************************



;
;------------------------------------------------------------------[#80]
LP_OPEN_S:
	LD A,B
	ADD A,A
	CP LP_SC_TAB.SIZE
	CCF
	RET C
	PUSH HL
	LD HL,LP_SC_TAB

	ADD A,L
	LD L,A
	LD A,H
	ADC A,0
	LD H,A
	LD A,(HL)
	INC HL
	LD H,(HL)
	LD L,A
	EX (SP),HL
	RET
LP_SC_TAB:
	DW LP_SET_32
	DW LP_SET_64
	DW LP_SET_40
	DW LP_SET_80
	DW LP_SET_32.X
	DW LP_SET_64.X
	DW LP_SET_40.X
	DW LP_SET_80.X
	DW PIC_SET_S1
	DW PIC_SET_S2
	; DW LP_SET_MNU
.SIZE	EQU $-LP_SC_TAB

;LP_SET_MNU:															; ????? 
;	SCF
;	RET
;	LD IX,LP_SCR_MNU
;	JP LP_SET_MODE

LP_SET_32:
	LD HL,#4104
.X:	LD IX,LP_SCR_32
	JP LP_SET_MODE

LP_SET_64:
	LD HL,#4104
.X:	LD IX,LP_SCR_64
	JP LP_SET_MODE

LP_SET_40:
	LD HL,#4000
.X:	LD IX,LP_SCR_40
	JP LP_SET_MODE

LP_SET_80:
	LD HL,#4000
.X:	LD IX,LP_SCR_80
	JP LP_SET_MODE

PIC_SET_S1:
	LD IX,PIC_320X256_1
	JP LP_SET_MODE

PIC_SET_S2:
	LD IX,PIC_320X256_2
	JP LP_SET_MODE
;------------------------------------------------------------------[#80]
;

;
;------------------------------------------------------------------[#B0]
; HL - место на экране по знакоместам (НЕ ИСПОЛЬЗУЕТСЯ)
; IX - описатель окна
WIN_OPEN:
	LP_OPEN_PG
	LD (SYS_PAGE.WIN_MAP_SC),IX	; карта окна
	PUSH DE
	LD HL,(SYS_PAGE.WIN_MAP_SC)
	LD DE,WIN_ID_0
	LD BC,Window_UserVars
	LDIR
	LD IX,WIN_ID_0
	POP DE
	LD L,(IX+Window_Variables.USER.PLACE_H)
	LD H,(IX+Window_Variables.USER.PLACE_V)
	LD (IX+Window_Variables.MODE_E),E
	JP WIN_OPEN_W1


; HL - PLACE
; IX - SIZE_HOR; IX+1 - SIZE_VER; IX+2,3; IX+4 - MODE;
; E - страница моды.
PIC_FN0:
LP_SET_MODE:
	LD A,H
	AND #10	; переместить бит 4 в регистр E
	XOR E
	LD E,A
	LD A,L
	AND #3F
	ADD HL,HL
	ADD HL,HL
	LD L,A
	LD A,H
	AND #3F
	LD H,A
	 LP_OPEN_PG
	LD (SYS_PAGE.WIN_MAP_SC),IX	; карта окна
	PUSH HL
	PUSH DE
	LD HL,(SYS_PAGE.WIN_MAP_SC)
	LD DE,SYS_PAGE.WIN_MAP_IX
	LD BC,Window_UserVars
	LDIR
	LD IX,SYS_PAGE.WIN_MAP_IX
	POP DE
	POP HL
	LD (IX+Window_Variables.USER.PLACE_H),L
	LD (IX+Window_Variables.USER.PLACE_V),H
	LD (IX+Window_Variables.MODE_E),E
WIN_OPEN_W1:
	LD A,L
	ADD A,A
	INC A			; вычисление PORT_Y
	BIT 4,E
	JR NZ,LP_SET_NO_OR
	OR #80			; если вывод на второй экран
LP_SET_NO_OR:
	LD (IX+Window_Variables.H_BEG),A
	LD D,A
	LD A,(IX+Window_Variables.USER.SIZE_H)
	ADD A,A
	ADD A,D
	LD (IX+Window_Variables.H_END),A
	LD (SYS_PAGE.WIN_MODE_SC),DE	; место по горизонтали и страница моды
	LD A,H
	AND #3F
	ADD A,A
	ADD A,A
	LD L,A
	LD H,#C3
	LD (SYS_PAGE.WIN_MODE_SH),HL	; место по вертикали с адресом
	LD (IX+Window_Variables.V_BEG),A
	LD A,(IX+Window_Variables.USER.SIZE_V)
	ADD A,A
	ADD A,A
	ADD A,L
	LD (IX+Window_Variables.V_END),A

	LD L,(IX+Window_Variables.V_BEG)
	LD H,#C3
	LD B,(IX+Window_Variables.USER.SIZE_V)	; размер по вертикали


	LD (IX+Window_Variables.WORK_1),0
	LD A,(IX+Window_Variables.USER.MODE)	; знакогенератор плюс режим
	LD (IX+Window_Variables.WORK_2),A
	BIT 4,A
	JR NZ,LP_SET_LOOP	; переход, если текстовый режим

	AND #F0
	LD C,A
	LD A,(IX+Window_Variables.USER.GR_X)
	RRCA
	RRCA
	RRCA
	LD D,A
	AND #0F
	OR C
	LD (IX+Window_Variables.WORK_2),A

	LD A,D
	AND #E0
	LD C,A
	LD A,(IX+Window_Variables.USER.GR_Y)
	AND #1F
	OR C
	RLCA
	RLCA
	RLCA
	LD (IX+Window_Variables.WORK_1),A

LP_SET_LOOP:
	LD D,(IX+Window_Variables.H_BEG)	; D - начало строки (PORT_Y)
	LD C,(IX+Window_Variables.USER.SIZE_H)	; размер по горизонтали
	LD A,(IX+Window_Variables.USER.MODE)	; знакогенератор плюс режим

	PUSH BC
	CALL LP_MODE_LINE
	POP BC
	INC L
	INC L
	INC L
	INC L
	DJNZ LP_SET_LOOP

	LD A,(IX+Window_Variables.MODE_E)
	AND 1
	OUT (RGMOD),A
	; LD A,(IX+Window_Variables.MODE)
	; BIT 4,A
	 LP_CLOSE_PG
	; RET Z
	CALL LP_INI_P
	; LD A,(SYS_PAGE.WIN_MODE_SC)
	; OUT (RGMOD),A
	CALL LP_SIZE
	XOR A
	RET

WIN_CLOSE:
	SCF
	RET


; Установка режима на линии
LP_MODE_LINE:
	BIT 0,(IX+Window_Variables.USER.MODE_S)
	JP NZ,LP_MODE_LINE2	; идти на спектрум
	BIT 4,A
	JP Z,LP_MODE_LINE3	; идти на графику!
	DEC D

; 	текстовый режим.

	EX AF,AF'
	LD A,#50
	OUT (SLOT3),A
	LD A,L	; вертикальное положение
	CP #80
	JR NC,LP_EXIT_MODE

LP_MODE_RECURSE:
	LD A,D	; горизонтальное положение
	AND 7FH
	SUB 80
	JR C,LP_MODE_LL
	SUB 48
	NEG

	LD E,A	; запомнить
	ADD A,D
	LD D,A	; новое положение

	LD A,E	; восстановить
	RRA
	AND 3FH
	SUB C
	JR NC,LP_EXIT_MODE
	NEG
	LD C,A	; новое значение C
	JR LP_MODE_RECURSE

LP_MODE_LL:
	NEG
	RRA
	AND 3FH
	CP C
	JR NC,LP_MODE_LR
	LD C,A
LP_MODE_LR:
	EX AF,AF'

	INC D
LP_MD_LL1:
	EX AF,AF'
	LD A,D
	OUT (PORT_Y),A
	EX AF,AF'
	LD (HL),A	; режим
	INC D
	EX AF,AF'
	LD A,D
	OUT (PORT_Y),A
	EX AF,AF'
	LD (HL),A	; режим
	INC D
	DEC C
	JR NZ,LP_MD_LL1

	EX AF,AF'
LP_EXIT_MODE:
	LD A,SYS_PAGE
	OUT (SLOT3),A
	EX AF,AF'
	RET

; Установка режима на линии
;	Spectrum mode
LP_MODE_LINE2:
	LD A,(IX+Window_Variables.WORK_2)
	LD B,(IX+Window_Variables.WORK_1)

	DEC D

	EX AF,AF'
	LD A,#50
	OUT (SLOT3),A
	LD A,L	; вертикальное положение
	CP #80
	JR NC,LP_EXIT_MODE2

LP_MODE_RECURSE2:
	LD A,D	; горизонтальное положение
	AND #7F
	SUB 80
	JR C,LP_MODE_LL2
	SUB 48
	NEG

	LD E,A	; запомнить
	ADD A,D
	LD D,A	; новое положение

	LD A,E	; восстановить
	RRA
	AND #3F
	SUB C
	JR NC,LP_EXIT_MODE2
	NEG
	LD C,A	; новое значение C
	JR LP_MODE_RECURSE2

LP_MODE_LL2:
	NEG
	RRA
	AND #3F
	CP C
	JR NC,LP_MODE_LR2
	LD C,A
LP_MODE_LR2:
	EX AF,AF'

	INC D
LP_MD_LL2:
	EX AF,AF'
	LD A,D
	OUT (PORT_Y),A
	EX AF,AF'
	LD (HL),A	; режим
	INC L
	LD (HL),B
	INC L
	LD (HL),B
	DEC L
	DEC L

	INC D
	BIT 4,A
	JR NZ,lp_md_ll3x
	INC B
lp_md_ll3x:
	EX AF,AF'
	LD A,D
	OUT (PORT_Y),A
	EX AF,AF'
	LD (HL),A	; режим
	INC L
	LD (HL),B
	INC L
	LD (HL),B
	DEC L
	DEC L

	INC D

	INC B
	JR NZ,LP_NO_ADD_40
	ADD A,40H
LP_NO_ADD_40:

	DEC C
	JR NZ,LP_MD_LL2

	EX AF,AF'
LP_EXIT_MODE2:
	LD A,SYS_PAGE
	OUT (SLOT3),A
	EX AF,AF'

	LD (IX+Window_Variables.WORK_1),B
	LD (IX+Window_Variables.WORK_2),A
	RET


LP_MODE_LINE3:	; Установка режима на линии

;	Grafic Mode

	LD A,(IX+Window_Variables.WORK_1)
	LD B,(IX+Window_Variables.WORK_2)

	DEC D

	EX AF,AF'
	LD A,#50
	OUT (SLOT3),A
	LD A,L	; вертикальное положение
	CP 80H
	JR NC,LP_EXIT_MODE3

LP_MODE_RECURSE3:
	LD A,D	; горизонтальное положение
	AND 7FH
	SUB 80
	JR C,LP_MODE_LL3
	SUB 48
	NEG

	LD E,A	; запомнить
	ADD A,D
	LD D,A	; новое положение

	LD A,E	; восстановить
	RRA
	AND 3FH
	SUB C
	JR NC,LP_EXIT_MODE3
	NEG
	LD C,A	; новое значение C
	JR LP_MODE_RECURSE3

LP_MODE_LL3:
	NEG
	RRA
	AND 3FH
	CP C
	JR NC,LP_MODE_LR3
	LD C,A
LP_MODE_LR3:
	EX AF,AF'

	INC D

	BIT 5,B
	JR Z,LP_GR_640

LP_MD_LL3:

	EX AF,AF'
	LD A,D
	OUT (PORT_Y),A
	EX AF,AF'
	LD (HL),B	; режим
	INC L
	LD (HL),A	; режим 2
	INC L
	LD (HL),0	; режим 2
	DEC L
	DEC L

	INC D

;	EX AF,AF'
;	LD A,D
;	OUT (PORT_Y),A
;	EX AF,AF'
;	LD (HL),B	; режим
;	INC L
;	LD (HL),A	; режим 2
;	DEC L

	INC D

	INC A
	LD E,A
	AND 7
	JR NZ,LP_NO_INC_B
	LD A,E
	SUB 8
	LD E,A
	INC B
LP_NO_INC_B:
	LD A,E

	DEC C
	JR NZ,LP_MD_LL3

LP_640_RET:
	EX AF,AF'
LP_EXIT_MODE3:
	LD A,SYS_PAGE
	OUT (SLOT3),A
	EX AF,AF'

	LD A,(IX+Window_Variables.WORK_1)
	ADD A,8
	LD (IX+Window_Variables.WORK_1),A
	RET

LP_GR_640:
	EX AF,AF'
	LD A,D
	OUT (PORT_Y),A
	EX AF,AF'
	LD (HL),B	; режим 1
	INC L
	LD (HL),A	; режим 2
	INC L
	LD (HL),0	; режим 3

	INC D

	EX AF,AF'
	LD A,D
	OUT (PORT_Y),A
	EX AF,AF'
	LD (HL),0	; режим 3
	DEC L
	LD (HL),A	; режим 2
	DEC L
	LD (HL),B	; режим 1

	INC D

	INC A
	LD E,A
	AND 7
	JR NZ,LP_NO_INC_B6
	LD A,E
	SUB 8
	LD E,A
	INC B
LP_NO_INC_B6:
	LD A,E

	DEC C
	JR NZ,LP_GR_640
	JP LP_640_RET


;*****************************************************************


LP_SCROLL_UD:
	DEC B
	JR Z,LP_SCROLL_UP
	DEC B
	JR Z,LP_SCROLL_DN
	SCF
	RET

; Вход:
;  D - верхняя строка ( от 0 )
;  E - число скроллируемых строк
LP_SCROLL_UP:
	DEC E
	RET Z
	 LP_OPEN_PG
	LD B,E
	LD E,0		;!FIXIT чёт тут нечисто, подгонка под один вариант окна глобального?
	CALL	.RUN
.EXIT:	 LP_CLOSE_PG
	RET
	;
.RUN:	PUSH BC
	CALL LP_AT_D
	CALL LP_TAB_E	; вычислить переменные для строки
	POP BC
.loop2:	EXX
	PUSH HL
	EXX
	POP HL

	LD E,L
	LD D,H
	INC L
	INC L
	INC L
	INC L

	LD A,(WIN_ID_0.V_END)
	CP L
	;JR C,.EXIT	; если конец, то выход
	RET C
	PUSH BC

	LD A,L
	EXX
	LD L,A
	EXX

	LD A,(WIN_ID_0.USER.SIZE_H)
	ADD A,A			; число байт в строке для переноса
	ADD A,A

	LD C,A
	LD B,0

	LD A,#50
	OUT (SLOT3),A		; открыть страницу для переноса
	EXX
	LD A,D		; получить порт начала строки
	EXX
.loop1:	OUT (PORT_Y),A
	INC A		; следующее значение порта
	LDI
	LDD
	OUT (PORT_Y),A
	INC A		; следующее значение порта
	LDI
	LDD
	JP PE,.loop1

	LD A,SYS_PAGE
	OUT (SLOT3),A
	POP BC
	DJNZ .loop2
	RET



; Вход :
;  D - верхняя строка ( от 0 )
;  E - число скроллируемых строк
LP_SCROLL_DN:
	DEC E		;!FIXIT правильно?
	RET Z

	LP_OPEN_PG
	LD B,E
	LD E,0
	LD A,D
	ADD A,B
;	DEC A
	LD D,A
	PUSH BC
	CALL LP_AT_D
	CALL LP_TAB_E
	POP BC

.loop2:	EXX
	PUSH HL
	EXX
	POP HL

	LD E,L
	LD D,H
	DEC L
	DEC L
	DEC L
	DEC L

	LD A,(WIN_ID_0.V_BEG)
	CP L		; .CONT: L >= A 
	JR Z,.CONT
	JR NC,.EXIT	; если конец, то выход
.CONT:	PUSH BC

	LD A,L
	EXX
	LD L,A
	EXX

	LD A,(WIN_ID_0.USER.SIZE_H)
	ADD A,A
	ADD A,A
	LD C,A
	LD B,0

	LD A,#50
	OUT (SLOT3),A
	EXX
	LD A,D
	EXX
.loop1:	OUT (PORT_Y),A
	INC A
	LDI
	LDD
	OUT (PORT_Y),A
	INC A
	LDI
	LDD
	JP PE,.loop1

	LD A,SYS_PAGE
	OUT (SLOT3),A

	POP BC
	DJNZ .loop2
.EXIT:	LP_CLOSE_PG
	RET


; DE - место символа в окне
; А - номер окна
; выход: HL - символ/атрибут B - знакогенератор
WIN_GET_SYM:
	AND A
	SCF
	RET NZ

	CALL LP_BEG_P

        CALL LP_AT_D
        CALL LP_TAB_E

	LD A,#50
	OUT (SLOT3),A

	EXX

	LD A,D
	OUT (PORT_Y),A

	LD A,(HL)
	EXX
	LD L,A
	EXX
	INC L
	LD A,(HL)
	EXX
	LD H,A
	EXX
	DEC L
	DEC L
	LD A,(HL)
	EXX
	LD B,A
	EXX
	INC L

	EXX
	JP LP_END_P
	;RET

; DE - место символа в окне
; А - номер окна
; HL - символ/атрибут
; B - знакогенератор
WIN_PUT_SYM:
	AND A
	SCF
	RET NZ

	CALL LP_BEG_P

        CALL LP_AT_D
        CALL LP_TAB_E

	LD A,#50
	OUT (SLOT3),A

	EXX

	LD A,D
	OUT (PORT_Y),A

	EXX
	LD A,L
	EXX

	LD (HL),A
	INC L

	EXX
	LD A,H
	EXX

	LD (HL),A
	DEC L
	DEC L

	EXX
	LD A,B
	EXX

	LD (HL),A
	INC L

	EXX
	JP	LP_END_P


; HL - размер окна
; DE - положение окна
; A - номер окна
; IX - новое положение окна
WIN_MOVE:	      
	AND A
	SCF
	RET NZ
	PUSH IX
	PUSH HL
	LD B,SHARED_PAGE
	LD IX,SLOT3.MEM_ADDR
	CALL WIN_COPY_WIN1
	POP HL
	POP DE
	LD B,SHARED_PAGE
	LD IX,SLOT3.MEM_ADDR
	CALL WIN_RESTORE.Start
	AND A
	RET


; HL - размер сохраняемого окна
; DE - место сохраняемого окна
; IX - адрес сохраняемого окна, в странице 4000h
; А - номер окна, B - страница
WIN_COPY:
	AND A
	SCF
	RET NZ
WIN_COPY_WIN1:
	CALL LP_BEG_P

	IN A,(SLOT1)
	PUSH AF

        CALL LP_AT_D
        CALL LP_TAB_E

	LD (SYS_PAGE.SYS_WORK1),SP

	LD A,B
	OUT (SLOT3),A
	LD A,#50
	OUT (SLOT1),A

	EXX
	 RES 7,H
	 LD C,D
	EXX

.COPY_loop2:
	LD A,L
	EXX
	 LD B,A
	 ;
	 ADD A,A
	 ADD A,XL
	 LD XL,A
	 JR NC,.NO_INC_XH
	 INC XH
.NO_INC_XH:
	 LD SP,IX
	 ;
	 LD A,C
	 ADD A,B
.COPY_loop:
	 DEC A
	 OUT (PORT_Y),A
	 LD E,(HL)
	 INC L
	 LD D,(HL)
	 DEC L
	 PUSH DE
	 DJNZ .COPY_loop
	 ;
	 INC HL
	 INC HL
	 INC HL
	 INC HL
	EXX
	DEC H
	JR NZ,.COPY_loop2
	;
	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD SP,(SYS_PAGE.SYS_WORK1)
	;
	POP AF
	OUT (SLOT1),A
	JP LP_END_P.short
	;AND A
	;RET


; HL - размер сохраняемого окна
; DE - место сохраняемого окна
; IX - адрес данных восстанавливаемого окна
WIN_RESTORE:
	AND A
	SCF
	RET NZ
.Start:
	CALL LP_BEG_P
	;
	IN A,(SLOT1)
	PUSH AF
	;
        CALL LP_AT_D
        CALL LP_TAB_E
	;
	LD (SYS_PAGE.SYS_WORK1),SP
	LD SP,IX
	;
	LD A,B
	OUT (SLOT3),A
	LD A,#50
	OUT (SLOT1),A
	;
	EXX
	 RES 7,H
	 LD C,D
	EXX
.L2:	LD A,L
	EXX
	 LD B,A
	 LD A,C
.L1:	 OUT (PORT_Y),A
	 INC A
	 POP DE
	 LD (HL),E
	 INC L
	 LD (HL),D
	 DEC L
	 DJNZ .L1
	 ;
	 INC HL
	 INC HL
	 INC HL
	 INC HL
	EXX
	DEC H
	JR NZ,.L2

	LD A,SYS_PAGE
	OUT (SLOT3),A

	LD SP,(SYS_PAGE.SYS_WORK1)

	POP AF
	OUT (SLOT1),A
	JP	LP_END_P.short
;======================================================================;




;!FIXIT нет описания, недоделана. Печать с управляющими символами
;------------------------------------------------------------------[#E0]
; DE - место символа в окне
; HL - адрес с выводимой строкой
; B  - разделитель
LP_PR_LINE_DIR:
	CALL LP_BEG_P
	LD A,#50
	OUT (SLOT3),A

.loop:	EXX
	LD A,D
	OUT (PORT_Y),A
	EXX
	LD A,(HL)
	INC HL
	CP B
	JR Z,.exit
	EXX
	; печатаемые символы
	 CP 14
	 JR NC,.print
	 CP 7
	 JR C,.print
	; управляющие символы
	 SUB 7
	 JR Z,LP_BELL		; A = 07 "BELL"
	 DEC A
	 JR Z,LP_BACK		; A = 08 "Backspace"
	 DEC A
	 JR Z,LP_TAB		; A = 09 "TAB"
	 DEC A
	 JR Z,LP_LF		; А = 10 "Line Feed"
	 DEC A
	 JR Z,.VT		; А = 11 "Vertical Tabulation" = "Line Feed", если LF работает как CRLF
	 DEC A
	 JR Z,LP_CLS		; А = 12 "Form feed" - разрыв страницы, начало нового листа, может работать как VT
	 DEC A
	 JR Z,LP_CR		; А = 13 "Carriage Return"
	;

	; выводить!
.VT:	; ...
	; ...
.print:	LD	(HL),A
	INC	D

.next:	; ...
	; ...
	 DJ_NEXT_HL
	EXX
	JR	.loop

.exit:	JP	LP_END_P
;
;
LP_PRINT_LN_D11:
	LD A,#50
	OUT (SLOT3),A
	JR LP_PR_LINE_DIR.next

;!TODO недоделана
LP_BELL:
	JR LP_PR_LINE_DIR.next

LP_BACK:
	LD A,SYS_PAGE
	OUT (SLOT3),A

	LD A,(WIN_ID_0.H_BEG)
	CP D
	JR Z,LP_PRINT_LN_D11
	INC B
	DEC D
	JR LP_PRINT_LN_D11

;-------[TAB]
LP_TAB:	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD A,(WIN_ID_0.H_BEG)
	SUB D
	NEG
	AND %0000'0111
	NEG
	ADD A,8
	LD C,A
	LD A,#50
	OUT (SLOT3),A

.loop:	LD (HL),' '
	INC D
	DEC B
	JR Z,.end_Line
	DEC C
	JR NZ,.loop

	JR LP_PR_LINE_DIR.next
.end_Line:
	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD A,(WIN_ID_0.H_BEG)
	LD D,A
	LD A,(WIN_ID_0.SIZE_REL)
	LD B,A
	;JP	LP_LF
;-------[TAB end]
LP_LF:	LD A,SYS_PAGE
	OUT (SLOT3),A

	INC L
	INC L
	INC L
	INC L

	LD A,(WIN_ID_0.V_END)
	CP L
	JR NC,LP_PRINT_LN_D11
	;!TEST BIOS SCROLL 
	 ;LD A,(WIN_ID_0.V_BEG)
	 ;LD L,A	; вернуться наверх без скролла!!!
	 ;-------------------------------------------------------------\
	 PUSH	HL
	 PUSH	BC
	 EXX
	 PUSH	BC
	 PUSH	DE
	 EXX

	 LD	A,(WIN_ID_0.USER.SIZE_V)
	 LD	B,A
	 CALL	LP_SCROLL_UP.RUN

	 EXX
	 POP	DE
	 POP	BC
	 EXX
	 POP	BC
	 POP	HL
	 ;-------------------------------------------------------------/
	;
	; scrolling ????
	JR LP_PRINT_LN_D11

LP_CLS:	; ...
	; scrolling ????
	JR LP_PR_LINE_DIR.next

LP_CR:	LD A,SYS_PAGE
	OUT (SLOT3),A

	LD A,(WIN_ID_0.H_BEG)
	LD D,A
	LD A,(WIN_ID_0.SIZE_REL)
	LD B,A

	JR LP_PRINT_LN_D11
;------------------------------------------------------------------[#E0]

