;	DISPLAY "Service"
; !FIXIT тут можно, походу, дохрена убрать

; ; страницы с конфой для Sp97, для совместимости с древними прогами
; PG_SP1	equ #EC
; PG_SP2	equ #EE
; PG_AY	equ #EA
; ;

; ;!TODO замутить заливку конфы, рестарт, перехват ресета силами BIOS
; PG_Sp2000		EQU #FE
; PG_Sp2000_REINIT	EQU #FD
;
RST_CONF:
;--[] ZX Spectrum
.AY8910:
	LD D,#35							;!HARDCODE REG #35 - BASIC SETTING 1 (SYS_PAGE.CONFIG_DE+1 = #C13B on PAGE #FE) 
	CALL CMOS_RD
	OR 1
	CALL CMOS_WR

	LD BC,Port_All_Mode
	IN A,(C)
	AND #FE								;!HARDCODE 
	OUT (C),A							; ACC_OFF

	;LD A,PG_AY
	LD DE,ACEX.Config_ID.Sp97_AY
	JR .INT_PLD
;--[]

;--[] Sprinter ZX
.SP97_1:
	LD D,#35							;!HARDCODE REG #35 - BASIC SETTING 1 (SYS_PAGE.CONFIG_DE+1 = #C13B on PAGE #FE) 
	CALL CMOS_RD
	AND #FE
	CALL CMOS_WR

	LD BC,Port_All_Mode
	IN A,(C)
	AND #FE								;!HARDCODE 
	OUT (C),A							; ACC_OFF

	;LD A,PG_SP1
	LD DE,ACEX.Config_ID.Sp97_1
	JR .INT_PLD
;--[]

;--[]
.SP97_2:
	LD BC,Port_All_Mode
	IN A,(C)
	OR 1								; ACC_ON
	OUT (C),A
	;LD A,PG_SP2
	LD DE,ACEX.Config_ID.Sp97_2
	JR .INT_PLD
;--[]


;--[]
;[x]
.SP2000:
	LD BC,Port_All_Mode
	IN A,(C)
	OR 1								; ACC_ON
	OUT (C),A
	LD DE,ACEX.Config_ID.Sp2000
	JR .INT_PLD
;--[]


;--[]
.CUSTOM:
	CP #80
	JR NC,.CHOOSE_CNF
        ; only for old FLEX10K soft compatible
	LD C,SLOT3
	IN B,(C)
	OUT (C),A							; PAGE с прошивкой
	LD DE,(#C090)						        ; PLD-ID
	OUT (C),B							; RET page
;--[]	;JR INT_PLD
.INT_PLD:       ; only for old FLEX10K soft compatible
        LD      C,SLOT3
	IN      B,(C)
	 LD     A,SYS_PAGE
	 OUT    (C),A
	 LD     (SYS_PAGE.CONFIG_BYTE),DE
	OUT     (C),B

        LD A,E		; config-byte
	CP #FF
	LD A,#80
	JR Z,.YES_CBL
	XOR A
.YES_CBL:
	LD BC,CBL.SYS_PORT
	OUT (C),A

	LD A,E		; config-byte

	OR #FE								;!HARDCODE 
	LD BC,Port_All_Mode					        ; SYSTEM Spectrum/Sprinter
	OUT (C),A

	LD A,#3C
	OUT (FDC_93.DrvCTRL),A

	XOR A
	RET
	;
	;[x]
.CHOOSE_CNF:
        ; [x]
         CP	ACEX.Config_PG.Sp2000_SoftSetUp
	 JP	Z,.ReturnSoftReset
	 ;
         CP	ACEX.Config_PG.Sp2000
         JR	Z,.INIT_ACEX
	 ;
	 CP	ACEX.Config_PG.Sp2000_SetUp
	 JR	Z,.SP2000
        ;

        ; only for old FLEX10K soft compatible
	CP ACEX.Config_PG.Sp97_1
	LD DE,ACEX.Config_ID.Sp97_1
	JR Z,.INT_PLD
	CP ACEX.Config_PG.Sp97_2
	LD DE,ACEX.Config_ID.Sp97_2
	JR Z,.INT_PLD
	CP ACEX.Config_PG.Sp97_AY
	LD DE,ACEX.Config_ID.Sp97_AY
	JR Z,.INT_PLD
	SCF
	RET
	;
	;[x]
.INIT_ACEX:
	DI
	; устанавливаем нулевую карту портов
	LD	A,CNF_PORT.CNF_0
	OUT	(SYS_PORT.ON),A
	; и так понятно что делает
	IN	A,(SLOT3)						; сохраняем номер воткнутой страницы
	PUSH	AF
	LD	A,Spec_Page
	OUT	(SLOT3),A
	; проверяем размер блока с конфой и получаем страницы конфы
	LD	HL,Spec_Page.bitstream_pages
	LD	A,B
	AND	A
	JR	Z,.INIT_ACEX.ReloadConfFromROM
	;
	CALL	EMM.GetMemBlkPages
	LD	A,B
	JR	C,.INIT_ACEX.ERROR
	CP	BitStream_SizeInPages+1	; количество страниц в кэш для бистрима плюс одна
	JR	NC,.INIT_ACEX.ERROR
	LD	A,(Spec_Page.bitstream_pages)
	INC	A
	JR	Z,.INIT_ACEX.ERROR	
	;
.INIT_ACEX.ReloadConfFromROM:
	; закидываем в Spec_Page прогу для заливки конфы
	LD	HL,.INIT_ACEX.PROGRAM
	LD	DE,Spec_Page.init_acex
	LD	BC,.INIT_ACEX.PROGRAM.Size
	LDIR
	; если ZF=0, то процедура сделает ресет с перезаливкой из BIOS, иначе из КЭШ
	CALL	Spec_Page.init_acex
	LD	BC,256*BIOS.REINIT.HARD_RESET + BIOS.REINIT
	;
	; на входе в BC параметры функции BIOS
.INIT_ACEX.ifSoftreset:
	; сохраняем воткнутые страницы в Spec_Page
	IN	A,(SLOT0)
	LD	E,A
	IN	A,(SLOT1)
	LD	D,A
	IN	A,(SLOT2)
	POP	HL			; восстанавливаем номер воткнутой страницы
	LD	L,A
	LD	(Spec_Page.page_0),DE
	LD	(Spec_Page.page_2),HL
	; достаём адрес возврата в вызывающую функцию и сохраняем в Spec_Page
	POP	DE
	LD	HL,RST_18_1.exit
	XOR	A
	SBC	HL,DE
	JR	NZ,.set_ret			; NZ - если вызов был по RST #18
	POP	DE			; если вызов был в ОЗУ по RST 8
	INC	A
.set_ret:
	LD	(Spec_Page.RET_addr),DE
	; A=0 - SYS_PORT.ON
	; A=1 - SYS_PORT.OFF
	LD	(Spec_Page.Reload_Version),A
	LD	HL,0
	ADD	HL,SP
	LD	(Spec_Page.Stack_Point),HL
	; Устанавливаем ключи
	LD	HL,Spec_Page.flag_R
	LD	(HL),"R"
	INC	HL
	LD	(HL),"S"
	INC	HL
	LD	(HL),"T"
	;
	; .. ... ... .. 
	;!TODO сделать функцию по заливке своей конфы, перехвату ресета.
	; *. Вход в подфункцию только через RST 08 или #18
	; *. Сохранить все страницы пользователя в SYS_PAGE для перехвата ресета
	; *. Достать со стека адрес возврата и сохранить в SYS_PAGE для перехвата ресета
	; *. Сохранить куда-нибудь значение стека
	; *
	; .. ... ... .. 
	;LD	BC,256*BIOS.REINIT.HARD_RESET + BIOS.REINIT
	JP_to_BIOS
	;
.ReturnSoftReset:
	DI
	; устанавливаем нулевую карту портов
	LD	A,CNF_PORT.CNF_0
	OUT	(SYS_PORT.ON),A
	; и так понятно что делает
	IN	A,(SLOT3)						; сохраняем номер воткнутой страницы
	PUSH	AF
	LD	A,Spec_Page
	OUT	(SLOT3),A
	;
	LD	BC,256*BIOS.REINIT.SOFT_RESET + BIOS.REINIT
	JR	.INIT_ACEX.ifSoftreset
	;
	;;;
.INIT_ACEX.ERROR:
	POP	AF
	OUT	(SLOT3),A
	SCF
	RET
;
.INIT_ACEX.PROGRAM:
	DISP	Spec_Page.init_acex
		;
		SAFE_PORTY
		IN	A,(FastRAM.ON)
		IN	A,(SLOT1)
		LD	(.slot1_page),A
		;
		LD	A,#FE						; чтоб проверить, что вызывать после CALL NZ,.INIT_ACEX.PROGRAM.LOAD
		; тут ZF должен быть из вызывающей процедуры
		CALL	NZ,.INIT_ACEX.PROGRAM.LOAD			; если RAM_BLOCK ID не равен 0, то выполняется
		INC	A						; флаг ZF=0 грузим из ROM
		;
.INIT_ACEX.PROGRAM.SET_KEYS:
		LD	A,3
		OUT	(FastRAM.SLOT0),A				; Страница КЭШ = 3
		;
		LD	HL,.INIT_ACEX.Reload_String			; флаг перезагрузки из КЭШ-а
		JR	Z,.skip						; устанавливаем флаг перезагрузки из КЭШ-а
		INC	L						; затираем флаг перезагрузки из КЭШ-а
.skip:		LD	DE,ACEX.LOADER.String_Address-#C000
		LD	BC,#10
		LDIR

		LD	HL,#FFFF					; залить конфу только при первой перезагрузке
		;LD	HL,ACEX.LOADER.Reload_Flag			; заливать конфу при каждой перезагрузке
		LD	(ACEX.LOADER.Reload_Flag_Address-#C000),HL
		;
.INIT_ACEX.PROGRAM.END:
		XOR	A
		OUT	(FastRAM.SLOT0),A
		IN	A,(FastRAM.OFF)
.slot1_page+1:	LD	A,0
		OUT	(SLOT1),A
		RET
		;
		;
.INIT_ACEX.PROGRAM.LOAD:
		XOR	A						; страница КЭШ
		LD	HL,Spec_Page.bitstream_pages
		OUT	(FastRAM.SLOT0),A				; Страница КЭШ = 0
		INC	A
.INIT_ACEX.PROGRAM.load_loop:
		EX	AF,AF'
		LD	A,(HL)
		INC	HL
		CP	#FF
		RET	Z
		OUT	(SLOT1),A					; страница с данными файла
		EX	AF,AF'
		;
		; перекидывание #3000 байтов в КЭШ(0) = #1000
		EXX
		 LD	HL,#4000					
		 LD	DE,#1000
		 LD	BC,#3000
		 LDIR
		 ; докидывание #1000 байтов в КЭШ(1) = #0000
		 ; HL = #7000
		 OUT	(FastRAM.SLOT0),A				; Страница КЭШ = 1
		 INC	A
		 ;
		 LD	D,C		; LD DE,0
		 LD	B,#10		; LD BC,#1000
		 LDIR
		EXX
		JR	.INIT_ACEX.PROGRAM.load_loop

	
.INIT_ACEX.Reload_String:
		DB	ACEX.RELOAD_STRING
	;
 ENT
.INIT_ACEX.PROGRAM.Size	EQU	$-.INIT_ACEX.PROGRAM
;
;***************************************

;[x]
;--------------------------[;!TODO потестить]--------------------------;
; B - параметр сброса
; B = 1 - RESTART.
; B = 2 - Soft reset
; B = 3 - Hard reset
; B = 4 - Reinit spectrum pages
REINIT:	DEC     B
	JR      Z,.Restart      ;1
	DEC     B
	JR      Z,.SoftReset    ;2
	DEC     B
	JR      Z,.HardReset    ;3
	DEC     B
	SCF
	RET     NZ
.ReinitZXpages:                 ;4
 	LD DE,RESERVED_PAGES                                            ; таблица занятых системных страниц
	LD HL,SYS_PAGE.RAMD_FAT                                         ; Адрес FAT ОЗУ.

        LD C,SLOT3
        IN B,(C)
        LD A,SYS_PAGE
        OUT (SLOT3),A
       
	LD A,(DE)
.zxloop:
	CP #FF
	JR Z,.endzxloop
	INC DE
	LD L,A

        LD A,(HL)
        AND A
        JR NZ,.errorzxloop

        LD A,(DE)
	LD (HL),A
	JR .zxloop

.errorzxloop:
        DEC DE
        LD HL,-RESERVED_PAGES-1
        ADD HL,DE
        JR NC,.errorzxloop_noChanges

        DEC DE
        LD H,high SYS_PAGE.RAMD_FAT
        LD A,(DE)
	LD L,A
        LD A,#FF
	LD (HL),A
.errorzxloop_noChanges:
        SCF
.endzxloop:
        OUT (C),B
        RET
;

;[x]
.HardReset:
        DI
        LD      A,DCP_PAGE
        OUT     (SLOT1),A                                               ; set DCP page
        LD      A,ACEX.RESET
        LD      (#4400),A                                               ; open for WR
.loop:  LD      BC,#0100                                                ; цикл сброса
        OUT     (C),C
        LD      B,0
        OUT     (C),C
        JR      .loop                                                   ; полностью зациклить!
;

;[x]
.Restart:
	DI
	LD      A,0
	LD      BC,#1FFD
	OUT     (C),A
	LD      B,#7F
	OUT     (C),A
	LD      A,#40
	OUT     (SLOT3),A
	LD      A,5
	OUT     (SLOT1),A
	LD      A,2
	OUT     (SLOT3),A
	LD      A,0
	OUT     (SLOT0),A
	OUT     (RGADR),A
	OUT     (RGMOD),A
	JP 0                                                            ;Restart
;

;
.SoftReset:
        DI
	LD A,#10
	LD BC,#1FFD
	OUT (C),A							; 8-я страница !!

	LD A,RESET_PAGE
	OUT (SLOT3),A
	LD A,CNF_PORT.TURBO.OFF
	OUT (SYS_PORT.ROM),A
.loop2:	LD (#C000),A                                                    ; Soft RESET !!!
	JR .loop2
;
;----------------------------------------------------------------------;
;

;
;----------------------------------------------------------------------;
; не должно портить DE
SET_ROM_FLAG_ZX:
	EX	AF,AF'
	 IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,Spec_Page
	OUT	(SLOT3),A
	XOR	A
	LD	(Spec_Page.flag_Z),A
	LD	(Spec_Page.flag_X),A
	EX	AF,AF'
	OUT	(SLOT3),A
	RET
;----------------------------------------------------------------------;
;