Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
<<importTiddlers>>
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<!--{{{-->
<div class='header' role='banner' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' role='navigation' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' role='navigation' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' role='complementary' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea' role='main'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected {color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0 3px 0 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0; padding-bottom:0;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='toolbar' role='navigation' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
''Use with extra care!''
|!|!Type|!Size (bits)|!Example|!Minimum Value|!Maximum Value|
||byte|8|byte b = 65;|-128|127|
||char([[*|Configurable 16 or 8 bit char type]])|16|char c = 'A'; char c = 65;|0|65535|
||short|16|short s = 65;|-32768|32767|
||int|16|int i = 65;|-32768|32767|
||long|16|long l = 65L;|-32768|32767|
||[[float|half precision float]]|16|float f = 65f;|-65504.0|65504.0|
||[[double|half precision double]]|16|double d = 65.55;|-65504.0|65504.0|
||boolean|8|boolean b = true;|>|true or false|
''Remark'' 
Nevertheless the reserved space on [[stack|Stack Layout]] for ''double'' and ''long'' is 2 * 16 Bit.
Recommended mode for 16 Bit micros.
|!|!Type|!Size (bits)|!Example|!Minimum Value|!Maximum Value|
||byte|8|byte b = 65;|-128|127|
||char([[*|Configurable 16 or 8 bit char type]])|16|char c = 'A'; char c = 65;|0|65535|
||short|16|short s = 65;|-32768|32767|
||int|16|int i = 65;|-32768|32767|
||long|32|long l = 65L;|-2147483648|2147483647|
||[[float|half precision float]]|16|float f = 65f;|-65504.0|65504.0|
||[[double|double 32]]|32|double d = 65.55;|>|+/- 1.4023x10^-45 to 3.4028x10^+38|
||boolean|8|boolean b = true;|>|true or false|
|!|!Type|!Size (bits)|!Example|!Minimum Value|!Maximum Value|
||byte|8|byte b = 65;|-128|127|
||char([[*|Configurable 16 or 8 bit char type]])|16|char c = 'A'; char c = 65;|0|65535|
||short|16|short s = 65;|-32768|32767|
||int|32|int i = 65;|-2147483648|2147483647|
||long|32|long l = 65L;|-2147483648|2147483647|
||float|32|float f = 65f;|>|+/- 1.4023x10^-45 to 3.4028x10^+38|
||[[double|double 32]]|32|double d = 65.55;|>|+/- 1.4023x10^-45 to 3.4028x10^+38|
||boolean|8|boolean b = true;|>|true or false|
''Remark'' 
Nevertheless the reserved space on [[stack|Stack Layout]] for ''double'' and ''long'' is 2 * 32 Bit.
|!|!Type|!Size (bits)|!Example|!Minimum Value|!Maximum Value|
||byte|8|byte b = 65;|-128|127|
||char([[*|Configurable 16 or 8 bit char type]])|16|char c = 'A'; char c = 65;|0|65535|
||short|16|short s = 65;|-32768|32767|
||int|32|int i = 65;|-2147483648|2147483647|
||long|64|long l = 65L;|-9223372036854775808|9223372036854775807|
||float|32|float f = 65f;|>|+/- 1.4023x10^-45 to 3.4028x10^+38|
||double|64|double d = 65.55;|>|+/- 4.9406x10^-324 to 1.7977x10^+308|
||boolean|8|boolean b = true;|>|true or false|

''Remark 1:'' 
~HaikuVM maps all primitive data types to corresponding C data types. For example JAVA type ''double'' is mapped to C type ''double''. This sounds obvious but may cause problems. ([[More ...|double and float support]])

''Remark 2:'' 
~HaikuVM makes extra effort to map the JAVA type ''long'' to a C type which has 64Bit precision. (Using C types 'long long' or 'int64_t' depending on the compiler).
During runtime the Haiku VM interpretes the JAVA byte code, stored in C data structures. ([[More ...|Compact HaikuVM Code]]) So ~HaikuVM will not (and is not designed to) load class files. ~HaikuVM is an ahead-of-time (AOT) compiler with a various degree of ahead-of-time compilation.

For the messured results given in this article I haikufied [[haikuvm.bench.Fibonacci.java|http://sourceforge.net/p/haiku-vm/code/HEAD/tree/trunk/haikuBench/src/main/java/haikuvm/bench/Fibonacci.java]] for a duemilanove, used in the test bed of [[nanovm.bench.BenchmarkPicker.java|http://sourceforge.net/p/haiku-vm/code/HEAD/tree/trunk/haikuBench/src/main/java/nanovm/bench/BenchmarkPicker.java]].

Until now ~HaikuVM supports this AOT degrees/options (see also option ''~AOTVariant'' in [[Command Line Options]]):

!~HAIKU_AOTBytecodeAsJump
See [[Token threading|https://en.wikipedia.org/wiki/Threaded_code#Token_threading]].
*Elapsed time: 4302 msec
*Program:    5298 bytes (16.2% Full)
*Data:       1723 bytes (84.1% Full)
!~HAIKU_AOTBytecodeAsSwitch
Use ~HaikuVM bytecodes and C-switch to the C code which implements a bytecode. See [[Bytecode|https://en.wikipedia.org/wiki/Bytecode]].
The GCC compiler does a very good job with the C-switch by using a jump table. (You may shut it off to see the difference: -fno-jump-tables.)
*Elapsed time: 4230 msec
*Program:    5294 bytes (16.2% Full)
*Data:       1723 bytes (84.1% Full)
!~HAIKU_AOTThreadedAsCall
Since ~HaikuVM 1.4.0. See [[Subroutine threading|https://en.wikipedia.org/wiki/Threaded_code#Subroutine_threading]].
*Elapsed time: 3912 msec
*Program:    6414 bytes (19.6% Full)
*Data:       1723 bytes (84.1% Full)
--Once I messured this:
*Elapsed time: 4497 msec
*Program:    5466 bytes (16.7% Full)
*Data:       1723 bytes (84.1% Full)
Or this:
*elapsed time: 4540 ms
*Program:    5832 bytes (17.8% Full)
*Data:       1721 bytes (84.0% Full)
I don't know what happened in the mean time?
--
!~HAIKU_AOTThreadedAsJump
Not implemented yet. See [[Direct threading|https://en.wikipedia.org/wiki/Threaded_code#Direct_threading]].
I have no idea how to solve this in C (without using assembler) because we have to have extern access to function-local (GCC) labels (for exceptionTable and functionTable) which can only be done via assembler (declare labels as global).

!~HAIKU_AOTCompiled
Not implemented yet. Will be a classic ahead of time compiler (here bytecodes into C++ code) instead interpreting bytecode during runtime (space vs. time).

!Meaning of the Directories
~HaikuVM comes with a set of directories as a conglomeration of multiple single-purpose projects. First ~HaikuVM consists of a couple of Java and C++ projects. Here I'll shed some light on the directories in haikuVM and what they are for:

''haikuVM''
*''bin''<br>For Windows and Linux commands (e.g. like haikulink) to be used with ~HaikuVM. ([[More ...|Commands]])
*''bootstrap''<br>A collection of ~MicroKernels and usefull microcontroller platform specific Java classes/libs. Often used (import) from the Java examples (see below).
*''config''<br>Central place for the configuration file '~HaikuVM.properties'. ([[More ...|HaikuVM.properties]])
*''examples''<br>Serves as a pool of example java files to be used as simple starter for your projects.
*''gallerie''<br>Short examples shared with the ~HaikuVM community. (Just send it via e-mail or use other ways.)
*''haikuBench''<br>Benchmarks and ~JUnits (mostly) for internal use.
*''haikufier''<br>Implementation of all the ~HaikuVM commands. This is the machine room of ~HaikuVM during compile and link time.
*''haikuRT''<br>This is the special ~HaikuVM runtime. The leJOS runtime is prefered but some core classes (like Thread, String, etc.) have to be tweeked/substituted for ~HaikuVM and ~AVRs and small RAM footprint. So haikuRT will precede classes.jar (see lib) in every classpath used with your project.
*''haikuVM''<br>C file templates used to be copied into your (empty) project directory to be cross compiled for your micro.  This is the machine room, the Java VM, of ~HaikuVM during runtime on the target micro itself.
*''hardware''<br>Service only for Windows users. Consists of WINAVR, AVRDUDE, AVR libs and include files. (Linux users have to install this separately, see [[here|Linux]].)
*''lib''
**jars<br>All this ~JAR-files needed for the commands in bin.
***classes.jar -> Java runtime as borrowed from the leJOS project.
***haikutools.jar -> Central place of all the ~HaikuVM commands as used in bin. Build from sources in haikufier.
***bcel-5.2.jar -> The BCEL project used in haikulink to disassemble class files.
**~C-LIBs and *.h include files<br>Made for the Tutorials about Duemilanove and Leonardo using JNI via ~C-LIBs.
*''myCProject''<br>A template directory for your project (and tutorials). Any other ''empty'' directory, elsewhere on your disk, will do as well. ([[More ...|Your Project on Disk and at Runtime]])
Here Arduino stands for Arduino Duemilanove because the Duemilanove is the reference system of ~HaikuVM. Other Arduino flavors work as well.

This is about how to program a Duemilanove in JAVA (not using the [[Arduino IDE]]) to let the LED blink. This could be done easy without an extra thread. But just for example and because I'm proud of ~HaikuVM having Threads, I show this blink solution using a thread.
<code java>
package arduino.tutorial;

import static haiku.avr.lib.arduino.WProgram.*;

public class BlinkWithThread extends Thread {
    static byte ledPin = 13;            // LED connected to digital pin 13

    public void run()                   // run over and over again
    {
        while (true) {
            digitalWrite(ledPin, HIGH); // sets the LED on
            delay(1000);                // waits for a second
            digitalWrite(ledPin, LOW);  // sets the LED off
            delay(1000);                // waits for a second
        }
    }

    public static void main(String[] args) {
        pinMode(ledPin, OUTPUT);        // sets the digital pin as output
        new BlinkWithThread().start();
    }
}
</code>

After you have installed all needed software (see GettingStarted) you can proceed with the following 2 steps to let the ~BlinkWithThread program run on your Duemilanove:
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config arduino -o BlinkWithThread.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread.java
</code>

*[[haiku]] first calls [[haikuc]] which calls javac to compile ''~BlinkWithThread.java'' into ''~BlinkWithThread.class'' (bytecode).
*[[haiku]] second calls [[haikulink]] which first translates the ''~BlinkWithThread.class'' into a ''C program'' and adds the Haiku VM (which is written also in C). Second it cross compiles and links all C sources into the file ''~BlinkWithThread.hex'' by calling 'make all' of WINAVR.
*[[haiku]] third calls [[haikuupload]] which finally uploads ''~BlinkWithThread.hex'' to the Arduino by calling avrdude.
Most of this steps are configurable in the file [[HaikuVM.properties]] or can be modified by giving other [[Command Line Options]]. For instance [[HaikuVM.properties]] assumes that your ARDUINO is connected on port com17. Change the following line of [[HaikuVM.properties]] to adapt to your configuration:
{{{
arduino.Port = com17
}}}
Or call [[haiku]] with a port name like this:
<code bash>
C:\haikuVM\bin\haiku -v --Config arduino --Config:Port com5 -o BlinkWithThread.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread.java
</code>

For those who are curious to see how any Arduino can be programmed with JAVA and the [[Arduino IDE]], follow this [[link|Processing]].



After you have installed all needed software (see GettingStarted) you can alternativly proceed with the following 4 steps to let the ~BlinkWithThread program run on your Arduino:
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haikuc                                               C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread.java
C:\haikuVM\bin\haikulink -v --Config arduino -o BlinkWithThread.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread 
C:\haikuVM\bin\haikuupload                      BlinkWithThread.hex
</code>

*[[haikuc]] calls javac to compile ''~BlinkWithThread.java'' into ''~BlinkWithThread.class'' (bytecode).
*[[haikulink]] first translates the ''~BlinkWithThread.class'' into a ''C program'' and adds the Haiku VM (which is written also in C). Second it cross compiles and links all C sources into the file ''~BlinkWithThread.hex'' by calling make of WINAVR.
*[[haikuupload]] finally uploads ''~BlinkWithThread.hex'' to the Arduino by calling avrdude.
Most of this steps are configurable in the file [[HaikuVM.properties]] or can be modified by giving other [[Command Line Options]]. For instance [[HaikuVM.properties]] assumes that your ARDUINO is connected on port com17. Change the following line of [[HaikuVM.properties]] to adapt to your configuration:
{{{
arduino.Port = com17
}}}


I assume that you already have 
#installed your Arduino IDE 1.0.5 into '''C:\arduino-1.0.5''' or Arduino IDE 1.6.4 into '''C:\arduino-1.6.4'''. (But don't panic. It's not limited to these named directories. In fact one is free to choose any directory to install Arduino IDE in. In what follows, it's just a convenient named reference for me.)
#tested your Arduino IDE installation by successfully compile and upload at least one native processing sketch example shipped with the Arduino IDE (e.g. Blink) to your Arduino (e.g. Leonardo).
#downloaded and unziped ~HaikuVM into '''C:\haikuVM'''.
#made sure that a Java JDK is in your ~PATH-variable. 

<<<
''WARNING 1:'' If you use ''Win 8'' and installed the Arduino IDE in ''C:\Program Files (x86)\Arduino\libraries'', make sure if you have write permission in this directory:
<code bash>
cd C:\Program Files (x86)\Arduino\libraries
echo hello >test.txt
</code>
<<<

Using ~HaikuVM with the Arduino IDE is done in two phases:
#First, use ~HaikuVM to compile your Java program ("abuseing" ~HaikuVM as a ''~Java-to-C'' compiler) into the Arduino ''library'' directory (see below). The library directory ~HaikuVM then will include the freshly made processing sketch corresponding to your Java program.
#Second, (re-)start the Arduino IDE and compile and upload the freshly generated processing sketch found in directory ~HaikuVM. Make sure you select your Arduino hardware (e.g. Leonardo).

For a first test, please pick a prepared Java program, called 'Blink', from the ~HaikuVM examples using the 'arduinoIDE' configuration like this:
<code bash>
cd C:\arduino-1.6.4\libraries
C:\haikuVM\bin\haiku -v --Config arduinoIDE C:\haikuVM\examples\src\main\java\processing\examples\_01_Basics\Blink.java
</code>

This will install a new Arduino library called '~HaikuVM' with an example called '~HaikuVM' as well. Now start your Arduino IDE, navigate to library '~HaikuVM' and start and upload example '~HaikuVM' to your Arduino hardware. You should see the Arduino LED blink.

[img[images/ArduinoIDE.png]]

From here you may proceed with other examples from 'C:\haikuVM\examples\src\main\java\processing\examples' like this:
<code bash>
C:\haikuVM\bin\haiku -v --Config arduinoIDE C:\haikuVM\examples\src\main\java\processing\examples\_08_Strings\StringLengthTrim.java
</code>
This will overwrite the contents of the former generated Arduino library '~HaikuVM' (and its example '~HaikuVM') to reflect the new ~StringLengthTrim content.

You can do even better. If your Arduino board is configured in the Arduino IDE, then there is no need to start your Arduino IDE by hand. Instead try the configurations ''arduinoIDEVerify'' or ''arduinoIDEUpload'' as you like ([[see also|Contributors]]):
<code bash>
cd C:\arduino-1.0.5\libraries  
 #then
C:\haikuVM\bin\haiku -v --Config arduinoIDEVerify C:\haikuVM\examples\src\main\java\processing\examples\_01_Basics\Blink.java
 #or
C:\haikuVM\bin\haiku -v --Config arduinoIDEUpload C:\haikuVM\examples\src\main\java\processing\examples\_01_Basics\Blink.java
</code>

<<<
''WARNING 2:'' When starting with the configurations given above, I sometimes get this exception from the Arduino IDE. I easily could ignore it.
<code bash>
Exception in thread "cc.arduino.packages.discoverers.serial.SerialBoardsLister" java.lang.NullPointerException
        at processing.app.Platform.resolveDeviceByVendorIdProductId(Platform.java:143)
        at processing.app.windows.Platform.resolveDeviceAttachedTo(Platform.java:301)
        at cc.arduino.packages.discoverers.serial.SerialBoardsLister.run(SerialBoardsLister.java:83)
        at java.util.TimerThread.mainLoop(Timer.java:555)
        at java.util.TimerThread.run(Timer.java:505)
</code>
<<<

After this, feel free to write your own Java programs, using the rich C++ libraries coming with the Arduino IDE. For those who want to learn more about seamless access of the rich C++ libraries coming with the Arduino IDE, I recommend reading the [[Tutorial JNI]].
This is how to program an Asuro (with an Atmega8) robot in JAVA (using the JAVA ported ~AsuroLib 2.8.0 rc1 [[which is originaly written in C|https://sourceforge.net/projects/asuro/]]).
<code java>
package asuro.tutorial;

import static haiku.avr.lib.asuro.lib2_8_0_rc1.AsuroLib2_8_0_rc1.*;

public class Blink {
    public static void main(String[] args) {
        Init(); // initialize the ASURO

        while (true) {
            StatusLED(GREEN);
            Msleep(1000);
            StatusLED(RED);
            Msleep(1000);
        }
    }
}
</code>

After you have installed all needed software (see GettingStarted) you can proceed with the following 5 steps to let the Blink program run on your ASURO:
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config asuro -o Blink.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\Blink.java 
</code>
([[See an alternativ approach.|Asuro Details]])

*[[haiku]] first calls [[haikuc]] which calls javac to compile ''Blink.java'' into ''Blink.class'' (bytecode).
*[[haiku]] second calls [[haikulink]] which first translates the ''Blink.class'' into a ''C program'' and adds the Haiku VM (which is written also in C). Second it cross compiles and links all C sources into the file ''Blink.hex'' by calling make of WINAVR.
*[[haiku]] third calls [[haikuupload]] which finally uploads ''Blink.hex'' to the ASURO by calling ~ASUROFlash155.
Most of this steps are configurable in the file [[HaikuVM.properties|HaikuVM.properties]] or can be modified by giving other [[command line options|Command Line Options]].  For instance [[HaikuVM.properties]] assumes that your ASURO code is uploaded with ~ASUROFlash155.exe (not shipped with ~HaikuVM). Change the following line of [[HaikuVM.properties]] to adapt to your configuration:
{{{
asuro.Upload = cmd /c start ASUROFlash155
}}}

If you curious to see how the blinking can be achieved by ''using threads'', take a look into './examples/src/main/java/asuro/tutorial/~BlinkWithThread.java' and/or proceed like this:
<code bash>
C:\haikuVM\bin\haiku -v --Config asuro -o BlinkWithThread.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread.java
</code>
After you have installed all needed software (see GettingStarted) you can alternativly proceed with the following 4 steps to let the Blink program run on your ASURO:
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haikuc                                   C:\haikuVM\examples\src\main\java\arduino\tutorial\Blink.java
C:\haikuVM\bin\haikulink -v --Config asuro -o Blink.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\Blink 
C:\haikuVM\bin\haikuupload                    Blink.hex
</code>

*[[haikuc]] calls javac to compile ''Blink.java'' into ''Blink.class'' (bytecode).
*[[haikulink]] first translates the ''Blink.class'' into a ''C program'' and adds the Haiku VM (which is written also in C). Second it cross compiles and links all C sources into the file ''Blink.hex'' by calling make of WINAVR.
*[[haikuupload]] finally uploads ''Blink.hex'' to the ASURO by calling ~ASUROFlash155.
Most of this steps are configurable in the file [[HaikuVM.properties|HaikuVM.properties]] or can be modified by giving other [[command line options|Command Line Options]].  For instance [[HaikuVM.properties]] assumes that your ASURO code is uploaded with ~ASUROFlash155.exe (not shipped with ~HaikuVM). Change the following line of [[HaikuVM.properties]] to adapt to your configuration:
{{{
asuro.Upload = cmd /c start ASUROFlash155
}}}

If you curious to see how the blinking can be achieved by ''using threads'', take a look into './examples/src/main/java/asuro/tutorial/~BlinkWithThread.java' and/or proceed like this:
<code bash>
C:\haikuVM\bin\haikuc                                             C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread.java
C:\haikuVM\bin\haikulink -v --Config asuro -o BlinkWithThread.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread
C:\haikuVM\bin\haikuupload                    BlinkWithThread.hex
</code>
The HaikuVM annotation ''~NativeCppMethod'' is tailor made for accessing C++ class methods. To be used in Java classes which are designed as a ''proxy'' to this C++ classes. If you follow this simple rules then things are easy:
#The java class, used as a proxy, must have the same name as the corresponding C++ class.
#The first field of your Java proxy must be of type Object ''and'' should be named 'realSubject', to be used as a pointer to the corresponding C++ object (the real subject).
#It is good practice to write a Java constructur to set this field.
#If a Java method is static then HaikuVM will generate the call to the corresponding static method of this C++ class.
#If a Java method is static and named like the Java class ''or'' has name 'cppConstructor' then HaikuVM will generate the corresponding C++ constructor call.
#If a Java method is virtuell then HaikuVM will generate the call to the corresponding C++ method.
As a result you may write this:
<code java>
package arduino.tutorial.beyondjni;

import haiku.vm.NativeCBody;
import haiku.vm.NativeCppMethod;

@NativeCBody(cImpl = 
	"class AccessCppTutorial {\n" +
	"public:\n" +
	"	static long s;\n" +
	"	static long getS();\n" +
	"	static void setS(long s);\n" +
	"\n" +
	"	int a;\n" +
	"\n" +
	"	AccessCppTutorial(int a);\n" +
	"\n" +
	"	int getA();\n" +
	"	void setA(int);\n" +
	"};\n" +
	"long AccessCppTutorial::s;\n" +
	"\n" +
	"AccessCppTutorial::AccessCppTutorial(int a) {\n" +
	"	this->a=a;\n" +
	"}\n" +
	"long AccessCppTutorial::getS() {\n" +
	"	return AccessCppTutorial::s;\n" +
	"}\n" +
	"void AccessCppTutorial::setS(long s) {\n" +
	"	AccessCppTutorial::s=s;\n" +
	"}\n" +
	"\n" +
	"int AccessCppTutorial::getA() {\n" +
	"	return a;\n" +
	"}\n" +
	"void AccessCppTutorial::setA(int a) {\n" +
	"	this->a=a;\n" +
	"}"
	)
public class AccessCppTutorial {
    private AccessCppTutorial realSubject;

    public AccessCppTutorial(int a) {
    	realSubject=AccessCppTutorial.AccessCppTutorial(a);
    }

	@NativeCppMethod
    private native static AccessCppTutorial AccessCppTutorial(int a);

	@NativeCppMethod
	public static native void setS(long s);
		
	@NativeCppMethod
	public static native long getS();

	@NativeCppMethod
	public native void setA(int a);
		
	@NativeCppMethod
	public native int getA();
}
</code>

To get this snippet in file 'nativeCFunction.cpp':

<code c++>
...
//////////////////Start of user code given per Java class by cImpl
class AccessCppTutorial {
public:
	static long s;
	static long getS();
	static void setS(long s);

	int a;

	AccessCppTutorial(int a);

	int getA();
	void setA(int);
};
long AccessCppTutorial::s;

AccessCppTutorial::AccessCppTutorial(int a) {
	this->a=a;
}
long AccessCppTutorial::getS() {
	return AccessCppTutorial::s;
}
void AccessCppTutorial::setS(long s) {
	AccessCppTutorial::s=s;
}

int AccessCppTutorial::getA() {
	return a;
}
void AccessCppTutorial::setA(int a) {
	this->a=a;
}
//////////////////End   of user code given per Java class by cImpl

...

JNIEXPORT jobject Java_arduino_tutorial_beyondjni_AccessCppTutorial_AccessCppTutorial
  (JNIEnv *env, jclass obj, jint arg1)
{
    return (jobject) new AccessCppTutorial(arg1);
}

...

JNIEXPORT void Java_arduino_tutorial_beyondjni_AccessCppTutorial_setS
  (JNIEnv *env, jclass obj, jlong arg1)
{
    AccessCppTutorial::setS(arg1);
}

...

JNIEXPORT jlong Java_arduino_tutorial_beyondjni_AccessCppTutorial_getS
  (JNIEnv *env, jclass obj)
{
    return AccessCppTutorial::getS();
}

...

JNIEXPORT void Java_arduino_tutorial_beyondjni_AccessCppTutorial_setA
  (JNIEnv *env, jobject obj, jint arg1)
{
    (*(AccessCppTutorial**) obj)->setA(arg1);
}

...

JNIEXPORT jint Java_arduino_tutorial_beyondjni_AccessCppTutorial_getA
  (JNIEnv *env, jobject obj)
{
    return (*(AccessCppTutorial**) obj)->getA();
}
...
</code>

~HaikuVM does an impressive amount of work for you, isn't it?
If you look back to tutorials [[JNI enhanced]] and [[JNI using functions from a C library using annotations]] you still may find that it's a lot of hustle to induce only a small portion of C code into your Java program. Can we do better? Is there a simple way to merge your non-boilerplate C code (or even Assembler code) into your Java program? The answer is yes! HaikuVM (since version 1.3.2) supports the annotation member ''cImpl''. Equiped with this feature and together what you have learned from the tutorial [[JNI using functions from a C library using annotations]] you may rewrite '~JNIenhanced.java' into '~JNIbeyond.java' like this:
<code java>
package arduino.tutorial;

import haiku.vm.NativeCBody;
import haiku.vm.NativeCppFunction;

@NativeCBody(cImpl = "static double result;")
public class JNIbeyond {

	@NativeCppFunction(cImpl = "result = arg1 + TF2FLOAT(arg2) + TD2DOUBLE(arg3);")
    private static native void add(int a, float b, double c);
		
	@NativeCppFunction(cImpl = "return DOUBLE2TD(result);")
    private static native double result();
    
    public static void main(String[] args) {
        int a=4;
        float b=5;
        double c=6;
        
        add(a, b, c);
        System.out.println(a+" + "+b+" + "+c+" = "+result());
    }
}
</code>

Now the automatic generated file './myCProject/haikuVM/utility/nativeCFunctions.cpp' looks like this:
<code cpp>
...
//////////////////Start of user code given per Java class by cImpl
static double result;
//////////////////End   of user code given per Java class by cImpl

/*
 * Class:     arduino/tutorial/JNIbeyond
 * Method:    add
 * Signature: (IFD)V
 */
JNIEXPORT void Java_arduino_tutorial_JNIbeyond_add
  (JNIEnv *env, jclass obj, jint arg1, jfloat arg2, jdouble arg3)
{
//////////////////Start of user code given by cImpl
result = arg1 + TF2FLOAT(arg2) + TD2DOUBLE(arg3);
//////////////////End   of user code given by cImpl
}

...

/*
 * Class:     arduino/tutorial/JNIbeyond
 * Method:    result
 * Signature: ()D
 */
JNIEXPORT jdouble Java_arduino_tutorial_JNIbeyond_result
  (JNIEnv *env, jclass obj)
{
//////////////////Start of user code given by cImpl
return DOUBLE2TD(result);
//////////////////End   of user code given by cImpl
}
...
</code>
Handy, isn't it?

In addition, if you take a look on an example given by Reinhard Pröll [[here|https://sourceforge.net/p/haiku-vm/code/HEAD/tree/trunk/gallerie/src/main/java/avr/gallerie/user/rp/arduino/sensor/]], you will find, that HaikuVM (since version 1.3.2) even ''handles your *.c, *.cpp and *.h files'' merged in your Java main file directory.
After you have installed all needed software (see GettingStarted) you are prepared to run the ''~BlinkSimple'' program on your AVR (e.g. ~ATmega328p).
<<tiddler avr.tutorial.BlinkSimple>>

You have to proceed with the following steps to prepare and let the ''~BlinkSimple'' program run on your AVR.
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku --Config duemilanove --Config:Port com7 C:\haikuVM\examples\src\main\java\avr\tutorial\BlinkSimple
</code>
This is what happens:
*[[haikuc]] calls javac to compile ''~BlinkSimple.java'' into ''~BlinkSimple.class'' (bytecode).
*[[haikulink]] first translates the ''~BlinkSimple.class'' into a ''C program'' and adds the Haiku VM (which is written also in C). Second it cross compiles and links all C sources into the file ''~BlinkSimple.hex'' by calling make of WINAVR.
*[[haikuupload]] finally uploads ''~BlinkSimple.hex'' to the AVR by calling avrdude.
Most of this steps are configurable in the file [[HaikuVM.properties|HaikuVM.properties]] or can be modified by giving other [[command line options|Command Line Options]].  For instance [[HaikuVM.properties]] assumes that your AVR code is uploaded with avrdude. Change the following line of [[HaikuVM.properties]] to adapt to your upload configuration:
{{{
duemilanove.Upload = ...
}}}

This code of ''~BlinkSimple.java'' uses a simple busy-wait delay loop to let the LED blink.

From here you might proceed with 'C:\haikuVM\examples\src\main\java\avr\tutorial\Blink.java'. Which uses Thread.sleep(..) for handling delays, which in turn relies on timer 0 overflow interrupt (resulting in non-busy-wait).
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
The tool [[haiku]] (and others) support the following command line options:
*"""--"""verbose | -v
*:verbose
*"""--"""classpath <javaclasspath>
*:extends the default classpath given by HaikuVM
*"""--"""Config:<propertyname> <value>
*:set a propertyname value
*"""--"""Config <config>
*:sets the main target configuration

!Option """--"""classpath  <javaclasspath>
The default classpath given by HaikuVM is:
:~HAIKU_HOME\haikuRT\src\main\java;~HAIKU_HOME\bootstrap\src\main\java;~HAIKU_HOME\examples\src\main\java;~HAIKU_HOME\haikuBench\src\main\java;~HAIKU_HOME\gallerie\src\main\java;~HAIKU_HOME\incubator\src\main\java
(For experts: This classpath as defined in './bin/makeclasses.mk')
<code bash>
mkdir \myPrograms
cd \myPrograms
C:\HaikuVM\bin\haiku --Config duemilanove --classpath C:\myWorkspace\src\main\java C:\myWorkspace\src\main\java\test\Hello.java
 # in WINDOWS surround a concatenated path with escaped "-characters 
C:\HaikuVM\bin\haiku --Config duemilanove --classpath \"F:\runtime-EclipseApplication\asdf\lib\myLib.jar;F:\runtime-EclipseApplication\asdf\bin;\" F:\runtime-EclipseApplication\asdf\src\asdf\trial.java
</code>

You may prepend to the default classpath with your <javaclasspath> given with this option.

!Option """--"""Config ...
This are typical configuration options you may want to set with the commandline option 
{{{--Config:<propertyname> <value>}}} 
or, as an alternative
{{{--Config:<propertyname>=<value>}}} 
where <propertyname> is one of this. Properties which have an abreviation are marked with *:
*Align
*~AOTVariant
*Char
*Clock
*Config*
*Extension
*GC
*~InitialMainThreadStackSize
*~InitialOtherThreadStackSize
*~MemorySize
*~MicroKernel
*Mode*
*~PanicExceptions
*~PanicSupport
*Port
*Target
*Threads
*~TimerInterrupt
Example:
{{{--Config:Char 2}}}
!!Align
If your hardware or C/C++ compiler only supports data or code alignment not equal to 1, then you may use this configuration parameter to adapt ~HaikuVM code generation to this needs. See [[Porting]].

Example:
{{{--Config:Align 2}}}
Technically, this example #define(s) a C/C++ preprocessor variable to 2:
{{{#define HAIKU_Align (2)}}}

!!~AOTVariant
*~HAIKU_AOTBytecodeAsJump
*~HAIKU_AOTBytecodeAsSwitch
*~HAIKU_AOTThreadedAsCall
!!Char
For configurable 16 or 8 bit char type. This will ''not'' affect the size of a basic char type when not stored in an array. This flag was invented only to reduce the size of char arrays. Possible values are [[More ...|Configurable 16 or 8 bit char type]]
*~HAIKU_CHAR_16 | ~HAIKU_CHAR_2 | 16 | 2<br>Characters in an array need 2 Bytes (for JAVA compliants)
*''~HAIKU_CHAR_8 | ~HAIKU_CHAR_1 | 8 | 1''<br>Characters in an array need 1 Byte (Default and most convenient for micros)
Example:
{{{--Config:Char 2}}}
!!Clock
Clock frequence of the microcontoller in Hz (e.g. use 16000000 for 16 ~MHz) to be used for the cross compiler.

Example:
{{{--Config:Clock 16000000}}}
!!Config
Because Config is frequently used it has an abreviation
{{{--Config:Config arduino}}}
is the same as
{{{--Config arduino}}}
To find possible values take a look into your [[HaikuVM.properties]] file.
!!Extension
Defines the file extension of the result of [[haikulink]] step. (Default is 'hex'.)
!!GC
To set the type of garbage collection [[More ...|Garbage collection]]
*~HAIKU_NoGC<br>No GC (no garbage collection at all)
*''~HAIKU_ConservativGC''<br>Stop the world GC (default)
*~HAIKU_IncrementalGC<br>Incremental GC (slices of work of the GC are done between interpretation of bytecodes)
*~HAIKU_CompactingGC<br>Stop the world compacting GC (experimental)
Example:
{{{--Config:GC HAIKU_ConservativGC}}}
!!~InitialMainThreadStackSize
In general ~HaikuVM allocates a [[stack frame|Stack Layout]] for each function called. This works perfect because JAVA knows the maximum stack size needed for each function in advance. One drawback is heap fragmentation. Another is wasted time to allocate all this tiny stack frames on heap. But, before allocating tiny stack frames on the heap ~HaikuVM uses the initial stack given for the main thread. The size of this stack is defined by property ~InitialMainThreadStackSize. To optimize speed and heap fragmentation you may size this initial stack segment to your needs. Default is a size of 145 ints (new int[~InitialMainThreadStackSize]).

Example:
{{{--Config:InitialMainThreadStackSize 300}}}
!!~InitialOtherThreadStackSize
Same as ~InitialMainThreadStackSize but for all other threads per thread.

Example:
{{{--Config:InitialMainThreadStackSize 50}}}
!!~MemorySize
Is the overall stack and heap size in bytes of RAM which ~HaikuVM may use. For ~AVRs default is '(RAMEND - 0x100) - 300'. So, 300 bytes are reserved for the internal use of the Haiku VM itself. [[More ...|Your Project on Disk and at Runtime]]

Example:
{{{--Config:MemorySize 1500}}}
''Warning:'' In ~HaikuVM ~MemorySize is restricted to be < 32768. (2^15).
!!~MicroKernel
To define your wanted [[MicroKernel|Tutorial All About MicroKernels]] class on commandline e.g.:
{{{--Config:MicroKernel haiku.avr.lib.simple010.HaikuMicroKernel}}} 
If you don't want to use a micro kernel:
{{{--Config:MicroKernel undef}}}
!!Mode
For configurable 64, 32 or 16 bit data types [[More ...|Configurable 64, 32 or 16 bit data types]]
*~HAIKU_32_64 | 32/64<br>for JAVA compliants
*~HAIKU_32_32 | 32/32
*''~HAIKU_16_32 | 16/32''<br>default and most convenient for micros
*~HAIKU_16_16 | 16/16
Because Mode is frequently used it has an abreviation
{{{--Config:Mode 16/32}}}
is the same as
{{{--Mode 16/32}}}
!!~PanicExceptions
The Haiku VM itself is written in C but, some data conditions are detected to be signaled as JAVA exceptions into your JAVA code. Here is a complete list of supported internal exceptions:
<<tiddler PanicExceptions>>If you want that some of this exceptions should be thrown into your JAVA they should be or-ed into ~PanicExceptions e.g. like this:
{{{--Config:PanicExceptions "NullPointerException|NoSuchMethodError|OutOfMemoryError|ClassCastException|InternalError|ArrayIndexOutOfBoundsException|StackOverflowError"}}}
[[More ...|Panic Support]]
!!~PanicSupport
Convenient flag to switch the list given with ~PanicExceptions on and off.
*''0'' no exceptions, given with ~PanicExceptions, are thrown internally.
*1 internal exceptions, given with ~PanicExceptions, are thrown.
{{{--Config:PanicSupport 1}}}
!!Port
Is the device Name for flashing your microcontroller. For example write {{{--Config:Port com5}}} to use port '~COM5:' in WINDOWS.
Write {{{--Config:Port /dev/ttyUSB0}}} to use port '/dev/ttyUSB0' in UNIX. 
Sometimes it doesn't make sense to specify a port at all, because your microcontroller has to be flashed with a special tool. E.g. the ASURO Robot has to be flashed with ~ASUROFlash155.
!!Target
Is the target code or architecture of your microcontroller to be used for the cross compiler.
{{{--Config:Target atmega328p}}}
!!Threads
~HaikuVM automatically detects if thread support is needed for your program. 
*0
*1
If you want to force thread support use:
{{{--Config:Threads 1}}}
!!~TimerInterrupt
On a microcontroller timer interrupts ([[More ...|Tutorial Interrupts]]) are used to support timing functions. [[More ...|Tutorial Timing]]
*''undef''<br>Default: no timer interrups are used.
*~TIMER0_OVF_vect<br>Default for most AVR configurations ([[More ...|HaikuVM.properties]]).
You may overwrite this on commandline like this:
{{{--Config:TimerInterrupt TIMER2_OVF_vect}}}
The ~HaikuVM tools are:
* [[haiku]]
* [[haikuc]]
* [[haikulink]]
* [[haikuupload]]

See also [[Command Line Options]].
----
<<<
Inspirations and initial sources are from the leJOS commands which can be found [[here|http://lejos.sourceforge.net/nxt/nxj/tutorial/Preliminaries/CompileAndRun.htm]].
This are the leJOS NXJ tools for compiling, linking and uploading of programs:
* nxj
* nxjc
* nxjlink
* nxjupload
<<<
If you take a look at the following JAVA code:
<code java>
package haikuvm.bench;

public class Fibonacci32Bit {
  static int fib(int n) {
    if(n < 2) 
      return 1;
    else
      return fib(n-2) + fib(n-1);
  } 

  public static void main(String[] args) {
	long t0 = System.currentTimeMillis();
    for(int i=0;i<=30;i++)
      System.out.println("Fibonacci of "+i+" is "+fib(i)+" in "+(System.currentTimeMillis()-t0)+" ms");
  }
}
</code>
Then javap says:
<code bash>
javap -c -classpath C:\haikuVM\haikuBench\bin haikuvm\bench\Fibonacci32Bit
</code>
That the bytecode in ~Fibonacci32Bit.class sums up to 97 bytes:
<code bash>
Compiled from "Fibonacci32Bit.java"
public class haikuvm.bench.Fibonacci32Bit extends java.lang.Object{
public haikuvm.bench.Fibonacci32Bit();
  Code:
   0:   aload_0
   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V
   4:   return

static int fib(int);
  Code:
   0:   iload_0
   1:   iconst_2
   2:   if_icmpge       7
   5:   iconst_1
   6:   ireturn
   7:   iload_0
   8:   iconst_2
   9:   isub
   10:  invokestatic    #16; //Method fib:(I)I
   13:  iload_0
   14:  iconst_1
   15:  isub
   16:  invokestatic    #16; //Method fib:(I)I
   19:  iadd
   20:  ireturn

public static void main(java.lang.String[]);
  Code:
   0:   invokestatic    #23; //Method java/lang/System.currentTimeMillis:()J
   3:   lstore_1
   4:   iconst_0
   5:   istore_3
   6:   goto    64
   9:   getstatic       #29; //Field java/lang/System.out:Ljava/io/PrintStream;
   12:  new     #33; //class java/lang/StringBuilder
   15:  dup
   16:  ldc     #35; //String Fibonacci of
   18:  invokespecial   #37; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
   21:  iload_3
   22:  invokevirtual   #40; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   25:  ldc     #44; //String  is
   27:  invokevirtual   #46; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   30:  iload_3
   31:  invokestatic    #16; //Method fib:(I)I
   34:  invokevirtual   #40; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   37:  ldc     #49; //String  in
   39:  invokevirtual   #46; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   42:  invokestatic    #23; //Method java/lang/System.currentTimeMillis:()J
   45:  lload_1
   46:  lsub
   47:  invokevirtual   #51; //Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
   50:  ldc     #54; //String  ms
   52:  invokevirtual   #46; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   55:  invokevirtual   #56; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   58:  invokevirtual   #60; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   61:  iinc    3, 1
   64:  iload_3
   65:  bipush  30
   67:  if_icmple       9
   70:  return
}
</code>

^^For those who are curious to know how this is coded in ~HaikuVM should take a look [[here|Compact HaikuVM Code]].^^

If you compare this with a corresponding C program:
<code c>
int32_t fib(int32_t n) {
	if(n < 2) 
	  return 1;
	else
	  return fib(n-2) + fib(n-1);
} 

int fib_main() {
	int32_t i;
	long t0 = millis();
	for(i=0;i<=30;i++) {
          printf("Fibonacci of %ld is %ld in %ld ms\n", i, fib(i), (long)(millis()-t0));
	}
	return 0;
}
</code>
Then a disassembly listing says:
<code bash>
000001e0 <fib>:
 1e0:	af 92       	push	r10
 1e2:	bf 92       	push	r11
 1e4:	cf 92       	push	r12
 1e6:	df 92       	push	r13
 1e8:	ef 92       	push	r14
 1ea:	ff 92       	push	r15
 1ec:	0f 93       	push	r16
 1ee:	1f 93       	push	r17
 1f0:	7b 01       	movw	r14, r22
 1f2:	8c 01       	movw	r16, r24
 1f4:	aa 24       	eor	r10, r10
 1f6:	bb 24       	eor	r11, r11
 1f8:	65 01       	movw	r12, r10
 1fa:	82 e0       	ldi	r24, 0x02	; 2
 1fc:	e8 16       	cp	r14, r24
 1fe:	f1 04       	cpc	r15, r1
 200:	01 05       	cpc	r16, r1
 202:	11 05       	cpc	r17, r1
 204:	b4 f0       	brlt	.+44     	; 0x232 <fib+0x52>
 206:	8e ef       	ldi	r24, 0xFE	; 254
 208:	9f ef       	ldi	r25, 0xFF	; 255
 20a:	af ef       	ldi	r26, 0xFF	; 255
 20c:	bf ef       	ldi	r27, 0xFF	; 255
 20e:	e8 0e       	add	r14, r24
 210:	f9 1e       	adc	r15, r25
 212:	0a 1f       	adc	r16, r26
 214:	1b 1f       	adc	r17, r27
 216:	c8 01       	movw	r24, r16
 218:	b7 01       	movw	r22, r14
 21a:	0e 94 f0 00 	call	0x1e0	; 0x1e0 <fib>
 21e:	08 94       	sec
 220:	e1 1c       	adc	r14, r1
 222:	f1 1c       	adc	r15, r1
 224:	01 1d       	adc	r16, r1
 226:	11 1d       	adc	r17, r1
 228:	a6 0e       	add	r10, r22
 22a:	b7 1e       	adc	r11, r23
 22c:	c8 1e       	adc	r12, r24
 22e:	d9 1e       	adc	r13, r25
 230:	e4 cf       	rjmp	.-56     	; 0x1fa <fib+0x1a>
 232:	a6 01       	movw	r20, r12
 234:	95 01       	movw	r18, r10
 236:	2f 5f       	subi	r18, 0xFF	; 255
 238:	3f 4f       	sbci	r19, 0xFF	; 255
 23a:	4f 4f       	sbci	r20, 0xFF	; 255
 23c:	5f 4f       	sbci	r21, 0xFF	; 255
 23e:	b9 01       	movw	r22, r18
 240:	ca 01       	movw	r24, r20
 242:	1f 91       	pop	r17
 244:	0f 91       	pop	r16
 246:	ff 90       	pop	r15
 248:	ef 90       	pop	r14
 24a:	df 90       	pop	r13
 24c:	cf 90       	pop	r12
 24e:	bf 90       	pop	r11
 250:	af 90       	pop	r10
 252:	08 95       	ret

...

000002d0 <fib_main>:
 2d0:	2f 92       	push	r2
 2d2:	3f 92       	push	r3
 2d4:	4f 92       	push	r4
 2d6:	5f 92       	push	r5
 2d8:	6f 92       	push	r6
 2da:	7f 92       	push	r7
 2dc:	8f 92       	push	r8
 2de:	9f 92       	push	r9
 2e0:	af 92       	push	r10
 2e2:	bf 92       	push	r11
 2e4:	cf 92       	push	r12
 2e6:	df 92       	push	r13
 2e8:	ef 92       	push	r14
 2ea:	ff 92       	push	r15
 2ec:	0f 93       	push	r16
 2ee:	1f 93       	push	r17
 2f0:	cf 93       	push	r28
 2f2:	df 93       	push	r29
 2f4:	0e 94 b0 00 	call	0x160	; 0x160 <millis>
 2f8:	1b 01       	movw	r2, r22
 2fa:	2c 01       	movw	r4, r24
 2fc:	ee 24       	eor	r14, r14
 2fe:	ff 24       	eor	r15, r15
 300:	87 01       	movw	r16, r14
 302:	66 24       	eor	r6, r6
 304:	77 24       	eor	r7, r7
 306:	43 01       	movw	r8, r6
 308:	c0 e0       	ldi	r28, 0x00	; 0
 30a:	d1 e0       	ldi	r29, 0x01	; 1
 30c:	5c c0       	rjmp	.+184    	; 0x3c6 <fib_main+0xf6>
 30e:	22 e0       	ldi	r18, 0x02	; 2
 310:	e2 16       	cp	r14, r18
 312:	f1 04       	cpc	r15, r1
 314:	01 05       	cpc	r16, r1
 316:	11 05       	cpc	r17, r1
 318:	b4 f0       	brlt	.+44     	; 0x346 <fib_main+0x76>
 31a:	8e ef       	ldi	r24, 0xFE	; 254
 31c:	9f ef       	ldi	r25, 0xFF	; 255
 31e:	af ef       	ldi	r26, 0xFF	; 255
 320:	bf ef       	ldi	r27, 0xFF	; 255
 322:	e8 0e       	add	r14, r24
 324:	f9 1e       	adc	r15, r25
 326:	0a 1f       	adc	r16, r26
 328:	1b 1f       	adc	r17, r27
 32a:	c8 01       	movw	r24, r16
 32c:	b7 01       	movw	r22, r14
 32e:	0e 94 f0 00 	call	0x1e0	; 0x1e0 <fib>
 332:	08 94       	sec
 334:	e1 1c       	adc	r14, r1
 336:	f1 1c       	adc	r15, r1
 338:	01 1d       	adc	r16, r1
 33a:	11 1d       	adc	r17, r1
 33c:	a6 0e       	add	r10, r22
 33e:	b7 1e       	adc	r11, r23
 340:	c8 1e       	adc	r12, r24
 342:	d9 1e       	adc	r13, r25
 344:	e4 cf       	rjmp	.-56     	; 0x30e <fib_main+0x3e>
 346:	0e 94 b0 00 	call	0x160	; 0x160 <millis>
 34a:	ad b7       	in	r26, 0x3d	; 61
 34c:	be b7       	in	r27, 0x3e	; 62
 34e:	1e 97       	sbiw	r26, 0x0e	; 14
 350:	0f b6       	in	r0, 0x3f	; 63
 352:	f8 94       	cli
 354:	be bf       	out	0x3e, r27	; 62
 356:	0f be       	out	0x3f, r0	; 63
 358:	ad bf       	out	0x3d, r26	; 61
 35a:	ed b7       	in	r30, 0x3d	; 61
 35c:	fe b7       	in	r31, 0x3e	; 62
 35e:	31 96       	adiw	r30, 0x01	; 1
 360:	12 96       	adiw	r26, 0x02	; 2
 362:	dc 93       	st	X, r29
 364:	ce 93       	st	-X, r28
 366:	11 97       	sbiw	r26, 0x01	; 1
 368:	62 82       	std	Z+2, r6	; 0x02
 36a:	73 82       	std	Z+3, r7	; 0x03
 36c:	84 82       	std	Z+4, r8	; 0x04
 36e:	95 82       	std	Z+5, r9	; 0x05
 370:	08 94       	sec
 372:	a1 1c       	adc	r10, r1
 374:	b1 1c       	adc	r11, r1
 376:	c1 1c       	adc	r12, r1
 378:	d1 1c       	adc	r13, r1
 37a:	a6 82       	std	Z+6, r10	; 0x06
 37c:	b7 82       	std	Z+7, r11	; 0x07
 37e:	c0 86       	std	Z+8, r12	; 0x08
 380:	d1 86       	std	Z+9, r13	; 0x09
 382:	62 19       	sub	r22, r2
 384:	73 09       	sbc	r23, r3
 386:	84 09       	sbc	r24, r4
 388:	95 09       	sbc	r25, r5
 38a:	62 87       	std	Z+10, r22	; 0x0a
 38c:	73 87       	std	Z+11, r23	; 0x0b
 38e:	84 87       	std	Z+12, r24	; 0x0c
 390:	95 87       	std	Z+13, r25	; 0x0d
 392:	0e 94 2a 01 	call	0x254	; 0x254 <jprintf>
 396:	84 01       	movw	r16, r8
 398:	73 01       	movw	r14, r6
 39a:	08 94       	sec
 39c:	e1 1c       	adc	r14, r1
 39e:	f1 1c       	adc	r15, r1
 3a0:	01 1d       	adc	r16, r1
 3a2:	11 1d       	adc	r17, r1
 3a4:	2d b7       	in	r18, 0x3d	; 61
 3a6:	3e b7       	in	r19, 0x3e	; 62
 3a8:	22 5f       	subi	r18, 0xF2	; 242
 3aa:	3f 4f       	sbci	r19, 0xFF	; 255
 3ac:	0f b6       	in	r0, 0x3f	; 63
 3ae:	f8 94       	cli
 3b0:	3e bf       	out	0x3e, r19	; 62
 3b2:	0f be       	out	0x3f, r0	; 63
 3b4:	2d bf       	out	0x3d, r18	; 61
 3b6:	3f e1       	ldi	r19, 0x1F	; 31
 3b8:	e3 16       	cp	r14, r19
 3ba:	f1 04       	cpc	r15, r1
 3bc:	01 05       	cpc	r16, r1
 3be:	11 05       	cpc	r17, r1
 3c0:	31 f0       	breq	.+12     	; 0x3ce <fib_main+0xfe>
 3c2:	37 01       	movw	r6, r14
 3c4:	48 01       	movw	r8, r16
 3c6:	aa 24       	eor	r10, r10
 3c8:	bb 24       	eor	r11, r11
 3ca:	65 01       	movw	r12, r10
 3cc:	a0 cf       	rjmp	.-192    	; 0x30e <fib_main+0x3e>
 3ce:	df 91       	pop	r29
 3d0:	cf 91       	pop	r28
 3d2:	1f 91       	pop	r17
 3d4:	0f 91       	pop	r16
 3d6:	ff 90       	pop	r15
 3d8:	ef 90       	pop	r14
 3da:	df 90       	pop	r13
 3dc:	cf 90       	pop	r12
 3de:	bf 90       	pop	r11
 3e0:	af 90       	pop	r10
 3e2:	9f 90       	pop	r9
 3e4:	8f 90       	pop	r8
 3e6:	7f 90       	pop	r7
 3e8:	6f 90       	pop	r6
 3ea:	5f 90       	pop	r5
 3ec:	4f 90       	pop	r4
 3ee:	3f 90       	pop	r3
 3f0:	2f 90       	pop	r2
 3f2:	08 95       	ret
</code>
that the binary size for only this two functions (not including library code) sums up to 407 bytes for an AVR ~ATmega328p.

Conclusion: This ~HaikuVM program is ''about 4 times more compact'' than a plain C program (without counting library overhead). 
Given, for example, the following JAVA code:
<code java>
package haikuvm.bench;

public class Fibonacci32Bit {
  static int fib(int n) {
    if(n < 2) 
      return 1;
    else
      return fib(n-2) + fib(n-1);
  } 

  public static void main(String[] args) {
	long t0 = System.currentTimeMillis();
    for(int i=0;i<=30;i++)
      System.out.println("Fibonacci of "+i+" is "+fib(i)+" in "+(System.currentTimeMillis()-t0)+" ms");
  }
}
</code>

Then [[haikulink]] transformes the resulting bytecode into initialized plain C structs like this:
<code c>
/**
static int fib(int n)
Code(max_stack = 3, max_locals = 1, code_length = 21)
*/
const           haikuvm_bench_Fibonacci32Bit_fib_II_t haikuvm_bench_Fibonacci32Bit_fib_II PROGMEM ={
3+1 +2,    0,    1,    // max_stack, purLocals, purParams

OP_ILOAD_0,                                                            // 0:    iload_0
OP_ICONST_2,                                                           // 1:    iconst_2
OP_IF_ICMPGE,        TARGET(7),                                        // 2:    if_icmpge		#7
OP_ICONST_1,                                                           // 5:    iconst_1
OP_IRETURN,                                                            // 6:    ireturn
OP_ILOAD_0,                                                            // 7:    iload_0
OP_ICONST_2,                                                           // 8:    iconst_2
OP_ISUB,                                                               // 9:    isub
OP_INVOKESHORT_haikuvm_bench_Fibonacci32Bit_fib_II,                    // 10:   invokestatic	haikuvm.bench.Fibonacci32Bit.fib (I)I (16)
OP_ILOAD_0,                                                            // 13:   iload_0
OP_ICONST_1,                                                           // 14:   iconst_1
OP_ISUB,                                                               // 15:   isub
OP_INVOKESHORT_haikuvm_bench_Fibonacci32Bit_fib_II,                    // 16:   invokestatic	haikuvm.bench.Fibonacci32Bit.fib (I)I (16)
OP_IADD,                                                               // 19:   iadd
OP_IRETURN,                                                            // 20:   ireturn
};

/**
public static void main(String[] args)
Code(max_stack = 6, max_locals = 4, code_length = 71)
*/
const           haikuvm_bench_Fibonacci32Bit_main_YLjava_lang_String_V_t haikuvm_bench_Fibonacci32Bit_main_YLjava_lang_String_V PROGMEM ={
6+4 +2,    3,    1,    // max_stack, purLocals, purParams

OP_INVOKESHORT_java_lang_System_currentTimeMillis_J,                   // 0:    invokestatic	java.lang.System.currentTimeMillis ()J (23)
OP_LSTORE_1,                                                           // 3:    lstore_1
OP_ICONST_0,                                                           // 4:    iconst_0
OP_ISTORE_3,                                                           // 5:    istore_3
OP_GOTO,             TARGET(64),                                       // 6:    goto		#64
OP_GETSTATIC_L,      SADR(java_lang_System_out),                       // 9:    getstatic		java.lang.System.out Ljava/io/PrintStream; (29)
OP_NEW,              ADR(java_lang_StringBuilder__class),              // 12:   new		<java.lang.StringBuilder> (33)
OP_DUP,                                                                // 15:   dup
OP_LDC_S,            CADR(Const0005),                                  // 16:   ldc		"Fibonacci of " (35)
OP_INVOKESHORT_java_lang_StringBuilder__init__Ljava_lang_String_V,     // 18:   invokespecial	java.lang.StringBuilder.<init> (Ljava/lang/String;)V (37)
OP_ILOAD_3,                                                            // 21:   iload_3
OP_INVOKEVIRTUAL,    B(1), LB(MSG_append__I_Ljava_lang_StringBuilder), 
                                                                       // 22:   invokevirtual	java.lang.StringBuilder.append (I)Ljava/lang/StringBuilder; (40)
OP_LDC_S,            CADR(Const0006),                                  // 25:   ldc		" is " (44)
OP_INVOKEVIRTUAL,    B(1), LB(MSG_append__Ljava_lang_String__Ljava_lang_StringBuilder), 
                                                                       // 27:   invokevirtual	java.lang.StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; (46)
OP_ILOAD_3,                                                            // 30:   iload_3
OP_INVOKESHORT_haikuvm_bench_Fibonacci32Bit_fib_II,                    // 31:   invokestatic	haikuvm.bench.Fibonacci32Bit.fib (I)I (16)
OP_INVOKEVIRTUAL,    B(1), LB(MSG_append__I_Ljava_lang_StringBuilder), 
                                                                       // 34:   invokevirtual	java.lang.StringBuilder.append (I)Ljava/lang/StringBuilder; (40)
OP_LDC_S,            CADR(Const0007),                                  // 37:   ldc		" in " (49)
OP_INVOKEVIRTUAL,    B(1), LB(MSG_append__Ljava_lang_String__Ljava_lang_StringBuilder), 
                                                                       // 39:   invokevirtual	java.lang.StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; (46)
OP_INVOKESHORT_java_lang_System_currentTimeMillis_J,                   // 42:   invokestatic	java.lang.System.currentTimeMillis ()J (23)
OP_LLOAD_1,                                                            // 45:   lload_1
OP_LSUB,                                                               // 46:   lsub
OP_INVOKEVIRTUAL,    B(2), LB(MSG_append__J_Ljava_lang_StringBuilder), 
                                                                       // 47:   invokevirtual	java.lang.StringBuilder.append (J)Ljava/lang/StringBuilder; (51)
OP_LDC_S,            CADR(Const0008),                                  // 50:   ldc		" ms" (54)
OP_INVOKEVIRTUAL,    B(1), LB(MSG_append__Ljava_lang_String__Ljava_lang_StringBuilder), 
                                                                       // 52:   invokevirtual	java.lang.StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; (46)
OP_INVOKEVIRTUAL,    B(0), LB(MSG_toString___Ljava_lang_String),       // 55:   invokevirtual	java.lang.StringBuilder.toString ()Ljava/lang/String; (56)
OP_INVOKEVIRTUAL,    B(1), LB(MSG_println__Ljava_lang_String__V),      // 58:   invokevirtual	java.io.PrintStream.println (Ljava/lang/String;)V (60)
OP_IINC1, B(3),                                                        // 61:   iinc		%3	1
OP_ILOAD_3,                                                            // 64:   iload_3
OP_BIPUSH,           B(30),                                            // 65:   bipush		30
OP_IF_ICMPLE,        TARGET(9),                                        // 67:   if_icmple		#9
OP_RETURN,                                                             // 70:   return
};

const class_t haikuvm_bench_Fibonacci32Bit__class PROGMEM = {
	& java_lang_Object__class,
	sizeof(haikuvm_bench_Fibonacci32Bit),
	0,
};
</code>
~HaikuVM supports two char type sizes for char arrays (arrays only):
*~HAIKU_CHAR_16  (for JAVA compliants)
*~HAIKU_CHAR_8 (default and most convenient for ~AVRs)
The used char type size for arrays can be configured in the [[HaikuVM.properties]] file or as [[command line option|Command Line Options]].
This will ''not'' affect the size of a basic char type when not stored in an array. This flag was invented only to reduce the size of char arrays.
~HaikuVM supports four memory modes:
#[[32/64 (for JAVA compliants)]]
#[[32/32]]
#[[16/32 (default and most convenient for micros)]]
#[[16/16]]

|!Overview|>|>|>|>|>|>|
|!Type|!32/64|!32/32|!16/32|!16/16|
|byte| 8 |>|>|>|
|char([[*|Configurable 16 or 8 bit char type]])| 16 |>|>|>|
|short| 16 |>|>|>|
|int|32|32|16|16|
|long|64|32|32|16|
|float|32|32|16|16|
|double|64|32|32|16|
|boolean| 8 |>|>|>|>|

The used memory mode can be configured in the [[HaikuVM.properties]] file or as [[command line option|Command Line Options]].
[img[images/email.png]]

You will find forum/discussion threads [[here|http://sourceforge.net/p/haiku-vm/discussion/]].

Please report bugs [[here|http://sourceforge.net/p/haiku-vm/tickets/]].


In papers and reports, please refer to ~HaikuVM as follows:
''Genom Bob. ~HaikuVM: a small JAVA VM for microcontrollers. http://haiku-vm.sourceforge.net/''
e.g. using the following ~BibTeX code:
{{{
@MISC{~HaikuVM,
        author = {Genom Bob},
        title = {~HaikuVM: a small JAVA VM for microcontrollers},
        howpublished = "\url{http://haiku-vm.sourceforge.net/}"
}
}}}
!Donors
Be the first who donate. I'm looking forward to get hardware to port ~HaikuVM on.

!Contributors
I wish to thank all the people that directly or indirectly contributed to the project:
*''Reinhard Pröll'', contributed:
** a way to insert C code into your Java source files. ([[More ...|Beyond JNI: put C code into your java files]])
** a new configuration entry ''arduinoIDEVerify'' in [[HaikuVM.properties]] to verify your project by using the [[Arduino IDE]] tools.
** a new configuration entry ''arduinoIDEUpload'' in [[HaikuVM.properties]] to verify, compile and upload your project by using the [[Arduino IDE]] tools.
*''Carl van Denzen'', worked on the leonardo port.
*''Alan'', worked on the gertboard port.

!Thanks
* [[leJOS|http://en.wikipedia.org/wiki/LeJOS]] for the java class runtime library HaikuVM tooks advantage of.
* [[BCEL|https://commons.apache.org/proper/commons-bcel/]] the Byte Code Engineering Library (Apache Commons BCELâ„¢) to convert java class files into C code.
* [[Fizzed|http://fizzed.com/oss/rxtx-for-java]] for 64Bit RXTX for Java. (before HaikuVM 1.3.2)
* [[jSSC |https://code.google.com/p/java-simple-serial-connector/]] for the library for working with serial ports from Java. (since HaikuVM 1.3.2)
[[What is it?]]
[[Release Notes]]
<<tiddler [[Arduino]]>>
!Installing ~ESP8266 Platform in Arduino IDE 1.8.1
To install the ~ESP8266 Platform in Arduino IDE, I followed the advices of this link: 
https://create.arduino.cc/projecthub/ROBINTHOMAS/programming-esp8266-esp-01-with-arduino-011389

Then I wired the ~ESP01 like this with my UNO (Many people say that this is risky because the data lines of the ~ESP01 are not 5V tolerant, but I had luck):
{{{
logical wiring schematic for programming
ESP 8266   ---------- UNO    
VCC, CH_PD ---------- 3.3V
GND, GPIO2 ---------- GND
TX         ---------- TX(#1)
RX         ---------- RX(#0) 
RESET      ---------- start ESP then connect to GND then release (or connect to VCC)
}}}

As a first check I selected and uploaded Blink.ino to let the blue build-in LED of the esp8266 blink:
Arduino 1.8.1 IDE -> Files -> Examples -> ~ESP8266 -> Blink 
Success!

!Configuration
See file [[HaikuVM.properties]]:
{{{
Align = 4
Mode = 32/32
AOTVariant = HAIKU_AOTBytecodeAsJump
MemorySize = 5000
}}}

!First try with ~HaikuVM Version 1.4.2
The program is located at '.\haikuBench\src\main\java\haikuvm\bench\~Fibonacci32Bit.java'. See also [[Performance]].
The program was haikufied as follows:
<code bash>
cd C:\Arduino-1.8.1\libraries
C:\haikuVM\bin\haiku -v --Config esp8266-arduinoIDEWithMainUsingSystemUpload "C:\Users\Genom\Development\haikuVM\haikuBench\src\main\java\haikuvm\bench\Fibonacci32Bit.java"
</code>

Then I ''re-''started the Arduino 1.8.1 IDE to compile, link und upload as follows:
Arduino 1.8.1 IDE -> Files -> Examples -> ~HaikuVM -> ~ArduinoSketch -> ~HaikuVM
After some garbage characters I got this result:

!Performance ~HaikuVM
<code bash>
...
Fibonacci of 0 is 1 in 3 ms
Fibonacci of 1 is 1 in 9 ms
Fibonacci of 2 is 2 in 15 ms
Fibonacci of 3 is 3 in 23 ms
Fibonacci of 4 is 5 in 30 ms
Fibonacci of 5 is 8 in 39 ms
Fibonacci of 6 is 13 in 47 ms
Fibonacci of 7 is 21 in 56 ms
Fibonacci of 8 is 34 in 68 ms
Fibonacci of 9 is 55 in 84 ms
Fibonacci of 10 is 89 in 102 ms
Fibonacci of 11 is 144 in 122 ms
Fibonacci of 12 is 233 in 140 ms
Fibonacci of 13 is 377 in 161 ms
Fibonacci of 14 is 610 in 185 ms
Fibonacci of 15 is 987 in 217 ms
Fibonacci of 16 is 1597 in 260 ms
Fibonacci of 17 is 2584 in 327 ms
Fibonacci of 18 is 4181 in 426 ms
Fibonacci of 19 is 6765 in 579 ms
Fibonacci of 20 is 10946 in 823 ms
Fibonacci of 21 is 17711 in 1205 ms
Fibonacci of 22 is 28657 in 1819 ms
Fibonacci of 23 is 46368 in 2804 ms
Fibonacci of 24 is 75025 in 4390 ms
Fibonacci of 25 is 121393 in 6952 ms
Fibonacci of 26 is 196418 in 11085 ms
Fibonacci of 27 is 317811 in 17763 ms
Fibonacci of 28 is 514229 in 28557 ms
Fibonacci of 29 is 832040 in 46016 ms
Fibonacci of 30 is 1346269 in 74255 ms

Soft WDT reset

ctx: cont 
sp: 3ffefaa0 end: 3ffefce0 offset: 01b0
...
</code>

!Performance C/C++
This is the competing C program for fib(30) in the Arduino IDE for ~ESP01:
<code c>
int32_t fib(int32_t n) {  
    if(n < 2)   
      return 1;  
    else  
      return fib(n-2) + fib(n-1);  
}   
  
int main() {  
    int32_t i;  
    long t0 = millis();  
    for(i=0;i<=30;i++) {  
          Serial.print("Fibonacci of ");
          Serial.print(i); 
          Serial.print(" is ");
          Serial.print(fib(i)); 
          Serial.print(" in ");
          Serial.print((long)(millis()-t0));  
          Serial.println(" ms");
    }  
    return 0;  
}  

void setup() {
  Serial.begin(57600);
    while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

}

void loop() {
  main();
  delay(1000);
}
</code>
Which needs only ''1277 ms''.

Conclusion: This (specific) plain C/C++ program is ''58.4 times faster'' than the corresponding JAVA program running with ~HaikuVM.


!Some interesting links
https://espressif.com/en/support/download/documents
http://www.esp8266.com/wiki/doku.php
http://hackaday.com/2015/03/18/how-to-directly-program-an-inexpensive-esp8266-wifi-module/
http://esp8266.github.io/Arduino/versions/2.3.0/doc/ota_updates/readme.html#update-process---memory-view
Some AT Commands: https://forum.arduino.cc/index.php?topic=283043.30

!Step 1 - Import from subversion repository at sourceforge 
"Import ..." 
-> "SVN" 
-> "Checkout Projects from SVN" 
-> "Create a new repository location" 
-> "Next" 
-> """URL=svn://svn.code.sf.net/p/haiku-vm/code/tags/HaikuVM-1.2.4"""
-> "Next"
-> select all subfolders from "bin" to "myProject"
-> "Finish"

After this step your eclipse IDE should show something like this:

[img[images/eclipse_step1.png]]

!Step 2 - Setup 'haiku' as external tool
Configure 'haiku.bat' (if on Windows) or 'haiku' (if on Linux) as external tool like this:

[img[images/eclipse_step2.png]]
-v ${file_prompt: a java file}

<<tiddler chmod>>
!Step 3 - Run external tool 'haiku'
When prompted pick a ~JAVA-file (for example 'Blink.java') in:
./haikuVM/examples/src/main/java/arduino/tutorial/Blink.java

!Use your own workspace
If you want to develop in your own workspace (lets say 'C:\myExamples') you have to use the ''"""--"""classpath'' option of the command [[haiku]] like this:
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku --Config duemilanove --Config:Port com5 --classpath C:\myWorkspace\src\main\java C:\myWorkspace\src\main\java\test\Hello.java
</code>
!Getting started with a Leonardo or Micro (or Duemilanove) using the Arduino IDE
Start with the following JAVA program (see [[Tutorials]]).
<code java>
package processing.examples._01_Basics;
import static processing.hardware.arduino.cores.arduino.Arduino.*;
public class Blink {
    static byte ledPin = 13;            // LED connected to digital pin 13

    public static void loop()           // run over and over again
    {
        digitalWrite(ledPin, HIGH);     // sets the LED on
        delay(1000);                    // waits for a second
        digitalWrite(ledPin, LOW);      // sets the LED off
        delay(1000);                    // waits for a second
    }

    public static void setup() {
        pinMode(ledPin, OUTPUT);        // sets the digital pin as output
    }
}
</code>
Haikufy your JAVA Program into your [[Arduino IDE]] like this:
<code bash>
cd C:\arduino-1.0.5\libraries
C:\haikuVM\bin\haiku -v --Config arduinoIDE C:\haikuVM\examples\src\main\java\processing\examples\_01_Basics\Blink.java
</code>
And upload it to your Leonardo with your [[Arduino IDE]]. ([[More...|Processing]])
Type the text for 'Exceptions'
''Q: What to do if I have error: "Exception in thread "main" java.lang.~UnsupportedClassVersionError: haikuvm/pc/tools/~HaikuVM : Unsupported major.minor version 52.0"''
''A:'' Haikuvm needs at least Java version 1.8.0. Please use the proper Java version and set ~LEJOS_NXT_JAVA_HOME to this Java path.
<code bash>
set LEJOS_NXT_JAVA_HOME=C:\Program Files\Java\jdk1.8.0
</code>

''Q: Is it possible to use my own project or workspace with ~HaikuVM?''
''A:'' Yes. If you haikufy don't forget to set the classpath to your project like this  ([[More ...|haiku]]):
<code bash>
mkdir \myPrograms
cd \myPrograms
C:\HaikuVM\bin\haiku --Config duemilanove --classpath C:\myWorkspace\src\main\java C:\myWorkspace\src\main\java\test\Hello.java
</code>

''Q: Do I need the Arduino Uno Firmware on my ~ATMega328P or/and the Arduino IDE to run ~HaikuVM?''
''A:'' No, virtually everthing you need for ~HaikuVM comes with the download. (For Linux user see [[here|Linux]].) One critical point is the flash tool. If your device needs an other tool than avrdude, you have to download it from elsewhere. ([[More ...|http://backsite.wordpress.com/2013/02/28/java-fur-arduino-und-andere-mcs-mit-haikuvm/]])

''Q: All appears to go well, but the program doesn't appear to be running on the ~ATmega. It just sits there silently. Any idea?''
''A:'' I suggest to start with a basic and simple busy-wait example for AVR which you will find in './haikuVM/examples/src/main/java/avr/tutorial/~BlinkSimple.java' and is described in more detail [[here|BlinkSimple]]. 
Caution: First you have to edit and change it to your needs because this example assumes that the LED is on PORTB.
<code bash>
cd haikuVM/myCProject

/home/bob/haikuVM/bin/haikuc /home/bob/haikuVM/examples/src/main/java/avr/tutorial/BlinkSimple.java
/home/bob/haikuVM/bin/haikulink -v --Config simple010 -o BlinkSimple.hex /home/bob/haikuVM/examples/src/main/java/avr/tutorial/BlinkSimple.java
</code>

''Q: I'm trying to compile it in './bin/' with:
'./haiku -v - -Config arduino -o ~BlinkWithThread.hex ./~BlinkWithThread.java'
but have no success. Why?''
''A:'' Don't try it in ./bin/ and don't try it with relative pathes. Instead follow this wiki suggestions, move into ./haikuVM/myCProject and use absolute pathes like so:
<code bash>
cd haikuVM/myCProject

/home/bob/haikuVM/bin/haiku -v --Config simple010 -o BlinkSimple.hex /home/bob/haikuVM/examples/src/main/java/avr/tutorial/BlinkSimple.java
</code>


''Q: Is it possible to save the output of the command haiku into a trace file?''
''A:'' Yes, there are two ways I can think of:
<code bash>
c:\haikuVM\bin\haiku -v --Config simple010 -o BlinkSimple.hex C:\haikuVM\examples\src\main\java\avr\tutorial\BlinkSimple.java >std.out 2>std.err
or
c:\haikuVM\bin\haiku -v --Config simple010 -o BlinkSimple.hex C:\haikuVM\examples\src\main\java\avr\tutorial\BlinkSimple.java >std.outerr 2>&1
</code>

''Q: Is AVRISPMKII supported?''
''A:'' Not direct. You have to install libusbWin32 first. Then, when using 'usb' as port, has a chance to do the job.
<code bash>
c:\haikuVM\bin\haiku -v --Config simple010 --Config:Port usb -o BlinkSimple.hex C:\haikuVM\examples\src\main\java\avr\tutorial\BlinkSimple.java >std.out 2>std.err
</code>
 
''Q: Are interrupts enabled?''
''A:'' Yes, interrupts are enabled by default.

''Q: Is it possible to write my own interrupt routines?''
''A:'' Yes, see the tutorial about interrupts. Keep in mind that '~TIMER0_OVF_vect' interrupt is reserved for ~HaikuVM.

''Q: Is it possible to call a Java method from within a C function?''
''A:'' This is difficult.
#You need a Thread and a stack frame for the Java method.
#The method must be reachable for Java/~HaikuVM as well. (Otherwise it's optimized away.)

''Q: If I use JNI, I assume the used mechanism (cppConstructor / cobject) maps any methods with the same signature to the corresponding method of the c++ instance, is that correct?''
''A:'' Not quite right. You are expecting to much magic. You have to look at it thru Java glasses, like HaikuVM does. Please take a look at this tutorials: [[Tutorial JNI]]

''Q: If I use JNI, where need the .h/.cpp files to be placed to get picked up?''
''A:'' Short answer: anywhere in your myCProject folder ''OR'' In the same folder as your main java. For a long answer see: [[JNI enhanced]]

''Q: I want to change ~HaikuVM code (e.g. 'simpleOS.c'), what is the best place?''
''A:'' There are three answers:
#If your change is very project specific then './myCProject/haikuVM/simpleOS.c' is the best place.
#If the change is more general then './haikuVM/simpleOS.c' is the best place. But this will be overwritten with the download of the next ~HaikuVM version. 
#If the change is an enhancment of ~HaikuVM then send it to me or join the project as a developer.

''Q: The probem is, that avr-gcc needs include files (p.e. stdio.h).''
''A:'' 
#What's your avr-gcc version? The command 'avr-gcc -version' will print the current version. Compare this with commited versions [[here|Reported Usage]].
#Is your avr-gcc proper installed? Please, do an isolated test of avr-gcc with a simple ~HelloWorld.c program.

''Q: Is it possible to compile more than one Java program with ~HaikuVM and upload the HEX to arduino?''
''A:'' Compiling more than one Java program into one (third) program is not a question of ~HaikuVM but of Java programming. Consider this ''Program1'':
<code java>
package faqs.programs;
public class Program1 {
    public static void main(String[] args) {
        System.out.println("Hello ");
    }
}
</code>
and this ''Program2'':
<code java>
package faqs.programs;
public class Program2 {
    public static void main(String[] args) {
        System.out.println("World!");
    }
}
</code>
Both can be called from within this ''Program3'':
<code java>
package faqs.programs;
public class Program3 {
    public static void main(String[] args) {
        Program1.main(null);
        Program2.main(null);
    }
}
</code>
And may be compiled and uploaded like this:
<code bash>
mkdir \myPrograms
cd \myPrograms
C:\haikuVM\bin\haiku --Config duemilanove C:\haikuVM\examples\src\main\java\faqs\programs\Program3.java
</code>

''Q: Is it possible to compile against a JAR library with ~HaikuVM?''
''A:'' Again, this is not a question of ~HaikuVM but of Java skill. Take the example from above and put ''Program1'' and ''Program2'' into 'mylib.jar' or  use the prepared example comming with ~HaikuVM like this:
<code bash>
mkdir \myPrograms
cd \myPrograms
C:\HaikuVM\bin\haiku -v --Mode 16/32 --Config duemilanove --classpath C:\HaikuVM\lib\examples\mylib.jar C:\HaikuVM\examples\src\main\java\faqs\programs\Program3.java
</code>

''Q: Does ~HaikuVM support serialisation?''
''A:'' No. It's not possible for two reasons:
# ~HaikuVM does not support reflection.
# ~HaikuVM uses the leJOS runtime. And this runtime has no implementation of ~ObjectOutputStream nor ~ObjectInputStream.
I only can think of a proprietary solution for ~HaikuVM (and a much weaker solution than serialisation support of a full blown JVM). The [[Memory Layout of HaikuVM Objects]] tries to mimic a C struct layout of a block of memory e.g. an object memory space. (In contrast a classic Java class typically doesn't.) The idea is to make the mapping to C as close as possible to simplify implementation and improve execution speed.

''Q: How can I contribute to the project?''
''A:'' 
If you are a programmer and want to contribute code, ~HaikuVM is open-source and you are welcome to do so! Just send us your patches. There is no guarantee that your patch will be added to the upstream source, and all changes are carefully reviewed.

If you are not a programmer, but want to help out, feel free to look through the documentation or try installing ~HaikuVM and test it out. General editing, documentation contributions, and testing are always helpful.

''Q: How can I become an official member of the project?''
''A:'' 
The short answer is: "by being asked."

People are only added as official members of the ~HaikuVM project after their work has been proven. This usually means you will have contributed code in the form of patches before, or we know you from extensive testing work, or you frequently help with documentation, and we are impressed enough that we want you as part of the project.

All that said, you do not need to be a member of the project to help out. Feel free to contribute anything.

''Q: I think I've found a bug. How do I report it?''
''A:'' 
The project hosts a bug tracking here https://sourceforge.net/p/haiku-vm/tickets/. All bugs should be reported there as new tickets. This is also where you would request a new feature.

''Q: I need help! Where can I find some?''
''A:'' 
The project hosts forums at https://sourceforge.net/p/haiku-vm/discussion/general/. If you have a SourceForge username (or don't mind registering one), this is a good place to start.

If none of those options suffice, you can always email any of the project members directly. You will usually get a personal response, time permitting. 

''Q: How can I help ~HaikuVM?''
''A:'' I have multiple ideas open and you can work on any of them by joining as a developer. For example, 
* You can port ~HaikuVM on a PIC or ARM. 
* You can also help by fixing mistakes on this wiki-website 
* Improve the ~HaikuVM core. 
* Write a plugin for processing and its IDE. 
In short, I will appreciate any kind of help. So [[contact|Contact]] me now with your ideas for helping ~HaikuVM. Remember this project belongs to community and you. It will be a success only with your help and support. 

* Quasi-preemptive threads ([[More ...|Preemptive threads]])
* Exceptions ([[More ...|Exceptions]])
* Synchronization
* double and float support ([[More ...|double and float support]])
* Arrays, including multidimensional ones 
* Recursion 
* Object references are direct pointers (i.e. no handles)
* Two word object header to minimize heap overhead (object size and class pointer) ([[More ...|Memory Layout of HaikuVM Objects]])
* Garbage collection ([[More ...|Garbage collection]])
* Supports inheritance and interfaces
* Runs on
** AVR ~ATmega8, AVR ~ATmega328p (and Windows, UNIX) ([[More ...|Runs on AVR ATmega8, AVR ATmega328p (and Windows, UNIX)]])
** Windows and UNIX ([[More ...|Runs on AVR ATmega8, AVR ATmega328p (and Windows, UNIX)]])
** [[RCX 2.0]]
** [[ESP8266 (ESP01)]]
* Configurable 64, 32 or 16 bit data types including [[half precision float]] ([[More ...|Configurable 64, 32 or 16 bit data types]]) 
* Configurable 16 or 8 bit type for char arrays ([[More ...|Configurable 16 or 8 bit char type]])
* Tested with Suns JAVA 1.6, 1.7 and 1.8
* ~HaikuVM is written in C, with zero assembler code ([[More ...|Zero Assembler Code]])
* Panic Support ([[More ...|Panic Support]])
* Compact: Requires only down to 5k Bytes of code memory which includes ~HaikuVM ''and'' your Java program. ([[More ...|Compact]])
* Performance
** About 66k Java opcodes per second on 8 Mhz  AVR ~ATmega8 ([[More ...|Performance]])
** Twice as fast as Micro Python ([[More ...|Performance compared with micropython]])
* Needs only 250 Bytes RAM (the rest is for your JAVA application)
* Direct access to memory ([[More ...|Memory Access]])
* Partial support of JNI ([[More ...|Tutorial JNI]])
* Direct access to C/C++ functions via annotations ''@~NativeCFunction'' and ''@~NativeCppFunction''. ([[More ...|Tutorial JNI]])
* Insert C code into your Java file using annotation member ''cImpl''. ([[More ...|Beyond JNI: put C code into your java files]])
* Uses its own lightweight native interface for internal native methods without overhead of JNI
* Uses a static linking model to reduce code footprint
* Auto detection of needed bytecodes. In other words: The haikufied program is linked only with bytecodes your Java program uses. ([[More ...|Compact HaikuVM Code]])
* Per-method dependency analyzer, that determines a set of methods that are really needed to run your application, so HaikuVM won't translate whole JAR files or class directories
* Supports multiple interpreter techniques ([[More ...|Ahead-of-time (AOT) compiler]])
* one register stack-caching

!Limitations
* Does not support reflection (Serialisation but also jRuby or Groovy are unlikely to run against ~HaikuVM)
* Does not call static class initializers in lazy order (instead they are all called eager just before your main method is called)
* Does not supports class loaders
* Garbage collection without compaction
* No class loader support
* No object finalization support
* Array objects have no type information (and no typechecking in the bytecode handlers for Arrays)
* No weak references
* Interfaces partial supported
* No interrupt handlers may written in ~HaikuVM. Use JNI for this, see [[Tutorial Interrupts]].
On default ~HaikuVM uses a simple mark & sweep conservative garbage collector (GC=~HAIKU_ConservativGC). I chose this algorithm because of its simplicity. A downside is, that non-compacting collectors typically cause fragmentation on the heap. Another is, that the mark phase is usually implemented using recursion, which can potentially cause stack overflows. I therefore implemented a slower but non-recursive marking algorithm. Until now ~HaikuVM supports three types of ~GCs:
#No GC (no garbage collection at all) {{{GC=HAIKU_NoGC}}}
#Stop the world GC (default) {{{GC=HAIKU_ConservativGC}}}
#Incremental GC (slices of work of the GC are done between interpretation of bytecodes) {{{GC=HAIKU_IncrementalGC}}}
#Stop the world compacting GC (experimental) {{{GC=HAIKU_CompactingGC}}}
The GC mode can be configured in the [[HaikuVM.properties]] file or as [[command line option|Command Line Options]].
~HaikuVM at its core, is just another JAVA VM for micros (I began with ~AVRs). I decided to go without building an own JAVA runtime. Instead ~HaikuVM is tailor made to use the JAVA runtime coming with [[leJOS]]. ~HaikuVM works by compiling JAVA bytecode to C structs to be compiled by a C cross compiler for your target platform. So, the resulting code is small and fast. ([[More ...|Architecture]])

To produce an executable for a given target from a set of Java source files and libraries, three sets of tools are used:
*''JAVA tools''<br>A JAVA 6 compiler (or higher) and SDK from Oracle. ~HaikuVM is shipped with the leJOS runtime library. But you are invited to experiment with other runtime libraries as e.g. Oracle, ~OpenJDK or GNU Classpath. Any editor will do, but I recommend an Eclipse IDE to ease development and deployment. No matter what is the preferred development environment the outcome is a set of class files making up the application.
*''~HaikuVM tools'' ([[More ...|Commands]])<br>These tools make up the core part of the ~HaikuVM environment. The outcome of the ~HaikuVM tools is a set of auto generated C files making up the C version of the application.The user points to the main entry point of the application (the main method) and the tools will now do two things:
**Compute the dependency extent of the main method (often called closure). This is the set of methods that may be executed as a result of running main, and the set of fields and other resources (e.g constants) that may be referenced. The tool will compute a conservative estimate of this set through a static analysis of the source code. The closure will contain both, code produced by the user and code extracted from referred libraries.
**Translate the closure into C code. The C code produced is basically a set of unsigned char arrays containing the byte code and a C representation of the constant pools. This C code can be thought of as a C version of the class files making up the dependency extent of the main method.
*''C/C++ tools''<br>These tools are the existing set of tools used by the embedded developer to translate C source code into uploadable hex files for the target. In many cases this will be some version of the GCC tool chain, but it may also be some other C tool chain. Using this C compiler the C source generated by the ~HaikuVM tools can be linked with the ~HaikuVM interpreter to produce the final executable for the target.

Software which you need:
#JAVA sdk 1.6 (or higher)
#[[download|https://sourceforge.net/projects/haiku-vm/files/downloads]] and unzip ~HaikuVM into C:\haikuVM
#Then haikufy, upload and run your JAVA Program on your Microcontroller.
Software the download includes:
#~HaikuVM tools
#[[leJOS]] runtime
#~WinAVR 20100110 (Windows C cross compiler for ~AVRs)
''Remark'': On LINUX you have to install a C cross compiler for ~AVRs by hand.

As an option I recommend the [[Eclipse IDE]] for development.
But using the [[Arduino IDE]] for Arduinos is supported as well.

~HaikuVM just should work out of the box. Unlike other JAVA ~VMs for microcontrollers it adapts automatically to the needs of your JAVA program. For example if your program don't uses doubles then bytecodes and C code for doubles are eliminated automatically. If your program don't uses multi-threading then bytecodes and C code for multi-threading are eliminated automatically. And so on. This means that virtually no fiddling with configurations is needed and memory consumption of ~HaikuVM is always squeezed down to the minimum.

Comments and questions are welcome ([[Contact]]). Keep in mind, this is still a work in progress, so there is more to come: both in terms of features and in terms of optimizations... 

!Getting started with a Duemilanove
Start with the following JAVA program.
<code java>
package arduino.tutorial;
import static haiku.avr.lib.arduino.WProgram.*;
public class Blink {
    static byte ledPin = 13;            // LED connected to digital pin 13

    public static void loop()           // run over and over again
    {
        digitalWrite(ledPin, HIGH);     // sets the LED on
        delay(1000);                    // waits for a second
        digitalWrite(ledPin, LOW);      // sets the LED off
        delay(1000);                    // waits for a second
    }

	public static void main(String[] args) {
        pinMode(ledPin, OUTPUT);        // sets the digital pin as output
        while(true) {
        	loop();
        }
    }
}
</code>
Haikufy, upload and run your JAVA Program on an ARDUINO like this:
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config duemilanove --Config:Port com5 C:\haikuVM\examples\src\main\java\arduino\tutorial\Blink.java
</code>
Assuming that your ARDUINO (the Duemilanove is the reference system for ~HaikuVM) is connected on port com5. 


!Getting started with others
Take a look into [[Reported Usage]] and follow the links.



//HaikuVM// - A Java VM for ARDUINO and other micros using the leJOS runtime.
These are some of the current configuration targets in ~HaikuVM.properties:
#pc
#unix
#arduino (default)
#arduinoIDE
#arduinoIDEVerify
#arduinoIDEUpLoad
#wiring
#duemilanove
#duemilanove.~ProcessingCLIB
#asuro
#nanovm
Some of this targets point to the same hardware (board) but different [[MicroKernels|Tutorial All About MicroKernels]] or ~OSs.

To be used like this (for example):
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config duemilanove -o BlinkWithThread.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread.java
</code>
or this (if your target is an [[Ubuntu]] unix):
<code bash>
cd /home/bob/haikuVM/myCProject  
/home/bob/haikuVM/bin/haiku -v --Config unix /home/bob/haikuVM/examples/src/main/java/arduino/tutorial/HelloWorldJava.java
</code>


The file ~HaikuVM.properties is looked up in the following two pathes:
*<myCProject>\~HaikuVM.properties
*<~HaikuVM_HOME>\config\~HaikuVM.properties
If you followed the guidelines given in this document, then this will evaluate to:
*C:\haikuVM\myCProject\~HaikuVM.properties
*C:\haikuVM\config\~HaikuVM.properties
Many of the used properties of file '~HaikuVM.properties' may be overwritten in the command line and are explained here [[Command Line Options]].

The ~HaikuVM.properties may be inspected [[here|http://sourceforge.net/p/haiku-vm/code/HEAD/tree/trunk/config/HaikuVM.properties]] to find out how the targets above are covered with default values.
(unordered)
*Use [[Gradle|https://sourceforge.net/p/haiku-vm/discussion/general/thread/6db5a31e/]] to overcome IDE dependencies.
**Support for ~NetBeans IDE.
**Integration of bytecode optimization by using the open source tool [[ProGuard|http://proguard.sourceforge.net/]].
*Use and integrate with an AVR simulator like e.g. [[SimulAVR|http://www.nongnu.org/simulavr/]].
*Integrate a scripting language like FORTH.
*Seamless integration with C++ objects. (Currently I'm attracted to the idea of [[SWIG|http://www.swig.org/Doc1.3/Java.html#imclass]].)
*Implement a compacting garbage collector to solve 'dead by fragmentation'.
*Enable runtime debugging.
*Seamless integration with interrupts (~ISRs). This is, handling Interupts in Java.
*Ahead of time Compiler (into C++ code) instead using the bytecode interpreter (space vs. time).
*String constants stay in flash memory (and are never copied to RAM when used).
* Threads with different priority
''Class annotation: ~NativeCHeader(cImpl="<Your Cpp Code>")''
~HaikuVM writes <Your Cpp Code> into file 'nativeCFunction.cpp'. ([[More ...|Beyond JNI: Java class as proxy to a C++ class]])

''Class annotation: ~NativeCBody''
Just a synonym for annotation ~NativeCHeader. ([[More ...|Beyond JNI: Java class as proxy to a C++ class]])

''Java attribute: native''
~HaikuVM generates JNI blueprint code into file '~HaikuJNI.c'. ([[More ...|JNI simple]])

''Method annotation: ~NativeCFunction''
Applies only on native Java methods. ~HaikuVM generates reasonable JNI code into file 'nativeCFunction.cpp'. The corresponding C function is assumed to be declared as: extern "C". ([[More ...|JNI using functions from a C library using annotations]])

''Method annotation: ~NativeCppFunction''
Applies only on native Java methods. ~HaikuVM generates reasonable JNI code into file 'nativeCFunction.cpp'. The corresponding C++ function is assumed to be declared as: extern. ([[More ...|JNI using functions from a C library using annotations]])

''Method annotation: ~NativeCppMethod''
Applies only on native Java methods. ~HaikuVM generates reasonable JNI code into file 'nativeCFunction.cpp' assuming that the Java class is a proxy to the corresponding C++ class. ([[More ...|Beyond JNI: Java class as proxy to a C++ class]])

''Method annotation: ~NativeProcessingFunction''
Just a synonym for annotation ~NativeCppFunction. (For future use.)

''Variable annotation: ~NativeCVariable''
Static Java variables annotated with @~NativeCVariable# (where # is one of 8, 16, 32 or 64) are directly mapped to (equal named and existing) C Variables. ([[More ...|Memory Access]]) So ~HaikuVM will not allocate memory for this variables in the JAVA static memory space: 
*~NativeCVariable8
*~NativeCVariable16
*~NativeCVariable32
*~NativeCVariable64
If you think "JNI", in most cases, the Java part of the code degenerates to a proxy to the real C subject. Here is some summary when using JNI with HaikuVM. I'm going with this example snippet:

<code java>
package arduino.tutorial.beyondjni;

import haiku.vm.NativeCBody;
import haiku.vm.NativeCFunction;
import haiku.vm.NativeCppFunction;
import haiku.vm.NativeCppMethod;

@NativeCBody(cImpl = "// some impl is needed (even a comment only) to force a local C++ namespace")
public class JNISummery {
	//////////////// 	just native
	public native double min(double x, double y);
	public static native double max(double x, double y);


	//////////////// 	@NativeCFunction
	@NativeCFunction
	public native double sin(double x);
	@NativeCFunction
	public static native double cos(double x);


	//////////////// 	@NativeCppFunction
	@NativeCppFunction
	public native double tan(double x);
	@NativeCppFunction
	public static native double sqrt(double x);


	//////////////// 	@NativeCppMethod
	@NativeCppMethod
	public static native void setS(long s);
	@NativeCppMethod
	public static native long getS();
	@NativeCppMethod
	public native void setA(int a);
	@NativeCppMethod
	public native int getA();


	//////////////// 	@NativeCppMethod and C++ Constructors
	@NativeCppMethod
    private native static JNISummery JNISummery(int a);
	@NativeCppMethod
    private native static JNISummery cppConstructor(int a);


    private JNISummery realSubject;
	static private JNISummery obj1=new JNISummery(101);

    public JNISummery(int a) {
    	realSubject=JNISummery(a);
    	realSubject=cppConstructor(a);
    }

    public static void main(String[] args) {
    	setS(110); obj1.setA(111);

    	System.out.println("class: "+getS());
        System.out.println("obj1:  "+obj1.getA());

        System.out.println("min : "+obj1.min(1, 3));
        System.out.println("max : "+max(1,5));
        System.out.println("sin : "+obj1.sin(1));
        System.out.println("cos : "+cos(1));
        System.out.println("tan : "+obj1.tan(1));
        System.out.println("sqrt: "+sqrt(1));
    }
}
</code>

!Java attribute: native
When using attribute ''native'', ~HaikuVM generates an empty JNI C code blueprint into file ''haikuJNI.c''. You have to cut&past them into your C files and fill out the gap (See 'TODO: insert your code here' in the function body below).
<code java>
############## Java
public native double min(double x, double y);
</code>
<code java>
############## HaikuVM for you in haikuJNI.c
JNIEXPORT jdouble Java_arduino_tutorial_beyondjni_JNISummery_min JNICALL
  (JNIEnv *env, jobject obj, jdouble arg1, jdouble arg2)
{
    // TODO: insert your code here
    return 0;
}
</code>

!~HaikuVM annotation: ~NativeCFunction
You get more out of HaikuVM and closer to what you want, if you use the supported annotation ''~NativeCFunction''. Now HaikuVM fills out the gap with some ''default C code'' and puts the whole thing into file ''nativeCFunctions.cpp''. Because ''native'' is used an empty JNI C code blueprint is generated into file ''haikuJNI.c'' as well (see above).
<code java>
############## Java
@NativeCFunction
public static native double cos(double x);
</code>
<code java>
############## HaikuVM for you in nativeCFunctions.cpp
#ifndef cos
extern "C" double cos(double);
#endif
JNIEXPORT jdouble Java_arduino_tutorial_beyondjni_JNISummery_cos
  (JNIEnv *env, jclass obj, jdouble arg1)
{
    return DOUBLE2TD(cos(TD2DOUBLE(arg1)));
}
</code>

!~HaikuVM annotation: ~NativeCppFunction
You get more out of HaikuVM and closer to what you want, if you use the supported annotation ''~NativeCppFunction''. Now HaikuVM fills out the gap with some ''default C code'' and puts the whole thing into file ''nativeCFunctions.cpp''.
<code java>
############## Java
@NativeCppFunction
public native double tan(double x);
</code>
<code java>
############## HaikuVM for you in nativeCFunctions.cpp
#ifndef tan
extern double tan(double);
#endif
JNIEXPORT jdouble Java_arduino_tutorial_beyondjni_JNISummery_tan
  (JNIEnv *env, jobject obj, jdouble arg1)
{
    return DOUBLE2TD(tan(TD2DOUBLE(arg1)));
}
</code>

!~HaikuVM annotation: ~NativeCppMethod
You can get even closer to what you want, if you use the supported annotation ''~NativeCppMethod''. Now HaikuVM fills out more gaps with some ''default C code'' and puts the whole thing into file ''nativeCFunctions.cpp''.
static:
<code java>
############## Java
@NativeCppMethod
public static native void setS(long s);
</code>
<code java>
############## HaikuVM for you in nativeCFunctions.cpp
JNIEXPORT void Java_arduino_tutorial_beyondjni_JNISummery_setS
  (JNIEnv *env, jclass obj, jlong arg1)
{
    JNISummery::setS(arg1);
}
</code>
dynamic:
<code java>
############## Java
@NativeCppMethod
public native int getA();
</code>
<code java>
############## HaikuVM for you in nativeCFunctions.cpp
JNIEXPORT jint Java_arduino_tutorial_beyondjni_JNISummery_getA
  (JNIEnv *env, jobject obj)
{
    return (*(JNISummery**) obj)->getA(); // works if the first field in your Java class holds the pointer to the C++ object
}
</code>

!~HaikuVM annotation: ~NativeCppMethod and C++ constructors
~HaikuVM generates constructor code as well. If a Java method is static and named like the Java class or named 'cppConstructor' then HaikuVM will generates the corresponding C++ constructor call.
<code java>
############## Java
@NativeCppMethod
private native static JNISummery JNISummery(int a);
</code>
<code java>
############## HaikuVM for you in nativeCFunctions.cpp
JNIEXPORT jobject Java_arduino_tutorial_beyondjni_JNISummery_JNISummery
  (JNIEnv *env, jclass obj, jint arg1)
{
    return (jobject) new JNISummery(arg1);
}
</code>

!~HaikuVM annotation: ~NativeCppMethod with a more realistic example
The HaikuVM annotation ~NativeCppMethod is tailor made for accessing C++ methods. To be used in Java classes which are designed as a proxy to this C++ classes. If you follow this rules then things are easy:
#The first field of your Java proxy must be of type Object, to be used as a pointer to the corresponding C++ object (real subject).
#You have to write a Java constructur to set this field.
#If a Java method is static then HaikuVM will generate the call to the corresponding static method of this C++ class.
#If a Java method is static and named like the Java class or named 'cppConstructor' then HaikuVM will generate the corresponding C++ constructor call.
#If a Java method is virtuell then HaikuVM will generate the call to the corresponding C++ method.
As a result you may write this:
<code java>
package avr.gallerie.user.bachiander;

@NativeCHeader(cImpl = "#include <LedControl.h>")
public class LedControl {
    private Object any; // Pointer to real c++ object of LedControl.cpp

    @NativeCppMethod
    private native static Object LedControl(int dataPin, int clkPin, int csPin, int numDevices);

    LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
        any=LedControl.LedControl(dataPin, clkPin, csPin, numDevices);
    }

    @NativeCppMethod
    public native void setLed(int addr, int row, int col, boolean state);
};
</code>

!~HaikuVM annotation with member: cImpl
This is still not what you want. Because C function 'cppConstructor(arg1, arg2, arg3, arg4)' is undefined. What you really want is to call the constructor of the C class '~LedControl'. You can overwrite the default C code by using member ''cImpl'' of annotation ''~NativeCppFunction''. This enables you to merge your own C code into the generated file 'nativeCFunctions.cpp'.
<code java>
############## Java
@NativeCHeader(cImpl = "#include <LedControl.h>")
public class LedControl {
...
@NativeCppFunction(cImpl = "return (jobject) new LedControl(arg1, arg2, arg3, arg4);")
private native static Object cppConstructor(int dataPin, int clkPin, int csPin, int numDevices);
</code>
<code java>
############## HaikuVM for you in nativeCFunctions.cpp
//////////////////Start of user code given per Java class by cImpl
#include <LedControl.h>
//////////////////End   of user code given per Java class by cImpl
...
JNIEXPORT jobject Java_avr_gallerie_user_bachiander_LedControl_cppConstructor
  (JNIEnv *env, jclass obj, jint arg1, jint arg2, jint arg3, jint arg4)
{
//////////////////Start of user code given by cImpl
return (jobject) new LedControl(arg1, arg2, arg3, arg4);
//////////////////End   of user code given by cImpl
}
</code>

!Accessing C++ fields and C++ methods
Now, when we focus for example on method setLed(..) it becomes ugly. Because if you want to call the setLed(..) C++ member method, you have the need to access the Java field cobject to reach your C++ object. This in turn means you have to mess around with a lot of JNI stuff. (Which HaikuVM supports to some very low degree.)
<code java>
############## Java
@NativeCppFunction(cImpl = 
	"#define cls avr_gallerie_user_bachiander_LedControl\n" +
	"jfieldID fid = (*env)->GetFieldID(env, cls, cobject, \"Ljava/lang/Object;\");\n" +
	"if (fid == 0)\n" +
	"    return;\n" +
	"LedControl* cobj = (LedControl*)((*env)->GetObjectField(env, obj, fid));\n" +
	"cobj -> setLed(arg1, arg2, arg3, arg4);")
public native void setLed(int addr, int row, int col, boolean state);
</code>
<code java>
############## HaikuVM for you in nativeCFunctions.cpp
JNIEXPORT void Java_avr_gallerie_user_bachiander_LedControl_setLed
  (JNIEnv *env, jobject obj, jint arg1, jint arg2, jint arg3, jboolean arg4)
{
//////////////////Start of user code given by cImpl
#define cls avr_gallerie_user_bachiander_LedControl
jfieldID fid = (*env)->GetFieldID(env, cls, cobject, "Ljava/lang/Object;");
if (fid == 0)
    return;
LedControl* cobj = (LedControl*) ((*env)->GetObjectField(env, obj, fid));
cobj -> setLed(arg1, arg2, arg3, arg4);
//////////////////End   of user code given by cImpl
}
</code>

Your complete Java code now looks like this:
<code java>
package avr.gallerie.user.bachiander;

@NativeCHeader(cImpl = "#include <LedControl.h>")
public class LedControl {
    private Object cobject; // Pointer to real c++ object of LedControl.cpp

    @NativeCppFunction(cImpl = "return (jobject) new LedControl(arg1, arg2, arg3, arg4);")
    private native static Object cppConstructor(int dataPin, int clkPin, int csPin, int numDevices);

    LedControl(int dataPin, int clkPin, int csPin, int numDevices) {
        cobject=cppConstructor(dataPin, clkPin, csPin, numDevices);
    }

    @NativeCppFunction(cImpl = 
        "#define cls avr_gallerie_user_bachiander_LedControl\n" +
        "jfieldID fid = (*env)->GetFieldID(env, cls, cobject, \"Ljava/lang/Object;\");\n" +
        "if (fid == 0)\n" +
        "    return;\n" +
        "LedControl* cobj = (LedControl*)((*env)->GetObjectField(env, obj, fid));\n" +
        "cobj -> setLed(arg1, arg2, arg3, arg4);")
    public native void setLed(int addr, int row, int col, boolean state);
};
</code>
Can we do better?

Maybe [[this|https://sourceforge.net/p/haiku-vm/discussion/general/thread/25b657d8/]] thread is of some additional help.

But often you don't need JNI. [[Here|http://sourceforge.net/p/haiku-vm/code/HEAD/tree/trunk/gallerie/src/main/java/avr/gallerie/user/cvdenzen/arduino/libraries/liquidcrystal/LiquidCrystal.java]] is an example of ~LiquidCrystal in Java. 
Let's proceed with an example using other Java types. Here the first native function should add an int, float and double. A second native function should deliver the result.
<code java>
package arduino.tutorial;

public class JNIenhanced {

    private static native void add(int a, float b, double c);
    private static native double result();
    
    public static void main(String[] args) {
        int a=3;
        float b=4;
        double c=5;
        
        add(a, b, c);
        System.out.println(a+" + "+b+" + "+c+" = "+result());
    }
}
</code>
Again copy the needed functions from 'haikuJNI.c' into file './myCProject/tutorial/~JNIenhanced.c'. And insert the intended code. You should come out with something similar like this:
<code cpp>
#include <jni.h>

static double result;
...
JNIEXPORT void Java_arduino_tutorial_JNIenhanced_add
  (JNIEnv *env, jclass obj, jint arg1, jfloat arg2, jdouble arg3)
{
    result = arg1 + arg2 + arg3;
}

...

JNIEXPORT jdouble Java_arduino_tutorial_JNIenhanced_result
  (JNIEnv *env, jclass obj)
{
    return result;
}
...
</code>

Come on, be brave and give it a try. The output is ''unexpected'':
{{{
3 + 4.0 + 5.0 = 17416.0
}}}
What's wrong here? Remember that in 16/32 mode (see [[Configurable 64, 32 or 16 bit data types]] and in [[half precision float]]) a Java float is a 16Bit data type and therefore is just a storage type. The AVR compiler does not support 16Bit floats. You have to use the right ~HaikuVM macros to unpack/pack float16 to something meaningful for AVR, as so:
<code cpp>
#include <jni.h>

static double result;
...
JNIEXPORT void Java_arduino_tutorial_JNIenhanced_add
  (JNIEnv *env, jclass obj, jint arg1, jfloat arg2, jdouble arg3)
{
    result = arg1 + TF2FLOAT(arg2) + TD2DOUBLE(arg3);
}

...

JNIEXPORT jdouble Java_arduino_tutorial_JNIenhanced_result
  (JNIEnv *env, jclass obj)
{
    return DOUBLE2TD(result);
}
...
</code>
Now we get the expected result:
{{{
3 + 4.0 + 5.0 = 12.0
}}}

As you can see in line 09 and 37, I was extra careful and used the unpack/pack macros for doubles, as well. Just to make this code more portable in case you want to give it a try in 16/16 memory mode.
I follow an example which I found here (http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/field.html) and adapted it for ~HaikuVM.
 
First, the example Java code looks like this:
<code java>
package arduino.tutorial;

class JNI_FieldAccess {
    static int si;
    String s;

    private native void accessFields();

    public static void main(String args[]) {
        JNI_FieldAccess c = new JNI_FieldAccess();
        JNI_FieldAccess.si = 100;
        c.s = "abc";
        c.accessFields();
        System.out.println("In Java:");
        System.out.println("  FieldAccess.si = " + JNI_FieldAccess.si);
        System.out.println("  c.s = \"" + c.s + "\"");
    }
}
</code>

Second, the original JNI C code for the native method accessFields() looks like this (cut&pasted from the source referenced above):
<code C>
#include <stdio.h>
#include <jni.h>
#include "FieldAccess.h"

JNIEXPORT void JNICALL
Java_arduino_tutorial_JNI_FieldAccess_accessFields(JNIEnv *env, jobject obj)
{
  jclass cls = (*env)->GetObjectClass(env, obj);
  jfieldID fid;
  jstring jstr;
  const char *str;
  jint si;

  printf("In C:\n");

  fid = (*env)->GetStaticFieldID(env, cls, "si", "I");
  if (fid == 0)
    return;
  si = (*env)->GetStaticIntField(env, cls, fid);
  printf("  FieldAccess.si = %d\n", si);
  (*env)->SetStaticIntField(env, cls, fid, 200);

  fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");
  if (fid == 0)
    return;
  jstr = (*env)->GetObjectField(env, obj, fid);
  str = (*env)->GetStringUTFChars(env, jstr, 0);
  printf("  c.s = \"%s\"\n", str);
  (*env)->ReleaseStringUTFChars(env, jstr, str);

  jstr = (*env)->NewStringUTF(env, "123");
  (*env)->SetObjectField(env, obj, fid, jstr);
}
</code>

Third, for ~HaikuVM (since 1.2.3) the C code part has to be modified like this to work. And I assume that a char is only 1 byte long (see [[HaikuVM.properties]] Char = 1):
<code C>
#include <stdio.h>
#include <jni.h>

#include "../HaikuVM/utility/haikuConfig.h"
#include "../HaikuVM/utility/haikuJava.h"

JNIEXPORT void JNICALL
Java_arduino_tutorial_JNI_FieldAccess_accessFields(JNIEnv *env, jobject obj)
{
//jclass  cls = (*env)->GetObjectClass(env, obj);
  #define cls arduino_tutorial_JNI_FieldAccess
  jfieldID fid;
  jstring jstr;
  char *str;
  jint si;

  printf("In C:\n");

//fid = (*env)->GetStaticFieldID(env, cls, "si", "I");
  fid = (*env)->GetStaticFieldID(env, cls,  si , "I");
  if (fid == 0)
    return;
  si = (*env)->GetStaticIntField(env, cls, fid);
  printf("  FieldAccess.si = %d\n", si);
  (*env)->SetStaticIntField(env, cls, fid, 200);

//fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");
  fid = (*env)->GetFieldID(env, cls,  s , "Ljava/lang/String;");
  if (fid == 0)
    return;
  jstr = (*env)->GetObjectField(env, obj, fid);
  str = (*env)->GetStringUTFChars(env, jstr, 0);
  printf("  c.s = \"%s\"\n", str);
  (*env)->ReleaseStringUTFChars(env, jstr, str);

  jstr = (*env)->NewStringUTF(env, "123");
  (*env)->SetObjectField(env, obj, fid, jstr);
}

JNIEXPORT void native_arduino_tutorial_JNI_FieldAccess_accessFields_V(void) {
    pushTop();    // Save variable top onto stack.
    {
        jobject    obj = pop()->a;
        JNIEnv     *env = (JNIEnv*)&top;
        Java_arduino_tutorial_JNI_FieldAccess_accessFields(&env, obj);
    }
    popTop();
}
</code>

You see, the main difference comes from the fact, that ~HaikuVM needs to build the access to class 'arduino.tutorial.~JNI_FieldAccess' and fields 'si' and 's' during ''compile-time'' (si, s) and not during run-time ("si", "s"). The JNI C code can be found here: 'myCProject:tutorials/~JNI_FieldAccess.c'.

I'm on my way to narrow the gap between the proprietary ~HaikuVM solution and the official JNI way. For now take it as it is.
In case you write some Java code which declares a ''native method'' like here:
<code java>
package arduino.tutorial;

public class JNIsimple {

    private static native int add(int a, int b);
    
    public static void main(String[] args) {
        int a=3;
        int b=4;
        System.out.println(a+" + "+b+" = "+add(a,b));
    }
}
</code>
~HaikuVM will detect this situation during the run of [[haikulink]] and writes JNI code templates and some wrapper code which is proprietary for ~HaikuVM, in your project directory file './myCProject/haikuVM/utility/haikuJNI.c'. In our case you will find something like this:
<code cpp>
...
/*
 * Class:     arduino.tutorial.JNIsimple
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint Java_arduino_tutorial_JNIsimple_add
  (JNIEnv *env, jclass obj, jint arg1, jint arg2)
{
    // TODO: insert your code here
    return 0;
}

/*
 * Proprietary HaikuVM stack to JNI interface function.
 * DO NOT EDIT THIS FUNCTION � it is machine generated.
 *
 * Class:     java.lang.System
 * Method:    getDataAddress
 * Signature: (Ljava/lang/Object;)I
 */
JNIEXPORT void native_arduino_tutorial_JNIsimple_add_III(void) {
    pushTop();	// Save variable top onto stack.
    {
        jint	arg2 = pop()->i;
        jint	arg1 = pop()->i;
        jobject	obj = NULL;
        JNIEnv *env = NULL;
        top.s1.i = Java_arduino_tutorial_JNIsimple_add(env, obj, arg1, arg2);
    }
    // Variable top holds the return value.
}
...
</code>
You have to copy this into some C file of your project directory. In case of this tutorial, do this in file './myCProject/tutorial/~JNIsimple.c'. The first function body '~Java_java_lang_System_getDataAddress' is the pure JNI function. The second function 'native_arduino_tutorial_~JNIsimple_add_III' is a proprietary ~HaikuVM function which just interfaces between the internal ~HaikuVM stack and the JNI function. Do not edit this function unless you know what you do. For the rest of this tutorial we will forget about the proprietary function(s) and will concentrate on the JNI functions.

Give life to your first JNI function by replacing the auto generated code (in file './myCProject/tutorial/~JNIsimple.c') by your semantic. In our case add arg1 and arg2.
<code cpp>
#include <jni.h>
...
JNIEXPORT jint Java_arduino_tutorial_JNIsimple_add
  (JNIEnv *env, jclass obj, jint arg1, jint arg2)
{
    return arg1 + arg2;
}
...
</code>
That's it! Now compile (by using haikulink) again and your native function will be used. Easy isn't it? (Don't forget to include 'jni.h', as can be seen in line 01.)

''Note''
~HaikuVM is a simple VM. When calling one of your JNI C functions the complete Haiku VM (that is every thread) is suspended. So keep in mind, that your JNI C functions have to be cooperative and lean.
Using functions from a C library is easy as 1,2,3 provided this library is included in your configuration. In this example we want to see the difference - if any - between the Java function Math.sin(x) and the C function sin(x) coming with C in the standard C library 'libm.a'. (Luckily 'libm.a' is included in virtual every [[HaikuVM.properties]] configuration.) Here is the Java code:
<code java>
package arduino.tutorial;

public class JNINativeLIBC {

    private static native double sin(double a);
    
    public static void main(String[] args) {
        double x=2.1;
        System.out.println("Calculate sin("+x+")");
        System.out.println("This is the JAVA result: "+Math.sin(x));
        System.out.println("This is the libc result: "+sin(x));
    }
}
</code>
Again, you have to copy the automatic generated template in 'haikuJNI.c' into your own C file (let's say './myCProject/tutorial/~JNINativeLIBC.cpp') and add the call to sin(x). From the previous chapter you already learned to use the right ~HaikuVM macros to unpack/pack the values. At the end you should come out with some code like this, which does the job:
<code cpp>
...
JNIEXPORT jdouble Java_arduino_tutorial_JNINativeLIBC_sin
  (JNIEnv *env, jclass obj, jdouble arg1)
{
    return DOUBLE2TD(sin(TD2DOUBLE(arg1)));
}
...
</code>
This is pretty simple, isn't it?

Can we do much simpler? Yes, ~HaikuVM can! See [[here|JNI using functions from a C library using annotations]].
As you might have recognized [[here|JNI using functions from a C library]], interfacing to a C function is boilerplate code. ~HaikuVM can do this for you automatic. And you virtually will have no need to write C JNI code for this.

In this example I use sin(x) from the C math library of AVR and print the result side by side with the pure Java Math.sin(x). At the core, I just annotate the native method in question (here sin(double a)) with  ''@~NativeCFunction'' like so:
<code java>
package arduino.tutorial;

import haiku.vm.NativeCFunction;


public class JNINativeLIBC {

    @NativeCFunction
    private static native double sin(double a);
    
    public static void main(String[] args) {
        double x=2.1;
        System.out.println("Calculate sin("+x+")");
        System.out.println("This is the JAVA result: "+Math.sin(x));
        System.out.println("This is the libc result: "+sin(x));
    }
}
</code>
JNI functions annotated like this are generated into file './myCProject/haikuVM/utility/nativeCFunctions.cpp'. Here is the automatic generated result including macros to unpack/pack the values:
<code cpp>
...
JNIEXPORT jdouble Java_arduino_tutorial_JNINativeLIBC_sin
  (JNIEnv *env, jclass obj, jdouble arg1)
{
    return DOUBLE2TD(sin(TD2DOUBLE(arg1)));
}
...
</code>

As you might have expected, there is a similar annotation called ''@~NativeCppFunction'' to refer to C++ functions.

This makes it quite easy to take advantage of native platform features without incurring the high overhead of configuring and building JNI code for multiple platforms.

Here is a list of all supported JNI annotations:
#''@~NativeCFunction''
#''@~NativeCppFunction'' and its synonym ''@~NativeProcessingFunction''
#''@~NativeCBody'' and its synonym ''@~NativeCHeader''
#''@~NativeCppMethod''
All of them support the member ''cImpl''. (See tutorial [[Beyond JNI: put C code into your java files]])

BTW, if you want your own library to be included, use variable ''CLIBS'' of your configuration in [[HaikuVM.properties]]. For an example usage take a look at configuration 'leonardo.~UsingCLIB'.
This is how to let the examples, published in ''javamagazine'', run:

<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config duemilanove C:\haikuVM\examples\src\main\java\de\javamagazin\Blink.java
</code>

<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config duemilanove C:\haikuVM\examples\src\main\java\de\javamagazin\BlinkWithThread.java
</code>

<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config duemilanove.UsingCLIB C:\haikuVM\examples\src\main\java\de\javamagazin\BlinkArduino.java
</code>

<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config duemilanove.ProcessingCLIB C:\haikuVM\examples\src\main\java\de\javamagazin\BlinkProcessing.java
</code>

To let Leonardo talk to you, just enter the next two lines (assuming Leonardo is listening on port 32):
<code bash>
cd C:\haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config leonardo.UsingCLIB  --Config:Port com31  C:\haikuVM\examples\src\main\java\arduino\tutorial\HelloWorldProcessing.java
</code>

This solution variant uses a pre-compiled and pre-linked ~Arduino-Leonardo core library to have full access to USB.

After haikufying, the script continous and is ready to upload your code to the Leonardo, signaling it like this, to give yoe a chance to press the reset button:
<code bash>
read -t 6 -p "Please press the  R E S E T  button on the Leonardo"; avrdude -patmega32u4 -cavr109 -PCOM31 -b57600 ...
</code>

Now, it's all about timing. When you see this message you should immediatly press the reset button on the Leonardo. After about 6 seconds the Leonardo closes com32 and is ready for avrdude on com31. If the upload was successful avrdude will show somthing like this:
<code bash>
...
avrdude.exe: verifying ...
avrdude.exe: 9904 bytes of flash verified

avrdude.exe done.  Thank you.
</code>

As an alternative you might program your Leonardo with ~HaikuVM thru your [[Arduino IDE]].
!JAVA ~VMs
[[leJOS|http://en.wikipedia.org/wiki/LeJOS]] (and [[tinyVM|http://tinyvm.sourceforge.net/]])
[[NanoVM|http://www.harbaum.org/till/nanovm/index.shtml]] is a java virtual machine for the Atmel AVR ~ATmega8 CPU, the member of the AVR CPU family used e.g. in the DLR Asuro robot, manufactured by AREXX engineering. With the ~NanoVM, the Asuro can be programmed in the popular Java language.

[[TakaTuka:|http://takatuka.sourceforge.net/]] A Java Virtual Machine for Tiny Platforms. 
*For me it is an inspiring source of optimization of bytecodes itself.
[[Darjeeling|http://darjeeling.sourceforge.net/]] is a Virtual Machine (VM) for Micro Controller Units (MCU). It can execute a large subset of the Java language on 8- and 16-bit platforms, such as Atmega128 or ~MSP430. 

[[Squawk|http://en.wikipedia.org/wiki/Squawk_virtual_machine]] is a Java micro edition virtual machine for embedded system and small devices. I was surprised to see that ~HaikuVM shares similarities in:
*Threading and Synchronization. Synchronized methods and the use of the "synchronized" keyword generate explicit monitorenter/exit ~HaikuVM bytecodes. Unlike in Java, the "invoke" bytecodes never perform synchronization.
*Bytecode rewriting to squeeze the memory footprint.
[[Harissa|http://www.usenix.org/publications/library/proceedings/coots97/full_papers/muller/muller_html/node3.html]]: a compiler from Java bytecode to C
[[Toba|http://www.cs.arizona.edu/projects/sumatra/toba/doc/]]: A ~Java-to-C translator
[[Vishia|http://www.vishia.org/Java2C/]]:  java to C translator
[[jcgo|http://www.ivmaisoft.com/jcgo/demos.htm]]: a Java source to C code
[[jc|http://jcvm.sourceforge.net/]]
[[Soot|http://www.sable.mcgill.ca/soot/]]: a Java Optimization Framework
[[gnu classpath|http://www.gnu.org/software/classpath/stories.html]]
[[FLEX|http://flex.cscott.net/]] is a compiler infrastructure written in Java for Java
[[SlimVM|http://www.christianwimmer.at/Publications/Kerschbaumer09a/Kerschbaumer09a.pdf]]: A Small Footprint Java Virtual Machine for Connected Embedded Systems (loads JAVA Lib chunks on demand from a server)
[[dalvik|http://5963581449325967972-a-1802744773732722657-s-sites.googlegroups.com/site/io/dalvik-vm-internals/2008-05-29-Presentation-Of-Dalvik-VM-Internals.pdf?attachauth=ANoY7coivl317Iz9z-vk_afdBjSK6peZRoJRihQ9LLzPR3xEdKyZC7zToSfwFZfSCwsTFNtBp9x4UddWlIlExgrdGV0WIQFkHpXaBatDLur3GWnEV5HjS1k9EKJm_WmCHHPxYY0eEneX038ZcGdwUQi2dYvmGCReR2jBNykZbHkgJov1pfPT1uqz-HEd-3Rwef2x_al4ag5xZ43nsvwXjx5nVIi_I7Dx7MjXVBVrj1-gtoSojMlvv4a-qCyW4aa7PZVrsWzCOfDB&attredirects=0]]
[[jop|http://www.jopdesign.com/perf.jsp]] includes FPGA hardware: picoJAVA, femtoJAVA
[[bajos|http://code.google.com/p/bajos/wiki/FeaturesAndLimits]]
[[Javolution|http://javolution.org/]] real time JAVA
[[JNode|http://www.jnode.org/]]
[[uJ|http://dmitry.co/index.php?p=./04.Thoughts/11. uJ - a micro JVM]] Too big for an ~ATmega328p
[[KESO|http://www4.cs.fau.de/Research/KESO/]] To avoid the interpretation of bytecode on the target controllers, the Java bytecode is compiled to a native code binary image ahead of time. Based on OSEK/VDX -> no new Thread(), no exceptions ([[More ...|https://www4.cs.fau.de/Lehre/WS10/P_HOTSYS/Folien/07_KESO.pdf]])
Has an interesting concept of memory-mapped objects.
[[simpleRTJ|http://www.csc.uvic.ca/~mcheng/360/notes/simpleRTJ/]] "Specially optimized to run on the embedded systems with limited memory resources (from 48KB). On average the simpleRTJ will not require more than 18-23KB of RAM to run."
[[icelab HVM|http://icelab.dk/index.html]] Produces an executable for a given target from a set of Java source files and libraries.
~PreonVM (Virtenio) A VM for embedded systems and small devices.

http://en.wikipedia.org/wiki/List_of_Java_virtual_machines

!Other non-JAVA ~VMs
[[EmbedVM|http://www.clifford.at/embedvm/]] Very fast but supports only 8-bit and 16-bit data types, no floats.
[[SBI|http://evprojects.altervista.org/projects/sbi/]] Assembler-like syntax.
[[AmForth|http://sourceforge.net/projects/amforth/]] is an easily extendible command interpreter for the Atmel ~AVR8 Atmega micro controller family. It has a turnkey feature for embedded use too.
[[Forth|http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=626&item_type=project]] other older project.
[[occam-pi:|http://concurrency.cc/]] An IDE uploads your native OCCAM code to a web service running in the Amazon VM cloud. This service compiles it into downloadable bytecode for a so called TVM which is running on your Arduino.
[[Micro Python|https://micropython.org/]]: See my [[performance test|Performance compared with micropython]]

!Miscellaneous
[[ProGuard|http://proguard.sourceforge.net/]]
~ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions.

!Creative and inspiring
*[[SWIG|http://www.swig.org/Doc1.3/Java.html#imclass]] integration with C++ objects.
*Memory Access: http://www.kdgregory.com/index.php?page=java.byteBuffer
My Linux is UBUNTU 12.04 LTS. And this is what I did as some user 'bob'.
After downloading of haikuVM into '/home/bob/haikuVM' I had to do minor preparation:
<code bash>
# I changed some shell scripts to have execute permission
chmod +x haikuVM/bin/*

# Sorry some scripts may still have '\r\n' instead of '\n' only
dos2unix haikuVM/bin/*

# I found that javac and the AVR tool chain was missing on my UBUNTU
sudo apt-get install openjdk-6-jdk
sudo apt-get install gcc-avr binutils-avr gdb-avr avr-libc avrdude

# I plugged in my ARDUINO Duemilanove and found out that it came on /dev/ttyUSB0
ls -ltr /dev
#sudo usermod -aG dialout bob # does not work for me
sudo chmod a+rw /dev/ttyUSB0
ls -ltr /dev/ttyUSB0
</code>
''Important Note 1''
Until now I have reported success for gcc-avr 4.5.1 and 4.5.3. But no success with 4.6.2.

I then had to modify [[HaikuVM.properties]] to adapt to '/dev/ttyUSB0' by changing this two lines for arduino:

<code bash>
...
arduino.Port = /dev/ttyUSB0
arduino.Upload = avrdude -pm328p -cstk500v1 -P$(HAIKU_PORT) -b57600 -Uflash:w:$(HAIKU_OUTPUT):a
...
</code>
Finally, I first proceeded step by step:
<code bash>
cd haikuVM/myCProject

/home/bob/haikuVM/bin/haikuc /home/bob/haikuVM/examples/src/main/java/arduino/tutorial/BlinkWithThread.java
/home/bob/haikuVM/bin/haikulink -v --Config arduino -o BlinkWithThread.hex /home/bob/haikuVM/examples/src/main/java/arduino/tutorial/BlinkWithThread 
/home/bob/haikuVM/bin/haikuupload BlinkWithThread.hex
</code>
Then I did it again but now, as an alternative, with a one-liner:
<code bash>
/home/bob/haikuVM/bin/haiku -v --Config arduino -o BlinkWithThread.hex /home/bob/haikuVM/examples/src/main/java/arduino/tutorial/BlinkWithThread
</code>
''Important Note 2''
Before you call any of these scripts mentioned above (haikuc, haikulink, haikuupload or haiku) make sure you are in an empty directory! Any empty directory will work, but I suggest to move (cd) into the prepared directory 'haikuVM/myCProject' which comes with the download.
Version 1.4.3
[[GettingStarted]]
[[Features]]
[[Release Notes]]
[[Command Line Options]]
[[Ideas and brainstorms]]
[[Code Size|Compact]]
[[Speed|Performance]]
[[Support|http://sourceforge.net/p/haiku-vm/tickets/]]
[[Arduino]]
[[Processing]]
[[Asuro Robot|Asuro]]
[[leJOS]]
[[Download|https://sourceforge.net/projects/haiku-vm/files/latest/download]]
[[Tutorials]]
[[Reported Usage]]
[[FAQ]]
[[Porting]]
[[Contributors]]
[[Sourceforge]]
[[Links]]
[[Contact]]
When it comes to microcontroller programming it is often necessary to have direct access to memory and microcontroler registers. Although against the spirit of JAVA but, having methods for memory access is convenient. ~HaikuVM supports two different techniques to access memory:
#Classic: ~HaikuVM offers native getter and setter methods to access memory.
#Annotational: ~HaikuVM allows to annotate static fields as ''@~NativeCVariable#''
!Classic: Getters and Setters
~HaikuVM offers native getter and setter methods to access memory.
<code java>
package haiku.vm;
public class MemoryAccess {
    public static native void   setMemory8(int adr, int int8);
    public static native void   setMemory16(int adr, int int16);
    public static native int    getMemory8(int adr);
    public static native int    getMemory16(int adr);
    
    ...
}
</code>
Armed with this set of methods and if you know the wanted memory addresses, it's easy to read out e.g. analog data from an ~ATmega8, without being forced to fall back to C code:
<code java>
    ...
    public static final long F_CPU   = 8000000L;
    public static final int REFS0    = 6;
    public static final int ADSC     = 6;
    public static final int ADIF     = 4;
    public static final int ADC      = (((0x04) + 0x20)); //16Bit
    public static final int ADCSRA   = (((0x06) + 0x20));
    public static final int ADMUX    = (((0x07) + 0x20));
    ...

    public static int ReadADC(int mux) {
        setMemory8(ADMUX, (1 << REFS0) | mux);              // voltage reference with external capacity
        setMem(ADCSRA, (1 << ADSC));                        // start the AD conversion

        while ((getMemory8(ADCSRA) & (1 << ADIF)) == 0)     // wait for the end of the AD conversion
            ;

        return getMemory16(ADC);                            // read 16Bit result
    }
</code>
Remark: It's not always easy to find out the proper addresses which are needed for the getter and setter methods.
!Annotational
Static variables annotated with ''@~NativeCVariable#'' (where # is one of 8, 16, 32 or 64) are directly mapped to (equal named and existing) C Variables. So ~HaikuVM will not allocate memory for this variables in the JAVA static memory space.
The example given for the 'Classic' technique may now be rewritten like this:
<code java>
    ...
    public static final long F_CPU  = 8000000L;
    public static final int REFS0   = 6;
    public static final int ADSC    = 6;
    public static final int ADIF    = 4;
    @NativeCVariable16 
    public static volatile int ADC;
    @NativeCVariable8 
    public static volatile int ADCSRA;
    @NativeCVariable8 
    public static volatile int ADMUX;
    ...

    public static int ReadADC(int mux) {
        ADMUX =  (1 << REFS0) | mux;            // voltage reference with external capacity
        ADCSRA |= (1 << ADSC);                  // start the AD conversion

        while ((ADCSRA & (1 << ADIF)) == 0)     // wait for the end of the AD conversion
            ;

        return ADC;                             // read 16Bit result
    }
</code>
Here the variables ADC, ADCSRA and ADMUX (with exactly this names) have to exist in the underlying C code or libraries. (This condition is fullfilled for AVR projects because this variables are declared somewhere in include files given for ~AVRs.)

Using this technique allows you to copy&past many C examples to JAVA.

I have to mention a common pitfall. Reading a 8Bit C variable into a JAVA int variable is possible. ~HaikVM handles the incoming 8Bit C value as a (signed) byte type which causes the sign to be propagated to the int. If this is not what you want then mask with 0xff. Like shown in the following snippet from a Two Wire module:
<code java>
    ...
    public static final int TWEA = 0x06;
    public static final int TWINT = 0x07;
    public static final int TWEN = 0x02;
    @NativeCVariable8 
    public static volatile int TWCR;
    @NativeCVariable8 
    public static volatile int TWDR;
    ...

    static int i2c_read_byte() {  
        TWCR = (1 << TWINT) | (1 << TWEA) | (1 << TWEN); // start data reception, transmit ACK  
        while (((TWCR & (1 << TWINT))==0));  
        return TWDR & 0xff; // mask with 0xff to unmask sign
    }  
</code>
!A Word of Warning
#The size of ~HaikuVM JAVA types like int and long depends on your [[Memory Mode|Configurable 64, 32 or 16 bit data types]]. Where the introduced memory access methods (see above) don't depend on this. For example, if you call getMemory16(..) the result is always truncated to 16 Bit independent of your selected [[Memory Mode|Configurable 64, 32 or 16 bit data types]]. In other words, type sizes of ~HaikuVM JAVA variables and C variables are independent.
#Native C variables are out of scope for the garbage collector. This means, be extra careful if you store object pointers into C variables.

!~HaikuVM Objects
Let's start by comparing two class definitions. The first one is a C struct, the second one is Java. They both declare the same member variables, with (mostly) the same types, the C struct describes the layout of a block of memory and ~HaikuVM tries to mimic this as close as possible (in contrast a classic Java class typically doesn't). The idea is to make the mapping to C as close as possible to simplify implementation and improve execution speed.
<code C>
struct {
  unsigned int x;
  unsigned int y;
} Coordinate;
</code>
<code Java>
class Coordinate {
  int x;
  int y;
}
</code>
In fact, ~HaikuVM maps this Java object to memory by generating a C typedef like this:
<code C>
struct {
  jint x;
  jint y;
} Coordinate;
</code>
In ~HaikuVM, objects are pointers to this memory structures.

~HaikuVM does not use the C heap and malloc(..) is not used to allocate memory for Java objects. Instead ~HaikuVM uses its own ~GCalloc(..) function to place Java objects on its own heap and puts meta information (memory size and Java class) just before this object memory layout. One way to express meta information plus object layout in C might look like this.
<code C>
typedef struct {
  jheapsize allocsize;
  jclass clazz;
  struct {
    jint x;
    jint y;
  } Coordinate;
} CoordinateWithHaikuVMOverhead;
</code>
Where
*''allocsize'' is the memory size in bytes including bytes needed for this header.
*''clazz'' is a pointer to the (flash) memory where the class of this object is described. See ''~HaikuVM Classes'' below.
In addition the most significant bit of ''allocsize'' is used to mark an object in the mark phase of [[garbage collection|Garbage collection]].
!~HaikuVM Array Objects
For example a Java array of N doubles 
<code Java>
  new double[N];
</code>
is dynamic mapped into heap memory like this:
<code C>
typedef struct {
  jheapsize allocsize;  // memory size is in bytes and including bytes needed for this header
  jclass clazz;
  struct {
    jint length;
    jdouble array[N];
  } jdoubleArrayMem;
} ADoubleArrayWithHaikuVMOverhead;
</code>
In C it's possible to place an already sized array into a struc.
<code C>
struct {
  int data[10];
} Data;
</code>
This isn't possible in ~HaikuVM. If you write this in Java:
<code Java>
class Data {
  int[] data= new int[10];
};
</code>
~HaikuVM will do something similar like this during compile time:
<code C>
typedef struct {
  jheapsize allocsize;
  jclass clazz;
  struct {
    jobject data;
  } Data;
} DataWithHaikuVMOverhead;
</code>
Where ''data'' is a pointer to a Java array object. Then the Java array object is allocated like this during run time:
<code C>
typedef struct {
  jheapsize allocsize;
  jclass clazz;
  struct {
    jint length;
    jint array[10];
  } jintArrayMem;
} AnIntArrayWithHaikuVMOverhead;
</code>
And the memory address of '~AnIntArrayWithHaikuVMOverhead.jintArrayMem' is assigned to (the C pointer) '~DataWithHaikuVMOverhead.Data.data' .
!~HaikuVM Classes
In ~HaikuVM a class definition is placed in flash memory (and not on the Java heap). Its layout is expressed like this:
<code C>
typedef struct class_t {
  const struct class_t * superClass;  // pointer to superclass (this class extends superClass)
  const jheapsize mem;                // size of object in bytes
  const uint8_t size;                 // length of msg2meth[]
  const msg2meth_t msg2meth[];        // msgIdx -> meth for every virtual method
} class_t;
</code>
And ''msg2meth'' is a direct C array (not a pointer to an array) with ''size'' entries. Containing the list of all (local) virtual Java methods of a class. Each array element looks like this:
<code C>
typedef struct {
  const uint8_t msgIdx;
  const ByteCode * meth;
} msg2meth_t;
</code>
Where ''msgIdx'' is the global unique message index (representing the signature of a method) of this virtual method and ''meth'' is a pointer to the bytecode of the [[method body|Compact HaikuVM Code]].
!~HaikuVM Stack
This is the declararion of a stack block:
<code C>
typedef struct {
  jint length;
  stack_t stack[N];
} stackFrame_t;
</code>
Where type stack_t is declared like this:
<code C>
typedef union {
  jboolean z;
  jbyte b;
  jchar c;
  jshort s;
  jint i;
  jfloat f;
  jobject a;
//for smooth debugging:
  void * v;
  char * ch;
  array_t * ay;
  HVM_String * str;
 // float: needed for conversion in LDC because of PROGMEM
  jint fl;
} stack_t;
</code>
In cases where two stack elements are involved to hold a value (double and long) the memory layout is cast like this:
<code C>
typedef union {
  struct {stack_t s0; stack_t s1;};
  jdouble d;
  julong dl; // double: used with LDC because of PROGMEM
  jlong j; // long
} top_t;
</code>
Stack blocks are allocated on the heap like ordenary objects (and it looks like any array):
<code C>
typedef struct {
  jheapsize allocsize;
  jclass clazz; // java.lang.Object
  jint length;
  stack_t stack[N];
} AHeapViewOfAStackBlock;
</code>
([[More ...|Stack Layout]])
!References
I recommend to read the very good article on this site http://www.kdgregory.com/index.php?page=java.byteBuffer
For example currentTimeMillis() is defined as ''native'' in java.lang.System:
<code java>
package java.lang;
...
public class System {
...
    /**
     * Returns the current time in milliseconds.
     * This is the number of milliseconds since the AVR has been on.
     */
    public static native long currentTimeMillis();
...
}
</code>

~HaikuVM produces the following snippet in file ./haikuVM/utility/haikuJNI.c for you.
<code c>
/*
 * Class:     java.lang.System
 * Method:    currentTimeMillis
 * Signature: ()J
 */
JNIEXPORT jlong Java_java_lang_System_currentTimeMillis
  (JNIEnv *, jclass);

JNIEXPORT jlong Java_java_lang_System_currentTimeMillis
  (JNIEnv *env, jclass obj)
{
    // TODO: insert your code here
    return 0;
}

/*
 * Proprietary HaikuVM stack to JNI interface function.
 * DO NOT EDIT THIS FUNCTION - it is machine generated.
 * 
 * Class:     java.lang.System
 * Method:    currentTimeMillis
 * Signature: ()J
 */
JNIEXPORT void native_java_lang_System_currentTimeMillis_J(void) {
    pushTop();    // Save variable top onto stack.
    {
        jclass     obj = NULL;
        JNIEnv     *env = NULL; // not used in HaikuVM
        top.j = Java_java_lang_System_currentTimeMillis(env, obj);
    }
    // Variable top holds the return value. But we have to push the lower half.
    pushTop0();
}
</code>
In this case C function //native_java_lang_~System_currentTimeMillis_J(void)// is the interface between the proprietary ~HaikuVM stack layout and the plain JNI C method //~Java_java_lang_System_currentTimeMillis(~JNIEnv *env, jobject obj)// which finally has to implement the basic functionality.

So, file ./haikuC/haikuJNI.c is a good resource for your C function templates because ~HaikuVM produces a snippet for ''every'' native JAVA method found in your program. It is is a slightly better solution than using the standard native-method-C-file-generator: ''javah.exe'' which ships with the SDK. Because it bridges the gap between JNI and the proprietary ~HaikuVM stack layout by generating //native_...(..)// C functions as well.

See also [[Tutorial JNI]].
!!2017/04/30: HaikuVM runs on the [[Raspberry Pi 3]]. 
!!2017/03/20: HaikuVM runs on the [[ESP8266 (ESP01)]]. 
!!2016/01/05: Published a DIY RCX 2.0 IR Programmer
* Because nowadays it's hard to get the RCX IR tower working, I developed an incredible simple Arduino based RCX 2.0 Programmer to be found [[here|https://github.com/BobGenom/arduino_sketches/tree/master/RCX2_IR_Programmer1]].
!!2015/12/27: In version 1.4.1 the RCX is supported
* The RCX 2.0 is supported. See [[Porting HaikuVM to the Lego RCX Brick]] and [[RCX 2.0]].
* Version 1.4.0 is released.
!!2015/08/20: The RCX is in my focus
* On my way to support a [[Lego RCX Brick|Porting HaikuVM to the Lego RCX Brick]].
!!2015/08/03: Progress in performance
*Introduced the ~AOTVariant ''~HAIKU_AOTThreadedAsCall'' and achieved a [[performance|Performance History]] boost of about 20%. ([[More ...|Ahead-of-time (AOT) compiler]])
!!2015/06/15: Improved this document.
*Described a known bug an how to fix it in the [[Release Notes]].
*Tried to make better documentation for [[Commands]].
*Defined and applied the tag 'commands'.
*Explained about and added a new FAQ about own workspaces and option ''"""--"""classpath''.
!!2015/06/06: Beyond JNI support
*Written a new tutorial [[Beyond JNI: put C code into your java files]] explaining the use of annotation member ''cImpl''.
!!2014/11/16: Improved this document.
*A new chapter about [[Porting]].
*A new chapter about [[Memory Layout of HaikuVM Objects]]
!!2014/11/06: Version 1.2.3 is released.
*Improved this HTML documentation.
*Now JNI support is very close to the standard [[JNI field access]]
*New support for ARDUINO IDE 1.5.8
**New support for ARDUINO Micro. Based on Leonardo support.
**Re-newed support for ARDUINO Leonardo
!!2014/07/24: Version 1.2.2 is released.
!!2014/04/12: Tested ~HaikuVM 1.2.2 pre-release with JAVA 8
* Now ~HaikuVM runs with JAVA 1.8.0_05.
!!2014/04/03: ~HaikuVM runs on an Attiny45
* For programming the Attiny45 in JAVA/~HaikuVM with the Arduino IDE, I followed this tutorial: http://highlowtech.org/?p=1695 <br>Then I wrote [['BlinkAttiny45.java'|https://sourceforge.net/p/haiku-vm/code/HEAD/tree/trunk/examples/src/main/java/processing/examples/_01_Basics/BlinkAttiny45.java]] - which blinks a LED on Pin 0 - as a proof of concept. Sadly, only 90 Bytes are left (out of 256 ~ATTiny45 RAM) for the JAVA/~HaikuVM heap.
!!2014/03/01: Version 1.2.1 is released.
* Fixed minor configuration odds.
!!2014/01/20: Version 1.2.0 is released.
* Better and inovative Panic Support using an extra panic room (if configured) on the heap. ([[More ...|Panic Support]])
!!2013/11/26
* I tested the YĂºn successfully with ~HaikuVM and [[Arduino IDE]]! (Since some days I'm the proud owner of a YĂºn.)
!!2013/11/16: Version 1.1.1 is released.
* Enabled ~HaikuVM for JAVA 7.
* Integration with Arduino IDE 1.5 (and Arduino Due).
* Checked against many tests coming from [[Darjeeling|http://darjeeling.sourceforge.net/]] (or ~TakaTuka?)
!!2013/10/23
* Added a [[Wish List]].
!!2013/10/20: Version 1.1.0 is released.
*Reshaped JAVA object layout (structs) to support seamless integration with native C structs.<br> See this wonderful explanation in [[The Organization of Objects|http://www.kdgregory.com/index.php?page=java.byteBuffer]] to understand the problem behind the sceens.
!!2013/09/27: Support for the Arduino IDE
*See here [[Arduino IDE]]
!!2013/08/21: More complete documentation
*New Tutorial [[JNI field access]]
*Enhanced [[Tutorial Blink]]
*Enhanced [[Tutorial JNI]]
!!2013/08/04: Version 1.0.4 is released.
If you want to test ~HaikuVM but you don't have a microcontroller, here are two ways to get your first impression:
*Support for Windows as target. ([[More ...|Visual Studio]])
*Support for Ubuntu as target. ([[More ...|Ubuntu]])
!!2013/07/14: Version 1.0.3 is released.
Including examples given for an article in ''javamagazine''. ([[More ...|Javamagazine Examples]])
Full support for Leonardo. ([[More ...|Leonardo]])
Annotations ''@~NativeCFunction'' and ''@~NativeCppFunction'' to refer seamless to given C/C++ functions. ([[More ...|Tutorial JNI]])
!!2013/03/03: Version 1.0.2 is released. 
Including a tutorial about JNI. ([[More ...|Tutorials]])
!!2013/02/09: Better Linux support. 
Tested on UBUNTU 12.04 LTE. ([[More ...|Linux]])
!!2013/01/01: Single line command interface
Enter one line to compile, upload and run your JAVA program (let's say '~BlinkWithThread') to an Arduino connected on port com5:
<code bash>
cd haikuVM\myCProject
C:\haikuVM\bin\haiku -v --Config arduino --Config:Port com5 -o BlinkWithThread.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\BlinkWithThread.java
</code>
Or Linux:
<code bash>
cd haikuVM/myCProject
/home/bob/haikuVM/bin/haiku -v --Config arduino --Config:Port /dev/ttyUSB0 /home/bob/haikuVM/examples/src/main/java/arduino/tutorial/BlinkWithThread.java 
</code>

!!2013/01/01: Direct access to memory and microcontroller registers
Static fields annotated with ''@~NativeCVariable#'' (where # is one of 8, 16, 32 or 64) are directly mapped to (equal named and existing) C variables. ([[More ...|Memory Access]])
<code java>
    ...
    public static final int UDRE0 = 5;
    @NativeCVariable8 // tells HaikuVM to map UCSR0A to a 8Bit C variable called UCSR0A 
    public static volatile int UCSR0A;
    @NativeCVariable8 // tells HaikuVM to map UDR0 to a 8Bit C variable called UDR0
    public static volatile int UDR0;
    ...
    public void write(int b) {
        while ( (UCSR0A & (1 << UDRE0)) == 0 ) /*poll*/ ;
        UDR0=b;
    };
</code>
Most of the code written for microcontrollers was originally written in C. This direct access to memory technique allows you to virtually copy&past this to JAVA.

!Overview
During runtime, ~HaikuVM is able to check for odd JVM conditions and, if detected, throws an exception. This exceptions are thrown from within the JVM kernel and not from your code. Following a tradition this state is often called panic which is a short for kernel panic. In a full panic aware ~HaikuVM one of the following 10 exceptions are thrown by the JVM, corresponding to the reason of panic:
<<tiddler PanicExceptions>>But for a microcontroller a full blown panic support might be overkill with respect to the given resources. Many people who program a  microcontroller  in plain C/C++ are checking only for relevant conditions by hand e.g. on null-pointer or array-index-out-of-bounds conditions. Some do not check at all or neglect to check. If an odd condition happens the program chrashes. In many circumstances you can live with this. ~HaikuVM gives you the chance to configure and even program your needs.

!Mode: No Panic Support
For having no panic support at all set the following configuration ([[read more about configuration ...|HaikuVM.properties]])
*~PanicSupport = 0
*~PanicExceptions = 0x0
No C/C++ code for any panic condition is included in the ~HaikuVM (~PanicExceptions = 0x0).
If any of this conditions will occur during runtime, your program is likely to crash. On the other hand, in this mode, the ~HaikuVM code is very dense and, because all runtime panic checks are missing, the fastest code possible.
There is no need for your panic handler and therefore it is not included (~PanicSupport = 0).
Configure this mode if your program is tested very well and you don't expect any panic condition to appear during runtime.

!Mode: Simple Panic Support
For having simple panic support set the following configuration
*~PanicSupport = 0
*~PanicExceptions = <list some exceptions here>
A reasonable setting could be this:
*~PanicExceptions = ~NullPointerException | ~NoSuchMethodError | ~OutOfMemoryError | ~ClassCastException
C/C++ code for the selected panic conditions is included in the ~HaikuVM.
If any of this conditions will occur during runtime, ~HaikuVM will detect this because ~HaikuVM is adviced to activate C/C++ code to detect this. But ~HaikuVM will ''not'' throw the indended exception. Instead ~HaikuVM will unwind the runtime stack for the current thread (silently) and - as a "poor mans" fallback - will ''continue'' execution in the main(..) or run() method. This is because you decided to not use a panic handler (~PanicSupport = 0).

!Mode: Panic Support and the Panic Room
For having flexible or full blown panic support set the following configuration
*~PanicSupport = 1
*~PanicExceptions = <list some exceptions here>
A full blown setting is this:
*~PanicExceptions = ~NullPointerException | ~ArrayStoreException | ~IndexOutOfBoundsException | ~NoSuchMethodError | ~StackOverflowError | ~OutOfMemoryError | ~ClassCastException | ~ArrayIndexOutOfBoundsException | ~InternalError | ~ArithmeticException
or for short:
*~PanicExceptions = 0xffff
C/C++ code for detecting the selected panic conditions is included in the ~HaikuVM.
Therefore, if any of this conditions will occur during runtime, ~HaikuVM will detect this and will call ''your'' panic handler function, written as Java method panic(..) with the following panic values:
|~HaikuVM Panic Value|Intended exception to be thrown|
| 2 |~NullPointerException|
| 4 |~ArrayStoreException|
| 8 |~IndexOutOfBoundsException|
| 16 |~NoSuchMethodError|
| 32 |~StackOverflowError|
| 64 |~OutOfMemoryError|
| 128 |~ClassCastException|
| 256 |~ArrayIndexOutOfBoundsException|
| 512 |~InternalError|
| 1024 |~ArithmeticException|
What really happens in the body of panic(..) is up to you. Typically your code will instantiate the proper Exception object and throws it. That's all!

Sounds easy, but from here things can go worse. Imagine that memory is low and you run out of memory just while instantiating the requested, let's say, ~NullPointerException. Or even worse, there is no space to call your panic handler function at all. This is, what I call real panic. Now, what you need is memory to fullfill your mission. For this situation ~HaikuVM invented the ''panic room''. The field ''panicRoom'' may hold an arbitrary JAVA object e.g. an Array of Bytes where you reserve some memory for this critial case. 

In the case of ~StackOverflowError or ~OutOfMemoryError, the only thing ~HaikuVM does before calling your panic(..) method is, to set field panicRoom=null, with the intention to release this memory to let your panic(..) method have some room to execute. If this does not help (e.g. panicRoom space was to low to support full panic(..) execution) ~HaikuVM falls back to ''Simple Panic Support''.

A running ''example'' of a panic(..) method can be seen in ''[[haiku.vm.MicroKernel|http://sourceforge.net/p/haiku-vm/code/HEAD/tree/trunk/bootstrap/src/main/java/haiku/vm/MicroKernel.java]]''. Just overwrite this code to change the behavior to your needs.
*~ArithmeticException
*~ArrayIndexOutOfBoundsException
*~ArrayStoreException
*~ClassCastException
*~IndexOutOfBoundsException
*~InternalError
*~NoSuchMethodError
*~NullPointerException
*~OutOfMemoryError
*~StackOverflowError
!General
The former Java virtual machines (which are Java virtual machines without ~HotSpot technique), which simply interpreted bytecodes one at a time, were clocked at 30 to 50 times slower than natively compiled C++. Just-in-time (JIT) compilers have narrowed the performance gap to 3 to 10 times slower than C++. Current Java virtual machines come with ~HotSpot technique, which makes them par with or better then natively compiled C++ [[[1]|http://www.artima.com/designtechniques/hotspot.html]].

~HaikuVM is a Java virtual machine, which simply interpretes bytecodes one at a time. So don't expect miracles in speed.

Here we start with performance of ~HaikuVM (Revision 52). But you may also take a look into chapter [[Performance History]] to see development along revisions. And you might be interested to compare it with [[others|Performance Others]].
 

!Performance of ~HaikuVM (Revision 52)
The performance test was made on an ''Atmega328p'' 16Mhz with the following JAVA program:
<code java>
public class Fibonacci32Bit {
  static int fib(int n) {
    if(n < 2)
      return 1;
    else
      return fib(n-2) + fib(n-1);
  }

  public static void main(String[] args) {
    long t0 = System.currentTimeMillis();
    for(int i=0;i<=30;i++)
      System.out.println("Fibonacci of "+i+" is "+fib(i)+" in "+(System.currentTimeMillis()-t0)+" ms");
  }
}
</code>
The program is located at '.\haikuBench\src\main\java\haikuvm\bench\~Fibonacci32Bit.java'.
The program was compiled, linked und uploaded as follows:
<code bash>
C:\haikuVM\bin\haiku --Config arduino --Mode 32/64 C:\haikuVM\haikuBench\src\main\java\haikuvm\bench\Fibonacci32Bit
</code>
During cross compiling with ~WinAVR 20100110 the optimization level was set for size: -Os
Result:
<code bash>
Fibonacci of 0 is 1 in 73 ms
Fibonacci of 1 is 1 in 127 ms
Fibonacci of 2 is 2 in 194 ms
Fibonacci of 3 is 3 in 261 ms
Fibonacci of 4 is 5 in 326 ms
Fibonacci of 5 is 8 in 391 ms
Fibonacci of 6 is 13 in 458 ms
Fibonacci of 7 is 21 in 535 ms
Fibonacci of 8 is 34 in 610 ms
Fibonacci of 9 is 55 in 694 ms
Fibonacci of 10 is 89 in 787 ms
Fibonacci of 11 is 144 in 888 ms
Fibonacci of 12 is 233 in 1010 ms
Fibonacci of 13 is 377 in 1167 ms
Fibonacci of 14 is 610 in 1369 ms
Fibonacci of 15 is 987 in 1653 ms
Fibonacci of 16 is 1597 in 2046 ms
Fibonacci of 17 is 2584 in 2633 ms
Fibonacci of 18 is 4181 in 3538 ms
Fibonacci of 19 is 6765 in 4934 ms
Fibonacci of 20 is 10946 in 7133 ms
Fibonacci of 21 is 17711 in 10643 ms
Fibonacci of 22 is 28657 in 16259 ms
Fibonacci of 23 is 46368 in 25300 ms
Fibonacci of 24 is 75025 in 39851 ms
Fibonacci of 25 is 121393 in 63353 ms
Fibonacci of 26 is 196418 in 101303 ms
Fibonacci of 27 is 317811 in 162640 ms
Fibonacci of 28 is 514229 in 261832 ms
Fibonacci of 29 is 832040 in 422249 ms
Fibonacci of 30 is 1346269 in 681731 ms
</code>
So this JAVA program running with ~HaikuVM Revision 52 needed ''681731 ms'' for fib(30). ([[Compare with results from newer revisions.|Performance History]])


!!Compared with plain C running on ARDUINO Duemilanove

This is the competing C program for fib(30):
<code c>
int32_t fib(int32_t n) {
	if(n < 2) 
	  return 1;
	else
	  return fib(n-2) + fib(n-1);
} 

int main() {
	int32_t i;
	long t0 = millis();
	for(i=0;i<=30;i++) {
          printf("Fibonacci of %ld is %ld in %ld ms\n", i, fib(i), (long)(millis()-t0));
	}
	return 0;
}
</code>
This C program, again compiled with ~WinAVR 20100110 -Os (optimize for size), needed ''19494 ms'' and compiled with -O3 (optimize for speed) needed ''16825 ms''.

Conclusion: This (specific) plain C program is ''35 (or 41) times faster'' than the corresponding JAVA program runnning with ~HaikuVM.

!!Compared with leJOS on NXJ

Because ~HaikuVM is not ported on NXJ (until now), I had to compare it in an indirect way. For this I put a question about performance into the leJOS forum ([[see ...|http://lejos.sourceforge.net/forum/viewtopic.php?f=7&t=2989&p=14800&hilit=performance#p14800]]).

Thankfully I got this answer:
"Anyway it turns out that ~RobotC like NXC does not support recursion so the fib test is not looking like a good test case. But I ran it anyway in Java the total time taken for up to and including fib 30 is ''197566'', the same code in gcc based C takes ''3432ms'', so the native C code in this instance is ''57 times faster''."

So there is a chance that ~HaikuVM would be faster than leJOS by a factor of 1,6 (=57/35) or 1,4. But this comparision must be taken with care.

!!Compared with leJOS on RCX

|!Programming Language|!Time [ms]|!~AOTVariant|
|!C (h8300-hms-gcc)| 150200||
|!~LeJOS 2.1.0| 2776000|Bytecode in a switch|
|!~HaikuVM 1.4.0| 1965000|~HAIKU_AOTBytecodeAsJump|


!!Compared with JAVA 1.6 under Windows XP 32Bit
The program was compiled and linked as follows:
<code bash>
haiku -target WIN32 -r Fibonacci32Bit
</code>
I used the Microsoft Visual C++ 2005 compiler. The final runtime was ''1204 ms'' on my computer.

Pure JAVA 1.6 needed ''656 ms''. To be fair I ran it in pure interpreter mode like this:
<code bash>
java -Xint Fibonacci32Bit
</code>

Conclusion: ~HaikuVM is about a factor of 2 slower than pure JAVA (interpreting). Not bad for an application not using assembler and using a data alignment set to 1 byte.
 
Because I was curious I ran it with JAVA 1.6 Hotspot and it needed only ''47ms'' for fib(30) on my computer.



Cross compiled with ~WinAVR 20100110 the optimization level was set for size: -Os ([[More ...|Performance]])
!Quick Overview
|!Revision|!Program Size|!Data Size|!Time [ms]|!~AOTVariant|
|684|21866|1841|467121|~HAIKU_AOTThreadedAsCall|
|684|20090 |1841|496587|~HAIKU_AOTBytecodeAsSwitch|
|606|20068|1841|507281|~HAIKU_AOTBytecodeAsJump|
|232|19656|1834|526701|~HAIKU_AOTBytecodeAsJump|
|180|19636|1834|544781|~HAIKU_AOTBytecodeAsJump|
|52|?|?|681731|~HAIKU_AOTBytecodeAsJump|


!Revision 684 fib(30) with ~HAIKU_AOTThreadedAsCall
Program:   21866 bytes
Data:       1841 bytes
<code bash>
Fibonacci of 0 is 1 in 78 ms
Fibonacci of 1 is 1 in 125 ms
Fibonacci of 2 is 2 in 176 ms
Fibonacci of 3 is 3 in 236 ms
Fibonacci of 4 is 5 in 289 ms
Fibonacci of 5 is 8 in 348 ms
Fibonacci of 6 is 13 in 404 ms
Fibonacci of 7 is 21 in 470 ms
Fibonacci of 8 is 34 in 531 ms
Fibonacci of 9 is 55 in 605 ms
Fibonacci of 10 is 89 in 682 ms
Fibonacci of 11 is 144 in 763 ms
Fibonacci of 12 is 233 in 864 ms
Fibonacci of 13 is 377 in 982 ms
Fibonacci of 14 is 610 in 1132 ms
Fibonacci of 15 is 987 in 1336 ms
Fibonacci of 16 is 1597 in 1625 ms
Fibonacci of 17 is 2584 in 2042 ms
Fibonacci of 18 is 4181 in 2672 ms
Fibonacci of 19 is 6765 in 3645 ms
Fibonacci of 20 is 10946 in 5174 ms
Fibonacci of 21 is 17711 in 7600 ms
Fibonacci of 22 is 28657 in 11459 ms
Fibonacci of 23 is 46368 in 17663 ms
Fibonacci of 24 is 75025 in 27653 ms
Fibonacci of 25 is 121393 in 43750 ms
Fibonacci of 26 is 196418 in 69752 ms
Fibonacci of 27 is 317811 in 111752 ms
Fibonacci of 28 is 514229 in 179661 ms
Fibonacci of 29 is 832040 in 289487 ms
Fibonacci of 30 is 1346269 in 467121 ms
</code>

!Revision 684 fib(30) with ~HAIKU_AOTBytecodeAsSwitch
Program:   20090 bytes (61.3% Full)
Data:       1841 bytes (89.9% Full)
<code bash>
Fibonacci of 0 is 1 in 79 ms
Fibonacci of 1 is 1 in 132 ms
Fibonacci of 2 is 2 in 188 ms
Fibonacci of 3 is 3 in 253 ms
Fibonacci of 4 is 5 in 311 ms
Fibonacci of 5 is 8 in 367 ms
Fibonacci of 6 is 13 in 437 ms
Fibonacci of 7 is 21 in 498 ms
Fibonacci of 8 is 34 in 571 ms
Fibonacci of 9 is 55 in 637 ms
Fibonacci of 10 is 89 in 713 ms
Fibonacci of 11 is 144 in 806 ms
Fibonacci of 12 is 233 in 914 ms
Fibonacci of 13 is 377 in 1041 ms
Fibonacci of 14 is 610 in 1196 ms
Fibonacci of 15 is 987 in 1417 ms
Fibonacci of 16 is 1597 in 1723 ms
Fibonacci of 17 is 2584 in 2168 ms
Fibonacci of 18 is 4181 in 2838 ms
Fibonacci of 19 is 6765 in 3873 ms
Fibonacci of 20 is 10946 in 5495 ms
Fibonacci of 21 is 17711 in 8066 ms
Fibonacci of 22 is 28657 in 12173 ms
Fibonacci of 23 is 46368 in 18770 ms
Fibonacci of 24 is 75025 in 29378 ms
Fibonacci of 25 is 121393 in 46496 ms
Fibonacci of 26 is 196418 in 74140 ms
Fibonacci of 27 is 317811 in 118791 ms
Fibonacci of 28 is 514229 in 190990 ms
Fibonacci of 29 is 832040 in 307736 ms
Fibonacci of 30 is 1346269 in 496587 ms
</code>

!Revision 606 fib(30)
Program:   20068 bytes (61.2% Full)
Data:       1841 bytes (89.9% Full)
<code bash>
Fibonacci of 0 is 1 in 79 ms
Fibonacci of 1 is 1 in 132 ms
Fibonacci of 2 is 2 in 188 ms
Fibonacci of 3 is 3 in 253 ms
Fibonacci of 4 is 5 in 311 ms
Fibonacci of 5 is 8 in 368 ms
Fibonacci of 6 is 13 in 438 ms
Fibonacci of 7 is 21 in 502 ms
Fibonacci of 8 is 34 in 575 ms
Fibonacci of 9 is 55 in 640 ms
Fibonacci of 10 is 89 in 716 ms
Fibonacci of 11 is 144 in 809 ms
Fibonacci of 12 is 233 in 917 ms
Fibonacci of 13 is 377 in 1037 ms
Fibonacci of 14 is 610 in 1205 ms
Fibonacci of 15 is 987 in 1427 ms
Fibonacci of 16 is 1597 in 1741 ms
Fibonacci of 17 is 2584 in 2196 ms
Fibonacci of 18 is 4181 in 2878 ms
Fibonacci of 19 is 6765 in 3930 ms
Fibonacci of 20 is 10946 in 5587 ms
Fibonacci of 21 is 17711 in 8215 ms
Fibonacci of 22 is 28657 in 12410 ms
Fibonacci of 23 is 46368 in 19145 ms
Fibonacci of 24 is 75025 in 29989 ms
Fibonacci of 25 is 121393 in 47470 ms
Fibonacci of 26 is 196418 in 75702 ms
Fibonacci of 27 is 317811 in 121329 ms
Fibonacci of 28 is 514229 in 195080 ms
Fibonacci of 29 is 832040 in 314359 ms
Fibonacci of 30 is 1346269 in 507281 ms
</code>
!Revision 232 fib(30)
Program:   19656 bytes (60.0% Full)
Data:       1834 bytes (89.6% Full)
<code bash>
Fibonacci of 0 is 1 in 87 ms
Fibonacci of 1 is 1 in 147 ms
Fibonacci of 2 is 2 in 207 ms
Fibonacci of 3 is 3 in 268 ms
Fibonacci of 4 is 5 in 331 ms
Fibonacci of 5 is 8 in 392 ms
Fibonacci of 6 is 13 in 459 ms
Fibonacci of 7 is 21 in 527 ms
Fibonacci of 8 is 34 in 597 ms
Fibonacci of 9 is 55 in 672 ms
Fibonacci of 10 is 89 in 755 ms
Fibonacci of 11 is 144 in 863 ms
Fibonacci of 12 is 233 in 976 ms
Fibonacci of 13 is 377 in 1117 ms
Fibonacci of 14 is 610 in 1282 ms
Fibonacci of 15 is 987 in 1508 ms
Fibonacci of 16 is 1597 in 1839 ms
Fibonacci of 17 is 2584 in 2316 ms
Fibonacci of 18 is 4181 in 3023 ms
Fibonacci of 19 is 6765 in 4126 ms
Fibonacci of 20 is 10946 in 5855 ms
Fibonacci of 21 is 17711 in 8580 ms
Fibonacci of 22 is 28657 in 12938 ms
Fibonacci of 23 is 46368 in 19941 ms
Fibonacci of 24 is 75025 in 31202 ms
Fibonacci of 25 is 121393 in 49355 ms
Fibonacci of 26 is 196418 in 78669 ms
Fibonacci of 27 is 317811 in 126030 ms
Fibonacci of 28 is 514229 in 202598 ms
Fibonacci of 29 is 832040 in 326417 ms
Fibonacci of 30 is 1346269 in 526701 ms
</code>
!Revision 180 fib(30)
Program:   19636 bytes (59.9% Full)
Data:       1834 bytes (89.6% Full)
<code bash>
Fibonacci of 0 is 1 in 99 ms
Fibonacci of 1 is 1 in 163 ms
Fibonacci of 2 is 2 in 229 ms
Fibonacci of 3 is 3 in 293 ms
Fibonacci of 4 is 5 in 354 ms
Fibonacci of 5 is 8 in 420 ms
Fibonacci of 6 is 13 in 484 ms
Fibonacci of 7 is 21 in 562 ms
Fibonacci of 8 is 34 in 636 ms
Fibonacci of 9 is 55 in 713 ms
Fibonacci of 10 is 89 in 815 ms
Fibonacci of 11 is 144 in 912 ms
Fibonacci of 12 is 233 in 1026 ms
Fibonacci of 13 is 377 in 1181 ms
Fibonacci of 14 is 610 in 1360 ms
Fibonacci of 15 is 987 in 1598 ms
Fibonacci of 16 is 1597 in 1943 ms
Fibonacci of 17 is 2584 in 2432 ms
Fibonacci of 18 is 4181 in 3173 ms
Fibonacci of 19 is 6765 in 4312 ms
Fibonacci of 20 is 10946 in 6084 ms
Fibonacci of 21 is 17711 in 8912 ms
Fibonacci of 22 is 28657 in 13429 ms
Fibonacci of 23 is 46368 in 20669 ms
Fibonacci of 24 is 75025 in 32314 ms
Fibonacci of 25 is 121393 in 51088 ms
Fibonacci of 26 is 196418 in 81401 ms
Fibonacci of 27 is 317811 in 130386 ms
Fibonacci of 28 is 514229 in 209579 ms
Fibonacci of 29 is 832040 in 337641 ms
Fibonacci of 30 is 1346269 in 544781 ms
</code>
!cygwin 32/64 (pc14)
:fib(35): Is 'haikuvm.bench.~Fibonacci32Bit' tweaked to calculate all Fibonacci numbers up to 35.
|!Name|!Type|!Heap|!fib(35)|!Comment|
|!JVM 7|hotspot|| 0.430s|
|!gcc 4.3.2|compiled -O0|| 1.302s|~Fibonacci32Bit written in C for reference|
|!HVM 2.1.19|compiled -O0|300000| 2.807s|
|!|||||
|!JVM 7|interpret (-Xint)|| 5.547s|
|!~HaikuVM r684|interpret -O3|300000| 9.325s|~HAIKU_AOTBytecodeAsSwitch|
|!~HaikuVM r684|interpret -O3|300000| 10.915s|~HAIKU_AOTThreadedAsCall|
|!HVM 2.1.19|interpret -O3|300000| 12.749s|
|!~HaikuVM r610|interpret -O3|300000| 13.194s|~HAIKU_AOTBytecodeAsJump|
|!~HaikuVM r684|interpret -O0|300000| 15.841s|~HAIKU_AOTThreadedAsCall|
|!~HaikuVM r684|interpret -O0|300000| 17.335s|~HAIKU_AOTBytecodeAsSwitch|
|!~HaikuVM r610|interpret -O0|300000| 22.340s|~HAIKU_AOTBytecodeAsJump|
|!HVM 2.1.19|interpret -O0|300000| 27.971s|
!General
Performance of ~HaikuVM 1.4.2 compared with [[micropython|https://micropython.org/]].

!Performance Test
On https://github.com/micropython/micropython/wiki/Performance I found the following performance test program given by Metallicow.

''Micro Python v1.0.1 on 2014-05-12; ~PYBv1.0 with ~STM32F405RG on Teensy 3.1: (96Mhz ARM)''
<code java>
def performanceTest():
    millis = pyb.millis
    endTime = millis() + 10000
    count = 0
    while millis() < endTime:
        count += 1
    print("Count: ", count)
performanceTest() 
</code>
''Count: 1,098,681''
!
Metallicow compared it with the following processing program on the same hardware plattform.
''C++ on Teensy 3.1: (96Mhz ARM)''
<code java>
#include <Arduino.h>  
void setup() {  
    Serial1.begin(115200);  
    uint32_t endTime = millis() + 10000;  
    uint32_t count = 0;  
    while (millis() < endTime)  
        count++;  
    Serial1.print("Count: ");  
    Serial1.println(count);  
}  
void loop() {  
}  
</code>
''Count: 95,835,923''

''Conclusion:'' Processing/C++ is 87.2 times faster then Micro Python.
 
!
I repeated this with ~ArduinoIDE 1.8.1 for my:
''Arduino Uno (16 ~MHz Atmega328) with C++''
<code java>
void setup() {  
    Serial.begin(57600);  
    uint32_t endTime = millis() + 10000;  
    uint32_t count = 0;  
    while (millis() < endTime)  
        count++;  
    Serial.print("Count: ");  
    Serial.println(count);  
}  
void loop() {  
}  
</code>
''Count: 5,130,033''
!
And finally compared it with ~HaikuVM 1.4.2 using ~ArduinoIDE 1.8.1 for my:
''~HaikuVM on Arduino Uno: (16 ~MHz Atmega328)''
<code java>
public class PerformanceTestMetallicow {
	public static void main(String[] args) {
	    long endTime = System.currentTimeMillis() + 10000;
	    long count = 0;
	    while (System.currentTimeMillis() < endTime)
	        count++;
	    System.out.println("Count: "+count);
	}
}
</code>
''Count: 104,527''

FYI: I haikufied like this:
<code bash>
cd C:\Arduino-1.8.1\libraries
C:\HaikuVM\bin\haiku -v --Config arduinoIDEWithMainUsingSystemUpload --Config:Mode 32/32 "C:\HaikuVM\haikuBench\src\main\java\haikuvm\bench\PerformanceTestMetallicow.java"
</code>

''Conclusion:'' Processing/C++ is 49.1 times faster then ~HaikuVM.

!General
Some words on porting to C++ compiler platforms. First, you will find some pre-configurate targets in [[HaikuVM.properties]]. You may use this to find a template for a new target. For new platforms you have to keep this in mind:

!!!Include Path
* all: ''./utility''

!!!Data Alignment
~HaikuVM likes a packed data alignment of 1 byte.
*win-avr: ''-fpack-struct''
*gcc: ''-fpack-struct=1''
*visual C:  ''-Zp1''
But, for example, with the compiler for the Hitachi H8/300 CPU in the Lego RCX brick (GNU h8300-hms-gcc 3.3.1), I hade problems when packing structs: "error: initializer for integer value is too complicated". So,  ~HaikuVM has to support other data alignments. For example use:
*''"""--"""Config:Align 2'' with h8300-hms-gcc
or e.g. others
*''"""--"""Config:Align 4'' if you experiment with visual C compiler option ''-Zp4''.
An other example is, when compiling with the Arduino IDE, setting compiler options is not feasible (e.g. with the esp8266 port), then ~HaikuVM alignment can be adapted by setting the ''Align'' config option.

!!!Delete unused Code and Data
Some compilers can be command to keep code size and data size small by deleting unused functions and data. Which is of some importance on small micro controllers.
*win-avr: ''-ffunction-sections -fdata-sections''
*gcc: ''"""--"""gc-sections''
The h8300-hms-gcc 3.3.1 does not support this. In this case, I build an archive from the source and link against this archive to get the same effect.

!!!Compiler Errors to Warnings
*visual C: ''-D_~CRT_SECURE_NO_WARNINGS''

!Example: Porting to Duemilanove on a Raspberry Pi 3

*First download ~HaikuVM into directory {{{/home/pi/haikuVM}}}.
*Second download the AVR cross compiler. Typically it installs itself in {{{/usr/bin}}}.
*Connect your Duemilanove to your Raspberry Pi. Typically it then will be accessible by {{{/dev/ttyACM0}}}.

After you have installed all needed software (see also GettingStarted) you are prepared to run the ''~BlinkSimple'' program on your Duemilanove (e.g. ~ATmega328p).
<<tiddler avr.tutorial.BlinkSimple>>

Because we cross compile from Raspberry Pi 3 to the Duemilanove we decided to call our configuration {{{pi.duemilanove}}}. Add the following lines to [[HaikuVM.properties]] to adapt to your configuration:
{{{
pi.duemilanove.Extends = avr
pi.duemilanove.Target = atmega328p
pi.duemilanove.CC = /usr/bin/avr-gcc
pi.duemilanove.CXX = /usr/bin/avr-g++
pi.duemilanove.LINKER = /usr/bin/avr-g++
pi.duemilanove.Upload = /usr/bin/avrdude -p $(HAIKU_TARGET) -c arduino -P $(HAIKU_PORT) -b 115200 -U flash:w:$(HAIKU_OUTPUT)
}}}
Because we let inherit (//Extends//) the new configuration from {{{avr}}} we only have to configure a few properties like //Target//, //CC//, //CXX//, //LINKER// and //Upload// to adapt to the AVR cross compiler on the Raspberry.

To complete, you have to proceed with the following steps to prepare and let the ''~BlinkSimple'' program run on your Duemilanove.
<code bash>
cd /home/pi/haikuVM/myCProject
/home/pi/haikuVM/bin/haiku -v --Config pi.duemilanove --Config:Port /dev/ttyACM0 /home/pi/haikuVM/examples/src/main/java/avr/tutorial/BlinkSimple.java
</code>

An hommage to the leJOS team who developed the java class library I took advantage of.
Or my long way to support a Lego RCX Brick.
!The goal
I own an old "Robotics Invention System 2.0" (RIS 2.0) with an USB IR Tower. I want to port HaikuVM to the (yellow) Lego RCX brick (RCX for short) which is delivered with this RIS 2.0. This are the planed steps to go:
#Install RIS 2.0 and make a smoke test to check if everything is running.
#Install leJOS and make a smoke test to check if everything is running.
#Port HaikuVM to the RCX.
#Run some benchmarks with HaikuVM and leJOS and compare them.
!Install RIS 2.0 and make a smoke test
First, I tried it on my new Windows 7 64 Bit System (~WIN7PC). It turns out that there is no 64 Bit driver for the USB Tower to be found.

Second, I tried it on an old XP 32 Bit computer (~PC14). I had no luck. I could install RIS 2.0 but XP hangs whenever I start the RIS 2.0.

Third, I tried it on another even older XP 32 Bit hardware (~OLDPC14). With this I had luck. The RIS 2.0 did start. It found that no firmware is loaded on the RCX and automaticaly offered and started a firmware upload to the RCX via the USB IR tower. This succeeded without any problem. After this I was able to program a little melodie with the RIS 2.0 and uploaded the program to the RCX which finally started to play the tones autonomiously.

(Sadly it only installed and ran with administrator rights.)

!Install leJOS and make a smoke test
I followed this intructions http://www.lejos.org/tutorial/getstarted/firstbrick/win32.html
!!leJOS 3.0.0rc2
I downloaded ''leJOS 3.0.0rc2'' from [[here|http://sourceforge.net/projects/rcx.lejos.p/files/lejos-win32/3.0.0rc2/]] and installed it at ~OLDPC14 into directory:
C:\lejos_rcx

Tipp: You need to install the original USB IR tower driver from the RIS 2.0 CD.
Tipp: You need a java 32 Bit JDK in your PATH.

Then I started like this:
<code bash>
set LEJOS_HOME=C:\lejos_rcx
set PATH=%PATH%;%LEJOS_HOME%\bin
set CLASSPATH=%CLASSPATH%;.;%LEJOS_HOME%/lib/classes.jar;%LEJOS_HOME%/lib/pcrcxcomm.jar
set RCXTTY=usb
cd %LEJOS_HOME%\bin
firmdl.bat
</code>
And got this response:
<code bash>
read firmware srec
  100%
Installing firmware
Loading native libs
Deleting firmware
Firmware deleted
Downloading firmware
  100%
Firmware downloaded
Unlocking firmware
Unlock firmware failed: Tower error: no response from rcx
</code>
Sadly this finally failed! (Some say the reason is low battery but this was not the case.)

!!leJOS 2.1.0
I felt back to download ''leJOS 2.1.0'' from [[here|http://sourceforge.net/projects/rcx.lejos.p/files/lejos-win32/2.1.0]] and installed it (again) at ~OLDPC14 into directory:
C:\lejos_rcx

When "firmdl.bat" started it hangs without any response. Even worse, I was not able to kill this process. Instead I had to hard restart the computer (pushing the power off button).

Then I tried "lejosfirmdl.exe" because I read that this is an older non-java substitute for "firmdl.bat". It succeed, but for unknown reason I needed 3 tries to succeed. (Sometimes I found a task called "lejosrun.exe" running (what is it?). Sometimes killing this task with "taskkill /IM lejosrun.exe" helped, sometimes not. In the later case I had to hard (!) restart the computer to get rid of it.)

<code bash>
C:\leJOS_RCX\bin>lejosfirmdl -f
Use --help for options.
segment.length[0] = 13686 (14k)
segment.length[1] = 2938 (3k)
Total image size=16624 (17k)

C:\leJOS_RCX\bin>lejosfirmdl -f
Use --help for options.
segment.length[0] = 13686 (14k)
segment.length[1] = 2938 (3k)
Total image size=16624 (17k)

C:\leJOS_RCX\bin>lejosfirmdl -f
Use --help for options.
segment.length[0] = 13686 (14k)
segment.length[1] = 2938 (3k)
Total image size=16624 (17k)
Transferring "/cygdrive/c/lejos_rcx/bin/../bin/lejos.srec" to RCX...
100%
</code>
The RCX showed up a "9.0 0" in its display (is this a good sign? I guessed so).

Than I followed the example given in the README file:
<code bash>
C:\leJOS_RCX>cd examples\view
C:\leJOS_RCX\examples\view>set CLASSPATH=.
C:\leJOS_RCX\examples\view>lejosc *.java
javac: target release 1.1 conflicts with default source release 1.5
</code>
The problem was, that I used ~JDK-1.6.0 already. Using "lejosc.exe" like this finally worked:

<code bash>
C:\leJOS_RCX\examples\view>lejosc -source 1.2 *.java
C:\leJOS_RCX\examples\view>lejos View
100%
</code>
After pressing the Run-button on the RCX, the View.java program on the RCX did what it is supposed to do: showing sensor values and manipulate motor speed.

Fine, that worked!

!!A first JAVA benchmark with leJOS on the RCX
With leJOS 2.1.0 this Java program needs about ''2776000 ms'' to finish fib(30). (And needed about 22000 ms (22720 ms to be precise) to finish on fib(20).)
<code java>
import josx.platform.rcx.*;

class Fibonacci {

  static int fib(int n) {
    if(n < 2) 
      return 1;
    else
      return fib(n-2) + fib(n-1);
  } 

  public static void main(String[] args) {
    int t0=(int)System.currentTimeMillis();
    for(int i=0;i<=30;i++) {
    	LCD.showNumber(fib(i)%10000);
    }
    LCD.showNumber(((((int)System.currentTimeMillis())-t0)/1000)%10000);
    for(;;);
  }
}
</code>
Some strange constructs are needed: First leJOS does not support long arithmetic. Second LCD.showNumber(..) just displays 4 digits. (All larger numbers are mapped to 9999.)

!Port HaikuVM to the RCX
First, I need a C/C++ cross compiler for h8300.

!!No luck with "DJGPP H8300 cross compiler" recommend from brickos
I was not able to build the cross compiler for Windows/DOS when following this instructions:
http://brickos.sourceforge.net/documents.htm
http://brickos.sourceforge.net/docs/install-DJGPP.html
Instead it turns out that all the tools for building are made for Win 32 Bit only. They "fail" on my 64 Bit Win 7 telling me that 32 Bit OS is needed.

!!Partial luck with "GNU Dev Tools 3.2-1 for the Hitachi H8/300[HS]"
http://sourceforge.net/projects/h8300-hms/files/h8300-hms-gcc/3.2-1%20%28Mingw%20windows%29/
At least I was able to compile, upload and run some simple C programs.  Even HaikuVM is working to some extend if you restrict yourself to HaikuVM Mode 16/32 and cross compiler option -02.

But I had stability problems with other programs. When it comes to HaikuVM Mode 32/32 (which is needed to be compatible with leJOS and JAVA programs written for leJOS) the cross compiler produced bad code in function invoke(..) so I had to use -O3. But here the compiler was not able to access some types which are defined as union in the expected way. 

Today I really don't know why I had this problems. At the end, it just was the offensive usage of the compiler option "-mrelax" (and "-relax"). I banned it, but at the same time I switched to version 3.3.1-1.

!!Luck with "GNU Dev Tools 3.3.1-1 for the Hitachi H8/300[HS]"
http://sourceforge.net/projects/h8300-hms/files/h8300-hms-gcc/3.3.1-1%20%28Windows%20Mingw%29/

Some foundings with this micro controller and compiler:
*von-neumann-architecture
*2 Byte alignment
*~Big-Endian
*sizeof(short) -> 2
*sizeof(int) -> 2
*sizeof(long) -> 4
*sizeof(long long) -> 4 (is a surprise for me)
*sizeof(float) -> 4
*sizeof(double) -> 4

I was perfectly able to compile, upload (using lejosfirmdl.exe) and run C programs (see an example below).

!!!A first C benchmark with the installed GNU Toolchain for h8300 on the RCX
<code c>
int32_t fib(int32_t n) {  
    if(n < 2)   
      return 1;  
    else  
      return fib(n-2) + fib(n-1);  
}   
  
int main() {  
    int32_t i;  
    long t0;  

	init_rcx();

	t0 = millis();  
	for(i=0;i<=30;i++) {  
		LCD_showNumber(fib(i) % 10000);
	}
	LCD_showNumber((millis() - t0)/100);
	sleep(120);
	return 0;
}
</code>
This C program, compiled with h8300-hms-gcc -O2 or -Os (optimize for size), needed ''150200 ms'' and compiled with -O3 (optimize for speed) needed ''150200 ms'' as well (I wonder, because the binary program size increased).

First conclusion: This (specific) plain C program is 18.48 times faster than the corresponding JAVA program runnning with leJOS.

!!A first JAVA benchmark with HaikuVM on the RCX
With ~HaikuVM revision 704 the Java program Fibonacci.java (see above) needs about ''1965000 ms'' to finish fib(30).

|!Programming Language|!Time [ms]|!~AOTVariant|
|!C (h8300-hms-gcc)| 150200||
|!~LeJOS 2.1.0| 2776000|Bytecode in a switch|
|!~HaikuVM 1.4.0| 1965000|~HAIKU_AOTBytecodeAsJump|

See also: [[RCX 2.0]].
See: [[Performance]].
See: [[The RCX Memory]].
!~IR-Communication hardware
For firmware and program upload on an 32 Bit XP Computer I used 
#the RIS 2.0 USB IR Tower
#the ~RS232 IR Transceiver from the ASURO ROBOT KIT (see Links)
For firmware and program upload on an 64 Bit Computer I used 
#the ~RS232 IR Transceiver from the ASURO ROBOT KIT (see Links)

For Java program IO (System.out, System.in) I used 
#the ~RS232 IR Transceiver from the ASURO ROBOT KIT (see Links)

Or use my incredible simple Arduino RCX 2.0 Programmer https://github.com/BobGenom/arduino_sketches/tree/master/RCX2_IR_Programmer1

!!The Byte Protocol
Each request/reply is sent as a packet of bytes on a serial communication line between the computer and the RCX. This serial line consists of two infrared transmitter/receiver devices (at 950 mn), one connected to the computer via an RS232 communication port, the other build into the RCX. The baud rate is 2400; this is the number of bits sent per second. To mark the start and end of each byte, a byte is sent preceeded by a start bit and followed by a stop bit. Also, a single parity bit is appended to the byte. The parity bit is chosen so the number of bits in the 9 bit value sent is odd. Hence, each byte is sent as 11 bits. Furthermore, each byte in a packet except the first, i.e. 0x55, is sent as two bytes, the byte itself and its bit complement. The result is a packet with an equal number of zero bits and one bits (the header byte 0x55 also has an equal number of zero and one bits). This allows an infrared receiver to compensate for a constant signal bias (caused by ambient light) simply by subtracting the average signal value. Hence, each 8 bit value in a packet, except the first, is sent as 22 bits in all. With a baud rate of 2400 this takes 22 bit /2400 bit/sec = 9 msec for each byte.

!!The Bit Protocol
Each bit transmitted between the two infrared transmitter/receiver devices is represented with bit value 0 as a 417 usec period of infrared light pulsed with a frequency of 38kHz, and bit value 1 as a 417 usec period with no infrared light. The duration of the period for a single bit is related to the baud rate as follows 1 bit/2400 bit/sec = 417 usec.

!!The RS232 Connected Infrared Transmitter/Receiver
The infrared transmitter/receiver connected to the RS232 serial port, echoes the bytes sent by the computer to the serial port. This means that the bytes received after sending a packet, is a copy of the packet in front of the reply packet received from the RCX executive. 

!!More details about Infrared Transmitter/Receiver
(from: http://lego.wikia.com/wiki/Mindstorms_RCX)
The IR interface on the RCX is able to communicate with Spybots, Scout Bricks, Lego Train, and the NXT (using a third-party infrared link sensor.) The RCX 1.0 IR receiver carrier frequency is 38.5 kHz, while the RCX 2.0 IR carrier frequency is 76 kHz. Both versions can transmit on either frequency. The carrier signal is generated by one of the RCX's internal timers. The RCX communicates with a computer using a Serial or USB IR tower. The tower is supported by Windows 98, Me, and XP (32-bit). A patch is available for hyper-threading/multi-core CPUs. There is no formal support for Windows Vista (32-bit), but there are reports of correct functionality. The USB tower does not work on a 64-bit OS unless a 32-bit OS is used in conjunction with a virtual machine. The serial tower works normally under 64-bit Windows 7 using a third-party USB-to-serial adapter. All versions of the RCX have a unique number printed on it, necessary for technical support and used as the ID number of the RCX for your Lego Mindstorms account on the now-defunct Lego Mindstorms RCX website. The first RCX produced is marked "000001" and was on display at the Mindstorms 10th Anniversary event. 

!Usage
Follow this [[link|RCX 2.0]].

!Links
RCX
http://www.lejos.org/rcx-downloads.php
http://legolab.daimi.au.dk/CSaEA/RCX/Manual.dir/RCXManual.html (a must read!)
http://moss.csc.ncsu.edu/~mueller/rt/rt00/mindstorm/www.crynwr.com/lego-robotics/ (a must read!)
http://www.kirkwood.edu/pdf/uploaded/262/programming_with_lejos_pt_1.pdf

~LeJOS 2.1.0 download from here: 
http://sourceforge.net/projects/rcx.lejos.p/files/lejos-win32/2.1.0

GNU Toolchain for h8300 C/C++
A windows gcc cross compiler for h8300
http://sourceforge.net/projects/h8300-hms/files/h8300-hms-gcc/
http://www.vorlesungen.uni-osnabrueck.de/informatik/robot00/doc/lego/tinyvm.pdf
http://gnutoolchains.com/building/
http://brickos.sourceforge.net/documents.htm (!!)
http://brickos.sourceforge.net/docs/install-DJGPP.html (It is made for Win 32 Bit only. It fails on 64 Bit!!)

Renesas toolchain for h8300 C/C++
Another windows cross compiler for h8300. (You have to register before download.)
http://am.renesas.com/request?SCREEN_ID=ViewGRSDownloadSearch&EXECUTE_ACTION=search&LAYER_ID=2969&CATEGORY_ID=1#

lejos packaging for Fedora
http://www.lejos.org/forum/viewtopic.php?f=7&t=7164&p=25909&hilit=toolchain&sid=062745a1e3af5da2be260dd9d4bae06e#p25909

Where can I get the GCC compiler for the NXT firmware?
http://www.lejos.org/forum/viewtopic.php?f=7&t=2907&p=14277&hilit=toolchain&sid=062745a1e3af5da2be260dd9d4bae06e#p14277

Porting leJOS to another hardware
http://www.lejos.org/forum/viewtopic.php?f=5&t=1900&p=9152&hilit=toolchain+rcx&sid=062745a1e3af5da2be260dd9d4bae06e#p9152

lejos unlocking firmware failed tower error (USB Sniffer)
http://bricks.stackexchange.com/questions/1099/rcx-firmware-download-problem

http://www.datasheetarchive.com/H8%2F300-datasheet.html

http://www.mientki.ruhosting.nl/data_www/lego_knex/lego_electronica/ir_tower/ir_tower.html

Mindstorms ~IR-communication:
https://mattallen37.wordpress.com/2011/04/18/rcx-ftdi-ir-adapter-tower/
http://krazatchu.ca/2012/05/07/superduplex-an-infrared-bootloader-for-arduino/
http://www.tau.ac.il/~stoledo/lego/AVR-ir/
https://minordiscoveries.wordpress.com/2014/01/20/using-nqc-on-a-raspberry-pi-to-program-a-lego-mindstorms-rcx-brick/
Serial comm using IR with an arduino: http://forum.arduino.cc/index.php?topic=10555.0
http://www.analysir.com/blog/
For simple 2400 baud IO, I used the ~RS232 IR Transceiver from the ASURO ROBOT KIT: http://www.arexx.nl/arexx.php?cmd=goto&cparam=p_asuro

Using RCX lego sensors with arduino
https://seriousrobotics.wordpress.com/2011/11/20/using-rcx-lego-sensors-with-arduino/
~HaikuVM implements effective quasi-preemptive thread scheduling with atomic JVM instructions. 

~HaikuVM is preemptive on bytecode level not on machine instruction Level.  (That's why I call it quasi-preemptive.) As a consequence every bytecode is executed atomar (and so are all native methods). ~HaikuVM supports thread synchronization with the Java ''synchronized'' keyword. In contrast to some other implementations monitor counters are not stored in the object headers but rather live in a separate construct to further save space. (Because in a microcontroller the vast majority of objects will never act as monitors.)

Timeslicing is done by performing a context switch on schedule-instructions which are selected bytecodes and specific native methods. Schedule-instructions are:
* branch bytecodes (either backward or forward)
* any invoke* bytecode (e.g. invokestatic)
* any *return bytecode (e.g. ireturn)
* Thread.yield()
* Thread.sleep(..)
* Thread.join()
* wait(..)
* synchronized methods or synchronized blocks
This is how to program virtual any Arduino in JAVA using the processing habit (not using main() but setup() and loop()), library and the [[Arduino IDE]] to let the LED blink.
<code java>
package processing.examples._01_Basics;

import static processing.hardware.arduino.cores.arduino.Arduino.*;

public class Blink {
    static byte ledPin = 13;            // LED connected to digital pin 13

    public static void loop()           // run over and over again
    {
        digitalWrite(ledPin, HIGH);     // sets the LED on
        delay(1000);                    // waits for a second
        digitalWrite(ledPin, LOW);      // sets the LED off
        delay(1000);                    // waits for a second
    }

    public static void setup() {
        pinMode(ledPin, OUTPUT);        // sets the digital pin as output
    }
}
</code>
<hr>
<<tiddler [[Arduino IDE]]>>

A big part of the ''wiring core library'' is ported to JAVA. For the rest help is wanted.
This is about how to program a RCX in JAVA.  This program calculates the Fibonacci numbers from 0 to 19 and shows them on the LCD display. At the end it displays the elapsed time in seconds for this job. And waits until the power key is pressed. (The showNumber(..) method just displays 4 digits. Therefore I modulo all numbers by 10000.)

<code java>
package raw_rcx;
import static haiku.rcx.lib.ROM.*;

public class Fibonacci {
	static int fib(int n) {
		if (n < 2)
			return 1;
		else
			return fib(n - 2) + fib(n - 1);
	}

	public static void main(String[] args) {
		int t0 = (int) System.currentTimeMillis();
		for (int i = 0; i <= 20; i++) {
			showNumber(fib(i) % 10000);
		}
		int dt = ((((int) System.currentTimeMillis()) - t0) / 1000) % 10000;
		showNumber(dt);

		short_t status = new short_t();
		get_power_status(POWER_KEY, status);
		while (status.s != 0) {
			get_power_status(POWER_KEY, status);
		}
	}
}
</code>

After you have installed all needed software (see [[GettingStarted]]) you can proceed with the following steps to let the Fibonacci program run on your RCX:
<code bash>
mkdir myProject
cd myProject
C:\haikuVM\bin\haiku -v --Config rcx C:\haikuVM\examples\src\main\java\raw_rcx\Fibonacci.java
</code>

*[[haiku]] first calls [[haikuc]] which calls javac to compile ''Fibonacci.java'' into ''Fibonacci.class'' (bytecode).
*[[haiku]] second calls [[haikulink]] which first translates the ''Fibonacci.class'' into a ''C program'' and adds the Haiku VM (which is written also in C). Second it cross compiles and links all C sources into the file ''Fibonacci.srec''.
*[[haiku]] third calls [[haikuupload]] which finally uploads ''Fibonacci.srec'' to the RCX via the infrared connection by calling ''lejosfirmdl''.
Most of this steps are configurable in the file [[HaikuVM.properties]] or can be modified by giving other [[Command Line Options]]. For instance [[HaikuVM.properties]] assumes that your RCX is connected on port com8. Change the following line of [[HaikuVM.properties]] to adapt to your configuration:
{{{
rcx.Port = usb
}}}
Or call [[haiku]] with an explicit port name like this:
<code bash>
C:\haikuVM\bin\haiku -v --Config rcx --Config:Port com5 C:\haikuVM\examples\src\main\java\raw_rcx\Fibonacci.java
or
C:\haikuVM\bin\haiku --Config rcx --Config:Port usb C:\haikuVM\examples\src\main\java\raw_rcx\robots\FollowLine.java
</code>

For those who are curious to read about the "making of RCX support", may follow this [[link|Porting HaikuVM to the Lego RCX Brick]].



If you want to get a first impression about ~HaikuVM but you don't have a microcontroller, here is a way to get it.
If you have a Raspberry Pi (tested with ~RPi 3 and "Linux raspberrypi3 4.4.34-v7+ #930 SMP Wed Nov 23 15:20:41 GMT 2016 armv7l GNU/Linux") you just enter:
<code bash>
cd /home/pi/haikuVM/myCProject  
/home/pi/haikuVM/bin/haiku -v --Config unix /home/pi/haikuVM/examples/src/main/java/arduino/tutorial/HelloWorldJava.java
</code>

<<tiddler chmod>>
!Some results
:fib(35): Is 'haikuvm.bench.~Fibonacci32Bit' tweaked to calculate all Fibonacci numbers up to 35.
|!Name|!Type|!Heap|!fib(35)|!Comment|
|!gcc 4.9.2|compiled -O3|| 0.473s|~Fibonacci32Bit written in C for reference|
|!JVM 8|hotspot|| 0.762s|
|!gcc 4.9.2|compiled -O0|| 1.535s|~Fibonacci32Bit written in C for reference|
|!JVM 8|interpret (-Xint)|| 17.064s|
|!~HaikuVM r759|interpret -O3|300000| 39.903s|~HAIKU_AOTBytecodeAsSwitch|
|!~HaikuVM r759|interpret -O3|300000| 46.432s|~HAIKU_AOTBytecodeAsJump|
|!~HaikuVM r759|interpret -O0|300000| 116.911s|~HAIKU_AOTBytecodeAsJump|

Here is the C program for reference:
<code c>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>

unsigned long millis() {
        struct timeval t;
        gettimeofday(&t, 0);
        return t.tv_sec * 1000 + t.tv_usec / 1000;
}

typedef int int32_t;

int32_t fib(int32_t n) {
    if(n < 2)
      return 1;
    else
      return fib(n-2) + fib(n-1);
}

int main() {
    int32_t i;
    long t0 = millis();
    for(i=0;i<=35;i++) {
          printf("Fibonacci of %ld is %ld in %ld ms\n", i, fib(i), (long)(millis()-t0));
    }
    return 0;
}
</code>
!Version 1.4.3 (Revision: 766) (Date: 2017/04/30)
#HaikuVM runs on the [[Raspberry Pi 3]]. 
#Enhanced chapter [[Porting]] with an example.
!Version 1.4.2 (Revision: 750) (Date: 2017/03/20)
#HaikuVM runs on the esp8266 via [[Arduino IDE]]. ([[More ...|ESP8266 (ESP01)]]).
#HaikuVM compared with Micro Python. ([[More ...|Performance compared with micropython]]).
#Slightly enhanced documentation summary of [[JNI features|JNI Summary]].
!Version 1.4.1 (Revision: 735) (Date: 2015/12/27)
#Bug fixed: when used with Arduino IDE
#Don't force inline or noinline, leave it to the C compiler
!Version 1.4.0 (Revision: 726) (Date: 2015/12/07)
#HaikuVM runs on the lego RCX 2.0. See [[Porting HaikuVM to the Lego RCX Brick]] and [[RCX 2.0]].
#Introduced the ~AOTVariant ''~HAIKU_AOTThreadedAsCall'' and achieved a [[performance|Performance History]] boost of about 20%. ([[More ...|Ahead-of-time (AOT) compiler]])
#Bug fixed: When using ~AOTVariant ''~HAIKU_AOTBytecodeAsSwitch'' with AVR.
#Bug fixed: On error the windows console now stays open. (Before this the console made an exit.)
#Bug fixed: For targets Windows and UNIX the console is now opened with """_O_BINARY""". Before, I had CRCRLF instead of CRLF for new line.
#haikuupload now accepts option {{{--Config:Port}}}
!Version 1.3.3 (Revision: 676) (Date: 2015/06/30)
#Bug fixed: When using with configurations ''arduinoIDEUpload'' or ''arduinoIDEVerify'' on Win 8.
#Support for new annotation ''@~NativeCppMethod'' to support Java classes which are designed as proxies of C++ classes. ([[More ...|Beyond JNI: Java class as proxy to a C++ class]])
#New feature: Looking for 'make' in own directory './hardware/'
!Version 1.3.2 (Revision: 663) (Date: 2015/06/07)
#Completed the list of supported JNI annotations:
##''@~NativeCFunction''
##''@~NativeCppFunction'' and its synonym ''@~NativeProcessingFunction''
##''@~NativeCBody'' (new) and its synonym ''@~NativeCHeader''
#All of them support the member ''cImpl''. See new tutorial [[Beyond JNI: put C code into your java files]]
#In addition HaikuVM now ''handles your *.c, *.cpp and *.h files'', merged in your Java main file directory.
#Bug fixed: System.arraycopy() didn't work anymore.
#Bug fixed: have to use ~HAIKU_AOTBytecodeAsSwitch with configuration "pc"
#Bug fixed: simpleOS.c had problems with ".\Microsoft Visual Studio 8\VC\~PlatformSDK\Include\~WinGDI.h"
#Relaxed the visibility of some custom Thread methods. (Followed an advice given by ~TimReset.)
#Implemented (Arduino) functions interrupt() and noInterrupt()
#~JUNITs rearranged to make harder junit test much simpler before doing the deployment.
##added a test for use with arduino IDE
##added a test for Serial print*
#Using preprocessor #error "YOUR MESSAGE", to notify about errors detected during compile time
#''Known Bug'': When using with configurations ''arduinoIDEUpload'' or ''arduinoIDEVerify'' on Win 8. Please identify and change two property values in file [[HaikuVM.properties]] like this:
<code bash>
...
arduinoIDEUpload.Upload = ../../../arduino --upload 'libraries/HaikuVM/ArduinoSketch/HaikuVM/HaikuVM.ino'
...
arduinoIDEVerify.Upload = ../../../arduino --verify 'libraries/HaikuVM/ArduinoSketch/HaikuVM/HaikuVM.ino'
...
</code>
Or redefine the property value 'Update' at the command line on the fly:  
<code bash>
C:\haikuVM\bin\haiku -v --Config arduinoIDEUpload --Config:Upload "../../../arduino --upload 'libraries/HaikuVM/ArduinoSketch/HaikuVM/HaikuVM.ino'" C:\haikuVM\examples\src\main\java\processing\examples\_01_Basics\Blink.java
</code>
!Version 1.3.1 (Revision: 632) (Date: 2015/05/16)
#Support for Arduino IDE 1.6.4.
#Bug fixed with Arduino IDE: <filename>.java compile error undefined reference to interpretNextByteCode. 
#Bug fixed: Now Script haikuc exits with error if a javac error happens.
!Version 1.3.0 (Revision: 624) (Date: 2015/05/04)
#Changed from using "~VirtualMachineError" to "~InternalError" following a suggestion from Nicolas Carranza given [[here|https://sourceforge.net/p/haiku-vm/discussion/general/thread/cfc37a11/?limit=25#9bb9/be4c]].
#New feature for the Arduino IDE: There is no need to start your Arduino IDE by hand. Instead try the configurations ''arduinoIDEVerify'' or ''arduinoIDEUpload'' ([[More ...|Arduino IDE]]).
#Bug fixed: Support of "Windows 8.1 Home" which caused unexpected [[problems|https://sourceforge.net/p/haiku-vm/discussion/general/thread/4ac7ed8a/]].
#Bug fixed: When using Java type ''long'' with Mode 32/64 (or 32/32) on hardware with only 16 Bit int. 
#Bug fixed: When using Java constants longer than 16 Bit with Mode 32/64 (or 32/32) on hardware with only 16 Bit int. 
!Version 1.2.3 (Revision: 604) (Date: 2014/11/05)
#Support for Arduino IDE 1.5.8.
#Put more user friendly information into the closure process.
#Bug fixed: When using C keyword 'const' in conjunction with 'PROGMEM' with new AVR compiler.
!Version 1.2.2 (Revision: 590) (Date: 2014/07/24)
#Crash fixed: When accessing double fields (~GETFIELD_D) ~HaikuVM crashed.
#Bug fixed: When declaring multidimensional array fields, C code declarations for this arrays were generated wrong.
#Bug fixed: When called with a user defined JAR file. (See [[FAQ]]s)
!Version 1.2.1 (Revision: 571) (Date: 2014/03/01)
#Bug fixed: When running for target PC 'make.exe' wasn't found in PATH if used in Visual Studio Console.
!Version 1.2.0 (Revision: 557) (Date: 2014/01/20)
#Bug fixed: instanceOf now returns ''false'' if obj==null
#Bug fixed: now a class is included, even if only referenced by byte codes "checkcast" or "instanceof".
#Bug fixed: when handling fields using generic types.
#Enhanced: Added more basic tests (still not all are passing)
#Enhanced: Having undefined virtual methods resulting in message: "%s [%d] was never declared!" will not stop haikufying any more. Instead a severe warning is given.
#Enhanced: If a method is included into the application image I added a (indexed) reason why it was included (is in the closure). Just to debug complex situations.
#Enhanced: makefile now better for UNIX (and WINDOWS?)
#Enhanced: less C warnings
#Enhanced: automated ~JUNITs for linux
#Renamed: from throwException() to panic(int exceptionCode, int exceptionArg)
#Renamed: configuration options ([[More ...|Panic Support]])
##~InternalExceptionEnable into ~PanicExceptions
##~InternalExceptionThrow into ~PanicSupport
#Nicer message: "Looking for '~HaikuVM.properties' in path: .."
!Version 1.1.1 (Revision: 542) (Date: 2013/11/17)
#Bug fixed: With byte codes ~I2B, ~I2S and BIPUSH.
#Bug fixed: Which prevented any change of the configuration (more or less). (Thank you Carl.)
#Enhanced Nullpointer hardening.
#Support for ~ArithmeticException.
#Getting more OS independent with put/getchar.
#Support for int16_t/int32_t agnostic Integer and Long classes.
#Tuned for UNIX.
!Version 1.1.0 (Revision: 510) (Date: 2013/10/26)
#Support for Arduino IDE 1.5.4 (and ''Arduino Due'' compiles at least. Feedback wanted.)!!!
#Reshaped JAVA object layout (structs) to support seamless integration with native C structs.
#Bug fixed: When path to JAVA contains spaces. (Thank you Carl.)
#Bug fixed: When compiled for Leonardo.
#Bug fixed: now cleans up before each new cross compilation.
!Version 1.0.5 (Revision: 483) (Date: 2013/09/27)
#Support for the [[Arduino IDE]] 1.0.5
!Version 1.0.4 (Revision: 444) (Date: 2013/08/04)
#Bug fixed: jint putchar(int) -> int putchar(int)
#Using ''$(~HAIKU_LINKER)'' to access any linker. Which in turn supported MS Visual Studio.
#Support for ~WIN32 / X86 target.
#Windows: use %TEMP%\haikuvm as target for *.class files.
#Used more canonicalPathes (which makes traces easier to read).
#Allows relative class names.
#~NativeCVariableEnhanced.c uses now only C features (not C++ features)
!Version 1.0.3 (Revision: 434) (Date: 2013/07/14)
#Better error messages.
#Enhanced usability.
#Arduino Leonardo is supported (including serial io). ([[More ...|Leonardo]])
#New configuration variable ''~TimerInterrupt'' to enable ISR for timing.
#Support for annotational [[Memory Access]] of your own C variables. ([[More ...|Tutorial JNI]])
#Enhanced JNI Support:
##Support of cpp files.
##Using ''$(~HAIKU_CC)'' and ''$(~HAIKU_CXX)'' instead of constants avr-gcc and avr-g++.
##Closer to javah Output.
##Support for C library access.
#Stricter C(++) syntax.
#Annotations @~NativeCFunction and @~NativeCPPFunction for more seamless JNI support
!Version 1.0.2 (Revision: 311) (Date: 2013/03/03)
#Bug fixed: ldc() for ints (~LDC_I) stored an int at wrong place in top.
#Bug fixed: now C #includes follow JAVA nested static scopes.
#JNI is now prepared to go public. ([[More ...|Tutorial JNI]])
#Correct millisecond timing now works for a wider range of Mz. ([[More ...|Tutorial Timing]])
#Bug fixed: Stdout and Stderr of shell commands were merged characterwise.
#Linux: No need for dos2unix any more.
!Version 1.0.1 (Revision: 285) (Date: 2013/02/11)
#Bug fixed: synchronized method failed if it had more then one RETURN.
#Entering com ports is more homogen between Windows and Linux now.
!Version 1.0.0 (Revision: 277) (Date: 2013/02/09)
#Better Linux support. ([[More ...|Linux]])
#Less C compiler warnings during cross compile phase
#~JUnits for many major features
#Basic AVR tutorial
!Version 0.9.5 (Revision: 258) (Date: 2013/01/01)
#Support for annotational [[Memory Access]]
#Support for numeric constrains for adapt to Memory models (~DBL_CNSTR, ~FLT_CNSTR, ~LONG_CNSTR, ~INT_CNSTR)
#First (remote) ~JUnit
#Bug fixed: Support for synchronized non-void methods
#Bug fixed: a quote in a String "'" is now supported.
#Less cross compiler warnings.
!Version 0.9.4 (Revision: 232) (Date: 2012/12/02)
#~WinAVR 20100110 included in download
#Support for arduino-1.0.2
#[[haiku]] command now supports {{{--Config:Port <port>}}}
#Reduced compiler warnings
#Moved available() and read() to ~HardwareSerial.
#Added AVR Two Wire constants
*OS
**[[Windows|Visual Studio]]
**[[UBUNTU 12.04 LTS; 12.10|Ubuntu]]
**[[Raspberry Pi 3]]
**[[Mac OS X Mountain Lion|http://backsite.wordpress.com/2013/02/28/java-fur-arduino-und-andere-mcs-mit-haikuvm/]]
*Microcontroller
**[[ATmega328p|Duemilanove]]
**[[Atmega8|Asuro]]
**Atmega16
**[[Hitachi chip H8/3292 with an H8/300 CPU|RCX 2.0]]
**[[ESP8266 (ESP01)]]
*Platforms
**[[Arduino]]
***[[YĂºn|Arduino IDE]]
***[[Duemilanove]]
***[[Leonardo]]
***[[Micro|Arduino IDE]]
***[[UNO SMD R2|http://backsite.wordpress.com/2013/02/28/java-fur-arduino-und-andere-mcs-mit-haikuvm/]] ~~(The configuration should be 'atmega328p' and, for some unknown reason, the baud rate has to be 115200 only.)~~
***[[ESP8266 (ESP01)]]
**[[ASURO|Asuro]]
**NIBOBEE
**Gertboard
**lego mindstorm
***[[RCX 2.0]]
*Software
**Java
***oracle jdk1.6.0
***java 7 (32 and 64)
***java 8 (jdk1.8.0_05) 
**Compiler
***gcc
****4.6.3 (compare with avr-gcc 4.6.2 which has a reported failure)
***Microsoft Compiler
****VS 2005
****VS 2008
****VS 2010
**Crosscompiler
***GNU: avr-gcc
****4.5.1
****4.5.3
****4.3.2 (~WinAVR 20081205)
****4.3.3 (~WinAVR 20100110)
**** (4.6.2 has a reported failure)
****4.8.2
****4.9.2 (Sadly produces slow code but very small code. Half the size of 4.3.2.)
***GNU: h8300-hms-gcc
****[[3.3.1|RCX 2.0]]
**Flash Tools
***avrdude
***~ASUROFlash155
***~Nibobee-Programmer
***[[lejosfirmdl|RCX 2.0]]
**~IDEs
***Eclipse (Indigo, Kepler R1)
***Arduino IDE (1.0.5, 1.5.4, 1.5.8)
~HaikuVM is successfully testet against the following targets (and some more):
#AVR
## ~ATmega8 ([[More ...|Asuro]])
## ~ATmega328p ([[More ...|Arduino]])
## ~ATmega32u4 ([[More ...|Leonardo]])
#Windows XP (32Bit) ([[More ...|Visual Studio]])
#Windows 2008 R2 (64Bit) ([[More ...|Visual Studio]])
#UNIX (Ubuntu 64Bit) ([[More ...|Ubuntu]])
A Java VM for ARDUINO and other micros using the leJOS runtime.
//HaikuVM//
[[Summary|http://sourceforge.net/projects/haiku-vm/]]
[[Download|https://sourceforge.net/projects/haiku-vm/files/downloads/]]
Subversion [[RO|https://sourceforge.net/p/haiku-vm/code/]] [[HTTPS|https://svn.code.sf.net/p/haiku-vm/code/trunk]]

See also:
[[Discussion|https://sourceforge.net/p/haiku-vm/discussion/general/]]
[[Tickets|https://sourceforge.net/p/haiku-vm/tickets/milestones]]
Each stack block has a variable called 'length' and consists of length stack slots. A stack slot has the size of the type stack_t (jint or jobject (void* in C), what ever needs more bytes [[see|Configurable 64, 32 or 16 bit data types]]). As usual for ~JVMs ~HaikuVM uses two slots if it stores a long or a double on the stack. ~HaikuVM does not try to save stack space by using only part of a slot (eg. to store a byte).

|N-1| possible unused |
|..|~|
|..|~|
|61|bgcolor(#6f9): frame 3 |
|..|~|
|..|~|
|35|~|
|34|bgcolor(#6f9): frame 2 |
|..|~|
|21|~|
|20|bgcolor(#6f9): frame 1 |
|..|~|
|..|~|
|2|~|
|1|bgcolor(#66b): previous stack block|
|0|bgcolor(#66b): last stack pointer |
| |bgcolor(#66b): length = N |
| initial stack block |c

|M-1| possible unused |
|..|~|
|..|bgcolor(#6f9): frame |
|..|~|
|2|~|
|1|bgcolor(#66b): previous stack block|
|0|bgcolor(#66b): last stack pointer |
| |bgcolor(#66b): length = M |
| contiguous stack block |c

Where 
* N is [[InitialMainThreadStackSize|HaikuVM.properties]], if it's the ''first'' stack block for the main thread.
* N is [[InitialOtherThreadStackSize|HaikuVM.properties]], if it's the ''first'' stack block for any other thread.
* M is the maximum stack (//size// + 4*2) needed for the stack block of a called function. For example if javac calculated a stack //size// of 20 stack slots for a function (including call arguments and local variables) then M=20+4*2. More general: M=//size//+4*sizeof(stack_t). (Which roughly translates to  M=//size//+4*sizeof(*void). But beware of targets having 32 Bit pointers and 64 Bit ints.) 
~HaikuVM reserves 4 more slots than javac calculated because ~HaikuVM technical needs:
*previous stack block
*last stack pointer
*last program counter (of a frame)
*previous frame (of a frame)
Each thread has its own stack queue. This queue is a one directional linked list, connected via 'previous stack'. The intention of ''first'' stack blocks is to keep many stack frames. Contiguous stack blocks usualy keep only one stack frame.

Each function call (per thread) allocates its own (stack) frame on its thread stack. To save space, function frames do overlap (where ever possible). This usualy happens - and is intended - for the ''first'' stack block of the main thread and any other threads ''first'' stack block.

|21| function stack |
|..|~|
|9|~|
|8|bgcolor(#68b): last program counter |
|7|bgcolor(#68b): previous frame |
|6|bgcolor(#6fa): local2 |
|5|~|
|4|bgcolor(#6fa): local1 |
|3|bgcolor(#6f9): arg3 |
|2|bgcolor(#6f9): arg2 |
|1|bgcolor(#6f9): arg1 |
|0|bgcolor(#6f9): object |
| frame layout |c

See [[Memory Layout of HaikuVM Objects]] for more C details.
.tiddler {padding:1em 1em 0;  font-size:1.2em;border-bottom-style:solid; border-width:5px;border-color:#04b; 
font-family: "Verdana",Arial,sans-serif;
line-height: 1.4em;
}
.viewer pre {padding:0.5em; margin-left:0.5em; font-size:.9em; line-height:0.9em; overflow:auto;}
div.tiddler .subtitle {font-size: 7pt;}
h1,h2,h3,h4,h5,h6 {
    #color:[[ColorPalette::Foreground]]; 
    background:transparent;
    color: rgb(32, 74, 135);
    font-family: "Verdana",Arial,sans-serif;
    #font-family: "Georgia","Times New Roman",serif;
}
.title {
    #color:[[ColorPalette::Foreground]];
    line-height: 120%;
    color: rgb(32, 74, 135);
    font-family: "Verdana",Arial,sans-serif;
    #font-family: "Georgia","Times New Roman",serif;
}  
[[StyleSheetSyntaxHighlighter]]
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected {color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size: .75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0 3px 0 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0; padding-bottom:0;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for ~SyntaxHighlighter
***/

/*{{{*/
.dp-highlighter
{
	font-family: "Consolas", "Courier New", Courier, mono, serif;
	font-size: 12px;
	background-color: #E7E5DC;
	width: 99%;
	overflow: auto;
	margin: 18px 0 18px 0 !important;
	padding-top: 1px; /* adds a little border on top when controls are hidden */
}

/* clear styles */
.dp-highlighter ol,
.dp-highlighter ol li,
.dp-highlighter ol li span 
{
	margin: 0;
	padding: 0;
	border: none;
}

.dp-highlighter a,
.dp-highlighter a:hover
{
	background: none;
	border: none;
	padding: 0;
	margin: 0;
}

.dp-highlighter .bar
{
	padding-left: 45px;
}

.dp-highlighter.collapsed .bar,
.dp-highlighter.nogutter .bar
{
	padding-left: 0px;
}

.dp-highlighter ol
{
	list-style: decimal; /* for ie */
	background-color: #fff;
	margin: 0px 0px 1px 45px !important; /* 1px bottom margin seems to fix occasional Firefox scrolling */
	padding: 0px;
	color: #5C5C5C;
}

.dp-highlighter.nogutter ol,
.dp-highlighter.nogutter ol li
{
	list-style: none !important;
	margin-left: 0px !important;
}

.dp-highlighter ol li,
.dp-highlighter .columns div
{
	list-style: decimal-leading-zero; /* better look for others, override cascade from OL */
	list-style-position: outside !important;
	border-left: 3px solid #6CE26C;
	background-color: #F8F8F8;
	color: #5C5C5C;
	padding: 0 3px 0 10px !important;
	margin: 0 !important;
	line-height: 14px;
}

.dp-highlighter.nogutter ol li,
.dp-highlighter.nogutter .columns div
{
	border: 0;
}

.dp-highlighter .columns
{
	background-color: #F8F8F8;
	color: gray;
	overflow: hidden;
	width: 100%;
}

.dp-highlighter .columns div
{
	padding-bottom: 5px;
}

.dp-highlighter ol li.alt
{
	background-color: #FFF;
	color: inherit;
}

.dp-highlighter ol li span
{
	color: black;
	background-color: inherit;
}

/* Adjust some properties when collapsed */

.dp-highlighter.collapsed ol
{
	margin: 0px;
}

.dp-highlighter.collapsed ol li
{
	display: none;
}

/* Additional modifications when in print-view */

.dp-highlighter.printing
{
	border: none;
}

.dp-highlighter.printing .tools
{
	display: none !important;
}

.dp-highlighter.printing li
{
	display: list-item !important;
}

/* Styles for the tools */

.dp-highlighter .tools
{
	padding: 3px 8px 3px 10px;
	font: 9px Verdana, Geneva, Arial, Helvetica, sans-serif;
	color: silver;
	background-color: #f8f8f8;
	padding-bottom: 10px;
	border-left: 3px solid #6CE26C;
}

.dp-highlighter.nogutter .tools
{
	border-left: 0;
}

.dp-highlighter.collapsed .tools
{
	border-bottom: 0;
}

.dp-highlighter .tools a
{
	font-size: 9px;
	color: #a0a0a0;
	background-color: inherit;
	text-decoration: none;
	margin-right: 10px;
}

.dp-highlighter .tools a:hover
{
	color: red;
	background-color: inherit;
	text-decoration: underline;
}

/* About dialog styles */

.dp-about { background-color: #fff; color: #333; margin: 0px; padding: 0px; }
.dp-about table { width: 100%; height: 100%; font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; }
.dp-about td { padding: 10px; vertical-align: top; }
.dp-about .copy { border-bottom: 1px solid #ACA899; height: 95%; }
.dp-about .title { color: red; background-color: inherit; font-weight: bold; }
.dp-about .para { margin: 0 0 4px 0; }
.dp-about .footer { background-color: #ECEADB; color: #333; border-top: 1px solid #fff; text-align: right; }
.dp-about .close { font-size: 11px; font-family: Tahoma, Verdana, Arial, sans-serif !important; background-color: #ECEADB; color: #333; width: 60px; height: 22px; }

/* Language specific styles */

.dp-highlighter .comment, .dp-highlighter .comments { color: #008200; background-color: inherit; }
.dp-highlighter .string { color: blue; background-color: inherit; }
.dp-highlighter .keyword { color: #069; font-weight: bold; background-color: inherit; }
.dp-highlighter .preprocessor { color: gray; background-color: inherit; }

/*}}}*/
/***
!Metadata:
|''Name:''|SyntaxHighlighterPlugin|
|''Description:''|Code Syntax Highlighter Plugin for TiddlyWiki.|
|''Version:''|1.1.3|
|''Date:''|Oct 24, 2008|
|''Source:''|http://www.coolcode.cn/show-310-1.html|
|''Author:''|Ma Bingyao (andot (at) ujn (dot) edu (dot) cn)|
|''License:''|[[GNU Lesser General Public License|http://www.gnu.org/licenses/lgpl.txt]]|
|''~CoreVersion:''|2.4.1|
|''Browser:''|Firefox 1.5+; InternetExplorer 6.0; Safari; Opera; Chrome; etc.|

!Syntax:
{{{
<code options>
codes
</code>
}}}

!Examples:
{{{
<code java>
public class HelloWorld {
    public static void main(String args[]) {
        System.out.println("HelloWorld!");
    }
}
</code>
}}}

!Revision History:
|''Version''|''Date''|''Note''|
|1.1.2|Oct 15, 2008|Optimize Highlight|
|1.0.0|Oct 13, 2008|Initial release|

!Code section:
***/
//{{{
var dp={sh:{Toolbar:{},Utils:{},RegexLib:{},Brushes:{},Strings:{AboutDialog:"<html><head><title>About...</title></head><body class=\"dp-about\"><table cellspacing=\"0\"><tr><td class=\"copy\"><p class=\"title\">dp.SyntaxHighlighter</div><div class=\"para\">Version: {V}</p><p><a href=\"http://www.dreamprojections.com/syntaxhighlighter/?ref=about\" target=\"_blank\">http://www.dreamprojections.com/syntaxhighlighter</a></p>&copy;2004-2007 Alex Gorbatchev.</td></tr><tr><td class=\"footer\"><input type=\"button\" class=\"close\" value=\"OK\" onClick=\"window.close()\"/></td></tr></table></body></html>"},ClipboardSwf:null,Version:"1.5.1"}};dp.SyntaxHighlighter=dp.sh;dp.sh.Toolbar.Commands={ExpandSource:{label:"+ expand source",check:function($){return $.collapse},func:function($,_){$.parentNode.removeChild($);_.div.className=_.div.className.replace("collapsed","")}},ViewSource:{label:"view plain",func:function($,_){var A=dp.sh.Utils.FixForBlogger(_.originalCode).replace(/</g,"&lt;"),B=window.open("","_blank","width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=0");B.document.write("<textarea style=\"width:99%;height:99%\">"+A+"</textarea>");B.document.close()}},CopyToClipboard:{label:"copy to clipboard",check:function(){return window.clipboardData!=null||dp.sh.ClipboardSwf!=null},func:function($,A){var B=dp.sh.Utils.FixForBlogger(A.originalCode).replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&");if(window.clipboardData)window.clipboardData.setData("text",B);else if(dp.sh.ClipboardSwf!=null){var _=A.flashCopier;if(_==null){_=document.createElement("div");A.flashCopier=_;A.div.appendChild(_)}_.innerHTML="<embed src=\""+dp.sh.ClipboardSwf+"\" FlashVars=\"clipboard="+encodeURIComponent(B)+"\" width=\"0\" height=\"0\" type=\"application/x-shockwave-flash\"></embed>"}alert("The code is in your clipboard now")}},PrintSource:{label:"print",func:function($,B){var _=document.createElement("IFRAME"),A=null;_.style.cssText="position:absolute;width:0px;height:0px;left:-500px;top:-500px;";document.body.appendChild(_);A=_.contentWindow.document;dp.sh.Utils.CopyStyles(A,window.document);A.write("<div class=\""+B.div.className.replace("collapsed","")+" printing\">"+B.div.innerHTML+"</div>");A.close();_.contentWindow.focus();_.contentWindow.print();alert("Printing...");document.body.removeChild(_)}},About:{label:"?",func:function(_){var A=window.open("","_blank","dialog,width=300,height=150,scrollbars=0"),$=A.document;dp.sh.Utils.CopyStyles($,window.document);$.write(dp.sh.Strings.AboutDialog.replace("{V}",dp.sh.Version));$.close();A.focus()}}};dp.sh.Toolbar.Create=function(B){var A=document.createElement("DIV");A.className="tools";for(var _ in dp.sh.Toolbar.Commands){var $=dp.sh.Toolbar.Commands[_];if($.check!=null&&!$.check(B))continue;A.innerHTML+="<a href=\"#\" onclick=\"dp.sh.Toolbar.Command('"+_+"',this);return false;\">"+$.label+"</a>"}return A};dp.sh.Toolbar.Command=function(_,$){var A=$;while(A!=null&&A.className.indexOf("dp-highlighter")==-1)A=A.parentNode;if(A!=null)dp.sh.Toolbar.Commands[_].func($,A.highlighter)};dp.sh.Utils.CopyStyles=function(A,_){var $=_.getElementsByTagName("link");for(var B=0;B<$.length;B++)if($[B].rel.toLowerCase()=="stylesheet")A.write("<link type=\"text/css\" rel=\"stylesheet\" href=\""+$[B].href+"\"></link>")};dp.sh.Utils.FixForBlogger=function($){return(dp.sh.isBloggerMode==true)?$.replace(/<br\s*\/?>|&lt;br\s*\/?&gt;/gi,"\n"):$};dp.sh.RegexLib={MultiLineCComments:new RegExp("/\\*[\\s\\S]*?\\*/","gm"),SingleLineCComments:new RegExp("//.*$","gm"),SingleLinePerlComments:new RegExp("#.*$","gm"),DoubleQuotedString:new RegExp("\"(?:\\.|(\\\\\\\")|[^\\\"\"\\n])*\"","g"),SingleQuotedString:new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'","g")};dp.sh.Match=function(_,$,A){this.value=_;this.index=$;this.length=_.length;this.css=A};dp.sh.Highlighter=function(){this.noGutter=false;this.addControls=true;this.collapse=false;this.tabsToSpaces=true;this.wrapColumn=80;this.showColumns=true};dp.sh.Highlighter.SortCallback=function($,_){if($.index<_.index)return-1;else if($.index>_.index)return 1;else if($.length<_.length)return-1;else if($.length>_.length)return 1;return 0};dp.sh.Highlighter.prototype.CreateElement=function(_){var $=document.createElement(_);$.highlighter=this;return $};dp.sh.Highlighter.prototype.GetMatches=function(_,B){var $=0,A=null;while((A=_.exec(this.code))!=null)this.matches[this.matches.length]=new dp.sh.Match(A[0],A.index,B)};dp.sh.Highlighter.prototype.AddBit=function($,A){if($==null||$.length==0)return;var C=this.CreateElement("SPAN");$=$.replace(/ /g,"&nbsp;");$=$.replace(/</g,"&lt;");$=$.replace(/\n/gm,"&nbsp;<br>");if(A!=null){if((/br/gi).test($)){var _=$.split("&nbsp;<br>");for(var B=0;B<_.length;B++){C=this.CreateElement("SPAN");C.className=A;C.innerHTML=_[B];this.div.appendChild(C);if(B+1<_.length)this.div.appendChild(this.CreateElement("BR"))}}else{C.className=A;C.innerHTML=$;this.div.appendChild(C)}}else{C.innerHTML=$;this.div.appendChild(C)}};dp.sh.Highlighter.prototype.IsInside=function(_){if(_==null||_.length==0)return false;for(var A=0;A<this.matches.length;A++){var $=this.matches[A];if($==null)continue;if((_.index>$.index)&&(_.index<$.index+$.length))return true}return false};dp.sh.Highlighter.prototype.ProcessRegexList=function(){for(var $=0;$<this.regexList.length;$++)this.GetMatches(this.regexList[$].regex,this.regexList[$].css)};dp.sh.Highlighter.prototype.ProcessSmartTabs=function(E){var B=E.split("\n"),$="",D=4,A="\t";function _(A,E,_){var B=A.substr(0,E),C=A.substr(E+1,A.length),$="";for(var D=0;D<_;D++)$+=" ";return B+$+C}function C(B,C){if(B.indexOf(A)==-1)return B;var D=0;while((D=B.indexOf(A))!=-1){var $=C-D%C;B=_(B,D,$)}return B}for(var F=0;F<B.length;F++)$+=C(B[F],D)+"\n";return $};dp.sh.Highlighter.prototype.SwitchToList=function(){var C=this.div.innerHTML.replace(/<(br)\/?>/gi,"\n"),B=C.split("\n");if(this.addControls==true)this.bar.appendChild(dp.sh.Toolbar.Create(this));if(this.showColumns){var A=this.CreateElement("div"),_=this.CreateElement("div"),E=10,G=1;while(G<=150)if(G%E==0){A.innerHTML+=G;G+=(G+"").length}else{A.innerHTML+="&middot;";G++}_.className="columns";_.appendChild(A);this.bar.appendChild(_)}for(var G=0,D=this.firstLine;G<B.length-1;G++,D++){var $=this.CreateElement("LI"),F=this.CreateElement("SPAN");$.className=(G%2==0)?"alt":"";F.innerHTML=B[G]+"&nbsp;";$.appendChild(F);this.ol.appendChild($)}this.div.innerHTML=""};dp.sh.Highlighter.prototype.Highlight=function(C){function A($){return $.replace(/^\s*(.*?)[\s\n]*$/g,"$1")}function $($){return $.replace(/\n*$/,"").replace(/^\n*/,"")}function _(B){var E=dp.sh.Utils.FixForBlogger(B).split("\n"),C=new Array(),D=new RegExp("^\\s*","g"),$=1000;for(var F=0;F<E.length&&$>0;F++){if(A(E[F]).length==0)continue;var _=D.exec(E[F]);if(_!=null&&_.length>0)$=Math.min(_[0].length,$)}if($>0)for(F=0;F<E.length;F++)E[F]=E[F].substr($);return E.join("\n")}function D(A,$,_){return A.substr($,_-$)}var F=0;if(C==null)C="";this.originalCode=C;this.code=$(_(C));this.div=this.CreateElement("DIV");this.bar=this.CreateElement("DIV");this.ol=this.CreateElement("OL");this.matches=new Array();this.div.className="dp-highlighter";this.div.highlighter=this;this.bar.className="bar";this.ol.start=this.firstLine;if(this.CssClass!=null)this.ol.className=this.CssClass;if(this.collapse)this.div.className+=" collapsed";if(this.noGutter)this.div.className+=" nogutter";if(this.tabsToSpaces==true)this.code=this.ProcessSmartTabs(this.code);this.ProcessRegexList();if(this.matches.length==0){this.AddBit(this.code,null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol);return}this.matches=this.matches.sort(dp.sh.Highlighter.SortCallback);for(var E=0;E<this.matches.length;E++)if(this.IsInside(this.matches[E]))this.matches[E]=null;for(E=0;E<this.matches.length;E++){var B=this.matches[E];if(B==null||B.length==0)continue;this.AddBit(D(this.code,F,B.index),null);this.AddBit(B.value,B.css);F=B.index+B.length}this.AddBit(this.code.substr(F),null);this.SwitchToList();this.div.appendChild(this.bar);this.div.appendChild(this.ol)};dp.sh.Highlighter.prototype.GetKeywords=function($){return"\\b"+$.replace(/ /g,"\\b|\\b")+"\\b"};dp.sh.BloggerMode=function(){dp.sh.isBloggerMode=true};dp.sh.HighlightAll=function(N,B,K,I,O,E){function A(){var $=arguments;for(var _=0;_<$.length;_++){if($[_]==null)continue;if(typeof($[_])=="string"&&$[_]!="")return $[_]+"";if(typeof($[_])=="object"&&$[_].value!="")return $[_].value+""}return null}function J($,_){for(var A=0;A<_.length;A++)if(_[A]==$)return true;return false}function L(A,B,C){var _=new RegExp("^"+A+"\\[(\\w+)\\]$","gi"),$=null;for(var D=0;D<B.length;D++)if(($=_.exec(B[D]))!=null)return $[1];return C}function C(B,A,_){var $=document.getElementsByTagName(_);for(var C=0;C<$.length;C++)if($[C].getAttribute("name")==A)B.push($[C])}var T=[],P=null,M={},$="innerHTML";C(T,N,"pre");C(T,N,"textarea");if(T.length==0)return;for(var R in dp.sh.Brushes){var F=dp.sh.Brushes[R].Aliases;if(F==null)continue;for(var G=0;G<F.length;G++)M[F[G]]=R}for(G=0;G<T.length;G++){var _=T[G],U=A(_.attributes["class"],_.className,_.attributes["language"],_.language),Q="";if(U==null)continue;U=U.split(":");Q=U[0].toLowerCase();if(M[Q]==null)continue;P=new dp.sh.Brushes[M[Q]]();_.style.display="none";P.noGutter=(B==null)?J("nogutter",U):!B;P.addControls=(K==null)?!J("nocontrols",U):K;P.collapse=(I==null)?J("collapse",U):I;P.showColumns=(E==null)?J("showcolumns",U):E;var D=document.getElementsByTagName("head")[0];if(P.Style&&D){var S=document.createElement("style");S.setAttribute("type","text/css");if(S.styleSheet)S.styleSheet.cssText=P.Style;else{var H=document.createTextNode(P.Style);S.appendChild(H)}D.appendChild(S)}P.firstLine=(O==null)?parseInt(L("firstline",U,1)):O;P.Highlight(_[$]);P.source=_;_.parentNode.insertBefore(P.div,_)}};version.extensions.SyntaxHighLighterPlugin={major:1,minor:1,revision:3,date:new Date(2008,10,24)};dp.sh.ClipboardSwf="clipboard.swf";dp.sh.Highlight=function(_,Q,B,J,H,M,D){function A(){var $=arguments;for(var _=0;_<$.length;_++){if($[_]==null)continue;if(typeof($[_])=="string"&&$[_]!="")return $[_]+"";if(typeof($[_])=="object"&&$[_].value!="")return $[_].value+""}return null}function I($,_){for(var A=0;A<_.length;A++)if(_[A]==$)return true;return false}function K(A,B,C){var _=new RegExp("^"+A+"\\[(\\w+)\\]$","gi"),$=null;for(var D=0;D<B.length;D++)if(($=_.exec(B[D]))!=null)return $[1];return C}var N=null,$="innerHTML";if(this.registered==undefined){var L={};for(var O in dp.sh.Brushes){var E=dp.sh.Brushes[O].Aliases;if(E==null)continue;for(var F=0;F<E.length;F++)L[E[F]]=O}this.registered=L}Q=Q.split(":");language=Q[0].toLowerCase();if(this.registered[language]==null)return;N=new dp.sh.Brushes[this.registered[language]]();_.style.display="none";N.noGutter=(B==null)?I("nogutter",Q):!B;N.addControls=(J==null)?!I("nocontrols",Q):J;N.collapse=(H==null)?I("collapse",Q):H;N.showColumns=(D==null)?I("showcolumns",Q):D;var C=document.getElementsByTagName("head")[0],P=document.getElementById(N.CssClass);if(N.Style&&C&&!P){P=document.createElement("style");P.setAttribute("id",N.CssClass);P.setAttribute("type","text/css");if(P.styleSheet)P.styleSheet.cssText=N.Style;else{var G=document.createTextNode(N.Style);P.appendChild(G)}C.appendChild(P)}N.firstLine=(M==null)?parseInt(K("firstline",Q,1)):M;N.Highlight(_[$]);N.source=_;_.parentNode.insertBefore(N.div,_)};config.formatters.push({name:"SyntaxHighlighter",match:"^<code[\\s]+[^>]+>\\n",element:"pre",handler:function(_){this.lookaheadRegExp=/<code[\s]+([^>]+)>\n((?:^[^\n]*\n)+?)(^<\/code>$\n?)/mg;this.lookaheadRegExp.lastIndex=_.matchStart;var $=this.lookaheadRegExp.exec(_.source);if($&&$.index==_.matchStart){var C=$[1],B=$[2];if(config.browser.isIE)B=B.replace(/\n/g,"\r");var A=createTiddlyElement(_.output,this.element,null,null,B);dp.sh.Highlight(A,C);_.nextMatch=$.index+$[0].length}}});config.formatterHelpers.enclosedTextHelper=function(_){this.lookaheadRegExp.lastIndex=_.matchStart;var $=this.lookaheadRegExp.exec(_.source);if($&&$.index==_.matchStart){var B=$[1];if(config.browser.isIE)B=B.replace(/\n/g,"\r");var A=createTiddlyElement(_.output,this.element,null,null,B);switch(_.matchText){case"/*{{{*/\n":dp.sh.Highlight(A,"css");break;case"//{{{\n":dp.sh.Highlight(A,"js");break;case"<!--{{{-->\n":dp.sh.Highlight(A,"xml");break}_.nextMatch=$.index+$[0].length}};dp.sh.Brushes.AS3=function(){var _="class interface package",$="Array Boolean Date decodeURI decodeURIComponent encodeURI encodeURIComponent escape "+"int isFinite isNaN isXMLName Number Object parseFloat parseInt "+"String trace uint unescape XML XMLList "+"Infinity -Infinity NaN undefined "+"as delete instanceof is new typeof "+"break case catch continue default do each else finally for if in "+"label return super switch throw try while with "+"dynamic final internal native override private protected public static "+"...rest const extends function get implements namespace set "+"import include use "+"AS3 flash_proxy object_proxy "+"false null this true "+"void Null";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"blockcomment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"definition"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp("var","gm"),css:"variable"}];this.CssClass="dp-as";this.Style=".dp-as .comment { color: #009900; font-style: italic; }"+".dp-as .blockcomment { color: #3f5fbf; }"+".dp-as .string { color: #990000; }"+".dp-as .preprocessor { color: #0033ff; }"+".dp-as .definition { color: #9900cc; font-weight: bold; }"+".dp-as .keyword { color: #0033ff; }"+".dp-as .variable { color: #6699cc; font-weight: bold; }"};dp.sh.Brushes.AS3.prototype=new dp.sh.Highlighter();dp.sh.Brushes.AS3.Aliases=["as","actionscript","ActionScript","as3","AS3"];dp.sh.Brushes.Bash=function(){var _="alias bg bind break builtin cd command compgen complete continue "+"declare dirs disown echo enable eval exec exit export fc fg "+"getopts hash help history jobs kill let local logout popd printf "+"pushd pwd read readonly return set shift shopt source "+"suspend test times trap type typeset ulimit umask unalias unset wait",$="case do done elif else esac fi for function if in select then "+"time until while";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("[()[\\]{}]","g"),css:"delim"},{regex:new RegExp("\\$\\w+","g"),css:"vars"},{regex:new RegExp("\\w+=","g"),css:"vars"},{regex:new RegExp("\\s-\\w+","g"),css:"flag"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-bash";this.Style=".dp-bash .builtin {color: maroon; font-weight: bold;}"+".dp-bash .comment {color: gray;}"+".dp-bash .delim {font-weight: bold;}"+".dp-bash .flag {color: green;}"+".dp-bash .string {color: red;}"+".dp-bash .vars {color: blue;}"};dp.sh.Brushes.Bash.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Bash.Aliases=["bash","sh"];dp.sh.Brushes.Batch=function(){var _="APPEND ATTRIB CD CHDIR CHKDSK CHOICE CLS COPY DEL ERASE DELTREE "+"DIR EXIT FC COMP FDISK FIND FORMAT FSUTIL HELP JOIN "+"LABEL LOADFIX MK MKDIR MEM MEMMAKER MORE MOVE MSD PCPARK "+"PRINT RD RMDIR REN SCANDISK SHARE SORT SUBST SYS "+"TIME DATE TREE TRUENAME TYPE UNDELETE VER XCOPY",$="DO ELSE FOR IN CALL CHOICE GOTO SHIFT PAUSE ERRORLEVEL "+"IF NOT EXIST LFNFOR START SETLOCAL ENDLOCAL ECHO SET";this.regexList=[{regex:new RegExp("REM.*$","gm"),css:"comment"},{regex:new RegExp("::.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("[()[\\]{}]","g"),css:"delim"},{regex:new RegExp("%\\w+%","g"),css:"vars"},{regex:new RegExp("%%\\w+","g"),css:"vars"},{regex:new RegExp("\\w+=","g"),css:"vars"},{regex:new RegExp("@\\w+","g"),css:"keyword"},{regex:new RegExp(":\\w+","g"),css:"keyword"},{regex:new RegExp("\\s/\\w+","g"),css:"flag"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-batch";this.Style=".dp-batch .builtin {color: maroon; font-weight: bold;}"+".dp-batch .comment {color: gray;}"+".dp-batch .delim {font-weight: bold;}"+".dp-batch .flag {color: green;}"+".dp-batch .string {color: red;}"+".dp-batch .vars {color: blue;font-weight: bold;}"};dp.sh.Brushes.Batch.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Batch.Aliases=["batch","dos"];dp.sh.Brushes.ColdFusion=function(){this.CssClass="dp-coldfusion";this.Style=".dp-coldfusion { font: 13px \"Courier New\", Courier, monospace; }"+".dp-coldfusion .tag, .dp-coldfusion .tag-name { color: #990033; }"+".dp-coldfusion .attribute { color: #990033; }"+".dp-coldfusion .attribute-value { color: #0000FF; }"+".dp-coldfusion .cfcomments { background-color: #FFFF99; color: #000000; }"+".dp-coldfusion .cfscriptcomments { color: #999999; }"+".dp-coldfusion .keywords { color: #0000FF; }"+".dp-coldfusion .mgkeywords { color: #CC9900; }"+".dp-coldfusion .numbers { color: #ff0000; }"+".dp-coldfusion .strings { color: green; }";this.mgKeywords="setvalue getvalue addresult viewcollection viewstate";this.keywords="var eq neq gt gte lt lte not and or true false "+"abs acos addsoaprequestheader addsoapresponseheader "+"arrayappend arrayavg arrayclear arraydeleteat arrayinsertat "+"arrayisempty arraylen arraymax arraymin arraynew "+"arrayprepend arrayresize arrayset arraysort arraysum "+"arrayswap arraytolist asc asin atn binarydecode binaryencode "+"bitand bitmaskclear bitmaskread bitmaskset bitnot bitor bitshln "+"bitshrn bitxor ceiling charsetdecode charsetencode chr cjustify "+"compare comparenocase cos createdate createdatetime createobject "+"createobject createobject createobject createobject createodbcdate "+"createodbcdatetime createodbctime createtime createtimespan "+"createuuid dateadd datecompare dateconvert datediff dateformat "+"datepart day dayofweek dayofweekasstring dayofyear daysinmonth "+"daysinyear de decimalformat decrementvalue decrypt decryptbinary "+"deleteclientvariable directoryexists dollarformat duplicate encrypt "+"encryptbinary evaluate exp expandpath fileexists find findnocase "+"findoneof firstdayofmonth fix formatbasen generatesecretkey "+"getauthuser getbasetagdata getbasetaglist getbasetemplatepath "+"getclientvariableslist getcontextroot getcurrenttemplatepath "+"getdirectoryfrompath getencoding getexception getfilefrompath "+"getfunctionlist getgatewayhelper gethttprequestdata gethttptimestring "+"getk2serverdoccount getk2serverdoccountlimit getlocale "+"getlocaledisplayname getlocalhostip getmetadata getmetricdata "+"getpagecontext getprofilesections getprofilestring getsoaprequest "+"getsoaprequestheader getsoapresponse getsoapresponseheader "+"gettempdirectory gettempfile gettemplatepath gettickcount "+"gettimezoneinfo gettoken hash hour htmlcodeformat htmleditformat "+"iif incrementvalue inputbasen insert int isarray isbinary isboolean "+"iscustomfunction isdate isdebugmode isdefined isk2serverabroker "+"isk2serverdoccountexceeded isk2serveronline isleapyear islocalhost "+"isnumeric isnumericdate isobject isquery issimplevalue issoaprequest "+"isstruct isuserinrole isvalid isvalid isvalid iswddx isxml "+"isxmlattribute isxmldoc isxmlelem isxmlnode isxmlroot javacast "+"jsstringformat lcase left len listappend listchangedelims listcontains "+"listcontainsnocase listdeleteat listfind listfindnocase listfirst "+"listgetat listinsertat listlast listlen listprepend listqualify "+"listrest listsetat listsort listtoarray listvaluecount "+"listvaluecountnocase ljustify log log10 lscurrencyformat lsdateformat "+"lseurocurrencyformat lsiscurrency lsisdate lsisnumeric lsnumberformat "+"lsparsecurrency lsparsedatetime lsparseeurocurrency lsparsenumber "+"lstimeformat ltrim max mid min minute month monthasstring now "+"numberformat paragraphformat parameterexists parsedatetime pi "+"preservesinglequotes quarter queryaddcolumn queryaddrow querynew "+"querysetcell quotedvaluelist rand randomize randrange refind "+"refindnocase releasecomobject removechars repeatstring replace "+"replacelist replacenocase rereplace rereplacenocase reverse right "+"rjustify round rtrim second sendgatewaymessage setencoding "+"setlocale setprofilestring setvariable sgn sin spanexcluding "+"spanincluding sqr stripcr structappend structclear structcopy "+"structcount structdelete structfind structfindkey structfindvalue "+"structget structinsert structisempty structkeyarray structkeyexists "+"structkeylist structnew structsort structupdate tan timeformat "+"tobase64 tobinary toscript tostring trim ucase urldecode urlencodedformat "+"urlsessionformat val valuelist week wrap writeoutput xmlchildpos "+"xmlelemnew xmlformat xmlgetnodetype xmlnew xmlparse xmlsearch xmltransform "+"xmlvalidate year yesnoformat";this.stringMatches=new Array();this.attributeMatches=new Array()};dp.sh.Brushes.ColdFusion.prototype=new dp.sh.Highlighter();dp.sh.Brushes.ColdFusion.Aliases=["coldfusion","cf"];dp.sh.Brushes.ColdFusion.prototype.ProcessRegexList=function(){function B(_,$){_[_.length]=$}function A(A,$){for(var _=0;_<A.length;_++)if(A[_]==$)return _;return-1}var _=null,$=null;this.GetMatches(new RegExp("\\b(\\d+)","gm"),"numbers");this.GetMatches(new RegExp(this.GetKeywords(this.mgKeywords),"igm"),"mgkeywords");this.GetMatches(dp.sh.RegexLib.SingleLineCComments,"cfscriptcomments");this.GetMatches(dp.sh.RegexLib.MultiLineCComments,"cfscriptcomments");this.GetMatches(new RegExp("(&lt;|<)!---[\\s\\S]*?---(&gt;|>)","gm"),"cfcomments");$=new RegExp("(cfset\\s*)?([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?')*","gm");while((_=$.exec(this.code))!=null){if(_[1]!=undefined&&_[1]!="")continue;if(_[3]!=undefined&&_[3]!=""&&_[3]!="\"\""&&_[3]!="''"){B(this.matches,new dp.sh.Match(_[2],_.index,"attribute"));B(this.matches,new dp.sh.Match(_[3],_.index+_[0].indexOf(_[3]),"attribute-value"));B(this.stringMatches,_[3]);B(this.attributeMatches,_[2])}}this.GetMatches(new RegExp("(&lt;|<)/*\\?*(?!\\!)|/*\\?*(&gt;|>)","gm"),"tag");$=new RegExp("(?:&lt;|<)/*\\?*\\s*([:\\w-.]+)","gm");while((_=$.exec(this.code))!=null)B(this.matches,new dp.sh.Match(_[1],_.index+_[0].indexOf(_[1]),"tag-name"));$=new RegExp(this.GetKeywords(this.keywords),"igm");while((_=$.exec(this.code))!=null)if(A(this.attributeMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"keywords"));$=new RegExp("cfset\\s*.*(\".*?\"|'.*?')","gm");while((_=$.exec(this.code))!=null)if(_[1]!=undefined&&_[1]!=""){B(this.matches,new dp.sh.Match(_[1],_.index+_[0].indexOf(_[1]),"strings"));B(this.stringMatches,_[1])}while((_=dp.sh.RegexLib.DoubleQuotedString.exec(this.code))!=null)if(A(this.stringMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"strings"));while((_=dp.sh.RegexLib.SingleQuotedString.exec(this.code))!=null)if(A(this.stringMatches,_[0])==-1)B(this.matches,new dp.sh.Match(_[0],_.index,"strings"))};dp.sh.Brushes.Cpp=function(){var _="ATOM BOOL BOOLEAN BYTE CHAR COLORREF DWORD DWORDLONG DWORD_PTR "+"DWORD32 DWORD64 FLOAT HACCEL HALF_PTR HANDLE HBITMAP HBRUSH "+"HCOLORSPACE HCONV HCONVLIST HCURSOR HDC HDDEDATA HDESK HDROP HDWP "+"HENHMETAFILE HFILE HFONT HGDIOBJ HGLOBAL HHOOK HICON HINSTANCE HKEY "+"HKL HLOCAL HMENU HMETAFILE HMODULE HMONITOR HPALETTE HPEN HRESULT "+"HRGN HRSRC HSZ HWINSTA HWND INT INT_PTR INT32 INT64 LANGID LCID LCTYPE "+"LGRPID LONG LONGLONG LONG_PTR LONG32 LONG64 LPARAM LPBOOL LPBYTE LPCOLORREF "+"LPCSTR LPCTSTR LPCVOID LPCWSTR LPDWORD LPHANDLE LPINT LPLONG LPSTR LPTSTR "+"LPVOID LPWORD LPWSTR LRESULT PBOOL PBOOLEAN PBYTE PCHAR PCSTR PCTSTR PCWSTR "+"PDWORDLONG PDWORD_PTR PDWORD32 PDWORD64 PFLOAT PHALF_PTR PHANDLE PHKEY PINT "+"PINT_PTR PINT32 PINT64 PLCID PLONG PLONGLONG PLONG_PTR PLONG32 PLONG64 POINTER_32 "+"POINTER_64 PSHORT PSIZE_T PSSIZE_T PSTR PTBYTE PTCHAR PTSTR PUCHAR PUHALF_PTR "+"PUINT PUINT_PTR PUINT32 PUINT64 PULONG PULONGLONG PULONG_PTR PULONG32 PULONG64 "+"PUSHORT PVOID PWCHAR PWORD PWSTR SC_HANDLE SC_LOCK SERVICE_STATUS_HANDLE SHORT "+"SIZE_T SSIZE_T TBYTE TCHAR UCHAR UHALF_PTR UINT UINT_PTR UINT32 UINT64 ULONG "+"ULONGLONG ULONG_PTR ULONG32 ULONG64 USHORT USN VOID WCHAR WORD WPARAM WPARAM WPARAM "+"char bool short int __int32 __int64 __int8 __int16 long float double __wchar_t "+"clock_t _complex _dev_t _diskfree_t div_t ldiv_t _exception _EXCEPTION_POINTERS "+"FILE _finddata_t _finddatai64_t _wfinddata_t _wfinddatai64_t __finddata64_t "+"__wfinddata64_t _FPIEEE_RECORD fpos_t _HEAPINFO _HFILE lconv intptr_t "+"jmp_buf mbstate_t _off_t _onexit_t _PNH ptrdiff_t _purecall_handler "+"sig_atomic_t size_t _stat __stat64 _stati64 terminate_function "+"time_t __time64_t _timeb __timeb64 tm uintptr_t _utimbuf "+"va_list wchar_t wctrans_t wctype_t wint_t signed",$="break case catch class const __finally __exception __try "+"const_cast continue private public protected __declspec "+"default delete deprecated dllexport dllimport do dynamic_cast "+"else enum explicit extern if for friend goto inline "+"mutable naked namespace new noinline noreturn nothrow "+"register reinterpret_cast return selectany "+"sizeof static static_cast struct switch template this "+"thread throw true false try typedef typeid typename union "+"using uuid virtual void volatile whcar_t while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^ *#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"datatypes"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-cpp";this.Style=".dp-cpp .datatypes { color: #2E8B57; font-weight: bold; }"};dp.sh.Brushes.Cpp.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Cpp.Aliases=["cpp","c","c++"];dp.sh.Brushes.CSharp=function(){var $="abstract as base bool break byte case catch char checked class const "+"continue decimal default delegate do double else enum event explicit "+"extern false finally fixed float for foreach get goto if implicit in int "+"interface internal is lock long namespace new null object operator out "+"override params private protected public readonly ref return sbyte sealed set "+"short sizeof stackalloc static string struct switch this throw true try "+"typeof uint ulong unchecked unsafe ushort using virtual void while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c";this.Style=".dp-c .vars { color: #d00; }"};dp.sh.Brushes.CSharp.prototype=new dp.sh.Highlighter();dp.sh.Brushes.CSharp.Aliases=["c#","c-sharp","csharp"];dp.sh.Brushes.CSS=function(){var _="ascent azimuth background-attachment background-color background-image background-position "+"background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top "+"border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color "+"border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width "+"border-bottom-width border-left-width border-width border cap-height caption-side centerline clear clip color "+"content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display "+"elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font "+"height letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top "+"margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans "+"outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page "+"page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position "+"quotes richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress "+"table-layout text-align text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em "+"vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index",$="above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder "+"both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed "+"continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double "+"embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia "+"gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic "+"justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha "+"lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower "+"navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset "+"outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side "+"rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow "+"small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize "+"table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal "+"text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin "+"upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow",A="[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif";this.regexList=[{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\#[a-zA-Z0-9]{3,6}","g"),css:"value"},{regex:new RegExp("(-?\\d+)(.\\d+)?(px|em|pt|:|%|)","g"),css:"value"},{regex:new RegExp("!important","g"),css:"important"},{regex:new RegExp(this.GetKeywordsCSS(_),"gm"),css:"keyword"},{regex:new RegExp(this.GetValuesCSS($),"g"),css:"value"},{regex:new RegExp(this.GetValuesCSS(A),"g"),css:"value"}];this.CssClass="dp-css";this.Style=".dp-css .value { color: black; }"+".dp-css .important { color: red; }"};dp.sh.Highlighter.prototype.GetKeywordsCSS=function($){return"\\b([a-z_]|)"+$.replace(/ /g,"(?=:)\\b|\\b([a-z_\\*]|\\*|)")+"(?=:)\\b"};dp.sh.Highlighter.prototype.GetValuesCSS=function($){return"\\b"+$.replace(/ /g,"(?!-)(?!:)\\b|\\b()")+":\\b"};dp.sh.Brushes.CSS.prototype=new dp.sh.Highlighter();dp.sh.Brushes.CSS.Aliases=["css"];dp.sh.Brushes.Delphi=function(){var $="abs addr and ansichar ansistring array as asm begin boolean byte cardinal "+"case char class comp const constructor currency destructor div do double "+"downto else end except exports extended false file finalization finally "+"for function goto if implementation in inherited int64 initialization "+"integer interface is label library longint longword mod nil not object "+"of on or packed pansichar pansistring pchar pcurrency pdatetime pextended "+"pint64 pointer private procedure program property pshortstring pstring "+"pvariant pwidechar pwidestring protected public published raise real real48 "+"record repeat set shl shortint shortstring shr single smallint string then "+"threadvar to true try type unit until uses val var varirnt while widechar "+"widestring with word write writeln xor";this.regexList=[{regex:new RegExp("\\(\\*[\\s\\S]*?\\*\\)","gm"),css:"comment"},{regex:new RegExp("{(?!\\$)[\\s\\S]*?}","gm"),css:"comment"},{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\{\\$[a-zA-Z]+ .+\\}","g"),css:"directive"},{regex:new RegExp("\\b[\\d\\.]+\\b","g"),css:"number"},{regex:new RegExp("\\$[a-zA-Z0-9]+\\b","g"),css:"number"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-delphi";this.Style=".dp-delphi .number { color: blue; }"+".dp-delphi .directive { color: #008284; }"+".dp-delphi .vars { color: #000; }"};dp.sh.Brushes.Delphi.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Delphi.Aliases=["delphi","pascal"];dp.sh.Brushes.Java=function(){var $="abstract assert boolean break byte case catch char class const "+"continue default do double else enum extends "+"false final finally float for goto if implements import "+"instanceof int interface long native new null "+"package private protected public return "+"short static strictfp super switch synchronized this throw throws true "+"transient try void volatile while";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b","gi"),css:"number"},{regex:new RegExp("(?!\\@interface\\b)\\@[\\$\\w]+\\b","g"),css:"annotation"},{regex:new RegExp("\\@interface\\b","g"),css:"keyword"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-j";this.Style=".dp-j .annotation { color: #646464; }"+".dp-j .number { color: #C00000; }"};dp.sh.Brushes.Java.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Java.Aliases=["java"];dp.sh.Brushes.JScript=function(){var $="abstract boolean break byte case catch char class const continue debugger "+"default delete do double else enum export extends false final finally float "+"for function goto if implements import in instanceof int interface long native "+"new null package private protected public return short static super switch "+"synchronized this throw throws transient true try typeof var void volatile while with";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c"};dp.sh.Brushes.JScript.prototype=new dp.sh.Highlighter();dp.sh.Brushes.JScript.Aliases=["js","jscript","javascript"];dp.sh.Brushes.Lua=function(){var $="break do end else elseif function if local nil not or repeat return and then until while this",_="math\\.\\w+ string\\.\\w+ os\\.\\w+ debug\\.\\w+ io\\.\\w+ error fopen dofile coroutine\\.\\w+ arg getmetatable ipairs loadfile loadlib loadstring longjmp print rawget rawset seek setmetatable assert tonumber tostring";this.regexList=[{regex:new RegExp("--\\[\\[[\\s\\S]*\\]\\]--","gm"),css:"comment"},{regex:new RegExp("--[^\\[]{2}.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"func"},];this.CssClass="dp-lua"};dp.sh.Brushes.Lua.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Lua.Aliases=["lua"];dp.sh.Brushes.Mxml=function(){this.CssClass="dp-mxml";this.Style=".dp-mxml .cdata { color: #000000; }"+".dp-mxml .tag { color : #0000ff; }"+".dp-mxml .tag-name { color: #0000ff; }"+".dp-mxml .script { color: green; }"+".dp-mxml .metadata { color: green; }"+".dp-mxml .attribute { color: #000000; }"+".dp-mxml .attribute-value { color: #990000; }"+".dp-mxml .trace { color: #cc6666; }"+".dp-mxml .var { color: #6699cc; }"+".dp-mxml .comment { color: #009900; }"+".dp-mxml .string { color: #990000; }"+".dp-mxml .keyword { color: blue; }"};dp.sh.Brushes.Mxml.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Mxml.Aliases=["mxml"];dp.sh.Brushes.Mxml.prototype.ProcessRegexList=function(){function H(_,$){_[_.length]=$}function B(B,_){var A=0,$=false;for(A=0;A<B.length;A++)if(_.index>B[A].firstIndex&&_.index<B[A].lastIndex)$=true;return $}var $=0,F=null,D=null,A=null,C="",E=new Array(),_="abstract boolean break byte case catch char class const continue debugger "+"default delete do double else enum export extends false final finally float "+"for function goto if implements import in instanceof int interface long native "+"new null package private protected public return short static super switch "+"synchronized this throw throws transient true try typeof var void volatile while with",G=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords("trace"),"gm"),css:"trace"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"keyword"}];A=new RegExp("&lt;\\!\\[CDATA\\[(.|\\s)*?\\]\\]&gt;","gm");while((F=A.exec(this.code))!=null){C=F[0].substr(0,12);H(this.matches,new dp.sh.Match(C,F.index,"cdata"));C=F[0].substr(12,F[0].length-12-6);for(var I=0;I<G.length;I++)while((D=G[I].regex.exec(C))!=null)H(this.matches,new dp.sh.Match(D[0],F.index+12+D.index,G[I].css));C=F[0].substr(F[0].length-6,6);H(this.matches,new dp.sh.Match(C,F.index+F[0].length-6,"cdata"));E.push({firstIndex:F.index,lastIndex:F.index+F[0].length-1})}this.GetMatches(new RegExp("(&lt;|<)!--\\s*.*?\\s*--(&gt;|>)","gm"),"comments");A=new RegExp("([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?'|\\w+)*|(\\w+)","gm");while((F=A.exec(this.code))!=null){if(F[1]==null)continue;if(B(E,F))continue;H(this.matches,new dp.sh.Match(F[1],F.index,"attribute"));if(F[2]!=undefined)H(this.matches,new dp.sh.Match(F[2],F.index+F[0].indexOf(F[2]),"attribute-value"))}A=new RegExp("(?:&lt;|<)/*\\?*\\s*([:\\w-.]+)","gm");while((F=A.exec(this.code))!=null){if(B(E,F))continue;C=F[0].substr(4,F[0].length-4);switch(C){case"mx:Script":case"/mx:Script":H(this.matches,new dp.sh.Match(F[0]+"&gt;",F.index,"script"));break;case"mx:Metadata":case"/mx:Metadata":H(this.matches,new dp.sh.Match(F[0]+"&gt;",F.index,"metadata"));break;default:H(this.matches,new dp.sh.Match(F[0],F.index,"tag-name"));break}}A=new RegExp("\\?&gt;|&gt;|/&gt;","gm");while((F=A.exec(this.code))!=null){if(B(E,F))continue;H(this.matches,new dp.sh.Match(F[0],F.index,"tag"))}};dp.sh.Brushes.Perl=function(){var _="abs accept alarm atan2 bind binmode bless caller chdir chmod chomp chop chown chr chroot close closedir connect cos crypt dbmclose dbmopen defined delete dump each endgrent endhostent endnetent endprotoent endpwent endservent eof exec exists exp fcntl fileno flock fork format formline getc getgrent getgrgid getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgrp getppid getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt glob gmtime grep hex import index int ioctl join keys kill lc lcfirst length link listen localtime lock log lstat m map mkdir msgctl msgget msgrcv msgsnd no oct open opendir ord pack pipe pop pos print printf prototype push q qq quotemeta qw qx rand read readdir readline readlink readpipe recv ref rename reset reverse rewinddir rindex rmdir scalar seek seekdir semctl semget semop send setgrent sethostent setnetent setpgrp setpriority setprotoent setpwent setservent setsockopt shift shmctl shmget shmread shmwrite shutdown sin sleep socket socketpair sort splice split sprintf sqrt srand stat study sub substr symlink syscall sysopen sysread sysseek system syswrite tell telldir tie tied time times tr truncate uc ucfirst umask undef unlink unpack unshift untie utime values vec waitpid wantarray warn write qr",$="s select goto die do package redo require return continue for foreach last next wait while use if else elsif eval exit unless switch case",A="my our local";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("(\\$|@|%)\\w+","g"),css:"vars"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(A),"gm"),css:"declarations"}];this.CssClass="dp-perl"};dp.sh.Brushes.Perl.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Perl.Aliases=["perl"];dp.sh.Brushes.Php=function(){var _="abs acos acosh addcslashes addslashes "+"array_change_key_case array_chunk array_combine array_count_values array_diff "+"array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill "+"array_filter array_flip array_intersect array_intersect_assoc array_intersect_key "+"array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map "+"array_merge array_merge_recursive array_multisort array_pad array_pop array_product "+"array_push array_rand array_reduce array_reverse array_search array_shift "+"array_slice array_splice array_sum array_udiff array_udiff_assoc "+"array_udiff_uassoc array_uintersect array_uintersect_assoc "+"array_uintersect_uassoc array_unique array_unshift array_values array_walk "+"array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert "+"basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress "+"bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir "+"checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists "+"closedir closelog copy cos cosh count count_chars date decbin dechex decoct "+"deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log "+"error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded "+"feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents "+"fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype "+"floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf "+"fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname "+"gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt "+"getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext "+"gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set "+"interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double "+"is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long "+"is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault "+"is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br "+"parse_ini_file parse_str parse_url passthru pathinfo readlink realpath rewind rewinddir rmdir "+"round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split "+"str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes "+"stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk "+"strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime "+"strtoupper strtr strval substr substr_compare",$="and or xor __FILE__ __LINE__ array as break case "+"cfunction class const continue declare default die do else "+"elseif empty enddeclare endfor endforeach endif endswitch endwhile "+"extends for foreach function include include_once global if "+"new old_function return static switch use require require_once "+"var while __FUNCTION__ __CLASS__ "+"__METHOD__ abstract interface public implements extends private protected throw";this.regexList=[{regex:dp.sh.RegexLib.SingleLineCComments,css:"comment"},{regex:dp.sh.RegexLib.MultiLineCComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp("\\$\\w+","g"),css:"vars"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-c"};dp.sh.Brushes.Php.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Php.Aliases=["php"];dp.sh.Brushes.Python=function(){var $="and assert break class continue def del elif else "+"except exec finally for from global if import in is "+"lambda not or pass print raise return try yield while",_="None True False self cls class_";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:new RegExp("^\\s*@\\w+","gm"),css:"decorator"},{regex:new RegExp("(['\"]{3})([^\\1])*?\\1","gm"),css:"comment"},{regex:new RegExp("\"(?!\")(?:\\.|\\\\\\\"|[^\\\"\"\\n\\r])*\"","gm"),css:"string"},{regex:new RegExp("'(?!')*(?:\\.|(\\\\\\')|[^\\''\\n\\r])*'","gm"),css:"string"},{regex:new RegExp("\\b\\d+\\.?\\w*","g"),css:"number"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"special"}];this.CssClass="dp-py";this.Style=".dp-py .builtins { color: #ff1493; }"+".dp-py .magicmethods { color: #808080; }"+".dp-py .exceptions { color: brown; }"+".dp-py .types { color: brown; font-style: italic; }"+".dp-py .commonlibs { color: #8A2BE2; font-style: italic; }"};dp.sh.Brushes.Python.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Python.Aliases=["py","python"];dp.sh.Brushes.Ruby=function(){var $="alias and BEGIN begin break case class def define_method defined do each else elsif "+"END end ensure false for if in module new next nil not or raise redo rescue retry return "+"self super then throw true undef unless until when while yield",_="Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload "+"Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol "+"ThreadGroup Thread Time TrueClass";this.regexList=[{regex:dp.sh.RegexLib.SingleLinePerlComments,css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(":[a-z][A-Za-z0-9_]*","g"),css:"symbol"},{regex:new RegExp("(\\$|@@|@)\\w+","g"),css:"variable"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"},{regex:new RegExp(this.GetKeywords(_),"gm"),css:"builtin"}];this.CssClass="dp-rb";this.Style=".dp-rb .symbol { color: #a70; }"+".dp-rb .variable { color: #a70; font-weight: bold; }"};dp.sh.Brushes.Ruby.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Ruby.Aliases=["ruby","rails","ror"];dp.sh.Brushes.Sql=function(){var _="abs avg case cast coalesce convert count current_timestamp "+"current_user day isnull left lower month nullif replace right "+"session_user space substring sum system_user upper user year",$="absolute action add after alter as asc at authorization begin bigint "+"binary bit by cascade char character check checkpoint close collate "+"column commit committed connect connection constraint contains continue "+"create cube current current_date current_time cursor database date "+"deallocate dec decimal declare default delete desc distinct double drop "+"dynamic else end end-exec escape except exec execute false fetch first "+"float for force foreign forward free from full function global goto grant "+"group grouping having hour ignore index inner insensitive insert instead "+"int integer intersect into is isolation key last level load local max min "+"minute modify move name national nchar next no numeric of off on only "+"open option order out output partial password precision prepare primary "+"prior privileges procedure public read real references relative repeatable "+"restrict return returns revoke rollback rollup rows rule schema scroll "+"second section select sequence serializable set size smallint static "+"statistics table temp temporary then time timestamp to top transaction "+"translation trigger true truncate uncommitted union unique update values "+"varchar varying view when where with work",A="all and any between cross in join like not null or outer some";this.regexList=[{regex:new RegExp("--(.*)$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:dp.sh.RegexLib.SingleQuotedString,css:"string"},{regex:new RegExp(this.GetKeywords(_),"gmi"),css:"func"},{regex:new RegExp(this.GetKeywords(A),"gmi"),css:"op"},{regex:new RegExp(this.GetKeywords($),"gmi"),css:"keyword"}];this.CssClass="dp-sql";this.Style=".dp-sql .func { color: #ff1493; }"+".dp-sql .op { color: #808080; }"};dp.sh.Brushes.Sql.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Sql.Aliases=["sql"];dp.sh.Brushes.Vb=function(){var $="AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto "+"Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate "+"CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType "+"Date Decimal Declare Default Delegate Dim DirectCast Do Double Each "+"Else ElseIf End Enum Erase Error Event Exit False Finally For Friend "+"Function Get GetType GoSub GoTo Handles If Implements Imports In "+"Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module "+"MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing "+"NotInheritable NotOverridable Object On Option Optional Or OrElse "+"Overloads Overridable Overrides ParamArray Preserve Private Property "+"Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume "+"Return Select Set Shadows Shared Short Single Static Step Stop String "+"Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until "+"Variant When While With WithEvents WriteOnly Xor";this.regexList=[{regex:new RegExp("'.*$","gm"),css:"comment"},{regex:dp.sh.RegexLib.DoubleQuotedString,css:"string"},{regex:new RegExp("^\\s*#.*","gm"),css:"preprocessor"},{regex:new RegExp(this.GetKeywords($),"gm"),css:"keyword"}];this.CssClass="dp-vb"};dp.sh.Brushes.Vb.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Vb.Aliases=["vb","vb.net"];dp.sh.Brushes.Xml=function(){this.CssClass="dp-xml";this.Style=".dp-xml .cdata { color: #ff1493; }"+".dp-xml .tag, .dp-xml .tag-name { color: #069; font-weight: bold; }"+".dp-xml .attribute { color: red; }"+".dp-xml .attribute-value { color: blue; }"};dp.sh.Brushes.Xml.prototype=new dp.sh.Highlighter();dp.sh.Brushes.Xml.Aliases=["xml","xhtml","xslt","html","xhtml"];dp.sh.Brushes.Xml.prototype.ProcessRegexList=function(){function B(_,$){_[_.length]=$}var $=0,A=null,_=null;this.GetMatches(new RegExp("(&lt;|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](&gt;|>)","gm"),"cdata");this.GetMatches(new RegExp("(&lt;|<)!--\\s*.*?\\s*--(&gt;|>)","gm"),"comments");_=new RegExp("([:\\w-.]+)\\s*=\\s*(\".*?\"|'.*?'|\\w+)*|(\\w+)","gm");while((A=_.exec(this.code))!=null){if(A[1]==null)continue;B(this.matches,new dp.sh.Match(A[1],A.index,"attribute"));if(A[2]!=undefined)B(this.matches,new dp.sh.Match(A[2],A.index+A[0].indexOf(A[2]),"attribute-value"))}this.GetMatches(new RegExp("(&lt;|<)/*\\?*(?!\\!)|/*\\?*(&gt;|>)","gm"),"tag");_=new RegExp("(?:&lt;|<)/*\\?*\\s*([:\\w-.]+)","gm");while((A=_.exec(this.code))!=null)B(this.matches,new dp.sh.Match(A[1],A.index+A[0].indexOf(A[1]),"tag-name"))}
//}}}
The H8/3292 chip of the RCX operates in mode 2. The mode can be read as the values of bit 1 and bit 0 in the Mode Control Register at address 0xffc5. In mode 2 the on-chip ROM, RAM, and register field are enabled. Furthermore, the 32 Kbytes external RAM chip is mapped into the 16-bit address space by external address decoding logic. We can only access the external RAM chip when we use adresses in those parts of the address space that are not occupied by the on-chip memories.

The memory map is thus determined by the choice of mode 2 and the external address decoding. The resulting memory layout is as follows:
|Addresse range|Memory type|Contents|
|0x000 - 0x3fff|on-chip mask programmable ROM|H8/3292 interrupt vectors, RCX executive|
|0x8000 - 0xefff|off chip RAM|program/data|
|0xf000|off-chip register|device register for RCX output ports|
|0xfd80 - 0xff7f|on-chip RAM|RCX interrupt vectors/program/data|
|0xff88 - 0xffff|on-chip register field|H8/3292 device registers|
(Taken from http://legolab.daimi.au.dk/CSaEA/RCX/Manual.dir/RCXManual.html#Microcontroller)

From here HaikuVM uses addresse range 0x8000 - 0xefff:
|Addresse range|Size|Contents|
|0x8000 - 0xcfff| 20480|JVM: section text / bytecode: section haiku|
|0xd000 - 0xefff| 8192|heap / data / initialized data|
For more details see file /haikuVM/hardware/tools/lejos_rcx/rcx.lds

Using a default heap size of 5000 byte.
!Workflow of ~HaikuVM
The basic idea behind ~HaikuVM is pretty simple. ~HaikuVM uses javac to generate class files and then post processes them a bit. The resulting class files turn into data, stuffed in C structures that you compile and bundle with the Haiku JVM and the system libraries to get an executable program (in the case of the Arduino, a hex file). All parts are compiled by a C cross compiler for your target platform. During runtime the Haiku VM interpretes the JAVA byte code, stored in the C data structures mentioned above.  ([[More ...|Compact HaikuVM Code]]) So ~HaikuVM will not (and is not designed to) load class files after C compilation is done. ~HaikuVM is an [[Ahead-of-time (AOT) compiler]].

[img[images/overview.png]]
!!step one (java to class)
Translate your JAVA program with [[haikuc]] into a class-file (bytecode). This will translate the JAVA class given by you. From this seed it recursively determines which classes and class members are used. All other classes and class members are discarded. For this job [[haikuc]] uses javac. But it will not compile against rt.jar (the standard JAVA runtime). Instead it will use the leJOS runtime which is given in classes.jar. Superseded by haikuRT, to pick and overwrite a specific small set of this leJOS runtime classes to adapt to ~HaikuVM and micros.
!!step two (class to C)
Basically [[haikulink]] will read the bytecode (using the BCEL library) and translate it into C data structures. In contrast, other systems e.g. GCJ will translate direct into C program code. With Haiku the only C code is the C code of the Haiku virtual machine (Haiku VM) itself augmented with C data structures.  Together this is linked into the binary by [[haikulink]]. During runtime (e.g. in an Atmega8) the Haiku VM interpretes the data in the (above mentioned) C data structures.  ([[More ...|Compact HaikuVM Code]])
!!step three (C to binary)
Because [[haikulink]] translated into C code we now need to cross-compile it for the target machine. This is in contrast to leJOS (and ~NanoVM) where no cross-compiling step is needed. On the other hand cross-compiling allows a tight coupling of the above C data structures and the Haiku VM. In addition the linker step will eliminate all unneeded code and data. This is the main reason for having surprisingly short binaries representing your JAVA program.
!!step four (upload and run)
[[haikuupload]] uploads the binary builded in step three, to the microprocessor.
!Philosopie of ~HaikuVM
~HaikuVM tries to use as less as possible native methods. (Native methods are methods which have to be written in C.) The idea is to reduce (not restrict) the native methods to the following small set:
A) reading from and writting to RAM memory like this:
*public static native int  getMemory8(int adr);
*public static native void setMemory8(int adr, int value);
*... about 10 more memory setter and getter methods
B) A method for getting the time in milliseconds:
*public static native long currentTimeMillis();
C) A method for copying arrays:
*public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
D) And methods for Thread schedule:
*private native int fork();
*private native int setStateAndSwitch(int state);
Before a simple ~HalloWorld Java program like this:
<code java>
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
</code>
will run on a micro you usually have to initialize several things. This boilerplate code for basic initialization have to be written for each Java program you write. Typically you have to write code for:
* initialize serial output (baud rate etc.).
* code a basic write(aByte) and readByte() method.
* initialize a time base.
* write an exception handler.

You will find different approaches for this. Here I list only three:
#Write code for initialization in your Java program<br>This is flexible when adapting to different ~AVRs but pollutes your Jave code.
#Write code for initialization in C, right into Haiku VM's C code<br>This has to be specific for an AVR model and could be done for every AVR with a big #if. But then it's easy to forget a specific AVR or initialisation aspect and, for new micros, you are forced to write C code. In this concern it's an inflexible approach but, at the end, does not pollute your Java code.
#Write code for initialization in C, using JNI functionality<br>This is a variant of the above alternative.

Here I give you an example for the first approach:  initialization (of an Arduino Duemilanove) in your Java program:
<code java>
package arduino.tutorial;

import static haiku.avr.AVRConstants.*;

public class HelloWorldWithoutHaikuKernel {
    private static final int BAUD_RATE = 57600;
    private static final long F_CPU = 16000000;

    private static void init() {
        // set baud rate
        final short t = (short) (((F_CPU >> 4) + (BAUD_RATE >>> 1)) / BAUD_RATE - 1);
        UBRR0H = (t >>> 8);
        UBRR0L = t;
        UCSR0B = (1 << RXEN0) | (1 << TXEN0);
    }

    private static void write(int b) {
        while ((UCSR0A & (1 << UDRE0)) == 0)
            ;

        UDR0 = b;
    }

    public static void println(String line) {
        for (int i = 0; i < line.length(); i++) {
            write(line.charAt(i));
        }
        write('\r');
        write('\n');
    }

    public static void main(String[] args) {
        init();
        println("Hello World");
        while(true) ;
    }
}
</code>
Because no timer methods are needed and no exceptions are thrown the code for initializing this is neglegted. At least this program is complete and will print "Hello World" on an Arduino Duemilanove. But it includes all the things which are needed to configure an Arduino Duemilanove for this job. Due to this fact it is not portable to other micros.

|bgcolor(#6f6): ~HelloWorldWithoutHaikuKernel<br><br><br><br> |
|bgcolor(#66b): The Haiku VM<br> |
|bgcolor(#b66): Hardware: Duemilanove  |
| Your "Hello World" program is specific for Duemilanove  |c

~HaikuVM follows an ''innovative fourth'' approach by introducing a ''~MicroKernel''. The idea is that the ~MicroKernel, written in Java, should cover all the target micro specific initialization code. So the C part of ~HaikuVM can kept more generic and free from model specific C code. (With the intention that nobody is forced to write C code for a new micro.) While your main Java program can be expressed without being polluted by boilerplate code for specific AVR initialization.

Factoring out initialisation code from ~HelloWorldWithoutHaikuKernel into a ''~HaikuKernel'' looks like this for an Arduino Duemilanove:
<code java>
package arduino.tutorial;

import static haiku.avr.AVRConstants.*;
import java.io.*;

public class HaikuKernel {
    private static final int BAUD_RATE = 57600;
    private static final long F_CPU = 16000000;

    private static void init() {
        // set baud rate
        final short t = (short) (((F_CPU >> 4) + (BAUD_RATE >>> 1)) / BAUD_RATE - 1);
        UBRR0H = (t >>> 8);
        UBRR0L = t;
        UCSR0B = (1 << RXEN0) | (1 << TXEN0);
        
        // set timer 0 prescale factor to 64
        TCCR0B = (1<<CS01)  | (1<<CS00);
        
        // enable timer 0 overflow interrupt
        TIMSK0 = (1<<TOIE0);

        System.out = new PrintStream(new OutputStream() {
            public void write(int b) throws IOException {
                while ((UCSR0A & (1 << UDRE0)) == 0)
                    ;

                UDR0 = b;
            }
        });
    }

    public static void main(String[] args) {
        init();
        haiku.vm.HaikuMagic.main(args); // attention, attention, here is some magic
        Thread.currentThread().stop();
    }
}
</code>
In conjunction with this ~HaikuKernel you are ready to use the ''now portable'' ~HelloWorld program from the begin of this tutorial. For this you have to configure this ~HaikuKernel  in '~HaikuVM.properties' to be used with your configuration. Then HaikuVM will start your ~MicroKernel first. Then the ~MicroKernel will start your program. For this you may have noticed line 35. Line 35 leading us to some ''Haiku magic''. The magic here is that [[haikulink]] will substitute the call of ''haiku.vm.~HaikuMagic.main(args)'' by the call of your Java main method. In this tutorial effectively resulting in a call of ''~HelloWorld.main(args)'' during linktime.

|bgcolor(#6f6): ~HelloWorld<br> |
|bgcolor(#6b6): <br>~MicroKernel: ~HaikuKernel for Duemilanove<br><br><br> |
|bgcolor(#66b): The Haiku VM<br> |
|bgcolor(#b66): Hardware: Duemilanove  |
| Only the ~MicroKernel is specific for Duemilanove  |c

Now your program (and others) runs unchanged on an Arduino Leonardo. (And you only have to write a Microkernel for a micro once.)

|bgcolor(#6f6): ~HelloWorld<br> |
|bgcolor(#6b6): <br>~MicroKernel: ~HaikuKernel for Leonardo<br><br><br> |
|bgcolor(#66b): The Haiku VM<br> |
|bgcolor(#b66): Hardware: Leonardo |
| Only the ~MicroKernel is specific for Leonardo |c


The download of ~HaikuVM includes predefined ~HaikuKernels for several AVR models and platforms. If yours is missing and you designed a ~HaikuKernel for it, please send it to me. I will include it in future versions of ~HaikuVM.

You may set your ~MicroKernel in file [[HaikuVM.properties]] or at the [[Command Line|Command Line Options]]. If you don't want to use a micro kernel use the special value ''undef''.

Advantages of using a ~MicroKernel:
* no need for JNI code to initialize your AVR.
* full flexibility in Java having no need to switch to C.
* initialization code written in Java ~MicroKernels tends to be 4 times shorter than equivalent C code (see [[Compact]]).
* exception handler is seamingly integrated in the general exception handling of Java.

To be continued ...
Blink is the "Hello World" for microcontroller. The primary goal of Blink is to let a LED blink, which is connected with one of the pins of the microcontroller in focus. All examples given here, assume that you use a microcontroller based on ~ATmega328p.

!~BlinkSimple

If you are a beginner or faced with the fact having a microcontroller not supported by ~HaikuVM yet, then this is a good starting point. For ~BlinkSimple.java, only the pure minimum of preconditions for running a ~HaikuVM program are need to be fullfilled. Especialy timing and serial IO is no precondition for ~BlinkSimple.

~BlinkSimple assumes that the LED is connected with Port B and Bit 5. The ''manual for ~ATmega328p'' states that you need register DDRB to set the ~IN- or OUTPUT direction of every pin of PORTB. Here we set pin 5 to output. To have direct memory access to the underlying 8 Bit C Variables DDRB and PORTB we have to declare them and annotate them as @~NativeCVariable8 (see chapter [[Memory Access]]).

<code java>
import haiku.vm.NativeCVariable8;

public class BlinkSimple {
    @NativeCVariable8
    private static volatile int DDRB;
    
    @NativeCVariable8
    private static volatile int PORTB;

    private static final int LED = 1 << 5;

    private static void delay(int nounit) {
        while(nounit>0) {
            nounit--;
        }
    }

    public static void main(String[] args) {
        // Data direction of I/O-Port.
        DDRB = LED; // set pin 5 to output
        while (true) {
            PORTB |= LED; // on
            delay(3000);
            PORTB &= ~LED; // off
            delay(3000);
        }
    }
}
</code>

~BlinkSimple can be started like this (provided you installed ~HaikuVM in C:\haikuVM):
<code bash>
mkdir myProject 
cd myProject 
C:\haikuVM\bin\haiku -v --Config avr -o BlinkSimple.hex C:\haikuVM\examples\src\main\java\avr\tutorial\BlinkSimple.java
</code>

So far so simple. But we can do better. The problem with ~BlinkSimple is the delay-function.We just have a loop wasting some CPU cycles (busy wait).  And we don't have any time units. What we really want, is a blink intervall of 3000 milli seconds. To accomplish this we have to setup proper timing.

!Blink

Next we want to use Thread.sleep(..) for the delay-function. For this we have to setup proper timing. In this tutorial all you have to know is that timing is done via timer 0 overflow interrupt. (For more details on timing see [[Tutorial Timing]].)  You have to set timer 0 prescale factor to 64 and enable timer 0 overflow interrupt. The timer 0 overflow interrupt itself is already part of the Haiku VM code (and assumes a prescale factor of 64). So you don't have to care about this now. To find the proper registers to set you have to take a look into the ''manual for ~ATmega328p''. We have to use register ~TCCR0B to set the prescale factor and ~TIMSK0 to enable the interrupt.

<code java>
package avr.tutorial;

import haiku.vm.NativeCVariable8;

public class Blink {
    @NativeCVariable8
    private static volatile int TCCR0B;
    private static final int CS00 = 0;
    private static final int CS01 = 1;
    private static final int CS02 = 2;
    private static final int WGM02 = 3;
    private static final int FOC0B = 6;
    private static final int FOC0A = 7;

    @NativeCVariable8
    private static volatile int TIMSK0;
    private static final int TOIE0 = 0;
    private static final int OCIE0A = 1;
    private static final int OCIE0B = 2;

    @NativeCVariable8
    private static volatile int PORTB;

    @NativeCVariable8
    private static volatile int DDRB;
    
    private static final int LED = _BV(5);

    private static void initAtmega328p_16MHz() {
        // set timer 0 prescale factor to 64
        // for correct millisecond timing of:
        // Atmega328p 16MHz
        TCCR0B |= _BV(CS01) | _BV(CS00);

        // enable timer 0 overflow interrupt
        // important for:
        // Thread.sleep(ms)
        // System.currentTimeMillis()
        TIMSK0 |= _BV(TOIE0);
    }

    private static void delay(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
        }
    }

    public static int _BV(int bit) {
        return 1 << bit;
    }

    public static void main(String[] args) {
        initAtmega328p_16MHz();

        // Data direction of I/O-Port.
        DDRB = LED;
        while (true) {
            PORTB |= LED; // on
            delay(3000);
            PORTB &= ~LED; // off
            delay(3000);
        }
    }
}
</code>

Blink can be started like this (provided you installed ~HaikuVM in C:\haikuVM):
<code bash>
mkdir myProject 
cd myProject 
C:\haikuVM\bin\haiku -clean -v --Config duemilanove C:\haikuVM\examples\src\main\java\avr\tutorial\Blink.java
</code>
~~Here I use option -clean just to make sure that files, possible left from the previous example, are deleted to not interfere with this Blink example.~~

!Blinky

Can we do better. Yes, we can. All this native variable declarations are already done for you in 'haiku.avr.~AVRConstants.java'. So, if we import this, the code become more compact.

<code java>
package avr.tutorial;

import static haiku.avr.AVRConstants.*;

public class Blinky {
    // LED is connected with PORTB and Bit 5.
    // give it a name:
    private static final int LED = 1 << 5;

    private static void initAtmega328p_16MHz() {
        // set timer 0 prescale factor to 64
        // for correct millisecond timing of:
        // Atmega328p 16MHz
        TCCR0B |= (1<<CS01) | (1<<CS00);

        // enable timer 0 overflow interrupt
        // important for:
        // Thread.sleep(ms)
        // System.currentTimeMillis()
        TIMSK0 |= (1<<TOIE0);
    }

    public static void main(String[] args) throws InterruptedException {
        initAtmega328p_16MHz();

        // initialize the digital pin as an output.
        DDRB |= LED;
        // the loop runs forever:
        while (true) {
            PORTB |= LED;       // turn the LED on (HIGH is the voltage level)
            Thread.sleep(1000); // wait for a second
            PORTB &= ~LED;      // turn the LED off by making the voltage LOW
            Thread.sleep(1000); // wait for a second
        }
    }
}
</code>

Again, Blinky can be started like this (provided you installed ~HaikuVM in C:\haikuVM):
<code bash>
mkdir myProject 
cd myProject 
C:\haikuVM\bin\haiku -clean --Config duemilanove C:\haikuVM\examples\src\main\java\avr\tutorial\Blinky.java
</code>

!~BlinkyWithMicroKernel

Can we do better. Yes, we still can. With the configuration 'duemilanove' comes a ~MicroKernel which is specific for the Duemilanove. Brief, a microkernel is a piece of ''JAVA'' code which function is to initialize the hardware. (See [[Tutorial All About MicroKernels]] to learn more about microkernels. The invention of microkernels, itself written in JAVA, is possibly the biggest invention of HaikuVM.) Now, after the initialization of timer0 is factored out into a ~MicroKernel the code becomes very compact.
<code java>
package avr.tutorial;

import static haiku.avr.AVRConstants.*;

public class BlinkyWithMicroKernel {
    // LED is connected with PORTB and Bit 5.
    // give it a name:
    private static final int LED = 1 << 5;

    public static void main(String[] args) throws InterruptedException {
        // initialize the digital pin as an output.
        DDRB |= LED;
        // the loop runs forever:
        while (true) {
            PORTB |= LED;       // turn the LED on (HIGH is the voltage level)
            Thread.sleep(1000); // wait for a second
            PORTB &= ~LED;      // turn the LED off by making the voltage LOW
            Thread.sleep(1000); // wait for a second
        }
    }
}
</code>

~BlinkyWithMicroKernel can be started like this (provided you installed ~HaikuVM in C:\haikuVM):
<code bash>
mkdir myProject 
cd myProject 
C:\haikuVM\bin\haiku -clean --Config duemilanove C:\haikuVM\examples\src\main\java\avr\tutorial\BlinkyWithMicroKernel.java
</code>

You might be interrested in [[Tutorial Interrupts]], too.
There are many examples in file [[HaikuVM.properties]] for allready configured microcontrollers. If yours is not in the file, start by copying a configuration which closest match your micro and give it a new name. Then adapt the values to your needs.
There might be situations where interaction with an C interrupt routine is wanted. ~HaikuVM, as a JAVA VM, does not support interrupts. Instead, interrupt routines have to be written in C. This can be done for every interrupt, except for the timer 0 overflow interrupt which is reserved for ~HaikuVM's timing. (But is configurable via option [[TimerInterrupt|Command Line Options]].) ''Interrupts are enabled by default in ~HaikuVM.''

It's not the goal of this tutorial to explain interrupts. Here are great tutorials on AVR interrupts:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=55347

In this tutorial I want to show how to interact with a '~TIMER2_OVF_vect' interrupt routine. The timer 2 overflow interrupt is handled in function  '~TIMER2_OVF_vect' mean and lean by just incrementing a variable of type jlong. This is how the C code looks like to accomplish this:
<code cpp>
#include ???
#include <avr/interrupt.h>

volatile static jlong timer2_interrupts = 0;

ISR(TIMER2_OVF_vect) {
    timer2_interrupts ++;
}
</code>

On the other end there is a Java program which wants to read out the value of timer2_interrupts and prints the first 10 values. This is how the Java program looks like (until now):
<code java>
package arduino.tutorial;

import static haiku.avr.AVRConstants.*;

public class InterruptTimer2 {

    private static native long getTimer2();

    public static void main(String[] args) {
        // TODO: set up timer2

        for (int i = 0; i < 10; i++) {
            System.out.println("Value of timer2_interrupts is: " + getTimer2());
        }
    }
}
</code>

As you may have expected, we use a ''native'' Java method to read out the value of timer2_interrupts (see line 07 above). From the [[Tutorial JNI]] we have learned that ''all'' JNI C function wrappers are generated during the [[haikulink]] phase and placed in file './myCProject/haikuVM/utility/haikuJNI.c' for cut&past usage. So we pick our getTimer2(..) function wrapper and getTime2(..) JNI template from there and cut&past it into our C file which now becomes:
<code cpp>
#include <jni.h>
#include <avr/interrupt.h>

volatile static jlong timer2_interrupts = 0;

ISR(TIMER2_OVF_vect) {
    timer2_interrupts ++;
}

/**
 * Automatic generated JNI template
 * getTimer2()J
 */
JNIEXPORT jlong Java_avr_tutorial_Interrupt1_getTimer2( JNIEnv *env, jobject obj) {
    // TODO: insert your code here
    return 0;
}

/**
 * Automatic generated JNI wrapper
 * getTimer2()J
 */
JNIEXPORT void native_arduino_tutorial_InterruptTimer2_getTimer2_J(void) {
    pushTop();	// Save variable top onto stack.
    {
        jobject	obj = NULL;
        JNIEnv *env = NULL;
        top.j = Java_arduino_tutorial_InterruptTimer2_getTimer2(env, obj);
    }
    // Variable top holds the return value. But we have to push the lower half.
    pushTop0();
}
</code>
(Don't forget to insert line 01 to include the basic JNI type declarations.)

If you inspect the JNI function '~Java_avr_tutorial_Interrupt1_getTimer2(env, obj)' you will see a TODO which has to be filled. In our case we want to access and return the value of timer2_interrupts:
<code cpp>
#include <jni.h>
#include <avr/interrupt.h>

volatile static jlong timer2_interrupts = 0;

ISR(TIMER2_OVF_vect) {
    timer2_interrupts ++;
}

/**
 * Automatic generated JNI template
 * getTimer2()J
 */
JNIEXPORT jlong Java_arduino_tutorial_InterruptTimer2_getTimer2(JNIEnv *env, jobject obj) {
    jlong value;
    uint8_t oldSREG = SREG;
    cli(); // we don't want to be desturbed by an interrupt
    value = timer2_interrupts;
    SREG = oldSREG; // restore interruptable state again.
    return value;
}

/**
 * Automatic generated JNI wrapper
 * getTimer2()J
 */
JNIEXPORT void native_arduino_tutorial_InterruptTimer2_getTimer2_J(void) {
    pushTop();	// Save variable top onto stack.
    {
        jobject	obj = NULL;
        JNIEnv *env = NULL;
        top.j = Java_arduino_tutorial_InterruptTimer2_getTimer2(env, obj);
    }
    // Variable top holds the return value. But we have to push the lower half.
    pushTop0();
}
</code>
(See also './haikuVM/myCProject/tutorials/interruptTimer2.c').

There is only a final step missing. We have to initialize timer 2 and its overflow interrupt (here for ~ATmega328p) . In this example its done in the Java main(..) method of our example (see also 'arduino.tutorial/~InterruptTimer2.java'):
<code java>
package arduino.tutorial;

import static haiku.avr.AVRConstants.*;

public class InterruptTimer2 {

    private static native long getTimer2();

    public static void main(String[] args) {
        // prescaler 1024
        TCCR2B = (1<<CS22) | (1<<CS21) | (1<<CS20);

        // enable timer interrupt overflow
        TIMSK2 = (1<<TOIE2);

        for (int i = 0; i < 10; i++) {
            System.out.println("Value of timer2_interrupts is: " + getTimer2());
        }
    }
}
</code>

Have fun when playing with different prescale values!

*[[JNI Overview]]
*[[Native JAVA Methods]]
*[[JNI simple]]
*[[JNI enhanced]]
*[[JNI using functions from a C library]]
*[[JNI using functions from a C library using annotations]]
*[[Beyond JNI: put C code into your java files]]
*[[Beyond JNI: Java class as proxy to a C++ class]]
*[[JNI field access]]
*[[JNI Summary]]
Here are great tutorials on AVR timers:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106
This tutorial on timing in ~HaikuVM compliments those. Those tutorials are aimed at the C language, here I'll give some insight on how ~HaikuVM uses the AVR's timers.

First of all, the VM of Haiku (written in C) does not set or configure any timer, it's up to your Java program to do that. Many simple C and therefore Java programs do work without the use of timers. 

On the other hand, when you start to use some of Java's time methods like 
*Thread.sleep(..), 
*Thread.wait(..), 
*System.currentTimeMillis()
*Or you want to use multiple Threads 
then ''a proper setup of timer 0 is important''. Therefore many [[HaikuMicroKernels|Tutorial All About MicroKernels]] (written in Java) will setup a timer. The VM of Haiku (for ~AVRs) is designed in a way that proper timing relies on timer 0 overflow interrupt. The timer 0 overflow interrupt is handled in an already predefined interrupt routine '~TIMER0_OVF_vect' (located in file './haikuVM/simpleOS.c') and just increments variable 'timer0_interrupts'. From this variable the function millis() derives the milliseconds for Thread.sleep(..), Thread.wait(..), etc. and for Thread scheduling. Here is some C-code, to give you a clue:
<code cpp>
volatile jmillis timer0_interrupts = 0;
...
SIGNAL(TIMER0_OVF_vect)
{
    timer0_interrupts++;
}
...
julong millis()
{
    jmillis m;
    uint8_t oldSREG = SREG;
    cli();
    m = timer0_interrupts;
    SREG = oldSREG;
    return m * HAIKU_MillisDividend / HAIKU_MillisDivisor;
}
</code>
Where ''~HAIKU_MillisDividend'' and ''~HAIKU_MillisDivisor'' are #defines (see file 'haikuDefs.h') and those values will be pre-calculated automatically during the [[haikulink]] phase derived from HaikuVM property Clock (see [[HaikuVM.properties]]). The values for ''~HAIKU_MillisDividend'' and ''~HAIKU_MillisDivisor'' are calculated in a way to produce an interrupt every millisecond as close as possible (assuming a prescaler of 64 for timer 0). See the table below. If, for some reasons, you don't want to live with the predefined values or you want to use a different prescale you have to define your values manually in file '~HaikuVM.properties' like this:
<code bash>
myconfig.MillisDividend = 128
myconfig.MillisDivisor = 125
</code>
Where "myconfig" is the Config-parameter you choose in the commandline of [[haikulink]] or [[haiku]].

This is a snipped showing how you setup the timer 0 with a prescale of 64 and enable timer 0 overflow interrupt for an Atmega8, Atmega16,  etc.:
<code java>
import static haiku.avr.AVRConstants.*;
...
// In main():
        // Timer-Configuration: Prescaler to 1/64
        TCCR0 |= (1 << CS01);
        TCCR0 |= (1 << CS00);
        // Timer-Overflow-Interrupt-Enable Timer0
        TIMSK |= (1 << TOIE0); 
...
</code>

This is a snipped showing how you setup the timer 0 with a prescale of 64 and enable timer 0 overflow interrupt for an Atmega328p,  etc.:
<code java>
import static haiku.avr.AVRConstants.*;
...
// In main():
        TCCR0B |= _BV(CS01) | _BV(CS00); // set prescaler to 1/64
        TIMSK0 |= _BV(TOIE0); // Timer0-Overflow-Interrupt-Enable
...
</code>

For a complete, running Java example which sets up timer 0 for ~ATmega328p take a look at 'C:\haikuVM\examples\src\main\java\avr\tutorial\Blink.java' and/or here [[Tutorial Blink]].

Here is a table, presenting what  ''~MillisDividend'' and ''~MillisDivisor'' ~HaikuVM will calculate and assign automatically (in blue) for some commonly used Clock values [Hz], if  ~HAIKU_MillisDividend and ~HAIKU_MillisDivisor are not configured manually.
| Clock [Hz] | Prescale | ~MillisDividend | ~MillisDivisor | Error in [ms/s] | Overflow32 [min] | Resolution [ms] |
| 8000000 | 1| 4 | 125 |0.00000 | 572.662 | 0.0320000 |
|~| 8| 32 | 125 |0.00000 | 572.662 | 0.256000 |
|~| 64|bgcolor(#66f):  256 |bgcolor(#66f):  125 |0.00000 | 572.662 | 2.04800 |
|~| 256| 1024 | 125 |0.00000 | 572.662 | 8.19200 |
|~| 1024| 2261 | 69 |0.00353827 | 1037.43 | 32.7681 |
||||||||
| 12000000 | 1| 8 | 375 |0.00000 | 190.887 | 0.0213333 |
|~| 8| 64 | 375 |0.00000 | 190.887 | 0.170667 |
|~| 64|bgcolor(#66f): 512 |bgcolor(#66f): 375 |0.00000 | 190.887 | 1.36533 |
|~| 256| 2048 | 375 |0.00000 | 190.887 | 5.46133 |
|~| 1024| 2119 | 97 |0.00125846 | 737.967 | 21.8454 |
||||||||
| 15000000 | 1| 32 | 1875 |0.00000 | 38.1775 | 0.0170667 |
|~| 8| 256 | 1875 |0.00000 | 38.1775 | 0.136533 |
|~| 64|bgcolor(#66f): 2048 |bgcolor(#66f): 1875 |0.00000 | 38.1775 | 1.09227 |
|~| 256| 2853 | 653 |-0.000186938 | 109.621 | 4.36907 |
|~| 1024| 367 | 21 |-0.00435965 | 3408.70 | 17.4762 |
||||||||
| 16000000 | 1| 2 | 125 |0.00000 | 572.662 | 0.0160000 |
|~| 8| 16 | 125 |0.00000 | 572.662 | 0.128000 |
|~| 64|bgcolor(#66f): 128 |bgcolor(#66f): 125 |0.00000 | 572.662 | 1.02400 |
|~| 256| 512 | 125 |0.00000 | 572.662 | 4.09600 |
|~| 1024| 2048 | 125 |0.00000 | 572.662 | 16.3840 |
||||||||
| 20000000 | 1| 8 | 625 |0.00000 | 114.532 | 0.0128000 |
|~| 8| 64 | 625 |0.00000 | 114.532 | 0.102400 |
|~| 64|bgcolor(#66f): 512 |bgcolor(#66f): 625 |0.00000 | 114.532 | 0.819200 |
|~| 256| 2048 | 625 |0.00000 | 114.532 | 3.27680 |
|~| 1024| 367 | 28 |-0.00435965 | 2556.53 | 13.1071 |
*Overview
**[[Tool Chain]]
**[[Architecture]]
**[[Your Project on Disk and at Runtime]]
*Tutorials
**[[Tutorial Blink]]
**[[Tutorial Timing]]
**[[Tutorial Basic Serial IO]]
**[[Tutorial Use Your Own C main Function]]
**[[Tutorial JNI]]<<tiddler [[Tutorial JNI]]>>
**[[Tutorial Interrupts]]
**[[Tutorial All About MicroKernels]]
**[[Tutorial How to configure micro controllers currently not supported in file HaikuVM.properties]]
**[[Tutorial Direct Memory Access|Memory Access]]
**[[Tutorial Memory Layout of HaikuVM Objects|Memory Layout of HaikuVM Objects]]
**[[Different Targets|Runs on AVR ATmega8, AVR ATmega328p (and Windows, UNIX)]]
***[[Arduino]]
***[[ATmega32u4|Leonardo]]
***[[Processing]]
***[[Asuro]]
***[[Windows|Visual Studio]]
***[[LINUX|Ubuntu]]
*~IDEs
**[[Eclipse IDE]]
**[[Arduino IDE]]
If you want to get a first impression about ~HaikuVM but you don't have a microcontroller, here is a way to get it.
If you have Ubuntu (tested with 12.04) you just enter:
<code bash>
cd /home/bob/haikuVM/myCProject  
/home/bob/haikuVM/bin/haiku -v --Config unix /home/bob/haikuVM/examples/src/main/java/arduino/tutorial/HelloWorldJava.java
</code>

<<tiddler chmod>>
If you want to get a first impression about ~HaikuVM but you don't have a microcontroller, here is a way to get it.
If you have MS Windows and Visual Studio (tested with ''Visual Studio 8'' and ''Visual Studio 10 Express'') you have  to open the 'Visual Studio Console'. Here you just enter:
<code bash>
cd C:\haikuVM\myCProject  
C:\haikuVM\bin\haiku -v --Config pc C:\haikuVM\examples\src\main\java\arduino\tutorial\HelloWorldJava.java 
</code>
~HaikuVM is a JAVA VM for micro controllers. It implements all JAVA byte codes (without "invokedynamic").

~HaikuVM has been started for hobbyists who develop applications for ~AVRs (e.g. ARDUINO) to open the world of JAVA.
''Yes, with ~HaikuVM you can program any ARDUINO with JAVA!'' ([[More ...|Processing]])

~HaikuVM is so small that it even runs on an atmega8 (and the ASURO robot).
''And yes, you can program an ASURO robot with JAVA!'' ([[More ...|Asuro]])

It is extremely small - stripped down on an AVR Attiny45 to less then 4K.

But for the beginner I suggest to start with a simple and basic AVR example. ([[More ...|BlinkSimple]])

~HaikuVM works by compiling JAVA byte code to C data structures to be compiled by a C cross compiler for your [[target|Runs on AVR ATmega8, AVR ATmega328p (and Windows, UNIX)]] platform. So, the resulting code is small and fast. ([[More ...|Tool Chain]]) 

[img[images/overview.png]]
For further details take a look [[here|Architecture]].
If you want to zoom into details on AVR Flash and RAM usage take a look at [[this|Your Project on Disk and at Runtime]] page.
!On the Disk
You have to move (cd) into an empty directory which will be used for your project. Any empty directory will do. In addition, ~HaikuVM comes with a template directory called 'myCProject' for your project (and tutorials). At the beginning, and to follow the examples and tutorials more literally, I suggest to pick this one.
*''myCProject/'' (Any other name and (initial) ''empty'' directory, elsewhere on your disk, will do as well.)<br>During a run of haikulink directories will be created here. (Some only once.)
**''~HaikuVM/''<br>The Java VM (see [[Architecture]]).
**''~HaikuVM/utility/''<br>Mainly constants and static variables including method- and exception-tables as derived from your Java program. Other stuff like JNI function templates and debug information:
***Table of constants (''haikuConfig.c'', ''haikuConfig.h'')
***Table of exceptions, table of functions (''haikuConfig.c'', ''haikuConfig.h'')
***Bytecode as prepared and linked for the Haiku VM. "Bytecode" here has to be translated to [["initialized C structs"|Compact HaikuVM Code]].
****C structs initializing a class description and all methods bytecode. (''haikuJava.c'')
****C structs describing the memory layout of objects and methods. (''haikuJava.h'')
***Bytecode map to function labels (''bytecodeDispatcher.h'')
***JNI code (standard) and ~HaikuVM native C functions support (''haikuJNI.c'' and ''nativeCFunctions.cpp'')
**''~HaikuVM/examples/~HaikuVM/''<br>Contains a generic ino-file just in case, to be compatible with the [[Arduino IDE]] as well.
**''target/cross/''<br>Contains all stuff needed for 'make' to cross compile your project.
!On the Microcontroller
!!Flash usage
Here is a diagram to give you an impression about how flash memory is used from ~HaikuVM. This is only a rough estimate about the relation of the sections mentioned below. The concret layout (and order) is not important for ~HaikuVM and is up to the (AVR) linker.
|e| possible unused |
|e|~|
|e|~|
|e|~|
|e|~|
|d|bgcolor(#6f6): Your Java Program |
|d|~|
|d|~|
|d|~|
|c|bgcolor(#6d6): Your ~MicroKernel (possible empty) |
|b|bgcolor(#6b6): Constants and exception tables |
|a|bgcolor(#66b): The Haiku VM |
|a|~|
| flash usage |c

*''Section [a] The Haiku VM''<br>This section corresponds to the project directory '~HaikuVM'. It contains the C program which in fact is the Haiku VM (the equivalent to the Java VM). Although the sourcecode of ~HaikuVM has constant size, the resulting flash memory consumption of section [a-b] depends of your Java program. This is because ~HaikuVM is designed in a way that the AVR linker is able to pick only the source code needed. For example if you don't use double devision the bytecode DDIV (which divides two doubles) is not linked into the flash image. (And therefore saves space.)
*''Section [b] Constants and exception tables''<br>This section corresponds to the project directory '~HaikuVM/utility'.
*''Section [c] Your [[MicroKernel | Tutorial All About MicroKernels]] (possible empty)''<br>This section corresponds to the project directory '~HaikuVM/utility'. This is only a logical section. Physically it's completely merged with section [d].
*''Section [d] Your Java Program''<br>This section corresponds to the project directory '~HaikuVM/utility' and contains the bytecode (as refined by haikulink) of your Java Program.
!!RAM usage
|C|bgcolor(#6f6): Java stack and object heap |
|C|~|
|C|~|
|C|~|
|C|~|
|B|bgcolor(#6d6): Java static variables |
|A|bgcolor(#66b): C stack (ABI) and variables for the Haiku VM |
| RAM usage |c

*''Section [A] C stack (ABI) and variables for Haiku VM''<br>This section defines the space which is needed for the plain Haiku VM to do its job. This stack corresponds in no way with the Java [[stack|Stack Layout]].
*''Section [B] Java static variables''<br>This section defines the space for the Java static variables your Java program (section [c] + [d]) is using.
*''Section [C] Java stack and object heap''<br>This area consists entirely of Java objects and is subject to garbage collection.

''Note''
The size of section [B] + [C] is defined by your ~HaikuVM property ''Memory'' as declared in [[HaikuVM.properties]] of your configuration. The rest of the RAM is used by section [A]. Please select ~HaikuVM property ''Memory'' in a way that section [A] has room to live. In my experience 300 byte is enough (for an Atmega328p).

For being portable, I decided to code the VM in pure C (no assembler and no C++).
<code java>
package avr.tutorial;
import static haiku.avr.AVRConstants.*;
public class BlinkSimple {
    private static final int LED = 1 << 5;

    private static void delay(int nounit) {
        while(nounit>0) {
            nounit--;
        }
    }

    public static void main(String[] args) {
        // Data direction of I/O-Port.
        DDRB = LED;
        while (true) {
            PORTB |= LED; // on
            delay(3000);
            PORTB &= ~LED; // off
            delay(30000);
        }
    }
}
</code>
''Caution:'' You may have to edit and change it to your needs because this example assumes that the LED is on PORTB.
On Unix, if the first time, don't forget to change shell scripts to have execute permission like this:
<code bash>
chmod +x haikuVM/bin/*
</code>
On some compilers (e.g. winavr / gcc-avr) the JAVA type ''double'' is mapped to C type ''float''.
~HaikuVM supports double and float types. But details depend on the underlying hardware and C compiler infrastructure. Because ~HaikuVM works by translating JAVA bytecode to C code. So, for instance, the WINAVR C Compiler supports double and float types but the double type has only 32 Bits and is, behind the scenes, effectively a C float type.
!compile, link, upload and run a program
Usage: 
haiku [-v|"""--"""verbose] ["""--"""Config <config>] ["""--"""Config:<propertyname> <value>]* ["""--"""classpath <javaclasspath>] <main-class>

Options are:
:-v #verbose
:"""--"""Config:<propertyname> <value> #set a propertyname value ([[More...|Command Line Options]])
:"""--"""Config <config> #sets the main target configuration ([[More...|Command Line Options]])
:"""--"""classpath <javaclasspath> #extends the default classpath given by HaikuVM
<<<
The default classpath given by HaikuVM is:
:~HAIKU_HOME\haikuRT\src\main\java;~HAIKU_HOME\bootstrap\src\main\java;~HAIKU_HOME\examples\src\main\java;~HAIKU_HOME\haikuBench\src\main\java;~HAIKU_HOME\gallerie\src\main\java;~HAIKU_HOME\incubator\src\main\java
(For experts: This classpath as defined in './bin/makeclasses.mk')
<<<

Example: Use default traget (property 'Config') as defined in [[HaikuVM.properties]]:
<code bash>
haiku -v HelloWorld 
haiku -v HelloWorld.java
</code>

Example: Overwriting default properties of [[HaikuVM.properties]]:
<code bash>
haiku --Config duemilanove HelloWorld.java
haiku --Config duemilanove --Mode 16/32 HelloWorld.java
haiku --Config duemilanove --Config:Mode 32/64 HelloWorld.java
haiku --Config duemilanove --Config:Mode=32/64 HelloWorld.java
haiku --Config duemilanove --classpath myWorkspace1 HelloWorld.java
haiku --Config duemilanove --classpath \"myWorkspace1;myWorkspace2\" HelloWorld.java
</code>
The haiku command links and uploads a JAVA program. It is the equivalent of haikulink followed by haikuupload.

Any of the options for haikulink and haikuupload can be specified.

The default binary name is <main-class>.hex, e.g. Tune.hex.

See also [[Commands]].
!compile a JAVA program
Compiles one or more java files.

Usage: haikuc <java-files>
Example: 
<code bash>
haikuc HelloWorld.java
</code>
Internally haikuc calls javac with parameters:
-bootclasspath <path to haikuRT and classes.jar> <java-files>

-bootclasspath is set because ~HaikuVM does not use the standard java.lang classes but has its own versions in haikuRT and classes.jar.

See also [[Commands]].
!haikufy the program and cross-compile the resulting C Program
Calls the ~HaikuVM linker.

Usage:
haikulink [-v|"""--"""verbose] [-g|"""--"""debug] [-gr|"""--"""remotedebug] [-a|"""--"""all] 
  [-dm|"""--"""disablememcompaction] [-ea|"""--"""enableassertions] [-ec|"""--"""enablechecks] 
  ["""--"""Config <config>] ["""--"""Config:<propertyname> <value>]* [-od|"""--"""outputdebug <debug-file> ]
  -o <binary> main-class

Example:
<code bash>
haikulink -v -o HelloWorld.hex HelloWorld
</code>
Links the specified main class with any classes that it refers in the current directory and with the standard ~HaikuVM classes from haikuRT and classes.jar (from leJOS) to produce a C program. Next this C program will be cross-compiled into the binary HEX program that can be uploaded and run.

The -v or """--"""verbose flag causes a list of class names and method signatures included in the binary to be sent to the standard output. This output is extremely useful for debugging.

The -g or """--"""debug flag is not yet supported by ~HaikuVM.

The -gr or """--"""remotedebug flag is not yet supported by ~HaikuVM.

The -od or """--"""outputdebug flag is not yet supported by ~HaikuVM.

The -ec or """--"""enablechecks flag is used to enable additional run time checks. These checks are relatively expensive (and rarely generate errors) and so are off by default. The checks that this setting enables is defined in [[HaikuVM.properties]] by the property ~PanicExceptions and are usually:
<<tiddler PanicExceptions>>The -ea or """--"""enableassertions flag is used to enable the checking of assert statements with the program.

The -dm or """--"""disablememcompactions flag is always set for ~HaikuVM. So memory compaction is always disabled and can not be enabled for ~HaikuVM. Normally a marture garbage collector will attempt to move large objects in memory to maximize the amount of contiguous free space, this is not implemented in the simple garbage collector of ~HaikuVM.

The linker removes methods that are not used. Specify -a or """--"""all to include all methods whether they are used or not. This should never be necessary.

The -o <binary> option is used to define the name of the output file.

The """--"""Config <config> option is an addition of ~HaikuVM to specify (overwrite) the default configuration of the [[HaikuVM.properties]].

The """--"""Config:<propertyname> <value> option is an addition of ~HaikuVM to set (overwrite) any value of the [[HaikuVM.properties]].

Use the -h or """--"""help flag to print out the options.

See also [[Commands]].
!upload a program
Usage: 
haikuupload ["""--"""Config:<propertyname> <value>]* <binary>

Example:
<code bash>
haikuupload HelloWorld.hex
</code>
Uploads the binary (.hex) file. 

None of the (leJOS) options are supported yet (but may be in future). Instead the upload is configurated in [[HaikuVM.properties]] and may be changed in the command line by overwriting property values with the option """--"""Config:<propertyname> <value>.

See also [[Commands]].
The JAVA type ''double'' type is a half precision float.
*The minimum strictly positive (subnormal) value is 2^-24 	~ 5.96 * 10^-8.
*The minimum positive normal value is 2^-14 				~ 6.10 * 10^-5.
*The maximum representable value is (2-2^-10) * 2^15 		= 65504.
The JAVA ''double'' is only a storage type. The ~HaikuVM unpacks it into a C float for calculations.
~HaikuVM supports half precision float (see [[wikipedia|http://en.wikipedia.org/wiki/Half-precision_floating-point_format]]) in case you select a 16Bit data type for JAVA type ''float''. This is only a storage type. The ~HaikuVM unpacks it into a C float for calculations.
*The minimum strictly positive (subnormal) value is 2^-24 	~ 5.96 * 10^-8.
*The minimum positive normal value is 2^-14 				~ 6.10 * 10^-5.
*The maximum representable value is (2-2^-10) * 2^15 		= 65504.
~HaikuVM, at its core, is just another JAVA VM for micros. I decided to go without building an own JAVA runtime. Instead ~HaikuVM is tailor made to use the JAVA runtime coming with [[leJOS|http://en.wikipedia.org/wiki/LeJOS]].
''NOT IMPLEMENTED'' But this is the idea:

Besides //bootclasspath// and //classpath//, well known from javac, [[haikulink]] supports a third form called //redirectmethodpath//.
For example currentTimeMillis() is defined as ''native'' in java.lang.System:
<code java>
package java.lang;
...
public class System {
...
    /**
     * Returns the current time in milliseconds.
     * This is the number of milliseconds since the AVR has been on.
     */
    public static native long currentTimeMillis();
...
}
</code>

If you don't want to implement it in plain C and you know the memory address where the millis are stored, lets say for example the address is 123, you might write a second class System including a implementation of currentTimeMillis() like this:
<code java>
package java.lang;
public class System {
    public static long currentTimeMillis() {
        return haiku.vm.MemoryAccess.getMemoryLong(123);
    }
}
</code>

Lets say the class file is 'C:\haikuVM\myCProject\redirects\java\lang\System.class' then, to use it, you have to call [[haikulink]] like this:
<code bash>
C:\haikuVM\bin\haikulink -v -redirectmethodpath C:\haikuVM\myCProject\redirects --Config arduino -o Blink.hex C:\haikuVM\examples\src\main\java\arduino\tutorial\Blink
</code>

This will ''not overwrite'' the definition of ''class'' System given in classes.jar from leJOS, but will ''overwrite only'' the implementation of the ''method'' currentTimeMillis() given in classes.jar,  hence the name of the option //redirect''method''path//.

This technique of overwriting method implementations is ''not restricted to native methods'' but will work for regular methods as well.