--> ap/xxxxx

* __

deprecated in favour of sourceforge and notes

scrying-serial-palm: (2007.09.24:2 atmegascheme#12 tech_notes2#11)

1] code and board mistakes. remember - 22 is AGND, 21 AREF by 10 nF tied to GND, and 20 aVCC

see http://tuxgraphics.org/electronics/200705/article07051.shtml

Example code:


rough atmega-palm connection notes (2007.09.24:1 atmegascheme#11 tech_notes2#10)

[primarily for debugging scrying boards]

1] Using standard ATmega8 breadboarded (runs at 8MHz with external crystal) connected to Palm Pilot by way of DIY serial level convertor (MAX3232 - white cable here to pin3 (TXD)

2] Set fuse for external oscillator using the prg_fusebit_uc shell script - option -w 0 for external crystal

3] project home is ~/projects/scryer/avrscheme

4] swop over TX and RX as null modem for Palm - achieved in home-made gender changer!

ATmega Scheme latest: (2007.07.11:1 scrying_tech_notes#22 atmegascheme#10)

From ActorNet paper: [http://osl.cs.uiuc.edu/docs/actornet/kwonActorNet.pdf]

The callcc operator accesses the current continuation (CC)—an abstraction of the rest of the program remain- ing to execute. For example, the CC of the expression (add 1 (mul 2 ↓ 3)) at the ↓ mark can be regarded as a single-parameter function c1: (lambda (x) (c2 (mul 2 x))), where c2 is an another single-parameter function (lambda (x) (add 1 x)). In general, the CC can be regarded as a stack of single-parameter functions. The operand of callcc is a single-parameter function: when callcc is called the CC is passed to the operand function.

In actorNet, the CC and the value that will be passed to it form the state of an actor. Because an actor can read its current continuation, it can duplicate itself or migrate to an- other platform voluntarily by sending its continuation–value pair to another actor. The other actor simply evaluates the continuation on the value to duplicate the sender’s behavior.

For our own work stressing remote execution and concurrency:

Each ActorNet platform hosts a launcher actor which regards messages sent to it as programs and evaluates them.

Actors rather than iterated execution. User as actor in environment also.

Other features:

[from above paper also]

Other Schemes of note:

Icbins: http://www.accesscom.com/~darius/hacks/icbins/

Minischeme: ftp://ftp.cs.indiana.edu/pub/scheme-repository/imp/minischeme.tar.gz

s9fes: http://t3x.org/bits/s9fes/

Tinyscheme: http://tinyscheme.sourceforge.net/home.html

More Scheme on the ATmega (2007.06.24:1 atmegascheme#9 scrying_tech_notes#17)

... now ATmega128 (low power) board:

[this is the reduced test board sans SRAM]:



[above corrected on 25/6/2007: programming jumper P6 to wrong pins]

To be tested (1/ test fuse bits for 8 MHz 2/ programming 3/ serial)

Further links for ATMega Scheme implementation:

XS: Lisp on Lego MindStorms: http://www.yuasa.kuis.kyoto-u.ac.jp/~yuasa/xs/index.html

Scheme implementation for AVR-based Mica-series wireless sensor nodes:

ActorNet: http://osl.cs.uiuc.edu/nest/:-1.1.tar.gz

ATmega serial and notes: (2007.01.09:2 tech_notes#2 atmegascheme#8)

1] Using old MAX3232 circuit from PIC times (see http://www.geocities.com/vsurducan/electro/PIC/pic84lcd.htm) with pin 11 of 3232 (T1IN) to TX pin 3 on ATmega, 12 (R1OUT) to RX pin 2.

2] 1 MHz is factory default internal oscillator frequency which we CAN change with Guido's prg_fusebit_uc script (1 MHz means we have to stay at 2400 baud and this is as set in minicom: 2400 8N1) - can only be changed without external oscillator upto 8 MHz

3] Sample serial writing code as follows:

#include <stdio.h>
#include <avr/io.h>
#include <inttypes.h>
#define F_CPU 1000000UL  // 1 MHz
#include <avr/delay.h>

#define BAUD 2400

#define F_OSC 1000000 //default setting
#define UART_BAUD_RATE 2400

void init_uart(void)
  // set baud rate

  // Enable receiver and transmitter; enable RX interrupt
  UCSRB = (1<<RXEN) | (1<<TXEN);

  //asynchronous 8N1
  UCSRC = (1<<URSEL) | (3<<UCSZ0);

static int uart_putchar(char c, FILE *stream);

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE);

static int uart_putchar(char c, FILE *stream)
  if (c == '\n')
    uart_putchar('\r', stream);
  loop_until_bit_is_set(UCSRA, UDRE);
  UDR = c;
  return 0;

  stdout = &mystdout;
  while(1) printf("help!");
  return 0;

4] serial echo (read/write echoes characters typed from miniterm based on wiring.c from Arduino):


5] Forgot that Emacs/Brood code of Tom Schouten's is all wrapped up in Forth... should be easy enough to use PLT or other Lisp/Scheme to wrap up communications with the scrying scheme board.

6] Next step is to use the LQFP32 packaged FT232BL (not R) board -

Kicad program for schematics looks good but we will have to modify the 232R component (both SMD and DIL ATmegas are available in additional libraries).


Kicad: http://www.lis.inpg.fr/realise_au_lis/kicad/

Libraries: http://www.kicadlib.org/

(Oregano (limited as to component libraries), and Xcircuit also as possible schematic capture offerings).

Related sources for LispCPU and ATmega Scheme interpreter: (2007.01.08:2 lispcpu#7 atmegascheme#7)


All in some way encoding a similar implementation and raising the same issues and questions (implementation as establishing of primitives in the host language (say C or assembly) and using these as building blocks for the to-some-extent bootstrapping interpreter to abstract out lower level detail (eg. storage, reading and writing of single characters). Such abstraction - everything is a list.

Questions thus:

With reference to 1] - make-procedure function:

(define (make-procedure parameters body env)
  (list 'procedure parameters body env))

In the Lisp reader.

From Chaitin's code:

All strings are as characters within the tree of cells. obj_list points to a list (in this same cellular memory) of pointers to all of these (for example primitives) which are initialised first off as built-in atoms. cons is the base operation to construct/allocate such lists. Key functions: lookup_word and mk_atom. All is list operations on storage.

Evaluation handles define first (question of binding) before eval (ev function) proper.

SICP p.377. Binding and frames. Operations on the environment:

The evaluator needs operations for manipulating environments. As explained in section 3.2, an environment is a sequence of frames, where each frame is a table of bindings that associate variables with their corresponding values. We use the following operations for manipulating environments:

(lookup-variable-value )

returns the value that is bound to the symbol in the environment , or signals an error if the variable is unbound.

(extend-environment )

returns a new environment, consisting of a new frame in which the symbols in the list are bound to the corresponding elements in the list , where the enclosing environment is the environment .

(define-variable! )

adds to the first frame in the environment a new binding that associates the variable with the value .

(set-variable-value! )

changes the binding of the variable in the environment so that the variable is now bound to the value , or signals an error if the variable is unbound.


Stripped down Chaitin (2007.01.03:2)

compiles only for the ATmega128

ATmega8: /usr/libexec/gcc/avr/ld: region text is full (lisp2.out section .text)

test with added serial support for prompt

Started on mini Scheme interpreter for the memory deficient (2007.01.03:1 atmegascheme#5 tech_notes#334)

ATmega8 platform, using free software tools, and based on Steele and Sussman's Design of Lisp-based Processors, and Abelson and Sussman's


;;SECTION 5.4.1
  (test (op self-evaluating?) (reg exp))
  (branch (label ev-self-eval))
  (test (op variable?) (reg exp))
  (branch (label ev-variable))
  (test (op quoted?) (reg exp))
  (branch (label ev-quoted))
  (test (op assignment?) (reg exp))
  (branch (label ev-assignment))
  (test (op definition?) (reg exp))
  (branch (label ev-definition))
  (test (op if?) (reg exp))
  (branch (label ev-if))
  (test (op lambda?) (reg exp))
  (branch (label ev-lambda))
  (test (op begin?) (reg exp))
  (branch (label ev-begin))
  (test (op application?) (reg exp))
  (branch (label ev-application))
  (goto (label unknown-expression-type))

also a pinch of Chaitin's C Lisp interpreter...


in contrast Steele and Sussman make use of a 3 bit type field (plus 8 bits for the address) for 7 types (thus 256x 11 bit words)

#define CONSTANTL 0
#define CONSTANTS 1
#define VAREF 2
#define CC 3
#define PROC 4
#define COND 5
#define PROCEDURE 6
#define QUOTE 7

further storage notes (Steel/Sussman):

The method we use for implementing CAR, CDR and CONS is the usual one of using two consecutive words of memory to hold a list cell, the first being the cdr and the second the car, where each word of memory can hold a type field and an address field. The address part of the pointer is in turn the address within the linear memory of the record pointed to.

Abelson and Sussman use two vectors: the_cars and the_cdrs


We can use vectors to implement the basic pair structures required for a list-structured memory. Let us imagine that computer memory is divided into two vectors: the-cars and the-cdrs. We will represent list structure as follows: A pointer to a pair is an index into the two vectors. The car of the pair is the entry in the-cars with the designated index, and the cdr of the pair is the entry in the-cdrs with the designated index. We also need a representation for objects other than pairs (such as numbers and symbols) and a way to distinguish one kind of data from another. There are many methods of accomplishing this, but they all reduce to using typed pointers, that is, to extending the notion of “pointer” to include information on data type.7 The data type enables the system to distinguish a pointer to a pair (which consists of the “pair” data type and an index into the memory vectors) from pointers to other kinds of data (which consist of some other data type and whatever is being used to represent data of that type). Two data objects are considered to be the same (eq?) if their pointers are identical.


The reader maintains a table, traditionally called the obarray, of all the symbols it has ever encountered. When the reader encounters a character string and is about to construct a symbol, it checks the obarray to see if it has ever before seen the same character string. If it has not, it uses the characters to construct a new symbol (a typed pointer to a new character sequence) and enters this pointer in the obarray. If the reader has seen the string before, it returns the symbol pointer stored in the obarray. This process of replacing character strings by unique pointers is called interning symbols.

cons as:

 (op vector-set!) (reg the-cars) (reg free) (reg <reg2>))
 (op vector-set!) (reg the-cdrs) (reg free) (reg <reg3>))
(assign <reg1> (reg free))
(assign free (op +) (reg free) (const 1))

further instruction summary:

A controller instruction in our register-machine language has one of
the following forms, where each <inputi> is either (reg
<register-name>) or (const <constant-value>).

These instructions were introduced in section 5.1.1:

(assign <register-name> (reg <register-name>))

(assign <register-name> (const <constant-value>))

(assign <register-name> (op <operation-name>) <input1> ... <inputn>)

(perform (op <operation-name>) <input1> ... <inputn>)

(test (op <operation-name>) <input1> ... <inputn>)

(branch (label <label-name>))

(goto (label <label-name>))

The use of registers to hold labels was introduced in section 5.1.3:

(assign <register-name> (label <label-name>))

(goto (reg <register-name>))

Instructions to use the stack were introduced in section 5.1.4:

(save <register-name>)

Chaitin's Lisp interpreter: (2007.01.02:4 atmegascheme#4 lisp#4)


The Art of the Interpreter of, the Modularity Complex (Parts Zero, One, and Two) (2007.01.02:3 atmegascheme#3 tech_notes#333 cpu#8 lisp#3 scheme#1)


further Scheme research:

icbins: from http://www.accesscom.com/~darius/

with further interesting code there...

from the README from icbins:

Here we have an exercise in stripping a Lisp to barest essentials, dropping the host tether early, and repeatedly changing and rebuilding, to practice evolving a self-hosted system. Only the garbage collector and the lowest-level Lisp primitives are in C. The source is an order of magnitude smaller than the already-lightweight UTS's. You might find this of interest if you want to do similar exercises or if you'd just like to read a tiny Lisp system with no magic (small self-hosting Lisps typically rely on powerful primitives like READ, PRINT, and GC). This could be cut down further; hopefully I'll come back to it someday.

no go chicken scheme -> avr-gcc (system heavy libraries) (2007.01.02:2 atmegascheme#2 arduino#2 tech_notes#332 cpu#7)

First steps for ATmega Scheme Interpreter: (2007.01.02:1 atmegascheme#1 arduino#1 tech_notes#331 cpu#6)

-a) checl we have ftdi_sio and usbserial modules built and loaded

a) we have the Arduino codebase

b) on Gentoo: emerge crossdev (had to first set PORTDIR_OVERLAY=/usr/portage in /etc/make.conf)

takes some time...

c) emerge avrdude programming utility AFTER b) succeeds

d) check out Makefile and modify as below

# Arduino makefile
# This makefile allows you to build sketches from the command line
# without the Arduino environment (or Java).
# The Arduino environment does preliminary processing on a sketch before
# compiling it.  If you're using this makefile instead, you'll need to do
# a few things differently:
#   - Give your program's file a .cpp extension (e.g. foo.cpp).
#   - Put this line at top of your code: #include <WProgram.h>
#   - Write prototypes for all your functions (or define them before you
#     call them).  A prototype declares the types of parameters a
#     function will take and what type of value it will return.  This
#     means that you can have a call to a function before the definition
#     of the function.  A function prototype looks like the first line of
#     the function, with a semi-colon at the end.  For example:
#     int digitalRead(int pin);
# Instructions for using the makefile:
#  1. Copy this file into the folder with your sketch.
#  2. Below, modify the line containing "TARGET" to refer to the name of
#     of your program's file without an extension (e.g. TARGET = foo).
#  3. Modify the line containg "ARDUINO" to point the directory that
#     contains the Arduino core (for normal Arduino installations, this
#     is the lib/targets/arduino sub-directory).
#  4. Modify the line containing "PORT" to refer to the filename
#     representing the USB or serial connection to your Arduino board
#     (e.g. PORT = /dev/tty.USB0).  If the exact name of this file
#     changes, you can use * as a wildcard (e.g. PORT = /dev/tty.USB*).
#  5. At the command line, change to the directory containing your
#     program's file and the makefile.
#  6. Type "make" and press enter to compile/verify your program.
#  7. Type "make upload", reset your Arduino board, and press enter  to
#     upload your program to the Arduino board.
# $Id$



e) test code:


make: avr-g++: Command not found

next try: (after: http://www.arduino.cc/playground/Linux/Gentoo )

USE='-nocxx' emerge cross-avr/gcc cross-avr/avr-libc

make succeeds - we have a blink1.hex and so on

f) make upload


few changes to Makefile for avrdude and avrusb500 programmer, updated to new core Arduino necessitating more Makefile changes and now programs fine with 5v attached to ATmega on breadboard

g) pin mapping: http://www.arduino.cc/en/Hacking/

eg. digital pin 13 in blink LED example is true ATmega8 pin 19

// On the Arduino board, digital pins are also used
// for the analog output (software PWM).  Analog input
// pins are a separate set.

//             +-\/-+
//       PC6  1|    |28  PC5 (AI 5)
// (D 0) PD0  2|    |27  PC4 (AI 4)
// (D 1) PD1  3|    |26  PC3 (AI 3)
// (D 2) PD2  4|    |25  PC2 (AI 2)
// (D 3) PD3  5|    |24  PC1 (AI 1)
// (D 4) PD4  6|    |23  PC0 (AI 0)
//       VCC  7|    |22  GND
//       GND  8|    |21  AREF
//       PB6  9|    |20  AVCC
//       PB7 10|    |19  PB5 (D 13)
// (D 5) PD5 11|    |18  PB4 (D 12)
// (D 6) PD6 12|    |17  PB3 (D 11) PWM
// (D 7) PD7 13|    |16  PB2 (D 10) PWM
// (D 8) PB0 14|    |15  PB1 (D 9) PWM
//             +----+

h) one problem with Scheme/Arduino plan is presented by wiring.c which wraps setup and loop into main function.. but we could easily replace this