;        "MENU PROGRAMS."
;*********************************
;       FOR INCLUDE !!!
;*********************************
;       Обслуживание МЕНЮ
;       HL - адрес таблицы программ
;       A - номер в таблице
;           если A=-1, то возврат,
;           иначе выполнение
;*****************************
EXEC_PNT:
        INC A
        RET Z
        ;!FIXIT почему не так?
         ; DEC     A
         ; JR      Z,EXEC_HL
         ; LD      D,0
         ; LD      E,A
         ; XOR     A
         ; ADC     HL,DE
         ; ADC     HL,DE
        ;
EXEC_PNT_LOOP:
        DEC A
        JR Z,EXEC_HL
        INC HL
        INC HL
        JR EXEC_PNT_LOOP
EXEC_HL:
        LD E,(HL)
        INC HL
        LD D,(HL)
        INC HL
        EX DE,HL
        JP (HL)
RET_FROM_M:
        POP HL
        RET

;****************************************
;       РАБОТА С MENU_128
;****************************************
;       ВХОД:  DE - адрес меню
;              BC - длина меню
;       ВЫХОД: A - выбранный пункт
;****************************************
RUN_MENU:
        PUSH IX
        PUSH DE         ; DE - MENU
        PUSH BC         ; BC - len_menu

        LD A,(DE)
        DEC A           ; число CMD
        CP 9            ; !HARDCODE макисмальное число пунктов меню
        JR C,RUN_M_1
RUN_MN_ERR:
        POP BC
        POP DE
        LD A,#FF       ; вернуться с номером 255 - ошибка
        POP IX
        RET
RUN_M_1:
        LD A,(ZX_VARS.PROG.SWAP_ROM)
        CP #F5					        ; сравнить А с опкодом PUSH AF
        JR NZ,RUN_MN_ERR


        LD HL,LEN_P_M
        ADD HL,BC                       ; HL - нужная длина памяти
        LD B,H                          ; HL -> BC
        LD C,L
        LD HL,(ZX_VARS.WORK_SPACE)      ; HL - начало раб обл

        PUSH BC
        PUSH HL

        CALL C_1655     ; получить рабочую память

        POP DE
        PUSH DE         ; начало раб обл

        LD BC,LEN_P_M   ; длина программы меню
        LD HL,MENU_128  ; сама программа
        LDIR            ; программа перемещена. DE - место для MENU
        POP BC
        PUSH BC         ; начало программы

        PUSH DE         ; сохранить место для MENU
        LD DE,MN_128_S  ; данные для shifter
        CALL SHIFTER    ; изменить данные в соответствии с положением в MEM
        POP DE          ; вернуть место для MENU

        POP HL          ; начало программы
        POP IX          ; длина данных
        POP BC          ; длина меню
        EX (SP),HL      ; HL - меню
        LDIR            ; переместить данные MENU

        POP HL          ; адрес программы MENU
        PUSH HL
        PUSH IX         ; длина раб. обл
        CALL JP_HL      ; вызов программы MENU
        POP BC          ; вернуть длину раб обл
        POP HL          ; и начала программы

        PUSH AF         ; сохранить номер выбора
        CALL C_19E8     ; освободить память !!
        POP AF          ; вернуть номер выбора
        POP IX
        RET             ; возврат из программы RUN_MENU
JP_HL:  JP (HL)
;**************************************
;            128k MENU
;**************************************
;!HARDCODE
MENU_PROG       EQU     #25B9   ; #25B9  in sp_128.asm
;SWAP_ROM       EQU     #5B00
NEW_SP          EQU     #1F45   ; L1F45: in sp_128.asm
RET_SP          EQU     #1F20   ; L1F20: in sp_128.asm

;**************************************
;  Программа вызова MENU_128 из ОЗУ.
;**************************************
MN_128_S:
        DB SH_1 - MENU_128+1
        DB SH_2 - MENU_128+1
        DB SH_3 - MENU_128+1
        DB SH_4 - MENU_128+1
        DB SH_5 - MENU_128
        DB SH_6 - MENU_128
        DB SH_7 - MENU_128
        DB SH_8 - MENU_128
        DB SH_9 - MENU_128
        DB SH_A - MENU_128
        DB SH_B - MENU_128
        DB SH_C - MENU_128
        DB 0
;**************************************
;  Эта программа перемещается в озу
;**************************************
MENU_128:
        XOR     A
        OUT     (SYS_PORT.RAM),A
        CALL    ZX_VARS.PROG.SWAP_ROM
        CALL    NEW_SP

SH_1:   LD      DE,MENU_DAT - MENU_128
        LD      HL,ZX_VARS.MENU_TBL.JUMP
        LD      BC,4
        LDIR

SH_2:   LD      HL,MENU_128_E - MENU_128
        LD      (ZX_VARS.MENU_TBL.JUMP),HL
SH_3:   LD      HL,MENU_128_E2 - MENU_128
        LD      (ZX_VARS.MENU_TBL.TEXT),HL
        JP      MENU_PROG

RET_M   EQU     $-MENU_128
SH_4:   LD      HL,MENU_DAT - MENU_128
        LD      DE,ZX_VARS.MENU_TBL.JUMP
        LD      BC,4
        LDIR

        CALL    RET_SP
        CALL    ZX_VARS.PROG.SWAP_ROM
        EX      AF,AF'
         ;LD    A,0
         ;OUT   (CNF_PORT),A
         LD     A,SYS_PORT.EXTENSION
         OUT    (SYS_PORT.ROM),A            ;!!!!! версия для ПЗУ
        EX      AF,AF'
        RET
MENU_DAT:
        DW 0,0
MENU_128_E:
        DB 8
        DB 0
SH_5:   DW RET_M
        DB 1
SH_6:   DW RET_M
        DB 2
SH_7:   DW RET_M
        DB 3
SH_8:   DW RET_M
        DB 4
SH_9:   DW RET_M
        DB 5
SH_A:   DW RET_M
        DB 6
SH_B:   DW RET_M
        DB 7
SH_C:   DW RET_M
MENU_128_E2:

LEN_P_M EQU $-MENU_128

;**************************************
;       RST 30 - получение    BC SPACES с адреса HL
;       #19E8  - освобождение BC spaces с адреса HL
; HL - раб. ячейка
; BC - адрес программы
; DE - адрес данных для перемещения
SHIFTER:
        LD A,(DE)       ; (DE) - SHIFT IN PROG
        AND A
        RET Z
        INC DE
        LD L,A
        LD H,0

        ADD HL,BC       ; HL - ADRESS FOR SHIFT
        LD A,(HL)       ; (HL)=(HL)+BC
        ADD A,C
        LD (HL),A
        INC HL
        LD A,(HL)
        ADC A,B
        LD (HL),A
        JR SHIFTER

;*******************************************
; МЕНЮ :  байт 1 - для результата
;         байт 2 - число пунктов +1
;         название меню, код 0FFh ( COPY )
;         пункты меню окончание байтом с
;         уст, 7-м битом + пустая строка !!
;*******************************************
BASIC_MENU:
;        LD A,(HL)
;        CP 'S'
;        JP Z,SET_SYSTEM

        LD DE,(ZX_VARS.CH_ADR)
        PUSH DE
        LD (ZX_VARS.CH_ADR),HL
        CALL_48X #1C8C  ; SYMBOL VAR
        CALL_48X #2BF1  ; input txt !!!
                        ; DE - adr
                        ; BC - len
        PUSH DE
        PUSH BC
        INC DE
        CALL TST_M
        JR C,NO_EXE_M
        CALL RUN_MENU
	LD (IY+0),255
NO_EXE_M:
        POP BC
        POP DE
        LD (DE),A
        POP HL
        LD (ZX_VARS.CH_ADR),HL
        JP SW_ROM
TST_M:
        PUSH DE
        PUSH BC
        EX DE,HL
        LD D,(HL)
        INC D
        LD A,255
        CPIR
        JR NZ,ERR_TST_M
LOOP_TST_M:
        LD A,B
        OR C
        JR Z,ERR_TST_M

        BIT 7,(HL)
        INC HL
        DEC BC
        JR Z,LOOP_TST_M
        DEC D
        JR NZ,LOOP_TST_M
        POP BC
        POP DE
        AND A
        RET

ERR_TST_M:
        POP BC
        POP DE
        LD A,255
        SCF
        RET

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

CALL_DOS_MOVE:
        LD HL,DOS_PROG
        LD DE,DOS_PROG.Exec
        LD BC,DOS_PROG.Size
        LDIR
        RET
;
;       HL - адрес команды, BC - длина команды
CALL_DOS1:
	LD C,(HL)
	INC HL
	LD B,0
        LD DE,(ZX_VARS.E_LINE)
        LD (ZX_VARS.CH_ADR),DE
        LDIR
        LD (ZX_VARS.WORK_SPACE),DE
        LD (ZX_VARS.STK_BOT),DE
        LD (ZX_VARS.STK_END),DE
        CALL CALL_DOS_MOVE
        JP DOS_PROG.Exec

DOS_PROG:
        DISP #5C00 - DOS_PROG.Size      ;!HARDCODE
          //DOS_PROG:
.Exec:    PUSH    AF
          XOR     A
          OUT     (SYS_PORT.RAM),A
          POP     AF
          //DOS_PROG_A+1:
.Patch+2: CALL    #3D03                 ;!HARDCODE
          PUSH    AF
          ;!FIXIT сделать через условие компиляции ZX_ROM_BIOS
           //LD  A,0
           //OUT (CNF_PORT),A
           LD   A,SYS_PORT.EXTENSION
           OUT  (SYS_PORT.ROM),A        ;!!!!! версия для ПЗУ
          POP     AF
          RET
          //DOS_PROG_LEN
.Size     EQU $ - .Exec
        ENT

        ;????? вроде, не используются
CONT_PROG:
         LD HL,#1AFD    ;!HARDCODE COM_LN:
         PUSH HL
         LD HL,#5B00    ;!HARDCODE
         PUSH HL
         LD DE,ZX_VARS.FLG_INPUT
         LD BC,1
         LD A,#E8       ;!HARDCODE
         LD (DE),A
         JP SW_ROM
CALL_DOS:
         PUSH HL
         PUSH DE
         PUSH BC
         PUSH AF
         CALL CALL_DOS_MOVE
         LD A,#13               ;!HARDCODE #13 из AUTO_1303
         LD (DOS_PROG.Patch),A
         POP AF
         POP BC
         POP DE
         POP HL
         JP DOS_PROG.Exec
        ;
;

;=======================================================================;
;=======================================================================;
;=======================================================================;
SERVICE:
        //LD    HL,SR_TAB
        LD      DE,SR_MENU
        LD      BC,SR_MENU.Size
        //PUSH  HL
        CALL    RUN_MENU	;09f3
         LD     HL,SR_TAB
        //POP   HL
        CALL    EXEC_PNT
        JR      SERVICE

SR_TAB: DW UTILIT
        DW GOTO_TRDOS.m128
        DW GOTO_TRDOS.m48
        DW TURBO_OFF
        DW TURBO_ON
	DW CLEAR_RAM
        DW RET_FROM_M

; DC - every last character of a string will have bit 7 set
SR_MENU:
        BYTE 8                          ; количество пунктов
        BYTE    'Options ',#FF          ; заголовок меню
        DC      'RUN disk.trd'
        DC      '128 TR-DOS'
        DC      '48  TR-DOS'
        DC      'TURBO OFF '
        DC      'TURBO ON '
        DC      'Clear RAM'
        DC      'RETURN'
        DC      " "                     ; маркер конца
.Size   EQU $-SR_MENU

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

;SR_48R:
GOTO_TRDOS:
.m128:  LD      A,#10
        JR      .RUN
;SR_48:
.m48:   LD      A,#30           ; Стопор на PORT_128 !!!
;SR_48A:
.RUN:   LD      BC,#7FFD
        OUT     (C),A       
        LD      BC,0            ; НА 0 !!
        PUSH    BC
        LD      BC,#3D2F        ; В DOS !
        PUSH    BC
        JP      SW_ROM

;*******************************
TURBO_OFF:
        LD      A,BIOS.FN_TURBO.OFF
        LD      C,BIOS.FN_TURBO
        JP_to_BIOS
TURBO_ON:
        LD      A,BIOS.FN_TURBO.ON
        LD      C,BIOS.FN_TURBO
        JP_to_BIOS

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

CLEAR_RAM:
	DI
	LD	C,BIOS.FullInit
	RST_to_BIOS
	; при очистке памяти из меню спектрума возврат в DSS по CAD
	;  будет опасным (RAM Blocks освободились),
	;  поэтому отключаем перехват ресета.
	LD      A,ACEX.RET_PORT
	LD      BC,BIOS.SET_PORTS
	;[x] SET_PORTS: no need to call from #3D13 and DI. 31/12/23
	 ;CALL    ToBIOS_3D13
	 RST_to_BIOS
	;
	EI
	RET

;SR_CL_MEM:
;        DI
;        LD A,10H
;SR_CL_R2:
;	LD BC,1FFDH
;        OUT (C),A
;        EX AF,AF'
;	XOR A
;SR_CL_R1:
;	LD BC,7FFDH
;        OUT (C),A
;        LD HL,0C000H
;        LD DE,0C001H
;        LD BC,03FFFH
;        LD (HL),L
;        LDIR
;        INC A
;        CP 48H
;        JR NZ,SR_CL_R1
;        EX AF,AF'
;        CP 0
;        JP Z,BASIC_128        ; выход на сброс BASIC 128
;        LD A,0
;        JR SR_CL_R2

;*****************************
;    ***  MENU IS-DOS  ***
;*****************************

ISDOS:
        LD      HL,IS_TAB
        LD      DE,IS_MENU
        LD      BC,IS_MENU.Size
        PUSH    HL
        CALL    RUN_MENU
        POP     HL
        CALL    EXEC_PNT
        JR      ISDOS

IS_TAB:
;        DW TR_DOS
;        DW SP_DOS
	DW SPRINTER_1X
	DW AY8910_X
	DW PENTAGON
	DW SCORPION
	DW PENTAGON512
	DW SPRINTER_reset       ;SPRINTER_2X
	DW RET_FROM_M

; DC - every last character of a string will have bit 7 set
IS_MENU:
        BYTE    8               ; количество пунктов
        BYTE    'Hardware',#FF  ; заголовок меню
        DC      'Sprinter ZX '
        DC      'ZX Spectrum'
        DC      'Pentagon 128'
        DC      'Scorpion 256'
        DC      'Pentagon 512'
        DC      'Restart '
        DC      'RETURN'
        DC      " "             ; маркер конца
.Size   EQU $-IS_MENU

;******************************
;SP_DOS:
;	LD B,0E2H
;	LD A,0E1H
;	JR TR_DOS1
;TR_DOS:
;	LD B,0EAH
;	LD A,0E1H
;TR_DOS1:
;	CALL DOS_ON
;	CALL SET_ROM_PAGES
;	CALL DOS_OFF
;	RET
;******************************


;**************************************************
;Sprinter ZX
SPRINTER_1X:
        CALL    _SET_CNF
        LD      C,BIOS.RST_CONF.SP97_1
	RST_to_BIOS
	CALL    CNF_PN_320
        LD      L,2             ;FN_SYNC.INT_PENT
        JR      1F              ;!FIXIT метку придумать
;
;ZX Spectrum
AY8910_X:
        CALL    _SET_CNF
        LD      C,BIOS.RST_CONF.AY8910
	RST_to_BIOS

        LD      A,#FA           ; no ACC, Original waits
        LD      (Port_All_Mode),A
      
	CALL    CNF_SC_312
        LD      L,3             ;FN_SYNC.INT_ORIG
1:	LD      DE,CNF_PORT.CNF_0 + CNF_PORT.TURBO.ON
	CALL    CONFIG_SET
	CALL    CLS             ;!FIXIT нужно ли?
	RET
;

SCORPION:
        CALL    _SET_CNF
	CALL    CNF_SC_312
        LD      L,1             ;FN_SYNC.INT_SCORP
	LD      DE,CNF_PORT.CNF_1 + CNF_PORT.TURBO.ON
	JR      CONFIG_SET

PENTAGON:
        CALL    _SET_CNF
	CALL    CNF_PN_320
        LD      L,2             ;FN_SYNC.INT_PENT
	LD      DE,CNF_PORT.CNF_2 + CNF_PORT.TURBO.ON
	JR      CONFIG_SET

PENTAGON512:
        CALL    _SET_CNF
	CALL    CNF_PN_320
        LD      L,2             ;FN_SYNC.INT_PENT
	LD      DE,CNF_PORT.CNF_2 + CNF_PORT.TURBO.ON + CNF_PORT.CNF_512
;	JR      CONFIG_SET
CONFIG_SET:
	PUSH    DE

	EI
	HALT
	DI

	IN      A,(SLOT3)
	EX      AF,AF'
	LD      A,SYS_PAGE
	OUT     (SLOT3),A
	LD      (SYS_PAGE.CONFIG_DE),DE
        ;!FIXIT есть ли смысл делать до FN_SYNC?
	 LD      A,(ZX_VARS.BORDER)
	 RRCA
	 RRCA
	 RRCA
	 AND     7
	 OUT     (BorderColor),A
        ;
	EX      AF,AF'
	OUT     (SLOT3),A

        LD      A,L
        LD      C,BIOS.FN_SYNC
	RST_to_BIOS

	LD      HL,#4104                        ;!HARDCODE
	LD      E,0
	LD      BC,256*4 + BIOS.LP_OPEN_S       ;!HARDCODE
	RST_to_BIOS

	LD      HL,#5104                        ;!HARDCODE
	LD      E,0
	LD      BC,256*4 + BIOS.LP_OPEN_S
	RST_to_BIOS

	POP     DE
	LD      A,E
	OUT     (SYS_PORT.ROM),A

	IM      1
        EI
	RET

SPRINTER_reset:
        CALL    _SET_CNF
        LD      BC,256*BIOS.REINIT.SOFT_RESET + BIOS.REINIT
	JP_to_BIOS

_SET_CNF:
        DI
	LD A,CNF_PORT.CNF_0 + CNF_PORT.TURBO.ON
	OUT (SYS_PORT.ROM),A
        RET

CNF_SC_312:
	LD A,Port_VSYNC.SET_312L
	OUT (Port_VSYNC),A
	RET

CNF_PN_320:
	LD A,Port_VSYNC.SET_320L
	OUT (Port_VSYNC),A
	RET
        
;	LD A,CNF_0
;	OUT (SYS_PORT.ROM),A
;	CALL DOS_OFF
;	JP 0

;*****************************
;    *** MENU UTILITES ***
;*****************************
;!FIXIT это запуск c:\disk.trd - не думаю, что это нужно, можно заменить
UTILIT:
        LD HL,C_DISK_C
        CALL CALL_DOS1

        ;!TEST
	 ;CALL DOS_ON
	 ;LD A,0		; DETECT_HDD
	 ;CALL EXP_HDD
         LD     C,BIOS.HDD_INIT
         RST_to_BIOS
	 ;CALL DOS_OFF
        ;

	JR C,DISK_UTILIT

	LD HL,C_DISK_C3
        CALL CALL_DOS1

UTIL_DISK:
        XOR     A
        ;!TEST
         LD     C,BIOS.FreeMemRMD
         RST_to_BIOS
	 ;CALL EMM_FN3            ;!!!!! через RST_to_BIOS EMM.FreeMemRMD
        ;

        LD HL,C_DEMO6
        CALL CALL_DOS1

        XOR     A
        ;!TEST
         LD     C,BIOS.GET_RAMD_ST
         RST_to_BIOS
	 ;CALL GET_RAMD_ST
        ;

	JR C,UTIL_DISK_L1
	JR Z,UTIL_DISK_L1

        LD HL,C_DISK_C1
        CALL CALL_DOS1
        LD HL,C_DISK_C2
        CALL CALL_DOS1
        RET

UTIL_DISK_L1:
	LD A,(ZX_VARS.OPER_DISK)
	INC A
	CP 2
	JR Z,DISK_UTIL_RET
        LD HL,C_DISK_C5
        CALL CALL_DOS1
	JR UTIL_DISK

DISK_UTIL_RET:
        LD HL,C_DISK_C6
        CALL CALL_DOS1
	RET

DISK_UTILIT:
	LD HL,C_DISK_C4
        CALL CALL_DOS1
	JR UTIL_DISK

C_DEMO6:        DB .Size, ZX_Token.rem, ':/disk.trd', 13,80
.Size           EQU $-C_DEMO6-1

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

;VERSION: DEFB 22,21,0
;        DEFB 16,2,"Expansion 3.02    1997 ELSY Co.",16,1,0FFh

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

DOS_RUN:
        LD HL,C_DISK_C1
        CALL CALL_DOS1

        LD HL,C_DISK_C2
        CALL CALL_DOS1
	RET

START_TRD:
        LD HL,C_DISK_C
        CALL CALL_DOS1
        LD HL,C_DISK_C0
        CALL CALL_DOS1
	LD HL,C_DISK_C3
        CALL CALL_DOS1
	RET

C_DISK_C:       DB .Size, ZX_Token.rem, ':', 13,80
.Size           EQU $-C_DISK_C-1

C_DISK_C0:      DB .Size, ZX_Token.rem, ':/CLEAR E', 13,80
.Size           EQU $-C_DISK_C0-1

C_DISK_C1:      DB .Size, ZX_Token.rem, ':/RMD E', 13,80
.Size           EQU $-C_DISK_C1-1

C_DISK_C2:      DB .Size, ZX_Token.rem, ':RUN', 13,80
.Size           EQU $-C_DISK_C2-1

C_DISK_C3:      DB .Size, ZX_Token.rem, ':/HDD', 13,80
.Size           EQU $-C_DISK_C3-1

C_DISK_C4:      DB .Size, ZX_Token.rem, ':/FDD', 13,80
.Size           EQU $-C_DISK_C4-1

C_DISK_C5:      DB .Size, ZX_Token.rem, ':/B:', 13,80
.Size           EQU $-C_DISK_C5-1

C_DISK_C6:      DB .Size, ZX_Token.rem, ':/A:', 13,80
.Size           EQU $-C_DISK_C6-1
;