/*
=======================================================================================================================
								EEPROM Api By NeO_2kX v.1 Alpha
=======================================================================================================================

Патч представляет собой библиотеку, которая экспортирует функции для чтения/записи в особый блок EEPROM'а.
Блок высвобождается в результате переноса пользовательской базы Т9(UDB)  в файловую систему TFS(файл "/user/T9.udb").
Патч выполнен для прошивки X100XEDG1.
Если есть желание, то портирование на другие модели Sysol(возможно, что и Swift) не должно вызвать особых затруднений.
Обращение к блокам реализовано через функции Read_EEPROM и Write_EEPROM.
Ключевым моментом в параметрах этих функций является смещение от начала блока.
Размер блока – 1024 байта.

Смещения регистрируются в теме патча на форуме сайта SGH.RU.

(с)NeO_2kX, 2007
=======================================================================================================================
*/

.binid X100XEDG1
.include "EERROM_API.h"

/*
@Отключение инициализации UDB при старте телефона
.start 0023867C:
nop
nop
*/

@Отключение валидации UDB базы
.start 0x00236DC8
	CMP R0, R0

@Новый вариант T9Res_ReadUdbData
T9Res_ReadUdbData:
PUSH	{R1-R7,LR}
@Buf
	MOV		R7, R0

@Чтение файла в буфер	
	MOV		R2, R7
	MOV		R1, #0x1
	LSL		R1, R1, #10				@0x400
	MOV		R0, #0
	BL		Read_File_Call			@{POS, SIZE, TO}
	
@Проверка размера базы	
	LDRH	R0, [R7, #0]
	MOV		R5, #0x1
	LSL		R5, R5, #10				@0x400
	CMP		R0, R5
	BNE		T9Res_ReadUdbData_Clear

@Проверка SYM_CLASS	
	LDRH	R0, [R7, #6]
	CMP		R0, #0xF
	BEQ		Exit_T9Res_ReadUdbData

T9Res_ReadUdbData_Clear:
@Зануление базы
	MOV		R2, #0x1
	LSL		R2, R2, #10				@0x400
	MOV		R1, #0x0
	MOV		R0, R7
	BL		memset

@Заполнение параметров	
	STRH	R5, [R7, #0]			@DATA_SIZE	
	MOV		R1, #0xF				
	STRH	R1, [R7, #6]			@SYM_CLASS

Exit_T9Res_ReadUdbData:
	MOV		R0, #0
POP		{R1-R7, PC}

ExternalFunc Read_File_Call Read_File

@Новый вариант T9Res_WriteUdbData
T9Res_WriteUdbData:
@Запись в файл из буфера
PUSH	{R1-R2,LR}		
	MOV		R2, R0
	MOV		R1, #0x1
	LSL		R1, R1, #10				@0x400
	MOV		R0, #0
	BL		Write_File_Call
	MOV		R0, #0x1
POP		{R1-R2, PC}

ExternalFunc Write_File_Call Write_File

.start Patch_Start
@Сингатура
.string "<EEPROM Api By NeO_2kX>"

.align 1
Read_EEPROM:
@In:
@R0 - Offset
@R1 - Type
@Out:
@R0 - Value
PUSH 	{R2-R5, LR}
	MOV		R4, R0
	MOV 	R5, R1

@Проверка входных данных на корректность	
	CMP		R1, #2
	BGT		Exit_Read_EEPROM
	
	MOV 	R1, #0x3
	LSL 	R1, R1, #8
	ADD 	R1, #0xFF             		@0x3FF
	
	CMP		R0, R1
	BGT		Exit_Read_EEPROM
	

@Чтение блока
	LDR		R0, =0x00001970
	BL		hfd2_30ReadBlockNameInRamImage
	
@Вычисление смещения
	ADD		R0, R0, R4
	
	CMP 	R5, #1
	BEQ		Read_EEPROM_pword
	
	CMP		R5, #2
	BEQ		Read_EEPROM_word

@Чтение байта	
	LDRB	R0, [R0]
	B		Exit_Read_EEPROM

@Чтение полуслова	
Read_EEPROM_pword:
	LDRH 	R0, [R0]
	B		Exit_Read_EEPROM

@Чтение слова	
Read_EEPROM_word:
	LDR		R0, [R0]

Exit_Read_EEPROM:	
POP 	{R2-R5, PC}
.data

.align 1
Write_EEPROM:
@R0 - Offset
@R1 - Type
@R2 - Val
PUSH 	{R3-R7, LR}
	MOV		R6, R0
	MOV		R5, R1
	MOV		R4, R2

@Проверка входных данных на корректность	
	CMP		R1, #2
	BGT		Exit_Write_EEPROM
	
	MOV 	R1, #0x3
	LSL 	R1, R1, #8
	ADD 	R1, #0xFF             		@0x3FF
	
	CMP		R0, R1
	BGT		Exit_Write_EEPROM

@Чтение блока		
	LDR		R0, =0x00001970
	MOV		R7, R0
	BL		hfd2_30ReadBlockNameInRamImage

@Вычисление смещения	
	ADD		R0, R0, R6
	
	CMP		R5, #1
	BEQ		Write_EEPROM_pword

	CMP		R5, #2
	BEQ		Write_EEPROM_word

@Сохранение байта
	STRB	R4, [R0]
	B		Write_EEPROM_Save

@Сохранение полуслова	
Write_EEPROM_pword:
	STRH	R4, [R0]
	B		Write_EEPROM_Save

@Сохранение слова	
Write_EEPROM_word:	
	STR		R4, [R0]

@Сохранение в EEPROM
Write_EEPROM_Save:	
	SUB		R1, R0, R6
	MOV		R0, R7
	BL		hfd2_31SaveBlockNameInRamImage
	
Exit_Write_EEPROM:	
POP 	{R3-R7, PC}
.data

.string "<Read_File>"
@Функция чтения из файла
@R0 - pos
@R1 - len
@R2 - to
.align 1
Read_File:
.equ Read_File_Stack_Size 	#12
.equ Read_File_bytesread	#4
PUSH 	{R3-R7, LR}
SUB 	SP, SP, #Read_File_Stack_Size

	ADD 	R7, R0, #0		@pos
	ADD 	R6, R1, #0		@len
	STR 	R2, [SP, #8]

@Открытие файла	
	MOV		R2, #7
	ADR 	R1, ="/user/T9.udb"
	MOV		R0, SP
	BL		ffsOpenFile				; (int* handle, char* filename, mode):(int)
	CMP 	R0, #0
	BNE		Read_File_Exit

@Установка указателя	
	ADD		R3, SP, #Read_File_bytesread
	ADD		R2, R7, #0
	MOV		R1, #1
	LDR 	R0, [SP]
	BL		ffsSeekFile				@(uint fid, ulong pos, long offset, ulong *new_ptr);

@Чтение файла	
	ADD		R3, SP, #Read_File_bytesread
	ADD		R2, R6, #0
	LDR		R1, [SP, #8]
	LDR		R0, [SP]
	BL		ffsReadFile				; (int handle, void* buf, bytestoread, bytesread*):(int)

@Закрытие файла	
	LDR		R0, [SP]
	BL		ffsCloseFile

Read_File_Exit:	
ADD 	SP, SP, #Read_File_Stack_Size
POP		{R3-R7, PC}
.data

.string "<Write_File>"
.align 1
@Функция записи в файл
@R0 - pos
@R1 - len
@R2 - from
Write_File:
.equ Write_File_Stack_Size 	#12
.equ Write_File_Temp		#4
PUSH 	{R3-R7, LR}
SUB 	SP, SP, #Write_File_Stack_Size

	ADD		R7, R0, #0				@pos
	ADD		R6, R1, #0				@len
	STR		R2, [SP, #8]			@buf

@Открытие файла	
	MOV 	R2, #7
	ADR 	R1, ="/user/T9.udb"
	MOV		R0, SP
	BL		ffsOpenFile				; (int* handle, char* filename, mode):(int)
	CMP		R0, #0
	BNE		Write_File_Exit

@Установка указателя	
	ADD		R3, SP, #Write_File_Temp		
	ADD		R2, R7, #0
	MOV		R1, #1
	LDR 	R0, [SP]
	BL		ffsSeekFile				@(uint fid, ulong pos, long offset, ulong *new_ptr);

@Запись файла	
	ADD 	R2, R6, #0
	LDR		R1, [SP, #8]
	LDR		R0, [SP]
	BL		ffsWriteFile			; (uint fid, void *buffer, ulong bcount):(int)
	
@Закрытие файла		
	LDR		R0, [SP]
	BL		ffsCloseFile

Write_File_Exit:	
ADD 	SP, SP, #Write_File_Stack_Size	
POP		{R3-R7, PC}
.data

.string "</EEPROM Api By NeO_2kX>"