forked from KolibriOS/kolibrios
kolibri-libc:
[include] - ksys.h : fixed sruct name - string.h: set memcpy, memset, and memove as static for libtcc - stdio.h: added sscanf and ungetc - stdint.h: added int64 limits [stdio] fixed *scanf functions added ungetc functon [lib] - upated binaries - added libtcc.a for tcc optimization [crt] - removed duplicate files [samples] - added fasm libc.obj example - updated old examples git-svn-id: svn://kolibrios.org@8718 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
611fac2831
commit
1c24cac315
@ -23,6 +23,10 @@
|
|||||||
#define INT64_MIN (-9223372036854775807LL-1LL)
|
#define INT64_MIN (-9223372036854775807LL-1LL)
|
||||||
#define INT64_MAX (9223372036854775807LL)
|
#define INT64_MAX (9223372036854775807LL)
|
||||||
#define UINT64_MAX (18446744073709551615ULL)
|
#define UINT64_MAX (18446744073709551615ULL)
|
||||||
|
#else
|
||||||
|
#define INT64_MAX 0x7fffffffffffffffLL
|
||||||
|
#define INT64_MIN (-INT64_MAX - 1LL)
|
||||||
|
#define UINT64_MAX (__CONCAT(INT64_MAX, U) * 2ULL + 1ULL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _STDINT_H_*/
|
#endif /* _STDINT_H_*/
|
||||||
|
@ -107,11 +107,12 @@ extern int _FUNC(putchar)(int);
|
|||||||
extern int _FUNC(puts)(const char *);
|
extern int _FUNC(puts)(const char *);
|
||||||
extern int _FUNC(scanf)(const char *restrict, ...);
|
extern int _FUNC(scanf)(const char *restrict, ...);
|
||||||
extern char* _FUNC(gets)(char *str);
|
extern char* _FUNC(gets)(char *str);
|
||||||
//extern int _FUNC(ungetc)(int, FILE *);
|
extern int _FUNC(ungetc)(int, FILE *);
|
||||||
extern int _FUNC(vfprintf)(FILE *restrict, const char *restrict, va_list);
|
extern int _FUNC(vfprintf)(FILE *restrict, const char *restrict, va_list);
|
||||||
extern int _FUNC(vfscanf)(FILE *restrict, const char *restrict, va_list);
|
extern int _FUNC(vfscanf)(FILE *restrict, const char *restrict, va_list);
|
||||||
extern int _FUNC(vprintf)(const char *restrict, va_list);
|
extern int _FUNC(vprintf)(const char *restrict, va_list);
|
||||||
extern int _FUNC(vscanf)(const char *restrict, va_list);
|
extern int _FUNC(vscanf)(const char *restrict, va_list);
|
||||||
|
extern int _FUNC(sscanf)(const char*, const char *restrict, ...);
|
||||||
extern int _FUNC(vsscanf)(const char *, const char*, va_list);
|
extern int _FUNC(vsscanf)(const char *, const char*, va_list);
|
||||||
|
|
||||||
extern int _FUNC(remove)(const char *);
|
extern int _FUNC(remove)(const char *);
|
||||||
|
@ -29,13 +29,16 @@ extern void* _FUNC(memccpy)(void *restrict dest, const void *restrict src, int c
|
|||||||
area pointed to by s1. If the two areas overlap, behaviour is undefined.
|
area pointed to by s1. If the two areas overlap, behaviour is undefined.
|
||||||
Returns the value of s1.
|
Returns the value of s1.
|
||||||
*/
|
*/
|
||||||
extern void* _FUNC(memcpy)(void* s1, const void* s2, size_t n);
|
|
||||||
|
|
||||||
/* Copy a number of n characters from the memory area pointed to by s2 to the
|
#ifdef __TINYC__
|
||||||
area pointed to by s1. The two areas may overlap.
|
extern void* memcpy(void* s1, const void* s2, size_t n);
|
||||||
Returns the value of s1.
|
extern void* memset(void* s, int c, size_t n);
|
||||||
*/
|
|
||||||
extern void* memmove(void* s1, const void* s2, size_t n);
|
extern void* memmove(void* s1, const void* s2, size_t n);
|
||||||
|
#else
|
||||||
|
extern void* _FUNC(memcpy)(void* s1, const void* s2, size_t n);
|
||||||
|
extern void* _FUNC(memset)(void* s, int c, size_t n);
|
||||||
|
extern void* _FUNC(memmove)(void* s1, const void* s2, size_t n);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Copy the character array s2 (including terminating '\0' byte) into the
|
/* Copy the character array s2 (including terminating '\0' byte) into the
|
||||||
character array s1.
|
character array s1.
|
||||||
@ -160,14 +163,6 @@ extern char* _FUNC(strstr)(const char * s1, const char * s2);
|
|||||||
*/
|
*/
|
||||||
extern char* _FUNC(strtok)(char* s1, const char* s2);
|
extern char* _FUNC(strtok)(char* s1, const char* s2);
|
||||||
|
|
||||||
/* Miscellaneous functions */
|
|
||||||
|
|
||||||
/* Write the character c (interpreted as unsigned char) to the first n
|
|
||||||
characters of the memory area pointed to by s.
|
|
||||||
Returns s.
|
|
||||||
*/
|
|
||||||
extern void* _FUNC(memset)(void* s, int c, size_t n);
|
|
||||||
|
|
||||||
/* Map an error number to a (locale-specific) error message string. Error
|
/* Map an error number to a (locale-specific) error message string. Error
|
||||||
numbers are typically errno values, but any number is mapped to a message.
|
numbers are typically errno values, but any number is mapped to a message.
|
||||||
TODO: PDCLib does not yet support locales.
|
TODO: PDCLib does not yet support locales.
|
||||||
|
@ -152,7 +152,7 @@ typedef struct{
|
|||||||
unsigned in_data_size;
|
unsigned in_data_size;
|
||||||
void* out_data_ptr;
|
void* out_data_ptr;
|
||||||
unsigned out_data_size;
|
unsigned out_data_size;
|
||||||
}ksys_drv_ctl_t;
|
}ksys_ioctl_t;
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
@ -1028,7 +1028,7 @@ ksys_drv_hand_t _ksys_load_pe_driver(char *driver_path, char *cmd_line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
unsigned _ksys_work_driver(ksys_drv_ctl_t *ioctl)
|
unsigned _ksys_work_driver(ksys_ioctl_t *ioctl)
|
||||||
{
|
{
|
||||||
unsigned status;
|
unsigned status;
|
||||||
asm_inline(
|
asm_inline(
|
||||||
|
Binary file not shown.
BIN
programs/develop/libraries/kolibri-libc/lib/libtcc.a
Normal file
BIN
programs/develop/libraries/kolibri-libc/lib/libtcc.a
Normal file
Binary file not shown.
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
KTCC=../../../ktcc/trunk/bin/kos32-tcc
|
KTCC=../../../ktcc/trunk/bin/kos32-tcc
|
||||||
|
FASM= fasm
|
||||||
KPACK = kpack
|
KPACK = kpack
|
||||||
CFLAGS = -I../include
|
CFLAGS = -I../include
|
||||||
LDFLAGS = -nostdlib -L../lib ../lib/crt0.o
|
LDFLAGS = -nostdlib -L../lib ../lib/crt0.o
|
||||||
@ -12,13 +13,16 @@ string_test.kex \
|
|||||||
whois.kex \
|
whois.kex \
|
||||||
file_io.kex \
|
file_io.kex \
|
||||||
tmpdisk_work.kex \
|
tmpdisk_work.kex \
|
||||||
exp_drv_work.kex
|
fasm/sprintf_test.kex
|
||||||
|
|
||||||
|
|
||||||
all: $(BIN)
|
all: $(BIN)
|
||||||
|
|
||||||
%.kex : %.c
|
%.kex : %.c
|
||||||
$(KTCC) $(CFLAGS) $(LDFLAGS) $< -o $@ -lnetwork -lc.obj
|
$(KTCC) $(CFLAGS) $(LDFLAGS) $< -o $@ -ltcc -lnetwork -lc.obj
|
||||||
|
$(KPACK) --nologo $@
|
||||||
|
|
||||||
|
%.kex : %.asm
|
||||||
|
$(FASM) $< $@
|
||||||
$(KPACK) --nologo $@
|
$(KPACK) --nologo $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@ -64,7 +64,7 @@ int main()
|
|||||||
ksys_pos_t mouse_pos;
|
ksys_pos_t mouse_pos;
|
||||||
strcpy(statusbar, "Program running...Double click on TEXT for details");
|
strcpy(statusbar, "Program running...Double click on TEXT for details");
|
||||||
|
|
||||||
_ksys_get_colors(&sys_color_table);
|
_ksys_get_system_colors(&sys_color_table);
|
||||||
_ksys_set_event_mask(0xC0000027); // mouse events only when focused window and mouse inside
|
_ksys_set_event_mask(0xC0000027); // mouse events only when focused window and mouse inside
|
||||||
|
|
||||||
do{
|
do{
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
format binary as "kex"
|
||||||
|
|
||||||
|
use32
|
||||||
|
org 0x0
|
||||||
|
db 'MENUET01'
|
||||||
|
dd 0x01
|
||||||
|
dd START
|
||||||
|
dd IM_END
|
||||||
|
dd MEM
|
||||||
|
dd MEM
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
|
||||||
|
include '../../../../../macros.inc'
|
||||||
|
include '../../../../../proc32.inc'
|
||||||
|
include '../../../../../KOSfuncs.inc'
|
||||||
|
include '../../../../../dll.inc'
|
||||||
|
;include '../../../../../debug-fdo.inc'
|
||||||
|
|
||||||
|
;__DEBUG__ = 1
|
||||||
|
;__DEBUG_LEVEL__ = 2
|
||||||
|
|
||||||
|
START:
|
||||||
|
stdcall dll.Load, @IMPORT
|
||||||
|
test eax, eax
|
||||||
|
jnz exit
|
||||||
|
|
||||||
|
cinvoke libc_strlen, test_str1
|
||||||
|
;DEBUGF 2, "%d", eax
|
||||||
|
mcall SF_SYS_MISC, SSF_MEM_ALLOC, eax
|
||||||
|
mov [test_str2], eax
|
||||||
|
|
||||||
|
cinvoke libc_sprintf, [test_str2], format_str, str_var, [dec_var], dword [float_var], dword[float_var+4], [hex_var]
|
||||||
|
cinvoke libc_puts, test_str1
|
||||||
|
cinvoke libc_puts, [test_str2]
|
||||||
|
|
||||||
|
cinvoke libc_strcmp, test_str1, [test_str2]
|
||||||
|
|
||||||
|
test eax, eax
|
||||||
|
jz print_succ
|
||||||
|
jmp print_fail
|
||||||
|
|
||||||
|
print_succ:
|
||||||
|
cinvoke libc_puts, success_msg
|
||||||
|
jmp exit
|
||||||
|
|
||||||
|
print_fail:
|
||||||
|
cinvoke libc_puts, failed_msg
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mcall SF_SYS_MISC, SSF_MEM_FREE, [test_str2]
|
||||||
|
mcall SF_TERMINATE_PROCESS
|
||||||
|
|
||||||
|
; data
|
||||||
|
|
||||||
|
format_str db "%s %d %f 0x%x", 0
|
||||||
|
test_str1 db "Test 463 -26.432100 0x9d81", 0
|
||||||
|
test_str2 dd 0
|
||||||
|
|
||||||
|
str_var db "Test",0
|
||||||
|
dec_var dd 463
|
||||||
|
float_var dq -26.4321
|
||||||
|
hex_var dd 40321
|
||||||
|
|
||||||
|
success_msg db "Test successful!", 0
|
||||||
|
failed_msg db "Test failed!", 0
|
||||||
|
|
||||||
|
align 4
|
||||||
|
|
||||||
|
@IMPORT:
|
||||||
|
library libc, 'libc.obj'
|
||||||
|
import libc, \
|
||||||
|
libc_sprintf, 'sprintf', \
|
||||||
|
libc_strcmp, 'strcmp', \
|
||||||
|
libc_strlen, 'strlen', \
|
||||||
|
libc_puts, 'puts'
|
||||||
|
|
||||||
|
IM_END:
|
||||||
|
align 4
|
||||||
|
rb 1024 ; stack
|
||||||
|
MEM:
|
@ -3,8 +3,11 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
char* test_string1 = "Hello world!";
|
char* test_string1 = "Hello world!";
|
||||||
|
int a, b;
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
|
sscanf("43 53","%d %d",&a, &b);
|
||||||
|
printf("(43 53) = (%d %d)\n", a, b);
|
||||||
printf("Hello world! = %s\n", test_string1);
|
printf("Hello world! = %s\n", test_string1);
|
||||||
printf("345.358980 = %f\n", 345.35898);
|
printf("345.358980 = %f\n", 345.35898);
|
||||||
printf("345 = %d\n", (int)345.35898);
|
printf("345 = %d\n", (int)345.35898);
|
||||||
|
@ -37,7 +37,7 @@ int main(){
|
|||||||
tmpdisk_add.disk_size = TMPDISK_SIZE*1024*1024/512;
|
tmpdisk_add.disk_size = TMPDISK_SIZE*1024*1024/512;
|
||||||
tmpdisk_add.disk_id = 5;
|
tmpdisk_add.disk_id = 5;
|
||||||
|
|
||||||
ksys_drv_ctl_t ioctl;
|
ksys_ioctl_t ioctl;
|
||||||
ioctl.func_num = DEV_ADD_DISK;
|
ioctl.func_num = DEV_ADD_DISK;
|
||||||
ioctl.handler = tmpdisk_drv;
|
ioctl.handler = tmpdisk_drv;
|
||||||
ioctl.in_data_ptr = &tmpdisk_add;
|
ioctl.in_data_ptr = &tmpdisk_add;
|
||||||
|
@ -19,9 +19,10 @@ all:
|
|||||||
$(KPACK) $(LIB)
|
$(KPACK) $(LIB)
|
||||||
../linuxtools/LoaderGen symbols.txt ../loader
|
../linuxtools/LoaderGen symbols.txt ../loader
|
||||||
../linuxtools/LoaderBuild ../loader
|
../linuxtools/LoaderBuild ../loader
|
||||||
|
$(MAKE) -C libtcc
|
||||||
rm -rf exports
|
rm -rf exports
|
||||||
install:
|
install:
|
||||||
cp -f ../lib/libc.obj ~/.kex/root/RD/1/LIB
|
cp -f ../lib/libc.obj ~/.kex/root/RD/1/LIB
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm ../lib/libc.obj
|
rm ../lib/*
|
||||||
|
@ -1 +0,0 @@
|
|||||||
__CPU_type fix p5
|
|
@ -4,11 +4,10 @@ public start
|
|||||||
public start as '_start'
|
public start as '_start'
|
||||||
;extrn mf_init
|
;extrn mf_init
|
||||||
extrn main
|
extrn main
|
||||||
;include 'debug2.inc'
|
include '../../../../../proc32.inc'
|
||||||
include 'proc32.inc'
|
include '../../../../../macros.inc'
|
||||||
include 'macros.inc'
|
include '../../../../../dll.inc'
|
||||||
include 'dll.inc'
|
;include '../../../../../debug.inc'
|
||||||
__DEBUG__=0
|
|
||||||
|
|
||||||
;start_:
|
;start_:
|
||||||
virtual at 0
|
virtual at 0
|
||||||
@ -151,9 +150,12 @@ load_imports:
|
|||||||
mov dword[ebx], eax
|
mov dword[ebx], eax
|
||||||
jmp .handle_next_import
|
jmp .handle_next_import
|
||||||
.done:
|
.done:
|
||||||
|
;DEBUGF 1, "Library: %s not loaded!\n", esi
|
||||||
|
;mcall -1
|
||||||
ret
|
ret
|
||||||
.fail:
|
.fail:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;==============================
|
;==============================
|
||||||
|
|
||||||
;==============================
|
;==============================
|
||||||
@ -201,37 +203,6 @@ load_library:
|
|||||||
mov eax, 0
|
mov eax, 0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; ==== memmove for tcc ======
|
|
||||||
|
|
||||||
proc memmove c, to:dword,from:dword,count:dword
|
|
||||||
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
mov ecx,[count]
|
|
||||||
test ecx,ecx
|
|
||||||
jz no_copy_block_
|
|
||||||
mov esi,[from]
|
|
||||||
mov edi,[to]
|
|
||||||
cmp esi, edi
|
|
||||||
je no_copy_block_
|
|
||||||
jg copy_
|
|
||||||
add esi, ecx
|
|
||||||
add edi, ecx
|
|
||||||
dec esi
|
|
||||||
dec edi
|
|
||||||
std
|
|
||||||
copy_:
|
|
||||||
rep movsb
|
|
||||||
cld
|
|
||||||
no_copy_block_:
|
|
||||||
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
mov eax,[to]
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
|
|
||||||
;==============================
|
;==============================
|
||||||
|
|
||||||
lib_init_str db 'lib_init', 0
|
lib_init_str db 'lib_init', 0
|
||||||
@ -239,7 +210,6 @@ lib_init_str db 'lib_init', 0
|
|||||||
public argc as '__argc'
|
public argc as '__argc'
|
||||||
public params as '__argv'
|
public params as '__argv'
|
||||||
public path as '__path'
|
public path as '__path'
|
||||||
public memmove
|
|
||||||
|
|
||||||
section '.bss'
|
section '.bss'
|
||||||
buf_len = 0x400
|
buf_len = 0x400
|
||||||
@ -249,5 +219,3 @@ argv rd max_parameters
|
|||||||
path rb buf_len
|
path rb buf_len
|
||||||
params rb buf_len
|
params rb buf_len
|
||||||
|
|
||||||
;section '.data'
|
|
||||||
;include_debug_strings ; ALWAYS present in data section
|
|
||||||
|
@ -1,193 +0,0 @@
|
|||||||
format ELF
|
|
||||||
section '.text' executable
|
|
||||||
public start
|
|
||||||
public start as '_start'
|
|
||||||
;extrn mf_init
|
|
||||||
extrn main
|
|
||||||
include '../../../../programs/proc32.inc'
|
|
||||||
;include 'debug2.inc'
|
|
||||||
__DEBUG__=0
|
|
||||||
|
|
||||||
;start_:
|
|
||||||
virtual at 0
|
|
||||||
db 'MENUET01' ; 1. Magic number (8 bytes)
|
|
||||||
dd 0x01 ; 2. Version of executable file
|
|
||||||
dd start ; 3. Start address
|
|
||||||
dd 0x0 ; 4. Size of image
|
|
||||||
dd 0x100000 ; 5. Size of needed memory
|
|
||||||
dd 0x100000 ; 6. Pointer to stack
|
|
||||||
hparams dd 0x0 ; 7. Pointer to program arguments
|
|
||||||
hpath dd 0x0 ; 8. Pointer to program path
|
|
||||||
end virtual
|
|
||||||
|
|
||||||
start:
|
|
||||||
;DEBUGF 'Start programm\n'
|
|
||||||
;init heap of memory
|
|
||||||
mov eax,68
|
|
||||||
mov ebx,11
|
|
||||||
int 0x40
|
|
||||||
|
|
||||||
;DEBUGF ' path "%s"\n params "%s"\n', .path, .params
|
|
||||||
; check for overflow
|
|
||||||
;; that not work
|
|
||||||
; mov al, [path+buf_len-1]
|
|
||||||
; or al, [params+buf_len-1]
|
|
||||||
; jnz .crash
|
|
||||||
; check if path written by OS
|
|
||||||
mov [argc], 0
|
|
||||||
mov eax, [hparams]
|
|
||||||
test eax, eax
|
|
||||||
jz .without_path
|
|
||||||
mov eax, path
|
|
||||||
cmp word ptr eax, 32fh ; '/#3' UTF8
|
|
||||||
jne .without_path
|
|
||||||
mov word ptr eax, 12fh ; '/#1' fix to CP866
|
|
||||||
.without_path:
|
|
||||||
mov esi, eax
|
|
||||||
call push_param
|
|
||||||
; retrieving parameters
|
|
||||||
mov esi, params
|
|
||||||
xor edx, edx ; dl - èä¸ò ïàðàìåòð(1) èëè ðàçäåëèòåëè(0)
|
|
||||||
; dh - ñèìâîë ñ êîòîðîãî íà÷àëñÿ ïàðàìåòð (1 êàâû÷êè, 0 îñòàëüíîå)
|
|
||||||
mov ecx, 1 ; cl = 1
|
|
||||||
; ch = 0 ïðîñòî íîëü
|
|
||||||
.parse:
|
|
||||||
lodsb
|
|
||||||
test al, al
|
|
||||||
jz .run
|
|
||||||
test dl, dl
|
|
||||||
jnz .findendparam
|
|
||||||
;{åñëè áûë ðàçäåëèòåëü
|
|
||||||
cmp al, ' '
|
|
||||||
jz .parse ;çàãðóæåí ïðîáåë, ãðóçèì ñëåäóþùèé ñèìâîë
|
|
||||||
mov dl, cl ;íà÷èíàåòñÿ ïàðàìåòð
|
|
||||||
cmp al, '"'
|
|
||||||
jz @f ;çàãðóæåíû êàâû÷êè
|
|
||||||
mov dh, ch ;ïàðàìåòð áåç êàâû÷åê
|
|
||||||
dec esi
|
|
||||||
call push_param
|
|
||||||
inc esi
|
|
||||||
jmp .parse
|
|
||||||
|
|
||||||
@@:
|
|
||||||
mov dh, cl ;ïàðàìåòð â êàâû÷åêàõ
|
|
||||||
call push_param ;åñëè íå ïðîáåë çíà÷èò íà÷èíàåòñÿ êàêîé òî ïàðàìåòð
|
|
||||||
jmp .parse ;åñëè áûë ðàçäåëèòåëü}
|
|
||||||
|
|
||||||
.findendparam:
|
|
||||||
test dh, dh
|
|
||||||
jz @f ; áåç êàâû÷åê
|
|
||||||
cmp al, '"'
|
|
||||||
jz .clear
|
|
||||||
jmp .parse
|
|
||||||
@@:
|
|
||||||
cmp al, ' '
|
|
||||||
jnz .parse
|
|
||||||
|
|
||||||
.clear:
|
|
||||||
lea ebx, [esi - 1]
|
|
||||||
mov [ebx], ch
|
|
||||||
mov dl, ch
|
|
||||||
jmp .parse
|
|
||||||
|
|
||||||
.run:
|
|
||||||
;DEBUGF 'call main(%x, %x) with params:\n', [argc], argv
|
|
||||||
if __DEBUG__ = 1
|
|
||||||
mov ecx, [argc]
|
|
||||||
@@:
|
|
||||||
lea esi, [ecx * 4 + argv-4]
|
|
||||||
DEBUGF '0x%x) "%s"\n', cx, [esi]
|
|
||||||
loop @b
|
|
||||||
end if
|
|
||||||
push argv
|
|
||||||
push [argc]
|
|
||||||
call main
|
|
||||||
.exit:
|
|
||||||
;DEBUGF 'Exit from prog\n';
|
|
||||||
xor eax,eax
|
|
||||||
dec eax
|
|
||||||
int 0x40
|
|
||||||
dd -1
|
|
||||||
.crash:
|
|
||||||
;DEBUGF 'E:buffer overflowed\n'
|
|
||||||
jmp .exit
|
|
||||||
;============================
|
|
||||||
push_param:
|
|
||||||
;============================
|
|
||||||
;parameters
|
|
||||||
; esi - pointer
|
|
||||||
;description
|
|
||||||
; procedure increase argc
|
|
||||||
; and add pointer to array argv
|
|
||||||
; procedure changes ebx
|
|
||||||
mov ebx, [argc]
|
|
||||||
cmp ebx, max_parameters
|
|
||||||
jae .dont_add
|
|
||||||
mov [argv+4*ebx], esi
|
|
||||||
inc [argc]
|
|
||||||
.dont_add:
|
|
||||||
ret
|
|
||||||
|
|
||||||
proc memcpy c, to:dword,from:dword,count:dword
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
mov ecx,[count]
|
|
||||||
test ecx,ecx
|
|
||||||
jz no_copy_block
|
|
||||||
mov esi,[from]
|
|
||||||
mov edi,[to]
|
|
||||||
cld
|
|
||||||
rep movsb
|
|
||||||
no_copy_block:
|
|
||||||
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
mov eax, [to]
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
proc memmove c, to:dword,from:dword,count:dword
|
|
||||||
|
|
||||||
push esi
|
|
||||||
push edi
|
|
||||||
mov ecx,[count]
|
|
||||||
test ecx,ecx
|
|
||||||
jz no_copy_block_
|
|
||||||
mov esi,[from]
|
|
||||||
mov edi,[to]
|
|
||||||
cmp esi, edi
|
|
||||||
je no_copy_block_
|
|
||||||
jg copy_
|
|
||||||
add esi, ecx
|
|
||||||
add edi, ecx
|
|
||||||
dec esi
|
|
||||||
dec edi
|
|
||||||
std
|
|
||||||
copy_:
|
|
||||||
rep movsb
|
|
||||||
cld
|
|
||||||
no_copy_block_:
|
|
||||||
|
|
||||||
pop edi
|
|
||||||
pop esi
|
|
||||||
mov eax,[to]
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
|
|
||||||
;==============================
|
|
||||||
public argc as '__argc'
|
|
||||||
public params as '__argv'
|
|
||||||
public path as '__path'
|
|
||||||
public memcpy
|
|
||||||
public memmove
|
|
||||||
|
|
||||||
section '.bss'
|
|
||||||
buf_len = 0x400
|
|
||||||
max_parameters=0x20
|
|
||||||
argc rd 1
|
|
||||||
argv rd max_parameters
|
|
||||||
path rb buf_len
|
|
||||||
params rb buf_len
|
|
||||||
|
|
||||||
;section '.data'
|
|
||||||
;include_debug_strings ; ALWAYS present in data section
|
|
@ -1,158 +0,0 @@
|
|||||||
;-----------------------------------------------------------------------------
|
|
||||||
; load one or more DLL file in COFF format and try to import functions by our list
|
|
||||||
; if first function in import list begins with 'lib_', call it as DLL initialization
|
|
||||||
; return eax = 1 as fail, if anyone of .obj file not found in /sys/lib
|
|
||||||
; return 0 if all fine, but 0 not garantees in succesfull import - see dll.Link comment
|
|
||||||
; dirties all registers! eax, ebx, ecx, edx, esi, edi
|
|
||||||
proc dll.Load, import_table:dword
|
|
||||||
mov esi, [import_table]
|
|
||||||
.next_lib:
|
|
||||||
mov edx, [esi]
|
|
||||||
or edx, edx
|
|
||||||
jz .exit
|
|
||||||
push esi
|
|
||||||
mov esi, [esi + 4]
|
|
||||||
mov edi, s_libdir.fname
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
stosb
|
|
||||||
or al, al
|
|
||||||
jnz @b
|
|
||||||
mcall 68, 19, s_libdir
|
|
||||||
or eax, eax
|
|
||||||
jz .fail
|
|
||||||
stdcall dll.Link, eax, edx
|
|
||||||
push eax
|
|
||||||
mov eax, [eax]
|
|
||||||
cmp dword[eax], 'lib_'
|
|
||||||
pop eax
|
|
||||||
jnz @f
|
|
||||||
stdcall dll.Init, [eax + 4]
|
|
||||||
@@:
|
|
||||||
pop esi
|
|
||||||
add esi, 8
|
|
||||||
jmp .next_lib
|
|
||||||
.exit:
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
.fail:
|
|
||||||
add esp, 4
|
|
||||||
xor eax, eax
|
|
||||||
inc eax
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
; scans dll export table for a functions we want to import
|
|
||||||
; break scan on first unresolved import
|
|
||||||
; no return value
|
|
||||||
proc dll.Link, exp:dword, imp:dword
|
|
||||||
push eax
|
|
||||||
mov esi, [imp]
|
|
||||||
test esi, esi
|
|
||||||
jz .done
|
|
||||||
.next:
|
|
||||||
lodsd
|
|
||||||
test eax, eax
|
|
||||||
jz .done
|
|
||||||
stdcall dll.GetProcAddress, [exp], eax
|
|
||||||
or eax, eax
|
|
||||||
jz @f
|
|
||||||
mov [esi - 4], eax
|
|
||||||
jmp .next
|
|
||||||
@@:
|
|
||||||
mov dword[esp], 0
|
|
||||||
.done:
|
|
||||||
pop eax
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
; calls lib_init with predefined parameters
|
|
||||||
; no return value
|
|
||||||
proc dll.Init, dllentry:dword
|
|
||||||
pushad
|
|
||||||
mov eax, mem.Alloc
|
|
||||||
mov ebx, mem.Free
|
|
||||||
mov ecx, mem.ReAlloc
|
|
||||||
mov edx, dll.Load
|
|
||||||
stdcall [dllentry]
|
|
||||||
popad
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
; scans export table for a sz_name function
|
|
||||||
; returns in eax function address or 0 if not found
|
|
||||||
proc dll.GetProcAddress, exp:dword, sz_name:dword
|
|
||||||
mov edx, [exp]
|
|
||||||
xor eax, eax
|
|
||||||
.next:
|
|
||||||
or edx, edx
|
|
||||||
jz .end
|
|
||||||
cmp dword[edx], 0
|
|
||||||
jz .end
|
|
||||||
stdcall strcmp, [edx], [sz_name]
|
|
||||||
test eax, eax
|
|
||||||
jz .ok
|
|
||||||
add edx, 8
|
|
||||||
jmp .next
|
|
||||||
.ok:
|
|
||||||
mov eax, [edx + 4]
|
|
||||||
.end:
|
|
||||||
cmp eax, -1
|
|
||||||
jnz @f
|
|
||||||
xor eax, eax
|
|
||||||
@@:
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
; compares strings
|
|
||||||
; returns eax = 0 if equal, -1 otherwise
|
|
||||||
proc strcmp, str1:dword, str2:dword
|
|
||||||
push esi edi
|
|
||||||
mov esi, [str1]
|
|
||||||
mov edi, [str2]
|
|
||||||
xor eax, eax
|
|
||||||
@@:
|
|
||||||
lodsb
|
|
||||||
scasb
|
|
||||||
jne .fail
|
|
||||||
or al, al
|
|
||||||
jnz @b
|
|
||||||
jmp .ok
|
|
||||||
.fail:
|
|
||||||
or eax, -1
|
|
||||||
.ok:
|
|
||||||
pop edi esi
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
if defined dll.Load
|
|
||||||
s_libdir:
|
|
||||||
db '/sys/lib/'
|
|
||||||
.fname rb 32
|
|
||||||
end if
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
proc mem.Alloc, size
|
|
||||||
push ebx ecx
|
|
||||||
mov ecx, [size]
|
|
||||||
mcall 68, 12
|
|
||||||
pop ecx ebx
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
proc mem.ReAlloc, mptr, size
|
|
||||||
push ebx ecx edx
|
|
||||||
mov ecx, [size]
|
|
||||||
mov edx, [mptr]
|
|
||||||
mcall 68, 20
|
|
||||||
pop edx ecx ebx
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
;-----------------------------------------------------------------------------
|
|
||||||
proc mem.Free, mptr
|
|
||||||
push ebx ecx
|
|
||||||
mov ecx,[mptr]
|
|
||||||
mcall 68, 13
|
|
||||||
pop ecx ebx
|
|
||||||
ret
|
|
||||||
endp
|
|
||||||
;-----------------------------------------------------------------------------
|
|
@ -1,597 +0,0 @@
|
|||||||
@^ fix macro comment {
|
|
||||||
^@ fix }
|
|
||||||
|
|
||||||
; --------------------------
|
|
||||||
macro library [lname,fname]
|
|
||||||
{
|
|
||||||
forward
|
|
||||||
dd __#lname#_library_table__,__#lname#_library_name__
|
|
||||||
common
|
|
||||||
dd 0
|
|
||||||
forward
|
|
||||||
align 4
|
|
||||||
__#lname#_library_name__ db fname,0
|
|
||||||
}
|
|
||||||
|
|
||||||
macro import lname,[name,sname]
|
|
||||||
{
|
|
||||||
common
|
|
||||||
align 4
|
|
||||||
__#lname#_library_table__:
|
|
||||||
forward
|
|
||||||
if used name
|
|
||||||
name dd __#name#_import_name__
|
|
||||||
end if
|
|
||||||
common
|
|
||||||
dd 0
|
|
||||||
forward
|
|
||||||
if used name
|
|
||||||
align 4
|
|
||||||
__#name#_import_name__ db sname,0
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro export [name,sname]
|
|
||||||
{
|
|
||||||
forward
|
|
||||||
dd __#name#_export_name__,name
|
|
||||||
common
|
|
||||||
dd 0
|
|
||||||
forward
|
|
||||||
align 4
|
|
||||||
__#name#_export_name__ db sname,0
|
|
||||||
}
|
|
||||||
; -------------------------
|
|
||||||
|
|
||||||
macro m2m dest,src {
|
|
||||||
push src
|
|
||||||
pop dest
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
macro iglobal {
|
|
||||||
IGlobals equ IGlobals,
|
|
||||||
macro __IGlobalBlock { }
|
|
||||||
|
|
||||||
macro uglobal {
|
|
||||||
UGlobals equ UGlobals,
|
|
||||||
macro __UGlobalBlock { }
|
|
||||||
|
|
||||||
endg fix } ; Use endg for ending iglobal and uglobal blocks.
|
|
||||||
|
|
||||||
|
|
||||||
macro IncludeIGlobals{
|
|
||||||
macro IGlobals dummy,[n] \{ __IGlobalBlock
|
|
||||||
purge __IGlobalBlock \}
|
|
||||||
match I, IGlobals \{ I \} }
|
|
||||||
|
|
||||||
macro IncludeUGlobals{
|
|
||||||
macro UGlobals dummy,[n] \{
|
|
||||||
\common
|
|
||||||
\local begin, size
|
|
||||||
begin = $
|
|
||||||
virtual at $
|
|
||||||
\forward
|
|
||||||
__UGlobalBlock
|
|
||||||
purge __UGlobalBlock
|
|
||||||
\common
|
|
||||||
size = $ - begin
|
|
||||||
end virtual
|
|
||||||
rb size
|
|
||||||
\}
|
|
||||||
match U, UGlobals \{ U \} }
|
|
||||||
|
|
||||||
uglobal
|
|
||||||
endg
|
|
||||||
|
|
||||||
iglobal
|
|
||||||
endg
|
|
||||||
|
|
||||||
|
|
||||||
; new application structure
|
|
||||||
macro meos_app_start
|
|
||||||
{
|
|
||||||
use32
|
|
||||||
org 0x0
|
|
||||||
|
|
||||||
db 'MENUET01'
|
|
||||||
dd 0x01
|
|
||||||
dd __start
|
|
||||||
dd __end
|
|
||||||
dd __memory
|
|
||||||
dd __stack
|
|
||||||
|
|
||||||
if used __params & ~defined __params
|
|
||||||
dd __params
|
|
||||||
else
|
|
||||||
dd 0x0
|
|
||||||
end if
|
|
||||||
|
|
||||||
dd 0x0
|
|
||||||
}
|
|
||||||
MEOS_APP_START fix meos_app_start
|
|
||||||
KOS_APP_START fix meos_app_start
|
|
||||||
|
|
||||||
macro code
|
|
||||||
{
|
|
||||||
__start:
|
|
||||||
}
|
|
||||||
CODE fix code
|
|
||||||
|
|
||||||
macro data
|
|
||||||
{
|
|
||||||
__data:
|
|
||||||
IncludeIGlobals
|
|
||||||
}
|
|
||||||
DATA fix data
|
|
||||||
|
|
||||||
macro udata
|
|
||||||
{
|
|
||||||
if used __params & ~defined __params
|
|
||||||
__params:
|
|
||||||
db 0
|
|
||||||
__end:
|
|
||||||
rb 255
|
|
||||||
else
|
|
||||||
__end:
|
|
||||||
end if
|
|
||||||
__udata:
|
|
||||||
IncludeUGlobals
|
|
||||||
}
|
|
||||||
UDATA fix udata
|
|
||||||
|
|
||||||
macro meos_app_end
|
|
||||||
{
|
|
||||||
align 32
|
|
||||||
rb 2048
|
|
||||||
__stack:
|
|
||||||
__memory:
|
|
||||||
}
|
|
||||||
MEOS_APP_END fix meos_app_end
|
|
||||||
KOS_APP_END fix meos_app_end
|
|
||||||
|
|
||||||
|
|
||||||
; macro for defining multiline text data
|
|
||||||
struc mstr [sstring]
|
|
||||||
{
|
|
||||||
forward
|
|
||||||
local ssize
|
|
||||||
virtual at 0
|
|
||||||
db sstring
|
|
||||||
ssize = $
|
|
||||||
end virtual
|
|
||||||
dd ssize
|
|
||||||
db sstring
|
|
||||||
common
|
|
||||||
dd -1
|
|
||||||
}
|
|
||||||
|
|
||||||
; macro for defining multiline text data
|
|
||||||
struc mls [sstring]
|
|
||||||
{
|
|
||||||
forward
|
|
||||||
local ssize
|
|
||||||
virtual at 0
|
|
||||||
db sstring ; mod
|
|
||||||
ssize = $
|
|
||||||
end virtual
|
|
||||||
db ssize
|
|
||||||
db sstring
|
|
||||||
common
|
|
||||||
db -1 ; mod
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; strings
|
|
||||||
macro sz name,[data] { ; [mike.dld]
|
|
||||||
common
|
|
||||||
if used name
|
|
||||||
name db data
|
|
||||||
.size = $-name
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro szZ name,[data] { ; same as sz, but for zero terminated string [dunkaist]
|
|
||||||
common
|
|
||||||
if used name
|
|
||||||
name db data,0
|
|
||||||
.size = $-name-1
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
sz0 fix szZ
|
|
||||||
|
|
||||||
macro lsz name,[lng,data] { ; [mike.dld]
|
|
||||||
common
|
|
||||||
if used name
|
|
||||||
label name
|
|
||||||
forward
|
|
||||||
if lang eq lng
|
|
||||||
db data
|
|
||||||
end if
|
|
||||||
common
|
|
||||||
.size = $-name
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro szc name,elsz,[data] { ; [mike.dld]
|
|
||||||
common
|
|
||||||
local s,m
|
|
||||||
m = 0
|
|
||||||
if used name
|
|
||||||
label name
|
|
||||||
forward
|
|
||||||
virtual at 0
|
|
||||||
db data
|
|
||||||
s = $
|
|
||||||
end virtual
|
|
||||||
d#elsz s
|
|
||||||
if m < s
|
|
||||||
m = s
|
|
||||||
end if
|
|
||||||
db data
|
|
||||||
common
|
|
||||||
.size = $-name
|
|
||||||
.maxl = m
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro lszc name,elsz,[lng,data] { ; [mike.dld]
|
|
||||||
common
|
|
||||||
local s,m,c
|
|
||||||
m = 0
|
|
||||||
c = 0
|
|
||||||
if used name
|
|
||||||
label name
|
|
||||||
forward
|
|
||||||
if lang eq lng
|
|
||||||
virtual at 0
|
|
||||||
db data
|
|
||||||
s = $
|
|
||||||
end virtual
|
|
||||||
d#elsz s
|
|
||||||
if m < s
|
|
||||||
m = s
|
|
||||||
end if
|
|
||||||
db data
|
|
||||||
c = c+1
|
|
||||||
end if
|
|
||||||
common
|
|
||||||
.size = $-name
|
|
||||||
.maxl = m
|
|
||||||
.count = c
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
; easy system call macro
|
|
||||||
macro mpack dest, hsrc, lsrc
|
|
||||||
{
|
|
||||||
if (hsrc eqtype 0) & (lsrc eqtype 0)
|
|
||||||
mov dest, (hsrc) shl 16 + lsrc
|
|
||||||
else
|
|
||||||
if (hsrc eqtype 0) & (~lsrc eqtype 0)
|
|
||||||
mov dest, (hsrc) shl 16
|
|
||||||
add dest, lsrc
|
|
||||||
else
|
|
||||||
mov dest, hsrc
|
|
||||||
shl dest, 16
|
|
||||||
add dest, lsrc
|
|
||||||
end if
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro __mov reg,a,b { ; mike.dld
|
|
||||||
if (~a eq)&(~b eq)
|
|
||||||
mpack reg,a,b
|
|
||||||
else if (~a eq)&(b eq)
|
|
||||||
mov reg,a
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
include 'config.inc'
|
|
||||||
;__CPU_type equ p5
|
|
||||||
SYSENTER_VAR equ 0
|
|
||||||
|
|
||||||
macro mcall a,b,c,d,e,f,g { ; [mike.dld], [Ghost]
|
|
||||||
local ..ret_point
|
|
||||||
__mov eax,a
|
|
||||||
__mov ebx,b
|
|
||||||
__mov ecx,c
|
|
||||||
__mov edx,d
|
|
||||||
__mov esi,e
|
|
||||||
__mov edi,f
|
|
||||||
__mov ebp,g
|
|
||||||
|
|
||||||
if __CPU_type eq p5
|
|
||||||
int 0x40
|
|
||||||
else
|
|
||||||
if __CPU_type eq p6
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
push ..ret_point ; it may be 2 or 5 byte
|
|
||||||
sysenter
|
|
||||||
..ret_point:
|
|
||||||
pop edx
|
|
||||||
pop ecx
|
|
||||||
|
|
||||||
else
|
|
||||||
if __CPU_type eq k6
|
|
||||||
push ecx
|
|
||||||
syscall
|
|
||||||
pop ecx
|
|
||||||
else
|
|
||||||
display 'ERROR : unknown CPU type (set to p5)', 10, 13
|
|
||||||
__CPU_type equ p5
|
|
||||||
int 0x40
|
|
||||||
end if
|
|
||||||
end if
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
; -------------------------
|
|
||||||
macro __header a,[b] {
|
|
||||||
common
|
|
||||||
use32
|
|
||||||
org 0
|
|
||||||
db 'MENUET',a
|
|
||||||
forward
|
|
||||||
if b eq
|
|
||||||
dd 0
|
|
||||||
else
|
|
||||||
dd b
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro __section name {
|
|
||||||
align 16
|
|
||||||
label name
|
|
||||||
}
|
|
||||||
|
|
||||||
macro __func name {
|
|
||||||
if ~used name
|
|
||||||
display 'FUNC NOT USED: ',`name,13,10
|
|
||||||
else
|
|
||||||
align 4
|
|
||||||
name:
|
|
||||||
;diff16 `name,0,name
|
|
||||||
}
|
|
||||||
|
|
||||||
macro endf { end if }
|
|
||||||
|
|
||||||
macro diff16 title,l1,l2
|
|
||||||
{
|
|
||||||
local s,d
|
|
||||||
s = l2-l1
|
|
||||||
display title,': 0x'
|
|
||||||
repeat 8
|
|
||||||
d = '0' + s shr ((8-%) shl 2) and $0F
|
|
||||||
if d > '9'
|
|
||||||
d = d + 'A'-'9'-1
|
|
||||||
end if
|
|
||||||
display d
|
|
||||||
end repeat
|
|
||||||
display 13,10
|
|
||||||
}
|
|
||||||
|
|
||||||
macro diff10 title,l1,l2
|
|
||||||
{
|
|
||||||
local s,d,z,m
|
|
||||||
s = l2-l1
|
|
||||||
z = 0
|
|
||||||
m = 1000000000
|
|
||||||
display title,': '
|
|
||||||
repeat 10
|
|
||||||
d = '0' + s / m
|
|
||||||
s = s - (s/m)*m
|
|
||||||
m = m / 10
|
|
||||||
if d <> '0'
|
|
||||||
z = 1
|
|
||||||
end if
|
|
||||||
if z <> 0
|
|
||||||
display d
|
|
||||||
end if
|
|
||||||
end repeat
|
|
||||||
display 13,10
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
macro movi arg1,arg2
|
|
||||||
{
|
|
||||||
if (arg1 in <eax,ebx,ecx,edx,esi,edi,ebp,esp>) & ((arg2 eqtype 0) | (arg2 eqtype '0'))
|
|
||||||
if (arg2) = 0
|
|
||||||
xor arg1,arg1
|
|
||||||
else if (arg2) = 1
|
|
||||||
xor arg1,arg1
|
|
||||||
inc arg1
|
|
||||||
else if (arg2) = -1
|
|
||||||
or arg1,-1
|
|
||||||
else if (arg2) >= -128 & (arg2) <= 127
|
|
||||||
push arg2
|
|
||||||
pop arg1
|
|
||||||
else
|
|
||||||
mov arg1,arg2
|
|
||||||
end if
|
|
||||||
else
|
|
||||||
mov arg1,arg2
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
macro RGB [a] {
|
|
||||||
common
|
|
||||||
match (r=,g=,b),a \{
|
|
||||||
\dd ((r) shl 16) or ((g) shl 8) or (b)
|
|
||||||
\}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struc POINT _t,_dx,_dy {
|
|
||||||
.x _t _dx
|
|
||||||
.y _t _dy
|
|
||||||
}
|
|
||||||
|
|
||||||
; structure definition helper
|
|
||||||
include 'struct.inc'
|
|
||||||
|
|
||||||
struct RECT
|
|
||||||
left dd ?
|
|
||||||
top dd ?
|
|
||||||
right dd ?
|
|
||||||
bottom dd ?
|
|
||||||
ends
|
|
||||||
|
|
||||||
struct BOX
|
|
||||||
left dd ?
|
|
||||||
top dd ?
|
|
||||||
width dd ?
|
|
||||||
height dd ?
|
|
||||||
ends
|
|
||||||
|
|
||||||
; structures used in KolibriOS
|
|
||||||
struct process_information
|
|
||||||
cpu_usage dd ? ; +0
|
|
||||||
window_stack_position dw ? ; +4
|
|
||||||
window_stack_value dw ? ; +6
|
|
||||||
dw ? ; +8
|
|
||||||
process_name rb 12 ; +10
|
|
||||||
memory_start dd ? ; +22
|
|
||||||
used_memory dd ? ; +26
|
|
||||||
PID dd ? ; +30
|
|
||||||
box BOX ; +34
|
|
||||||
slot_state dw ? ; +50
|
|
||||||
dw ? ; +52
|
|
||||||
client_box BOX ; +54
|
|
||||||
wnd_state db ? ; +70
|
|
||||||
rb (1024-71)
|
|
||||||
ends
|
|
||||||
|
|
||||||
struct system_colors
|
|
||||||
frame dd ? ;nonset1
|
|
||||||
grab dd ? ;nonset2
|
|
||||||
work_dark dd ?
|
|
||||||
work_light dd ?
|
|
||||||
grab_text dd ? ;window_title
|
|
||||||
work dd ?
|
|
||||||
work_button dd ?
|
|
||||||
work_button_text dd ?
|
|
||||||
work_text dd ?
|
|
||||||
work_graph dd ?
|
|
||||||
ends
|
|
||||||
|
|
||||||
struct FILEDATE
|
|
||||||
Second db ?
|
|
||||||
Minute db ?
|
|
||||||
Hour db ?
|
|
||||||
db ?
|
|
||||||
Day db ?
|
|
||||||
Month db ?
|
|
||||||
Year dw ?
|
|
||||||
ends
|
|
||||||
|
|
||||||
struct FILEINFO
|
|
||||||
Attributes dd ?
|
|
||||||
IsUnicode db ?
|
|
||||||
db 3 dup(?)
|
|
||||||
DateCreate FILEDATE
|
|
||||||
DateAccess FILEDATE
|
|
||||||
DateModify FILEDATE
|
|
||||||
Size dq ?
|
|
||||||
ends
|
|
||||||
|
|
||||||
cmove fix cmovz
|
|
||||||
|
|
||||||
macro cmovz reg1, reg2 {
|
|
||||||
|
|
||||||
local ..jumpaddr
|
|
||||||
|
|
||||||
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
|
|
||||||
jnz ..jumpaddr
|
|
||||||
mov reg1, reg2
|
|
||||||
..jumpaddr:
|
|
||||||
else
|
|
||||||
cmovz reg1, reg2
|
|
||||||
end if
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
cmovne fix cmovnz
|
|
||||||
|
|
||||||
macro cmovnz reg1, reg2 {
|
|
||||||
|
|
||||||
local ..jumpaddr
|
|
||||||
|
|
||||||
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
|
|
||||||
jz ..jumpaddr
|
|
||||||
mov reg1, reg2
|
|
||||||
..jumpaddr:
|
|
||||||
else
|
|
||||||
cmovnz reg1, reg2
|
|
||||||
end if
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
macro cmovg reg1, reg2 {
|
|
||||||
|
|
||||||
local ..jumpaddr
|
|
||||||
|
|
||||||
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
|
|
||||||
jle ..jumpaddr
|
|
||||||
mov reg1, reg2
|
|
||||||
..jumpaddr:
|
|
||||||
else
|
|
||||||
cmovg reg1, reg2
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
macro cmovl reg1, reg2 {
|
|
||||||
|
|
||||||
local ..jumpaddr
|
|
||||||
|
|
||||||
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
|
|
||||||
jge ..jumpaddr
|
|
||||||
mov reg1, reg2
|
|
||||||
..jumpaddr:
|
|
||||||
else
|
|
||||||
cmovl reg1, reg2
|
|
||||||
end if
|
|
||||||
}
|
|
||||||
|
|
||||||
; replaces /programs/cmp.inc
|
|
||||||
irp cond, e, ne, g, ng, l, nl, ge, le {
|
|
||||||
macro cmp#cond a, b, c\{
|
|
||||||
cmp a, b
|
|
||||||
j#cond c
|
|
||||||
\}
|
|
||||||
}
|
|
||||||
|
|
||||||
; constants
|
|
||||||
|
|
||||||
; events
|
|
||||||
EV_IDLE = 0
|
|
||||||
EV_TIMER = 0
|
|
||||||
EV_REDRAW = 1
|
|
||||||
EV_KEY = 2
|
|
||||||
EV_BUTTON = 3
|
|
||||||
EV_EXIT = 4
|
|
||||||
EV_BACKGROUND = 5
|
|
||||||
EV_MOUSE = 6
|
|
||||||
EV_IPC = 7
|
|
||||||
EV_STACK = 8
|
|
||||||
|
|
||||||
; event mask bits for function 40
|
|
||||||
EVM_REDRAW = 1b
|
|
||||||
EVM_KEY = 10b
|
|
||||||
EVM_BUTTON = 100b
|
|
||||||
EVM_EXIT = 1000b
|
|
||||||
EVM_BACKGROUND = 10000b
|
|
||||||
EVM_MOUSE = 100000b
|
|
||||||
EVM_IPC = 1000000b
|
|
||||||
EVM_STACK = 10000000b
|
|
||||||
EVM_DEBUG = 100000000b
|
|
||||||
EVM_STACK2 = 1000000000b
|
|
||||||
|
|
||||||
EVM_MOUSE_FILTER = 0x80000000
|
|
||||||
EVM_CURSOR_FILTER = 0x40000000
|
|
@ -1,301 +0,0 @@
|
|||||||
|
|
||||||
; Macroinstructions for defining and calling procedures
|
|
||||||
|
|
||||||
macro stdcall proc,[arg] ; directly call STDCALL procedure
|
|
||||||
{ common
|
|
||||||
if ~ arg eq
|
|
||||||
reverse
|
|
||||||
pushd arg
|
|
||||||
common
|
|
||||||
end if
|
|
||||||
call proc }
|
|
||||||
|
|
||||||
macro invoke proc,[arg] ; indirectly call STDCALL procedure
|
|
||||||
{ common
|
|
||||||
if ~ arg eq
|
|
||||||
reverse
|
|
||||||
pushd arg
|
|
||||||
common
|
|
||||||
end if
|
|
||||||
call [proc] }
|
|
||||||
|
|
||||||
macro ccall proc,[arg] ; directly call CDECL procedure
|
|
||||||
{ common
|
|
||||||
size@ccall = 0
|
|
||||||
if ~ arg eq
|
|
||||||
reverse
|
|
||||||
pushd arg
|
|
||||||
size@ccall = size@ccall+4
|
|
||||||
common
|
|
||||||
end if
|
|
||||||
call proc
|
|
||||||
if size@ccall
|
|
||||||
add esp,size@ccall
|
|
||||||
end if }
|
|
||||||
|
|
||||||
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
|
|
||||||
{ common
|
|
||||||
size@ccall = 0
|
|
||||||
if ~ arg eq
|
|
||||||
reverse
|
|
||||||
pushd arg
|
|
||||||
size@ccall = size@ccall+4
|
|
||||||
common
|
|
||||||
end if
|
|
||||||
call [proc]
|
|
||||||
if size@ccall
|
|
||||||
add esp,size@ccall
|
|
||||||
end if }
|
|
||||||
|
|
||||||
macro proc [args] ; define procedure
|
|
||||||
{ common
|
|
||||||
match name params, args>
|
|
||||||
\{ define@proc name,<params \} }
|
|
||||||
|
|
||||||
prologue@proc equ prologuedef
|
|
||||||
|
|
||||||
macro prologuedef procname,flag,parmbytes,localbytes,reglist
|
|
||||||
{ local loc
|
|
||||||
loc = (localbytes+3) and (not 3)
|
|
||||||
parmbase@proc equ ebp+8
|
|
||||||
localbase@proc equ ebp-loc
|
|
||||||
if parmbytes | localbytes
|
|
||||||
push ebp
|
|
||||||
mov ebp,esp
|
|
||||||
if localbytes
|
|
||||||
sub esp,loc
|
|
||||||
end if
|
|
||||||
end if
|
|
||||||
irps reg, reglist \{ push reg \} }
|
|
||||||
|
|
||||||
epilogue@proc equ epiloguedef
|
|
||||||
|
|
||||||
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
|
|
||||||
{ irps reg, reglist \{ reverse pop reg \}
|
|
||||||
if parmbytes | localbytes
|
|
||||||
leave
|
|
||||||
end if
|
|
||||||
if flag and 10000b
|
|
||||||
retn
|
|
||||||
else
|
|
||||||
retn parmbytes
|
|
||||||
end if }
|
|
||||||
|
|
||||||
close@proc equ
|
|
||||||
|
|
||||||
macro define@proc name,statement
|
|
||||||
{ local params,flag,regs,parmbytes,localbytes,current
|
|
||||||
if used name
|
|
||||||
name:
|
|
||||||
match =stdcall args, statement \{ params equ args
|
|
||||||
flag = 11b \}
|
|
||||||
match =stdcall, statement \{ params equ
|
|
||||||
flag = 11b \}
|
|
||||||
match =c args, statement \{ params equ args
|
|
||||||
flag = 10001b \}
|
|
||||||
match =c, statement \{ params equ
|
|
||||||
flag = 10001b \}
|
|
||||||
match =params, params \{ params equ statement
|
|
||||||
flag = 0 \}
|
|
||||||
match =uses reglist=,args, params \{ regs equ reglist
|
|
||||||
params equ args \}
|
|
||||||
match =regs =uses reglist, regs params \{ regs equ reglist
|
|
||||||
params equ \}
|
|
||||||
match =regs, regs \{ regs equ \}
|
|
||||||
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
|
|
||||||
virtual at parmbase@proc
|
|
||||||
match =,args, params \{ defargs@proc args \}
|
|
||||||
match =args@proc args, args@proc params \{ defargs@proc args \}
|
|
||||||
parmbytes = $-(parmbase@proc)
|
|
||||||
end virtual
|
|
||||||
name # % = parmbytes/4
|
|
||||||
all@vars equ
|
|
||||||
current = 0
|
|
||||||
macro locals
|
|
||||||
\{ virtual at localbase@proc+current
|
|
||||||
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
|
|
||||||
struc db [val] \\{ \common deflocal@proc .,db,val \\}
|
|
||||||
struc du [val] \\{ \common deflocal@proc .,du,val \\}
|
|
||||||
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
|
|
||||||
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
|
|
||||||
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
|
|
||||||
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
|
|
||||||
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
|
|
||||||
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
|
|
||||||
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
|
|
||||||
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
|
|
||||||
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
|
|
||||||
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
|
|
||||||
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
|
|
||||||
macro endl
|
|
||||||
\{ purge label
|
|
||||||
restruc db,du,dw,dp,dd,dt,dq
|
|
||||||
restruc rb,rw,rp,rd,rt,rq
|
|
||||||
current = $-(localbase@proc)
|
|
||||||
end virtual \}
|
|
||||||
macro ret operand
|
|
||||||
\{ match any, operand \\{ retn operand \\}
|
|
||||||
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
|
|
||||||
macro finish@proc
|
|
||||||
\{ localbytes = current
|
|
||||||
match close:reglist, close@proc:<regs> \\{ close name,flag,parmbytes,localbytes,reglist \\}
|
|
||||||
end if \} }
|
|
||||||
|
|
||||||
macro defargs@proc [arg]
|
|
||||||
{ common
|
|
||||||
if ~ arg eq
|
|
||||||
forward
|
|
||||||
local ..arg,current@arg
|
|
||||||
match argname:type, arg
|
|
||||||
\{ current@arg equ argname
|
|
||||||
label ..arg type
|
|
||||||
argname equ ..arg
|
|
||||||
if qqword eq type
|
|
||||||
dd ?,?,?,?,?,?,?,?
|
|
||||||
else if dqword eq type
|
|
||||||
dd ?,?,?,?
|
|
||||||
else if tbyte eq type
|
|
||||||
dd ?,?,?
|
|
||||||
else if qword eq type | pword eq type
|
|
||||||
dd ?,?
|
|
||||||
else
|
|
||||||
dd ?
|
|
||||||
end if \}
|
|
||||||
match =current@arg,current@arg
|
|
||||||
\{ current@arg equ arg
|
|
||||||
arg equ ..arg
|
|
||||||
..arg dd ? \}
|
|
||||||
common
|
|
||||||
args@proc equ current@arg
|
|
||||||
forward
|
|
||||||
restore current@arg
|
|
||||||
common
|
|
||||||
end if }
|
|
||||||
|
|
||||||
macro deflocal@proc name,def,[val] { name def val }
|
|
||||||
|
|
||||||
macro deflocal@proc name,def,[val]
|
|
||||||
{ common
|
|
||||||
match vars, all@vars \{ all@vars equ all@vars, \}
|
|
||||||
all@vars equ all@vars name
|
|
||||||
forward
|
|
||||||
local ..var,..tmp
|
|
||||||
..var def val
|
|
||||||
match =?, val \{ ..tmp equ \}
|
|
||||||
match any =?, val \{ ..tmp equ \}
|
|
||||||
match any (=?), val \{ ..tmp equ \}
|
|
||||||
match =label, def \{ ..tmp equ \}
|
|
||||||
match tmp : value, ..tmp : val
|
|
||||||
\{ tmp: end virtual
|
|
||||||
initlocal@proc ..var,def value
|
|
||||||
virtual at tmp\}
|
|
||||||
common
|
|
||||||
match first rest, ..var, \{ name equ first \} }
|
|
||||||
|
|
||||||
struc label type { label . type }
|
|
||||||
|
|
||||||
macro initlocal@proc name,def
|
|
||||||
{ virtual at name
|
|
||||||
def
|
|
||||||
size@initlocal = $ - name
|
|
||||||
end virtual
|
|
||||||
position@initlocal = 0
|
|
||||||
while size@initlocal > position@initlocal
|
|
||||||
virtual at name
|
|
||||||
def
|
|
||||||
if size@initlocal - position@initlocal < 2
|
|
||||||
current@initlocal = 1
|
|
||||||
load byte@initlocal byte from name+position@initlocal
|
|
||||||
else if size@initlocal - position@initlocal < 4
|
|
||||||
current@initlocal = 2
|
|
||||||
load word@initlocal word from name+position@initlocal
|
|
||||||
else
|
|
||||||
current@initlocal = 4
|
|
||||||
load dword@initlocal dword from name+position@initlocal
|
|
||||||
end if
|
|
||||||
end virtual
|
|
||||||
if current@initlocal = 1
|
|
||||||
mov byte [name+position@initlocal],byte@initlocal
|
|
||||||
else if current@initlocal = 2
|
|
||||||
mov word [name+position@initlocal],word@initlocal
|
|
||||||
else
|
|
||||||
mov dword [name+position@initlocal],dword@initlocal
|
|
||||||
end if
|
|
||||||
position@initlocal = position@initlocal + current@initlocal
|
|
||||||
end while }
|
|
||||||
|
|
||||||
macro endp
|
|
||||||
{ purge ret,locals,endl
|
|
||||||
finish@proc
|
|
||||||
purge finish@proc
|
|
||||||
restore regs@proc
|
|
||||||
match all,args@proc \{ restore all \}
|
|
||||||
restore args@proc
|
|
||||||
match all,all@vars \{ restore all \} }
|
|
||||||
|
|
||||||
macro local [var]
|
|
||||||
{ common
|
|
||||||
locals
|
|
||||||
forward done@local equ
|
|
||||||
match varname[count]:vartype, var
|
|
||||||
\{ match =BYTE, vartype \\{ varname rb count
|
|
||||||
restore done@local \\}
|
|
||||||
match =WORD, vartype \\{ varname rw count
|
|
||||||
restore done@local \\}
|
|
||||||
match =DWORD, vartype \\{ varname rd count
|
|
||||||
restore done@local \\}
|
|
||||||
match =PWORD, vartype \\{ varname rp count
|
|
||||||
restore done@local \\}
|
|
||||||
match =QWORD, vartype \\{ varname rq count
|
|
||||||
restore done@local \\}
|
|
||||||
match =TBYTE, vartype \\{ varname rt count
|
|
||||||
restore done@local \\}
|
|
||||||
match =DQWORD, vartype \\{ label varname dqword
|
|
||||||
rq count*2
|
|
||||||
restore done@local \\}
|
|
||||||
match =QQWORD, vartype \\{ label varname qqword
|
|
||||||
rq count*4
|
|
||||||
restore done@local \\}
|
|
||||||
match =XWORD, vartype \\{ label varname xword
|
|
||||||
rq count*2
|
|
||||||
restore done@local \\}
|
|
||||||
match =YWORD, vartype \\{ label varname yword
|
|
||||||
rq count*4
|
|
||||||
restore done@local \\}
|
|
||||||
match , done@local \\{ virtual
|
|
||||||
varname vartype
|
|
||||||
end virtual
|
|
||||||
rb count*sizeof.\#vartype
|
|
||||||
restore done@local \\} \}
|
|
||||||
match :varname:vartype, done@local:var
|
|
||||||
\{ match =BYTE, vartype \\{ varname db ?
|
|
||||||
restore done@local \\}
|
|
||||||
match =WORD, vartype \\{ varname dw ?
|
|
||||||
restore done@local \\}
|
|
||||||
match =DWORD, vartype \\{ varname dd ?
|
|
||||||
restore done@local \\}
|
|
||||||
match =PWORD, vartype \\{ varname dp ?
|
|
||||||
restore done@local \\}
|
|
||||||
match =QWORD, vartype \\{ varname dq ?
|
|
||||||
restore done@local \\}
|
|
||||||
match =TBYTE, vartype \\{ varname dt ?
|
|
||||||
restore done@local \\}
|
|
||||||
match =DQWORD, vartype \\{ label varname dqword
|
|
||||||
dq ?,?
|
|
||||||
restore done@local \\}
|
|
||||||
match =QQWORD, vartype \\{ label varname qqword
|
|
||||||
dq ?,?,?,?
|
|
||||||
restore done@local \\}
|
|
||||||
match =XWORD, vartype \\{ label varname xword
|
|
||||||
dq ?,?
|
|
||||||
restore done@local \\}
|
|
||||||
match =YWORD, vartype \\{ label varname yword
|
|
||||||
dq ?,?,?,?
|
|
||||||
restore done@local \\}
|
|
||||||
match , done@local \\{ varname vartype
|
|
||||||
restore done@local \\} \}
|
|
||||||
match ,done@local
|
|
||||||
\{ var
|
|
||||||
restore done@local \}
|
|
||||||
common
|
|
||||||
endl }
|
|
@ -1,240 +0,0 @@
|
|||||||
|
|
||||||
; Macroinstructions for defining data structures
|
|
||||||
|
|
||||||
macro struct name
|
|
||||||
{ virtual at 0
|
|
||||||
fields@struct equ name
|
|
||||||
match child parent, name \{ fields@struct equ child,fields@\#parent \}
|
|
||||||
sub@struct equ
|
|
||||||
struc db [val] \{ \common define field@struct .,db,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc dw [val] \{ \common define field@struct .,dw,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc du [val] \{ \common define field@struct .,du,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc dd [val] \{ \common define field@struct .,dd,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc dp [val] \{ \common define field@struct .,dp,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc dq [val] \{ \common define field@struct .,dq,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc dt [val] \{ \common define field@struct .,dt,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc rb count \{ define field@struct .,db,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc rw count \{ define field@struct .,dw,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc rd count \{ define field@struct .,dd,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc rp count \{ define field@struct .,dp,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc rq count \{ define field@struct .,dq,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
struc rt count \{ define field@struct .,dt,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro db [val] \{ \common \local anonymous
|
|
||||||
define field@struct anonymous,db,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro dw [val] \{ \common \local anonymous
|
|
||||||
define field@struct anonymous,dw,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro du [val] \{ \common \local anonymous
|
|
||||||
define field@struct anonymous,du,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro dd [val] \{ \common \local anonymous
|
|
||||||
define field@struct anonymous,dd,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro dp [val] \{ \common \local anonymous
|
|
||||||
define field@struct anonymous,dp,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro dq [val] \{ \common \local anonymous
|
|
||||||
define field@struct anonymous,dq,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro dt [val] \{ \common \local anonymous
|
|
||||||
define field@struct anonymous,dt,<val>
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro rb count \{ \local anonymous
|
|
||||||
define field@struct anonymous,db,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro rw count \{ \local anonymous
|
|
||||||
define field@struct anonymous,dw,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro rd count \{ \local anonymous
|
|
||||||
define field@struct anonymous,dd,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro rp count \{ \local anonymous
|
|
||||||
define field@struct anonymous,dp,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro rq count \{ \local anonymous
|
|
||||||
define field@struct anonymous,dq,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro rt count \{ \local anonymous
|
|
||||||
define field@struct anonymous,dt,count dup (?)
|
|
||||||
fields@struct equ fields@struct,field@struct \}
|
|
||||||
macro union \{ fields@struct equ fields@struct,,union,<
|
|
||||||
sub@struct equ union \}
|
|
||||||
macro struct \{ fields@struct equ fields@struct,,substruct,<
|
|
||||||
sub@struct equ substruct \} }
|
|
||||||
|
|
||||||
macro ends
|
|
||||||
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
|
|
||||||
restruc rb,rw,rd,rp,rq,rt
|
|
||||||
purge db,dw,du,dd,dp,dq,dt
|
|
||||||
purge rb,rw,rd,rp,rq,rt
|
|
||||||
purge union,struct
|
|
||||||
match name tail,fields@struct, \\{ if $
|
|
||||||
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
|
|
||||||
err
|
|
||||||
end if \\}
|
|
||||||
match name=,fields,fields@struct \\{ fields@struct equ
|
|
||||||
make@struct name,fields
|
|
||||||
define fields@\\#name fields \\}
|
|
||||||
end virtual \}
|
|
||||||
match any, sub@struct \{ fields@struct equ fields@struct> \}
|
|
||||||
restore sub@struct }
|
|
||||||
|
|
||||||
macro make@struct name,[field,type,def]
|
|
||||||
{ common
|
|
||||||
local define
|
|
||||||
define equ name
|
|
||||||
forward
|
|
||||||
local sub
|
|
||||||
match , field \{ make@substruct type,name,sub def
|
|
||||||
define equ define,.,sub, \}
|
|
||||||
match any, field \{ define equ define,.#field,type,<def> \}
|
|
||||||
common
|
|
||||||
match fields, define \{ define@struct fields \} }
|
|
||||||
|
|
||||||
macro define@struct name,[field,type,def]
|
|
||||||
{ common
|
|
||||||
virtual
|
|
||||||
db `name
|
|
||||||
load initial@struct byte from 0
|
|
||||||
if initial@struct = '.'
|
|
||||||
display 'Error: name of structure should not begin with a dot.',0Dh,0Ah
|
|
||||||
err
|
|
||||||
end if
|
|
||||||
end virtual
|
|
||||||
local list
|
|
||||||
list equ
|
|
||||||
forward
|
|
||||||
if ~ field eq .
|
|
||||||
name#field type def
|
|
||||||
sizeof.#name#field = $ - name#field
|
|
||||||
else
|
|
||||||
label name#.#type
|
|
||||||
rb sizeof.#type
|
|
||||||
end if
|
|
||||||
local value
|
|
||||||
match any, list \{ list equ list, \}
|
|
||||||
list equ list <value>
|
|
||||||
common
|
|
||||||
sizeof.#name = $
|
|
||||||
restruc name
|
|
||||||
match values, list \{
|
|
||||||
struc name value \\{ \\local \\..base
|
|
||||||
match any, fields@struct \\\{ fields@struct equ fields@struct,.,name,<values> \\\}
|
|
||||||
match , fields@struct \\\{ label \\..base
|
|
||||||
forward
|
|
||||||
match , value \\\\{ field type def \\\\}
|
|
||||||
match any, value \\\\{ field type value
|
|
||||||
if ~ field eq .
|
|
||||||
rb sizeof.#name#field - ($-field)
|
|
||||||
end if \\\\}
|
|
||||||
common label . at \\..base \\\}
|
|
||||||
\\}
|
|
||||||
macro name value \\{
|
|
||||||
match any, fields@struct \\\{ \\\local anonymous
|
|
||||||
fields@struct equ fields@struct,anonymous,name,<values> \\\}
|
|
||||||
match , fields@struct \\\{
|
|
||||||
forward
|
|
||||||
match , value \\\\{ type def \\\\}
|
|
||||||
match any, value \\\\{ \\\\local ..field
|
|
||||||
..field = $
|
|
||||||
type value
|
|
||||||
if ~ field eq .
|
|
||||||
rb sizeof.#name#field - ($-..field)
|
|
||||||
end if \\\\}
|
|
||||||
common \\\} \\} \} }
|
|
||||||
|
|
||||||
macro enable@substruct
|
|
||||||
{ macro make@substruct substruct,parent,name,[field,type,def]
|
|
||||||
\{ \common
|
|
||||||
\local define
|
|
||||||
define equ parent,name
|
|
||||||
\forward
|
|
||||||
\local sub
|
|
||||||
match , field \\{ match any, type \\\{ enable@substruct
|
|
||||||
make@substruct type,parent,sub def
|
|
||||||
purge make@substruct
|
|
||||||
define equ define,.,sub, \\\} \\}
|
|
||||||
match any, field \\{ define equ define,.\#field,type,<def> \\}
|
|
||||||
\common
|
|
||||||
match fields, define \\{ define@\#substruct fields \\} \} }
|
|
||||||
|
|
||||||
enable@substruct
|
|
||||||
|
|
||||||
macro define@union parent,name,[field,type,def]
|
|
||||||
{ common
|
|
||||||
virtual at parent#.#name
|
|
||||||
forward
|
|
||||||
if ~ field eq .
|
|
||||||
virtual at parent#.#name
|
|
||||||
parent#field type def
|
|
||||||
sizeof.#parent#field = $ - parent#field
|
|
||||||
end virtual
|
|
||||||
if sizeof.#parent#field > $ - parent#.#name
|
|
||||||
rb sizeof.#parent#field - ($ - parent#.#name)
|
|
||||||
end if
|
|
||||||
else
|
|
||||||
virtual at parent#.#name
|
|
||||||
label parent#.#type
|
|
||||||
type def
|
|
||||||
end virtual
|
|
||||||
label name#.#type at parent#.#name
|
|
||||||
if sizeof.#type > $ - parent#.#name
|
|
||||||
rb sizeof.#type - ($ - parent#.#name)
|
|
||||||
end if
|
|
||||||
end if
|
|
||||||
common
|
|
||||||
sizeof.#name = $ - parent#.#name
|
|
||||||
end virtual
|
|
||||||
struc name [value] \{ \common
|
|
||||||
label .\#name
|
|
||||||
last@union equ
|
|
||||||
forward
|
|
||||||
match any, last@union \\{ virtual at .\#name
|
|
||||||
field type def
|
|
||||||
end virtual \\}
|
|
||||||
match , last@union \\{ match , value \\\{ field type def \\\}
|
|
||||||
match any, value \\\{ field type value \\\} \\}
|
|
||||||
last@union equ field
|
|
||||||
common rb sizeof.#name - ($ - .\#name) \}
|
|
||||||
macro name [value] \{ \common \local ..anonymous
|
|
||||||
..anonymous name value \} }
|
|
||||||
|
|
||||||
macro define@substruct parent,name,[field,type,def]
|
|
||||||
{ common
|
|
||||||
virtual at parent#.#name
|
|
||||||
forward
|
|
||||||
if ~ field eq .
|
|
||||||
parent#field type def
|
|
||||||
sizeof.#parent#field = $ - parent#field
|
|
||||||
else
|
|
||||||
label parent#.#type
|
|
||||||
rb sizeof.#type
|
|
||||||
end if
|
|
||||||
common
|
|
||||||
sizeof.#name = $ - parent#.#name
|
|
||||||
end virtual
|
|
||||||
struc name value \{
|
|
||||||
label .\#name
|
|
||||||
forward
|
|
||||||
match , value \\{ field type def \\}
|
|
||||||
match any, value \\{ field type value
|
|
||||||
if ~ field eq .
|
|
||||||
rb sizeof.#parent#field - ($-field)
|
|
||||||
end if \\}
|
|
||||||
common \}
|
|
||||||
macro name value \{ \local ..anonymous
|
|
||||||
..anonymous name \} }
|
|
@ -8,7 +8,6 @@
|
|||||||
#include "sys/closedir.c"
|
#include "sys/closedir.c"
|
||||||
|
|
||||||
#include "stdio/clearerr.c"
|
#include "stdio/clearerr.c"
|
||||||
#include "stdio/vscanf.c"
|
|
||||||
#include "stdio/gets.c"
|
#include "stdio/gets.c"
|
||||||
#include "stdio/setbuf.c"
|
#include "stdio/setbuf.c"
|
||||||
#include "stdio/fgetc.c"
|
#include "stdio/fgetc.c"
|
||||||
@ -21,7 +20,6 @@
|
|||||||
#include "stdio/fseek.c"
|
#include "stdio/fseek.c"
|
||||||
#include "stdio/fgetpos.c"
|
#include "stdio/fgetpos.c"
|
||||||
#include "stdio/fclose.c"
|
#include "stdio/fclose.c"
|
||||||
#include "stdio/vsscanf.c"
|
|
||||||
#include "stdio/snprintf.c"
|
#include "stdio/snprintf.c"
|
||||||
#include "stdio/rename.c"
|
#include "stdio/rename.c"
|
||||||
#include "stdio/getchar.c"
|
#include "stdio/getchar.c"
|
||||||
@ -31,7 +29,6 @@
|
|||||||
#include "stdio/fputs.c"
|
#include "stdio/fputs.c"
|
||||||
#include "stdio/fputc.c"
|
#include "stdio/fputc.c"
|
||||||
#include "stdio/fgets.c"
|
#include "stdio/fgets.c"
|
||||||
#include "stdio/vfscanf.c"
|
|
||||||
#include "stdio/fflush.c"
|
#include "stdio/fflush.c"
|
||||||
#include "stdio/format_scan.c"
|
#include "stdio/format_scan.c"
|
||||||
#include "stdio/printf.c"
|
#include "stdio/printf.c"
|
||||||
@ -93,7 +90,6 @@
|
|||||||
#include "stdlib/difftime.c"
|
#include "stdlib/difftime.c"
|
||||||
#include "stdlib/realloc.c"
|
#include "stdlib/realloc.c"
|
||||||
#include "stdlib/ldiv.c"
|
#include "stdlib/ldiv.c"
|
||||||
#include "stdlib/libtcc1.c"
|
|
||||||
#include "stdlib/abs.c"
|
#include "stdlib/abs.c"
|
||||||
#include "stdlib/div.c"
|
#include "stdlib/div.c"
|
||||||
#include "stdlib/atol.c"
|
#include "stdlib/atol.c"
|
||||||
|
17
programs/develop/libraries/kolibri-libc/source/libtcc/Makefile
Executable file
17
programs/develop/libraries/kolibri-libc/source/libtcc/Makefile
Executable file
@ -0,0 +1,17 @@
|
|||||||
|
KTCC_DIR=../../../../ktcc/trunk
|
||||||
|
|
||||||
|
KTCC=$(KTCC_DIR)/bin/kos32-tcc
|
||||||
|
FASM=fasm
|
||||||
|
|
||||||
|
OBJ= memcpy.o memmove.o memset.o libtcc1.o
|
||||||
|
|
||||||
|
all: $(OBJ)
|
||||||
|
ar -crs ../../lib/libtcc.a $(OBJ)
|
||||||
|
rm -f *.o
|
||||||
|
|
||||||
|
%.o : %.c
|
||||||
|
$(KTCC) -c $< -o $@
|
||||||
|
|
||||||
|
%.o : %.asm
|
||||||
|
$(FASM) $< $@
|
||||||
|
|
763
programs/develop/libraries/kolibri-libc/source/libtcc/libtcc1.c
Normal file
763
programs/develop/libraries/kolibri-libc/source/libtcc/libtcc1.c
Normal file
@ -0,0 +1,763 @@
|
|||||||
|
/* TCC runtime library.
|
||||||
|
Parts of this code are (c) 2002 Fabrice Bellard
|
||||||
|
|
||||||
|
Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
In addition to the permissions in the GNU General Public License, the
|
||||||
|
Free Software Foundation gives you unlimited permission to link the
|
||||||
|
compiled version of this file into combinations with other programs,
|
||||||
|
and to distribute those combinations without any restriction coming
|
||||||
|
from the use of this file. (The General Public License restrictions
|
||||||
|
do apply in other respects; for example, they cover modification of
|
||||||
|
the file, and distribution when not linked into a combine
|
||||||
|
executable.)
|
||||||
|
|
||||||
|
This file is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING. If not, write to
|
||||||
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#include <stdint.h>
|
||||||
|
#define TCC_TARGET_I386
|
||||||
|
|
||||||
|
#define W_TYPE_SIZE 32
|
||||||
|
#define BITS_PER_UNIT 8
|
||||||
|
|
||||||
|
typedef int Wtype;
|
||||||
|
typedef unsigned int UWtype;
|
||||||
|
typedef unsigned int USItype;
|
||||||
|
typedef long long DWtype;
|
||||||
|
typedef unsigned long long UDWtype;
|
||||||
|
|
||||||
|
struct DWstruct {
|
||||||
|
Wtype low, high;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct DWstruct s;
|
||||||
|
DWtype ll;
|
||||||
|
} DWunion;
|
||||||
|
|
||||||
|
typedef long double XFtype;
|
||||||
|
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
||||||
|
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
||||||
|
|
||||||
|
/* the following deal with IEEE single-precision numbers */
|
||||||
|
#define EXCESS 126
|
||||||
|
#define SIGNBIT 0x80000000
|
||||||
|
#define HIDDEN (1 << 23)
|
||||||
|
#define SIGN(fp) ((fp) & SIGNBIT)
|
||||||
|
#define EXP(fp) (((fp) >> 23) & 0xFF)
|
||||||
|
#define MANT(fp) (((fp) & 0x7FFFFF) | HIDDEN)
|
||||||
|
#define PACK(s,e,m) ((s) | ((e) << 23) | (m))
|
||||||
|
|
||||||
|
/* the following deal with IEEE double-precision numbers */
|
||||||
|
#define EXCESSD 1022
|
||||||
|
#define HIDDEND (1 << 20)
|
||||||
|
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
|
||||||
|
#define SIGND(fp) ((fp.l.upper) & SIGNBIT)
|
||||||
|
#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
|
||||||
|
(fp.l.lower >> 22))
|
||||||
|
#define HIDDEND_LL ((long long)1 << 52)
|
||||||
|
#define MANTD_LL(fp) ((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
|
||||||
|
#define PACKD_LL(s,e,m) (((long long)((s)+((e)<<20))<<32)|(m))
|
||||||
|
|
||||||
|
/* the following deal with x86 long double-precision numbers */
|
||||||
|
#define EXCESSLD 16382
|
||||||
|
#define EXPLD(fp) (fp.l.upper & 0x7fff)
|
||||||
|
#define SIGNLD(fp) ((fp.l.upper) & 0x8000)
|
||||||
|
|
||||||
|
/* only for x86 */
|
||||||
|
union ldouble_long {
|
||||||
|
long double ld;
|
||||||
|
struct {
|
||||||
|
unsigned long long lower;
|
||||||
|
unsigned short upper;
|
||||||
|
} l;
|
||||||
|
};
|
||||||
|
|
||||||
|
union double_long {
|
||||||
|
double d;
|
||||||
|
#if 1
|
||||||
|
struct {
|
||||||
|
unsigned int lower;
|
||||||
|
int upper;
|
||||||
|
} l;
|
||||||
|
#else
|
||||||
|
struct {
|
||||||
|
int upper;
|
||||||
|
unsigned int lower;
|
||||||
|
} l;
|
||||||
|
#endif
|
||||||
|
long long ll;
|
||||||
|
};
|
||||||
|
|
||||||
|
union float_long {
|
||||||
|
float f;
|
||||||
|
unsigned int l;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* XXX: we don't support several builtin supports for now */
|
||||||
|
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM)
|
||||||
|
|
||||||
|
/* XXX: use gcc/tcc intrinsic ? */
|
||||||
|
#if defined(TCC_TARGET_I386)
|
||||||
|
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
|
||||||
|
__asm__ ("subl %5,%1\n\tsbbl %3,%0" \
|
||||||
|
: "=r" ((USItype) (sh)), \
|
||||||
|
"=&r" ((USItype) (sl)) \
|
||||||
|
: "0" ((USItype) (ah)), \
|
||||||
|
"g" ((USItype) (bh)), \
|
||||||
|
"1" ((USItype) (al)), \
|
||||||
|
"g" ((USItype) (bl)))
|
||||||
|
#define umul_ppmm(w1, w0, u, v) \
|
||||||
|
__asm__ ("mull %3" \
|
||||||
|
: "=a" ((USItype) (w0)), \
|
||||||
|
"=d" ((USItype) (w1)) \
|
||||||
|
: "%0" ((USItype) (u)), \
|
||||||
|
"rm" ((USItype) (v)))
|
||||||
|
#define udiv_qrnnd(q, r, n1, n0, dv) \
|
||||||
|
__asm__ ("divl %4" \
|
||||||
|
: "=a" ((USItype) (q)), \
|
||||||
|
"=d" ((USItype) (r)) \
|
||||||
|
: "0" ((USItype) (n0)), \
|
||||||
|
"1" ((USItype) (n1)), \
|
||||||
|
"rm" ((USItype) (dv)))
|
||||||
|
#define count_leading_zeros(count, x) \
|
||||||
|
do { \
|
||||||
|
USItype __cbtmp; \
|
||||||
|
__asm__ ("bsrl %1,%0" \
|
||||||
|
: "=r" (__cbtmp) : "rm" ((USItype) (x))); \
|
||||||
|
(count) = __cbtmp ^ 31; \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#error unsupported CPU type
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* most of this code is taken from libgcc2.c from gcc */
|
||||||
|
UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
|
||||||
|
{
|
||||||
|
DWunion ww;
|
||||||
|
DWunion nn, dd;
|
||||||
|
DWunion rr;
|
||||||
|
UWtype d0, d1, n0, n1, n2;
|
||||||
|
UWtype q0, q1;
|
||||||
|
UWtype b, bm;
|
||||||
|
|
||||||
|
nn.ll = n;
|
||||||
|
dd.ll = d;
|
||||||
|
|
||||||
|
d0 = dd.s.low;
|
||||||
|
d1 = dd.s.high;
|
||||||
|
n0 = nn.s.low;
|
||||||
|
n1 = nn.s.high;
|
||||||
|
|
||||||
|
#if !defined(UDIV_NEEDS_NORMALIZATION)
|
||||||
|
if (d1 == 0)
|
||||||
|
{
|
||||||
|
if (d0 > n1)
|
||||||
|
{
|
||||||
|
/* 0q = nn / 0D */
|
||||||
|
|
||||||
|
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||||
|
q1 = 0;
|
||||||
|
|
||||||
|
/* Remainder in n0. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* qq = NN / 0d */
|
||||||
|
|
||||||
|
if (d0 == 0)
|
||||||
|
d0 = 1 / d0; /* Divide intentionally by zero. */
|
||||||
|
|
||||||
|
udiv_qrnnd (q1, n1, 0, n1, d0);
|
||||||
|
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||||
|
|
||||||
|
/* Remainder in n0. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rp != 0)
|
||||||
|
{
|
||||||
|
rr.s.low = n0;
|
||||||
|
rr.s.high = 0;
|
||||||
|
*rp = rr.ll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* UDIV_NEEDS_NORMALIZATION */
|
||||||
|
|
||||||
|
if (d1 == 0)
|
||||||
|
{
|
||||||
|
if (d0 > n1)
|
||||||
|
{
|
||||||
|
/* 0q = nn / 0D */
|
||||||
|
|
||||||
|
count_leading_zeros (bm, d0);
|
||||||
|
|
||||||
|
if (bm != 0)
|
||||||
|
{
|
||||||
|
/* Normalize, i.e. make the most significant bit of the
|
||||||
|
denominator set. */
|
||||||
|
|
||||||
|
d0 = d0 << bm;
|
||||||
|
n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
|
||||||
|
n0 = n0 << bm;
|
||||||
|
}
|
||||||
|
|
||||||
|
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||||
|
q1 = 0;
|
||||||
|
|
||||||
|
/* Remainder in n0 >> bm. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* qq = NN / 0d */
|
||||||
|
|
||||||
|
if (d0 == 0)
|
||||||
|
d0 = 1 / d0; /* Divide intentionally by zero. */
|
||||||
|
|
||||||
|
count_leading_zeros (bm, d0);
|
||||||
|
|
||||||
|
if (bm == 0)
|
||||||
|
{
|
||||||
|
/* From (n1 >= d0) /\ (the most significant bit of d0 is set),
|
||||||
|
conclude (the most significant bit of n1 is set) /\ (the
|
||||||
|
leading quotient digit q1 = 1).
|
||||||
|
|
||||||
|
This special case is necessary, not an optimization.
|
||||||
|
(Shifts counts of W_TYPE_SIZE are undefined.) */
|
||||||
|
|
||||||
|
n1 -= d0;
|
||||||
|
q1 = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Normalize. */
|
||||||
|
|
||||||
|
b = W_TYPE_SIZE - bm;
|
||||||
|
|
||||||
|
d0 = d0 << bm;
|
||||||
|
n2 = n1 >> b;
|
||||||
|
n1 = (n1 << bm) | (n0 >> b);
|
||||||
|
n0 = n0 << bm;
|
||||||
|
|
||||||
|
udiv_qrnnd (q1, n1, n2, n1, d0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* n1 != d0... */
|
||||||
|
|
||||||
|
udiv_qrnnd (q0, n0, n1, n0, d0);
|
||||||
|
|
||||||
|
/* Remainder in n0 >> bm. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rp != 0)
|
||||||
|
{
|
||||||
|
rr.s.low = n0 >> bm;
|
||||||
|
rr.s.high = 0;
|
||||||
|
*rp = rr.ll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* UDIV_NEEDS_NORMALIZATION */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (d1 > n1)
|
||||||
|
{
|
||||||
|
/* 00 = nn / DD */
|
||||||
|
|
||||||
|
q0 = 0;
|
||||||
|
q1 = 0;
|
||||||
|
|
||||||
|
/* Remainder in n1n0. */
|
||||||
|
if (rp != 0)
|
||||||
|
{
|
||||||
|
rr.s.low = n0;
|
||||||
|
rr.s.high = n1;
|
||||||
|
*rp = rr.ll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 0q = NN / dd */
|
||||||
|
|
||||||
|
count_leading_zeros (bm, d1);
|
||||||
|
if (bm == 0)
|
||||||
|
{
|
||||||
|
/* From (n1 >= d1) /\ (the most significant bit of d1 is set),
|
||||||
|
conclude (the most significant bit of n1 is set) /\ (the
|
||||||
|
quotient digit q0 = 0 or 1).
|
||||||
|
|
||||||
|
This special case is necessary, not an optimization. */
|
||||||
|
|
||||||
|
/* The condition on the next line takes advantage of that
|
||||||
|
n1 >= d1 (true due to program flow). */
|
||||||
|
if (n1 > d1 || n0 >= d0)
|
||||||
|
{
|
||||||
|
q0 = 1;
|
||||||
|
sub_ddmmss (n1, n0, n1, n0, d1, d0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
q0 = 0;
|
||||||
|
|
||||||
|
q1 = 0;
|
||||||
|
|
||||||
|
if (rp != 0)
|
||||||
|
{
|
||||||
|
rr.s.low = n0;
|
||||||
|
rr.s.high = n1;
|
||||||
|
*rp = rr.ll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UWtype m1, m0;
|
||||||
|
/* Normalize. */
|
||||||
|
|
||||||
|
b = W_TYPE_SIZE - bm;
|
||||||
|
|
||||||
|
d1 = (d1 << bm) | (d0 >> b);
|
||||||
|
d0 = d0 << bm;
|
||||||
|
n2 = n1 >> b;
|
||||||
|
n1 = (n1 << bm) | (n0 >> b);
|
||||||
|
n0 = n0 << bm;
|
||||||
|
|
||||||
|
udiv_qrnnd (q0, n1, n2, n1, d1);
|
||||||
|
umul_ppmm (m1, m0, q0, d0);
|
||||||
|
|
||||||
|
if (m1 > n1 || (m1 == n1 && m0 > n0))
|
||||||
|
{
|
||||||
|
q0--;
|
||||||
|
sub_ddmmss (m1, m0, m1, m0, d1, d0);
|
||||||
|
}
|
||||||
|
|
||||||
|
q1 = 0;
|
||||||
|
|
||||||
|
/* Remainder in (n1n0 - m1m0) >> bm. */
|
||||||
|
if (rp != 0)
|
||||||
|
{
|
||||||
|
sub_ddmmss (n1, n0, n1, n0, m1, m0);
|
||||||
|
rr.s.low = (n1 << b) | (n0 >> bm);
|
||||||
|
rr.s.high = n1 >> bm;
|
||||||
|
*rp = rr.ll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ww.s.low = q0;
|
||||||
|
ww.s.high = q1;
|
||||||
|
return ww.ll;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __negdi2(a) (-(a))
|
||||||
|
|
||||||
|
long long __divdi3(long long u, long long v)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
DWunion uu, vv;
|
||||||
|
DWtype w;
|
||||||
|
|
||||||
|
uu.ll = u;
|
||||||
|
vv.ll = v;
|
||||||
|
|
||||||
|
if (uu.s.high < 0) {
|
||||||
|
c = ~c;
|
||||||
|
uu.ll = __negdi2 (uu.ll);
|
||||||
|
}
|
||||||
|
if (vv.s.high < 0) {
|
||||||
|
c = ~c;
|
||||||
|
vv.ll = __negdi2 (vv.ll);
|
||||||
|
}
|
||||||
|
w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
|
||||||
|
if (c)
|
||||||
|
w = __negdi2 (w);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/KaMeHb-UA/UE4m/blob/1d9ad5bfead06520570c7f24dad062f9f8717c1a/\
|
||||||
|
Engine/Extras/ThirdPartyNotUE/emsdk/emscripten/incoming/system/lib/compiler-rt/lib/\
|
||||||
|
builtins/divmoddi4.c
|
||||||
|
long long __divmoddi4(long long a, long long b, long long* rem)
|
||||||
|
{
|
||||||
|
long long d = __divdi3(a, b);
|
||||||
|
*rem = a - (d * b);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long __moddi3(long long u, long long v)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
DWunion uu, vv;
|
||||||
|
DWtype w;
|
||||||
|
|
||||||
|
uu.ll = u;
|
||||||
|
vv.ll = v;
|
||||||
|
|
||||||
|
if (uu.s.high < 0) {
|
||||||
|
c = ~c;
|
||||||
|
uu.ll = __negdi2 (uu.ll);
|
||||||
|
}
|
||||||
|
if (vv.s.high < 0)
|
||||||
|
vv.ll = __negdi2 (vv.ll);
|
||||||
|
|
||||||
|
__udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
|
||||||
|
if (c)
|
||||||
|
w = __negdi2 (w);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
|
||||||
|
{
|
||||||
|
return __udivmoddi4 (u, v, (UDWtype *) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
|
||||||
|
{
|
||||||
|
UDWtype w;
|
||||||
|
|
||||||
|
__udivmoddi4 (u, v, &w);
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: fix tcc's code generator to do this instead */
|
||||||
|
long long __ashrdi3(long long a, int b)
|
||||||
|
{
|
||||||
|
#ifdef __TINYC__
|
||||||
|
DWunion u;
|
||||||
|
u.ll = a;
|
||||||
|
if (b >= 32) {
|
||||||
|
u.s.low = u.s.high >> (b - 32);
|
||||||
|
u.s.high = u.s.high >> 31;
|
||||||
|
} else if (b != 0) {
|
||||||
|
u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
|
||||||
|
u.s.high = u.s.high >> b;
|
||||||
|
}
|
||||||
|
return u.ll;
|
||||||
|
#else
|
||||||
|
return a >> b;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: fix tcc's code generator to do this instead */
|
||||||
|
unsigned long long __lshrdi3(unsigned long long a, int b)
|
||||||
|
{
|
||||||
|
#ifdef __TINYC__
|
||||||
|
DWunion u;
|
||||||
|
u.ll = a;
|
||||||
|
if (b >= 32) {
|
||||||
|
u.s.low = (unsigned)u.s.high >> (b - 32);
|
||||||
|
u.s.high = 0;
|
||||||
|
} else if (b != 0) {
|
||||||
|
u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
|
||||||
|
u.s.high = (unsigned)u.s.high >> b;
|
||||||
|
}
|
||||||
|
return u.ll;
|
||||||
|
#else
|
||||||
|
return a >> b;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: fix tcc's code generator to do this instead */
|
||||||
|
long long __ashldi3(long long a, int b)
|
||||||
|
{
|
||||||
|
#ifdef __TINYC__
|
||||||
|
DWunion u;
|
||||||
|
u.ll = a;
|
||||||
|
if (b >= 32) {
|
||||||
|
u.s.high = (unsigned)u.s.low << (b - 32);
|
||||||
|
u.s.low = 0;
|
||||||
|
} else if (b != 0) {
|
||||||
|
u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b));
|
||||||
|
u.s.low = (unsigned)u.s.low << b;
|
||||||
|
}
|
||||||
|
return u.ll;
|
||||||
|
#else
|
||||||
|
return a << b;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef COMMIT_4ad186c5ef61_IS_FIXED
|
||||||
|
long long __tcc_cvt_ftol(long double x)
|
||||||
|
{
|
||||||
|
unsigned c0, c1;
|
||||||
|
long long ret;
|
||||||
|
__asm__ __volatile__ ("fnstcw %0" : "=m" (c0));
|
||||||
|
c1 = c0 | 0x0C00;
|
||||||
|
__asm__ __volatile__ ("fldcw %0" : : "m" (c1));
|
||||||
|
__asm__ __volatile__ ("fistpll %0" : "=m" (ret));
|
||||||
|
__asm__ __volatile__ ("fldcw %0" : : "m" (c0));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !__x86_64__ */
|
||||||
|
|
||||||
|
/* XXX: fix tcc's code generator to do this instead */
|
||||||
|
float __floatundisf(unsigned long long a)
|
||||||
|
{
|
||||||
|
DWunion uu;
|
||||||
|
XFtype r;
|
||||||
|
|
||||||
|
uu.ll = a;
|
||||||
|
if (uu.s.high >= 0) {
|
||||||
|
return (float)uu.ll;
|
||||||
|
} else {
|
||||||
|
r = (XFtype)uu.ll;
|
||||||
|
r += 18446744073709551616.0;
|
||||||
|
return (float)r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double __floatundidf(unsigned long long a)
|
||||||
|
{
|
||||||
|
DWunion uu;
|
||||||
|
XFtype r;
|
||||||
|
|
||||||
|
uu.ll = a;
|
||||||
|
if (uu.s.high >= 0) {
|
||||||
|
return (double)uu.ll;
|
||||||
|
} else {
|
||||||
|
r = (XFtype)uu.ll;
|
||||||
|
r += 18446744073709551616.0;
|
||||||
|
return (double)r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long double __floatundixf(unsigned long long a)
|
||||||
|
{
|
||||||
|
DWunion uu;
|
||||||
|
XFtype r;
|
||||||
|
|
||||||
|
uu.ll = a;
|
||||||
|
if (uu.s.high >= 0) {
|
||||||
|
return (long double)uu.ll;
|
||||||
|
} else {
|
||||||
|
r = (XFtype)uu.ll;
|
||||||
|
r += 18446744073709551616.0;
|
||||||
|
return (long double)r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long __fixunssfdi (float a1)
|
||||||
|
{
|
||||||
|
register union float_long fl1;
|
||||||
|
register int exp;
|
||||||
|
register unsigned long l;
|
||||||
|
|
||||||
|
fl1.f = a1;
|
||||||
|
|
||||||
|
if (fl1.l == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
exp = EXP (fl1.l) - EXCESS - 24;
|
||||||
|
|
||||||
|
l = MANT(fl1.l);
|
||||||
|
if (exp >= 41)
|
||||||
|
return (unsigned long long)-1;
|
||||||
|
else if (exp >= 0)
|
||||||
|
return (unsigned long long)l << exp;
|
||||||
|
else if (exp >= -23)
|
||||||
|
return l >> -exp;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long __fixunsdfdi (double a1)
|
||||||
|
{
|
||||||
|
register union double_long dl1;
|
||||||
|
register int exp;
|
||||||
|
register unsigned long long l;
|
||||||
|
|
||||||
|
dl1.d = a1;
|
||||||
|
|
||||||
|
if (dl1.ll == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
exp = EXPD (dl1) - EXCESSD - 53;
|
||||||
|
|
||||||
|
l = MANTD_LL(dl1);
|
||||||
|
|
||||||
|
if (exp >= 12)
|
||||||
|
return (unsigned long long)-1;
|
||||||
|
else if (exp >= 0)
|
||||||
|
return l << exp;
|
||||||
|
else if (exp >= -52)
|
||||||
|
return l >> -exp;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long __fixunsxfdi (long double a1)
|
||||||
|
{
|
||||||
|
register union ldouble_long dl1;
|
||||||
|
register int exp;
|
||||||
|
register unsigned long long l;
|
||||||
|
|
||||||
|
dl1.ld = a1;
|
||||||
|
|
||||||
|
if (dl1.l.lower == 0 && dl1.l.upper == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
exp = EXPLD (dl1) - EXCESSLD - 64;
|
||||||
|
|
||||||
|
l = dl1.l.lower;
|
||||||
|
|
||||||
|
if (exp > 0)
|
||||||
|
return (unsigned long long)-1;
|
||||||
|
else if (exp >= -63)
|
||||||
|
return l >> -exp;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long __fixsfdi (float a1)
|
||||||
|
{
|
||||||
|
long long ret; int s;
|
||||||
|
ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
|
||||||
|
return s ? ret : -ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long __fixdfdi (double a1)
|
||||||
|
{
|
||||||
|
long long ret; int s;
|
||||||
|
ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
|
||||||
|
return s ? ret : -ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long __fixxfdi (long double a1)
|
||||||
|
{
|
||||||
|
long long ret; int s;
|
||||||
|
ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
|
||||||
|
return s ? ret : -ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(TCC_TARGET_X86_64) && !defined(_WIN64)
|
||||||
|
|
||||||
|
#ifndef __TINYC__
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#else
|
||||||
|
/* Avoid including stdlib.h because it is not easily available when
|
||||||
|
cross compiling */
|
||||||
|
#include <stddef.h> /* size_t definition is needed for a x86_64-tcc to parse memset() */
|
||||||
|
void *malloc(unsigned long long);
|
||||||
|
void *memset(void *s, int c, size_t n);
|
||||||
|
void free(void*);
|
||||||
|
void abort(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum __va_arg_type {
|
||||||
|
__va_gen_reg, __va_float_reg, __va_stack
|
||||||
|
};
|
||||||
|
|
||||||
|
//This should be in sync with the declaration on our include/stdarg.h
|
||||||
|
/* GCC compatible definition of va_list. */
|
||||||
|
typedef struct {
|
||||||
|
unsigned int gp_offset;
|
||||||
|
unsigned int fp_offset;
|
||||||
|
union {
|
||||||
|
unsigned int overflow_offset;
|
||||||
|
char *overflow_arg_area;
|
||||||
|
};
|
||||||
|
char *reg_save_area;
|
||||||
|
} __va_list_struct;
|
||||||
|
|
||||||
|
#undef __va_start
|
||||||
|
#undef __va_arg
|
||||||
|
#undef __va_copy
|
||||||
|
#undef __va_end
|
||||||
|
|
||||||
|
void __va_start(__va_list_struct *ap, void *fp)
|
||||||
|
{
|
||||||
|
memset(ap, 0, sizeof(__va_list_struct));
|
||||||
|
*ap = *(__va_list_struct *)((char *)fp - 16);
|
||||||
|
ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
|
||||||
|
ap->reg_save_area = (char *)fp - 176 - 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *__va_arg(__va_list_struct *ap,
|
||||||
|
enum __va_arg_type arg_type,
|
||||||
|
int size, int align)
|
||||||
|
{
|
||||||
|
size = (size + 7) & ~7;
|
||||||
|
align = (align + 7) & ~7;
|
||||||
|
switch (arg_type) {
|
||||||
|
case __va_gen_reg:
|
||||||
|
if (ap->gp_offset + size <= 48) {
|
||||||
|
ap->gp_offset += size;
|
||||||
|
return ap->reg_save_area + ap->gp_offset - size;
|
||||||
|
}
|
||||||
|
goto use_overflow_area;
|
||||||
|
|
||||||
|
case __va_float_reg:
|
||||||
|
if (ap->fp_offset < 128 + 48) {
|
||||||
|
ap->fp_offset += 16;
|
||||||
|
return ap->reg_save_area + ap->fp_offset - 16;
|
||||||
|
}
|
||||||
|
size = 8;
|
||||||
|
goto use_overflow_area;
|
||||||
|
|
||||||
|
case __va_stack:
|
||||||
|
use_overflow_area:
|
||||||
|
ap->overflow_arg_area += size;
|
||||||
|
ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align);
|
||||||
|
return ap->overflow_arg_area - size;
|
||||||
|
|
||||||
|
default:
|
||||||
|
#ifndef __TINYC__
|
||||||
|
fprintf(stderr, "unknown ABI type for __va_arg\n");
|
||||||
|
#endif
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __x86_64__ */
|
||||||
|
|
||||||
|
/* Flushing for tccrun */
|
||||||
|
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_I386)
|
||||||
|
|
||||||
|
void __clear_cache(void *beginning, void *end)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(TCC_TARGET_ARM)
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void __clear_cache(void *beginning, void *end)
|
||||||
|
{
|
||||||
|
/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
|
||||||
|
* However, there is no ARM asm parser in tcc so we use it for now */
|
||||||
|
#if 1
|
||||||
|
syscall(__ARM_NR_cacheflush, beginning, end, 0);
|
||||||
|
#else
|
||||||
|
__asm__ ("push {r7}\n\t"
|
||||||
|
"mov r7, #0xf0002\n\t"
|
||||||
|
"mov r2, #0\n\t"
|
||||||
|
"swi 0\n\t"
|
||||||
|
"pop {r7}\n\t"
|
||||||
|
"ret");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#warning __clear_cache not defined for this architecture, avoid using tcc -run
|
||||||
|
#endif
|
@ -0,0 +1,24 @@
|
|||||||
|
format ELF
|
||||||
|
|
||||||
|
section '.text' executable
|
||||||
|
include '../../../../../proc32.inc'
|
||||||
|
|
||||||
|
public memcpy
|
||||||
|
|
||||||
|
proc memcpy c, to:dword,from:dword,count:dword
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
mov ecx,[count]
|
||||||
|
test ecx,ecx
|
||||||
|
jz no_copy_block
|
||||||
|
mov esi,[from]
|
||||||
|
mov edi,[to]
|
||||||
|
cld
|
||||||
|
rep movsb
|
||||||
|
no_copy_block:
|
||||||
|
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
mov eax, [to]
|
||||||
|
ret
|
||||||
|
endp
|
@ -0,0 +1,34 @@
|
|||||||
|
format ELF
|
||||||
|
|
||||||
|
section '.text' executable
|
||||||
|
include '../../../../../proc32.inc'
|
||||||
|
|
||||||
|
public memmove
|
||||||
|
|
||||||
|
proc memmove c, to:dword,from:dword,count:dword
|
||||||
|
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
mov ecx,[count]
|
||||||
|
test ecx,ecx
|
||||||
|
jz no_copy_block_
|
||||||
|
mov esi,[from]
|
||||||
|
mov edi,[to]
|
||||||
|
cmp esi, edi
|
||||||
|
je no_copy_block_
|
||||||
|
jg copy_
|
||||||
|
add esi, ecx
|
||||||
|
add edi, ecx
|
||||||
|
dec esi
|
||||||
|
dec edi
|
||||||
|
std
|
||||||
|
copy_:
|
||||||
|
rep movsb
|
||||||
|
cld
|
||||||
|
no_copy_block_:
|
||||||
|
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
mov eax,[to]
|
||||||
|
ret
|
||||||
|
endp
|
@ -0,0 +1,16 @@
|
|||||||
|
format ELF
|
||||||
|
section '.text' executable
|
||||||
|
public memset
|
||||||
|
|
||||||
|
memset:
|
||||||
|
push edi
|
||||||
|
mov edi,[esp+8]
|
||||||
|
mov eax,[esp+12]
|
||||||
|
mov ecx,[esp+16]
|
||||||
|
jecxz .no_set
|
||||||
|
cld
|
||||||
|
rep stosb
|
||||||
|
.no_set:
|
||||||
|
mov eax, [esp+8]
|
||||||
|
pop edi
|
||||||
|
ret
|
@ -13,13 +13,28 @@ todo:
|
|||||||
-radix point always '.', no LOCALEs
|
-radix point always '.', no LOCALEs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "format_scan.h"
|
|
||||||
|
|
||||||
static int __try_parse_real(long double *real, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
|
typedef int (*virtual_getc)(void *sp, const void *obj);
|
||||||
|
typedef void (*virtual_ungetc)(void *sp, int c, const void *obj);
|
||||||
|
|
||||||
|
enum flags_t
|
||||||
|
{
|
||||||
|
flag_unsigned = 0x02,
|
||||||
|
flag_register = 0x04,
|
||||||
|
flag_plus = 0x08,
|
||||||
|
flag_left_just = 0x10,
|
||||||
|
flag_lead_zeros = 0x20,
|
||||||
|
flag_space_plus = 0x40,
|
||||||
|
flag_hash_sign = 0x80,
|
||||||
|
flag_point = 0x100
|
||||||
|
};
|
||||||
|
|
||||||
|
int try_parse_real(long double *real, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||||
// returns 1 if OK, -1 == EOF, -2 parse broken
|
// returns 1 if OK, -1 == EOF, -2 parse broken
|
||||||
{
|
{
|
||||||
int sign = 1, have_digits = 0;
|
int sign = 1, have_digits = 0;
|
||||||
@ -138,7 +153,7 @@ static int __try_parse_real(long double *real, int ch, const void *src, void *sa
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __try_parse_int(long long *digit, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
|
int try_parse_int(long long *digit, int ch, const void *src, void *save, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||||
{
|
{
|
||||||
int sign = 1, base = 10, have_digits = 0;
|
int sign = 1, base = 10, have_digits = 0;
|
||||||
|
|
||||||
@ -208,7 +223,7 @@ static int __try_parse_int(long long *digit, int ch, const void *src, void *save
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vgetc, virtual_ungetc vungetc)
|
int format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vgetc, virtual_ungetc vungetc)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int length;
|
int length;
|
||||||
@ -363,7 +378,7 @@ int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vg
|
|||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
arg_str = va_arg(argp, char*);
|
arg_str = va_arg(argp, char*);
|
||||||
if (fmt1 == 0) length = STDIO_MAX_MEM; // max string scan 4096
|
if (fmt1 == 0) length = 4095; // max string scan 4096
|
||||||
else length = fmt1;
|
else length = fmt1;
|
||||||
for (i = 0; i < length; i++)
|
for (i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
@ -375,7 +390,7 @@ int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vg
|
|||||||
break;
|
break;
|
||||||
case 'd': case 'i': case 'u':
|
case 'd': case 'i': case 'u':
|
||||||
case 'o': case 'p': case 'x':
|
case 'o': case 'p': case 'x':
|
||||||
i = __try_parse_int(&digit, ch, src, &save, vgetc, vungetc);
|
i = try_parse_int(&digit, ch, src, &save, vgetc, vungetc);
|
||||||
if (i < 0) goto exit_me;
|
if (i < 0) goto exit_me;
|
||||||
|
|
||||||
if (flag_long == 0) { arg_int = va_arg(argp, int*); *arg_int = (int)digit; } else
|
if (flag_long == 0) { arg_int = va_arg(argp, int*); *arg_int = (int)digit; } else
|
||||||
@ -385,7 +400,7 @@ int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vg
|
|||||||
case 'a': case 'A': case 'f': case 'F':
|
case 'a': case 'A': case 'f': case 'F':
|
||||||
case 'e': case 'E':
|
case 'e': case 'E':
|
||||||
case 'g': case 'G':
|
case 'g': case 'G':
|
||||||
i = __try_parse_real(&real, ch, src, &save, vgetc, vungetc);
|
i = try_parse_real(&real, ch, src, &save, vgetc, vungetc);
|
||||||
if (i < 0) goto exit_me;
|
if (i < 0) goto exit_me;
|
||||||
|
|
||||||
if (flag_long == 0) { arg_float = va_arg(argp, float*); *arg_float = (float)real; } else
|
if (flag_long == 0) { arg_float = va_arg(argp, float*); *arg_float = (float)real; } else
|
||||||
|
@ -1,11 +1,40 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int virtual_getc_file(void *sp, const void *obj)
|
||||||
|
// get next chat from file obj, save point is ptr to string char ptr
|
||||||
|
{
|
||||||
|
FILE *f = (FILE *)obj;
|
||||||
|
int ch = fgetc(f);
|
||||||
|
|
||||||
|
//printf("getc '%c'[%d];", ch, ch);
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void virtual_ungetc_file(void *sp, int c, const void *obj)
|
||||||
|
// if can, one step back savepoint in s
|
||||||
|
{
|
||||||
|
FILE *f = (FILE *)obj;
|
||||||
|
|
||||||
|
if (f) ungetc(c, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int vfscanf ( FILE * stream, const char * format, va_list arg )
|
||||||
|
{
|
||||||
|
return format_scan(stream, format, arg, &virtual_getc_file, &virtual_ungetc_file);
|
||||||
|
};
|
||||||
|
|
||||||
int fscanf ( FILE * stream, const char * format, ...)
|
int fscanf ( FILE * stream, const char * format, ...)
|
||||||
{
|
{
|
||||||
va_list arg;
|
va_list arg;
|
||||||
int n;
|
int n;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
|
|
||||||
n = vfscanf(stream, format, arg);
|
n = vfscanf(stream, format, arg);
|
||||||
|
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,50 @@
|
|||||||
//#include "format_scan.h"
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <string.h>
|
||||||
|
char *__scanf_buffer = 0;
|
||||||
|
|
||||||
|
int virtual_getc_con(void *sp, const void *obj)
|
||||||
|
// get next chat from string obj, save point is ptr to string char ptr
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
const char**spc= (const char**)sp;
|
||||||
|
if (!spc) return EOF; // error
|
||||||
|
|
||||||
|
if (!*spc) *spc = __scanf_buffer; // first call, init savepoint
|
||||||
|
|
||||||
|
while (!**spc) // need to read more
|
||||||
|
{
|
||||||
|
if(!gets(__scanf_buffer)) return EOF;
|
||||||
|
*spc = __scanf_buffer;
|
||||||
|
strcat(__scanf_buffer,"\n"); // imitate delimiter
|
||||||
|
}
|
||||||
|
if (**spc == 26 || **spc == 3) // ^C ^Z end of scan, clear buffer
|
||||||
|
{
|
||||||
|
*spc = __scanf_buffer;
|
||||||
|
*__scanf_buffer = 0;
|
||||||
|
return EOF; // ^C ^Z
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = **spc; (*spc)++ ;
|
||||||
|
|
||||||
|
//printf("getc '%c'[%d];", ch, ch);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void virtual_ungetc_con(void *sp, int c, const void *obj)
|
||||||
|
// if can, one step back savepoint in s
|
||||||
|
{
|
||||||
|
const char**spc= (const char**)sp;
|
||||||
|
|
||||||
|
if (spc && *spc > __scanf_buffer) (*spc)--;
|
||||||
|
//printf("Ungetc '%c'[%d];", c, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vscanf ( const char * format, va_list arg )
|
||||||
|
{
|
||||||
|
return format_scan(NULL, format, arg, &virtual_getc_con, &virtual_ungetc_con);
|
||||||
|
};
|
||||||
|
|
||||||
int scanf ( const char * format, ...)
|
int scanf ( const char * format, ...)
|
||||||
{
|
{
|
||||||
@ -8,8 +52,8 @@ int scanf ( const char * format, ...)
|
|||||||
int n;
|
int n;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
|
|
||||||
if(__scanf_buffer == NULL) __scanf_buffer = malloc(STDIO_MAX_MEM);
|
if(__scanf_buffer == NULL) __scanf_buffer = malloc(4096);
|
||||||
if(__scanf_buffer == NULL) errno = ENOMEM; return ENOMEM;
|
if(__scanf_buffer == NULL) return -3;
|
||||||
|
|
||||||
*__scanf_buffer = 0;
|
*__scanf_buffer = 0;
|
||||||
n = vscanf(format, arg);
|
n = vscanf(format, arg);
|
||||||
|
@ -1,11 +1,45 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
int virtual_getc_str(void *sp, const void *obj)
|
||||||
|
// get next chat from string obj, save point is ptr to string char ptr
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
const char *s = (const char *)obj;
|
||||||
|
const char**spc= (const char**)sp;
|
||||||
|
if (!s || !spc) return EOF; // error
|
||||||
|
|
||||||
|
if (!*spc) *spc = s; // first call, init savepoint
|
||||||
|
|
||||||
|
if (!**spc) return EOF; // EOS
|
||||||
|
|
||||||
|
ch = **spc; (*spc)++ ;
|
||||||
|
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void virtual_ungetc_str(void *sp, int c, const void *obj)
|
||||||
|
// if can, one step back savepoint in s
|
||||||
|
{
|
||||||
|
const char *s = (const char *)obj;
|
||||||
|
const char**spc= (const char**)sp;
|
||||||
|
|
||||||
|
if (s && spc && *spc > s) (*spc)--;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsscanf ( const char * s, const char * format, va_list arg )
|
||||||
|
{
|
||||||
|
return format_scan(s, format, arg, &virtual_getc_str, &virtual_ungetc_str);
|
||||||
|
};
|
||||||
|
|
||||||
int sscanf ( const char * s, const char * format, ...)
|
int sscanf ( const char * s, const char * format, ...)
|
||||||
{
|
{
|
||||||
va_list arg;
|
va_list arg;
|
||||||
int n;
|
int n;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
|
|
||||||
n = vsscanf(s, format, arg);
|
n = vsscanf(s, format, arg);
|
||||||
|
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
// non standard realization - support for virtually change ONLY ONE char
|
||||||
|
|
||||||
|
int ungetc(int c, FILE* file)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if(!file){
|
||||||
|
errno = EBADF;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file->mode != _STDIO_F_R){
|
||||||
|
errno = EACCES;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file->position > file->start_size || file->position == 0 || c == EOF || file->__ungetc_emu_buff != EOF)
|
||||||
|
{
|
||||||
|
errno = EOF;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->__ungetc_emu_buff = c;
|
||||||
|
file->position--;
|
||||||
|
return c;
|
||||||
|
}
|
@ -1,55 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
//#include "format_scan.h"
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
// non standard realization - support for virtually change ONLY ONE char
|
|
||||||
|
|
||||||
static int __ungetc_emu(int c, FILE* stream)
|
|
||||||
{
|
|
||||||
unsigned res;
|
|
||||||
if(stream){
|
|
||||||
errno = EINVAL;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
if ((stream->mode & 3) != _STDIO_F_R && (stream->mode & _STDIO_F_A) == 0){
|
|
||||||
errno = EACCES;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
ksys_bdfe_t *file_info = malloc(sizeof(ksys_bdfe_t));
|
|
||||||
if(file_info==NULL){
|
|
||||||
errno = ENOMEM;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
if(!_ksys_file_get_info(stream->name, file_info)){
|
|
||||||
errno = ENFILE;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
if (stream->position > file_info->size || stream->position == 0 || c == EOF || stream->__ungetc_emu_buff != EOF){
|
|
||||||
errno = EOF;
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->__ungetc_emu_buff = c;
|
|
||||||
stream->position --;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __virtual_getc_file(void *sp, const void *obj)
|
|
||||||
{
|
|
||||||
FILE *f = (FILE *)obj;
|
|
||||||
int ch = fgetc(f);
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __virtual_ungetc_file(void *sp, int c, const void *obj)
|
|
||||||
{
|
|
||||||
FILE *f = (FILE *)obj;
|
|
||||||
if (f) __ungetc_emu(c, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
int vfscanf(FILE * stream, const char * format, va_list arg)
|
|
||||||
{
|
|
||||||
return _format_scan(stream, format, arg, &__virtual_getc_file, &__virtual_ungetc_file);
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
|
|
||||||
char *__scanf_buffer=NULL;
|
|
||||||
typedef int (*virtual_getc)(void *sp, const void *obj);
|
|
||||||
typedef void (*virtual_ungetc)(void *sp, int c, const void *obj);
|
|
||||||
|
|
||||||
char *__scanf_buffer;
|
|
||||||
|
|
||||||
extern int _format_scan(const void *src, const char *fmt, va_list argp, virtual_getc vgetc, virtual_ungetc vungetc);
|
|
||||||
|
|
||||||
static int __virtual_getc_con(void *sp, const void *obj)
|
|
||||||
// get next chat from string obj, save point is ptr to string char ptr
|
|
||||||
{
|
|
||||||
int ch;
|
|
||||||
const char**spc= (const char**)sp;
|
|
||||||
if (!spc) return EOF; // error
|
|
||||||
if (!*spc) *spc = __scanf_buffer; // first call, init savepoint
|
|
||||||
|
|
||||||
while (!**spc) // need to read more
|
|
||||||
{
|
|
||||||
if(!gets(__scanf_buffer)) return EOF;
|
|
||||||
*spc = __scanf_buffer;
|
|
||||||
strcat(__scanf_buffer,"\n"); // imitate delimiter
|
|
||||||
}
|
|
||||||
if (**spc == 26 || **spc == 3) // ^C ^Z end of scan, clear buffer
|
|
||||||
{
|
|
||||||
*spc = __scanf_buffer;
|
|
||||||
*__scanf_buffer = 0;
|
|
||||||
return EOF; // ^C ^Z
|
|
||||||
}
|
|
||||||
|
|
||||||
ch = **spc; (*spc)++ ;
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __virtual_ungetc_con(void *sp, int c, const void *obj)
|
|
||||||
// if can, one step back savepoint in s
|
|
||||||
{
|
|
||||||
const char**spc= (const char**)sp;
|
|
||||||
|
|
||||||
if (spc && *spc > __scanf_buffer) (*spc)--;
|
|
||||||
//printf("Ungetc '%c'[%d];", c, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int vscanf(const char * format, va_list arg)
|
|
||||||
{
|
|
||||||
return _format_scan(NULL, format, arg, &__virtual_getc_con, &__virtual_ungetc_con);
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
//#include "format_scan.h"
|
|
||||||
|
|
||||||
static int __virtual_getc_str(void *sp, const void *obj)
|
|
||||||
// get next chat from string obj, save point is ptr to string char ptr
|
|
||||||
{
|
|
||||||
int ch;
|
|
||||||
const char *s = (const char *)obj;
|
|
||||||
const char**spc= (const char**)sp;
|
|
||||||
if (!s || !spc) return EOF; // error
|
|
||||||
|
|
||||||
if (!*spc) *spc = s; // first call, init savepoint
|
|
||||||
|
|
||||||
if (!**spc) return EOF; // EOS
|
|
||||||
|
|
||||||
ch = **spc; (*spc)++ ;
|
|
||||||
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __virtual_ungetc_str(void *sp, int c, const void *obj)
|
|
||||||
// if can, one step back savepoint in s
|
|
||||||
{
|
|
||||||
const char *s = (const char *)obj;
|
|
||||||
const char**spc= (const char**)sp;
|
|
||||||
|
|
||||||
if (s && spc && *spc > s) (*spc)--;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vsscanf(const char * s, const char * format, va_list arg)
|
|
||||||
{
|
|
||||||
return _format_scan(s, format, arg, &__virtual_getc_str, &__virtual_ungetc_str);
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user