diff --git a/libunix/Makefile b/libunix/Makefile new file mode 100644 index 0000000..e278c7e --- /dev/null +++ b/libunix/Makefile @@ -0,0 +1,61 @@ +# +# (c) 2005 Laurent Vivier +# + +TOP = $(shell pwd) +CFLAGS = -nostdlib -nodefaultlibs -Wall -Werror -Wno-multichar -fpic +CPPFLAGS = -I$(TOP) -I$(TOP)/../libmacos -DARCH_M68K + +LIBRARY = libunix.a + +SOURCES = divsi3.S modsi3.S mulsi3.S udivsi3.S umodsi3.S free.c malloc.c \ + memcpy.c memset.c printf.c putchar.c puts.c read.c sprintf.c \ + strcpy.c strlen.c strncpy.c vsprintf.c write.c + +HEADERS = + +DISTFILES = $(SOURCES) $(HEADERS) + +OBJS = $(patsubst %.S,%.o,$(SOURCES:.c=.o)) + +all: $(LIBRARY) + +$(LIBRARY): $(OBJS) + $(AR) rc $@ $^ + +install: install-headers install-lib + +install-lib: + install -d $(DESTDIR)/$(PREFIX)/usr/lib/ + install $(LIBRARY) $(DESTDIR)/$(PREFIX)/usr/lib/$(LIBRARY) + +install-headers: + for file in $(HEADERS); do \ + dir=$$(dirname $$file); \ + if [ "$$dir" != "" ] ; then \ + mkdir -p $(DESTDIR)/$(PREFIX)/usr/include/$$dir; \ + fi; \ + cp -p $$file $(DESTDIR)/$(PREFIX)/usr/include/$$file; \ + done + +uninstall: uninstall-lib uninstall-headers + +uninstall-lib: + rm -f $(DESTDIR)/$(PREFIX)/usr/lib/$(LIBRARY) + +uninstall-headers: + for file in $(HEADERS); do \ + rm -f $(DESTDIR)/$(PREFIX)/usr/include/$$file; \ + done + +dist: + for file in $(DISTFILES); do \ + dir=$$(dirname $$file); \ + if [ "$$dir" != "" ] ; then \ + mkdir -p $(DISTDIR)/libunix/$$dir; \ + fi; \ + cp -p $$file $(DISTDIR)/libunix/$$file; \ + done + +clean: + rm -f $(OBJS) $(LIBRARY) diff --git a/libunix/divsi3.S b/libunix/divsi3.S new file mode 100644 index 0000000..32a5470 --- /dev/null +++ b/libunix/divsi3.S @@ -0,0 +1,38 @@ +/* + * + * (c) 2004,2005 Laurent Vivier + * + * Some parts from libgcc routines for 68000 w/o floating-point hardware. + * Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. + * + */ + + .chip 68000 + + .align 2 + + .globl __divsi3 +__divsi3: + movel %d2, %sp@- + + moveq #1, %d2 /* sign of result stored in %d2 (=1 or =-1) */ + movel %sp@(12), %d1 /* %d1 = divisor */ + jpl __divsi3L1 + negl %d1 + negb %d2 /* change sign because divisor <0 */ +__divsi3L1: movel %sp@(8), %d0 /* %d0 = dividend */ + jpl __divsi3L2 + negl %d0 + negb %d2 + +__divsi3L2: movel %d1, %sp@- + movel %d0, %sp@- + bsr __udivsi3 /* divide abs(dividend) by abs(divisor) */ + addql #8, %sp + + tstb %d2 + jpl __divsi3L3 + negl %d0 + +__divsi3L3: movel %sp@+, %d2 + rts diff --git a/libunix/free.c b/libunix/free.c new file mode 100644 index 0000000..cc491b1 --- /dev/null +++ b/libunix/free.c @@ -0,0 +1,6 @@ +#include + +void free(void *ptr) +{ + DisposePtr(ptr); +} diff --git a/libunix/malloc.c b/libunix/malloc.c new file mode 100644 index 0000000..ad03aed --- /dev/null +++ b/libunix/malloc.c @@ -0,0 +1,7 @@ +#include +#include + +void *malloc(size_t size) +{ + return NewPtr(size); +} diff --git a/libunix/memcpy.c b/libunix/memcpy.c new file mode 100644 index 0000000..d54b707 --- /dev/null +++ b/libunix/memcpy.c @@ -0,0 +1,11 @@ +#include + +void* memcpy(void* __dest, __const void* __src, + size_t __n) +{ + int i; + char *d = (char *)__dest, *s = (char *)__src; + + for (i=0;i<__n;i++) d[i] = s[i]; + return __dest; +} diff --git a/libunix/memset.c b/libunix/memset.c new file mode 100644 index 0000000..7a3ede3 --- /dev/null +++ b/libunix/memset.c @@ -0,0 +1,10 @@ +#include + +void* memset(void* s, int c, size_t n) +{ + int i; + char *ss = (char*)s; + + for (i=0;i + * + * Some parts from libgcc routines for 68000 w/o floating-point hardware. + * Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. + * + */ + + .chip 68000 + + .align 2 + + .globl __modsi3 +__modsi3: + movel %sp@(8), %d1 /* %d1 = divisor */ + movel %sp@(4), %d0 /* %d0 = dividend */ + movel %d1, %sp@- + movel %d0, %sp@- + bsr __divsi3 + addql #8, %sp + movel %sp@(8), %d1 /* %d1 = divisor */ + movel %d1, %sp@- + movel %d0, %sp@- + bsr __mulsi3 /* %d0 = (a/b)*b */ + addql #8, %sp + movel %sp@(4), %d1 /* %d1 = dividend */ + subl %d0, %d1 /* %d1 = a - (a/b)*b */ + movel %d1, %d0 + rts diff --git a/libunix/mulsi3.S b/libunix/mulsi3.S new file mode 100644 index 0000000..538cc24 --- /dev/null +++ b/libunix/mulsi3.S @@ -0,0 +1,26 @@ +/* + * + * (c) 2004,2005 Laurent Vivier + * + * Some parts from libgcc routines for 68000 w/o floating-point hardware. + * Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. + * + */ + + .chip 68000 + + .align 2 + + .globl __mulsi3 +__mulsi3: + movew %sp@(4), %d0 /* x0 -> %d0 */ + muluw %sp@(10), %d0 /* x0*y1 */ + movew %sp@(6), %d1 /* x1 -> %d1 */ + muluw %sp@(8), %d1 /* x1*y0 */ + addl %d1, %d0 + swap %d0 + clrw %d0 + movew %sp@(6), %d1 /* x1 -> %d1 */ + muluw %sp@(10), %d1 /* x1*y1 */ + addl %d1, %d0 + rts diff --git a/libunix/printf.c b/libunix/printf.c new file mode 100644 index 0000000..30e97e2 --- /dev/null +++ b/libunix/printf.c @@ -0,0 +1,22 @@ +#include +#include + +extern void console_putstring(const char *s); + +static char __printf_buffer[2048]; + +int +printf(const char * format, ...) +{ + va_list args; + int len; + + va_start(args, format); + len = vsprintf(__printf_buffer, format, args); + va_end(args); + + if (len) + console_putstring(__printf_buffer); + + return len; +} diff --git a/libunix/putchar.c b/libunix/putchar.c new file mode 100644 index 0000000..0f21592 --- /dev/null +++ b/libunix/putchar.c @@ -0,0 +1,6 @@ +extern int console_putchar(int c); + +int putchar (int c) +{ + return console_putchar(c); +} diff --git a/libunix/puts.c b/libunix/puts.c new file mode 100644 index 0000000..7af81c8 --- /dev/null +++ b/libunix/puts.c @@ -0,0 +1,10 @@ +extern void console_putstring(const char *s); +extern int console_putchar(int c); + +int puts(const char * s) +{ + console_putstring(s); + console_putchar('\n'); + + return -1; +} diff --git a/libunix/read.c b/libunix/read.c new file mode 100644 index 0000000..8da4412 --- /dev/null +++ b/libunix/read.c @@ -0,0 +1,26 @@ +#include +#include +#include + +ssize_t read(int fd, void *buf, size_t count) +{ + int res; + ParamBlockRec param; + long available; + + res = SerGetBuf(fd, &available); + if ( (res != noErr) || (available == 0) ) + return 0; + + param.ioCompletion = 0; + param.ioVRefNum = 0; + param.ioRefNum = fd; + param.ioBuffer = (u_int32_t)buf; + param.ioReqCount= count > available ? available : count; + param.ioPosMode = fsAtMark; + param.ioPosOffset = 0; + res = PBReadSync(¶m); + if (res != noErr) + return 0; + return param.ioActCount; +} diff --git a/libunix/sprintf.c b/libunix/sprintf.c new file mode 100644 index 0000000..d2ff60a --- /dev/null +++ b/libunix/sprintf.c @@ -0,0 +1,14 @@ +#include +#include + +int sprintf(char * s, const char * format, ...) +{ + va_list params; + int r; + + va_start(params, format); + r = vsprintf(s, format, params); + va_end(params); + + return r; +} diff --git a/libunix/strcpy.c b/libunix/strcpy.c new file mode 100644 index 0000000..9f4c8e9 --- /dev/null +++ b/libunix/strcpy.c @@ -0,0 +1,7 @@ +char *strcpy (char *__restrict __dest, + __const char *__restrict __src) +{ + while ( (*__dest ++ = *__src++) ); + + return __dest; +} diff --git a/libunix/strlen.c b/libunix/strlen.c new file mode 100644 index 0000000..b00ce25 --- /dev/null +++ b/libunix/strlen.c @@ -0,0 +1,11 @@ +int strlen(const char* s) +{ + int len; + + if (!s) return 0; + + len = 0; + while (*s++) len++; + + return len; +} diff --git a/libunix/strncpy.c b/libunix/strncpy.c new file mode 100644 index 0000000..0365d2b --- /dev/null +++ b/libunix/strncpy.c @@ -0,0 +1,9 @@ +#include + +char *strncpy (char *__restrict __dest, + __const char *__restrict __src, size_t __n) +{ + while ( (*__dest ++ = *__src++) && __n--); + + return __dest; +} diff --git a/libunix/udivsi3.S b/libunix/udivsi3.S new file mode 100644 index 0000000..0c71483 --- /dev/null +++ b/libunix/udivsi3.S @@ -0,0 +1,58 @@ +/* + * + * (c) 2004,2005 Laurent Vivier + * + * Some parts from libgcc routines for 68000 w/o floating-point hardware. + * Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. + * + */ + + .chip 68000 + + .align 2 + + .globl __udivsi3 +__udivsi3: + movel %d2, %sp@- + movel %sp@(12), %d1 /* %d1 = divisor */ + movel %sp@(8), %d0 /* %d0 = dividend */ + + cmpl #0x10000, %d1 /* divisor >= 2 ^ 16 ? */ + jcc __udivsi3L3 /* then try next algorithm */ + movel %d0, %d2 + clrw %d2 + swap %d2 + divu %d1, %d2 /* high quotient in lower word */ + movew %d2, %d0 /* save high quotient */ + swap %d0 + movew %sp@(10), %d2 /* get low dividend + high rest */ + divu %d1, %d2 /* low quotient */ + movew %d2, %d0 + jra __udivsi3L6 + +__udivsi3L3: movel %d1, %d2 /* use %d2 as divisor backup */ +__udivsi3L4: lsrl #1, %d1 /* shift divisor */ + lsrl #1, %d0 /* shift dividend */ + cmpl #0x10000, %d1 /* still divisor >= 2 ^ 16 ? */ + jcc __udivsi3L4 + divu %d1, %d0 /* now we have 16-bit divisor */ + andl #0xffff, %d0 /* mask out divisor, ignore remainder */ + +/* Multiply the 16-bit tentative quotient with the 32-bit divisor. Because of + the operand ranges, this might give a 33-bit product. If this product is + greater than the dividend, the tentative quotient was too large. */ + movel %d2, %d1 + mulu %d0, %d1 /* low part, 32 bits */ + swap %d2 + mulu %d0, %d2 /* high part, at most 17 bits */ + swap %d2 /* align high part with low part */ + tstw %d2 /* high part 17 bits? */ + jne __udivsi3L5 /* if 17 bits, quotient was too large */ + addl %d2, %d1 /* add parts */ + jcs __udivsi3L5 /* if sum is 33 bits, quotient was too large */ + cmpl %sp@(8), %d1 /* compare the sum with the dividend */ + jls __udivsi3L6 /* if sum > dividend, quotient was too large */ +__udivsi3L5: subql #1, %d0 /* adjust quotient */ + +__udivsi3L6: movel %sp@+, %d2 + rts diff --git a/libunix/umodsi3.S b/libunix/umodsi3.S new file mode 100644 index 0000000..d72b439 --- /dev/null +++ b/libunix/umodsi3.S @@ -0,0 +1,30 @@ +/* + * + * (c) 2004,2005 Laurent Vivier + * + * Some parts from libgcc routines for 68000 w/o floating-point hardware. + * Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc. + * + */ + + .chip 68000 + + .align 2 + + .globl __umodsi3 +__umodsi3: + movel %sp@(8), %d1 /* %d1 = divisor */ + movel %sp@(4), %d0 /* %d0 = dividend */ + movel %d1, %sp@- + movel %d0, %sp@- + bsr __udivsi3 + addql #8, %sp + movel %sp@(8), %d1 /* %d1 = divisor */ + movel %d1, %sp@- + movel %d0, %sp@- + bsr __mulsi3 /* %d0 = (a/b)*b */ + addql #8, %sp + movel %sp@(4), %d1 /* %d1 = dividend */ + subl %d0, %d1 /* %d1 = a - (a/b)*b */ + movel %d1, %d0 + rts diff --git a/libunix/vsprintf.c b/libunix/vsprintf.c new file mode 100644 index 0000000..fdacc45 --- /dev/null +++ b/libunix/vsprintf.c @@ -0,0 +1,211 @@ +/*- + * Copyright (c) 1986, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this +software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this +software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE +LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY +WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 + * + * + * Extracted vsprinf & adapted by BenH for MountX, Wed, June 3 1998. + * Added support for pascal strings. + */ + +#include + +typedef unsigned long u_long; +typedef unsigned int u_int; +typedef unsigned char u_char; + +#define NBBY 8 + +static char *ksprintn(u_long ul, int base, int *lenp, int prec); + +/* + * Scaled down version of sprintf(3). + */ +int +vsprintf(char *buf, const char *cfmt, va_list ap) +{ + register const char *fmt = cfmt; + register char *p, *bp; + register int ch, base; + u_long ul; + int lflag, tmp, width, pstring; + int prec, precspec; + char padc; + + for (bp = buf; ; ) { + padc = ' '; + width = 0; + prec = 0; + precspec = 0; + pstring = 0; + while ((ch = *(u_char *)fmt++) != '%') + if ((*bp++ = (char)ch) == '\0') + return ((bp - buf) - 1); + + lflag = 0; +reswitch: switch (ch = *(u_char *)fmt++) { + case '0': + padc = '0'; + goto reswitch; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + for (width = 0;; ++fmt) { + width = width * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + goto reswitch; + + case '#': + pstring = 1; + goto reswitch; + case '*': + width = va_arg(ap, int); + goto reswitch; + case '.': + precspec = 1; + if (*fmt == '*') { + prec = va_arg(ap, int); + ++fmt; + goto reswitch; + } + for (prec = 0;; ++fmt) { + ch = *fmt; + if (ch < '0' || ch > '9') + break; + prec = prec * 10 + ch - '0'; + } + goto reswitch; + case 'l': + lflag = 1; + goto reswitch; + /* case 'b': ... break; XXX */ + case 'c': + *bp++ = (char)va_arg(ap, int); + break; + /* case 'r': ... break; XXX */ + case 's': + p = va_arg(ap, char *); + if (pstring) + { + prec = precspec ? ((prec < *p) ? prec : *p) : *p; + p++; + precspec = 1; + } + while ((!precspec || (--prec >= 0)) && ((*bp = *p++) != 0)) + ++bp; + break; + case 'd': + ul = (unsigned long)(lflag ? va_arg(ap, long) : va_arg(ap, int)); + if ((long)ul < 0) { + *bp++ = (char)'-'; + ul = (unsigned long)(-(long)ul); + } + base = 10; + goto number; + break; + case 'o': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, +u_int); + base = 8; + goto number; + break; + case 'u': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, +u_int); + base = 10; + goto number; + break; + case 'p': + *bp++ = '0'; + *bp++ = 'x'; + ul = (u_long)va_arg(ap, void *); + base = 16; + goto number; + case 'x': + case 'X': + ul = lflag ? va_arg(ap, u_long) : va_arg(ap, +u_int); + base = 16; +number: p = ksprintn(ul, base, &tmp, prec); + if (width && (width -= tmp) > 0) + while (width--) + *bp++ = padc; + while ((ch = *p--) != 0) + *bp++ = (char)ch; + break; + default: + *bp++ = '%'; + if (lflag) + *bp++ = 'l'; + /* FALLTHROUGH */ + case '%': + *bp++ = (char)ch; + } + } +} + +/* + * Put a number (base <= 16) in a buffer in reverse order; return an + * optional length and a pointer to the NULL terminated (preceded?) + * buffer. + */ +static char * +ksprintn(u_long ul, int base, int *lenp, int prec) +{ /* A long in base 8, plus NULL. */ + static char buf[sizeof(long) * NBBY / 3 + 4]; + register char *p; + int i; + p = buf; + for(i=0;i 0 || ul != 0) && p < buf + sizeof(buf) - 1); + if (lenp) + *lenp = p - buf; + return (p); +} diff --git a/libunix/write.c b/libunix/write.c new file mode 100644 index 0000000..308a95c --- /dev/null +++ b/libunix/write.c @@ -0,0 +1,21 @@ +#include +#include + +ssize_t write(int fd, const void *buf, size_t count) +{ + int res; + ParamBlockRec param; + + param.ioCompletion = 0; + param.ioVRefNum = 0; + param.ioRefNum = fd; + param.ioBuffer = (u_int32_t)buf; + param.ioReqCount= count; + param.ioPosMode = fsAtMark; + param.ioPosOffset = 0; + res = PBWriteSync(¶m); + if (res != noErr) + return 0; + + return param.ioActCount; +} diff --git a/second/misc.c b/second/misc.c index 0078650..a11c056 100644 --- a/second/misc.c +++ b/second/misc.c @@ -4,59 +4,13 @@ * */ +#include #include #include #include "misc.h" #include "console.h" -int strlen(const char* s) -{ - int len; - - if (!s) return 0; - - len = 0; - while (*s++) len++; - - return len; -} - -void* memset(void* s, int c, size_t n) -{ - int i; - char *ss = (char*)s; - - for (i=0;i