Initial version of Sortix.
This commit is contained in:
commit
9b79673dcb
|
@ -0,0 +1,113 @@
|
|||
ifndef CPU
|
||||
CPU=x86
|
||||
endif
|
||||
|
||||
REMOTE=192.168.2.6
|
||||
REMOTEUSER=sortie
|
||||
REMOTECOPYDIR:=/home/$(REMOTEUSER)/Desktop/MaxsiOS
|
||||
MODULES=libmaxsi hello sortix
|
||||
|
||||
VERSION=0.4
|
||||
DEBNAME:=sortix_$(VERSION)_$(CPU)
|
||||
DEBSRCNAME:=sortix_$(VERSION)
|
||||
DEBDIR:=builds/$(DEBNAME)
|
||||
DEBSRCDIR:=builds/$(DEBSRCNAME)-src
|
||||
DEBFILE:=builds/$(DEBNAME).deb
|
||||
PACKAGENAME:=sortix
|
||||
ISODIR:=builds/$(DEBNAME)-iso
|
||||
ISOFILE:=builds/$(DEBNAME).iso
|
||||
JSNAME:=jssortix_$(VERSION)_$(CPU).bin
|
||||
|
||||
all:
|
||||
(for D in $(MODULES); do $(MAKE) all $(MFLAGS) --directory $$D; done)
|
||||
clean:
|
||||
(for D in $(MODULES); do $(MAKE) clean $(MFLAGS) --directory $$D; done)
|
||||
|
||||
distclean: clean cleanbuilds
|
||||
|
||||
cleanbuilds:
|
||||
rm -rf builds/
|
||||
rm -f sortix.iso
|
||||
|
||||
everything: all deb iso jssortix
|
||||
|
||||
# Local machine
|
||||
|
||||
install: all
|
||||
cp sortix/sortix.bin /boot
|
||||
cp debsrc/etc/grub.d/42_sortix /etc/grub.d/42_sortix
|
||||
chmod +x /etc/grub.d/42_sortix
|
||||
update-grub
|
||||
|
||||
uninstall:
|
||||
rm -f /boot/sortix.bin
|
||||
rm -f /etc/grub.d/42_sortix
|
||||
update-grub
|
||||
|
||||
# Remote machine
|
||||
|
||||
install-remote: all
|
||||
scp -r ./ $(REMOTE):$(REMOTECOPYDIR)
|
||||
scp sortix/sortix.bin root@$(REMOTE):/boot
|
||||
ssh root@$(REMOTE) "init 6"
|
||||
|
||||
uninstall-remote:
|
||||
ssh root@$(REMOTE) "rm /boot/sortix.bin"
|
||||
|
||||
# Packaging
|
||||
|
||||
deb: debfile debsource
|
||||
|
||||
debfile: all
|
||||
rm -rf $(DEBDIR)
|
||||
mkdir -p $(DEBDIR)
|
||||
cp -r debsrc/. $(DEBDIR)
|
||||
mkdir -p $(DEBDIR)/boot
|
||||
cp sortix/sortix.bin $(DEBDIR)/boot
|
||||
cat debsrc/DEBIAN/control | \
|
||||
sed "s/SORTIX_PACKAGE_NAME/$(PACKAGENAME)/g" | \
|
||||
sed "s/SORTIX_VERSION/$(VERSION)/g" | \
|
||||
sed "s/SORTIX_ARCH/all/g" | \
|
||||
cat > $(DEBDIR)/DEBIAN/control
|
||||
dpkg --build $(DEBDIR) $(DEBFILE)
|
||||
rm -rf $(DEBDIR)/DEBIAN
|
||||
(cd builds/$(DEBNAME) && tar cfzv ../$(DEBNAME).tar.gz `ls`)
|
||||
rm -rf $(DEBDIR)
|
||||
|
||||
debsource: all
|
||||
rm -rf $(DEBSRCDIR)
|
||||
mkdir -p $(DEBSRCDIR)
|
||||
for D in `ls | grep -v builds`; do cp -r $$D $(DEBSRCDIR); done
|
||||
(cd $(DEBSRCDIR) && make distclean)
|
||||
(cd builds && tar cfzv $(DEBSRCNAME)-src.tar.gz $(DEBSRCNAME)-src)
|
||||
rm -rf $(DEBSRCDIR)
|
||||
|
||||
jssortix: all
|
||||
mkdir -p builds
|
||||
$(MAKE) jssortix $(MFLAGS) --directory sortix
|
||||
cp sortix/jssortix.bin builds/$(JSNAME)
|
||||
|
||||
# Bootable images
|
||||
|
||||
iso: all debsource
|
||||
rm -rf $(ISODIR)
|
||||
mkdir -p builds
|
||||
mkdir -p $(ISODIR)
|
||||
cp -r isosrc/. $(ISODIR)
|
||||
cp sortix/sortix.bin $(ISODIR)/boot
|
||||
cp hello/hello $(ISODIR)/boot/sortix.initrd
|
||||
cp builds/$(DEBSRCNAME)-src.tar.gz $(ISODIR)
|
||||
grub-mkrescue -o $(ISOFILE) $(ISODIR)
|
||||
rm -rf $(ISODIR)
|
||||
|
||||
sortix.iso: iso
|
||||
cp $(ISOFILE) sortix.iso
|
||||
|
||||
# Virtualization
|
||||
run-virtualbox: sortix.iso
|
||||
virtualbox --startvm sortix
|
||||
|
||||
run-virtualbox-debug: sortix.iso
|
||||
virtualbox --debug --start-running --startvm sortix
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Package: SORTIX_PACKAGE_NAME
|
||||
Version: SORTIX_VERSION
|
||||
Section: kernel
|
||||
Priority: optional
|
||||
Architecture: SORTIX_ARCH
|
||||
Essential: no
|
||||
Recommends: grub2, xorriso
|
||||
Provides: sortix
|
||||
Maintainer: Jonas Termansen [sortie@maxsi.org]
|
||||
Description: Sortix is a small hobby kernel developed for the heck of it.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
update-grub
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
if [ "$1" != "upgrade" ]; then update-grub; fi
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
if [ -f /boot/sortix.bin ]; then
|
||||
echo "Found Sortix kernel: /boot/sortix" >&2
|
||||
|
||||
cat << EOF
|
||||
menuentry "Sortix" {
|
||||
multiboot /boot/sortix.bin
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# This is a bit bothersome design, but it should serve well enough as a simple
|
||||
# cross-compiler for the Sortix operating system.
|
||||
|
||||
ifndef CPU
|
||||
CPU=x86
|
||||
endif
|
||||
|
||||
ifeq ($(CPU),x86)
|
||||
X86FAMILY=1
|
||||
CPUDEFINES=-DPLATFORM_X86
|
||||
CPUFLAGS=-m32
|
||||
CPULDFLAGS=-melf_i386
|
||||
endif
|
||||
|
||||
ifeq ($(CPU),x64)
|
||||
X86FAMILY=1
|
||||
CPUDEFINES=-DPLATFORM_X64
|
||||
CPUFLAGS=-m64
|
||||
CPULDFLAGS=-melf_x86_64
|
||||
endif
|
||||
|
||||
LIBMAXSIROOT=../libmaxsi
|
||||
|
||||
INCLUDES=-I $(LIBMAXSIROOT)/c/h/ -I ../
|
||||
CPPFLAGS=$(CPUDEFINES)
|
||||
|
||||
LD=ld
|
||||
LDFLAGS=$(CPULDFLAGS) -Ttext 400000 $(LIBMAXSIROOT)/start.o
|
||||
CC=gcc
|
||||
CFLAGS=$(CPUFLAGS) -nostdinc -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-stack-protector $(INCLUDES)
|
||||
CXX=g++
|
||||
CXXFLAGS=$(CPUFLAGS) -nostdinc -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector $(INCLUDES)
|
||||
LIBC=$(LIBMAXSIROOT)/libc.a
|
||||
|
||||
all: hello
|
||||
|
||||
hello: hello.o
|
||||
$(LD) $(LDFLAGS) hello.o -o hello.tmp $(LIBC)
|
||||
objcopy -O binary hello.tmp hello
|
||||
|
||||
hello.o: hello.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -O2 -c hello.c -o hello.o
|
||||
|
||||
clean:
|
||||
rm -f hello.tmp hello.o hello
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("\e[m\e[0J");
|
||||
printf("OH MY GOD! Sortix can load programs!\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
insmod part_msdos
|
||||
insmod ext2
|
||||
insmod png
|
||||
|
||||
if loadfont /boot/grub/fonts/unicode.pf2 ; then
|
||||
set gfxmode=800x600
|
||||
insmod vbe
|
||||
insmod vga
|
||||
insmod gfxterm
|
||||
fi
|
||||
terminal_output gfxterm
|
||||
|
||||
if background_image /boot/grub/sortix.png ; then
|
||||
set color_normal=white/black
|
||||
set color_highlight=white/light-gray
|
||||
else
|
||||
set menu_color_normal=white/black
|
||||
set menu_color_highlight=white/light-gray
|
||||
fi
|
||||
|
||||
set timeout=10
|
||||
set default="0"
|
||||
|
||||
menuentry "Sortix" {
|
||||
multiboot /boot/sortix.bin
|
||||
module /boot/sortix.initrd
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 149 KiB |
|
@ -0,0 +1,135 @@
|
|||
ifndef CPU
|
||||
CPU=x86
|
||||
endif
|
||||
|
||||
ifeq ($(CPU),x86)
|
||||
CPUDEFINES=-DPLATFORM_X86
|
||||
CPUFLAGS=-m32
|
||||
CPULDFLAGS=-melf_i386
|
||||
CPUASFLAGS=-32
|
||||
CPUNASMFLAGS=-felf32
|
||||
endif
|
||||
|
||||
ifeq ($(CPU),x64)
|
||||
CPU=x64
|
||||
CPUDEFINES=-DPLATFORM_X64
|
||||
CPUFLAGS=-fPIC -m64
|
||||
CPULDFLAGS=-melf_x86_64
|
||||
CPUASFLAGS=-64
|
||||
CPUNASMFLAGS=-felf64
|
||||
endif
|
||||
|
||||
DEFINES=-DLIBMAXSI_LIBRARY -DSORTIX $(CPUDEFINES)
|
||||
FLAGSRELEASE=-O2
|
||||
FLAGSDEBUG=-O2
|
||||
FLAGS=$(CPUFLAGS) -std=gnu++0x -Wall -Wextra -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-stack-protector -nostdinc $(FLAGSRELEASE) $(DEFINES)
|
||||
LDFLAGS=$(CPULDFLAGS)
|
||||
ASFLAGS=$(CPUASFLAGS)
|
||||
NASMFLAGS=$(CPUNASMFLAGS)
|
||||
|
||||
COBJS=c/file.o
|
||||
CHEADERS=\
|
||||
c/h/unistd.h \
|
||||
c/h/stdlib.h \
|
||||
c/h/wchar.h \
|
||||
c/h/stddef.h \
|
||||
c/h/fcntl.h \
|
||||
c/h/stdarg.h \
|
||||
c/h/wctype.h \
|
||||
c/h/features.h \
|
||||
c/h/string.h \
|
||||
c/h/sys/stat.h \
|
||||
c/h/sys/types.h \
|
||||
c/h/stdio.h
|
||||
|
||||
COMMONOBJS=c++.o thread.o io.o memory.o string.o error.o format.o
|
||||
SORTIXOBJS:=$(addprefix sortix/,$(COMMONOBJS))
|
||||
LIBMAXSIOBJS:=$(COMMONOBJS)
|
||||
HEADERS=error.h io.h memory.h platform.h string.h syscall.h thread.h types.h format.h
|
||||
|
||||
OBJS:=$(LIBMAXSIOBJS)
|
||||
BINS:=libmaxsi.so
|
||||
|
||||
ifndef LIBMAXSI_NO_STATIC
|
||||
BINS:=$(BINS) libmaxsi.a
|
||||
endif
|
||||
|
||||
ifndef LIBMAXSI_NO_SORTIX
|
||||
BINS:=$(BINS) libmaxsi-sortix.a start.o
|
||||
endif
|
||||
|
||||
ifndef LIBMAXSI_NO_LIBC
|
||||
OBJS:=$(OBJS) $(COBJS)
|
||||
BINS:=$(BINS) libc.so
|
||||
ifndef LIBMAXSI_NO_STATIC
|
||||
BINS:=$(BINS) libc.a
|
||||
endif
|
||||
|
||||
HEADERS:=$(HEADERS) $(CHEADERS)
|
||||
|
||||
else
|
||||
DEFINES:=$(DEFINES) -DLIBMAXSI_NO_LIBC
|
||||
endif
|
||||
|
||||
CFLAGS:=$(FLAGS) -std=c99 -Ic/h -I..
|
||||
CXXFLAGS:=$(FLAGS) -nostdinc++ -fno-rtti -I.. -Ic/h
|
||||
SORTIXFLAGS:=$(CXXFLAGS) -DSORTIX_KERNEL -I.. -I../..
|
||||
|
||||
all: $(BINS)
|
||||
|
||||
libmaxsi.a: $(OBJS)
|
||||
ar rcs libmaxsi.a $(OBJS)
|
||||
|
||||
libmaxsi.so: $(OBJS)
|
||||
ld $(LDFLAGS) -shared -o $@ $(OBJS)
|
||||
|
||||
libmaxsi-sortix.a: $(SORTIXOBJS)
|
||||
ar rcs libmaxsi-sortix.a $(SORTIXOBJS)
|
||||
|
||||
libc.a: libmaxsi.a
|
||||
ln -sf $< $@
|
||||
|
||||
libc.so: libmaxsi.so
|
||||
ln -sf $< $@
|
||||
|
||||
# libmaxsi
|
||||
|
||||
*.cpp: $(HEADERS)
|
||||
|
||||
%.o: %.cpp
|
||||
g++ -c $< -o $@ $(CXXFLAGS)
|
||||
|
||||
%.h: hsrc/%.h
|
||||
echo "/* WARNING: This header is generated - edits will be lost! */" > $@
|
||||
mxmpp -I decl $< >> $@
|
||||
|
||||
%.o: %.s
|
||||
as $(ASFLAGS) $< -o $@
|
||||
|
||||
%.o: %.asm
|
||||
nasm $(CPUNASMFLAGS) $< -o $@
|
||||
|
||||
# libc
|
||||
|
||||
c/*.c: $(CHEADERS)
|
||||
|
||||
c/%.o: c/%.c
|
||||
gcc -c $< -o $@ $(CFLAGS)
|
||||
|
||||
c/h/%.h: c/hsrc/%.h
|
||||
echo "/* WARNING: This header is generated - edits will be lost! */" > $@
|
||||
mxmpp -I decl -I c/decl $< >> $@
|
||||
|
||||
# libmaxsi-sortix
|
||||
|
||||
sortix/*.cpp: $(HEADERS)
|
||||
|
||||
sortix/%.o: %.cpp $(HEADERS)
|
||||
g++ -c $< -o $@ $(SORTIXFLAGS)
|
||||
|
||||
sortix/%.o: sortix/%.cpp
|
||||
g++ -c $< -o $@ $(SORTIXFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o sortix/*.o c/*.o *.a *.so $(CHEADERS) $(HEADERS)
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
c++.cpp
|
||||
Implements required C++ stuff for use in the Sortix kernel.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
extern "C" void __cxa_pure_virtual()
|
||||
{
|
||||
// This shouldn't happen. TODO: Possibly crash the kernel here.
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
|
||||
// TODO: These two stubs are buggy!
|
||||
|
||||
// Divides two 64-bit integers in O(logN). I think.
|
||||
extern "C" uint64_t __udivdi3(uint64_t A, uint64_t B)
|
||||
{
|
||||
uint64_t ACC = 0;
|
||||
uint64_t R = 0;
|
||||
uint64_t PWR = 1;
|
||||
uint64_t EXP = B;
|
||||
|
||||
while ( EXP <= A - ACC )
|
||||
{
|
||||
R += PWR;
|
||||
ACC += EXP;
|
||||
|
||||
if ( 2 * EXP <= A - ACC )
|
||||
{
|
||||
PWR++;
|
||||
EXP *= 2;
|
||||
}
|
||||
else if ( A - ACC < B )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( A - ACC < EXP )
|
||||
{
|
||||
PWR--;
|
||||
EXP /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
// Mods two 64-bit integers in O(logN). I think.
|
||||
extern "C" uint64_t __umoddi3(uint64_t A, uint64_t B)
|
||||
{
|
||||
uint64_t ACC = 0;
|
||||
uint64_t R = 0;
|
||||
uint64_t PWR = 1;
|
||||
uint64_t EXP = B;
|
||||
|
||||
while ( EXP <= A - ACC )
|
||||
{
|
||||
R += PWR;
|
||||
ACC += EXP;
|
||||
|
||||
if ( 2 * EXP <= A - ACC )
|
||||
{
|
||||
PWR++;
|
||||
EXP *= 2;
|
||||
}
|
||||
else if ( A - ACC < B )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( A - ACC < EXP )
|
||||
{
|
||||
PWR--;
|
||||
EXP /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return A - ACC;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef _FILE_DECL
|
||||
#define _FILE_DECL
|
||||
struct _IO_FILE;
|
||||
typedef struct _IO_FILE FILE;
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1 /* Seek from current position. */
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 2 /* Seek from end of file. */
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef WEOF
|
||||
#define WEOF (-1)
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _USECONDS_T_DECL
|
||||
#define _USECONDS_T_DECL
|
||||
typedef __useconds_t useconds_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _WCTRANS_T_DECL
|
||||
#define _WCTRANS_T_DECL
|
||||
typedef __wctrans_t wctrans_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _WCTYPE_T_DECL
|
||||
#define _WCTYPE_T_DECL
|
||||
typedef __wctype_t wctype_t;
|
||||
#endif
|
|
@ -0,0 +1,305 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
file.c
|
||||
Implements every related to the FILE structure. This API is not compatible
|
||||
enough with LibMaxsi's design goals, so it is implemented as a layer upon
|
||||
the C functions in LibMaxsi.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if 0
|
||||
|
||||
// TODO: Make a real errno system!
|
||||
volatile int errno;
|
||||
#define EINVAL 1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
off_t pos;
|
||||
mbstate_t state;
|
||||
} _fpos_t;
|
||||
|
||||
struct _IO_FILE
|
||||
{
|
||||
int fd;
|
||||
_fpos_t pos;
|
||||
};
|
||||
|
||||
// TODO: Actually implement these stubs.
|
||||
|
||||
char* fgets(char* restrict s, int n, FILE* restrict stream)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE* fdopen(int fildes, const char* mode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *fmemopen(void* restrict buf, size_t size, const char* restrict mode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE* fopen(const char* restrict filename, const char* restrict mode)
|
||||
{
|
||||
int len;
|
||||
if ( mode[0] == '\0' ) { errno = EINVAL; return NULL; } else
|
||||
if ( mode[1] == '\1' ) { len = 1; } else
|
||||
if ( mode[2] == '\0' ) { len = 2; }
|
||||
if ( mode[3] == '\0' ) { len = 3; } else { errno = EINVAL; return NULL; }
|
||||
|
||||
int oflags;
|
||||
|
||||
if ( len == 1 || (len == 2 && mode[1] == 'b') )
|
||||
{
|
||||
switch ( mode[0] )
|
||||
{
|
||||
case 'r': oflags = O_RDONLY; break;
|
||||
case 'w': oflags = O_WRONLY | O_TRUNC | O_CREAT; break;
|
||||
case 'a': oflags = O_WRONLY | O_APPEND | O_CREAT; break;
|
||||
default: errno = EINVAL; return NULL;
|
||||
}
|
||||
}
|
||||
else if ( (len == 2 && mode[1] == '+') || (len == 3 && mode[1] == '+' && mode[1] == 'b') || (len == 3 && mode[1] == 'b' && mode[1] == '+') )
|
||||
{
|
||||
switch ( mode[0] )
|
||||
{
|
||||
case 'r': oflags = O_RDWR; break;
|
||||
case 'w': oflags = O_RDWR | O_TRUNC | O_CREAT; break;
|
||||
case 'a': oflags = O_RDWR | O_APPEND | O_CREAT; break;
|
||||
default: errno = EINVAL; return NULL;
|
||||
}
|
||||
}
|
||||
else { errno = EINVAL; return NULL; }
|
||||
|
||||
// TODO: Does anything else modify this mask?
|
||||
// TODO: POSIX says this should be "S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH",
|
||||
// but Linux applies this in a simple test case!
|
||||
mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
|
||||
|
||||
FILE* file = malloc(sizeof(FILE));
|
||||
|
||||
if ( file == NULL ) { return NULL; }
|
||||
|
||||
int fd = open(filename, oflags, perms);
|
||||
|
||||
if ( fd < 0 ) { free(file); return NULL; }
|
||||
|
||||
file->fd = fd;
|
||||
// TODO: set other stuff here!
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
FILE* freopen(const char* restrict filename, const char *restrict mode, FILE* restrict stream)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE* popen(const char* command, const char* mode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE* tmpfile(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fclose(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int feof(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ferror(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fflush(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fgetc(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fgetpos(FILE* restrict stream, fpos_t* restrict pos)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fileno(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fprintf(FILE* restrict stream, const char* restrict format, ...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fputc(int c, FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fputs(const char* restrict s, FILE* restrict stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fscanf(FILE* restrict stream, const char* restrict format, ... )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fseek(FILE* stream, long offset, int whence)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fseeko(FILE* stream, off_t offset, int whence)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fsetpos(FILE* stream, const fpos_t* pos)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ftrylockfile(FILE* file)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getc(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getc_unlocked(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pclose(FILE* steam)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int putc(int c, FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int putc_unlocked(int c, FILE* steam)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int setvbuf(FILE* restrict stream, char* restrict buf, int type, size_t size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ungetc(int c, FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int vfprintf(FILE* restrict stream, const char* restrict format, va_list ap)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int vfscanf(FILE* restrict stream, const char* restrict format, va_list arg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int vprintf(FILE* restrict stream, const char* restrict format, va_list ap)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
long ftell(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
off_t ftello(FILE* stream)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t fread(void* restrict ptr, size_t size, size_t nitems, FILE* restrict stream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t fwrite(const void* restrict ptr, size_t size, size_t nitems, FILE* restrict stream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clearerr(FILE* stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void flockfile(FILE* file)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void funlockfile(FILE* file)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void rewind(FILE* stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void setbuf(FILE* restrict stream, char* restrict buf)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
fcntl.h
|
||||
File control options.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
/* TODO: POSIX-1.2008 compliance is only partial */
|
||||
|
||||
#ifndef _FCNTL_H
|
||||
#define _FCNTL_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* TODO: F_* missing here */
|
||||
|
||||
/* TODO: FD_CLOEXEC missing here */
|
||||
|
||||
/* TODO: F_RDLCK, F_UNLCK, F_WRLCK missing here */
|
||||
|
||||
@include(SEEK_SET.h)
|
||||
@include(SEEK_CUR.h)
|
||||
@include(SEEK_END.h)
|
||||
|
||||
/* TODO: Keep these aligned with those in the Sortix kernel */
|
||||
#define O_ACCMODE 0003
|
||||
#define O_RDONLY 00
|
||||
#define O_WRONLY 01
|
||||
#define O_RDWR 02
|
||||
#define O_CREAT 0100
|
||||
#define O_EXCL 0200
|
||||
#define O_NOCTTY 0400
|
||||
#define O_TRUNC 01000
|
||||
#define O_APPEND 02000
|
||||
#define O_NONBLOCK 04000
|
||||
#define O_NDELAY O_NONBLOCK
|
||||
#define O_SYNC 04010000
|
||||
#define O_FSYNC O_SYNC
|
||||
#define O_ASYNC 020000
|
||||
|
||||
@include(mode_t.h)
|
||||
@include(mode_t_values.h)
|
||||
|
||||
/* TODO: AT_FDCWD missing here */
|
||||
/* TODO: AT_EACCESS missing here */
|
||||
/* TODO: AT_SYMLINK_NOFOLLOW missing here */
|
||||
/* TODO: AT_SYMLINK_FOLLOW missing here */
|
||||
/* TODO: AT_REMOVEDIR missing here */
|
||||
|
||||
/* TODO: POSIX_FADV_* missing here */
|
||||
|
||||
@include(pid_t.h)
|
||||
|
||||
struct _flock
|
||||
{
|
||||
short l_type; /* Type of lock; F_RDLCK, F_WRLCK, F_UNLCK. */
|
||||
short l_whence; /* Type of lock; F_RDLCK, F_WRLCK, F_UNLCK. */
|
||||
off_t l_start; /* Relative offset in bytes. */
|
||||
off_t l_len; /* Size; if 0 then until EOF. */
|
||||
pid_t l_pid; /* Process ID of the process holding the lock; returned with F_GETLK. */
|
||||
};
|
||||
|
||||
typedef struct _flock flock;
|
||||
|
||||
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
||||
#ifndef SORTIX_UNIMPLEMENTED
|
||||
int creat(const char* path, mode_t mode);
|
||||
int fcntl(int fd, int cmd, ...);
|
||||
int open(const char* path, int oflag, ...);
|
||||
int openat(int fd, const char* path, int oflag, ...);
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
features.h
|
||||
Various things for various systems, programs, compabillity, and whatnot.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _FEATURES_H
|
||||
#define _FEATURES_H 1
|
||||
|
||||
/* C++ needs to know that types and declarations are C, not C++. */
|
||||
#ifdef __cplusplus
|
||||
#define __BEGIN_DECLS extern "C" {
|
||||
#define __END_DECLS }
|
||||
#else
|
||||
#define __BEGIN_DECLS
|
||||
#define __END_DECLS
|
||||
#define restrict
|
||||
#endif
|
||||
|
||||
#define __POSIX_NO_OBSOLETE
|
||||
|
||||
#ifdef __POSIX_NO_OBSOLETE
|
||||
#define __POSIX_OBSOLETE 999999L
|
||||
#else
|
||||
#define __POSIX_OBSOLETE 200112L
|
||||
#endif
|
||||
|
||||
#include <sortix/bits.h>
|
||||
|
||||
// Don't provide things from standard headers that is not implemented in libmaxsi/sortix.
|
||||
#define SORTIX_UNIMPLEMENTED
|
||||
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
stdarg.h
|
||||
Handle variable argument list
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _STDARG_H
|
||||
#define _STDARG_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@include(va_list.h)
|
||||
|
||||
#define va_start(ap, argN) ap = (void*) ((&argN) + 1)
|
||||
#define va_copy(dest, src) dest = src
|
||||
#define va_arg(ap, type) (ap = (void*) ((type*) ap) + 1, *(((type*) ap) - 1)
|
||||
#define va_end(ap) ap = null
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
stddef.h
|
||||
Standard type definitions.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _STDDEF_H
|
||||
#define _STDDEF_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@include(NULL.h)
|
||||
|
||||
#define offsetof(type, member) ((size_t) &(type)) - (size_t) (&(member)))
|
||||
|
||||
@include(ptrdiff_t.h)
|
||||
|
||||
@include(wchar_t.h)
|
||||
|
||||
@include(size_t.h)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
|
@ -0,0 +1,157 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
stdio.h
|
||||
Standard buffered input/output.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _STDIO_H
|
||||
#define _STDIO_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@include(FILE.h)
|
||||
|
||||
struct _fpos_t;
|
||||
typedef struct _fpos_t fpos_t;
|
||||
|
||||
@include(off_t.h)
|
||||
@include(size_t.h)
|
||||
@include(ssize_t.h)
|
||||
@include(va_list.h)
|
||||
@include(NULL.h)
|
||||
|
||||
/* TODO: Implement BUFSIZ */
|
||||
/* TODO: Implement L_ctermid */
|
||||
#if __POSIX_OBSOLETE <= 200801
|
||||
/* TODO: Implement L_tmpnam */
|
||||
#endif
|
||||
|
||||
/* The possibilities for the third argument to `fseek'.
|
||||
These values should not be changed. */
|
||||
@include(SEEK_SET.h)
|
||||
@include(SEEK_CUR.h)
|
||||
@include(SEEK_END.h)
|
||||
|
||||
/* The possibilities for the third argument to `setvbuf'. */
|
||||
#define _IOFBF 0 /* Fully buffered. */
|
||||
#define _IOLBF 1 /* Line buffered. */
|
||||
#define _IONBF 2 /* No buffering. */
|
||||
|
||||
#define EOF (-1)
|
||||
|
||||
/* FILENAME_MAX, FOPEN_MAX, TMP_MAX are not defined because libmaxsi and Sortix
|
||||
do not have these restrictions. */
|
||||
|
||||
/* Default path prefix for `tempnam' and `tmpnam'. */
|
||||
#if __POSIX_OBSOLETE <= 200801
|
||||
#define P_tmpdir "/tmp"
|
||||
#endif
|
||||
|
||||
extern FILE* stdin;
|
||||
extern FILE* stdout;
|
||||
extern FILE* stderr;
|
||||
|
||||
/* C89/C99 say they're macros. Make them happy. */
|
||||
#define stdin stdin
|
||||
#define stdout stdout
|
||||
#define stderr stderr
|
||||
|
||||
extern int printf(const char* restrict format, ...);
|
||||
|
||||
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
||||
#ifndef SORTIX_UNIMPLEMENTED
|
||||
extern char* ctermid(char* s);
|
||||
extern char* fgets(char* restrict s, int n, FILE* restrict stream);
|
||||
extern FILE* fdopen(int fildes, const char* mode);
|
||||
extern FILE *fmemopen(void* restrict buf, size_t size, const char* restrict mode);
|
||||
extern FILE* fopen(const char* restrict filename, const char* restrict mode);
|
||||
extern FILE* freopen(const char* restrict filename, const char *restrict mode, FILE* restrict stream);
|
||||
extern FILE* open_memstream(char** bufp, size_t* sizep);
|
||||
extern FILE* popen(const char* command, const char* mode);
|
||||
extern FILE* tmpfile(void);
|
||||
extern int dprintf(int fildes, const char* restrict format, ...);
|
||||
extern int fclose(FILE* stream);
|
||||
extern int feof(FILE* stream);
|
||||
extern int ferror(FILE* stream);
|
||||
extern int fflush(FILE* stream);
|
||||
extern int fgetc(FILE* stream);
|
||||
extern int fgetpos(FILE* restrict stream, fpos_t* restrict pos);
|
||||
extern int fileno(FILE* stream);
|
||||
extern int fprintf(FILE* restrict stream, const char* restrict format, ...);
|
||||
extern int fputc(int c, FILE* stream);
|
||||
extern int fputs(const char* restrict s, FILE* restrict stream);
|
||||
extern int fscanf(FILE* restrict stream, const char* restrict format, ... );
|
||||
extern int fseek(FILE* stream, long offset, int whence);
|
||||
extern int fseeko(FILE* stream, off_t offset, int whence);
|
||||
extern int fsetpos(FILE* stream, const fpos_t* pos);
|
||||
extern int ftrylockfile(FILE* file);
|
||||
extern int getc(FILE* stream);
|
||||
extern int getchar_unlocked(void);
|
||||
extern int getchar(void);
|
||||
extern int getc_unlocked(FILE* stream);
|
||||
extern int pclose(FILE* steam);
|
||||
extern int putchar(int c);
|
||||
extern int putchar_unlocked(int c);
|
||||
extern int putc(int c, FILE* stream);
|
||||
extern int putc_unlocked(int c, FILE* steam);
|
||||
extern int puts(const char* s);
|
||||
extern int remove(const char* path);
|
||||
extern int rename(const char* oldname, const char* newname);
|
||||
extern int renameat(int oldfd, const char* oldname, int newfd, const char* newname);
|
||||
extern int scanf(const char* restrict format, ...);
|
||||
extern int setvbuf(FILE* restrict stream, char* restrict buf, int type, size_t size);
|
||||
extern int snprintf(char* restrict s, size_t n, const char* restrict format, ...);
|
||||
extern int sprintf(char* restrict s, const char* restrict format, ...);
|
||||
extern int sscanf(const char* restrict s, const char* restrict format, ...);
|
||||
extern int ungetc(int c, FILE* stream);
|
||||
extern int vdprintf(int fildes, const char* restrict format, va_list ap);
|
||||
extern int vfprintf(FILE* restrict stream, const char* restrict format, va_list ap);
|
||||
extern int vfscanf(FILE* restrict stream, const char* restrict format, va_list arg);
|
||||
extern int vprintf(const char* restrict format, va_list ap);
|
||||
extern int vscanf(const char* restrict format, va_list arg);
|
||||
extern int vsnprintf(char* restrict, size_t, const char* restrict, va_list);
|
||||
extern int vsprintf(char* restrict s, const char* restrict format, va_list ap);
|
||||
extern int vsscanf(const char* restrict s, const char* restrict format, va_list arg);
|
||||
extern long ftell(FILE* stream);
|
||||
extern off_t ftello(FILE* stream);
|
||||
extern size_t fread(void* restrict ptr, size_t size, size_t nitems, FILE* restrict stream);
|
||||
extern size_t fwrite(const void* restrict ptr, size_t size, size_t nitems, FILE* restrict stream);
|
||||
extern ssize_t getdelim(char** restrict lineptr, size_t* restrict n, int delimiter, FILE* restrict stream);
|
||||
extern ssize_t getline(char** restrict lineptr, size_t* restrict n, FILE* restrict stream);
|
||||
extern void clearerr(FILE* stream);
|
||||
extern void flockfile(FILE* file);
|
||||
extern void funlockfile(FILE* file);
|
||||
extern void perror(const char* s);
|
||||
extern void rewind(FILE* stream);
|
||||
extern void setbuf(FILE* restrict stream, char* restrict buf);
|
||||
|
||||
#if __POSIX_OBSOLETE <= 200801
|
||||
extern char* gets(char* s);
|
||||
extern char* tmpnam(char* s);
|
||||
extern char* tempnam(const char* dir, const char* pfx);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
|
@ -0,0 +1,125 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
stdlib.h
|
||||
Standard library definitions.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _STDLIB_H
|
||||
#define _STDLIB_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#define EXIT_SUCCESS (0)
|
||||
#define EXIT_FAILURE (1)
|
||||
|
||||
/* TODO: This random interface is stupid. What should a good value be? */
|
||||
#define RAND_MAX 32767
|
||||
|
||||
/* TODO: MB_CUR_MAX is missing here */
|
||||
/* TODO: div_t, ldiv_t, and lldiv_t is missing here */
|
||||
typedef int div_t, ldiv_t, lldiv_t;
|
||||
|
||||
@include(NULL.h)
|
||||
@include(size_t.h)
|
||||
@include(wchar_t.h)
|
||||
|
||||
/* TODO: WEXITSTATUS, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, WTERMSIG, WUNTRACED is missing here */
|
||||
|
||||
/* TODO: _Exit(int) is missing here */
|
||||
|
||||
void exit(int);
|
||||
void free(void*);
|
||||
void* malloc(size_t);
|
||||
|
||||
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
||||
#ifndef SORTIX_UNIMPLEMENTED
|
||||
long a64l(const char* s);
|
||||
void abort(void);
|
||||
int abs(int value);
|
||||
int atexit(void (*function)(void));
|
||||
double atof(const char* value);
|
||||
int atoi(const char*);
|
||||
long atol(const char*);
|
||||
long long atoll(const char*);
|
||||
void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*));
|
||||
void* calloc(size_t, size_t);
|
||||
div_t div(int, int);
|
||||
double drand48(void);
|
||||
double erand48(unsigned short [3]);
|
||||
char* getenv(const char*);
|
||||
int getsubopt(char**, char* const *, char**);
|
||||
int grantpt(int);
|
||||
char* initstate(unsigned, char*, size_t);
|
||||
long jrand48(unsigned short [3]);
|
||||
char* l64a(long);
|
||||
long labs(long);
|
||||
void lcong48(unsigned short [7]);
|
||||
ldiv_t ldiv(long, long);
|
||||
long long llabs(long long);
|
||||
lldiv_t lldiv(long long, long long);
|
||||
long lrand48(void);
|
||||
int mblen(const char*, size_t);
|
||||
size_t mbstowcs(wchar_t *restrict, const char* restrict, size_t);
|
||||
int mbtowc(wchar_t *restrict, const char* restrict, size_t);
|
||||
char* mkdtemp(char*);
|
||||
int mkstemp(char*);
|
||||
long mrand48(void);
|
||||
long nrand48(unsigned short[3]);
|
||||
int posix_memalign(void**, size_t, size_t);
|
||||
int posix_openpt(int);
|
||||
char* ptsname(int);
|
||||
int putenv(char*);
|
||||
void qsort(void*, size_t, size_t, int (*)(const void*, const void*));
|
||||
int rand(void);
|
||||
long random(void);
|
||||
void* realloc(void*, size_t);
|
||||
char* realpath(const char* restrict, char* restrict);
|
||||
unsigned short *seed48(unsigned short [3]);
|
||||
int setenv(const char*, const char*, int);
|
||||
void setkey(const char*);
|
||||
char* setstate(char*);
|
||||
void srand(unsigned);
|
||||
void srand48(long);
|
||||
void srandom(unsigned);
|
||||
double strtod(const char* restrict, char** restrict);
|
||||
float strtof(const char* restrict, char** restrict);
|
||||
long strtol(const char* restrict, char** restrict, int);
|
||||
long double strtold(const char* restrict, char** restrict);
|
||||
long long strtoll(const char* restrict, char** restrict, int);
|
||||
unsigned long strtoul(const char* restrict, char** restrict, int);
|
||||
unsigned long long strtoull(const char* restrict, char** restrict, int);
|
||||
int system(const char*);
|
||||
int unlockpt(int);
|
||||
int unsetenv(const char*);
|
||||
size_t wcstombs(char* restrict, const wchar_t *restrict, size_t);
|
||||
int wctomb(char*, wchar_t);
|
||||
|
||||
#if __POSIX_OBSOLETE <= 200801
|
||||
int rand_r(unsigned *);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
|
@ -0,0 +1,77 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
string.h
|
||||
String operations.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _STRING_H
|
||||
#define _STRING_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@include(NULL.h)
|
||||
@include(size_t.h)
|
||||
@include(locale_t.h)
|
||||
|
||||
void* memcpy(void* restrict, const void* restrict, size_t);
|
||||
char* strcat(char* restrict, const char* restrict);
|
||||
int strcmp(const char*, const char*);
|
||||
char* strcpy(char* restrict, const char* restrict);
|
||||
size_t strlen(const char*);
|
||||
int strncmp(const char*, const char*, size_t);
|
||||
|
||||
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
||||
#ifndef SORTIX_UNIMPLEMENTED
|
||||
void* memccpy(void* restrict, const void* restrict, int, size_t);
|
||||
void* memchr(const void*, int, size_t);
|
||||
int memcmp(const void*, const void*, size_t);
|
||||
void* memmove(void*, const void*, size_t);
|
||||
void* memset(void*, int, size_t);
|
||||
char* stpcpy(char* restrict, const char* restrict);
|
||||
char* stpncpy(char* restrict, const char* restrict, size_t);
|
||||
char* strchr(const char*, int);
|
||||
int strcoll(const char*, const char*);
|
||||
int strcoll_l(const char*, const char*, locale_t);
|
||||
size_t strcspn(const char*, const char*);
|
||||
char* strdup(const char*);
|
||||
char* strerror(int);
|
||||
char* strerror_l(int, locale_t);
|
||||
int strerror_r(int, char*, size_t);
|
||||
char* strncat(char* restrict, const char* restrict, size_t);
|
||||
char* strncpy(char* restrict, const char* restrict, size_t);
|
||||
char* strndup(const char*, size_t);
|
||||
size_t strnlen(const char*, size_t);
|
||||
char* strpbrk(const char*, const char*);
|
||||
char* strrchr(const char*, int);
|
||||
char* strsignal(int);
|
||||
size_t strspn(const char*, const char*);
|
||||
char* strstr(const char*, const char*);
|
||||
char* strtok(char* restrict, const char* restrict);
|
||||
char* strtok_r(char* restrict, const char* restrict, char** restrict);
|
||||
size_t strxfrm(char* restrict, const char* restrict, size_t);
|
||||
size_t strxfrm_l(char* restrict, const char* restrict, size_t, locale_t);
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
stat.h
|
||||
Data returned by the stat() function.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
// TODO: Make this header comply with POSIX-1.2008
|
||||
|
||||
#ifndef _STAT_H
|
||||
#define _STAT_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@include(mode_t_values.h)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
types.h
|
||||
Data types.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
// TODO: Make this header comply with POSIX-1.2008
|
||||
|
||||
#ifndef _STAT_H
|
||||
#define _STAT_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@include(useconds_t.h)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http:/*www.gnu.org/licenses/>.
|
||||
|
||||
unistd.h
|
||||
The <unistd.h> header defines miscellaneous symbolic constants and types,
|
||||
and declares miscellaneous functions.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
/* TODO: POSIX-1.2008 compliance is only partial */
|
||||
|
||||
#ifndef _UNISTD_H
|
||||
#define _UNISTD_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Currently just say we support the newest POSIX. */
|
||||
/* TODO: Support the newest POSIX. */
|
||||
#define _POSIX_VERSION 200809L
|
||||
#define _POSIX2_VERSION 200809L
|
||||
|
||||
/* Currently just say we support the newest X/Open */
|
||||
/* TODO: Support the newest X/Open */
|
||||
#define _XOPEN_VERSION 700
|
||||
|
||||
/* TODO: _POSIX_*, _POSIX2_*, _XOPEN_* is missing here. */
|
||||
|
||||
/* TODO: _POSIX_*, _POSIX2_* is missing here. */
|
||||
|
||||
@include(NULL.h)
|
||||
|
||||
/* TODO: F_OK, R_OK, W_OK, X_OK is missing here. */
|
||||
|
||||
/* TODO: _CS_* is missing here. */
|
||||
|
||||
@include(SEEK_CUR.h)
|
||||
@include(SEEK_END.h)
|
||||
@include(SEEK_SET.h)
|
||||
|
||||
/* TODO: F_* is missing here. */
|
||||
|
||||
/* TODO: _PC_* is missing here. */
|
||||
|
||||
/* TODO: _SC_* is missing here. */
|
||||
|
||||
#define STDIN_FILENO (0)
|
||||
#define STDOUT_FILENO (1)
|
||||
#define STDERR_FILENO (2)
|
||||
|
||||
/* TODO: _POSIX_VDISABLE is missing here. */
|
||||
|
||||
@include(size_t.h)
|
||||
@include(ssize_t.h)
|
||||
@include(uid_t.h)
|
||||
@include(gid_t.h)
|
||||
@include(off_t.h)
|
||||
@include(pid_t.h)
|
||||
|
||||
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
||||
#ifndef SORTIX_UNIMPLEMENTED
|
||||
int access(const char*, int);
|
||||
unsigned alarm(unsigned);
|
||||
int chdir(const char*);
|
||||
int chown(const char*, uid_t, gid_t);
|
||||
int close(int);
|
||||
size_t confstr(int, char*, size_t);
|
||||
char* crypt(const char*, const char*);
|
||||
char* ctermid(char*);
|
||||
int dup(int);
|
||||
int dup2(int, int);
|
||||
void _exit(int);
|
||||
void encrypt(char [64], int);
|
||||
int execl(const char*, const char*, ...);
|
||||
int execle(const char*, const char*, ...);
|
||||
int execlp(const char*, const char*, ...);
|
||||
int execv(const char*, char* const []);
|
||||
int execve(const char*, char* const [], char* const []);
|
||||
int execvp(const char*, char* const []);
|
||||
int faccessat(int, const char*, int, int);
|
||||
int fchdir(int);
|
||||
int fchown(int, uid_t, gid_t);
|
||||
int fchownat(int, const char*, uid_t, gid_t, int);
|
||||
int fdatasync(int);
|
||||
int fexecve(int, char* const [], char* const []);
|
||||
pid_t fork(void);
|
||||
long fpathconf(int, int);
|
||||
int fsync(int);
|
||||
int ftruncate(int, off_t);
|
||||
char* getcwd(char*, size_t);
|
||||
gid_t getegid(void);
|
||||
uid_t geteuid(void);
|
||||
gid_t getgid(void);
|
||||
int getgroups(int, gid_t []);
|
||||
long gethostid(void);
|
||||
int gethostname(char*, size_t);
|
||||
char* getlogin(void);
|
||||
int getlogin_r(char*, size_t);
|
||||
int getopt(int, char* const [], const char*);
|
||||
pid_t getpgid(pid_t);
|
||||
pid_t getpgrp(void);
|
||||
pid_t getpid(void);
|
||||
pid_t getppid(void);
|
||||
pid_t getsid(pid_t);
|
||||
uid_t getuid(void);
|
||||
int isatty(int);
|
||||
int lchown(const char*, uid_t, gid_t);
|
||||
int link(const char*, const char*);
|
||||
int linkat(int, const char*, int, const char*, int);
|
||||
int lockf(int, int, off_t);
|
||||
off_t lseek(int, off_t, int);
|
||||
int nice(int);
|
||||
long pathconf(const char*, int);
|
||||
int pause(void);
|
||||
int pipe(int [2]);
|
||||
ssize_t pread(int, void*, size_t, off_t);
|
||||
ssize_t pwrite(int, const void*, size_t, off_t);
|
||||
ssize_t read(int, void*, size_t);
|
||||
ssize_t readlink(const char* restrict, char* restrict, size_t);
|
||||
ssize_t readlinkat(int, const char* restrict, char* restrict, size_t);
|
||||
int rmdir(const char*);
|
||||
int setegid(gid_t);
|
||||
int seteuid(uid_t);
|
||||
int setgid(gid_t);
|
||||
int setpgid(pid_t, pid_t);
|
||||
int setregid(gid_t, gid_t);
|
||||
int setreuid(uid_t, uid_t);
|
||||
pid_t setsid(void);
|
||||
int setuid(uid_t);
|
||||
unsigned sleep(unsigned);
|
||||
void swab(const void* restrict, void* restrict, ssize_t);
|
||||
int symlink(const char*, const char*);
|
||||
int symlinkat(const char*, int, const char*);
|
||||
void sync(void);
|
||||
long sysconf(int);
|
||||
pid_t tcgetpgrp(int);
|
||||
int tcsetpgrp(int, pid_t);
|
||||
int truncate(const char*, off_t);
|
||||
char* ttyname(int);
|
||||
int ttyname_r(int, char*, size_t);
|
||||
int unlink(const char*);
|
||||
int unlinkat(int, const char*, int);
|
||||
ssize_t write(int, const void*, size_t);
|
||||
|
||||
#if __POSIX_OBSOLETE <= 200801
|
||||
pid_t setpgrp(void);
|
||||
#endif
|
||||
|
||||
extern char* optarg;
|
||||
extern int opterr, optind, optopt;
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
wchar.h
|
||||
Handle variable argument list
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _WCHAR_H
|
||||
#define _WCHAR_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@include(FILE.h)
|
||||
@include(locale_t.h)
|
||||
@include(size_t.h)
|
||||
@include(va_list.h)
|
||||
@include(wchar_t.h)
|
||||
@include(wint_t.h)
|
||||
@include(WCHAR_MAX.h)
|
||||
@include(WCHAR_MIN.h)
|
||||
@include(WEOF.h)
|
||||
@include(NULL.h)
|
||||
|
||||
#ifndef __mbstate_t_defined
|
||||
/* Conversion state information. */
|
||||
typedef struct
|
||||
{
|
||||
int __count;
|
||||
union
|
||||
{
|
||||
wint_t __wch;
|
||||
char __wchb[4];
|
||||
} __value; /* Value so far. */
|
||||
} mbstate_t;
|
||||
#define __mbstate_t_defined 1
|
||||
#endif
|
||||
|
||||
#if __POSIX_OBSOLETE <= 200809L
|
||||
@include(wctype_t.h)
|
||||
#endif
|
||||
|
||||
struct tm;
|
||||
|
||||
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
||||
#ifndef SORTIX_UNIMPLEMENTED
|
||||
double wcstod(const wchar_t* restrict, wchar_t** restrict);
|
||||
FILE* open_wmemstream(wchar_t** bufp, size_t* sizep);
|
||||
float wcstof(const wchar_t* restrict, wchar_t** restrict);
|
||||
int fputws(const wchar_t* restrict, FILE* restrict);
|
||||
int fwide(FILE*, int);
|
||||
int fwprintf(FILE* restrict, const wchar_t* restrict, ...);
|
||||
int fwscanf(FILE* restrict, const wchar_t* restrict, ...);
|
||||
int mbsinit(const mbstate_t*);
|
||||
int swprintf(wchar_t* restrict, size_t, const wchar_t* restrict, ...);
|
||||
int swscanf(const wchar_t* restrict, const wchar_t* restrict, ...);
|
||||
int vfwprintf(FILE* restrict, const wchar_t* restrict, va_list);
|
||||
int vfwscanf(FILE* restrict, const wchar_t* restrict, va_list);
|
||||
int vswprintf(wchar_t* restrict, size_t, const wchar_t* restrict, va_list);
|
||||
int vswscanf(const wchar_t* restrict, const wchar_t* restrict, va_list);
|
||||
int vwprintf(const wchar_t* restrict, va_list);
|
||||
int vwscanf(const wchar_t* restrict, va_list);
|
||||
int wcscmp(const wchar_t*, const wchar_t*);
|
||||
int wcscoll(const wchar_t*, const wchar_t*);
|
||||
int wcsncmp(const wchar_t*, const wchar_t*, size_t);
|
||||
int wcswidth(const wchar_t*, size_t);
|
||||
int wctob(wint_t);
|
||||
int wcwidth(wchar_t);
|
||||
int wmemcmp(const wchar_t*, const wchar_t*, size_t);
|
||||
int wprintf(const wchar_t* restrict, ...);
|
||||
int wscanf(const wchar_t* restrict, ...);
|
||||
long double wcstold(const wchar_t* restrict, wchar_t** restrict);
|
||||
long long wcstoll(const wchar_t* restrict, wchar_t** restrict, int);
|
||||
long wcstol(const wchar_t* restrict, wchar_t** restrict, int);
|
||||
size_t mbrlen(const char* restrict, size_t, mbstate_t* restrict);
|
||||
size_t mbrtowc(wchar_t* restrict, const char* restrict, size_t, mbstate_t* restrict);
|
||||
size_t mbsrtowcs(wchar_t* restrict, const char** restrict, size_t, mbstate_t* restrict);
|
||||
size_t wcrtomb(char* restrict, wchar_t, mbstate_t* restrict);
|
||||
size_t wcscspn(const wchar_t*, const wchar_t*);
|
||||
size_t wcsftime(wchar_t* restrict, size_t, const wchar_t* restrict, const struct tm* restrict);
|
||||
size_t wcslen(const wchar_t*);
|
||||
size_t wcsrtombs(char* restrict, const wchar_t** restrict, size_t, mbstate_t* restrict);
|
||||
size_t wcsspn(const wchar_t*, const wchar_t*);
|
||||
size_t wcsxfrm(wchar_t* restrict, const wchar_t* restrict, size_t);
|
||||
unsigned long long wcstoull(const wchar_t* restrict, wchar_t** restrict, int);
|
||||
unsigned long wcstoul(const wchar_t* restrict, wchar_t** restrict, int);
|
||||
wchar_t* fgetws(wchar_t* restrict, int, FILE* restrict);
|
||||
wchar_t* wcscat(wchar_t* restrict, const wchar_t* restrict);
|
||||
wchar_t* wcschr(const wchar_t*, wchar_t);
|
||||
wchar_t* wcscpy(wchar_t* restrict, const wchar_t* restrict);
|
||||
wchar_t* wcsncat(wchar_t* restrict, const wchar_t* restrict, size_t);
|
||||
wchar_t* wcsncpy(wchar_t* restrict, const wchar_t* restrict, size_t);
|
||||
wchar_t* wcspbrk(const wchar_t*, const wchar_t*);
|
||||
wchar_t* wcsrchr(const wchar_t*, wchar_t);
|
||||
wchar_t* wcsstr(const wchar_t* restrict, const wchar_t* restrict);
|
||||
wchar_t* wcstok(wchar_t* restrict, const wchar_t* restrict, wchar_t** restrict);
|
||||
wchar_t* wcswcs(const wchar_t*, const wchar_t*);
|
||||
wchar_t* wmemchr(const wchar_t*, wchar_t, size_t);
|
||||
wchar_t* wmemcpy(wchar_t* restrict, const wchar_t* restrict, size_t);
|
||||
wchar_t* wmemmove(wchar_t*, const wchar_t*, size_t);
|
||||
wchar_t* wmemset(wchar_t*, wchar_t, size_t);
|
||||
wint_t btowc(int);
|
||||
wint_t fgetwc(FILE*);
|
||||
wint_t fputwc(wchar_t, FILE*);
|
||||
wint_t getwc(FILE*);
|
||||
wint_t getwchar(void);
|
||||
wint_t putwchar(wchar_t);
|
||||
wint_t putwc(wchar_t, FILE*);
|
||||
wint_t ungetwc(wint_t, FILE*);
|
||||
|
||||
#if __POSIX_OBSOLETE <= 200809L
|
||||
int iswalnum(wint_t);
|
||||
int iswalpha(wint_t);
|
||||
int iswcntrl(wint_t);
|
||||
int iswctype(wint_t, wctype_t);
|
||||
int iswdigit(wint_t);
|
||||
int iswgraph(wint_t);
|
||||
int iswlower(wint_t);
|
||||
int iswprint(wint_t);
|
||||
int iswpunct(wint_t);
|
||||
int iswspace(wint_t);
|
||||
int iswupper(wint_t);
|
||||
int iswxdigit(wint_t);
|
||||
wint_t towlower(wint_t);
|
||||
wint_t towupper(wint_t);
|
||||
wctype_t wctype(const char *);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
wctype.h
|
||||
Wide-character classification and mapping utilities
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _WCTYPE_H
|
||||
#define _WCTYPE_H 1
|
||||
|
||||
#include <features.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@include(wint_t.h)
|
||||
@include(wctrans_t.h)
|
||||
@include(locale_t.h)
|
||||
@include(WEOF.h)
|
||||
|
||||
/* TODO: These are not implemented in libmaxsi/sortix yet. */
|
||||
#ifndef SORTIX_UNIMPLEMENTED
|
||||
int iswalnum(wint_t);
|
||||
int iswalnum_l(wint_t, locale_t);
|
||||
int iswalpha(wint_t);
|
||||
int iswalpha_l(wint_t, locale_t);
|
||||
int iswblank(wint_t);
|
||||
int iswblank_l(wint_t, locale_t);
|
||||
int iswcntrl(wint_t);
|
||||
int iswcntrl_l(wint_t, locale_t);
|
||||
int iswctype(wint_t, wctype_t);
|
||||
int iswctype_l(wint_t, wctype_t, locale_t);
|
||||
int iswdigit(wint_t);
|
||||
int iswdigit_l(wint_t, locale_t);
|
||||
int iswgraph(wint_t);
|
||||
int iswgraph_l(wint_t, locale_t);
|
||||
int iswlower(wint_t);
|
||||
int iswlower_l(wint_t, locale_t);
|
||||
int iswprint(wint_t);
|
||||
int iswprint_l(wint_t, locale_t);
|
||||
int iswpunct(wint_t);
|
||||
int iswpunct_l(wint_t, locale_t);
|
||||
int iswspace(wint_t);
|
||||
int iswspace_l(wint_t, locale_t);
|
||||
int iswupper(wint_t);
|
||||
int iswupper_l(wint_t, locale_t);
|
||||
int iswxdigit(wint_t);
|
||||
int iswxdigit_l(wint_t, locale_t);
|
||||
wint_t towctrans(wint_t, wctrans_t);
|
||||
wint_t towctrans_l(wint_t, wctrans_t, locale_t);
|
||||
wint_t towlower(wint_t);
|
||||
wint_t towlower_l(wint_t, locale_t);
|
||||
wint_t towupper(wint_t);
|
||||
wint_t towupper_l(wint_t, locale_t);
|
||||
wctrans_t wctrans(const char *);
|
||||
wctrans_t wctrans_l(const char *, locale_t);
|
||||
wctype_t wctype(const char *);
|
||||
wctype_t wctype_l(const char *, locale_t);
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
string.c
|
||||
Implements things from <string.h> that is slightly incompatible with
|
||||
how libmaxsi does stuff.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
char* strdup(const char* input)
|
||||
{
|
||||
size_t inputsize = strlen(input);
|
||||
char* result = (char*) malloc(inputsize + 1);
|
||||
if ( result == NULL ) { return NULL; }
|
||||
memcpy(result, input, inputsize + 1);
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef NULL
|
||||
#define NULL __NULL
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef WCHAR_MAX
|
||||
#define WCHAR_MAX __WCHAR_MAX
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef WCHAR_MIN
|
||||
#define WCHAR_MIN __WCHAR_MIN
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _GID_T_DECL
|
||||
#define _GID_T_DECL
|
||||
typedef __gid_t gid_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _ID_T_DECL
|
||||
#define _ID_T_DECL
|
||||
typedef __id_t id_t;
|
||||
#endif
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef _INTN_T_DECL
|
||||
#define _INTN_T_DECL
|
||||
|
||||
/* Define basic signed types. */
|
||||
typedef __int8_t int8_t;
|
||||
typedef __int16_t int16_t;
|
||||
typedef __int32_t int32_t;
|
||||
typedef __int64_t int64_t;
|
||||
|
||||
/* Define basic unsigned types. */
|
||||
typedef __uint8_t uint8_t;
|
||||
typedef __uint16_t uint16_t;
|
||||
typedef __uint32_t uint32_t;
|
||||
typedef __uint64_t uint64_t;
|
||||
|
||||
/* The maximum width integers available on this platform. */
|
||||
typedef __intmax_t intmax_t;
|
||||
typedef __uintmax_t uintmax_t;
|
||||
|
||||
/* Define an integer able to hold the size of the largest continious memory */
|
||||
/* region and define pointer safe integer types. */
|
||||
typedef __size_t size_t;
|
||||
typedef __ssize_t ssize_t;
|
||||
typedef __intptr_t intptr_t;
|
||||
typedef __uintptr_t uintptr_t;
|
||||
typedef __ptrdiff_t ptrdiff_t;
|
||||
|
||||
#define INT8_MIN __INT8_MIN
|
||||
#define INT16_MIN __INT16_MIN
|
||||
#define INT32_MIN __INT32_MIN
|
||||
#define INT64_MIN __INT64_MIN
|
||||
#define INT8_MAX __INT8_MAX
|
||||
#define INT16_MAX __INT16_MAX
|
||||
#define INT32_MAX __INT32_MAX
|
||||
#define INT64_MAX __INT64_MAX
|
||||
#define UINT8_MAX __UINT8_MAX
|
||||
#define UINT16_MAX __UINT16_MAX
|
||||
#define UINT32_MAX __UINT32_MAX
|
||||
#define UINT64_MAX __UINT64_MAX
|
||||
|
||||
#define INTMAX_MIN __INTMAX_MIN
|
||||
#define INTMAX_MAX __INTMAX_MAX
|
||||
#define UINTMAX_MAX __UINTMAX_MAX
|
||||
|
||||
#define CHAR_BIT __CHAR_BIT
|
||||
#define SCHAR_MIN __SCHAR_MIN
|
||||
#define SCHAR_MAX __SCHAR_MAX
|
||||
#define UCHAR_MAX __UCHAR_MAX
|
||||
#define CHAR_MIN __CHAR_MIN
|
||||
#define CHAR_MAX __CHAR_MAX
|
||||
|
||||
#define WCHAR_MIN __WCHAR_MIN
|
||||
#define WCHAR_MAX __WCHAR_MAX
|
||||
|
||||
#define SHRT_MIN __SHRT_MIN
|
||||
#define SHRT_MAX __SHRT_MAX
|
||||
#define USHRT_MAX __USHRT_MAX
|
||||
|
||||
#define WORD_BIT __WORD_BIT
|
||||
#define INT_MIN __INT_MIN
|
||||
#define INT_MAX __INT_MAX
|
||||
#define UINT_MAX __UINT_MAX
|
||||
|
||||
#define LONG_BIT __LONG_BIT
|
||||
#define LONG_MIN __LONG_MIN
|
||||
#define LONG_MAX __LONG_MAX
|
||||
#define ULONG_MAX __ULONG_MAX
|
||||
|
||||
#define LONG_MIN __LONG_MIN
|
||||
#define LLONG_MAX __LLONG_MAX
|
||||
#define ULLONG_MAX __ULLONG_MAX
|
||||
|
||||
#define SSIZE_MIN __SSIZE_MIN
|
||||
#define SSIZE_MAX __SSIZE_MAX
|
||||
#define SIZE_MAX __SIZE_MAX
|
||||
#define INTPTR_MIN __INTPTR_MIN
|
||||
#define INTPTR_MAX __INTPTR_MAX
|
||||
#define UINTPTR_MAX __UINTPTR_MAX
|
||||
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _INTPTR_T_DECL
|
||||
#define _INTPTR_T_DECL
|
||||
typedef __intptr_t intptr_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _LOCALE_T_DECL
|
||||
#define _LOCALT_T_DECL
|
||||
typedef __locale_t locale_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _MODE_T_DECL
|
||||
#define _MODE_T_DECL
|
||||
typedef __mode_t mode_t;
|
||||
#endif
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef _MODE_T_VALUES_DECL
|
||||
#define _MODE_T_VALUES_DECL
|
||||
#define S_IRUSR __S_IREAD /* Read by owner. */
|
||||
#define S_IWUSR __S_IWRITE /* Write by owner. */
|
||||
#define S_IXUSR __S_IEXEC /* Execute by owner. */
|
||||
/* Read, write, and execute by owner. */
|
||||
#define S_IRWXU (__S_IREAD|__S_IWRITE|__S_IEXEC)
|
||||
|
||||
#define S_IRGRP (S_IRUSR >> 3) /* Read by group. */
|
||||
#define S_IWGRP (S_IWUSR >> 3) /* Write by group. */
|
||||
#define S_IXGRP (S_IXUSR >> 3) /* Execute by group. */
|
||||
/* Read, write, and execute by group. */
|
||||
#define S_IRWXG (S_IRWXU >> 3)
|
||||
|
||||
#define S_IROTH (S_IRGRP >> 3) /* Read by others. */
|
||||
#define S_IWOTH (S_IWGRP >> 3) /* Write by others. */
|
||||
#define S_IXOTH (S_IXGRP >> 3) /* Execute by others. */
|
||||
/* Read, write, and execute by others. */
|
||||
#define S_IRWXO (S_IRWXG >> 3)
|
||||
|
||||
#define __S_ISUID 04000 /* Set user ID on execution. */
|
||||
#define __S_ISGID 02000 /* Set group ID on execution. */
|
||||
#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
|
||||
#define __S_IREAD 0400 /* Read by owner. */
|
||||
#define __S_IWRITE 0200 /* Write by owner. */
|
||||
#define __S_IEXEC 0100 /* Execute by owner. */
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _OFF_T_DECL
|
||||
#define _OFF_T_DECL
|
||||
typedef __off_t off_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _PID_T_DECL
|
||||
#define _PID_T_DECL
|
||||
typedef __pid_t pid_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _PTRDIFF_T_DECL
|
||||
#define _PTRDIFF_T_DECL
|
||||
typedef __ptrdiff_t ptrdiff_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _SIZE_T_DECL
|
||||
#define _SIZE_T_DECL
|
||||
typedef __size_t size_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _SSIZE_T_DECL
|
||||
#define _SSIZE_T_DECL
|
||||
typedef __ssize_t ssize_t;
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _UID_T_DECL
|
||||
#define _UID_T_DECL
|
||||
typedef __uid_t uid_t;
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _VALIST_DECL
|
||||
#define _VALIST_DECL
|
||||
#define va_start(v,l) __builtin_va_start(v,l)
|
||||
#define va_arg(v,l) __builtin_va_arg(v,l)
|
||||
#define va_end(v) __builtin_va_end(v)
|
||||
#define va_copy(d,s) __builtin_va_copy(d,s)
|
||||
typedef __builtin_va_list va_list;
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef _WCHAR_T_DECL
|
||||
#define _WCHAR_T_DECL
|
||||
#if !defined(__cplusplus)
|
||||
typedef __wchar_t wchar_t;
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef _WINT_T_DECL
|
||||
#define _WINT_T_DECL
|
||||
typedef __wint_t wint_t;
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
error.cpp
|
||||
Error reporting functions and utilities.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "error.h"
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace Error
|
||||
{
|
||||
// TODO: merge with errno interface.
|
||||
int _errornumber;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
format.cpp
|
||||
Provides printf formatting functions that uses callbacks.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "string.h"
|
||||
#include "format.h"
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace Format
|
||||
{
|
||||
int UInt8ToString(uint8_t Num, char* Dest)
|
||||
{
|
||||
uint8_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 9 ) { Copy /= 10; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 10; Num /= 10; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
int UInt16ToString(uint16_t Num, char* Dest)
|
||||
{
|
||||
uint16_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 9 ) { Copy /= 10; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 10; Num /= 10; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
int UInt32ToString(uint32_t Num, char* Dest)
|
||||
{
|
||||
uint32_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 9 ) { Copy /= 10; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 10; Num /= 10; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
int UInt64ToString(uint64_t Num, char* Dest)
|
||||
{
|
||||
uint64_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 9 ) { Copy /= 10; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 10; Num /= 10; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
// Missing functions here.
|
||||
|
||||
int UInt32ToString16(uint32_t Num, char* Dest)
|
||||
{
|
||||
uint32_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 15 ) { Copy /= 16; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
if ( Num % 16 < 10 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dest[Offset] = 'A' + (Num % 16) - 10;
|
||||
}
|
||||
Num /= 16; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
int UInt64ToString16(uint64_t Num, char* Dest)
|
||||
{
|
||||
uint64_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 15 ) { Copy /= 16; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
if ( Num % 16 < 10 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dest[Offset] = 'A' + (Num % 16) - 10;
|
||||
}
|
||||
Num /= 16; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
#define READY_SIZE 128
|
||||
|
||||
#define READY_FLUSH() \
|
||||
ready[readylen] = '\0'; \
|
||||
if ( 0 < readylen && callback && callback(user, ready, readylen) != readylen ) { return SIZE_MAX; } \
|
||||
written += readylen; readylen = 0;
|
||||
|
||||
size_t Virtual(Callback callback, void* user, const char* format, va_list parameters)
|
||||
{
|
||||
size_t written = 0;
|
||||
size_t readylen = 0;
|
||||
char ready[READY_SIZE + 1];
|
||||
|
||||
while ( *format != '\0' )
|
||||
{
|
||||
char c = *(format++);
|
||||
|
||||
if ( c != '%' )
|
||||
{
|
||||
if ( READY_SIZE <= readylen ) { READY_FLUSH(); }
|
||||
ready[readylen++] = c;
|
||||
continue;
|
||||
}
|
||||
|
||||
const nat UNSIGNED = 0;
|
||||
const nat BIT64 = (1<<0);
|
||||
const nat HEX = (1<<1);
|
||||
const nat STRING = 4;
|
||||
const nat CHARACTER = 5;
|
||||
#ifdef PLATFORM_X64
|
||||
const nat WORDWIDTH = BIT64;
|
||||
#else
|
||||
const nat WORDWIDTH = 0;
|
||||
#endif
|
||||
|
||||
// TODO: Support signed datatypes!
|
||||
|
||||
nat type = 0;
|
||||
|
||||
bool scanning = true;
|
||||
while ( scanning )
|
||||
{
|
||||
switch( *(format++) )
|
||||
{
|
||||
case '3':
|
||||
case '2':
|
||||
break;
|
||||
case '6':
|
||||
case '4':
|
||||
type |= BIT64;
|
||||
break;
|
||||
case 'p':
|
||||
type = WORDWIDTH | HEX;
|
||||
scanning = false;
|
||||
break;
|
||||
case 'z':
|
||||
type |= WORDWIDTH;
|
||||
break;
|
||||
case 'u':
|
||||
type |= UNSIGNED;
|
||||
scanning = false;
|
||||
break;
|
||||
case 'x':
|
||||
type |= HEX;
|
||||
scanning = false;
|
||||
break;
|
||||
case 's':
|
||||
type = STRING;
|
||||
scanning = false;
|
||||
break;
|
||||
case 'c':
|
||||
type = CHARACTER;
|
||||
scanning = false;
|
||||
break;
|
||||
default:
|
||||
return SIZE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case UNSIGNED:
|
||||
{
|
||||
if ( READY_SIZE - readylen < 10 ) { READY_FLUSH(); }
|
||||
uint32_t num = va_arg(parameters, uint32_t);
|
||||
readylen += UInt32ToString(num, ready + readylen);
|
||||
break;
|
||||
}
|
||||
case UNSIGNED | BIT64:
|
||||
{
|
||||
if ( READY_SIZE - readylen < 20 ) { READY_FLUSH(); }
|
||||
uint64_t num = va_arg(parameters, uint64_t);
|
||||
readylen += UInt64ToString(num, ready + readylen);
|
||||
break;
|
||||
}
|
||||
case UNSIGNED | HEX:
|
||||
{
|
||||
if ( READY_SIZE - readylen < 8 ) { READY_FLUSH(); }
|
||||
uint32_t num = va_arg(parameters, uint32_t);
|
||||
readylen += UInt32ToString16(num, ready + readylen);
|
||||
break;
|
||||
}
|
||||
case UNSIGNED | BIT64 | HEX:
|
||||
{
|
||||
if ( READY_SIZE - readylen < 16 ) { READY_FLUSH(); }
|
||||
uint64_t num = va_arg(parameters, uint64_t);
|
||||
readylen += UInt64ToString16(num, ready + readylen);
|
||||
break;
|
||||
}
|
||||
case STRING:
|
||||
{
|
||||
READY_FLUSH();
|
||||
const char* str = va_arg(parameters, const char*);
|
||||
size_t len = String::Length(str);
|
||||
if ( callback && callback(user, str, len) != len ) { return SIZE_MAX; }
|
||||
written += len;
|
||||
break;
|
||||
}
|
||||
case CHARACTER:
|
||||
{
|
||||
int c = va_arg(parameters, int);
|
||||
if ( READY_SIZE <= readylen ) { READY_FLUSH(); }
|
||||
ready[readylen++] = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READY_FLUSH();
|
||||
|
||||
return written;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
error.h
|
||||
Error reporting functions and utilities.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_ERROR_H
|
||||
#define LIBMAXSI_ERROR_H
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace Error
|
||||
{
|
||||
// TODO: merge with errno interface.
|
||||
|
||||
const int SUCCESS = 0;
|
||||
const int NONE = 1;
|
||||
const int DENIED = 2;
|
||||
const int NOTFOUND = 3;
|
||||
const int NOSUPPORT = 4;
|
||||
const int NOTIMPLEMENTED = 5;
|
||||
const int PENDING = 6;
|
||||
const int BADINPUT = 7;
|
||||
const int CORRUPT = 8;
|
||||
const int NOMEM = 9;
|
||||
const int NOTDIR = 10;
|
||||
const int ISDIR = 11;
|
||||
|
||||
const int ENOTBLK = 12;
|
||||
const int ENODEV = 13;
|
||||
|
||||
extern int _errornumber;
|
||||
|
||||
inline int Last() { return _errornumber; }
|
||||
inline void Set(int error) { _errornumber = error; }
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
format.h
|
||||
Provides printf formatting functions that uses callbacks.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_FORMAT_H
|
||||
#define LIBMAXSI_FORMAT_H
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace Format
|
||||
{
|
||||
typedef size_t (*Callback)(void* user, const char* string, size_t stringlen);
|
||||
|
||||
size_t Virtual(Callback callback, void* user, const char* format, va_list parameters);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
io.h
|
||||
Functions for management of input and output.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_IO_H
|
||||
#define LIBMAXSI_IO_H
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace IO
|
||||
{
|
||||
// TODO:
|
||||
|
||||
enum Seek_t { SEEK_SET, SEEK_CUR, SEEK_END };
|
||||
|
||||
int Open(const char* Path, int Flags, int Mode = 0); // TODO: Better default value for Mode
|
||||
int Close(int FileDesc = -1);
|
||||
int Truncate(int FileDesc, intmax_t Size = 0);
|
||||
int Sync(int FileDesc = -1);
|
||||
intmax_t Seek(int FileDesc, intmax_t Offset, Seek_t Whence = SEEK_SET);
|
||||
size_t Read(int FileDesc, const void* Buffer, size_t BufferSize);
|
||||
size_t Write(int FileDesc, const void* Buffer, size_t BufferSize);
|
||||
size_t ReadAt(int FileDesc, const void* Buffer, size_t BufferSize, intmax_t Position);
|
||||
size_t WriteAt(int FileDesc, const void* Buffer, size_t BufferSize, intmax_t Position);
|
||||
}
|
||||
|
||||
namespace StdOut
|
||||
{
|
||||
size_t Print(const char* Message);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
memory.h
|
||||
Useful functions for manipulating memory, as well as the implementation
|
||||
of the heap.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_MEMORY_H
|
||||
#define LIBMAXSI_MEMORY_H
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace Memory
|
||||
{
|
||||
void Init();
|
||||
void* Allocate(size_t Size);
|
||||
void Free(void* Addr);
|
||||
size_t GetChunkOverhead();
|
||||
void* Copy(void* Dest, const void* Src, size_t Length);
|
||||
void* Set(void* Dest, int Value, size_t Length);
|
||||
}
|
||||
}
|
||||
|
||||
inline void* operator new(size_t, void* p) { return p; }
|
||||
inline void* operator new[](size_t, void* p) { return p; }
|
||||
inline void operator delete (void*, void*) { };
|
||||
inline void operator delete[](void*, void*) { };
|
||||
|
||||
inline void* operator new(size_t Size) { return Maxsi::Memory::Allocate(Size); }
|
||||
inline void* operator new[](size_t Size) { return Maxsi::Memory::Allocate(Size); }
|
||||
inline void operator delete (void* Addr) { return Maxsi::Memory::Free(Addr); };
|
||||
inline void operator delete[](void* Addr) { return Maxsi::Memory::Free(Addr); };
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
platform.h
|
||||
Defines platform specific stuff.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_PLATFORM_H
|
||||
#define LIBMAXSI_PLATFORM_H
|
||||
|
||||
// Detect which platform we are compiling to and declare some useful macros.
|
||||
#ifdef PLATFORM_X86
|
||||
#define CPU X86
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X64
|
||||
#define CPU X64
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_X86) || defined(PLATFORM_X64)
|
||||
#define PLATFORM_X86_FAMILY
|
||||
#define CPU_FAMILY X86_FAMILY
|
||||
#endif
|
||||
|
||||
// Libmaxsi is also compatible as a C library, if enabled.
|
||||
#ifdef LIBMAXSI_LIBRARY
|
||||
#if defined(SORTIX_KERNEL) && !defined(LIBMAXSI_NO_LIBC)
|
||||
#define LIBMAXSI_NO_LIBC
|
||||
#endif
|
||||
|
||||
#ifndef LIBMAXSI_NO_LIBC
|
||||
#define LIBMAXSI_LIBC
|
||||
#endif
|
||||
|
||||
#ifdef LIBMAXSI_LIBC
|
||||
#define DUAL_FUNCTION(Type, CName, LibMaxsiName, Parameters) \
|
||||
Type LibMaxsiName Parameters __attribute__ ((weak, alias (#CName))); \
|
||||
extern "C" Type CName Parameters
|
||||
#else
|
||||
#define DUAL_FUNCTION(Type, CName, LibMaxsiName, Parameters) \
|
||||
Type LibMaxsiName Parameters
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SORTIX_KERNEL
|
||||
#define ASSERT(invariant) \
|
||||
if ( unlikely(!(invariant)) ) \
|
||||
{ \
|
||||
Sortix::PanicF("Assertion failure: %s:%u: %s: %s\n", __FILE__, __LINE__, __PRETTY_FUNCTION__, #invariant); \
|
||||
while ( true ) { } \
|
||||
}
|
||||
#else
|
||||
|
||||
#define ASSERT(invariant)
|
||||
|
||||
#endif
|
||||
|
||||
#define STATIC_ASSERT(condition) static_assert(condition, #condition)
|
||||
|
||||
// Define common datatypes.
|
||||
#include "types.h"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SORTIX_KERNEL
|
||||
#include <sortix/platform.h>
|
||||
#include <sortix/log.h>
|
||||
#include <sortix/panic.h>
|
||||
#endif
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
string.h
|
||||
Useful functions for manipulating strings.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_STRING_H
|
||||
#define LIBMAXSI_STRING_H
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
const char ASCII_ESCAPE = 27;
|
||||
|
||||
size_t Length(const char* String);
|
||||
char* Clone(const char* Source);
|
||||
char* Combine(size_t NumParameters, ...);
|
||||
char* Copy(char* Dest, const char* Src);
|
||||
char* Cat(char* Dest, const char* Src);
|
||||
int Compare(const char* A, const char* B);
|
||||
int CompareN(const char* A, const char* B, size_t MaxLength);
|
||||
int StartsWith(const char* Haystack, const char* Needle);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
string.h
|
||||
Useful functions for manipulating strings.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_SYSCALL_H
|
||||
#define LIBMAXSI_SYSCALL_H
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
#ifdef SORTIX_KERNEL
|
||||
#warning ===
|
||||
#warning Sortix does not support syscalls from within the kernel, building this part of LibMaxsi should not be needed, and should not be used in kernel mode
|
||||
#warning ===
|
||||
#endif
|
||||
|
||||
#define DECL_SYSCALL0(type,fn) type fn();
|
||||
#define DECL_SYSCALL1(type,fn,p1) type fn(p1);
|
||||
#define DECL_SYSCALL2(type,fn,p1,p2) type fn(p1,p2);
|
||||
#define DECL_SYSCALL3(type,fn,p1,p2,p3) type fn(p1,p2,p3);
|
||||
#define DECL_SYSCALL4(type,fn,p1,p2,p3,p4) type fn(p1,p2,p3,p4);
|
||||
#define DECL_SYSCALL5(type,fn,p1,p2,p3,p4,p5) type fn(p1,p2,p3,p4,p5);
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
|
||||
#define DEFN_SYSCALL0(type, fn, num) \
|
||||
inline type fn() \
|
||||
{ \
|
||||
type a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL1(type, fn, num, P1) \
|
||||
inline type fn(P1 p1) \
|
||||
{ \
|
||||
type a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL2(type, fn, num, P1, P2) \
|
||||
inline type fn(P1 p1, P2 p2) \
|
||||
{ \
|
||||
type a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1), "c" ((size_t)p2)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL3(type, fn, num, P1, P2, P3) \
|
||||
inline type fn(P1 p1, P2 p2, P3 p3) \
|
||||
{ \
|
||||
type a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1), "c" ((size_t)p2), "d" ((size_t)p3)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL4(type, fn, num, P1, P2, P3, P4) \
|
||||
inline type fn(P1 p1, P2 p2, P3 p3, P4 p4) \
|
||||
{ \
|
||||
type a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1), "c" ((size_t)p2), "d" ((size_t)p3), "D" ((size_t)p4)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL5(type, fn, num, P1, P2, P3, P4, P5) \
|
||||
inline type fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \
|
||||
{ \
|
||||
type a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1), "c" ((size_t)p2), "d" ((size_t)p3), "D" ((size_t)p4), "S" ((size_t)p5)); \
|
||||
return a; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL0_VOID(fn, num) \
|
||||
inline void fn() \
|
||||
{ \
|
||||
size_t a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num)); \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL1_VOID(fn, num, P1) \
|
||||
inline void fn(P1 p1) \
|
||||
{ \
|
||||
size_t a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1)); \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL2_VOID(fn, num, P1, P2) \
|
||||
inline void fn(P1 p1, P2 p2) \
|
||||
{ \
|
||||
size_t a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1), "c" ((size_t)p2)); \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL3_VOID(fn, num, P1, P2, P3) \
|
||||
inline void fn(P1 p1, P2 p2, P3 p3) \
|
||||
{ \
|
||||
size_t a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1), "c" ((size_t)p2), "d" ((size_t)p3)); \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL4_VOID(fn, num, P1, P2, P3, P4) \
|
||||
inline void fn(P1 p1, P2 p2, P3 p3, P4 p4) \
|
||||
{ \
|
||||
size_t a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1), "c" ((size_t)p2), "d" ((size_t)p3), "D" ((size_t)p4)); \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL5_VOID(fn, num, P1, P2, P3, P4, P5) \
|
||||
inline void fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \
|
||||
{ \
|
||||
size_t a; \
|
||||
asm volatile("int $0x80" : "=a" (a) : "0" (num), "b" ((size_t)p1), "c" ((size_t)p2), "d" ((size_t)p3), "D" ((size_t)p4), "S" ((size_t)p5)); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define DEFN_SYSCALL0(type, fn, num) \
|
||||
inline type fn() \
|
||||
{ \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL1(type, fn, num, P1) \
|
||||
inline type fn(P1 p1) \
|
||||
{ \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL2(type, fn, num, P1, P2) \
|
||||
inline type fn(P1 p1, P2 p2) \
|
||||
{ \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL3(type, fn, num, P1, P2, P3) \
|
||||
inline type fn(P1 p1, P2 p2, P3 p3) \
|
||||
{ \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL4(type, fn, num, P1, P2, P3, P4) \
|
||||
inline type fn(P1 p1, P2 p2, P3 p3, P4 p4) \
|
||||
{ \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL5(type, fn, num, P1, P2, P3, P4, P5) \
|
||||
inline type fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \
|
||||
{ \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL0_VOID(fn, num) \
|
||||
inline void fn() \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL1_VOID(fn, num, P1) \
|
||||
inline void fn(P1 p1) \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL2_VOID(fn, num, P1, P2) \
|
||||
inline void fn(P1 p1, P2 p2) \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL3_VOID(fn, num, P1, P2, P3) \
|
||||
inline void fn(P1 p1, P2 p2, P3 p3) \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL4_VOID(fn, num, P1, P2, P3, P4) \
|
||||
inline void fn(P1 p1, P2 p2, P3 p3, P4 p4) \
|
||||
{ \
|
||||
}
|
||||
|
||||
#define DEFN_SYSCALL5_VOID(fn, num, P1, P2, P3, P4, P5) \
|
||||
inline void fn(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) \
|
||||
{ \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
thread.h
|
||||
Exposes system calls for thread creation and management.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_THREAD_H
|
||||
#define LIBMAXSI_THREAD_H
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace Thread
|
||||
{
|
||||
typedef void* (*Entry)(void*);
|
||||
|
||||
size_t Create(Entry Start, const void* Parameter, size_t StackSize = SIZE_MAX);
|
||||
void Exit(const void* Result);
|
||||
void Sleep(long Seconds);
|
||||
void USleep(long Microseconds);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
types.h
|
||||
Declares the required datatypes based on the kernel's configuration.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef LIBMAXSI_TYPES_H
|
||||
#define LIBMAXSI_TYPES_H
|
||||
|
||||
#include <sortix/bits.h>
|
||||
|
||||
@include(NULL.h)
|
||||
|
||||
@include(intn_t.h)
|
||||
|
||||
@include(wint_t.h)
|
||||
@include(id_t.h)
|
||||
@include(gid_t.h)
|
||||
@include(pid_t.h)
|
||||
@include(uid_t.h)
|
||||
@include(locale_t.h)
|
||||
@include(mode_t.h)
|
||||
@include(off_t.h)
|
||||
@include(gid_t.h)
|
||||
|
||||
@include(va_list.h)
|
||||
|
||||
// Maxsi datatype extentions.
|
||||
typedef __nat nat;
|
||||
typedef uint8_t byte;
|
||||
typedef uintptr_t addr_t;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
io.h
|
||||
Functions for management of input and output.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "syscall.h"
|
||||
#include "io.h"
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace StdOut
|
||||
{
|
||||
DEFN_SYSCALL1(size_t, SysPrint, 4, const char*);
|
||||
|
||||
size_t Print(const char* Message)
|
||||
{
|
||||
return SysPrint(Message);
|
||||
}
|
||||
|
||||
#ifdef LIBMAXSI_LIBC
|
||||
extern "C" int printf(const char* /*restrict*/ format, ...)
|
||||
{
|
||||
// TODO: The format string is currently being ignored!
|
||||
return Print(format);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,484 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
memory.cpp
|
||||
Useful functions for manipulating memory, as well as the implementation
|
||||
of the heap.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "memory.h"
|
||||
#include "error.h"
|
||||
#include "io.h" // DEBUG
|
||||
|
||||
#ifdef SORTIX_KERNEL
|
||||
#include <sortix/platform.h>
|
||||
#include <sortix/globals.h> // DEBUG
|
||||
#include <sortix/iprintable.h> // DEBUG
|
||||
#include <sortix/log.h> // DEBUG
|
||||
|
||||
#include <sortix/memorymanagement.h>
|
||||
#include <sortix/panic.h>
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace VirtualMemory
|
||||
{
|
||||
extern uintptr_t KernelHalfStart;
|
||||
extern uintptr_t KernelHalfEnd;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define IsGoodChunkPosition(Chunk) ((uintptr_t) Wilderness + WildernessSize <= (uintptr_t) (Chunk) && (uintptr_t) (Chunk) <= (uintptr_t) HeapStart)
|
||||
#define IsGoodChunkInfo(Chunk) ( ( (UnusedChunkFooter*) (((byte*) (Chunk)) + (Chunk)->Size - sizeof(UnusedChunkFooter)) )->Size == (Chunk)->Size )
|
||||
#define IsGoodChunk(Chunk) (IsGoodChunkPosition(Chunk) && (Chunk)->Size >= 32 && IsGoodChunkPosition((uintptr_t) (Chunk) + (Chunk)->Size) && IsGoodChunkInfo(Chunk) )
|
||||
#define IsGoodUnusedChunk(Chunk) ( IsGoodChunk(Chunk) && ( Chunk->NextUnused == NULL || IsGoodChunkPosition(Chunk->NextUnused) ) )
|
||||
#define IsGoodUsedChunk(Chunk) ( IsGoodChunk(Chunk) && Chunk->Magic == Magic )
|
||||
#ifdef PLATFORM_X64
|
||||
#define IsGoodBinIndex(Index) ( 4 <= Index && Index < 32 )
|
||||
#else
|
||||
#define IsGoodBinIndex(Index) ( 5 <= Index && Index < 64 )
|
||||
#endif
|
||||
#define IsAligned(Value, Alignment) ( (Value & (Alignment-1)) == 0 )
|
||||
|
||||
#define BITS(x) (8UL*sizeof(x))
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
// TODO: How should this API exist? Should it be publicly accessasble?
|
||||
// Where should the C bindings (if relevant) be declared and defined?
|
||||
// Is it part of the kernel or the standard library? What should it be
|
||||
// called? Is it an extension? For now, I'll just leave this here, hidden
|
||||
// away in libmaxsi until I figure out how libmaxsi/sortix should handle
|
||||
// facilities currently only available on Sortix.
|
||||
namespace System
|
||||
{
|
||||
namespace Memory
|
||||
{
|
||||
bool Allocate(void* /*position*/, size_t /*length*/)
|
||||
{
|
||||
// TODO: Implement a syscall for this!
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
// This magic word is useful to see if the program has written into the
|
||||
// chunk's header or footer, which means the program has malfunctioned
|
||||
// and ought to be terminated.
|
||||
#ifdef PLATFORM_X64
|
||||
const size_t Magic = 0xDEADDEADDEADDEADULL;
|
||||
#else
|
||||
const size_t Magic = 0xDEADDEAD;
|
||||
#endif
|
||||
|
||||
// All requsted sizes must be a multiple of this.
|
||||
const size_t Alignment = 16ULL;
|
||||
|
||||
// Returns the index of the most significant set bit.
|
||||
inline size_t BSR(size_t Value)
|
||||
{
|
||||
#if 1
|
||||
ASSERT(Value > 0);
|
||||
for ( size_t I = 8*sizeof(size_t); I > 0; I-- )
|
||||
{
|
||||
if ( Value & ( 1 << (I-1) ) ) { return I-1; }
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
size_t Result;
|
||||
asm("bsr %0, %1" : "=r"(Result) : "r"(Value));
|
||||
return Result;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns the index of the least significant set bit.
|
||||
inline size_t BSF(size_t Value)
|
||||
{
|
||||
#if 1
|
||||
ASSERT(Value > 0);
|
||||
for ( size_t I = 0; I < 8*sizeof(size_t); I++ )
|
||||
{
|
||||
if ( Value & ( 1 << I ) ) { return I; }
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
size_t Result;
|
||||
asm("bsf %0, %1" : "=r"(Result) : "r"(Value));
|
||||
return Result;
|
||||
#endif
|
||||
}
|
||||
// NOTE: BSR(N) = Log2RoundedDown(N).
|
||||
|
||||
// NOTE: BSR(N-1)+1 = Log2RoundedUp(N), N > 1.
|
||||
// PROOF: If X=2^N is a power of two, then BSR(X) = Log2(X) = N.
|
||||
// If X is not a power of two, then BSR(X) will return the previous
|
||||
// power of two.
|
||||
// If we want the next power of two for a non-power-of-two then
|
||||
// BSR(X)+1 would work. However, this causes problems for X=2^N, where
|
||||
// it returns a value one too big.
|
||||
// BSR(X-1)+1 = BSR(X)+1 give the same value for all X that is not a
|
||||
// power of two. For X=2^N, BSR(X-1)+1 will be one lower, which is
|
||||
// exactly what we want. QED.
|
||||
|
||||
// Now declare some structures that are put around the allocated data.
|
||||
struct UnusedChunkHeader
|
||||
{
|
||||
size_t Size;
|
||||
UnusedChunkHeader* NextUnused;
|
||||
};
|
||||
|
||||
struct UnusedChunkFooter
|
||||
{
|
||||
void* Unused;
|
||||
size_t Size;
|
||||
};
|
||||
|
||||
struct UsedChunkHeader
|
||||
{
|
||||
size_t Size;
|
||||
size_t Magic;
|
||||
};
|
||||
|
||||
struct UsedChunkFooter
|
||||
{
|
||||
size_t Magic;
|
||||
size_t Size;
|
||||
};
|
||||
|
||||
// How much extra space will our headers use?
|
||||
const size_t ChunkOverhead = sizeof(UsedChunkHeader) + sizeof(UsedChunkFooter);
|
||||
size_t GetChunkOverhead() { return ChunkOverhead; }
|
||||
|
||||
// A bin for each power of two.
|
||||
UnusedChunkHeader* Bins[BITS(size_t)];
|
||||
|
||||
// INVARIANT: A bit is set for each bin if it contains anything.
|
||||
size_t BinContainsChunks;
|
||||
|
||||
// And south of everything, there is nothing allocated, at which
|
||||
// extra space can be added on-demand.
|
||||
// INVARIANT: Wilderness is always page-aligned!
|
||||
const byte* HeapStart;
|
||||
const byte* Wilderness;
|
||||
size_t WildernessSize;
|
||||
|
||||
// Initializes the heap system.
|
||||
void Init()
|
||||
{
|
||||
Memory::Set(Bins, 0, sizeof(Bins));
|
||||
#ifdef SORTIX_KERNEL
|
||||
Wilderness = (byte*) Sortix::VirtualMemory::KernelHalfEnd;
|
||||
#else
|
||||
// TODO: This is very 32-bit specific!
|
||||
Wilderness = (byte*) 0x80000000;
|
||||
#endif
|
||||
HeapStart = Wilderness;
|
||||
WildernessSize = 0;
|
||||
BinContainsChunks = 0;
|
||||
}
|
||||
|
||||
// Expands the wilderness block (the heap grows downwards).
|
||||
bool ExpandWilderness(size_t NeededSize)
|
||||
{
|
||||
if ( NeededSize <= WildernessSize ) { return true; }
|
||||
|
||||
ASSERT(Wilderness != NULL);
|
||||
|
||||
// Check if we are going too far down (beneath the NULL position!).
|
||||
if ( (uintptr_t) Wilderness < NeededSize ) { return false; }
|
||||
|
||||
#ifdef SORTIX_KERNEL
|
||||
// Check if the wilderness would grow larger than the kernel memory area.
|
||||
if ( ( ((uintptr_t) Wilderness) - Sortix::VirtualMemory::KernelHalfStart ) < NeededSize ) { return false; }
|
||||
#endif
|
||||
|
||||
// Figure out how where the new wilderness will be.
|
||||
uintptr_t NewWilderness = ((uintptr_t) Wilderness) + WildernessSize - NeededSize;
|
||||
|
||||
// And now align downwards to the page boundary.
|
||||
NewWilderness &= ~(0xFFFUL);
|
||||
|
||||
ASSERT(NewWilderness < (uintptr_t) Wilderness);
|
||||
|
||||
// Figure out where and how much memory we need.
|
||||
byte* MemoryStart = (byte*) NewWilderness;
|
||||
size_t MemorySize = (uintptr_t) Wilderness - (uintptr_t) NewWilderness;
|
||||
|
||||
#ifndef SORTIX_KERNEL // We are user-space.
|
||||
|
||||
// Ask the kernel to map memory to the needed region!
|
||||
if ( !System::Memory::Allocate(MemoryStart, MemorySize) ) { return false; }
|
||||
|
||||
#else // We are Sortix.
|
||||
|
||||
// Figure out how many pages we need.
|
||||
size_t NumPages = MemorySize / 4096;
|
||||
size_t PagesLeft = NumPages;
|
||||
|
||||
ASSERT(NumPages > 0);
|
||||
|
||||
// Attempt to allocate and map each of them.
|
||||
while ( PagesLeft > 0 )
|
||||
{
|
||||
PagesLeft--;
|
||||
|
||||
// Get a raw unused physical page.
|
||||
void* Page = Sortix::Page::Get();
|
||||
|
||||
if ( Page == NULL )
|
||||
{
|
||||
// If none is available, simply let the allocation fail
|
||||
// and unallocate everything we did allocate so far.
|
||||
while ( PagesLeft < NumPages )
|
||||
{
|
||||
PagesLeft++;
|
||||
|
||||
uintptr_t OldVirtual = NewWilderness + 4096 * PagesLeft;
|
||||
void* OldPage = Sortix::VirtualMemory::LookupAddr(OldVirtual);
|
||||
Sortix::VirtualMemory::Map(0, OldVirtual, 0);
|
||||
Sortix::Page::Put(OldPage);
|
||||
}
|
||||
|
||||
// Flash the TLB to restore everything safely.
|
||||
Sortix::VirtualMemory::Flush();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Map the physical page to a virtual one.
|
||||
uintptr_t VirtualAddr = NewWilderness + 4096 * PagesLeft;
|
||||
|
||||
Sortix::VirtualMemory::Map((uintptr_t) Page, VirtualAddr, TABLE_PRESENT | TABLE_WRITABLE);
|
||||
}
|
||||
|
||||
// Now flush the TLB such that the new pages can be safely used.
|
||||
Sortix::VirtualMemory::Flush();
|
||||
#endif
|
||||
|
||||
// Update the wilderness information now that it is safe.
|
||||
Wilderness = MemoryStart;
|
||||
WildernessSize += MemorySize;
|
||||
|
||||
ASSERT(WildernessSize >= NeededSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Allocates a continious memory region of Size bytes that must be deallocated using Free.
|
||||
DUAL_FUNCTION(void*, malloc, Allocate, (size_t Size))
|
||||
{
|
||||
// Always allocate a multiple of alignment (round up to nearest aligned size).
|
||||
// INVARIANT: Size is always aligned after this statement.
|
||||
Size = (Size + Alignment - 1) & ~(Alignment-1);
|
||||
|
||||
// Account for the overhead of the headers and footers.
|
||||
Size += ChunkOverhead;
|
||||
|
||||
ASSERT((Size & (Alignment-1)) == 0);
|
||||
|
||||
// Find the index of the smallest usable bin.
|
||||
// INVARIANT: Size is always at least ChunkOverhead bytes, thus
|
||||
// Size-1 will never be 0, and thus BSR is always defined.
|
||||
size_t MinBinIndex = BSR(Size-1)+1;
|
||||
ASSERT(IsGoodBinIndex(MinBinIndex));
|
||||
|
||||
// Make a bitmask that filters away all bins that are too small.
|
||||
size_t MinBinMask = ~((1 << MinBinIndex) - 1);
|
||||
ASSERT( ( (1 << (MinBinIndex-1)) & MinBinMask ) == 0);
|
||||
|
||||
// Now filter all bins away that are too small.
|
||||
size_t AvailableBins = BinContainsChunks & MinBinMask;
|
||||
|
||||
// Does any bin contain an usable chunk?
|
||||
if ( AvailableBins > 0 )
|
||||
{
|
||||
// Now find the smallest usable bin.
|
||||
size_t BinIndex = BSF( AvailableBins );
|
||||
ASSERT(IsGoodBinIndex(BinIndex));
|
||||
|
||||
// And pick the first thing in it.
|
||||
UnusedChunkHeader* Chunk = Bins[BinIndex];
|
||||
ASSERT(IsGoodUnusedChunk(Chunk));
|
||||
|
||||
// Increment the bin's linked list.
|
||||
Bins[BinIndex] = Chunk->NextUnused;
|
||||
ASSERT(Chunk->NextUnused == NULL || IsGoodUnusedChunk(Chunk->NextUnused));
|
||||
|
||||
// Find the size of this bin (also the value of this bins flag).
|
||||
size_t BinSize = 1 << BinIndex;
|
||||
ASSERT(BinSize >= Size);
|
||||
|
||||
// If we emptied the bin, then remove the flag that says this bin is usable.
|
||||
ASSERT(BinContainsChunks & BinSize);
|
||||
if ( Chunk->NextUnused == NULL ) { BinContainsChunks ^= BinSize; }
|
||||
|
||||
// Figure out where the chunk ends.
|
||||
uintptr_t ChunkEnd = ((uintptr_t) Chunk) + Chunk->Size;
|
||||
|
||||
// If we were to split the chunk into one used part, and one unused part, then
|
||||
// figure out where the unused part would begin.
|
||||
uintptr_t NewChunkStart = ((uintptr_t) Chunk) + Size;
|
||||
|
||||
// INVARIANT: NewChunkStart is always less or equal to ChunkEnd,
|
||||
// because Size is less or equal to Chunk->Size (otherwise this
|
||||
// chunk could not have been selected above).
|
||||
ASSERT(NewChunkStart <= ChunkEnd);
|
||||
// INVARIANT: NewChunkStart is aligned because Chunk is (this
|
||||
// is made sure when chunks are made when expanding into the
|
||||
// wilderness, when splitting blocks, and when combining them),
|
||||
// and because Size is aligned (first thing we make sure).
|
||||
ASSERT( IsAligned(NewChunkStart, Alignment) );
|
||||
|
||||
// Find the size of the possible new chunk.
|
||||
size_t NewChunkSize = ChunkEnd - NewChunkStart;
|
||||
|
||||
UsedChunkHeader* ResultHeader = (UsedChunkHeader*) Chunk;
|
||||
|
||||
// See if it's worth it to split the chunk into two, if any space is left in it.
|
||||
if ( NewChunkSize >= sizeof(UnusedChunkHeader) + sizeof(UnusedChunkFooter) )
|
||||
{
|
||||
// Figure out which bin to put the new chunk in.
|
||||
size_t NewBinIndex = BSR(NewChunkSize);
|
||||
ASSERT(IsGoodBinIndex(NewBinIndex));
|
||||
|
||||
// Mark that a chunk is available for this bin.
|
||||
BinContainsChunks |= (1 << NewBinIndex);
|
||||
|
||||
// Now write some headers and footers for the new chunk.
|
||||
UnusedChunkHeader* NewChunkHeader = (UnusedChunkHeader*) NewChunkStart;
|
||||
ASSERT(IsGoodChunkPosition(NewChunkStart));
|
||||
|
||||
NewChunkHeader->Size = NewChunkSize;
|
||||
NewChunkHeader->NextUnused = Bins[NewBinIndex];
|
||||
ASSERT(NewChunkHeader->NextUnused == NULL || IsGoodChunk(NewChunkHeader->NextUnused));
|
||||
|
||||
UnusedChunkFooter* NewChunkFooter = (UnusedChunkFooter*) (ChunkEnd - sizeof(UnusedChunkFooter));
|
||||
NewChunkFooter->Size = NewChunkSize;
|
||||
NewChunkFooter->Unused = NULL;
|
||||
|
||||
// Put the new chunk in front of our linked list.
|
||||
ASSERT(IsGoodUnusedChunk(NewChunkHeader));
|
||||
Bins[NewBinIndex] = NewChunkHeader;
|
||||
|
||||
// We need to modify our resulting chunk to be smaller.
|
||||
ResultHeader->Size = Size;
|
||||
}
|
||||
|
||||
// Set the required magic values.
|
||||
UsedChunkFooter* ResultFooter = (UsedChunkFooter*) ( ((byte*) ResultHeader) + ResultHeader->Size - sizeof(UsedChunkFooter) );
|
||||
ResultHeader->Magic = Magic;
|
||||
ResultFooter->Magic = Magic;
|
||||
ResultFooter->Size = Size;
|
||||
|
||||
ASSERT(IsGoodUsedChunk(ResultHeader));
|
||||
|
||||
return ((byte*) ResultHeader) + sizeof(UnusedChunkHeader);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have no free chunks that are big enough, let's expand our heap into the unknown, if possible.
|
||||
if ( WildernessSize < Size && !ExpandWilderness(Size) ) { Error::Set(Error::NOMEM); return NULL; }
|
||||
|
||||
// Write some headers and footers around our newly allocated data.
|
||||
UsedChunkHeader* ResultHeader = (UsedChunkHeader*) (Wilderness + WildernessSize - Size);
|
||||
UsedChunkFooter* ResultFooter = (UsedChunkFooter*) (Wilderness + WildernessSize - sizeof(UsedChunkFooter));
|
||||
WildernessSize -= Size;
|
||||
|
||||
ResultHeader->Size = Size;
|
||||
ResultHeader->Magic = Magic;
|
||||
ResultFooter->Size = Size;
|
||||
ResultFooter->Magic = Magic;
|
||||
|
||||
ASSERT(IsGoodUsedChunk(ResultHeader));
|
||||
|
||||
return ((byte*) ResultHeader) + sizeof(UsedChunkHeader);
|
||||
}
|
||||
}
|
||||
|
||||
// Frees a continious memory region allocated by Allocate.
|
||||
DUAL_FUNCTION(void, free, Free, (void* Addr))
|
||||
{
|
||||
// Just ignore NULL-pointers.
|
||||
if ( Addr == NULL ) { return; }
|
||||
|
||||
// Restore the chunk information structures.
|
||||
UsedChunkHeader* ChunkHeader = (UsedChunkHeader*) ( ((byte*) Addr) - sizeof(UsedChunkHeader) );
|
||||
UsedChunkFooter* ChunkFooter = (UsedChunkFooter*) ( ((byte*) ChunkHeader) + ChunkHeader->Size - sizeof(UsedChunkFooter) );
|
||||
|
||||
ASSERT(IsGoodUsedChunk(ChunkHeader));
|
||||
|
||||
// If you suspect a chunk of bein' a witch, report them immediately. I cannot stress that enough. Witchcraft will not be tolerated.
|
||||
if ( ChunkHeader->Magic != Magic || ChunkFooter->Magic != Magic || ChunkHeader->Size != ChunkFooter->Size )
|
||||
{
|
||||
#ifdef SORTIX_KERNEL
|
||||
Sortix::PanicF("Witchcraft detected!\n", ChunkHeader);
|
||||
#endif
|
||||
// TODO: Report witchcraft (terminating the process is probably a good idea).
|
||||
}
|
||||
|
||||
// TODO: Combine this chunk with its neighbors, if they are also unused.
|
||||
|
||||
// Calculate which bin this chunk belongs to.
|
||||
size_t BinIndex = BSR(ChunkHeader->Size);
|
||||
ASSERT(IsGoodBinIndex(BinIndex));
|
||||
|
||||
// Mark that a chunk is available for this bin.
|
||||
BinContainsChunks |= (1 << BinIndex);
|
||||
|
||||
UnusedChunkHeader* UnChunkHeader = (UnusedChunkHeader*) ChunkHeader;
|
||||
UnusedChunkFooter* UnChunkFooter = (UnusedChunkFooter*) ChunkFooter;
|
||||
|
||||
// Now put this chunk back in the linked list.
|
||||
ASSERT(Bins[BinIndex] == NULL || IsGoodUnusedChunk(Bins[BinIndex]));
|
||||
UnChunkHeader->NextUnused = Bins[BinIndex];
|
||||
UnChunkFooter->Unused = NULL;
|
||||
|
||||
ASSERT(IsGoodUnusedChunk(UnChunkHeader));
|
||||
Bins[BinIndex] = UnChunkHeader;
|
||||
}
|
||||
|
||||
DUAL_FUNCTION(void*, memcpy, Copy, (void* Dest, const void* Src, size_t Length))
|
||||
{
|
||||
char* D = (char*) Dest; const char* S = (const char*) Src;
|
||||
|
||||
for ( size_t I = 0; I < Length; I++ )
|
||||
{
|
||||
D[I] = S[I];
|
||||
}
|
||||
|
||||
return Dest;
|
||||
}
|
||||
|
||||
DUAL_FUNCTION(void*, memset, Set, (void* Dest, int Value, size_t Length))
|
||||
{
|
||||
byte* D = (byte*) Dest;
|
||||
|
||||
for ( size_t I = 0; I < Length; I++ )
|
||||
{
|
||||
D[I] = Value & 0xFF;
|
||||
}
|
||||
|
||||
return Dest;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
start.s
|
||||
A stub for linking to the C runtime on Sortix.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
.globl _start
|
||||
|
||||
.section .text
|
||||
|
||||
.text 0x100000
|
||||
.type _start, @function
|
||||
_start:
|
||||
|
||||
# Run main
|
||||
# TODO: Sortix should push these values to the stack itself!
|
||||
push $0x0 # argv
|
||||
push $0 # argc
|
||||
call main
|
||||
|
||||
# Now return mains result when exiting the process
|
||||
mov %eax, %ebx
|
||||
mov $1, %eax
|
||||
mov $0x0, %ebx # TODO: This syscall exits a thread, not a process!
|
||||
int $0x80
|
|
@ -0,0 +1,137 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
string.cpp
|
||||
Useful functions for manipulating strings.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "string.h"
|
||||
#include "memory.h"
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
DUAL_FUNCTION(size_t, strlen, Length, (const char* String))
|
||||
{
|
||||
size_t Result = 0;
|
||||
|
||||
while ( String[Result] != '\0' )
|
||||
{
|
||||
Result++;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
DUAL_FUNCTION(char*, strcpy, Copy, (char* Dest, const char* Src))
|
||||
{
|
||||
char* OriginalDest = Dest;
|
||||
|
||||
while ( *Src != '\0' )
|
||||
{
|
||||
*Dest = *Src;
|
||||
Dest++; Src++;
|
||||
}
|
||||
|
||||
return OriginalDest;
|
||||
}
|
||||
|
||||
DUAL_FUNCTION(char*, strcat, Cat, (char* Dest, const char* Src))
|
||||
{
|
||||
char* OriginalDest = Dest;
|
||||
|
||||
while ( *Dest != '\0' ) { Dest++; }
|
||||
|
||||
while ( *Src != '\0' )
|
||||
{
|
||||
*Dest = *Src;
|
||||
Dest++; Src++;
|
||||
}
|
||||
|
||||
return OriginalDest;
|
||||
}
|
||||
|
||||
DUAL_FUNCTION(int, strcmp, Compare, (const char* A, const char* B))
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
if ( *A == '\0' && *B == '\0' ) { return 0; }
|
||||
if ( *A < *B ) { return -1; }
|
||||
if ( *A > *B ) { return 1; }
|
||||
A++; B++;
|
||||
}
|
||||
}
|
||||
|
||||
char* Clone(const char* Input)
|
||||
{
|
||||
size_t InputSize = Length(Input);
|
||||
char* Result = new char[InputSize + 1];
|
||||
if ( Result == NULL ) { return NULL; }
|
||||
Memory::Copy(Result, Input, InputSize + 1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
char* Combine(size_t NumParameters, ...)
|
||||
{
|
||||
va_list param_pt;
|
||||
|
||||
va_start(param_pt, NumParameters);
|
||||
|
||||
// First calculate the string length.
|
||||
size_t ResultLength = 0;
|
||||
const char* TMP = 0;
|
||||
|
||||
for ( size_t I = 0; I < NumParameters; I++ )
|
||||
{
|
||||
TMP = va_arg(param_pt, const char*);
|
||||
|
||||
if ( TMP != NULL ) { ResultLength += strlen(TMP); }
|
||||
}
|
||||
|
||||
// Allocate a string with the desired length.
|
||||
char* Result = new char[ResultLength+1];
|
||||
|
||||
Result[0] = 0;
|
||||
|
||||
va_end(param_pt);
|
||||
va_start(param_pt, NumParameters);
|
||||
|
||||
size_t ResultOffset = 0;
|
||||
|
||||
for ( size_t I = 0; I < NumParameters; I++ )
|
||||
{
|
||||
TMP = va_arg(param_pt, const char*);
|
||||
|
||||
if ( TMP )
|
||||
{
|
||||
size_t TMPLength = strlen(TMP);
|
||||
strcpy(Result + ResultOffset, TMP);
|
||||
ResultOffset += TMPLength;
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
thread.cpp
|
||||
Exposes system calls for thread creation and management.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#ifdef LIBMAXSI_LIBC
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include "syscall.h"
|
||||
#include "thread.h"
|
||||
|
||||
#ifdef SORTIX_KERNEL
|
||||
extern "C" void PanicF(const char* Format, ...);
|
||||
#endif
|
||||
|
||||
namespace Maxsi
|
||||
{
|
||||
namespace Thread
|
||||
{
|
||||
typedef void (*SysEntry)(size_t, Entry, void*);
|
||||
DEFN_SYSCALL4(size_t, SysCreate, 0, SysEntry, Entry, const void*, size_t);
|
||||
DEFN_SYSCALL1_VOID(SysExit, 1, const void*);
|
||||
DEFN_SYSCALL1_VOID(SysSleep, 2, long);
|
||||
DEFN_SYSCALL1_VOID(SysUSleep, 3, long);
|
||||
|
||||
void Exit(const void* Result)
|
||||
{
|
||||
SysExit(Result);
|
||||
}
|
||||
|
||||
#ifdef LIBMAXSI_LIBC
|
||||
extern "C" void exit(int result)
|
||||
{
|
||||
SysExit(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ThreadStartup(size_t Id, Entry Start, void* Parameter)
|
||||
{
|
||||
Exit(Start(Parameter));
|
||||
}
|
||||
|
||||
size_t Create(Entry Start, const void* Parameter, size_t StackSize)
|
||||
{
|
||||
return SysCreate(&ThreadStartup, Start, Parameter, StackSize);
|
||||
}
|
||||
|
||||
#ifdef LIBMAXSI_LIBC
|
||||
extern "C" unsigned sleep(unsigned Seconds) { SysSleep(Seconds); return 0; /* TODO: Posix mentions something about signals and whatnot. */}
|
||||
#endif
|
||||
|
||||
// TODO: Thinking about it, there is no need for this to be a long.
|
||||
// Sortix will never run for that long time, and shouldn't it be unsigned long?
|
||||
void Sleep(long Seconds)
|
||||
{
|
||||
SysSleep(Seconds);
|
||||
}
|
||||
|
||||
|
||||
#ifdef LIBMAXSI_LIBC
|
||||
extern "C" int usleep(useconds_t Microseconds) { SysUSleep(Microseconds); return 0; }
|
||||
#endif
|
||||
|
||||
void USleep(long Microseconds)
|
||||
{
|
||||
SysUSleep(Microseconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
@ -0,0 +1,68 @@
|
|||
subdirs = @subdirs@
|
||||
top_srcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
bindir = $(exec_prefix)/bin
|
||||
infodir = $(prefix)/info
|
||||
libdir = $(prefix)/lib/gnudl
|
||||
mandir = $(prefix)/man/man1
|
||||
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PACKAGE_TARNAME = @PACKAGE_NAME@-@PACKAGE_VERSION@
|
||||
CC=@CC@
|
||||
CXX=@CXX@
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
CXXFLAGS=@CXXFLAGS@ -Wall
|
||||
LDFLAGS=@LDFLAGS@ $(LIBS)
|
||||
LIBS = @LIBS@
|
||||
INSTALL = @INSTALL@
|
||||
EXEEXT = @EXEEXT@
|
||||
HOST = @HOST@
|
||||
BINARY=mxmpp$(EXEEXT)
|
||||
|
||||
DISTDIR:=$(PACKAGE_TARNAME)
|
||||
DISTFILES=config.guess config.h.in config.sub configure configure.ac COPYING README install-sh Makefile.in mxmpp.cpp
|
||||
|
||||
all: $(BINARY)
|
||||
|
||||
$(BINARY): mxmpp.cpp
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ mxmpp.cpp $(LDFLAGS) $(TARGET_ARCH)
|
||||
|
||||
clean:
|
||||
$(RM) $(BINARY)
|
||||
|
||||
distclean: clean
|
||||
$(RM) Makefile config.h config.status config.cache config.log
|
||||
$(RM) -r $(BUILDDIR) $(DISTDIR)
|
||||
|
||||
install: all
|
||||
$(INSTALL) $(BINARY) $(bindir)
|
||||
|
||||
dist: dist-gzip
|
||||
|
||||
dist-all: dist-gzip dist-lzma dist-bzip2 dist-xz
|
||||
|
||||
dist-gzip: $(DISTDIR)
|
||||
$(RM) $(PACKAGE_TARNAME).tar.gz
|
||||
tar -cf - $(DISTDIR) | gzip -9 > $(PACKAGE_TARNAME).tar.gz
|
||||
|
||||
dist-lzma: $(DISTDIR)
|
||||
$(RM) $(PACKAGE_TARNAME).tar.lzma
|
||||
tar -cf - $(DISTDIR) | lzma -9 > $(PACKAGE_TARNAME).tar.lzma
|
||||
|
||||
dist-bzip2: $(DISTDIR)
|
||||
$(RM) $(PACKAGE_TARNAME).tar.bz2
|
||||
tar -cf - $(DISTDIR) | bzip2 -9 > $(PACKAGE_TARNAME).tar.bz2
|
||||
|
||||
dist-xz: $(DISTDIR)
|
||||
$(RM) $(PACKAGE_TARNAME).tar.xz
|
||||
tar -cf - $(DISTDIR) | xz -c > $(PACKAGE_TARNAME).tar.xz
|
||||
|
||||
$(DISTDIR): FORCE
|
||||
mkdir -p $(DISTDIR)
|
||||
cp -rv $(DISTFILES) $(DISTDIR)
|
||||
|
||||
FORCE:
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
This is a small command-line tool for creating sound files in .wav or raw header-less PCM format with a specific frequency, duration, and amplitude.
|
||||
|
||||
= Website
|
||||
Please see http://www.maxsi.org/software/mksound/
|
||||
|
||||
= Features
|
||||
* Supports .wav format and header-less PCM format.
|
||||
* Generates sound files with a specific frequency, amplitude, and duration.
|
||||
* Supports any sample rate.
|
||||
* Supports any number of channels
|
||||
* Sound data can be piped to audio software.
|
||||
* Cross-Platform - works on GNU/Linux and Windows, and (possibly) Mac OS X.
|
||||
|
||||
= Releases
|
||||
== Version 0.2 - Thursday, July 14 2011
|
||||
* Added support for any number of channels.
|
||||
* Added support for any number of channels.
|
||||
|
||||
== Version 0.1 - Wednesday, July 13 2011
|
||||
* Initial release.
|
||||
|
||||
= Installing
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
= License Terms
|
||||
Maxsi mksound is licensed under the GNU GPL (verson 3 or later), which means it is free software, giving your the right to freely use, study, modify and redistribute it. There is a few conditions to use the software, such as you must provide its source code when redistributing it.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,152 @@
|
|||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* this is an AmigaOS4 platform */
|
||||
#undef AMIGAOS4_HOST
|
||||
|
||||
/* this is an Android platform */
|
||||
#undef ANDROID_HOST
|
||||
|
||||
/* this is a Darwin platform */
|
||||
#undef DARWIN_HOST
|
||||
|
||||
/* this is a FreeBSD platform */
|
||||
#undef FREEBSD_HOST
|
||||
|
||||
/* this is a GNU platform */
|
||||
#undef GNU_HOST
|
||||
|
||||
/* this is a Haiku platform */
|
||||
#undef HAIKU_HOST
|
||||
|
||||
/* Define to 1 if you have the `close' function. */
|
||||
#undef HAVE_CLOSE
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `fprintf' function. */
|
||||
#undef HAVE_FPRINTF
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `open' function. */
|
||||
#undef HAVE_OPEN
|
||||
|
||||
/* Define to 1 if you have the `perror' function. */
|
||||
#undef HAVE_PERROR
|
||||
|
||||
/* Define to 1 if you have the `printf' function. */
|
||||
#undef HAVE_PRINTF
|
||||
|
||||
/* Define to 1 if you have the `sscanf' function. */
|
||||
#undef HAVE_SSCANF
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#undef HAVE_STDBOOL_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#undef HAVE_STDIO_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strcmp' function. */
|
||||
#undef HAVE_STRCMP
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `write' function. */
|
||||
#undef HAVE_WRITE
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#undef HAVE__BOOL
|
||||
|
||||
/* this is a Linux platform */
|
||||
#undef LINUX_HOST
|
||||
|
||||
/* this is a NetBSD platform */
|
||||
#undef NETBSD_HOST
|
||||
|
||||
/* this is an OpenBSD platform */
|
||||
#undef OPENBSD_HOST
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* this is a Solaris platform */
|
||||
#undef SOLARIS_HOST
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* this is a Win32 platform */
|
||||
#undef WIN32_HOST
|
||||
|
||||
/* this is a WINCE6 platform */
|
||||
#undef WINCE6_HOST
|
||||
|
||||
/* this is a WINCE platform */
|
||||
#undef WINCE_HOST
|
||||
|
||||
/* this is a 64 platform */
|
||||
#undef WORDSIZE
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#undef _UINT8_T
|
||||
|
||||
/* this is a 64 bit powerpc */
|
||||
#undef __powerpc64__
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 16 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef int16_t
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 8 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint8_t
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,110 @@
|
|||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.67])
|
||||
AC_INIT([mxmpp], [0.1], [sortie@maxsi.org])
|
||||
AC_CONFIG_SRCDIR([mxmpp.cpp])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
AC_CANONICAL_BUILD
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_SYSTEM
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CC
|
||||
AC_MINGW32
|
||||
AC_EXEEXT
|
||||
AC_PROG_INSTALL
|
||||
|
||||
dnl Some things you can only do by looking at the platform name.
|
||||
case "${host}" in
|
||||
powerpc-apple-darwin*)
|
||||
AC_DEFINE([__powerpc64__], [1], [this is a 64 bit powerpc])
|
||||
darwin=yes
|
||||
AC_DEFINE([DARWIN_HOST], [1], [this is a Darwin platform])
|
||||
;;
|
||||
*-apple-darwin*)
|
||||
darwin=yes
|
||||
AC_DEFINE([DARWIN_HOST], [1], [this is a Darwin platform])
|
||||
;;
|
||||
dnl Unfortunately, all BSD distributions are not identical, so
|
||||
dnl as tacky as it is to look for the distribution name, we don't
|
||||
dnl have much choice. The use of these should be avoid as much as possible.
|
||||
*-openbsd*)
|
||||
bsd=yes
|
||||
openbsd=yes
|
||||
AC_DEFINE([OPENBSD_HOST], [1], [this is an OpenBSD platform])
|
||||
;;
|
||||
*-freebsd* | *-kfreebsd*)
|
||||
bsd=yes
|
||||
freebsd=yes
|
||||
AC_DEFINE([FREEBSD_HOST], [1], [this is a FreeBSD platform])
|
||||
;;
|
||||
*-netbsd*)
|
||||
bsd=yes
|
||||
netbsd=yes
|
||||
AC_DEFINE([NETBSD_HOST], [1], [this is a NetBSD platform])
|
||||
;;
|
||||
*-*solaris*)
|
||||
solaris=yes
|
||||
AC_DEFINE([SOLARIS_HOST], [1], [this is a Solaris platform])
|
||||
;;
|
||||
*-*linux*)
|
||||
linux=yes
|
||||
AC_DEFINE([LINUX_HOST], [1], [this is a Linux platform])
|
||||
;;
|
||||
*-cygwin* | *-mingw* | *-pw32*)
|
||||
windows=yes
|
||||
AC_DEFINE([WIN32_HOST], [1], [this is a Win32 platform])
|
||||
;;
|
||||
*64-*-*bsd*)
|
||||
bsd_os=bsd
|
||||
AC_DEFINE([WORDSIZE], [64], [this is a 64 platform])
|
||||
;;
|
||||
*-*amigaos*)
|
||||
amigaos4=yes
|
||||
AC_DEFINE([AMIGAOS4_HOST], [1], [this is an AmigaOS4 platform])
|
||||
;;
|
||||
*-*haiku*)
|
||||
haiku=yes
|
||||
AC_DEFINE([HAIKU_HOST], [1], [this is a Haiku platform])
|
||||
;;
|
||||
*-gnu*)
|
||||
gnu=yes
|
||||
AC_DEFINE([GNU_HOST], [1], [this is a GNU platform])
|
||||
;;
|
||||
*-*wince)
|
||||
wince=yes
|
||||
AC_DEFINE([WINCE_HOST], [1], [this is a WINCE platform])
|
||||
;;
|
||||
*-*winmo)
|
||||
wince=yes
|
||||
AC_DEFINE([WINCE_HOST], [1], [this is a WINCE platform])
|
||||
AC_DEFINE([WINCE6_HOST], [1], [this is a WINCE6 platform])
|
||||
;;
|
||||
*-android*)
|
||||
android=yes
|
||||
AC_DEFINE([ANDROID_HOST], [1], [this is an Android platform])
|
||||
;;
|
||||
esac
|
||||
|
||||
HOST="$host"
|
||||
AC_SUBST([HOST])
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([fcntl.h unistd.h sys/types.h sys/stat.h])
|
||||
AC_CHECK_HEADERS([stdint.h stdio.h string.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_HEADER_STDBOOL
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_UINT8_T
|
||||
AC_TYPE_INT16_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_FUNCS([open write close fprintf strcmp printf sscanf perror])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
|
@ -0,0 +1,322 @@
|
|||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2004-09-10.20
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=
|
||||
chgrpcmd=
|
||||
stripcmd=
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dstarg=
|
||||
no_target_directory=
|
||||
|
||||
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
-c (ignored)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test -n "$1"; do
|
||||
case $1 in
|
||||
-c) shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
--help) echo "$usage"; exit 0;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd=$stripprog
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t) dstarg=$2
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-T) no_target_directory=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit 0;;
|
||||
|
||||
*) # When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
test -n "$dir_arg$dstarg" && break
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dstarg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dstarg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dstarg=$arg
|
||||
done
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -z "$1"; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src ;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
src=
|
||||
|
||||
if test -d "$dst"; then
|
||||
mkdircmd=:
|
||||
chmodcmd=
|
||||
else
|
||||
mkdircmd=$mkdirprog
|
||||
fi
|
||||
else
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dstarg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dstarg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst ;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dstarg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst/`basename "$src"`
|
||||
fi
|
||||
fi
|
||||
|
||||
# This sed command emulates the dirname command.
|
||||
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if test ! -d "$dstdir"; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-$defaultIFS}"
|
||||
|
||||
oIFS=$IFS
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS=$oIFS
|
||||
|
||||
pathcomp=
|
||||
|
||||
while test $# -ne 0 ; do
|
||||
pathcomp=$pathcomp$1
|
||||
shift
|
||||
if test ! -d "$pathcomp"; then
|
||||
$mkdirprog "$pathcomp"
|
||||
# mkdir can fail with a `File exist' error in case several
|
||||
# install-sh are creating the directory concurrently. This
|
||||
# is OK.
|
||||
test -d "$pathcomp" || exit
|
||||
fi
|
||||
pathcomp=$pathcomp/
|
||||
done
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
$doit $mkdircmd "$dst" \
|
||||
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
||||
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
||||
|
||||
else
|
||||
dstfile=`basename "$dst"`
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
$doit $cpprog "$src" "$dsttmp" &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
||||
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|
||||
|| {
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
if test -f "$dstdir/$dstfile"; then
|
||||
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
||||
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
||||
|| {
|
||||
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||
(exit 1); exit
|
||||
}
|
||||
else
|
||||
:
|
||||
fi
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||
}
|
||||
}
|
||||
fi || { (exit 1); exit; }
|
||||
done
|
||||
|
||||
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||
{
|
||||
(exit 0); exit
|
||||
}
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
|
@ -0,0 +1,414 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of mksound.
|
||||
|
||||
mksound 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 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
mksound 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 mksound. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
mxmpp.cpp
|
||||
A simple macro preprocessor.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef S_IRGRP
|
||||
#define S_IRGRP (0)
|
||||
#endif
|
||||
#ifndef S_IWGRP
|
||||
#define S_IWGRP (0)
|
||||
#endif
|
||||
#ifndef S_IROTH
|
||||
#define S_IROTH (0)
|
||||
#endif
|
||||
#ifndef S_IWOTH
|
||||
#define S_IWOTH (0)
|
||||
#endif
|
||||
|
||||
bool writeall(int fd, const void* p, size_t size)
|
||||
{
|
||||
const uint8_t* buffer = (const uint8_t*) p;
|
||||
|
||||
size_t bytesWritten = 0;
|
||||
|
||||
while ( bytesWritten < size )
|
||||
{
|
||||
ssize_t written = write(fd, buffer + bytesWritten, size - bytesWritten);
|
||||
if ( written < 0 ) { perror("write"); return false; }
|
||||
bytesWritten += written;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void usage(int argc, char* argv[])
|
||||
{
|
||||
printf("usage: %s [OPTIONS] [FILE]...\n", argv[0]);
|
||||
printf("Preprocess FILE(s), or standard input.");
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" -o <file> Write output to this file\n");
|
||||
printf(" Default = Standard Output\n");
|
||||
printf(" -I <file> Add this directory to the include search paths\n");
|
||||
printf(" If no paths are set, include from working dir\n");
|
||||
printf(" -q Surpress normal output\n");
|
||||
printf(" -v Be verbose\n");
|
||||
printf(" --usage Display this screen\n");
|
||||
printf(" --help Display this screen\n");
|
||||
printf(" --version Display version information\n");
|
||||
}
|
||||
|
||||
void version()
|
||||
{
|
||||
printf("The Maxsi Macro PreProcessor 0.1\n");
|
||||
printf("Copyright (C) 2011 Jonas 'Sortie' Termansen\n");
|
||||
printf("This is free software; see the source for copying conditions. There is NO\n");
|
||||
printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
|
||||
printf("website: http://www.maxsi.org/software/mxmpp/\n");
|
||||
}
|
||||
|
||||
struct searchpath
|
||||
{
|
||||
const char* path;
|
||||
searchpath* next;
|
||||
};
|
||||
|
||||
struct inputfile
|
||||
{
|
||||
const char* path;
|
||||
inputfile* next;
|
||||
};
|
||||
|
||||
int outfd = -1;
|
||||
|
||||
searchpath* firstpath = NULL;
|
||||
inputfile* firstfile = NULL;
|
||||
|
||||
const size_t CONSTRUCT_SIZE = 511;
|
||||
const size_t BUFFER_SIZE = 4096;
|
||||
|
||||
bool verbose = false;
|
||||
|
||||
char* search(const char* filename);
|
||||
bool include(const char* parameter);
|
||||
bool expand(const char* command, const char* parameter);
|
||||
bool process(int fd);
|
||||
bool process(const char* path);
|
||||
|
||||
char* search(const char* filename)
|
||||
{
|
||||
size_t filenamelen = strlen(filename);
|
||||
|
||||
for ( searchpath* path = firstpath; path != NULL; path = path->next )
|
||||
{
|
||||
size_t searchpathlen = strlen(path->path);
|
||||
size_t filepathlen = searchpathlen + 1 + filenamelen;
|
||||
char* filepath = new char[filepathlen + 1];
|
||||
strcpy(filepath, path->path);
|
||||
strcpy(filepath + searchpathlen, "/");
|
||||
strcpy(filepath + searchpathlen + 1, filename);
|
||||
|
||||
struct stat sts;
|
||||
int statrs = stat(filepath, &sts);
|
||||
if ( statrs < 0 && errno != ENOENT )
|
||||
{
|
||||
fprintf(stderr, "error: could not stat file '%s': %s\n", filepath, strerror(errno)); return NULL;
|
||||
}
|
||||
|
||||
bool found = ( statrs != -1 );
|
||||
|
||||
if ( verbose )
|
||||
{
|
||||
fprintf(stderr, "info: searching for '%s': %s\n", filepath, ( found ) ? "found" : "not found");
|
||||
}
|
||||
|
||||
if ( found )
|
||||
{
|
||||
return filepath;
|
||||
}
|
||||
|
||||
delete[] filepath;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool include(const char* parameter)
|
||||
{
|
||||
if ( parameter[0] == '\0' )
|
||||
{
|
||||
fprintf(stderr, "error: @include expects a non-empty parameter\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( parameter[0] == '/' )
|
||||
{
|
||||
return process(parameter);
|
||||
}
|
||||
|
||||
char* included = search(parameter);
|
||||
|
||||
if ( included == NULL )
|
||||
{
|
||||
fprintf(stderr, "error: could not find included file '%s'\n", parameter);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = process(included);
|
||||
delete[] included;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool expand(const char* command, const char* parameter)
|
||||
{
|
||||
if ( strcmp(command, "@include") == 0 )
|
||||
{
|
||||
return include(parameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "error: unknown macro command %s\n", command);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool process(int fd)
|
||||
{
|
||||
char construct[CONSTRUCT_SIZE+1];
|
||||
char buffer[BUFFER_SIZE];
|
||||
size_t constructed = 0;
|
||||
int phase = 0;
|
||||
|
||||
const char* command = NULL;
|
||||
const char* parameter = NULL;
|
||||
|
||||
bool quote = false;
|
||||
bool backslash = false;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
ssize_t numread = read(fd, buffer, BUFFER_SIZE);
|
||||
if ( numread == 0 ) { break; }
|
||||
if ( numread < 0 ) { perror("read"); return false; }
|
||||
size_t writefrom = 0;
|
||||
|
||||
for ( ssize_t i = 0; i < numread; i++ )
|
||||
{
|
||||
if ( constructed == 0 )
|
||||
{
|
||||
if ( buffer[i] == '\\' ) { backslash = !backslash; continue; }
|
||||
if ( buffer[i] == '"' && !backslash ) { quote = !quote; }
|
||||
if ( buffer[i] == '@' && !quote )
|
||||
{
|
||||
if ( i - writefrom > 0 )
|
||||
{
|
||||
if ( !writeall(outfd, buffer + writefrom, i - writefrom) ) { return false; }
|
||||
}
|
||||
construct[0] = '@'; constructed++;
|
||||
}
|
||||
backslash = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( phase == 0 )
|
||||
{
|
||||
if ( ( ('a' <= buffer[i] && buffer[i] <= 'z' ) ||
|
||||
('A' <= buffer[i] && buffer[i] <= 'Z' ) ) &&
|
||||
( constructed < CONSTRUCT_SIZE) )
|
||||
{
|
||||
construct[constructed] = buffer[i]; constructed++;
|
||||
}
|
||||
else if ( buffer[i] == '(' )
|
||||
{
|
||||
construct[constructed] = '\0'; constructed++;
|
||||
command = construct;
|
||||
parameter = construct + constructed;
|
||||
phase++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
construct[constructed] = '\0';
|
||||
fprintf(stderr, "error: expected '(' after '%s'\n", construct);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( phase == 1 )
|
||||
{
|
||||
if ( buffer[i] == ')' )
|
||||
{
|
||||
construct[constructed] = '\0';
|
||||
if ( !expand(command, parameter) ) { return false; }
|
||||
phase = 0;
|
||||
constructed = 0;
|
||||
writefrom = i + 1;
|
||||
}
|
||||
else if ( buffer[i] != '\n' && buffer[i] != '\r' && constructed < CONSTRUCT_SIZE )
|
||||
{
|
||||
construct[constructed] = buffer[i]; constructed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
construct[constructed] = '\0';
|
||||
fprintf(stderr, "error: expected ')' after '%s'\n", parameter);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( constructed == 0 && numread - writefrom > 0 )
|
||||
{
|
||||
if ( !writeall(outfd, buffer + writefrom, numread - writefrom) ) { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool process(const char* path)
|
||||
{
|
||||
int fd;
|
||||
if ( strcmp(path, "-") == 0 ) { fd = 0; }
|
||||
else if ( (fd = open(path, O_RDONLY) ) < 0 )
|
||||
{
|
||||
fprintf(stderr, "error: couldn't open file '%s'\n", path); return false;
|
||||
}
|
||||
|
||||
if ( verbose )
|
||||
{
|
||||
fprintf(stderr, "info: including file '%s'\n", path);
|
||||
}
|
||||
|
||||
bool result = process(fd);
|
||||
|
||||
if ( verbose )
|
||||
{
|
||||
fprintf(stderr, "info: end of file '%s'\n", path);
|
||||
}
|
||||
|
||||
if ( close(fd) < 0 )
|
||||
{
|
||||
perror("close"); return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
const char* dest = NULL;
|
||||
searchpath* lastpath = NULL;
|
||||
inputfile* lastfile = NULL;
|
||||
|
||||
for ( int i = 1; i < argc; i++ )
|
||||
{
|
||||
if ( strcmp(argv[i], "-I") == 0 )
|
||||
{
|
||||
if ( 2 <= argc - i )
|
||||
{
|
||||
searchpath* path = new searchpath();
|
||||
path->path = argv[i+1];
|
||||
path->next = NULL;
|
||||
if ( firstpath == NULL ) { firstpath = path; } else { lastpath->next = path; }
|
||||
lastpath = path;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if ( strcmp(argv[i], "-o") == 0 )
|
||||
{
|
||||
if ( 2 <= argc - i )
|
||||
{
|
||||
dest = argv[i+1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if ( strcmp(argv[i], "-v") == 0 )
|
||||
{
|
||||
verbose = true;
|
||||
}
|
||||
else if ( strcmp(argv[i], "-q") == 0 )
|
||||
{
|
||||
verbose = false;
|
||||
}
|
||||
else if ( strcmp(argv[i], "--help") == 0 )
|
||||
{
|
||||
usage(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
else if ( strcmp(argv[i], "--usage") == 0 )
|
||||
{
|
||||
usage(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
else if ( strcmp(argv[i], "--version") == 0 )
|
||||
{
|
||||
version();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
inputfile* file = new inputfile();
|
||||
file->path = argv[i];
|
||||
file->next = NULL;
|
||||
if ( firstfile == NULL ) { firstfile = file; } else { lastfile->next = file; }
|
||||
lastfile = file;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dest == NULL || strcmp(dest, "-") == 0 ) { outfd = 1; }
|
||||
else if ( (outfd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) ) < 0 )
|
||||
{
|
||||
fprintf(stderr, "error: couldn't open file '%s'\n", dest); return 1;
|
||||
}
|
||||
|
||||
if ( firstpath == NULL )
|
||||
{
|
||||
firstpath = new searchpath;
|
||||
firstpath->path = ".";
|
||||
firstpath->next = NULL;
|
||||
lastpath = firstpath;
|
||||
}
|
||||
|
||||
if ( firstfile == NULL )
|
||||
{
|
||||
firstfile = new inputfile;
|
||||
firstfile->path = "-";
|
||||
firstfile->next = NULL;
|
||||
lastfile = firstfile;
|
||||
}
|
||||
|
||||
inputfile* tmp = firstfile;
|
||||
while ( tmp != NULL )
|
||||
{
|
||||
if ( !process(tmp->path) ) { return 1; }
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if ( close(outfd) < 0 )
|
||||
{
|
||||
perror("close"); return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
ifndef CPU
|
||||
CPU=x86
|
||||
endif
|
||||
|
||||
ifeq ($(CPU),x86)
|
||||
X86FAMILY=1
|
||||
CPUDEFINES=-DPLATFORM_X86
|
||||
CPUFLAGS=-m32
|
||||
CPULDFLAGS=-melf_i386
|
||||
CPUASFLAGS=-32
|
||||
CPUNASMFLAGS=-felf32
|
||||
CPUOBJS=$(CPU)/boot.o $(CPU)/base.o $(CPU)/x86.o
|
||||
endif
|
||||
|
||||
ifeq ($(CPU),x64)
|
||||
X86FAMILY=1
|
||||
CPUDEFINES=-DPLATFORM_X64
|
||||
CPUFLAGS=-m64 -ffreestanding -mcmodel=large -mno-red-zone
|
||||
CPULDFLAGS=-melf64-little -z max-page-size=0x1000
|
||||
CPUASFLAGS=-64
|
||||
CPUNASMFLAGS=-felf64
|
||||
CPUOBJS=$(CPU)/base.o $(CPU)/x64.o
|
||||
endif
|
||||
|
||||
ifdef X86FAMILY
|
||||
CPUOBJS:=$(CPUOBJS) \
|
||||
$(CPU)/memorymanagement-asm.o \
|
||||
$(CPU)/interrupt.o \
|
||||
$(CPU)/gdt.o
|
||||
CPUFLAGS:=$(CPUFLAGS) -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
|
||||
endif
|
||||
|
||||
DIRS=. x64 x86
|
||||
|
||||
DEFINES:=-DSORTIX_KERNEL $(CPUDEFINES)
|
||||
DEFINES:=$(DEFINES) -DPLATFORM_VIRTUAL_MEMORY
|
||||
DEFINES:=$(DEFINES) -DPLATFORM_KERNEL_HEAP
|
||||
#DEFINES:=$(DEFINES) -DPLATFORM_SERIAL
|
||||
#DEFINES:=$(DEFINES) -DPLATFORM_HTP
|
||||
#DEFINES:=$(DEFINES) -DCONWAY
|
||||
#DEFINES:=$(DEFINES) -DPONG
|
||||
DEFINES:=$(DEFINES) -DINITRD
|
||||
CPPFLAGSRELEASE=-s -O3
|
||||
CPPFLAGSDEBUG=
|
||||
CPPFLAGS=-I.. $(CPUDEFINES) $(CPUFLAGS) -std=gnu++0x -Wall -Wextra -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector $(DEFINES) $(CPPFLAGSRELEASE)
|
||||
OBJS=$(CPUOBJS) kernel.o descriptor_tables.o isr.o time.o log.o iprintable.o panic.o keyboard.o memorymanagement.o scheduler.o syscall.o application.o pong.o sound.o pci.o uart.o conway.o test.o http.o vgaterminal.o serialterminal.o ../libmaxsi/libmaxsi-sortix.a
|
||||
JSOBJS:=$(subst .o,-js.o,$(OBJS))
|
||||
|
||||
all: sortix.bin
|
||||
|
||||
# jssortix compilation
|
||||
|
||||
jssortix: jssortix.bin
|
||||
|
||||
jssortix.bin: $(JSOBJS)
|
||||
ld -melf_i386 -Ttext 100000 -o jssortix.out $(JSOBJS)
|
||||
objcopy -O binary jssortix.out jssortix.bin
|
||||
|
||||
# x64 compilation
|
||||
x64/boot.o: x64/boot.s
|
||||
as -32 $< -o $@
|
||||
|
||||
sortix-x64.tmp: $(OBJS) x64/boot.o
|
||||
ld -N -melf_x86_64 -Ttext 110000 -o sortix-x64-internal.out $(OBJS)
|
||||
objcopy -O binary sortix-x64-internal.out sortix-x64-internal.tmp
|
||||
objcopy --add-section kernel64=sortix-x64-internal.tmp \
|
||||
--set-section-flag kernel64=alloc,data,load,contents \
|
||||
$(CPU)/boot.o
|
||||
ld -melf_i386 -Ttext 100000 $(CPU)/boot.o -o $@
|
||||
# move section to 0x11000
|
||||
objcopy --change-section-address kernel64=1114112 $@
|
||||
|
||||
# x86 compilation
|
||||
|
||||
sortix-x86.tmp: $(OBJS)
|
||||
ld -melf_i386 -Ttext 100000 -o $@ $(OBJS)
|
||||
|
||||
# general rules
|
||||
|
||||
sortix.bin: sortix-$(CPU).tmp
|
||||
cp -vu $< $@
|
||||
|
||||
%.o: %.cpp
|
||||
g++ -c $< -o $@ $(CPPFLAGS)
|
||||
|
||||
%.o: %.s
|
||||
as $(CPUASFLAGS) $< -o $@
|
||||
|
||||
%.o: %.asm
|
||||
nasm $(CPUNASMFLAGS) $< -o $@
|
||||
|
||||
%-js.o: %.cpp
|
||||
g++ -c $< -o $@ $(CPPFLAGS) -DJSSORTIX
|
||||
|
||||
%-js.o: %.s
|
||||
as $(CPUASFLAGS) $< -o $@
|
||||
|
||||
%-js.o: %.asm
|
||||
nasm $(CPUNASMFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
for D in $(DIRS); do rm -fv $$D/*.o $$D/*.bin $$D/*.out $$D/*.tmp; done
|
||||
|
||||
# Local machine
|
||||
|
||||
install: sortix.bin
|
||||
cp sortix.bin /boot
|
||||
|
||||
uninstall:
|
||||
rm -f /boot/sortix.bin
|
||||
|
||||
# Remote machine
|
||||
|
||||
install-remote: sortix.bin
|
||||
scp -r ./ 192.168.2.6:/home/sortie/Desktop/sortix
|
||||
scp sortix.bin root@192.168.2.6:/boot
|
||||
ssh root@192.168.2.6 "init 6"
|
||||
|
||||
uninstall-remote:
|
||||
ssh root@192.168.2.6 "rm /boot/sortix.bin"
|
|
@ -0,0 +1,63 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
application.cpp
|
||||
A test application for the scheduler and libmaxsi.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <libmaxsi/platform.h>
|
||||
#include <libmaxsi/thread.h>
|
||||
#include <libmaxsi/io.h>
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
void* TestThread(void* Parameter)
|
||||
{
|
||||
for ( size_t I = 0; I < 64; I++ )
|
||||
{
|
||||
StdOut::Print(".");
|
||||
Thread::USleep(20*1000); // Sleep 100 * 1000 microseconds = 100 ms.
|
||||
}
|
||||
|
||||
StdOut::Print("\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// The entry point in this sample program for sortix.
|
||||
void* RunApplication(void* Parameter)
|
||||
{
|
||||
StdOut::Print("Hello, says the thread!\n");
|
||||
|
||||
const char* Message = "Oooh! And message passing works!\n";
|
||||
|
||||
while ( true )
|
||||
{
|
||||
StdOut::Print("Created Thread: ");
|
||||
if ( Thread::Create(TestThread, Message) == 0 )
|
||||
{
|
||||
StdOut::Print("ERROR: Could not create child thread\n");
|
||||
}
|
||||
Thread::USleep(1300 * 1000); // Sleep 2 seconds.
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
astroids.cpp
|
||||
IN SPACE, NO ONE CAN HEAR YOU find ~ | xargs shred
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include <libmaxsi/string.h>
|
||||
#include "globals.h"
|
||||
#include "iirqhandler.h"
|
||||
#include "iprintable.h"
|
||||
#include "keyboard.h"
|
||||
#include "timer.h"
|
||||
#include "log.h"
|
||||
#include "astroids.h"
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
DEFINE_GLOBAL_OBJECT(Astroids, Astroids);
|
||||
|
||||
const int Height = 25;
|
||||
const int Width = 80;
|
||||
|
||||
void Astroids::Init()
|
||||
{
|
||||
Time = 0;
|
||||
|
||||
Reset();
|
||||
Update();
|
||||
|
||||
GKeyboard->SetReader(this);
|
||||
GTimer->SetTimerable(this);
|
||||
}
|
||||
|
||||
void Astroids::ClearScreen()
|
||||
{
|
||||
uint16_t* Destination = (uint16_t*) 0xB8000;
|
||||
|
||||
// Copy and apply colors.
|
||||
for ( int Y = 0; Y < Height; Y++ )
|
||||
{
|
||||
uint16_t Color = COLOR8_BLACK << 8;
|
||||
|
||||
for ( int X = 0; X < Width; X++ )
|
||||
{
|
||||
Destination[X + Y*Width] = ' ' | Color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Astroids::Reset()
|
||||
{
|
||||
ClearScreen();
|
||||
PX = Width/2;
|
||||
PY = Height/2;
|
||||
PVX = 0;
|
||||
PVY = 0;
|
||||
TrailX = PX;
|
||||
TrailY = PY;
|
||||
TrailLen = 0;
|
||||
TrailMaxLen = 15;
|
||||
}
|
||||
|
||||
void Astroids::Update()
|
||||
{
|
||||
uint16_t* Destination = (uint16_t*) 0xB8000;
|
||||
|
||||
PX += PVX; PX = ((nat) PX) % ((nat) Width);
|
||||
PY += PVY; PY = ((nat) PY) % ((nat) Height);
|
||||
|
||||
uint16_t Prev = 0;
|
||||
if ( !(PVX == 0 && PVY == 0) && Destination[PX + PY*Width] > 0 ) { Reset(); }
|
||||
|
||||
if ( !(PVX == 0 && PVY == 0) )
|
||||
{
|
||||
if ( PVX < 0 ) { Prev = 0; }
|
||||
if ( PVX > 0 ) { Prev = 1; }
|
||||
if ( PVY < 0 ) { Prev = 2; }
|
||||
if ( PVY > 0 ) { Prev = 3; }
|
||||
|
||||
if ( TrailMaxLen <= TrailLen )
|
||||
{
|
||||
uint16_t AtTrail = Destination[TrailX + TrailY*Width];
|
||||
Destination[TrailX + TrailY*Width] = ' ' | (COLOR8_BLACK << 8);
|
||||
if ( (AtTrail & 0x4) == 0 ) { TrailX--; } else
|
||||
if ( (AtTrail & 0x4) == 1 ) { TrailX++; } else
|
||||
if ( (AtTrail & 0x4) == 2 ) { TrailY--; } else
|
||||
if ( (AtTrail & 0x4) == 3 ) { TrailY++; }
|
||||
}
|
||||
else { TrailLen++; }
|
||||
}
|
||||
Destination[PX + PY*Width] = (COLOR8_GREEN << 12) | Prev;
|
||||
|
||||
NextUpdate = Time + 75;
|
||||
}
|
||||
|
||||
void Astroids::OnKeystroke(uint32_t CodePoint, bool KeyUp)
|
||||
{
|
||||
const uint32_t UP = 0xFFFFFFFF - 20;
|
||||
const uint32_t LEFT = 0xFFFFFFFF - 21;
|
||||
const uint32_t RIGHT = 0xFFFFFFFF - 22;
|
||||
const uint32_t DOWN = 0xFFFFFFFF - 23;
|
||||
|
||||
if ( CodePoint == '\n' && !KeyUp )
|
||||
{
|
||||
ClearScreen();
|
||||
Reset();
|
||||
Update();
|
||||
}
|
||||
|
||||
if ( !(PVX == 0 && PVY == 1) && (CodePoint == 'w' || CodePoint == 'W') && !KeyUp ) { PVY = -1; PVX = 0; }
|
||||
if ( !(PVX == 1 && PVY == 0) && (CodePoint == 'a' || CodePoint == 'A') && !KeyUp ) { PVY = 0; PVX = -1; }
|
||||
if ( !(PVX == 0 && PVY == -1) && (CodePoint == 's' || CodePoint == 'S') && !KeyUp ) { PVY = 1; PVX = 0; }
|
||||
if ( !(PVX == -1 && PVY == 0) && (CodePoint == 'd' || CodePoint == 'D') && !KeyUp ) { PVY = 0; PVX = 1; }
|
||||
}
|
||||
|
||||
void Astroids::OnFuture(uint32_t Miliseconds)
|
||||
{
|
||||
Time += Miliseconds;
|
||||
|
||||
if ( NextUpdate <= Time ) { Update(); }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
astroids.h
|
||||
IN SPACE, NO ONE CAN HEAR YOU find ~ | xargs shred
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_ASTROIDS_H
|
||||
#define SORTIX_ASTROIDS_H
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
class Astroids : public IKeystrokable, public ITimerable
|
||||
{
|
||||
private:
|
||||
nat Time;
|
||||
nat NextUpdate;
|
||||
|
||||
private:
|
||||
int PX;
|
||||
int PY;
|
||||
int TrailX;
|
||||
int TrailY;
|
||||
int TrailLen;
|
||||
int TrailMaxLen;
|
||||
int PVX;
|
||||
int PVY;
|
||||
|
||||
public:
|
||||
void Init();
|
||||
|
||||
private:
|
||||
void ClearScreen();
|
||||
void Reset();
|
||||
void Update();
|
||||
|
||||
public:
|
||||
virtual void OnKeystroke(uint32_t CodePoint, bool KeyUp);
|
||||
virtual void OnFuture(uint32_t Miliseconds);
|
||||
|
||||
};
|
||||
|
||||
DECLARE_GLOBAL_OBJECT(Astroids, Astroids);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of LibMaxsi.
|
||||
|
||||
LibMaxsi is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
LibMaxsi 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 Lesser General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with LibMaxsi. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
types.h
|
||||
Declares the required datatypes for the x86 architecture.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
#include "x86/bits.h"
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_X64
|
||||
#include "x64/bits.h"
|
||||
#endif
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
conway.cpp
|
||||
THE GAME! You lost it. OF LIFE!
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "iprintable.h"
|
||||
#include "log.h"
|
||||
#include "vga.h"
|
||||
|
||||
#ifdef PLATFORM_SERIAL
|
||||
#include "uart.h"
|
||||
#endif
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace Conway
|
||||
{
|
||||
const int Height = 25;
|
||||
const int Width = 80;
|
||||
const int RowStride = Width + 2;
|
||||
const int BufferSize = (Height+2) * (Width+2);
|
||||
|
||||
#ifdef PLATFORM_SERIAL
|
||||
VGA::Frame FrameData;
|
||||
VGA::Frame* Frame = &FrameData;
|
||||
#else
|
||||
VGA::Frame* Frame = (VGA::Frame*) 0xB8000;
|
||||
#endif
|
||||
|
||||
char FrameA[BufferSize];
|
||||
char FrameB[BufferSize];
|
||||
char* CurrentFrame;
|
||||
char* LastFrame;
|
||||
bool Running;
|
||||
int PosX;
|
||||
int PosY;
|
||||
int TimeToNextFrame;
|
||||
int Time;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for ( int I = 0; I < BufferSize; I++ ) { FrameA[I] = 0; FrameB[I] = 0; }
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
CurrentFrame = FrameA;
|
||||
LastFrame = FrameB;
|
||||
|
||||
Running = false;
|
||||
|
||||
PosY = Height / 2 + 1;
|
||||
PosX = Width / 2 + 1;
|
||||
Time = 0;
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Cycle()
|
||||
{
|
||||
for ( int Y = 1; Y <= Height; Y++ )
|
||||
{
|
||||
for ( int X = 1; X <= Width; X++ )
|
||||
{
|
||||
int AliveAround = 0;
|
||||
int Current = LastFrame[Y * RowStride + X];
|
||||
|
||||
if ( LastFrame[(Y-1) * RowStride + (X-1)] > 0 ) { AliveAround++; }
|
||||
if ( LastFrame[(Y-1) * RowStride + (X-0)] > 0 ) { AliveAround++; }
|
||||
if ( LastFrame[(Y-1) * RowStride + (X+1)] > 0 ) { AliveAround++; }
|
||||
if ( LastFrame[(Y-0) * RowStride + (X-1)] > 0 ) { AliveAround++; }
|
||||
if ( LastFrame[(Y-0) * RowStride + (X+1)] > 0 ) { AliveAround++; }
|
||||
if ( LastFrame[(Y+1) * RowStride + (X-1)] > 0 ) { AliveAround++; }
|
||||
if ( LastFrame[(Y+1) * RowStride + (X-0)] > 0 ) { AliveAround++; }
|
||||
if ( LastFrame[(Y+1) * RowStride + (X+1)] > 0 ) { AliveAround++; }
|
||||
|
||||
CurrentFrame[Y * RowStride + X] = ( (Current > 0 && (AliveAround == 3 || AliveAround == 2)) || (Current == 0 && AliveAround == 3) ) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Swap buffers.
|
||||
char* TMP = LastFrame; LastFrame = CurrentFrame; CurrentFrame = TMP;
|
||||
}
|
||||
|
||||
void Render()
|
||||
{
|
||||
uint16_t* Destination = Frame->Data;
|
||||
|
||||
uint16_t Set = 'O' | (COLOR8_LIGHT_GREY << 8);
|
||||
uint16_t Unset = ' ' | (COLOR8_LIGHT_GREY << 8);
|
||||
|
||||
for ( int Y = 1; Y <= Height; Y++ )
|
||||
{
|
||||
for ( int X = 1; X <= Width; X++ )
|
||||
{
|
||||
Destination[(Y-1) * Width + (X-1)] = (LastFrame[Y * RowStride + X] > 0) ? Set : Unset;
|
||||
}
|
||||
}
|
||||
|
||||
// Render the cursor.
|
||||
if ( !Running )
|
||||
{
|
||||
Destination[(PosY-1) * Width + (PosX-1)] |= (COLOR8_RED << 12);
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_SERIAL
|
||||
UART::RenderVGA(Frame);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Update(int TimePassed)
|
||||
{
|
||||
#ifdef PLATFORM_SERIAL
|
||||
while ( true )
|
||||
{
|
||||
int C = UART::TryPopChar();
|
||||
|
||||
if ( C == 'r' || C == 'R' ) { TimeToNextFrame = 0; Running = !Running; }
|
||||
|
||||
if ( !Running )
|
||||
{
|
||||
if ( C == 'w' || C == 'W' ) { if ( PosY > 1 ) { PosY--; } }
|
||||
if ( C == 's' || C == 'S' ) { if ( PosY < Height ) { PosY++; } }
|
||||
if ( C == 'a' || C == 'A' ) { if ( PosX > 1 ) { PosX--; } }
|
||||
if ( C == 'd' || C == 'D' ) { if ( PosX < Width ) { PosX++; } }
|
||||
if ( C == 'c' || C == 'C' ) { Clear(); }
|
||||
if ( C == ' ' ) { LastFrame[PosY * RowStride + PosX] = 1 - LastFrame[PosY * RowStride + PosX]; }
|
||||
}
|
||||
|
||||
if ( C == -1 ) { break; }
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( Running )
|
||||
{
|
||||
if ( TimeToNextFrame <= TimePassed )
|
||||
{
|
||||
Cycle();
|
||||
TimeToNextFrame = 50;
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeToNextFrame -= TimePassed;
|
||||
}
|
||||
}
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
void OnFuture()
|
||||
{
|
||||
const int TimePassed = 10;
|
||||
|
||||
Time += TimePassed;
|
||||
|
||||
|
||||
#ifdef PLATFORM_SERIAL
|
||||
|
||||
#ifdef JSSORIX
|
||||
const nat WaitTime = 2000;
|
||||
#else
|
||||
const nat WaitTime = 3500;
|
||||
#endif
|
||||
|
||||
// Artificially display the boot welcome screen.
|
||||
if ( Time < WaitTime ) { return; }
|
||||
#endif
|
||||
|
||||
Update(TimePassed);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
conway.h
|
||||
THE GAME! You lost it. OF LIFE!
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_CONWAY_H
|
||||
#define SORTIX_CONWAY_H
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace Conway
|
||||
{
|
||||
void Init();
|
||||
void Cycle();
|
||||
void Render();
|
||||
void Update(int TimePassed);
|
||||
void OnFuture();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,210 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
descriptor_tables.cpp
|
||||
Initializes and handles the GDT, TSS and IDT.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "iirqhandler.h"
|
||||
#include <libmaxsi/memory.h>
|
||||
#include "descriptor_tables.h"
|
||||
#include "isr.h"
|
||||
#include "panic.h"
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace GDT
|
||||
{
|
||||
// Lets us access our ASM functions from our C++ code.
|
||||
extern "C" void gdt_flush(addr_t);
|
||||
extern "C" void tss_flush();
|
||||
|
||||
gdt_entry_t gdt_entries[6];
|
||||
gdt_ptr_t gdt_ptr;
|
||||
tss_entry_t tss_entry;
|
||||
|
||||
void Init()
|
||||
{
|
||||
gdt_ptr.limit = (sizeof(gdt_entry_t) * 6) - 1;
|
||||
gdt_ptr.base = (addr_t) &gdt_entries;
|
||||
|
||||
SetGate(0, 0, 0, 0, 0); // Null segment
|
||||
SetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
|
||||
SetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
|
||||
SetGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
|
||||
SetGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
|
||||
WriteTSS(5, 0x10, 0x0);
|
||||
|
||||
gdt_flush((addr_t) &gdt_ptr);
|
||||
tss_flush();
|
||||
}
|
||||
|
||||
// Set the value of a GDT entry.
|
||||
void SetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran)
|
||||
{
|
||||
gdt_entries[num].base_low = (base & 0xFFFF);
|
||||
gdt_entries[num].base_middle = (base >> 16) & 0xFF;
|
||||
gdt_entries[num].base_high = (base >> 24) & 0xFF;
|
||||
|
||||
gdt_entries[num].limit_low = (limit & 0xFFFF);
|
||||
gdt_entries[num].granularity = (limit >> 16) & 0x0F;
|
||||
|
||||
gdt_entries[num].granularity |= gran & 0xF0;
|
||||
gdt_entries[num].access = access;
|
||||
}
|
||||
|
||||
// Initialise our task state segment structure.
|
||||
void WriteTSS(int32_t num, uint16_t ss0, uint32_t esp0)
|
||||
{
|
||||
// Firstly, let's compute the base and limit of our entry into the GDT.
|
||||
addr_t base = (addr_t) &tss_entry;
|
||||
uint32_t limit = base + sizeof(tss_entry);
|
||||
|
||||
// Now, add our TSS descriptor's address to the GDT.
|
||||
SetGate(num, base, limit, 0xE9, 0x00);
|
||||
|
||||
// Ensure the descriptor is initially zero.
|
||||
Memory::Set(&tss_entry, 0, sizeof(tss_entry));
|
||||
|
||||
tss_entry.ss0 = ss0; // Set the kernel stack segment.
|
||||
tss_entry.esp0 = esp0; // Set the kernel stack pointer.
|
||||
|
||||
// Here we set the cs, ss, ds, es, fs and gs entries in the TSS. These specify what
|
||||
// segments should be loaded when the processor switches to kernel mode. Therefore
|
||||
// they are just our normal kernel code/data segments - 0x08 and 0x10 respectively,
|
||||
// but with the last two bits set, making 0x0b and 0x13. The setting of these bits
|
||||
// sets the RPL (requested privilege level) to 3, meaning that this TSS can be used
|
||||
// to switch to kernel mode from ring 3.
|
||||
tss_entry.cs = 0x08 | 0x3;
|
||||
tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x10 | 0x3;
|
||||
}
|
||||
|
||||
void SetKernelStack(size_t* stack)
|
||||
{
|
||||
#ifdef PLATFORM_X86
|
||||
tss_entry.esp0 = (uint32_t) stack;
|
||||
#else
|
||||
#warning "TSS is not yet supported on this arch!"
|
||||
while(true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace IDT
|
||||
{
|
||||
// Lets us access our ASM functions from our C++ code.
|
||||
extern "C" void idt_flush(uint32_t);
|
||||
|
||||
idt_entry_t idt_entries[256];
|
||||
idt_ptr_t idt_ptr;
|
||||
|
||||
void Init()
|
||||
{
|
||||
#ifdef PLATFORM_X86
|
||||
idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
|
||||
idt_ptr.base = (uint32_t)&idt_entries;
|
||||
|
||||
Memory::Set(&idt_entries, 0, sizeof(idt_entry_t)*256);
|
||||
|
||||
// Remap the irq table.
|
||||
X86::OutPortB(0x20, 0x11);
|
||||
X86::OutPortB(0xA0, 0x11);
|
||||
X86::OutPortB(0x21, 0x20);
|
||||
X86::OutPortB(0xA1, 0x28);
|
||||
X86::OutPortB(0x21, 0x04);
|
||||
X86::OutPortB(0xA1, 0x02);
|
||||
X86::OutPortB(0x21, 0x01);
|
||||
X86::OutPortB(0xA1, 0x01);
|
||||
X86::OutPortB(0x21, 0x0);
|
||||
X86::OutPortB(0xA1, 0x0);
|
||||
|
||||
SetGate( 0, (uint32_t) isr0 , 0x08, 0x8E);
|
||||
SetGate( 1, (uint32_t) isr1 , 0x08, 0x8E);
|
||||
SetGate( 2, (uint32_t) isr2 , 0x08, 0x8E);
|
||||
SetGate( 3, (uint32_t) isr3 , 0x08, 0x8E);
|
||||
SetGate( 4, (uint32_t) isr4 , 0x08, 0x8E);
|
||||
SetGate( 5, (uint32_t) isr5 , 0x08, 0x8E);
|
||||
SetGate( 6, (uint32_t) isr6 , 0x08, 0x8E);
|
||||
SetGate( 7, (uint32_t) isr7 , 0x08, 0x8E);
|
||||
SetGate( 8, (uint32_t) isr8 , 0x08, 0x8E);
|
||||
SetGate( 9, (uint32_t) isr9 , 0x08, 0x8E);
|
||||
SetGate(10, (uint32_t) isr10, 0x08, 0x8E);
|
||||
SetGate(11, (uint32_t) isr11, 0x08, 0x8E);
|
||||
SetGate(12, (uint32_t) isr12, 0x08, 0x8E);
|
||||
SetGate(13, (uint32_t) isr13, 0x08, 0x8E);
|
||||
SetGate(14, (uint32_t) isr14, 0x08, 0x8E);
|
||||
SetGate(15, (uint32_t) isr15, 0x08, 0x8E);
|
||||
SetGate(16, (uint32_t) isr16, 0x08, 0x8E);
|
||||
SetGate(17, (uint32_t) isr17, 0x08, 0x8E);
|
||||
SetGate(18, (uint32_t) isr18, 0x08, 0x8E);
|
||||
SetGate(19, (uint32_t) isr19, 0x08, 0x8E);
|
||||
SetGate(20, (uint32_t) isr20, 0x08, 0x8E);
|
||||
SetGate(21, (uint32_t) isr21, 0x08, 0x8E);
|
||||
SetGate(22, (uint32_t) isr22, 0x08, 0x8E);
|
||||
SetGate(23, (uint32_t) isr23, 0x08, 0x8E);
|
||||
SetGate(24, (uint32_t) isr24, 0x08, 0x8E);
|
||||
SetGate(25, (uint32_t) isr25, 0x08, 0x8E);
|
||||
SetGate(26, (uint32_t) isr26, 0x08, 0x8E);
|
||||
SetGate(27, (uint32_t) isr27, 0x08, 0x8E);
|
||||
SetGate(28, (uint32_t) isr28, 0x08, 0x8E);
|
||||
SetGate(29, (uint32_t) isr29, 0x08, 0x8E);
|
||||
SetGate(30, (uint32_t) isr30, 0x08, 0x8E);
|
||||
SetGate(31, (uint32_t) isr31, 0x08, 0x8E);
|
||||
SetGate(32, (uint32_t) irq0, 0x08, 0x8E);
|
||||
SetGate(33, (uint32_t) irq1, 0x08, 0x8E);
|
||||
SetGate(34, (uint32_t) irq2, 0x08, 0x8E);
|
||||
SetGate(35, (uint32_t) irq3, 0x08, 0x8E);
|
||||
SetGate(36, (uint32_t) irq4, 0x08, 0x8E);
|
||||
SetGate(37, (uint32_t) irq5, 0x08, 0x8E);
|
||||
SetGate(38, (uint32_t) irq6, 0x08, 0x8E);
|
||||
SetGate(39, (uint32_t) irq7, 0x08, 0x8E);
|
||||
SetGate(40, (uint32_t) irq8, 0x08, 0x8E);
|
||||
SetGate(41, (uint32_t) irq9, 0x08, 0x8E);
|
||||
SetGate(42, (uint32_t) irq10, 0x08, 0x8E);
|
||||
SetGate(43, (uint32_t) irq11, 0x08, 0x8E);
|
||||
SetGate(44, (uint32_t) irq12, 0x08, 0x8E);
|
||||
SetGate(45, (uint32_t) irq13, 0x08, 0x8E);
|
||||
SetGate(46, (uint32_t) irq14, 0x08, 0x8E);
|
||||
SetGate(47, (uint32_t) irq15, 0x08, 0x8E);
|
||||
SetGate(128, (uint32_t) isr128, 0x08, 0x8E); // System Calls
|
||||
SetGate(177, (uint32_t) isr177, 0x08, 0x8E); // System Calls
|
||||
|
||||
idt_flush((uint32_t)&idt_ptr);
|
||||
#else
|
||||
#warning "IDT is not yet supported on this arch!"
|
||||
while(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
|
||||
{
|
||||
idt_entries[num].base_lo = base & 0xFFFF;
|
||||
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
|
||||
|
||||
idt_entries[num].sel = sel;
|
||||
idt_entries[num].always0 = 0;
|
||||
idt_entries[num].flags = flags | 0x60;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
descriptor_tables.cpp
|
||||
Initializes and handles the GDT, TSS and IDT.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_DESCRIPTOR_TABLES_H
|
||||
#define SORTIX_DESCRIPTOR_TABLES_H
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace GDT
|
||||
{
|
||||
// This structure contains the value of one GDT entry.
|
||||
// We use the attribute 'packed' to tell GCC not to change
|
||||
// any of the alignment in the structure.
|
||||
struct gdt_entry_struct
|
||||
{
|
||||
uint16_t limit_low; // The lower 16 bits of the limit.
|
||||
uint16_t base_low; // The lower 16 bits of the base.
|
||||
uint8_t base_middle; // The next 8 bits of the base.
|
||||
uint8_t access; // Access flags, determine what ring this segment can be used in.
|
||||
uint8_t granularity;
|
||||
uint8_t base_high; // The last 8 bits of the base.
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct gdt_entry_struct gdt_entry_t;
|
||||
|
||||
// This struct describes a GDT pointer. It points to the start of
|
||||
// our array of GDT entries, and is in the format required by the
|
||||
// lgdt instruction.
|
||||
struct gdt_ptr_struct
|
||||
{
|
||||
uint16_t limit; // The upper 16 bits of all selector limits.
|
||||
addr_t base; // The address of the first gdt_entry_t struct.
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct gdt_ptr_struct gdt_ptr_t;
|
||||
|
||||
// A struct describing a Task State Segment.
|
||||
struct tss_entry_struct
|
||||
{
|
||||
uint32_t prev_tss; // The previous TSS - if we used hardware task switching this would form a linked list.
|
||||
uint32_t esp0; // The stack pointer to load when we change to kernel mode.
|
||||
uint32_t ss0; // The stack segment to load when we change to kernel mode.
|
||||
uint32_t esp1; // Unused...
|
||||
uint32_t ss1;
|
||||
uint32_t esp2;
|
||||
uint32_t ss2;
|
||||
uint32_t cr3;
|
||||
uint32_t eip;
|
||||
uint32_t eflags;
|
||||
uint32_t eax;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t ebx;
|
||||
uint32_t esp;
|
||||
uint32_t ebp;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint32_t es; // The value to load into ES when we change to kernel mode.
|
||||
uint32_t cs; // The value to load into CS when we change to kernel mode.
|
||||
uint32_t ss; // The value to load into SS when we change to kernel mode.
|
||||
uint32_t ds; // The value to load into DS when we change to kernel mode.
|
||||
uint32_t fs; // The value to load into FS when we change to kernel mode.
|
||||
uint32_t gs; // The value to load into GS when we change to kernel mode.
|
||||
uint32_t ldt; // Unused...
|
||||
uint16_t trap;
|
||||
uint16_t iomap_base;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct tss_entry_struct tss_entry_t;
|
||||
|
||||
void Init();
|
||||
void SetGate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran);
|
||||
void WriteTSS(int32_t num, uint16_t ss0, uint32_t esp0);
|
||||
void SetKernelStack(size_t* stack);
|
||||
}
|
||||
|
||||
namespace IDT
|
||||
{
|
||||
|
||||
// A struct describing an interrupt gate.
|
||||
struct idt_entry_struct
|
||||
{
|
||||
uint16_t base_lo; // The lower 16 bits of the address to jump to when this interrupt fires.
|
||||
uint16_t sel; // Kernel segment selector.
|
||||
uint8_t always0; // This must always be zero.
|
||||
uint8_t flags; // More flags. See documentation.
|
||||
uint16_t base_hi; // The upper 16 bits of the address to jump to.
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct idt_entry_struct idt_entry_t;
|
||||
|
||||
// A struct describing a pointer to an array of interrupt handlers.
|
||||
// This is in a format suitable for giving to 'lidt'.
|
||||
struct idt_ptr_struct
|
||||
{
|
||||
uint16_t limit;
|
||||
addr_t base; // The address of the first element in our idt_entry_t array.
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct idt_ptr_struct idt_ptr_t;
|
||||
|
||||
void Init();
|
||||
void SetGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags);
|
||||
}
|
||||
}
|
||||
|
||||
// These extern directives let us access the addresses of our ASM ISR handlers.
|
||||
extern "C" void isr0 ();
|
||||
extern "C" void isr1 ();
|
||||
extern "C" void isr2 ();
|
||||
extern "C" void isr3 ();
|
||||
extern "C" void isr4 ();
|
||||
extern "C" void isr5 ();
|
||||
extern "C" void isr6 ();
|
||||
extern "C" void isr7 ();
|
||||
extern "C" void isr8 ();
|
||||
extern "C" void isr9 ();
|
||||
extern "C" void isr10();
|
||||
extern "C" void isr11();
|
||||
extern "C" void isr12();
|
||||
extern "C" void isr13();
|
||||
extern "C" void isr14();
|
||||
extern "C" void isr15();
|
||||
extern "C" void isr16();
|
||||
extern "C" void isr17();
|
||||
extern "C" void isr18();
|
||||
extern "C" void isr19();
|
||||
extern "C" void isr20();
|
||||
extern "C" void isr21();
|
||||
extern "C" void isr22();
|
||||
extern "C" void isr23();
|
||||
extern "C" void isr24();
|
||||
extern "C" void isr25();
|
||||
extern "C" void isr26();
|
||||
extern "C" void isr27();
|
||||
extern "C" void isr28();
|
||||
extern "C" void isr29();
|
||||
extern "C" void isr30();
|
||||
extern "C" void isr31();
|
||||
extern "C" void isr128();
|
||||
extern "C" void isr177();
|
||||
extern "C" void irq0 ();
|
||||
extern "C" void irq1 ();
|
||||
extern "C" void irq2 ();
|
||||
extern "C" void irq3 ();
|
||||
extern "C" void irq4 ();
|
||||
extern "C" void irq5 ();
|
||||
extern "C" void irq6 ();
|
||||
extern "C" void irq7 ();
|
||||
extern "C" void irq8 ();
|
||||
extern "C" void irq9 ();
|
||||
extern "C" void irq10();
|
||||
extern "C" void irq11();
|
||||
extern "C" void irq12();
|
||||
extern "C" void irq13();
|
||||
extern "C" void irq14();
|
||||
extern "C" void irq15();
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
descriptors.h
|
||||
Handles file descriptors, socket descriptors, and whatnot for each process.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_DESCRIPTORS_H
|
||||
#define SORTIX_DESCRIPTORS_H
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
class Device;
|
||||
|
||||
struct Description
|
||||
{
|
||||
nat type;
|
||||
Device* object;
|
||||
};
|
||||
|
||||
class DescriptorTable
|
||||
{
|
||||
public:
|
||||
DescriptorTable();
|
||||
~DescriptorTable();
|
||||
|
||||
private:
|
||||
int _numDescs
|
||||
Description* _descs;
|
||||
|
||||
public:
|
||||
int Reserve();
|
||||
void UseReservation(int index, Device* object);
|
||||
int Allocate(Device* object;
|
||||
bool Free(int index);
|
||||
|
||||
public:
|
||||
inline Description* get(int index)
|
||||
{
|
||||
if ( _numDescs <= index ) { return NULL; }
|
||||
return _descs + index;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
device.cpp
|
||||
A base class for all devices.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "device.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
void Device::close()
|
||||
{
|
||||
_refCount--;
|
||||
if ( _refCount == 0 )
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void Device::Think()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Device::RequestThink()
|
||||
{
|
||||
Think();
|
||||
}
|
||||
|
||||
bool Device::Sync()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
device.h
|
||||
A base class for all devices.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_DEVICE_H
|
||||
#define SORTIX_DEVICE_H
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
class User;
|
||||
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
// Flags
|
||||
const nat READABLE = (1<<0);
|
||||
const nat WRITABLE = (1<<1);
|
||||
const nat SEEKABLE = (1<<2);
|
||||
const nat SIZEABLE = (1<<3);
|
||||
const nat BLOCK = (1<<4);
|
||||
const nat FLAGMASK = ((1<<5)-1);
|
||||
|
||||
// Types
|
||||
const nat TYPEMASK = ~FLAGMASK;
|
||||
const nat STREAM = (1<<5);
|
||||
const nat BUFFER = (2<<5);
|
||||
const nat DIRECTORY = (3<<5);
|
||||
const nat FILESYSTEM = (4<<5);
|
||||
const nat NETWORK = (5<<5);
|
||||
const nat SOUND = (6<<5);
|
||||
const nat GRAPHICS = (7<<5);
|
||||
const nat MOUSE = (8<<5);
|
||||
const nat KEYBOARD = (9<<5);
|
||||
const nat PRINTER = (10<<5);
|
||||
const nat SCANNER = (11<<5);
|
||||
const nat OTHER = TYPEMASK;
|
||||
|
||||
public:
|
||||
volatile size_t _refCount;
|
||||
|
||||
public:
|
||||
Device() { RefCount = 1; }
|
||||
virtual ~Device() { }
|
||||
|
||||
private:
|
||||
User* _owner;
|
||||
|
||||
public:
|
||||
bool IsOwner(User* candidate) { return candidate == _owner; }
|
||||
|
||||
public:
|
||||
bool Close();
|
||||
void RequestThink();
|
||||
|
||||
protected:
|
||||
virtual void Think();
|
||||
|
||||
public:
|
||||
virtual bool Sync();
|
||||
virtual nat Flags() = 0;
|
||||
|
||||
public:
|
||||
bool IsType(nat type) { return Flags() & TYPEMASK == type); }
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
filesystem.cpp
|
||||
Abstracts away a file system device.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "device.h"
|
||||
#include "thread.h"
|
||||
#include "process.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
bool DevFileSystem::LegalNodeName(const char* name)
|
||||
{
|
||||
if ( *name == '\0' ) { return false; }
|
||||
while ( *name != '\0' )
|
||||
{
|
||||
if ( *name == '/' ) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DevFileSystem::Open(const char* path, nat openFlags, nat mode, Mount::SysCallback* callbackInfo, Thread* thread)
|
||||
{
|
||||
#if 0
|
||||
nat requestMode = flags & O_LOWERFLAGS;
|
||||
|
||||
MXFSNode* node;
|
||||
|
||||
if ( flags & O_CREAT )
|
||||
{
|
||||
if ( flags & O_DIRECTORY ) { return CreateDirectory(path, flags, permissions, type); }
|
||||
else { return CreateFile(path, flags, permissions, type); }
|
||||
}
|
||||
else
|
||||
{
|
||||
node = Search(path);
|
||||
}
|
||||
|
||||
if ( node == NULL ) { return NULL; }
|
||||
|
||||
if ( node->IsDir() )
|
||||
{
|
||||
if ( requestMode == O_SEARCH || requestMode == O_RDONLY )
|
||||
{
|
||||
// TODO: Make a directory device.
|
||||
Error::Set(Error::NOTIMPLEMENTED);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error::Set(Error::ISDIR);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
filesystem.h
|
||||
Abstracts away a file system device.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_FILESYSTEM_H
|
||||
#define SORTIX_FILESYSTEM_H
|
||||
|
||||
#include "device.h"
|
||||
#include "mount.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
class Thread;
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
struct SysCallback
|
||||
{
|
||||
Device* device;
|
||||
union { int deviceError; nat deviceType; }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: These belong in libmaxsi!
|
||||
|
||||
const nat O_RDONLY = 1;
|
||||
const nat O_WRONLY = 2;
|
||||
const nat O_RDWR = 3;
|
||||
const nat O_EXEC = 4;
|
||||
const nat O_SEARCH = 5;
|
||||
const nat O_LOWERFLAGS = 0x7;
|
||||
|
||||
// TODO: Sortix might never support all of these flags if they are stupid.
|
||||
const nat O_APPEND = (1<<3);
|
||||
const nat O_CLOEXEC = (1<<4);
|
||||
const nat O_CREAT = (1<<5);
|
||||
const nat O_DIRECTORY = (1<<6);
|
||||
const nat O_DSYNC = (1<<6);
|
||||
const nat O_EXCL = (1<<7);
|
||||
const nat O_NOCTTY = (1<<8);
|
||||
const nat O_NOFOLLOW = (1<<9);
|
||||
const nat O_RSYNC = (1<<11);
|
||||
const nat O_SYNC = (1<<12);
|
||||
const nat O_TRUNC = (1<<13);
|
||||
const nat O_TTY_INIT = (1<<13);
|
||||
|
||||
// If O_RDONLY, then no one is allowed to write to this, or if O_RDWD then
|
||||
// no one else is allowed to use this besides me.
|
||||
const nat O_EXCLUSIVELY = (1<<14);
|
||||
const nat O_USERSPACEABLE = ((1<<15)-1);
|
||||
|
||||
const nat O_MOUNT = (1<<31);
|
||||
|
||||
class DevFileSystem : public Device
|
||||
{
|
||||
public:
|
||||
DevFileSystem() { };
|
||||
virtual ~DevFileSystem() { }
|
||||
|
||||
public:
|
||||
bool LegalNodeName(const char* name);
|
||||
|
||||
public:
|
||||
virtual int Initialize(MountPoint* mountPoint, const char* commandLine) = 0;
|
||||
|
||||
public:
|
||||
virtual bool Open(const char* path, nat openFlags, nat mode, FileSystem::SysCallback* callbackInfo, Thread* thread);
|
||||
|
||||
};
|
||||
|
||||
namespace FileSystem
|
||||
{
|
||||
DevFileSystem* CreateDriver(const char* fsType);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
globals.h
|
||||
Macros useful to declare and define global objects in Sortix.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_GLOBALS_H
|
||||
#define SORTIX_GLOBALS_H
|
||||
|
||||
#define DECLARE_GLOBAL_OBJECT(Type, Name) extern Type* G##Name;
|
||||
#define DEFINE_GLOBAL_OBJECT(Type, Name) Type D##Name; Type* G##Name = &D##Name;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
http.cpp
|
||||
A very small http server running in kernel mode, heh!
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include <libmaxsi/string.h>
|
||||
#include <libmaxsi/memory.h>
|
||||
#include "uart.h"
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace HTTP
|
||||
{
|
||||
uint32_t Left;
|
||||
|
||||
bool TryByte(char* Dest)
|
||||
{
|
||||
if ( Left == 0 )
|
||||
{
|
||||
UART::Read((uint8_t*) &Left, sizeof(Left));
|
||||
}
|
||||
|
||||
if ( Left == 0 ) { return false; }
|
||||
|
||||
UART::Read((uint8_t*) Dest, 1);
|
||||
Left--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Close()
|
||||
{
|
||||
uint32_t ToSend = 0;
|
||||
UART::Write(&ToSend, sizeof(ToSend));
|
||||
}
|
||||
|
||||
void Send(const char* Response, uint32_t Len)
|
||||
{
|
||||
UART::Write(&Len, sizeof(Len));
|
||||
UART::Write(Response, Len);
|
||||
}
|
||||
|
||||
void Respond(const char* Body, uint32_t Len)
|
||||
{
|
||||
const char* Headers = "HTTP/1.1 200 Success\r\nConnection: close\r\nContent-Type: application/xhtml+xml\r\n\r\n";
|
||||
Send(Headers, String::Length(Headers));
|
||||
Send(Body, Len);
|
||||
Close();
|
||||
}
|
||||
|
||||
void HandleResource(const char* Operation, const char* Resource)
|
||||
{
|
||||
if ( String::Compare(Resource, "/") == 0 )
|
||||
{
|
||||
const char* Response =
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n"
|
||||
" <head>\n"
|
||||
" <title>Hello, World!</title>\n"
|
||||
" </head>\n"
|
||||
" <body>\n"
|
||||
" <h1>\"Hello, World!\" said Sortix with a big smile!</h1>\n"
|
||||
" <p>\"Finally\", Sortix continued, \"someone completed a working HTTP server that runs under Sortix, which runs as a virtual machine, that communicates over a serial terminal driver to proxy server that communicates with the real internet!\".</p>\n"
|
||||
" <p>Sortix was happy.</p>\n"
|
||||
" <p>This website was served by a server running under my very own operating system, which is connected to the internet through a serial modem driver. Heh!</p>\n"
|
||||
" </body>\n"
|
||||
"</html>\n"
|
||||
;
|
||||
|
||||
Respond(Response, String::Length(Response)); return;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* Response = "HTTP/1.1 400 Not Found\r\nConnection: close\r\n\r\nHTTP 404 File Not Found\n";
|
||||
Send(Response, String::Length(Response)); Close(); return;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleConnection()
|
||||
{
|
||||
char Buffer[1024];
|
||||
|
||||
char* Operation = NULL;
|
||||
char* Resource = NULL;
|
||||
|
||||
size_t Used = 0;
|
||||
|
||||
nat State = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( !TryByte(Buffer + Used) ) { return; }
|
||||
Used++;
|
||||
Buffer[Used] = '\0';
|
||||
|
||||
if ( State == 0 )
|
||||
{
|
||||
if ( Used >= 4 )
|
||||
{
|
||||
if ( Buffer[0] == 'G' && Buffer[1] == 'E' && Buffer[2] == 'T' && Buffer[3] == ' ' )
|
||||
{
|
||||
State++;
|
||||
Buffer[3] = '\0';
|
||||
Operation = Buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* Response = "HTTP/1.1 501 Not Implemented\r\nConnection: close\r\n\r\nThis request is not supported by this server!\n";
|
||||
Send(Response, String::Length(Response)); Close(); return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( State == 1 )
|
||||
{
|
||||
if ( Buffer[Used-1] == ' ' )
|
||||
{
|
||||
Resource = Buffer + 4;
|
||||
Buffer[Used-1] = '\0';
|
||||
State++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Used == 1024 )
|
||||
{
|
||||
const char* Response = "HTTP/1.1 400 Bad Request\r\n\r\n";
|
||||
Send(Response, String::Length(Response)); Close(); return;
|
||||
}
|
||||
}
|
||||
|
||||
nat LineChars = 0;
|
||||
|
||||
while ( LineChars < 4 )
|
||||
{
|
||||
char TMP;
|
||||
if ( !TryByte(&TMP) ) { return; }
|
||||
|
||||
if ( TMP == '\r' || TMP == '\n' )
|
||||
{
|
||||
LineChars++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LineChars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
HandleResource(Operation, Resource);
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
Left = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
HandleConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
iirqhandler.h
|
||||
An interface for classes able to handle IRQs.
|
||||
|
||||
TODO: This is stupid. Get rid of this header and put the declaration
|
||||
someplace more intelligent.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_IIRQHANDLER_H
|
||||
#define SORTIX_IIRQHANDLER_H
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
typedef void (*InterruptHandler)(CPU::InterruptRegisters* Registers);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,257 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
iprintable.cpp
|
||||
A common interface shared by all devices that can be printed text to.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "iprintable.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
int UInt8ToString(uint8_t Num, char* Dest)
|
||||
{
|
||||
uint8_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 9 ) { Copy /= 10; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 10; Num /= 10; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
int UInt16ToString(uint16_t Num, char* Dest)
|
||||
{
|
||||
uint16_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 9 ) { Copy /= 10; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 10; Num /= 10; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
int UInt32ToString(uint32_t Num, char* Dest)
|
||||
{
|
||||
uint32_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 9 ) { Copy /= 10; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 10; Num /= 10; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
int UInt64ToString(uint64_t Num, char* Dest)
|
||||
{
|
||||
uint64_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 9 ) { Copy /= 10; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 10; Num /= 10; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
// Missing functions here.
|
||||
|
||||
int UInt32ToString16(uint32_t Num, char* Dest)
|
||||
{
|
||||
uint32_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 15 ) { Copy /= 16; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
if ( Num % 16 < 10 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dest[Offset] = 'A' + (Num % 16) - 10;
|
||||
}
|
||||
Num /= 16; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
int UInt64ToString16(uint64_t Num, char* Dest)
|
||||
{
|
||||
uint64_t Copy = Num;
|
||||
int Result = 0;
|
||||
|
||||
while ( Copy > 15 ) { Copy /= 16; Result++; }
|
||||
|
||||
int Offset = Result;
|
||||
while ( Offset >= 0 )
|
||||
{
|
||||
if ( Num % 16 < 10 )
|
||||
{
|
||||
Dest[Offset] = '0' + Num % 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
Dest[Offset] = 'A' + (Num % 16) - 10;
|
||||
}
|
||||
Num /= 16; Offset--;
|
||||
}
|
||||
|
||||
return Result + 1;
|
||||
}
|
||||
|
||||
// Missing functions here.
|
||||
|
||||
#define READY_SIZE 128
|
||||
#define READY_FLUSH() Ready[AmountReady] = 0; Written += Print(Ready); AmountReady = 0;
|
||||
#define F(N) (*(Format+N))
|
||||
|
||||
#define U32 1
|
||||
#define U64 2
|
||||
#define X32 3
|
||||
#define X64 4
|
||||
#define STRING 5
|
||||
#define CHAR 6
|
||||
|
||||
|
||||
size_t IPrintable::PrintF(const char* Format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, Format);
|
||||
size_t result = PrintFV(Format, list);
|
||||
va_end(list);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t IPrintable::PrintFV(const char* Format, va_list Parameters)
|
||||
{
|
||||
size_t Written = 0;
|
||||
char Ready[READY_SIZE + 1];
|
||||
int AmountReady = 0;
|
||||
|
||||
while ( *Format != '\0' )
|
||||
{
|
||||
if ( *Format != '%' )
|
||||
{
|
||||
Ready[AmountReady] = *Format; AmountReady++; Format++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int Type = 0;
|
||||
int Len = 1;
|
||||
|
||||
if ( F(1) == 'c' ) { Type = CHAR; Len += 1; } else
|
||||
if ( F(1) == 's' ) { Type = STRING; Len += 1; } else
|
||||
if ( F(1) == 'u' ) { Type = U32; Len += 1; } else
|
||||
if ( F(1) == '3' && F(2) == '2' && F(3) == 'u' ) { Type = U32; Len += 3; } else
|
||||
if ( F(1) == '6' && F(2) == '4' && F(3) == 'u' ) { Type = U64; Len += 3; } else
|
||||
if ( F(1) == 'x' ) { Type = X32; Len += 1; } else
|
||||
if ( F(1) == '3' && F(2) == '2' && F(3) == 'x' ) { Type = X32; Len += 3; } else
|
||||
if ( F(1) == '6' && F(2) == '4' && F(3) == 'x' ) { Type = X64; Len += 3; } else
|
||||
#ifdef PLATFORM_X86
|
||||
if ( F(1) == 'z' ) { Type = U32; Len += 1; } else
|
||||
if ( F(1) == 'p' ) { Type = X32; Len += 1; } else
|
||||
#elif defined(PLATFORM_X64)
|
||||
if ( F(1) == 'z' ) { Type = U64; Len += 1; } else
|
||||
if ( F(1) == 'p' ) { Type = X64; Len += 1; } else
|
||||
#endif
|
||||
//#ifdef PLATFORM_X86_FAMILY
|
||||
if ( F(1) == 'j' && F(2) == 'u' ) { Type = U64; Len += 2; } else
|
||||
if ( F(1) == 'j' && F(2) == 'x' ) { Type = X64; Len += 2; } else { }
|
||||
//#endif
|
||||
|
||||
if ( Type == STRING )
|
||||
{
|
||||
// TODO: This isn't efficient.
|
||||
READY_FLUSH();
|
||||
const char* param = va_arg(Parameters, const char*);
|
||||
Written += Print(param);
|
||||
}
|
||||
else if ( Type == CHAR )
|
||||
{
|
||||
if ( READY_SIZE <= AmountReady ) { READY_FLUSH(); }
|
||||
uint32_t param = va_arg(Parameters, uint32_t);
|
||||
Ready[AmountReady] = param & 0xFF; AmountReady++;
|
||||
}
|
||||
else if ( Type == U32 )
|
||||
{
|
||||
if ( READY_SIZE - AmountReady < 10 ) { READY_FLUSH(); }
|
||||
uint32_t Num = va_arg(Parameters, uint32_t);
|
||||
AmountReady += UInt32ToString(Num, Ready + AmountReady);
|
||||
}
|
||||
else if ( Type == U64 )
|
||||
{
|
||||
if ( READY_SIZE - AmountReady < 20 ) { READY_FLUSH(); }
|
||||
uint64_t Num = va_arg(Parameters, uint64_t);
|
||||
AmountReady += UInt64ToString(Num, Ready + AmountReady);
|
||||
}
|
||||
else if ( Type == X32 )
|
||||
{
|
||||
if ( READY_SIZE - AmountReady < 8 ) { READY_FLUSH(); }
|
||||
uint32_t Num = va_arg(Parameters, uint32_t);
|
||||
AmountReady += UInt32ToString16(Num, Ready + AmountReady);
|
||||
}
|
||||
else if ( Type == X64 )
|
||||
{
|
||||
if ( READY_SIZE - AmountReady < 16 ) { READY_FLUSH(); }
|
||||
uint64_t Num = va_arg(Parameters, uint64_t);
|
||||
AmountReady += UInt64ToString16(Num, Ready + AmountReady);
|
||||
}
|
||||
else // Unsupported/unknown format. Just echo!
|
||||
{
|
||||
Ready[AmountReady] = *Format; AmountReady++; Written++;
|
||||
}
|
||||
|
||||
Format += Len;
|
||||
}
|
||||
|
||||
if ( READY_SIZE == AmountReady ) { READY_FLUSH(); }
|
||||
}
|
||||
|
||||
// Flush our cache.
|
||||
if ( AmountReady ) { Ready[AmountReady] = 0; Written += Print(Ready); }
|
||||
|
||||
return Written;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
iprintable.h
|
||||
A common interface shared by all devices that can be printed text to.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SORTIX_IPRINTABLE_H
|
||||
#define SORTIX_IPRINTABLE_H
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
int UInt8ToString(uint8_t Num, char* Dest);
|
||||
int UInt16ToString(uint16_t Num, char* Dest);
|
||||
int UInt32ToString(uint32_t Num, char* Dest);
|
||||
int UInt64ToString(uint64_t Num, char* Dest);
|
||||
|
||||
class IPrintable
|
||||
{
|
||||
public:
|
||||
size_t PrintFV(const char* Format, va_list Parameters);
|
||||
size_t PrintF(const char* Format, ...);
|
||||
|
||||
public:
|
||||
virtual size_t Print(const char* Message) = 0;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// isr.c -- High level interrupt service routines and interrupt request handlers.
|
||||
// Part of this code is modified from Bran's kernel development tutorials.
|
||||
// Rewritten for JamesM's kernel development tutorials.
|
||||
//
|
||||
|
||||
#include "platform.h"
|
||||
#include "globals.h"
|
||||
#include "iprintable.h"
|
||||
#include "iirqhandler.h"
|
||||
#include "log.h"
|
||||
#include "isr.h"
|
||||
#include "panic.h"
|
||||
|
||||
size_t numknownexceptions = 19;
|
||||
const char* exceptions[] = { "Divide by zero", "Debug", "Non maskable interrupt", "Breakpoint",
|
||||
"Into detected overflow", "Out of bounds", "Invalid opcode",
|
||||
"No coprocessor", "Double fault", "Coprocessor segment overrun",
|
||||
"Bad TSS", "Segment not present", "Stack fault",
|
||||
"General protection fault", "Page fault", "Unknown interrupt",
|
||||
"Coprocessor fault", "Alignment check", "Machine check" };
|
||||
|
||||
Sortix::InterruptHandler interrupt_handlers[256];
|
||||
|
||||
void register_interrupt_handler(uint8_t n, Sortix::InterruptHandler handler)
|
||||
{
|
||||
interrupt_handlers[n] = handler;
|
||||
}
|
||||
|
||||
// This gets called from our ASM interrupt handler stub.
|
||||
extern "C" void isr_handler(Sortix::CPU::InterruptRegisters* Regs)
|
||||
{
|
||||
#ifdef PLATFORM_X86
|
||||
if ( Regs->int_no < 32 )
|
||||
{
|
||||
const char* message = ( Regs->int_no < numknownexceptions ) ? exceptions[Regs->int_no] : "Unknown";
|
||||
Sortix::PanicF("Unhandled CPU Exception id %zu '%s' at eip=0x%zx (cr2=0x%p)", Regs->int_no, message, Regs->eip, Regs->cr2);
|
||||
}
|
||||
|
||||
if ( interrupt_handlers[Regs->int_no] != NULL )
|
||||
{
|
||||
interrupt_handlers[Regs->int_no](Regs);
|
||||
}
|
||||
#else
|
||||
#warning "ISR handlers are not supported on this arch"
|
||||
while(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
// This gets called from our ASM interrupt handler stub.
|
||||
extern "C" void irq_handler(Sortix::CPU::InterruptRegisters* Regs)
|
||||
{
|
||||
#ifdef PLATFORM_X86
|
||||
if ( Regs->int_no != 32 )
|
||||
{
|
||||
Sortix::Log::PrintF("IRQ eax=%u, int_no=%u, err_code=%u, eip=0x%x!\n", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip);
|
||||
}
|
||||
|
||||
if ( Regs->int_no < 32 || 48 < Regs->int_no ) { Sortix::PanicF("IRQ eax=%u, int_no=%u, err_code=%u, eip=%u!", Regs->eax, Regs->int_no, Regs->err_code, Regs->eip); }
|
||||
|
||||
// TODO! IRQ 7 and 15 might be spurious and might need to be ignored.
|
||||
// See http://wiki.osdev.org/PIC for details (section Spurious IRQs).
|
||||
|
||||
// Send an EOI (end of interrupt) signal to the PICs.
|
||||
if (Regs->int_no >= 40) { Sortix::X86::OutPortB(0xA0, 0x20); } // Send reset signal to slave if this interrupt involved the slave.
|
||||
Sortix::X86::OutPortB(0x20, 0x20); // Send reset signal to master.
|
||||
|
||||
if ( interrupt_handlers[Regs->int_no] != NULL )
|
||||
{
|
||||
interrupt_handlers[Regs->int_no](Regs);
|
||||
}
|
||||
#else
|
||||
#warning "IRQ handlers are not supported on this arch"
|
||||
while(true);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// isr.h -- Interface and structures for high level interrupt service routines.
|
||||
// Part of this code is modified from Bran's kernel development tutorials.
|
||||
// Rewritten for JamesM's kernel development tutorials.
|
||||
//
|
||||
|
||||
// A few defines to make life a little easier
|
||||
#define IRQ0 32
|
||||
#define IRQ1 33
|
||||
#define IRQ2 34
|
||||
#define IRQ3 35
|
||||
#define IRQ4 36
|
||||
#define IRQ5 37
|
||||
#define IRQ6 38
|
||||
#define IRQ7 39
|
||||
#define IRQ8 40
|
||||
#define IRQ9 41
|
||||
#define IRQ10 42
|
||||
#define IRQ11 43
|
||||
#define IRQ12 44
|
||||
#define IRQ13 45
|
||||
#define IRQ14 46
|
||||
#define IRQ15 47
|
||||
|
||||
void register_interrupt_handler(uint8_t n, Sortix::InterruptHandler handler);
|
||||
|
|
@ -0,0 +1,274 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
kernel.cpp
|
||||
A common interface shared by all devices that can be printed text to.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include <libmaxsi/memory.h>
|
||||
#include <libmaxsi/string.h>
|
||||
#include <libmaxsi/format.h>
|
||||
#include "globals.h"
|
||||
#include "iprintable.h"
|
||||
#include "log.h"
|
||||
#include "panic.h"
|
||||
#include "descriptor_tables.h"
|
||||
#include "iirqhandler.h"
|
||||
#include "time.h"
|
||||
#include "keyboard.h"
|
||||
#include "multiboot.h"
|
||||
#include "memorymanagement.h"
|
||||
#include "scheduler.h"
|
||||
#include "syscall.h"
|
||||
#include "pong.h"
|
||||
#include "conway.h"
|
||||
#include "pci.h"
|
||||
#include "uart.h"
|
||||
#include "serialterminal.h"
|
||||
#include "vgaterminal.h"
|
||||
|
||||
using namespace Maxsi;
|
||||
|
||||
void* RunApplication(void* Parameter);
|
||||
|
||||
extern "C" size_t stack[4096] = {0};
|
||||
extern "C" size_t stackend = 0;
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
#ifdef PLATFORM_HTTP
|
||||
namespace HTTP { void Init(); }
|
||||
#endif
|
||||
|
||||
void DoBSoD()
|
||||
{
|
||||
#ifdef PLATFORM_SERIAL
|
||||
UART::WriteChar(27);
|
||||
UART::WriteChar(91);
|
||||
UART::WriteChar(48 + 4);
|
||||
UART::WriteChar(48 + 4);
|
||||
UART::WriteChar(109);
|
||||
#endif
|
||||
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print("Windows Boot Manager has experienced a problem. ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" Status: 0xc000000f ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" Info: An error occured during transferring execution. ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print("You can try to recover the system with the Microsoft Windows System Recovery ");
|
||||
Log::Print("Tools. (You might need to restart the system manually). ");
|
||||
Log::Print(" ");
|
||||
Log::Print("If the problem continues, please contact your system administrator or computer ");
|
||||
Log::Print("manufacturer. ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
|
||||
#ifdef JSSORTIX
|
||||
JSSortix::Exit();
|
||||
#else
|
||||
while ( true ) { }
|
||||
#endif
|
||||
}
|
||||
|
||||
void DoMaxsiLogo()
|
||||
{
|
||||
Log::Print(" _ ");
|
||||
Log::Print(" / \\ ");
|
||||
Log::Print(" /\\ /\\ / \\ ");
|
||||
Log::Print(" / \\ / \\ | | ");
|
||||
Log::Print(" / \\/ \\ | | ");
|
||||
Log::Print(" | O O \\_______________________ / | ");
|
||||
Log::Print(" | | ");
|
||||
Log::Print(" | \\_______/ / ");
|
||||
Log::Print(" \\ / ");
|
||||
Log::Print(" ------ --------------- ---/ ");
|
||||
Log::Print(" / \\ / \\ ");
|
||||
Log::Print(" / \\ / \\ ");
|
||||
Log::Print(" / \\ / \\ ");
|
||||
Log::Print(" /_____________\\ /____________\\ ");
|
||||
Log::Print(" ");
|
||||
}
|
||||
|
||||
void DoWelcome()
|
||||
{
|
||||
#ifdef BSOD
|
||||
DoBSoD();
|
||||
#endif
|
||||
|
||||
DoMaxsiLogo();
|
||||
|
||||
#ifdef PLATFORM_SERIAL
|
||||
#ifdef PONG
|
||||
Log::Print(" = THE SORTIX KERNEL - PONG EDITION = ");
|
||||
#elif defined(CONWAY)
|
||||
Log::Print(" = THE SORTIX KERNEL - CONWAY'S GAME OF LIFE EDITION = ");
|
||||
#else
|
||||
Log::Print(" ");
|
||||
#endif
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
Log::Print(" ");
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void KernelInit(unsigned long Magic, multiboot_info_t* BootInfo)
|
||||
{
|
||||
#ifdef JSSORTIX
|
||||
// TODO: Make JSVM multiboot compliant.
|
||||
multiboot_info_t MBInfo; BootInfo = &MBInfo;
|
||||
multiboot_memory_map_t MBMMap;
|
||||
|
||||
MBMMap.addr = 0x100000;
|
||||
MBMMap.len = 0xC00000;
|
||||
MBMMap.type = MULTIBOOT_MEMORY_AVAILABLE;
|
||||
MBMMap.size = sizeof(MBMMap) - sizeof(MBMMap.size);
|
||||
BootInfo->flags = MULTIBOOT_INFO_MEM_MAP;
|
||||
BootInfo->mmap_addr = (multiboot_uint32_t) &MBMMap;
|
||||
BootInfo->mmap_length = sizeof(MBMMap);
|
||||
#endif
|
||||
|
||||
// Initialize the default terminal.
|
||||
Maxsi::Format::Callback logcallback;
|
||||
void* logpointer;
|
||||
|
||||
#if PLATFORM_SERIAL
|
||||
// Initialize the serial driver.
|
||||
UART::Init();
|
||||
|
||||
SerialTerminal::Init();
|
||||
logcallback = SerialTerminal::Print;
|
||||
logpointer = NULL;
|
||||
|
||||
#else
|
||||
VGATerminal::Init();
|
||||
logcallback = VGATerminal::Print;
|
||||
logpointer = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
// Initialize the kernel log.
|
||||
Log::Init(logcallback, logpointer);
|
||||
|
||||
// Just a test to see if the color system works! Make the BG red!
|
||||
Log::Print("\e[37;41m\e[2J");
|
||||
|
||||
// Display the boot welcome screen.
|
||||
DoWelcome();
|
||||
|
||||
#ifndef JSSORTIX
|
||||
// Search for PCI devices and load their drivers.
|
||||
PCI::Init();
|
||||
#endif
|
||||
|
||||
// Initialize the paging.
|
||||
Page::Init(BootInfo);
|
||||
|
||||
uint8_t* initrd = NULL;
|
||||
size_t initrdsize = 0;
|
||||
|
||||
#ifdef INITRD
|
||||
uint8_t** modules = (uint8_t**) BootInfo->mods_addr;
|
||||
for ( uint32_t I = 0; I < BootInfo->mods_count; I++ )
|
||||
{
|
||||
initrdsize = modules[2*I+1] - modules[2*I+0];
|
||||
initrd = modules[2*I+0];
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize the GDT and TSS structures.
|
||||
GDT::Init();
|
||||
|
||||
// Initialize the interrupt descriptor tables.
|
||||
IDT::Init();
|
||||
|
||||
if ( BootInfo == NULL ) { Panic("kernel.cpp: The bootinfo structure was NULL. Are your bootloader multiboot compliant?"); }
|
||||
|
||||
|
||||
// Initialize the keyboard.
|
||||
Keyboard::Init();
|
||||
|
||||
#ifdef PLATFORM_VIRTUAL_MEMORY
|
||||
// Initialize virtual memory. TODO: This is not fully working yet.
|
||||
VirtualMemory::Init();
|
||||
|
||||
#ifdef PLATFORM_KERNEL_HEAP
|
||||
// Initialize the kernel heap.
|
||||
Maxsi::Memory::Init();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Initialize system calls.
|
||||
Syscall::Init();
|
||||
|
||||
// Initialize the scheduler.
|
||||
Scheduler::Init();
|
||||
|
||||
Thread::Entry initstart = RunApplication;
|
||||
|
||||
if ( initrd != NULL )
|
||||
{
|
||||
void* loadptr = (void*) 0x400000;
|
||||
uintptr_t loadint = (uintptr_t) loadptr;
|
||||
|
||||
#ifdef PLATFORM_VIRTUAL_MEMORY
|
||||
ASSERT(initrdsize <= 4096);
|
||||
void* apppageptr = Page::Get();
|
||||
uintptr_t apppageint = (uintptr_t) apppageptr;
|
||||
|
||||
uintptr_t flags = TABLE_PRESENT | TABLE_WRITABLE | TABLE_USER_SPACE;
|
||||
VirtualMemory::Map(apppageint, loadint, flags);
|
||||
VirtualMemory::Flush();
|
||||
#endif
|
||||
|
||||
Memory::Copy(loadptr, initrd, initrdsize);
|
||||
initstart = (Thread::Entry) loadptr;
|
||||
}
|
||||
|
||||
if ( Scheduler::CreateThread(NULL, initstart) == NULL )
|
||||
{
|
||||
Panic("Could not create a sample thread!");
|
||||
}
|
||||
|
||||
// Lastly set up the timer driver and we are ready to run the OS.
|
||||
Time::Init();
|
||||
|
||||
// Run the OS.
|
||||
Scheduler::MainLoop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,709 @@
|
|||
/******************************************************************************
|
||||
|
||||
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix 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 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix 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 Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
keyboard.cpp
|
||||
A driver for the PS2 Keyboard.
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "platform.h"
|
||||
#include "globals.h"
|
||||
#include "iprintable.h"
|
||||
#include "iirqhandler.h"
|
||||
#include "log.h"
|
||||
#include "panic.h"
|
||||
#include "keyboard.h"
|
||||
#include "isr.h"
|
||||
|
||||
#include "pong.h"
|
||||
|
||||
namespace Sortix
|
||||
{
|
||||
namespace Keyboard
|
||||
{
|
||||
namespace Layouts
|
||||
{
|
||||
const uint32_t UNKNOWN = 0xFFFFFFFF;
|
||||
const uint32_t ESC = 0xFFFFFFFF - 1;
|
||||
const uint32_t CTRL = 0xFFFFFFFF - 2;
|
||||
const uint32_t LSHFT = 0xFFFFFFFF - 3;
|
||||
const uint32_t RSHFT = 0xFFFFFFFF - 4;
|
||||
const uint32_t ALT = 0xFFFFFFFF - 5;
|
||||
const uint32_t F1 = 0xFFFFFFFF - 6;
|
||||
const uint32_t F2 = 0xFFFFFFFF - 7;
|
||||
const uint32_t F3 = 0xFFFFFFFF - 8;
|
||||
const uint32_t F4 = 0xFFFFFFFF - 9;
|
||||
const uint32_t F5 = 0xFFFFFFFF - 10;
|
||||
const uint32_t F6 = 0xFFFFFFFF - 11;
|
||||
const uint32_t F7 = 0xFFFFFFFF - 12;
|
||||
const uint32_t F8 = 0xFFFFFFFF - 13;
|
||||
const uint32_t F9 = 0xFFFFFFFF - 14;
|
||||
const uint32_t F10 = 0xFFFFFFFF - 15;
|
||||
const uint32_t F11 = 0xFFFFFFFF - 16;
|
||||
const uint32_t F12 = 0xFFFFFFFF - 17;
|
||||
const uint32_t SCRLCK = 0xFFFFFFFF - 18;
|
||||
const uint32_t HOME = 0xFFFFFFFF - 19;
|
||||
const uint32_t UP = 0xFFFFFFFF - 20;
|
||||
const uint32_t LEFT = 0xFFFFFFFF - 21;
|
||||
const uint32_t RIGHT = 0xFFFFFFFF - 22;
|
||||
const uint32_t DOWN = 0xFFFFFFFF - 23;
|
||||
const uint32_t PGUP = 0xFFFFFFFF - 24;
|
||||
const uint32_t PGDOWN = 0xFFFFFFFF - 25;
|
||||
const uint32_t END = 0xFFFFFFFF - 26;
|
||||
const uint32_t INS = 0xFFFFFFFF - 27;
|
||||
const uint32_t DEL = 0xFFFFFFFF - 28;
|
||||
const uint32_t CAPS = 0xFFFFFFFF - 29;
|
||||
const uint32_t NONE = 0xFFFFFFFF - 30;
|
||||
const uint32_t ALTGR = 0xFFFFFFFF - 31;
|
||||
const uint32_t NUMLCK = 0xFFFFFFFF - 32;
|
||||
|
||||
namespace US
|
||||
{
|
||||
uint32_t sg[128] =
|
||||
{
|
||||
UNKNOWN,
|
||||
ESC,
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'0',
|
||||
'-',
|
||||
'=',
|
||||
'\b',
|
||||
'\t',
|
||||
'q',
|
||||
'w',
|
||||
'e',
|
||||
'r',
|
||||
't',
|
||||
'y',
|
||||
'u',
|
||||
'i',
|
||||
'o',
|
||||
'p',
|
||||
'[',
|
||||
']',
|
||||
'\n',
|
||||
CTRL,
|
||||
'a',
|
||||
's',
|
||||
'd',
|
||||
'f',
|
||||
'g',
|
||||
'h',
|
||||
'j',
|
||||
'k',
|
||||
'l',
|
||||
';',
|
||||
'\'',
|
||||
'`',
|
||||
LSHFT,
|
||||
'\\',
|
||||
'z',
|
||||
'x',
|
||||
'c',
|
||||
'v',
|
||||
'b',
|
||||
'n',
|
||||
'm',
|
||||
',',
|
||||
'.',
|
||||
'/',
|
||||
RSHFT,
|
||||
'*',
|
||||
ALT,
|
||||
' ',
|
||||
CAPS,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
NUMLCK,
|
||||
SCRLCK,
|
||||
HOME,
|
||||
UP,
|
||||
PGUP,
|
||||
'-',
|
||||
LEFT,
|
||||
UNKNOWN,
|
||||
RIGHT,
|
||||
'+',
|
||||
END,
|
||||
DOWN,
|
||||
PGDOWN,
|
||||
INS,
|
||||
DEL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
F11,
|
||||
F12,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
uint32_t Sg[128] =
|
||||
{
|
||||
UNKNOWN,
|
||||
ESC,
|
||||
'!',
|
||||
'@',
|
||||
'#',
|
||||
'$',
|
||||
'%',
|
||||
'^',
|
||||
'&',
|
||||
'*',
|
||||
'(',
|
||||
')',
|
||||
'_',
|
||||
'+',
|
||||
'\b',
|
||||
'\t', // TODO: Make it de-tab!
|
||||
'Q',
|
||||
'W',
|
||||
'E',
|
||||
'R',
|
||||
'T',
|
||||
'Y',
|
||||
'U',
|
||||
'I',
|
||||
'O',
|
||||
'P',
|
||||
'{',
|
||||
'}',
|
||||
'\n',
|
||||
CTRL,
|
||||
'A',
|
||||
'S',
|
||||
'D',
|
||||
'F',
|
||||
'G',
|
||||
'H',
|
||||
'J',
|
||||
'K',
|
||||
'L',
|
||||
':',
|
||||
'"',
|
||||
'~',
|
||||
LSHFT,
|
||||
'|',
|
||||
'Z',
|
||||
'X',
|
||||
'C',
|
||||
'V',
|
||||
'B',
|
||||
'N',
|
||||
'M',
|
||||
'<',
|
||||
'>',
|
||||
'?',
|
||||
RSHFT,
|
||||
'*',
|
||||
ALT,
|
||||
' ',
|
||||
CAPS,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
NUMLCK,
|
||||
SCRLCK,
|
||||
HOME,
|
||||
UP,
|
||||
PGUP,
|
||||
'-',
|
||||
LEFT,
|
||||
UNKNOWN,
|
||||
RIGHT,
|
||||
'+',
|
||||
END,
|
||||
DOWN,
|
||||
PGDOWN,
|
||||
INS,
|
||||
DEL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
F11,
|
||||
F12,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
uint32_t sG[128] =
|
||||
{
|
||||
UNKNOWN,
|
||||
ESC,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
'\b',
|
||||
'\t',
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
'\n',
|
||||
CTRL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
LSHFT,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
RSHFT,
|
||||
UNKNOWN,
|
||||
ALT,
|
||||
' ',
|
||||
CAPS,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
NUMLCK,
|
||||
SCRLCK,
|
||||
HOME,
|
||||
UP,
|
||||
PGUP,
|
||||
'-',
|
||||
LEFT,
|
||||
UNKNOWN,
|
||||
RIGHT,
|
||||
'+',
|
||||
END,
|
||||
DOWN,
|
||||
PGDOWN,
|
||||
INS,
|
||||
DEL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
F11,
|
||||
F12,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
uint32_t SG[128] =
|
||||
{
|
||||
UNKNOWN,
|
||||
ESC,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
'\b',
|
||||
'\t',
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
'\n',
|
||||
CTRL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
LSHFT,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
RSHFT,
|
||||
UNKNOWN,
|
||||
ALT,
|
||||
' ',
|
||||
CAPS,
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
NUMLCK,
|
||||
SCRLCK,
|
||||
HOME,
|
||||
UP,
|
||||
PGUP,
|
||||
'-',
|
||||
LEFT,
|
||||
UNKNOWN,
|
||||
RIGHT,
|
||||
'+',
|
||||
END,
|
||||
DOWN,
|
||||
PGDOWN,
|
||||
INS,
|
||||
DEL,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
F11,
|
||||
F12,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
uint32_t* Layout[4] = { sg, Sg, sG, SG };
|
||||
}
|
||||
|
||||
uint32_t** Layout = US::Layout;
|
||||
|
||||
nat Mask = 0;
|
||||
nat LockMask = 0;
|
||||
|
||||
const nat Shift = (1<<0);
|
||||
const nat AltGr = (1<<1);
|
||||
const nat ScrLck = (1<<2);
|
||||
const nat LEDScrLck = (1<<0);
|
||||
const nat LEDNumLck = (1<<1);
|
||||
const nat LEDCapsLck = (1<<2);
|
||||
|
||||
uint32_t GetCodePoint(uint8_t Scancode)
|
||||
{
|
||||
nat TableIndex = 0x3 & (Mask ^ LockMask);
|
||||
|
||||
//Log::PrintF("[m=%x,lm=%x,ti=%x]", Mask, LockMask, TableIndex);
|
||||
|
||||
uint32_t CodePoint = Layout[TableIndex][Scancode & 0x7F];
|
||||
|
||||
if ( CodePoint == UNKNOWN ) { return UNKNOWN; }
|
||||
if ( Scancode & 0x80 )
|
||||
{
|
||||
if ( CodePoint == LSHFT ) { Mask &= ~Shift; }
|
||||
if ( CodePoint == ALTGR ) { Mask &= ~AltGr; }
|
||||
if ( CodePoint == SCRLCK ) { Mask &= ~ScrLck; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( CodePoint == LSHFT ) { Mask |= Shift; }
|
||||
if ( CodePoint == ALTGR ) { Mask |= AltGr; }
|
||||
if ( CodePoint == SCRLCK ) { Mask |= ScrLck; }
|
||||
if ( CodePoint == CAPS ) { LockMask ^= Shift; SetLEDs(LEDCapsLck); }
|
||||
}
|
||||
|
||||
return CodePoint;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LEDs;
|
||||
|
||||
void Init()
|
||||
{
|
||||
// Initialize variables.
|
||||
LEDs = 0;
|
||||
|
||||
// Register our keystroke callback.
|
||||
register_interrupt_handler(IRQ1, OnIRQ1);
|
||||
|
||||
// If any scancodes were already pending, our interrupt handler
|
||||
// will never be called. Let's just discard anything pending.
|
||||
CPU::InPortB(0x60);
|
||||
}
|
||||
|
||||
void OnIRQ1(CPU::InterruptRegisters* Regs)
|
||||
{
|
||||
// Read the scancode from the data register.
|
||||
uint8_t Scancode = CPU::InPortB(0x60);
|
||||
|
||||
//Log::PrintF("[%u]", Scancode);
|
||||
|
||||
uint32_t CodePoint = Layouts::GetCodePoint(Scancode);
|
||||
|
||||
bool KeyUp = (Scancode & 0x80) > 0;
|
||||
|
||||
#if PONG
|
||||
Pong::OnKeystroke(CodePoint, KeyUp); return;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
return;
|
||||
#endif
|
||||
//if ( Reader != NULL ) { Reader->OnKeystroke(CodePoint, KeyUp); return; }
|
||||
|
||||
// Use this to debug the exact scancodes you receive!
|
||||
//Log::PrintF("[%u/U+%x]", Scancode, CodePoint);
|
||||
|
||||
if ( CodePoint == Layouts::UNKNOWN ) { Log::PrintF("^%u", Scancode);return; }
|
||||
|
||||
if ( CodePoint & (1<<31) ) { return; }
|
||||
|
||||
// The high bit of the scancode is set if the key is released.
|
||||
if ( Scancode & 0x80 ) { return; }
|
||||
|
||||
if ( CodePoint & 0xFFFFFF80 ) { Log::PrintF("U+%x", CodePoint); return; }
|
||||
|
||||
Log::PrintF("%s", &CodePoint); // Little endian hack!
|
||||
}
|
||||
|
||||
void SetLEDs(uint8_t Toggle)
|
||||
{
|
||||
LEDs ^= Toggle;
|
||||
|
||||
while ( (CPU::InPortB(0x64) & (1<<1)) != 0 ) { } //loop Until zero
|
||||
CPU::OutPortB(0x60, 0xED);
|
||||
while ( (CPU::InPortB(0x64) & (1<<1)) != 0 ) { } //loop Until zero
|
||||
CPU::OutPortB(0x60, LEDs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue