;[BEGIN]
;//MODULE: DSETUP, Main module of BIOS SETUP & BOOTSTRAP
;//CREATE: ??-??-????	AUTHOR:	Denis Parinov
;//UPDATE: 23-04-2001	DNS	Remake for Sp2000 mainboard
;---------------------------------------------------------------
;Rev	Date	   Name	Description
;---------------------------------------------------------------
;R08	04-03-2002 DNS	Disabled Open TRDOS
;R07	16-02-2002 DNS	Add routine for check CMOS clock registers.
;R06	28-01-2002 DNS	Add new items to SETUP Utility for screen position.
;R05	01-10-2001 DNS	Found BUG with size of boot messages, messages for secondary
;			IDE were removed. (BUG NOT FIXED!) --- ты ошибаешься, друг мой)))
;R04	14-09-2001 DNS	Added procedure GET_BOARD_NUMBER
;R03	30-07-2001 DNS  Developed a new IDE DETECT routine and fixied any bugs
;R02    25-07-2001 DNS  Add Secondary IDE
;R01	23-04-2001 DNS	Removed procedure GET_ID and make new which
;                       will be take Model Name.
;---------------------------------------------------------------

;Memory	dump							; !TODO переделать
;#0000-#3FFF : STANDART	ROM BIOS
;#4000-#7BFF : NOT USED	MEMORY
;#7C00-#7C7F : SYSTEM JUMP RESIDENT
;#7C80-#7DFF : NOT USED	MEMORY
;#7E00-#7FFF : SECTOR BUFFER AND TEMPORY AREA
;#8000-#8002 : SETUP ENTRY POINT
;#8003-#80F0 : STACK FRAME						;!!!!!  посмотреть
;#80F1-#80FD : NOT USED	MEMORY
;#80FE-#80FF : INTERRUPT ADDRESS
;#8000-#B3FF : SETUP AND BOOT PROGRAM
;#B400-#BAFF : BOOT MESSAGES					;!!!!!  посмотреть
;#B900-#BEFF : SETUP MESSAGES AND ITEMS			;!!!!!  посмотреть
;#BF00-#BFFF : STACK FRAME						;!!!!!  посмотреть!
;#C000-#D8FF : NOT USED	MEMORY
;---DELETED--- #D900-#FFFF : UNPACKED	LOGOTYPE

;System page(#FE) dump
;#F000-#F007 : db "RESTART",0 ;First start identificator
;#F008-#F00F : db hour,min,sec,day,month,century,year,reserved ; PowerOn date
;#F010-#F017 : db hour,min,sec,day,mouth,century,year,reserved ; Reboot date
;
;#FEE0-#FEEF : Any buffer (Video mode set?!) Used in Sprinter DOS and CD driver
;#FF00
;

; для варианта с запаковкой части бинарника (может не сработать без напильника за давностью лет)
 IFDEF PREBUILD
;  ENCODING "DOS"
  DEVICE	ZXSPECTRUM4096                                          ; модель с 4 метрами памяти
  MMU		2 e, 0                                                  ; страница 0 в банку 2 и проверка на границы.
  INCLUDE 'src/bios/shared/includes.inc'
  ORG	COMPILE_ADDR.MAIN
  OUTPUT 'Build/Bin/temp/MAIN.BIN'
 ENDIF

;SYS_PAGE.RAMD_KEYS      EQU     #C180                                           ; ключи RAM-Disks
;RAMD_KEY_NUM   EQU     16
;SYS_PAGE       EQU     #FE                                             ; страница с системными переменными BIOS
;SYS_PORT_ON    EQU     #7C
;SYS_PORT_OFF	EQU     #3C
;STACK          EQU     #80F0
;PAGE0          EQU     #82
;PAGE1          EQU     #A2
;PAGE2          EQU     #C2
;SLOT3          EQU     #E2
;Y_PORT         EQU     #89
;SYSPAGE	EQU	#FE
;INT            EQU     #80

;ITMADDR        EQU     MSG_Items_Buffer
;ITMTABS        EQU     #BA00                                           ;!!!!! b900
;ITMTABS        EQU     ITMADDR

;FDD	EQU	#03


TEMP	EQU	#7E00   						; !HARDCODE 
MEMMAP2	EQU	TEMP                                                    ; должно быть выровнено по ALIGN 256
TPOINTD	EQU	TEMP - SYS_PAGE.RAMD_KEYS.NUM - SYS_PAGE.Sp_RAMD_KEYS.NUM ; [x] 4/11/23


;=======================================
;SETUP_MAIN:
MAIN_START:
	POP	AF
	POP	HL
	LD	SP,STACK
	PUSH	HL
	LD      (RET_TO_EXP_ADDR),hl
	JP	START
;	DB	"(C) 2002 PETERS PLUS LTD "
RET_TO_EXP_ADDR: WORD 0000                                                   ; place for save ret address to exp

;
;------------------- ;!!!!!  посмотреть
; Значения времени и даты в кмос записаны десятичными значениями
; и в регистре A на выходе из функции #F6 (CMOS_RD) BIOS значения десятичные.
GETTIME:
	PUSH    HL
	LD      D,CMOS.Register.hours
        CALL    CMOS_RD
	CP      #24                                                     ;24
	jp      nc,.error
	LD      (HL),A
	INC     HL

	LD      D,CMOS.Register.minutes
        CALL    CMOS_RD
	CP      #5A                                                     ; 60
	jp      nc,.error
	LD      (HL),A
	INC     HL

	LD      D,CMOS.Register.seconds
        CALL    CMOS_RD
	CP      #5A                                                     ; 60
	jp      nc,.error
	LD      (HL),A
	INC     HL

	LD      D,CMOS.Register.date					; число
        CALL    CMOS_RD
	CP      #32
	jp      nc,.error
	LD      (HL),A
	INC     HL

	LD      D,CMOS.Register.month
        CALL    CMOS_RD
	CP      #13                                                     ;13
	jp      nc,.error
	LD      (HL),A
	INC     HL

	LD      D,CMOS.Register.century
        CALL    CMOS_RD
	CP      #1A                                                     ;20
	jp      c,.error
	CP      #9A                                                     ;100
	jp      nc,.error
	LD      (HL),A
	INC     HL

	LD      D,CMOS.Register.year
        CALL    CMOS_RD
	CP      #9A                                                     ;100
	jp      nc,.error
	LD      (HL),A

; 	DEC	HL
; 	LD	C,A
; 	LD	A,19
; 	CP	(HL)
; 	RET	Z
; 	LD	A,20
; 	CP	(HL)
; 	RET	Z
; 	LD	A,80
; 	CP	C
; 	LD	A,20
; 	JR	NC,.correct_century
; 	LD	A,19
; .correct_century:
; 	LD	(HL),A
; 	LD	D,#32							;CENTURY
; 	LD	C,#F7   						; !HARDCODE
; 	RST_to_BIOS_18

	POP HL
	RET 
.error:
	LD HL,.default_date
	POP DE
	LD BC,7
	LDIR

;---[]
;!FIXIT
	CALL CMSERR
	; LD	HL,.default_date
	; call writeDateTimeToCmos
;---[]

	ld a,#FF
	ld (ERRSUM.ErrDateTime),a
	RET

 LUA ALLPASS
	sj.insert_define("Current_CENTURY", math.modf(tonumber(os.date("%Y"))/100))
	sj.insert_define("Current_YEAR", tonumber(os.date("%y")))
	sj.insert_define("Current_MONTH", tonumber(os.date("%m")))
	sj.insert_define("Current_DATE", tonumber(os.date("%d")))	
 ENDLUA

.default_date:
	BYTE 0,0,0				; Hours, minutes, seconds
	BYTE #Current_DATE
	BYTE #Current_MONTH
	BYTE #Current_CENTURY
	BYTE #Current_YEAR

	UNDEFINE Current_DATE
	UNDEFINE Current_MONTH
	UNDEFINE Current_CENTURY
	UNDEFINE Current_YEAR
;--------------------------------
;
;R07 ; !FIXIT CMOS сделать согласно доке на кмос
; если батарейка села, то при чеке кмоса выдавать соответствующую ошибку и, возможно, работать как без кмоса.
CMOSINIT:
	LD	D,CMOS.Register.CTRLregA                                ; !FIXIT FREQ
        CALL    CMOS_RD
	CP	#26                                                     ; !FIXIT 
	JR	NZ,CMSERR

	LD	D,CMOS.Register.CTRLregC
        CALL    CMOS_RD
	CP	#50
	RET	Z
CMSERR:
	LD	D,CMOS.Register.CTRLregB
	LD	A,#82							;TIME FORMAT    ; !FIXIT CMOS
        CALL    CMOS_WR

	LD	D,CMOS.Register.CTRLregA
	LD	A,#26                                                   ; !FIXIT CMOS FREQ
        CALL    CMOS_WR

	LD	D,CMOS.Register.CTRLregC
	LD	A,#0                                                    ; !FIXIT CMOS
        CALL    CMOS_WR

	LD	HL,GETTIME.default_date
	call    writeDateTimeToCmos

	LD	D,CMOS.Register.CTRLregB
	LD	A,#02							;TIME FORMAT    ; !FIXIT CMOS
        CALL    CMOS_WR

	; LD	D,13
	; LD	A,#80                                                   ; !FIXIT CMOS
	; LD	C,#F7   						; !HARDCODE
	; RST_to_BIOS
	RET

CLEARM:	IN	A,(SLOT3)
	PUSH	AF
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	; save RAM disks on reboot when memory is cleared
	LD	HL,SYS_PAGE.RAMD_KEYS
	LD	DE,TPOINTD
	LD	BC,SYS_PAGE.RAMD_KEYS.NUM
	LDIR
	; [x] 4/11/23
	 LD	HL,SYS_PAGE.Sp_RAMD_KEYS
	 LD	DE,TPOINTD + SYS_PAGE.RAMD_KEYS.NUM
	 LD	BC,SYS_PAGE.Sp_RAMD_KEYS.NUM
	 LDIR
	;
	; очищаем RAM Table
	LD	HL,MEMMAP2
	LD	DE,MEMMAP2+1
	LD	BC,255
	LD	(HL),0
	LDIR 
	; восстанавливаем RAM диски 
	LD	IX,SYS_PAGE.RAMD_KEYS					;RAM DISKS
	LD	H,high SYS_PAGE.RAMD_FAT
	LD	D,high MEMMAP2
	LD	BC,SYS_PAGE.RAMD_KEYS.NUM*256 + #FF
	CALL	.MEMLOOP
	; [x] 4/11/23
	 LD	IX,SYS_PAGE.Sp_RAMD_KEYS
	 LD	B,SYS_PAGE.Sp_RAMD_KEYS.NUM
	 CALL	.MEMLOOP
	;
        CALL    EMM.InitMem
	LD	BC,CMOS_CELL.BootUpParams.Mask.SaveRAMdisks		;#400E
	CALL	G_VALUE
	OR	A
	CALL	NZ,CCHAIN
	POP	AF
	OUT	(SLOT3),A
	;!TEST; [ ]	04/11/2023 Отдельные рамдиски для режима спектрума и DSS.
	 LD	B,high BIOS.SWAP_RAM_DRIVES.Sp2000
	 JP	SWAP_RAM_DRIVES
	;
	;
.MEMLOOP:
	LD	A,(IX)
	INC	IX
	OR	A
	LD	L,A
	CALL	NZ,RCHAIN
	DJNZ	.MEMLOOP
	RET
;

;
;
; before_intPointer       EQU $
;                         BLOCK   #FF - low $,0                            ; выравнивание на #xxFF                        
; INT_POINTER:		WORD    0

;  ASSERT +low INT_POINTER = #FF, 'ERROR! Not valid interrupt pointer!'
;  IFDEF PREBUILD
;         ASSERT INT_POINTER-before_intPointer < 16, 'Warning! To much space before INT_POINTER.'
;  ELSE
;    IF INT_POINTER-before_intPointer > 16
;         DISPLAY 'Warning! To much space before INT_POINTER: ',/D,INT_POINTER-before_intPointer
;    ENDIF
;  ENDIF

; INT_HANDLER:
; 	PUSH	AF
; 	EX	AF,AF'
; 	PUSH	AF
; 	PUSH	BC
; 	PUSH	DE
; 	PUSH	HL
; 	EXX 
; 	PUSH	BC
; 	PUSH	DE
; 	PUSH	HL
; 	PUSH	IX
; 	PUSH	IY
; 	CALL	KEYSCAN
; 	POP	IY
; 	POP	IX
; 	POP	HL
; 	POP	DE
; 	POP	BC
; 	EXX 
; 	POP	HL
; 	POP	DE
; 	POP	BC
; 	POP	AF
; 	EX	AF,AF'
; 	POP	AF
; 	EI 
; 	RETI 
; ;

INT_OFF:
	DI 
	LD	A,#3F
	LD	I,A
	IM	1
	RET 

INT_ON:
	DI 
	LD	A,+high INT_POINTER
	LD	I,A
	LD	HL,INT_HANDLER
	LD	(INT_POINTER),HL
	IM	2
	EI 
	RET 
;

;
;------------------------[go to spectrum from bios]---------------------;
EXIT_SETUP:
	CALL	INT_OFF
;
;	LD	BC,#020E
;	CALL	G_VALUE
;	OR	A
;	LD	A,#EC	;SPRINTER
;	JR	Z,XFLEX
;	LD	A,#EA	;SPECTRUM
;XFLEX:
        LD      A,ROM.BIOS
        OUT     (SYS_PORT.ROM),A
	POP	HL                                                      ; пихается в EXP.ASM в процедуре 
	JP      (HL)
; LD	(JMPHL),HL

	;	LD	C,#F3
	;	RST_to_BIOS
; JMPHL		EQU $+1
; 			JP	#0000
;-----------------------------------------------------------------------;


INSTALL:
	CALL	INT_ON
	CALL	SET_CGA
	XOR	A
	OUT	(#FE),A
	LD	IX,win_descriptor.tab80x32
	LD	HL,#0000
	LD	E,1
        CALL    WIN_OPEN

	LD	DE,0
	LD	HL,#2050
        LD      B,7
        CALL    LP_CLS_WIN

	LD	DE,0
	LD	HL,#0820
        LD      B,0
        CALL    LP_CLS_WIN

	CALL	SETLAND
 
	CALL	GET_ID
	LD	DE,#0028				; !HARDCODE
        CALL    LP_SET_PLACE
	LD	HL,memBUFFER.ID
	LD	A,COLORS.CGA.INC.LCYAN
	CALL	CPRINTZ
	; LD	HL,BUILD
	; LD	A,COLORS.CGA.INC.LCYAN
	; CALL	CPRINTZ

	LD	DE,#0128				; !HARDCODE
        CALL    LP_SET_PLACE
	LD	A,msgStrings.copyRightPeters
	LD	E,COLORS.CGA.INC.LGREEN
	CALL	POSTMSC

	LD	DE,#0228				; !HARDCODE
        CALL    LP_SET_PLACE
	LD	A,msgStrings.copyRightSPTeam
	LD	E,COLORS.CGA.INC.GREEN
	CALL	POSTMSC

 IF BETA_BUILD
	LD	DE,#0328
        CALL    LP_SET_PLACE
	LD	A,msgStrings.testBIOSmsg
	LD	E,COLORS.CGA.FLASH + COLORS.CGA.INC.RED
	CALL	POSTMSC
 ENDIF

	IN	A,(SLOT3)
	PUSH	AF
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	HL,RebootDate
	CALL	GETTIME
	POP	AF
	OUT	(SLOT3),A
	RET 

;BUILD:
;	db	', BIOS v', Disk_subsystem_ver_txt,0                    ; !FIXIT может воткнуть вместе с msgStrings ?

RSTID:	DB	"RESTART",0
.size   EQU     $-RSTID

Start_again:
	ld sp,STACK-2
START:
	DI 
	PUSH	AF
	XOR	A
	LD	(ERRSUM),A
	LD	(ERRSUM.ErrDateTime),A

;	LD	C,#97
;	RST_to_BIOS_18
;	XOR	A
;	LD	C,#F2
;	RST_to_BIOS_18
;------------------------------ ;!!!!!  посмотреть
;	CALL	KINIT
;------------------------------ ;!!!!!  посмотреть

;--------[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:
;---------------------------------------


;R08	CALL	OPENDOS
	CALL	ZXCLS
	CALL	READING
	CALL	TCHEKSM
	CALL	NZ,SETDEFX

	;!TODO CMOS Disabled use of CONFIG_DE (#C13A) word
	 ;LD	A,#1C
	 ;CALL	READCMS
	 ;PUSH	AF
	 ;LD	A,CMOS_CELL.HardwareConfiguration
	 ;CALL	READCMS
	 ;POP	DE
	 ;LD	E,A
	;

	LD	C,SLOT3
	IN	B,(C)
	PUSH	BC
	LD	A,SYS_PAGE
	OUT	(C),A

;	LD	(SYS_PAGE.CONFIG_DE),DE

	LD	HL,SYS_PAGE.INT_ADRESS		;EXTENDED INTERRUPT
	XOR	A
	LD	(HL),A
	INC	L
	LD	(HL),A
	INC	L
	LD	(HL),A
	INC	L
	LD	(HL),A
	POP	BC
	OUT	(C),B

	CALL	TRQUICK
	CALL	FINSTAL
	CALL	CLEARM
	CALL	RESCREEN

;R06
	LD	BC,CMOS_CELL.BootUpParams.Mask.QuickStart		;#010E
	CALL	G_VALUE
	POP	BC
	INC	B
	DEC	B
	JR	NZ,QIGNORE						; результат проверки Space из exp.asm [space_check]
	PUSH	AF
	LD	C,SLOT3
	IN	B,(C)
	PUSH	BC
	LD	A,SYS_PAGE
	OUT	(C),A
	LD	HL,SYS_PAGE.RESTART_ID
	LD	DE,RSTID
	LD	B,RSTID.size
	CALL	COMPARE
	CALL	NZ,SETRSTS
	POP	BC
	OUT	(C),B
	JR	Z,HOTST
	POP	AF
	JR	QIGNORE

SETRSTS:
	PUSH	AF
	LD	HL,RSTID
	LD	DE,SYS_PAGE.RESTART_ID
	LD	BC,RSTID.size
	LDIR 
	LD	HL,PowerOnDate                                          ; !TODO изменить под структуру, когда структура переменных будет готова						
	CALL	GETTIME
	POP	AF
	RET 

HOTST:
	POP	AF
	OR	A
	JP	NZ,EXIT_SETUP
QIGNORE:
	CALL	INSTALL
	LD	DE,#0528
	;CALL	ScreenPOS.LOCAT
        CALL    LP_SET_PLACE
	LD	A,msgStrings.toSetupButton
	LD	E,COLORS.CGA.FLASH + COLORS.CGA.INC.WHITE
	CALL	POSTMSC

	LD	DE,#0900
	;CALL	ScreenPOS.LOCAT
        CALL    LP_SET_PLACE
ERRSUM+1:
	LD	A,#00				;MEM Patch!
	OR	A
	JR	Z,.ErrDateTime
	XOR	A
	ld (.ErrDateTime+1),a					; если контрольная сумма слетела, то сообщение о кривых дате/времени в кмос не выводим
	LD	A,msgStrings.cmosChecksumErr
	LD	E,COLORS.CGA.INC.RED
	CALL	POSTMSC
	CALL	ScreenPOS.CRLF
	CALL	ScreenPOS.CRLF
	JR CHEKOK

.ErrDateTime+1:
	LD	A,0
	OR      A
	JR      Z,CHEKOK
	LD	A,msgStrings.cmosDateTimeErr
	LD	E,COLORS.CGA.INC.RED
	CALL	POSTMSC
	CALL	ScreenPOS.CRLF
	CALL	ScreenPOS.CRLF

CHEKOK:	;CALL	ScreenPOS.GET_CUR
        CALL    LP_GET_PLACE
	PUSH	DE
	CALL	LOGOTYPE

	LD	DE,#0000
	;CALL	ScreenPOS.LOCAT
        CALL    LP_SET_PLACE
	LD	A,msgStrings.spModel
	CALL	POSTMSG
	CALL	PIDNUM
	CALL	ScreenPOS.CRLF

	LD	A,msgStrings.boardID
	CALL	POSTMSG
	CALL	PIDBOARD
	CALL	ScreenPOS.CRLF

	LD	A,msgStrings.spCNFver
	CALL	POSTMSG
	CALL	CNF_VER_PRINT
	CALL	ScreenPOS.CRLF

	LD	A,msgStrings.spMemory
	CALL	POSTMSG
        CALL    EMM.GetMemSize
	PUSH	BC
	CALL	PMEMORY
	CALL	ScreenPOS.CRLF
	LD	A,msgStrings.memoryAvailable
	CALL	POSTMSG
	POP	HL
	CALL	PMEMORY
	CALL	ScreenPOS.CRLF
	
        ;CALL	TSTCMOS
        CALL    CMOS_TEST

	LD	A,msgStrings.cmosNone
	JR	C,CMOS_ABSENT
	; CMOS OK
	CALL	CMOSINIT
	LD	A,msgStrings.cmosFound
	CALL	POSTMSG
	LD	A,','
	CALL	PRINT_CHAR
	LD	A," "
	CALL	PRINT_CHAR
	LD	HL,RebootDate
	CALL	PRNTIME
	CALL	ScreenPOS.CRLF
	JR	INFO_MESSAGE
CMOS_ABSENT:
	CALL	POSTMSG
INFO_MESSAGE:							;!FIXIT название неправильное 
	LD	DE,#0528
        CALL    LP_SET_PLACE
	LD	A,msgStrings.forAltBootButton
	LD	E,COLORS.CGA.INC.WHITE
	CALL	POSTMSC

	POP	DE
        CALL    LP_SET_PLACE

	CALL	TSETUP		;!TODO может пихнуть её на прерывания?

	CALL	CONFIGURE_IDE_DRIVES.START
	CALL	CTRLKEY
	LD	A,B
	AND	#10
	JR	NZ,ABOOT

	CALL	TSETUP

	LD	BC,CMOS_CELL.BootDrives.Mask.SysDisk			;#0710
	CALL	PrepareToBOOT       
	LD	A,msgStrings.bootFail
	LD	E,COLORS.CGA.INC.LRED
	CALL	C,POSTMSC
	CALL	ScreenPOS.CRLF
	;
	CALL	INT_ON
ABOOT:	LD	A,msgStrings.bootAltDrv
	LD	E,COLORS.CGA.INC.LGREEN
	CALL	POSTMSC

	LD	BC,CMOS_CELL.BootDrives.Mask.AltSysDisk			;#7010
	CALL	PrepareToBOOT
	LD	A,msgStrings.bootFail
	LD	E,COLORS.CGA.INC.LRED
	CALL	C,POSTMSC
	CALL	ScreenPOS.CRLF

	;NO START DISK  - RESTART / SETUP / ZX SPECTRUM mode
	LD	BC,CMOS_CELL.Options.Mask.RebootMSG			;#021D
	CALL	G_VALUE
	OR	A
	JP	Z,EXIT_SETUP

	CALL	ScreenPOS.CRLF
	LD	A,msgStrings.afterBootFail
	LD	E,COLORS.CGA.INC.RED
	CALL	POSTMSC

	;EI
        CALL	INT_ON 
AGAKEY:	CALL	WAITKEY
	LD	HL,#4F00	; DEL - go to settings
	;AND	A
	SBC	HL,DE
	JR	Z,ENTER_SETUP
	CP	#1B		; ESC - go to zx spectrum mode
	JP	Z,EXIT_SETUP
	CP	#0D		; ENTER - restart
	JP	NZ,AGAKEY
	XOR	A
	JP	Start_again

TSETUP:
	CALL	SCANKEY
	RET	Z
	LD	HL,#4F00	; DEL - go to settings
	AND	A
	SBC	HL,DE
	JR	Z,ENTER_SETUP
	LD	HL,#011B
	AND	A
	SBC	HL,DE
	JR	NZ,TSETUP
	POP	HL		; убираем лишнее
	JP	EXIT_SETUP
ENTER_SETUP:
	XOR A
	LD	(ITEM_Restore),A
	CALL	SETTINGS
	XOR	A
	JP	Start_again

COMPARE:
	LD	A,(DE)
	CP	(HL)
	RET	NZ
	INC	HL
	INC	DE
	DJNZ	COMPARE
	RET 

; ????? перенести это в функции БИОС?
; HL - data to write: BYTE Hours, minutes, seconds, day, month, century, year. (2022: 20 - century, 22 - year)
writeDateTimeToCmos: ;!FIXIT
	LD	A,(HL)
	LD	D,CMOS.Register.hours
        CALL    CMOS_WR

	INC	HL
	LD	A,(HL)
	LD	D,CMOS.Register.minutes
        CALL    CMOS_WR

	INC	HL
	LD	A,(HL)
	LD	D,CMOS.Register.seconds
        CALL    CMOS_WR	

	INC	HL
	LD	A,(HL)
	LD	D,CMOS.Register.date
        CALL    CMOS_WR

	INC	HL
	LD	A,(HL)
	LD	D,CMOS.Register.month
        CALL    CMOS_WR

	INC	HL
	LD	A,(HL)
	LD	D,CMOS.Register.century
        CALL    CMOS_WR

	INC	HL
	LD	A,(HL)	
	LD	D,CMOS.Register.year
        CALL    CMOS_WR
	RET

RESCREEN:	;R06
		LD	A,CMOS_CELL.ScreenPosition
		CALL	READCMS
		LD	B,A
		LD	A,ACEX.HOLD
		JP	SET_PORTS
		; PUSH	AF
		; IN	A,(SLOT3)
		; LD	E,A
		; LD	A,DCP_PAGE
		; OUT	(SLOT3),A
		; LD	A,(#C400)		;c400 for first cfg 50176       ; !TODO можно переделать на вызов функции биоса
		; LD	D,A
		; LD	A,ACEX.HOLD
		; LD	(#C400),A
		; POP	AF
		; LD	BC,0
		; OUT	(C),A
		; LD	A,D
		; LD	(#C400),A
		; LD	A,E
		; OUT	(SLOT3),a
		; RET
;
;R07
; CMOSINIT:
; 	LD	D,10							;FREQ
; 	LD	C,#F6							;READ CMOS
; 	RST_to_BIOS
; 	CP	#26
; 	JR	NZ,CMSERR
; 	LD	D,12
; 	LD	C,#F6
; 	RST_to_BIOS
; 	CP	#50
; 	RET	Z
; CMSERR:
; 	LD	D,10
; 	LD	A,#26							;FREQ
; 	LD	C,#F7
; 	RST_to_BIOS
; 	LD	D,11
; 	LD	A,#02							;TIME FORMAT
; 	LD	C,#F7
; 	RST_to_BIOS
; 	LD	D,12
; 	LD	A,#50
; 	LD	C,#F7
; 	RST_to_BIOS
; 	LD	D,13
; 	LD	A,#80
; 	LD	C,#F7
; 	RST_to_BIOS
; 	RET

;------------------- ;!!!!!  посмотреть
; 0 - 1-st FDD
; 1 - 2-nd FDD
; 2 - 1-st IDE
; 3 - 2-nd IDE
; 4 - 3-rd IDE
; 5 - 4-th IDE
; 6 - RAM-DISK
;
; -> BC - ячейка и маска для чтения значения кмос для загрузочного драйва

;
;[  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ]
RECOVERYstart:
	        LD	A,msgStrings.bootRecovery
	        CALL	POSTMSG
        ;

        ; Выбор рамдиска для рекавери
        _mRECOVERYrdChooseTYPE  RECOVERYrdChooseTYPE

        ; прибиваем последний рамдиск, если занят
.killRAMdisk:   LD      A,SYS_PAGE.RAMD_KEYS.NUM-1
                LD      (.RDkey),A
                CALL    EMM.FreeMemRMD
                JR      NC,.setRAMdisk
                JR      Z,.setRAMdisk
                RET                                                     ; непонятная ошибка - выходим
.setRAMdisk:    LD      A,(.RDkey)
                LD      B,ROM_DISK.Pages.Size
                CALL    EMM.GetMemRMD
                JR      NC,.IMGread                                     ; свободный рамдиск найден
                DEC     A
                JR      Z,.FreeMem                                      ; ошибка - недостаточно памяти, вызываем очистку памяти
                RET                                                     ; непонятная ошибка - выходим                                               
.FreeMem:       CALL    EMM.FullInit
                JR      .killRAMdisk
;

; Вход: A - RAM block ID
.IMGread:
        ; Вариант копирования ROM -> RAM disk
        _mRECOVERYmountTYPE     RECOVERYmountTYPE
;
        ;Exit from "ROM Disk to RAM disk" procedure
.RDkey+*:       LD      A,0
                OR      #60                                             ; !HARDCODE сделать им всем названия
                LD      B,A                                             ; передаём загрузочное устройство в OS_LOAD
                JP	OS_LOAD
        ;
;[  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ][  ]
;

PrepareToBOOT:
	;CALL	INT_ON
	HALT
	CALL	PORTS_INIT.clean_kbd_buf	;Clearing the keyboard buffer
	CALL	PORTS_INIT.clean_mouse_buf	;Clearing the mouse buffer
	CALL	INT_OFF
	; тут не должно быть испорчено значение BC
	CALL	G_VALUE
	LD	B,0
        ;   FDD
	OR	A
	JR	Z,FDSTART                                               ; FDD A:
        INC     B
        DEC     A
	JR	Z,FDSTART                                               ; FDD B:
        ;   IDE
	LD	B,#80
	DEC	A
	JR	Z,HDSTART
	INC     B               ;LD	B,#81
	DEC	A
	JR	Z,HDSTART
	INC     B               ;LD	B,#82
	DEC	A
	JR	Z,HDSTART
	INC     B               ;LD	B,#83
	DEC	A
	JR	Z,HDSTART
        ;   RAM
	DEC	A
	JR	Z,RDSTART
        ;   ROM
        DEC     A
	JP	Z,RECOVERYstart
        ;   Error
	SCF 
	RET 

FDSTART:
        PUSH	BC
	PUSH	BC
	LD	A,msgStrings.bootFdd
	CALL	POSTMSG
	POP	AF
        CALL    FDD_5x_RESET
	POP	BC
	RET	C
	JP	OS_LOAD
;!TODO
CDSTART:
	PUSH	BC
	LD	A,msgStrings.bootCd
	CALL	POSTMSG
	POP	AF
	PUSH	AF
	CALL	PRINT_CHANEL
	;
	POP	BC
	SET	6,B
	SCF 
	RET 

RDSTART:
	LD	A,msgStrings.bootRamDrv
	CALL	POSTMSG
        LD      B,#60   						; !HARDCODE: 6 - тип драйва RAM-DRV, 0 - номер драйва
.loop:  PUSH	BC
	CALL	OS_LOAD
	POP	BC
        INC	B
        LD	A,#6F   						; !HARDCODE - максимальное число рамдисков
        SUB	B
        JR	NC,.loop 
        RET


HDSTART:
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,B
	;
	AND	#03		;R02 %00000011
	LD	IY,IDE.INIT_TBL_IDE0
	JR	Z,.next
	;
	LD	IY,IDE.INIT_TBL_IDE1
	CP	1							;R02
	JR	Z,.next	
	;
	LD	IY,IDE.INIT_TBL_IDE2					;R02
	CP	2							;R02
	JR	Z,.next
	;
	LD	IY,IDE.INIT_TBL_IDE3					;R02
	;
.next:	LD	A,(IY+IDE.HDD_INIT_TABLE.DriveType)
	EX	AF,AF'
	OUT	(SLOT3),A
	EX	AF,AF'
	CP	IDE.Device.CDROM
	JP	Z,CDSTART
	PUSH	AF
	PUSH	BC
	LD	A,msgStrings.bootHdd
	CALL	POSTMSG
	POP	AF
	PUSH	AF
	CALL	PRINT_CHANEL

	POP	BC
	POP	AF
	CP	#FF
	SCF 
	RET	Z
OS_LOAD:
	LD	HL,#0000
	LD	IX,#0001
	LD	DE,TEMP
	LD	A,B
	LD	BC,1*256 + BIOS.DRV_READ
        PUSH	AF
        RST     ToBIOS_18
        
	POP	BC
	RET	C
	LD	A,B
	EX	AF,AF'
	LD	HL,TEMP
	LD	DE,SYSID
	LD	B,SYSID.length
.loop:	LD	A,(DE)
	CP	(HL)
	SCF 
	RET	NZ
	INC	HL
	INC	DE
	DJNZ .loop
	EX	AF,AF'
	PUSH	AF
	LD	A,msgStrings.bootOk
	LD	E,COLORS.CGA.INC.LGREEN
	;CALL	POSTMSG
	CALL	POSTMSC
	CALL	ScreenPOS.CRLF
	POP	AF
	POP	HL
;	JP	MOVE0
MOVE0:	DI 
	IM	1
	LD	HL,MOVE1
	LD	DE,#7C00						; !HARDCODE 
	LD	BC,MOVE1.length
	LDIR 
	JP	#7C00
MOVE1:	LD	SP,#7FFF						; !HARDCODE 
	LD	HL,TEMP
	LD	DE,#8000						; !HARDCODE 
	LD	BC,#0200						; !HARDCODE 
	LDIR 
	JP	#8000+SYSID.length ;#800C				; !HARDCODE 
.length	EQU $-MOVE1
SYSID:	DZ	"Starting..."
.length	EQU	$-SYSID

FD144A:	DB	#80,#12,#02,#50,#00,#00,#02,FDD_INI_TABLE.FDD
FD720A:	DB	#00,#09,#02,#50,#00,#00,#02,FDD_INI_TABLE.FDD

FINSTAL:
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	HL,FDD_INI_TABLE.FDD_0
	LD	BC,SYS_PAGE.FDD_TBL.Size*256 + #FF	; table_size*256 + fill_byte 
.FILLFDD:
	LD	(HL),C
	INC	HL
	DJNZ	.FILLFDD
	;
	EX	AF,AF'
	OUT	(SLOT3),A
	LD	BC,CMOS_CELL.DrivesSetup_1.Mask.FirstFDD		;#0311
	CALL	G_VALUE
	LD	HL,FD720A
	OR	A
	JR	Z,SETFD0
	LD	HL,FD144A
	DEC	A
	JR	NZ,NOFDD0
SETFD0:
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	DE,FDD_INI_TABLE.FDD_0
	LD	BC,#0008						; !HARDCODE
	LDIR 
	EX	AF,AF'
	OUT	(SLOT3),A
NOFDD0:
	LD	BC,CMOS_CELL.DrivesSetup_1.Mask.SecondFDD		;#0C11
	CALL	G_VALUE
	LD	HL,FD720A
	OR	A
	JR	Z,SETFD1
	LD	HL,FD144A
	DEC	A
	JR	NZ,NOFDD1
SETFD1:
	IN	A,(SLOT3)
	EX	AF,AF'
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	DE,FDD_INI_TABLE.FDD_1
	LD	BC,#0008						; !HARDCODE
	LDIR 
	EX	AF,AF'
	OUT	(SLOT3),A
NOFDD1:
	RET 


PIDNUM:	LD	HL,memBUFFER.ID
	LD	BC,#00FF
	XOR	A
	CPIR
	LD	A,(HL)
	OR	A
	RET	Z
	CALL	PRINTZ
	RET

PIDBOARD:
        CALL    FN_CRIPT.board_id

	PUSH	DE
	PUSH	HL
	PUSH	BC
	LD	A,B
	CALL	PRNHEX
	LD	A,'-'
	CALL	PRINT_CHAR
	POP	BC
	LD	A,C
	CALL	PRNHEX
	LD	A,'-'
	CALL	PRINT_CHAR
	POP	HL
	CALL	IZPRINT
	POP	DE
	PUSH	DE
	LD	A,D
	CALL	PRNHEX
	POP	DE
	LD	A,E
	JP	PRNHEX

CNF_VER_PRINT:
 	LD	HL,memBUFFER.ID
	IFN	BIOS.FN_VERSION.STR.BitstreamVer = 0
	 LD	BC,BIOS.FN_VERSION.STR.BitstreamVer*256
	 XOR	A
.loop:	 CPIR
	 DJNZ	.loop
	ENDIF
	JP	PRINTZ

;PIDNUM	LD	A,#0D
;	LD	HL,ID_BUFFER
;	LD	BC,#0030
;	CPIR 
;	RET	NZ
;	INC	HL
;	LD	BC,#0286
;	RST_to_BIOS_18
;	INC	HL
;	LD	BC,#0586
;	RST_to_BIOS_18
;	INC	HL
;	LD	BC,#0286
;	RST_to_BIOS_18
;	XOR	A
;	RET 

;PIDDATE
;	LD	A,#0D
;	LD	HL,ID_BUFFER
;	LD	BC,#0030
;	CPIR 
;	RET	NZ
;	INC	HL
;	CPIR 
;	RET	NZ
;	INC	HL
;	LD	BC,#0A86
;	JP_to_BIOS

//////////////////////////////////////////////////////////////////////
 INCLUDE	'IM2_INT.asm'
//////////////////////////////////////////////////////////////////////

PRNHEX:	LD	D,A
	RRCA 
	RRCA 
	RRCA 
	RRCA 
	AND	#0F
	ADD	A,#30
	CP	#3A
	JR	C,PRNH1
	ADD	A,7
PRNH1:	CALL	PRINT_CHAR
	LD	A,D
	AND	#0F
	ADD	A,#30
	CP	#3A
	JP	C,PRINT_CHAR
	ADD	A,7
	JP	PRINT_CHAR

PHEX:	LD	D,A
	RRCA 
	RRCA 
	RRCA 
	RRCA 
	AND	#0F
	ADD	A,#30
	CALL	PRINT_CHAR
	LD	A,D
	AND	#0F
	ADD	A,#30
	JP	PRINT_CHAR

PRNTIME:
	IN	A,(SLOT3)
	PUSH	AF
	LD	A,SYS_PAGE
	OUT	(SLOT3),A
	LD	A,(HL)
	CALL	PHEX
	LD	A,":"
	CALL	PRINT_CHAR
	INC	L
	LD	A,(HL)
	CALL	PHEX
	LD	A,":"
	CALL	PRINT_CHAR
	INC	L
	LD	A,(HL)
	CALL	PHEX
	POP	AF
	OUT	(SLOT3),A
	RET 


PMEMORY:
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL
	ADD	HL,HL	; * 16
	CALL	IPRINT
	LD	A,"K"
	JP	PRINT_CHAR

ZXCLS:	LD	HL,#4000
	LD	DE,#4001
	LD	BC,#1AFF
	LD      (HL),L
	LDIR 
	RET 

GET_ID:	LD	HL,memBUFFER.ID
	;LD	C,BIOS.FN_VERSION
	;JP_to_BIOS
        JP      FN_VERSION


;R01GET_ID
;R01	LD	A,#10
;R01	LD	BC,#1FFD
;R01	OUT	(C),A
;R01	LD	C,SLOT3
;R01	IN	B,(C)
;R01	PUSH	BC
;R01	LD	A,#EE
;R01	OUT	(C),A
;R01	LD	HL,#FFD0
;R01	LD	DE,ID_BUFFER
;R01	LD	BC,#30
;R01	LDIR 
;R01	POP	BC
;R01	OUT	(C),B
;R01	XOR	A
;R01	LD	BC,#1FFD
;R01	OUT	(C),A
;R01	RET 


RCHAIN:
	LD	E,L
	LDI 
	DEC	L
	LD	L,(HL)
	INC	L
	RET	Z
	DEC	L
	JR	RCHAIN

CCHAIN:
	LD	HL,MEMMAP2
	LD	DE,SYS_PAGE.RAMD_FAT
	XOR	A
CCHAINC:
	CP	(HL)
	JR	Z,NOCOPYC
	LD	E,L
	LDI 
	DEC	L
NOCOPYC:
	INC	L
	JR	NZ,CCHAINC
	LD	HL,TPOINTD
	LD	DE,SYS_PAGE.RAMD_KEYS
	LD	BC,SYS_PAGE.RAMD_KEYS.NUM
	LDIR 
	RET 

TRQUICK:
;REGISTER #1E
; %0000'0011 - TR DOS A:	Default	 / FDD / HDD / RMD
; %0000'1100 - TR DOS B:	Default	 / FDD / HDD / RMD
; %0011'0000 - TR DOS C:	Default	 / FDD / HDD / RMD
; %1100'0000 - TR DOS D:	Default	 / FDD / HDD / RMD
	LD	BC,CMOS_CELL.TRDOSmount.Mask.A				;#031E
	LD	A,0
	CALL	TRDOSX
	LD	BC,CMOS_CELL.TRDOSmount.Mask.B				;#0C1E
	LD	A,1
	CALL	TRDOSX
	LD	BC,CMOS_CELL.TRDOSmount.Mask.C				;#301E
	LD	A,2
	CALL	TRDOSX
	LD	BC,CMOS_CELL.TRDOSmount.Mask.D				;#C01E
	LD	A,3

TRDOSX:
	; PUSH	AF
	; CALL	G_VALUE
	; POP	BC
	; OR	A
	; RET	Z
	; LD	C,BIOS.FDD_TO_DRV
	; DEC	A
	; JP	Z,ToBIOS_18
	; LD	C,BIOS.HDD_TO_DRV
	; DEC	A
	; JP	Z,ToBIOS_18
	; SCF 
	; RET 
	PUSH	AF
	CALL	G_VALUE
	POP	BC
	OR	A
	RET	Z
	DEC	A
	JP	Z,FDD_TO_DRV
	DEC	A
	JP	Z,HDD_TO_DRV
	SCF 
	RET 

; открывает порт #FE на чтение в 3-й карте портов
; OPENDOS:
; 	DI 
; 	IN	A,(SLOT3)
; 	EX	AF,AF'
; 	LD	A,#40
; 	OUT	(SLOT3),A
; 	LD	HL,#C000
; 	LD	DE,#F000
; 	LD	BC,#0400
; 	LDIR 
; 	LD	A,#40
; 	LD	(#F26E),A
; 	LD	(#F27E),A
; 	LD	(#F2EE),A
; 	LD	(#F2FE),A
; 	LD	(#F36E),A
; 	LD	(#F37E),A
; 	LD	(#F3EE),A
; 	LD	(#F3FE),A
; 	LD	HL,#F000
; 	LD	DE,#F400
; 	LD	BC,#0C00
; 	LDIR 
; 	EX	AF,AF'
; 	OUT	(SLOT3),A
; 	RET 
;



setFRAME:
.double:
        LD	HL,.dataDoubleAll
        JR	.setElements
.single:
        LD	HL,.dataSingleAll
        JR	.setElements
.high:  LD	HL,.dataSingleDown
        JR	.setElements
.low:   LD	HL,.dataSingleUp
        JR	.setElements
.medium:
        LD	HL,.dataSingleMedium
;       JR	.setElements
.setElements:
	LD	DE,ElementsBuffer
	LD	BC,ElementsBuffer.Size
	LDIR 
	RET 

.dataDoubleAll:    BYTE "╔╗═║╚╝", "╠╣╦╩"        ; #C9,#BB,#CD,#BA,#C8,#BC, #CC,#B9,#CB,#CA
.dataSingleAll:    BYTE "┌┐─│└┘", "├┤┬┴"        ; #DA,#BF,#C4,#B3,#C0,#D9, #C3,#B4,#C2,#C1
.dataSingleDown:   BYTE "╔╗─║╟╢", "╟╢╤┴"        ; #C9,#BB,#C4,#BA,#C7,#B6, #C7,#B6,#D1,#C1
.dataSingleUp:     BYTE "╟╢─║╚╝", "╟╢┬╧"        ; #C7,#B6,#C4,#BA,#C8,#BC, #C7,#B6,#C2,#CF
.dataSingleMedium: BYTE "╟╢─║╟╢", "╟╢┬┴"        ; #C7,#B6,#C4,#BA,#C7,#B6, #C7,#B6,#C2,#C1
;
ElementsBuffer:
.UpLeft:           BYTE "┌"                     ; UL - UpLeft
.UpRight:          BYTE "┐"                     ; UR - UpRight
.HorizontalLine:   BYTE "─"                     ; ZL - HorizontalLine
.VerticalLine:     BYTE "│"                     ; VL - VerticalLine
.DownLeft:         BYTE "└"                     ; LL - DownLeft
.DownRight:        BYTE "┘"                     ; LR - DownRight
.LeftCenter:       BYTE "├"                     ; LC - LeftCenter
.RightCenter:      BYTE "┤"                     ; RC - RightCenter
.UpCenter:         BYTE "┬"                     ; UC - UpCenter
.DownCenter:       BYTE "┴"                     ; DC - DownCenter
.Size              EQU  $-ElementsBuffer
;

 INCLUDE	'VIDEO_IO.asm'
 INCLUDE	'AUTOIDE.asm'
 INCLUDE	'SETTINGS.asm'
 INCLUDE	'KEY.asm'
;.......................................

KEY:	EI 
	JP	WAITKEY

FindStringAddr:
	LD	L,A
	LD	H,0
	LD	BC,memBUFFER.Messages
	ADD	HL,HL
	ADD	HL,BC
	LD	A,(HL)
	INC	HL
	LD	H,(HL)
	LD	L,A	
	RET

POSTLEN:
	CALL FindStringAddr
	LD	BC,#0100
	XOR	A
	CPIR 
	LD	A,#FF
	SUB	C
	SRL	A
	LD	C,A
	LD	A,40
	SUB	C
	LD	E,A
	;JP	ScreenPOS.LOCAT
        JP      LP_SET_PLACE

POSTMSG:
	CALL    FindStringAddr
	JP	PRINTZ

POSTMSC:
	CALL    FindStringAddr
	LD	A,E
	JP	CPRINTZ

SETLAND:
	LD	A,#0E   						; !HARDCODE CMOS ячейка options
	CALL	READCMS
	AND	#04     						; !HARDCODE CMOS значение языка
	JR	NZ,.RUS
	;
	LD	HL,MSG_ENG
	LD	DE,memBUFFER.Messages
	LD	BC,MSG_ENG.size
	LDIR
	RET
	;
.RUS:	LD	HL,MSG_RUS
	LD	DE,memBUFFER.Messages
	LD	BC,MSG_RUS.size
	LDIR
	RET
;
; print boot drive number
PRINT_CHANEL:
	 AND	#0F
	 LD	C,A
	 ;
	 LD	A,msgStrings.parPriIdeMA
	 JR	Z,.print_chanel
	 ;
	 LD	A,msgStrings.parPriIdeSl
	 DEC	C
	 JR	Z,.print_chanel
	 ;
	 LD	A,msgStrings.parSecIdeMA
	 DEC	C
	 JR	Z,.print_chanel
	 ;
	 LD	A,msgStrings.parSecIdeSl
.print_chanel:
	 CALL	FindStringAddr
	 ;CALL	LP_GET_PLACE
	 ;LD	A,ScreenPOS.SUBNAME.POS
	 ;SUB	E
	 ;LD	B,A
	 LD	B,0
	 LD	D,#FF
	 JP	LP_PRINT_LINE6
;


;---------------------------------------
 INCLUDE 'src/bios/ROM/SETUP/messages.z80'
;---------------------------------------
;

        STRUCT  MAIN_BUFFERS
ID              BLOCK #100
Messages        BLOCK MSG_ENG.size
Shared          BLOCK 1024
End             BYTE
        ENDS


memBUFFER       MAIN_BUFFERS = $
STACK           EQU #C000
.size           EQU 128


; ID_BUFFER               EQU $
; MSG_Buffer              EQU ID_BUFFER+#100
; TMP_BUFFER              EQU MSG_Buffer + MSG_ENG.size

 IF memBUFFER.End-1 > #C000-STACK.size
	DISPLAY 'memBUFFER.Shared overlaps STACK by:	',/A,(memBUFFER.End-1)-(#C000-STACK.size)
	ASSERT memBUFFER.End-1 < #C000-STACK.size
 ENDIF

 IFDEF PREBUILD
	OUTEND

	DISPLAY '-----[Set_Pictures Prebuild start]-----'
	MMU		1 e, 0						; страница 0 в банку 0 и проверка на границы.
	ORG		ROM_MAP.LOGO
	INCLUDE 'src/bios/logo/Set_Pictures.asm'
	DISPLAY '-----[Set_Pictures Prebuild done ]-----'
 ELSE
        DISPLAY '------------------[Main.asm]------------------'		
        DISPLAY 'End code address:                ',/A,$-1
        DISPLAY 'Code size:                       ',/A,$-COMPILE_ADDR.MAIN
        DISPLAY 'End buffers address:             ',/A,memBUFFER.End-1
        DISPLAY 'Free memory:                     ',/A,#C000-(memBUFFER.End-1)-STACK.size
        DISPLAY 'Unused bytes before INT_POINTER: ',/A,INT_POINTER-before_intPointer
 ENDIF
;