Update of /cvsroot/pure-data/externals/pdp/system
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/system
Added Files:
CONTENTS Makefile pdp.c
Log Message:
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: pdp.c ---
/*
* Pure Data Packet system implementation: setup code
* Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include "pdp_config.h"
#include "pdp_post.h"
/* all symbols are C style */
#ifdef __cplusplus
extern "C"
{
#endif
/* module setup declarations (all C-style) */
/* pdp system / internal stuff */
void pdp_debug_setup(void);
void pdp_list_setup(void);
void pdp_pdsym_setup(void);
void pdp_forth_setup(void);
void pdp_forth_def_setup(void);
void pdp_symbol_setup(void);
void pdp_type_setup(void);
void pdp_packet_setup(void);
void pdp_ut_setup(void);
void pdp_queue_setup(void);
void pdp_control_setup(void);
void pdp_image_setup(void);
void pdp_bitmap_setup(void);
void pdp_matrix_setup(void);
/* pdp modules */
void pdp_xv_setup(void);
void pdp_add_setup(void);
void pdp_mul_setup(void);
void pdp_mix_setup(void);
void pdp_randmix_setup(void);
void pdp_qt_setup(void);
void pdp_v4l_setup(void);
void pdp_reg_setup(void);
void pdp_conv_setup(void);
void pdp_bq_setup(void);
void pdp_del_setup(void);
void pdp_snap_setup(void);
void pdp_trigger_setup(void);
void pdp_route_setup(void);
void pdp_noise_setup(void);
void pdp_gain_setup(void);
void pdp_chrot_setup(void);
void pdp_scope_setup(void);
void pdp_scale_setup(void);
void pdp_zoom_setup(void);
void pdp_scan_setup(void);
void pdp_scanxy_setup(void);
void pdp_sdl_setup(void);
void pdp_cheby_setup(void);
void pdp_grey2mask_setup(void);
void pdp_constant_setup(void);
void pdp_logic_setup(void);
void pdp_glx_setup(void);
void pdp_loop_setup(void);
void pdp_description_setup(void);
void pdp_convert_setup(void);
void pdp_stateless_setup(void);
void pdp_mat_mul_setup(void);
void pdp_mat_lu_setup(void);
void pdp_mat_vec_setup(void);
void pdp_plasma_setup(void);
void pdp_cog_setup(void);
void pdp_histo_setup(void);
void pdp_array_setup(void);
void pdp_udp_send_setup(void);
void pdp_udp_receive_setup(void);
void pdp_rawin_setup(void);
void pdp_rawout_setup(void);
/* hacks */
void pdp_inspect_setup(void);
/* testing */
void pdp_dpd_test_setup(void);
/* library setup routine */
void pdp_setup(void){
/* babble */
pdp_post ("PDP: pure data packet");
#ifdef PDP_VERSION
pdp_post("PDP: version " PDP_VERSION );
#endif
/* setup pdp system */
/* kernel */
pdp_pdsym_setup();
pdp_debug_setup();
pdp_symbol_setup();
pdp_list_setup();
pdp_type_setup();
pdp_packet_setup();
pdp_control_setup();
/* types */
pdp_image_setup();
pdp_bitmap_setup();
#ifdef HAVE_PDP_GSL
pdp_matrix_setup();
#endif
pdp_queue_setup();
/* setup utility toolkit */
pdp_ut_setup();
/* setup pdp pd modules*/
pdp_add_setup();
pdp_mul_setup();
pdp_mix_setup();
pdp_randmix_setup();
pdp_reg_setup();
pdp_conv_setup();
pdp_bq_setup();
pdp_del_setup();
pdp_snap_setup();
pdp_trigger_setup();
pdp_route_setup();
pdp_noise_setup();
pdp_plasma_setup();
pdp_gain_setup();
pdp_chrot_setup();
pdp_scope_setup();
pdp_scale_setup();
pdp_zoom_setup();
pdp_scan_setup();
pdp_scanxy_setup();
pdp_grey2mask_setup();
pdp_constant_setup();
pdp_logic_setup();
pdp_loop_setup();
pdp_description_setup();
pdp_convert_setup();
pdp_stateless_setup();
pdp_cog_setup();
pdp_array_setup();
pdp_rawin_setup();
pdp_rawout_setup();
/* experimental stuff */
pdp_inspect_setup();
pdp_udp_send_setup();
pdp_udp_receive_setup();
/* testing */
//pdp_dpd_test_setup();
/* optional stuff */
#ifdef HAVE_PDP_READLINE
pdp_forthconsole_setup();
#endif
#ifdef HAVE_PDP_GSL
pdp_histo_setup();
pdp_cheby_setup();
pdp_mat_mul_setup();
pdp_mat_lu_setup();
pdp_mat_vec_setup();
#endif
#ifdef HAVE_PDP_QT
pdp_qt_setup();
#endif
#ifdef HAVE_PDP_XV
pdp_xv_setup();
#endif
#ifdef HAVE_PDP_SDL
pdp_sdl_setup();
#endif
#ifdef HAVE_PDP_V4L
pdp_v4l_setup();
#endif
#ifdef HAVE_PDP_GLX
pdp_glx_setup();
#endif
}
#ifdef __cplusplus
}
#endif
--- NEW FILE: Makefile ---
include ../Makefile.config
all: $(PDP_TARGET) pdp.o
common:
make -C net
make -C X11
make -C png
make -C type
make -C kernel
make -C image $(PDP_TARGET)
linux_mmx: common
make -C mmx
linux: common
darwin: common
clean:
rm -f *~
rm -f *.o
make -C mmx clean
make -C net clean
make -C X11 clean
make -C png clean
make -C image clean
make -C type clean
make -C kernel clean
--- NEW FILE: CONTENTS ---
X11 x window specific code
forth packet forth code
image image processing code
kernel the core pdp system
mmx mmx assembly code
net networking support
png png support
type different packet type implementations
Update of /cvsroot/pure-data/externals/pdp/scaf/rules
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/scaf/rules
Added Files:
Makefile carules.scaf
Log Message:
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: carules.scaf ---
( Pure Data Packet - ca rules library. )
( Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org> )
( )
( 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 2 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, write to the Free Software )
( Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. )
( this is the standard ca rules library )
( a rule that is accessible from the ouside should start with "rule_" )
( and has to return exactly one item on the stack (this is checked in pdp_ca) )
( a word is a sequence of non whitespace characters (\S+) )
( words are separated by whitespace (\s+) )
( so "word ;" is not the same as "word;" )
( all words between the "(" word and the ")" word are ignored )
( ":" starts a definition, the next word is the name of the new word )
( newline ends a definition )
( no more than one definition per line )
( no more than one line per definition )
( ";" returns to calling word )
( if no ";" is encountered the next defined word is executed )
( this is to have multiple entry points )
( multiple exit points don't make sense since there are no conditional words )
: +(4) ++++ ; ( 4 bit add TOS - carry on TOS )
: +(3) +++ ; ( 3 bit add TOS - carry on TOS )
: +(2) ++ ; ( 2 bit add TOS - carry on TOS )
: +top @-+ +(4) drop @0+ +(4) drop @++ +(4) ; ( add top row to reg - carry on TOS )
: +mid @-0 +(4) drop @00 +(4) drop @+0 +(4) ; ( add mid row to reg - carry on TOS )
: +bot @-- +(4) drop @0- +(4) drop @+- +(4) ; ( add bot row to reg - carry on TOS )
: +all +top drop +mid drop +bot ; ( add all cells to reg - carry on TOS )
: +mid-1 @-0 +(4) drop @+0 +(4) ; ( add mid row except center element to reg - carry on TOS )
: +all-1 +top drop +mid-1 drop +bot ; ( add all cells expet middle one to reg - carry on TOS )
: countall a-0 +all drop ; ( count all cells - no stack effect )
: countall-1 a-0 +all-1 drop ; ( count all cells except middle one - no stack effect )
: +topbot @0+ +(3) drop @0- +(3) ;
: +leftright @+0 +(3) drop @-0 +(3) ;
: +star +topbot drop +leftright ;
: countstar a-0 +star drop ;
: =2or3? @a2 not @a1 and ; ( sum equal to 2 or 3? only checks 3 bits )
: =3? =2or3? @a0 and ; ( sum equal to 3 ? )
: =2? =2or3? @a0 not and ; ( sum equal to 2 ? )
: =4? @a2 @a1 not and @a0 not and ; ( sum equal to 4 ? )
( some test rules )
( : rule_one 1 ; )
( : rule_zero 0 ; )
( : rule_id @00 ; )
: rule_shiftleft @+0 ;
: rule_shifttop @0- ;
: rule_shiftbot @0+ ;
: rule_shifttopright @-- ;
: rule_strobe @00 not ;
( game of life )
: rule_gameoflife countall-1 =2? @00 and =3? or ;
( wolfram's rule 110)
: rule_w110 @00 @+0 and not @-0 @00 @+0 or or and ;
( some other rules )
: rule_w110mod @0+ @+0 and not @-+ @0+ @++ or or and ;
: rule_w110mod2 @0+ @+0 and not @-+ @0+ @+0 or or and ;
: rule_w110mod3 @0+ @++ and not @-+ @0+ @++ or or and @-0 @00 @+0 or or and ;
: rule_golmod countall-1 =3? @00 and =2? or ;
: rule_golmod2 countall-1 =2? @0+ and =3? or ;
: rule_golmod3 countall-1 =2? @++ and =3? or ;
: rule_golmod4 countall-1 =2? @++ @-- or and =3? or ;
: rule_golmod5 countall-1 =2? @++ @-- or and =3? @+- and or ;
: rule_golmod6 countall-1 =2? @++ @-- or and =3? @+- and or @0+ or ;
: rule_golmod7 countall-1 =2? @++ @-- or and =3? @+- and or @0+ or @00 and ;
( ca's with a short settling time )
: rule_block countstar =4? not =2? and @00 or ;
: rule_noiseedges countstar =4? =3? or not =2? and @00 or @++ xor ;
: rule_noiseplanes countstar =4? =3? or not =2? and @00 or @++ xor @-- xor ;
( : rule_noiseplanes countstar =4? =3? or not =2? and @00 or @++ xor @-- xor ; )
: rule_fire countall-1 =2? @0+ and =3? or ;
--- NEW FILE: Makefile ---
OBJ = carules.scafo
.SUFFIXES: .scaf
.SUFFIXES: .scafo
.scaf.scafo:
../compiler/scafc $*.scaf
all: $(OBJ)
clean:
rm -f *.scafo
rm -f *.s
rm -f *~
Update of /cvsroot/pure-data/externals/pdp/scaf
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/scaf
Added Files:
COPYING Makefile Makefile.config Makefile.config.in README
README.scaf TODO configure configure.ac
Log Message:
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: configure ---
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
# Copyright (C) 2003 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
# Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
[...4085 lines suppressed...]
# config.status does its own redirection, appending to config.log.
# Unfortunately, on DOS this fails, as config.log is still kept open
# by configure, so config.status won't be able to write to it; its
# output is simply discarded. So we exec the FD to /dev/null,
# effectively closing config.log, so it can be properly (re)opened and
# appended to by config.status. When coming back to configure, we
# need to make the FD available again.
if test "$no_create" != yes; then
ac_cs_success=:
ac_config_status_args=
test "$silent" = yes &&
ac_config_status_args="$ac_config_status_args --quiet"
exec 5>/dev/null
$SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
$ac_cs_success || { (exit 1); exit 1; }
fi
--- NEW FILE: Makefile ---
include Makefile.config
all: pdp_scaf.pd_linux
pdp_scaf_all:
make -C include
make -C compiler
make -C rules
make -C pdp
clean:
rm -f *~
rm -f pdp_scaf.pd_linux
make -C include clean
make -C compiler clean
make -C rules clean
make -C pdp clean
mrproper: clean
rm -rf configure
rm -rf config.status
rm -rf config.log
rm -rf autom4te.cache
#this needs to stay in
#rm -rf Makefile.config
pdp_scaf.pd_linux: pdp_scaf_all
rm -f pdp_scaf.pd_linux
gcc -export_dynamic -shared -o pdp_scaf.pd_linux pdp/*.o $(PDP_CA_LIBS)
install: all
install -d $(prefix)/lib/scaf
install -m 755 compiler/scafc $(prefix)/bin || echo failed
install -m 755 compiler/scafc.pl $(prefix)/lib/scaf || echo failed
install -m 644 compiler/kernel.scaf $(prefix)/lib/scaf || echo failed
install -m 644 compiler/scafmacro.s $(prefix)/lib/scaf || echo failed
install -m 644 compiler/optim.rules $(prefix)/lib/scaf || echo failed
install -m 755 rules/carules.scafo $(prefix)/lib/scaf/default.scafo || echo failed
#Check if pd is installed in $(prefix)/lib/pd.
#If this fails the pdp_scaf lib and the docs won't be installed.
test -d $(prefix)/lib/pd
install -m 755 pdp_scaf.pd_linux $(prefix)/lib/pd/externs
install -m 644 doc/*.pd $(prefix)/lib/pd/doc/5.reference
--- NEW FILE: README.scaf ---
SCAF - simple cellular automaton forth
scaf is a virtual machine / forth environment for binary arithmic
tailored to 2D 1 cell neighbourhood cellular automata.
scaf is a compiled language. programs run inside a "feeder"
(sort of operating system if you want)
the feeder is responsable for loading/storing CA cells
from/to memory. data in memory is organized as a scanline
encoded toroidial bitplane (lsb = left). to simplify the feeder
and the stack machine, the top left corner of the rectangular grid
of pixels will shift down every processing step. this enables
to keep a cell neighbourhood in a couple of registers.
the stack machine has the following architecture:
CA stack: (%esi), TOS: %mm0 (32x2 cells. lsb = top left)
CA horizon: (%edi) (64x4 cells. (%edi) = top row. lsb = left)
scratch register: %mm1, %mm2
bitmask register: %mm3 = 0xffffffffffffffff
4 bit counter: %mm4-%mm7
the stack size / organization is not known to the stack machine.
it can be thought of as operating on a 3x3 cell neightbourhood.
the only purpose of the forth program is to determine the CA local update rule.
the machine is supposed to be very minimal. no looping control.
no adressing modes. no conditional code. so recursion is not allowed
(no way to stop it) there are 9 words to load the cell neigbourhood
on the stack. the rest is just logic and stack manips.
the counter can be used for counting neighbourhood cells, like in the
game of life. the zero test and sign bit can be used for comparisons.
there are kernel words for loading constants into the counter register,
and for communication between stack and register.
the horizon is limited to 3x3, however it can be easily extended to
32x3. extending it further than that would require a redesign of the
forth + feeder.
HOW TO CREATE NEW CA RULES
edit scaf/modules/carules.scaf or create your own source lib and add
the name to the scaf/modules/Makefile. type make in scaf/modules
to compile. if you get error messages from the assembler saying things
like
Error: no such instruction: `xxx'
or
Error: invalid character '_' in mnemonic
this means there are undefined words in your source file. since not
all characters are allowed in an asm file, the offending characters are
converted to _SOMETHINGELSE_
if you are stuck somewhere, just look at the output of scaf.pl on
your .scaf file to determine where the problem is.
words that can be accessed from inside pdp_ca have to start with the
prefix rule_ and have to leave a single item on the data stack (the return
value) other rules can have all the stack effect you want, but for safety
reasons they can't be accessed from within pdp_ca.
FORTH SYSTEM CODE
the forth system is made up of the following files:
kernel.scaf: a collection of forth kernel words
scafmacro.s: a set of asm macro definitions used in kernel.scaf
optim.rules: some substitution rules to eliminate redundant
stack manipulations
scaf.pl: the compiler
scaf.pl is run like this:
scaf.pl -Isystemdir source.scaf
if the -I switch is left out, the current directory is searched
for the system files. the compiler produces an assembler source
that includes scafmacro.s on standard output.
the code it produces is relatively fast. it only uses and/or/xor
and shift mmx instructions. it's not optimal use of silicon but
it's pretty fast given what's possible. the feeder routine could
be improved though.
porting to another platform would require a rewrite of scafmacro.s
the rest can be reused. if the target machine has 64 bit registers
(or if you can emulate this one using more registers) porting is
relatively easy. for larger registers a small change needs to
be made to the feeder routine in pdp_ca.c
--- NEW FILE: Makefile.config ---
# build flags
# define the include paths here if configure can't find them
# PDP_CFLAGS=-I/somehere/pdp/include
# PD_CFLAGS=-I/somewhere/pd/src
prefix=/usr/local
PDP_CA_INCLUDE = -I/home/tom/pd/packet/include -I/home/tom/pd/packet/scaf/include
PDP_CA_LIBS = -ldl -lm
DEFAULT_RULES_LIB = /usr/local/lib/scaf/default.scafo
PDP_CA_AFLAGS =
#--gstabs
PDP_CA_CFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \
-Wall -W -Wstrict-prototypes -Werror \
-Wno-unused -Wno-parentheses -Wno-switch -g $(PDP_CFLAGS) $(PD_CFLAGS) \
-DPDP_CA_RULES_LIB=\"$(DEFAULT_RULES_LIB)\"
# -Wshadow
# compiler and assembler
#CC = gcc-3.2
#CC = gcc
#AS = as
# build rules
.c.o:
$(CC) $(PDP_CA_CFLAGS) $(PDP_CA_INCLUDE) $(PDP_CA_DEFS) -o $*.o -c $*.c
.s.o:
$(AS) -o $*.o $*.s $(PDP_CA_AFLAGS)
--- NEW FILE: configure.ac ---
AC_INIT(pdp/pdp_ca_system.c)
AC_PROG_CC
AC_HEADER_STDC
dnl default install prefix is /usr/local
if test $prefix == "NONE";
then
prefix=/usr/local
fi
AC_PATH_PROG(PDP_CONFIG,pdp-config,"no", $PATH)
AC_CHECK_LIB(m,sin)
AC_CHECK_LIB(dl,dlopen,, echo libdl not found. sorry... || exit 1)
TOPSRC=`pwd`
PARENT=`dirname $TOPSRC`
dnl if pdp-config is found use it to get the cflags
if ! test $PDP_CONFIG == "no"
then
PDP_CPPFLAGS=`$PDP_CONFIG --cflags`
dnl if not, check in the parent dir (in case we are distributed with the pdp package)
elif test -f $PARENT/include/pdp.h
then
PDP_CPPFLAGS="-I$PARENT/include"
fi
CPPFLAGS="$CPPFLAGS $PDP_CPPFLAGS"
AC_CHECK_HEADER(m_pd.h,,PD_OK=no)
AC_CHECK_HEADER(pdp.h,,PDP_OK=no)
if test PD_OK == "no";
then
echo "WARNING: m_pd.h not found. Is PD installed?
echo "WARNING: You can ignore this warning if you have set the PD_CFLAGS manually in Makefile.config.in
fi
if test PDP_OK == "no";
then
echo "WARNING: pdp.h not found. Is PDP installed?
echo "WARNING: You can ignore this warning if you have set the PDP_CFLAGS manually in Makefile.config.in
fi
CPPFLAGS="$CPPFLAGS $PDFLAGS $PDPFLAGS -I$TOPSRC/include"
DEFAULT_RULES_LIB=$prefix/lib/scaf/default.scafo;
AC_SUBST(DEFAULT_RULES_LIB)
AC_CONFIG_FILES(Makefile.config)
AC_OUTPUT
--- NEW FILE: Makefile.config.in ---
# build flags
# define the include paths here if configure can't find them
# PDP_CFLAGS=-I/somehere/pdp/include
# PD_CFLAGS=-I/somewhere/pd/src
prefix=@prefix@
PDP_CA_INCLUDE = @CPPFLAGS@
PDP_CA_LIBS = @LIBS@
DEFAULT_RULES_LIB = @DEFAULT_RULES_LIB@
PDP_CA_AFLAGS =
#--gstabs
PDP_CA_CFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \
-Wall -W -Wstrict-prototypes -Werror \
-Wno-unused -Wno-parentheses -Wno-switch -g $(PDP_CFLAGS) $(PD_CFLAGS) \
-DPDP_CA_RULES_LIB=\"$(DEFAULT_RULES_LIB)\"
# -Wshadow
# compiler and assembler
#CC = gcc-3.2
#CC = gcc
#AS = as
# build rules
.c.o:
$(CC) $(PDP_CA_CFLAGS) $(PDP_CA_INCLUDE) $(PDP_CA_DEFS) -o $*.o -c $*.c
.s.o:
$(AS) -o $*.o $*.s $(PDP_CA_AFLAGS)
--- NEW FILE: COPYING ---
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) 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
this service 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 make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. 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.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR PDP.LICENSE, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
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
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE 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.
END OF TERMS AND CONDITIONS
Appendix: 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
convey 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) 19yy <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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision 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, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This 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 Library General
Public License instead of this License.
--- NEW FILE: README ---
PDP_SCAF for pdp v0.7
Cellular Automata modules for PDP
Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The GNU Public Licence can be found in the file COPYING
------------------------------------------------------------------
This is a pdp extension lib that contains modules for cellular
automata built on a (very) minimal forth-like virtual system
(scaf - simple cellular automaton forth) to define update rules. a
compiler is included to produce scafo object code that can be
dynamically loaded into the pdp_ca module. so it is possible to
add/change rules without restarting pd (note however you need to close
all lib files before the dynamic loader reloads the lib). see
scaf/README for details.
pdp_ca2image and pdp_image2ca are included for conversion between
CA packets and image packets. (pdp_ca2image produces greyscale
images)
Have a look at the patches in test/ for some crude docs. The file
README.scaf contains some more info on the internals.
Requirements:
* pd
* pdp
* linux
* perl for the forth compiler
* an intel/amd processor that supports MMX
Building:
./configure
make
make install
If you don't have both libraries in the same dir and want to keep
it that way, hardcode the paths in Makefile.config.in and run
configure. You need to do "make install" to install the scaf compiler
"scafc" and the default ruleset. This is to be able to load plain
(text) rule files and have the default rules loaded when you create
a pdp_ca object.
Using:
add "-lib <SCAF_DIR>/pdp_scaf" to the pd command line after the
"-lib <PDP_DIR>/pdp" part.
launch pd with the options -lib $PDP_DIR/pdp -path $PDP_DIR/abstractions
Directory structure:
include/ header files
pdp/ pdp external code
compiler/ forth system code
test/ some test patches (cryptic doc)
rules/ ca rule libraries
Please let me know if you discover a bug or think something doesn't work
right. Code, documentation or example patches are more than welcome of
course.
Have Fun,
Tom
last modified: 2003/01/12
--- NEW FILE: TODO ---
* add decimating to pdp_ca2image
* clean up library
* add translation option to pdp_ca (modify so horizontal shifts by 1 are possible)
Update of /cvsroot/pure-data/externals/pdp/scaf/compiler
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/scaf/compiler
Added Files:
Makefile kernel.scaf optim.rules scafc scafc.pl scafmacro.s
Log Message:
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: scafmacro.s ---
# Pure Data Packet - scaf assembler macros.
# Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# this file contains pure asm macros. it is to be included before assembly
# after scaforth.pl has processed the .scaf file
# *************************** JMP CALL RET **************************************
# j c r
.macro j address
jmp \address
.endm
.macro c address
call \address
.endm
.macro r
ret
.endm
# *************************** CA CELL ACCESS MACROS *****************************
# dropldTL - dropldBR
# shift / load rectangle macros:
# shift rectangle horizontal
# result is in reg1
.macro shift reg1 reg2 count
psllq $(16-\count), \reg1
psrlq $(16+\count), \reg2
psrlq $32, \reg1
psllq $32, \reg2
por \reg2, \reg1
.endm
.macro ldtop reg1 reg2
movq (%edi), \reg1
movq 8(%edi), \reg2
.endm
.macro ldcenter reg1 reg2
movq 8(%edi), \reg1
movq 16(%edi), \reg2
.endm
.macro ldbottom reg1 reg2
movq 16(%edi), \reg1
movq 24(%edi), \reg2
.endm
# dropld from top row
# dropld the top left square
.macro dropldTL
ldtop %mm0, %mm1
shift %mm0, %mm1, -1
.endm
# dropld the top mid square
.macro dropldTM
ldtop %mm0, %mm1
shift %mm0, %mm1, 0
.endm
# dropld the top right square
.macro dropldTR
ldtop %mm0, %mm1
shift %mm0, %mm1, 1
.endm
# dropld from center row
# dropld the mid left square
.macro dropldML
ldcenter %mm0, %mm1
shift %mm0, %mm1, -1
.endm
# dropld the mid mid square
.macro dropldMM
ldcenter %mm0, %mm1
shift %mm0, %mm1, 0
.endm
# dropld the mid right square
.macro dropldMR
ldcenter %mm0, %mm1
shift %mm0, %mm1, 1
.endm
# dropld from bottom row
# dropld the bottom left square
.macro dropldBL
ldbottom %mm0, %mm1
shift %mm0, %mm1, -1
.endm
# dropld the bottom mid square
.macro dropldBM
ldbottom %mm0, %mm1
shift %mm0, %mm1, 0
.endm
# dropld the bottom right square
.macro dropldBR
ldbottom %mm0, %mm1
shift %mm0, %mm1, 1
.endm
# *************************** CA STACK MANIP MACROS *****************************
# these are the only asm macros that have a stack effect other than
# just replacing the TOS
#
# dup drop dropdup swap nip dropover
.macro dup
lea -8(%esi), %esi
movq %mm0, (%esi)
.endm
.macro drop
movq (%esi), %mm0
lea 8(%esi), %esi
.endm
.macro dropdup
movq (%esi), %mm0
.endm
.macro nipdup
movq %mm0, (%esi)
.endm
.macro swap
movq (%esi), %mm1
movq %mm0, (%esi)
movq %mm1, %mm0
.endm
.macro nip
lea 8(%esi), %esi
.endm
.macro dropover
movq 8(%esi), %mm0
.endm
# *************************** CA BOOLEAN LOGIC MACROS *****************************
# overxor overand overor not
.macro overxor
pxor (%esi), %mm0
.endm
.macro overand
pand (%esi), %mm0
.endm
.macro overor
por (%esi), %mm0
.endm
.macro not
pxor %mm3, %mm0
.endm
# *************************** CONSTANTS *****************************
# dropzero dropone
.macro dropzero
pxor %mm0, %mm0
.endm
.macro dropone
pcmpeqw %mm0, %mm0
.endm
# *************************** 4 BIT REG ACCESS ******************************
# dupsta0 - dupsta4 droplda0 - droplda4
# store bit in accumulator
# bit store
.macro dupsta0
movq %mm0, %mm4
.endm
.macro dupsta1
movq %mm0, %mm5
.endm
.macro dupsta2
movq %mm0, %mm6
.endm
.macro dupsta3
movq %mm0, %mm7
.endm
# load bit from accumulator
.macro droplda0
movq %mm4, %mm0
.endm
.macro droplda1
movq %mm5, %mm0
.endm
.macro droplda2
movq %mm6, %mm0
.endm
.macro droplda3
movq %mm7, %mm0
.endm
# *************************** LOAD 4 BIT CONSTANT IN REG ******************************
# a0000 - a1111
.macro ldbit0 value
.ifeq \value
movq %mm1, %mm4
.else
movq %mm3, %mm4
.endif
.endm
.macro ldbit1 value
.ifeq \value
movq %mm1, %mm5
.else
movq %mm3, %mm5
.endif
.endm
.macro ldbit2 value
.ifeq \value
movq %mm1, %mm6
.else
movq %mm3, %mm6
.endif
.endm
.macro ldbit3 value
.ifeq \value
movq %mm1, %mm7
.else
movq %mm3, %mm7
.endif
.endm
.macro ldbin b3 b2 b1 b0
pxor %mm1, %mm1
ldbit0 \b0
ldbit1 \b1
ldbit2 \b2
ldbit3 \b3
.endm
.macro a0000
ldbin 0 0 0 0
.endm
.macro a0001
ldbin 0 0 0 1
.endm
.macro a0010
ldbin 0 0 1 0
.endm
.macro a0011
ldbin 0 0 1 1
.endm
.macro a0100
ldbin 0 1 0 0
.endm
.macro a0101
ldbin 0 1 0 1
.endm
.macro a0110
ldbin 0 1 1 0
.endm
.macro a0111
ldbin 0 1 1 1
.endm
.macro a1000
ldbin 1 0 0 0
.endm
.macro a1001
ldbin 1 0 0 1
.endm
.macro a1010
ldbin 1 0 1 0
.endm
.macro a1011
ldbin 1 0 1 1
.endm
.macro a1100
ldbin 1 1 0 0
.endm
.macro a1101
ldbin 1 1 0 1
.endm
.macro a1110
ldbin 1 1 1 0
.endm
.macro a1111
ldbin 1 1 1 1
.endm
# *************************** 4 BIT COUNTER ******************************
# adds TOS to bit of counter and returns carry in TOS
#
# adb0 - adb3
.macro adb0
movq %mm4, %mm2
pxor %mm0, %mm4
pand %mm2, %mm0
.endm
.macro adb1
movq %mm5, %mm2
pxor %mm0, %mm5
pand %mm2, %mm0
.endm
.macro adb2
movq %mm6, %mm2
pxor %mm0, %mm6
pand %mm2, %mm0
.endm
.macro adb3
movq %mm7, %mm2
pxor %mm0, %mm7
pand %mm2, %mm0
.endm
# *************************** ACCUMULATOR TESTS ***************************
# dropisnonzero4 - dropisnonzero1
.macro dropisnonzero4
movq %mm4, %mm0
por %mm5, %mm0
por %mm6, %mm0
por %mm7, %mm0
.endm
.macro dropisnonzero3
movq %mm4, %mm0
por %mm5, %mm0
por %mm6, %mm0
.endm
.macro dropisnonzero2
movq %mm4, %mm0
por %mm5, %mm0
.endm
.macro dropisnonzero1
movq %mm4, %mm0
.endm
# *************************** REGISTER SHIFT OPERATIONS **********************
# shift and leave shifted out byte on stack
# rotate trough top of stack
.macro dropshiftright
movq %mm4, %mm0
movq %mm5, %mm4
movq %mm6, %mm5
movq %mm7, %mm6
pxor %mm7, %mm7
.endm
.macro dropshiftleft
movq %mm7, %mm0
movq %mm6, %mm7
movq %mm5, %mm6
movq %mm4, %mm5
pxor %mm4, %mm4
.endm
.macro dropshiftrighta
movq %mm4, %mm0
movq %mm5, %mm4
movq %mm6, %mm5
movq %mm7, %mm6
.endm
.macro rotateright
movq %mm4, %mm1
movq %mm5, %mm4
movq %mm6, %mm5
movq %mm7, %mm6
movq %mm1, %mm7
.endm
.macro rotateleft
movq %mm7, %mm1
movq %mm6, %mm7
movq %mm5, %mm6
movq %mm4, %mm5
movq %mm1, %mm4
.endm
.macro rotaterightstack
movq %mm0, %mm1
movq %mm4, %mm0
movq %mm5, %mm4
movq %mm6, %mm5
movq %mm7, %mm6
movq %mm1, %mm7
.endm
.macro rotateleftstack
movq %mm0, %mm1
movq %mm7, %mm0
movq %mm6, %mm7
movq %mm5, %mm6
movq %mm4, %mm5
movq %mm1, %mm4
.endm
# *************************** OTHER REGISTER OPERATIONS **********************
# anot : complement reg (can be used to implement subtraction)
.macro anot
pxor %mm3, %mm4
pxor %mm3, %mm5
pxor %mm3, %mm6
pxor %mm3, %mm7
.endm
--- NEW FILE: kernel.scaf ---
( Pure Data Packet - scaforth kernel. )
( Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org> )
( )
( 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 2 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, write to the Free Software )
( Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. )
( this file contains the inline words in the scaforth kernel. )
( when a file is compiled to asm, it will consist of word )
( definition asm routines, macros and jmp call ret instructions. )
( )
( all words in this file are defined in terms of asm macros )
( defined in scafmacros.s )
( stack manip words )
: over dup dropover ;
( neighbourhood cell fetch words )
: @-+ dup dropldTL ;
: @0+ dup dropldTM ;
: @++ dup dropldTR ;
: @-0 dup dropldML ;
: @00 dup dropldMM ;
: @+0 dup dropldMR ;
: @-- dup dropldBL ;
: @0- dup dropldBM ;
: @+- dup dropldBR ;
( boolean logic )
: or overor nip ;
: xor overxor nip ;
: and overand nip ;
( binary constant loading )
: 1 dup dropone ;
: 0 dup dropzero ;
( 4,3,2,1 bit add stack to register, leave carry on stack )
: ++++ adb0 adb1 adb2 adb3 ;
: +++ adb0 adb1 adb2 ;
: ++ adb0 adb1 ;
: + adb0 ;
( 4,3,2 bit shifted 1 add )
: ++++<<1 adb1 adb2 adb3 ;
: +++<<1 adb1 adb2 ;
: ++<<1 adb1 ;
( 4,3 bit shifted 2 add )
: ++++<<2 adb2 adb3 ;
: +++<<2 adb2 ;
( 4 bit shifted 3 add )
: ++++<<3 adb3 ;
( 4 bit accumulator access )
: !a0 dupsta0 drop ;
: !a1 dupsta1 drop ;
: !a2 dupsta2 drop ;
: !a3 dupsta3 drop ;
: @a0 dup droplda0 ;
: @a1 dup droplda1 ;
: @a2 dup droplda2 ;
: @a3 dup droplda3 ;
( 4,3,2,1 bit accumulator zero tests )
: ?anz dup dropisnonzero4 ;
: ?anz4 dup dropisnonzero4 ;
: ?anz3 dup dropisnonzero3 ;
: ?anz2 dup dropisnonzero2 ;
: ?anz1 dup dropisnonzero1 ;
( load constants into accumulator )
: a0 a0000 ;
: a-0 a0000 ;
: a+0 a0000 ;
: a+1 a0001 ;
: a+2 a0010 ;
: a+3 a0011 ;
: a+4 a0100 ;
: a+5 a0101 ;
: a+6 a0110 ;
: a+7 a0111 ;
: a+8 a1000 ;
: a+9 a1001 ;
: a+10 a1010 ;
: a+11 a1011 ;
: a+12 a1100 ;
: a+13 a1101 ;
: a+14 a1110 ;
: a+15 a1111 ;
: a-8 a1000 ;
: a-7 a1001 ;
: a-6 a1010 ;
: a-5 a1011 ;
: a-4 a1100 ;
: a-3 a1101 ;
: a-2 a1110 ;
: a-1 a1111 ;
--- NEW FILE: scafc ---
#!/bin/sh
#scaf->scafo compiler
if test "xx$1" == "xx"
then
echo
echo "scaf rules compiler"
echo "usage:"
echo " scafc source [dest]"
echo
exit 0
fi
if test "xx$2" == "xx"
then
DEST=$1o
else
DEST=$2
fi
if ! test -f $1
then
echo "source module $1 not found."
exit 1
fi
SCAFDIR=`dirname $0`
if ! test -f $SCAFDIR/scafc.pl;
then
SCAFDIR=`dirname $SCAFDIR`
SCAFDIR="$SCAFDIR/lib/scaf"
if ! test -f $SCAFDIR/scafc.pl
then
echo "scaf library not found in $SCAFDIR"
exit 1
fi
fi
TMP_S=`tempfile -s .s`
$SCAFDIR/scafc.pl -I$SCAFDIR $1 > $TMP_S \
&& gcc -export_dynamic -shared -o $DEST $TMP_S \
&& strip --strip-unneeded $DEST \
&& rm $TMP_S \
|| exit 1
--- NEW FILE: Makefile ---
all:
clean:
rm -f *~
rm -f *.o
--- NEW FILE: scafc.pl ---
#!/usr/bin/perl
# Pure Data Packet - scafc: scaf compiler.
# Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# set this if you want to enable/disable optimizing
$optimize = 1;
# this parses a single scaf line
# it is not very intelligent. only looks for 1 def on a line
# todo: change later so it can read multiple lines
sub remove_illegal_characters {
my $line = shift;
$$line =~ s/\+/_PLUS_/g;
$$line =~ s/-/_MINUS_/g;
$$line =~ s/\@/_AT_/g;
$$line =~ s/:/_COLON_/g;
$$line =~ s/\?/_QMARK_/g;
$$line =~ s/<</_SHIFT_/g;
$$line =~ s/</_ST_/g;
$$line =~ s/>/_GT_/g;
$$line =~ s/=/_EQ_/g;
$$line =~ s/\(/_OPEN_/g;
$$line =~ s/\)/_CLOSE_/g;
}
sub parse_scaf_line {
my $word, $def, $sub;
shift;
# this transforms the source into a parsed assembly like form
# a word label: "<word>:<ret>"
# a word definition line "<tab><word><ret>"
# last def = <ret><ret>
# dont process if line doesn't have a def
# first remove comments
s/\(\s+(\S+\s+)*?\)//g;
if (m/:\s+/){
# separate word and definition
m/:\s+(\S+)\s+(.*)/;
$word = $1;
$def = $2;
# remove illegal characters;
remove_illegal_characters \$word;
remove_illegal_characters \$def;
# format definition in asm style
$def =~ s/(\S+)(\s*)/\t$1\n/g;
# replace ; by r
$def =~ s/\s+;\s*/\n\tr\n/;
# put word: def into one string
$sub = "$word:\n$def\n";
# debug
#$sub =~ s/\t/<tab>/g;
#$sub =~ s/\n/<ret>\n/g;
#print "$sub";
return $sub;
}
};
# load and parse scaf source file
sub load_source {
my $filename = shift;
open(SOURCE, $filename) or die "Can't locate source module $filename\n";
my @parsedsource;
while (<SOURCE>){
my $sub = parse_scaf_line $_;
if ($sub) {
push @parsedsource, ($sub);
}
}
close(SOURCE);
return @parsedsource;
}
# this routine parses the optimization rules
sub load_optim {
my $filename = shift;
open(OPTIM, $filename) or die "Can't locate optimization rule file $filename\n";
my @parsedoptim;
while (<OPTIM>){
unless (m/\A\#/){
if (m/\"\s*(.*?)\s*\".*?\"\s*(.*?)\s*\"/)
{
my $source = $1;
my $dest = $2;
$source =~ s/\s+/\n\t/;
$dest =~ s/\s+/\n\t/;
$source = "\t$source\n";
$dest = "\t$dest\n";
remove_illegal_characters \$source;
remove_illegal_characters \$dest;
push @parsedoptim, ("$source:$dest");
}
}
}
close(OPTIM);
return @parsedoptim;
}
# inline one parsed source's definitions into another parsed source's
sub inline_defs {
my $dest = shift;
my $source = shift;
#print @$dest;
#print @$source;
# loop over file with inline defs
foreach (@$source) {
#print "<SUB>$_</SUB>\n";
m/(\S+):\n(.*)\tr\n/s;
my $def = "\t$1\n";
my $body = $2;
#print "<DEF>$def</DEF>\n";
#print "<BODY>$body</BODY>\n";
foreach (@$dest) {
s/$def/$body/g;
}
}
}
# this changes <WORD> to c <WORD> or j <WORD> all defined words
# the undefined words are supposed to be asm macros
sub call_defs {
my $dest = shift;
foreach (@$dest){
m/(\S+):\n/s;
my $word = $1;
foreach (@$dest){
s/\t$word\n\tr\n/\tj $word\n/sg;
s/\t$word\n/\tc $word\n/sg;
}
}
}
# substitue word sequences in dest using optim table
sub subst_optim {
my $dest = shift;
my $optim = shift;
foreach (@$optim){
m/(.*?):(.*)/s;
my $key = $1;
my $subst = $2;
foreach (@$dest){
s/$key/$subst/sg;
}
}
}
# add directives to produce global symbols
# global symbols need to start with carule_
sub global_syms {
my $source = shift;
foreach (@$source){
s/rule_(\S+):\n/.globl\trule_$1\n.type\trule_$1,\@function\nrule_$1:\n/sg;
}
}
# create an array with names for bookkeeping
sub name_array {
my @namearray;
my $source = shift;
push @namearray, (".globl rulenames\nrulenames:\n");
foreach (@$source){
if (m/rule_(\S+):/s){
push @namearray, (".asciz\t\"$1\"\n");
}
}
push @namearray, (".byte\t0\n");
return @namearray;
}
# main program body
$dir=".";
$source = "-";
# parse command line
foreach (@ARGV){
if (m/-I(.*)/) {
$dir = $1;
}
else {
$source = $_;
}
}
$kernel = "$dir/kernel.scaf";
$macro = "$dir/scafmacro.s";
$rules = "$dir/optim.rules";
# load files
@psource = load_source $source;
@pkernel = load_source $kernel;
@poptim = load_optim $rules;
# substitute kernel defs in source
if ($optimize) {subst_optim \@psource, \@poptim;}
inline_defs \@psource, \@pkernel;
if ($optimize) {subst_optim \@psource, \@poptim;}
call_defs \@psource;
global_syms \@psource;
@pnames = name_array \@psource;
# print out asm file
print ".include \"$macro\"\n\n";
print @psource;
print @pnames;
--- NEW FILE: optim.rules ---
# Pure Data Packet - scaf optimization rules.
# Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# this file contains scaf source optimization rules for scaf compiler
# applied after kernel word inlining and before compilation to asm
# one rule that's not in here, and is the responsability for the
# final compilation step: "word ;" is "jmp word" instead of "call word ret"
# TODO: think about order!
# no discrimination between pre inline and post inline optimization ops yet
# pre inline optimizations
"over xor" -> "overxor"
"over and" -> "overand"
"over or" -> "overor"
"drop 1" -> "dropone"
"drop 0" -> "dropzero"
"over add" -> "overadd"
"over addc" -> "overaddc"
"dup !a0" -> "dupsta0"
"dup !a1" -> "dupsta1"
"dup !a2" -> "dupsta2"
"dup !a3" -> "dupsta3"
"drop @a0" -> "droplda0"
"drop @a1" -> "droplda1"
"drop @a2" -> "droplda2"
"drop @a3" -> "droplda3"
"drop ?anz" -> "dropisnonzero4"
"drop ?anz4" -> "dropisnonzero4"
"drop ?anz3" -> "dropisnonzero3"
"drop ?anz2" -> "dropisnonzero2"
"drop ?anz1" -> "dropisnonzero1"
"drop @-+" -> "dropldTL"
"drop @0+" -> "dropldTM"
"drop @++" -> "dropldTR"
"drop @-0" -> "dropldML"
"drop @00" -> "dropldMM"
"drop @+0" -> "dropldMR"
"drop @--" -> "dropldBL"
"drop @0-" -> "dropldBM"
"drop @+-" -> "dropldBR"
# post inline optimizations
"dup drop" -> ""
"swap drop" -> "nip"
"dup swap" -> "dup"
"drop dup" -> "dropdup"
"drop over" -> "dropover"
"nip dup" -> "nipdup"
Update of /cvsroot/pure-data/externals/pdp/scaf/pdp
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/scaf/pdp
Added Files:
Makefile pdp_ca.c pdp_ca_system.c scaf_feeder.s
Log Message:
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: pdp_ca.c ---
/*
* Pure Data Packet module for cellular automata
* Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "pdp_ca.h"
#include "pdp_internals.h"
#include <dlfcn.h>
#include <stdio.h>
t_class *pdp_ca_class; // a cellular automaton processor: single input - single output
//t_class *pdp_ca2_class; // double input - single output
t_class *pdp_ca2image_class; // converter from ca -> grey/yv12
t_class *pdp_image2ca_class; // converter from grey/yv12 -> ca
// *********************** CA CLASS STUFF *********************
// this is defined in the makefile
// #define PDP_CA_RULES_LIB "/path/default.scafo"
#define PDP_CA_STACKSIZE 256
#define PDP_CA_MODE_1D 1
#define PDP_CA_MODE_2D 2
typedef struct pdp_ca_data_struct
{
unsigned int env[2*4];
unsigned int reg[2*4];
unsigned int stack[2*PDP_CA_STACKSIZE];
short int random_seed[4];
} t_pdp_ca_data;
typedef struct pdp_ca_struct
{
t_object x_obj;
t_float x_f;
t_outlet *x_outlet0;
int x_queue_id;
/* double buffering data packets */
int x_packet0;
int x_packet1;
/* some data on the ca_routine */
void (*x_ca_routine)(void);
void *x_ca_libhandle;
char *x_ca_rulenames;
int x_ca_nbrules;
char ** x_ca_rulename;
t_symbol *x_lastrule;
/* nb of iterations */
int x_iterations;
/* shift ca on output */
int x_horshift;
int x_vershift;
/* operation mode */
int x_mode;
int x_fullscreen1d;
/* aligned vector data */
t_pdp_ca_data *x_data;
/* output packet type */
t_symbol *x_packet_type;
} t_pdp_ca;
/* 1D: process from packet0 -> packet0 */
static void pdp_ca_process_ca_1D(t_pdp_ca *x)
{
t_pdp *header = pdp_packet_header(x->x_packet0);
unsigned int *data = (unsigned int *)pdp_packet_data (x->x_packet0);
int width = pdp_type_ca_info(header)->width;
int height = pdp_type_ca_info(header)->height;
int i;
unsigned int saved;
/* load TOS in middle of buffer to limit the effect of stack errors */
unsigned int *tos = &x->x_data->stack[2*(PDP_CA_STACKSIZE/2)];
unsigned int *env = &x->x_data->env[0];
unsigned int *reg = &x->x_data->reg[0];
void *ca_routine = x->x_ca_routine;
unsigned int rtos;
/* double word width: number of unsigned ints per row */
int dwwidth = width >> 5;
int currow = pdp_type_ca_info(header)->currow;
unsigned long long result = 0;
unsigned short temp;
unsigned short *usdata;
/* set destination row to 4th row from top (ca time horizon is 3 deep) */
int dwrow0 = (((currow + height - 3) % height) * width) >> 5;
int dwrow1 = (((currow + height - 2) % height) * width) >> 5;
int dwrow2 = (((currow + height - 1) % height) * width) >> 5;
int dwrow3 = (currow * width) >> 5;
/* exit if there isn't a valid routine */
if(!ca_routine) return;
/* compute new row */
for(i=0; i < (dwwidth-1) ; i+=1){
env[0] = data[dwrow0 + i];
env[1] = data[dwrow0 + i + 1];
env[2] = data[dwrow1 + i];
env[3] = data[dwrow1 + i + 1];
env[4] = data[dwrow2 + i];
env[5] = data[dwrow2 + i + 1];
result = scaf_feeder(tos, reg, ca_routine, env);
data[dwrow3 + i] = result & 0xffffffff;
}
// i == dwwidth-1
/* compute last column in row */
env[0] = data[dwrow0 + i];
env[1] = data[dwrow0];
env[2] = data[dwrow1 + i];
env[3] = data[dwrow1];
env[4] = data[dwrow2 + i];
env[5] = data[dwrow2];
result = scaf_feeder(tos, reg, ca_routine, env);
data[dwrow3 + i] = result & 0xffffffff;
/* undo the shift */
usdata = (unsigned short *)(&data[dwrow3]);
temp = usdata[(dwwidth*2)-1];
for (i = (dwwidth*2 - 1); i > 0; i--){
usdata[i] = usdata[i-1];
}
usdata[0] = temp;
/* check data stack pointer */
rtos = (unsigned int)tos;
if (env[0] != rtos){
if (env[0] > rtos) post("pdp_ca: ERROR: stack underflow detected in ca routine");
if (env[0] < rtos) post("pdp_ca: ERROR: ca routine returned more than one item");
x->x_ca_routine = 0;
post("pdp_ca: rule disabled");
}
/* save current row */
pdp_type_ca_info(header)->currow = (currow + 1) % height;
}
/* 2D: process from packet0 -> packet1 */
static void pdp_ca_process_ca_2D(t_pdp_ca *x)
{
t_pdp *header0 = pdp_packet_header(x->x_packet0);
t_pdp *header1 = pdp_packet_header(x->x_packet1);
unsigned int *data0 = (unsigned int *)pdp_packet_data (x->x_packet0);
unsigned int *data1 = (unsigned int *)pdp_packet_data (x->x_packet1);
int width = pdp_type_ca_info(header0)->width;
int height = pdp_type_ca_info(header0)->height;
int i,j;
/* load TOS in middle of buffer to limit the effect of stack errors */
unsigned int *tos = &x->x_data->stack[2*(PDP_CA_STACKSIZE/2)];
unsigned int *env = &x->x_data->env[0];
unsigned int *reg = &x->x_data->reg[0];
void *ca_routine = x->x_ca_routine;
unsigned int rtos;
int offset = pdp_type_ca_info(header0)->offset;
int xoffset = offset % width;
int yoffset = offset / width;
/* double word width: number of unsigned ints per row */
int dwwidth = width >> 5;
unsigned long long result = 0;
/* exit if there isn't a valid routine */
if(!ca_routine) return;
if(!header0) return;
if(!header1) return;
//post("pdp_ca: PRE offset: %d, xoffset: %d, yoffset: %d", offset, xoffset, yoffset);
/* calculate new offset: lines shift up, rows shift left by 16 cells */
xoffset = (xoffset + width - 16) % width;
yoffset = (yoffset + height - 1) % height;
offset = yoffset * width + xoffset;
//post("pdp_ca: PST offset: %d, xoffset: %d, yoffset: %d", offset, xoffset, yoffset);
pdp_type_ca_info(header1)->offset = offset;
for(j=0; j<dwwidth*(height - 2); j+=(dwwidth<<1)){
for(i=0; i < (dwwidth-1) ; i+=1){
env[0] = data0[i + j];
env[1] = data0[i + j + 1];
env[2] = data0[i + j + dwwidth];
env[3] = data0[i + j + dwwidth + 1];
env[4] = data0[i + j + (dwwidth<<1)];
env[5] = data0[i + j + (dwwidth<<1) + 1];
env[6] = data0[i + j + (dwwidth<<1) + dwwidth];
env[7] = data0[i + j + (dwwidth<<1) + dwwidth + 1];
result = scaf_feeder(tos, reg, ca_routine, env);
data1[i + j] = result & 0xffffffff;
data1[i + j + dwwidth] = result >> 32;
}
// i == dwwidth-1
env[0] = data0[i + j];
env[1] = data0[j];
env[2] = data0[i + j + dwwidth];
env[3] = data0[j + dwwidth];
env[4] = data0[i + j + (dwwidth<<1)];
env[5] = data0[j + (dwwidth<<1)];
env[6] = data0[i + j + (dwwidth<<1) + dwwidth];
env[7] = data0[j + (dwwidth<<1) + dwwidth];
result = scaf_feeder(tos, reg, ca_routine, env);
data1[i + j] = result & 0xffffffff;
data1[i + j + dwwidth] = result >> 32;
}
// j == dwwidth*(height - 2)
for(i=0; i < (dwwidth-1) ; i+=1){
env[0] = data0[i + j];
env[1] = data0[i + j + 1];
env[2] = data0[i + j + dwwidth];
env[3] = data0[i + j + dwwidth + 1];
env[4] = data0[i];
env[5] = data0[i + 1];
env[6] = data0[i + dwwidth];
env[7] = data0[i + dwwidth + 1];
result = scaf_feeder(tos, reg, ca_routine, env);
data1[i + j] = result & 0xffffffff;
data1[i + j + dwwidth] = result >> 32;
}
// j == dwwidth*(height - 2)
// i == dwwidth-1
env[0] = data0[i + j];
env[1] = data0[j];
env[2] = data0[i + j + dwwidth];
env[3] = data0[j + dwwidth];
env[4] = data0[i];
env[5] = data0[0];
env[6] = data0[i + dwwidth];
env[7] = data0[dwwidth];
result = scaf_feeder(tos, reg, ca_routine, env);
data1[i + j] = result & 0xffffffff;
data1[i + j + dwwidth] = result >> 32;
/* check data stack pointer */
rtos = (unsigned int)tos;
if (env[0] != rtos){
if (env[0] > rtos) post("pdp_ca: ERROR: stack underflow detected in ca routine");
if (env[0] < rtos) post("pdp_ca: ERROR: ca routine returned more than one item");
x->x_ca_routine = 0;
post("pdp_ca: rule disabled");
}
return;
}
static void pdp_ca_swappackets(t_pdp_ca *x)
{
/* swap packets */
int packet = x->x_packet1;
x->x_packet1 = x->x_packet0;
x->x_packet0 = packet;
}
/* tick advance CA one timestep */
static void pdp_ca_bang_thread(t_pdp_ca *x)
{
int encoding;
int packet;
int i;
int iterations = x->x_iterations;
/* invariant: the two packets are allways valid and compatible
so a bang is allways possible. this means that in the pdp an
invalid packet needs to be converted to a valid one */
if (-1 == x->x_packet0) pdp_post("warning: packet 0 invalid");
if (-1 == x->x_packet1) pdp_post("warning: packet 1 invalid");
if (PDP_CA_MODE_2D == x->x_mode){
for(i=0; i < iterations; i++){
/* process form packet0 -> packet1 */
pdp_ca_process_ca_2D(x);
/* swap */
pdp_ca_swappackets(x);
}
}
else if (PDP_CA_MODE_1D == x->x_mode){
if (x->x_fullscreen1d){
t_pdp *header0 = pdp_packet_header(x->x_packet0);
pdp_type_ca_info(header0)->currow = 0;
pdp_type_ca_info(header0)->offset = 0;
iterations = pdp_type_ca_info(header0)->height;
}
for(i=0; i < iterations; i++){
pdp_ca_process_ca_1D(x);
}
}
}
static void pdp_ca_sendpacket(t_pdp_ca *x)
{
/* adjust offset before sending */
t_pdp *header0 = pdp_packet_header(x->x_packet0);
int offset, width, height, xoffset, yoffset, horshift, vershift;
if (!header0) return;
offset = pdp_type_ca_info(header0)->offset;
width = pdp_type_ca_info(header0)->width;
height = pdp_type_ca_info(header0)->height;
xoffset = offset % width;
yoffset = offset / width;
horshift = x->x_horshift;
vershift = x->x_vershift;
horshift %= width;
if (horshift < 0) horshift += width;
vershift %= height;
if (vershift < 0) vershift += height;
xoffset = (xoffset + horshift) % width;
yoffset = (yoffset + vershift) % height;
offset = yoffset * width + xoffset;
pdp_type_ca_info(header0)->offset = offset;
/* output the packet */
outlet_pdp(x->x_outlet0, x->x_packet0);
}
static void pdp_ca_bang(t_pdp_ca *x)
{
/* we don't use input packets for testing dropping here
but check the queue_id to see if processing is
still going on */
if (-1 == x->x_queue_id){
pdp_queue_add(x, pdp_ca_bang_thread, pdp_ca_sendpacket, &x->x_queue_id);
}
else{
pdp_control_notify_drop(-1);
}
}
/* this method stores the packet into x->x_packet0 (the packet
to be processed) if it is valid. x->x_packet1 is not compatible
it is regenerated so that it is
in short, when this routine returns both packets are valid
and compatible.
*/
static void pdp_ca_copy_rw_if_valid(t_pdp_ca *x, int packet)
{
t_pdp *header = pdp_packet_header(packet);
t_pdp *header1 = pdp_packet_header(x->x_packet1);
int grabpacket;
int convertedpacket;
/* check if header is valid */
if (!header) return;
if (PDP_CA != header->type) return;
if (PDP_CA_STANDARD != pdp_type_ca_info(header)->encoding) return;
/* packet is a ca, register it */
pdp_packet_mark_unused(x->x_packet0);
x->x_packet0 = pdp_packet_copy_rw(packet);
/* make sure we have the right header */
header = pdp_packet_header(x->x_packet0);
/* make sure that the other packet is compatible */
if ((pdp_type_ca_info(header1)->width != pdp_type_ca_info(header)->width) ||
(pdp_type_ca_info(header1)->height != pdp_type_ca_info(header)->height)) {
/* if not, throw away and clone the new one */
pdp_packet_mark_unused(x->x_packet1);
x->x_packet1 = pdp_packet_clone_rw(x->x_packet0);
}
if (-1 == x->x_packet0) pdp_post("warning: packet 0 invalid");
if (-1 == x->x_packet1) pdp_post("warning: packet 1 invalid");
};
/* hot packet inlet */
static void pdp_ca_input_0(t_pdp_ca *x, t_symbol *s, t_floatarg f)
{
if (s == gensym("register_rw")){
pdp_ca_copy_rw_if_valid(x, (int)f);
}
else if (s == gensym("process")){
pdp_ca_bang(x);
}
}
/* cold packet inlet */
static void pdp_ca_input_1(t_pdp_ca *x, t_symbol *s, t_floatarg f)
{
if (s == gensym("register_rw"))
{
pdp_ca_copy_rw_if_valid(x, (int)f);
}
}
static void pdp_ca_rule_string(t_pdp_ca *x, char *c)
{
char tmp[256];
void (*ca_routine)(void);
/* check if we can find string */
sprintf(tmp, "rule_%s", c);
if (!(ca_routine = dlsym(x->x_ca_libhandle, tmp))){
post("pdp_ca: can't fine ca rule %s (symbol: %s)", c, tmp);
return;
}
/* ok, so store routine address */
else{
x->x_ca_routine = ca_routine;
x->x_lastrule = gensym(c);
}
}
static void pdp_ca_rule(t_pdp_ca *x, t_symbol *s)
{
/* make sure lib is loaded */
if (!x->x_ca_libhandle) return;
/* set rule by name */
pdp_ca_rule_string(x, s->s_name);
}
static void pdp_ca_rule_index(t_pdp_ca *x, t_float f)
{
int i = (int)f;
/* make sure lib is loaded */
if (!x->x_ca_libhandle) return;
/* check index */
if (i<0) return;
if (i>=x->x_ca_nbrules) return;
/* set rule by index */
pdp_ca_rule_string(x, x->x_ca_rulename[i]);
}
static void pdp_ca_close(t_pdp_ca *x)
{
if (x->x_ca_libhandle){
dlclose(x->x_ca_libhandle);
x->x_ca_libhandle = 0;
x->x_ca_routine = 0;
if (x->x_ca_rulename){
free (x->x_ca_rulename);
x->x_ca_rulename = 0;
}
}
}
static void pdp_ca_printrules(t_pdp_ca *x)
{
int i;
if (!(x->x_ca_libhandle)) return;
post("pdp_ca: found %d rules: ", x->x_ca_nbrules);
for(i=0;i<x->x_ca_nbrules; i++) post("%3d: %s ", i, x->x_ca_rulename[i]);
}
/* open code library */
static void pdp_ca_openlib(t_pdp_ca *x, t_symbol *s)
{
char *c;
int words;
/* close current lib, if one */
pdp_ca_close(x);
/* try to open new lib */
if (!(x->x_ca_libhandle = dlopen(s->s_name, RTLD_NOW))){
post("pdp_ca: can't open ca library %s\n%s", s->s_name, dlerror());
x->x_ca_libhandle = 0;
return;
}
/* scan for valid rules */
if (!(x->x_ca_rulenames = (char *)dlsym(x->x_ca_libhandle, "rulenames"))){
post("pdp_ca: ERROR: %s does not contain a name table. closing.", s->s_name);
pdp_ca_close(x);
return;
}
/* count rules */
words = 0;
for(c = (char *)x->x_ca_rulenames; *c;){
words++;
while(*c++);
}
x->x_ca_nbrules = words;
x->x_ca_rulename = (char **)malloc(sizeof(char *) * words);
/* build name array */
words = 0;
for(c = (char *)x->x_ca_rulenames; *c;){
x->x_ca_rulename[words] = c;
words++;
while(*c++);
}
/* ok, we're done */
post("pdp_ca: opened rule library %s", s->s_name ,x->x_ca_nbrules);
/* print rule names */
//pdp_ca_printrules(x);
/* set last selected rule */
pdp_ca_rule(x, x->x_lastrule);
}
/* compile source file and open resulting code library */
static void pdp_ca_opensrc(t_pdp_ca *x, t_symbol *s)
{
#define TMPSIZE 1024
char commandline[TMPSIZE];
char library[TMPSIZE];
int status;
/* setup compiler args */
snprintf(library, TMPSIZE, "%so", s->s_name);
snprintf(commandline, TMPSIZE, "scafc %s %s", s->s_name, library);
/* call compiler */
if (system(commandline))
{
post ("pdp_ca: error compiling %s", s->s_name);
}
else
{
post("pdp_ca: compiled %s", s->s_name);
pdp_ca_openlib(x, gensym(library));
}
}
/* open a source file or a library, depending on extension */
static void pdp_ca_open(t_pdp_ca *x, t_symbol *s)
{
char *name = s->s_name;
char *end = name;
while(*end) end++;
if (end == name){
post("pdp_ca: invalid file name");
return;
}
/* if the name ends with 'o' assume it is a library */
if (end[-1] == 'o'){
pdp_ca_openlib(x, s);
}
/* otherwize, assume it is a source file */
else{
pdp_ca_opensrc(x, s);
}
}
/* init the current packet with random noise */
static void pdp_ca_rand(t_pdp_ca *x){
t_pdp *header = pdp_packet_header(x->x_packet0);
short int *data = (short int *) pdp_packet_data(x->x_packet0);
int i;
int nbshortints = (pdp_type_ca_info(header)->width >> 4) * pdp_type_ca_info(header)->height;
for(i=0; i<nbshortints; i++)
data[i] = random();
}
static void pdp_ca_newca(t_pdp_ca *x, t_float width, t_float height)
{
/* delete old packets */
pdp_packet_mark_unused(x->x_packet0);
pdp_packet_mark_unused(x->x_packet1);
/* create new packets */
x->x_packet0 = pdp_packet_new_ca(PDP_CA, width, height);
x->x_packet1 = pdp_packet_clone_rw(x->x_packet0);
}
static void pdp_ca_iterations(t_pdp_ca *x, t_float f)
{
int i = (int)f;
if (i < 0) i = 0;
x->x_iterations = i;
}
static void pdp_ca_horshift16(t_pdp_ca *x, t_float f)
{
x->x_horshift = 16 * (int)f;
}
static void pdp_ca_vershift(t_pdp_ca *x, t_float f)
{
x->x_vershift = (int)f;
}
static void pdp_ca_set1d(t_pdp_ca *x)
{
x->x_mode = PDP_CA_MODE_1D;
}
static void pdp_ca_set2d(t_pdp_ca *x)
{
x->x_mode = PDP_CA_MODE_2D;
}
static void pdp_ca_fullscreen1d(t_pdp_ca *x, t_floatarg f)
{
if (f == 0.0f) x->x_fullscreen1d = 0;
if (f == 1.0f) x->x_fullscreen1d = 1;
}
static void pdp_ca_free(t_pdp_ca *x)
{
pdp_packet_mark_unused(x->x_packet0);
pdp_packet_mark_unused(x->x_packet1);
pdp_ca_close(x);
free(x->x_data);
}
void *pdp_ca_new(void)
{
t_pdp_ca *x = (t_pdp_ca *)pd_new(pdp_ca_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("pdp"), gensym("pdp1"));
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("iterations"));
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
x->x_packet0 = -1;
x->x_packet1 = -1;
x->x_queue_id = -1;
x->x_data = (t_pdp_ca_data *)malloc(sizeof(t_pdp_ca_data));
x->x_ca_routine = 0;
x->x_ca_libhandle = 0;
x->x_ca_rulename = 0;
x->x_horshift = 0;
x->x_vershift = 0;
pdp_ca_newca(x, 64, 64);
pdp_ca_iterations(x, 1);
pdp_ca_set2d(x);
pdp_ca_fullscreen1d(x, 0);
x->x_packet_type = gensym("grey");
x->x_lastrule = gensym("gameoflife");
pdp_ca_openlib(x, gensym(PDP_CA_RULES_LIB));
return (void *)x;
}
// *********************** CA CONVERTER CLASSES STUFF *********************
// TODO: move this to a separate file later together with other converters (part of system?)
#define PDP_CA2IMAGE 1
#define PDP_IMAGE2CA 2
typedef struct pdp_ca_conv_struct
{
t_object x_obj;
t_float x_f;
int x_threshold;
int x_packet;
t_outlet *x_outlet0;
/* solve identity crisis */
int x_whoami;
/* output packet type */
/* only greyscale for now */
t_symbol *x_packet_type;
} t_pdp_ca_conv;
/* hot packet inlet */
static void pdp_ca_conv_input_0(t_pdp_ca_conv *x, t_symbol *s, t_floatarg f)
{
int packet = -1;
if (s == gensym("register_ro")){
pdp_packet_mark_unused(x->x_packet);
x->x_packet = pdp_packet_copy_ro((int)f);
return;
}
else if (s == gensym("process")){
switch(x->x_whoami){
case PDP_CA2IMAGE:
packet = pdp_type_ca2grey(x->x_packet);
break;
case PDP_IMAGE2CA:
packet = pdp_type_grey2ca(x->x_packet, x->x_threshold);
break;
}
/* throw away the original packet */
pdp_packet_mark_unused(x->x_packet);
x->x_packet = -1;
/* pass the fresh packet */
pdp_packet_pass_if_valid(x->x_outlet0, &packet);
/* unregister the freshly created packet */
//pdp_packet_mark_unused(packet);
/* output if valid */
//if (-1 != packet) outlet_pdp(x->x_outlet0, packet);
}
}
void pdp_ca_conv_free(t_pdp_ca_conv *x)
{
pdp_packet_mark_unused(x->x_packet);
}
void pdp_image2ca_threshold(t_pdp_ca_conv *x, t_float f)
{
f *= 0x8000;
if (f < -0x7fff) f = -0x7fff;
if (f > 0x7fff) f = 0x7fff;
x->x_threshold = (short int)f;
}
void *pdp_ca2image_new(void)
{
t_pdp_ca_conv *x = (t_pdp_ca_conv *)pd_new(pdp_ca2image_class);
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
x->x_packet_type = gensym("grey");
x->x_packet = -1;
x->x_whoami = PDP_CA2IMAGE;
return (void *)x;
}
void *pdp_image2ca_new(void)
{
t_pdp_ca_conv *x = (t_pdp_ca_conv *)pd_new(pdp_image2ca_class);
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("threshold"));
x->x_outlet0 = outlet_new(&x->x_obj, &s_anything);
x->x_packet_type = gensym("grey");
x->x_packet = -1;
x->x_whoami = PDP_IMAGE2CA;
x->x_threshold = 0x4000;
return (void *)x;
}
// *********************** CLASS SETUP FUNCTIONS *********************
#ifdef __cplusplus
extern "C"
{
#endif
void pdp_ca2image_setup(void)
{
pdp_ca2image_class = class_new(gensym("pdp_ca2image"), (t_newmethod)pdp_ca2image_new,
(t_method)pdp_ca_conv_free, sizeof(t_pdp_ca), 0, A_NULL);
class_addmethod(pdp_ca2image_class, (t_method)pdp_ca_conv_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL);
}
void pdp_image2ca_setup(void)
{
pdp_image2ca_class = class_new(gensym("pdp_image2ca"), (t_newmethod)pdp_image2ca_new,
(t_method)pdp_ca_conv_free, sizeof(t_pdp_ca), 0, A_NULL);
class_addmethod(pdp_image2ca_class, (t_method)pdp_ca_conv_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_image2ca_class, (t_method)pdp_image2ca_threshold, gensym("threshold"), A_FLOAT, A_NULL);
}
void pdp_ca_setup(void)
{
pdp_ca_class = class_new(gensym("pdp_ca"), (t_newmethod)pdp_ca_new,
(t_method)pdp_ca_free, sizeof(t_pdp_ca), 0, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_iterations, gensym("iterations"), A_FLOAT, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_bang, gensym("bang"), A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_printrules, gensym("rules"), A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_rand, gensym("random"), A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_newca, gensym("ca"), A_FLOAT, A_FLOAT, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_newca, gensym("dim"), A_FLOAT, A_FLOAT, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_horshift16, gensym("hshift16"), A_FLOAT, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_vershift, gensym("vshift"), A_FLOAT, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_close, gensym("close"), A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_openlib, gensym("openlib"), A_SYMBOL, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_opensrc, gensym("opensrc"), A_SYMBOL, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_open, gensym("open"), A_SYMBOL, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_rule, gensym("rule"), A_SYMBOL, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_rule_index, gensym("ruleindex"), A_FLOAT, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_input_0, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_input_1, gensym("pdp1"), A_SYMBOL, A_DEFFLOAT, A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_set1d, gensym("1D"), A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_set2d, gensym("2D"), A_NULL);
class_addmethod(pdp_ca_class, (t_method)pdp_ca_fullscreen1d, gensym("fullscreen1D"), A_FLOAT, A_NULL);
}
#ifdef __cplusplus
}
#endif
--- NEW FILE: pdp_ca_system.c ---
/*
* Cellular Automata Extension Module for pdp - Main system code
* Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "pdp_ca.h"
#include "pdp_internals.h"
/* all symbols are C-style */
#ifdef __cplusplus
extern "C"
{
#endif
/* check if packet is a valid ca packet */
int pdp_packet_ca_isvalid(int packet)
{
t_pdp *header = pdp_packet_header(packet);
if (!header) return 0;
if (PDP_CA != header->type) return 0;
if (PDP_CA_STANDARD != pdp_type_ca_info(header)->encoding) return 0;
return 1;
}
static t_pdp_symbol *pdp_packet_ca_get_description(int packet)
{
t_pdp *header = pdp_packet_header(packet);
char description[1024];
char *c = description;
int encoding;
if (!header) return pdp_gensym("invalid");
if (header->type == PDP_CA){
c += sprintf(c, "ca");
switch(pdp_type_ca_info(header)->encoding){
case PDP_CA_STANDARD: c += sprintf(c, "/1bit2D"); break;
default:
c += sprintf(c, "/unknown"); goto exit;
}
c += sprintf(c, "/%dx%d",
pdp_type_ca_info(header)->width,
pdp_type_ca_info(header)->height);
exit:
return pdp_gensym(description);
}
else return pdp_gensym("unknown");
}
/* create a new ca packet */
int pdp_packet_new_ca(int encoding, int width, int height)
{
int p;
int w = (int)width;
int h = (int)height;
int bytesize;
t_pdp *header;
/* ensure with = multiple of 64 */
w &= 0xffffffc0;
/* ensure height = multiple of 4 */
w &= 0xfffffffc;
w = (w<64) ? 64 : w;
h = (h<4) ? 4 : h;
bytesize = (w>>3) * h;
/* create new packets */
p = pdp_packet_new(PDP_CA, bytesize);
header = pdp_packet_header(p);
if (!header) {
pdp_post("error: can't create CA packet");
return -1;
}
pdp_type_ca_info(header)->encoding = PDP_CA_STANDARD;
pdp_type_ca_info(header)->width = w;
pdp_type_ca_info(header)->height = h;
pdp_type_ca_info(header)->offset = 0;
pdp_type_ca_info(header)->currow = 0; /* only used for 1D ca */
pdp_type_ca_info(header)->currow = 0;
header->desc = 0;
header->desc = pdp_packet_ca_get_description(p);
//post("creating %s", header->desc->s_name);
return p;
}
/* convert a CA packet to greyscale */
inline void _pdp_type_ca2grey_convert_word(unsigned short int source, short int *dest)
{
int i;
for (i = 15; i>=0; i--){
dest[i] = ((unsigned short)(((short int)(source & 0x8000)) >> 14)) >> 1;
source <<= 1;
}
}
int pdp_type_ca2grey(int packet)
{
int w, h, s, x, y, srcindex;
long long offset, xoffset, yoffset;
short int *dest;
unsigned short int *source;
t_pdp *header;
t_pdp *newheader;
int newpacket;
if (!(pdp_packet_ca_isvalid(packet))) return -1;
header = pdp_packet_header(packet);
w = pdp_type_ca_info(header)->width;
h = pdp_type_ca_info(header)->height;
s = w*h;
source = (unsigned short int *)pdp_packet_data(packet);
offset = pdp_type_ca_info(header)->offset;
yoffset = (offset / w) * w;
xoffset = offset % w;
//post("pdp_type_ca2grey: offset: %d, xoffset: %d, yoffset: %d", offset, xoffset, yoffset);
newpacket = pdp_packet_new_image_grey(w, h);
newheader = pdp_packet_header(newpacket);
if (!newheader) return -1;
//newheader->info.image.width = w;
//newheader->info.image.height = h;
//newheader->info.image.encoding = PDP_IMAGE_GREY;
dest = (short int *)pdp_packet_data(newpacket);
#define check_srcindex \
if (srcindex >= (s >> 4)) post ("pdp_type_ca2grey: srcindex out of bound");
#define check_dstindex \
if ((x+y) >= s) post ("pdp_type_ca2grey: dstindex out of bound");
/* debug : dont' shift offset
if (0){
for(y=0; y< (h*w); y+=w){
for(x=0; x<w; x+=16){
_pdp_type_ca2grey_convert_word (source[(x+y)>>4], &dest[x+y]);
}
}
return newpacket;
}
*/
/* create top left */
for (y=0; y < (h*w) - yoffset; y+=w) {
for (x=0; x< (w - xoffset); x+=16) {
srcindex = (x+xoffset + y+yoffset) >> 4;
//check_srcindex;
//check_dstindex;
_pdp_type_ca2grey_convert_word (source[srcindex], &dest[x+y]);
}
}
/* create top right */
for (y=0; y < (h*w) - yoffset; y+=w) {
for (x = (w - xoffset); x < w; x+=16) {
srcindex = (x+xoffset-w + y+yoffset) >> 4;
//check_srcindex;
//check_dstindex;
_pdp_type_ca2grey_convert_word (source[srcindex], &dest[x+y]);
}
}
/* create bottom left */
for (y=(h*w) - yoffset; y < h*w; y+=w) {
for (x=0; x< (w - xoffset); x+=16) {
srcindex = (x+xoffset + y+yoffset-(w*h)) >> 4;
//check_srcindex;
//check_dstindex;
_pdp_type_ca2grey_convert_word (source[srcindex], &dest[x+y]);
}
}
/* create bottom right */
for (y=(h*w) - yoffset; y < h*w; y+=w) {
for (x = (w - xoffset); x < w; x+=16) {
srcindex = (x+xoffset-w + y+yoffset-(w*h)) >> 4;
//check_srcindex;
//check_dstindex;
_pdp_type_ca2grey_convert_word (source[srcindex], &dest[x+y]);
}
}
return newpacket;
}
inline unsigned short int _pdp_type_grey2ca_convert_word(short int *src, short int threshold)
{
short int tmp;
short int dest = 0;
int i;
for (i = 15; i >= 0; i--){
dest <<= 1;
dest |= (src[i] > threshold);
}
return dest;
}
int pdp_type_grey2ca(int packet, short int threshold)
{
int w, h, s, x, y, srcindex;
long long offset, xoffset, yoffset;
short int *dest;
short int *source;
t_pdp *header;
t_pdp *newheader;
int newpacket;
if (!(pdp_packet_image_isvalid(packet))) return -1;
header = pdp_packet_header(packet);
w = header->info.image.width;
h = header->info.image.height;
s = w*h;
source = (unsigned short int *)pdp_packet_data(packet);
if ( (PDP_IMAGE_GREY != header->info.image.encoding)
&& (PDP_IMAGE_YV12 != header->info.image.encoding)) return -1;
newpacket = pdp_packet_new_ca(PDP_CA_STANDARD, w, h);
newheader = pdp_packet_header(newpacket);
if (!newheader) return -1;
dest = (short int *)pdp_packet_data(newpacket);
for(y=0; y< (h*w); y+=w){
for(x=0; x<w; x+=16){
dest[(x+y)>>4] = _pdp_type_grey2ca_convert_word (&source[x+y], threshold);
}
}
return newpacket;
}
/* returns a pointer to the ca subheader given the pdp header */
t_ca *pdp_type_ca_info(t_pdp *x){return (t_ca *)(&x->info.raw);}
void pdp_ca_setup(void);
void pdp_ca2image_setup(void);
void pdp_image2ca_setup(void);
static int _ca_to_image(int packet, t_pdp_symbol *template)
{
return pdp_type_ca2grey(packet);
}
static int _image_to_ca(int packet, t_pdp_symbol *template)
{
// convert with default threshold == 0.5
return pdp_type_grey2ca(packet, 0.5f);
}
void pdp_scaf_setup(void)
{
t_pdp_conversion_program *program;
/* babble */
post ("PDP: pdp_scaf extension library");
/* setup modules */
pdp_ca_setup();
pdp_ca2image_setup();
pdp_image2ca_setup();
/* setup type conversion */
program = pdp_conversion_program_new(_ca_to_image, 0);
pdp_type_register_conversion(pdp_gensym("ca/*/*"), pdp_gensym("image/*/*"), program);
pdp_type_register_conversion(pdp_gensym("ca/*/*"), pdp_gensym("image/grey/*"), program);
program = pdp_conversion_program_new(_image_to_ca, 0);
pdp_type_register_conversion(pdp_gensym("image/grey/*"), pdp_gensym("ca/*/*"), program);
}
#ifdef __cplusplus
}
#endif
--- NEW FILE: Makefile ---
current: all_modules
include ../Makefile.config
OBJECTS = pdp_ca.o pdp_ca_system.o scaf_feeder.o
all_modules: $(OBJECTS)
clean:
rm -f *~
rm -f *.o
--- NEW FILE: scaf_feeder.s ---
# Pure Data Packet - scaf feeder routine.
# Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
#
# 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# for dup
.include "../compiler/scafmacro.s"
# *rg is only used for returning the stack pointer
# the 4 bit counter is using registers mm4-mm7 now
# long long scaf_feeder(void *tos, void *rg, *void() ca_rule, void *env)
.globl scaf_feeder
.type scaf_feeder, @function
scaf_feeder:
pushl %ebp
movl %esp, %ebp
push %esi
push %edi
movl 20(%ebp), %edi # load env ptr
movl 8(%ebp), %esi # load TOS2 ptr
movl 16(%ebp), %eax # address of ca routine
pcmpeqw %mm3, %mm3 # load 1 reg
call *%eax # TOS = 32x2 cell result
dup # push %mm0 to memory
movl (%esi), %eax
movl 4(%esi), %edx
lea 16(%esi), %esi # discard stack
movl %esi, (%edi) # store for stack underflow check
emms
pop %edi
pop %esi
leave
ret
Update of /cvsroot/pure-data/externals/pdp/scaf/include
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6756/scaf/include
Added Files:
Makefile pdp_ca.h
Log Message:
checking in pdp 0.12.4 from http://zwizwa.fartit.com/pd/pdp/pdp-0.12.4.tar.gz
--- NEW FILE: pdp_ca.h ---
/*
* Cellular Automata Extension Module for pdp - Main header file
* Copyright (c) by Tom Schouten <pdp(a)zzz.kotnet.org>
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef PDP_CA_H
#define PDP_CA_H
#include "pdp.h"
/* 2D CA DATA PACKET */
typedef struct
{
unsigned int encoding; /* CA data format */
unsigned int width; /* CA width (in 1 bit cells) */
unsigned int height; /* CA height (in 1 bit cells) */
unsigned int offset; /* bit offset of upper left corner */
unsigned int currow; /* current row to compute for 1D CA */
} t_ca;
/* CA encodings */
#define PDP_CA_STANDARD 1 /* rectangular CA */
/* pdp data packet types */
#define PDP_CA 2 /* 1bit toroidial shifted scanline encoded cellular automaton */
/* all symbols are C-style */
#ifdef __cplusplus
extern "C"
{
#endif
/* constructor */
int pdp_packet_new_ca(int encoding, int width, int height);
/* some utility methods for CA */
int pdp_packet_ca_isvalid(int packet);
int pdp_type_ca2grey(int packet);
int pdp_type_grey2ca(int packet, short int threshold);
/* returns a pointer to the ca subheader given the pdp header */
t_ca *pdp_type_ca_info(t_pdp *x);
/* mmx feeder routine */
unsigned long long scaf_feeder(void *tos, void *reg, void (*ca_rule)(void), void *env);
#ifdef __cplusplus
}
#endif
#endif //PDP_CA_H
--- NEW FILE: Makefile ---
current:
clean:
rm -f *~