				BASIC Stamp II


			       Ŀ
			  TX Ĵ1           24 PWR
			  RX Ĵ2           23 GND
			 ATN Ĵ3           22 RES
			 GND Ĵ4           21 +5V
			  P0 Ĵ5           20 P15
			  P1 Ĵ6           19 P14
			  P2 Ĵ7           18 P13
			  P3 Ĵ8           17 P12
			  P4 Ĵ9           16 P11
			  P5 Ĵ10          15 P10
			  P6 Ĵ11          14 P9
			  P7 Ĵ12          13 P8
			       
			            BS2-IC

Pin	Name	Description

1	TX	Serial output		Connect to pin 2 of PC serial DB9 (RX)
2	RX	Serial input		Connect to pin 3 of PC serial DB9 (TX)
3	ATN	Serial attention	Connect to pin 4 of PC serial DB9 (DTR)
4	GND	Serial ground		Connect to pin 5 of PC serial DB9 (GND)

5	P0	I/O pin 0		Each I/O can source 20ma and sink 25ma.
6	P1	I/O pin 1
7	P2	I/O pin 2		P0-P7 and P8-P15, as groups, can each
8	P3	I/O pin 3		source a total of 40ma and sink 50ma.
9	P4	I/O pin 4
10	P5	I/O pin 5
11	P6	I/O pin 6
12	P7	I/O pin 7
13	P8	I/O pin 8
14	P9	I/O pin 9
15	P10	I/O pin 10
16	P11	I/O pin 11
17	P12	I/O pin 12
18	P13	I/O pin 13
19	P14	I/O pin 14
20	P15	I/O pin 15

21	+5V *	+5V supply		5-volt input or regulated output.
22	RES	Reset I/O pin		Pull low to reset; goes low in reset
23	GND	System ground
24	PWR *	Regulator input		Voltage regulator input; takes 5-15 VDC



Internal Perspective:

The BS2 has 2K bytes of EEPROM which holds the executable BASIC program and any
data.  Memory not used by the BASIC program can be read and written at run-time
as a data bank, or initialized with data at download time.  This memory is only
affected by downloading or run-time modification.

There are 32 bytes of RAM which serve as variable space and I/O pin interface
for the BASIC program.  This memory can be accessed as words, bytes, nibbles,
or bits.  Each time the BASIC program is run anew, this memory is cleared to
all zeroes.

So, the 2K byte EEPROM is for program and data, and only affected by initial
downloading or run-time modification.  It survives power-down.  The 32 bytes of
RAM are for run-time variables and I/O pin access.  This memory is cleared each
time the BS2 is powered up, reset, or downloaded to.


The 2K-byte EEPROM is arranged as follows:

	   byte $000     Data start
		                |
		                |
		                |
		                |
		            Data end
		      
		      
		      
		      
		      
		      
		            Program end
		                 |
		                 |
		                 |
		                 |
	   byte $7FF     Program start


The 32-byte RAM is arranged as follows:

WORD                BITS                  Description             R/W
-------------------------------------------------------------------------------
$0-  x x x x  x x x x  x x x x  x x x x   Pin input states        read-only
$1-  x x x x  x x x x  x x x x  x x x x   Pin output latches	  read/write
$2-  x x x x  x x x x  x x x x  x x x x   Pin directions    	  read/write
$3-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$4-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$5-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$6-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$7-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$8-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$9-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$A-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$B-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$C-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$D-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$E-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write
$F-  x x x x  x x x x  x x x x  x x x x   variable space    	  read/write


Word $0 always reflects the read-state of all 16 I/O pins.  Whether a pin is an
input or output, it's logical state can be read in this word.  Word $0 is
accessed by the following symbolic names:

	INS	the entire 16-bit word

	INL	the low byte of INS
	INH	the high byte of INS

	INA	the low nibble of INL
	INB	the high nibble of INL
	INC	the low nibble of INH
	IND	the high nibble of INH

	IN0	the low bit of INS - corresponds to pin P0
	 |
	 |
	 |
	IN15	the high bit of INS - corresponds to pin P15


Word $1 contains the output latches for all 16 I/O pins.  If a pin is in input
mode, this data is unused, but when a pin is in output mode, its corresponding
word $1 bit sets its state.  The bits are all readable and writable, regardless
of pin direction.  The following symbolic names access word $1:

	OUTS	the entire 16-bit word

	OUTL	the low byte of OUTS
	OUTH	the high byte of OUTS

	OUTA	the low nibble of OUTL
	OUTB	the high nibble of OUTL
	OUTC	the low nibble of OUTH
	OUTD	the high nibble of OUTH

	OUT0	the low bit of OUTS - corresponds to pin P0
	 |
	 |
	 |
	OUT15	the high bit of OUTS - corresponds to pin p15


Word $2 contains the direction bits for all 16 I/O pins.  To place a pin in
input mode, its corresponding word $2 bit must be cleared to 0.  To put a pin
into output mode, its corresponding word $2 bit must be set to 1, at which
time its word $1 bit will determine whether it is high or low.  Word $2 has
these symbolic names:

	DIRS	the entire 16-bit word

	DIRL	the low byte of DIRS
	DIRH	the high byte of DIRS

	DIRA	the low nibble of DIRL
	DIRB	the high nibble of DIRL
	DIRC	the low nibble of DIRH
	DIRD	the high nibble of DIRH

	DIR0	the low bit of DIRS - corresponds to pin P0
	 |
	 |
	 |
	DIR15	the high bit of DIRS - corresponds to pin p15


Words $3-$F are for general purpose variable use and have no pre-assigned
symbolic names.  The VAR statement is used to allocate this memory.



The above text has introduced the physical pin-out of the BS2 as well as
the internal EEPROM, RAM, and I/O structure.




Programming the BASIC Stamp II



In the BASIC Stamp II, there are two general categories of BASIC statements:
compile-time and run-time.  Compile-time statements are resolved when you
compile the program (Alt-R or Alt-M) and do not generate any executable code.
Run-time statements, on the other hand, generate code and are executed at run-
time.

There are three compile-time statements.  They are used for declaring
variables, constants, and data.  They are:

		VAR	CON	and	DATA



		The VAR statment - for defining variables

Your program should begin with a declaration of all of its variables.  VAR
statements assign symbolic names to variable RAM (RAM not used by I/O - words
$3-$F).  This is done as follows:

	'Declare the variables

	cat	var	nib		'make "cat" a nibble variable
	mouse	var	bit		'make "mouse" a bit variable
	dog	var	byte		'make "dog" a byte variable
	rhino	var	word		'make "rhino" a word variable
	snake	var	bit(10)		'make "snake" a 10-piece bit variable

The compiler will group all words, bytes, nibs, and bits, and respectively
arrange them into unused RAM.  By pressing Alt-M, you can see a picture of
the RAM allocation.  First, the three I/O words are shown, then all words,
bytes, nibs, and finally, bits, are seen.  Empty RAM follows.  Alt-M is a quick
way to assess how much RAM you've used.

The VAR usage options are as follows:

	'define unique variables

	sym1	VAR	bit		'make a bit variable
	sym2	VAR	nib		'make a nibble variable
	sym3	VAR	byte		'make a byte variable
	sym4	VAR	word		'make a word variable

		'After bit/nib/byte/word a value may be placed
		'within parentheses to declare an array size:

	sym5	VAR	nib (10)	'make a 10 nibble array

	'define variables-within-variables or alias variables

	sym6	VAR	sym4.highbit	'make a bit variable of sym4's highbit
	sym7	VAR	sym4.lowbit	'make a bit variable of sym4's lowbit
	sym8	VAR	sym2		'make an alternate name for sym2

		'When using VAR to assign non-unique variables (a variable
		'name is used in lieu of bit/nib/byte/word(size)), a period may
		'be placed after the variable name and followed by modifiers.
		'Modifiers are used to identify sub-pieces of the initially-
		'mentioned variable.

	sym9	VAR	sym4.highbyte.lownib.bit2	'picky, picky...


	Here are all the variable modifiers:

	LOWBYTE			'low byte of a word
	HIGHBYTE		'high byte of a word
	BYTE0			'byte0 (low byte) of a word
	BYTE1			'byte1 (high byte) of a word

	LOWNIB			'low nibble of a word or byte
	HIGHNIB			'high nibble of a word or byte
	NIB0			'nib0 of a word or byte
	NIB1			'nib1 of a word or byte
	NIB2			'nib2 of a word
	NIB3			'nib3 of a word

	LOWBIT			'low bit of a word, byte, or nibble
	HIGHBIT			'high bit of a word, byte, or nibble
	BIT0			'bit0 of a word, byte, or nibble
	BIT1			'bit1 of a word, byte, or nibble
	BIT2			'bit2 of a word, byte, or nibble
	BIT3			'bit3 of a word, byte, or nibble
	BIT4			'bit4 of a word or byte
	BIT5			'bit5 of a word or byte
	BIT6			'bit6 of a word or byte
	BIT7			'bit7 of a word or byte
	BIT8			'bit8 of a word
	BIT9			'bit9 of a word
	BIT10			'bit10 of a word
	BIT11			'bit11 of a word
	BIT12			'bit12 of a word
	BIT13			'bit13 of a word
	BIT14			'bit14 of a word
	BIT15			'bit15 of a word


In summary, to declare variables, VAR statements are used.  VAR statements
either declare unique variables or variables-within-variables/alias-variables.

For defining unique variables:

	symbol	VAR	size (array)

	- symbol is a unique name for a variable
	- size is either WORD, BYTE, NIB, or BIT
	- (array) is an optional expression which declares an array size

For defining variables-within-variables or alias-variables

	symbol	VAR	variable.modifiers

	- symbol is a unique name for a variable
	- variable is a defined variable name
	- .modifiers are optional and used to define variables-within-variables

The compiler will group all declarations by size (in the case of unique
variables) and assign them to unused RAM.  Alt-M lets you see the result of
this process.  Non-unique variables are in-whole or in-part derived from unique
variables and get assigned within the unique-variable memory.

Keep in mind that you may make alias names for the pin variables:

	keyin	var	in5		'make "keyin" a way to read P5's state.



		The CON statment - for defining constants

The CON statement is similar to the VAR statement, except that it is for
defining constant values and assigning them to symbolic names.  This is
handy for having a single declaration which gets accessed throughout your
program.  The CON syntax is as follows:

	symbol	CON	expression	'assign expression to "symbol"

	- symbol is a unique symbolic name for a constant
	- expression is a compile-time-resolvable constant

	level	CON	10		'"level" is same as 10 in program
	limit	CON	10*4<<2		'"limit" is 160

expressions after CON can contain the following binary operators and are
resolved left-to-right:

	+	add
	-	subtract
	*	multiply
	/	divide
	<<	shift left
	>>	shift right
	&	logical AND
	|	logical OR
	^	logical XOR

example:
	growth	CON	100-light/gel	'"light" and "gel" are CON's, too



		The DATA statment - for defining data

EEPROM memory not used by your BASIC program can be used for data storage.
Keep in mind that your BASIC program builds from the end of memory towards
the start of memory.  This allocation is automatic.  Your data, on the other
hand, builds from the start of memory towards the end.  The sum of program and
data memory cannot exceed the 2K byte limit.  The compiler will always tell you
when you have a conflict.

DATA statements are used to build data into unused memory.  Initially, the DATA
location is set to 0.  It is advanced by 1 for each byte declared.  Here is an
example DATA statement:

table	DATA	"Here is a string..."

Usually, you will want to precede DATA statements with a unique symbol name.
The symbol name will be assigned a constant value (as if via CON) which is the
current data pointer.  The text following 'DATA' is usually a list of bytes
which can be constant expressions.  In the above example (assuming this was
the first DATA statement in the program), "table" becomes a constant symbol of
value 0; "Here is a string..." is broken into individual bytes and placed
into EEPROM memory sequentially.  Alt-M and two <SPACE>s will show you the
result of this line.

The DATA pointer may be altered at any time by an @ sign followed by a new
pointer value:

list	DATA	@$100,"some data"

DATA has a few variations of use to allocate defined and undefined data.
Defined data is fully declared and known at compile time.  Undefined data
is the mere allocation of data space, while not assigning values into the bytes
of EEPROM (to be done at run-time, instead).  Defined and undefined data are
declared as follows:

	for defined data:

fee	DATA	0,1,2,3,4,5,6,7,8,9	'actual bytes
fie	DATA	word 1000		'make two bytes: $E8 and $03
foe	DATA	0 (256)			'256 bytes initialized as 0

	for undefined data:

fum	DATA	(1024)			'reserved 1K byte of undefined data
scratch	DATA	word (16)		'reserve 16 words of undefined data


Important concept:	Defined DATA and BASIC program memory are always
			downloaded to the BS2.  Undefined data and unused
			EEPROM memory are not downloaded.  This allows you
			to change programs while keeping data, assuming both
			programs defined the same stretch of memory as
			undefined DATA.  Alt-M will show you maps of EEPROM
			allocation.  This download/don't-download rule is
			applied to 16-byte blocks.  If any byte within a 16-
			byte block is defined DATA or BASIC program, that
			whole block is downloaded.  Use Alt-M to see this.


In summary, DATA is used to define EEPROM byte usage that doesn't conflict
with the BASIC program storage:

- DATA can be preceeded by a symbol which will be assigned the constant value
  of the current DATA pointer.

- Byte-size data is assumed, but 'word' can be used to break a word into two
  bytes of storage.

- The @ sign is used to redirect the DATA pointer.  If a symbol preceeds a
  DATA statement and the first thing after DATA is @, the new pointer value
  is assigned to the symbol.

- Defined data is spelled out, so to speak, with numbers and letters.

- Defined data may be repeated at the byte or word level using (array).

- Undefined data may be reserved by using (array) unpreeceded by a value.

Note:	DATA can contain references to DATA symbols:

	t1		DATA	"Here's table 1...",0
	t2		DATA	"Here's table 2...",0
	t3		DATA	"Here's table 3...",0
	t4		DATA	"Here's table 4...",0

	t_starts	DATA	word t1, word t2, word t3, word t4



			Run-Time Expressions
	----------------------------------------------------

Run-time expressions can contain constants, variables, operators, and
parentheses.  They are resolved using 16-bit math.

Constants can be in several forms:

	label			- a label may be assigned a constant via CON
	$BA1F			- Hex
	%111001111		- Binary
	99			- Decimal
	"A"			- ASCII

	Note:  When more than one character is within quotes, they are
	separated by the compiler as such: "DOG" becomes "D","O","G".
	"String"+$80 becomes: "S","t","r","i","n","g"+$80.

Variables can be accessed a number of ways:

	somevar			- Some variable
	wordvar.highbit		- Use modifiers to access sub-variables
	nibarray(index)		- A variable followed by an expression in
				  quotes is indexed as an array (0=1st element)
	word.bit0(bitoffset)	- Scan a word, one bit at a time

	Say a variable were defined as such:

	string var byte (10)

	It could be accessed as:

	string			- the 1st byte
	string (0)		- the 1st byte
	string (1)		- the 2nd byte
	string (9)		- the 10th (last) byte
	string.lownib(nibindex)	- nibindex could be 0-19
	string.lowbit(bitindex)	- bitindex could be 0-79


There are binary, unary, and conditional expression operators.

Unary operators preceed a variable or constant or (expression) and have
highest priority.  They are as follows:

	SQR	- Square root of unsigned 16-bit value
	ABS	- Absolute of signed 16-bit value
	~	- One's complement of 16-bit value (bitwise not)
	-	- Two's complement of 16-bit value (negation)
	DCD	- 2^n decoder of 4-bit value (0...15 -> 1,2,4,8,16,...32768)
	NCD	- Priority encoder of 16-bit value
		  (=>32768,=>16384,=>8192,...=1 -> 15,14,13,...1 ; 0 -> $FFFF)
	COS	- Cosine of 8-bit value. Result is in the range of +-127,
		  unit circle is 0-255 radial units.
	SIN	- Sine of 8-bit value. Result is in the range of +-127,
		  unit circle is 0-255 radial units.

	Examples:
			sin bytevar
			sqr 50000
			~ in0

Binary operators take two terms and go between variables, constants, or
expressions.  They are as follows:

	&	- Bitwise AND
	|	- Bitwise OR
	^	- Bitwise XOR
	MIN	- limit value to minimum
	MAX	- limit value to maximum
	+	- addition
	-	- subtraction
	*	- multiply
	**	- multiply and return high 16-bits of result
	*/	- multiply and return middle 16-bits of result
		  (use to simultaneously multiply by a whole and a part;
		  ie. 'value */ $0180' multiplies by 1 and a half)
	/	- divide
	//	- divide and return remainder
	DIG	- return decimal digit; '12345 dig 3' returns 2
	<<	- shift left
	>>	- shift right
	REV	- reverse order of bits, lsb-justified; '%100110 rev 6'
		  yields %011001

	Examples:
			ypos * xsize + xpos
			randword // 20
			countacc min 200 - 200 / 200

Parentheses can be placed to special-order the pattern of expression
resolution.  Though unary operators have highest priority and binary operators
have secondary priority, and with those rules expressions are resolved left-to-
right, parentheses can override priority:

X+1*Y-1		'something's wrong here if we need (X+1)*(Y-1)
(X+1)*(Y-1)	'do it right

Up to 8 levels of parentheses can be used.


For use within conditional expressions (IF), there is a special unary operator
and several binary operators.  These conditional operators have highest
priority of all.

	NOT		- highest priority unary
	AND, OR, XOR	- highest priority binaries

	Note: These are arithmetically identical to expression operators:
	      		~	&	|	^
	      though they differ in application.

Lower-priority conditional binary operators (still higher than expression ops):

	<		- less than
	<=		- less than or equal to
	=		- equal to
	=>		- equal to or greater than
	>		- greater than
	<>		- not equal

	Note: These comparison operators return 0 for false and $FFFF for true.
	      Combined with NOT, AND, OR, and XOR, complex tests can be done.


To summarize, here are some examples:

	outs = ~ dcd nibarray(index)	'lookup a nibble, decode it, not it
	IF x<1 or not y>3 and (z=0 xor r=3) then loopback



				Run-Time Instructions
		----------------------------------------------------
	     Anywhere a value is requested, an expression may be placed

===============================================================================
DEBUG outputdata
===============================================================================
Show variables and messages for debugging purposes.

usage:	DEBUG "Here we are!"	'show message when executed

When executed, the data after DEBUG will be sent to the PC for
display.  DEBUG data can be displayed in several modes.  Straight
data can be relayed to the PC, or you can have values printed in decimal,
hex, binary, or ascii.  In the number-printing modes, the result of an
expression can be printed or a complete relation can be shown between the
expression and its result.  For example:

	DEBUG dec? X		'show variable X in decimal

		will yield (if x=1):

	X = 1

	DEBUG dec X		'show variable X in decimal

		yields:

	1

To print numbers, there are several words which can preceed expressions:

	ASC?			'show ascii value w/relation
	STR     bytevar		'output string from byte array - until 0
	STR     bytevar\length	'output string from byte array - length bytes
	REP     value\count	'output value count times
	DEC     value		'print value in decimal
   DEC1-DEC5    value		'print value in decimal - 1-5 digits
	SDEC    value		'print value in signed decimal
  SDEC1-SDEC5   value		'print value in signed decimal - 1-5 digits
	HEX     value		'print value in hex
   HEX1-HEX4    value		'print value in hex - 1-4 digits
	SHEX    value		'print value in signed hex
  SHEX1-SHEX4   value		'print value in signed hex - 1-4 digits
	IHEX    value		'print value in hex w/'$'
  IHEX1-IHEX4   value		'print value in hex w/'$' - 1-4 digits
	ISHEX   value		'print value in signed hex w/'$'
 ISHEX1-ISHEX4  value		'print value in signed hex w/'$' - 1-4 digits
	BIN     value		'print value in binary
   BIN1-BIN4    value		'print value in binary - 1-4 digits
	SBIN    value		'print value in signed binary
  SBIN1-SBIN16  value		'print value in signed binary - 1-4 digits
	IBIN    value		'print value in binary w/'%'
  IBIN1-IBIN16  value		'print value in binary w/'%' - 1-4 digits
	ISBIN   value		'print value in signed binary w/'%'
 ISBIN1-ISBIN16 value		'print value in signed binary w/'%' -1-4 digits

To print the literal text expression along with the result, follow any of the
words with a '?'.  A lone '?' is the same as 'DEC?'.  REP cannot be followed
by a '?', but ASC needs one.


DEBUG statements can contain many strings and numbers, separated by commas.  In
addition, there are several special control characters which are interpreted by
the DEBUG screen:

	name	value	effect
	------------------------------------------------------
	CLS	0	clears the screen and homes the cursor
	HOME	1	homes the cursor
	BELL	7	beep the PC speaker
	BKSP	8	backspace - backs up the cursor
	TAB	9	advances to the next 8th column
	CR	13	carriage return - down to next line

	DEBUG	cls,dec ina,"   "	'cls, print ina in decimal, spaces too

Example program using DEBUG:

	count	var	byte

	loop:	debug sdec? sin count	'show the signed-decimal sine of count
		count = count + 1	'increment count
		if count <> 0 then loop	'loop until count rolls over


===============================================================================
FOR...NEXT
===============================================================================
The FOR...NEXT loop.

usage:	FOR variable = start TO end {STEP stepval}
	{some code}
	NEXT

STEP is for specifying a step value other than the default of 1; if specified,
stepval must be positive since whether to add or subtract stepval from variable
is determined dynamically at run-time (this allows '10 TO 0' without specifying
a negative STEP value.).

FOR...NEXT loops can be nested up to 16 deep.

Note: NEXT is stand-alone and implies the variable from the last FOR statement.


===============================================================================
BRANCH
===============================================================================
Branch according to an index.

usage:	BRANCH	index,[label0,label1,label2,...labelN]

If index=0, a GOTO label0 will be executed.  If index=1, a GOTO label1 will be
executed.  If the index exceeds the number of label entries, no branch will
occur and execution will proceed at the next instruction.


===============================================================================
IF
===============================================================================
Branch conditionally.

usage:	IF conditionalexpression THEN label
	ie. IF x=1 then redoit

If the result of conditionalexpression is not 0, execution will be continued
at label.  Else, execution continues at the next instruction.


===============================================================================
GOTO
===============================================================================
Go to a new point in the program.

usage:	GOTO joe

A branch to joe will occur, rather than execution continuing at the next
instruction.


===============================================================================
GOSUB
===============================================================================
Go to a subroutine (and then RETURN later).

usage:	GOSUB ledset

The execution point is stored and then a branch to ledset occurs.  When
a RETURN is encountered (in ledset), execution continues at the instruction
following the GOSUB.

GOSUB's may be nested up to 4 deep and you are allowed 255 of them in your
program.


===============================================================================
RETURN
===============================================================================
Return from a subroutine.

usage:	RETURN

The execution point is set to the instruction after the GOSUB that got into
the subroutine executing the RETURN.

If a RETURN is executed without a corresponding GOSUB, execution begins anew
at the start of the program.


===============================================================================
Variable Assignment
===============================================================================
assign a value to a variable.

usage:	variable = value

Value is an expression which gets written to variable.


===============================================================================
LOOKUP
===============================================================================
Lookup a variable according to an index.

usage:	LOOKUP	index,[value0,value1,value2,...valueN],variable

If index=0, value0 will be written to variable.  If index=1, value1 will be
written to variable.  If the index exceeds the number of value entries, the
variable will not be affected.


===============================================================================
LOOKDOWN
===============================================================================
Lookdown a value and return an index.

usage:	LOOKDOWN value,??[value0,value1,value2,...valueN],variable

?? is a comparison operator: =,<>,>,<,<=,=> (= is the default).  A comparison
is made between value and value0; if the result is true, 0 is written into
variable.  If that comparison was false, another comparison is made between
value and value1; if the result is true, 1 is written into variable.  This
process continues until a true is yielded, at which time the index is written
into variable, or until all entries are exhausted in which case variable is
unaffected.


===============================================================================
RANDOM
===============================================================================
Pseudo-randomly iterate a word variable.

usage:	RANDOM	wordvariable

wordvariable will be iterated 16 times to potentially change every bit.


===============================================================================
SEROUT tpin,baudmode,{pace,}[outputdata]
SEROUT tpin\fpin,baudmode,{timeout,tlabel,}[outputdata]
===============================================================================
Output data serially.

usage:	SEROUT 3,6+$4000,["The temperature is ",dec temp," degrees.",cr]

Tpin is 0-15 for an I/O pin, or 16 for the internal serial port.  Fpin is an
option to specify a flow-control pin.  Baudmode is a composite value which
specifies baud rate, parity mode, true/inverted output, and open/driven output.
If no fpin was specified, an optional pace in milliseconds may be declared to
pace characters by a number of milliseconds.  If an fpin was specified, an
optional timeout (in milliseconds) and timeout label may be specified to enable
timeout and branching for flow-control.

Baudmode is the bit period expressed in microseconds-20 (ie 300 baud is 3313).
An easy formula for computing the baud rate (baudmode bits 0-12) is:

     int (1,000,000/baud) - 20

baudmode's bit 15 ($8000) is 0 for driven, 1 for open-drain/source (SEROUT)
baudmode's bit 14 ($4000) is 0 for true, 1 for inverted.
baudmode's bit 13 ($2000) is 0 for 8-bit no parity, 1 for 7-bit parity

outputdata follows the DEBUG conventions

note:	If tpin=16 (internal port), baudmode's bits 14 and 15 are ignored.
	However, they will affect operation of fpin.


===============================================================================
SERIN rpin{\fpin},baudmode,{plabel,}{timeout,tlabel,}[inputdata]
===============================================================================
Input data serially.

usage:	SERIN 16,32+$2000,60000,nothingcame,[WAIT (","),STR bytearray\16\","]

Rpin is 0-15 for an I/O pin, or 16 for the internal serial port.  Fpin is an
optional flow-control pin.  Baudmode is described in SEROUT.  Plabel is a an
option to specify a where to branch in the event of a parity error (parity mode
must be enabled).  Timeout is an optional value to specify how long to wait in
milliseconds before giving up and branching to tlabel.  Inputdata follows the
conventions below:

		variable		'input a byte and store into variable

		STR bytearray\L{\E}	'input a string into bytearray of
					'length L with optional end-character
					'of E (0's will fill remaining bytes)

		SKIP L			'Input and ignore L bytes

		WAITSTR bytearray	'Wait for bytearray string (bytearray
					'is 0-terminated)

		WAITSTR bytearray\L	'Wait for bytearray string of length L

		WAIT (value,value,...)	'Wait for up to a six-byte sequence

		DEC     variable	'input decimal value
	   DEC1-DEC5    variable	'input decimal value of fixed length
		SDEC    variable	'input signed decimal value
	  SDEC1-SDEC5   variable	'" of fixed length
		HEX     variable	'input hex value
	   HEX1-HEX4    variable	'" of fixed length
		SHEX    variable	'input signed hex value
	  SHEX1-SHEX4   variable	'" of fixed length
		IHEX    variable	'input indicated ($) hex value
	  IHEX1-IHEX4   variable	'" of fixed length
		ISHEX   variable	'input signed inidicated ($) hex value
	 ISHEX1-ISHEX4  variable	'" of fixed length
		BIN     variable	'input binary value
	   BIN1-BIN16   variable	'" of fixed length
		SBIN    variable	'input signed binary value
	  SBIN1-SBIN16  variable	'" of fixed length
		IBIN    variable	'input indicated (%) binary value
	  IBIN1-IBIN16  variable	'" of fixed length
		ISBIN   variable	'input signed indicated (%) bin value
	 ISBIN1-ISBIN16 variable	'" of fixed length


note:	If rpin=16 (internal port), baudmode's bits 14 and 15 are ignored.
	However, they will affect operation of fpin.


===============================================================================
READ
===============================================================================
Read a byte from the EEPROM.

usage:	READ	location,variable

Location is 0-2047.  Variable will receive the byte read from location.


===============================================================================
WRITE
===============================================================================
Write a byte into the EEPROM.

usage:	WRITE	location,byte

Location is 0-2047.  Byte is 0-255.  Byte will be written into location.


===============================================================================
XOUT
===============================================================================
Output X-10 codes to a TW523 or TW513 module (by X-10 Powerhouse).

usage:	XOUT	mpin,zpin,[house\keyorcommand{\cycles,...]

Mpin will be made a low output and is the modulation control.  Zpin will be
made an input and is the zero-crossing detect.  House is the house code (0-15
is 'A'-'P').  Keyorcommand is a key (0-15 is '1'-'16') or command (see table
below).  Cycles is an optional number which overrides the default of two; this
should only be used with 'dim' and 'bright' commands.

command symbol		value
------------------------------
UNITON			%10010
UNITOFF			%11010
UNITSOFF		%11100
LIGHTSON		%10100
DIM			%11110
BRIGHT			%10110

TW513/TW523-to-BS2 connections:   1-to-zpin, 2-to-VSS, 3-to-VSS, 4-to-mpin
				  (also zpin to VDD via 10K resistor)


===============================================================================
SHIFTOUT
===============================================================================
Shift bits out synchronously.

usage:	SHIFTOUT dpin,cpin,mode,[data{\bits},...]

Dpin is the data output, cpin is the clock output.  Mode is 0 for lsb-first or
1 for msb-first.  Data is a value to be shifted out.  Bits is an optional bit
count (8 is the default).

The following symbols are defined for use with SHIFTOUT:

symbol		value
---------------------
LSBFIRST	0
MSBFIRST	1


===============================================================================
SHIFTIN
===============================================================================
Shift bits in synchronously.

usage:	SHIFTIN dpin,cpin,mode,[variable{\bits},...]

Dpin is the data input, cpin is the clock output.  Mode is 0 for msb-first/
pre-clock, 1 for lsb-first/pre-clock, 2 for msb-first/post-clock, or 3 for
lsb-first/post-clock.  Variable receives the shifted-in data.  Bits is an
optional bit count (8 is the default).

The following symbols are defined for use with SHIFTIN:

symbol		value
---------------------
MSBPRE		0
LSBPRE		1
MSBPOST		2
LSBPOST		3


===============================================================================
COUNT
===============================================================================
Count cycles on a pin for some milliseconds.

usage:	COUNT	pin,period,variable

Pin will be placed in input mode.  For 'period' milliseconds, cycles will be
counted on pin.  Both sides of the waveform must be at least 4us in duration,
limiting the input frequency to 125KHz (assuming 50/50 duty cycle).  The result
(0-65535) will be written into variable.


===============================================================================
PULSOUT
===============================================================================
Output a timed pulse.

usage:	PULSOUT	pin,period

Pin will be made an output opposite of it's OUTx value for period*2us.  Pin
will be left in output mode with OUTx state.


===============================================================================
PULSIN
===============================================================================
Input a timed pulse.

usage:	PULSIN	pin,state,variable

Pin will be placed in input mode.  A pulse of 'state' will be waited for and
measured with 2us resolution and the result will be written into variable.  If
an overflow occurs while waiting for any edge, (>65535*2us or >131ms), 0 will
be written into variable.


===============================================================================
BUTTON
===============================================================================
Debounce button, auto-repeat, and branch if button is in target state.

usage:	BUTTON  pin,downstate,delay,rate,bytevariable,targetstate,label

Pin will be placed in input mode.  Downstate is the state which is read when
the button is pressed.  Delay specifies down-time before auto-repeat in BUTTON
cycles.  Rate specifies the auto-repeat rate in BUTTON cycles. Bytevariable is
the workspace.  It must be cleared to 0 before being used by BUTTON for the
first time.  Targetstate specifies what state (0=not pressed, 1=pressed) the
button should be in for a branch to occur.  Label specifies where to go if the
button is in the target state.


===============================================================================
INPUT, OUTPUT, LOW, HIGH, TOGGLE, REVERSE
===============================================================================
Modify a pin's input/output high/low state.

usage:	INPUT	pin

Pin is 0-15.

modified:	OUTx	DIRx
----------------------------
INPUT		same	0
OUTPUT		same	1
LOW		0	1
HIGH		1	1
TOGGLE		flip	1
REVERSE		same	flip


===============================================================================
FREQOUT
===============================================================================
Output a sine-wave(s) for some time.

usage:	FREQOUT	pin,milliseconds,freq1{,freq2}

Pin will be temporarily placed in output mode for modulation.  Milliseconds
specifies how long to output the frequency(s).  Freq1 specifies the (first)
frequency in 1Hz units (0-32768Hz).  Freq2 is optional and specifies a second
frequency.

The pin may be filtered by an RC circuit to achieve a clean sine-wave(s).
High-Z speakers may be driven with a coupling cap and a filter cap.


===============================================================================
DTMFOUT
===============================================================================
Output DTMF tones.

usage:	DTMFOUT	pin,{ontime,offtime,}[key,key,key,...]

Pin will be temporarily placed in output mode for modulation.  The default
on and off times are 200ms and 50ms.  ontime and offtime are optional overrides
which specify milliseconds.  Key(s) are 0-15; 0-9 are the digits '0'-'9'; 10 is
'*'; 11 is '#'; 12-15 are 'A'-'D' which are fourth-column codes unavailable on
normal phones.

The pin may be filtered by an RC circuit to achieve a clean sine-waves.
High-Z speakers may be driven with a coupling cap and a filter cap.


===============================================================================
PWM
===============================================================================
Pulse-width modulate a pin for some time.

usage:	PWM	pin,duty,cycles

Pin will be temporarily made an output while it is modulated.  Duty is an 8-bit
value (0-255) which specifies the duty-cycle.  Cycles is the number of 256
pin update periods which take ~1ms.  When done, pin will be placed in input
mode to allow the voltage to remain until another PWM is executed.

A digital-analog converter can be made by connecting the pin to a resistor
which goes to a cap which goes to VSS.  The resistor-cap junction will reflect
the duty (0-5V) during and after PWM.


===============================================================================
RCTIME
===============================================================================
Measure an R-C charge/discharge time.

usage:	RCTIME	pin,state,variable

Pin will be placed in input mode and time will be measure in 2us units while
pin is in 'state'.  The result will be written into variable.  If an overflow
occurs (>131ms), 0 will be written.

This is useful for measuring resistor-capacitor charge/discharge times.  Since
the logic threshold of a pin is ~1.4 volts, it is best to have the RC voltage
go from the 5V supply towards ground, yielding a span of ~3.6 volts.  For
example, to convert a potentiometer setting to a number:  connect a .1uf cap
to VDD (5V); the other side of the cap goes to both the pin and the center-tap
of the pot; the side-tap of the pot goes to VSS (ground); make the pin high
for 1ms, then do RCTIME; the resistor-cap junction will start at 5V and fall
towards ground.  When ~1.4 is reached, the counting will terminate and the
result will be returned to variable.  Adjusting the pot causes the returned
value to go up or down.  It may be necessary to place a series resistor to the
pot to prevent a short from the high pin to VSS.


===============================================================================
NAP
===============================================================================
Nap for a short period.

usage:	NAP x

Enter low-power mode for a short period.  When the period is over, the I/O's
will go high-z for ~18ms and execution will continue at the next instruction.

The x values for NAP are as follows:

	x	~seconds
	----------------
	0	.018
	1	.036
	2	.072
	3	.14
	4	.29
	5	.58
	6	1.2
	7	2.3


===============================================================================
SLEEP
===============================================================================
Sleep for x seconds (x=0 to 65535).

usage:	SLEEP x

Enter low-power mode and keep I/O's updated.  Every ~2.3 seconds the I/O's
will go high-z for ~18ms.  Approximately 50ua average current will be consumed.
When x seconds have been accrued in SLEEP mode, execution continues at the next
instruction.  Though the granularity of SLEEP is ~2.3 seconds, the error is
within 1% over extended periods of time.

===============================================================================
END
===============================================================================
End program.

usage:	END

Enter low-power mode and keep I/O's updated.  Every ~2.3 seconds the I/O's
will go high-z for ~18ms.  Approximately 50ua average current will be consumed.
END is terminated only by a hardware reset.


===============================================================================
PAUSE
===============================================================================
Pause for x milliseconds (x=0 to 65535).

usage:	PAUSE	x

A delay of x milliseconds will occur.


===============================================================================
STOP
===============================================================================
Stop execution.

usage:	STOP

Execution is frozen, but low-power mode is not entered.  This is like
END, except that the I/O's never go high-z; they remain driven.  Reset
will end STOP.
