Initial checkin of spinix (original version 1.33)
This commit is contained in:
commit
99bd77d966
|
@ -0,0 +1,5 @@
|
||||||
|
cd src
|
||||||
|
bstc -b -O cgru $1.spin
|
||||||
|
cp $1.binary ../root/bin/$1
|
||||||
|
rm $1.binary
|
||||||
|
cd ..
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Build the the boot program
|
||||||
|
cd src
|
||||||
|
bstc -b -O cgru boot.spin
|
||||||
|
cp boot.binary ..
|
||||||
|
rm boot.binary
|
||||||
|
cd ..
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
# Build filetest
|
||||||
|
cd filetest
|
||||||
|
cp ../src/spinix.* .
|
||||||
|
make clean
|
||||||
|
make
|
||||||
|
make binary
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Build fibo
|
||||||
|
cd cdemos
|
||||||
|
cd fibo
|
||||||
|
cp ../../src/spinix.* .
|
||||||
|
make clean
|
||||||
|
./buildit
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Build the dhrystone benchmark
|
||||||
|
cd cdemos
|
||||||
|
cd dry
|
||||||
|
cp ../../src/spinix.* .
|
||||||
|
make clean
|
||||||
|
./buildit
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Build a simple hello world program
|
||||||
|
cd cdemos
|
||||||
|
cd hello
|
||||||
|
cp ../../src/spinix.* .
|
||||||
|
make clean
|
||||||
|
./buildit
|
||||||
|
cd ../..
|
||||||
|
|
||||||
|
# Build the chess program
|
||||||
|
cd chess
|
||||||
|
./buildit
|
||||||
|
cd ..
|
|
@ -0,0 +1,81 @@
|
||||||
|
# Clean directories and remake them
|
||||||
|
rm -rf root
|
||||||
|
mkdir root
|
||||||
|
mkdir root/bin
|
||||||
|
mkdir root/tmp
|
||||||
|
mkdir root/manpages
|
||||||
|
mkdir root/devel
|
||||||
|
mkdir root/demos
|
||||||
|
mkdir root/forth
|
||||||
|
mkdir root/scripts
|
||||||
|
|
||||||
|
# Build the boot program
|
||||||
|
./build_boot
|
||||||
|
|
||||||
|
# Copy license and startup script to root
|
||||||
|
cp license.txt root
|
||||||
|
cp src/_shellrc root/bin
|
||||||
|
|
||||||
|
# Generate _sysparm and copy to root
|
||||||
|
cd src
|
||||||
|
date +%s >_sysparm
|
||||||
|
echo -6 3 0 >>_sysparm
|
||||||
|
echo 0 0 0 >>_sysparm
|
||||||
|
echo "GPWD /" >>_sysparm
|
||||||
|
echo "LSCRIPT_FILE /bin/_shellrc" >>_sysparm
|
||||||
|
echo "P# 0" >>_sysparm
|
||||||
|
cd ..
|
||||||
|
cp src/_sysparm root
|
||||||
|
|
||||||
|
# Build the bin apps
|
||||||
|
./build_src
|
||||||
|
|
||||||
|
# Copy the devel files
|
||||||
|
cp devel/* root/devel
|
||||||
|
|
||||||
|
# Copy the man pages
|
||||||
|
cp manpages/* root/manpages
|
||||||
|
|
||||||
|
# Build lerner
|
||||||
|
cd lerner
|
||||||
|
cp ../src/sysdefs.spin .
|
||||||
|
cp ../src/exit.spin .
|
||||||
|
bstc -b -O cgru lerner.spin
|
||||||
|
cp lerner.binary ../root/demos/lerner
|
||||||
|
rm *.binary
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Build vga512
|
||||||
|
cd vga512
|
||||||
|
cp ../src/sysdefs.spin .
|
||||||
|
cp ../src/exit.spin .
|
||||||
|
bstc -b VGA_512x384_Bitmap_Demo.spin
|
||||||
|
cp VGA_512x384_Bitmap_Demo.binary ../root/demos/vga512
|
||||||
|
rm *.binary
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Move vgatdemo from bin to demos
|
||||||
|
mv root/bin/vgatdemo root/demos
|
||||||
|
|
||||||
|
# Copy the C demos
|
||||||
|
cp cdemos/dry/dry.binary root/demos/dry
|
||||||
|
cp cdemos/fibo/fibo.binary root/demos/fibo
|
||||||
|
cp cdemos/hello/hello.binary root/demos/hello
|
||||||
|
|
||||||
|
# Copy C filetest program
|
||||||
|
cp filetest/filetest.binary root/demos/filetest
|
||||||
|
|
||||||
|
# Copy C chess program
|
||||||
|
cp chess/chess.binary root/demos/chess
|
||||||
|
|
||||||
|
# Build pfth and copy the Forth files
|
||||||
|
cd pfth
|
||||||
|
bstc -b ospfth.spin
|
||||||
|
cp ospfth.binary ../root/bin/pfth
|
||||||
|
cp *.fth ../root/forth
|
||||||
|
cp *.txt ../root/forth
|
||||||
|
mv ../root/forth/_startup.fth ../root
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Copy the script files
|
||||||
|
cp scripts/* root/scripts
|
|
@ -0,0 +1,61 @@
|
||||||
|
# Build the bin apps
|
||||||
|
./build_bin alias
|
||||||
|
./build_bin cat
|
||||||
|
./build_bin chmod
|
||||||
|
./build_bin config
|
||||||
|
./build_bin cp
|
||||||
|
./build_bin date
|
||||||
|
./build_bin declare
|
||||||
|
./build_bin diag
|
||||||
|
./build_bin diff
|
||||||
|
./build_bin dos2unix
|
||||||
|
./build_bin ed
|
||||||
|
./build_bin export
|
||||||
|
./build_bin ted
|
||||||
|
./build_bin grep
|
||||||
|
./build_bin halt
|
||||||
|
./build_bin head
|
||||||
|
./build_bin history
|
||||||
|
./build_bin let
|
||||||
|
./build_bin linefeed
|
||||||
|
./build_bin ls
|
||||||
|
./build_bin man
|
||||||
|
./build_bin mkdir
|
||||||
|
./build_bin more
|
||||||
|
./build_bin mv
|
||||||
|
./build_bin od
|
||||||
|
./build_bin printenv
|
||||||
|
./build_bin rb
|
||||||
|
./build_bin reboot
|
||||||
|
./build_bin rm
|
||||||
|
./build_bin sb
|
||||||
|
./build_bin set
|
||||||
|
./build_bin shell
|
||||||
|
./build_bin spasm
|
||||||
|
./build_bin spinit
|
||||||
|
./build_bin splink
|
||||||
|
./build_bin tail
|
||||||
|
./build_bin tar
|
||||||
|
./build_bin test
|
||||||
|
./build_bin touch
|
||||||
|
./build_bin unalias
|
||||||
|
./build_bin unix2dos
|
||||||
|
./build_bin unset
|
||||||
|
./build_bin vi
|
||||||
|
./build_bin vgatdemo
|
||||||
|
./build_bin wc
|
||||||
|
|
||||||
|
# Copy the shell scripts
|
||||||
|
cp src/spc root/bin
|
||||||
|
|
||||||
|
# Copy text files
|
||||||
|
cp src/*.txt root/bin
|
||||||
|
|
||||||
|
# Build files for spasm
|
||||||
|
cd src
|
||||||
|
grep PUB clibsd.spin >../root/devel/clibsd.spn
|
||||||
|
cp ../root/devel/clibsd.spn ../root/devel/clibsd.spa
|
||||||
|
bstc -b clibsd.spin
|
||||||
|
cp clibsd.binary ../root/devel/clibsd.bin
|
||||||
|
rm clibsd.binary
|
||||||
|
cd ..
|
|
@ -0,0 +1,128 @@
|
||||||
|
# #########################################################
|
||||||
|
# This makefile fragment builds LMM/XMM/XMMC demo programs
|
||||||
|
#
|
||||||
|
# To use it, define:
|
||||||
|
# PROPLIB to be the path to this directory
|
||||||
|
# NAME to be the name of project
|
||||||
|
# - this is used to create the final program $(NAME).elf
|
||||||
|
# OBJS to be the object files needed for the project
|
||||||
|
# MODEL to lmm, xmm, or xmmc
|
||||||
|
# CFLAGS to be desired CFLAGS
|
||||||
|
#
|
||||||
|
# Then set up a default "all" target (normally this will be
|
||||||
|
# all: $(NAME).elf
|
||||||
|
# and finally
|
||||||
|
# include $(PROPLIB)/demo.mk
|
||||||
|
#
|
||||||
|
# Copyright (c) 2011 Parallax Inc.
|
||||||
|
# All rights MIT licensed
|
||||||
|
# #########################################################
|
||||||
|
|
||||||
|
# where we installed the propeller binaries and libraries
|
||||||
|
PREFIX = /opt/parallax
|
||||||
|
|
||||||
|
ifndef MODEL
|
||||||
|
MODEL=lmm
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef BOARD
|
||||||
|
BOARD=$(PROPELLER_LOAD_BOARD)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(BOARD),)
|
||||||
|
BOARDFLAG=-b$(BOARD)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(CHIP),)
|
||||||
|
CHIPFLAG = -m$(CHIP)
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS_NO_MODEL := $(CFLAGS) $(CHIPFLAG)
|
||||||
|
CFLAGS += -m$(MODEL) $(CHIPFLAG)
|
||||||
|
CXXFLAGS += $(CFLAGS)
|
||||||
|
LDFLAGS += $(CFLAGS) -fno-exceptions -fno-rtti
|
||||||
|
|
||||||
|
ifneq ($(LDSCRIPT),)
|
||||||
|
LDFLAGS += -T $(LDSCRIPT)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# basic gnu tools
|
||||||
|
CC = propeller-elf-gcc
|
||||||
|
CXX = propeller-elf-g++
|
||||||
|
LD = propeller-elf-ld
|
||||||
|
AS = propeller-elf-as
|
||||||
|
AR = propeller-elf-ar
|
||||||
|
OBJCOPY = propeller-elf-objcopy
|
||||||
|
LOADER = propeller-load
|
||||||
|
LOADER2 = p2load
|
||||||
|
|
||||||
|
# BSTC program
|
||||||
|
BSTC=bstc
|
||||||
|
SPINDIR=.
|
||||||
|
|
||||||
|
ifneq ($(NAME),)
|
||||||
|
$(NAME).elf: $(OBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(LIBNAME),)
|
||||||
|
lib$(LIBNAME).a: $(OBJS)
|
||||||
|
$(AR) rs $@ $(OBJS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CC) $(CXXFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
%.o: %.s
|
||||||
|
$(CC) -o $@ -c $<
|
||||||
|
|
||||||
|
#
|
||||||
|
# a .cog program is an object file that contains code intended to
|
||||||
|
# run in a COG separate from the main program; i.e., it's a COG
|
||||||
|
# driver that the linker will place in the .text section.
|
||||||
|
#
|
||||||
|
%.cog: %.c
|
||||||
|
$(CC) $(CFLAGS_NO_MODEL) -mcog -r -o $@ $<
|
||||||
|
$(OBJCOPY) --localize-text --rename-section .text=$@ $@
|
||||||
|
|
||||||
|
%.cog: %.cogc
|
||||||
|
$(CC) $(CFLAGS_NO_MODEL) -mcog -xc -r -o $@ $<
|
||||||
|
$(OBJCOPY) --localize-text --rename-section .text=$@ $@
|
||||||
|
|
||||||
|
#
|
||||||
|
# a .ecog program is an object file that contains code intended to
|
||||||
|
# run in a COG separate from the main program; i.e., it's a COG
|
||||||
|
# driver that the linker will place in the .drivers section which
|
||||||
|
# gets loaded to high EEPROM space above 0x8000.
|
||||||
|
#
|
||||||
|
%.ecog: %.c
|
||||||
|
$(CC) $(CFLAGS_NO_MODEL) -mcog -r -o $@ $<
|
||||||
|
$(OBJCOPY) --localize-text --rename-section .text=$@ $@
|
||||||
|
|
||||||
|
%.ecog: %.ecogc
|
||||||
|
$(CC) $(CFLAGS_NO_MODEL) -mcog -xc -r -o $@ $<
|
||||||
|
$(OBJCOPY) --localize-text --rename-section .text=$@ $@
|
||||||
|
|
||||||
|
%.binary: %.elf
|
||||||
|
$(LOADER) -s $<
|
||||||
|
|
||||||
|
%.dat: $(SPINDIR)/%.spin
|
||||||
|
$(BSTC) -Ox -c -o $(basename $@) $<
|
||||||
|
|
||||||
|
%_firmware.o: %.dat
|
||||||
|
$(OBJCOPY) -I binary -B propeller -O $(CC) $< $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.elf *.a *.cog *.ecog *.binary
|
||||||
|
|
||||||
|
#
|
||||||
|
# how to run
|
||||||
|
run: $(NAME).elf
|
||||||
|
$(LOADER) $(BOARDFLAG) $(NAME).elf -r -t
|
||||||
|
|
||||||
|
run2: $(NAME).elf
|
||||||
|
$(LOADER2) $(NAME).elf -t
|
||||||
|
#
|
|
@ -0,0 +1,56 @@
|
||||||
|
# #########################################################
|
||||||
|
# This makefile builds the dhrystone program
|
||||||
|
#
|
||||||
|
# At the moment only the LMM model works.
|
||||||
|
#
|
||||||
|
# To build with LMM model, enter $ make clean; make
|
||||||
|
# To build with XMM model, enter $ make clean; make MODEL=xmm
|
||||||
|
# To build with XMMC model, enter $ make clean; make MODEL=xmmc
|
||||||
|
#
|
||||||
|
# Copyright (c) 2011 Parallax, Inc.
|
||||||
|
# All rights MIT licensed
|
||||||
|
# #########################################################
|
||||||
|
|
||||||
|
# Common make
|
||||||
|
COMMON = ../common
|
||||||
|
|
||||||
|
ifndef OPT
|
||||||
|
OPT=-O0
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef PASSES
|
||||||
|
PASSES=3000
|
||||||
|
endif
|
||||||
|
|
||||||
|
#
|
||||||
|
# objects for this program
|
||||||
|
#
|
||||||
|
|
||||||
|
NAME = dry
|
||||||
|
OBJS = dry1.o dry2.o spinix.o
|
||||||
|
|
||||||
|
# default build target
|
||||||
|
all: $(NAME).elf
|
||||||
|
|
||||||
|
# flags to use
|
||||||
|
# MSC_CLOCK selects the clock() function for timing
|
||||||
|
# printf=__simple_printf makes sure we use the small printf
|
||||||
|
# -DINTEGER_ONLY removes floating point
|
||||||
|
|
||||||
|
DEFINES = -Dprintf=__simple_printf -DMSC_CLOCK -DINTEGER_ONLY -DFIXED_NUMBER_OF_PASSES=$(PASSES)
|
||||||
|
CFLAGS = $(OPT) $(DEFINES)
|
||||||
|
|
||||||
|
#
|
||||||
|
# include the fragment that defines most of everything
|
||||||
|
#
|
||||||
|
include $(COMMON)/common.mk
|
||||||
|
|
||||||
|
dry1.o: dry.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
dry2.o: dry.c
|
||||||
|
$(CC) $(CFLAGS) -DPASS2 -o $@ -c $<
|
||||||
|
|
||||||
|
spinix.o: spinix.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ -c $<
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
make
|
||||||
|
propeller-load -s -D clkfreq=1347436867 -D clkmode=98 dry.elf
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,45 @@
|
||||||
|
#include <propeller.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
|
||||||
|
static int run_prog[] = {
|
||||||
|
0xa0bc65f0, 0x08bc6e32, 0x80fc6404, 0x08bc7032, 0x80fc6404, 0x08bc6032,
|
||||||
|
0x80fc6404, 0x08bc6232, 0x80fc63ff, 0x28fc6209, 0x08fc6600, 0x00fc6804,
|
||||||
|
0x083c6029, 0x083c5c2a, 0x083c582b, 0x08bc642b, 0x863c642c, 0x5c68000f,
|
||||||
|
0x80fc6001, 0x80fc5d00, 0x80fc5d00, 0xe4fc620c, 0x087c6600, 0x007c6804,
|
||||||
|
0x04fc6a08, 0x04fc6c0a, 0xa0bc6236, 0x84bc6235, 0x28fc6202, 0x083c5a35,
|
||||||
|
0x80fc6a04, 0xe4fc621d, 0x083c5a36, 0x80fc6c04, 0x083c6e36, 0x80fc6c04,
|
||||||
|
0x083c7036, 0x0cfc6401, 0x60fc6407, 0x68bc5e32, 0x0c7c5e02, 0x00007fd8,
|
||||||
|
0x00007fdc, 0x00007fd4, 0x00000072, 0x00000000, 0x00000000, 0x0007c010};
|
||||||
|
|
||||||
|
static int arg_list[] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
void spinix_enter(int argc, char **argv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinix_exit(int retval)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int cogspi = (*(int *)spinix_spi_engine_cog) - 1;
|
||||||
|
arg_list[2] = *(int *)spinix_shell_sector;
|
||||||
|
arg_list[3] = *(int *)spinix_shell_size;
|
||||||
|
|
||||||
|
*(int *)spinix_return_value = retval;
|
||||||
|
|
||||||
|
// Stop all the cogs except this one and the SD SPI cog
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (i != cogid() && i != cogspi)
|
||||||
|
cogstop(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear and return all the locks
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
lockclr(i);
|
||||||
|
lockret(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start run_prog in this cog
|
||||||
|
coginit(cogid(), run_prog, arg_list);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#define spinix_start 0x7c00 // Extra space for the stand-alone loader
|
||||||
|
#define spinix_rendezvous 0x7e50
|
||||||
|
#define spinix_environ_vars 0x7e50
|
||||||
|
#define spinix_environ_vars_end 0x7ed3
|
||||||
|
#define spinix_argv_parms 0x7ed4
|
||||||
|
#define spinix_return_value 0x7f94
|
||||||
|
#define spinix_vga_cog 0x7f98
|
||||||
|
#define spinix_vga_handle 0x7f9c
|
||||||
|
#define spinix_sd_pins 0x7fa0
|
||||||
|
#define spinix_config 0x7fa4
|
||||||
|
#define spinix_shell_sector 0x7fa8
|
||||||
|
#define spinix_unixtime 0x7fac
|
||||||
|
#define spinix_cycle0 0x7fb0
|
||||||
|
#define spinix_timezone 0x7fb4
|
||||||
|
#define spinix_scriptline 0x7fb8
|
||||||
|
#define spinix_ifflag 0x7fbc
|
||||||
|
#define spinix_whileflag 0x7fc0
|
||||||
|
#define spinix_shell_size 0x7fc4
|
||||||
|
#define spinix_shell_level 0x7fc8
|
||||||
|
#define spinix_bootflag 0x7fcc
|
||||||
|
#define spinix_spi_engine_cog 0x7fd0
|
||||||
|
#define spinix_spi_command 0x7fd4
|
||||||
|
#define spinix_spi_block_index 0x7fd8
|
||||||
|
#define spinix_spi_buffer_address 0x7fdc
|
||||||
|
#define spinix_serial 0x7fe0
|
||||||
|
#define spinix_stdio 0x7fe4
|
||||||
|
#define spinix_stdin 0x7fe8
|
||||||
|
#define spinix_stdout 0x7fec
|
||||||
|
#define spinix_memlocknum 0x7ff0
|
||||||
|
#define spinix_memfreelist 0x7ff4
|
||||||
|
#define spinix_malloclist 0x7ff8
|
||||||
|
#define spinix_laststackaddr 0x7ffc
|
||||||
|
#define spinix_checkword 0xdead1eaf
|
||||||
|
#define spinix_proc_type_spin 1
|
||||||
|
#define spinix_proc_type_pasm 2
|
||||||
|
#define spinix_proc_type_capp 3
|
||||||
|
#define spinix_proc_type_driver 0x80
|
||||||
|
#define spinix_run_shell_wait 0x00
|
||||||
|
#define spinix_run_shell_nowait 0x08
|
||||||
|
#define spinix_run_kill_caller 0x10
|
||||||
|
#define spinix_run_at_address0 0x20
|
||||||
|
#define spinix_run_c_program 0x40
|
||||||
|
#define spinix_run_spin_program 0x80
|
||||||
|
#define spinix_run_stand_alone 0x100
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# objects for this program
|
||||||
|
#
|
||||||
|
|
||||||
|
PROPLIB = ../common
|
||||||
|
|
||||||
|
NAME = fibo
|
||||||
|
OBJS = fibo.o spinix.o
|
||||||
|
|
||||||
|
# memory model
|
||||||
|
MODEL = lmm
|
||||||
|
|
||||||
|
#
|
||||||
|
# enable experimental fcache code for this demo
|
||||||
|
#
|
||||||
|
#CFLAGS = -Os -mfcache
|
||||||
|
CFLAGS = -g -Os
|
||||||
|
#CFLAGS = -g
|
||||||
|
|
||||||
|
all: $(NAME).elf
|
||||||
|
|
||||||
|
include $(PROPLIB)/common.mk
|
|
@ -0,0 +1,2 @@
|
||||||
|
propeller-elf-gcc -Os -mlmm -o fibo.elf fibo.c spinix.c
|
||||||
|
propeller-load -s -D clkfreq=1347436867 -D clkmode=98 fibo.elf
|
|
@ -0,0 +1,47 @@
|
||||||
|
//#include <stdio.h>
|
||||||
|
//#include <string.h>
|
||||||
|
//#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <propeller.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
|
||||||
|
//#define CNT _CNT
|
||||||
|
//#define CLKFREQ _CLKFREQ
|
||||||
|
|
||||||
|
unsigned int fibo (unsigned int n)
|
||||||
|
{
|
||||||
|
if (n < 2)
|
||||||
|
{
|
||||||
|
return (n);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return fibo(n - 1) + fibo(n - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern unsigned int clock(void);
|
||||||
|
|
||||||
|
int main (int argc, char* argv[])
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
int result;
|
||||||
|
unsigned int startTime;
|
||||||
|
unsigned int endTime;
|
||||||
|
unsigned int executionTime;
|
||||||
|
unsigned int rawTime;
|
||||||
|
|
||||||
|
printf("hello, world!\r\n");
|
||||||
|
for (n = 0; n <= 26; n++)
|
||||||
|
{
|
||||||
|
printf("fibo(%02d) = ", n);
|
||||||
|
startTime = clock();
|
||||||
|
result = fibo(n);
|
||||||
|
endTime = clock();
|
||||||
|
rawTime = endTime - startTime;
|
||||||
|
executionTime = rawTime / (CLKFREQ / 1000);
|
||||||
|
printf ("%06d (%05ums) (%u ticks)\n", result, executionTime, rawTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
spinix_exit(0);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include <propeller.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
|
||||||
|
static int run_prog[] = {
|
||||||
|
0xa0bc65f0, 0x08bc6e32, 0x80fc6404, 0x08bc7032, 0x80fc6404, 0x08bc6032,
|
||||||
|
0x80fc6404, 0x08bc6232, 0x80fc63ff, 0x28fc6209, 0x08fc6600, 0x00fc6804,
|
||||||
|
0x083c6029, 0x083c5c2a, 0x083c582b, 0x08bc642b, 0x863c642c, 0x5c68000f,
|
||||||
|
0x80fc6001, 0x80fc5d00, 0x80fc5d00, 0xe4fc620c, 0x087c6600, 0x007c6804,
|
||||||
|
0x04fc6a08, 0x04fc6c0a, 0xa0bc6236, 0x84bc6235, 0x28fc6202, 0x083c5a35,
|
||||||
|
0x80fc6a04, 0xe4fc621d, 0x083c5a36, 0x80fc6c04, 0x083c6e36, 0x80fc6c04,
|
||||||
|
0x083c7036, 0x0cfc6401, 0x60fc6407, 0x68bc5e32, 0x0c7c5e02, 0x00007fd8,
|
||||||
|
0x00007fdc, 0x00007fd4, 0x00000072, 0x00000000, 0x00000000, 0x0007c010};
|
||||||
|
|
||||||
|
static int arg_list[] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
void spinix_enter(int argc, char **argv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinix_exit(int retval)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int cogspi = (*(int *)spinix_spi_engine_cog) - 1;
|
||||||
|
arg_list[2] = *(int *)spinix_shell_sector;
|
||||||
|
arg_list[3] = *(int *)spinix_shell_size;
|
||||||
|
|
||||||
|
*(int *)spinix_return_value = retval;
|
||||||
|
|
||||||
|
// Stop all the cogs except this one and the SD SPI cog
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (i != cogid() && i != cogspi)
|
||||||
|
cogstop(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear and return all the locks
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
lockclr(i);
|
||||||
|
lockret(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start run_prog in this cog
|
||||||
|
coginit(cogid(), run_prog, arg_list);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#define spinix_start 0x7c00 // Extra space for the stand-alone loader
|
||||||
|
#define spinix_rendezvous 0x7e50
|
||||||
|
#define spinix_environ_vars 0x7e50
|
||||||
|
#define spinix_environ_vars_end 0x7ed3
|
||||||
|
#define spinix_argv_parms 0x7ed4
|
||||||
|
#define spinix_return_value 0x7f94
|
||||||
|
#define spinix_vga_cog 0x7f98
|
||||||
|
#define spinix_vga_handle 0x7f9c
|
||||||
|
#define spinix_sd_pins 0x7fa0
|
||||||
|
#define spinix_config 0x7fa4
|
||||||
|
#define spinix_shell_sector 0x7fa8
|
||||||
|
#define spinix_unixtime 0x7fac
|
||||||
|
#define spinix_cycle0 0x7fb0
|
||||||
|
#define spinix_timezone 0x7fb4
|
||||||
|
#define spinix_scriptline 0x7fb8
|
||||||
|
#define spinix_ifflag 0x7fbc
|
||||||
|
#define spinix_whileflag 0x7fc0
|
||||||
|
#define spinix_shell_size 0x7fc4
|
||||||
|
#define spinix_shell_level 0x7fc8
|
||||||
|
#define spinix_bootflag 0x7fcc
|
||||||
|
#define spinix_spi_engine_cog 0x7fd0
|
||||||
|
#define spinix_spi_command 0x7fd4
|
||||||
|
#define spinix_spi_block_index 0x7fd8
|
||||||
|
#define spinix_spi_buffer_address 0x7fdc
|
||||||
|
#define spinix_serial 0x7fe0
|
||||||
|
#define spinix_stdio 0x7fe4
|
||||||
|
#define spinix_stdin 0x7fe8
|
||||||
|
#define spinix_stdout 0x7fec
|
||||||
|
#define spinix_memlocknum 0x7ff0
|
||||||
|
#define spinix_memfreelist 0x7ff4
|
||||||
|
#define spinix_malloclist 0x7ff8
|
||||||
|
#define spinix_laststackaddr 0x7ffc
|
||||||
|
#define spinix_checkword 0xdead1eaf
|
||||||
|
#define spinix_proc_type_spin 1
|
||||||
|
#define spinix_proc_type_pasm 2
|
||||||
|
#define spinix_proc_type_capp 3
|
||||||
|
#define spinix_proc_type_driver 0x80
|
||||||
|
#define spinix_run_shell_wait 0x00
|
||||||
|
#define spinix_run_shell_nowait 0x08
|
||||||
|
#define spinix_run_kill_caller 0x10
|
||||||
|
#define spinix_run_at_address0 0x20
|
||||||
|
#define spinix_run_c_program 0x40
|
||||||
|
#define spinix_run_spin_program 0x80
|
||||||
|
#define spinix_run_stand_alone 0x100
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# objects for this program
|
||||||
|
#
|
||||||
|
|
||||||
|
PROPLIB = ../common
|
||||||
|
|
||||||
|
NAME = hello
|
||||||
|
OBJS = hello.o spinix.o
|
||||||
|
|
||||||
|
# memory model
|
||||||
|
MODEL = lmm
|
||||||
|
|
||||||
|
#
|
||||||
|
# enable experimental fcache code for this demo
|
||||||
|
#
|
||||||
|
#CFLAGS = -Os -mfcache
|
||||||
|
CFLAGS = -g -Os
|
||||||
|
#CFLAGS = -g
|
||||||
|
|
||||||
|
all: $(NAME).elf
|
||||||
|
|
||||||
|
include $(PROPLIB)/common.mk
|
|
@ -0,0 +1,2 @@
|
||||||
|
propeller-elf-gcc -Os -mlmm -o hello.elf hello.c spinix.c
|
||||||
|
propeller-load -s -D clkfreq=1347436867 -D clkmode=98 hello.elf
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
|
||||||
|
int main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
spinix_enter();
|
||||||
|
printf("Hello World!\n");
|
||||||
|
spinix_exit(0);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include <propeller.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
|
||||||
|
static int run_prog[] = {
|
||||||
|
0xa0bc65f0, 0x08bc6e32, 0x80fc6404, 0x08bc7032, 0x80fc6404, 0x08bc6032,
|
||||||
|
0x80fc6404, 0x08bc6232, 0x80fc63ff, 0x28fc6209, 0x08fc6600, 0x00fc6804,
|
||||||
|
0x083c6029, 0x083c5c2a, 0x083c582b, 0x08bc642b, 0x863c642c, 0x5c68000f,
|
||||||
|
0x80fc6001, 0x80fc5d00, 0x80fc5d00, 0xe4fc620c, 0x087c6600, 0x007c6804,
|
||||||
|
0x04fc6a08, 0x04fc6c0a, 0xa0bc6236, 0x84bc6235, 0x28fc6202, 0x083c5a35,
|
||||||
|
0x80fc6a04, 0xe4fc621d, 0x083c5a36, 0x80fc6c04, 0x083c6e36, 0x80fc6c04,
|
||||||
|
0x083c7036, 0x0cfc6401, 0x60fc6407, 0x68bc5e32, 0x0c7c5e02, 0x00007fd8,
|
||||||
|
0x00007fdc, 0x00007fd4, 0x00000072, 0x00000000, 0x00000000, 0x0007c010};
|
||||||
|
|
||||||
|
static int arg_list[] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
void spinix_enter(int argc, char **argv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinix_exit(int retval)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int cogspi = (*(int *)spinix_spi_engine_cog) - 1;
|
||||||
|
arg_list[2] = *(int *)spinix_shell_sector;
|
||||||
|
arg_list[3] = *(int *)spinix_shell_size;
|
||||||
|
|
||||||
|
*(int *)spinix_return_value = retval;
|
||||||
|
|
||||||
|
// Stop all the cogs except this one and the SD SPI cog
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (i != cogid() && i != cogspi)
|
||||||
|
cogstop(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear and return all the locks
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
lockclr(i);
|
||||||
|
lockret(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start run_prog in this cog
|
||||||
|
coginit(cogid(), run_prog, arg_list);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#define spinix_start 0x7c00 // Extra space for the stand-alone loader
|
||||||
|
#define spinix_rendezvous 0x7e50
|
||||||
|
#define spinix_environ_vars 0x7e50
|
||||||
|
#define spinix_environ_vars_end 0x7ed3
|
||||||
|
#define spinix_argv_parms 0x7ed4
|
||||||
|
#define spinix_return_value 0x7f94
|
||||||
|
#define spinix_vga_cog 0x7f98
|
||||||
|
#define spinix_vga_handle 0x7f9c
|
||||||
|
#define spinix_sd_pins 0x7fa0
|
||||||
|
#define spinix_config 0x7fa4
|
||||||
|
#define spinix_shell_sector 0x7fa8
|
||||||
|
#define spinix_unixtime 0x7fac
|
||||||
|
#define spinix_cycle0 0x7fb0
|
||||||
|
#define spinix_timezone 0x7fb4
|
||||||
|
#define spinix_scriptline 0x7fb8
|
||||||
|
#define spinix_ifflag 0x7fbc
|
||||||
|
#define spinix_whileflag 0x7fc0
|
||||||
|
#define spinix_shell_size 0x7fc4
|
||||||
|
#define spinix_shell_level 0x7fc8
|
||||||
|
#define spinix_bootflag 0x7fcc
|
||||||
|
#define spinix_spi_engine_cog 0x7fd0
|
||||||
|
#define spinix_spi_command 0x7fd4
|
||||||
|
#define spinix_spi_block_index 0x7fd8
|
||||||
|
#define spinix_spi_buffer_address 0x7fdc
|
||||||
|
#define spinix_serial 0x7fe0
|
||||||
|
#define spinix_stdio 0x7fe4
|
||||||
|
#define spinix_stdin 0x7fe8
|
||||||
|
#define spinix_stdout 0x7fec
|
||||||
|
#define spinix_memlocknum 0x7ff0
|
||||||
|
#define spinix_memfreelist 0x7ff4
|
||||||
|
#define spinix_malloclist 0x7ff8
|
||||||
|
#define spinix_laststackaddr 0x7ffc
|
||||||
|
#define spinix_checkword 0xdead1eaf
|
||||||
|
#define spinix_proc_type_spin 1
|
||||||
|
#define spinix_proc_type_pasm 2
|
||||||
|
#define spinix_proc_type_capp 3
|
||||||
|
#define spinix_proc_type_driver 0x80
|
||||||
|
#define spinix_run_shell_wait 0x00
|
||||||
|
#define spinix_run_shell_nowait 0x08
|
||||||
|
#define spinix_run_kill_caller 0x10
|
||||||
|
#define spinix_run_at_address0 0x20
|
||||||
|
#define spinix_run_c_program 0x40
|
||||||
|
#define spinix_run_spin_program 0x80
|
||||||
|
#define spinix_run_stand_alone 0x100
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
propeller-elf-gcc -o chess.elf -Os -mlmm -fno-exceptions chess.c -ltiny -lpthread
|
||||||
|
propeller-load -s chess.elf
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
||||||
|
chess.c
|
||||||
|
>compiler=C
|
||||||
|
>memtype=lmm main ram
|
||||||
|
>optimize=-Os
|
||||||
|
>-fno-exceptions
|
||||||
|
>-ltiny
|
||||||
|
>-lpthread
|
||||||
|
>BOARD::C3F
|
|
@ -0,0 +1,31 @@
|
||||||
|
con
|
||||||
|
_clkmode = $62
|
||||||
|
_clkfreq = $4E495053 ' SPIN
|
||||||
|
|
||||||
|
obj
|
||||||
|
c : "clibsd"
|
||||||
|
|
||||||
|
pub main(argc, argv) | n, startTime, endTime, executionTime, rawTime
|
||||||
|
c.enter(argc, argv)
|
||||||
|
c.printf0(string("hello, world!\n"))
|
||||||
|
n := 0
|
||||||
|
repeat while n =< 26
|
||||||
|
c.printf1(string("fibo(%d) = "), n)
|
||||||
|
startTime := clock
|
||||||
|
result := fibo(n)
|
||||||
|
endTime := clock
|
||||||
|
rawTime := endTime - startTime
|
||||||
|
executionTime := rawTime / (CLKFREQ / 1000)
|
||||||
|
c.printf3(string("%d (%dms) (%d ticks)\n"), result, executionTime, rawTime)
|
||||||
|
n++
|
||||||
|
c.exit(0)
|
||||||
|
|
||||||
|
pub clock
|
||||||
|
result := cnt
|
||||||
|
|
||||||
|
pub fibo(n)
|
||||||
|
if n < 2
|
||||||
|
return n
|
||||||
|
else
|
||||||
|
return fibo(n - 1) + fibo(n - 2)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
con
|
||||||
|
_clkmode = $62
|
||||||
|
_clkfreq = $4E495053 ' SPIN
|
||||||
|
|
||||||
|
obj
|
||||||
|
c : "clibsd"
|
||||||
|
|
||||||
|
pub main(argc, argv)
|
||||||
|
c.enter(argc, argv)
|
||||||
|
c.printf0(string("Hello World\n"))
|
||||||
|
c.exit(0)
|
|
@ -0,0 +1,7 @@
|
||||||
|
#shell
|
||||||
|
echo spinit pong
|
||||||
|
spinit pong
|
||||||
|
echo spasm pong
|
||||||
|
spasm pong
|
||||||
|
echo splink pong.bin pongclib.bin pong
|
||||||
|
splink pong.bin pongclib.bin pong
|
|
@ -0,0 +1,13 @@
|
||||||
|
#shell
|
||||||
|
echo spinit pongsubs
|
||||||
|
spinit pongsubs
|
||||||
|
echo spasm pongsubs
|
||||||
|
spasm pongsubs
|
||||||
|
echo splink pongsubs.bin clibsd.bin pongclib.bin
|
||||||
|
splink pongsubs.bin clibsd.bin pongclib.bin
|
||||||
|
echo spinit pong
|
||||||
|
spinit pong
|
||||||
|
echo spasm pong
|
||||||
|
spasm pong
|
||||||
|
echo splink pong.bin pongclib.bin pong
|
||||||
|
splink pong.bin pongclib.bin pong
|
|
@ -0,0 +1,7 @@
|
||||||
|
#shell
|
||||||
|
echo spinit pongsubs
|
||||||
|
spinit pongsubs
|
||||||
|
echo spasm pongsubs
|
||||||
|
spasm pongsubs
|
||||||
|
echo splink pongsubs.bin clibsd.bin pongclib.bin
|
||||||
|
splink pongsubs.bin clibsd.bin pongclib.bin
|
|
@ -0,0 +1,174 @@
|
||||||
|
CON
|
||||||
|
_clkmode = $62
|
||||||
|
_clkfreq = $4E495053 ' SPIN
|
||||||
|
|
||||||
|
height = 3
|
||||||
|
xmax = 78
|
||||||
|
xmin = 1
|
||||||
|
ymax = 23
|
||||||
|
ymin = 1
|
||||||
|
|
||||||
|
OBJ
|
||||||
|
p : "pongsubs"
|
||||||
|
c : "clibsd"
|
||||||
|
|
||||||
|
DAT
|
||||||
|
left long 0
|
||||||
|
right long 0
|
||||||
|
config long 0
|
||||||
|
x long 0
|
||||||
|
y long 0
|
||||||
|
xvel long 0
|
||||||
|
yvel long 0
|
||||||
|
score0 long 0
|
||||||
|
score1 long 0
|
||||||
|
center long 0
|
||||||
|
xold long 1
|
||||||
|
yold long 1
|
||||||
|
|
||||||
|
pub main(argc, argv) | time, deltat
|
||||||
|
c.enter(argc, argv)
|
||||||
|
p.splash
|
||||||
|
initialize
|
||||||
|
deltat := clkfreq/20
|
||||||
|
time := cnt
|
||||||
|
repeat
|
||||||
|
check_input
|
||||||
|
update_position
|
||||||
|
check_score
|
||||||
|
p.plotit(xold, yold, p.getval(xold, yold))
|
||||||
|
p.plotit(x, y, "@")
|
||||||
|
xold := x
|
||||||
|
yold := y
|
||||||
|
time += deltat
|
||||||
|
repeat while (cnt - time) < deltat
|
||||||
|
c.setconfig(config)
|
||||||
|
c.putchar(13)
|
||||||
|
c.exit(0)
|
||||||
|
|
||||||
|
pub initialize | i
|
||||||
|
c.putchar(0)
|
||||||
|
config := c.getconfig
|
||||||
|
c.setconfig(1)
|
||||||
|
center := (xmin + xmax)/2
|
||||||
|
p.updatevars(ymin, center, score0, score1)
|
||||||
|
x := 1
|
||||||
|
y := 10
|
||||||
|
xvel := 1
|
||||||
|
yvel := 1
|
||||||
|
left := (ymin + ymax)/2
|
||||||
|
right := left
|
||||||
|
p.moveto(xmin-1, ymin-1)
|
||||||
|
i := xmin-1
|
||||||
|
repeat while i++ =< xmax + 1
|
||||||
|
c.putchar("#")
|
||||||
|
p.moveto(xmin-1, ymax+1)
|
||||||
|
i := xmin-1
|
||||||
|
repeat while i++ =< xmax + 1
|
||||||
|
c.putchar("#")
|
||||||
|
i := ymin
|
||||||
|
repeat while i =< ymax
|
||||||
|
p.moveto(center, i)
|
||||||
|
c.putchar(".")
|
||||||
|
i++
|
||||||
|
p.plotpaddle(xmin-1, left, height)
|
||||||
|
p.plotpaddle(xmax+1, right, height)
|
||||||
|
p.putnum(center-8, ymin+1, 0)
|
||||||
|
p.putnum(center+3, ymin+1, 0)
|
||||||
|
p.moveto(xmin+1, ymin)
|
||||||
|
|
||||||
|
pub update_position
|
||||||
|
x += xvel
|
||||||
|
y += yvel
|
||||||
|
if y < ymin
|
||||||
|
y := ymin - y
|
||||||
|
yvel := 0 - yvel
|
||||||
|
c.putchar(7)
|
||||||
|
elseif y > ymax
|
||||||
|
y := 2 * ymax - y
|
||||||
|
yvel := 0 - yvel
|
||||||
|
c.putchar(7)
|
||||||
|
|
||||||
|
pub check_score
|
||||||
|
if x < xmin
|
||||||
|
if y =< left + height and y => left - height
|
||||||
|
x := xmin - x
|
||||||
|
xvel := 0 - xvel
|
||||||
|
c.putchar(7)
|
||||||
|
else
|
||||||
|
scoreit(1)
|
||||||
|
elseif x > xmax
|
||||||
|
if y =< right + height and y => right - height
|
||||||
|
x := 2 * xmax - x
|
||||||
|
xvel := 0 - xvel
|
||||||
|
c.putchar(7)
|
||||||
|
else
|
||||||
|
scoreit(0)
|
||||||
|
if y =< left + height and y => left - height
|
||||||
|
|
||||||
|
pub check_input | val
|
||||||
|
repeat while p.kbhit
|
||||||
|
val := c.getchar
|
||||||
|
if val == "x"
|
||||||
|
c.putchar(0)
|
||||||
|
c.setconfig(config)
|
||||||
|
c.exit(0)
|
||||||
|
if val == "q"
|
||||||
|
move_left_up
|
||||||
|
move_left_up
|
||||||
|
if val == "a"
|
||||||
|
move_left_down
|
||||||
|
move_left_down
|
||||||
|
if val == "p"
|
||||||
|
move_right_up
|
||||||
|
move_right_up
|
||||||
|
if val == "l"
|
||||||
|
move_right_down
|
||||||
|
move_right_down
|
||||||
|
|
||||||
|
pub move_left_up
|
||||||
|
if left > ymin + height
|
||||||
|
p.plotit(xmin-1, left + height, " ")
|
||||||
|
left--
|
||||||
|
p.plotit(xmin-1, left - height, "#")
|
||||||
|
|
||||||
|
pub move_left_down
|
||||||
|
if left < ymax - height
|
||||||
|
p.plotit(xmin-1, left - height, " ")
|
||||||
|
left++
|
||||||
|
p.plotit(xmin-1, left + height, "#")
|
||||||
|
|
||||||
|
pub move_right_up
|
||||||
|
if right > ymin + height
|
||||||
|
p.plotit(xmax+1, right + height, " ")
|
||||||
|
right--
|
||||||
|
p.plotit(xmax+1, right - height, "#")
|
||||||
|
|
||||||
|
pub move_right_down
|
||||||
|
if right < ymax - height
|
||||||
|
p.plotit(xmax+1, right - height, " ")
|
||||||
|
right++
|
||||||
|
p.plotit(xmax+1, right + height, "#")
|
||||||
|
|
||||||
|
pub scoreit(player)
|
||||||
|
if player
|
||||||
|
score1++
|
||||||
|
p.putnum(center+3, ymin+1, score1)
|
||||||
|
if right > (ymin+ymax)/2
|
||||||
|
y := right - height - 3
|
||||||
|
else
|
||||||
|
y := right + height + 3
|
||||||
|
x := xmax + 1
|
||||||
|
xvel := 0 - 1
|
||||||
|
else
|
||||||
|
score0++
|
||||||
|
p.putnum(center-8, ymin+1, score0)
|
||||||
|
if left > (ymin+ymax)/2
|
||||||
|
y := left - height - 3
|
||||||
|
else
|
||||||
|
y := left + height + 3
|
||||||
|
x := xmin - 1
|
||||||
|
xvel := 1
|
||||||
|
yvel := 1
|
||||||
|
p.updatevars(ymin, center, score0, score1)
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
OBJ
|
||||||
|
c : "clibsd"
|
||||||
|
|
||||||
|
dat
|
||||||
|
score0 long 0
|
||||||
|
score1 long 0
|
||||||
|
ymin long 0
|
||||||
|
center long 0
|
||||||
|
|
||||||
|
pub splash
|
||||||
|
c.putchar(0)
|
||||||
|
c.printf0(string("PONG\n"))
|
||||||
|
c.printf0(string("----\n"))
|
||||||
|
c.printf0(string("Press 'q' and 'a' to move the"))
|
||||||
|
c.printf0(string(" left paddle up and down\n"))
|
||||||
|
c.printf0(string("Press 'p' and 'l' to move the"))
|
||||||
|
c.printf0(string(" right paddle up and down\n"))
|
||||||
|
c.printf0(string("Press 'x' to exit\n"))
|
||||||
|
c.printf0(string("Press any key to start\n"))
|
||||||
|
c.getchar
|
||||||
|
|
||||||
|
pub updatevars(p_ymin, p_center, p_score0, p_score1)
|
||||||
|
ymin := p_ymin
|
||||||
|
center := p_center
|
||||||
|
score0 := p_score0
|
||||||
|
score1 := p_score1
|
||||||
|
|
||||||
|
pub plotit(xpos, ypos, val)
|
||||||
|
moveto(xpos, ypos)
|
||||||
|
c.putchar(val)
|
||||||
|
|
||||||
|
pub moveto(xpos, ypos)
|
||||||
|
c.putchar(2)
|
||||||
|
c.putchar(xpos)
|
||||||
|
c.putchar(ypos)
|
||||||
|
|
||||||
|
pub kbhit | stream, handle, rxhead, rxtail
|
||||||
|
stream := c.getstdin
|
||||||
|
handle := long[stream][1]
|
||||||
|
rxhead := word[handle][6]
|
||||||
|
rxtail := word[handle][7]
|
||||||
|
return rxhead <> rxtail
|
||||||
|
|
||||||
|
dat
|
||||||
|
digit
|
||||||
|
byte %111111, %110011, %110011, %110011, %111111
|
||||||
|
byte %001100, %011100, %001100, %001100, %011110
|
||||||
|
byte %111111, %000011, %111111, %110000, %111111
|
||||||
|
byte %111111, %000011, %001111, %000011, %111111
|
||||||
|
byte %110011, %110011, %111111, %000011, %000011
|
||||||
|
byte %111111, %110000, %111111, %000011, %111111
|
||||||
|
byte %111111, %110000, %111111, %110011, %111111
|
||||||
|
byte %111111, %000011, %000110, %000110, %000110
|
||||||
|
byte %111111, %110011, %111111, %110011, %111111
|
||||||
|
byte %111111, %110011, %111111, %000011, %000011
|
||||||
|
|
||||||
|
pub getval(xpos, ypos) | ptr, val
|
||||||
|
if xpos == center
|
||||||
|
return "."
|
||||||
|
if ypos < ymin + 1 or ypos > ymin + 5
|
||||||
|
return " "
|
||||||
|
if xpos < center - 8 or xpos > center + 8
|
||||||
|
return " "
|
||||||
|
if xpos > center - 3 and xpos < center + 3
|
||||||
|
return " "
|
||||||
|
if xpos < center
|
||||||
|
val := score0
|
||||||
|
xpos -= center - 8
|
||||||
|
else
|
||||||
|
val := score1
|
||||||
|
xpos -= center + 3
|
||||||
|
val := byte[@digit][val*5 + ypos - ymin - 1]
|
||||||
|
if val & ($20 >> xpos)
|
||||||
|
result := "#"
|
||||||
|
else
|
||||||
|
result := " "
|
||||||
|
|
||||||
|
pub putnum(xpos, ypos, num) | ptr, temp, i, j
|
||||||
|
i := 5
|
||||||
|
ptr := @digit + (num//10)*5
|
||||||
|
repeat while i--
|
||||||
|
j := 6
|
||||||
|
temp := byte[ptr++]
|
||||||
|
moveto(xpos, ypos++)
|
||||||
|
repeat while j--
|
||||||
|
if temp & $20
|
||||||
|
c.putchar("#")
|
||||||
|
else
|
||||||
|
c.putchar(" ")
|
||||||
|
temp <<= 1
|
||||||
|
|
||||||
|
pub plotpaddle(xpos, ypos, height) | i
|
||||||
|
i := ypos - height
|
||||||
|
repeat while i =< ypos + height
|
||||||
|
plotit(xpos, i, "#")
|
||||||
|
i++
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
con
|
||||||
|
_clkmode = $62
|
||||||
|
_clkfreq = $4E495053 ' SPIN
|
||||||
|
|
||||||
|
obj
|
||||||
|
c : "clibsd"
|
||||||
|
|
||||||
|
dat
|
||||||
|
primes long $00020001, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
last long 0
|
||||||
|
|
||||||
|
pub main(argc, argv) | i, j, n, num, maxnum, count, prime
|
||||||
|
|
||||||
|
c.enter(argc, argv)
|
||||||
|
|
||||||
|
if argc <> 2
|
||||||
|
c.printf0(string("usage: prime max_number\n"))
|
||||||
|
c.exit(1)
|
||||||
|
|
||||||
|
maxnum := 0
|
||||||
|
i := long[argv][1]
|
||||||
|
repeat while byte[i]
|
||||||
|
maxnum := (maxnum * 10) + byte[i++] - "0"
|
||||||
|
|
||||||
|
c.printf1(string("%d "), 1)
|
||||||
|
c.printf1(string("%d "), 2)
|
||||||
|
|
||||||
|
num := (@last - @primes)/2
|
||||||
|
n := 2
|
||||||
|
i := 3
|
||||||
|
count := 2
|
||||||
|
repeat while i < maxnum
|
||||||
|
j := 2
|
||||||
|
repeat while j < n
|
||||||
|
prime := word[@primes][j]
|
||||||
|
if prime * prime > i
|
||||||
|
j := n
|
||||||
|
quit
|
||||||
|
if i / prime * prime == i
|
||||||
|
quit
|
||||||
|
j++
|
||||||
|
if j == n
|
||||||
|
if n < num
|
||||||
|
word[@primes][n++] := i
|
||||||
|
if n == num and i * i < maxnum
|
||||||
|
maxnum := i * i
|
||||||
|
c.printf1(string("%d "), i)
|
||||||
|
if ++count => 10
|
||||||
|
count := 0
|
||||||
|
c.printf0(string("\n"))
|
||||||
|
i += 2
|
||||||
|
if count
|
||||||
|
c.printf0(string("\n"))
|
||||||
|
c.exit(0)
|
|
@ -0,0 +1,47 @@
|
||||||
|
This directory contains sample Spin programs that can be compiled by the Spin
|
||||||
|
development tools. These tools consist of spinit, spasm, splink and spc.
|
||||||
|
|
||||||
|
spinit is a Spin compiler that produces Spin assmebly (spasm) code. It is
|
||||||
|
executed as follows:
|
||||||
|
|
||||||
|
spinit hello.spn
|
||||||
|
|
||||||
|
This will generate the Spasm source file, hello.spa. The Spasm assmebler
|
||||||
|
is executed as follows:
|
||||||
|
|
||||||
|
spasm hello.spa
|
||||||
|
|
||||||
|
This will assemble the hello.spa Spasm source file, and generate the
|
||||||
|
output file hello.bin. The hello programs uses the clibsd object. An
|
||||||
|
executable file can be created by linking hello.bin with clibsd.bin using
|
||||||
|
the Spin linke, splink. This is done as follows:
|
||||||
|
|
||||||
|
splink hello.bin clibsd.bin hello
|
||||||
|
|
||||||
|
You can then run hello as a normal Spinix program.
|
||||||
|
|
||||||
|
An assembly listing can be produced by using the -l option, as follows:
|
||||||
|
|
||||||
|
spasm -l hello.spa
|
||||||
|
|
||||||
|
When running spinit and spasm, the file extensions are optional, and are
|
||||||
|
assumed to be .spn and .spa if not specified.
|
||||||
|
|
||||||
|
A Spin program can be compiled into an executable with one command by using
|
||||||
|
the spc command. The hello pragram can be built by typing
|
||||||
|
|
||||||
|
spc hello
|
||||||
|
|
||||||
|
The will run spinit, spasm and splink.
|
||||||
|
|
||||||
|
This directory contains the following sample programs:
|
||||||
|
|
||||||
|
hello - Hello World Program
|
||||||
|
fibo - A Spin version of the PropGCC fibo program
|
||||||
|
prime - A program that prints prime numbers
|
||||||
|
pong - A simple pong program developed entirely under spinix
|
||||||
|
pongsubs - Object used by pong
|
||||||
|
|
||||||
|
The pong program can be built using the script makepong.all. The pongsubs
|
||||||
|
object can be built and linked to clibsd using makepong.sub. makepong will
|
||||||
|
compile pong and link it to the combined pongsubs/clibsd object.
|
|
@ -0,0 +1,20 @@
|
||||||
|
CC=propeller-elf-gcc
|
||||||
|
MODEL=lmm
|
||||||
|
CFLAGS=-Os -m$(MODEL)
|
||||||
|
LDFLAGS=-m$(MODEL)
|
||||||
|
OBJDIR=./
|
||||||
|
SRCDIR=./
|
||||||
|
|
||||||
|
OBJS = filetest.o printf.o spinix.o file_io.o
|
||||||
|
HDRS =
|
||||||
|
|
||||||
|
filetest.elf: $(OBJS)
|
||||||
|
@$(CC) $(LDFLAGS) $(OBJS) -o $@ -s
|
||||||
|
binary:
|
||||||
|
propeller-load -s -D clkfreq=1347436867 -D clkmode=98 filetest.elf
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.elf *.binary
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(HDRS)
|
||||||
|
@$(CC) $(CFLAGS) -c $< -o $@
|
|
@ -0,0 +1,394 @@
|
||||||
|
/*
|
||||||
|
DOSFS Embedded FAT-Compatible Filesystem
|
||||||
|
(C) 2005 Lewin A.R.W. Edwards (sysadm@zws.com)
|
||||||
|
11/5/2011 Added PROPGCC_MODS and DFS_DIRECTORY - Dave Hein
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DOSFS_H
|
||||||
|
#define _DOSFS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PROPGCC_MODS /* This flag is used to enable changes for PropGCC */
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// User-supplied functions
|
||||||
|
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count);
|
||||||
|
uint32_t DFS_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count);
|
||||||
|
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// Configurable items
|
||||||
|
#define MAX_PATH 64 // Maximum path length (increasing this will
|
||||||
|
// GREATLY increase stack requirements!)
|
||||||
|
#define DIR_SEPARATOR '/' // character separating directory components
|
||||||
|
|
||||||
|
// End of configurable items
|
||||||
|
//===================================================================
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// 32-bit error codes
|
||||||
|
#define DFS_OK 0 // no error
|
||||||
|
#define DFS_EOF 1 // end of file (not an error)
|
||||||
|
#define DFS_WRITEPROT 2 // volume is write protected
|
||||||
|
#define DFS_NOTFOUND 3 // path or file not found
|
||||||
|
#define DFS_PATHLEN 4 // path too long
|
||||||
|
#define DFS_ALLOCNEW 5 // must allocate new directory cluster
|
||||||
|
#define DFS_IOERR 6 // i/o error
|
||||||
|
#define DFS_INVAL 7 // invalid argument
|
||||||
|
#define DFS_ERRMISC 0xffffffff // generic error
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// File access modes
|
||||||
|
#define DFS_READ 1 // read-only
|
||||||
|
#define DFS_WRITE 2 // write-only
|
||||||
|
#ifdef PROPGCC_MODS
|
||||||
|
#define DFS_DIRECTORY 0x10 // directory-mode
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// Miscellaneous constants
|
||||||
|
#define SECTOR_SIZE 512 // sector size in bytes
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// Internal subformat identifiers
|
||||||
|
#define FAT12 0
|
||||||
|
#define FAT16 1
|
||||||
|
#define FAT32 2
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// DOS attribute bits
|
||||||
|
#define ATTR_READ_ONLY 0x01
|
||||||
|
#define ATTR_HIDDEN 0x02
|
||||||
|
#define ATTR_SYSTEM 0x04
|
||||||
|
#define ATTR_VOLUME_ID 0x08
|
||||||
|
#define ATTR_DIRECTORY 0x10
|
||||||
|
#define ATTR_ARCHIVE 0x20
|
||||||
|
#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Directory entry structure
|
||||||
|
note: if name[0] == 0xe5, this is a free dir entry
|
||||||
|
if name[0] == 0x00, this is a free entry and all subsequent entries are free
|
||||||
|
if name[0] == 0x05, the first character of the name is 0xe5 [a kanji nicety]
|
||||||
|
|
||||||
|
Date format: bit 0-4 = day of month (1-31)
|
||||||
|
bit 5-8 = month, 1=Jan..12=Dec
|
||||||
|
bit 9-15 = count of years since 1980 (0-127)
|
||||||
|
Time format: bit 0-4 = 2-second count, (0-29)
|
||||||
|
bit 5-10 = minutes (0-59)
|
||||||
|
bit 11-15= hours (0-23)
|
||||||
|
*/
|
||||||
|
typedef struct _tagDIRENT {
|
||||||
|
uint8_t name[11]; // filename
|
||||||
|
uint8_t attr; // attributes (see ATTR_* constant definitions)
|
||||||
|
uint8_t reserved; // reserved, must be 0
|
||||||
|
uint8_t crttimetenth; // create time, 10ths of a second (0-199 are valid)
|
||||||
|
uint8_t crttime_l; // creation time low byte
|
||||||
|
uint8_t crttime_h; // creation time high byte
|
||||||
|
uint8_t crtdate_l; // creation date low byte
|
||||||
|
uint8_t crtdate_h; // creation date high byte
|
||||||
|
uint8_t lstaccdate_l; // last access date low byte
|
||||||
|
uint8_t lstaccdate_h; // last access date high byte
|
||||||
|
uint8_t startclus_h_l; // high word of first cluster, low byte (FAT32)
|
||||||
|
uint8_t startclus_h_h; // high word of first cluster, high byte (FAT32)
|
||||||
|
uint8_t wrttime_l; // last write time low byte
|
||||||
|
uint8_t wrttime_h; // last write time high byte
|
||||||
|
uint8_t wrtdate_l; // last write date low byte
|
||||||
|
uint8_t wrtdate_h; // last write date high byte
|
||||||
|
uint8_t startclus_l_l; // low word of first cluster, low byte
|
||||||
|
uint8_t startclus_l_h; // low word of first cluster, high byte
|
||||||
|
uint8_t filesize_0; // file size, low byte
|
||||||
|
uint8_t filesize_1; //
|
||||||
|
uint8_t filesize_2; //
|
||||||
|
uint8_t filesize_3; // file size, high byte
|
||||||
|
} DIRENT, *PDIRENT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Partition table entry structure
|
||||||
|
*/
|
||||||
|
typedef struct _tagPTINFO {
|
||||||
|
uint8_t active; // 0x80 if partition active
|
||||||
|
uint8_t start_h; // starting head
|
||||||
|
uint8_t start_cs_l; // starting cylinder and sector (low byte)
|
||||||
|
uint8_t start_cs_h; // starting cylinder and sector (high byte)
|
||||||
|
uint8_t type; // type ID byte
|
||||||
|
uint8_t end_h; // ending head
|
||||||
|
uint8_t end_cs_l; // ending cylinder and sector (low byte)
|
||||||
|
uint8_t end_cs_h; // ending cylinder and sector (high byte)
|
||||||
|
uint8_t start_0; // starting sector# (low byte)
|
||||||
|
uint8_t start_1; //
|
||||||
|
uint8_t start_2; //
|
||||||
|
uint8_t start_3; // starting sector# (high byte)
|
||||||
|
uint8_t size_0; // size of partition (low byte)
|
||||||
|
uint8_t size_1; //
|
||||||
|
uint8_t size_2; //
|
||||||
|
uint8_t size_3; // size of partition (high byte)
|
||||||
|
} PTINFO, *PPTINFO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Master Boot Record structure
|
||||||
|
*/
|
||||||
|
typedef struct _tagMBR {
|
||||||
|
uint8_t bootcode[0x1be]; // boot sector
|
||||||
|
PTINFO ptable[4]; // four partition table structures
|
||||||
|
uint8_t sig_55; // 0x55 signature byte
|
||||||
|
uint8_t sig_aa; // 0xaa signature byte
|
||||||
|
} MBR, *PMBR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
BIOS Parameter Block structure (FAT12/16)
|
||||||
|
*/
|
||||||
|
typedef struct _tagBPB {
|
||||||
|
uint8_t bytepersec_l; // bytes per sector low byte (0x00)
|
||||||
|
uint8_t bytepersec_h; // bytes per sector high byte (0x02)
|
||||||
|
uint8_t secperclus; // sectors per cluster (1,2,4,8,16,32,64,128 are valid)
|
||||||
|
uint8_t reserved_l; // reserved sectors low byte
|
||||||
|
uint8_t reserved_h; // reserved sectors high byte
|
||||||
|
uint8_t numfats; // number of FAT copies (2)
|
||||||
|
uint8_t rootentries_l; // number of root dir entries low byte (0x00 normally)
|
||||||
|
uint8_t rootentries_h; // number of root dir entries high byte (0x02 normally)
|
||||||
|
uint8_t sectors_s_l; // small num sectors low byte
|
||||||
|
uint8_t sectors_s_h; // small num sectors high byte
|
||||||
|
uint8_t mediatype; // media descriptor byte
|
||||||
|
uint8_t secperfat_l; // sectors per FAT low byte
|
||||||
|
uint8_t secperfat_h; // sectors per FAT high byte
|
||||||
|
uint8_t secpertrk_l; // sectors per track low byte
|
||||||
|
uint8_t secpertrk_h; // sectors per track high byte
|
||||||
|
uint8_t heads_l; // heads low byte
|
||||||
|
uint8_t heads_h; // heads high byte
|
||||||
|
uint8_t hidden_0; // hidden sectors low byte
|
||||||
|
uint8_t hidden_1; // (note - this is the number of MEDIA sectors before
|
||||||
|
uint8_t hidden_2; // first sector of VOLUME - we rely on the MBR instead)
|
||||||
|
uint8_t hidden_3; // hidden sectors high byte
|
||||||
|
uint8_t sectors_l_0; // large num sectors low byte
|
||||||
|
uint8_t sectors_l_1; //
|
||||||
|
uint8_t sectors_l_2; //
|
||||||
|
uint8_t sectors_l_3; // large num sectors high byte
|
||||||
|
} BPB, *PBPB;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extended BIOS Parameter Block structure (FAT12/16)
|
||||||
|
*/
|
||||||
|
typedef struct _tagEBPB {
|
||||||
|
uint8_t unit; // int 13h drive#
|
||||||
|
uint8_t head; // archaic, used by Windows NT-class OSes for flags
|
||||||
|
uint8_t signature; // 0x28 or 0x29
|
||||||
|
uint8_t serial_0; // serial#
|
||||||
|
uint8_t serial_1; // serial#
|
||||||
|
uint8_t serial_2; // serial#
|
||||||
|
uint8_t serial_3; // serial#
|
||||||
|
uint8_t label[11]; // volume label
|
||||||
|
uint8_t system[8]; // filesystem ID
|
||||||
|
} EBPB, *PEBPB;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extended BIOS Parameter Block structure (FAT32)
|
||||||
|
*/
|
||||||
|
typedef struct _tagEBPB32 {
|
||||||
|
uint8_t fatsize_0; // big FAT size in sectors low byte
|
||||||
|
uint8_t fatsize_1; //
|
||||||
|
uint8_t fatsize_2; //
|
||||||
|
uint8_t fatsize_3; // big FAT size in sectors high byte
|
||||||
|
uint8_t extflags_l; // extended flags low byte
|
||||||
|
uint8_t extflags_h; // extended flags high byte
|
||||||
|
uint8_t fsver_l; // filesystem version (0x00) low byte
|
||||||
|
uint8_t fsver_h; // filesystem version (0x00) high byte
|
||||||
|
uint8_t root_0; // cluster of root dir, low byte
|
||||||
|
uint8_t root_1; //
|
||||||
|
uint8_t root_2; //
|
||||||
|
uint8_t root_3; // cluster of root dir, high byte
|
||||||
|
uint8_t fsinfo_l; // sector pointer to FSINFO within reserved area, low byte (2)
|
||||||
|
uint8_t fsinfo_h; // sector pointer to FSINFO within reserved area, high byte (0)
|
||||||
|
uint8_t bkboot_l; // sector pointer to backup boot sector within reserved area, low byte (6)
|
||||||
|
uint8_t bkboot_h; // sector pointer to backup boot sector within reserved area, high byte (0)
|
||||||
|
uint8_t reserved[12]; // reserved, should be 0
|
||||||
|
|
||||||
|
uint8_t unit; // int 13h drive#
|
||||||
|
uint8_t head; // archaic, used by Windows NT-class OSes for flags
|
||||||
|
uint8_t signature; // 0x28 or 0x29
|
||||||
|
uint8_t serial_0; // serial#
|
||||||
|
uint8_t serial_1; // serial#
|
||||||
|
uint8_t serial_2; // serial#
|
||||||
|
uint8_t serial_3; // serial#
|
||||||
|
uint8_t label[11]; // volume label
|
||||||
|
uint8_t system[8]; // filesystem ID
|
||||||
|
} EBPB32, *PEBPB32;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Logical Boot Record structure (volume boot sector)
|
||||||
|
*/
|
||||||
|
typedef struct _tagLBR {
|
||||||
|
uint8_t jump[3]; // JMP instruction
|
||||||
|
uint8_t oemid[8]; // OEM ID, space-padded
|
||||||
|
BPB bpb; // BIOS Parameter Block
|
||||||
|
union {
|
||||||
|
EBPB ebpb; // FAT12/16 Extended BIOS Parameter Block
|
||||||
|
EBPB32 ebpb32; // FAT32 Extended BIOS Parameter Block
|
||||||
|
} ebpb;
|
||||||
|
uint8_t code[420]; // boot sector code
|
||||||
|
uint8_t sig_55; // 0x55 signature byte
|
||||||
|
uint8_t sig_aa; // 0xaa signature byte
|
||||||
|
} LBR, *PLBR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Volume information structure (Internal to DOSFS)
|
||||||
|
*/
|
||||||
|
typedef struct _tagVOLINFO {
|
||||||
|
uint8_t unit; // unit on which this volume resides
|
||||||
|
uint8_t filesystem; // formatted filesystem
|
||||||
|
|
||||||
|
// These two fields aren't very useful, so support for them has been commented out to
|
||||||
|
// save memory. (Note that the "system" tag is not actually used by DOS to determine
|
||||||
|
// filesystem type - that decision is made entirely on the basis of how many clusters
|
||||||
|
// the drive contains. DOSFS works the same way).
|
||||||
|
// See tag: OEMID in dosfs.c
|
||||||
|
// uint8_t oemid[9]; // OEM ID ASCIIZ
|
||||||
|
// uint8_t system[9]; // system ID ASCIIZ
|
||||||
|
uint8_t label[12]; // volume label ASCIIZ
|
||||||
|
uint32_t startsector; // starting sector of filesystem
|
||||||
|
uint8_t secperclus; // sectors per cluster
|
||||||
|
uint16_t reservedsecs; // reserved sectors
|
||||||
|
uint32_t numsecs; // number of sectors in volume
|
||||||
|
uint32_t secperfat; // sectors per FAT
|
||||||
|
uint16_t rootentries; // number of root dir entries
|
||||||
|
|
||||||
|
uint32_t numclusters; // number of clusters on drive
|
||||||
|
|
||||||
|
// The fields below are PHYSICAL SECTOR NUMBERS.
|
||||||
|
uint32_t fat1; // starting sector# of FAT copy 1
|
||||||
|
uint32_t rootdir; // starting sector# of root directory (FAT12/FAT16) or cluster (FAT32)
|
||||||
|
uint32_t dataarea; // starting sector# of data area (cluster #2)
|
||||||
|
} VOLINFO, *PVOLINFO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Flags in DIRINFO.flags
|
||||||
|
*/
|
||||||
|
#define DFS_DI_BLANKENT 0x01 // Searching for blank entry
|
||||||
|
|
||||||
|
/*
|
||||||
|
Directory search structure (Internal to DOSFS)
|
||||||
|
*/
|
||||||
|
typedef struct _tagDIRINFO {
|
||||||
|
uint32_t startcluster; // first cluster in dir
|
||||||
|
uint32_t currentcluster; // current cluster in dir
|
||||||
|
uint8_t currentsector; // current sector in cluster
|
||||||
|
uint8_t currententry; // current dir entry in sector
|
||||||
|
uint8_t *scratch; // ptr to user-supplied scratch buffer (one sector)
|
||||||
|
uint8_t flags; // internal DOSFS flags
|
||||||
|
} DIRINFO, *PDIRINFO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
File handle structure (Internal to DOSFS)
|
||||||
|
*/
|
||||||
|
typedef struct _tagFILEINFO {
|
||||||
|
PVOLINFO volinfo; // VOLINFO used to open this file
|
||||||
|
uint32_t dirsector; // physical sector containing dir entry of this file
|
||||||
|
uint8_t diroffset; // # of this entry within the dir sector
|
||||||
|
uint8_t mode; // mode in which this file was opened
|
||||||
|
uint32_t firstcluster; // first cluster of file
|
||||||
|
uint32_t filelen; // byte length of file
|
||||||
|
|
||||||
|
uint32_t cluster; // current cluster
|
||||||
|
uint32_t pointer; // current (BYTE) pointer
|
||||||
|
uint32_t parentcluster; // first cluster of parent dir
|
||||||
|
} FILEINFO, *PFILEINFO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set the Date and Time in a DIRENT to the Default Date and Time.
|
||||||
|
*/
|
||||||
|
void DFS_SetDirEntDateTime(PDIRENT pde);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set the Cluster in a DIRENT
|
||||||
|
*/
|
||||||
|
void DFS_SetStartCluster(PDIRENT pde, uint32_t cluster);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get starting sector# of specified partition on drive #unit
|
||||||
|
NOTE: This code ASSUMES an MBR on the disk.
|
||||||
|
scratchsector should point to a SECTOR_SIZE scratch area
|
||||||
|
Returns 0xffffffff for any error.
|
||||||
|
If pactive is non-NULL, this function also returns the partition active flag.
|
||||||
|
If pptype is non-NULL, this function also returns the partition type.
|
||||||
|
If psize is non-NULL, this function also returns the partition size.
|
||||||
|
*/
|
||||||
|
uint32_t DFS_GetPtnStart(uint8_t unit, uint8_t *scratchsector, uint8_t pnum, uint8_t *pactive, uint8_t *pptype, uint32_t *psize);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Retrieve volume info from BPB and store it in a VOLINFO structure
|
||||||
|
You must provide the unit and starting sector of the filesystem, and
|
||||||
|
a pointer to a sector buffer for scratch
|
||||||
|
Attempts to read BPB and glean information about the FS from that.
|
||||||
|
Returns 0 OK, nonzero for any error.
|
||||||
|
*/
|
||||||
|
uint32_t DFS_GetVolInfo(uint8_t unit, uint8_t *scratchsector, uint32_t startsector, PVOLINFO volinfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open a directory for enumeration by DFS_GetNextDirEnt
|
||||||
|
You must supply a populated VOLINFO (see DFS_GetVolInfo)
|
||||||
|
The empty string or a string containing only the directory separator are
|
||||||
|
considered to be the root directory.
|
||||||
|
Returns 0 OK, nonzero for any error.
|
||||||
|
*/
|
||||||
|
uint32_t DFS_OpenDir(PVOLINFO volinfo, uint8_t *dirname, PDIRINFO dirinfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get next entry in opened directory structure. Copies fields into the dirent
|
||||||
|
structure, updates dirinfo. Note that it is the _caller's_ responsibility to
|
||||||
|
handle the '.' and '..' entries.
|
||||||
|
A deleted file will be returned as a NULL entry (first char of filename=0)
|
||||||
|
by this code. Filenames beginning with 0x05 will be translated to 0xE5
|
||||||
|
automatically. Long file name entries will be returned as NULL.
|
||||||
|
returns DFS_EOF if there are no more entries, DFS_OK if this entry is valid,
|
||||||
|
or DFS_ERRMISC for a media error
|
||||||
|
*/
|
||||||
|
uint32_t DFS_GetNext(PVOLINFO volinfo, PDIRINFO dirinfo, PDIRENT dirent);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open a file for reading or writing. You supply populated VOLINFO, a path to the file,
|
||||||
|
mode (DFS_READ or DFS_WRITE) and an empty fileinfo structure. You also need to
|
||||||
|
provide a pointer to a sector-sized scratch buffer.
|
||||||
|
Returns various DFS_* error states. If the result is DFS_OK, fileinfo can be used
|
||||||
|
to access the file from this point on.
|
||||||
|
*/
|
||||||
|
uint32_t DFS_OpenFile(PVOLINFO volinfo, uint8_t *path, uint8_t mode, uint8_t *scratch, PFILEINFO fileinfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Read an open file
|
||||||
|
You must supply a prepopulated FILEINFO as provided by DFS_OpenFile, and a
|
||||||
|
pointer to a SECTOR_SIZE scratch buffer.
|
||||||
|
Note that returning DFS_EOF is not an error condition. This function updates the
|
||||||
|
successcount field with the number of bytes actually read.
|
||||||
|
*/
|
||||||
|
uint32_t DFS_ReadFile(PFILEINFO fileinfo, uint8_t *scratch, uint8_t *buffer, uint32_t *successcount, uint32_t len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write an open file
|
||||||
|
You must supply a prepopulated FILEINFO as provided by DFS_OpenFile, and a
|
||||||
|
pointer to a SECTOR_SIZE scratch buffer.
|
||||||
|
This function updates the successcount field with the number of bytes actually written.
|
||||||
|
*/
|
||||||
|
uint32_t DFS_WriteFile(PFILEINFO fileinfo, uint8_t *scratch, uint8_t *buffer, uint32_t *successcount, uint32_t len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Seek file pointer to a given position
|
||||||
|
This function does not return status - refer to the fileinfo->pointer value
|
||||||
|
to see where the pointer wound up.
|
||||||
|
Requires a SECTOR_SIZE scratch buffer
|
||||||
|
*/
|
||||||
|
void DFS_Seek(PFILEINFO fileinfo, uint32_t offset, uint8_t *scratch);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete a file
|
||||||
|
scratch must point to a sector-sized buffer
|
||||||
|
*/
|
||||||
|
uint32_t DFS_UnlinkFile(PVOLINFO volinfo, uint8_t *path, uint8_t *scratch);
|
||||||
|
|
||||||
|
// If we are building a host-emulation version, include host support
|
||||||
|
#ifdef HOSTVER
|
||||||
|
#include "hostemu.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _DOSFS_H
|
|
@ -0,0 +1,87 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
#include "varsubs.h"
|
||||||
|
|
||||||
|
static char retvalstr[16];
|
||||||
|
|
||||||
|
void sprintdec(char *str, int val)
|
||||||
|
{
|
||||||
|
int scale;
|
||||||
|
int zeroflag = 0;
|
||||||
|
|
||||||
|
if (val < 0)
|
||||||
|
{
|
||||||
|
*str++ = '-';
|
||||||
|
val = -val;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (scale = 1000000000; scale > 1; scale /= 10)
|
||||||
|
{
|
||||||
|
if (val >= scale)
|
||||||
|
{
|
||||||
|
*str++ = '0' + val/scale;
|
||||||
|
val %= scale;
|
||||||
|
zeroflag = 1;
|
||||||
|
}
|
||||||
|
else if (zeroflag)
|
||||||
|
*str++ = '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
*str++ = '0' + val;
|
||||||
|
*str = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *varsubs_FindVar(char *str)
|
||||||
|
{
|
||||||
|
char *ptr = (char *)spinix_environ_vars;
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
if (!strcmp(str, ptr + 1))
|
||||||
|
{
|
||||||
|
if (*ptr != varsubs_ALIAS_FLAG)
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *varsubs_GetVarVal(char *name)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
if (!strcmp(name, "?"))
|
||||||
|
{
|
||||||
|
sprintdec(retvalstr, *(int *)spinix_return_value);
|
||||||
|
return retvalstr;
|
||||||
|
}
|
||||||
|
if ((ptr = varsubs_FindVar(name)))
|
||||||
|
{
|
||||||
|
return ptr + strlen(ptr) + 1;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void enter(void)
|
||||||
|
{
|
||||||
|
char *mode;
|
||||||
|
char *ptr = varsubs_GetVarVal("PWD");
|
||||||
|
if (ptr) chdir(ptr);
|
||||||
|
ptr = varsubs_GetVarVal("<");
|
||||||
|
if (*ptr)
|
||||||
|
printf("stdin = %s\n", ptr);
|
||||||
|
ptr = varsubs_GetVarVal(">");
|
||||||
|
if (*ptr)
|
||||||
|
mode = ">";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr = varsubs_GetVarVal(">>");
|
||||||
|
if (*ptr)
|
||||||
|
mode = ">>";
|
||||||
|
}
|
||||||
|
printf("stdout = %s %s\n", mode, ptr);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
# #########################################################
|
||||||
|
# This file contains the SD driver code for the C3
|
||||||
|
# Propeller board. It contains the low-level three file
|
||||||
|
# system routines, which are DFS_InitFileIO, DFS_ReadSector
|
||||||
|
# and DFS_WriteSector.
|
||||||
|
#
|
||||||
|
# Written by Dave Hein with contributions from other GCC
|
||||||
|
# development team members.
|
||||||
|
# Copyright (c) 2011 Parallax, Inc.
|
||||||
|
# MIT Licensed
|
||||||
|
# #########################################################
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/driver.h>
|
||||||
|
#include <compiler.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <propeller.h>
|
||||||
|
#include "sd_internal.h"
|
||||||
|
|
||||||
|
#define SD_INIT_CMD 0x0d
|
||||||
|
#define SD_READ_CMD 0x11
|
||||||
|
#define SD_WRITE_CMD 0x15
|
||||||
|
#define BUS_LOCK_CMD 0x1D
|
||||||
|
|
||||||
|
static volatile uint32_t __attribute__((section(".hub"))) sd_lock = -1;
|
||||||
|
static volatile uint32_t __attribute__((section(".hub"))) *sd_mbox;
|
||||||
|
|
||||||
|
#if defined(__PROPELLER_XMM__) || defined(__PROPELLER_XMMC__)
|
||||||
|
#define USE_XMM_MBOX
|
||||||
|
extern uint16_t _xmm_mbox_p;
|
||||||
|
#endif
|
||||||
|
uint32_t *_sd_mbox_p = 0;
|
||||||
|
|
||||||
|
// This routine sends a command to the driver cog and returns the result
|
||||||
|
// It must be loaded in HUB RAM so we don't generate a cache miss
|
||||||
|
static uint32_t __attribute__((section(".hubtext"))) do_cmd(uint32_t *params)
|
||||||
|
{
|
||||||
|
//printf("%x %x %x %x\n", sd_mbox, params[0], params[1], params[2]);
|
||||||
|
sd_mbox[1] = params[1];
|
||||||
|
sd_mbox[2] = params[2];
|
||||||
|
sd_mbox[0] = params[0];
|
||||||
|
while (sd_mbox[0] == params[0]);
|
||||||
|
return sd_mbox[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// This routine passes a bus lock to the low-level driver
|
||||||
|
void dfs_use_lock(uint32_t lockId)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (sd_mbox)
|
||||||
|
do_cmd(BUS_LOCK_CMD | (lockId << 8));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
sd_lock = lockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This routine initializes the low-level driver
|
||||||
|
int DFS_InitFileIO(void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
int retries = 5;
|
||||||
|
|
||||||
|
#if !defined(USE_XMM_MBOX)
|
||||||
|
sd_mbox = _sd_mbox_p;
|
||||||
|
if (!_sd_mbox_p)
|
||||||
|
return DFS_INVAL;
|
||||||
|
#else
|
||||||
|
if (_sd_mbox_p)
|
||||||
|
sd_mbox = _sd_mbox_p;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sd_mbox = (uint32_t *)(uint32_t)_xmm_mbox_p;
|
||||||
|
retries = -1; // We're using the SD Cache driver - it's already initialized!
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Handle the case where we were given the lock before dfs_mount() was called.
|
||||||
|
if (sd_lock != -1)
|
||||||
|
dfs_use_lock(sd_lock);
|
||||||
|
|
||||||
|
while (retries-- > 0)
|
||||||
|
{
|
||||||
|
if (do_cmd(SD_INIT_CMD) == 0)
|
||||||
|
return DFS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DFS_IOERR;
|
||||||
|
#else
|
||||||
|
sd_mbox = (uint32_t *)0x7fd4;
|
||||||
|
return DFS_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// This routine reads 512-byte sectors into a buffer. If the buffer is
|
||||||
|
// not located in hub memory it reads the sectors into the scratch buffer,
|
||||||
|
// and then copies it to to the buffer.
|
||||||
|
uint32_t DFS_ReadSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count)
|
||||||
|
{
|
||||||
|
uint32_t params[3], result;
|
||||||
|
while (count > 0) {
|
||||||
|
if (((uint32_t)buffer) & 0xffff0000)
|
||||||
|
params[2] = (uint32_t)dfs_scratch;
|
||||||
|
else
|
||||||
|
params[2] = (uint32_t)buffer;
|
||||||
|
params[0] = 'r';
|
||||||
|
params[1] = sector;
|
||||||
|
result = do_cmd(params);
|
||||||
|
if (result != 0) {
|
||||||
|
return DFS_IOERR;
|
||||||
|
}
|
||||||
|
if (((uint32_t)buffer) & 0xffff0000)
|
||||||
|
memcpy(buffer, dfs_scratch, SECTOR_SIZE);
|
||||||
|
buffer += SECTOR_SIZE;
|
||||||
|
++sector;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DFS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This routine writes 512-byte sectors from a buffer. If the buffer is
|
||||||
|
// not located in hub memory the data is first copied to the scratch buffer,
|
||||||
|
// and then written from the scratch buffer.
|
||||||
|
uint32_t DFS_WriteSector(uint8_t unit, uint8_t *buffer, uint32_t sector, uint32_t count)
|
||||||
|
{
|
||||||
|
uint32_t params[3], result;
|
||||||
|
while (count > 0) {
|
||||||
|
if (((uint32_t)buffer) & 0xffff0000)
|
||||||
|
{
|
||||||
|
memcpy(dfs_scratch, buffer, SECTOR_SIZE);
|
||||||
|
params[2] = (uint32_t)dfs_scratch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
params[2] = (uint32_t)buffer;
|
||||||
|
params[0] = 'w';
|
||||||
|
params[1] = sector;
|
||||||
|
result = do_cmd(params);
|
||||||
|
if (result != 0) {
|
||||||
|
return DFS_IOERR;
|
||||||
|
}
|
||||||
|
buffer += SECTOR_SIZE;
|
||||||
|
++sector;
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
return DFS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSDDriver(uint32_t configwords[2])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
+--------------------------------------------------------------------
|
||||||
|
| TERMS OF USE: MIT License
|
||||||
|
+--------------------------------------------------------------------
|
||||||
|
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
+------------------------------------------------------------------
|
||||||
|
*/
|
|
@ -0,0 +1,505 @@
|
||||||
|
/*
|
||||||
|
############################################################################
|
||||||
|
# This program is used to test the basic functions of the SD file system.
|
||||||
|
# It implements simple versions of the cat, rm, ls, echo, cd, pwd, mkdir and
|
||||||
|
# rmdir commands plus the <, > and >> file redirection operators.
|
||||||
|
# The program starts up the file driver and then prompts for a command.
|
||||||
|
#
|
||||||
|
# Written by Dave Hein
|
||||||
|
# Copyright (c) 2011 Parallax, Inc.
|
||||||
|
# MIT Licensed
|
||||||
|
############################################################################
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <cog.h>
|
||||||
|
#include <propeller.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
|
||||||
|
extern _Driver _SimpleSerialDriver;
|
||||||
|
extern _Driver _FileDriver;
|
||||||
|
|
||||||
|
/* This is a list of all drivers we can use in the
|
||||||
|
* program. The default _InitIO function opens stdin,
|
||||||
|
* stdout, and stderr based on the first driver in
|
||||||
|
* the list (the serial driver, for us)
|
||||||
|
*/
|
||||||
|
_Driver *_driverlist[] = {
|
||||||
|
&_SimpleSerialDriver,
|
||||||
|
&_FileDriver,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
char *FindChar(char *ptr, int val);
|
||||||
|
|
||||||
|
FILE *stdinfile;
|
||||||
|
FILE *stdoutfile;
|
||||||
|
|
||||||
|
/* Print help information */
|
||||||
|
void Help()
|
||||||
|
{
|
||||||
|
printf("Commands are help, cat, rm, ls, ll, echo, cd, pwd and exit\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cd(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2) return;
|
||||||
|
|
||||||
|
if (chdir(argv[1]))
|
||||||
|
perror(argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pwd(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint8_t buffer[64];
|
||||||
|
char *ptr = getcwd(buffer, 64);
|
||||||
|
if (!ptr)
|
||||||
|
perror(0);
|
||||||
|
else
|
||||||
|
fprintf(stdoutfile, "%s\n", ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void Mkdir(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (mkdir(argv[i], 0))
|
||||||
|
perror(argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rmdir(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (rmdir(argv[i]))
|
||||||
|
perror(argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This routine implements the file cat function */
|
||||||
|
void Cat(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int num;
|
||||||
|
void *infile;
|
||||||
|
uint8_t buffer[40];
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
if (argc == 1 || stdinfile != stdin)
|
||||||
|
infile = stdinfile;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infile = fopen(argv[i], "r");
|
||||||
|
if (infile == 0)
|
||||||
|
{
|
||||||
|
perror(argv[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (infile == stdin)
|
||||||
|
{
|
||||||
|
while (gets(buffer))
|
||||||
|
{
|
||||||
|
if (buffer[0] == 4) break;
|
||||||
|
fprintf(stdoutfile, "%s\n", buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((num = fread(buffer, 1, 40, infile)))
|
||||||
|
fwrite(buffer, 1, num, stdoutfile);
|
||||||
|
}
|
||||||
|
if (i)
|
||||||
|
fclose(infile);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine deletes the files specified by the command line arguments */
|
||||||
|
void Remove(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (remove(argv[i]))
|
||||||
|
perror(argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine echos the command line arguments */
|
||||||
|
void Echo(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (i != argc - 1)
|
||||||
|
fprintf(stdoutfile, "%s ", argv[i]);
|
||||||
|
else
|
||||||
|
fprintf(stdoutfile, "%s\n", argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine lists the root directory or any subdirectories specified
|
||||||
|
in the command line arguments. If the "-l" option is specified, it
|
||||||
|
will print the file attributes and size. Otherwise, it will just
|
||||||
|
print the file names. */
|
||||||
|
void List(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
char *ptr;
|
||||||
|
char fname[13];
|
||||||
|
int32_t count = 0;
|
||||||
|
uint32_t filesize;
|
||||||
|
uint32_t longflag = 0;
|
||||||
|
char *path;
|
||||||
|
char drwx[5];
|
||||||
|
int column;
|
||||||
|
int prevlen;
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *entry;
|
||||||
|
|
||||||
|
// Check flags
|
||||||
|
for (j = 1; j < argc; j++)
|
||||||
|
{
|
||||||
|
if (argv[j][0] == '-')
|
||||||
|
{
|
||||||
|
if (!strcmp(argv[j], "-l"))
|
||||||
|
longflag = 1;
|
||||||
|
else
|
||||||
|
printf("Unknown option \"%s\"\n", argv[j]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List directories
|
||||||
|
for (j = 1; j < argc || count == 0; j++)
|
||||||
|
{
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
count--;
|
||||||
|
path = "./";
|
||||||
|
}
|
||||||
|
else if (argv[j][0] == '-')
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
path = argv[j];
|
||||||
|
|
||||||
|
if (count >= 2)
|
||||||
|
fprintf(stdoutfile, "\n%s:\n", path);
|
||||||
|
|
||||||
|
dirp = opendir(path);
|
||||||
|
|
||||||
|
if (!dirp)
|
||||||
|
{
|
||||||
|
perror(path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
column = 0;
|
||||||
|
prevlen = 14;
|
||||||
|
while (entry = readdir(dirp))
|
||||||
|
{
|
||||||
|
if (entry->name[0] == '.') continue;
|
||||||
|
ptr = fname;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (entry->name[i] == ' ') break;
|
||||||
|
*ptr++ = tolower(entry->name[i]);
|
||||||
|
}
|
||||||
|
if (entry->name[8] != ' ')
|
||||||
|
{
|
||||||
|
*ptr++ = '.';
|
||||||
|
for (i = 8; i < 11; i++)
|
||||||
|
{
|
||||||
|
if (entry->name[i] == ' ') break;
|
||||||
|
*ptr++ = tolower(entry->name[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ptr = 0;
|
||||||
|
filesize = entry->filesize_3;
|
||||||
|
filesize = (filesize << 8) | entry->filesize_2;
|
||||||
|
filesize = (filesize << 8) | entry->filesize_1;
|
||||||
|
filesize = (filesize << 8) | entry->filesize_0;
|
||||||
|
strcpy(drwx, "-rw-");
|
||||||
|
if (entry->attr & ATTR_READ_ONLY)
|
||||||
|
drwx[2] = '-';
|
||||||
|
if (entry->attr & ATTR_ARCHIVE)
|
||||||
|
drwx[3] = 'x';
|
||||||
|
if (entry->attr & ATTR_DIRECTORY)
|
||||||
|
{
|
||||||
|
drwx[0] = 'd';
|
||||||
|
drwx[3] = 'x';
|
||||||
|
}
|
||||||
|
if (longflag)
|
||||||
|
fprintf(stdoutfile, "%s %8d %s\n", drwx, filesize, fname);
|
||||||
|
else if (++column == 5)
|
||||||
|
{
|
||||||
|
for (i = prevlen; i < 14; i++) fprintf(stdoutfile, " ");
|
||||||
|
fprintf(stdoutfile, "%s\n", fname);
|
||||||
|
column = 0;
|
||||||
|
prevlen = 14;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = prevlen; i < 14; i++) fprintf(stdoutfile, " ");
|
||||||
|
prevlen = strlen(fname);
|
||||||
|
fprintf(stdoutfile, "%s", fname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
if (!longflag && column)
|
||||||
|
fprintf(stdoutfile, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine returns a pointer to the first character that doesn't
|
||||||
|
match val. */
|
||||||
|
char *SkipChar(char *ptr, int val)
|
||||||
|
{
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
if (*ptr != val) break;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine returns a pointer to the first character that matches val. */
|
||||||
|
char *FindChar(char *ptr, int val)
|
||||||
|
{
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
if (*ptr == val) break;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine extracts tokens from a string that are separated by one or
|
||||||
|
more spaces. It returns the number of tokens found. */
|
||||||
|
int tokenize(char *ptr, char *tokens[])
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
ptr = SkipChar(ptr, ' ');
|
||||||
|
if (*ptr == 0) break;
|
||||||
|
if (ptr[0] == '>')
|
||||||
|
{
|
||||||
|
ptr++;
|
||||||
|
if (ptr[0] == '>')
|
||||||
|
{
|
||||||
|
tokens[num++] = ">>";
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tokens[num++] = ">";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ptr[0] == '<')
|
||||||
|
{
|
||||||
|
ptr++;
|
||||||
|
tokens[num++] = "<";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tokens[num++] = ptr;
|
||||||
|
ptr = FindChar(ptr, ' ');
|
||||||
|
if (*ptr) *ptr++ = 0;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine searches the list of tokens for the redirection operators
|
||||||
|
and opens the files for input, output or append depending on the
|
||||||
|
operator. */
|
||||||
|
int CheckRedirection(char **tokens, int num)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < num-1; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp(tokens[i], ">"))
|
||||||
|
{
|
||||||
|
stdoutfile = fopen(tokens[i+1], "w");
|
||||||
|
if (!stdoutfile)
|
||||||
|
{
|
||||||
|
perror(tokens[i+1]);
|
||||||
|
stdoutfile = stdout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strcmp(tokens[i], ">>"))
|
||||||
|
{
|
||||||
|
stdoutfile = fopen(tokens[i+1], "a");
|
||||||
|
if (!stdoutfile)
|
||||||
|
{
|
||||||
|
perror(tokens[i+1]);
|
||||||
|
stdoutfile = stdout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!strcmp(tokens[i], "<"))
|
||||||
|
{
|
||||||
|
stdinfile = fopen(tokens[i+1], "r");
|
||||||
|
if (!stdinfile)
|
||||||
|
{
|
||||||
|
perror(tokens[i+1]);
|
||||||
|
stdinfile = stdin;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
for (j = i + 2; j < num; j++) tokens[j-2] = tokens[j];
|
||||||
|
i--;
|
||||||
|
num -= 2;
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This routine closes files that were open for redirection */
|
||||||
|
void CloseRedirection()
|
||||||
|
{
|
||||||
|
if (stdinfile != stdin)
|
||||||
|
{
|
||||||
|
fclose(stdinfile);
|
||||||
|
stdinfile = stdin;
|
||||||
|
}
|
||||||
|
if (stdoutfile != stdout)
|
||||||
|
{
|
||||||
|
fclose(stdoutfile);
|
||||||
|
stdoutfile = stdout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getdec(char *ptr)
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
while (*ptr) val = (val * 10) + *ptr++ - '0';
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char pins[4];
|
||||||
|
static char *CWD;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void GetConfig(int argc, char **argv)
|
||||||
|
{
|
||||||
|
unsigned int *lptr;
|
||||||
|
char *ptr = argv[argc-1];
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
ptr = (char *)(((((int)ptr) + 3) >> 2) << 2);
|
||||||
|
lptr = (unsigned int *)ptr;
|
||||||
|
//printf("%8.8x, %8.8x, %s\n", lptr[0], lptr[1], ptr + 8);
|
||||||
|
memcpy(pins, &lptr[1], 4);
|
||||||
|
CWD = ptr + 8;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The program starts the file system. It then loops reading commands
|
||||||
|
and calling the appropriate routine to process it. */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
char *tokens[20];
|
||||||
|
uint8_t buffer[80];
|
||||||
|
|
||||||
|
stdinfile = stdin;
|
||||||
|
stdoutfile = stdout;
|
||||||
|
|
||||||
|
spinix_enter();
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
Help();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
printf("\n> ");
|
||||||
|
fflush(stdout);
|
||||||
|
gets(buffer);
|
||||||
|
num = tokenize(buffer, tokens);
|
||||||
|
num = CheckRedirection(tokens, num);
|
||||||
|
if (num == 0) continue;
|
||||||
|
if (!strcmp(tokens[0], "help"))
|
||||||
|
Help();
|
||||||
|
else if (!strcmp(tokens[0], "cat"))
|
||||||
|
Cat(num, tokens);
|
||||||
|
else if (!strcmp(tokens[0], "ls"))
|
||||||
|
List(num, tokens);
|
||||||
|
else if (!strcmp(tokens[0], "ll"))
|
||||||
|
{
|
||||||
|
tokens[num++] = "-l";
|
||||||
|
List(num, tokens);
|
||||||
|
}
|
||||||
|
else if (!strcmp(tokens[0], "rm"))
|
||||||
|
Remove(num, tokens);
|
||||||
|
else if (!strcmp(tokens[0], "echo"))
|
||||||
|
Echo(num, tokens);
|
||||||
|
else if (!strcmp(tokens[0], "cd"))
|
||||||
|
Cd(num, tokens);
|
||||||
|
else if (!strcmp(tokens[0], "pwd"))
|
||||||
|
Pwd(num, tokens);
|
||||||
|
#if 0
|
||||||
|
else if (!strcmp(tokens[0], "mkdir"))
|
||||||
|
Mkdir(num, tokens);
|
||||||
|
else if (!strcmp(tokens[0], "rmdir"))
|
||||||
|
Rmdir(num, tokens);
|
||||||
|
#endif
|
||||||
|
else if (!strcmp(tokens[0], "exit"))
|
||||||
|
spinix_exit(0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Invalid command\n");
|
||||||
|
Help();
|
||||||
|
}
|
||||||
|
CloseRedirection();
|
||||||
|
}
|
||||||
|
|
||||||
|
spinix_exit(0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
+--------------------------------------------------------------------
|
||||||
|
| TERMS OF USE: MIT License
|
||||||
|
+--------------------------------------------------------------------
|
||||||
|
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
+------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/sd.h>
|
||||||
|
|
||||||
|
void mount(int MISO, int CLK, int MOSI, int CS)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
uint32_t mountErr;
|
||||||
|
_SD_Params params;
|
||||||
|
|
||||||
|
if (MISO == 10 && CLK == 11 && MOSI == 9 && CS == 25)
|
||||||
|
{
|
||||||
|
params.AttachmentType = _SDA_SerialDeMUX;
|
||||||
|
params.pins.SerialDeMUX.MISO = MISO;
|
||||||
|
params.pins.SerialDeMUX.CLK = CLK;
|
||||||
|
params.pins.SerialDeMUX.MOSI = MOSI;
|
||||||
|
params.pins.SerialDeMUX.CLR = CS;
|
||||||
|
params.pins.SerialDeMUX.INC = 8;
|
||||||
|
params.pins.SerialDeMUX.ADDR = 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
params.AttachmentType = _SDA_SingleSPI;
|
||||||
|
params.pins.SingleSPI.MISO = MISO;
|
||||||
|
params.pins.SingleSPI.CLK = CLK;
|
||||||
|
params.pins.SingleSPI.MOSI = MOSI;
|
||||||
|
params.pins.SingleSPI.CS = CS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mountErr = dfs_mount(¶ms)))
|
||||||
|
{
|
||||||
|
printf("Mount error: %d\n", mountErr);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
void printdec(FILE *fp, int val)
|
||||||
|
{
|
||||||
|
int scale;
|
||||||
|
int zeroflag = 0;
|
||||||
|
|
||||||
|
if (val < 0)
|
||||||
|
{
|
||||||
|
fputc('-', fp);
|
||||||
|
val = -val;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (scale = 1000000000; scale > 1; scale /= 10)
|
||||||
|
{
|
||||||
|
if (val >= scale)
|
||||||
|
{
|
||||||
|
fputc('0' + val/scale, fp);
|
||||||
|
val %= scale;
|
||||||
|
zeroflag = 1;
|
||||||
|
}
|
||||||
|
else if (zeroflag)
|
||||||
|
fputc('0', fp);
|
||||||
|
else
|
||||||
|
fputc(' ', fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputc('0'+val, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printhex(FILE *fp, int val)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static char hexdigits[] = "0123456789abcdef";
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
fputc(hexdigits[(val >> 28)&15], fp);
|
||||||
|
val <<= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _doprint(FILE *fp, const char *fmt, va_list args )
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
while (*fmt)
|
||||||
|
{
|
||||||
|
val = *fmt++;
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
if (val == 's')
|
||||||
|
{
|
||||||
|
state = 0;
|
||||||
|
val = va_arg(args, int);
|
||||||
|
fputs((char *)val, fp);
|
||||||
|
}
|
||||||
|
else if (val == 'd')
|
||||||
|
{
|
||||||
|
state = 0;
|
||||||
|
val = va_arg(args, int);
|
||||||
|
printdec(fp, val);
|
||||||
|
}
|
||||||
|
else if (val == 'x')
|
||||||
|
{
|
||||||
|
state = 0;
|
||||||
|
val = va_arg(args, int);
|
||||||
|
printhex(fp, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (val == '%') state = 1;
|
||||||
|
else fputc(val, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int printf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
_doprint(stdout, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fprintf(FILE *fp, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
_doprint(fp, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef _SD_INTERNAL_H
|
||||||
|
#define _SD_INTERNAL_H
|
||||||
|
|
||||||
|
#include "dosfs.h"
|
||||||
|
|
||||||
|
extern int dfs_mountflag;
|
||||||
|
extern VOLINFO dfs_volinfo;
|
||||||
|
extern char dfs_currdir[MAX_PATH];
|
||||||
|
extern __attribute__((section(".hub"))) uint8_t dfs_scratch[512];
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include <propeller.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
|
||||||
|
static int run_prog[] = {
|
||||||
|
0xa0bc65f0, 0x08bc6e32, 0x80fc6404, 0x08bc7032, 0x80fc6404, 0x08bc6032,
|
||||||
|
0x80fc6404, 0x08bc6232, 0x80fc63ff, 0x28fc6209, 0x08fc6600, 0x00fc6804,
|
||||||
|
0x083c6029, 0x083c5c2a, 0x083c582b, 0x08bc642b, 0x863c642c, 0x5c68000f,
|
||||||
|
0x80fc6001, 0x80fc5d00, 0x80fc5d00, 0xe4fc620c, 0x087c6600, 0x007c6804,
|
||||||
|
0x04fc6a08, 0x04fc6c0a, 0xa0bc6236, 0x84bc6235, 0x28fc6202, 0x083c5a35,
|
||||||
|
0x80fc6a04, 0xe4fc621d, 0x083c5a36, 0x80fc6c04, 0x083c6e36, 0x80fc6c04,
|
||||||
|
0x083c7036, 0x0cfc6401, 0x60fc6407, 0x68bc5e32, 0x0c7c5e02, 0x00007fd8,
|
||||||
|
0x00007fdc, 0x00007fd4, 0x00000072, 0x00000000, 0x00000000, 0x0007c010};
|
||||||
|
|
||||||
|
static int arg_list[] = {0, 0, 0, 0};
|
||||||
|
|
||||||
|
void spinix_enter(int argc, char **argv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void spinix_exit(int retval)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int cogspi = (*(int *)spinix_spi_engine_cog) - 1;
|
||||||
|
arg_list[2] = *(int *)spinix_shell_sector;
|
||||||
|
arg_list[3] = *(int *)spinix_shell_size;
|
||||||
|
|
||||||
|
*(int *)spinix_return_value = retval;
|
||||||
|
|
||||||
|
// Stop all the cogs except this one and the SD SPI cog
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
if (i != cogid() && i != cogspi)
|
||||||
|
cogstop(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear and return all the locks
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
lockclr(i);
|
||||||
|
lockret(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start run_prog in this cog
|
||||||
|
coginit(cogid(), run_prog, arg_list);
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#define spinix_start 0x7c00 // Extra space for the stand-alone loader
|
||||||
|
#define spinix_rendezvous 0x7e50
|
||||||
|
#define spinix_environ_vars 0x7e50
|
||||||
|
#define spinix_environ_vars_end 0x7ed3
|
||||||
|
#define spinix_argv_parms 0x7ed4
|
||||||
|
#define spinix_return_value 0x7f94
|
||||||
|
#define spinix_vga_cog 0x7f98
|
||||||
|
#define spinix_vga_handle 0x7f9c
|
||||||
|
#define spinix_sd_pins 0x7fa0
|
||||||
|
#define spinix_config 0x7fa4
|
||||||
|
#define spinix_shell_sector 0x7fa8
|
||||||
|
#define spinix_unixtime 0x7fac
|
||||||
|
#define spinix_cycle0 0x7fb0
|
||||||
|
#define spinix_timezone 0x7fb4
|
||||||
|
#define spinix_scriptline 0x7fb8
|
||||||
|
#define spinix_ifflag 0x7fbc
|
||||||
|
#define spinix_whileflag 0x7fc0
|
||||||
|
#define spinix_shell_size 0x7fc4
|
||||||
|
#define spinix_shell_level 0x7fc8
|
||||||
|
#define spinix_bootflag 0x7fcc
|
||||||
|
#define spinix_spi_engine_cog 0x7fd0
|
||||||
|
#define spinix_spi_command 0x7fd4
|
||||||
|
#define spinix_spi_block_index 0x7fd8
|
||||||
|
#define spinix_spi_buffer_address 0x7fdc
|
||||||
|
#define spinix_serial 0x7fe0
|
||||||
|
#define spinix_stdio 0x7fe4
|
||||||
|
#define spinix_stdin 0x7fe8
|
||||||
|
#define spinix_stdout 0x7fec
|
||||||
|
#define spinix_memlocknum 0x7ff0
|
||||||
|
#define spinix_memfreelist 0x7ff4
|
||||||
|
#define spinix_malloclist 0x7ff8
|
||||||
|
#define spinix_laststackaddr 0x7ffc
|
||||||
|
#define spinix_checkword 0xdead1eaf
|
||||||
|
#define spinix_proc_type_spin 1
|
||||||
|
#define spinix_proc_type_pasm 2
|
||||||
|
#define spinix_proc_type_capp 3
|
||||||
|
#define spinix_proc_type_driver 0x80
|
||||||
|
#define spinix_run_shell_wait 0x00
|
||||||
|
#define spinix_run_shell_nowait 0x08
|
||||||
|
#define spinix_run_kill_caller 0x10
|
||||||
|
#define spinix_run_at_address0 0x20
|
||||||
|
#define spinix_run_c_program 0x40
|
||||||
|
#define spinix_run_spin_program 0x80
|
||||||
|
#define spinix_run_stand_alone 0x100
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "spinix.h"
|
||||||
|
#include "varsubs.h"
|
||||||
|
|
||||||
|
static char retvalstr[16];
|
||||||
|
|
||||||
|
//******************************************************************************
|
||||||
|
// Copyright (c) 2013 Dave Hein
|
||||||
|
// See end of file for terms of use.
|
||||||
|
//******************************************************************************
|
||||||
|
char *varsubs_FindVar(char *str)
|
||||||
|
{
|
||||||
|
char *ptr = (char *)spinix_environ_vars;
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
if (!strcmp(str, ptr + 1))
|
||||||
|
{
|
||||||
|
if (*ptr != varsubs_ALIAS_FLAG)
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *varsubs_FindAlias(char *str)
|
||||||
|
{
|
||||||
|
char *ptr = (char *)spinix_environ_vars;
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
if (!strcmp(str, ptr + 1))
|
||||||
|
{
|
||||||
|
if (*ptr == varsubs_ALIAS_FLAG)
|
||||||
|
{
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *varsubs_FindEnd(void)
|
||||||
|
{
|
||||||
|
char *ptr = (char *)spinix_environ_vars;
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
ptr += strlen(ptr) + 1;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *varsubs_RemoveEntry(char *ptr1)
|
||||||
|
{
|
||||||
|
int i, len;
|
||||||
|
char *ptr2 = ptr1 + strlen(ptr1) + 1;
|
||||||
|
ptr2 += strlen(ptr2) + 1;
|
||||||
|
while (*ptr2)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
len = strlen(ptr2) + 1;
|
||||||
|
memmove (ptr1, ptr2, len);
|
||||||
|
ptr1 += len;
|
||||||
|
ptr2 += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ptr1 = 0;
|
||||||
|
return ptr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void varsubs_RemoveVar(char *name)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
if ((ptr = varsubs_FindVar(name)))
|
||||||
|
{
|
||||||
|
ptr = varsubs_RemoveEntry(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void varsubs_SaveVar(char *name, char *value, int type)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
int space, len1, len2;
|
||||||
|
// Check if variable already exists
|
||||||
|
if ((ptr = varsubs_FindVar(name)))
|
||||||
|
{
|
||||||
|
type = *ptr;
|
||||||
|
ptr = varsubs_RemoveEntry(ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr = varsubs_FindEnd();
|
||||||
|
}
|
||||||
|
// Check if space is available
|
||||||
|
space = spinix_environ_vars_end - (int)ptr + 1;
|
||||||
|
len1 = strlen(name) + 1;
|
||||||
|
len2 = strlen(value) + 1;
|
||||||
|
if ((space < len1 + len2 + 2))
|
||||||
|
{
|
||||||
|
printf("Not enough variable space\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ((space < len1 + len2 + 82))
|
||||||
|
{
|
||||||
|
printf("space = %d, need = %d\n", space, len1 + len2 + 2);
|
||||||
|
}
|
||||||
|
// Add variable
|
||||||
|
*ptr++ = type;
|
||||||
|
memmove (ptr, name, len1);
|
||||||
|
ptr += len1;
|
||||||
|
memmove (ptr, value, len2);
|
||||||
|
ptr += len2;
|
||||||
|
*ptr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *varsubs_GetVarVal(char *name)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
if (!strcmp(name, "?"))
|
||||||
|
{
|
||||||
|
sprintf(retvalstr, "%d", *(int *)spinix_return_value);
|
||||||
|
return retvalstr;
|
||||||
|
}
|
||||||
|
if ((ptr = varsubs_FindVar(name)))
|
||||||
|
{
|
||||||
|
return ptr + strlen(ptr) + 1;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *varsubs_Val(char *ptr)
|
||||||
|
{
|
||||||
|
if (*ptr != '$') return ptr;
|
||||||
|
return varsubs_GetVarVal(ptr + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int varsubs_NumVal(char *ptr)
|
||||||
|
{
|
||||||
|
if (*ptr == '$')
|
||||||
|
{
|
||||||
|
if (!strcmp(ptr, "$?"))
|
||||||
|
{
|
||||||
|
return *(int *)spinix_return_value;
|
||||||
|
}
|
||||||
|
ptr = varsubs_GetVarVal(ptr + 1);
|
||||||
|
}
|
||||||
|
return atol(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
char *varsubs_FindChar(char *str, int val)
|
||||||
|
{
|
||||||
|
while (*str && *str != val) str++;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *varsubs_SkipChar(char *str, int val)
|
||||||
|
{
|
||||||
|
while (*str && *str == val) str++;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
| TERMS OF USE: MIT License |
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
|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 |
|
||||||
|
|AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
|
|LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,|
|
||||||
|
|OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE|
|
||||||
|
|SOFTWARE. |
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
*/
|
|
@ -0,0 +1,17 @@
|
||||||
|
// CONSTANTS
|
||||||
|
#define varsubs_GLOBAL_FLAG 'G'
|
||||||
|
#define varsubs_LOCAL_FLAG 'L'
|
||||||
|
#define varsubs_PARM_FLAG 'P'
|
||||||
|
#define varsubs_ALIAS_FLAG 'A'
|
||||||
|
|
||||||
|
char *varsubs_FindVar(char *str);
|
||||||
|
char *varsubs_FindAlias(char *str);
|
||||||
|
char *varsubs_FindEnd(void);
|
||||||
|
char *varsubs_RemoveEntry(char *ptr1);
|
||||||
|
void varsubs_RemoveVar(char *name);
|
||||||
|
void varsubs_SaveVar(char *name, char *value, int type);
|
||||||
|
char *varsubs_GetVarVal(char *name);
|
||||||
|
char *varsubs_Val(char *ptr);
|
||||||
|
int varsubs_NumVal(char *ptr);
|
||||||
|
char *varsubs_FindChar(char *str, int val);
|
||||||
|
char *varsubs_SkipChar(char *str, int val);
|
|
@ -0,0 +1,315 @@
|
||||||
|
'******************************************************************************
|
||||||
|
' Floating Point I/O Routines
|
||||||
|
' Author: Dave Hein
|
||||||
|
' Copyright (c) 2010
|
||||||
|
' See end of file for terms of use.
|
||||||
|
'******************************************************************************
|
||||||
|
'******************************************************************************
|
||||||
|
' Revison History
|
||||||
|
' v1.0 - 4/2/2010 First official release
|
||||||
|
'******************************************************************************
|
||||||
|
{
|
||||||
|
These routines are used by the C library to perform formatted floating point
|
||||||
|
I/O. The two output routines, putfloate and putfloatf write to string.
|
||||||
|
|
||||||
|
Input formatting is performed by the strtofloat routine. It uses a pointer
|
||||||
|
to a string pointer and returns the resulting floating point value.
|
||||||
|
|
||||||
|
If floating point I/O is not required for an application this file can be
|
||||||
|
removed by deleting the references to the object and the three routines in
|
||||||
|
clib.spin.
|
||||||
|
}
|
||||||
|
|
||||||
|
'******************************************************************************
|
||||||
|
' Floating Point Routines
|
||||||
|
'******************************************************************************
|
||||||
|
PUB putfloate(str, x, width, digits) | man, exp10, signbit
|
||||||
|
{{
|
||||||
|
Convert the floating point value in x to a string of characters in scientific
|
||||||
|
notation in str. digits determines the number of fractional digits used and
|
||||||
|
width determines the minimum length of the output string. Leading blanks are
|
||||||
|
added to achieve the minimum width.
|
||||||
|
}}
|
||||||
|
if (digits < 0)
|
||||||
|
digits := 6
|
||||||
|
signbit := tofloat10(x, @man, @exp10)
|
||||||
|
exp10 += round10(digits + 1, @man) + digits
|
||||||
|
width -= 5 + signbit - (digits <> 0)
|
||||||
|
repeat while (width-- > digits)
|
||||||
|
byte[str++] := " "
|
||||||
|
if (signbit)
|
||||||
|
byte[str++] := "-"
|
||||||
|
str := utoa10(man, str, 1)
|
||||||
|
byte[str++] := "e"
|
||||||
|
if (exp10 => 0)
|
||||||
|
byte[str++] := "+"
|
||||||
|
else
|
||||||
|
byte[str++] := "-"
|
||||||
|
exp10 := 0-exp10
|
||||||
|
if (exp10 < 10)
|
||||||
|
byte[str++] := "0"
|
||||||
|
str := utoa10(exp10, str, -1)
|
||||||
|
byte[str] := 0
|
||||||
|
return str
|
||||||
|
|
||||||
|
PUB putfloatf(str, x, width, digits) | lead0, trail0, man, exp10, signbit, digits0
|
||||||
|
{{
|
||||||
|
Convert the floating point value in x to a string of character in standard
|
||||||
|
notation in str. digits determines the number of fractional digits used and
|
||||||
|
width determines the minimum length of the output string. Leading blanks are
|
||||||
|
added to achieve the minimum width.
|
||||||
|
}}
|
||||||
|
if (digits < 0)
|
||||||
|
digits := 6
|
||||||
|
signbit := tofloat10(x, @man, @exp10)
|
||||||
|
digits0 := numdigits(man, @lead0) + exp10
|
||||||
|
if (digits0 > 0)
|
||||||
|
width -= digits0
|
||||||
|
digits0 += digits
|
||||||
|
if (digits0 > 8)
|
||||||
|
digits0 := 8
|
||||||
|
exp10 += round10(digits0, @man) + digits0 - 1
|
||||||
|
if (digits0 < 0)
|
||||||
|
digits0 := 0
|
||||||
|
elseif (digits0 == 0 and man == 1 and digits > 0)
|
||||||
|
digits0 := 1
|
||||||
|
lead0 := digits - digits0
|
||||||
|
trail0 := digits - digits0 + exp10 + 1
|
||||||
|
width -= signbit + digits - (lead0 => 0) + 1
|
||||||
|
repeat while (width-- > 0)
|
||||||
|
byte[str++] := " "
|
||||||
|
if (signbit)
|
||||||
|
byte[str++] := "-"
|
||||||
|
if (lead0 => 0)
|
||||||
|
byte[str++] := "0"
|
||||||
|
if (lead0 > 0)
|
||||||
|
byte[str++] := "."
|
||||||
|
repeat while (lead0-- > 0)
|
||||||
|
byte[str++] := "0"
|
||||||
|
if (digits0 > 0)
|
||||||
|
str := utoa10(man, str, exp10 + 1)
|
||||||
|
exp10 -= digits0 - 1
|
||||||
|
repeat while (trail0-- > 0)
|
||||||
|
if (exp10-- == 0)
|
||||||
|
byte[str++] := "."
|
||||||
|
byte[str++] := "0"
|
||||||
|
byte[str] := 0
|
||||||
|
return str
|
||||||
|
|
||||||
|
PUB strtofloat(pstr) | value, exp10, exp10a, signbit, mode, char, esignbit, str
|
||||||
|
{{
|
||||||
|
Convert the string of characters pointer to by "pstr" into a floating point
|
||||||
|
value. The input can be in either standard or scientific notation. Leading
|
||||||
|
blanks are ignored. The string pointed to by "pstr" is updated to the last
|
||||||
|
character postioned that caused processing to be completed.
|
||||||
|
}}
|
||||||
|
str := long[pstr]
|
||||||
|
esignbit := 0
|
||||||
|
mode := 0
|
||||||
|
value := 0
|
||||||
|
exp10 := 0
|
||||||
|
exp10a := 0
|
||||||
|
signbit := 0
|
||||||
|
repeat
|
||||||
|
char := byte[str++]
|
||||||
|
if (char == 0)
|
||||||
|
quit
|
||||||
|
case mode
|
||||||
|
0:
|
||||||
|
case char
|
||||||
|
"0".."9": value := char - "0"
|
||||||
|
"-" : signbit := 1
|
||||||
|
" " : next
|
||||||
|
"+": mode := 1
|
||||||
|
other:quit
|
||||||
|
mode := 1
|
||||||
|
1 :
|
||||||
|
case char
|
||||||
|
"0".."9":
|
||||||
|
if (value =< 200_000_000)
|
||||||
|
value := (value * 10) + char - "0"
|
||||||
|
else
|
||||||
|
exp10++
|
||||||
|
".": mode := 2
|
||||||
|
"e", "E": mode := 3
|
||||||
|
other: quit
|
||||||
|
2:
|
||||||
|
case char
|
||||||
|
"0".."9":
|
||||||
|
if (value =< 200_000_000)
|
||||||
|
value := (value * 10) + char - "0"
|
||||||
|
exp10--
|
||||||
|
"e", "E": mode := 3
|
||||||
|
other: quit
|
||||||
|
3:
|
||||||
|
case char
|
||||||
|
"0".."9": exp10a := char - "0"
|
||||||
|
"-" : esignbit := 1
|
||||||
|
"+": mode := 4
|
||||||
|
other:quit
|
||||||
|
mode := 4
|
||||||
|
4:
|
||||||
|
case char
|
||||||
|
"0".."9":exp10a := (exp10a * 10) + char - "0"
|
||||||
|
other: quit
|
||||||
|
if (esignbit)
|
||||||
|
exp10 -= exp10a
|
||||||
|
else
|
||||||
|
exp10 += exp10a
|
||||||
|
long[pstr] := str
|
||||||
|
return fromfloat10(value, exp10, signbit)
|
||||||
|
|
||||||
|
DAT
|
||||||
|
{{
|
||||||
|
|
||||||
|
________________________
|
||||||
|
These tables of scalers are used to scale a floating point number by a ratio of a
|
||||||
|
power of 10 versus a power of 2.
|
||||||
|
}}
|
||||||
|
''SCALE1 10/16 100/128 1000/1024 10^6/2^20 10^12/2^40 10^24/2^80
|
||||||
|
scale1 long 1342177280, 1677721600, 2097152000, 2048000000, 1953125000, 1776356839
|
||||||
|
''SCALE2 8/10 64/100 512/1000 2^19/10^6 2^39/10^12 2^79/10^24
|
||||||
|
scale2 long 1717986918, 1374389535, 1099511628, 1125899907, 1180591621, 1298074215
|
||||||
|
nbits1 byte 4, 7, 10, 20, 40, 80
|
||||||
|
nbits2 byte 3, 6, 9, 19, 39, 79
|
||||||
|
ndecs byte 1, 2, 3, 6, 12, 24
|
||||||
|
|
||||||
|
PRI floatloop(man, pexp0, pexp1, step0, step1, scale, pexp2, step2) | i
|
||||||
|
{{
|
||||||
|
This private routine reduces the value of exp0 toward 0 while increasing the value
|
||||||
|
of exp1. This is done in a successive approximation method using the scaling
|
||||||
|
table passed in "scale". This routine is used here to convert between a mantissa
|
||||||
|
times a power of 2 or 10 to a mantissa times a power of 10 or 2.
|
||||||
|
}}
|
||||||
|
repeat i from 5 to 0
|
||||||
|
if (long[pexp0] => byte[step0][i])
|
||||||
|
man := (man ** long[scale][i]) << 1
|
||||||
|
long[pexp0] -= byte[step0][i]
|
||||||
|
long[pexp1] += byte[step1][i]
|
||||||
|
if ((man & $40000000) == 0)
|
||||||
|
man <<= 1
|
||||||
|
long[pexp2] -= step2
|
||||||
|
return man
|
||||||
|
|
||||||
|
PRI tofloat10(value, pman, pexp10) | exp2, exp10, man
|
||||||
|
{{
|
||||||
|
This private routine converts from a mantissa times a power of 2 to a mantissa
|
||||||
|
times a power of 10.
|
||||||
|
}}
|
||||||
|
result := value >> 31
|
||||||
|
exp2 := ((value >> 23) & 255) - 157
|
||||||
|
man := ((value & $007fffff) | $00800000) << 7
|
||||||
|
exp10 := 0
|
||||||
|
if (exp2 =< 0)
|
||||||
|
exp2 := -exp2
|
||||||
|
man := floatloop(man, @exp2, @exp10, @nbits1, @ndecs, @scale1, @exp2, -1)
|
||||||
|
man >>= exp2
|
||||||
|
exp10 := -exp10
|
||||||
|
else
|
||||||
|
exp2 += 2
|
||||||
|
man := floatloop(man, @exp2, @exp10, @nbits2, @ndecs, @scale2, @exp2, 1)
|
||||||
|
man >>= 2 - exp2
|
||||||
|
long[pman] := man
|
||||||
|
long[pexp10] := exp10
|
||||||
|
|
||||||
|
PRI fromfloat10(man, exp10, signbit) | exp2
|
||||||
|
{{
|
||||||
|
This private routine converts from a mantissa times a power of 10 to a mantissa
|
||||||
|
times a power of two.
|
||||||
|
}}
|
||||||
|
if (man == 0)
|
||||||
|
return 0
|
||||||
|
exp2 := 0
|
||||||
|
repeat while(man & $40000000) == 0
|
||||||
|
man <<= 1
|
||||||
|
exp2--
|
||||||
|
if (exp10 =< 0)
|
||||||
|
exp10 := -exp10
|
||||||
|
exp2 := -exp2
|
||||||
|
man := floatloop(man, @exp10, @exp2, @ndecs, @nbits2, @scale2, @exp2, -1)
|
||||||
|
exp2 := -exp2
|
||||||
|
else
|
||||||
|
man := floatloop(man, @exp10, @exp2, @ndecs, @nbits1, @scale1, @exp2, 1)
|
||||||
|
repeat while(man & $ff000000)
|
||||||
|
man >>= 1
|
||||||
|
exp2++
|
||||||
|
return (signbit << 31) | ((exp2 + 150) << 23) | (man & $007fffff)
|
||||||
|
|
||||||
|
PRI numdigits(man, pdiv) : numdig | divisor
|
||||||
|
{{
|
||||||
|
This routine determines the number of decimal digits in the number in man.
|
||||||
|
}}
|
||||||
|
numdig := 10
|
||||||
|
divisor := 1000000000
|
||||||
|
repeat while (divisor > man)
|
||||||
|
numdig--
|
||||||
|
divisor /= 10
|
||||||
|
long[pdiv] := divisor
|
||||||
|
|
||||||
|
PRI round10(digits, pman) : exp10 | numdig, divisor, rounder, man
|
||||||
|
{{
|
||||||
|
This routine round the number poiinted to by pman to the number of decimal
|
||||||
|
digits specified by "digits".
|
||||||
|
}}
|
||||||
|
man := long[pman]
|
||||||
|
exp10 := numdigits(man, @divisor) - digits
|
||||||
|
if (digits < 0)
|
||||||
|
man := 0
|
||||||
|
elseif (digits == 0)
|
||||||
|
if (man / divisor => 5)
|
||||||
|
man := 1
|
||||||
|
exp10++
|
||||||
|
elseif (exp10 > 0)
|
||||||
|
rounder := 1
|
||||||
|
repeat exp10
|
||||||
|
rounder *= 10
|
||||||
|
man :=(man + (rounder >> 1)) / rounder
|
||||||
|
divisor /= rounder
|
||||||
|
if (man / divisor > 9)
|
||||||
|
man /= 10
|
||||||
|
exp10++
|
||||||
|
elseif (exp10 < 0)
|
||||||
|
repeat 0-exp10
|
||||||
|
man *= 10
|
||||||
|
long[pman] := man
|
||||||
|
|
||||||
|
PRI utoa10(number, str, point) | divisor, temp
|
||||||
|
{{
|
||||||
|
This routine converts the value in "number" to a string of decimal characters
|
||||||
|
in "str". A decimal point is added after the character position specified by
|
||||||
|
the value in "point".
|
||||||
|
}}
|
||||||
|
if (number == 0)
|
||||||
|
byte[str++] := "0"
|
||||||
|
byte[str] := 0
|
||||||
|
return str
|
||||||
|
divisor := 1_000_000_000
|
||||||
|
repeat while (divisor > number)
|
||||||
|
divisor /= 10
|
||||||
|
repeat while (divisor > 0)
|
||||||
|
if (point-- == 0)
|
||||||
|
byte[str++] := "."
|
||||||
|
temp := number / divisor
|
||||||
|
byte[str++] := temp + "0"
|
||||||
|
number -= temp * divisor
|
||||||
|
divisor /= 10
|
||||||
|
byte[str] := 0
|
||||||
|
return str
|
||||||
|
|
||||||
|
{{
|
||||||
|
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ TERMS OF USE: MIT License │
|
||||||
|
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│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 AUTHORS OR │
|
||||||
|
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||||
|
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
}}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,208 @@
|
||||||
|
'******************************************************************************
|
||||||
|
' C malloc written in Spin
|
||||||
|
' Author: Dave Hein
|
||||||
|
' Copyright (c) 2010
|
||||||
|
' See end of file for terms of use.
|
||||||
|
'******************************************************************************
|
||||||
|
'******************************************************************************
|
||||||
|
' Revison History
|
||||||
|
' v1.0 - 4/2/2010 First official release
|
||||||
|
'******************************************************************************
|
||||||
|
{
|
||||||
|
This object contains the malloc, free and calloc routines used by clib.
|
||||||
|
}
|
||||||
|
OBJ
|
||||||
|
sys : "sysdefs"
|
||||||
|
|
||||||
|
CON
|
||||||
|
NEXT_BLK = 0
|
||||||
|
BLK_SIZE = 1
|
||||||
|
HDR_SIZE = 4
|
||||||
|
'RAM_SIZE = $8000
|
||||||
|
RAM_SIZE = sys#rendezvous
|
||||||
|
CHECKWORD = $dead1eaf
|
||||||
|
|
||||||
|
DAT
|
||||||
|
locknum long 0
|
||||||
|
memfreelist long 0
|
||||||
|
malloclist long 0
|
||||||
|
laststackaddr long 0
|
||||||
|
|
||||||
|
PUB CheckStackSpace | addr
|
||||||
|
repeat addr from laststackaddr to 0 step 4
|
||||||
|
if long[addr] <> CHECKWORD
|
||||||
|
quit
|
||||||
|
result++
|
||||||
|
|
||||||
|
PUB GetMallocList
|
||||||
|
return malloclist
|
||||||
|
|
||||||
|
PUB GetFreeList
|
||||||
|
return memfreelist
|
||||||
|
|
||||||
|
PUB mallocinit(stacksize) | currblk, addr
|
||||||
|
'' Initialize the malloc heap "stacksize" longs after the current stack pointer
|
||||||
|
'' Allocate a lock and return the lock number plus one if successful, or zero if not
|
||||||
|
locknum := locknew + 1
|
||||||
|
currblk := @stacksize + (stacksize << 2)
|
||||||
|
'Fill stack with checkword
|
||||||
|
laststackaddr := currblk - 4
|
||||||
|
longfill(@stacksize + 40, CHECKWORD, stacksize - 10)
|
||||||
|
memfreelist := currblk
|
||||||
|
malloclist := 0
|
||||||
|
word[currblk]{NEXT_BLK} := 0
|
||||||
|
word[currblk][BLK_SIZE] := RAM_SIZE - currblk
|
||||||
|
return locknum
|
||||||
|
|
||||||
|
PUB malloc(size) | prevblk, currblk, nextblk, prevblk0, currblk0, size0
|
||||||
|
'' Allocate a memory block of "size" bytes. Return a pointer to the clock if
|
||||||
|
'' successful, or zero if a large enough memory block could not be found
|
||||||
|
'ser.dbprintf1(string("malloc: %d\n"), size)
|
||||||
|
prevblk := 0
|
||||||
|
prevblk0 := 0
|
||||||
|
currblk0 := 0
|
||||||
|
if (size =< 0)
|
||||||
|
return 0
|
||||||
|
repeat until not lockset(locknum - 1)
|
||||||
|
currblk := memfreelist
|
||||||
|
|
||||||
|
' Adjust size to nearest long plus the header size
|
||||||
|
size := ((size + 3) & (!3)) + HDR_SIZE
|
||||||
|
|
||||||
|
' Search for a block of memory
|
||||||
|
repeat while (currblk)
|
||||||
|
if (word[currblk][BLK_SIZE] => size)
|
||||||
|
prevblk0 := prevblk
|
||||||
|
currblk0 := currblk
|
||||||
|
prevblk := currblk
|
||||||
|
currblk := word[currblk]{NEXT_BLK}
|
||||||
|
|
||||||
|
currblk := currblk0
|
||||||
|
prevblk := prevblk0
|
||||||
|
|
||||||
|
' Return null if block not found
|
||||||
|
if (currblk == 0)
|
||||||
|
lockclr(locknum - 1)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
' Split block if larger than needed
|
||||||
|
size0 := word[currblk][BLK_SIZE] - size
|
||||||
|
if (size0 => HDR_SIZE + 4)
|
||||||
|
word[currblk][BLK_SIZE] := size0
|
||||||
|
currblk += size0
|
||||||
|
word[currblk][BLK_SIZE] := size
|
||||||
|
|
||||||
|
' Otherwise, use space without splitting and remove from memfreelist
|
||||||
|
else
|
||||||
|
nextblk := word[currblk]{NEXT_BLK}
|
||||||
|
if (prevblk)
|
||||||
|
word[prevblk]{NEXT_BLK} := nextblk
|
||||||
|
else
|
||||||
|
memfreelist := nextblk
|
||||||
|
|
||||||
|
' Add to the beginning of the malloc list
|
||||||
|
word[currblk]{NEXT_BLK} := malloclist
|
||||||
|
malloclist := currblk
|
||||||
|
lockclr(locknum - 1)
|
||||||
|
return currblk + HDR_SIZE
|
||||||
|
|
||||||
|
PUB freeraw(ptr, size)
|
||||||
|
repeat until not lockset(locknum - 1)
|
||||||
|
word[ptr][BLK_SIZE] := size
|
||||||
|
meminsert(ptr)
|
||||||
|
lockclr(locknum - 1)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
PUB free(ptr) | prevblk, currblk, nextblk
|
||||||
|
'' Return the memory block at "ptr" to the free list. Return a value of one
|
||||||
|
'' if successful, or zero if the memory block was not on the allocate list.
|
||||||
|
prevblk := 0
|
||||||
|
repeat until not lockset(locknum - 1)
|
||||||
|
nextblk := malloclist
|
||||||
|
currblk := ptr - HDR_SIZE
|
||||||
|
|
||||||
|
' Search the malloclist for the currblk pointer
|
||||||
|
repeat while (nextblk)
|
||||||
|
if (currblk == nextblk)
|
||||||
|
' Remove from the malloc list
|
||||||
|
if (prevblk)
|
||||||
|
word[prevblk]{NEXT_BLK} := word[nextblk]{NEXT_BLK}
|
||||||
|
else
|
||||||
|
malloclist := word[nextblk]{NEXT_BLK}
|
||||||
|
' Add to the free list
|
||||||
|
meminsert(nextblk)
|
||||||
|
lockclr(locknum - 1)
|
||||||
|
return 1
|
||||||
|
prevblk := nextblk
|
||||||
|
nextblk := word[nextblk]{NEXT_BLK}
|
||||||
|
|
||||||
|
' Return a NULL value if not found
|
||||||
|
lockclr(locknum - 1)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
PRI meminsert(currblk) | prevblk, nextblk
|
||||||
|
'' Insert a memory block back into the free list. Merge blocks together if
|
||||||
|
'' the memory block is contiguous with other blocks on the list.
|
||||||
|
prevblk := 0
|
||||||
|
nextblk := memfreelist
|
||||||
|
|
||||||
|
' Find Insertion Point
|
||||||
|
repeat while (nextblk)
|
||||||
|
if ((currblk => prevblk) and (currblk =< nextblk))
|
||||||
|
quit
|
||||||
|
prevblk := nextblk
|
||||||
|
nextblk := word[nextblk]{NEXT_BLK}
|
||||||
|
|
||||||
|
' Merge with the previous block if contiguous
|
||||||
|
if (prevblk and (prevblk + word[prevblk][BLK_SIZE] == currblk))
|
||||||
|
word[prevblk][BLK_SIZE] += word[currblk][BLK_SIZE]
|
||||||
|
' Also merge with next block if contiguous
|
||||||
|
if (prevblk + word[prevblk][BLK_SIZE] == nextblk)
|
||||||
|
word[prevblk][BLK_SIZE] += word[nextblk][BLK_SIZE]
|
||||||
|
word[prevblk]{NEXT_BLK} := word[nextblk]{NEXT_BLK}
|
||||||
|
|
||||||
|
' Merge with the next block if contiguous
|
||||||
|
elseif (nextblk and (currblk + word[currblk][BLK_SIZE] == nextblk))
|
||||||
|
word[currblk][BLK_SIZE] += word[nextblk][BLK_SIZE]
|
||||||
|
word[currblk]{NEXT_BLK} := word[nextblk]{NEXT_BLK}
|
||||||
|
if (prevblk)
|
||||||
|
word[prevblk]{NEXT_BLK} := currblk
|
||||||
|
else
|
||||||
|
memfreelist := currblk
|
||||||
|
|
||||||
|
' Insert in the middle of the free list if not contiguous
|
||||||
|
elseif (prevblk)
|
||||||
|
word[prevblk]{NEXT_BLK} := currblk
|
||||||
|
word[currblk]{NEXT_BLK} := nextblk
|
||||||
|
|
||||||
|
' Otherwise, insert at beginning of the free list
|
||||||
|
else
|
||||||
|
memfreelist := currblk
|
||||||
|
word[currblk]{NEXT_BLK} := nextblk
|
||||||
|
|
||||||
|
PUB calloc(size) | ptr
|
||||||
|
'' Allocate a memory block of "size" bytes and initialize to zero. Return
|
||||||
|
'' a pointer to the memory block if successful, or zero if a large enough
|
||||||
|
'' memory block could not be found.
|
||||||
|
ptr := malloc(size)
|
||||||
|
if (ptr)
|
||||||
|
longfill(ptr, 0, (size + 3) >> 2)
|
||||||
|
return ptr
|
||||||
|
|
||||||
|
{{
|
||||||
|
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ TERMS OF USE: MIT License │
|
||||||
|
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│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 AUTHORS OR │
|
||||||
|
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||||
|
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
}}
|
|
@ -0,0 +1,584 @@
|
||||||
|
'******************************************************************************
|
||||||
|
' Serial Driver for the C Function Library in Spin
|
||||||
|
' Author: Dave Hein
|
||||||
|
' Copyright (c) 2010
|
||||||
|
' See end of file for terms of use.
|
||||||
|
'******************************************************************************
|
||||||
|
'******************************************************************************
|
||||||
|
' Revison History
|
||||||
|
' v1.0 - 4/2/2010 First official release
|
||||||
|
'******************************************************************************
|
||||||
|
{{
|
||||||
|
This is a modified version of Ghip Gracey's Full-Duplex Serial Driver. This
|
||||||
|
serial driver has the following new features:
|
||||||
|
|
||||||
|
- Multiple serial ports may be started from any object or cog
|
||||||
|
- Any serial port is accessable from any object or cog using a device handle
|
||||||
|
- Transmit and receiver buffers can be different sizes
|
||||||
|
- Buffer sizes are defined by calling parameters
|
||||||
|
- Mode bit 4 enables the use of a lock to make the transmit multi-cog safe
|
||||||
|
|
||||||
|
The original FullDuplexSerial routines are retained for compatibility. A
|
||||||
|
handle is maintained locally so that the caller does not have to provide the
|
||||||
|
buffers or handle for the first serial port.
|
||||||
|
|
||||||
|
The enhanced methods use a handle, which is a pointer to a memory buffer that
|
||||||
|
contains the serial port's state information and transmit and receive buffers.
|
||||||
|
The size of the memory buffer is equal to header_size + rxsize + txsize in
|
||||||
|
bytes. The buffer must be long aligned. The transmit and receive buffer
|
||||||
|
sizes must be a power of 2. They can range anywhere from a value of 2 up to
|
||||||
|
the size of the available memory.
|
||||||
|
}}
|
||||||
|
CON
|
||||||
|
' Data structure byte offsets
|
||||||
|
' long variables
|
||||||
|
tm_seconds = 0
|
||||||
|
tm_clkticks = 4
|
||||||
|
bit_ticks = 8
|
||||||
|
' word variables
|
||||||
|
rx_head = 12
|
||||||
|
rx_tail = 14
|
||||||
|
tx_head = 16
|
||||||
|
tx_tail = 18
|
||||||
|
rx_buffer = 20
|
||||||
|
tx_buffer = 22
|
||||||
|
rx_mask = 24
|
||||||
|
tx_mask = 26
|
||||||
|
' byte variables
|
||||||
|
cog = 28
|
||||||
|
lock = 29
|
||||||
|
rx_pin = 30
|
||||||
|
tx_pin = 31
|
||||||
|
rxtx_mode = 32
|
||||||
|
header_size = 36
|
||||||
|
|
||||||
|
' Data structure storage for the default serial port
|
||||||
|
DAT
|
||||||
|
handle1 long 0
|
||||||
|
data_struct long 0[(header_size+16+16)/4]
|
||||||
|
|
||||||
|
''
|
||||||
|
''*****************************************************************************
|
||||||
|
''Original FullDuplexSerial routines for compatibility
|
||||||
|
''*****************************************************************************
|
||||||
|
PUB rxflush
|
||||||
|
'' Flush receive buffer
|
||||||
|
rxflush1(handle1)
|
||||||
|
|
||||||
|
PUB rxcheck
|
||||||
|
'' Check if byte received (never waits)
|
||||||
|
'' returns -1 if no byte received, $00..$FF if byte
|
||||||
|
return rxcheck1(handle1)
|
||||||
|
|
||||||
|
PUB rxtime(ms)
|
||||||
|
'' Wait ms milliseconds for a byte to be received
|
||||||
|
'' returns -1 if no byte received, $00..$FF if byte
|
||||||
|
return rxtime1(handle1, ms)
|
||||||
|
|
||||||
|
PUB rx
|
||||||
|
'' Receive byte (may wait for byte)
|
||||||
|
'' returns $00..$FF
|
||||||
|
return rx1(handle1)
|
||||||
|
|
||||||
|
PUB tx(txbyte)
|
||||||
|
'' Send byte (may wait for room in buffer)
|
||||||
|
tx1(handle1, txbyte)
|
||||||
|
|
||||||
|
PUB str(stringptr)
|
||||||
|
'' Send string
|
||||||
|
str1(handle1, stringptr)
|
||||||
|
|
||||||
|
PUB dec(value)
|
||||||
|
'' Print a decimal number
|
||||||
|
dec1(handle1, value)
|
||||||
|
|
||||||
|
PUB hex(value, digits)
|
||||||
|
'' Print a hexadecimal number
|
||||||
|
hex1(handle1, value, digits)
|
||||||
|
|
||||||
|
PUB bin(value, digits)
|
||||||
|
'' Print a binary number
|
||||||
|
bin1(handle1, value, digits)
|
||||||
|
|
||||||
|
''
|
||||||
|
''*****************************************************************************
|
||||||
|
''Enhanced routines
|
||||||
|
''*****************************************************************************
|
||||||
|
PUB kbhit
|
||||||
|
return kbhit1(handle1)
|
||||||
|
|
||||||
|
PUB kbhit1(handle)
|
||||||
|
return word[handle+rx_tail] <> word[handle+rx_head]
|
||||||
|
|
||||||
|
PUB rxflush1(handle)
|
||||||
|
'' Flush receive buffer
|
||||||
|
word[handle+rx_tail] := word[handle+rx_head]
|
||||||
|
|
||||||
|
PUB rxcheck1(handle) : rxbyte | rx_tail1, rx_buffer1
|
||||||
|
'' Check if byte received (never waits)
|
||||||
|
'' returns -1 if no byte received, $00..$FF if byte
|
||||||
|
rxbyte--
|
||||||
|
rx_tail1 := word[handle+rx_tail]
|
||||||
|
if rx_tail1 <> word[handle+rx_head]
|
||||||
|
rx_buffer1 := word[handle+rx_buffer]
|
||||||
|
rxbyte := byte[rx_buffer1+rx_tail1]
|
||||||
|
word[handle+rx_tail] := (rx_tail1 + 1) & word[handle+rx_mask]
|
||||||
|
|
||||||
|
PUB rxtime1(handle, ms) : rxbyte | t
|
||||||
|
'' Wait ms milliseconds for a byte to be received
|
||||||
|
'' returns -1 if no byte received, $00..$FF if byte
|
||||||
|
t := cnt
|
||||||
|
repeat until (rxbyte := rxcheck1(handle)) => 0 or (cnt - t) / (clkfreq / 1000) > ms
|
||||||
|
|
||||||
|
PUB rx1(handle) : rxbyte
|
||||||
|
'' Receive byte (may wait for byte)
|
||||||
|
'' returns $00..$FF
|
||||||
|
repeat while (rxbyte := rxcheck1(handle)) < 0
|
||||||
|
|
||||||
|
PRI txchar(handle, txbyte) | tx_mask1, tx_buffer1, tx_head1, tx_head2
|
||||||
|
'' Send byte (may wait for room in buffer)
|
||||||
|
tx_mask1 := word[handle+tx_mask]
|
||||||
|
tx_buffer1 := word[handle+tx_buffer]
|
||||||
|
tx_head1 := word[handle+tx_head]
|
||||||
|
tx_head2 := (tx_head1 + 1) & tx_mask1
|
||||||
|
repeat until (word[handle+tx_tail] <> tx_head2)
|
||||||
|
{
|
||||||
|
if (byte[handle+rxtx_mode] & %100000) and (txbyte == 10)
|
||||||
|
txbyte := 13
|
||||||
|
}
|
||||||
|
byte[tx_buffer1+tx_head1] := txbyte
|
||||||
|
word[handle+tx_head] := tx_head2
|
||||||
|
|
||||||
|
if byte[handle+rxtx_mode] & %1000
|
||||||
|
rx1(handle)
|
||||||
|
|
||||||
|
PUB tx1(handle, txbyte) | uselock, locknum
|
||||||
|
'' Send byte - Use lock if mode bit 4 is set
|
||||||
|
uselock := byte[handle+rxtx_mode] & %10000
|
||||||
|
|
||||||
|
if (uselock)
|
||||||
|
locknum := byte[handle+lock] - 1
|
||||||
|
repeat until not lockset(locknum)
|
||||||
|
|
||||||
|
txchar(handle, txbyte)
|
||||||
|
|
||||||
|
if (uselock)
|
||||||
|
lockclr(locknum)
|
||||||
|
|
||||||
|
PUB str1(handle, stringptr) | uselock, locknum, value
|
||||||
|
'' Send string - Use lock if mode bit 4 is set
|
||||||
|
uselock := byte[handle+rxtx_mode] & %10000
|
||||||
|
|
||||||
|
if (uselock)
|
||||||
|
locknum := byte[handle+lock] - 1
|
||||||
|
repeat until not lockset(locknum)
|
||||||
|
|
||||||
|
repeat strsize(stringptr)
|
||||||
|
txchar(handle, byte[stringptr++])
|
||||||
|
|
||||||
|
if (uselock)
|
||||||
|
lockclr(locknum)
|
||||||
|
|
||||||
|
PUB dec1(handle, value) | i
|
||||||
|
'' Print a decimal number
|
||||||
|
if (value < 0)
|
||||||
|
tx1(handle, "-")
|
||||||
|
if (value == NEGX)
|
||||||
|
tx1(handle, "2")
|
||||||
|
value += 2_000_000_000
|
||||||
|
value := -value
|
||||||
|
|
||||||
|
i := 1_000_000_000
|
||||||
|
repeat while (i > value and i > 1)
|
||||||
|
i /= 10
|
||||||
|
repeat while (i > 0)
|
||||||
|
tx1(handle, value/i + "0")
|
||||||
|
value //= i
|
||||||
|
i /= 10
|
||||||
|
|
||||||
|
PUB hex1(handle, value, digits)
|
||||||
|
'' Print a hexadecimal number
|
||||||
|
value <<= (8 - digits) << 2
|
||||||
|
repeat digits
|
||||||
|
tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
|
||||||
|
|
||||||
|
PUB bin1(handle, value, digits)
|
||||||
|
'' Print a binary number
|
||||||
|
value <<= 32 - digits
|
||||||
|
repeat digits
|
||||||
|
tx((value <-= 1) & 1 + "0")
|
||||||
|
|
||||||
|
PUB gethandle1
|
||||||
|
'' Get the local handle
|
||||||
|
return handle1
|
||||||
|
|
||||||
|
PUB dbprintf0(fmtstr)
|
||||||
|
dbprintf(fmtstr, @fmtstr)
|
||||||
|
|
||||||
|
PUB dbprintf1(fmtstr, arg1)
|
||||||
|
dbprintf(fmtstr, @arg1)
|
||||||
|
|
||||||
|
PUB dbprintf2(fmtstr, arg1, arg2)
|
||||||
|
dbprintf(fmtstr, @arg1)
|
||||||
|
|
||||||
|
PUB dbprintf3(fmtstr, arg1, arg2, arg3)
|
||||||
|
dbprintf(fmtstr, @arg1)
|
||||||
|
|
||||||
|
PUB dbprintf4(fmtstr, arg1, arg2, arg3, arg4)
|
||||||
|
dbprintf(fmtstr, @arg1)
|
||||||
|
|
||||||
|
PUB dbprintf5(fmtstr, arg1, arg2, arg3, arg4, arg5)
|
||||||
|
dbprintf(fmtstr, @arg1)
|
||||||
|
|
||||||
|
PUB dbprintf6(fmtstr, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||||
|
dbprintf(fmtstr, @arg1)
|
||||||
|
|
||||||
|
PUB dbprintf(fmtstr, arglist) | arg, val, digits
|
||||||
|
arg := long[arglist]
|
||||||
|
arglist += 4
|
||||||
|
repeat while (val := byte[fmtstr++])
|
||||||
|
if (val == "%")
|
||||||
|
digits := 0
|
||||||
|
repeat
|
||||||
|
case (val := byte[fmtstr++])
|
||||||
|
"d" : dec(arg)
|
||||||
|
"x" :
|
||||||
|
ifnot digits
|
||||||
|
digits := 8
|
||||||
|
hex(arg, digits)
|
||||||
|
"b" :
|
||||||
|
ifnot digits
|
||||||
|
digits := 32
|
||||||
|
bin(arg, digits)
|
||||||
|
"s" : str(arg)
|
||||||
|
"0".."9":
|
||||||
|
digits := (digits * 10) + val - "0"
|
||||||
|
next
|
||||||
|
0 : return
|
||||||
|
other: tx(val)
|
||||||
|
quit
|
||||||
|
arg := long[arglist]
|
||||||
|
arglist += 4
|
||||||
|
elseif (val == "\")
|
||||||
|
case (val := byte[fmtstr++])
|
||||||
|
"n" : tx(13)
|
||||||
|
"r" : tx(10)
|
||||||
|
0 : return
|
||||||
|
other: tx(val)
|
||||||
|
else
|
||||||
|
tx(val)
|
||||||
|
|
||||||
|
PUB settime(seconds, clkticks) | handle
|
||||||
|
handle := handle1
|
||||||
|
long[handle + tm_seconds] := seconds
|
||||||
|
long[handle + tm_clkticks] := clkticks | $80000000
|
||||||
|
repeat while long[handle + tm_clkticks] & $c0000000
|
||||||
|
|
||||||
|
PUB gettime(pclkticks) | handle
|
||||||
|
handle := handle1
|
||||||
|
long[handle + tm_clkticks] := $40000000
|
||||||
|
repeat while long[handle + tm_clkticks] & $c0000000
|
||||||
|
long[pclkticks] := long[handle + tm_clkticks]
|
||||||
|
return long[handle + tm_seconds]
|
||||||
|
|
||||||
|
''
|
||||||
|
''*****************************************************************************
|
||||||
|
''Original FullDuplexSerial routines for compatibility
|
||||||
|
''*****************************************************************************
|
||||||
|
PUB start(rxpin, txpin, mode, baudrate)
|
||||||
|
'' Start serial driver - starts a cog
|
||||||
|
'' returns false if no cog available
|
||||||
|
''
|
||||||
|
'' mode bit 0 = invert rx
|
||||||
|
'' mode bit 1 = invert tx
|
||||||
|
'' mode bit 2 = open-drain/source tx
|
||||||
|
'' mode bit 3 = ignore tx echo on rx
|
||||||
|
'' mode bit 4 = use lock
|
||||||
|
'' mode bit 5 = convert LF to CR on tx
|
||||||
|
return start1(@data_struct, rxpin, txpin, mode, baudrate, 256, 16)
|
||||||
|
|
||||||
|
''
|
||||||
|
''*****************************************************************************
|
||||||
|
''Enhanced routines
|
||||||
|
''*****************************************************************************
|
||||||
|
PUB start1(handle, rxpin, txpin, mode, baudrate, rxsize, txsize) : okay
|
||||||
|
'' Start serial driver - starts a cog
|
||||||
|
'' returns false if no cog available
|
||||||
|
''
|
||||||
|
'' mode bit 0 = invert rx
|
||||||
|
'' mode bit 1 = invert tx
|
||||||
|
'' mode bit 2 = open-drain/source tx
|
||||||
|
'' mode bit 3 = ignore tx echo on rx
|
||||||
|
'' mode bit 4 = use lock
|
||||||
|
'' mode bit 5 = convert LF to CR on tx
|
||||||
|
if (handle1)
|
||||||
|
if (handle1 == handle)
|
||||||
|
stop1(handle)
|
||||||
|
else
|
||||||
|
handle1 := handle
|
||||||
|
wordfill(handle+rx_head, 0, 4)
|
||||||
|
long[handle+tm_clkticks] := clkfreq + cnt
|
||||||
|
long[handle+tm_seconds] := 0
|
||||||
|
byte[handle+rx_pin] := rxpin
|
||||||
|
byte[handle+tx_pin] := txpin
|
||||||
|
byte[handle+rxtx_mode] := mode
|
||||||
|
long[handle+bit_ticks] := clkfreq / baudrate
|
||||||
|
word[handle+rx_buffer] := handle + header_size
|
||||||
|
word[handle+tx_buffer] := handle + header_size + rxsize
|
||||||
|
word[handle+rx_mask] := rxsize - 1
|
||||||
|
word[handle+tx_mask] := txsize - 1
|
||||||
|
if (mode & %10000)
|
||||||
|
okay := byte[handle+lock] := locknew + 1
|
||||||
|
if (okay == 0)
|
||||||
|
return 0
|
||||||
|
okay := byte[handle+cog] := cognew(@entry, handle) + 1
|
||||||
|
|
||||||
|
PUB stop1(handle) | cog1
|
||||||
|
'' Stop serial driver - frees a cog
|
||||||
|
cog1 := byte[handle+cog]
|
||||||
|
if cog1
|
||||||
|
cogstop(cog1 - 1)
|
||||||
|
longfill(handle, 0, header_size >> 2)
|
||||||
|
|
||||||
|
DAT
|
||||||
|
|
||||||
|
'***********************************
|
||||||
|
'* Assembly language serial driver *
|
||||||
|
'***********************************
|
||||||
|
|
||||||
|
org
|
||||||
|
'
|
||||||
|
'
|
||||||
|
' Entry
|
||||||
|
'
|
||||||
|
entry mov t1, par
|
||||||
|
add t1, #rx_pin
|
||||||
|
rdbyte t2,t1 'get rx_pin
|
||||||
|
mov rxbitmask,#1
|
||||||
|
shl rxbitmask,t2
|
||||||
|
|
||||||
|
add t1,#1 'get tx_pin
|
||||||
|
rdbyte t2,t1
|
||||||
|
mov txbitmask,#1
|
||||||
|
shl txbitmask,t2
|
||||||
|
|
||||||
|
add t1,#1 'get rxtx_mode
|
||||||
|
rdbyte rxtxmode,t1
|
||||||
|
|
||||||
|
mov t1, par
|
||||||
|
add t1, #bit_ticks 'get bit_ticks
|
||||||
|
rdlong bitticks,t1
|
||||||
|
|
||||||
|
mov t1, par
|
||||||
|
add t1, #tm_seconds 'get tmseconds
|
||||||
|
rdlong tmseconds,t1
|
||||||
|
|
||||||
|
mov t1, par
|
||||||
|
add t1, #tm_clkticks 'get tmclkticks
|
||||||
|
rdlong tmclkticks, #0 'get clkfreq
|
||||||
|
|
||||||
|
rdlong tmclkticks,t1
|
||||||
|
|
||||||
|
mov t1, par
|
||||||
|
add t1, #rx_buffer 'get rx_buffer ptr
|
||||||
|
rdword rxbuff,t1
|
||||||
|
|
||||||
|
add t1,#2 'get tx_buffer ptr
|
||||||
|
rdword txbuff,t1
|
||||||
|
|
||||||
|
add t1,#2 'get rx_mask
|
||||||
|
rdword rxmask,t1
|
||||||
|
|
||||||
|
add t1,#2 'get tx_mask
|
||||||
|
rdword txmask,t1
|
||||||
|
|
||||||
|
test rxtxmode,#%100 wz 'init tx pin according to mode
|
||||||
|
test rxtxmode,#%010 wc
|
||||||
|
if_z_ne_c or outa,txbitmask
|
||||||
|
if_z or dira,txbitmask
|
||||||
|
|
||||||
|
mov txcode,#transmit 'initialize multitasking addresses
|
||||||
|
mov clcode,#clock
|
||||||
|
|
||||||
|
'
|
||||||
|
'
|
||||||
|
' Receive
|
||||||
|
'
|
||||||
|
receive jmpret rxcode,txcode 'run a chunk of transmit code, then return
|
||||||
|
|
||||||
|
test rxtxmode,#%001 wz 'wait for start bit on rx pin
|
||||||
|
test rxbitmask,ina wc
|
||||||
|
if_z_eq_c jmp #receive
|
||||||
|
|
||||||
|
mov rxbits,#9 'ready to receive byte
|
||||||
|
mov rxcnt,bitticks
|
||||||
|
shr rxcnt,#1
|
||||||
|
add rxcnt,cnt
|
||||||
|
|
||||||
|
:bit add rxcnt,bitticks 'ready next bit period
|
||||||
|
|
||||||
|
:wait jmpret rxcode,txcode 'run a chuck of transmit code, then return
|
||||||
|
|
||||||
|
mov t1,rxcnt 'check if bit receive period done
|
||||||
|
sub t1,cnt
|
||||||
|
cmps t1,#0 wc
|
||||||
|
if_nc jmp #:wait
|
||||||
|
|
||||||
|
test rxbitmask,ina wc 'receive bit on rx pin
|
||||||
|
rcr rxdata,#1
|
||||||
|
djnz rxbits,#:bit
|
||||||
|
|
||||||
|
shr rxdata,#32-9 'justify and trim received byte
|
||||||
|
and rxdata,#$FF
|
||||||
|
test rxtxmode,#%001 wz 'if rx inverted, invert byte
|
||||||
|
if_nz xor rxdata,#$FF
|
||||||
|
|
||||||
|
mov t1, par
|
||||||
|
add t1, #rx_head
|
||||||
|
rdword t2, t1 'save received byte and inc head
|
||||||
|
add t2,rxbuff
|
||||||
|
wrbyte rxdata,t2
|
||||||
|
sub t2,rxbuff
|
||||||
|
add t2,#1
|
||||||
|
and t2,rxmask
|
||||||
|
wrword t2,t1
|
||||||
|
|
||||||
|
jmp #receive 'byte done, receive next byte
|
||||||
|
'
|
||||||
|
'
|
||||||
|
' Transmit
|
||||||
|
'
|
||||||
|
transmit jmpret txcode,clcode 'run a chunk of clock code, then return
|
||||||
|
|
||||||
|
mov t1,par 'check for head <> tail
|
||||||
|
add t1,#tx_head
|
||||||
|
rdword t2,t1
|
||||||
|
add t1,#2
|
||||||
|
rdword t3,t1
|
||||||
|
cmp t2,t3 wz
|
||||||
|
if_z jmp #transmit
|
||||||
|
|
||||||
|
add t3,txbuff 'get byte and inc tail
|
||||||
|
rdbyte txdata,t3
|
||||||
|
sub t3,txbuff
|
||||||
|
add t3,#1
|
||||||
|
and t3,txmask
|
||||||
|
wrword t3,t1
|
||||||
|
|
||||||
|
or txdata,#$100 'ready byte to transmit
|
||||||
|
shl txdata,#2
|
||||||
|
or txdata,#1
|
||||||
|
mov txbits,#11
|
||||||
|
mov txcnt,cnt
|
||||||
|
|
||||||
|
:bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode
|
||||||
|
test rxtxmode,#%010 wc
|
||||||
|
if_z_and_c xor txdata,#1
|
||||||
|
shr txdata,#1 wc
|
||||||
|
if_z muxc outa,txbitmask
|
||||||
|
if_nz muxnc dira,txbitmask
|
||||||
|
add txcnt,bitticks 'ready next cnt
|
||||||
|
|
||||||
|
:wait jmpret txcode,clcode 'run a chunk of clock code, then return
|
||||||
|
|
||||||
|
mov t1,txcnt 'check if bit transmit period done
|
||||||
|
sub t1,cnt
|
||||||
|
cmps t1,#0 wc
|
||||||
|
if_nc jmp #:wait
|
||||||
|
|
||||||
|
djnz txbits,#:bit 'another bit to transmit?
|
||||||
|
|
||||||
|
jmp #transmit 'byte done, transmit next byte
|
||||||
|
|
||||||
|
clock jmpret clcode,rxcode 'run the receive task
|
||||||
|
mov t2, par
|
||||||
|
add t2, #tm_clkticks
|
||||||
|
rdlong t1, t2
|
||||||
|
shl t1, #1 wc
|
||||||
|
if_c jmp #setclock
|
||||||
|
shl t1, #1 wc
|
||||||
|
if_c jmp #getclock
|
||||||
|
mov t1, cnt
|
||||||
|
sub t1, tmclkticks
|
||||||
|
shl t1, #1 wc
|
||||||
|
if_c jmp #clock
|
||||||
|
add tmseconds, #1
|
||||||
|
rdlong t1, #0
|
||||||
|
add tmclkticks, t1
|
||||||
|
jmp #clock
|
||||||
|
|
||||||
|
setclock shl t1, #3
|
||||||
|
shr t1, #4
|
||||||
|
rdlong tmclkticks, #0
|
||||||
|
add tmclkticks, cnt
|
||||||
|
sub tmclkticks, t1
|
||||||
|
mov t2, par
|
||||||
|
add t2, #tm_seconds
|
||||||
|
rdlong tmseconds, t2
|
||||||
|
mov t2, par
|
||||||
|
add t2, #tm_clkticks
|
||||||
|
wrlong t1, t2
|
||||||
|
jmp #clock
|
||||||
|
|
||||||
|
getclock rdlong t1, #0
|
||||||
|
mov t2, cnt
|
||||||
|
add t2, t1
|
||||||
|
sub t2, tmclkticks
|
||||||
|
mov t3, par
|
||||||
|
add t3, #tm_seconds
|
||||||
|
wrlong tmseconds, t3
|
||||||
|
mov t3, par
|
||||||
|
add t3, #tm_clkticks
|
||||||
|
wrlong t2, t3
|
||||||
|
jmp #clock
|
||||||
|
|
||||||
|
'
|
||||||
|
'
|
||||||
|
' Uninitialized data
|
||||||
|
'
|
||||||
|
t1 res 1
|
||||||
|
t2 res 1
|
||||||
|
t3 res 1
|
||||||
|
|
||||||
|
rxtxmode res 1
|
||||||
|
bitticks res 1
|
||||||
|
|
||||||
|
rxbitmask res 1
|
||||||
|
rxbuff res 1
|
||||||
|
rxdata res 1
|
||||||
|
rxbits res 1
|
||||||
|
rxcnt res 1
|
||||||
|
rxcode res 1
|
||||||
|
rxmask res 1
|
||||||
|
|
||||||
|
txbitmask res 1
|
||||||
|
txbuff res 1
|
||||||
|
txdata res 1
|
||||||
|
txbits res 1
|
||||||
|
txcnt res 1
|
||||||
|
txcode res 1
|
||||||
|
txmask res 1
|
||||||
|
|
||||||
|
tmclkticks res 1
|
||||||
|
tmseconds res 1
|
||||||
|
clcode res 1
|
||||||
|
|
||||||
|
fit $100
|
||||||
|
|
||||||
|
{{
|
||||||
|
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ TERMS OF USE: MIT License │
|
||||||
|
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│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 AUTHORS OR │
|
||||||
|
│COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||||
|
│ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||||
|
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||||
|
}}
|
|
@ -0,0 +1,34 @@
|
||||||
|
obj
|
||||||
|
sys : "sysdefs"
|
||||||
|
|
||||||
|
dat
|
||||||
|
run_prog
|
||||||
|
long $a0bc65f0, $08bc6e32, $80fc6404, $08bc7032, $80fc6404, $08bc6032
|
||||||
|
long $80fc6404, $08bc6232, $80fc63ff, $28fc6209, $08fc6600, $00fc6804
|
||||||
|
long $083c6029, $083c5c2a, $083c582b, $08bc642b, $863c642c, $5c68000f
|
||||||
|
long $80fc6001, $80fc5d00, $80fc5d00, $e4fc620c, $087c6600, $007c6804
|
||||||
|
long $04fc6a08, $04fc6c0a, $a0bc6236, $84bc6235, $28fc6202, $083c5a35
|
||||||
|
long $80fc6a04, $e4fc621d, $083c5a36, $80fc6c04, $083c6e36, $80fc6c04
|
||||||
|
long $083c7036, $0cfc6401, $60fc6407, $68bc5e32, $0c7c5e02, $00007fd8
|
||||||
|
long $00007fdc, $00007fd4, $00000072, $00000000, $00000000, $0007c010
|
||||||
|
|
||||||
|
arg_list long 0[4]
|
||||||
|
|
||||||
|
pub exit(retval) | i, cogspi
|
||||||
|
cogspi := long[sys#SPI_engine_cog] - 1
|
||||||
|
arg_list[2] := long[sys#shell_sector]
|
||||||
|
arg_list[3] := long[sys#shell_size]
|
||||||
|
long[sys#return_value] := retval
|
||||||
|
|
||||||
|
' Stop all the cogs except this one and the SD SPI cog
|
||||||
|
repeat i from 0 to 7
|
||||||
|
if (i <> cogid and i <> cogspi)
|
||||||
|
cogstop(i)
|
||||||
|
|
||||||
|
' Clear and return all the locks
|
||||||
|
repeat i from 0 to 7
|
||||||
|
lockclr(i)
|
||||||
|
lockret(i)
|
||||||
|
|
||||||
|
' Start run_prog in this cog
|
||||||
|
coginit(cogid, @run_prog, @arg_list)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,112 @@
|
||||||
|
'******************************************************************************
|
||||||
|
' Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
' See end of file for terms of use.
|
||||||
|
'******************************************************************************
|
||||||
|
CON
|
||||||
|
'start = $7e50 ' Extra space for the stand-alone loader
|
||||||
|
start = $7c00 ' Extra space for the stand-alone loader
|
||||||
|
|
||||||
|
' SD CLIB data
|
||||||
|
rendezvous = $7e50
|
||||||
|
|
||||||
|
' Exported variables
|
||||||
|
environ_vars = $7e50
|
||||||
|
environ_vars_end = $7ed3
|
||||||
|
|
||||||
|
' Argv parameter area
|
||||||
|
argv_parms = $7ed4
|
||||||
|
|
||||||
|
' Additional system parameters
|
||||||
|
return_value = $7f94
|
||||||
|
vga_cog = $7f98
|
||||||
|
vga_handle = $7f9c
|
||||||
|
sd_pins = $7fa0
|
||||||
|
config = $7fa4
|
||||||
|
shell_sector = $7fa8
|
||||||
|
|
||||||
|
' System time
|
||||||
|
unixtime = $7fac
|
||||||
|
cycle0 = $7fb0
|
||||||
|
timezone = $7fb4
|
||||||
|
{
|
||||||
|
' I2C Driver
|
||||||
|
i2c_cog = $7fb8
|
||||||
|
i2c_cmd = $7fbc
|
||||||
|
i2c_parm = $7fc0
|
||||||
|
|
||||||
|
' Kernel data
|
||||||
|
filelock = $7fc4
|
||||||
|
filecmd = $7fc8
|
||||||
|
fileparm = $7fcc
|
||||||
|
}
|
||||||
|
'Shell variables
|
||||||
|
scriptline = $7fb8
|
||||||
|
ifflag = $7fbc
|
||||||
|
whileflag = $7fc0
|
||||||
|
shell_size = $7fc4
|
||||||
|
shell_level = $7fc8
|
||||||
|
bootflag = $7fcc
|
||||||
|
|
||||||
|
'File I/O
|
||||||
|
spi_engine_cog = $7fd0
|
||||||
|
spi_command = $7fd4
|
||||||
|
spi_block_index = $7fd8
|
||||||
|
spi_buffer_address = $7fdc
|
||||||
|
|
||||||
|
' Basic CLIB data
|
||||||
|
' Serial data
|
||||||
|
serial = $7fe0
|
||||||
|
stdio = $7fe4
|
||||||
|
stdin = $7fe8
|
||||||
|
stdout = $7fec
|
||||||
|
|
||||||
|
' Malloc data
|
||||||
|
memlocknum = $7ff0
|
||||||
|
memfreelist = $7ff4
|
||||||
|
malloclist = $7ff8
|
||||||
|
laststackaddr = $7ffc
|
||||||
|
|
||||||
|
' Stack check word
|
||||||
|
checkword = $dead1eaf
|
||||||
|
|
||||||
|
' Process types
|
||||||
|
proc_type_spin = 1
|
||||||
|
proc_type_pasm = 2
|
||||||
|
proc_type_capp = 3
|
||||||
|
proc_type_driver = $80
|
||||||
|
|
||||||
|
' Run modes
|
||||||
|
run_shell_wait = $00
|
||||||
|
run_shell_nowait = $08
|
||||||
|
run_kill_caller = $10
|
||||||
|
run_at_address0 = $20
|
||||||
|
run_c_program = $40
|
||||||
|
run_spin_program = $80
|
||||||
|
run_stand_alone = $100
|
||||||
|
|
||||||
|
PUB main
|
||||||
|
return
|
||||||
|
|
||||||
|
{{
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
| TERMS OF USE: MIT License |
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
|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 |
|
||||||
|
|AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
|
|LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,|
|
||||||
|
|OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE|
|
||||||
|
|SOFTWARE. |
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
}}
|
|
@ -0,0 +1,26 @@
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
|The spinix software is distributed under the terms of the MIT license as |
|
||||||
|
|shown below. |
|
||||||
|
| |
|
||||||
|
|Copyright (c) 2011, 2012, 2013, Dave Hein |
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
| TERMS OF USE: MIT License |
|
||||||
|
+-----------------------------------------------------------------------------+
|
||||||
|
|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 |
|
||||||
|
|AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
||||||
|
|LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,|
|
||||||
|
|OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE|
|
||||||
|
|SOFTWARE. |
|
||||||
|
+-----------------------------------------------------------------------------+
|
|
@ -0,0 +1,24 @@
|
||||||
|
ALIAS(1) User Commands ALIAS(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
alias - create an alias
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
alias [name=value]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The alias command will create an alias symbol that will be used
|
||||||
|
generate a shell command. If not parameters are specified the list
|
||||||
|
of aliases will be printed.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013 Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility October 2013 ALIAS(1)
|
|
@ -0,0 +1,34 @@
|
||||||
|
BOOT(1) Spinix OS BOOT(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
boot - spinix boot program
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The spinix boot program resides in the Propeller boot EEPROM. When run
|
||||||
|
for the first time, the boot program prompts the user for the I/O pins
|
||||||
|
used to interface to the SD card. The pin values are stored back into
|
||||||
|
EEPROM so that the user does not need to specify them in subsequent
|
||||||
|
start ups.
|
||||||
|
|
||||||
|
The boot program starts up the serial and SD drivers. The serial and
|
||||||
|
SD drivers and the kernel each run in their own cog.
|
||||||
|
|
||||||
|
The boot program reads the file _shell.var, and set the SHELL
|
||||||
|
environment variable to the contents of this file. It then verifies
|
||||||
|
that the shell program exists, and starts the shell.
|
||||||
|
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
For more information see the man pages for spinix and shell.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013 Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX OS September 2013 BOOT(1)
|
|
@ -0,0 +1,25 @@
|
||||||
|
CAT(1) User Commands CAT(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
cat - concatenate files and print on the standard output
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
cat [FILE]...
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Concatenate FILE(s), or standard input to the standard output. When no
|
||||||
|
files are specified the standard input is used. Input from the standard
|
||||||
|
input is terminated by typing a ^D.
|
||||||
|
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 CAT(1)
|
|
@ -0,0 +1,24 @@
|
||||||
|
CD(1) User Commands CD(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
cd - change the working directory
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
cd [directory]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The cd utility changes the working directory in the current shell if
|
||||||
|
the directory path exists. Otherwise, the current working directory
|
||||||
|
will remain the same.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 CD(1)
|
|
@ -0,0 +1,24 @@
|
||||||
|
CHMOD(1) User Commands CHMOD(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
chmod - change file mode bits
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
chmod [MODE] [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Changes the mode bits of a FILE based on the MODE string. MODE is
|
||||||
|
either an octal number or contains the characters +-drwx. If an octal
|
||||||
|
number is specified, the bits map to the drwx field.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 CHMOD(1)
|
|
@ -0,0 +1,49 @@
|
||||||
|
CONFIG(1) User Commands CONFIG(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
config - configure the system
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
config [PARM]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The config utility is used to control how information is displayed on
|
||||||
|
the console terminal. The config utility writes the value of PARM to
|
||||||
|
the config location in Spinix. PARM is expressed as a hexadecimal
|
||||||
|
number.
|
||||||
|
|
||||||
|
The config value indicates the number of display lines, the terminal
|
||||||
|
type and whether a newline sends the line-feed and carriage-return
|
||||||
|
characters to the console. The format of PARM is "NNTL", where "NN" is
|
||||||
|
a 2-digit hex number indicating the number of display lines, "T" is a
|
||||||
|
single hex digit with a value of 0, 1 or 2 for TTY, PST or ANSI
|
||||||
|
terminal mode. "L" is a single hex digit with the following values:
|
||||||
|
|
||||||
|
0 - Do not send any characters
|
||||||
|
1 - Send a LF character
|
||||||
|
2 - Send a CR character
|
||||||
|
3 - Send a CR character followed by a LF
|
||||||
|
|
||||||
|
The "linefeed" command may also be used to enable/disable whether a
|
||||||
|
line-feed character is sent by a newline.
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
The following shows various examples of terminal configurations:
|
||||||
|
|
||||||
|
config 2 - TTY terminal with no line specification
|
||||||
|
config 12 - PST terminal with no line specification
|
||||||
|
config 23 - ANSI terminal with no line specification
|
||||||
|
config 1823 - 24-line ANSI terminal with CR and LF
|
||||||
|
config 2812 - 40-line PST terminal with CR
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 CONFIG(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
CP(1) User Commands CP(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
cp - copy files
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
cp [FILE1] [FILE2]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Copy FILE1 to FILE2
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 CP(1)
|
|
@ -0,0 +1,30 @@
|
||||||
|
DATE(1) User Commands DATE(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
date - display or set the system date and time
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
date [-s [yyyy/mm/dd] [hh:mm[:ss]]]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
If no parameters are specified the date and time will be displayed
|
||||||
|
in the yyyy/mm/dd hh:mm:ss format. If the -s option is specified
|
||||||
|
without any additional parameters the unix epoch time will be printed,
|
||||||
|
which is the number of seconds since the beginning of 1970.
|
||||||
|
|
||||||
|
If the -s option is specified with additional parameters the date
|
||||||
|
and/or time can be set by specifying either the date, time or both.
|
||||||
|
The date and time can be specified in either order, and the seconds
|
||||||
|
parameter is optional when specifying the time.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility September 2013 DATE(1)
|
|
@ -0,0 +1,31 @@
|
||||||
|
DECLARE(1) User Commands DECLARE(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
declare - declare one or more environment variables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
declare [-p] [-x] [name[=[value]]...]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
If no parameters are specified, export will print all of the
|
||||||
|
environment variables. If only the -p option is provided the variables
|
||||||
|
will be printed preceed by "declare -F ", where F will be x for
|
||||||
|
exported variables, and - for non-exported variables. If -x is
|
||||||
|
specified only the exported variables will be printed.
|
||||||
|
|
||||||
|
If one or more names is provided the variables will be declared. If
|
||||||
|
the name is followed by the "=" character the following value will be
|
||||||
|
assigned to the variable. If the -x option is specified before the
|
||||||
|
list of names the variables will be exported.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2013 DECLARE(1)
|
|
@ -0,0 +1,36 @@
|
||||||
|
DIAG(1) User Commands DIAG(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
diag - perform diagnostics
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
diag
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
diag implements the following commands:
|
||||||
|
|
||||||
|
help - Print commands
|
||||||
|
exit - Exit diag
|
||||||
|
stack - Print the amount of unused stack space
|
||||||
|
malloc - Print the malloc and free lists
|
||||||
|
peek address - Print value at address in EEPROM
|
||||||
|
poke address num - Write value at address in EEPROM
|
||||||
|
dump address num - Print num values statring at address in EEPROM
|
||||||
|
peekm address - Print value at address in memory
|
||||||
|
pokem address num - Write value at address in memory
|
||||||
|
dumpm address num - Print num values statring at address in memory
|
||||||
|
filename - Execute an application file
|
||||||
|
|
||||||
|
LIMITATIONS
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility November 2013 DIAG(1)
|
|
@ -0,0 +1,11 @@
|
||||||
|
help - Print commands
|
||||||
|
exit - Exit diag
|
||||||
|
stack - Print the amount of unused stack space
|
||||||
|
malloc - Print the malloc and free lists
|
||||||
|
peek address - Print value at address in EEPROM
|
||||||
|
poke address num - Write value at address in EEPROM
|
||||||
|
dump address num - Print num values statring at address in EEPROM
|
||||||
|
peekm address - Print value at address in memory
|
||||||
|
pokem address num - Write value at address in memory
|
||||||
|
dumpm address num - Print num values statring at address in memory
|
||||||
|
filename - Execute an application file
|
|
@ -0,0 +1,23 @@
|
||||||
|
DIFF(1) User Commands DIFF(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
diff - compare files line by line
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
diff [FILE1] [FILE2]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Compares FILE1 with FILE2 line by line, and prints the differences to
|
||||||
|
the standard output.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 DIFF(1)
|
|
@ -0,0 +1,26 @@
|
||||||
|
DOS2UNIX(1) User Commands DOS2UNIX(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
dos2unix - convert from from dos to unix format
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
dos2unix [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The dos2unix utility converts a text file from the DOS format to the
|
||||||
|
Unix format. A line in a DOS text file is terminated by the carriage-
|
||||||
|
return and line-feed characters. A Unix file is terminated only by
|
||||||
|
the line-feed character.
|
||||||
|
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 DOS2UNIX(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
ECHO(1) User Commands ECHO(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
echo - display a line of text
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
echo [STRING]...
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Echo the STRING(s) to standard output.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 ECHO(1)
|
|
@ -0,0 +1,313 @@
|
||||||
|
ED(1) User Commands ED(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
ed - text editor
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
ed [file]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
ed is a line-oriented text editor. It is used to create, display,
|
||||||
|
modify and otherwise manipulate text files. This version of ed
|
||||||
|
implements most of the commands in the standard ed utility. It does
|
||||||
|
not allow wildcard or escape characters in the search or replacement
|
||||||
|
strings, and it cannot execute shell commands. It also does not
|
||||||
|
implement the undo command, and it only allows one command per line.
|
||||||
|
|
||||||
|
There are two non-standard commands supported that provide assistance
|
||||||
|
in using ed. The 'h' command will print help information that
|
||||||
|
summarizes the commands available in ed. A 'V' command was added to
|
||||||
|
provide an enhanced visualization mode, which prints the text around the
|
||||||
|
current line after executing a command.
|
||||||
|
|
||||||
|
If invoked with a file argument, a copy of file is read into the
|
||||||
|
editor's buffer. Changes are made to this copy and not directly to file
|
||||||
|
itself. Upon quitting ed, any changes not explicitly saved with a 'w'
|
||||||
|
command are lost.
|
||||||
|
|
||||||
|
Editing is done in two distinct modes: command and input. When first
|
||||||
|
invoked, ed is in command mode. In this mode commands are read from the
|
||||||
|
standard input and executed to manipulate the contents of the editor
|
||||||
|
buffer. A typical command might look like:
|
||||||
|
|
||||||
|
,s/old/new/g
|
||||||
|
|
||||||
|
which replaces all occurrences of the string old with new.
|
||||||
|
|
||||||
|
When an input command, such as 'a' (append), 'i' (insert) or 'c'
|
||||||
|
(change), is given, ed enters input mode. This is the primary means of
|
||||||
|
adding text to a file. In this mode, no commands are available;
|
||||||
|
instead, the standard input is written directly to the editor buffer.
|
||||||
|
Lines consist of text up to and including a newline character. Input
|
||||||
|
mode is terminated by entering a single period (.) on a line.
|
||||||
|
|
||||||
|
All ed commands operate on whole lines or ranges of lines; e.g., the 'd'
|
||||||
|
command deletes lines; the 'm' command moves lines, and so on. It is
|
||||||
|
possible to modify only a portion of a line by means of replacement, as
|
||||||
|
in the example above. However even here, the 's' command is applied to
|
||||||
|
whole lines at a time.
|
||||||
|
|
||||||
|
In general, ed commands consist of zero or more line addresses, followed
|
||||||
|
by a single character command and possibly additional parameters; i.e.,
|
||||||
|
commands have the structure:
|
||||||
|
|
||||||
|
[address [,address]]command[parameters]
|
||||||
|
|
||||||
|
The address(es) indicate the line or range of lines to be affected by
|
||||||
|
the command. If fewer addresses are given than the command accepts,
|
||||||
|
then default addresses are supplied.
|
||||||
|
|
||||||
|
|
||||||
|
OPTIONS
|
||||||
|
file Specifies the name of a file to read. The default filename is
|
||||||
|
set to the specified file.
|
||||||
|
|
||||||
|
|
||||||
|
LINE ADDRESSING
|
||||||
|
An address represents the number of a line in the buffer. ed maintains
|
||||||
|
a current address which is typically supplied to commands as the default
|
||||||
|
address when none is specified. When a file is first read, the
|
||||||
|
current address is set to the last line of the file. In general, the
|
||||||
|
current address is set to the last line affected by a command.
|
||||||
|
|
||||||
|
A line address is constructed from one of the bases in the list below,
|
||||||
|
optionally followed by a numeric offset. The offset may include any
|
||||||
|
combination of digits, operators (i.e. + and -). Addresses are read
|
||||||
|
from left to right, and their values are computed relative to the
|
||||||
|
current address.
|
||||||
|
|
||||||
|
One exception to the rule that addresses represent line numbers is the
|
||||||
|
address 0 (zero). This means "before the first line," and is legal
|
||||||
|
wherever it makes sense.
|
||||||
|
|
||||||
|
An address range is two addresses separated either by a comma or
|
||||||
|
semicolon. The value of the first address in a range cannot exceed the
|
||||||
|
value of the second. If only one address is given in a range, then the
|
||||||
|
second address is set to the given address. If only one address is
|
||||||
|
expected, then the last address is used.
|
||||||
|
|
||||||
|
Each address in a comma-delimited range is interpreted relative to the
|
||||||
|
current address. In a semicolon-delimited range, the first address is
|
||||||
|
used to set the current address, and the second address is
|
||||||
|
interpreted relative to the first.
|
||||||
|
|
||||||
|
|
||||||
|
The following address symbols are recognized.
|
||||||
|
|
||||||
|
|
||||||
|
. The current line (address) in the buffer.
|
||||||
|
|
||||||
|
|
||||||
|
$ The last line in the buffer.
|
||||||
|
|
||||||
|
|
||||||
|
n The nth, line in the buffer where n is a number in the range
|
||||||
|
[0,$].
|
||||||
|
|
||||||
|
|
||||||
|
- The previous line. This is equivalent to -1.
|
||||||
|
|
||||||
|
|
||||||
|
-n The nth previous line, where n is a non-negative number.
|
||||||
|
|
||||||
|
|
||||||
|
+ The next line. This is equivalent to +1.
|
||||||
|
|
||||||
|
|
||||||
|
+n The nth next line, where n is a non-negative number.
|
||||||
|
|
||||||
|
|
||||||
|
, The first through last lines in the buffer. This is equivalent
|
||||||
|
to the address range 1,$.
|
||||||
|
|
||||||
|
|
||||||
|
; The current through last lines in the buffer. This is
|
||||||
|
equivalent to the address range .,$.
|
||||||
|
|
||||||
|
|
||||||
|
/re/ The next line containing the regular expression re. The search
|
||||||
|
wraps to the beginning of the buffer and continues down to the
|
||||||
|
current line, if necessary. // repeats the last search.
|
||||||
|
|
||||||
|
|
||||||
|
?re? The previous line containing the regular expression re. The
|
||||||
|
search wraps to the end of the buffer and continues up to the
|
||||||
|
current line, if necessary. ?? repeats the last search.
|
||||||
|
|
||||||
|
|
||||||
|
REGULAR EXPRESSIONS
|
||||||
|
Regular expressions are patterns used in selecting text. For example,
|
||||||
|
the ed command
|
||||||
|
|
||||||
|
g/string/
|
||||||
|
|
||||||
|
prints all lines containing string. Regular expressions are also used
|
||||||
|
by the 's' command for selecting old text to be replaced with new. This
|
||||||
|
version of ed does not use any wildcard or escape characters.
|
||||||
|
|
||||||
|
COMMANDS
|
||||||
|
All ed commands are single characters, though some require additional
|
||||||
|
parameters. ed commands must fit in a single line, and cannot be
|
||||||
|
continued to another line.
|
||||||
|
|
||||||
|
In general, only one command is allowed per line. The only exceptions
|
||||||
|
are the 'g' and 'v' commands, which can be followed by an 's', 'p', 'l'
|
||||||
|
or 'n' command.
|
||||||
|
|
||||||
|
ed recognizes the following commands. The commands are shown together
|
||||||
|
with the default address or address range supplied if none is specified
|
||||||
|
(in parenthesis).
|
||||||
|
|
||||||
|
(.)a Appends text to the buffer after the addressed line, which may
|
||||||
|
be the address 0 (zero). Text is entered in input mode. The
|
||||||
|
current address is set to last line entered.
|
||||||
|
|
||||||
|
(.,.)c Changes lines in the buffer. The addressed lines are deleted
|
||||||
|
from the buffer, and text is appended in their place. Text is
|
||||||
|
entered in input mode. The current address is set to last line
|
||||||
|
entered.
|
||||||
|
|
||||||
|
(.,.)d Deletes the addressed lines from the buffer. If there is a line
|
||||||
|
after the deleted range, then the current address is set to this
|
||||||
|
line. Otherwise the current address is set to the line before
|
||||||
|
the deleted range.
|
||||||
|
|
||||||
|
e file Edits file, and sets the default filename. If file is not
|
||||||
|
specified, then the default filename is used. Any lines in the
|
||||||
|
buffer are deleted before the new file is read. The current
|
||||||
|
address is set to the last line read.
|
||||||
|
|
||||||
|
E file Edits file unconditionally. This is similar to the e command,
|
||||||
|
except that unwritten changes are discarded without warning.
|
||||||
|
The current address is set to the last line read.
|
||||||
|
|
||||||
|
f file Sets the default filename to file. If file is not specified,
|
||||||
|
then the default filename is printed.
|
||||||
|
|
||||||
|
(1,$)g/re/command
|
||||||
|
Applies command to each of the addressed lines matching a
|
||||||
|
regular expression re. The current address is set to the line
|
||||||
|
currently matched before command is executed. At the end of the
|
||||||
|
'g' command, the current address is set to the last line
|
||||||
|
affected by command. The allowable commands are 's', 'p', 'l'
|
||||||
|
and 'n'. The 'p' command is used if command is not specified.
|
||||||
|
|
||||||
|
h Print help information, which summarizes the commands available.
|
||||||
|
Note that this is different than the standard usage for 'h',
|
||||||
|
which prints an explanation of the last error.
|
||||||
|
|
||||||
|
(.)i Inserts text in the buffer before the current line. Text is
|
||||||
|
entered in input mode. The current address is set to the last
|
||||||
|
line entered.
|
||||||
|
|
||||||
|
(.,.+1)j
|
||||||
|
Joins the addressed lines. The addressed lines are deleted from
|
||||||
|
the buffer and replaced by a single line containing their joined
|
||||||
|
text. The current address is set to the resultant line.
|
||||||
|
|
||||||
|
(.,.)l Prints the addressed lines unambiguously. The current address
|
||||||
|
is set to the last line printed.
|
||||||
|
|
||||||
|
(.,.)m(.)
|
||||||
|
Moves lines in the buffer. The addressed lines are moved to
|
||||||
|
after the right-hand destination address, which may be the
|
||||||
|
address 0 (zero). The current address is set to the new address
|
||||||
|
of the last line moved.
|
||||||
|
|
||||||
|
(.,.)n Prints the addressed lines along with their line numbers. The
|
||||||
|
current address is set to the last line printed.
|
||||||
|
|
||||||
|
(.,.)p Prints the addressed lines. The current address is set to the
|
||||||
|
last line printed.
|
||||||
|
|
||||||
|
P Toggles the command prompt on and off. The command prompt is by
|
||||||
|
default turned off.
|
||||||
|
|
||||||
|
q Quits ed.
|
||||||
|
|
||||||
|
Q Quits ed unconditionally. This is similar to the q command,
|
||||||
|
except that unwritten changes are discarded without warning.
|
||||||
|
|
||||||
|
($)r file
|
||||||
|
Reads file to after the addressed line. If file is not
|
||||||
|
specified, then the default filename is used. If there was no
|
||||||
|
default filename prior to the command, then the default filename
|
||||||
|
is set to file. Otherwise, the default filename is unchanged.
|
||||||
|
The current address is set to the last line read.
|
||||||
|
|
||||||
|
(.,.)s/re/replacement/
|
||||||
|
(.,.)s/re/replacement/g
|
||||||
|
Replaces text in the addressed lines matching a regular
|
||||||
|
expression re with replacement. By default, only the first
|
||||||
|
match in each line is replaced. If the 'g' (global) suffix is
|
||||||
|
given, then every match to be replaced. It is an error if no
|
||||||
|
substitutions are performed on any of the addressed lines. The
|
||||||
|
current address is set to the last line affected.
|
||||||
|
|
||||||
|
(.,.)t(.)
|
||||||
|
Copies (i.e., transfers) the addressed lines to after the right-
|
||||||
|
hand destination address, which may be the address 0 (zero).
|
||||||
|
The current address is set to the last line copied.
|
||||||
|
|
||||||
|
(1,$)v/re/command-list
|
||||||
|
Applies command-list to each of the addressed lines not matching
|
||||||
|
a regular expression re. This is similar to the 'g' command.
|
||||||
|
|
||||||
|
|
||||||
|
Vn If n is specified, the visualization mode is enabled and the
|
||||||
|
number of lines printed is set to n. Otherwise, the
|
||||||
|
visualization mode it toggled on or off. The visualization mode
|
||||||
|
is a non-standard feature that prints the text in the edit
|
||||||
|
buffer before and after the current line.
|
||||||
|
|
||||||
|
(1,$)w file
|
||||||
|
Writes the addressed lines to file. Any previous contents of
|
||||||
|
file is lost without warning. If there is no default filename,
|
||||||
|
then the default filename is set to file, otherwise it is
|
||||||
|
unchanged. If no filename is specified, then the default
|
||||||
|
filename is used. The current address is unchanged.
|
||||||
|
|
||||||
|
(.)x Copies (puts) the contents of the cut buffer to after the
|
||||||
|
addressed line. The current address is set to the last line
|
||||||
|
copied.
|
||||||
|
|
||||||
|
(.,.)y Copies (yanks) the addressed lines to the cut buffer. The cut
|
||||||
|
buffer is overwritten by subsequent 'y', 'j', 'd', or 'c'
|
||||||
|
commands. The current address is unchanged.
|
||||||
|
|
||||||
|
(.+1)zn Scrolls n lines at a time starting at addressed line. If n is
|
||||||
|
not specified, then the current window size is used. The
|
||||||
|
current address is set to the last line printed.
|
||||||
|
|
||||||
|
($)= Prints the line number of the addressed line.
|
||||||
|
|
||||||
|
(.+1)newline
|
||||||
|
Prints the addressed line, and sets the current address to that
|
||||||
|
line.
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
B. W. Kernighan and P. J. Plauger, Software Tools in Pascal , Addison-
|
||||||
|
Wesley, 1981.
|
||||||
|
|
||||||
|
LIMITATIONS
|
||||||
|
ed is limited to 200 characters per line. If an input line is greater
|
||||||
|
than 200 characters it will be broken up into multiple lines. The input
|
||||||
|
file must terminate lines with a newline (LF) character. Files will be
|
||||||
|
written using the UNIX LF line termination. The size of the file is
|
||||||
|
limited by the amount of buffer memory available to ed. If ed
|
||||||
|
encounters an error in a command line it will print '?' and return to
|
||||||
|
command mode. Attempting to quit ed or edit another file before writing
|
||||||
|
a modified buffer results in an error. If the command is entered a
|
||||||
|
second time, it succeeds, but any changes to the buffer are lost.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 ED(1)
|
|
@ -0,0 +1,44 @@
|
||||||
|
ED Commands
|
||||||
|
|
||||||
|
Line Addresses
|
||||||
|
n - nth line
|
||||||
|
. - current line
|
||||||
|
$ - last line
|
||||||
|
- - previous line
|
||||||
|
-n - nth previous line
|
||||||
|
+ - next line
|
||||||
|
+n - nth next line
|
||||||
|
n,m - lines n through m
|
||||||
|
, - first through last lines
|
||||||
|
; - current through last lines
|
||||||
|
/str/ - next line containing str
|
||||||
|
?str? - previous line containing str
|
||||||
|
|
||||||
|
Editing Commands
|
||||||
|
(.)a - append text after the addressed line
|
||||||
|
(.,.)c - replace the addressed lines with text
|
||||||
|
(.,.)d - delete the addressed lines
|
||||||
|
e file - discard all lines and edit the specified file
|
||||||
|
E file - unconditionally discard all lines and edit specified file
|
||||||
|
f file - set the current file name and print the name
|
||||||
|
(1,$)g/str/cmd - execute a command on lines containing str
|
||||||
|
h - print help information
|
||||||
|
(.)i - insert text before the addressed line
|
||||||
|
(.,.+1)j - join the addressed lines
|
||||||
|
(.,.)l - print the addressed lines unambiguously
|
||||||
|
(.,.)m(.) - move the addressed lines to after the right-hand address
|
||||||
|
(.,.)n - print the addresses lines with line numbers
|
||||||
|
(.,.)p - print the addresses lines
|
||||||
|
P - toggle the prompt mode
|
||||||
|
q - quit
|
||||||
|
($)r file - read the specified file after the addressed line
|
||||||
|
(.,.)s/st1/st2/g - substitute occurances of st1 with st2
|
||||||
|
(.,.)t(.) - copy the addressed lines to after the right-hand address
|
||||||
|
(1,$)v/str/cmd - execute a command on lines not containing str
|
||||||
|
Vn - set visualization mode to n lines or toggle on/off if no n
|
||||||
|
(1,$)w file - write the addressed lines to the specified file
|
||||||
|
(.)x - insert lines from the cut buffer after the addressed line
|
||||||
|
(.,.)y - yank the addressed lines to the cut buffer
|
||||||
|
(.+1)zn - scroll and print n lines from the addressed line
|
||||||
|
($)= - print the line number of the addressed line
|
||||||
|
(.+1) - print the addressed line
|
|
@ -0,0 +1,29 @@
|
||||||
|
EXPORT(1) User Commands EXPORT(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
export - export one or more environment variables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
export [name[=[value]]...]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
If no parameters are specified, export will print all of the exported
|
||||||
|
environment variables. If one or more varible are supplied they will
|
||||||
|
become exported variables. If the variable had been previously
|
||||||
|
declared as a non-exported variable it will be exported with its
|
||||||
|
current value unless the "=" character is included. If a value is
|
||||||
|
specified after the "=" character it will become the new value of the
|
||||||
|
variable. If no value follows the "=" character the variable will be
|
||||||
|
assigned a NULL value.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2013 EXPORT(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
GETMOD(1) User Commands GETMOD(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
getmod - print the mode of a file
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
getmode [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Print the mode of FILE.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 GETMOD(1)
|
|
@ -0,0 +1,23 @@
|
||||||
|
HALT(1) User Commands HALT(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
halt - halt the system
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
halt
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
All of the precesses are stopped, and the processor is put in an idle
|
||||||
|
state.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 HALT(1)
|
|
@ -0,0 +1,26 @@
|
||||||
|
HEAD(1) User Commands HEAD(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
head - print the beginning lines of a file
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
head [OPTION] [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The first 10 lines of FILE are printed to the standard output if OPTION
|
||||||
|
is not present. A different number of lines can be specified with a
|
||||||
|
"-n" OPTION, where n is the postivie number. The standard input is used
|
||||||
|
if FILE is not specified. In the case of the standard input, head will
|
||||||
|
terminate after reading "n" lines.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 HEAD(1)
|
|
@ -0,0 +1,25 @@
|
||||||
|
HISTORY(1) User Commands HISTORY(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
history - print the shell command history
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
history [-c] [n]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
If no parameters are specified, the history file containing the
|
||||||
|
previous shell commands will be printed out. If a number is specified
|
||||||
|
only the last "n" lines will be printed. If the -c option is specified
|
||||||
|
the history file will be deleted.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013 Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility October 2013 HISTORY(1)
|
|
@ -0,0 +1,53 @@
|
||||||
|
LERNER(1) User Commands LERNER(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
lerner - conversational program that learns
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
lerner
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Lerner is a stand-alone conversational program that can learn by
|
||||||
|
building a vocabulary. It supports a simple grammatical syntax
|
||||||
|
containing a subject, verb and predicate. The predicate can contain
|
||||||
|
an optional adjective. The syntax is as follows:
|
||||||
|
|
||||||
|
[article] subject verb [article] [adjective] predicate
|
||||||
|
|
||||||
|
Each field must consist of a single word. The articles, "a", "an" and
|
||||||
|
"the" are optional. Statements can be made questions by adding a "?"
|
||||||
|
at the end. Questions can also start with the words "who", "what",
|
||||||
|
"does", "do", "is" and "are". The question mark is optional when
|
||||||
|
starting a question with these words.
|
||||||
|
|
||||||
|
Words must be spelled with the same capitalization as they were
|
||||||
|
defined. One exception is at the beginning of a sentence where the
|
||||||
|
first letter can be capitalized even if the word was defined in
|
||||||
|
lower-case.
|
||||||
|
|
||||||
|
Lerner supports the following commands:
|
||||||
|
|
||||||
|
vocab [word] - Print the words I know
|
||||||
|
dump - Print the words as hex codes
|
||||||
|
forget - Remove a word from memory
|
||||||
|
save - Save the words to EEPROM
|
||||||
|
reset - Reset the word table
|
||||||
|
basic - Reset the word table to a basic list
|
||||||
|
history - Print the short term memory
|
||||||
|
goodbye - Exit the program
|
||||||
|
help - Print this list of commands
|
||||||
|
|
||||||
|
Lerner normally saves its vocabulary to the EEPROM. However, the save
|
||||||
|
function has been disabled in this version.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX Program March 2012 LERNER(1)
|
|
@ -0,0 +1,42 @@
|
||||||
|
LET(1) User Commands LET(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
let - print a manual entry
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
let name=val1[op1val2...]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Sets the value of the named shell variable to the value of an
|
||||||
|
arithmetic expression. The arithmetic expression is evaluated from
|
||||||
|
left to right. The allowable operators are as follows:
|
||||||
|
|
||||||
|
>= - Greater than or equal
|
||||||
|
<= - Less than or equal
|
||||||
|
== - Equal
|
||||||
|
!= - Not equal
|
||||||
|
&& - Logical and
|
||||||
|
|| - Logical or
|
||||||
|
>> - Arithmetic shift right
|
||||||
|
<< - Shift left
|
||||||
|
+ - Add
|
||||||
|
- - Subtract
|
||||||
|
* - Multiply
|
||||||
|
/ - Divide
|
||||||
|
& - Bitwise and
|
||||||
|
| - Bitwise or
|
||||||
|
< - Less than
|
||||||
|
> - Greater than
|
||||||
|
% - Modulus
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2013 LET(1)
|
|
@ -0,0 +1,26 @@
|
||||||
|
LINEFEED(1) User Commands LINEFEED(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
linefeed - enable or disable linefeeds
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
linefeed [PARM]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The linefeed utility is used to enable or disable line-feeds when
|
||||||
|
printing the newline character. PARM can be either "on" or "off" to
|
||||||
|
enable or disable line-feeds.
|
||||||
|
|
||||||
|
The "config" command may also be used to perform a similar function.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 LINEFEED(1)
|
|
@ -0,0 +1,29 @@
|
||||||
|
LS(1) User Commands LS(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
ls - list files
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
ls [OPTIONS] [DIRECTORIES]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
List the files in the DIRECTORIES to the standard output. If no
|
||||||
|
DIRECTORIES are specified, the current directory is listed. If OPTIONS
|
||||||
|
is not specified, only the file names will be listed. OPTIONS can be
|
||||||
|
one or more of the following:
|
||||||
|
|
||||||
|
-l - Long list that shows the attributes and lengths
|
||||||
|
-a - Show all files including hidden files that start with . and _
|
||||||
|
-e - Show the executable type
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 LS(1)
|
|
@ -0,0 +1,23 @@
|
||||||
|
MAN(1) User Commands MAN(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
man - print a manual entry
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
man [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Prints the manual entry for a FILE to the standard output. man uses
|
||||||
|
the same display mode as "more".
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 MAN(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
MKDIR(1) User Commands MKDIR(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
mkdir - make a directory
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
mkdir [DIRECTORY]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Creates a directory named DIRECTORY.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 MKDIR(1)
|
|
@ -0,0 +1,26 @@
|
||||||
|
MORE(1) User Commands MORE(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
more - display a file page by page
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
more [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Displays FILE page by page. The following commands are used:
|
||||||
|
|
||||||
|
<space> - Display next page
|
||||||
|
<CR> - Display next line
|
||||||
|
q - Quit
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 MORE(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
ECHO(1) User Commands ECHO(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
mv - move a file
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
mv [OLDNAME] [NEWNAME]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Moves a file from OLDNAME to NEWNAME.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 ECHO(1)
|
|
@ -0,0 +1,26 @@
|
||||||
|
OD(1) User Commands OD(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
od - octal dump
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
od [OPTION] [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Dumps the contents of FILE to the standard output in octal if OPTION is
|
||||||
|
not specified, or if OPTION is "-o". If OPTION is "-x" the file will
|
||||||
|
be dumped in hexadecimal, and if OPTION is "-a" it will be dumped in
|
||||||
|
ASCII. In ASCII mode, any non-printable characters will be displayed
|
||||||
|
as escacped characters.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 OD(1)
|
|
@ -0,0 +1,40 @@
|
||||||
|
PFTH(1) User Commands PFTH(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
pfth - interpret and execute Forth programs
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
pfth [FILE]...
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
pfth is a Forth interpreter that can load Forth source files from the
|
||||||
|
SD card and execute them. One or more Forth files can be specified
|
||||||
|
on the command, which will be loaded when pfth starts up.
|
||||||
|
|
||||||
|
pfth supports up to two simultaneous opened files. This allows one
|
||||||
|
file to be read while another one is written, or two files can be read
|
||||||
|
at the same time. This also allows including a file from another file.
|
||||||
|
|
||||||
|
Simple versions of the ls, cat, rm and cp commands are supported under
|
||||||
|
pfth. The Forth source files used by pfth are included in the /forth
|
||||||
|
directory. It also includes a Forth versin of the ted line editor,
|
||||||
|
some SD utilities and other sample programs.
|
||||||
|
|
||||||
|
The user can exit pfth and return to the Spinix shell by typing the
|
||||||
|
bye command.
|
||||||
|
|
||||||
|
LIMITATIONS
|
||||||
|
pfth processes a maximum of six command-line parameters. No more than
|
||||||
|
two files can be opened at the same time.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility August 2013 PFTH(1)
|
|
@ -0,0 +1,24 @@
|
||||||
|
PRINTENV(1) User Commands PRINTENV(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
printenv - print the exported environment variables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
printenv [name...]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
If no parameters are specified, printenv will print all of the exported
|
||||||
|
environment variables. If one or more varible names are supplied only
|
||||||
|
the values of the listed variables will be printed.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2013 PRINTENV(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
PWD(1) User Commands PWD(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
pwd - print working directory
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
pwd
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Prints the current working directory to the standard output.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 PWD(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
RB(1) User Commands RB(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
rb - receive binary
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
rb
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Receives a binary file from the serial port using the YMODEM protocol.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 RB(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
REBOOT(1) User Commands REBOOT(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
reboot
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
reboot
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Immediately reboots the processor.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 REBOOT(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
RM(1) User Commands RM(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
rm - remove a file
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
rm [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Remove FILE.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 RM(1)
|
|
@ -0,0 +1,22 @@
|
||||||
|
SB(1) User Commands SB(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
sb - send binary
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
sb [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Send FILE to the serial port using the YMODEM protocol.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 SB(1)
|
|
@ -0,0 +1,24 @@
|
||||||
|
SET(1) User Commands SET(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
set - print the environment variables
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
set
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
set prints all of the shell variables, which include exported variables
|
||||||
|
and non-exported variables.
|
||||||
|
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2013 SET(1)
|
|
@ -0,0 +1,101 @@
|
||||||
|
SHELL(1) User Commands SHELL(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
shell - Spinix shell program
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
shell
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Provides the command-line interface for the Spinix operating system.
|
||||||
|
The shell program can execute the following commands:
|
||||||
|
|
||||||
|
pwd - print the current working directory
|
||||||
|
cd - change working directory
|
||||||
|
echo - echo the command line parameters
|
||||||
|
FILE - execute FILE
|
||||||
|
|
||||||
|
Executable files can be one of the following:
|
||||||
|
|
||||||
|
- Spinix Spin application
|
||||||
|
- Spinix C application
|
||||||
|
- Stand-alone C or Spin program
|
||||||
|
- script file
|
||||||
|
|
||||||
|
Spinix examines the first long of a file to determine what type of
|
||||||
|
executable it is. A Spin app contains "SPIN" and a C app contains
|
||||||
|
"CAPP". C apps must use the LMM memory model.
|
||||||
|
|
||||||
|
A stand-alone C or Spin program is signalled by a clock frequency
|
||||||
|
between 80 and 120 MHz. Spinix will modify the clock frequency to
|
||||||
|
match the current clock frequency when the stand-along program is run.
|
||||||
|
It does not modify any other portion of the program.
|
||||||
|
|
||||||
|
C and Spin programs must be less than or equal to 31.5K bytes since the
|
||||||
|
spinix shared memory is located in the top 512 bytes of memory.
|
||||||
|
Program files must consist of contiguous sectors, since the loader does
|
||||||
|
not implement cluster chaining. This can be ensured by using 32K
|
||||||
|
clusters.
|
||||||
|
|
||||||
|
Standard I/O can be redirected by using the ">", "<" and ">>" comand-
|
||||||
|
line modifiers.
|
||||||
|
|
||||||
|
The first line of a script file must start with "#shell". Script file
|
||||||
|
can call another script file up to 26 levels deep.
|
||||||
|
|
||||||
|
Shell script files support the following commands:
|
||||||
|
|
||||||
|
if - conditionally execute based on following condition
|
||||||
|
then - must be on the next line after an "if" line
|
||||||
|
fi - terminates the body of an if statment
|
||||||
|
while - begin conditional loop based on following condition
|
||||||
|
do - must be on the next line after a "while" line
|
||||||
|
done - terminats the body of a while statement
|
||||||
|
exit - exit the script file
|
||||||
|
|
||||||
|
An if statement may contain an executable file, such as
|
||||||
|
|
||||||
|
if spinit file
|
||||||
|
or
|
||||||
|
if test $a -ne 0
|
||||||
|
|
||||||
|
The if statement will test the return value from the executable file,
|
||||||
|
which is referenced by $?. A short-hand version of using test is to
|
||||||
|
use bracket, so that the "if test" statement above can be written as
|
||||||
|
|
||||||
|
if [ $a -ne 0 ]
|
||||||
|
|
||||||
|
The shell allows defining variables using the "=" operator, such as
|
||||||
|
|
||||||
|
a=123
|
||||||
|
|
||||||
|
There must be no spaces before or after the equal. Double quotes
|
||||||
|
can be used to assign a value containing spaces, such as
|
||||||
|
|
||||||
|
b="This is a test"
|
||||||
|
|
||||||
|
Variables can be accessed by prepending a "$" character to the name.
|
||||||
|
From the previous examples, a and b can be printed using echo by
|
||||||
|
typing
|
||||||
|
|
||||||
|
echo $a $b
|
||||||
|
|
||||||
|
Spinix provides other variables, which are $?, $#, $1, $2, etc.
|
||||||
|
$? contains the return value from the last program that has been
|
||||||
|
executed. $# contains the number of command-line parameters, and
|
||||||
|
$1, $2, etc. contain the values of the command-line parameters.
|
||||||
|
|
||||||
|
|
||||||
|
LIMITATIONS
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 SHELL(1)
|
|
@ -0,0 +1,351 @@
|
||||||
|
SPASM(1) User Commands SPASM(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
spasm - spin assembler
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
spasm [-l] [-d] FILE
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Spasm assembles the source file given by FILE. The file name may
|
||||||
|
include the extension, or .spa will be assumed if no extension is
|
||||||
|
specified. The assembled binary program will written to a file with
|
||||||
|
the same root name plus a .bin extension. If -l is specified, it will
|
||||||
|
print an assembly listing. If -d is specified, spasm will print debug
|
||||||
|
information.
|
||||||
|
|
||||||
|
Spasm is an assembly language that defines mnemonics for Spin
|
||||||
|
bytecodes. Spin bytecodes are executed by the Spin interpreter, which
|
||||||
|
is loaded at boot time from the internal ROM. The Spin interpreter is
|
||||||
|
a stack-based virtual machine that uses the stack to store parameters
|
||||||
|
that are used by operators, such as add, sub, etc. The operators store
|
||||||
|
their results back onto the stack. There are other operators that
|
||||||
|
transfer data back and forth between the stack and hub RAM.
|
||||||
|
|
||||||
|
The Spin bytecodes are listed below. They are separated into four
|
||||||
|
major groups -- lower, memory, math and extened operators. The lower
|
||||||
|
group contains a mix of operators, including those that handle program
|
||||||
|
flow, lookup, lookdown, case, and several other miscellaneous functions.
|
||||||
|
The math operators implement the various math and logic functions that
|
||||||
|
use two arguments.
|
||||||
|
|
||||||
|
The memory operators implement load, store, execute and address
|
||||||
|
functions. A load operation reads data from the hub RAM and pushes it
|
||||||
|
onto the stack. A store operation pops a value off the stack and
|
||||||
|
stores it in RAM. The address operator is used to push the absolute
|
||||||
|
address of a hub RAM location onto the stack.
|
||||||
|
|
||||||
|
The execute operation is used to execute an operation directly on a RAM
|
||||||
|
location. The result can be optionally pushed to the stack. The
|
||||||
|
operations that can be executed directly on a hub RAM location include
|
||||||
|
the standard 32 math operations plus a small number of extended
|
||||||
|
operations. The extended operators include pre and post increment and
|
||||||
|
decrement, sign extension and the random function.
|
||||||
|
|
||||||
|
The format of the memory mnemonics is as follows:
|
||||||
|
|
||||||
|
<operation><size><type><mode>
|
||||||
|
operation = {ld, st, ex, la},
|
||||||
|
size = {b, w, l},
|
||||||
|
type = {i, l, o, a, v, s}
|
||||||
|
mode = {c, x, 0, 1, m1, p}
|
||||||
|
|
||||||
|
The operations are load, store, execute and load address as stated
|
||||||
|
earlier. The size refers to byte, word and long. The types are
|
||||||
|
immediate, local, object, absolute, variable and stack. The modes
|
||||||
|
are compact, indexed, zero, one, minus one and packed.
|
||||||
|
|
||||||
|
As an example, the instruction ldwi means load-word-immediate. It
|
||||||
|
will load an immediate value onto the stack. The instruction stba
|
||||||
|
will store a byte at the absolute address residing in the stack.
|
||||||
|
|
||||||
|
There are compact instructions that use a single byte to address
|
||||||
|
the first 8 long values residing in the method's stack frame or in
|
||||||
|
an object's variable space. These use the size, type and mode
|
||||||
|
characters "llc". As an example, the method result value can be
|
||||||
|
set with the "stllc 0" instruction. The fourth long in the objet's
|
||||||
|
variable section could be loaded with "ldllc 12".
|
||||||
|
|
||||||
|
When an execute memory operation is specified it is followed by one of
|
||||||
|
the math operators or an extended operator. An execute instruction may
|
||||||
|
also specify the "load" extended operator to save the result on the
|
||||||
|
stack. Examples of using execute instructions are as follows:
|
||||||
|
|
||||||
|
exlo $8 add ' Add value on stack to the object long at offset $8
|
||||||
|
exwv $20 preinc ' Increment the VAR word at offset $20
|
||||||
|
exll $10 postdec load ' Decrement stack location $10 and load
|
||||||
|
|
||||||
|
Spasm also includes psuedo-ops, which are shortened versions of the
|
||||||
|
memory mnenomics. The psuedo-ops are made up only of the operation
|
||||||
|
and size fields, plus the "x" charater if it is indexed. The
|
||||||
|
psuedo-ops are mapped to explicit opcodes depending on the context
|
||||||
|
of the operand. As an example "ldl 1" maps into "ldli1", and
|
||||||
|
"ldl result" maps into "ldllc 0".
|
||||||
|
|
||||||
|
The Spasm opcodes are listed below. The offsets used for the jump
|
||||||
|
instructions are signed offsets that are relative to the address of the
|
||||||
|
next instruction. A "jmp 0" instruction will just execute the next
|
||||||
|
instruction.
|
||||||
|
|
||||||
|
Signed offsets are encoded in either one or two bytes depending
|
||||||
|
on the value of the most significant bit in the first byte. If the
|
||||||
|
MSB is zero the remaining seven bits are treated as a signed 7-bit
|
||||||
|
number in the range from -64 to 63. If the MSB is non-zero, the
|
||||||
|
remaining seven bits are used as the most significant bits of a 15-bit
|
||||||
|
signed number, and the next byte provides the eight least sigficant
|
||||||
|
bits. The 15-bit signed offset has a range from -16384 to 16383.
|
||||||
|
|
||||||
|
The memory opcodes use an unsigned offset that can also be encoded in
|
||||||
|
one or two bytes. The MSB is used to determine whether it is one or
|
||||||
|
two bytes just like for signed offset. However, since it is unsigned,
|
||||||
|
the range for the one-byte offset is 0 to 128, and for two bytes it is
|
||||||
|
0 to 32768.
|
||||||
|
|
||||||
|
Lower Opcodes
|
||||||
|
-------------
|
||||||
|
00 ldfrmr - Load call frame with return value required
|
||||||
|
01 ldfrm - Load call frame
|
||||||
|
02 ldfrmar - Load call frame with abort trap & return value
|
||||||
|
03 ldfrma - Load call frame with abort trap
|
||||||
|
04 jmp offset - Jump to signed object offset
|
||||||
|
05 call meth - Call method
|
||||||
|
06 callobj meth, obj - Call method in object
|
||||||
|
07 callobjx meth, obj - Call method in object with index
|
||||||
|
08 tjz offset - Test and jump if zero
|
||||||
|
09 djnz offset - Decrement and jump if not zero
|
||||||
|
0a jz offset - Jump if zero
|
||||||
|
0b jnz offset - Jump if not zero
|
||||||
|
0c casedone - Case done without a match
|
||||||
|
0d casevalue - Execute if value matches case value
|
||||||
|
0e caserange - Execute if case value within range
|
||||||
|
0f lookdone - Look up/down done without a match
|
||||||
|
10 lookupval -
|
||||||
|
11 lookdnval
|
||||||
|
12 lookuprng
|
||||||
|
13 lookdnrng
|
||||||
|
14 pop - Discard N bytes from the stack
|
||||||
|
15 run - Prepare new spin cog stack for execution
|
||||||
|
16 strsize - Determine the size of a string
|
||||||
|
17 strcomp - Compare two strings
|
||||||
|
18 bytefill - Fill memory with a constant byte value
|
||||||
|
19 wordfill - Fill memory with a constant word value
|
||||||
|
1a longfill - Fill memory with a constant long value
|
||||||
|
1b waitpeq - Wait till pins are equal to a value
|
||||||
|
1c bytemove - Copy bytes to a new location
|
||||||
|
1d wordmove - Copy words to a new location
|
||||||
|
1e longmove - Copy longs to a new location
|
||||||
|
1f waitpne - Wait till pins are not equal to value
|
||||||
|
20 clkset - Change the clock frequency and mode
|
||||||
|
21 cogstop - Stop the specified cog
|
||||||
|
22 lockret - Return a lock
|
||||||
|
23 waitcnt - Wait for cnt to equal a specified value
|
||||||
|
24 ldlsx
|
||||||
|
25 stlsx
|
||||||
|
26 exlsx
|
||||||
|
27 waitvid - Wait on video
|
||||||
|
28 coginitret - Start a cog and return the cog number
|
||||||
|
29 locknewret - Allocate a lock and return the lock number
|
||||||
|
2a locksetret - Set a lock and return the previous value
|
||||||
|
2b lockclrret - Clear a lock and return the previous value
|
||||||
|
2c coginit - Start a cog
|
||||||
|
2d locknew - Allocate a lock with no return value
|
||||||
|
2e lockset - Set a lock with no return value
|
||||||
|
2f lockclr - Clear a lock with no return value
|
||||||
|
30 abort - Perform an abort to the next abort trap
|
||||||
|
31 abortval - Perform an abort and return a value
|
||||||
|
32 ret - Return without loading a return value
|
||||||
|
33 retval - Return and load a return value on the stack
|
||||||
|
34 ldlim1 - Load a minus 1
|
||||||
|
35 ldli0 - Load zero
|
||||||
|
36 ldli1 - Load 1
|
||||||
|
37 ldlip value - Load a packed-byte constant
|
||||||
|
38 ldbi value - Load a single-byte constant
|
||||||
|
39 ldwi value - Load a two-byte constant
|
||||||
|
3a ldmi value - Load a three-byte constant
|
||||||
|
3b ldli value - Load a four-byte constant
|
||||||
|
3c --- - Unused opcode
|
||||||
|
3d ldregbit - Load a bit from a register
|
||||||
|
3d stregbit - Store a bit to a register
|
||||||
|
3e ldregbits - Load bits from a register
|
||||||
|
3e stregbits - Store bit to a register
|
||||||
|
3f ldreg - Load a register
|
||||||
|
3f streg - Store a register
|
||||||
|
|
||||||
|
Compact Memory Opcodes
|
||||||
|
--------------
|
||||||
|
40 ldlvc offset - Load long variable compact
|
||||||
|
41 stlvc offset - Store long variable compact
|
||||||
|
42 exlvc offset - Execute on a long variable compact
|
||||||
|
43 lalvc offset - Load address of a long variable compact
|
||||||
|
60 ldllc offset - Load long local compact
|
||||||
|
61 stllc offset - Store long local compact
|
||||||
|
62 exllc offset - Execute on a long local compact
|
||||||
|
63 lallc offset - Load address of a long local compact
|
||||||
|
|
||||||
|
Byte Memory Opcodes
|
||||||
|
--------------
|
||||||
|
80 ldba - Load byte absolute
|
||||||
|
81 stba - Store byte absolute
|
||||||
|
82 exba - Execute on a byte absolute
|
||||||
|
83 laba - Load address of a byte absolute
|
||||||
|
84 ldbo offset - Load byte object offset
|
||||||
|
85 stbo offset
|
||||||
|
86 exbo offset
|
||||||
|
87 labo offset
|
||||||
|
88 ldbv offset - Load byte variable offset
|
||||||
|
89 stbv offset
|
||||||
|
8a exbv offset
|
||||||
|
8b labv offset
|
||||||
|
8c ldbl offset - Load byte local offset
|
||||||
|
8d stbl offset
|
||||||
|
8e exbl offset
|
||||||
|
8f labl offset
|
||||||
|
90 ldbax - Load byte absolute with index
|
||||||
|
91 stbax
|
||||||
|
92 exbax
|
||||||
|
93 labax
|
||||||
|
94 ldbox offset - Load byte object offset with index
|
||||||
|
95 stbox offset
|
||||||
|
96 exbox offset
|
||||||
|
97 labox offset
|
||||||
|
98 ldbvx offset - Load byte variable offset with index
|
||||||
|
99 stbvx offset
|
||||||
|
9a exbvx offset
|
||||||
|
9b labvx offset
|
||||||
|
9c ldblx offset - Load byte local offset with index
|
||||||
|
9d stblx offset
|
||||||
|
9e exblx offset
|
||||||
|
9f lablx offset
|
||||||
|
|
||||||
|
Word Memory Opcodes
|
||||||
|
-------------------
|
||||||
|
a0 ldwa - Load word absolute
|
||||||
|
a1 stwa
|
||||||
|
a2 exwa
|
||||||
|
a3 lawa
|
||||||
|
a4 ldwo offset
|
||||||
|
a5 stwo offset
|
||||||
|
a6 exwo offset
|
||||||
|
a7 lawo offset
|
||||||
|
a8 ldwv offset
|
||||||
|
a9 stwv offset
|
||||||
|
aa exwv offset
|
||||||
|
ab lawv offset
|
||||||
|
ac ldwl offset
|
||||||
|
ad stwl offset
|
||||||
|
ae exwl offset
|
||||||
|
af lawl offset
|
||||||
|
b0 ldwax - Load word absolute with index
|
||||||
|
b1 stwax
|
||||||
|
b2 exwax
|
||||||
|
b3 lawax
|
||||||
|
b4 ldwox offset
|
||||||
|
b5 stwox offset
|
||||||
|
b6 exwox offset
|
||||||
|
b7 lawox offset
|
||||||
|
b8 ldwvx offset
|
||||||
|
b9 stwvx offset
|
||||||
|
ba exwvx offset
|
||||||
|
bb lawvx offset
|
||||||
|
bc ldwlx offset
|
||||||
|
bd stwlx offset
|
||||||
|
be exwlx offset
|
||||||
|
bf lawlx offset
|
||||||
|
|
||||||
|
Long Memory Opcodes
|
||||||
|
-------------------
|
||||||
|
c0 ldla - Load long absolute
|
||||||
|
c1 stla
|
||||||
|
c2 exla
|
||||||
|
c3 lala
|
||||||
|
c4 ldlo offset
|
||||||
|
c5 stlo offset
|
||||||
|
c6 exlo offset
|
||||||
|
c7 lalo offset
|
||||||
|
c8 ldlv offset
|
||||||
|
c9 stlv offset
|
||||||
|
ca exlv offset
|
||||||
|
cb lalv offset
|
||||||
|
cc ldll offset
|
||||||
|
cd stll offset
|
||||||
|
ce exll offset
|
||||||
|
cf lall offset
|
||||||
|
d0 ldlax - Load long absolute with index
|
||||||
|
d1 stlax
|
||||||
|
d2 exlax
|
||||||
|
d3 lalax
|
||||||
|
d4 ldlox offset
|
||||||
|
d5 stlox offset
|
||||||
|
d6 exlox offset
|
||||||
|
d7 lalox offset
|
||||||
|
d8 ldlvx offset
|
||||||
|
d9 stlvx offset
|
||||||
|
da exlvx offset
|
||||||
|
db lalvx offset
|
||||||
|
dc ldllx offset
|
||||||
|
dd stllx offset
|
||||||
|
de exllx offset
|
||||||
|
df lallx offset
|
||||||
|
|
||||||
|
Math Opcodes
|
||||||
|
------------
|
||||||
|
e0 ror - Rotate right
|
||||||
|
e1 rol - Rotate left
|
||||||
|
e2 shr - Shift right
|
||||||
|
e3 shl - Shift left
|
||||||
|
e4 min - Maximum
|
||||||
|
e5 max - Minimum
|
||||||
|
e6 neg - Negate
|
||||||
|
e7 com - Compliment
|
||||||
|
e8 and - Bitwise and
|
||||||
|
e9 abs - Absolute value
|
||||||
|
ea or - Bitwise or
|
||||||
|
eb xor - Bitwise exclusive or
|
||||||
|
ec add - Add
|
||||||
|
ed sub - Subtract
|
||||||
|
ee sar - Shift arithmetic right
|
||||||
|
ef rev - Bit reverse
|
||||||
|
f0 andl - Logical and
|
||||||
|
f1 encode - Shift "1" left
|
||||||
|
f2 orl - Logical or
|
||||||
|
f3 decode - Find left-most "1" bit
|
||||||
|
f4 mul - Multiply
|
||||||
|
f5 mulh - Multiply high
|
||||||
|
f6 div - Divide
|
||||||
|
f7 mod - Modulus
|
||||||
|
f8 sqrt - Square root
|
||||||
|
f9 cmplt - Less than
|
||||||
|
fa cmpgt - Greater than
|
||||||
|
fb cmpne - Not equal
|
||||||
|
fc cmpeq - Equal
|
||||||
|
fd cmple - Less than or equal
|
||||||
|
fe cmpge - Greater than or equal
|
||||||
|
ff notl - Logical not
|
||||||
|
|
||||||
|
Extended opcodes
|
||||||
|
----------------
|
||||||
|
00 load - Load the value
|
||||||
|
02 repeat - Repeat index from first to last
|
||||||
|
06 repeats - Repeat index from first to last with step
|
||||||
|
08 randf - Forward random number
|
||||||
|
0c randr - Reverse random number
|
||||||
|
10 sexb - Sign extend byte
|
||||||
|
14 sexw - Sign extend word
|
||||||
|
18 postclr - Post clear to zero
|
||||||
|
1c postset - Post set to all ones
|
||||||
|
26 preinc - Pre-increment
|
||||||
|
2e postinc - Post-increment
|
||||||
|
36 predec - Pre-decrement
|
||||||
|
3e postdec - Post-decrement
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPASM March 2012 SPASM(1)
|
|
@ -0,0 +1,26 @@
|
||||||
|
SPC(1) User Commands SPC(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
spc - spinix compiler collection
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
spc FILE
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
spc is a script file that compiles a Spin program into a spinix
|
||||||
|
executable by running the spinit, spasm and splink utilities. At each
|
||||||
|
step, spc will check to see if the step ran correctly before starting
|
||||||
|
the next one. In the final step, spc will link the compiled program
|
||||||
|
with the clibsd object to produce a spinix executable.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPC November 2013 SPC(1)
|
|
@ -0,0 +1,33 @@
|
||||||
|
SPINIT(1) User Commands SPINIT(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
spinit - spin compiler
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
spinit [-d] FILE
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
spinit compiles a Spin program, and generates spasm code. spinit
|
||||||
|
handles a subset of the Spin language. It dese not compile PASM code,
|
||||||
|
and it does not implement the following Spin keywords:
|
||||||
|
|
||||||
|
CASE, LOOKUP, LOOKUPZ, LOOKDOWN, LOOKDOWNZ, VAR, CONSTANT
|
||||||
|
FROM, TO, STEP, FLOAT, ROUND, TRUNC
|
||||||
|
|
||||||
|
spinit also does not allow arrays to be defined.
|
||||||
|
|
||||||
|
If the -d option is specified, spinit will print out debug information
|
||||||
|
as it compiles.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIT November 2013 SPINIT(1)
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
SPINIX(1) Spinix OS SPINIX(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
spinix - spinix operating system
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Spinix is a linux-like operating system that runs on a Parallax
|
||||||
|
Propeller processor interfaced to an SD card. It consists of a boot
|
||||||
|
program, shell and many applications.
|
||||||
|
|
||||||
|
The boot program resides in the Propeller boot EEPROM. When run for
|
||||||
|
the first time, the boot program prompts the user for the I/O pins used
|
||||||
|
to interface to the SD card. The boot program then starts up the shell
|
||||||
|
program.
|
||||||
|
|
||||||
|
Spinix maintains a rendevous area of memory at the top of memory. The
|
||||||
|
rendevous area contains mail boxes that are used to talk to the
|
||||||
|
console and SD driver.
|
||||||
|
|
||||||
|
The shell provides a user interface that accepts commands from the
|
||||||
|
user, and executes programs that are store on the SD card.
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
For more information see the man pages on the boot program and the
|
||||||
|
shell.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2013 Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX OS September 2013 SPINIX(1)
|
|
@ -0,0 +1,30 @@
|
||||||
|
SPLINK(1) User Commands SPLINK(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
splink - spin linker
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
splink FILE1 FILE2 FILE3 [-d]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
splink links FILE1 with FILE2 and writes the results to FILE3. FILE1
|
||||||
|
is the top object file, and it must contain only one Spin object. The
|
||||||
|
second file may contain one or more objects. The objects listed in the
|
||||||
|
OBJ section of the top object must be in the same order as those in the
|
||||||
|
second file.
|
||||||
|
|
||||||
|
LIMITATIONS
|
||||||
|
splink does not support VAR sections.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, 2013, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPLINK November 2013 SPLINK(1)
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
TAIL(1) User Commands TAIL(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
tail - display a file tail
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
tail [OPTIONS] [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Display the last 10 lines of a file to the standard output if OPTION is
|
||||||
|
not specified. An OPTION of "-n" will display the last n lines.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 TAIL(1)
|
|
@ -0,0 +1,24 @@
|
||||||
|
TAR(1) User Commands TAR(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
tar - process a file archive
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
tar [OPTION] [FILE] [FILELIST]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Create a tar file named FILE if OPTION is "-cf". FILELIST is a list of
|
||||||
|
files to be added to the tar file. If OPTION is "-xf", files are
|
||||||
|
extracted from the tar file, FILE. FILELIST is not used in this case.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 TAR(1)
|
|
@ -0,0 +1,46 @@
|
||||||
|
TED(1) User Commands TED(1)
|
||||||
|
|
||||||
|
NAME
|
||||||
|
ted - tiny text editor
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
ted - [FILE]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Edits the file named FILE. ted is a subset of the ed text editor It
|
||||||
|
uses single letter commands that may be prefixed by a line number or a
|
||||||
|
range of line numbers. The "." character represents the current line,
|
||||||
|
and the "$" character is the last line number. A range is specifed by
|
||||||
|
two line numbers seperated by a comma, such as "1,10" or ".,$".
|
||||||
|
|
||||||
|
The commands are:
|
||||||
|
q - quit
|
||||||
|
w - write edit buffer to FILE
|
||||||
|
d - delete the current line
|
||||||
|
i - insert lines after the current line
|
||||||
|
a - append lines before the current line
|
||||||
|
p - print lines
|
||||||
|
n - print lines with line number
|
||||||
|
j - join the current line with the next line
|
||||||
|
# - move to line #
|
||||||
|
. - current line
|
||||||
|
$ - move to last line
|
||||||
|
- - move down one line
|
||||||
|
+ - move up one line
|
||||||
|
h - print help information
|
||||||
|
|
||||||
|
LIMITATIONS
|
||||||
|
A file name must be specified when starting ted or it will write a
|
||||||
|
blank file name when using the "w" command.
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
Dave Hein
|
||||||
|
|
||||||
|
COPYRIGHT
|
||||||
|
Copyright (c) 2011, 2012, Dave Hein
|
||||||
|
MIT License (See license.txt in the root directory)
|
||||||
|
This is free software: you are free to change and redistribute it.
|
||||||
|
There is no warranty, to the extent permitted by law.
|
||||||
|
|
||||||
|
|
||||||
|
SPINIX utility March 2012 TED(1)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue