Commits

Serge A. Zaitsev  committed 554dca1

added genall script, all pages are stored in this repo, too

  • Participants
  • Parent commits 8cf21db

Comments (0)

Files changed (11)

+#!/bin/sh
+
+./gendoc.sh "zserge's home" pages/index.mkd \
+	"zserge's home page: as simple as it should be" \
+	"software, minimalism, linux, embedded, avr, android, golang, KISS" \
+	> index.html
+
+./gendoc.sh "six - tiny IRC client" pages/six.mkd \
+	"six - simple IRC client kept simple" \
+	"irc, simple, client, terminal" \
+	> six.html
+
+./gendoc.sh "jsmn" pages/jsmn.mkd \
+	"The most simple JSON parser in C for small systems" \
+	"json, parse, c, unix, embedded, KISS, minimal, memory allocation" \
+	> jsmn.html
+
+./gendoc.sh "nikl" pages/nikl.mkd \
+	"Microframework for embedded systems development" \
+	"embedded system, rtos, protothread, development, avr, pic, arm, microcontroller, programming" > nikl.html
+
+./gendoc.sh "nikl" pages/j1vm.mkd\
+	"Tiny virtual machine for Forth language" \
+	"virtual machine, vm, forth, interpreter, compiler, assembler, stack, embedded, small, retro"> ivm.html
+
 <head>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 	<title>zserge's home</title>
-	<meta name="description" content="" />
-	<meta name="keywords" content="" />
+	<meta name="description" content="zserge's home page: as simple as it should be" />
+	<meta name="keywords" content="software, minimalism, linux, embedded, avr, android, golang, KISS" />
 
 	<link rel="stylesheet" href="style.css" type="text/css"/>
 	<script type="text/javascript">
 <ul>
 <li><a href="jsmn.html">jsmn</a>  - JSON parser for small systems
 [<a href="http://bitbucket.org/zserge/jsmn">repo</a>]</li>
-<li>six - very simple IRC client [<a href="http://bitbucket.org/zserge/six">repo</a>]</li>
+<li><a href="six.html">six</a> - very simple IRC client [<a href="http://bitbucket.org/zserge/six">repo</a>]</li>
 <li>gotftp - basic TFTP server written in Go
 [<a href="http://bitbucket.org/zserge/gotftp">repo</a>]</li>
+<li>j1vm - J1 Forth CPU simulator and compiler [<a href="http://bitbucket.org/zserge/j1vm">repo</a>]</li>
 <li><a href="nikl.html">nikl</a> - micro-framework for programming embedded systems [<a href="http://bitbucket.org/zserge/nikl">repo</a>]</li>
 <li><a href="ivm.html">ivm</a> - simple forth virtual machine (a part of <a href="nikl.html">nikl</a>) [<a href="http://bitbucket.org/zserge/nikl">repo</a>]</li>
 </ul>
 
 <ul>
 <li>You can email me at google mail: zaitsev.serge</li>
-<li>Or follow on twitter: zserge</li>
+<li>Or follow on twitter: <a href="http://twitter.com/zsergo">@zsergo</a></li>
 <li>Or read my <a href="http://zserge.wordpress.com">blog</a> (in russian)</li>
 </ul>
 	</div>
 <h1>IVM</h1>
 
 <p>IVM (IV Machine or Forth Machine) is a very simple virtual machine
-for small embedded devices. It's a stack machine and is designed
-to run Forth code.</p>
+for small embedded devices. It's a software implementation of
+<a href="http://http://excamera.com/sphinx/fpga-j1.html">J1 Forth CPU</a> and is binary
+compatible with it.
+IVM is a stack machine and is designed to run Forth code, but
+can be used as a general-purpose VM as well.</p>
 
-<h2>GOALS</h2>
+<h2>HOW CAN I USE IT?</h2>
 
-<p>Imagine that you have a very simple hardware with complicated logic.  You could
-use tiny chip with a few peripherals, as you need just a couple of GPIOs and 
-maybe UART or SPI. But your software will never fit that 2K of ROM that you
-can find on the cheapest microcontrollers. The solution can be run only a virtual 
-machine on the micro, but store code on external storage, like EEPROM or SPI
-flash.</p>
+<p>There can be various scenarios, but in general if you:</p>
 
-<p>Another situation. You need to update the firmware after the device is producted.
-You can write the firmware update module, and run it when, say, an SD card is plugged
-into the device. But, on the other hand, you can store the code on the external card
-as well, right?</p>
+<ul>
+<li>want to customize your software without reprogramming the firmware</li>
+<li>want to isolate and control your software</li>
+<li>have enough storage to put virtual machine there (it's about 1K!)</li>
+<li>have storage for the software running inside virtual machine (it's usually 
+more compact than native code)</li>
+<li>can write critical parts in native code and map them to VM memory-mapped I/O</li>
+<li>can forgive than it run 10 times slower than native code</li>
+</ul>
 
-<p>So, IVM is designed to be as small as possible (less than 1K) to fit even the smallest micros, and it
-should bring them to the new level by possibility of running external code.</p>
-
-<p>IVM should be flexible and easy to customize.</p>
+<p>...then you should try running IVM.</p>
 
 <h2>DESIGN</h2>
 
+<p>IVM is designed to be as small as possible (less than 1K) to fit even the
+smallest micros, and it should bring them to the new level by possibility of
+running external code.</p>
+
+<p>IVM is very flexible and easy to customize.</p>
+
 <p>IVM code is stored in the "/inc/ivm.h" file. It has two functions:</p>
 
 <ul>
 <p>You need to implement some functionality by your own:</p>
 
 <ul>
-<li><p>fetching instructions. Each instruction is a 2-byte word. Instruction 
-index is stored in the "pc" variable</p></li>
-<li><p>implementing memory. You must implement ivm<em>mem</em>put and ivm<em>mem</em>get functions
+<li>Fetching instructions. Each instruction is a 2-byte word. Instruction 
+index is stored in the <code>ivm_pc</code> variable</li>
+<li>Memory access. You must implement <code>ivm_mem_put</code> and <code>ivm_mem_get</code> functions
 to read and write to the memory. It is not a part of IVM code, because you can
 use your I/O ports in a memory mapped way, or you might want to cache some
-addresses if you use external memory chip. Also, you decide what is the amount
-of RAM available to the VM.</p></li>
+address range if you use external memory chip. Also, you decide what is the amount
+of RAM available to the VM.</li>
 </ul>
 
 <h2>INSTRUCTION SET</h2>
 
-<p>IVM has a simple assebler compatible with J1 chip.</p>
+<p>IVM has a simple instruction set compatible with the J1 Forth CPU.</p>
 
-<p>IVM has two stacks - data stack (DS) and return stack (RS).
-Default depth for both of them is 16 levels.</p>
+<p>IVM has two stacks - data stack (DS) and return stack (RS).  Default depth for
+both of them is 16 levels (<strong>WARNING: Original J1 has 32 levels!</strong>)</p>
 
-<p>Basically, there is 5 types of the instructions:</p>
+<p>Basically, there are 5 types of the instructions:</p>
 
 <ul>
 <li><p>LIT: put a number on the DS</p></li>
 <li><p>ALU: perform ariphmetic operation</p></li>
 </ul>
 
-<p>There is 16 types of ALU instructions, each of them can also manipulate
+<p>There are 16 types of ALU instructions, each of them can also manipulate
 DS and RS stacks, change PC and work with memory. For more details
 check the J1 project.</p>
 
 <h2>COMPILER</h2>
 
-<p>If you know Forth, you can use crosscompiler from J1 project.</p>
+<p>If you know Forth, you can use crosscompiler from the J1 project.</p>
 
-<p>There is a simple compiler written in Python (check utils/ivmc).
-It's not actually forth compiler, but is very similar.</p>
+<p>ALternatively, there is a separate project of developer tools for
+J1 CPU - <a href="http://bitbucket.org/zserge/j1vm">j1vm</a></p>
 
-<p>To compile your program you need to:</p>
+<p>There is a Forth compiler <code>j1c</code> and a simulator (<code>j1vm</code>).</p>
 
-<pre><code>$ ivmc file1.fs [file2.fs file2.fs ... ] rom.bin
+<h2>IVM FORTH BASICS</h2>
+
+<p><strong>Syntax</strong></p>
+
+<p>Forth has reverse Polish notation. So, to add two number you should
+write <code>2 3 +</code> and to add three numbers - <code>1 2 3 + +</code>.</p>
+
+<p>This is so, because Forth program is executed from left to right, so if you
+write <code>open read close</code> it will mean firth open, then read and finally close.
+This sounds more intuitive, right?</p>
+
+<p>Comments in Forth are like:</p>
+
+<pre><code>( this is a comment )
+\ this is a single line comment
 </code></pre>
 
-<p>This will create a binary file with is a IVM rom. Now you can
-put it on the external storage and run with your virtual machine.</p>
+<p><strong>Stacks</strong></p>
 
-<p>Files will be compiled in the order you write their names, so file2.fs
-can use functions from file1.fs.</p>
+<p><em>IVM has two stacks, so how do they work?</em></p>
 
-<h2>IVM FORTH-LIKE DIALECT</h2>
+<p>Data stack is a place where temporary values are stored and where
+all the calculations happen. So, if you write <code>2 3 +</code> it means:
+"put 2 on the top of the data stack, then put 3 over it, then run
+ALU function +". Function "+" fetches two items from the top of
+the stack, add them, and puts the result on the data stack as well,
+replacing that two items. So, if stack was like "1 2 3" before 
+calling "+", after that the stack will be "1 5".</p>
 
-<p>Source file is a list of space-separated words. Each words is a literal
-(number, letter) or a function.</p>
+<p>There is a specific notation that helps you to know how functions
+manipulate data stack. It's written like a comment. This is how
+we would describe "+" function: <code>( a b -- a+b )</code>. See? There were 
+<code>a</code> and <code>b</code> on the top, but we replace them with <code>a+b</code> sum.</p>
 
-<p>Forth uses postfix notation. </p>
+<p>How would you call this function: <code>( a b -- b a )</code>? Right, it's <code>swap</code>.
+And this one: <code>( a -- a a )</code> is <code>dup</code>, because it duplicates the top item.
+And this one: <code>( a -- )</code> is <code>drop</code>, because it drops the top item from
+the stack.</p>
 
-<p>IVM dialect is specific, because has inline macros.</p>
+<p><em>But why there are two stacks?</em></p>
 
-<p>Macro starts with '::' and ends with ';;' words.
-When macro is called somewhere in your code it is not replaced with a jump or call,
-like a normal funtion, but is inserted in your code, e.g:</p>
+<p>The second stack is a return stack, but it does more than storing
+return addresses when calling functions. You can put your local values
+there when playing with data stack, and fetch them later.</p>
 
-<pre><code>...
-: inc ( x -- x+1 ) 1 + ;
-2 inc
+<p>Whan if you need a function like <code>( a b c d -- a+b c+d )</code>?
+First you call <code>+</code> and get <code>( a b c+d )</code>. But now you need to 
+remove that <code>c+d</code> from the top of the stack! You can move that item
+to the return stack. Use functions <code>&gt;r</code> and <code>r&gt;</code> to do that.
+The first one is "put-to-return-stack" and the second one is
+"fetch-from-return-stack", but it's obvious because of the arrow
+position. So, this is your code for the function above:</p>
+
+<pre><code>( a b c d -- a+b c+d)
++ ( a b c+d )
+&gt;r ( a b )
++ ( a+b )
+r&gt;  ( a+b c+d )
 </code></pre>
 
-<p>It will give code:</p>
+<p><strong>Memory</strong></p>
 
-<pre><code>Function code:
-0x100: LIT 1
-0x102: ALU_PLUS
-0x104: RETURN
+<p>If you need to store global variables, you can use memory-access functions: 
+<code>@</code> and <code>!</code>. They are "fetch" and "store" </p>
 
-Caller code:
-0x105: LIT 2
-0x106: CALL 0x100
+<p>It means, that <code>100 @</code> fetches 16-bit value from address 100, and <code>5 100 !</code> writes value 5 to address 100. At this moment variables and constants become handy.</p>
+
+<p>Both variables and constants differ from what you normally see in Forth. To make a global variable you write:</p>
+
+<pre><code>var my-var
 </code></pre>
 
-<p>If you rewrite it as a macro</p>
+<p>This allocates new variable address in RAM. If you need to make a constant definition write:</p>
 
-<pre><code>:: inc ( x -- x+1 ) 1 + ;;
-2 inc
+<pre><code>equ X 10
 </code></pre>
 
-<p>You will get:</p>
+<p>Now you can use them in your code: <code>my-var @</code> or <code>X my-var !</code>. Great thing is that you can use constants like variables if you need to use specific address (e.g. for memory-mapped I/O): </p>
 
-<pre><code>0x100: LIT 2
-0x102: LIT 1
-0x104: ALU_PLUS
+<pre><code>equ GPIO 1234
+( GPIO &amp; 0x80 )
+GPIO @ 128 &amp;
 </code></pre>
 
-<p>Macros are useful to define variables. Memory operators are '!' and '@', as in forth:</p>
+<h2>Control structures</h2>
 
-<pre><code>2 5 ! ( put 2 at address 0x5 )
-3 @ ( read from 0x3 to the top of DS )
+<p>At this point Forth is just an assembly language with weird syntax. Yes, it's compact, it's easy to learn and it's fast, but it's too much low-level. How do I make a loop? How to branch my code?</p>
+
+<p>It's easy. First, about branches. Internally, they use JZ/JMP instructions. The syntax is like:</p>
+
+<pre><code>&lt;condition&gt; if &lt;then-branch&gt; else &lt;else-branch&gt; then
+&lt;condition&gt; if &lt;then-branch&gt; then
+
+: max ( a b -- max[a,b] )
+    over over ( a b a b )
+    &gt; ( a b a&gt;b )
+    if ( a b )
+        drop ( a )
+    else
+        nip ( b )
+    then
 </code></pre>
 
-<p>Not to hardcode memory addresses, use macros (with no performance or size affects):</p>
+<p>There are several types of loops in the current implementation:</p>
 
-<pre><code>:: x 0 ;;
-:: y 1 ;;
-
-2 x ! ( write 2 to x ) y ! ( read from y )
+<pre><code>begin &lt;loop-body&gt; again ( infinite loop )
+begin &lt;loop-body&gt; &lt;condition&gt; until ( do .. while )
 </code></pre>
-
-<p>There is a base library (base.fs) with macros to use in your code.</p>
 	</div>
 </div>
 </body>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 	<title>jsmn</title>
 	<meta name="description" content="The most simple JSON parser in C for small systems" />
-	<meta name="keywords" content="json, parse, c, unix, embedded system, KISS, minimal, memory allocation" />
+	<meta name="keywords" content="json, parse, c, unix, embedded, KISS, minimal, memory allocation" />
 
 	<link rel="stylesheet" href="style.css" type="text/css"/>
 	<script type="text/javascript">

File pages/index.mkd

+zserge's home page
+==================
+
+Hi! I'm Serge. I'm a programmer.
+
+I like
+------
+
+I like: simplicity, unix, C, embedded systems, android, Go language. 
+
+I also like: music, retro computers and games, esoteric programming languages.
+But most of all I like my girlfriend, Anna.
+
+Projects
+--------
+
+It would be great if my works would be useful to someone.
+They are free, open source, and very simple:
+
+* [jsmn](jsmn.html)  - JSON parser for small systems
+[[repo](http://bitbucket.org/zserge/jsmn)]
+* [six](six.html) - very simple IRC client [[repo](http://bitbucket.org/zserge/six)]
+* gotftp - basic TFTP server written in Go
+	[[repo](http://bitbucket.org/zserge/gotftp)]
+* j1vm - J1 Forth CPU simulator and compiler [[repo](http://bitbucket.org/zserge/j1vm)]
+* [nikl](nikl.html) - micro-framework for programming embedded systems [[repo](http://bitbucket.org/zserge/nikl)]
+* [ivm](ivm.html) - simple forth virtual machine (a part of [nikl](nikl.html)) [[repo](http://bitbucket.org/zserge/nikl)]
+
+Contact
+-------
+
+I'm not a social guy, but 
+
+* You can email me at google mail: zaitsev.serge
+* Or follow on twitter: [@zsergo](http://twitter.com/zsergo)
+* Or read my [blog](http://zserge.wordpress.com) (in russian)
+

File pages/j1vm.mkd

+IVM
+===
+
+IVM (IV Machine or Forth Machine) is a very simple virtual machine
+for small embedded devices. It's a software implementation of
+[J1 Forth CPU](http://http://excamera.com/sphinx/fpga-j1.html) and is binary
+compatible with it.
+IVM is a stack machine and is designed to run Forth code, but
+can be used as a general-purpose VM as well.
+
+HOW CAN I USE IT?
+-----------------
+
+There can be various scenarios, but in general if you:
+
+* want to customize your software without reprogramming the firmware
+* want to isolate and control your software
+* have enough storage to put virtual machine there (it's about 1K!)
+* have storage for the software running inside virtual machine (it's usually 
+  more compact than native code)
+* can write critical parts in native code and map them to VM memory-mapped I/O
+* can forgive than it run 10 times slower than native code
+
+...then you should try running IVM.
+
+DESIGN
+------
+
+IVM is designed to be as small as possible (less than 1K) to fit even the
+smallest micros, and it should bring them to the new level by possibility of
+running external code.
+
+IVM is very flexible and easy to customize.
+
+IVM code is stored in the "/inc/ivm.h" file. It has two functions:
+
+- ivm_reset() - brings the VM back to the default state
+- ivm_step(op) - executes instruction "op" on the virtual machine
+
+You need to implement some functionality by your own:
+
+- Fetching instructions. Each instruction is a 2-byte word. Instruction 
+index is stored in the `ivm_pc` variable
+- Memory access. You must implement `ivm_mem_put` and `ivm_mem_get` functions
+to read and write to the memory. It is not a part of IVM code, because you can
+use your I/O ports in a memory mapped way, or you might want to cache some
+address range if you use external memory chip. Also, you decide what is the amount
+of RAM available to the VM.
+
+INSTRUCTION SET
+---------------
+
+IVM has a simple instruction set compatible with the J1 Forth CPU.
+
+IVM has two stacks - data stack (DS) and return stack (RS).  Default depth for
+both of them is 16 levels (**WARNING: Original J1 has 32 levels!**)
+
+Basically, there are 5 types of the instructions:
+
+- LIT: put a number on the DS
+
+- JMP: jump to address
+
+- JZ: jump to address if the value on the top of the DS is zero. 
+This instruction also deletes this value from the top of the DS.
+
+- CALL: store current address to the RS and jump to the address.
+This instruction makes it possible to implement functions.
+
+- ALU: perform ariphmetic operation
+
+There are 16 types of ALU instructions, each of them can also manipulate
+DS and RS stacks, change PC and work with memory. For more details
+check the J1 project.
+
+COMPILER
+--------
+
+If you know Forth, you can use crosscompiler from the J1 project.
+
+ALternatively, there is a separate project of developer tools for
+J1 CPU - [j1vm](http://bitbucket.org/zserge/j1vm)
+
+There is a Forth compiler `j1c` and a simulator (`j1vm`).
+
+IVM FORTH BASICS
+----------------
+
+**Syntax**
+
+Forth has reverse Polish notation. So, to add two number you should
+write `2 3 +` and to add three numbers - `1 2 3 + +`.
+
+This is so, because Forth program is executed from left to right, so if you
+write `open read close` it will mean firth open, then read and finally close.
+This sounds more intuitive, right?
+
+Comments in Forth are like:
+
+	( this is a comment )
+	\ this is a single line comment
+
+**Stacks**
+
+*IVM has two stacks, so how do they work?*
+
+Data stack is a place where temporary values are stored and where
+all the calculations happen. So, if you write `2 3 +` it means:
+"put 2 on the top of the data stack, then put 3 over it, then run
+ALU function +". Function "+" fetches two items from the top of
+the stack, add them, and puts the result on the data stack as well,
+replacing that two items. So, if stack was like "1 2 3" before 
+calling "+", after that the stack will be "1 5".
+
+There is a specific notation that helps you to know how functions
+manipulate data stack. It's written like a comment. This is how
+we would describe "+" function: `( a b -- a+b )`. See? There were 
+`a` and `b` on the top, but we replace them with `a+b` sum.
+
+How would you call this function: `( a b -- b a )`? Right, it's `swap`.
+And this one: `( a -- a a )` is `dup`, because it duplicates the top item.
+And this one: `( a -- )` is `drop`, because it drops the top item from
+the stack.
+
+*But why there are two stacks?*
+
+The second stack is a return stack, but it does more than storing
+return addresses when calling functions. You can put your local values
+there when playing with data stack, and fetch them later.
+
+Whan if you need a function like `( a b c d -- a+b c+d )`?
+First you call `+` and get `( a b c+d )`. But now you need to 
+remove that `c+d` from the top of the stack! You can move that item
+to the return stack. Use functions `>r` and `r>` to do that.
+The first one is "put-to-return-stack" and the second one is
+"fetch-from-return-stack", but it's obvious because of the arrow
+position. So, this is your code for the function above:
+
+	( a b c d -- a+b c+d)
+	+ ( a b c+d )
+	>r ( a b )
+	+ ( a+b )
+	r>  ( a+b c+d )
+
+**Memory**
+
+If you need to store global variables, you can use memory-access functions: 
+`@` and `!`. They are "fetch" and "store" 
+
+It means, that `100 @` fetches 16-bit value from address 100, and `5 100 !` writes value 5 to address 100. At this moment variables and constants become handy.
+
+Both variables and constants differ from what you normally see in Forth. To make a global variable you write:
+
+	var my-var
+
+This allocates new variable address in RAM. If you need to make a constant definition write:
+
+	equ X 10
+
+Now you can use them in your code: `my-var @` or `X my-var !`. Great thing is that you can use constants like variables if you need to use specific address (e.g. for memory-mapped I/O): 
+
+	equ GPIO 1234
+	( GPIO & 0x80 )
+	GPIO @ 128 & 
+
+Control structures
+------------------
+
+At this point Forth is just an assembly language with weird syntax. Yes, it's compact, it's easy to learn and it's fast, but it's too much low-level. How do I make a loop? How to branch my code?
+
+It's easy. First, about branches. Internally, they use JZ/JMP instructions. The syntax is like:
+
+	<condition> if <then-branch> else <else-branch> then
+	<condition> if <then-branch> then
+
+	: max ( a b -- max[a,b] )
+		over over ( a b a b )
+		> ( a b a>b )
+		if ( a b )
+			drop ( a )
+		else
+			nip ( b )
+		then
+
+There are several types of loops in the current implementation:
+
+	begin <loop-body> again ( infinite loop )
+	begin <loop-body> <condition> until ( do .. while )
+

File pages/jsmn.mkd

+
+JSMN
+====
+
+jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C.  It can be
+easily integrated into resource-limited or embedded projects.
+
+You can find more information about JSON format at [json.org][1]
+
+Library sources are available at [bitbucket.org/zserge/jsmn][2]
+
+Philosophy
+----------
+
+Most JSON parsers offer you a bunch of functions to load JSON data, parse it
+and extract any value by its name. jsmn proves that checking the correctness of
+every JSON packet or allocating temporary objects to store parsed JSON fields
+often is an overkill. 
+
+JSON format itself is extremely simple, so why should we complicate it?
+
+jsmn is designed to be	**robust** (it should work fine even with erroneous
+data), **fast** (it should parse data on the fly), **portable** (no superfluous
+dependencies or non-standard C extensions). An of course, **simplicity** is a
+key feature - simple code style, simple algorithm, simple integration into
+other projects.
+
+Features
+--------
+
+* compatible with C89
+* no dependencies (even libc!)
+* highly portable (tested on x86/amd64, ARM, AVR)
+* about 200 lines of code
+* extremely small code footprint
+* API contains only 2 functions
+* no dynamic memory allocation
+* incremental single-pass parsing
+* library code is covered with unit-tests
+
+Design
+------
+
+The rudimentary jsmn object is a **token**. Let's consider a JSON string:
+
+	'{ "name" : "Jack", "age" : 27 }'
+
+It holds the following tokens:
+
+* Object: `{ "name" : "Jack", "age" : 27}` (the whole object)
+* Strings: `"name"`, `"Jack"`, `"age"` (keys and some values)
+* Number: `27`
+
+In jsmn, tokens do not hold any data, but point to token boundaries in JSON
+string instead. In the example above jsmn will create tokens like: Object
+[0..31], String [3..7], String [12..16], String [20..23], Number [27..29].
+
+Every jsmn token has a type, which indicates the type of corresponding JSON
+token. jsmn supports the following token types:
+
+* Object - a container of key-value pairs, e.g.:
+	`{ "foo":"bar", "x":0.3 }`
+* Array - a sequence of values, e.g.:
+	`[ 1, 2, 3 ]`
+* String - a quoted sequence of chars, e.g.: `"foo"`
+* Primitive - a number, a boolean (`true`, `false`) or `null`
+
+Besides start/end positions, jsmn tokens for complex types (like arrays
+or objects) also contain a number of child items, so you can easily follow
+object hierarchy.
+
+This approach provides enough information for parsing any JSON data and makes
+it possible to use zero-copy techniques.
+
+Install
+-------
+
+To clone the repository you should have mercurial installed. Just run:
+
+	$ hg clone http://bitbucket.org/zserge/jsmn jsmn
+
+Repository layout is simple: jsmn.c and jsmn.h are library files; demo.c is an
+example of how to use jsmn (it is also used in unit tests); test.sh is a test
+script. You will also find README, LICENSE and Makefile files inside.
+
+To build the library, run `make`. It is also recommended to run `make test`.
+Let me know, if some tests fail.
+
+If build was successful, you should get a `libjsmn.a` library.
+The header file you should include is called `"jsmn.h"`.
+
+API
+---
+
+Token types are described by `jsmntype_t`:
+
+	typedef enum {
+		JSMN_OBJECT,
+		JSMN_ARRAY,
+		JSMN_STRING,
+		JSMN_PRIMITIVE
+	} jsmntype_t;
+
+**Note:** Unlike JSON data types, primitive tokens are not divided into
+numbers, booleans and null, because one can easily tell the type using the
+first character:
+
+* <code>'t', 'f'</code> - boolean 
+* <code>'n'</code> - null
+* <code>'-', '0'..'9'</code> - number
+
+Token is an object of `jsmntok_t` type:
+
+	typedef struct {
+		jsmntype_t type; // Token type
+		int start;       // Token start position
+		int end;         // Token end position
+		int size;        // Number of child (nested) tokens
+	} jsmntok_t;
+
+**Note:** string tokens point to the first character after
+the opening quote and the previous symbol before final quote. This was made 
+to simplify string extraction from JSON data.
+
+All job is done by `jsmn_parser` object. You can initialize a new parser using:
+
+	struct jsmn_parser parser;
+	jsmntok_t tokens[10];
+
+	// js - pointer to JSON string
+	// tokens - an array of tokens available
+	// 10 - number of tokens available
+	jsmn_init_parser(&parser, js, tokens, 10);
+
+This will create a parser, that can parse up to 10 JSON tokens from `js` string.
+
+Later, you can use `jsmn_parse(&parser)` function to process JSON string with the parser.
+If something goes wrong, you will get an error. Error will be one of these:
+
+* `JSMN_SUCCESS` - everything went fine. String was parsed
+* `JSMN_ERROR_INVAL` - bad token, JSON string is corrupted
+* `JSMN_ERROR_NOMEM` - not enough tokens, JSON string is too large
+* `JSMN_ERROR_PART` - JSON string is too short, expecting more JSON data
+
+If you get `JSON_ERROR_NOMEM`, you can re-allocate more tokens and call
+`jsmn_parse` once more.  If you read json data from the stream, you can
+periodically call `jsmn_parse` and check if return value is `JSON_ERROR_PART`.
+You will get this error until you reach the end of JSON data.
+
+Other info
+----------
+
+This software is distributed under [MIT license](http://www.opensource.org/licenses/mit-license.php),
+ so feel free to integrate it in your commercial products.
+
+[1]: http://www.json.org/
+[2]: https://bitbucket.org/zserge/jsmn/wiki/Home

File pages/nikl.mkd

+nikl
+====
+
+Nikl is a micro-framework for small embedded devices like AVR
+microcontrollers.
+
+HISTORY
+-------
+
+One day I decided to write a real-time OS. It had multitasking, semaphores and
+supported only ARM architecture. Then I tried to port it to use with the AVRs,
+but context switching was slow, memory was very limited and my OS became
+generally useless.
+
+Then, I started another project called avOS, that some kind of a kernel that
+was not real-time, and was widely using protothreads for pseudo-multitasking.
+Later the project was abandoned, but now I'm trying to give it a new born.
+
+PHILOSOPHY
+----------
+
+* No .c files, until they are really needed
+* This implies - no build system. You can take any compinations of modules you
+  need and just copy or symlink them to your project directory
+
+
+STRUCTURE
+---------
+
+You should see "/inc" folder. There is where all the modules are stored.
+Another folder is "/test". This is a folder with unit tests. 
+
+Let's go deeper. Inside "/inc" folder you should find modules for
+
+* bare-bone unit-testing (test.h)
+* list-based data structures (list.h)
+* FORTH virtual machine (ivm.h)
+
+For the IVM there is a simple comiler written in Python (see "/utils/ivmc").
+
+HOW TO USE TESTS
+----------------
+
+There is a bunch of unit-testing frameworks. But they all are an overkill for
+tiny embedded systems. If you just need to write a few tests for your device
+and have a possibility to detect which test failed - you can use test.h.
+
+Here's an example of typical usage. Assume we have a board that works with data
+on the SD card. We need to be sure that SD card is valid, and hardware is ready
+to use.  I still doubt if it is a correct usage of unit tests, as it seems like
+we test hardware, but this is how it works for me:
+
+	/* Use custom error notification, e.g. show line number on LCD,
+	 * or send message and line number over UART, or just turn the
+	 * error indicating LED on */
+	#define TEST_NOTIFY(msg, line)	lcd_display_number(line)
+
+	#include <test.h>
+
+	/* Check that after hardware initialization SD card is present */
+	int test_sdcard_available() {
+		int part_id;
+		sdcard_init();
+		check(sdcard_available() == 1);
+
+		/* Ensure that FAT partition ID is 1..4 */
+		part_id = sdcard_find_fat_partition();
+		check(part_id > 0 && part_id <= 4);
+
+		return 0;
+	}
+
+	/* Check that toggling LED port works correctly */
+	int test_leds() {
+		LED_PORT |= (1 << GREEN_LED);
+		check(LED_PORT & (1 << GREEN_LED));
+		LED_PORT &= ~(1 << GREEN_LED);
+		check((LED_PORT & ~(1 << GREEN_LED)) == 0);
+	}
+
+	....
+
+	test(test_sdcard_available(), "sdcard test");
+	test(test_leds(), "LED test");
+
+	...
+
+Ain't it simple? You basically write test functions that do some assertions.
+Then you call these functions and if the return value is non-zero - it means
+that the test has failed. In this case TEST_NOTIFY function will be called and
+it's your chance to tell user that something was wrong
+
+* your test functions must return 0 at the end to indicate success
+* you need to test values using check(condition) macro.
+* you need to run your test functions using test(func, descr) function
+* if you use your own TEST_NOTIFY implementation you can print test name
+  (msg argument) and line number (line argument), where the error occurred.
+
+HOW TO USE LISTS
+----------------
+
+Lists are stolen from linux kernel in a shameless way. They are not so easy-to-use
+as more common <sys/queue.h>, but are more flexible.
+
+To define an object, that can be linked into the list, do:
+
+	typedef struct {
+		/* My data */
+		int value1;
+		int value2;
+		/* List pointer */
+		list_t list;
+	} my_obj;
+
+To create a list head, do:
+
+	list_t my_obj_list;
+
+Next, initialize list:
+
+	list_init(&my_obj_list);
+
+And now you can do everything you want with your lists:
+
+	my_obj *a, *b, *c; /* object to add to the list */
+	list_t *tmp; /* list iterator */
+
+	list_add(&my_obj_list, &a->list);
+	list_add(&my_obj_list, &b->list);
+	list_add(&my_obj_list, &c->list);
+
+	list_del(&b->list);
+
+	list_for_each(&my_obj_list, tmp) {
+		/* This is how to get the object using list_entry() */
+		my_obj *iterator;
+		iterator = list_entry(tmp, my_obj, list);
+		printf("%d\n", iterator->value1);
+	}
+
+For now only double-linked lists are implemented. Soon single-linked lists and
+queues will be added.
+
+HOW TO USE IVM
+--------------
+
+IVM is not that simple. See IVM.README for more details to how use it.
+

File pages/six.mkd

+six
+===
+
+six - simple IRC client kept simple (that's what the name means: sicks ->
+six). six is really tiny piece of software - only 200 SLOC.
+
+It's mainly inspired by [sic](http://tools.suckless.org/sic).
+
+install
+-------
+
+Get the sources and compile it. The only dependency is Readline.
+
+	hg clone https://bitbucket.org/zserge/six
+	cd six
+	make
+
+If you want to install it - copy `six` binary to your `/usr/local/bin`
+folder. I hope one day I will add a `make install` rule.
+
+usage
+-----
+
+In short, you can run it like:
+
+	six <host>
+
+For more automated usage you can specify your nickname, channel name,
+password (if you are not paranoid) or a custom startup script:
+
+	six -n john -k pa55w0rd -j "#johnchan" irc.server.net
+
+	six -s <commands> irc.server.net
+
+commands
+--------
+
+After your connected to the server and passed authorization step
+you can use these commands:
+
+* `:j channel` - join the channel
+* `:l channel` - leave the channel
+* `:m nick msg` - send message to the user `<nick>`
+* `s nick` - set default interlocutor to `<nick>`
+
+Here's a typical session:
+
+	:j #johnchan
+	hi all!       <-- everyone on #johnchan reads this
+	:m jack hi, jack  <-- only Jack reads this
+	:m jane hi, jane <-- only Jane reads this
+
+	:s jane       <-- now you are talking to Jane by default
+	i'm using six IRC client and it's the best! <-- Jane reads this
+	wnat to try it?                             <-- and this, too
+
+Another piece of sugar is autoreply. When someone send you a message
+and you press `<tab>` his nickname is written as a recepient of your next
+message:
+
+	<john> hi!
+	(here you press Tab)
+	> :m john _ <-- here's your cursor
+	
+See?
+
+bitlbee
+-------
+
+I also like using six with bitlbee. I start it like:
+
+	six -s "PRIVMSG root :IDENTIFY myPassw0rd" localhost
+
+And then I easily use my jabber in the terminal.
+
+screenshots
+-----------
+
+If your terminal looks nice - `six` also looks nice ;)
+
+Here's my six+urxvt+tmux
+
+![screenshot](six.png)
+<!DOCTYPE HTML> 
+<html lang=en>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+	<title>six - tiny IRC client</title>
+	<meta name="description" content="six - simple IRC client kept simple" />
+	<meta name="keywords" content="irc, simple, client, terminal" />
+
+	<link rel="stylesheet" href="style.css" type="text/css"/>
+	<script type="text/javascript">
+
+	var _gaq = _gaq || [];
+	_gaq.push(['_setAccount', 'UA-16690724-5']);
+	_gaq.push(['_trackPageview']);
+
+	(function() {
+	var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+	ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+	var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+</head>
+<body>
+<div id="container">
+	<div id="content">
+<h1>six</h1>
+
+<p>six - simple IRC client kept simple (that's what the name means: sicks ->
+six). six is really tiny piece of software - only 200 SLOC.</p>
+
+<p>It's mainly inspired by <a href="http://tools.suckless.org/sic">sic</a>.</p>
+
+<h2>install</h2>
+
+<p>Get the sources and compile it. The only dependency is Readline.</p>
+
+<pre><code>hg clone https://bitbucket.org/zserge/six
+cd six
+make
+</code></pre>
+
+<p>If you want to install it - copy <code>six</code> binary to your <code>/usr/local/bin</code>
+folder. I hope one day I will add a <code>make install</code> rule.</p>
+
+<h2>usage</h2>
+
+<p>In short, you can run it like:</p>
+
+<pre><code>six &lt;host&gt;
+</code></pre>
+
+<p>For more automated usage you can specify your nickname, channel name,
+password (if you are not paranoid) or a custom startup script:</p>
+
+<pre><code>six -n john -k pa55w0rd -j "#johnchan" irc.server.net
+
+six -s &lt;commands&gt; irc.server.net
+</code></pre>
+
+<h2>commands</h2>
+
+<p>After your connected to the server and passed authorization step
+you can use these commands:</p>
+
+<ul>
+<li><code>:j channel</code> - join the channel</li>
+<li><code>:l channel</code> - leave the channel</li>
+<li><code>:m nick msg</code> - send message to the user <code>&lt;nick&gt;</code></li>
+<li><code>s nick</code> - set default interlocutor to <code>&lt;nick&gt;</code></li>
+</ul>
+
+<p>Here's a typical session:</p>
+
+<pre><code>:j #johnchan
+hi all!       &lt;-- everyone on #johnchan reads this
+:m jack hi, jack  &lt;-- only Jack reads this
+:m jane hi, jane &lt;-- only Jane reads this
+
+:s jane       &lt;-- now you are talking to Jane by default
+i'm using six IRC client and it's the best! &lt;-- Jane reads this
+wnat to try it?                             &lt;-- and this, too
+</code></pre>
+
+<p>Another piece of sugar is autoreply. When someone send you a message
+and you press <code>&lt;tab&gt;</code> his nickname is written as a recepient of your next
+message:</p>
+
+<pre><code>&lt;john&gt; hi!
+(here you press Tab)
+&gt; :m john _ &lt;-- here's your cursor
+</code></pre>
+
+<p>See?</p>
+
+<h2>bitlbee</h2>
+
+<p>I also like using six with bitlbee. I start it like:</p>
+
+<pre><code>six -s "PRIVMSG root :IDENTIFY myPassw0rd" localhost
+</code></pre>
+
+<p>And then I easily use my jabber in the terminal.</p>
+
+<h2>screenshots</h2>
+
+<p>If your terminal looks nice - <code>six</code> also looks nice ;)</p>
+
+<p>Here's my six+urxvt+tmux</p>
+
+<p><img src="six.png" alt="screenshot" title="" /></p>
+	</div>
+</div>
+</body>
+</html>

File six.png

Added
New image