forked from KolibriOS/kolibrios
487 lines
8.7 KiB
C
487 lines
8.7 KiB
C
|
|
||
|
#include "common.h"
|
||
|
|
||
|
#pragma pack(push, 1)
|
||
|
typedef struct
|
||
|
{
|
||
|
char sec;
|
||
|
char min;
|
||
|
char hour;
|
||
|
char rsv;
|
||
|
}detime_t;
|
||
|
#pragma pack(pop)
|
||
|
|
||
|
#pragma pack(push, 1)
|
||
|
typedef struct
|
||
|
{
|
||
|
char day;
|
||
|
char month;
|
||
|
short year;
|
||
|
}dedate_t;
|
||
|
#pragma pack(pop)
|
||
|
|
||
|
|
||
|
#pragma pack(push, 1)
|
||
|
typedef struct
|
||
|
{ unsigned attr;
|
||
|
unsigned flags;
|
||
|
union
|
||
|
{
|
||
|
detime_t ctime;
|
||
|
unsigned cr_time;
|
||
|
};
|
||
|
union
|
||
|
{
|
||
|
dedate_t cdate;
|
||
|
unsigned cr_date;
|
||
|
};
|
||
|
union
|
||
|
{
|
||
|
detime_t atime;
|
||
|
unsigned acc_time;
|
||
|
};
|
||
|
union
|
||
|
{
|
||
|
dedate_t adate;
|
||
|
unsigned acc_date;
|
||
|
};
|
||
|
union
|
||
|
{
|
||
|
detime_t mtime;
|
||
|
unsigned mod_time;
|
||
|
};
|
||
|
union
|
||
|
{
|
||
|
dedate_t mdate;
|
||
|
unsigned mod_date;
|
||
|
};
|
||
|
unsigned size;
|
||
|
unsigned size_high;
|
||
|
} FILEINFO;
|
||
|
#pragma pack(pop)
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
char *path;
|
||
|
int offset;
|
||
|
} dbgfile_t;
|
||
|
|
||
|
static dbgfile_t dbgfile;
|
||
|
|
||
|
static void _SysMsgBoardStr(char *text)
|
||
|
{
|
||
|
asm __volatile__
|
||
|
(
|
||
|
"call [DWORD PTR __imp__SysMsgBoardStr]"
|
||
|
:
|
||
|
:"S" (text)
|
||
|
);
|
||
|
};
|
||
|
|
||
|
int get_fileinfo(const char *path,FILEINFO *info)
|
||
|
{
|
||
|
int retval;
|
||
|
|
||
|
asm __volatile__
|
||
|
(
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"mov [esp+1], eax \n\t"
|
||
|
"push ebx \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 5 \n\t"
|
||
|
"mov ebx, esp \n\t"
|
||
|
"mov eax, 70 \n\t"
|
||
|
"int 0x40 \n\t"
|
||
|
"add esp, 28 \n\t"
|
||
|
:"=eax" (retval)
|
||
|
:"a" (path), "b" (info)
|
||
|
);
|
||
|
return retval;
|
||
|
};
|
||
|
|
||
|
int create_file(const char *path)
|
||
|
{
|
||
|
int retval;
|
||
|
asm __volatile__(
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"mov [esp+1], eax \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 2 \n\t"
|
||
|
"mov ebx, esp \n\t"
|
||
|
"mov eax, 70 \n\t"
|
||
|
"int 0x40 \n\t"
|
||
|
"add esp, 28"
|
||
|
:"=eax" (retval)
|
||
|
:"a" (path)
|
||
|
);
|
||
|
return retval;
|
||
|
};
|
||
|
|
||
|
int set_file_size(const char *path, unsigned size)
|
||
|
{
|
||
|
int retval;
|
||
|
asm __volatile__(
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"mov [esp+1], eax \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push ebx \n\t"
|
||
|
"push 4 \n\t"
|
||
|
"mov ebx, esp \n\t"
|
||
|
"mov eax, 70 \n\t"
|
||
|
"int 0x40 \n\t"
|
||
|
"add esp, 28"
|
||
|
:"=eax" (retval)
|
||
|
:"a" (path), "b" (size)
|
||
|
);
|
||
|
return retval;
|
||
|
};
|
||
|
|
||
|
int write_file(const char *path,const void *buff,
|
||
|
unsigned offset,unsigned count,unsigned *writes)
|
||
|
{
|
||
|
int retval;
|
||
|
asm __volatile__
|
||
|
("push ebx \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"mov [esp+1], eax \n\t"
|
||
|
"push ebx \n\t"
|
||
|
"push edx \n\t"
|
||
|
"push 0 \n\t"
|
||
|
"push ecx \n\t"
|
||
|
"push 3 \n\t"
|
||
|
"mov ebx, esp \n\t"
|
||
|
"mov eax, 70 \n\t"
|
||
|
"int 0x40 \n\t"
|
||
|
"test esi, esi \n\t"
|
||
|
"jz 1f \n\t"
|
||
|
"mov [esi], ebx \n\t"
|
||
|
"1:"
|
||
|
"add esp, 28 \n\t"
|
||
|
"pop ebx"
|
||
|
:"=eax" (retval)
|
||
|
:"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(writes)
|
||
|
);
|
||
|
return retval;
|
||
|
};
|
||
|
|
||
|
char * _putc(char *s, int c)
|
||
|
{
|
||
|
int i=0;
|
||
|
|
||
|
switch(c)
|
||
|
{
|
||
|
case '\n':
|
||
|
*s++ = '\r';
|
||
|
*s++ = '\n';
|
||
|
|
||
|
case '\r':
|
||
|
break;
|
||
|
|
||
|
case '\t':
|
||
|
do
|
||
|
{
|
||
|
*s++ = ' ';
|
||
|
}
|
||
|
while (i % 8 != 0);
|
||
|
break;
|
||
|
default:
|
||
|
*s++ = c;
|
||
|
}
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
char *print_string(char *buff, char* s)
|
||
|
{
|
||
|
int i=0;
|
||
|
char c;
|
||
|
|
||
|
while (c=*s++)
|
||
|
{
|
||
|
switch(c)
|
||
|
{
|
||
|
case '\r':
|
||
|
break;
|
||
|
|
||
|
case '\n':
|
||
|
*buff++ = '\r';
|
||
|
*buff++ = '\n';
|
||
|
i=0;
|
||
|
|
||
|
case '\t':
|
||
|
do
|
||
|
{
|
||
|
*buff++ = ' ';
|
||
|
i++;
|
||
|
}
|
||
|
while (i % 8 != 0);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
*buff++ = c;
|
||
|
i++;
|
||
|
};
|
||
|
}
|
||
|
return buff;
|
||
|
}
|
||
|
|
||
|
char *print_dec(char *buff,int val)
|
||
|
{
|
||
|
char dbuff[16];
|
||
|
int i = 14;
|
||
|
|
||
|
dbuff[15] = '\0';
|
||
|
do
|
||
|
{
|
||
|
dbuff[i] = (val % 10) + '0';
|
||
|
val = val / 10;
|
||
|
i--;
|
||
|
} while(val);
|
||
|
|
||
|
return print_string(buff, &dbuff[i+1]);
|
||
|
}
|
||
|
|
||
|
const char hexchars[] = "0123456789ABCDEF";
|
||
|
|
||
|
char *print_hex(char *buff, u32_t val)
|
||
|
{
|
||
|
int i;
|
||
|
for (i=sizeof(u32_t)*8-4; i >= 0; i -= 4)
|
||
|
buff = _putc(buff,hexchars[((u32_t)val >> i) & 0xF]);
|
||
|
return buff;
|
||
|
}
|
||
|
|
||
|
#define va_start(v,l) __builtin_va_start(v,l)
|
||
|
#define va_end(v) __builtin_va_end(v)
|
||
|
#define va_arg(v,l) __builtin_va_arg(v,l)
|
||
|
#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
|
||
|
#define va_copy(d,s) __builtin_va_copy(d,s)
|
||
|
#endif
|
||
|
#define __va_copy(d,s) __builtin_va_copy(d,s)
|
||
|
|
||
|
typedef __builtin_va_list __gnuc_va_list;
|
||
|
typedef __gnuc_va_list va_list;
|
||
|
|
||
|
#define arg(x) va_arg (ap, u32_t)
|
||
|
|
||
|
char txtbuf[128];
|
||
|
|
||
|
int printf(const char* format, ...)
|
||
|
{
|
||
|
u32_t ret = 1;
|
||
|
u32_t i = 0;
|
||
|
char *sbuf = txtbuf;
|
||
|
|
||
|
va_list ap;
|
||
|
|
||
|
va_start (ap, format);
|
||
|
|
||
|
if (format == 0)
|
||
|
return 0;
|
||
|
|
||
|
while (*format)
|
||
|
{
|
||
|
switch (*(format))
|
||
|
{
|
||
|
case '%':
|
||
|
next_fmt:
|
||
|
switch (*(++format))
|
||
|
{
|
||
|
case 'l': case '-':
|
||
|
case '0': case '1': case '2': case '3': case '4':
|
||
|
case '5': case '6': case '7': case '8': case '9':
|
||
|
goto next_fmt;
|
||
|
|
||
|
case 'c':
|
||
|
sbuf = _putc (sbuf,arg (i));
|
||
|
break;
|
||
|
case 'd':
|
||
|
sbuf = print_dec (sbuf,arg (i));
|
||
|
break;
|
||
|
case 'p':
|
||
|
case 'x':
|
||
|
sbuf = print_hex (sbuf,(u32_t) arg (i));
|
||
|
break;
|
||
|
case 's':
|
||
|
sbuf = print_string (sbuf,(char*) arg (i));
|
||
|
break;
|
||
|
default:
|
||
|
sbuf = print_string (sbuf,"?");
|
||
|
break;
|
||
|
}
|
||
|
i++;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
sbuf = _putc (sbuf,*format);
|
||
|
break;
|
||
|
}
|
||
|
format++;
|
||
|
}
|
||
|
|
||
|
va_end (ap);
|
||
|
*sbuf=0;
|
||
|
_SysMsgBoardStr(txtbuf);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
int dbg_open(char *path)
|
||
|
{
|
||
|
FILEINFO info;
|
||
|
|
||
|
dbgfile.offset = 0;
|
||
|
|
||
|
if(get_fileinfo(path,&info))
|
||
|
{
|
||
|
if(!create_file(path))
|
||
|
{
|
||
|
dbgfile.path = path;
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
return FALSE;
|
||
|
};
|
||
|
set_file_size(path, 0);
|
||
|
dbgfile.path = path;
|
||
|
dbgfile.offset = 0;
|
||
|
return TRUE;
|
||
|
};
|
||
|
|
||
|
int vsnprintf(char *s, size_t n, const char *format, va_list arg);
|
||
|
|
||
|
int dbgprintf(const char* format, ...)
|
||
|
{
|
||
|
unsigned writes;
|
||
|
|
||
|
int len=0;
|
||
|
// char *sbuf = txtbuf;
|
||
|
|
||
|
va_list ap;
|
||
|
|
||
|
va_start(ap, format);
|
||
|
if (format)
|
||
|
len = vsnprintf(txtbuf, 128, format, ap);
|
||
|
va_end(ap);
|
||
|
|
||
|
_SysMsgBoardStr(txtbuf);
|
||
|
|
||
|
if(dbgfile.path)
|
||
|
{
|
||
|
write_file(dbgfile.path,txtbuf,dbgfile.offset,len,&writes);
|
||
|
dbgfile.offset+=writes;
|
||
|
};
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
int snprintf(char *s, size_t n, const char *format, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
int retval;
|
||
|
|
||
|
va_start(ap, format);
|
||
|
retval = vsnprintf(s, n, format, ap);
|
||
|
va_end(ap);
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
/*
|
||
|
int snprintf(char *buf,int count, const char* format, ...)
|
||
|
{
|
||
|
int len;
|
||
|
|
||
|
// u32 ret = 1;
|
||
|
u32 i = 0;
|
||
|
char *sbuf = buf;
|
||
|
|
||
|
va_list ap;
|
||
|
|
||
|
va_start (ap, format);
|
||
|
|
||
|
if (format == 0)
|
||
|
return 0;
|
||
|
|
||
|
while (*format)
|
||
|
{
|
||
|
switch (*(format))
|
||
|
{
|
||
|
case '%':
|
||
|
next_fmt:
|
||
|
switch (*(++format))
|
||
|
{
|
||
|
case 'l': case '-':
|
||
|
case '0': case '1': case '2': case '3': case '4':
|
||
|
case '5': case '6': case '7': case '8': case '9':
|
||
|
goto next_fmt;
|
||
|
|
||
|
case 'c':
|
||
|
sbuf = _putc (sbuf,arg (i));
|
||
|
break;
|
||
|
case 'd':
|
||
|
sbuf = print_dec (sbuf,arg (i));
|
||
|
break;
|
||
|
case 'p':
|
||
|
case 'x':
|
||
|
sbuf = print_hex (sbuf,(u32) arg (i));
|
||
|
break;
|
||
|
case 's':
|
||
|
sbuf = print_string (sbuf,(char*) arg (i));
|
||
|
break;
|
||
|
default:
|
||
|
sbuf = print_string (sbuf,"?");
|
||
|
break;
|
||
|
}
|
||
|
i++;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
sbuf = _putc (sbuf,*format);
|
||
|
break;
|
||
|
}
|
||
|
format++;
|
||
|
}
|
||
|
|
||
|
va_end (ap);
|
||
|
*sbuf=0;
|
||
|
len = sbuf-txtbuf;
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
char *
|
||
|
RhdAppendString(char *s1, const char *s2)
|
||
|
{
|
||
|
|
||
|
if (!s2)
|
||
|
return s1;
|
||
|
else
|
||
|
if (!s1)
|
||
|
return strdup(s2);
|
||
|
else
|
||
|
{
|
||
|
int len = strlen(s1) + strlen(s2) + 1;
|
||
|
char *result = (char *)malloc(len);
|
||
|
|
||
|
if (!result) return s1;
|
||
|
|
||
|
strcpy(result,s1);
|
||
|
strcat(result,s2);
|
||
|
free(s1);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|