

;
 IFNDEF MODE_CBL
	DEFINE MODE_CBL 1	; 0 - OUTI ver, 1 - #FD page ver.
 ENDIF
 IFNDEF MUSIC_22khz
	DEFINE MUSIC_22khz 1
 ENDIF
 IF MUSIC_22khz
;	; #5944x128 blocks for play
	DEFINE _memPagesForMuz 179
	DEFINE _ramDiskNumForMuz 3
	DEFINE _lastPageMuzOffset #5E00

 ELSE
	DEFINE _memPagesForMuz 29	

 ENDIF
;

;-------------------------------[Includes]------------------------------
	INCLUDE 'Shared_Includes/macroses/macros.z80'
	INCLUDE 'Shared_Includes/constants/SP2000.inc'
	INCLUDE 'Shared_includes/constants/dss_equ.inc'
	INCLUDE 'Shared_Includes/constants/BIOS_equ.inc'
	INCLUDE 'Shared_includes/macroses/accelerator.z80'

	INCLUDELUA <Shared_Includes/LUA/Functions.LUA>

	INCLUDE 'version.inc'
;-----------------------------------------------------------------------
;

	STRUCT SPRITE_TBL
Slot		BYTE #FF		; PAGE OF SPRITE
Address		WORD #C000		; ADDRESS OF SPRITE
Height		BYTE #78		; высота
Width		BYTE #80		; ширина
X			WORD 0000		; координата левого столбца спрайта на экране 0..(319-width)
Y			BYTE #50		; координата верхней строки спрайта на экране 0..(255-Height)
Attribute	BYTE #5C		; bit0 == 1 - метка последнего спрайта в списке, а так это графическая страница с подрежимами записи
	ENDS

;
;-------------------------[Standart EQU section]------------------------
org_addr			EQU	#8000+CLP_Buffer
code_addr			EQU START
stack_point			EQU #BFFF
program_start		EQU START
Loader_length		EQU 0
;-----------------------------------------------------------------------
;

;
;-----------------------------[EQU section]-----------------------------
ScreenSize:
.X				EQU 320
.Y				EQU 256

 DEFINE BACKPLANE_BMP 0
 IF BACKPLANE_BMP
BackPlane:
.Height			EQU 223
.Width			EQU 1102
.OffsetY		EQU 0
.Scroll.Step	EQU	1
.Scroll.Width 	EQU 2*(BackPlane.Width/2 - ScreenSize.X/2)
.PalSize		EQU 64*4
.PalOffset		EQU 0*4
.RGBoffset		EQU	0													; or #436 if with BMP header and palette
.FIllColorNum	EQU 4													; номер цвета в палитре картинки для заливки сверху и снизу
.SizeBytes		EQU BackPlane.Height * BackPlane.Width
.SizePages		EQU BackPlane.SizeBytes/#4000 + (((BackPlane.SizeBytes mod #4000) != 0) * -1)

 ELSE
BackPlane:
.Height			EQU 200
.Width			EQU 520
.OffsetY		EQU 23
.Scroll.Step	EQU	1
.Scroll.Width 	EQU 2*(BackPlane.Width/2 - ScreenSize.X/2)
.PalSize		EQU 64*4
.PalOffset		EQU 0*4
.RGBoffset		EQU	0													; or #436 if with BMP header and palette
.FIllColorNum	EQU 63													; номер цвета в палитре картинки для заливки сверху и снизу
.SizeBytes		EQU BackPlane.Height * BackPlane.Width
.SizePages		EQU BackPlane.SizeBytes/#4000 + (((BackPlane.SizeBytes mod #4000) != 0) * -1)
 ENDIF
	DISPLAY "Backplane size = ",/H,BackPlane.SizeBytes, ", pages - ",BackPlane.SizePages," (",#4000 * BackPlane.SizePages," bytes)"

RaidenSprite:
.PalOffset		EQU 128*4
.PalSize		EQU 64*4

VARS					EQU #9000
SPRITE_OLD2				EQU VARS
SPRITE_OLD1				EQU VARS+2
SPRITE_NEW				EQU VARS+4
SPEED_Y					EQU VARS+16
SPEED_X					EQU VARS+17
RAMD_1					EQU VARS+18
DAT_SPR0				EQU VARS+#100
DAT_SPR1				EQU VARS+#200
DAT_SPR2				EQU VARS+#300

IM2_Handler				EQU #88FF
;-----------------------------------------------------------------------
;

	INCLUDE 'Shared_Includes/constants/EXE_Header.z80'
	ORG org_addr

	; ORG #100
    ; .PHASE #8000

START:
	ld c,Dss.GetVMod
	rst ToDSS
	jr nc,1F
	ld a,3					; если ошибка, то ставим дефолтные значения режима и номера экрана
	ld b,1

1:	ld (vid_mod_save),a
	ld a,b
	ld (scr_num_save),a

	ld hl,START_MSG
	ld c,Dss.PChars
	RST ToDSS

	ld hl,LOADING_MSG
	ld c,Dss.PChars
	RST ToDSS

	call Load_Resources
;	jp start_load
;	JP BEGIN


; start_load:
; 	ld sp,#BFFF

; 	LD HL,#9000
; 	LD A,#81
; CTL_10:
; 	LD (HL),#FF
; 	INC L
; 	CP L
; 	JR NZ,CTL_10
; 	LD A,#C0
; STL_11:
; 	LD (HL),L
; 	INC L
; 	CP L
; 	JR NZ,STL_11
; CTL_12:
; 	LD (HL),#FF
; 	INC L
; 	JR NZ,CTL_12

;	IN A,(SLOT3)
;	EX AF,AF'
; 	LD A,SYS_PAGE
; 	OUT (SLOT3),A
; 	LD A,(RAMD_KEYS.F)
; 	OUT (SLOT3),A
; 	AND A
; 	JR Z,NO_CODED

; 	LD HL,#C000
; 	LD D,#90
; CODED1:
; 	LD E,(HL)
; 	LD A,(DE)
; 	LD (HL),A
; 	INC L
; 	JR NZ,CODED1
; 	INC H
; 	JR NZ,CODED1
; 	IN A,(SLOT3)
; 	LD L,A
; 	LD A,SYS_PAGE
; 	OUT (SLOT3),A
; 	LD H, high RAMD_FAT
; 	LD A,(HL)
; 	OUT (SLOT3),A
; 	CP #FF
; 	LD HL,#C000
; 	JR NZ,CODED1
;NO_CODED:

;	IN A,(SLOT3)
;	EX AF,AF'


;-------TEST--------------------------[v]
	ld hl,#9000
	ld a,#FF
	ACC_SetBlockSize
		cp 0
	ACC_FillOneByte
		ld (hl),a
		inc h
		ld (hl),a
		inc h
		ld (hl),a
		inc h
		ld (hl),a
	ACC_Off


	ld hl,BackPlane.FileName
	ld a,1
	ld c,Dss.Open
	rst ToDSS
	di
	push af

	ld hl,#9000 + BackPlane.PalOffset
	ld de,BackPlane.PalSize
	LD C,Dss.Read
	rst ToDSS
	DI

	pop af
	ld c,Dss.Close
	rst ToDSS
	di

	ld hl,RaidenSprite.FileName
	ld a,1
	ld c,Dss.Open
	rst ToDSS
	di
	push af

	ld hl,#9000 + RaidenSprite.PalOffset
	ld de,RaidenSprite.PalSize
	LD C,Dss.Read
	rst ToDSS
	DI	

	pop af
	ld c,Dss.Close
	rst ToDSS
	di
;-------TEST--------------------------[^]
/*
	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD A,(RAMD_KEYS.G)
	OUT (SLOT3),A
;	LD HL,#C036			;	BACKGRN0.PAL		
;	LD BC,#0400
	LD HL,#C000
	LD DE,#9000 + BackPlane.PalOffset
	LD BC,BackPlane.PalSize
	LDIR

	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD A,(RAMD_KEYS.H)	;	RAIDEN.PAL
	OUT (SLOT3),A
;	LD HL,#C236
;	LD BC,#0100
	LD HL,#C000
	LD DE,#9000 + RaidenSprite.PalOffset
	LD BC,RaidenSprite.PalSize
	LDIR

	EX AF,AF'
	OUT (SLOT3),A
*/

	LD HL,#9000
	LD DE,0
	LD B,#FF
	LD A,0
	LD C,BIOS.PIC_SET_PAL
	RST ToBIOS

	LD HL,#9000
	LD DE,0
	LD B,#FF
	LD A,1
	LD C,BIOS.PIC_SET_PAL
	RST ToBIOS

	LD A,2
	LD C,BIOS.FN_SINC
	RST ToBIOS


	LD C,BIOS.LP_OPEN_S
	LD B,8
	LD E,0
	LD HL,#5000
	RST ToBIOS

	LD C,BIOS.LP_OPEN_S
	LD B,9
	LD E,1
	LD HL,#4000
	RST ToBIOS

;	IN A,(SLOT3)
;	EX AF,AF'
;	LD A,#10
;	OUT (SLOT3),A
;	LD HL,#8000
;	LD DE,#C000
;	LD BC,#4000
;	LDIR
;	ld (#C000),bc
;	ld (#C001),bc
;	EX AF,AF'
;	OUT (SLOT3),A


	; LD HL,#C100
	; LD DE,#0800
	; LD BC,#4005
	; RST ToBIOS

	; LD HL,STRING
	; LD DE,#C080
	; LD BC,STRING_LEN
	; LDIR

	; DI
	; IN A,(SLOT3)
	; LD C,#F3
	; RST ToBIOS

BEGIN:
	DI

	LD SP,#BFFF
	
	ld hl,IM2_Proc
	ld (IM2_Handler),hl
	ld a,high IM2_Handler
	ld i,a
	IM 2

	IN A,(SLOT3)
	EX AF,AF'
	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD A,(RAMD_KEYS.H)
	LD (SND_P),A
	EX AF,AF'
	OUT (SLOT3),A


	ei
	halt
	di

	ld d,BackPlane.FIllColorNum
	call FILL_SCR

	ei
	halt
	di

	in a,(RGMOD)
	xor 1
;	and 1
	out (RGMOD),a

	ld d,BackPlane.FIllColorNum
	call FILL_SCR

	LD HL,SPRITE_DATA
	ld de,DAT_SPR0

	ACC_SetBlockSize
		ld a,SPRITES_L
	ACC_CopyBlock
		ld a,(hl)
		ld (de),A
		INC D
		LD (DE),A
		INC D
		LD (DE),A
	ACC_Off

	LD (SPRITE_NEW),DE
	DEC D
	LD (SPRITE_OLD1),DE
	DEC D
	LD (SPRITE_OLD2),DE

	EI
	HALT

;-----[Инициализация Covox-Blaster]-----

	ld bc,CBL.SYS_PORT

 IF MODE_CBL	;	[ 1 ]	-----<

	IF MUSIC_22khz
		ld a,#9B
	ELSE
		ld a,#9A
	ENDIF

 ELSE			;	[ 2 ]	-----<
	IF MUSIC_22khz
		ld a,#9B
	ELSE
		ld a,#9A
	ENDIF

 ENDIF			;	[ . ]	-----<

	out (c),a
	CALL MUTE_CBL
;---------------------------------------


; IFN MODE_CBL : DI : ENDIF

;//////////////////////////////////////////////
LOOP_ALL:

	LD A,3
	LD (save_border),a
	OUT (BorderColor),A

;	LD IX,(SPRITE_OLD2)
;	CALL SPRITE_RESTORE
; IFN MODE_CBL : CALL PlayMusic : ENDIF

	CALL FON_LOAD
	LD IX,(SPRITE_NEW)
	CALL SPRITE_LOAD
; IFN MODE_CBL : CALL PlayMusic : ENDIF

	LD DE,(SPRITE_OLD2)
	LD HL,(SPRITE_OLD1)
	LD (SPRITE_OLD2),HL
	LD HL,(SPRITE_NEW)
	LD (SPRITE_OLD1),HL
	LD (SPRITE_NEW),DE

; IFN MODE_CBL : CALL PlayMusic : ENDIF
; IFN MODE_CBL : CALL PlayMusic : ENDIF

	LD A,5
	LD (save_border),a
	OUT (BorderColor),A

;	CALL FILL_SCR
;LOOP_WW:
;	IN A,(0FEH)
;	AND #20
;	JR Z,LOOP_WW

; IFN MODE_CBL : EI : HALT : DI : ENDIF
; IF  MODE_CBL

halt_loop_repeat:
					HALT
halt_JP_address+1:	JR halt_loop_repeat
halt_loop_exit:

; ENDIF
	in a,(RGMOD)
	xor 1
;	and 1
	out (RGMOD),a

; IFN MODE_CBL : CALL PlayMusic : ENDIF
; IFN MODE_CBL : CALL PlayMusic : ENDIF

	ld a,(IM2_Proc.exit_key)
	and a
	jr nz,LOOP_ALL
	jp EXIT_TO_DSS
;//////////////////////////////////////////////


FILL_SCR:
	ld a,#50
	out (SLOT3),a

	LD HL,#C040
	in a,(RGMOD)
	and a
	jr nz,no_ld_hl1
	ld HL,#C180
no_ld_hl1:

	ACC_SetBlockSize
		LD A,0
	ACC_Off

	OUT (PORT_Y),A
	LD B,160

begin_loop:
	ACC_FillScreenOneByte	; !FIXIT оптимизировать
		LD (HL),D
		INC HL
		LD (HL),D
		INC HL
	ACC_Off

	DJNZ begin_loop

	RET

SPRITE_DATA:

	DB #FF		; PAGE_SPRITE
	dw #C000	; ADRESS SPRITE
	DB #78,#80	; SIZE
	DW 0000		; HOR_PLACE
	DB #50		; WER_PLACE
	DB #5C		; ATRIBUTE

	DB #FF
	dw #C000
	DB #78,#80
	DW #0060
	DB #50
	DB #5C

	DB #FF
	dw #C000
	DB #78,#80
	DW #00C0
	DB #50
	DB #5D

SPRITES_L	EQU $-SPRITE_DATA

;=======================================================================
/*
; !TODO процедура не используется!!!

; IX - адрес данных спрайта
; DE - x-координата положения
; A  - y-координата положения
; B  - атрибуты спрайта
SPRITE_RESTORE:	
	push ix

	IN A,(SLOT1)
	PUSH AF
	IN A,(SLOT3)
	PUSH AF
	IN A,(PORT_Y)
	PUSH AF

loop_all_2:

;	ld a,(ix+8)	; atributes
;	AND #0C
;	OR #50
	LD A,#50
	out (SLOT1),a

	LD BC,#4040
	IN A,(RGMOD)
	AND A
	JR NZ,NO_SCR2
	LD BC,#4180
NO_SCR2:
	LD E,(IX+5)	; X coordinate
	LD D,(IX+6)

	ex de,hl
	add hl,bc
;	ex de,hl

	ld b,(IX+3)	; высота
	ld c,(IX+4)	; ширина
	LD A,(IX+7)	; Y coordinate
	out (PORT_Y),a

	ACC_SetBlockSize
		ld (HL),c
	ACC_Off

	ld c,PORT_Y
sprite_2load_loop2:

	ACC_CopyBlock
		inc (hl)
;		LD D,(HL)
;		LD (HL),D
	ACC_Off

	inc a           ; добавить смещение по Y
	out (c),a
	djnz sprite_2load_loop2

	ld bc,9
	add ix,bc
	bit 0,(ix-1)
	jr z,loop_all_2

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

	pop ix

	ret
*/
;=======================================================================


;	; PAGE_SPRITE
;       ; ADRESS SPRITE
;       ; SIZE_H,SIZE_V
;       ; HOR_PLACE
;       ; WER_PLACE
;       ; ATRIBUTE
FON_LOAD:

	IN A,(SLOT0)
	PUSH AF
	IN A,(SLOT1)
	PUSH AF
	IN A,(SLOT3)
	PUSH AF
	IN A,(PORT_Y)
	PUSH AF

	LD A,#50
	OUT (SLOT1),A

	LD A,SYS_PAGE
	OUT (SLOT3),A

	LD A,(RAMD_KEYS.G)
	LD H, high RAMD_FAT
	LD L,A
	EX AF,AF'
	LD A,(HL)
	OUT (SLOT0),A

	LD HL,#C000 + BackPlane.RGBoffset
	LD DE,(FON_SHIFT)
	ADD HL,DE

	LD DE,#4040
	IN A,(RGMOD)
	AND 1
	JR NZ,NO_SCR3
	LD DE,#4180
NO_SCR3:
	EX AF,AF'
	OUT (SLOT3),A

	LD A,BackPlane.Height + BackPlane.OffsetY
	OUT (PORT_Y),A

	LD A,BackPlane.Scroll.Width
FON_LOOP:
	EX AF,AF'

		DI
	ACC_SetBlockSize
		LD B,0
	ACC_CopyBlock
		LD A,(HL)
		LD (DE),A
		INC H
		INC D
	ACC_SetBlockSize
		LD C,#40
	ACC_CopyBlock
		LD A,(HL)
		LD (DE),A
		DEC H
		DEC D
	ACC_Off
		EI

	LD BC,BackPlane.Width
	ADD HL,BC
	BIT 7,H
	JR NZ,NO_PGN

	EXX

; IFN MODE_CBL : CALL PlayMusic : ENDIF

	LD B,SYS_PAGE
	LD C,SLOT0
	IN L,(C)
	OUT (C),B

	LD C,SLOT3
	OUT (C),L							; SLOT3 <-- SLOT0 <-- SYS_PAGE

	LD C,SLOT0
	LD H,2
	LD L,(HL)
/*
	LD C,SLOT0
	LD H,2
	LD A,(HL)
	CP #FF
	JR NZ,.setNextPage
;	LD A,(RAMD_KEYS.G - #C000)
	ld a,l
.setNextPage:
	OUT (C),A
*/
	OUT (C),L

	EXX
	SET 7,H
	SET 6,H

NO_PGN:
	IN A,(PORT_Y)
	DEC A
	OUT (PORT_Y),A
	EX AF,AF'
	DEC A
	JR NZ,FON_LOOP

;SetBackgroundScrollShift:
;
	LD A,(FON_SHIFT)
ADD_A:
	ADD A,BackPlane.Scroll.Step
	LD (FON_SHIFT),A
	JR Z,YES_EXX
	CP BackPlane.Scroll.Width
	JR NZ,NO_EXX

YES_EXX:
	LD A,(ADD_A+1)
	NEG
	LD (ADD_A+1),A
NO_EXX:
;
	POP AF
	OUT (PORT_Y),A
	POP AF
	OUT (SLOT3),A
	POP AF
	OUT (SLOT1),A
	POP AF
	OUT (SLOT0),A
	ret
FON_SHIFT:	DW BackPlane.Scroll.Width/2
;
;

SPRITE_LOAD:		; IX - адрес данных спрайтов
	push ix
	IN A,(SLOT1)
	PUSH AF
	IN A,(SLOT3)
	PUSH AF
	IN A,(PORT_Y)
	PUSH AF

	CALL NEXT_SPR

loop_all_1:

; IFN MODE_CBL : CALL PlayMusic : ENDIF

	LD A,(IX+SPRITE_TBL.Slot)
	OUT (SLOT3),A

	ld a,(ix+SPRITE_TBL.Attribute)	; atributes
	AND #0C
	OR #50
	out (SLOT1),a

	LD BC,#4040
	IN A,(RGMOD)
	AND 1
	JR NZ,NO_SCR1
	LD BC,#4180
NO_SCR1:

	LD L,(IX+SPRITE_TBL.X)	; X coordinate
	LD H,(IX+SPRITE_TBL.X+1)

	add hl,bc
	EX DE,HL

	LD L,(IX+SPRITE_TBL.Address)	; адрес данных
	LD H,(IX+SPRITE_TBL.Address+1)

/*
	; ld c,(IX+SPRITE_TBL.Width)
	LD A,(IX+SPRITE_TBL.Y)
	add a,(ix+SPRITE_TBL.Height)
	dec a
	out (PORT_Y),a
	ld A,(IX+SPRITE_TBL.Height)
*/

	LD A,(IX+SPRITE_TBL.Width)
	LD (blk_size),A

	LD A,(IX+SPRITE_TBL.Y)
	LD C,(ix+SPRITE_TBL.Height)
	add a,c
	dec a
	out (PORT_Y),a
	ld a,c


	DI
	ACC_SetBlockSize
blk_size+*: ld c,0
;		ld c,(IX+SPRITE_TBL.Width)
	ACC_Off

	LD B,0

	EXX

	LD C,PORT_Y
	IN E,(C)
	LD B,A
sprite_load_loop:
	EXX

	ACC_CopyBlock
		LD A,(HL)
		LD (DE),A
	ACC_Off

	ADD HL,BC

	EXX

	DEC E
	OUT (C),E
	DJNZ sprite_load_loop
	EI


	EXX

	ld bc,SPRITE_TBL
	add ix,bc
	bit 0,(ix-1)
	jr z,loop_all_1

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

	pop ix
	ret

NEXT_SPR:
/*
;SetBackgroundScrollShift:
	LD A,(FON_SHIFT)

ADD_A:
	ADD A,BackPlane.Scroll.Step
	LD (FON_SHIFT),A
	JR Z,YES_EXX
	CP BackPlane.Scroll.Width
	JR NZ,NO_EXX

YES_EXX:
	LD A,(ADD_A+1)
	NEG
	LD (ADD_A+1),A
NO_EXX:
*/
	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD H, high RAMD_FAT
	LD A,(NEXT_SPRITE)
	LD L,A
	LD L,(HL)
	LD (IX+SPRITE_TBL.Slot),L

	LD (IX+SPRITE_TBL.Slot+SPRITE_TBL),L
	LD (IX+SPRITE_TBL.Slot+SPRITE_TBL*2),L

	LD A,L
	LD (NEXT_SPRITE),A
	INC A
	RET NZ
	LD A,(RAMD_KEYS.F)
	LD (IX+SPRITE_TBL.Slot),A
	LD (IX+SPRITE_TBL.Slot+SPRITE_TBL),A
	LD (IX+SPRITE_TBL.Slot+SPRITE_TBL*2),A
	LD (NEXT_SPRITE),A
	RET
NEXT_SPRITE: db #FF


;
;
; SOUND_PG:	DB #FF
; SND_P:		DB #FF

;===============================================[v]
			IFN	MODE_CBL
;===============================================			
/*		 доделать на старый вариант без прерываний
; old
;SND_A:		DW #C000
PlayMusic:
	PUSH AF
	PUSH HL

	IN A,(#FE)
COV_ADR+*:	XOR 0
	AND #80
	JP NZ,NO_LD_SND

	PUSH DE
	PUSH BC

	LD A,(COV_ADR)
	CPL
	LD B,A


SND_A+*:	LD HL,#C000
	LD C,CBL.OUT
	LD D,16
	IN A,(SLOT3)
	LD E,A
	LD A,(SND_P)
	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,b
	cpl
	ld (COV_ADR),a

	LD A,H
	AND A
	JR NZ,NO_SNDP

	LD H, high RAMD_FAT
	LD A,(SND_P)
	LD L,A
	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD A,(HL)
	LD (SND_P),A
	INC A
	LD HL,#C000
	LD (SND_A),HL

	JR NZ,NO_SNDP
	LD A,(RAMD_KEYS.H)
	LD (SND_P),A

NO_SNDP:

	LD A,E
	OUT (SLOT3),A

	POP BC
	POP DE
NO_LD_SND:
	POP HL
	POP AF
	RET

; old end
*/

PlayMusic:

	LD A,2
	OUT (BorderColor),A

	PUSH HL
	PUSH DE
	PUSH BC

	ld a,halt_loop_repeat-halt_JP_address-1			; repeat loop
	ld (halt_JP_address),a

COV_ADR+*:	LD A,0
	CPL
	LD B,A


SND_A+*:	LD HL,#C000
	LD C,CBL.OUT
	LD D,16
	IN A,(SLOT3)
	LD E,A
SND_P+*: 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,b
	cpl
	ld (COV_ADR),a

	LD A,H
	AND A
	JR NZ,NO_SNDP

	LD H, high RAMD_FAT
	LD A,(SND_P)
	LD L,A
	LD A,SYS_PAGE
	OUT (SLOT3),A
	LD A,(HL)
	LD (SND_P),A
	INC A
	LD HL,#C000
	LD (SND_A),HL

	JR NZ,NO_SNDP
	LD A,(RAMD_KEYS.H)
	LD (SND_P),A

NO_SNDP:

	LD A,E
	OUT (SLOT3),A

	POP BC
	POP DE
	POP HL
	LD A,(save_border)
	OUT (BorderColor),A

	POP AF
	EI
	RETI

;===============================================
			ELSE
;===============================================
;
;===============================================
; new
PlayMusic:
	LD A,2
	OUT (BorderColor),A

	PUSH HL
	push de
	push bc				; !TODO оптимизировать

	ld a,halt_loop_repeat-halt_JP_address-1			; repeat loop
	ld (halt_JP_address),a

	IN A,(SLOT1)
	LD E,A
SND_P+*: LD A,0
	OUT (SLOT1),A

	ld a,CBL.BUFFER_PAGE
	ld bc,SLOT3
	in b,(c)
	out (c),a


SND_A+*:	ld hl,#4000
			ld d,#C0	
	ACC_SetBlockSize
		ld a,#80
	ACC_CopyBlock
 		ld a,(hl)
		ld (de),a
	ACC_Off
	
	out (c),b

	xor a
	ld hl,(SND_A)
	ld bc,128
	adc hl,bc
	LD (SND_A),HL

	LD A,H				; !TODO оптимизировать
	CP #80
	JR C,NO_SNDP

	LD H, high RAMD_FAT - #80
	LD A,(SND_P)
	LD L,A
	LD A,SYS_PAGE
	OUT (SLOT1),A
	LD A,(HL)
	LD (SND_P),A

	LD HL,#4000
checkLastPage+*: cp 0
	jp nz,1F
	LD A,(RAMD_KEYS.H)
	LD (SND_P),A
	ld hl,_lastPageMuzOffset
1:	LD (SND_A),HL

NO_SNDP:
	LD A,E
	OUT (SLOT1),A

	POP BC
	pop de
	POP HL
	LD A,(save_border)
	OUT (BorderColor),A

	POP AF
	EI
	RETI
; new end
;===============================================
			ENDIF
;===============================================[^]
;
COVOX_OFF:
	LD A,#80
	LD BC,CBL.SYS_PORT
	OUT (c),a
MUTE_CBL:
	ld a,#80
	LD BC,CBL.OUT
.loop:
	OUT (C),A
	DJNZ .loop
	RET


;
;-----------[Обработчик прерывания]-----------
IM2_Proc:
	DI
	PUSH AF

; IF MODE_CBL
	IN A,(CBL.INT_PORT)
	RLCA
/*
	JR NC,.set_nop
	CALL PlayMusic
	jp .keys_check
*/

	JP C,PlayMusic

	LD A,2
	LD (save_border),a
	OUT (BorderColor),A

.set_nop:
	xor a				; exit from loop
	ld (halt_JP_address),a
; ENDIF

.keys_check:
	ld a,+(high ZXKeys.Line_7) & +(high ZXKeys.Line_0)
	in a,(ZXKeys)
	and 1
	jp nz,.exit_int

	ld (.exit_key),a

.exit_int:
	pop af
	EI
	RETI

.exit_key:
	BYTE	#FF
;---------------------------------------------
;

;
;---------------------------------------------
; Функция возвращает физ.номер последней страницы блока
; A <-- ID блока
; NC --> A = физ.номер последней страницы блока
; CF --> хер его знает, ошибка какая-то
GetLastPageNumber:
	ld h, high RAMD_FAT
	inc a
	ld l,a

	ld a,SYS_PAGE
	ld c,SLOT3
	in b,(c)
	push bc
	out (c),a

	ld a,#FF
	ld bc,#100

	cpir
	scf
	jp PE,.exit

	dec hl
	dec hl
	ld a,(hl)
	and a

.exit:
	pop bc
	out (c),b
	ret
;---------------------------------------------
;

;
;----------------[EXIT to DSS]----------------
EXIT_TO_DSS:
	DI

	CALL COVOX_OFF
	CALL RMD_UNMAP

	LD A,1
	LD HL,RAMBlkIDs

.loop_mem:
	PUSH HL
	PUSH AF
	LD A,(HL)
	LD C,Dss.FreeMem
	RST ToDSS
	DI

	POP AF
	POP HL
	INC A
	INC HL

	CP FilesTBL.END+1
	JR C,.loop_mem


 IF MODE_CBL && MUSIC_22khz
	CALL MemHack.restore
 ENDIF


vid_mod_save+*: ld a,0
scr_num_save+*: ld b,0	
	ld c,Dss.SetVMod
	rst ToDSS

	ld de,0
	ld hl,#2050
	ld b,7
	ld a,32
	ld c,Dss.Clear
	RST ToDSS


	ld hl,START_MSG
	ld c,Dss.PChars
	RST ToDSS

;-----[Clean keyboard buffer]-----
clean_kbd_buf:
	IN	A,(Z84.SIO.Ch_A.Ctrl)
	BIT	0,A
	jr z,.exit
	IN	A,(Z84.SIO.Ch_A.Data)
	jr clean_kbd_buf
.exit:
;---------------------------------
	
	ld hl,EXIT_MSG
	ld c,Dss.PChars
	RST ToDSS

	IM 1
.loop_exit:
	LD B,0
	LD C,Dss.Exit
	RST ToDSS
	JR	.loop_exit
;---------------------------------------------
;

;-------[загрузка ресурсов игры]--------
Load_Resources:

 IF MODE_CBL && MUSIC_22khz
	CALL MemHack.free
 ENDIF

	in a,(SLOT3)
	ld (.SavePage),a

	LD B,FilesTBL.END
	LD DE,FilesTBL
	LD HL,RAMBlkIDs

;---------[Начало цикла]
.LR_loop:
	PUSH BC								;++счётчик
	PUSH HL								;++буфер под BlockID

	ex de,hl
	ld b,(hl)							; FilesTBL
	inc hl
	ld (.FileName),hl

; B - размер блока в страницах
	ld c,Dss.GetMem
	rst ToDSS
	di
; A - идентификатор блока памяти
	
	pop hl								;--буфер под BlockID
	ld (hl),a
	inc hl
	push hl								;++буфер под BlockID

; A - идентификатор блока
	ld hl,Temp_Buffer
	ld c,BIOS.GetMemBlkPages
	rst ToBIOS
	di
; B - число страниц в блоке
; HL - адрес буфера, в буфере список
;	физических страниц по порядку,
;	заканчивающийся байтом 0FFh

	push hl								;++буфер со списком страниц
	push bc								;++сколько страниц грузим

.FileName+*: ld hl,0

	ld a,1
	ld c,Dss.Open
	rst ToDSS
	di
	ld (.TempFileID),a
	pop bc								;--сколько страниц грузим
	pop hl								;--буфер со списком страниц

;---[читаем]
.readloop:
	ld a,(hl)
	out (SLOT3),a
	inc hl
	push hl								;++буфер со списком страниц
	push bc								;++сколько страниц грузим

.TempFileID+*: ld a,#FF					; файловый манипулятор

	LD HL,#C000							; адрес в памяти
	LD DE,#4000							; количество читаемых байт
	LD C,Dss.Read
	rst ToDSS
	DI

	pop bc								;--сколько страниц грузим
	pop hl								;--буфер со списком страниц
	DJNZ .readloop
;---[]

;---[закрываем]
	ld a,(.TempFileID)
	ld c,Dss.Close
	rst ToDSS
	di
;---[]

	ld de,(.FileName)
	ld hl,13
	add hl,de
	ex de,hl

	POP HL								;--буфер под BlockID
	POP BC								;--счётчик
	DJNZ .LR_loop 
;---------[]


;-----------[Маппинг на РАМ-Диски]
	CALL RMD_UNMAP
;---[Маппим на РАМ-Диски]
	LD A,1								; Номер рамдиска F:
	LD HL,RAMBlkIDs

.loop_map:
	PUSH HL
	PUSH AF
	LD B,(HL)
	LD C,BIOS.BLK_TO_RAMD
	RST ToBIOS
	DI

	POP AF
	POP HL
	INC A
	INC HL

	CP FilesTBL.END+1
	JR C,.loop_map
;---[]

;-----------[]

;-------------[Возврат]
.SavePage+*: ld a,0
	out (SLOT3),a

 IF MODE_CBL
	IF MUSIC_22khz
		ld a,(RAMBlkIDs + _ramDiskNumForMuz)
		ld bc, +( _memPagesForMuz - 1) * 256 + BIOS.GetMemPage
		rst ToBIOS
	;!FIXIT сделать проверку на ошибку
		ld (checkLastPage),a
	ENDIF
 ENDIF


	RET
;-------------[]

;---[освобождаем рамдиски F..I]
RMD_UNMAP:
	LD B,FilesTBL.END
.loop_unmap:
	PUSH BC

	LD A,B
	LD C,BIOS.RAMD_CLEAR
	RST ToBIOS
	DI

	POP BC
	DJNZ .loop_unmap
	RET
;---[]

;
;---[ MemHack ]
 IF MODE_CBL && MUSIC_22khz
MemHack:
.free:

	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A

	LD	HL,RAMD_FAT
	LD	DE,.Buff
	xor a
	ACC_SetBlockSize
		cp #10
	ACC_CopyBlock
		cp (hl)
		ld (de),a
	ACC_FillOneByte
		ld (hl),a
	ACC_Off

	LD	DE,.Buff + #10
	LD	L,DCP_PAGE		; #C240
	LD	A,(HL)
	LD	(DE),A
	INC	DE
	LD	(HL),#50		; Video Page
	INC	L				; #C241

	xor a
	ACC_SetBlockSize
		cp #07
	ACC_CopyBlock
		cp (hl)
		ld (de),a
	ACC_FillOneByte
		ld (hl),a
	ACC_Off

	EX	AF,AF'
	OUT	(SLOT3),A
	RET

.restore:
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A

	LD	DE,RAMD_FAT
	LD	HL,.Buff

	ACC_SetBlockSize
		cp #10
	ACC_CopyBlock
		cp (hl)
		ld (de),a
	ACC_Off

	LD	HL,.Buff + #10
	LD	E,DCP_PAGE		; #C240
	LD	A,(HL)
	LD	(DE),A
	INC	HL
	INC E

	ACC_SetBlockSize
		cp #7
	ACC_CopyBlock
		cp (hl)
		ld (de),a
	ACC_Off

	EX	AF,AF'
	OUT	(SLOT3),A
	RET
.Buff:	BLOCK #10+1+7, #FF

 ENDIF
;------------[]
;


save_border: BYTE 0

;---[Таблица загрузки файлов]
; длина в страницах				01 байт
; имя файла						13 байт
; 	если имя файла < 12 символов,
; 	то добить нулями до 12
; RAM DISKS OLD:
;	E - TRD
;	F - PIC.DAT		= RAIDENXX.DAT	
;	G - ARMORS2.BMP	= BACKGRND.BMP
;	H - RAYSTO1.BMP = RAIDEN01.BMP
;	I - MISS2.CBL	= MUSIC_01.CBL
;
; RAM DISKS NEW:
;	E - TRD
;	F - PIC.DAT		= RAIDENXX.DAT	
;	G - ARMORS2.BMP	= BACKGRND.BMP
;	H - MISS2.CBL	= MUSIC_01.CBL
FilesTBL:
        DZ      27,                     'RAIDENXX.DAT'          ; DISK F:
;       DZ      07,                     'BACKGRND.BMP'          ; DISK G:
 
 IF BACKPLANE_BMP
        DZ      BackPlane.SizePages,    'BACKGRN1.RGB'          ; DISK G: 
 ELSE
        DZ      BackPlane.SizePages,    'BACKGRN0.RGB'          ; DISK G:
 ENDIF

;       DZ      02,                     'RAIDEN01.BMP'          ; DISK H:       ; RAIDEN.PAL
 IF MODE_CBL && MUSIC_22khz
        DZ      _memPagesForMuz,        'MUSIC_02.CBL'          ; DISK H:
 ELSE
        DZ      _memPagesForMuz,        'MUSIC_01.CBL'          ; DISK H: 
 ENDIF
.END    EQU ($-FilesTBL)/14                                     ; количество файлов 

 IF BACKPLANE_BMP
BackPlane.FileName:     DZ      'BACKGRN1.PAL' 
 ELSE
BackPlane.FileName:     DZ      'BACKGRN0.PAL'
 ENDIF
RaidenSprite.FileName:  DZ      'RAIDEN.PAL  '


RAMBlkIDs:		BLOCK FilesTBL.END,0

Temp_Buffer:	BLOCK _memPagesForMuz + 1,#FF			; Длина в блоках самого большого из файлов выше + 1

START_MSG:		DB	13,10,13,10
				DB	'Mortal Kombat demo by Ivan Mak. 2002 year.',13,10
				DZ	'EXE v.',MK_VERSION,' by Anatoliy Belyanskiy. ',BUILD_DATE,' (',#91,') Sprinter Team.',13,10,13,10
LOADING_MSG:	DZ	'Loading resources, please wait...',13,10
EXIT_MSG:		DZ	'All done)))',13,10
;---[]
;
	ASSERT IM2_Handler>$, "The code leaks into the IM2 byte address!"
;
;
/*

EMM_FN7:		; получить следующую страницу блока по предыдущему
LD A,page       ; физическая страница блока
LD C,0C7h       ; номер функции
CALL 3D13h      ; NC -> A - следующая физическая страница блока
				;       A=FF - индицирует конец блока
				; CF -> ошибка номера страницы
; Информация о распределении памяти хранится в виде RAM Allocation Table,
; похожей на дисковый FAT. Поэтому нахождение физического номера следующей
; страницы по предыдущему физическому номеру происходит значительно быстрее,
; чем поиск по увеличенному на единицу логическому номеру.

	LD A,page  
	D C,BIOS.GetMemPageNext
	RST ToBIOS
	
EMM_FN4:		; получить физический номер страницы из блока
LD A,id_blk     ; идентификатор блока
LD B,page       ; логическая страница в блоке
LD C,0C4h       ; номер функции
CALL 3D13h      ; NC -> А - физический номер страницы
				; CF -> А=0 - нет такого блока, A=FF - конец блока
*/


