	DEVICE ZXSPECTRUM4096				; модель с 4 метрами памяти
	MMU 0 e, 1							; первая страница в банку 0 и проверка на границы
	OUTPUT './Build/DOOM2/d2_fram.bin'
;
SND_READ_SECTORS	EQU 4

/*
;------------[ПЕРЕДЕЛАТЬ!!!]------------

;---------------------------------------
*/


		ORG #1000

Module__D2_FRAM__Start EQU $
;
TRACE:

	IN A,(SLOT1)
	LD (TRACE_RET_SLOT1),A
	IN A,(SLOT3)
	LD (TRACE_RET_SLOT3),A

	LD A,#50
	OUT (SLOT3),A

	LD BC,#100
	OUT (C),C							; МАСШТАБ 1:1

	LD DE,(SCREEN_1)

	LD HL,(ANGLE_M)

	ADD HL,HL
;	ADD HL,HL
	LD A,H
	AND #3F
	OR #40
	BIT 6,H
	LD H,A
	RES 6,L

	LD A,(SKY_1)
	JR Z,NO_SKY_2
	LD A,(SKY_2)
NO_SKY_2:
	OUT (SLOT1),A

	LD A,0								;????????? не нужно?
	LD C,80
SKY_LOOP_1:

	ACC_SetBlockSize
		LD B,0
	ACC_CopyBlock
		LD B,(HL)
	ACC_SetBlockSize
		LD B,#80
	ACC_Off

	XOR A

	OUT (PORT_Y),A
	ACC_CopyScreenBlock
		LD (DE),A
	ACC_Off

	INC DE
	INC DE

	OUT (PORT_Y),A
	ACC_CopyScreenBlock
		LD (DE),A
	ACC_Off

	DEC DE

	OUT (PORT_Y),A
	ACC_CopyScreenBlock
		LD (DE),A
	ACC_Off

	INC DE
	INC DE

	OUT (PORT_Y),A
	ACC_CopyScreenBlock
		LD (DE),A
	ACC_Off

	INC DE

	INC H
	BIT 7,H
	JR Z,NO_NEXT_SKY

	RES 7,H
	SET 6,H

					IF YesSound
					CALL SOUND
					; ELSE
					; CALL YesSoundZero
					ENDIF

	LD A,(SKY_1)
	LD B,A
	IN A,(SLOT1)
	CP B
	LD A,B
	JR NZ,NO_SKY_2X
	LD A,(SKY_2)
NO_SKY_2X:
	OUT (SLOT1),A

NO_NEXT_SKY:
	DEC C
	JR NZ,SKY_LOOP_1

					IF YesSound
					CALL SOUND
					; ELSE
					; CALL YesSoundZero
					ENDIF
;
	EXX
SCREEN_1+1:
	 LD DE,#C040			; начало экрана
	 LD C,0							;!!!!!!!!!!!!!!!!!!!!!!!!!!
	EXX
;
ANGLE_M+1:
	LD HL,0				; начальный угол * 32

;
	LD A,H
	RLCA
	RLCA
	AND 3
	ADD A,TABLE_W/256
	LD D,A								; текущий квадрант

	SET 6,H
	RES 7,H								; HL - на таблице!!!

	LD B,40								; число лучей трассировки деленное на 8

TRACE_NEXT_:
;
	EXX
	 LD HL,(PLACE_L)						; текущее положение в таблице
	 INC HL
	 LD A,(HL)
	 LD (PLACE_L1),A
	 LD (PLACE_L2),A
	EXX
;
PLACE_L+1:
	LD A,(TABLE_TRACE+10)						; тонкое положение - положение в квадрате
;
	OUT (SLOT1),A
	LD (CONT_PAGE),A
;	JR TRACE_LOOP

TRACE_LOOP:
	LD A,#50
	OUT (SLOT3),A
	XOR A
	OUT (PORT_Y),A

	REPT 16
		LD E,(HL)						; первый и далее следующий кубик
		LD A,(DE)						; есть или нет?
		AND A
		JR NZ,TRACE_CONT					; если есть, рисовать!!
		INC L
	ENDR

PURE_LINE:
;
	EXX
		ACC_SetBlockSize
			LD A,#80					; пустая стенка
		ACC_Off
 ;		LD (DE),A						; LINE-Z-bufer
		OUT (PORT_Y),A

		LD A,(COLOR_LO)

		ACC_FillScreenOneByte
			LD (DE),A
		ACC_Off
		LD A,#70						; Z-bufer
		LD (DE),A
	EXX
;
	JR NEXT_ANGLE

;	трассировка закончена, стены нет.
TRACE_CONT:
; HL - таблица
; A - номер стенки
;
	EXX
		EX AF,AF'						;номер стенки
PLACE_L1+1:	LD A,5
 		OUT (SLOT1),A					; следующее положение в таблице

 ;		LD C,0
		LD B,1
		OUT (C),C						; МАСШТАБ 1:1
	EXX
;
	SET 4,L
	LD A,(HL)							; номер линии
;
	EXX
		LD H,A
 ;		LD L,0
		LD L,C
		SET 6,H
		RES 7,H

		EX AF,AF'
		OUT (SLOT1),A					; стенка. стенка раскидана на 16 килобайт

		ACC_SetBlockSize
			LD A,#40					; взять 64 байта
		ACC_CopyBlock
			LD A,(HL)					; взять немасштабированно!
		ACC_Off							; стенка в ОЗУ акселератора!

PLACE_L2+1:	LD A,5
		OUT (SLOT1),A					; следующее положение
	EXX
;
	RES 4,L
	LD A,(HL)							; A - высота

;	LD A,80H
;
	EXX
		LD H,TABLE_X/256
		LD L,A							; высота TABLE_X - таблица высот
		LD B,(HL)						; старшая часть коэфициента
 ;		ld b,0
		INC H

		LD L,(HL)						; младшая часть коэфициента/смещение в стенке
 ;		LD C,0
		OUT (C),L						; масштабирование
 ;		OUTI							; B уменьшается сначала!

		BIT 7,A
		JR Z,HIGH_1						; 64 точки, не на весь экран

 ; <64 точки, на весь экран
		XOR A
		OUT (PORT_Y),A					; с самого начала

		ACC_SetBlockSize
			LD (DE),A					; 256 байт И LINE-Z-bufer!!!!
		ACC_Off
		LD A,#58
		OUT (SLOT3),A
		ACC_CopyScreenBlock
			LD (DE),A					; ФИГАКС всю линию!!!
		ACC_Off
		XOR A
		LD (DE),A						; LINE-Z-bufer!!!!
	EXX
;
	JR NEXT_ANGLE

HIGH_1:
; A - высота, с которой рисуется стенка
	ACC_SetBlockSize
		LD (DE),A						; число точек потолка и пола! & LINE-Z-bufer
	ACC_Off
	NEG									; получить положение начала пола
	OUT (PORT_Y),A
	LD L,A

	LD A,#58
	OUT (SLOT3),A

;	LD A,#06							; цвет пола
;	LD A,#5F							; цвет пола серый
;	LD A,#CF							; цвет пола синий
COLOR_LO+1:	LD A,#2F						; цвет пола темнокрасный
;
	ACC_FillScreenOneByte
		LD (DE),A						; рисовать пол
	ACC_Off

;	LD A,11								; цвет потолка
;COLOR_HI EQU $-1
;	ACC_FillScreenOneByte
;	LD (DE),A							; рисовать потолок
;	ACC_Off

	LD A,L
	NEG
	OUT (PORT_Y),A

	LD A,L
;	IN A,(PORT_Y)
	ADD A,A
;	NEG									; выводимый размер стенки
;										  стенка в акселераторе!
	ACC_SetBlockSize
		LD (DE),A	;!!!!! прикольно
	ACC_CopyScreenBlock
		LD (DE),A						; положить стенку!
	ACC_Off

	EXX									;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

NEXT_ANGLE:

	EXX
		INC DE
		LD A,E
		AND 7
	EXX
	JR NZ,NO_TEST
	DEC B
	JR Z,TRACE_END

NO_TEST:
;
CONT_PAGE+1:	LD A,0
;
	OUT (SLOT1),A

	LD A,L
	AND #E0
	ADD A,32
	LD L,A
	JP NZ,TRACE_LOOP

;	CALL SOUND							; играть музыку на ковоксбластере!!!

					IF YesSound
					CALL SOUND
					; ELSE
					; CALL YesSoundZero
					ENDIF

	INC H
	BIT 7,H
	JP Z,TRACE_LOOP

	PUSH HL
	PUSH BC
;
CORNER_1+1:	LD A,#0F
;
	AND #0F
	RRCA
	RRCA
	LD C,A
	RRCA
	RRCA
	RRCA
	RRCA
	OR C
	AND #0F
;	XOR 03H
	XOR KWADR_CONST
	LD C,A

	LD B,0
	LD HL,TABLE_TRACE
	ADD HL,BC
	ADD HL,BC
	LD (PLACE_L),HL						; НОВОЕ тонкое положение
	POP BC
	POP HL

	INC D
	RES 2,D
	LD HL,#4000
	JP TRACE_NEXT_

TRACE_END:
;
TRACE_RET_SLOT3+1:	LD A,0
;
			OUT (SLOT3),A
;
TRACE_RET_SLOT1+1:	LD A,5
;
	OUT (SLOT1),A
	LD A,0
	OUT (PORT_Y),A
	RET
;
;***************************************
;

PRECALC_PLACE:
	LD HL,(ANGLE_A)
	LD A,L
	AND 0E0H
	LD L,A
	LD (ANGLE_M),HL

	LD A,(Y_COORD+1)
	AND 3
;	XOR 3
;	XOR C
	LD C,A
	LD A,(X_COORD+1)
	RLCA
	RLCA
	AND 0CH
;	XOR 0CH
	XOR C
	XOR 0FH

	LD C,A
	BIT 7,H
	JR Z,NO_NEG
	XOR 0FH
	LD C,A
NO_NEG:
	BIT 6,H
	JR Z,NO_CORN1

	RRCA
	RRCA
	LD C,A
	RRCA
	RRCA
	RRCA
	RRCA
	OR C

	AND #0F

KWADR_CONST		EQU #03					; #03/#0C

	XOR KWADR_CONST
	LD C,A

NO_CORN1:
	LD (CORNER_1),A
	LD B,0
	LD HL,TABLE_TRACE
	ADD HL,BC
	ADD HL,BC
	LD (PLACE_L),HL						; тонкое положение
	RET
;
;***************************************
;
; A - относительный номер страницы
SET_PICTURE:
	LD C,SLOT1
	IN B,(C)
	PUSH BC
	LD C,SLOT3
	IN B,(C)
	PUSH BC
	PUSH AF
	LD A,#50
	OUT (C),A

					IF YesSound
					CALL SOUND
					; ELSE
					; CALL YesSoundZero
					ENDIF
;
	ld bc,#0100							; масштабирование - 1
	OUT (C),C

	LD DE,(SCREEN_1)
	LD B,5								; 5 СТРАНИЦ

	ACC_SetBlockSize
		LD A,0							; по 256 байт
	ACC_Off
	OUT (PORT_Y),A

	POP AF

PIC_LOOP:
	PUSH BC

	PUSH AF
	LD HL,TABLE_MAIN
	ADD A,L
	LD L,A
	LD A,(HL)
	OUT (SLOT1),A

	LD HL,#4000
	LD B,64
LOOP_PG:
	ACC_CopyBlock
		LD A,(HL)
	ACC_CopyScreenBlock
		LD (DE),A
	ACC_Off
	INC DE
	INC H
	DJNZ LOOP_PG

	POP AF
	INC A

	POP BC

					IF YesSound
					CALL SOUND
					; ELSE
					; CALL YesSoundZero
					ENDIF

	DJNZ PIC_LOOP

	POP BC
	OUT (C),B
	POP BC
	OUT (C),B

	RET

NN_X:	DB 0
;
;***************************************
;

CALC_NEW_PLACE:

	LD HL,(ANGLE_A)

	LD BC,(A_SPEED)
	ADD HL,BC

	LD BC,(LF_)
	LD A,B
	LD B,C
	LD C,A
	INC BC
	LD C,0

	ADD HL,BC
	ADD HL,BC
	ADD HL,BC
	ADD HL,BC

	LD (ANGLE_A),HL

	LD A,H
	ADD A,20+8

	RRCA
	RRCA
	RRCA
	AND 1EH
	LD C,A
	LD B,0
	LD HL,TAB_ANGLE2

;TAB_SPEED EQU $-2

	ADD HL,BC
	LD E,(HL)							; step to Y
	INC L
	LD D,(HL)							; step to X

	LD HL,(Y_COORD)
	PUSH HL

	LD BC,(Y_SPEED)
	ADD HL,BC

	LD BC,(UP_)
	INC BC
	LD C,0
	LD A,B
	AND A
	JR Z,ZERO1

	LD B,E
	DEC A
;	BIT 7,E								; проверка на отрицательность шага

	JR Z,ZERO1
	LD A,B
	NEG
	LD B,A

ZERO1:

	ADD HL,BC
	LD (Y_COORD),HL

	ADD HL,BC
	LD BC,(Y_SPEED)
	ADD HL,BC

	PUSH DE
	CALL MAP_PLACE
	POP DE

	POP HL

	JR NC,CONT_MOVE1

	LD (Y_COORD),HL

	LD HL,(Y_SPEED)
	LD A,H
	CPL
	LD H,A
	LD A,L
	CPL
	LD L,A
	INC HL
	LD (Y_SPEED),HL

CONT_MOVE1:

	LD HL,(X_COORD)

	PUSH HL

	LD BC,(X_SPEED)
	ADD HL,BC

	LD BC,(UP_)
	INC BC
	LD C,0
	LD A,B
	AND A
	JR Z,ZERO2

	LD B,D
	DEC A
;	BIT 7,D
	JR Z,ZERO2
	LD A,B
	NEG
	LD B,A

ZERO2:
	ADD HL,BC

	LD (X_COORD),HL

	ADD HL,BC
	LD BC,(X_SPEED)
	ADD HL,BC

	CALL MAP_PLACE
	POP HL

	JR NC,CONT_MOVE2

	LD (X_COORD),HL

	LD HL,(X_SPEED)
	LD A,H
	CPL
	LD H,A
	LD A,L
	CPL
	LD L,A
	INC HL
	LD (X_SPEED),HL
CONT_MOVE2:
	RET

;
;***************************************
;
WEAPON_OUT:
	IN A,(SLOT1)
	PUSH AF
	IN A,(SLOT3)
	PUSH AF

;-------------[нужно ли???]-
	ld bc,#0100
	OUT (C),C							; МАСШТАБ 1:1
;---------------------------

	LD A,(PAGE_WEAPON)
	OUT (SLOT1),A
	LD A,#58
	OUT (SLOT3),A

WEAPON_SWITCH+1:
	LD HL,#4500							; положение спрайта оружия в странице
;
	LD DE,(SCREEN_1)
	LD A,E
	ADD A,100							; смешение спрайта оружия по горизонтали
	LD E,A

	ACC_SetBlockSize
		LD C,119						; длина спрайта оружия
	ACC_Off

;-------------[нужно ли???]-
	LD A,#FF							; нижняя линия
;---------------------------

	LD BC,#100

W_OUT_L:
	LD A,#44
	SUB H
	OUT (PORT_Y),A
;
;------[оптимизировать?]----------------
	OUT (C),C							; МАСШТАБ 1:1, начинать с 0
	ACC_CopyBlock
		LD A,(HL)
	ACC_Off
		OUT (C),C						; МАСШТАБ 1:1, начинать с 0
	ACC_CopyBlock
		LD (DE),A
	ACC_Off
;---------------------------------------
;
	INC H
	BIT 7,H
	JR Z,W_OUT_L

	LD A,(WEAPON_SWITCH)
	XOR #80
	LD (WEAPON_SWITCH),A

	POP AF
	OUT (SLOT3),A
	POP AF
	OUT (SLOT1),A
	RET
;
;***************************************
;

MAP_OUT:
	CALL MAP_PLACE

	IN A,(SLOT1)
	PUSH AF
	IN A,(SLOT3)
	PUSH AF
	LD A,(TABLE_WALL)
	OUT (SLOT1),A

	RES 4,H
;	SET 5,H

	PUSH HL
	LD A,(HL)
	PUSH AF

	LD (HL),#F7

	LD HL,#4000

	LD DE,(SCREEN_1)
	LD A,E
	ADD A,8
	LD E,A

MAP_LOOP_2:
	LD A,#58
	OUT (SLOT3),A

	LD BC,#0100
	OUT (C),C							; МАСШТАБ 1:1

; IF NORM_ACC
	 LD B,16
	 LD A,184

MAP_LOOP_1:

	 ACC_SetBlockSize
	 	LD C,0
	 ACC_CopyBlock
	 	LD C,(HL)
	 ACC_SetBlockSize
	 	LD C,#40
	 ACC_Off
	 
	 INC H
	 
	 REPT 4
	 	OUT (PORT_Y),A
	 	ACC_CopyBlock
	 		LD (DE),A
	 	ACC_Off
	 	INC A
	 ENDR
	 
	 DJNZ MAP_LOOP_1

;  ELSE
 
; 	 LD B,16
; 	 LD A,184

; MAP_LOOP_1:

; 	 ACC_SetBlockSize
; 	 	LD C,#40
; 	 ACC_CopyBlock
; 	 	LD C,(HL)
; 	 ACC_Off	 
	 
; 	 OUT (PORT_Y),A
; 	 ACC_CopyBlock
; 	 	LD (DE),A
; 	 ACC_Off
; 	 INC A	 
; 	 LD L,64
; 	 ACC_CopyBlock
; 	 	LD C,(HL)
; 	 ACC_Off
; 	 OUT (PORT_Y),A
; 	 ACC_CopyBlock
; 	 	LD (DE),A
; 	 ACC_Off
; 	 INC A	 
; 	 LD L,64*2
; 	 ACC_CopyBlock
; 	 	LD C,(HL)
; 	 ACC_Off
; 	 OUT (PORT_Y),A
; 	 ACC_CopyBlock
; 	 	LD (DE),A
; 	 ACC_Off
; 	 INC A	 
; 	 LD L,64*3
; 	 ACC_CopyBlock
; 	 	LD C,(HL)
; 	 ACC_Off
; 	 OUT (PORT_Y),A
; 	 ACC_CopyBlock
; 	 	LD (DE),A
; 	 ACC_Off
; 	 INC A	 
; 	 INC H
; 	 LD L,0	 
; 	 DJNZ MAP_LOOP_1
;  ENDIF
										
	LD BC,240
	EX DE,HL
	ADD HL,BC
	EX DE,HL
	LD A,H
	LD H,#60
	CP #50
	JR Z,MAP_LOOP_2

	XOR A
	OUT (PORT_Y),A

	POP AF
	POP HL
	LD (HL),A

	POP AF
	OUT (SLOT3),A
	POP AF
	OUT (SLOT1),A
	RET

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


; IX+0		- страница стенки
; IX+1,2	- адрес стенки в странице
; IX+3		- положение по вертикали - задает масштаб
; IX+4,5	- положение по горизонтали
; IX+6,7	- reserved
; IX+8,9	- X-add-parameter (коэфициент масштабирования по Y)
; IX+10		- реальная ширина стенки ???
; IX+11		- реальная высота стенки ???
WALL:	IN A,(SLOT3)
	LD (WALL_SLOT3_RET),A
	IN A,(SLOT1)
	LD (WALL_SLOT1_RET),A
	IN A,(PORT_Y)
	LD (WALL_PORT_Y_RET),A
	LD A,#58
	OUT (SLOT3),A

	LD A,(IX+0)					; страница стенки
	OUT (SLOT1),A

	EXX
		LD C,0					; порт масштаба

		LD H,TABLE_X/256			; таблица высот и коэфициентов масштабирования
		LD L,(IX+3)				; положение по Y / определяет высоту
		LD A,(HL)				; масштаб - LOW
		AND 3
		LD (X_ADD),A
		INC H
		LD A,(HL)				; масштаб - HIGH
		LD (X_ADD2),A
		DEC H

		LD A,L
		ADD A,A
		NEG					; ширина по горизонтали

		BIT 0,(IX+M_VAR3)
		JR Z,NO_DEL2
		RRA
		AND #7F
NO_DEL2:
		BIT 1,(IX+M_VAR3)
		JR Z,NO_DEL4
		AND A
		RRA
		RRA
		AND #3F
NO_DEL4:
	EXX

	LD B,A						; реальная ширина стенки???
;	LD B,(IX+10)					; ширина стенки

	LD C,0						; X-start-LOW

;	LD HL,(SCREEN_1)
	LD E,(IX+4)					; - адрес по горизонтали
	LD D,(IX+5)
;	ADD HL,DE

;	LD A,E
;	AND A
;	BIT 7,D
;	JR Z,WALL_NO_SCF
;	SCF
;	EX AF,AF'					; спрятать в AF - параметр счетчика и флаг
;							; CF - стенка не дошла до края
;							; в A сколько линий до начала экрана
;WALL_NO_SCF:
;
;	LD HL,140h
;	AND A
;	SBC HL,DE
;	LD A,L						; в A - сколько линий осталось до конца экрана??

	LD HL,(SCREEN_1)
	ADD HL,DE

;	LD A,(IX+3)
	LD A,B
	RRA
	AND #7F						; разделили на 2
	LD E,A
;	SUB 128
;	LD E,A
	LD D,0
	SBC HL,DE
	EX DE,HL

	LD H,(IX+2)							; старший адрес стенки
	LD L,(IX+1)

	LD A,#58
	OUT (SLOT3),A
WOLL_LOOP:

	XOR A
	OUT (PORT_Y),A

	LD A,D
	CP #C3
	JR NC,NO_WRITE_ALL					; не выводить за экран и закончить
	CP #C0
	JR C,NO_WRITE_LINE					; не выводить за экран

	LD A,(DE)							; Z-bufer!!!
	EXX
		CP L
	EXX
	JR C,NO_WRITE_LINE

	EXX
		LD B,1
		OUT (C),C						; масштаб - 1
		ACC_SetBlockSize
			LD B,#40					; задать длину линии
		ACC_Off
	EXX

	ACC_CopyBlock
		LD A,(HL)						; взять линию стенки
	ACC_Off

	EXX
; L - высота -128..0..127 !!!
		LD B,(HL)
		INC H
		LD A,(HL)						; масштаб - HIGH
		OUT (C),A
		INC H
		LD A,L
		ADD A,A
		JR NC,NO_Z_A1
		XOR A
NO_Z_A1:
		NEG
		ACC_SetBlockSize
			LD (HL),A					; задать длину линии
		ACC_Off
		DEC H
		DEC H
		LD A,L
	EXX

	BIT 7,A
	JR Z,NO_Z_A
	XOR A
NO_Z_A:
	OUT (PORT_Y),A						; задать порт Y

	ACC_CopyScreenBlock
		LD (DE),A						; вывести линию
	ACC_Off

	LD A,E
	AND #0F

					IF YesSound
					CALL Z,SOUND
					; ELSE
					; CALL Z,YesSoundZero
					ENDIF

NO_WRITE_LINE:

	INC DE								; новое значение X

	LD A,C
X_ADD2+1:
	ADD A,0								; X-add-parameter 2
	LD C,A
X_ADD+1:
	LD A,0								; X-add-parameter
	ADC A,H
	LD H,A								; следующая линия WOLL

	DJNZ WOLL_LOOP

NO_WRITE_ALL:
;
WALL_PORT_Y_RET+1:
	LD A,0
	OUT (PORT_Y),A
WALL_SLOT3_RET+1:
	LD A,0
	OUT (SLOT3),A
WALL_SLOT1_RET+1:
	LD A,5
	OUT (SLOT3),A
	RET

;
;
;***************************************
MAKE_MAP:
; HL - положение в текущей карте.
; делать все 4 квадранта
	PUSH HL
	LD DE,(LAST_HL)
	AND A
	SBC HL,DE
	LD A,H
	OR L
	JR NZ,CONT_MAKE
	POP HL
	LD (LAST_HL),HL
	RET

LAST_HL:	DW 0000

CONT_MAKE:
	POP HL
	LD (LAST_HL),HL
	IN A,(SLOT1)
	PUSH AF

	LD A,(TABLE_WALL)					; карта
	OUT (SLOT1),A

	LD DE,TABLE_W						; текущие карты
	PUSH HL

	LD C,16

MAP_L1:
	LD B,16
MAP_L2:
	LD A,(HL)
	LD (DE),A
	INC HL
	INC E
	DJNZ MAP_L2

	LD A,#30
	ADD A,L
	LD L,A
	LD A,H
	ADC A,0
	LD H,A

	DEC C
	JR NZ,MAP_L1

	INC D
	POP HL
	PUSH HL

	CALL SOUND

	LD C,16

MAP_L3:
	LD B,16

	PUSH HL

MAP_L4:
	LD A,(HL)
	LD (DE),A
	LD A,L
	ADD A,#40
	LD L,A
	LD A,H
	ADC A,0
	LD H,A
	INC E
	DJNZ MAP_L4
	POP HL

	DEC HL
	DEC C
	JR NZ,MAP_L3

	INC D
	POP HL
	PUSH HL

					IF YesSound
					CALL SOUND
					; ELSE
					; CALL YesSoundZero
					ENDIF

	LD C,16

MAP_L5:
	LD B,16

MAP_L6:
	LD A,(HL)
	LD (DE),A
	DEC HL
	INC E
	DJNZ MAP_L6

	LD A,L
	SUB 30H
	LD L,A
	LD A,H
	SBC A,0
	LD H,A

	DEC C
	JR NZ,MAP_L5

	INC D
	POP HL
	PUSH HL

					IF YesSound
					CALL SOUND
					ENDIF

	LD C,16

MAP_L7:
	LD B,16

	PUSH HL

MAP_L8:
	LD A,(HL)
	LD (DE),A
	LD A,L
	SUB 40H
	LD L,A
	LD A,H
	SBC A,0
	LD H,A

	INC E
	DJNZ MAP_L8
	POP HL

	INC HL
	DEC C
	JR NZ,MAP_L7

	POP HL

	POP AF
	OUT (SLOT1),A
	RET

MAP_PLACE:
; вычисление положения и проверка на
; наличие препятствий
	PUSH DE
	LD A,(X_COORD+1)
	LD E,A

	LD A,(Y_COORD+1)
	LD D,A

	CALL MAP_PLACE_X
	RES 5,H								; переключить карту на таблицу стенок
	POP DE
	RET

MAP_PLACE_X:
; DE - Y:X -> HL карта, E - препятствие

	LD A,E
	RRCA
	RRCA
	AND #3F
	LD L,A

	LD A,D
	RRCA
	RRCA
	AND #3F

	RRCA
	RRCA
	LD H,A
	AND #C0
	OR L
	LD L,A

	LD A,H
	AND #0F
;	OR 50H
	OR #70								; карта с препятствиями
	LD H,A								; HL - КАРТА

	IN A,(SLOT1)
	PUSH AF
	LD A,(TABLE_WALL)
	OUT (SLOT1),A
	LD A,(HL)
	LD E,A
;	RES 5,H								; переключить карту на таблицу стенок
	AND A
	JR Z,CONT_MOVE
	POP AF
	OUT (SLOT1),A
	SCF
	RET

CONT_MOVE:
	POP AF
	OUT (SLOT1),A
	AND A
	RET

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

;SOUND_PG:	DB #FF
;COV_ADR:	DB 0
;SND_P:		DB #FF
SND_A:		DW #C000
					IF YesSound
SND_STOP:
; остановить музыку
	PUSH AF
	PUSH BC

	LD BC,CBL.COVOX_OUT
	LD A,#80
SND_OUT_S:
	OUT (C),A							; забить ковокс-бластер одним значением
	DJNZ SND_OUT_S

	LD A,#C9							; забить возврат в программу играния музыки
	LD (SoundOnOff),A

	POP BC
	POP AF
	RET

SND_CONTINUE:							; продолжить музыку
	PUSH AF
	PUSH BC

	LD A,0								; забить NOP в программу играния музыки
	LD (SoundOnOff),A

	POP BC
	POP AF
	RET


INIT_SOUND:
; инициализировать музыку
SND_INIT:
	PUSH AF
	PUSH HL
	PUSH DE
	PUSH BC

	LD HL,0
	LD (SND_C1),HL
	LD (SND_C2),HL

	; LD A,0
	; LD (SND_P),A

	LD A,0
	LD (SoundOnOff),A

	LD B,0
	IN A,(SLOT3)
	LD E,A

	JR SND_INIT1
					ENDIF

SOUND:
					IF !YesSound
					; PUSH AF
					; CALL KBD_INT
					; POP AF
					RET
					ENDIF
;
					IF YesSound
SoundOnOff:
	NOP				; сюда вставляется команда RET для отключения звука и NOP для включения
	PUSH AF
	PUSH HL
SND_MORE:
	CALL KBD_INT
	IN A,(#FE)
;
COV_ADR+1:
	XOR 0				; covox адрес
;
	AND #80
	JP NZ,NO_LD_SND

	PUSH DE
	PUSH BC

	LD A,(COV_ADR)
	CPL
	LD B,A

	LD HL,(SND_A)
	LD C,CBL.COVOX_OUT
	LD D,16

	IN A,(SLOT3)
	LD E,A
D2_FRAM_SndPage+1:
	LD A,0
	OUT (SLOT3),A

L_DDX:
	OUTI
	OUTI
	OUTI
	OUTI

	OUTI
	OUTI
	OUTI
	OUTI

	DEC D
	JR NZ,L_DDX

	LD (SND_A),HL

	LD A,H
	AND A
	JP NZ,NO_SNDP

SND_INIT1:
	PUSH IX
	PUSH AF
	EX AF,AF'
	PUSH AF
	PUSH HL
	PUSH DE
	PUSH BC
	EXX
	PUSH HL
	PUSH DE
	PUSH BC

	AND A
	LD HL,(SND_C1)
	LD BC,SND_READ_SECTORS
	SBC HL,BC
	LD (SND_C1),HL
	LD HL,(SND_C2)
	LD C,B
	SBC HL,BC
	LD (SND_C2),HL

	JR NC,NO_NEW_COUNT

;	CALL SWITCH_SND

	CALL CLEAR_COVOX

	LD HL,SND_SEC1
	LD DE,SND_S1
	LD BC,8
	LDIR

	AND A
	LD HL,(SND_C1)
	LD BC,SND_READ_SECTORS
	SBC HL,BC
	LD (SND_C1),HL
	LD HL,(SND_C2)
	LD BC,0
	SBC HL,BC
	LD (SND_C2),HL

;_------[Чтение секторов с диска]-------
NO_NEW_COUNT:
	LD HL,-SND_READ_SECTORS*512			; буфер для данных
	LD A,(D2_FRAM_SndPage)			;!FIXIT		; страница буфера, если адрес в окне #C000
	LD DE,(SND_S1)					; абсолютный номер сектора Младшая часть
	LD IX,(SND_S2)					; абсолютный номер сектора Старшая часть
	LD B,SND_READ_SECTORS				; число читаемых секторов
	LD C,BIOS.HDD_READ				; функция чтения
	CALL HDD_FN
;---------------------------------------

	LD HL,(SND_S1)
	LD BC,SND_READ_SECTORS
	ADD HL,BC
	LD (SND_S1),HL

	LD HL,(SND_S2)
	LD C,B
	ADC HL,BC
	LD (SND_S2),HL

	LD HL,-SND_READ_SECTORS*512
	CALL EFFECTS

	POP BC
	POP DE
	POP HL
	EXX
	POP BC
	POP DE
	POP HL
	POP AF
	EX AF,AF'
	POP AF
	POP IX

	LD HL,-SND_READ_SECTORS*512
	LD (SND_A),HL

NO_SNDP:
	LD A,B
	CPL
	LD (COV_ADR),A

	LD A,E
	OUT (SLOT3),A

;	CALL INTERUPT

	POP BC
	POP DE
	JP SND_MORE

NO_LD_SND:

	POP HL
	POP AF
	RET
			ENDIF
;
			IF !YesSound
YesSoundZero:
			 PUSH AF
			 PUSH HL
			 CALL KBD_INT
			 POP HL
			 POP AF
			 RET
			 ENDIF

EFFECTS:
			IF !YesSound
			 RET
			ENDIF
	LD DE,(EFF_)
	LD A,D
	CP #C0
	RET NC

	IN A,(SLOT2)
	EX AF,AF'
	LD A,(EFF_PAGE)
	OUT (SLOT2),A

	LD BC,SND_READ_SECTORS*512

EFF_LOOP:
	LD A,(DE)
	ADD A,(HL)
	RRA
	LD (HL),A
	INC HL
	INC DE
	DEC C
	JR NZ,EFF_LOOP
	DJNZ EFF_LOOP

	LD (EFF_),DE
	EX AF,AF'
	OUT (SLOT2),A
	RET
;***************************************

CLEAR_Z_BUFER:
	IN A,(SLOT3)
	PUSH AF
	LD A,#50
	OUT (SLOT3),A

	LD A,0
	OUT (PORT_Y),A

	LD DE,(SCREEN_1)
	ACC_SetBlockSize
		LD A,0
	ACC_FillOneByte
		LD (DE),A
		INC D
	ACC_SetBlockSize
		LD B,#40
	ACC_FillOneByte
		LD (DE),A
	ACC_Off

	POP AF
	OUT (SLOT3),A
	RET
;***************************************

FIRE_S:
	LD A,(FIRE_B)
	AND A
	JR NZ,FIRE_X
	LD A,1
	LD (FIRE_CT),A
	RET
;
FIRE_CT:	DB 1
FIRE_B:		DB 0
EFF_:		DW #C000
;
FIRE_X:
	LD A, #80
	LD (EFF_+1),A						; включить эффект
	CALL MONSTR_BFG_INS					; вставить монстра огня!
	LD A,4
	LD (FIRE_CT),A
	XOR A
	LD (FIRE_B),A
	RET

;***************************************
KBD_INT:
	IN A,(Z84.SIO.Ch_A.Ctrl)
	BIT 0,A
	RET Z
	IN A,(Z84.SIO.Ch_A.Data)

	CP #E0
	JR Z,KBD_INT
	CP #E1
	JR Z,KBD_INT
	CP #F0
	JR Z,.KBD_OFF
	CP 3
	CALL Z,SAVE_PIC_PR

	PUSH AF
	LD A,(OFF_BYTE)
	AND A
	JR Z,.NO_LAST_KEY

	POP AF
	LD (LAST_KEY),A
	PUSH AF

.NO_LAST_KEY:
	POP AF

	CP 20								; CTRL
	JR Z,.EFF_ON
	CP 117								; KEY_UP
	JR Z,.DIR_UP
	CP 114								; KEY_DN
	JR Z,.DIR_DN
	CP 107								; KEY_LF
	JR Z,.DIR_LF
	CP 116								; KEY_RT
	JR Z,.DIR_RT

	JR .KBD_INT2

.KBD_OFF:
	XOR A
	LD (OFF_BYTE),A						; 0, если появилось отжимание
	JR KBD_INT

.KBD_INT1:
	PUSH HL
	LD HL,0
	LD (A_SPEED),HL
	LD (X_SPEED),HL
	LD (Y_SPEED),HL
	POP HL

.KBD_INT2:
	LD A,#FF
	LD (OFF_BYTE),A
	JR KBD_INT


.EFF_ON:
	LD A,(OFF_BYTE)
	LD (FIRE_B),A
	CALL FIRE_S
	JR .KBD_INT2

.DIR_UP:
	LD A,(OFF_BYTE)
	LD (UP_),A
	JR .KBD_INT1
.DIR_DN:
	LD A,(OFF_BYTE)
	LD (DN_),A
	JR .KBD_INT1
.DIR_LF:
	LD A,(OFF_BYTE)
	LD (LF_),A
	JR .KBD_INT1
.DIR_RT:
	LD A,(OFF_BYTE)
	LD (RT_),A
	JR .KBD_INT1

UP_:		DB #00
DN_:		DB #00
LF_:		DB #00
RT_:		DB #00
OFF_BYTE:	DB #FF

;
;INCLUDE INTMOUSE.ASZ
;

TAB_ANGLE:
	DB 0,1		; 0
	DB 1,1		; 45
	DB 1,1		; 45
	DB 1,0		; 90
	DB 1,0		; 90
	DB 1,-1		; 135
	DB 1,-1		; 135
	DB 0,-1		; 180
	DB 0,-1		; 180
	DB -1,-1
	DB -1,-1
	DB -1,0
	DB -1,0
	DB -1,1
	DB -1,1
	DB 0,1		; 0

TAB_ANGLE2:
	DB 0,2		; 0
	DB 1,2		; 22
	DB 2,2		; 45
	DB 2,1		; 67
	DB 2,0		; 90
	DB 2,-1		; 112
	DB 2,-2		; 135
	DB 1,-2		; 157
	DB 0,-2		; 180
	DB -1,-2
	DB -2,-2
	DB -2,-1
	DB -2,0
	DB -2,1
	DB -2,2
	DB -1,2		; 0

TAB_ANGLE3:

	DB 4,2		; 67
	DB 4,1		; 67

	DB 4,0		; 90
	DB 4,-1		; 112
	DB 4,-2		; 135
	DB 4,-3		; 135
	DB 4,-4		; 135
	DB 3,-4		; 157
	DB 2,-4		; 157
	DB 1,-4		; 157

	DB 0,-4		; 180
	DB -1,-4
	DB -2,-4
	DB -3,-4
	DB -4,-4
	DB -4,-3
	DB -4,-2
	DB -4,-1

	DB -4,0
	DB -4,1
	DB -4,2
	DB -4,3
	DB -4,4		; 0
	DB -3,4		; 0
	DB -2,4		; 0
	DB -1,4		; 0

	DB 0,4		; 0
	DB 1,4		; 0
	DB 2,4		; 22
	DB 3,4		; 45
	DB 4,4		; 45
	DB 4,3		; 45


MONSTR_ALL:
	LD HL,(ANGLE_M)
	RL L
	RL H
	RLA
	RL L
	RL H
	RLA
	RL L
	RL H
	RLA
	LD L,H
	AND 7
	LD H,A
	LD (ANGLE_R),HL

	LD IX,MONSTR_TABLE

MONSTR_LOOP:
	LD A,(IX+M_PAGE)
	AND A
	RET Z

;	JP MONSTR_ALL1

	LD A,(X_COORD+1)					; положение игрока
	SUB (IX+M_X+1)						; положение монстра
	ADD A,64
	JR Z,NO_M_OUT
	BIT 7,A								; проверка на дальность
	JR NZ,NO_M_OUT						; не выводить
									  
	SUB 64
	NEG
	LD L,A

	LD A,(Y_COORD+1)					; положение игрока
	SUB (IX+M_Y+1)						; положение монстра
	ADD A,64
	JR Z,NO_M_OUT

 	BIT 7,A
 	JR NZ,NO_M_OUT						; проверка на дальность

	SUB 64
	NEG
	LD H,A								; H - Y, L - X
	OR L
	JR Z,NO_M_OUT						; проверка на 0

	LD B,0

	BIT 7,H
	JR Z,A_NO_ADD4
	LD A,H								; поворот на 180 -X->X; -Y->Y
	NEG
	LD H,A
	LD A,L
	NEG
	LD L,A
	LD B,4
A_NO_ADD4:
	BIT 7,L
	JR Z,A_NO_ADD2
	LD A,L								; поворот на 90  Y->X; -X->Y
	NEG
	LD L,H
	LD H,A
	INC B
	INC B

A_NO_ADD2:
; B - информация о квадранте 0,2,4,6
; L - X-координата
; H - Y-координата

MONSTR_ALL1:

	LD A,L
	ADD A,A
	ADD A,A
	LD L,A
; HL - указатель на таблицу (4096 по 4b)
; HL - PAGE:(HL) данные
; для вывода на экран -> угол -> x-координата,
; высота/ширина

	SET 6,H
	IN A,(SLOT1)
	PUSH AF
	LD A,(PAGE_M_PLACE)
	OUT (SLOT1),A

	LD E,(HL)							; угол младший
	INC L
	LD D,(HL)							; угол старший
	INC L
	LD C,(HL)							; высота

	POP AF
	OUT (SLOT1),A

	LD A,D
	ADD A,B
	LD D,A								; добавить квадрант

	DEC C
	BIT 7,C
	JR Z,MONST_H1
	LD C,0								; монстр рядом
MONST_H1:
	INC C
	LD (IX+M_HIGH),C					; положение по вертикали

	LD HL,(ANGLE_R)
	AND A
	EX DE,HL
	SBC HL,DE

;	ADD HL,DE

;	LD DE,512+160-512
;	LD D,2
;	LD E,160

;	ADD HL,DE

	LD A,H
	AND 7
	LD H,A

	LD (IX+M_HOR),L						; угол
	LD (IX+M_HOR+1),H

	LD DE,128
	ADD HL,DE

	LD DE,256+320
	AND A
	SBC HL,DE							; проверка попадания монстра в угол зрения

	CALL C,WALL

										IF YesSound
										CALL SOUND
										; ELSE
										; CALL YesSoundZero
										ENDIF

NO_M_OUT:
	call MONSTR_NEXT_P

	LD DE,MONSTR_D_LEN
	ADD IX,DE
	JP MONSTR_LOOP

MONSTR_NEXT_P:
	BIT 7,(IX+M_VAR3)					; не меняюийся монстр (убитый)
	RET NZ

	LD A,(IX+M_VAR2)					; счетчик цикла
	AND 0Fh
	RLCA
	RLCA
	RLCA
	RLCA
	ADD A,(IX+M_VAR2)					; добавить младший байт к старшему
	LD (IX+M_VAR2),A
	AND 0F0h
	RET NZ								; вернуться, если не 0

;	JR NC,NO_ADD_MX
	BIT 6,(IX+M_VAR3)					; бит единичного показа	цикла
	JP Z,SW_MONS_X

	CALL SW_MONS_X
	RET Z
	SET 7,(IX+M_VAR3)					; остановить переключение
	RET

SW_MONS_X:
	LD A,(IX+M_X)
	ADD A,(IX+M_VX)
	LD (IX+M_X),A
	LD A,(IX+M_X+1)
	ADC A,(IX+M_VX+1)
	LD (IX+M_X+1),A
	LD A,(IX+M_Y)
	ADD A,(IX+M_VY)
	LD (IX+M_Y),A
	LD A,(IX+M_Y+1)
	ADC A,(IX+M_VY+1)
	LD (IX+M_Y+1),A

	LD A,(IX+M_X+1)
	LD E,A
	LD A,(IX+M_Y+1)
	LD D,A
	CALL MAP_PLACE_X					; проверить, нет ли препятствия
;										  если С - препятствие есть
	JR NC,CONT_MONS

; при встрече с препятствием
	BIT 3,(IX+M_VAR3)
	JR Z,CONT_MONS						; если 0, ничего не делать
;										  иначе - исчезновение монстра с
;										  выкидыванием из таблицы

	CALL MONSTR_DELET					; удалить монстра
	LD DE,-MONSTR_D_LEN
	ADD IX,DE							; переключиться на предыдущего
	XOR A								; и вернуться
	RET

CONT_MONS:

	BIT 2,(IX+M_VAR3)					; переключение по старшему адресу
	JR Z,SW_MONS

	LD A,(IX+M_ADR+1)					; переключатель адреса
	ADD A,(IX+M_VAR4)					; сколько добавлять
	AND 3Fh
	OR 40h
	LD (IX+M_ADR+1),A
	CP 40h								; признак завершения цикла
	RET

SW_MONS:
	LD A,(IX+M_ADR)						; переключатель адреса
	ADD A,40H
	LD (IX+M_ADR),A
	AND A								; признак завершения цикла
;NO_ADD_MX:
	RET


SAVE_PIC_PR:
	PUSH AF
	PUSH IX
	PUSH HL
	PUSH DE
	PUSH BC
	LD A,(FLAG)
	AND A
	JR NZ,NO_SAVE

	LD A,#FF
	LD (FLAG),A
	CALL SAVE_PIC
	LD A,0
	LD (FLAG),A
NO_SAVE:

	POP BC
	POP DE
	POP HL
	POP IX
	POP AF
	RET

SAVE_HL: DW 0
SAVE_P1: DW 0
SAVE_P2: DW 0
SAVE_RGA2: DB 0

SAVE_PIC:
	IN A,(SCREEN_SWITCH)
	AND 1
	LD HL,#C040
	JR NZ,SET_1X
	LD HL,#C180
SET_1X:
	LD IX,TABLE_PIC
	LD A,(IX)
	AND A
	RET Z

	LD DE,#8436

SAVE_PIC_X:
	LD (SAVE_HL),HL						; Pic line
	IN A,(PORT_Y)
	LD (SAVE_RGA2),A

	LD C,SLOT2
	IN B,(C)
	LD (SAVE_P1),BC
	LD C,SLOT3
	IN B,(C)
	LD (SAVE_P2),BC

	LD A,#50
	OUT (C),A						; Screen

	LD A,#FF
	OUT (PORT_Y),A						; Line 1

	LD A,(IX)
	OUT (SLOT2),A

NEXT_SV_LN:
	LD HL,(SAVE_HL)						; вспомнить линию

	LD B,160
LOOP_SV_PIC:
	LD A,(HL)
	LD (DE),A
	INC HL
	INC DE
	LD A,(HL)
	LD (DE),A
	INC HL
	INC DE

	bit 6,d
	JR Z,NO_NEXT_PAGE
	LD A,B
	LD BC,(SAVE_P1)
	OUT (C),B
	LD B,A
	INC IX
	LD A,(IX)
	OUT (SLOT2),A						; next page
	LD DE,#8000
NO_NEXT_PAGE:
	DJNZ LOOP_SV_PIC

;	CALL SOUND

	IN A,(PORT_Y)
	DEC A
	OUT (PORT_Y),A
	CP #FF
	JR NZ,NEXT_SV_LN

	LD BC,(SAVE_P2)
	OUT (C),B
	LD BC,(SAVE_P1)
	OUT (C),B
	LD A,(SAVE_RGA2)
	OUT (PORT_Y),A

	RET


;WALL_SET:

;***************************************
;		монстровая структура
; IX+0		- страница стенки
; IX+1,2	- адрес стенки в странице
; IX+3		- положение по вертикали - задает масштаб
; IX+4,5	- положение по горизонтали

; IX+6,7	- reserved
; IX+8,9	- X-add-parameter (коэфициент масштабирования по Y)
; IX+10		- реальная ширина стенки ???
; IX+11		- реальная высота стенки ???
; IX+12		- координата X
; IX+14		- координата Y
; IX+16		- скорость X
; IX+18		- скорость Y
; IX+20		- тип монстра
; IX+22		- переменные монстра

/*
SSS2:

	ENT	;.DEPHASE




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

;	DS 86F0H-$
;	DS 7F0H-$
;       db 'flc     C',0,80h,0,80H,80H,2,1
	DS #A000-$

	incbin "table.bin"
*/
;	ENT
	ASSERT $ < #1FFF, Relocate table "TABLE_W"!!!
D2_fram_END	EQU	$
;	
	OUTEND
;
	DISPLAY "d2_fram.bin starts - ",/H,TRACE
	DISPLAY "d2_fram.bin ends - ",/H,D2_fram_END
	DISPLAY "Dd2_fram.bin size - ",/H,D2_fram_END-TRACE
;