**************************************** * STARLET.C * * (C) 1999 Chang Il-kyu * * * * starletsoft@hotmail.com * **************************************** #define _FAR far typedef void _FAR *va_list; typedef unsigned size_t; #define NULL 0 #define __size(x) ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int)-1)) #define va_start(ap, parmN) ((void)((ap) = (va_list)((char _FAR *)(&parmN)+__size(parmN)))) #define va_arg(ap, type) (*(type _FAR *)(((*(char _FAR *_FAR *)&(ap))+=__size(type))-(__size(type)))) #define va_end(ap) ((void)0) #define MK_FP( seg,ofs )( (void _seg * )( seg ) +( void near * )( ofs )) #define FP_SEG( fp )( (unsigned )( void _seg * )( void far * )( fp )) #define FP_OFF( fp )( (unsigned )( fp )) #define _LEFT 0x0001 #define _WIDTH 0x0002 #define _PRECISION 0x0004 #define _ZERO 0x0008 #define _NUM 0x0010 #define is_digit(x) ((x)>='0' && (x) <='9') #define is_hex(x) ( ((x)>='0' && (x)<='9') || ((x)>='a' && (x)<='f') || ((x)>='A' && (x)<='F') ) #define is_atof(x) ((x)>='a' && (x)<='f') #define is_ATOF(x) ((x)>='A' && (x)<='F') #pragma inline static unsigned char _MaxCylinder; extern _heapbase, _heaplength, _stacklength; typedef struct heapstruct { unsigned short size; void *curr; struct heapstruct *prev; struct heapstruct *next; } localheap; localheap *_heaphead = NULL; char *strcpy(char *dest, const char *src) { while (*src) *dest++ = *src++; *dest = NULL; return dest; } char *strncpy(char *dest, const char *src, size_t maxlen) { while (maxlen--) *dest++ = *src++; return dest; } int strcmp(const char *s1, const char *s2) { while (*s1 == *s2++) if (*s1++ == 0) return (0); return (*(unsigned char *)s1 - *(unsigned char *)--s2); } void *memcpy(void *dest, const void *src, register size_t n) { register char *d = (char *) dest; register const char *s = (char *) src; if (n) while (n-- > 0) *d++ = *s++; return dest; } void *memmove(void *dest, const void *src, register size_t n) { register char *p1 = (char *) dest; register const char *p2 = (char *) src; if (n > 0) { if (p2 <= p1 && p2 + n > p1) { p1 += n; p2 += n; while (n-- > 0) *--p1 = *--p2; } else while (n-- > 0) *p1++ = *p2++; } return dest; } void *memset(void *s, int c, size_t n) { char *s1 = (char *) s; if (n > 0) while (n-- > 0) *s1++ = c; return s; } char *strchr(const char *s, int c) { while (*s) { if (*s == c) return (char *) s; s++; } return (char *) NULL; } size_t strlen(const char *s) { int len = 0; while (*s++) len++; return len; } void *malloc(size_t size) { localheap *n_heap, *t_heap; size_t gap, newsize; if (!size) return (void*)NULL; if (!_heaphead) { n_heap = (localheap*) _heapbase; n_heap->size = size + sizeof(localheap); if ( n_heap->size > _heaplength) return (void*)NULL; n_heap = (localheap *) _heapbase; n_heap->next = n_heap->prev = NULL; n_heap->curr = (void *) ((unsigned) n_heap + sizeof(localheap)); _heaphead = n_heap; return (void *) n_heap->curr; } else { n_heap = _heaphead; gap = (unsigned int) n_heap - _heapbase; newsize = size + sizeof(localheap); if (gap>=newsize) /* Insert */ { t_heap = (localheap*) _heapbase; t_heap->prev = NULL; t_heap->next = n_heap; n_heap->prev = t_heap; t_heap->curr = (void*) (_heapbase + sizeof(localheap)); t_heap->size = newsize; _heaphead = t_heap; return (void *) t_heap->curr; } while (n_heap->next) { gap = ((unsigned int) n_heap->next) - ((unsigned int) n_heap + n_heap->size); newsize = size + sizeof(localheap); if (gap>=newsize) /* Insert */ { t_heap = (localheap*) ((unsigned int) n_heap + n_heap->size); t_heap->prev = n_heap; t_heap->next = n_heap->next; n_heap->next->prev = t_heap; t_heap->curr = (void*) ((unsigned int) t_heap + sizeof(localheap)); t_heap->size = newsize; n_heap->next = t_heap; return (void *) t_heap->curr; } n_heap = n_heap->next; } /* End while */ gap = (unsigned int) n_heap + n_heap->size; gap = _heapbase + _heaplength - gap; newsize = size + sizeof(localheap); if (gapsize); n_heap->next = t_heap; t_heap->prev = n_heap; t_heap->next = NULL; t_heap->curr = (void*) ((unsigned int) t_heap + sizeof(localheap)); t_heap->size = newsize; return t_heap->curr; } } void free(void *block) { localheap *t_heap = _heaphead; if (!t_heap) return; do { if (t_heap->curr == block) { if (!t_heap->prev) { if (!t_heap->next) _heaphead = NULL; else { _heaphead = t_heap->next; t_heap->next->prev = NULL; } return; } else if (!t_heap->next) { t_heap->prev->next = NULL; return; } else { t_heap->prev->next = t_heap->next; t_heap->next->prev = t_heap->prev; return; } } t_heap = t_heap->next; } while (t_heap); } void *calloc(size_t nitems, size_t size) { unsigned long n_size; register char *alloc; n_size = (unsigned long) nitems * size; alloc = (n_size > 0xFFFF) ? NULL : (char *) malloc((unsigned) n_size); if(alloc) memset(alloc, 0, (unsigned) n_size); return (void*) alloc; } void *realloc(void *block, size_t size) { void *tmp; if ( (tmp = malloc(size)) == NULL ) return (void *) NULL; tmp = memmove(tmp, block, size); free(block); return tmp; } char* _Format(char *source, char *string, int flag, int width, int precision) { char tmp[25]; int index = 0, idx = 0; if (flag & _NUM) { tmp[idx++] = '0'; tmp[idx++] = 'x'; } /* # */ if ((flag & _PRECISION)) while ( (idx (--idx)) && (flag & _WIDTH) ) { if (flag & _LEFT) { index = 0; while (tmp[index]) string[index] = tmp[index++]; while (index < (width)) if (flag & _ZERO) string[index++] = '0'; else string[index++] = ' '; } else { index = 0; while (index < (width-idx-1)) if (flag & _ZERO) string[index++] = '0'; else string[index++] = ' '; idx = 0; while (tmp[idx]) string[index++] = tmp[idx++]; } } else { index = 0; while (tmp[index]) string[index] = tmp[index++]; } string[index] = 0; return string; } int vsprintf(char *buffer, const char *format, va_list args) { int flag=0, precision = 0, width = 0, idx; char nstr[25], tmp[66]; char *loc; while (*format) { if (*format == '%') { loc = (char *) format; flag = 0; format++; if (*format == '-') { flag |= _LEFT; format++; } if (*format == '#') { flag |= _NUM; format++; } if (*format == '0') { flag |= _ZERO; format++; } if (is_digit(*format)) { idx = 0; while (is_digit(*format)) nstr[idx++] = *format++; nstr[idx] = NULL; flag |= _WIDTH; width = (int) str2long(nstr); } if (*format == '.') { format++; idx = 0; while (is_digit(*format)) nstr[idx++] = *format++; nstr[idx] = NULL; flag |= _PRECISION; precision = (int) str2long(nstr); } switch(*format) { case 'i' : case 'd' : itoa(va_arg(args, int), nstr, 10); _Format(nstr, tmp, flag, width, precision); break; case 'u' : ultoa((unsigned long) va_arg(args, unsigned int), nstr, 10); _Format(nstr, tmp, flag, width, precision); break; case 'l' : if (*++format == 'u') { ultoa((unsigned long) va_arg(args, unsigned long), nstr, 10); _Format(nstr, tmp, flag, width, precision); } else { tmp[0] = '%'; tmp[1] = NULL; format = loc; } break; case 'o' : ultoa((unsigned long) va_arg(args, unsigned int), nstr, 8); _Format(nstr, tmp, flag, width, precision); break; case 'x' : ultox((unsigned long) va_arg(args, unsigned int), nstr, 0); _Format(nstr, tmp, flag, width, precision); break; case 'X' : ultox((unsigned long) va_arg(args, unsigned int), nstr, 1); _Format(nstr, tmp, flag, width, precision); break; case 'p' : ultox((unsigned long) va_arg(args, void *), nstr, 1 /* Caps */); _Format(nstr, tmp, flag, width, precision); break; case 'c' : nstr[0] = va_arg(args, char); nstr[1] = NULL; _Format(nstr, tmp, flag, width, precision); break; case 's' : _Format((char*) va_arg(args, char *), tmp, flag, width, precision); break; case '%' : break; default : tmp[0] = '%'; tmp[1] = NULL; format = loc; break; } idx = 0; while (tmp[idx]) *buffer++ = tmp[idx++]; format++; } else *buffer++ = *format++; } *buffer = NULL; return ((int) (format - buffer)); } int sprintf(char * buf, const char *format, ...) { va_list args; int i; va_start(args, format); i=vsprintf(buf,format,args); va_end(args); return i; } int putchar(int chr) { char far* memaddr; int tmp; if (chr == '\n') _CR(); else { asm { pusha push ds mov ah, 09h mov al, byte ptr chr mov bh, byte ptr _pagenum mov bl, byte ptr _background shl bl, 4 or bl, byte ptr _color mov cx, 1 int 10h pop ds popa } memaddr = (char far*) 0x00000450UL; tmp = (*memaddr)+2; if (tmp>_scrx2) _CR(); else *memaddr = tmp-1; } return chr; } void outchar(char chr) { if (chr == '\n') _CR(); else { asm { mov ah, 0eh mov al, byte ptr chr mov bh, byte ptr _pagenum mov bl, 7 int 10h } } } int puts(const char *str) { while (*str) putchar(*str++); return (int) str; } int putstr(const char *str) { while (*str) outchar(*str++); return (int) str; } int printf(const char* format, ...) { char *buf; va_list args; int i; buf = (char*) malloc(256); va_start(args, format); i=vsprintf(buf,format,args); va_end(args); putstr(buf); free(buf); return i; } int cprintf(const char* format, ...) { char *buf; va_list args; int i; buf = (char*) malloc(256); va_start(args, format); i=vsprintf(buf,format,args); va_end(args); puts(buf); free(buf); return i; } char *strcat(char *source, const char *dest) { register char *cat = source; for (; *source; ++source); while (*dest) *source++=*dest++; *source = (char) NULL; return (cat); }