📄 util.c
字号:
#include "fastmath.h"
#include "config.h"
#include "global.h"
#include "memmap.h"
#include "util.h"
#ifdef USE_DIV
#include "stdlib.h"
#endif
/*
** FUNCTION
** bin2bcd(BYTE x)
**
** DESCRIPTION
** transform a binary-represented number into packed BCD.
**
** 0x0c(12) -> 0x12
** 0x20(32) -> 0x32
**
** NOTE
** we used fast dividing-by-10 function to generate the result.
*/
int bin2bcd(BYTE x)
{
#ifdef USE_DIV
div_t res;
res = div(x, 10);
return (res.quot << 4) | (res.rem);
#else
#if 1
int Q = DIV10(x);
int R = x - 10 * Q;
return (Q << 4) | R;
#else
return ((x / 10) << 4) | (x % 10);
#endif
#endif
}
/*
** FUNCTION
** bcd2bin(BYTE x)
**
** DESCRIPTION
** transform a bcd-number into binary-represented
*/
int bcd2bin(BYTE x)
{
/*
for mips, a optimized version might be obtained using:
use CE (slower)
li %1, 10
shr %2, %0, 4
multu %1, %2
andi %1, %0, 0x000f
mflo %2
addu %1, %2
or
shr %1, %0, 4 // >>4
addu %2, %1, %1 // (2) = *2
shl %1, %2, 2 // (1) = (2)*4
addu %1, %2 // (1) = (1)+(2)
andi %2, %0, 0x000f // (2) = (0)&0x000f
addu %1, %2 // (1) = (1)+(2)
*/
return (x >> 4) * 10 + (x & 0x0f);
}
/*
** FUNCTION
** l2msf(UINT32 l)
**
** DESCRIPTION
** map a linear address of CDROM into MSF addressing
**
** NOTE
** msf is packed 4-byte structure with format
** [CI:MM:SS:FF], where MM/SS/FF is in binary.
*/
UINT32 l2msf(UINT32 l)
{
UINT32 ss, ff;
UINT32 l_75, l_4500;
l += 150;
l_75 = l / 75;
l_4500 = l_75 / 60;
ff = l - 75 * l_75;
ss = l_75 - 60 * l_4500;
return (l_4500 << 16) | (ss << 8) | (ff);
}
/*
** FUNCTION
** msf2l(UINT32 msf)
**
** DESCRIPTION
** map a MSF addressing into linear addressing
**
** NOTE
** (UINT32)msf is packed 4-byte structure with format
** [00:MM:SS:FF], where MM/SS/FF is in binary.
*/
UINT32 msf2l(UINT32 msf)
{
return MSF2l(msf_mm(msf), msf_ss(msf), msf_ff(msf));
}
/*
** FUNCTION
** addmsf_ss(UINT32 msf, int inc_s)
**
** DESCRIPTION
** adjust MSF address by (inc_s) seconds
*/
#define MSF_SECONDS 60
#define MSF_FRAMES 75
#define FIRST_FRAME 0x000200
UINT32 addmsf_ss(UINT32 msf, int inc_s)
{
UINT32 ret_msf;
int mm = msf_mm(msf);
int ss = msf_ss(msf) + inc_s;
int ff = msf_ff(msf);
while (ss < 0) {
ss += MSF_SECONDS;
mm--;
}
while (ss >= MSF_SECONDS) {
ss -= MSF_SECONDS;
mm++;
}
ret_msf = MSF(mm, ss, ff);
if (mm < 0)
ret_msf = 0x000200;
return ret_msf;
}
/*
** FUNCTION
** addmsf(UINT32 msf, int inc_f)
**
** DESCRIPTION
** adjust MSF address by #inc_f frames
*/
UINT32 addmsf(UINT32 msf, int inc_f)
{
UINT32 ret_msf;
int mm = msf_mm(msf);
int ss = msf_ss(msf);
int ff = msf_ff(msf) + inc_f;
while (ff < 0) {
ff += 75;
ss--;
}
while (ff >= 75) {
ff -= 75;
ss++;
}
while (ss < 0) {
ss += 60;
mm--;
}
while (ss >= 60) {
ss -= 60;
mm++;
}
ret_msf = MSF(mm, ss, ff);
if (mm < 0)
ret_msf = 0x000200;
if (ret_msf < 0x000200)
ret_msf = 0x000200;
return ret_msf;
}
UINT32 endian_swap_32(UINT32 original)
{
int result;
result = 0;
result += (original << 24);
result += (((original >> 8) << 24) >> 8);
result += (((original >> 16) << 24) >> 16);
result += (original >> 24);
return result;
}
UINT16 endian_swap_16(UINT16 original)
{
int result;
result = 0;
result += (original << 8);
result += (original >> 8);
return result;
}
#if 0
BYTE *strcpy(register BYTE *to, register const BYTE *from)
{
BYTE *save;
save = to;
for (; (BYTE)(*to = *from); ++from, ++to);
return (save);
}
#endif
BYTE *strcpylen(register BYTE *to, register const BYTE *from, UINT16 len)
{
BYTE *save;
UINT16 i;
save = to;
if (len) {
for (i = 0; (BYTE)(*to = *from); ++from, ++to, i++) {
if (i == len) {
*to = '\0';
break;
}
}
}
else {
*to = '\0';
}
return (save);
}
BYTE *strcpychn(register BYTE *to, register const BYTE *from, UINT16 len)
{
BYTE *save;
BYTE c;
UINT16 i;
save = to;
if (len) {
for (i = 0, c = 0; (BYTE)(*to = *from); ++from, ++to, i++) {
if (*to > 0x7F) c ^= 0x01;
if (i == len - 1) {
if (*to > 0x7F && c) {
*to = '\0';
break;
}
}
if (i == len) {
*to = '\0';
break;
}
}
}
else {
*to = '\0';
}
return (save);
}
BYTE *strncat(register BYTE *s, register const BYTE *append)
{
BYTE *save = s;
for (; *s; ++s);
// while (*s++ = *append++);
while ((BYTE)(*(s++) = *(append++)));
return (save);
}
BYTE *strchr(register BYTE *str, BYTE chr)
{
BYTE *s;
s = str;
while (*s) {
if (*s == chr)
return s;
s++;
}
return (BYTE *)NULL;
}
BYTE *strstr(register BYTE *str, BYTE *chr)
{
BYTE *s;
BYTE *c;
BYTE *t;
s = str;
while (*s) {
if (*s == *chr) {
t = s;
c = chr;
while (*c && *t) {
if (*t != *c) {
break;
}
t++;
c++;
if (!(*c)) {
return s;
}
}
}
s++;
}
return (BYTE *)NULL;
}
void memcopy(register BYTE *to, register const BYTE *from, UINT16 len)
{
UINT16 i;
for (i = 0; i < len; i++) {
*to = *from;
to++;
from++;
}
}
void memload(register BYTE *to, UINT32 from, UINT16 len)
{
switch (len) {
case 4:
*to++ = (from >> 24) & 0xFF;
case 3:
*to++ = (from >> 16) & 0xFF;
case 2:
*to++ = (from >> 8 ) & 0xFF;
case 1:
*to = (from ) & 0xFF;
break;
}
}
UINT32 DecStrToHex(BYTE *asc, BYTE len)
{
UINT32 Result;
BYTE i;
Result = 0;
for (i = 0; i < len; i++) {
Result *= 10;
Result += asc[i] - '0';
}
return Result;
}
void HexToDecStr(UINT32 hexdata, BYTE *result, BYTE len)
{
BYTE i, j;
BYTE c;
i = 0;
while (hexdata) {
*(result + i) = hexdata % 10 + '0';
i++;
hexdata /= 10;
}
for (j = i; j < len; j++) *(result + j) = '0';
for (i = 0; i < len / 2; i++) {
c = *(result + i);
*(result + i) = *(result + len - 1 - i);
*(result + len - 1 - i) = c;
}
}
const BYTE Hex2Asc[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
};
void Hex2Str(BYTE *dsc, BYTE src)
{
dsc[0] = Hex2Asc[src >> 4];
dsc[1] = Hex2Asc[src & 0x0F];
dsc[2] = '\x00';
}
void Dec2Str(BYTE *dsc, BYTE src)
{
BYTE i;
i = 0;
if (src >= 100) {
dsc[i++] = '0' + (src / 100) % 10;
dsc[i++] = '0' + (src / 10) % 10;
}
else
if (src >= 10) {
dsc[i++] = '0' + (src / 10) % 10;
}
dsc[i++] = '0' + (src ) % 10;
dsc[i] = '\x00';
}
UINT32 Str2Hex(BYTE *src)
{
UINT32 Result;
BYTE Value;
Result = 0;
while (*src) {
Result <<= 4;
Value = *src++;
if (Value >= '0' && Value <= '9') Result += Value - '0';
else if (Value >= 'A' && Value <= 'F') Result += Value - 'A' + 10;
else if (Value >= 'a' && Value <= 'f') Result += Value - 'a' + 10;
else return 0;
}
return Result;
}
UINT32 Str2Dec(BYTE *src)
{
UINT32 Result;
BYTE Value;
Result = 0;
while (*src) {
Result *= 10;
Value = *src++;
if (Value >= '0' && Value <= '9') Result += Value - '0';
else return 0;
}
return Result;
}
void Str2Unc(BYTE *dsc, BYTE *src)
{
while (*src) {
*dsc++ = '0';
*dsc++ = '0';
Hex2Str(dsc, *src);
dsc++;
dsc++;
src++;
}
*dsc = 0;
}
BYTE Str4Dig(BYTE *src, BYTE len)
{
BYTE i;
for (i = 0; i < len; i++) {
if (src[i] < '0' || src[i] > '9')
return FALSE;
}
return TRUE;
}
void Txt2Pdu(BYTE *dsc, BYTE *src)
{
*dsc++ = '6';
*dsc++ = '8';
while (*src) {
if (*(src + 1)) {
*dsc++ = *(src + 1);
*dsc++ = *src++;
src++;
}
else {
*dsc++ = 'F';
*dsc++ = *src;
break;
}
}
*dsc = 0;
}
void Pdu2Txt(BYTE *dsc, BYTE *src)
{
src += 2;
while (*src) {
*dsc++ = *(src + 1);
if (*src == 'F') break;
*dsc++ = *src++;
src++;
}
*dsc = 0;
}
BYTE Pdu2Asc(BYTE *dsc, BYTE *src)
{
BYTE Hi, Lo;
while (*src) {
if (*src++ == '0' && *src++ == '0') {
Hi = *src++;
Lo = *src++;
if (Hi >= '0' && Hi <= '7') {
if (Lo >= '0' && Lo <= '9') {
*dsc++ = ((Hi - '0') << 4) | (Lo - '0');
}
else
if (Lo >= 'A' && Lo <= 'F') {
*dsc++ = ((Hi - '0') << 4) | (Lo - 'A' + 10);
}
else return FALSE;
}
else return FALSE;
}
else return FALSE;
}
*dsc = 0;
return TRUE;
}
BYTE IsAlpha(BYTE c)
{
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
BYTE IsDigit(BYTE c)
{
return (c >= '0' && c <= '9');
}
BYTE IsPrint(BYTE c)
{
return (c >= ' ' && c <= '~');
}
UINT16 GBKToUnicode(UINT16 GBKData)
{
UINT16 i;
UINT16 Unicode;
#if defined(SUPPORT_SDRAM_FONT) && (ROM_SIZE != 40)
for (i = 0; i < UNICODE_TABLE_LEN * 2; i += 2) {
if (GBKData == *(GB_UNICODE + i) + 0x8080) {
Unicode = *(GB_UNICODE + i + 1) << 8;
Unicode |= *(GB_UNICODE + i + 1) >> 8;
return Unicode;
}
}
#else
for (i = 0; i < UNICODE_TABLE_LEN; i++) {
if (GBKData == UnicodeTable[i][0] + 0x8080) {
Unicode = UnicodeTable[i][1] << 8;
Unicode |= UnicodeTable[i][1] >> 8;
return Unicode;
}
}
#endif
return 0x0000;
}
UINT16 UnicodeToGBK(UINT16 Unicode)
{
UINT16 i;
UINT16 GBKData;
/*
GBKData = Unicode >> 8;
GBKData |= Unicode << 8;
Unicode = GBKData;
*/
#if defined(SUPPORT_SDRAM_FONT) && (ROM_SIZE != 40)
for (i = 0; i < UNICODE_TABLE_LEN * 2; i += 2) {
if (Unicode == *(GB_UNICODE + i + 1)) {
GBKData = *(GB_UNICODE + i) | 0x8080;
return GBKData;
}
}
#else
for (i = 0; i < UNICODE_TABLE_LEN; i++) {
if (Unicode == UnicodeTable[i][1]) {
GBKData = UnicodeTable[i][0] | 0x8080;
return GBKData;
}
}
#endif
return 0x0000;
}
void StrToPDUPhone(BYTE *StrTarget, BYTE *StrSource)
{
BYTE i;
BYTE Length;
Length = strlen(StrSource);
for (i = 0; i < Length; i += 2) {
StrTarget[i + 1] = StrSource[i];
if (i + 1 == Length)
StrTarget[i] = 'F';
else
StrTarget[i] = StrSource[i + 1];
}
StrTarget[i] = 0;
#if 0
if (StrSource != LineBuffer)
strcpy(LineBuffer, StrSource);
MenuPrintMessage(1);
strcpy(LineBuffer, StrTarget);
MenuPrintMessage(0);
#endif
}
void StrToPDUText(BYTE *StrTarget, BYTE *StrSource)
{
BYTE i;
BYTE Addr;
UINT16 Data;
BYTE StrTwoBit[3];
for (Addr = 0, i = 0; i < strlen(StrSource);) {
if (StrSource[i] < 0x80) { // Ascii char
Hex2Str(StrTwoBit, 0);
StrTarget[Addr++] = StrTwoBit[0];
StrTarget[Addr++] = StrTwoBit[1];
Hex2Str(StrTwoBit, StrSource[i]);
StrTarget[Addr++] = StrTwoBit[0];
StrTarget[Addr++] = StrTwoBit[1];
i++;
}
else { // HZ char
if (StrSource[i + 1] < 0x80) // Error
break;
Data = GBKToUnicode((StrSource[i] << 8) | StrSource[i + 1]);
Hex2Str(StrTwoBit, Data & 0xFF);
StrTarget[Addr++] = StrTwoBit[0];
StrTarget[Addr++] = StrTwoBit[1];
Hex2Str(StrTwoBit, Data >> 8);
StrTarget[Addr++] = StrTwoBit[0];
StrTarget[Addr++] = StrTwoBit[1];
i += 2;
}
}
StrTarget[Addr] = 0;
#if 0
if (StrSource != LineBuffer)
strcpy(LineBuffer, StrSource);
MenuPrintMessage(1);
strcpy(LineBuffer, StrTarget);
MenuPrintMessage(0);
#endif
}
void PDUTextToStr(BYTE *StrTarget, BYTE *StrSource)
{
BYTE i;
BYTE Addr;
UINT16 Data;
UINT16 Size;
BYTE StrFourBit[5];
Addr = 0; StrTarget[Addr] = 0;
Size = strlen(StrSource);
if (Size & 0x03) return;
for (i = 0; i < Size; i += 4) {
strcpylen(StrFourBit, StrSource + i, 4);
Data = Str2Hex(StrFourBit);
if (StrFourBit[0] == '0' && StrFourBit[1] == '0') {
if (Data > 0x7F) return;
StrTarget[Addr++] = Data;
StrTarget[Addr] = 0;
}
else {
Data = UnicodeToGBK(Data);
StrTarget[Addr++] = Data >> 8;
StrTarget[Addr++] = Data & 0xFF;
StrTarget[Addr] = 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -