<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
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
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]];}

	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]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.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]];}

#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 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}

.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:0em 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 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

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

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

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 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 0em;}
.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 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 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 0em 14em;}

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

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

.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:0em 0.25em; padding:0em 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:0px 3px 0px 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 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

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

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.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 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 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 1em;}
/* Fixes a feature in Firefox where print preview displays the noscript content */
noscript {display:none;}
<div class='header' 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 class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
<div class='toolbar' 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>
<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>>
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]]
I'm not the important one, so we'll make it quick.

//Name:// Jose
//Title:// Teaching Assistant (TA)
*Worked with ~MiniDRAGON+ since Spring '06
*Worked with 7 different microcontrollers
*Know assembly in 2 architectures
*Crazy enough to successfully get a BS in Electrical Engineering
!End of Days
Friday, May 8, 2009 is the ''last day to turn in labs.'' Any labs turned in ''after'' this date ''will //not// be graded.''

After Friday, May 8, 2009, the ''website'' will be ''taken down'' along with ''all content.'' It had a good, year-long run, and I like to think that most students appreciated having it. May it go with Mr. Engler and be at peace.
Background: #8a8a8a
Foreground: #393959
PrimaryPale: #CCCCCC
PrimaryLight: #000000
PrimaryMid: #120a8f
PrimaryDark: #666666
SecondaryPale: #eee9e9
SecondaryLight: #f0f8ff
SecondaryMid: #db4
SecondaryDark: #660000
TertiaryPale: #999999
TertiaryLight: #1f1f1f
TertiaryMid: #999
TertiaryDark: #333
Error: #f88
*''Follow the [[template|http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_report_template.doc]]!''
**''Remove Dr. Leung's formatting instructions!''
**The new template (as of mid-Fall 08) is ''nothing'' like the old template (as of Spring 08). There are only ''six'' headings: //objective, procedure, data and analysis, conclusion, references, and appendix//. Also, ''each heading'' should start on ''it's own'' page ''except'' for objective and procedure, since objective is usually small.
*Remember ''all'' of the report must be formatted with ''full justification''
*''ONLY'' the ''appendix and "proof"'' can be ''less than 12 point'' font
*The name of the course is "Microprocessor Systems Lab."
*This semester is ''not'' Spring 08.
*Flowcharts go in the ''procedure'' and must have text above ''and'' below them.
**Flowcharts ''are'' figures, therefore, they ''must have a figure number''.
**When you introduce a part of the lab in the procedure, include the flowchart ''within'' your discussion. i.e. ''DO NOT'' put all of your flowcharts back-to-back in the middle of your procedure.
*Do ''not'' include //BR, NOBR, ~PC_____, LOAD//, and etc in your data and analysis.
*At the ''end'' of the data, there should be a paragraph that discusses the data, i.e. whether or not the data makes sense ''not'' where it came from.
**Even if you do not need data, you still ''need a discussion'' about how whatever you did to prove it worked, i.e. how well it worked.
*Conclusions discuss how the objective was met by doing the lab
*Your book ''is'' considered a reference, therefore, you ''do'' have a reference page
*''Every'' lab has an appendix
*~A-S-S-E-E-M-B-L-Y is ''not'' how you spell "ASSEMBLY"
*List files ''do not'' go in your reports
*''IF'' the Register Maps are needed for the report, ''DO NOT'' include the "proof method" ''anywhere'' in the report
**"Proof Method" is the "before and after effect." i.e. memory contents ''before and after'' instruction/section of code
*The ''only attachment'' in your e-mails should be your ''reports''!
**Flowcharts, tables, and programs belong ''in your reports''!
*In your appendices, each program has it's own heading ''not'' figure number. i.e. //Appendix A, Appendix B// ''not'' //Fig. 3: Program 1, Fig. 4: Program 2//
|>|>|SiteTitle - SiteSubtitle|

''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint

<html>To contact Dr. Leung, you can go to the <a href="http://www.engineer.tamuk.edu/departments/eecs/eeen/information/faculty.htm" onClick="javascript: pageTracker._trackPageview('/links/faculty'); ">faculty page</a> on the engineering site.

To contact me and turn in your assignments, you can [[e-mail me]]. 
''Note:'' that the e-mail address ''//changes depending on the semester.//''
Subject line ''must be formatted'' as follows: //~EEEN3449, Name, Lab#_//.

In case you don't know who I am, go [[here|About]].</html>
<<tabs txtCLab
Lab10 "Lab 10" Lab10
Sometimes it's necessary to include custom HTML markup in the {{{<head>}}} of a TiddlyWiki file - typically for compatibility with ad serving software, external libraries, or for custom meta tags. The CustomMarkup operation defines four shadow tiddlers whose contents are spliced into the saved HTML file. (If you do a view/source you'll see the markers referred to below).
|!Title |!Location |!Marker |
|MarkupPreHead |Start of the {{{<head>}}} section |{{{<!--PRE-HEAD-START-->}}} |
|MarkupPostHead |End of the {{{<head>}}} section |{{{<!--POST-HEAD-START-->}}} |
|MarkupPreBody |Start of the {{{<body>}}} section |{{{<!--PRE-BODY-START-->}}} |
|MarkupPostBody |End of the {{{<body>}}} section |{{{<!--POST-BODY-START-->}}} |
MarkupPreHead is the only one with shadow content: a link to the default location of the RSS feed.
<<tabs txtDueDates
Lab10 "Lab 10" Lab10Due
Lab9 "Lab 9" Lab9Due
Lab8 "Lab 8" Lab8Due
Lab7 "Lab 7" Lab7Due
Lab6 "Lab 6" Lab6Due
Lab5 "Lab 5" Lab5Due
Lab4 "Lab 4" Lab4Due
Lab3 "Lab 3" Lab3Due
Lab2 "Lab 2" Lab2Due
Lab1 "Lab 1" Lab1Due

<html><iframe src="http://www.engineer.tamuk.edu/cleung/EEEN3449/EEEN%203449.htm" width="700" height="800"></iframe></html> 
[[EVBplus|http://www.evbplus.com/index.html]] is where we get the ~MiniDRAGON+, but [[here|http://www.evbplus.com/wytec_shopping/students.htm]] is where you actually order it. Make sure you get ~MiniDRP2/FH because it has ~D-Bug12 pre-installed.
For those of you who have laptops or computers ''without'' a COM port, then you'll ''need'' a ~RS232-to-USB Adaptor. Dr. Leung once found a seller on [[ebay|http://www.ebay.com]] who sold it for $4.71 and free shipping. However, I prefer [[the one from EVBplus|http://www.evbplus.com/wytec_shopping/accessories.htm]] because, as the site says, it's been ''tested and proven to work.'' Also, you'll save on shipping by getting both from ~EVBplus.
!Update on Eric Engler
Sadly, Mr. Engler [[passed away|http://www.geocities.com/siliconvalley/network/2114/]] on May 08, 2008. His son, Jason, has decided ''not'' to keep his main site, www.ericengler.com, alive. Therefore, I will be hosting a [[local copy|Welcome]] of ~AsmIDE 3.40 for us to use.

Eric Engler was a Canadian Delphi programmer who made some programs for Windows to interface with Freescale/Motorola 's 68HC11 and 68HC12 boards. Namely, he is responsible for the creation and upkeep of ~AsmIDE, which we use in our lab.

After having used his program for 3 years, I have often ripped on Mr. Engler for the bugs he has yet to fix. Now, I shall rip on Mr. Engler out of respect in the hope that his unfixed bugs will make us always remember him.

Sometimes, programmers ''can'' be immortal.
<html>''What type of website is this?''
This site is classified as a <a href="http://www.tiddlywiki.com/" onClick="javascript: pageTracker._trackPageview('/links/tiddlywiki'); ">TiddlyWiki</a>. If you check out <a href="http://www.tiddlytools.com/" onClick="javascript: pageTracker._trackPageview('/links/tiddlytools'); ">TiddlyTools</a>, then you can be well on the way to customizing your own.

''What is the report supposed to look like?''
You ''must follow'' <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_report_template.doc" onClick="javascript: pageTracker._trackPageview('/links/Report_template'); ">Dr. Leung's Template</a> to the "t." ''Note:'' the template tends to change often, so //check it regularly//. Also, //every lab must have a flowchart//. You can also look [[here|CommonMistakes]] for common mistakes so that you do not get huge points off for things I told you a million times.

''What format can I submit my report?''
Due to possible future problems with the reports being read, Microsoft Word's .doc format is the ''only'' acceptable format. Please ''do not'' save in Word's .docx format because it cannot be read on-campus.

''How do I submit the report?''
You submit them ''electronically'' to my e-mail. Subject line ''must be formatted'' as follows: //~EEEN3449, Name, Lab#_//. 
See [[Contact]] for more info.

''What if I don't turn in the report on time?''
You lose 10 points ''per week'' (use to be per day, so be grateful) out of 100 until you eventually automatically get a zero.

''How do I find out what grade I made?''
During ''the week of'' midterms and at the final lab, I will show you your mid-term and final lab grades, respectively.

If the above is unsatisfactory, you can e-mail me a request for grades of ''specific labs.'' I can then e-mail you the grades for the requested labs as well as graded copies of the labs. 

I prefer not to do this because you ''cannot'' correct your copies and ''re-submit them.''

''How much does this lab matter?''
As of Fall 2008, your lab grade is 25% of your class grade.

''What did I do wrong on my report?''
I usually take the time to show you what a perfect report looks like and you can take notes on what it takes to make the cut.</html>
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|Overrides|'HTML' formatter|
|Description|embed wiki syntax formatting inside of HTML content|
The ~HTMLFormatting plugin allows you to ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
>see [[HTMLFormattingPluginInfo]]
2008.04.26 [*.*.*] plugin size reduction: more documentation moved to HTMLFormattingInfo
2008.01.08 [*.*.*] plugin size reduction: documentation moved to HTMLFormattingInfo
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.06.14 [2.1.5] in formatter, removed call to e.normalize().  Creates an INFINITE RECURSION error in Safari!!!!
| see [[HTMLFormattingPluginInfo]] for additional revision details |
2005.06.26 [1.0.0] Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
version.extensions.HTMLFormatting = {major: 2, minor: 1, revision: 5, date: new Date(2007,6,14)};

// find the formatter for HTML and replace the handler
function initHTMLFormatter()
	for (var i=0; i<config.formatters.length && config.formatters[i].name!="html"; i++);
	if (i<config.formatters.length)	config.formatters[i].handler=function(w) {
		if (!this.lookaheadRegExp)  // fixup for TW2.0.x
			this.lookaheadRegExp = new RegExp(this.lookahead,"mg");
		this.lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var html=lookaheadMatch[1];
			// optionally suppress wiki-style literal handling of newlines
			if (html.indexOf('<hide linebreaks>')!=-1) html=html.replace(/\n/g,' ');
			// remove carriage returns (\r) added by IE textarea
			// encode newlines (\n) and macro brackets (<< and >>)
			// create span to hold HTML
			var e = createTiddlyElement(w.output,"span");
			// let browser parse HTML
			// walk node tree and call wikify() on each text node
			// continue wiki parsing
			w.nextMatch = this.lookaheadRegExp.lastIndex;

// wikify text nodes remaining after HTML content is processed (pre-order recursion)
function wikifyTextNodes(theNode)
	// textarea node doesn't get wikified, just decoded... 
	if (theNode.nodeName.toLowerCase()=='textarea')
	else for (var i=0;i<theNode.childNodes.length;i++) {
		var theChild=theNode.childNodes.item(i);
		if (theChild.nodeName.toLowerCase()=='option') continue;
		if (theChild.nodeName.toLowerCase()=='select') continue;
		if (theChild.nodeName=='#text') {
			var txt=theChild.nodeValue;
			// decode macro brackets and newlines
			// replace text node with wikified() span
			var newNode=createTiddlyElement(null,"span");
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2008-03-13 02:03:12 +1000 (Thu, 13 Mar 2008) $|
|Author:|Simon Baird <simon.baird@gmail.com>|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}

window.hideWhenLastTest = false;

window.removeElementWhen = function(test,place) {
	window.hideWhenLastTest = test;
	if (test) {


	hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( eval(paramString), place);

	showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !eval(paramString), place);

	hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);

	showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);

	hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAny(params), place);

	showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAny(params), place);

	hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);

	showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);

	hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);

	showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);

	hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title == params[0], place);

	showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title != params[0], place);

	'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !window.hideWhenLastTest, place);



!Lab 1: Addressing Mode
The ''week of'' Jan. 30, 2009, lab is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_1.doc" onClick="javascript: pageTracker._trackPageview('/links/lab1'); ">Lab1</a>. Lab 1 will be using the <a href="http://mannindustries.net/eeen3449/files/reg_map.doc" onClick="javascript: pageTracker._trackPageview('/downloads/reg_map'); ">Lab 1 Register Map</a> , provided, for data. There will not be a flowchart for Part A, there will be three flowcharts for Part B, and there will be one flowchart for Part C. Remember, each modified code ''and'' the original must be in the Appendix.
!!Part A
Part A is for practice with the ~D-Bug12 commands, terminal window, and ~AsmIDE in general. Therefore, you ''do not need to include Part A in your report''. Dr. Leung recommends using br and g, but using gt to the same place you would br eliminates about three steps.
!!Part B
For Part B, you verify the contents of ''all'' the registers ''before and after'' each indexed addressing mode. Then, you change the offset of each indexed addressing mode ''twice'' and re-verify the contents of ''all'' the registers ''for each'' addressing mode each time.
!!Part C
For Part C, you change each indexed addressing mode to Post/pre auto-increment/decrement mode, and verify the contents of all the registers before and after each indexed addressing mode ''except'' for indirect indexed addressing mode, because you cannot use post/pre auto-increment/decrement mode with indirect indexed addressing.</html>
!Lab 10: Interfacing ~LM34DZ with 9S12
<html>The ''week of'' Apr. 24, 2008 is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_10.doc" onClick="javascript: pageTracker._trackPageview('/links/lab10'); ">Lab10</a>. ''Remember:'' you need a flowchart for your program, and you need to use the "proof method," ''not'' the Register Maps. Finally, you ''must'' show me that your codes work ''before'' you submit the report. Otherwise, the report ''will not'' be graded.
!Sensor Checkout
Temperature sensors will be //checked out// during the lab. You ''must'' return them to get a grade for the lab. Also, failure to return them can result in an ''incomplete for the class!''
*''May 4, 2008 is the //last day// to return the sensor to me''. ''After'' this date, you must ''turn it in to Dr. Leung.''
*''Make sure you check-in when you return the sensor''.
!Lab Instructions
Interface with the Temperature Sensor, ~LM34DZ, and ''activate'' a buzzer when it reads a temperature ''above'' 85 &deg;F and ''disable'' the buzzer once it goes ''below'' 85 &deg;F.

"Proof" will be showing the contents of memory containing the conversion (either ~ATDDR0, or some location you specify) ''both'' when the buzzer is ''active'' and when it is ''disabled.''</html>
!Lab 10: Interfacing ~LM34DZ with 9S12
*Monday Lab
**May 4, 2008
*Friday Lab
**May 1, 2008
!Lab 10: Interfacing ~LM34DZ with 9S12
<ul><li><a href="./files/Datasheets/LM34DZ.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/map'); ">~LM34DZ Datasheet</a></li><li>Formula</li><ul><li>pg. 556</li></ul><li>Codes</li><ul><li>pgs. 572 & 573 (Example 12.6 & 12.7)</li></ul></ul></html>
!Lab 1: Addressing Mode
*Friday Lab
**Due Feb. 6, 2009
*Monday Lab
**Due Feb. 9, 2009
!Lab 1: Addressing Mode
<ul><li>Notes on <a href="./files/address_modes.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/address_modes'); ">Indexed Addressing Modes</a></li><li>Addressing Modes</li><ul><li>Pg 12 in book</li></ul></ul></html>
!Lab 2: Compute the array sum
The ''week of'' Feb. 06, 2009 lab is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_2.pdf" onClick="javascript: pageTracker._trackPageview('/links/lab2'); ">Lab2</a>. Use the code on page 57 and ''not'' the code that was provided in the lab. In this lab, you are ''first'' changing the array size and elements.  Parts a and b have their own flowchart, part c has two flowcharts, part d has no flowchart, and part e has  three flowcharts. Remember that each version of the code (including the original) belongs in the appendix.
!!Part a
For part a, you record the value for sum //as you add each element in the array// into the <a href="http://mannindustries.net/eeen3449/files/reg_map.doc" onClick="javascript: pageTracker._trackPageview('/downloads/reg_map'); ">Lab 1 Register Map</a>.
!!Part b
For part b, you repeat ''part a'', except that the array is added ''backwards.'' ''Note:'' that you ''cannot'' change the array, but you ''can'' change the rest of the code.
!!Part c
For part c, you repeat ''parts a & b'', except that sum is //initialized to 20 instead of 0// ''before'' you start summing the array.
!!Part d
For part d, you move the array to address $1500 through $1509. This is proved in your code that should be in your Appendix.
!!Part e
For part e, you repeat ''parts b & c'', but with the array at the beginning of the program, as in ''part d''.</html>
!Lab 2: Compute the array sum
*Friday Lab
**Due Feb. 13
*Monday Lab
**Due Feb. 16
!Lab 2: Compute the array sum
<ul><li>Notes on <a href="./files/simulate_loop.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/simulate_loop'); ">simulating the loop</a></li><li>Code</li><ul><li>Pg 56 in book</li></ul></ul></html>
!Lab 3: CCR Flags
The ''week of'' Feb. 13, 2009 lab is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_3.pdf" onClick="javascript: pageTracker._trackPageview('/links/lab3'); ">Lab3</a>.  The <a href="http://mannindustries.net/eeen3449/files/reg_map.doc" onClick="javascript: pageTracker._trackPageview('/downloads/reg_map'); ">Lab 1 Register Map</a> is where you record the data for this lab. You ''will need a flowchart'' for A and B, and the appendix will contain the instructions that were given to you in the lab.

''Note:'' You are ''not simulating'' these instructions on your ~MiniDRAGON+ because it is impossible to control the CCR completely. Therefore, after each register map,  you will have to //describe what is happening in your own words.//
!!Part A
Part A is done ''in sequence,'' that is, the results from a) go into the initialization of b) and so on. Each lower case letter shall have a single, full-page register map: first table for the initialization and the second table for the result after executing the instruction.
!!Part B
Part B is done ''independently'' that is, each lower case letter is initialized with the same information from the paragraph. Again, each lower case letter needs a single, full-page register map.</html>
!Lab 3: CCR Flags
*Friday Lab
**Due Feb. 20
*Monday Lab
**Due Feb. 23
!Lab 3: CCR Flags
<ul><li>Notes on <a href="./files/CCR.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/CCR'); ">CCR</a></li><li>CCR</li><ul><li>Pg 9 in book for intro</li><li>Pg 53 in book for more info</li></ul><li>Pg 62 in book for LSL/R and ROLR/L</li></ul></html>

<html>!Lab 4: Bit Testing
The ''week of'' Feb. 20, 2009 lab is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_4.pdf" onClick="javascript: pageTracker._trackPageview('/links/lab4'); ">Lab4</a>. ''Remember:'' you need a flowchart for ''each part'' and you need to use the "proof method," and ''not'' the Register Maps. Finally, you ''must'' show me that your codes work.
!!Part a
Code is on pg. 66. Address of data is $1500-$1501 and sum of 1's will be stored in $1505. Also, go ahead and remove the //forever   bra   forever// and replace it with //swi// because it will make the ~MiniDRAGON+ run in an eternal loop.
!!Part b
Use the array on pg. 58, but more useful code will be on pg. 61. Even numbers start at $1400 and odd numbers start at $1420.
!!Part c
Use array in Lab 4, but code on pg. 61. Even positive numbers start at $1400, odd positive numbers start at $1410, even negative numbers start at $1420, and odd negative numbers start at $1430.</html>
!Lab 4: Bit Testing
*Friday Lab
**Due Mar. 6 (because of the President's Inauguration)
*Monday Lab
**Due Mar. 2
!Lab 4: Bit Testing
<ul><li>Notes on <a href="./files/oddVSeven.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/oddVSeven'); ">Odd, even, pos, and neg</a></li><li>Notes on <a href="./files/stack.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/stack'); ">Stack Pointer</a></li><li>Stack opcodes</li><ul><li>pg. 126</li></ul><li>BRCLR and BRSET</li><ul><li>pg. 60 in book</li></ul><li>Part a</li><ul><li>Code pg. 66 in book</li></ul><li>Part b</li><ul><li>Array pg. 58 in book</li><li>Code pg.  61 in book</li></ul><li>Part c</li><ul><li>Code pg. 61 in book</html>
<html>!Lab 5: Bit Manipulation
The ''week of'' Mar. 2, 2009 is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_5.pdf" onClick="javascript: pageTracker._trackPageview('/links/lab5'); ">Lab5</a>. ''Remember:'' you need a flowchart for ''each part'' and you need to use the "proof method," ''not'' the Register Maps. Finally, you ''must'' show me that your codes work ''before'' you submit them.

For ''each'' part ''independently'' you are to ''//assign// a value to a memory location'' (yes, it's pointless step, but you have to do it anyway). Then ''put the value into an accumulator //from// the memory location'' and perform the bit manipulation on it (because you cannot manipulate bits directly in memory). Finally, ''put the result back into the memory location.'' The value you are to perform the bit manipulation on can be any of your choosing.
!Part a
''Toggle'' the ''odd bits'' and ''clear'' the ''even bits.''
!Part b
''Toggle'' the ''even bits'' and ''clear'' the ''odd bits.''
!Part c
''Toggle'' the ''most significant nibble (~MSn) //only//.''
!Part d
''Toggle'' the ''least significant nibble (~LSn) //only//.''
!Part e
''Swap'' the ~MSn and ~LSn of ''accumulator B.''
!Part f
''Swap'' the ~MSn and ~LSn of ''accumulator A.''</html>
!Lab 5: Bit Manipulation
*Monday Lab
**Due Mar. 9
*Friday Lab
**Due Mar. 13
!Lab 5: Bit Manipulation
<ul><li>Notes on <a href="./files/logic.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/logic'); ">boolean logic in assembly</a></li><li>Boolean Logic Instructions</li><ul><li>pg. 68 in book</li></ul><li>Shift and rotate instructions</li><ul><li>pg. 63 in book</li></ul></ul></html>
<html>!Lab 6: LED Traffic Light
The ''week of'' Mar. 9, 2009 is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_6.pdf" onClick="javascript: pageTracker._trackPageview('/links/lab6'); ">Lab6</a>. ''Remember:'' you need a flowchart for ''each part'' and you need to use the "proof method," ''not'' the Register Maps. Finally, you ''must'' show me that your codes work ''before'' you submit the report.

For ''each'' part, you are simulating the sequence of a traffic light: Green, yellow, then red.

!Part a
Light the ''green'' LED for ''3 seconds,'' the ''yellow'' LED for ''1 second'', and then the ''red'' LED for ''3 seconds.'' The "proof" will be showing the contents of ''//port B// before and after'' you execute the code.
!Part b
Repeat part a with the ''prescale factor set to 64.'' The "proof" will be the code in your Appendix (so don't worry about it).
!Part c
Repeat part a with the ''prescale factor set to 32.'' The "proof" will be the code in your Appendix (so don't worry about it).</html>
!Lab 6: LED Traffic Light
*Monday Lab
**Due Mar. 23
*Friday Lab
**Due Mar. 27
!Lab 6: LED Traffic Light
<ul><li>Notes on <a href="./files/input-output.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/IO'); ">I/O</a></li><li>Code pg. 280 in book</li><ul><li>''Note:'' You will ''not'' be using ''Port J'' in your programs</li></ul><li>Example/formula to calculate delay</li><ul><li>pg. 345 in book</li></ul</ul></html>
<html>!Lab 7: Siren Generation
The ''week of'' Mar. 23, 2009 is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_7.pdf" onClick="javascript: pageTracker._trackPageview('/links/lab7'); ">Lab7</a>. ''Remember:'' you need a flowchart for ''each part'' and you need to use the "proof method," ''not'' the Register Maps. Finally, you ''must'' show me that your codes work ''before'' you submit the report.

For ''both parts'', you must:
*Set the prescale factor to ''8''
*Use ''200 Hz'' as the ''low'' frequency
*Use ''1000 Hz'' as the ''high'' frequency
*Use the onboard buzzer
*Show "proof" by simulating the //forever// loop ''once'' and showing the contents of ''delay.''
*Insert a //swi// ''after the forever branch'' so that you can debug the program.

!Part A
Play the ''low frequency'' for ''0.5 s'' then ''nothing'' for ''0.5 s'' then the ''high frequency'' for ''0.5 s'' then ''nothing'' for ''0.5 s'' then loop forever.

!Part B
Play the ''low frequency'' for ''0.5 s'' then ''nothing'' for ''0.5 s'' then the ''high frequency'' for ''1 s'' then ''nothing'' for ''0.5 s'' then loop forever.</html>
!Lab 7: Siren Generation
*Monday Lab
**Due Mar. 30
*Friday Lab
**Due Apr. 3
!Lab 7: Siren Generation
<ul><li>Notes on <a href="./files/toneGen.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/tonGen'); ">Generating Tones</a></li><li>Where is the <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/MiniDR1.pdf" onClick="javascript: pageTracker._trackPageview('/links/MiniDR1'); ">Internal Speaker</a>?</li><li>Code</li><ul><li>p. 349</li><li>''Note:'' code is for ''Dragon12'' board, so some lines might be different.</li><li>''Note:'' include file was used, so registers must be self-defined (using EQU).</li></ul><li>Interrupts</li><ul><li>p. 222</li></ul><li>Interrupt Vectors</li><ul><li>p. 233</li></ul></ul></html>
<html>!Lab 8: PIN Verification
The ''weeks of'' Mar. 30, 2008 ''and'' Apr. 3, 2008 is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_8.pdf" onClick="javascript: pageTracker._trackPageview('/links/lab8'); ">Lab8</a>. ''Remember:'' you need a flowchart for ''parts a, c, and d'' and you need to use the "proof method," ''not'' the Register Maps. Finally, you ''must'' show me that your codes work ''before'' you submit the report.

!Part b & d
This is all done for you, so don't worry about it. No "proof," either.

!Part a
Assign ''four'' numbers ''in ASCII'' as a PIN and ''put them into the stack.'' ''Note:'' PIN ''must'' be in the ''stack'' and cannot be saved anywhere else. 

"Proof" is showing the contents of the ''memory address'' of the stack ''before and after'' you push the PIN.

!Part c
Compare each input with the corresponding PIN number and ''increment a counter'' every time the input ''matches'' the PIN. If counter=4, then input ''is'' the PIN, so sound a ''buzzer.'' Otherwise, input is ''not'' the PIN. 

"Proof" is simulating ''one comparison'' and showing the contents of the ''counter'' before ''and'' after the comparison.

!Part e
Set prescale factor to ''8'' in the ''10 ms delay.'' ''Note:'' The delay must ''still be 10 ms.'' 

No "proof" is needed for this part.</html>
!Lab 8: PIN Verification
* Due Apr. 17 for ''both'' labs

Yes, it's a ''two week'' lab (be afraid, be very afraid)
! Lab 8: PIN Verification
<ul><li><a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Keypad%20Interface.doc" onClick="javascript: pageTracker._trackPageview('/links/keypad_int'); ">Code</a> (Old/matrix Keypad code)</li><ul><li>pg. 306 in book</li></ul><li><a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Single%20Pole_%26_Common%20Bus.pdf" onClick="javascript: pageTracker._trackPageview('/links/cb_code'); ">Single pole / common bus code</a></li><li><a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Single_Pole_Common_Bus%20keypad.pdf" onClick="javascript: pageTracker._trackPageview('/links/cb_dat'); ">Single pole / common bus datasheet</a></li><li><a href="./files/stack.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/stack'); ">Stack Pointer Notes</a></li><ul><li>pg. 126 in book</li></ul><li>~Pull-Up Control Register (PUCR)</li><ul><li>pgs. 264 & 266</li></ul></ul></html>
<html>!Lab 9
The ''week of'' Nov. 10, 2008 is <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_9.pdf" onClick="javascript: pageTracker._trackPageview('/links/lab9'); ">Lab9</a>. ''Remember:'' you need a flowchart for ''parts b and c'', and you need to use the "proof method," ''not'' the Register Maps. Finally, you ''must'' show me that your codes work ''before'' you submit the report. Otherwise, the report ''will not'' be graded. See [[References]] for more info.

For ''all parts'' you must:
*Use two loops
**An outer loop to keep track of the number being processed.
**An inner loop to keep track of the bit in each number being processed.
//Note:// You ''can'' save the ''count'' of ones ''for each number'' to memory, but you ''must'' save the ''total count'' of ones to memory.

!Part a
Implement the two loops as described above.

No "proof" is needed for this part.
!Part b
Check if the bit is a 1 by shifting the bits to the ''right'' and testing to see if bit C in the CCR is a ''1''.

"Proof" is simulating ''both'' the inner and outer loops ''once'' and showing the contents of the ''total ones counter''.
!Part c
Check if the bit is a 1 by shifting the bits to the ''left'' and testing to see if bit C in the CCR is a ''1''.

"Proof" is simulating ''both'' the inner and outer loops ''once'' and showing the contents of the ''total ones counter''.</html>
!Lab 9: Use PWM to Dim a LED
*Monday Lab
**Due Apr. 27
*Friday Lab
**Due Apr. 24
!Lab 9: Use PWM to Dim a LED
*Code pg. 391 in book
!Lab 9: Use PWM to Dim a LED
The ''week of'' Apr. 17, 2009 is Lab9. ''Remember:'' you need a flowchart and you need to use the "proof method," ''not'' the Register Maps. Finally, you ''must'' show me that your codes work ''before'' you submit the report. Otherwise, the report ''will not'' be graded.
*Do ''not'' follow the instructions on Dr. Leung's site, they are ''wrong!''

Write a program so that an LED is gradually dimmed down ''to 10% in 5 seconds''.
*Use 100 as the initial duty and period values. 
*Dim the brightness ''by 10% in the first second'' and then ''by 20% per second for'' the remaining ''4 seconds''.
**This is done by decrementing the duty value by 1 every 100ms in the first second then by 2 every 100ms in the remaining 4 seconds.

For proof: 
*Simulate the ''decrement duty by 1 loop //once//'' and show the ''contents of the duty register''
*Simulate the ''decrement duty by 2 loop //once//'' and show the ''contents of the duty register''
''NOTE:'' "Archive" for ''instructions'' to previous labs for the ''current semester only.'' For ''notes on some labs'' see [[References]].

<<tabs txtLabs
Lab9 "Lab 9" Lab9new
Lab8 "Lab 8" Lab8
Lab7 "Lab 7" Lab7
Lab6 "Lab 6" Lab6
Lab5 "Lab 5" Lab5
Lab4 "Lab 4" Lab4
Lab3 "Lab 3" Lab3
Lab2 "Lab 2" Lab2
Lab1 "Lab 1" Lab1

!TAMUK Links
*[[TAMUK|http://www.tamuk.edu]]: University homepage
**[[Engineering|http://www.engineer.tamuk.edu]]: Engineering homepage
***[[Dr. Leung|http://www.engineer.tamuk.edu/CLeung/index.htm]]: Website for Dr. Leung who teaches [[EEEN3449|http://www.engineer.tamuk.edu/cleung/EEEN3449/EEEN%203449.htm]]
**[[Library|http://lib.tamuk.edu]]: Library's page
***[[OASIS|http://oasis.lib.tamuk.edu]]: Database's page
**[[Blue and Gold|http://www.tamuk.edu/bluegold/]]: Registration site
**[[Career Services|http://www.tamuk.edu/csc/]]: Get a job!
**[[Schedule|http://www.tamuk.edu/schedule/]]: Academic calendar, due dates, finals dates, and etc.
**[[MSUB|http://osa.tamuk.edu/]]: Memorial Student Union Building (and all organizations within) homepage
**[[webmail|http://www.tamuk.edu/email/]]: Campus e-mail
**[[mygroups|http://mygroups.tamuk.edu/]]: Online community for TAMUK organizations
**[[webct|http://webct.tamuk.edu/]]: Supposed to be a forum for classes
!External Links
*[[EEEN3449|http://www.engineer.tamuk.edu/cleung/EEEN3449/EEEN%203449.htm]]: Official ~EEEN3449 Site
*[[Freescale|http://www.freescale.com/]]: Makers of Motorolla's semiconductors; namely, ~MC9S12 series.
*[[MC9S12DP256|http://www.freescale.com/files/microcontrollers/doc/data_sheet/9S12DP256B.zip?fsrch=1&WT_TYPE=Data%20Sheets&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=zip&WT_ASSET=Documentation]]: Updated Data Sheets.
*[[MC9S12DG256|http://www.freescale.com/files/microcontrollers/doc/data_sheet/9S12DT256_ZIP.zip?fsrch=1&WT_TYPE=Data%20Sheets&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=zip&WT_ASSET=Documentation]]: Updated Data Sheets.
*[[AsmIDE|http://www.ericengler.com/AsmIDE.aspx]]: Eric Engler's site
[[Due Dates|DueDates]]
[[Current Lab|CurrentLab]]
[[Lab Archive|LabArchive]]
!Makeup Lab
*Thursday, December 4, 2008 ''before'' 5pm for ''both labs''

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-89073531-2"></script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-89073531-2');
<link rel="alternate" type="application/rss+xml" title="MicroLab" href="http://eeen3449.josealerma.com/index.xml" />
<link rel="shortcut icon" type="image/x-icon" href="http://eeen3449.josealerma.com/files/favicon.ico" />
<link rel="icon" href="http://eeen3449.josealerma.com/files/animated_favicon1.gif" type="image/gif" >
<link rel="icon" href="http://eeen3449.josealerma.com/files/favicon.ico" type="image/x-icon" />
<div id='header' class='header' macro='gradient vert   #555555       #3b3b3b '>
        <div class='siteTitle' refresh='content' tiddler='SiteTitle'></div>
        <span id='topMenu' refresh='content' tiddler='MainMenu'></span>

<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='macro' force='true' macro='slider chkSideBarTabs SideBarTabs "index ยป" "display lists of tiddlers"'></div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
<div id='footer' style="text-align:center"><html><a href="http://www.buy-ad-links.com/" ><img  border="0" src="http://www.yourhitstats.com/link_purchase-3729869.png" alt="link purchase"></a></html></div>
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Date:''|Apr 19, 2007|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			// checkbox linked with this password "save this password on this computer"
			// text savePasswordCheckboxLabel
		onChange: config.macros.option.genericOnChange

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
		return config.options[name] ? "true" : "false";

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
		set: function(name,value) {config.options[name] = decodeCookie(value);}

// need to reload options to load passwordOptions

if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

		pasPassword: "Test password"
<li><a href="./files/reg_map.doc" onClick="javascript: pageTracker._trackPageview('/downloads/reg_map'); ">Lab 1 Register Map</a> : ''Local'' copy, i.e. ''NOT'' on Dr. Leung's site.</li><li>How to do the <a href="./files/proof_method.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/proof_method'); ">"Proof Method"</a></li><li>How to <a href="./files/simulate_loop.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/simulate_loop'); ">Simulate the loop</a></li><li><a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Lab_report_template.doc" onClick="javascript: pageTracker._trackPageview('/links/Report_template'); ">Dr. Leung's Report Template</a></li><li>Avoid [[common mistakes|CommonMistakes]] so that you do not get huge points off for things I told you a million times.</li></ul>
!All Labs
<ul><li>Pin-out</li><ul><li><a href="./files/Datasheets/p42.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/pg42'); ">Pg 42</a> in ~MC9S12DP256.pdf</li></ul><li>Assembler Directives (ORG, RMB, and etc)</li><ul><li>Pg 32 in book</li></ul><li>~D-Bug12 Commands (PC,MD, and etc)</li><ul><li>Pg 86 in book</li></ul><li>Op-codes (LDAA, STAB, and etc)</li><ul><li>Pg 722 in book</li></ul><li>Registers (PORTA, DDRB, and etc)</li><ul><li>Pg 755 in book</li></ul><li>Flowchart Example</li><ul><li>Pg 36 in book</li></ul></ul></html>
!Individual Labs
<<tabs txtLabRef
Lab10 "Lab 10" Lab10Ref
Lab9 "Lab 9" Lab9Ref
Lab8 "Lab 8" Lab8Ref
Lab7 "Lab 7" Lab7Ref
Lab6 "Lab 6" Lab6Ref
Lab5 "Lab 5" Lab5Ref
Lab4 "Lab 4" Lab4Ref
Lab3 "Lab 3" Lab3Ref
Lab2 "Lab 2" Lab2Ref
Lab1 "Lab 1" Lab1Ref
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><html><br /><a href="./index.xml" title="RSS Feed"><img src="./files/valid-rss.png" alt="RSS"></a><br /></html>
|''Description''|displays search results as a simple list of matching tiddlers|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
!Revision History
!!v0.2.0 (2008-08-18)
* initial release
!!v0.3.0 (2008-08-19)
* added Open All button (renders Classic Search option obsolete)
* sorting by relevance (title matches before content matches)
!!v0.4.0 (2008-08-26)
* added tag matching
!To Do
* tag matching optional
* animations for container creation and removal
* when clicking on search results, do not scroll to the respective tiddler (optional)
* use template for search results
if(!version.extensions.SimpleSearchPlugin) { //# ensure that the plugin is only installed once
version.extensions.SimpleSearchPlugin = { installed: true };

if(!plugins) { var plugins = {}; }
plugins.SimpleSearchPlugin = {
	heading: "Search Results",
	containerId: "searchResults",
	btnCloseLabel: "close",
	btnCloseTooltip: "dismiss search results",
	btnCloseId: "search_close",
	btnOpenLabel: "Open all",
	btnOpenTooltip: "open all search results",
	btnOpenId: "search_open",
	displayResults: function(matches, query) {
		story.refreshAllTiddlers(true); // update highlighting within story tiddlers
		var el = document.getElementById(this.containerId);
		query = '"""' + query + '"""'; // prevent WikiLinks
		if(el) {
		} else { //# fallback: use displayArea as parent
			var container = document.getElementById("displayArea");
			el = document.createElement("div");
			el.setAttribute("id", this.containerId);
			el = container.insertBefore(el, container.firstChild);
		var msg = "!" + this.heading + "\n";
		if(matches.length > 0) {
			msg += "''" + config.macros.search.successMsg.format([matches.length.toString(), query]) + ":''\n";
			this.results = [];
			for(var i = 0 ; i < matches.length; i++) {
				msg += "* [[" + matches[i].title + "]]\n";
		} else {
			msg += "''" + config.macros.search.failureMsg.format([query]) + "''"; // XXX: do not use bold here!?
		createTiddlyButton(el, this.btnCloseLabel, this.btnCloseTooltip, plugins.SimpleSearchPlugin.closeResults, "button", this.btnCloseId);
		wikify(msg, el);
		if(matches.length > 0) { // XXX: redundant!?
			createTiddlyButton(el, this.btnOpenLabel, this.btnOpenTooltip, plugins.SimpleSearchPlugin.openAll, "button", this.btnOpenId);

	closeResults: function() {
		var el = document.getElementById(plugins.SimpleSearchPlugin.containerId);
		plugins.SimpleSearchPlugin.results = null;
		highlightHack = null;

	openAll: function(ev) {
		story.displayTiddlers(null, plugins.SimpleSearchPlugin.results);
		return false;

config.shadowTiddlers.StyleSheetSimpleSearch = "/*{{{*/\n" +
	"#" + plugins.SimpleSearchPlugin.containerId + " {\n" +
	"\toverflow: auto;\n" +
	"\tpadding: 5px 1em 10px;\n" +
	"\tbackground-color: [[ColorPalette::TertiaryPale]];\n" +
	"}\n\n" +
	"#" + plugins.SimpleSearchPlugin.containerId + " h1 {\n" +
	"\tmargin-top: 0;\n" +
	"\tborder: none;\n" +
	"}\n\n" +
	"#" + plugins.SimpleSearchPlugin.containerId + " ul {\n" +
	"\tmargin: 0.5em;\n" +
	"\tpadding-left: 1.5em;\n" +
	"}\n\n" +
	"#" + plugins.SimpleSearchPlugin.containerId + " .button {\n" +
	"\tdisplay: block;\n" +
	"\tborder-color: [[ColorPalette::TertiaryDark]];\n" +
	"\tpadding: 5px;\n" +
	"\tbackground-color: [[ColorPalette::TertiaryLight]];\n" +
	"}\n\n" +
	"#" + plugins.SimpleSearchPlugin.containerId + " .button:hover {\n" +
	"\tborder-color: [[ColorPalette::SecondaryMid]];\n" +
	"\tbackground-color: [[ColorPalette::SecondaryLight]];\n" +
	"}\n\n" +
	"#" + plugins.SimpleSearchPlugin.btnCloseId + " {\n" +
	"\tfloat: right;\n" +
	"\tmargin: -5px -1em 5px 5px;\n" +
	"}\n\n" +
	"#" + plugins.SimpleSearchPlugin.btnOpenId + " {\n" +
	"\tfloat: left;\n" +
	"\tmargin-top: 5px;\n" +
	"}\n" +
store.addNotification("StyleSheetSimpleSearch", refreshStyles);

// override Story.search()
Story.prototype.search = function(text, useCaseSensitive, useRegExp) {
	highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(), useCaseSensitive ? "mg" : "img");
	var matches = store.search(highlightHack, null, "excludeSearch");
	var q = useRegExp ? "/" : "'";
	plugins.SimpleSearchPlugin.displayResults(matches, q + text + q);

// override TiddlyWiki.search() to sort by relevance
TiddlyWiki.prototype.search = function(searchRegExp, sortField, excludeTag, match) {
	var candidates = this.reverseLookup("tags", excludeTag, !!match);
	var primary = [];
	var secondary = [];
	var tertiary = [];
	for(var t = 0; t < candidates.length; t++) {
		if(candidates[t].title.search(searchRegExp) != -1) {
		} else if(candidates[t].tags.join(" ").search(searchRegExp) != -1) {
		} else if(candidates[t].text.search(searchRegExp) != -1) {
	var results = primary.concat(secondary).concat(tertiary);
	if(sortField) {
		results.sort(function(a, b) {
			return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);
	return results;

} //# end of "install only once"
Microprocessor Systems Unofficial Site
[[EEEN 3449 Lab|Welcome]]
/*Monochrome Theme for TiddlyWiki*/
/*Design and CSS by Saq Imtiaz*/
/*Version 1.0*/
/*Modified by Jose*/

body {background:#3B3B3B; color:#C3C3C3; font:12px Verdana, Helvetica, sans-serif;

#header {padding: 0em 0em 0em 0em; background:transparent;	font-family: arial,helvetica; font-size:12px;

/*Tab support*/
.tabContents, .tabSelected { color: #ccc;
background: #3B3B3B; border:1px solid #3B3B3B; }
.tabUnselected {
color: #777; border:1px solid #3B3B3B;
background: #454545;

#footer{margin-left:1.75em; margin-right:23.5em; margin-top:0.5em; padding-top:1em; padding-bottom:10px;
border: 0px;
background: #454545;
color: #777;

/*More sidebar options*/
#sidebarTabs .tab {
font-size:90%; -moz-border-radius-topleft:.5em; -moz-border-radius-topright:.5em;}
#sidebarTabs .tabContents .tabContents{
font-family: arial,helvectica; background:#454545;border:0px solid #666; border-right:1px solid #454545;}
#sidebarTabs .button{color:#666; border:none; margin:0em 0.2em;
padding:0.2em 0.3em;
#sidebarTabs .button:active, #sidebarTabs .button:hover{border:none; background:#3B3B3B; color:#ccc;}

.siteTitle {
font-family: 'Trebuchet MS' sans-serif;
font-weight: bold;
font-size: 32px;
color: #ccc; margin-right:2em;margin-left:0.5em;

#topMenu br {display:none;}
#topMenu a, #topMenu .tiddlyLink, #topMenu .button {margin:0em; color:#CCC; padding:15px 15px 10px 15px;padding-top:1.6em;border:none; border-right: 1px solid #666;float:left;}
#topMenu {border-left: 1px solid #666;  float:left;margin:0;}
#topMenu a:hover {color:#ccc; background:#3b3b3b;}

#displayArea {margin-left:1.35em; margin-right:17.65em; margin-top:0.5em; padding-top:1em; padding-bottom:10px;}

.tiddler {background:#454545; margin-bottom:20px; padding:1em 2em 1em 2em;}

a, a:hover{
text-decoration: none; background:transparent;

.viewer a, .viewer a:hover{border-bottom:1px dotted #fff; font-weight:normal;}

.viewer .button, .editorFooter .button{
color: #fff;
border: 1px solid #fff;

.viewer .button:hover,
.editorFooter .button:hover, .viewer .button:active, .viewer .highlight,.editorFooter .button:active, .editorFooter .highlight{
color: #fff;
background: #3B3B3B;
border-color: #3B3B3B;

.title {color:#ccc; font-family:'Lucida Grande', Verdana, Sans-Serif; font-size:1.5em;

.subtitle, .subtitle a { color: #777; font-size: 0.95em;margin:0.2em;}
.shadow .title{color:#777;}

.toolbar {font-size:90%;}
.selected .toolbar a {color:#666;border:0;}
.selected .toolbar a:hover {color:#999; background:transparent;border:0;}

.toolbar .button:hover, .toolbar .highlight, .toolbar .marked, .toolbar a.button:active{color:#666;border:0; background:transparent;border:0;}

.tagging, .tagged {
border: 1px solid #555;
background-color: 	#444;

.selected .tagging, .selected .tagged {
background-color: 	#3B3B3B;
border: 1px solid #666;

.tagging .listTitle, .tagged .listTitle {
color: #666;

.selected .tagging .listTitle, .selected .tagged .listTitle {
color: #aaa;

.tagging .button, .tagged .button {
color:		#838383;
.selected .tagging .button, .selected .tagged .button {

.highlight, .marked {background:transparent; color:#111; border:none; text-decoration:underline;}

.tagging .button:hover, .tagged .button:hover, .tagging .button:active, .tagged .button:active {
border: none; background:transparent; text-decoration:underline; color:#333;

#sidebarOptions {margin-top:1em;}
#sidebar {margin-right:1.35em;}

#sidebarTabs .tabContents {	
	font-family: arial,helvetica;}

#sidebarOptions a, #sidebarOptions a:hover{border:none;color:#666;}
#sidebarOptions a:hover, #sidebarOptions a:active {background:#454545; color:#ccc;}
#sidebarTabs .tabContents {background:#454545;border:0px solid #666; border-right:1px solid #454545;}
#sidebarOptions input {background:#ccc; border:1px solid #666;}

#sidebarTabs .tabContents .tiddlyLink, #sidebarTabs .tabContents .button{color:#666;font-weight:normal;}
#sidebarTabs .tabContents .tiddlyLink:hover, #sidebarTabs .tabContents .button:hover {color:#ccc; background:transparent;}
.listTitle {color:#777;}

#sidebarTabs .tabSelected,#sidebarTabs .tabSelected:hover{background:#454545;border:none;color:#ccc; border:1px solid #454545;}
#sidebarTabs .tabUnselected{background:#3B3B3B; border:1px solid #454545; color:#666;}

   #sidebarTabs .txtMoreTab .tabSelected,
   #sidebarTabs .txtMoreTab .tab:hover,
   #sidebarTabs .txtMoreTab .tabContents{
color: #ccc;
background: #3B3B3B; border:1px solid #3B3B3B;

   #sidebarTabs .txtMoreTab .tabUnselected {
color: #777; border:1px solid #3B3B3B;
background: #454545;

#sidebarTabs .tabContents .button:hover, #sidebarTabs .tabContents .highlight, #sidebarTabs .tabContents .marked, #sidebarTabs .tabContents a.button:active{color:#ccc; background:transparent;}

   #sidebarOptions .sliderPanel {
background: #454545; font-size: .9em;

#sidebarOptions .sliderPanel input {border:1px solid #666; background:#ccc;}
#sidebarOptions .sliderPanel .txtOptionInput {border:1px solid #666;width:9em;}

#sidebarOptions .sliderPanel a {font-weight:normal; color:#666;background-color: #454545; border-bottom:1px dotted #333;}

#sidebarOptions .sliderPanel a:hover {
background-color: #454545;
border-bottom:1px dotted #111;

.popup {
background: #3B3B3B;
border: 1px solid #454545;

.popup li.disabled {
color: #000;

.popup li a, .popup li a:visited {
color: #777;
border: none;

.popup li a:hover {
background: #3b3b3b;
color: #c3c3c3;
border: none;
.popup hr {
	color: #777;
	background: #777;
	border-bottom: 1px;

.listBreak div{
	border-bottom: 1px solid #777;

#messageArea {
border: 4px dotted #ccc;
background: #454545;
color: #777;

#messageArea .button{

color: #3B3B3B;
border: 1px solid #ccc;

#messageArea .button:hover {

color: #ccc;
background: #3B3B3B;
border-color: #3B3B3B;

.viewer blockquote {
border-left: 5px solid #3B3B3B; background:#3B3B3B

.viewer table, .viewer td {
border: 1px solid 	#2E2E2E;

.viewer th, thead td {
background: #3B3B3B;
border: 1px solid #3B3B3B;
color: #ccc;
.viewer pre {
border: 1px solid #3b3b3b;
background: #5F5F5F;

.viewer code {
color: #c3c3c3; background:#5f5f5f;

.viewer hr {
border-top: dashed 1px #222; margin:0 1em;

.editor input {
border: 1px solid #ccc; margin-top:5px;

.editor textarea {
border: 1px solid #ccc;
/*Header color changed to be viewable*/
h1,h2,h3,h4,h5 { color: #7C7C7C; background: transparent; padding-bottom:2px; font-family: Arial, Helvetica, sans-serif; }
h1 {font-size:18px;}
h2 {font-size:16px;}
h3 {font-size: 14px;}
|Author|Lyall Pearce|
|License|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|Overrides|store.getSaver().externalizeTiddler(), store.getTiddler() and store.getTiddlerText()|
|Description|Encrypt/Decrypt Tiddlers with a Password key|

* Tag a tiddler with Encrypt(prompt)
** Consider the 'prompt' something to help you remember the password with. If multiple tiddlers can be encrypted with the same 'prompt' and you will only be asked for the password once.
* Upon save, the Tiddler will be encrypted and the tag replaced with Decrypt(prompt).
** Failure to encrypt (by not entering a password) will leave the tiddler unencrypted and will leave the Encrypt(prompt) tag in place. This means that the next time you save, you will be asked for the password again.
** To have multiple tiddlers use the same password - simply use the same 'prompt'.
** Tiddlers that are encrypted may be automatically tagged 'excludeSearch' as there is no point in searching encrypted data - this is configurable by an option - you still may want to search the titles of encrypted tiddlers
** Tiddlers that are encrypted may be automatically tagged 'excludeLists', if you have them encrypted, you may also want to keep them 'hidden' - this is configurable by an option.
** Automatic removal of excludeLists and excludeSearch tags is performed, if the above two options are set, only if these two tags are the last 2 tags for a tiddler, if they are positioned somewhere else in the tags list, they will be left in place, meaning that the decrypted tiddler will not be searchable and/or will not appear in lists.
** Encrypted tiddlers are stored as displayable hex, to keep things visibly tidy, should you display an encrypted tiddler. There is nothing worse than seeing a pile of gobbledy gook on your screen. Additionally, the encrypted data is easily cut/paste/emailed if displayed in hex form.
* Tiddlers are decrypted only if you click the decrypt button or the decryptAll button, not when you load the TiddlyWiki
** If you don't display a tiddler, you won't have the option to decrypt it (unless you use the {{{<<EncryptionDecryptAll>>}}} macro)
** Tiddlers will re-encrypt automatically on save.
** Decryption of Tiddlers does not make your TiddlyWiki 'dirty' - you will not be asked to save if you leave the page.
* Errors are reported via diagnostic messages.
** Empty passwords, on save, will result in the tiddler being saved unencrypted - this should only occur with new tiddlers, decrypted tiddlers or with tiddlers who have had their 'prompt' tag changed.
** Encrypted tiddlers know if they are decrypted successfully - failure to decrypt a tiddler will ''not'' lose your data.
** Editing of an encrypted (that has not been unencrypted) tiddler will result in loss of that tiddler as the SHA1 checksums will no longer match, upon decryption. To this end, it is best that you do not check the option.
** To change the password on a Tiddler, change the Encrypt('prompt') tag to a new prompt value, after decrypting the tiddler.
** You can edit the tags of an encrypted tiddler, so long as you do not edit the text.
** To change the password for all tiddlers of a particular prompt, use the {{{<<EncryptionChangePassword ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro.
** To decrypt all tiddlers of a particular "prompt string", use the {{{<<EncryptionDecryptAll ["button text" ["tooltip text" ["prompt string" ["accessKey"]]]]>>}}} macro - this will make tiddlers encrypted with "prompt string" searchable - or prompt for all 'prompt strings', if none is supplied.
Useful Buttons: 
<<EncryptionChangePassword>> - Change passwords of encrypted tiddlers.
<<EncryptionDecryptAll>> - Decrypt ALL tiddlers - enables searching contents of encrypted tiddlers.
<<option chkExcludeEncryptedFromSearch>> - If set, Encrypted Tiddlers are excluded from searching by tagging with excludeSearch. If Clear, excludeSearch is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Searching of Encrypted Tiddlers is only meaningful for the Title and Tags.
<<option chkExcludeEncryptedFromLists>> - If set, Encrypted Tiddlers are excluded from lists by tagging with excludeLists. If Clear, excludeLists is not added and it is also removed from existing Encrypted Tiddlers only if it is the last Tag. Preventing encrypted tiddlers from appearing in lists effectively hides them.
!!!!!Revision History
* 3.1.0 - When creating a new Encrypt(prompt) tiddler and you have not previously decrypted a tiddler with the same prompt, on save, you will be prompted for the password to encrypt the tiddler. Prior to encrypting, an attempt to decrypt all other tiddlers with the same prompt, is performed. If any tiddler fails to decrypt, the save is aborted - this is so you don't accidentally have 2 (or more!) passwords for the same prompt. Either you enter the correct password, change the prompt string and try re-saving or you cancel (and the tiddler is saved unencrypted).
* 3.0.1 - Allow Enter to be used for password entry, rather than having to press the OK button.
* 3.0.0 - Major revamp internally to support entry of passwords using forms such that passwords are no longer visible on entry. Completely backward compatible with old encrypted tiddlers. No more using the javascript prompt() function.
!!!!!Additional work

version.extensions.TiddlerEncryptionPlugin = {major: 3, minor: 1, revision: 0, date: new Date(2008,8,18)};

// where I cache the passwords - for want of a better place.
config.encryptionPasswords = new Array();
config.encryptionReEnterPasswords = false;

if(config.options.chkExcludeEncryptedFromSearch == undefined) config.options.chkExcludeEncryptedFromSearch = false;
if(config.options.chkExcludeEncryptedFromLists == undefined) config.options.chkExcludeEncryptedFromLists = false;

config.macros.EncryptionChangePassword = {};
config.macros.EncryptionChangePassword.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Change Passwords", 
				       (params[1] && params[1].length > 0) ? params[1] : "Change Passwords" + (params[2] ? " for prompt "+params[2] : ""), 
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("promptString", params[2]);

config.macros.EncryptionDecryptAll = {};
config.macros.EncryptionDecryptAll.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Decrypt All", 
				       (params[1] && params[1].length > 0) ? params[1] : "Decrypt All Tiddlers" + ((params[2] && params[2].length > 0) ? " for prompt "+params[2] : " for a given 'prompt string'"), 
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("promptString", params[2]);

config.macros.EncryptionDecryptThis = {};
config.macros.EncryptionDecryptThis.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
    var theButton = createTiddlyButton(place,
				       (params[0] && params[0].length > 0) ? params[0] : "Decrypt", 
				       (params[1] && params[1].length > 0) ? params[1] : "Decrypt this Tiddler", 
    if(params[2] && params[2].length > 0) {
	theButton.setAttribute("theTiddler", params[2]);
// Called by the EncryptionChangePassword macro/button
// Also invoked by the callback for password entry
function onClickEncryptionChangePassword(eventObject) {
    var promptString;
    if(!promptString && this.getAttribute) {
	promptString = this.getAttribute("promptString");
    // I do call this function directly
    if(!promptString && typeof(eventObject) == "string") {
	promptString = eventObject;
    if(!promptString) {
	promptString = prompt("Enter 'prompt string' to change password for:","");
    if(!promptString) {
    if(! config.encryptionPasswords[promptString]) {
	var changePasswordContext = {changePasswordPromptString: promptString,
				     callbackFunction: MyChangePasswordPromptCallback_TiddlerEncryptionPlugin};
	// Callback function will re-invoke this function

    // Decrypt ALL tiddlers for that prompt
    // Now ditch the cached password, this will force the re-request for the new password, on save.
    displayMessage("Save TiddlyWiki to set new password for '"+promptString+"'");
    config.encryptionPasswords[promptString] = null;
    // mark store as dirty so a save will be requrested.
// Called by the password entry form when the user clicks 'OK' button.
function MyChangePasswordPromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
// Called by the EncryptionDecryptThis macro/button
function onClickEncryptionDecryptThis() {
    var theTiddler = this.getAttribute("theTiddler");
    if(!theTiddler) {
    config.encryptionReEnterPasswords = true;
    try {
	theTiddler = store.getTiddler(theTiddler);
	config.encryptionReEnterPasswords = false;
    } catch (e) {
	if(e == "DecryptionFailed") {
	    displayMessage("Decryption failed");
    } // catch
// called by the EncryptionDecryptAlll macro/button
// Also called by the callback after the user clicks 'OK' button on the password entry form
function onClickEncryptionDecryptAll(eventObject) {
    var promptString;
    if(!promptString && this.getAttribute) {
	promptString = this.getAttribute("promptString");
    // I do call this function directly
    if(!promptString && typeof(eventObject) == "string") {
	promptString = eventObject;
    if(!promptString) {
	promptString = "";

    // Loop through all tiddlers, looking to see if there are any Decrypt(promptString) tagged tiddlers
    // If there are, check to see if their password has been cached.
    // If not, ask for the first one that is missing, that we find
    // the call back function will store that password then invoke this function again, 
    // which will repeat the whole process. If we find all passwords have been cached
    // then we will finally do the decryptAll functionality, which will then
    // be able to decrypt all the required tiddlers, without prompting.
    // We have to do this whole rigmarole because we are using a 'form' to enter the password
    // rather than the 'prompt()' function - which shows the value of the password.
    var tagToSearchFor="Decrypt("+promptString;
    config.encryptionReEnterPasswords = true; 
    var promptGenerated = false;
    store.forEachTiddler(function(store,tiddler) {
	    // Note, there is no way to stop the forEachTiddler iterations
	    if(!promptGenerated && tiddler && tiddler.tags) {
		for(var ix=0; ix<tiddler.tags.length && !promptGenerated; ix++) {
		    if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
			var tag = tiddler.tags[ix];
			var lastBracket=tag.lastIndexOf(")");
			if(lastBracket >= 0) {
			    // Ok, tagged with Encrypt(passwordPrompt)
			    // extract the passwordPrompt name
			    var passwordPromptString=tag.substring(8,lastBracket);
			    if(!config.encryptionPasswords[passwordPromptString]) {
				// no password cached, prompt and cache it, rather than decryptAll
				// callback from prompting form will resume decryptAll attempt.
				var decryptAllContext = {decryptAllPromptString: promptString,
							 callbackFunction: MyDecryptAllPromptCallback_TiddlerEncryptionPlugin};
				promptGenerated = true;
			    } // if(!config.encryptionPasswords
			} // if(lastBracket
		    } // if(tiddler.tags[ix]..
		} // for
	    } // if
	}); // store.forEachTiddler
    // If we get here, all passwords have been cached.
    if(!promptGenerated) {
	config.encryptionReEnterPasswords = false;
	// Now do the decrypt all functionality
	try {
	    store.forEachTiddler(function(store,tiddler) {
		    // Note, there is no way to stop the forEachTiddler iterations
		    if(tiddler && tiddler.tags) {
			for(var ix=0; ix<tiddler.tags.length; ix++) {
			    if(tiddler.tags[ix].indexOf(tagToSearchFor) == 0) {
				try {
				} catch (e) {
				    displayMessage("Decryption of '"+tiddler.title+"' failed.");
				    // throw e;
			    } // if(tiddler.tags
			} // for
		    } // if
		}); // store.forEachTiddler
	    displayMessage("All tiddlers" + (promptString != "" ? " for '"+promptString+"'" : "") + " have been decrypted");
	} catch (e) {
	    if(e == "DecryptionFailed") {
	} // catch

function MyDecryptAllPromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
    // restart the decryptAll process again after the user has entered a password.

saveChanges_TiddlerEncryptionPlugin = saveChanges;
saveChanges = function(onlyIfDirty,tiddlers) {
    // Loop through all tiddlers, looking to see if there are any Encrypt(string) tagged tiddlers
    // If there are, check to see if their password has been cached.
    // If not, ask for the first one that is missing, that we find
    // the call back function will store that password then invoke this function again, 
    // which will repeat the whole process. If we find all passwords have been cached
    // then we will finally call the original saveChanges() function, which will then
    // be able to save the tiddlers.
    // We have to do this whole rigmarole because we are using a 'form' to enter the password
    // rather than the 'prompt()' function - which shows the value of the password.
    config.encryptionReEnterPasswords = true; 
    var promptGenerated = false;
    store.forEachTiddler(function(store,tiddler) {
	    if(!promptGenerated && tiddler && tiddler.tags) {
		for(var ix=0; ix<tiddler.tags.length && !promptGenerated; ix++) {
		    if(tiddler.tags[ix].indexOf("Encrypt(") == 0) {
			var tag = tiddler.tags[ix];
			var lastBracket=tag.lastIndexOf(")");
			if(lastBracket >= 0) {
			    // Ok, tagged with Encrypt(passwordPrompt)
			    // extract the passwordPrompt name
			    var passwordPrompt=tag.substring(8,lastBracket);
			    if(!config.encryptionPasswords[passwordPrompt]) {
				// no password cached, prompt and cache it, rather than save
				var saveContext = {onlyIfDirty: onlyIfDirty, 
						   tiddlers: tiddlers, 
				                   callbackFunction: MySavePromptCallback_TiddlerEncryptionPlugin};
				promptGenerated = true;
			    } // if(!config.encryptionPasswords
			} // if(lastBracket
		    } // if(tiddler.tags[ix]..
		} // for
	    } // if
	}); // store.forEachTiddler
    // If we get here, all passwords have been cached.
    if(!promptGenerated) {
	config.encryptionReEnterPasswords = false;

function MySavePromptCallback_TiddlerEncryptionPlugin(context) {
    config.encryptionPasswords[context.passwordPrompt] = context.password;
    // validate the password entered by attempting to decrypt all tiddlers
    // with the same encryption prompt string.

    // restart the save process again
    saveChanges(context.onlyIfDirty, context.tiddlers);

store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin = store.getSaver().externalizeTiddler;
store.getSaver().externalizeTiddler = function(store, tiddler) {
    // Ok, got the tiddler, track down the passwordPrompt in the tags.
    // track down the Encrypt(passwordPrompt) tag
    if(tiddler && tiddler.tags) {
	for(var g=0; g<tiddler.tags.length; g++) {
	    var tag = tiddler.tags[g];
	    if(tag.indexOf("Encrypt(") == 0) {
		var lastBracket=tag.lastIndexOf(")");
		if(lastBracket >= 0) {
		    // Ok, tagged with Encrypt(passwordPrompt)
		    // extract the passwordPrompt name
		    var passwordPrompt=tag.substring(8,lastBracket);
		    // Ok, Encrypt this tiddler!
		    var decryptedSHA1 = Crypto.hexSha1Str(tiddler.text);
		    var password =  GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(passwordPrompt);
		    if(password) {
			var encryptedText = TEAencrypt(tiddler.text, password);
			encryptedText = StringToHext_TiddlerEncryptionPlugin(encryptedText);
			tiddler.text = "Encrypted("+decryptedSHA1+")\n"+encryptedText;
			// Replace the Tag with the Decrypt() tag
			// let the store know it's dirty
			store.setDirty(tiddler.title, true);
			// prevent searches on encrypted tiddlers, still nice to search on title though.
			if(config.options.chkExcludeEncryptedFromSearch == true) {
			// prevent lists of encrypted tiddlers
			if(config.options.chkExcludeEncryptedFromLists == true) {
		    } else {
			// do not encrypt - no password entered
		} // if (lastBracket...
	    } // if(tag.indexOf(...
	} // for(var g=0;...
    } // if(tiddler.tags...
    // Then, finally, do the save by calling the function we override.

    return store.getSaver().externalizeTiddler_TiddlerEncryptionPlugin(store, tiddler);

function CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler) {
    if(tiddler && tiddler.tags) {
	for(var g=0; g<tiddler.tags.length; g++) {
	    var tag = tiddler.tags[g];
	    if(tag.indexOf("Decrypt(") == 0) {
		var lastBracket=tag.lastIndexOf(")");
		if(lastBracket >= 0) {
		    if(tiddler.text.substr(0,10) == "Encrypted(") {
			var closingSHA1Bracket = tiddler.text.indexOf(")");
			var decryptedSHA1 = tiddler.text.substring(10, closingSHA1Bracket);
			// Ok, tagged with Decrypt(passwordPrompt)
			// extract the passwordPrompt name
			var passwordPrompt=tag.substring(8,lastBracket);
			// Ok, Decrypt this tiddler!
			var decryptedText = tiddler.text.substr(closingSHA1Bracket+2);
			decryptedText = HexToString_TiddlerEncryptionPlugin(decryptedText);
                        // prompt("Decryption request for Tiddler '"+tiddler.title+"'");
			var password = GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(passwordPrompt);
			if(password) {
			    decryptedText = TEAdecrypt(decryptedText, password );
			    var thisDecryptedSHA1 = Crypto.hexSha1Str(decryptedText);
			    if(decryptedSHA1 == thisDecryptedSHA1) {
				tiddler.text = decryptedText;
				// Replace the Tag with the Encrypt() tag
				if(tiddler.tags[tiddler.tags.length-1] == 'excludeLists') {
				    // Remove exclude lists only if it's the last entry
				    // as it's automatically put there by encryption
				if(tiddler.tags[tiddler.tags.length-1] == 'excludeSearch') {
				    // Remove exclude search only if it's the last entry
				    // as it's automatically put there by encryption
			    } else {
				// Did not decrypt, discard the password from the cache
				config.encryptionPasswords[passwordPrompt] = null;
				config.encryptionReEnterPasswords = false;
				throw "DecryptionFailed";
			} else {
			    // no password supplied, dont bother trying to decrypt
			    config.encryptionReEnterPasswords = false;
			    throw "DecryptionFailed";
		    } else {
			// Tagged as encrypted but not expected format, just leave it unchanged
		    break; // out of for loop
		} // if (lastBracket...
	    } // if(tag.indexOf(...
	} // for(var g=0;...
    } // if (tiddler && tags)
    return tiddler;

store.getTiddler_TiddlerEncryptionPlugin = store.getTiddler;
store.getTiddler = function(title) {
    var tiddler = store.getTiddler_TiddlerEncryptionPlugin(title);
    if(tiddler) { // shadow tiddlers are not expected to be encrypted.
	try {
	    return CheckTiddlerForDecryption_TiddlerEncryptionPlugin(tiddler);
	} catch (e) {
	    if(e == "DecryptionFailed") {
		var tiddler = store.getTiddler("DecryptionFailed");
		if(!tiddler) {
		    tiddler = new Tiddler();
				"<<EncryptionDecryptThis \"Decrypt\" \"Decrypt this tiddler\" \""+title+"\">>",
		return tiddler;
	    } // if(e)
	} // catch
    } // if(tiddler) {
    return null;

store.getTiddlerText_TiddlerEncryptionPlugin = store.getTiddlerText;
store.getTiddlerText = function(title,defaultText) {
    // Simply retrieve the tiddler, normally, if it requires decryption, it will be decrypted
    var decryptedTiddler = store.getTiddler(title);
    if(decryptedTiddler) {
	return decryptedTiddler.text;
    //Ok, rather than duplicate all the core code, the above code should fail if we reach here
    // let the core code take over.
    return  store.getTiddlerText_TiddlerEncryptionPlugin(title,defaultText);

// Given a prompt, search our cache to see if we have already entered the password.
// Can return null if the user enters nothing.
function MyPrompt_TiddlerEncryptionPlugin(promptString,defaultValue,context) {
    if(!context) {
	context = {};
    context.passwordPrompt = promptString;
    PasswordPrompt.prompt(MyPromptCallback_TiddlerEncryptionPlugin, context);

function MyPromptCallback_TiddlerEncryptionPlugin(context) {
    if(context.callbackFunction) {
    } else {
	config.encryptionPasswords[context.passwordPrompt] = context.password;

function GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString) {
    if(!config.encryptionPasswords[promptString]) {
	config.encryptionPasswords[promptString] = MyPrompt_TiddlerEncryptionPlugin(promptString, "");
    return config.encryptionPasswords[promptString]; // may be null, prompt can be cancelled.

function GetAndSetPasswordForPromptToDecrypt_TiddlerEncryptionPlugin(promptString) {
    if(config.encryptionReEnterPasswords) {
	return GetAndSetPasswordForPrompt_TiddlerEncryptionPlugin(promptString);
    } else {
	return config.encryptionPasswords[promptString];

// Make the encrypted tiddlies look a little more presentable.
function StringToHext_TiddlerEncryptionPlugin(theString) {
    var theResult = "";
    for(var i=0; i<theString.length; i++) {
	var theHex = theString.charCodeAt(i).toString(16);
	if(theHex.length<2) {
	    theResult += "0"+theHex;
	} else {
	    theResult += theHex;
	if(i && i % 32 == 0)
	    theResult += "\n";
    return theResult;

function HexToString_TiddlerEncryptionPlugin(theString) {
    var theResult = "";
    for(var i=0; i<theString.length; i+=2) {
	if(theString.charAt(i) == "\n") {
	theResult += String.fromCharCode(parseInt(theString.substr(i, 2),16));
    return theResult;
// Heavily leveraged from http://trac.tiddlywiki.org/browser/Trunk/contributors/SaqImtiaz/verticals/Hesperian/PasswordPromptPlugin.js  Revision 5635
PasswordPrompt ={
  prompt : function(callback,context){
	if (!context) {
	    context = {};
	var box = createTiddlyElement(document.getElementById("contentWrapper"),'div','passwordPromptBox');
	box.innerHTML = store.getTiddlerText('PasswordPromptTemplate');
	box.style.position = 'absolute';
	document.getElementById('promptDisplayField').value = context.passwordPrompt;
	var passwordInputField = document.getElementById('passwordInputField');
	passwordInputField.onkeyup = function(ev) {
	    var e = ev || window.event;
	    if(e.keyCode == 10 || e.keyCode == 13) { // Enter
		PasswordPrompt.submit(callback, context);
	document.getElementById('passwordPromptSubmitBtn').onclick = function(){PasswordPrompt.submit(callback,context);};
	document.getElementById('passwordPromptCancelBtn').onclick = function(){PasswordPrompt.cancel(callback,context);};
  center : function(el){
	var size = this.getsize(el);
	el.style.left = (Math.round(findWindowWidth()/2) - (size.width /2) + findScrollX())+'px';
	el.style.top = (Math.round(findWindowHeight()/2) - (size.height /2) + findScrollY())+'px';
  getsize : function (el){
	var x = {};
	x.width = el.offsetWidth || el.style.pixelWidth;
	x.height = el.offsetHeight || el.style.pixelHeight;
	return x;
  submit : function(cb,context){
	context.passwordPrompt = document.getElementById('promptDisplayField').value;
	context.password = document.getElementById('passwordInputField').value;
	var box = document.getElementById('passwordPromptBox');
	return false;

  cancel : function(cb,context){
	var box = document.getElementById('passwordPromptBox');
	return false;
  setStyles : function(){
	    "#passwordPromptBox dd.submit {margin-left:0; font-weight: bold; margin-top:1em;}\n"+
	    "#passwordPromptBox dd.submit .button {padding:0.5em 1em; border:1px solid #ccc;}\n"+
	    "#passwordPromptBox dt.heading {margin-bottom:0.5em; font-size:1.2em;}\n"+
	    "#passwordPromptBox {border:1px solid #ccc;background-color: #eee;padding:1em 2em;}",'passwordPromptStyles');
  template : '<form action="" onsubmit="return false;" id="passwordPromptForm">\n'+
  '    <dl>\n'+
  '        <dt class="heading">Please enter the password:</dt>\n'+
  '        <dt>Prompt:</dt>\n'+
  '        <dd><input type="text" readonly id="promptDisplayField" class="display"/></dd>\n'+
  '        <dt>Password:</dt>\n'+
  '        <dd><input type="password" tabindex="1" class="input" id="passwordInputField"/></dd>\n'+
  '        <dd class="submit">\n'+
  '            <a tabindex="2" href="javascript:;" class="button" id="passwordPromptSubmitBtn">OK</a>\n'+
  '            <a tabindex="3" href="javascript:;" class="button" id="passwordPromptCancelBtn">Cancel</a>\n'+
  '        </dd>\n'+
  '    </dl>\n'+
  init : function(){
	config.shadowTiddlers.PasswordPromptTemplate = this.template;

// http://www.movable-type.co.uk/scripts/tea-block.html
// TEAencrypt: Use Corrected Block TEA to encrypt plaintext using password
//             (note plaintext & password must be strings not string objects)
// Return encrypted text as string
function TEAencrypt(plaintext, password)
    if (plaintext.length == 0) return('');  // nothing to encrypt
    // 'escape' plaintext so chars outside ISO-8859-1 work in single-byte packing, but keep
    // spaces as spaces (not '%20') so encrypted text doesn't grow too long (quick & dirty)
    var asciitext = escape(plaintext).replace(/%20/g,' ');
    var v = strToLongs(asciitext);  // convert string to array of longs
    if (v.length <= 1) v[1] = 0;  // algorithm doesn't work for n<2 so fudge by adding a null
    var k = strToLongs(password.slice(0,16));  // simply convert first 16 chars of password as key
    var n = v.length;

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = 0;

    while (q-- > 0) {  // 6 + 52/n operations gives between 6 & 32 mixes on each word
        sum += delta;
        e = sum>>>2 & 3;
        for (var p = 0; p < n; p++) {
            y = v[(p+1)%n];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
            z = v[p] += mx;

    var ciphertext = longsToStr(v);

    return escCtrlCh(ciphertext);

// TEAdecrypt: Use Corrected Block TEA to decrypt ciphertext using password
function TEAdecrypt(ciphertext, password)
    if (ciphertext.length == 0) return('');
    var v = strToLongs(unescCtrlCh(ciphertext));
    var k = strToLongs(password.slice(0,16)); 
    var n = v.length;

    var z = v[n-1], y = v[0], delta = 0x9E3779B9;
    var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;

    while (sum != 0) {
        e = sum>>>2 & 3;
        for (var p = n-1; p >= 0; p--) {
            z = v[p>0 ? p-1 : n-1];
            mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
            y = v[p] -= mx;
        sum -= delta;

    var plaintext = longsToStr(v);

    // strip trailing null chars resulting from filling 4-char blocks:
    plaintext = plaintext.replace(/\0+$/,'');

    return unescape(plaintext);

// supporting functions

function strToLongs(s) {  // convert string to array of longs, each containing 4 chars
    // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
    var l = new Array(Math.ceil(s.length/4));
    for (var i=0; i<l.length; i++) {
        // note little-endian encoding - endianness is irrelevant as long as 
        // it is the same in longsToStr() 
        l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) + 
               (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
    return l;  // note running off the end of the string generates nulls since 
}              // bitwise operators treat NaN as 0

function longsToStr(l) {  // convert array of longs back to string
    var a = new Array(l.length);
    for (var i=0; i<l.length; i++) {
        a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF, 
                                   l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
    return a.join('');  // use Array.join() rather than repeated string appends for efficiency

function escCtrlCh(str) {  // escape control chars etc which might cause problems with encrypted texts
    return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });

function unescCtrlCh(str) {  // unescape potentially problematic nulls and control characters
    return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });

<html><div style="text-align:center"><img alt="Under Construction!" title="C'mon, not even I am that fast" src="http://eeen3449.josealerma.com/files/under-construction.gif" /></div></html>

*''It's still too early in the semester for lab content!!''
|''Description:''|Save to web a TiddlyWiki|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 4,
	date: new Date("2008-08-11"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0'

// Environment

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
// Upload Macro

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);

config.macros.upload.action = function(params)
		// for missing macro parameter set value from options
		if (!params) params = {};
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			return false;
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			return false;
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;

// uploadOptions Macro

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
			uploadCaption = config.macros.upload.label.uploadLabel;
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
	options: [
	refreshOptions: function(listWrapper) {
		var opts = [];
		for(i=0; i<this.options.length; i++) {
			var opt = {};
			opt.option = "";
			n = this.options[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
	onCancel: function(e)
		return false;
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 

// upload functions

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
		if (bidix.debugMode) 
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
	if(onlyIfDirty && !store.isDirty())
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
	// get original
	var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
	if (typeof r == "string")
	return r;

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
		} else {
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		var rssString = generateRss();
		// no UnicodeToUTF8 conversion needed when location is "file" !!!
		if (document.location.toString().substr(0,4) != "file")
			rssString = convertUnicodeToUTF8(rssString);	
	} else {

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
		} else {
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == 404)
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
		if (responseText.charAt(0) != '0')
			status = null;
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
	return r;

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;

// UploadLog
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
	return this;

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			this.tiddler.text = textArray.join('\n');		
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	// refresh and notifiy for immediate update
	store.notify(this.tiddler.title, true);

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
	this.addText(" "+status+" |");

// Utilities

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"

bidix.dirname = function(filePath) {
	if (!filePath) 
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));

bidix.basename = function(filePath) {
	if (!filePath) 
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;

// Initializations

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"

// Options Initializations

// Backstage
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}


<html>This site is the ''unofficial'' lab site for <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/EEEN%203449.htm" onClick="javascript: pageTracker._trackPageview('/links/EEEN3449'); ">~EEEN3449</a> (or [[Embedded link|EEEN3449Lecture]]) during the ''Spring 2009 semester''. Meaning that you should ''still'' check-out the other site for updates on tests and etc. Mainly, ''this site is for the lab'' portion of the class. Also, see <a href="http://www.engineer.tamuk.edu/cleung/EEEN3449/Class_%26_Lab%20Regulation.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/Lab_Regulations'); ">Lab Regulations</a> and <a href="http://www.engineer.tamuk.edu/Cleung/EEEN3449/Syllabus.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/Syllabus'); ">Syllabus</a> for more info about the lab.

Before being in the lab, you ''need to buy the book.'' Doesn't matter where you get it so long as you have it, because it is a very important reference.

You'll also need the ~MiniDRAGON+. Dr. Leung does offer to order them for you (yes, you still need to pay), but if you need other parts, ''//you must let him know in advance//'' so that he can include them in the order and thus save shipping. See [[EVBplus]] for more info.

Finally, you'll need ~AsmIDE. An old version comes with your ~MiniDRAGON+, but you can download the latest version (3.40, as of July 2007) <a href="./files/asmide340.zip" onClick="javascript: pageTracker._trackPageview('/downloads/asmide340'); ">here</a> (local copy). This is what you use to program and communicate with your ~MiniDRAGON+. Even 3.40 is buggy, and since [[Eric Engler passed away|EricEngler]], you'll have to deal with it like the rest of us. See <a href="./files/asmide_setup.pdf" onClick="javascript: pageTracker._trackPageview('/downloads/asmide_setup'); ">~AsmIDE Setup</a> for info on installing ~AsmIDE.</html>
config.options.chkHttpReadOnly = true;  // forbid edit buttons when viewed over HTTP
config.options.chkAutoSave = false; // disable Autosave
config.options.chkSaveBackups = false; // disable save backups
config.options.txtUserName= "Jose"; // default User Name
config.options.chkGenerateAnRssFeed= true; // create RSS feed when saving changes