<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8632654884908323411</id><updated>2012-01-28T14:35:17.913-08:00</updated><category term='Windows Mobile'/><category term='Reverse-engineer'/><category term='SMS Migration'/><category term='Win32 API'/><category term='Microsoft Office'/><category term='Xcode'/><category term='Singtel'/><category term='Microsoft Virtual PC'/><category term='VB.NET'/><category term='VmWare'/><category term='.NET Framework'/><category term='General Programming'/><category term='Blogger'/><category term='Microsoft Visual Studio'/><category term='Windows Embedded'/><category term='C++'/><category term='C#'/><category term='DirectShow'/><category term='Windows Phone 7'/><category term='Web Development'/><category term='VoIP'/><category term='Wikipedia'/><category term='iPhone'/><category term='Blackberry'/><category term='Telerik'/><category term='Windows Tips'/><category term='ASP/ASP.NET'/><category term='.NET Compact Framework'/><category term='Database'/><category term='Linux'/><category term='Mac OS'/><category term='Objective-C'/><category term='Networking'/><category term='Hardware'/><category term='Android'/><category term='Office OneNote'/><title type='text'>MD's Technical Sharing</title><subtitle type='html'>Knowledge is always more precious when shared :)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default?start-index=101&amp;max-results=100'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>215</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6699448244617022973</id><published>2011-12-24T00:24:00.000-08:00</published><updated>2012-01-15T18:18:54.132-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='Objective-C'/><title type='text'>Converting between NSString and C strings in an iOS project</title><content type='html'>I recently had to use a C library in an iPhone project, which is mostly in Objective-C. Things were going on smoothly until I had some C functions that return C strings (&lt;b&gt;wchar_t*&lt;/b&gt;, &lt;b&gt;char*&lt;/b&gt;) and require conversions in order to work with Objective-C &lt;b&gt;NSString*&lt;/b&gt; types.&lt;br /&gt;&lt;br /&gt;There are 3 ways to declare a string in an iOS project in xCode:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;NSString* str = @"hello world"; &lt;b&gt;&lt;i&gt;// declare an Objective-C string&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wchar_t* str = L"hello world"; &lt;b&gt;&lt;i&gt;// declare a wide-character (Unicode) string&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;char* str = "hello world";     &lt;b&gt;&lt;i&gt;// declare an ANSI string&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;If you declare a Unicode string via the &lt;b&gt;L"" &lt;/b&gt;syntax, the compiler defaults it to UTF32. The function &lt;b&gt;wcslen()&lt;/b&gt; to get the length (e.g. number of characters) of a string may not work properly if the input string is not UTF8 encoded. For example, try the following code:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wchar_t* str1 = L"Giới thiệu về Google"; &lt;b&gt;&lt;i&gt;// "About Google" in Vietnamese&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wchar_t* str2 = L"Gioi thieu ve Google"; &lt;b&gt;&lt;i&gt;// simplified with ANSI characters only&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;printf("str1 length: %d", wcslen(str1));&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;printf("str2 length: %d", wcslen(str2));  &lt;/div&gt;&lt;br /&gt;The code will output wrong length for str1 and correct length for str2, even though they have the same number of characters. I think &lt;b&gt;wcslen &lt;/b&gt;is confused by the UTF32 characters in str1 and counts some characters more than once. However, if I try the folowing code:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;char* str3 = "Giới thiệu về Google";&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;setlocale(LC_ALL, "en_US.UTF-8"); &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;int buflen = strlen(str3)+1;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wchar_t* buffer = malloc(buflen * sizeof(wchar_t));&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;mbstowcs(buffer, str3, buflen); &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;printf("str3 length: %d", wcslen(str3));&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;free(buffer);&lt;/div&gt;&lt;br /&gt;to declare an ANSI string and convert it to UTF8 wide string by using &lt;b&gt;setlocale &lt;/b&gt;to ensure the correct Unicode encoding, &lt;b&gt;wcslen &lt;/b&gt;will return the correct string length. Not knowing what the problem is, I have to make sure that all C strings in my project are UTF8 encoded. &lt;br /&gt;&lt;br /&gt;Conversion from &lt;b&gt;NSString*&lt;/b&gt; to an ANSI string (&lt;b&gt;char*&lt;/b&gt;) is easy using the built in &lt;b&gt;NSUTF8StringEncoding&lt;/b&gt; method. The returned value is valid as long as the original value is valid, so there is no need to release or free it. The following method (taken from my custom &lt;b&gt;NSString &lt;/b&gt;category) shows how to achieve this: &lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;- (const char*)getMultiByteString&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;return [self cStringUsingEncoding:NSUTF8StringEncoding];&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;It is a bit more complicated with C function &lt;b&gt;mbstowcs&lt;/b&gt; to convert from &lt;b&gt;NSString*&lt;/b&gt; to a wide string (&lt;b&gt;wchar_t*&lt;/b&gt;):&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;- (wchar_t*)getWideString&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;const char* temp = [self cStringUsingEncoding:NSUTF8StringEncoding];&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;int buflen = strlen(temp)+1; &lt;b&gt;&lt;i&gt;//including NULL terminating char&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wchar_t* buffer = malloc(buflen * sizeof(wchar_t));&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;mbstowcs(buffer, temp, buflen); &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;return buffer;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;It is the responsibility of the caller to free the returned buffer. To improve, one can free the return value in the &lt;b&gt;dealloc()&lt;/b&gt; method of &lt;b&gt;NSString&lt;/b&gt;. The return type should then be changed to &lt;b&gt;const wchar_t*&lt;/b&gt; to indicate that the returned value is read-only.&lt;br /&gt;&lt;br /&gt;Take note that &lt;b&gt;wchar_t&lt;/b&gt; is 2 bytes on Windows but 4 bytes on Unix/Linux (including iOS) is 4 bytes. The above function uses &lt;b&gt;sizeof&lt;/b&gt; to determine the size of &lt;b&gt;wchar_t&lt;/b&gt; for the sake of generality.&lt;br /&gt;&lt;br /&gt;Using &lt;b&gt;stringWithUTF8String &lt;/b&gt;and &lt;b&gt;wcstombs &lt;/b&gt;we can do the reverse and convert a C string into &lt;b&gt;NSString&lt;/b&gt;:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;+ (NSString*)stringWithWideString:(const wchar_t*)ws&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;i&gt;&lt;b&gt;    // Destination char array must allocate more than just wcslen(ws)&lt;/b&gt;&lt;/i&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;i&gt;&lt;b&gt;    // since unicode chars may consume more than 1 byte&lt;br /&gt;// we do not yet know how many bytes the created array may consume, so assume the max.&lt;/b&gt;&lt;/i&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;int bufflen = 8*wcslen(ws)+1;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;char* temp = malloc(bufflen);&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;wcstombs(temp, ws, bufflen);&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;NSString* retVal = [self stringWithUTF8String:temp];&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;free(temp);&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;return retVal;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/div&gt;&lt;br /&gt;I hope this will help other with similar problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6699448244617022973?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6699448244617022973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/12/converting-between-nsstring-and-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6699448244617022973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6699448244617022973'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/12/converting-between-nsstring-and-c.html' title='Converting between NSString and C strings in an iOS project'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-5191940223681632938</id><published>2011-11-16T19:08:00.000-08:00</published><updated>2012-01-07T19:24:32.635-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>HMC-35HD Media Player with NAS Server Review</title><content type='html'>A few days ago I upgraded my home media player from the HMC-35HD made by &lt;a href="http://www.mele.cn/cn/index.aspx"&gt;Mele&lt;/a&gt;, a Chinese company, to the &lt;a href="http://www.legitreviews.com/article/1350/1/"&gt;ASUS O!Play Air HDP-R3&lt;/a&gt; to enjoy the many video formats supported by the HDP-R3. Before I resell the unit and earn back some cash, I am writing this short review which will hopefully help others who intend to purchase this player.&lt;br /&gt;&lt;br /&gt;Overall the unit is very light, with a dimension of 220x196x73mm and weight of 1096g (without HDD) (see full specs &lt;a href="http://dl.dropbox.com/u/5881137/HMC-35HD%20%E8%A7%84%E6%A0%BC%E4%B9%A6-6468.xls"&gt;here&lt;/a&gt;). It seemingly offers a wide range of features, including playing of music and videos (AVI, WMV, FLV, etc), accessing shared folder via Samba and uPnP using Ethernet or Wifi, Internet radio and an &lt;a href="http://en.wikipedia.org/wiki/Network-attached_storage"&gt;NAS server&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-BcX8xBx5Hvo/TwfQUs1dCGI/AAAAAAAAAPg/jmpqgdn0vrw/s1600/mele_hmc-35hd_tartozekok.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-BcX8xBx5Hvo/TwfQUs1dCGI/AAAAAAAAAPg/jmpqgdn0vrw/s1600/mele_hmc-35hd_tartozekok.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Storage devices can be connected via USB, or by inserting into the SD card slot. There are also 2 internal slots for 3.5" SATA or IDE hard disk. When connected, the device can be used as an NAS server. Judging based on the physical design, it seems that only one hard disk, either SATA or IDE, can be connected at any time.&lt;br /&gt;&lt;br /&gt;This is the home screen of the player:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ifqg-syxN_E/Twe_WcW5UvI/AAAAAAAAAOo/xnFtunXY2Ck/s1600/IMG_20111225_231812.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-ifqg-syxN_E/Twe_WcW5UvI/AAAAAAAAAOo/xnFtunXY2Ck/s1600/IMG_20111225_231812.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The five icons from the left to right are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;USB Devices:&lt;/b&gt; open media files on devices connected via USB and on storage card inserted into the card reader. Enabled only if external storage devices are detected.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Hard Disk:&lt;/b&gt; open media files from the internal HDD. Enabled only if a SATA/IDE HDD is connected.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Settings:&lt;/b&gt; configure system settings such as video output or wireless access point&lt;/li&gt;&lt;li&gt;&lt;b&gt;Ethernet:&lt;/b&gt; access Samba/uPnP shared folder on LAN. Enabled only if the device is connected via Ethernet and assigned an IP address.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Wireless:&lt;/b&gt; access Samba/uPnP shared folder on wireless network. Enabled only if the device is connected to a wireless network and assigned an IP address.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Internet Radio.&lt;/b&gt; Enabled only if the device has an IP address on the network. I could never get this to work. Upon selection, it will attempt to load for a while and will just say "unable to connect". &lt;/li&gt;&lt;/ul&gt;The file explorer interface is fast and intuitive. However, if your storage device has a lot of files/folders, after selecting the icon, it may take up to a minute for the file list to show - I assume the player tries to index all files and folders on the drive as soon as the icon is selected. Sometimes if it takes too long, the operation will time out, resulting in an empty list and the device will erroneously report a huge drive:&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-a3jsC8pG5kk/TwfCRnS0zlI/AAAAAAAAAOw/YmHHaB8i5r0/s1600/IMG_20111225_231942.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-a3jsC8pG5kk/TwfCRnS0zlI/AAAAAAAAAOw/YmHHaB8i5r0/s1600/IMG_20111225_231942.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The device supports many video output modes such as component, composite, VGA and HDMI as well as 16:9 and 4:3 aspect ratio on both PAL/NTSC systems. This can be configured in Settings:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-8v7ZSzcl1fA/TwfC0YNN2QI/AAAAAAAAAO4/EHovH6j27iI/s1600/IMG_20111225_231854.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-8v7ZSzcl1fA/TwfC0YNN2QI/AAAAAAAAAO4/EHovH6j27iI/s1600/IMG_20111225_231854.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Video Output:&lt;/b&gt; you can set to Composite, VGA or Component.  HDMI output is automatic and will be enabled only when the unit detects  an HDMI monitor connected. To change the video output without opening  Settings, press the TV-OUT button on the player or on the remote control  a few times.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Component:&lt;/b&gt; I could not get it to work with my TV. The TV  will just flash the display from black to blue a few times and auto turn  off. The setting is also grayed out unless a component cable is  connected and video output is set to Component, making it difficult to  change the settings to fit your TV if the TV does not like the default  values. &lt;/li&gt;&lt;li&gt;&lt;b&gt;Composite:&lt;/b&gt; this works without much hassle. Just set the  correct aspect ratio for your TV and you're good to go. However, the  maximum resolution is 480i, defeating the purposes of a high-definition  media player.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;TV Standard: &lt;/b&gt;support either PAL or NTSC. Affect only composite output. PAL has slighter higher resolution than NTSC. Modern TVs will handle both PAL/NTSC automatically so there is no need to change this setting.&lt;/li&gt;&lt;li&gt;&lt;b&gt;TV Type: &lt;/b&gt;Support either 4:3 or 16:9 aspect ratio. However, the settings screen will be wrongly scaled while videos still playback with correct aspect ratio, leaving black gap on the left/right as in the above picture, if 16:9 aspect ratio is selected when it has been selected previously. 16:10 is not supported.&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;HDMI Mode: &lt;/b&gt;Set the HDMI resolution. Auto Detect is recommended. Notice that there may be HDMI handshaking failure, resulting  in no output, if you're using a HDMI-to-DVI converter to connect to a  monitor with DVI only. See also my previous &lt;a href="http://minhdanh2002.blogspot.com/2011/06/samsung-p2370-and-ati-moblity-graphics.html"&gt;post&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;&lt;b&gt;VGA Mode: &lt;/b&gt;Although VGA mode apparently only lists 640x480, 800x600, 1024x768 and 1280x1024, the resolution will be automatically adjusted to fit a 16:9 wide-screen monitor if the TV type is set to 16:9. VGA &lt;a href="http://en.wikipedia.org/wiki/Extended_display_identification_data"&gt;EDID&lt;/a&gt; is not used to identify the optimal resolution. Some TV may not show anything if the VGA resolution does not match its preferred resolution. To work around this, connect another LCD monitor and change the resolution.&lt;/li&gt;&lt;/ul&gt;At the back of the player, there are two identical rows of composite video and RCA audio output. Perhaps the designer wants you to be able to play on 2 different TVs at the same time, or perhaps for the sake of redundancy...&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-zX_KgevwHCI/TwfJOq1nvYI/AAAAAAAAAPI/zJSsSzm3OaA/s1600/Home-Multimedia-Center-HMC-35HD-.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-zX_KgevwHCI/TwfJOq1nvYI/AAAAAAAAAPI/zJSsSzm3OaA/s320/Home-Multimedia-Center-HMC-35HD-.jpg" width="104" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The player will always output audio via the RCA ports regardless of  which video output mode is selected. This may be useful if you want to  use a headphone. A RCA to 3.5mm cable is needed, obviously.&lt;br /&gt;&lt;br /&gt;You can connect the player to your home wireless networks. WEP/WPA/WPA2 encryption modes are supported. However, it is time consuming to enter the wireless key using the remote control: &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qwVO9KulQ8o/TwfHbMUHBhI/AAAAAAAAAPA/xsj9OAVIiiA/s1600/IMG_20111225_231917.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-qwVO9KulQ8o/TwfHbMUHBhI/AAAAAAAAAPA/xsj9OAVIiiA/s1600/IMG_20111225_231917.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;There is also a bug here. If the wireless network is using 26 hexadecimal characters as the WEP key, the last hex character must be a digit (0-9) and cannot be between A-F or you won't be able to enter it. I wish future firmwares will address this issue, but given how these Chinese companies work, I doubt there will ever be an update.&lt;br /&gt;&lt;br /&gt;The device has basic support for subtitles (.SRT and .SUB files). Subtitle will be automatically displayed if it has the same file name and is in the same folder as the movie; otherwise it can be selected manually. While English subtitle displays well, Unicode is not supported and font size can't be changed. Word wrapping for subtitle is also not supported.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-r2rvi5vIHjk/TwfKam4pIbI/AAAAAAAAAPY/ug-2-5IT7Rw/s1600/IMG_20111225_232302.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://4.bp.blogspot.com/-r2rvi5vIHjk/TwfKam4pIbI/AAAAAAAAAPY/ug-2-5IT7Rw/s320/IMG_20111225_232302.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/-S3kIdTPdr3Q/TwfKSRHJIDI/AAAAAAAAAPQ/YEaT7eJQleA/s1600/IMG_20111225_232302.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;I also tried accessing Samba and uPnP shared folders, which works. Take note that your shared folder must not be protected with a password. In Windows 7, Simple File Sharing has to be turned on, otherwise Windows will require the system password to access the shared folder. Unfortunately, NAS did not work in all my attempts. After installing the hard drive and pressing the NAS button on the remote control, the media player appeared to be in NAS mode but the shared folder is not accessible. Until this day, I do not know what the problem was.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Verdict&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Despite some problems setting up and the fact that NAS does not work, I would still say that the HMC-35HD is worth considering, especially if you can get it second-hand. To be honest, I never expected a Chinese-made device to deliver all its promised features and therefore mainly use it as a media player. The only two things that irritated me were that most MKV files are not supported and that sometimes playback would stop half way and go back to the file list while showing "UNSUPPORT" on the screen. For this reason, I upgraded and the Asus HDP-R3 has served me well so far.&lt;br /&gt;&lt;br /&gt;The user guide for the player (in Chinese only) can be downloaded &lt;a href="http://dl.dropbox.com/u/5881137/%E8%BF%AA%E7%BE%8E%E8%A7%86%20HMC-35HD%20%E5%BF%AB%E9%80%9F%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97.doc"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-5191940223681632938?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/5191940223681632938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/11/hmc-35hd-media-player-with-nas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5191940223681632938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5191940223681632938'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/11/hmc-35hd-media-player-with-nas.html' title='HMC-35HD Media Player with NAS Server Review'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-BcX8xBx5Hvo/TwfQUs1dCGI/AAAAAAAAAPg/jmpqgdn0vrw/s72-c/mele_hmc-35hd_tartozekok.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-5587258426027306300</id><published>2011-10-14T07:33:00.000-07:00</published><updated>2011-10-26T08:51:27.321-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>Dreambook W7: Cheap and apparently features-packed but unusable Chinese-made Android tablet</title><content type='html'>Well, if you're intending to buy this tablet, the title says it all. This article serves as a reminder to watch out for things that are too good to be true. Save your money and buy a proper tablet!&lt;br /&gt;&lt;br /&gt;It all looks promising at first - the Dreambook W7 is an Android 2.2 tablet (upgradeable to 2.3) running on a 1GHz Freescale IMX515 processor, 512MB RAM and 8GB internal storage. The device also has GPS, Bluetooth, SIM card slot (supports 3G, call and SMS), SD card slot supporting up to 16GB, mini-HDMI output and USB host capabilities, all for 350 SGD. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-sUFfSmAZUhQ/Tpg75CWyNWI/AAAAAAAAAN0/8ykrwcy_Nac/s1600/synrgic-dreambook-w7-chinistore-00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="221" src="http://2.bp.blogspot.com/-sUFfSmAZUhQ/Tpg75CWyNWI/AAAAAAAAAN0/8ykrwcy_Nac/s400/synrgic-dreambook-w7-chinistore-00.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Upon first look, with the HOME button, the device looks like a giant iPhone with a lot of extra connection ports. It is also thicker and heavier than other tablets. No problem yet considering the price, I guess.&lt;br /&gt;&lt;br /&gt;However, after some initial testing, problems soon emerged. The following list summarizes my findings:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The touchscreen&lt;b&gt; &lt;/b&gt;is very sensitive, to the point that makes the device unusable. Scrolling through a list or a web page would just randomly clicks on items or links on the screen. I install this &lt;a href="http://android.modaco.com/topic/322054-touchscreen-sensitivity-app-testing-required/"&gt;app&lt;/a&gt;, which reduces the sensitivity and seems to help a little, but it's still not good enough for web browsing.&lt;/li&gt;&lt;li&gt;Sometimes it is very hard to get passed the Android lock screen - the green button cannot move long enough to unlock the phone. I disable the lock by using the &lt;a href="https://market.android.com/details?id=org.jraf.android.nolock&amp;amp;hl=en"&gt;NoLock&lt;/a&gt; app.&lt;/li&gt;&lt;li&gt;In landscape mode, text box occupies entire screen area once the keypad is shown. This is a classic Android bug, reported &lt;a href="http://code.google.com/p/android/issues/detail?id=11185"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Even in landscape mode, the launcher home screen or program list still shows in portrait. But other screens appear correctly in landscape. Using a custom launcher such as ADW Launcher correctly changes the orientation, but the icon spacing is wrong.&lt;/li&gt;&lt;li&gt;No matter which firmware I tried, the FM radio doesn't work and just  produces white noise, even when the headset is connected. (The headset is known to be used as an antenna in many phone radios)&lt;/li&gt;&lt;li&gt;GPS works intermittently, depending on which firmware I am using. On some firmwares, GPS seems to be working but reports fake location of 0N 0W. Where GPS is working, it reports 2X the speed so it can't be used when driving. Location determination using cell ID and wifi network doesn't work. Neither does the compass work.&lt;/li&gt;&lt;li&gt;Despite numerous sites saying that this device has USB host, I could not get it to work. Basically, it doesn't even supply power to the connected USB device such as a mouse or a thumb drive&lt;/li&gt;&lt;li&gt;Even with the SD card unmounted, hot-swapping the SD card may hang the device. Changing the SIM card while the device is on will definitely lock it. To reset the device, press and hold the reset button, which is also the power indicator light, on the bottom left side.&lt;/li&gt;&lt;li&gt;The device does not seem to support "reboot". The default "reboot" option in Android and all other tools will simply turn the device off.&lt;/li&gt;&lt;li&gt;Many firmwares will have problem receiving incoming SMS (the message is not shown and discarded) while sending outgoing messages is fine.&lt;/li&gt;&lt;li&gt;Finally, things got worse with the Android 2.3 Beta firmware. Wifi will not work until wifi sleep policy is turned off, and 3G works intermittently.&lt;/li&gt;&lt;/ol&gt;With the long list of problems, all with common use cases, I guess &lt;a href="http://www.synrgic.com/"&gt;Synrgic&lt;/a&gt;, the manufacturer, does not have any kind of quality control over their products. There is also no good official tutorial to flash firmware for this device and all firmwares I could find are uploaded using various file sharing websites, not on the company official site like other devices.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Flashing the firmware&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Flashing firmware is a pain on this device.  First, you will need to find the correct ROM for your hardware version (either HD104 or HD105). Then, get the device into recovery mode: press and hold the HOME and BACK key and press the POWER key for a few seconds. Copying the bootimg.tgz and update.zip to /sdcard and use the recovery menu to start updating. Notice that on some firmwares, the internal memory is mounted as /sdcard and&amp;nbsp; the SD card itself is mounted as /sdcard/extsd so you may need to copy the images to the device main memory.&lt;br /&gt;&lt;br /&gt;Sometimes it just seems impossible to start in recovery mode despite pressing the correct key combination - the device will just perform a normal boot. You can get over this by using an app to reboot into recovery mode (the device needs to be rooted via z4root). The Dreambook will then turn off, and when started again, it will show the recovery loader.&lt;br /&gt;&lt;br /&gt;Another way to flash is via MFGTool, a utility by Freescale, manufacturer of the device's processor. This should be used only at a last resort since incorrect usage may brick the device and turn it into a paperweight. The steps are as follows:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Used Windows XP. Windows 7 may require applications to have admin privilege and different drivers which will just interfere with the flashing process.&lt;/li&gt;&lt;li&gt;Download the MFG ROM package of the device. Some ROMs can be found &lt;a href="http://www.synrgic.com:81/index.php?option=com_content&amp;amp;view=article&amp;amp;id=96&amp;amp;Itemid=196&amp;amp;lang=en"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Start the device in recovery loader, then choose "Wipe for MFG". Connect it to the USB port of your computer, then press and hold the RESET button for a moment. &lt;/li&gt;&lt;li&gt;The PC will then find a new FreeScale BulkIO device which require driver. Install the device using the driver supplied in the MFG ROM package. If the device is identified as Mass Storage, disconnect everything, reboot the device and try again.&lt;/li&gt;&lt;li&gt;Run MFGTool.exe. Click “Options” menu at upper-right corner, and further click configuration item, you can find below pop-up window. Click “USB Ports” tab, you can view all the USB port. Choose the one to which your device is connected and click “OK” to close the window.&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-2CD7ykjqfaE/TphPW26wCNI/AAAAAAAAAOE/Cokr7f3VPfk/s1600/mfgtoolusb.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="307" src="http://4.bp.blogspot.com/-2CD7ykjqfaE/TphPW26wCNI/AAAAAAAAAOE/Cokr7f3VPfk/s400/mfgtoolusb.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6. Click the green Start button and the flashing process should start. At the end of the process, the tool may say "Connect device" or report an "Updater Error". This is normal and the device should boot up to Android.&lt;br /&gt;&lt;ol&gt;&lt;/ol&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-uvoQGGXztvw/TphIaDJEDhI/AAAAAAAAAN8/aKuXEP3IgCk/s1600/mfgtool.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="214" src="http://3.bp.blogspot.com/-uvoQGGXztvw/TphIaDJEDhI/AAAAAAAAAN8/aKuXEP3IgCk/s640/mfgtool.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ol&gt;&lt;/ol&gt;The latest firmware available is V25 (27 May 2011). Unfortunately it seems that Synrgic has stopped supporting the Dreambook W7 and decided to move on with their other products and no future firmwares will be available.&lt;br /&gt;&lt;br /&gt;My conclusion is that the Dreambook W7, with a lot of out-of-the-box issues, can never be used as a productivity device, only  perhaps as an expensive tool for advanced users to learn more about Android by trying different  firmwares and applications in an attempt to solve these issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-5587258426027306300?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/5587258426027306300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/10/dreambook-w7-features-packed-but.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5587258426027306300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5587258426027306300'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/10/dreambook-w7-features-packed-but.html' title='Dreambook W7: Cheap and apparently features-packed but unusable Chinese-made Android tablet'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-sUFfSmAZUhQ/Tpg75CWyNWI/AAAAAAAAAN0/8ykrwcy_Nac/s72-c/synrgic-dreambook-w7-chinistore-00.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-8564095931134147233</id><published>2011-10-09T02:04:00.000-07:00</published><updated>2011-10-11T01:48:52.308-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reverse-engineer'/><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Rebuilding the Olevia LT19W 19" LCD TV Remote Control Unit</title><content type='html'>I have here in my room an Olevia &lt;a href="http://www.shopcite.com/ProductDetails.jsp?lang=eng&amp;amp;pid=PD10008771&amp;amp;usid=10030312554322&amp;amp;tabNo=2"&gt;LT19W &lt;/a&gt;19" LCD television that has no remote control unit. The buttons for this TV are located on the top panel so it would be a hassle to change volume or channel while watching. I decided to buy the RM-68 universal remote control from eBay hoping that I will be able to configure it to be used for my TV.&lt;br /&gt;&lt;br /&gt;Unfortunately, I was wrong. None of the suggested codes I found online could make the remote control work with my TV. I also spent half a day trying most of the codes listed in the instruction &lt;a href="http://dl.dropbox.com/u/5881137/RM68%20manual.zip"&gt;manual&lt;/a&gt;, but none works. My last try is to use the auto-search mode, which automatically tries all supported codes to see which one works:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-X8tn62RSb9k/TpFweX3_mSI/AAAAAAAAANk/O3FrVtlatTc/s1600/auto+search.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-X8tn62RSb9k/TpFweX3_mSI/AAAAAAAAANk/O3FrVtlatTc/s1600/auto+search.png" /&gt;&lt;/a&gt;&lt;/div&gt;Finally after 20 minutes of pressing the VOLUME+ key, I got my TV not to show the volume control as expected, but to display "Normal" at the bottom of the screen. What should be the volume control key turned out to be the key to change the "Picture Mode" of the TV. The TV also recognized some other keys on the RM68 but the mapping was wrong. For example, pressing channel 2 on the RM68 would turn off the television! In other words, although the TV responds to some keys on the RM68, it can't be used.&lt;br /&gt;&lt;br /&gt;I then had an idea. Since I had quite a few keys on the RM68 working, I may be able decode the remote control protocol for this TV. build a PIC-based remote control to simulate other keys and map them to a learning remote controller, which will be used in the long run. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Decoding the protocol&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;My initial research shows that most TV remote control use &lt;a href="http://en.wikipedia.org/wiki/Consumer_IR"&gt;consumer IR&lt;/a&gt; which transmits using an infrared wavelength of 930 nm, 870 nm or 950 nm at carrier frequency between 33 to 40 kHz or 50 to 60 kHz, with 38kHz being the most common. To decode the protocol, I picked up a TFMS 5400 IR receiver from my junkbox, which is optimal for 950nm infrared @ 40kHz carrier frequency. Although the RM68 transmits at 38kHz, the "Relative Frequency" graph on page 3 of the &lt;a href="http://dl.dropbox.com/u/5881137/TFMS%205XXX%20IR%20Receiver.pdf"&gt;datasheet &lt;/a&gt;shows that the TFMS 5400 would still detect 38kHz signal, just at 95% of the sensitivity. Following the datasheet, I built the receiver and fed the output to channel 1 of my &lt;a href="http://www.rigolna.com/products/digital-oscilloscopes/ds1000e/ds1052e/"&gt;Rigol DS1052E&lt;/a&gt; oscilloscope:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Y15Vuur7VMw/TpFYM3pozqI/AAAAAAAAANE/7RIzdICsKF0/s1600/TFMS+circuit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="204" src="http://2.bp.blogspot.com/-dJrYkzYOBMM/TpFxw4aRIrI/AAAAAAAAANo/uVP9n0j_SR4/s400/TFMS+circuit.png" width="400" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;By pointing the remote controller at the receiver and pressing a few keys while observing the oscilloscope display, the protocol soon became clear. Each key will transmit a data stream, consisting of an ID byte identifying the TV and a data byte identifying the key, in the following format:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;[header] [ID byte] [~ID byte] [data byte] [~data byte]&lt;/b&gt;&lt;br /&gt;where &lt;b&gt;~&lt;/b&gt; represents bit-wise NOT operation&lt;br /&gt;&lt;br /&gt;The output of the receiver is active low and will remain high if there's no signal received. Each data stream starts with a header consisting of a low pulse for 9ms followed by high pulse for around 4.3ms. The ID byte (which is 8 for the Olevia TV) and its complement (e.g. bit-wise not) is sent following the header. After the ID byte is the byte for the key pressed, and also its complement. Binary 0 is represented by a pulse for 0.5ms and binary 1 by a pulse for 1.6ms. There is a delay of 0.6ms between every bit. Bytes are sent in little-endian format, with the least significant bit being sent first. Depending on the key pressed, the data stream may last anywhere between 50 and 90ms. &lt;br /&gt;&lt;br /&gt;For example, the following data stream represents the POWER key, whose data byte is 0b00000010 (2 in decimal)&lt;br /&gt;&lt;br /&gt;[9ms low] [4.3ms high] 00010000 11101111&amp;nbsp;&amp;nbsp; 01000000 10111111&lt;br /&gt;&lt;br /&gt;The following screenshot from the Rigol oscilloscope shows the header and the ID byte:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_2Bv6KzCzCk/TpFayuVDrFI/AAAAAAAAANI/n3gD_sCOMTM/s1600/signal_received.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-_2Bv6KzCzCk/TpFayuVDrFI/AAAAAAAAANI/n3gD_sCOMTM/s1600/signal_received.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Building the transmitter&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To be able to simulate the rest of the keys, I used a PIC16F628 and a &lt;a href="http://dl.dropbox.com/u/5881137/TSAL%207400%20IR%20LED.pdf"&gt;TSAL 7400&lt;/a&gt; IR LED, with the information available &lt;a href="http://www.winpicprog.co.uk/pic_tutorial_ir_board.htm"&gt;here &lt;/a&gt;to build the transmitter circuit:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-zRANjjDRi9E/TpFzpe_DyFI/AAAAAAAAANs/SzSUdTBPX5g/s1600/board5.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-zRANjjDRi9E/TpFzpe_DyFI/AAAAAAAAANs/SzSUdTBPX5g/s1600/board5.gif" /&gt;&lt;/a&gt;&lt;/div&gt;For the receiver to be able to pick up the transmitter signal, the transmitter needs to modulate the signal at around 38-40kHz. Since the receiver receives in &lt;a href="http://en.wikipedia.org/wiki/Logic_level#Active_state"&gt;active low&lt;/a&gt;, this means pulsing the output at 38-40kHz for around 0.5ms for a binary 0, and staying low for 1.6ms for binary 1.&lt;br /&gt;&lt;br /&gt;But how do I actually pulse the output at the required frequency? Luckily the receiver is quite tolerant and any transmitted frequency within the the expected range will work. I used the assembly source code from &lt;a href="http://www.winpicprog.co.uk/pic_tutorial5.htm"&gt;here &lt;/a&gt;and modified it to suit my needs. &lt;a href="http://en.wikipedia.org/wiki/NOP"&gt;NOP instructions&lt;/a&gt; are used to generate the required pulse frequency, as seen in the following code snippet:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;IR_pulse&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; MOVWF&amp;nbsp;&amp;nbsp;&amp;nbsp; count&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ;&amp;nbsp; Pulses the IR led at 38KHz&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;irloop&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; BSF&amp;nbsp;&amp;nbsp;&amp;nbsp; IR_PORT,&amp;nbsp;&amp;nbsp;&amp;nbsp; IR_Out &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; BCF&amp;nbsp;&amp;nbsp;&amp;nbsp; IR_PORT,&amp;nbsp;&amp;nbsp;&amp;nbsp; IR_Out&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; NOP&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; DECFSZ&amp;nbsp;&amp;nbsp;&amp;nbsp; count,F&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; GOTO &amp;nbsp;&amp;nbsp;&amp;nbsp; irloop&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; RETLW&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you're not an assembly guru who knows exactly how many CPU cycles each instruction will take and is able to calculate the output frequency easily, you'll need an oscilloscope and lots of trial and error to get the desired output. This is when the Rigol DS1052E limited memory becomes a hassle. You will need to set the the TIME/DIV setting to a reasonable value that allows you to view the entire transmitted stream, but not at the expenses of losing too many sample points. Even at 1 mega samples of memory in long memory mode, signal &lt;a href="http://en.wikipedia.org/wiki/Aliasing"&gt;aliasing&lt;/a&gt; may occur if the TIME/DIV is set so high that the oscilloscope can't capture enough samples. For example, the following puzzled me for a few minutes when I attempted to transmit 1 bit of data:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-RQ5ax9U-vw0/TpFhG8bdiQI/AAAAAAAAANY/werKog90RbI/s1600/1bits_out_aliasing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-J2R_r5mvQdo/TpF1EJl4G1I/AAAAAAAAANw/8xd9nMSZyec/s1600/1bits_out_aliasing.png" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;br /&gt;The code pulses the output at 38kHz, but from the oscilloscope screen, it seems much less. However there was nothing wrong with the code, all that was needed is to lower the TIME/DIV settings and capture the output again:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-oVyRlM-Dzrk/TpFhhLl7plI/AAAAAAAAANc/oQq6RNJAosg/s1600/1bit_out_proper.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-oVyRlM-Dzrk/TpFhhLl7plI/AAAAAAAAANc/oQq6RNJAosg/s1600/1bit_out_proper.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This is the transmitted signal:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-CblBY9kwbDc/TpFcPfSRc8I/AAAAAAAAANM/RH1QUWCW3_g/s1600/PIC_out_header_and_first8bit.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-CblBY9kwbDc/TpFcPfSRc8I/AAAAAAAAANM/RH1QUWCW3_g/s1600/PIC_out_header_and_first8bit.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Applying "invert" on the input channel on the Rigol oscilloscope, I got the transmitted signal to resemble the received signal:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-XMKCAAvtgV4/TpFclrocwWI/AAAAAAAAANQ/0Vq1MjIMY94/s1600/PIC_OUT_inverted.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-XMKCAAvtgV4/TpFclrocwWI/AAAAAAAAANQ/0Vq1MjIMY94/s1600/PIC_OUT_inverted.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The PIC-based transmitter now works properly and the TV responds to it as how it did for the universal remote controller.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Simulating other keys&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;By varying the data byte, I am able to simulate many other keys. The full list of keys and their data bytes can be found in the following table:&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: medium none;"&gt;&lt;tbody&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Key&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Byte&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;10&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;9&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;8&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;18&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;5&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;17&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;6&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;16&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;7&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;14&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;8&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;13&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;9&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;12&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;22&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;Previous Channel&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;19&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;-/--&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;21&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;POWER&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;2&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;MUTE&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;MENU&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;Current Channel Display&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;24&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;Sound Mode&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;25&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;Picture Mode&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;26&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;Next Channel&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;29&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 126.65pt;" valign="top" width="169"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;Enter&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 34.9pt;" valign="top" width="47"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;28&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;With this, I am able to get my learning remote controller to learn the above keys and use it as the main remote controller for my TV.&lt;br /&gt;&lt;br /&gt;The assembly source code can be downloaded &lt;a href="http://dl.dropbox.com/u/5881137/OleviaTVRM.asm"&gt;here&lt;/a&gt;. It will repeatedly transmit the data stream for the "Channel 1" button. Unfortunately I could not find the data bytes for many other important keys, such as the volume control and TV/Video switch button. Perhaps these keys have data bytes outside the range I tried, or require a different protocol. I hope somebody with more time and expertise at PIC assembly programming can use my code and find out how to simulate these keys...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Reference:&lt;/b&gt;&lt;br /&gt;1. &lt;a href="http://www.moty22.co.uk/ir.php"&gt;Infrared TV Remote Decoder&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://www.winpicprog.co.uk/pic_tutorial5.htm"&gt;PIC Tutorial Five - Infrared Communication&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-8564095931134147233?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/8564095931134147233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/10/rebuilding-olevia-lt19w-tv-remote.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/8564095931134147233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/8564095931134147233'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/10/rebuilding-olevia-lt19w-tv-remote.html' title='Rebuilding the Olevia LT19W 19&quot; LCD TV Remote Control Unit'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-X8tn62RSb9k/TpFweX3_mSI/AAAAAAAAANk/O3FrVtlatTc/s72-c/auto+search.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-7903002382807251472</id><published>2011-09-29T00:00:00.000-07:00</published><updated>2011-10-14T10:13:17.535-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Compaq Contura 3/25C 80386 Laptop</title><content type='html'>I recently picked up a free Compaq Contura 3/25c, a very old IBM-compatible laptop computer from the early 1990s, with a 25MHz 80386 processor, 4MB onboard memory and 3.5in 1.44MB floppy drive. The original 120MB hard drive has been removed by the previous owner. The laptop is also in very bad shape, with dust all over the place and the LCD panel removed:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-3VCTYsC-IUs/TpEx-7XkXMI/AAAAAAAAAMI/qyWsmDO63pA/s1600/IMG_20110920_200255.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-3VCTYsC-IUs/TpEx-7XkXMI/AAAAAAAAAMI/qyWsmDO63pA/s1600/IMG_20110920_200255.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The laptop must have looked like this when new with the 8.4inch black and white LCD:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-05HY0D1VWzE/TpEyUyll4DI/AAAAAAAAAMM/X7n8qhNV_Rg/s1600/contura_3_25_mit_zubehoer.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-05HY0D1VWzE/TpEyUyll4DI/AAAAAAAAAMM/X7n8qhNV_Rg/s320/contura_3_25_mit_zubehoer.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I was trying to make it boot up by connecting an external monitor to the VGA port when I noticed that the VGA port is actually keyed via pin #9. No modern VGA cable would fit into this port until you break pin #9 on the cable or punch a hole on pin #9 of the port. Since there is actually no need to key a VGA DB9 connector because the shape of the port would prevent you from inserting it upside down anyway, later &lt;a href="http://en.wikipedia.org/wiki/VGA_connector"&gt;VGA ports&lt;/a&gt; used pin #9 as an optional +5V DC source. &lt;br /&gt;&lt;br /&gt;The unit boots up with a "RTC Lost Power" error message (see &lt;a href="http://dl.dropbox.com/u/5881137/CompaqTechRef.rtf"&gt;this&lt;/a&gt; for a full list of Compaq POST error messages). This is quite common with old laptop when the CMOS battery finally dies after a few years. So I opened it up in order to replace the battery:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-JwbkFeXhp9E/TpE1mamwokI/AAAAAAAAAMU/3yN4oFx_K4M/s1600/IMG_20110906_214332.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-JwbkFeXhp9E/TpE1mamwokI/AAAAAAAAAMU/3yN4oFx_K4M/s320/IMG_20110906_214332.jpg" width="320" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/-fAUpdYf0uR8/TpE1l_XO7mI/AAAAAAAAAMQ/GDRh3cHrfBE/s1600/IMG_20110906_214259.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-fAUpdYf0uR8/TpE1l_XO7mI/AAAAAAAAAMQ/GDRh3cHrfBE/s320/IMG_20110906_214259.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The laptop is using a CR2430 lithium coin battery placed in a socket to facilitate replacement. There is even a warning, in various languages, telling you about danger of explosion if the battery is incorrectly replaced. This surprised me, since modern laptops would probably just have the battery soldered onboard. Some may feature a motherboard socket for the battery connector, but the actual connections to the battery are permanently soldered, which means some wire-cutting and soldering needs to be done if the battery ever needs to be replaced. This is a CMOS battery from a newer laptop:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-faEhw3WAgyo/TpE3VK8fx2I/AAAAAAAAAMY/-SXDlXuSc-o/s1600/IMG_20111004_213432.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-faEhw3WAgyo/TpE3VK8fx2I/AAAAAAAAAMY/-SXDlXuSc-o/s320/IMG_20111004_213432.jpg" width="296" /&gt;&lt;/a&gt;&lt;/div&gt;I quickly ordered a pack of 5 CR2430 cells for a dirt cheap price from eBay. Notice the funny English on the packaging. Whoever typed this probably had no ideas what it means:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-WFvcAym-Vbc/TpE3uKsPW0I/AAAAAAAAAMc/UiS09ywthwo/s1600/IMG_20110906_214843.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="316" src="http://2.bp.blogspot.com/-WFvcAym-Vbc/TpE3uKsPW0I/AAAAAAAAAMc/UiS09ywthwo/s320/IMG_20110906_214843.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;With the CMOS battery replaced and a PS2 keyboard connected, I started the machine. Although many old laptops and PCs do not have an onboard BIOS and require the use of startup disks containing the BIOS utilities to change system settings, this machine has one, available in several languages, accessible via F10 at startup:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Y2cji3yT7Jc/TpE4FuNn4fI/AAAAAAAAAMg/BuctUOXziIg/s1600/IMG_20110906_222902.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="187" src="http://2.bp.blogspot.com/-Y2cji3yT7Jc/TpE4FuNn4fI/AAAAAAAAAMg/BuctUOXziIg/s320/IMG_20110906_222902.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;There are 2 startup disks for this laptop, formerly downloadable from Compaq website:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Disk 1: BIOS setup utility&lt;/li&gt;&lt;li&gt;Disk 2: Diagnostic utility&lt;/li&gt;&lt;/ul&gt;However, these downloads were removed when Compaq was merged with HP in 2003 and a lot of legacy support was gone. Although I eventually managed to find the disks with the help of &lt;a href="http://www.archive.org/index.php"&gt;archive.org&lt;/a&gt;, disk 1 comes with no COMMAND.COM and boots up to a DOS error "Bad or Missing Command Interpreter" error message. I fixed the error by putting MS-DOS 6.22 on it. The images for both disks as well as the original tool to create the disks (SP2054.exe) can be downloaded &lt;a href="http://dl.dropbox.com/u/5881137/Contura3_25c.zip"&gt;here&lt;/a&gt;. You will need &lt;a href="http://www.winimage.com/"&gt;WinImage &lt;/a&gt;to write the images to floppy disks.&lt;br /&gt;&lt;br /&gt;Unlike the motherboard SETUP, the SETUP utility on the disks uses graphic mode and takes a long time to start up:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-X6Dj71TJEuE/TpE69JASLDI/AAAAAAAAAMk/rvBDLIKhCQ8/s1600/IMG_20110906_223512.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-X6Dj71TJEuE/TpE69JASLDI/AAAAAAAAAMk/rvBDLIKhCQ8/s320/IMG_20110906_223512.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Since the original hard disk has been removed, my next task is to install a 2.5inch IDE hard drive before the notebook can be used for anything useful. Keeping in mind that laptops of this generation only use &lt;a href="http://en.wikipedia.org/wiki/Cylinder-head-sector"&gt;CHS addressing &lt;/a&gt;and does not support hard drive more than 512MB due to the &lt;a href="http://www.dewassoc.com/kbase/hard_drives/hard_drive_size_barriers.htm"&gt;1,024 cylinders limitation&lt;/a&gt;, I have chosen a 270MB IBM DHAA-2270 hard drive:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-9d1fLFb1kl8/TpE84EUZBqI/AAAAAAAAAMo/3sH6pCGCz7I/s1600/IMG_20110906_222504.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-9d1fLFb1kl8/TpE84EUZBqI/AAAAAAAAAMo/3sH6pCGCz7I/s320/IMG_20110906_222504.jpg" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;Still, installing the hard drive turns out to be no easy tasks as the BIOS only supports a limited number of hard drives types (which does not include my drive). There is also no support for auto detection or user-defined types:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-HZd-HSrOmIw/TpE9Wjc-l8I/AAAAAAAAAMs/nTN-qGiNlDo/s1600/IMG_20110906_222949.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-HZd-HSrOmIw/TpE9Wjc-l8I/AAAAAAAAAMs/nTN-qGiNlDo/s320/IMG_20110906_222949.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Interestingly, types 65 and 66 are empty, indicating that they are custom types and can be configured by either re-programming the BIOS as suggested in this forum &lt;a href="http://www.vintage-computer.com/vcforum/showthread.php?27150-use-a-hard-disk-not-in-BIOS-hard-disk-type-table"&gt;discussion,&lt;/a&gt; or by writing a tool that modifies the BIOS &lt;a href="http://www.win.tue.nl/%7Eaeb/linux/hdtypes/hdtypes-1.html"&gt;hard disk type table&lt;/a&gt; stored in memory and hope that the BIOS will recognize the changes. Either way, it's a shoot in the dark as I could find no instructions on flashing this laptop's BIOS, and there is also&lt;a href="http://www.blogger.com/goog_842588910"&gt; no &lt;/a&gt;&lt;a href="http://webpages.charter.net/danrollins/techhelp/0054.HTM"&gt;documented address&lt;/a&gt; where I can hope to find the type table.&lt;br /&gt;&lt;br /&gt;However, there is an easier way by using a drive &lt;a href="http://en.wikipedia.org/wiki/Dynamic_drive_overlay"&gt;overlay&lt;/a&gt; such as &lt;a href="http://dl.dropbox.com/u/5881137/anydrive.zip"&gt;ANYDRIVE &lt;/a&gt;or EZ-Drive. The trick is to specify a hard disk type in BIOS where the number of cylinders, heads and sectors is smaller than the actual value so that the BIOS will not report an error on POST and accept the hard disk. Once then, boot from a floppy disks with ANYDRIVE to set up the disk overlay, which will overwrite BIOS &lt;a href="http://en.wikipedia.org/wiki/INT_13H"&gt;Int 13h&lt;/a&gt; (which is used by DOS to query hard drive info) and respond with the correct disk geometry values. Run FDISK to setup the hard disk and you will be able to use the full capacity.&lt;br /&gt;&lt;br /&gt;This will work with DOS and Windows 3.1 or older which relies on Int 13h to access the hard disk. Operating systems such as Linux and some disk utilities may query the hard disk directly, resulting in possible data loss with the overlay installed. In Windows 3.1, 32-bit disk access must be turned off, otherwise Windows may also query the hard disk directly, resulting in similar problems. &lt;br /&gt;&lt;br /&gt;With the overlay installed, all existing data on the disk is lost and some PCs may also fail to recognize the drive. Since I do not want to copy data and programs to the laptop using floppy disks, the only other way is to use a serial or parallel cable, with the help of &lt;a href="http://en.wikipedia.org/wiki/Norton_Commander"&gt;Norton Commander&lt;/a&gt; 5.0 Link utility.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-FMriOVmnVQM/TpFC7_ApmFI/AAAAAAAAAM4/LIfXSM0S25Q/s1600/IMG_20110910_120757.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-FMriOVmnVQM/TpFC7_ApmFI/AAAAAAAAAM4/LIfXSM0S25Q/s320/IMG_20110910_120757.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-SJ41-I7rgN8/TpFC4kArYTI/AAAAAAAAAM0/np0c-oxiPi4/s1600/IMG_20110906_222949.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;Note that you cannot simply use a male-to-male serial or parallel cable, but rather a &lt;a href="http://en.wikipedia.org/wiki/Null_modem"&gt;null modem&lt;/a&gt; or a &lt;a href="http://en.wikipedia.org/wiki/LapLink_cable"&gt;null printer (Laplink)&lt;/a&gt; cable respectively. Since these cables are extremely over priced, I decided to go for soldering a null modem cable myself using the connectors available in my junkbox, and the pinout from &lt;a href="http://dl.dropbox.com/u/5881137/NC%20LINK%20pinout.txt"&gt;here&lt;/a&gt;. With my other PCs running Norton Commander (NC) from within Windows 98 acting as Master, I am able to copy the data to this laptop (acting as Slave). At a maximum theoretical speed of 115200bps, made slower by the noise-sensitive cable disrupting the copy process resulting in several misleading errors "There is not enough room to copy..." from NC, it took half a day to copy DOS programs, games and Windows 3.1 to the laptop.&lt;br /&gt;&lt;br /&gt;However, before I could think of some useful purposes for this laptop, it dies and fails to &lt;a href="http://en.wikipedia.org/wiki/Power-on_self-test"&gt;POST &lt;/a&gt;with no beeps and no display output. On every boot, the system simply hung after attempting to seek the floppy drive. There were perhaps several symptoms that the laptop was dying, for example the fact that I needed to press the POWER button multiple times (although the button itself is fine, as checked by a multimeter) to turn the laptop on and the wrong memory count of 21885KBytes extended memory in BIOS: &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-SDSYJhXqYus/TpFF-Qk2idI/AAAAAAAAAM8/NbQyUHv1ytg/s1600/IMG_20110906_222916.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-SDSYJhXqYus/TpFF-Qk2idI/AAAAAAAAAM8/NbQyUHv1ytg/s320/IMG_20110906_222916.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Since all basic troubleshooting does not seem to help and there are no user replaceable parts inside the motherboard, I eventually removed the hard disk and ran FDISK /MBR to remove the overlay, and toss the machine. Everything has its time, I guess.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Reference:&lt;/b&gt; &lt;br /&gt;&lt;a href="http://computermuseum.wordpress.com/2011/03/24/contura-325/"&gt;Contura 3/25 Serie 2820A&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-7903002382807251472?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/7903002382807251472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/10/compaq-contura-325c-80386-laptop.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7903002382807251472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7903002382807251472'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/10/compaq-contura-325c-80386-laptop.html' title='Compaq Contura 3/25C 80386 Laptop'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-3VCTYsC-IUs/TpEx-7XkXMI/AAAAAAAAAMI/qyWsmDO63pA/s72-c/IMG_20110920_200255.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-1823487348086597192</id><published>2011-09-19T01:03:00.000-07:00</published><updated>2011-09-19T06:19:11.650-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blogger'/><title type='text'>Blogspot bug: Google+ Share button and Google Friend Connect widget</title><content type='html'>Recently I observed that the Google Friend Connect widget that shows my site's followers on the left panel sometimes cannot be displayed. Refreshing the page did not help; clearing cookies and browser cache could only make it appear momentarily - the widget would disappear again eventually.&lt;br /&gt;&lt;br /&gt;Firefox's error console (accessible via Tools&amp;gt;Error Console or Ctrl-Shift-J) and this &lt;a href="http://www.google.com/support/forum/p/blogger/thread?tid=7fbbe3cbdf71c1ed&amp;amp;hl=en"&gt;post&lt;/a&gt; provide some hint: &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-057M6LTicNI/TnbvwVX4MPI/AAAAAAAAAMA/vTZ_mrqWCsA/s1600/followers_googleplus_conflict.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-057M6LTicNI/TnbvwVX4MPI/AAAAAAAAAMA/vTZ_mrqWCsA/s1600/followers_googleplus_conflict.png" /&gt;&lt;/a&gt;&lt;/div&gt;The error messages are: &lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Error: window.googleapisv0 is undefined&lt;br /&gt;Source File: https://apis.google.com/js/plusone.js&lt;br /&gt;Line: 12&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Error: google.friendconnect.container is undefined&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The .js &lt;a href="https://apis.google.com/js/plusone.js"&gt;file&lt;/a&gt; used for Google "+1" button displayed at the end of every post is possibly conflicting with the js &lt;a href="http://www.google.com/friendconnect/script/friendconnect.js"&gt;file&lt;/a&gt; for the Followers widget. As the both script files are obfuscated, it is not worthwhile for me to spend time investigating where the problem is. I ended up disabling the Share bar after every post by opening the &lt;b&gt;Design&lt;/b&gt; tab of my blog settings, clicking &lt;b&gt;Edit&lt;/b&gt; button at the bottom of the &lt;b&gt;Blog Posts&lt;/b&gt; element, and unchecking &lt;b&gt;Show Share Buttons&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qVpmK1unJo4/Tnb0hE_RluI/AAAAAAAAAME/4RkqvQ8_B20/s1600/blog+settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-qVpmK1unJo4/Tnb0hE_RluI/AAAAAAAAAME/4RkqvQ8_B20/s1600/blog+settings.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This would disable the entire set of share buttons even though I know I only need to disable the Google+ button. As there seems to be no way to show/hide each button individually, the only way to show only specific Share buttons (for example, share via Facebook) is to modify the page template and manually add in the code for the button.&lt;br /&gt;&lt;br /&gt;Once you have manually modified the page template, always use the &lt;b&gt;Edit HTML&lt;/b&gt; tab, and not the &lt;b&gt;Page Elements &lt;/b&gt;tab to change the blog layout. Otherwise your changes may be lost and there may also be other unexpected results.&lt;br /&gt;&lt;br /&gt;This is too much trouble, so the set of Share buttons at the end of every post in my blog will be disabled until this bug is fixed...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-1823487348086597192?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/1823487348086597192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/09/blogspot-bug-google-share-button.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/1823487348086597192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/1823487348086597192'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/09/blogspot-bug-google-share-button.html' title='Blogspot bug: Google+ Share button and Google Friend Connect widget'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-057M6LTicNI/TnbvwVX4MPI/AAAAAAAAAMA/vTZ_mrqWCsA/s72-c/followers_googleplus_conflict.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6879196503420618268</id><published>2011-08-19T20:51:00.000-07:00</published><updated>2011-08-22T05:35:02.761-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='Xcode'/><title type='text'>Xcode 4 bug: Crash when using Core Data Model from Xcode 3</title><content type='html'>I recently upgraded my Xcode from version 3 to 4.0.2 (build 4A2002a) and notice that Xcode keeps on crashing whenever I right click on a core data model used in an iOS application:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Pa7rJ8PrtMk/Tk8qnt4MoBI/AAAAAAAAALM/LDydXgHFFWY/s1600/crash+right+click.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-Pa7rJ8PrtMk/Tk8qnt4MoBI/AAAAAAAAALM/LDydXgHFFWY/s1600/crash+right+click.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The error message reads:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Xcode encountered an internal logic error. Choose "Continue" to continue running Xcode in an inconsistent state.&amp;nbsp; Choose "Crash" to halt Xcode and file a bug with Crash Reporter. Choosing "Crash" will result in the loss of all unsaved data.&lt;br /&gt;&lt;br /&gt;ASSERTION FAILURE in /SourceCache/IDEKit/IDEKit-303/Framework/Classes/StructureEditingAdditions/IDEStructureEditing+Additions.m:587&lt;br /&gt;Details:&amp;nbsp; Assertion failed: [indexes lastIndex] &amp;lt;= [_targetGroup.subitems count]&lt;br /&gt;Object:&amp;nbsp;&amp;nbsp; &lt;idecontaineritemstructureeditingtarget: 0x20289fd40=""&gt;&lt;br /&gt;Method:&amp;nbsp;&amp;nbsp; -structureEditingCanGroupSubitemsAtIndexes:&lt;br /&gt;Thread:&amp;nbsp;&amp;nbsp; &lt;nsthread: 0x200020700=""&gt;{name = (null), num = 1}&lt;br /&gt;Hints:&amp;nbsp;&amp;nbsp; None&lt;br /&gt;Backtrace:&lt;br /&gt;&amp;nbsp; 0&amp;nbsp; 0x0000000100949773 -[IDEAssertionHandler handleFailureInMethod:object:fileName:lineNumber:messageFormat:arguments:] (in IDEKit)&lt;br /&gt;&amp;nbsp; 1&amp;nbsp; 0x000000010006d394 _DVTAssertionFailureHandler (in DVTFoundation)&lt;br /&gt;&amp;nbsp; 2&amp;nbsp; 0x00000001009a683e -[IDEContainerItemStructureEditingTarget structureEditingCanGroupSubitemsAtIndexes:] (in IDEKit)&lt;br /&gt;&amp;nbsp; 3&amp;nbsp; 0x000000011e9e5661 -[IDEStructureNavigator _testOrGroupSelected:useContextualMenuSelection:] (in IDEStructureNavigator)&lt;br /&gt;&amp;nbsp; 4&amp;nbsp; 0x000000011e9e2617 -[IDEStructureNavigator validateUserInterfaceItem:] (in IDEStructureNavigator)&lt;br /&gt;&amp;nbsp; 5&amp;nbsp; 0x00007fff834a538b -[NSMenu _enableItem:] (in AppKit)&lt;br /&gt;&amp;nbsp; 6&amp;nbsp; 0x00007fff834a50e8 -[NSCarbonMenuImpl _carbonUpdateStatusEvent:handlerCallRef:] (in AppKit)&lt;br /&gt;&amp;nbsp; 7&amp;nbsp; 0x00007fff8348899c NSSLMMenuEventHandler (in AppKit)&lt;br /&gt;&amp;nbsp; 8&amp;nbsp; 0x00007fff884357f7 DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) (in HIToolbox)&lt;br /&gt;&amp;nbsp; 9&amp;nbsp; 0x00007fff88434d46 SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) (in HIToolbox)&lt;br /&gt;&amp;nbsp;10&amp;nbsp; 0x00007fff88452a81 SendEventToEventTarget (in HIToolbox)&lt;br /&gt;&amp;nbsp;11&amp;nbsp; 0x00007fff88481c35 SendHICommandEvent(unsigned int, HICommand const*, unsigned int, unsigned int, unsigned char, void const*, OpaqueEventTargetRef*, OpaqueEventTargetRef*, OpaqueEventRef**) (in HIToolbox)&lt;br /&gt;&amp;nbsp;12&amp;nbsp; 0x00007fff8849510f UpdateHICommandStatusWithCachedEvent (in HIToolbox)&lt;br /&gt;&amp;nbsp;13&amp;nbsp; 0x00007fff88431725 HIApplication::EventHandler(OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*) (in HIToolbox)&lt;br /&gt;&amp;nbsp;14&amp;nbsp; 0x00007fff884357f7 DispatchEventToHandlers(EventTargetRec*, OpaqueEventRef*, HandlerCallRec*) (in HIToolbox)&lt;br /&gt;&amp;nbsp;15&amp;nbsp; 0x00007fff88434d46 SendEventToEventTargetInternal(OpaqueEventRef*, OpaqueEventTargetRef*, HandlerCallRec*) (in HIToolbox)&lt;br /&gt;&amp;nbsp;16&amp;nbsp; 0x00007fff88452a81 SendEventToEventTarget (in HIToolbox)&lt;br /&gt;&amp;nbsp;17&amp;nbsp; 0x00007fff8849476f SendMenuOpening(MenuSelectData*, MenuData*, double, unsigned int, __CFDictionary*, unsigned char, unsigned char*) (in HIToolbox)&lt;br /&gt;&amp;nbsp;18&amp;nbsp; 0x00007fff885b77ae PopUpMenuSelectCore(MenuData*, Point, double, Point, unsigned short, unsigned int, Rect const*, unsigned short, unsigned int, Rect const*, Rect const*, __CFString const*, OpaqueMenuRef**, unsigned short*) (in HIToolbox)&lt;br /&gt;&amp;nbsp;19&amp;nbsp; 0x00007fff885b7dc2 _HandlePopUpMenuSelection7 (in HIToolbox)&lt;br /&gt;&amp;nbsp;20&amp;nbsp; 0x00007fff835da99b _NSSLMPopUpCarbonMenu3 (in AppKit)&lt;br /&gt;&amp;nbsp;21&amp;nbsp; 0x00007fff835dad4b -[NSCarbonMenuImpl _popUpContextMenu:withEvent:forView:withFont:] (in AppKit)&lt;br /&gt;&amp;nbsp;22&amp;nbsp; 0x00007fff8372bb37 -[NSMenu _popUpContextMenu:withEvent:forView:withFont:] (in AppKit)&lt;br /&gt;&amp;nbsp;23&amp;nbsp; 0x00007fff836304c0 -[NSControl _rightMouseUpOrDown:] (in AppKit)&lt;br /&gt;&amp;nbsp;24&amp;nbsp; 0x00007fff834270c7 -[NSWindow sendEvent:] (in AppKit)&lt;br /&gt;&amp;nbsp;25&amp;nbsp; 0x00007fff8335bafa -[NSApplication sendEvent:] (in AppKit)&lt;br /&gt;&amp;nbsp;26&amp;nbsp; 0x000000010085b36e -[IDEApplication sendEvent:] (in IDEKit)&lt;br /&gt;&amp;nbsp;27&amp;nbsp; 0x00007fff832f26de -[NSApplication run] (in AppKit)&lt;br /&gt;&amp;nbsp;28&amp;nbsp; 0x00007fff832eb3b0 NSApplicationMain (in AppKit)&lt;br /&gt;&amp;nbsp;29&amp;nbsp; 0x0000000100000eec&lt;br /&gt;&lt;/nsthread:&gt;&lt;/idecontaineritemstructureeditingtarget:&gt;&lt;br /&gt;&lt;/pre&gt;I may click 'Continue' on the dialog box to ignore the error, but subsequently Xcode would just crash randomly and too unstable to be used. For example, clicking on the Help menu would crash Xcode, but not any other menu.&lt;br /&gt;&lt;br /&gt;The root cause, after much investigation, was the hierarchy of the &lt;b&gt;.h &lt;/b&gt;and &lt;b&gt;.m &lt;/b&gt;files for the core data class objects. In my original project from Xcode 3, the &lt;b&gt;.h &lt;/b&gt;and &lt;b&gt;.m&lt;/b&gt; files stayed under the &lt;b&gt;.xcdatamodeld &lt;/b&gt;file in the project tree:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-G15ARnorL7Y/Tk8ryV7VU3I/AAAAAAAAALQ/_4YiH5kJDUY/s1600/original.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-G15ARnorL7Y/Tk8ryV7VU3I/AAAAAAAAALQ/_4YiH5kJDUY/s1600/original.png" /&gt;&lt;/a&gt;&lt;/div&gt;This was the default behavior on Xcode 3. However, Xcode 4 does not allow you to place these files under the .xcdatamodeld file, which is perhaps why it crashed since the case was never handled. I removed all the .h and .m files, regenerated them and put them under the CoreData group, and Xcode stopped crashing (for now):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-0fkp9erUHb8/Tk8sayrC6OI/AAAAAAAAALU/s4POilyI4a4/s1600/new.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-0fkp9erUHb8/Tk8sayrC6OI/AAAAAAAAALU/s4POilyI4a4/s1600/new.png" /&gt;&lt;/a&gt;&lt;/div&gt;I thought that was it, but unfortunately the problem did not stop there. Xcode again crashed when I attempted to commit the project to SVN:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-yDq69Hqodkg/Tk8s6bp47mI/AAAAAAAAALY/XhVZ0IJQGz4/s1600/crash+svn+commit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-yDq69Hqodkg/Tk8s6bp47mI/AAAAAAAAALY/XhVZ0IJQGz4/s1600/crash+svn+commit.png" /&gt;&lt;/a&gt;&lt;/div&gt;The reason for the crash was &lt;b&gt;'editorDocument should be an instance inheriting from IDE-QuickLookdocument, but...'&lt;/b&gt;&lt;idesourcecodedocument:...'&gt; Perhaps only Apple knows what this really means... Nothing really helped, including restarting Xcode, closing all open source code files or cleaning/rebuilding the project. In the end, I committed to SVN from command line, checked out a fresh copy of the project and Xcode no longer crashed when committing!&lt;/idesourcecodedocument:...'&gt;&lt;br /&gt;&lt;br /&gt;Finally, I am somewhat disappointed at Xcode 4.0.2. The UI changed significantly and some of the important behavior also changed, perhaps without any documentation at all! For example, for each core data relationship, the &lt;b&gt;Edit&amp;gt;Create NSManagedObject subclass...&lt;/b&gt; creates the methods to add/delete objects to the relationship in the .m file, but forgets to to put them in the header file. This results in plenty of compilation warnings if your code is from Xcode 3 and the core data class files are regenerated using Xcode 4. I have to resort to manually modifying the header files to add the correct method signatures...&lt;br /&gt;&lt;br /&gt;I hope these issues will soon be fixed in the next release of Xcode. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6879196503420618268?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6879196503420618268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/08/xcode-4-bug-crash-when-using-core-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6879196503420618268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6879196503420618268'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/08/xcode-4-bug-crash-when-using-core-data.html' title='Xcode 4 bug: Crash when using Core Data Model from Xcode 3'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-Pa7rJ8PrtMk/Tk8qnt4MoBI/AAAAAAAAALM/LDydXgHFFWY/s72-c/crash+right+click.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-5966488151804679632</id><published>2011-08-11T23:49:00.000-07:00</published><updated>2011-08-16T02:46:07.651-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Tips'/><title type='text'>HTC HD2 Android: Working with ext2 images under Windows</title><content type='html'>My &lt;a href="http://www.htc.com/europe/product/hd2/overview.html"&gt;HTC HD2&lt;/a&gt; running on Android from SD card had been working well for some time until it could not boot to Android one day (booting to Windows Mobile was still fine). Obviously I could redownload the same Android build, but this would mean loss of text messages, applications, call history and any other data not backed up or synchronized with Google server. In an attempt to salvage these data, I looked at the Android folder on the SD card and notice the following files:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;data.img:&lt;/b&gt; contains user data such as text messages, applications, etc.&lt;br /&gt;&lt;b&gt;system.ext2 &lt;/b&gt;and &lt;b&gt;rootfs.img:&lt;/b&gt; Android system files&lt;br /&gt;&lt;br /&gt;Although most guides suggest using a Linux live CD such as Ubuntu and use the &lt;b&gt;mount &lt;/b&gt;command to mount them as drives, which actually works, I wanted to do the same in Windows. My first try is to use &lt;a href="http://www.daemon-tools.cc/eng/downloads"&gt;Daemon Tools&lt;/a&gt;. This obviously has no chance of success, as the tool is meant to mount CD/DVD images, and not disk images, not to mention the Ext2 filesystem used by Android. I then tried various Windows tools to open/mount Linux images, and summarized the results in the following table. Take note that the image may be easily damaged if mounted by a tool not supporting it, or if not unmounted properly. If you want to try this, remember to back up first!&lt;br /&gt;&lt;br /&gt;&lt;m:smallfrac m:val="off"&gt;    &lt;m:dispdef&gt;    &lt;m:lmargin m:val="0"&gt;    &lt;m:rmargin m:val="0"&gt;    &lt;m:defjc m:val="centerGroup"&gt;    &lt;m:wrapindent m:val="1440"&gt;    &lt;m:intlim m:val="subSup"&gt;    &lt;m:narylim m:val="undOvr"&gt;   &lt;/m:narylim&gt;&lt;/m:intlim&gt; &lt;/m:wrapindent&gt;  &lt;/m:defjc&gt;&lt;/m:rmargin&gt;&lt;/m:lmargin&gt;&lt;/m:dispdef&gt;&lt;/m:smallfrac&gt;&lt;br /&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: medium none; width: 378px;"&gt;&lt;tbody&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 90.45pt;" valign="top" width="121"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: black black black -moz-use-text-color; border-style: solid solid solid none; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 57.7pt;" valign="top" width="77"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;data.img&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: black black black -moz-use-text-color; border-style: solid solid solid none; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 64.5pt;" valign="top" width="86"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;rootfs.img&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: black black black -moz-use-text-color; border-style: solid solid solid none; border-width: 1pt 1pt 1pt medium; padding: 0cm 5.4pt; width: 70.85pt;" valign="top" width="94"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;system.ext2&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border-color: -moz-use-text-color black black; border-style: none solid solid; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 90.45pt;" valign="top" width="121"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;a href="http://sourceforge.net/projects/ext2read/files/Ext2Read%20ver%202.0/ext2explore%202.0%20beta/"&gt;Ext2Explore&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 57.7pt;" valign="top" width="77"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 64.5pt;" valign="top" width="86"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 70.85pt;" valign="top" width="94"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border-color: -moz-use-text-color black black; border-style: none solid solid; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 90.45pt;" valign="top" width="121"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;a href="http://www.chrysocome.net/explore2fs"&gt;Explore2fs&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 57.7pt;" valign="top" width="77"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;X&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 64.5pt;" valign="top" width="86"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 70.85pt;" valign="top" width="94"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border-color: -moz-use-text-color black black; border-style: none solid solid; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 90.45pt;" valign="top" width="121"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;a href="http://arainia.com/software/gizmo/"&gt;GizMo Tools&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 57.7pt;" valign="top" width="77"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;X&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 64.5pt;" valign="top" width="86"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #00b050;"&gt;RW&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 70.85pt;" valign="top" width="94"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #00b050;"&gt;RW&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border-color: -moz-use-text-color black black; border-style: none solid solid; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 90.45pt;" valign="top" width="121"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;a href="http://www.ltr-data.se/opencode.html/#ImDisk"&gt;IMDisk Virtual Disk driver&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 57.7pt;" valign="top" width="77"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;X&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 64.5pt;" valign="top" width="86"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #00b050;"&gt;RW&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 70.85pt;" valign="top" width="94"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #00b050;"&gt;RW&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border-color: -moz-use-text-color black black; border-style: none solid solid; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 90.45pt;" valign="top" width="121"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;a href="http://www.diskinternals.com/linux-reader/"&gt;DiskInternal Linux Reader&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 57.7pt;" valign="top" width="77"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 64.5pt;" valign="top" width="86"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;X&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 70.85pt;" valign="top" width="94"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;X&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border-color: -moz-use-text-color black black; border-style: none solid solid; border-width: medium 1pt 1pt; padding: 0cm 5.4pt; width: 90.45pt;" valign="top" width="121"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;a href="http://www.winimage.com/"&gt;WinImage&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 57.7pt;" valign="top" width="77"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;X&lt;/span&gt;&lt;span style="color: #c00000;"&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 64.5pt;" valign="top" width="86"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 70.85pt;" valign="top" width="94"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0.0001pt;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;Legend&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;X&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;=failed &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #1f497d;"&gt;R&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;=read-only access&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;&lt;span style="color: #00b050;"&gt;RW&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;=read/write access&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You may need the &lt;a href="http://www.fs-driver.org/"&gt;Ext2 driver&lt;/a&gt; for Windows for some of the tools to work. Also read &lt;a href="http://deltafalcon.com/2010/04/mounting-an-android-emulator-sd-card-image-in-windows/"&gt;this&lt;/a&gt; tutorial on using IMDisk.&lt;br /&gt;&lt;br /&gt;Looking at the table, Ext2Explore does the best by supporting all 3 images, albeit with read-only access. GizMo and ImDisk support&amp;nbsp; read/write access for rootfs.img and system.ext2 (with IMDisk being more stable), but not for data.img, where most of the user data stays. DiskInternal Linux Reader supports data.img in read-only mode, but not the other two images.&lt;br /&gt;&lt;br /&gt;So what is so special about data.img? &lt;a href="http://www.osfight.de/en/2011/07/extrahieren-einbinden-und-manipulieren-von-nandroid-images/"&gt;Some websites&lt;/a&gt; say it is using &lt;a href="http://en.wikipedia.org/wiki/YAFFS"&gt;YAFFS2&lt;/a&gt; filesystem, which only applies for phones with Android on ROM. Since my Android is on SD card, I believe data.img still uses ext2, perhaps with some special format causing most Windows tools to fail mounting it. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extending system.ext2&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;My next challenge is to use Windows to extend my system.ext2 as I want to add some fonts and background images and my system.ext2 does not have enough space. This time, despite finding no Windows tools that provide read/write access to data.img, I find a set of &lt;a href="http://forum.xda-developers.com/showthread.php?t=824154"&gt;tools&lt;/a&gt; from xda-developers that does the job. The author compiled the source code of dd, dumpe2fs, e2fsck, mke2fs and resize2fs to run under Windows and built a user interface for it using &lt;a href="http://equi4.com/tclkit/"&gt;Tclkit&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i55.tinypic.com/2euk6e1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://i55.tinypic.com/2euk6e1.png" width="302" /&gt;&lt;/a&gt;&lt;/div&gt;However, the TopoResize app is poorly written and crashes all the time. I resorted to resizing the image using the command line tools mentioned above: &lt;br /&gt;&lt;br /&gt;&lt;div style="color: #666666; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;dd if=/dev/zero bs=1M count=XXX &amp;gt;&amp;gt; system.ext2&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;span style="color: black;"&gt;XXX = Amount of space in MB to be added to the image&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;resize2fs -f system.ext2 &lt;/span&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;span style="color: black;"&gt;Resize the filesystem in the image&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;e2fsck -f system.ext2 &lt;/div&gt;&lt;/div&gt;&lt;div style="color: black;"&gt;Perform a check on the new filesystem. Without this, Android may hang while booting up.&lt;/div&gt;&lt;br /&gt;The set of command line tools I used can be downloaded &lt;a href="http://dl.dropbox.com/u/5881137/ext2tools.zip"&gt;here&lt;/a&gt;. Next thing on my wishlist is to open data.img read/write on Windows; if anyone knows of a way, do leave a comment here. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-5966488151804679632?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/5966488151804679632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/08/htc-hd2-android-working-with-image.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5966488151804679632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5966488151804679632'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/08/htc-hd2-android-working-with-image.html' title='HTC HD2 Android: Working with ext2 images under Windows'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://i55.tinypic.com/2euk6e1_th.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-4110800131336883313</id><published>2011-07-29T04:39:00.000-07:00</published><updated>2011-08-20T06:11:11.342-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Still alive after all these years: NEC D3835 45MB SCSI hard disk</title><content type='html'>Recently I got around 20 old IDE/SCSI hard disks for free from a member of a Singapore technical forum and decided to try out all of them, one by one, with the help of an Adaptec &lt;a href="http://www.adaptec.com/en-us/support/scsi/2940/aha-2940uw/"&gt;AHA-2940UW&lt;/a&gt;, since my motherboard does not have SCSI ports. Utilizing the maximum available space in the chassis, I install 7 of them to my computer:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-MvmZs4xVncI/Tk-h5k_mjrI/AAAAAAAAALc/iSqHRz0k8JU/s1600/IMG_20110820_171224.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-MvmZs4xVncI/Tk-h5k_mjrI/AAAAAAAAALc/iSqHRz0k8JU/s1600/IMG_20110820_171224.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;The 2 identical Seagate &lt;a href="http://seagate.com/ww/v/index.jsp?name=Legacy&amp;amp;vgnextoid=cfd7c6ea20fbd010VgnVCM100000dd04090aRCRD&amp;amp;vgnextchannel=f424072516d8c010VgnVCM100000dd04090aRCRD&amp;amp;locale=en-US&amp;amp;reqPage=Legacy"&gt;ST31276A &lt;/a&gt;drives are installed on the primary IDE channel while the &lt;a href="http://www.netcomdirect.com/ibmda6gbat42.html"&gt;IBM DARA-206000&lt;/a&gt; 6GB 2.5in drive is installed on secondary master with the help of a cheap 2.5" to 3.5" IDE converter purchased from eBay.&lt;br /&gt;&lt;br /&gt;The 4 SCSI hard drives are detected separately by the SCSI BIOS. The last hard disk in the list, also the most notable, is the &lt;a href="http://support.necam.com/oem/HDD/D3835.asp"&gt;NEC D3835&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-fw5mfk4MjGY/Tk-jjf9Y0FI/AAAAAAAAALg/_H0L0F7oV-s/s1600/IMG_20110820_172058.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/-fw5mfk4MjGY/Tk-jjf9Y0FI/AAAAAAAAALg/_H0L0F7oV-s/s400/IMG_20110820_172058.jpg" width="300" /&gt;&lt;/a&gt;&lt;/div&gt;It's a 45MB 3500rpm SCSI hard disk drive, even older than the hard disk of my first computer (an old 80386 with a 106MB IDE hard disk). The rated speed is at 1.5MB/sec, way below the tens or hundreds megabytes per second which modern hard disks are capable of.&lt;br /&gt;&lt;br /&gt;It is so old that &lt;a href="http://www.hdtune.com/"&gt;HDTune&lt;/a&gt; refuses to test it: &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-sNCVmpbPSLE/Tk-lbRfEEeI/AAAAAAAAALk/OzTq1iRSqhM/s1600/ERRORH%257E1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="326" src="http://2.bp.blogspot.com/-sNCVmpbPSLE/Tk-lbRfEEeI/AAAAAAAAALk/OzTq1iRSqhM/s400/ERRORH%257E1.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The error message said "Read Error! Test Aborted" and popped up immediately after I clicked on the button to begin the test. But do not think that the hard disk is faulty - the error shows simply because the hard disk capacity is too small for HDTune to read/write data buffers onto it for testing. Perhaps the author did not expect such an old drive to be still alive today.&lt;br /&gt;&lt;br /&gt;All the installed hard disks can be seen from Disk Management in Control Panel, with the NEC in the last position, certified as 'healthy' by Windows:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-XTrsKeVouHQ/Tk-nKynPOmI/AAAAAAAAALo/tP9jgJuLZCI/s1600/HDDLIS%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-XTrsKeVouHQ/Tk-nKynPOmI/AAAAAAAAALo/tP9jgJuLZCI/s1600/HDDLIS%257E2.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Unfortunately Windows is just plain wrong and the hard disk is actually on its last legs:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-eBq6jjmFWqA/Tk-pGdpZ5KI/AAAAAAAAALs/qEz10nSrPbI/s1600/error+reading.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-eBq6jjmFWqA/Tk-pGdpZ5KI/AAAAAAAAALs/qEz10nSrPbI/s1600/error+reading.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The label says the manufacture date is December 1990, which means the drive is getting 21 this year. That's equivalent to 100+ years for a human being. You will get nowhere near that for a modern hard drive, flash drive, or even &lt;a href="http://en.wikipedia.org/wiki/Solid-state_drive"&gt;solid state drive&lt;/a&gt; (SSD). Commercial pressure has forced manufacturers to use cheaper components, resulting in shorter life expectancy of their products, and you must be very lucky to see any modern storage device lasting more than the warranty period without issues. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-4110800131336883313?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/4110800131336883313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/07/still-alive-after-all-these-years-nec.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4110800131336883313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4110800131336883313'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/07/still-alive-after-all-these-years-nec.html' title='Still alive after all these years: NEC D3835 45MB SCSI hard disk'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-MvmZs4xVncI/Tk-h5k_mjrI/AAAAAAAAALc/iSqHRz0k8JU/s72-c/IMG_20110820_171224.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-1984209675531054607</id><published>2011-07-24T01:44:00.000-07:00</published><updated>2011-07-25T07:24:27.901-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General Programming'/><title type='text'>The old new thing: mathematics of paper folding</title><content type='html'>A few weeks ago I received the following quiz as one of the questions for an exam. The question is about paper folding, something that we all know from an early age, and seems simple but it seems that no-one could answer it. I presented it in this article with my proposed solution in an attempt to show how a frustrating mathematics problem could be set from something so simple in our everyday life.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Problem&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Fold a sheet of A0 paper (841mm x 1189mm) in such a way that the longer side (1189mm) is divided into half its length, you will get a sheet of A1 paper (594mm x 841mm). Do the same for the resulting piece of paper and you'll get a sheet of A2 paper (420mm x 594mm). Repeat the same twice and you will get the commonly used paper size, A4 (210mm x 297mm). This process could repeat over and over again to get a paper size of &lt;b&gt;A&lt;/b&gt;n after n times, as demonstrated in the following diagram:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-qRwtLCMUQ40/Tiu28XoJdmI/AAAAAAAAAKY/3CO49jY0FMM/s1600/439px-A_size_illustration2_with_letter_and_legal.svg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://4.bp.blogspot.com/-qRwtLCMUQ40/Tiu28XoJdmI/AAAAAAAAAKY/3CO49jY0FMM/s400/439px-A_size_illustration2_with_letter_and_legal.svg.png" width="292" /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Now let us define an "inner fold" as the line created on the original paper when you fold it into half, unfold it and look at it from the front:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-0pnn29CTFGY/TiviZNHWp4I/AAAAAAAAAK8/of84r7d4ARk/s1600/c00848519.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-0pnn29CTFGY/TiviZNHWp4I/AAAAAAAAAK8/of84r7d4ARk/s1600/c00848519.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-NoA1W9P5Grc/Tiu3y5bZ-bI/AAAAAAAAAKc/ar2I-cjMX6s/s1600/c00848519.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;On the contrary, if you look at the resulting paper from the back, you will see an "outer fold".&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;After &lt;b&gt;n&lt;/b&gt; steps, unfold the original piece of paper and place it in front of you. Now calculate the number of "inner" and "outer" folds created on the paper (You position the paper and look at it the same way as how you did when you started folding it for the first time).&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;An example for up to n=3 is demonstrated in the following diagram. A normal dashed line indicates an inner fold while a bold dashed line indicates an outer fold.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://4.bp.blogspot.com/-yynsgtZFFNE/Tiu8ObwTJEI/AAAAAAAAAKk/DfoGCT5QXRI/s1600/example.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="297" src="http://4.bp.blogspot.com/-yynsgtZFFNE/Tiu8ObwTJEI/AAAAAAAAAKk/DfoGCT5QXRI/s640/example.png" width="640" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The number of inner and outer folds for up to n=6 is shown in the following table. Notice that if a fold is intersected by another fold, it is counted as 2 folds.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: medium none;"&gt;&lt;tbody&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;n&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Inner Folds&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Outer Folds&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 38.95pt;" valign="top" width="52"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Total&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;0&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;0&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;0&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 38.95pt;" valign="top" width="52"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;0&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;0&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 38.95pt;" valign="top" width="52"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 38.95pt;" valign="top" width="52"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;6&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 38.95pt;" valign="top" width="52"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;10&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;14&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;10&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 38.95pt;" valign="top" width="52"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;24&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;5&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;28&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;24&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 38.95pt;" valign="top" width="52"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;52&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;6&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;60&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;52&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 38.95pt;" valign="top" width="52"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;112&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The first task is to find a general formula or algorithm to calculate the number of inner and outer folds after &lt;b&gt;n&lt;/b&gt; times.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;My Proposed Solution&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As simple as it seems, there is no quick solution the problem. Since most people don't have an A0 sheet of paper at home to try to fold so many times, they can only attempt with the common A4 paper and get frustrated after a short  while when the paper becomes too thick to fold or the number of folds  too big to count. &lt;br /&gt;&lt;br /&gt;I proposed a simple solution below. My research also shows that there are several other approaches which may yield seemingly different formulas. Do not read it until you have attempted the question.:)&lt;br /&gt;&lt;br /&gt;&lt;div id="solution" style="visibility: visible;"&gt;First let us simplify the problem by calculating the total number of folds first. It is simply the total number of grid segments on the original piece of paper after &lt;b&gt;n&lt;/b&gt; steps.&lt;br /&gt;&lt;br /&gt;We first observe the total number of horizontal (from left edge to right edge) lines and vertical (from top edge to bottom edge) lines after every fold:&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: medium none;"&gt;&lt;tbody&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;n&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Horizontal &lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Vertical&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;0&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;5&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;7&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;6&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;7&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;7&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;This can be generalized into:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-tETEhxVLi8s/TivMvp2K2gI/AAAAAAAAAKo/RZYwzDDNbDA/s1600/formula1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="113" src="http://4.bp.blogspot.com/-tETEhxVLi8s/TivMvp2K2gI/AAAAAAAAAKo/RZYwzDDNbDA/s320/formula1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now look at each horizontal and vertical line and calculate the number of segments on each line:&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: medium none;"&gt;&lt;tbody&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;n&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Segments&lt;/b&gt;&lt;br /&gt;&lt;b&gt;/hori. line&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;Segments&lt;/b&gt;&lt;br /&gt;&lt;b&gt;/vert. line&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;1&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;0&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;2&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;3&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;2&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;5&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;4&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;8&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.2pt;" valign="top" width="30"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;6&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.2pt;" valign="top" width="87"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;8&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 50.5pt;" valign="top" width="67"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;8&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;This can be generalized into (for n=2 and above)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-NgBSYLwWfeI/TivNj6ut8LI/AAAAAAAAAKs/20mKIEVbbkY/s1600/formula2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="80" src="http://1.bp.blogspot.com/-NgBSYLwWfeI/TivNj6ut8LI/AAAAAAAAAKs/20mKIEVbbkY/s400/formula2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;The total number of folds after n steps is simply:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;No. of horizontal lines &lt;b&gt;x&lt;/b&gt; No. of segments on each + No. of vertical lines &lt;b&gt;x&lt;/b&gt; No. of segments on each&lt;/div&gt;&lt;br /&gt;With some efforts we are able to derive the formula for the total number of folds:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-8M-pOB2JQY8/TivQ_tGGGPI/AAAAAAAAAKw/_AP0Fqva4c4/s1600/formula3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="81" src="http://3.bp.blogspot.com/-8M-pOB2JQY8/TivQ_tGGGPI/AAAAAAAAAKw/_AP0Fqva4c4/s400/formula3.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Now that we have found out the total number of folds, let's calculate the difference between the number of inner folds and outer folds after each step:&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: medium none;"&gt;&lt;tbody&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt;"&gt;n&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt;"&gt;Inner Folds&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt;"&gt;Outer Folds&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 40.5pt;" valign="top" width="54"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;b&gt;&lt;span style="font-size: 12pt;"&gt;Diff.&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;0&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 40.5pt;" valign="top" width="54"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;2&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;3&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 40.5pt;" valign="top" width="54"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;2&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;3&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;6&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;4&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 40.5pt;" valign="top" width="54"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;2&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;4&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;14&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;10&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 40.5pt;" valign="top" width="54"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;4&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;5&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;28&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;24&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 40.5pt;" valign="top" width="54"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;4&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 5.4pt; width: 22.1pt;" valign="top" width="29"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;6&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 65.9pt;" valign="top" width="88"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;64&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 68.3pt;" valign="top" width="91"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;56&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-color: -moz-use-text-color black black -moz-use-text-color; border-style: none solid solid none; border-width: medium 1pt 1pt medium; padding: 0cm 5.4pt; width: 40.5pt;" valign="top" width="54"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0cm;"&gt;&lt;span style="font-size: 12pt;"&gt;8&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Surprisingly enough, the difference is simply:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-9vbLSvy5uck/TivR-OEvh9I/AAAAAAAAAK0/fIqC8wt112g/s1600/formula4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-9vbLSvy5uck/TivR-OEvh9I/AAAAAAAAAK0/fIqC8wt112g/s1600/formula4.png" /&gt;&lt;/a&gt;&lt;/div&gt;I leave this as an exercise for the reader to prove why. With the sum and the difference known, we can now calculate the number of inner and outer folds easily:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-2uelvY_JSeU/TivlZ0LvSgI/AAAAAAAAALE/HLaHO2vdvvg/s1600/formula5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="211" src="http://3.bp.blogspot.com/-2uelvY_JSeU/TivlZ0LvSgI/AAAAAAAAALE/HLaHO2vdvvg/s320/formula5.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;The first part of the problem is now solved. You can compare the results from our formulas with the example to make sure that the formulas are correct. Interestingly, the total number of folds after each step is equal to the number of outer folds in the next step. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bonus Question&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is the next part of the problem:&lt;b&gt;&lt;/b&gt;&lt;i&gt;&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"So far you have always been folding by the longer side of the resulting paper after every step (so that you could get an A1 paper from A0, A2 from A1, A3 from A2 and so on). Now you are told that this restriction is no longer necessary and you could fold the paper by either the shorter or the longer side. For example, fold an A0 paper (841mm x 1189mm) by the shorter side and you will get a piece of paper of size 420mm x 1189 mm.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;How would the final formula for the number of inner and outer folds change? Derive a method to calculate the total number of inner and outer folds after a given set of fold steps, where one can fold either way in each step."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Although I managed to write a program to solve this, I believe there is no need to describe it here as most readers by now would have understood the concept and would know how to approach this extension of the original problem.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Afterthoughts&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The concept  which the problem is based on is very simple and does not require any  fancy maths knowledge - anyone with perhaps a secondary school education  can understand the problem. However, among many whom I have asked, almost all  would immediately attempt the question but most would just become  frustrated and give up without ever finding the solution, or even the  correct approach. I believe it requires a high level of concentration  and logical thinking as the number of folds grows exponentially. Setting this as an exam question where students work under stress  and time constraints would therefore be unreasonable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-1984209675531054607?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/1984209675531054607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/07/old-new-thing-mathematics-of-paper.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/1984209675531054607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/1984209675531054607'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/07/old-new-thing-mathematics-of-paper.html' title='The old new thing: mathematics of paper folding'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-qRwtLCMUQ40/Tiu28XoJdmI/AAAAAAAAAKY/3CO49jY0FMM/s72-c/439px-A_size_illustration2_with_letter_and_legal.svg.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-5637671136718085542</id><published>2011-06-14T00:15:00.000-07:00</published><updated>2011-06-14T18:15:03.562-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Tips'/><title type='text'>Samsung P2370 and ATI Moblity Graphics Card</title><content type='html'>I recently bought a &lt;a href="http://www.samsung.com/sg/consumer/pc-peripherals-printer/monitor/lcd-monitor/LS23EFHKFV/XS/index.idx?pagetype=prd_detail"&gt;Samsung P2370&lt;/a&gt; LCD monitor in order to watch 1080p HD movies on my HP G42 laptop, which is using an &lt;a href="http://www.amd.com/uk/products/notebook/graphics/ati-mobility-hd-5400/Pages/hd-5470-specs.aspx"&gt;ATI Mobility Radeon HD5470&lt;/a&gt; graphics card. Much to my surprise, this combination did not work at all and was a total waste of time. Here is why.&lt;br /&gt;&lt;br /&gt;The monitor screen size is 23-inch, supporting full HD resolution at 1920x1080 and has only one DVI input. Interestingly, the on-screen display shows that the monitor searches for signal on both analog (likely referring to VGA) and digital (DVI) inputs. This is perhaps because the same firmware code base is shared with another similar model, the &lt;a href="http://www.samsung.com/sg/consumer/pc-peripherals-printer/monitor/lcd-monitor/LS23EMDKU/XS/index.idx?pagetype=prd_detail&amp;amp;tab=specification"&gt;Samsung P2370HD&lt;/a&gt; that supports VGA input, among many other things including a TV tuner.&lt;br /&gt;&lt;br /&gt;I first tried to connect the monitor to a DVD player with DVI output and everything worked well, so I proceeded to connect it to my HP G42 laptop HDMI port via a cheap DVI-to-HDMI converter purchased from eBay. Although the PC booted normally, with the monitor showing BIOS POST messages and Windows logo, the display is not detected once Windows finished booting. &lt;b&gt;Screen Resolution&lt;/b&gt; settings in Windows 7 reported &lt;b&gt;Another display not detected:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img843.imageshack.us/img843/8093/badu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="224" src="http://img843.imageshack.us/img843/8093/badu.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I tried to disconnect, reconnect, reboot Windows, reinstall driver to no avail. I also tried to install the Samsung &lt;a href="http://www.samsung.com/us/support/downloads/global"&gt;driver&lt;/a&gt; for the LCD. The notebook graphics card has 3 outputs: LCD panel, VGA and HDMI. However, the monitor driver install utility only offers to install driver onto the LCD and VGA output, but not the HDMI output.&lt;br /&gt;&lt;br /&gt;It then came to my attention that the P2370 was never detected - Windows played the "device connected" sound when I connected other monitors via HDMI, but not the P2370. The monitor worked well with other graphics cards, and the notebook graphics card HDMI output worked well with other monitors! So there must be something wrong with my special hardware combination. To my knowledge, unlike &lt;a href="http://en.wikipedia.org/wiki/Video_Graphics_Array"&gt;VGA &lt;/a&gt;where handshaking is optional and you can always force the graphics card to output to VGA port even when no monitor is connected, &lt;a href="http://en.wikipedia.org/wiki/HDMI"&gt;HDMI&amp;nbsp;&lt;/a&gt; has some compulsory &lt;a href="http://en.wikipedia.org/wiki/Display_Data_Channel"&gt;handshaking&lt;/a&gt; involved and the monitor has to be detected before the graphics card can output anything.&lt;br /&gt;&lt;br /&gt;I then tried &lt;a href="http://www.entechtaiwan.com/util/moninfo.shtm"&gt;MonInfo&lt;/a&gt; and surprisingly the P2370 could be detected properly, with all the parameters correct. I tried to create a custom monitor driver to use with &lt;a href="http://entechtaiwan.com/util/ps.shtm"&gt;PowerStrip&lt;/a&gt;, which did not help either because the graphics card did not 'see' the monitor! Not giving up yet, I tried Windows XP which does not have automatic monitor detection. This time round, the Samsung driver installation utility could install the driver to the HDMI output, but the HDMI port was still not visible in &lt;b&gt;Display Properties&lt;/b&gt;. I then tried to launch Windows in Safe Mode where only the VGA driver is loaded, and the P2370 always displayed a clone of the laptop LCD, much like what happened during boot time. The Fn key combination to switch between clone/extended desktop did not work. &lt;br /&gt;&lt;br /&gt;All this observations suggested that the hardware was fine and the problem was with the ATI driver for Windows which could not see the P2370 via HDMI for some reasons. My final attempt was to try various Linux variants, hoping that some Linux drivers may fix the problems. However, the same problem persisted:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;On Linux builds where the graphics card was detected properly, no output on HDMI.&lt;/li&gt;&lt;li&gt;On Linux builds with no driver for the graphics card, the P2370 displayed a clone of the laptop LCD&lt;/li&gt;&lt;/ol&gt;This is a dead end. In the end, I decided to sell the Samsung P2370 LCD and get a &lt;a href="http://reviews.cnet.com/lcd-monitors/dell-s2409w/4505-3174_7-33190912.html"&gt;Dell S2409W&lt;/a&gt; instead, which has served me well so far. During the troubleshooting, my research revealed that this is a &lt;a href="http://social.technet.microsoft.com/Forums/en-US/w7itprohardware/thread/39781976-8a3b-487f-8d93-8ce039f70128/"&gt;common &lt;/a&gt;problem (it's even in Google Autocomplete suggestion list, try to search for &lt;b&gt;'samsung p2370 ati problem'&lt;/b&gt;) with no official answers from either Samsung or ATI, and no solutions available.&lt;br /&gt;&lt;br /&gt;This problem may apply for other ATI card as well. The bottom line is not to buy Samsung P2370 and similar models if you're using an ATI graphics card!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-5637671136718085542?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/5637671136718085542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/06/samsung-p2370-and-ati-moblity-graphics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5637671136718085542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5637671136718085542'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/06/samsung-p2370-and-ati-moblity-graphics.html' title='Samsung P2370 and ATI Moblity Graphics Card'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-9031802010906443208</id><published>2011-05-07T20:54:00.000-07:00</published><updated>2011-05-07T22:34:24.566-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Phone 7'/><title type='text'>Windows Phone 7 and Singapore IDD prefix 0XX</title><content type='html'>When using my Windows Phone 7 today to make an international call using Singtel IDD 019, I realized that the call could not get through and the operator would always report "The number you have called is incorrect". Checking the call history showed that the prefix 019 has been replaced with "+9" by the Windows phone for unknown reasons. &lt;br /&gt;&lt;br /&gt;After much googling, I found a way to disable this. This is part of a feature called &lt;b&gt;International Assist&lt;/b&gt; by whoever designs the phone. To disable it, open &lt;b&gt;Settings&lt;/b&gt;, click on &lt;b&gt;Applications&lt;/b&gt; on the top bar, select &lt;b&gt;Phone&lt;/b&gt; and turn off &lt;b&gt;International Assist&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;I am not sure which standard defines that "01" is the same as "+" as an IDD prefix or why this feature should be on by default. In any case, it's just another hassle when using Windows Phone 7!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;See also:&lt;/b&gt;&lt;br /&gt;&lt;a href="http://www.techradar.com/news/phone-and-communications/mobile-phones/25-windows-phone-7-tips-and-tricks-902641"&gt;25 Windows Phone 7 tips and tricks&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-9031802010906443208?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/9031802010906443208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/05/windows-phone-7-and-singapore-idd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/9031802010906443208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/9031802010906443208'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/05/windows-phone-7-and-singapore-idd.html' title='Windows Phone 7 and Singapore IDD prefix 0XX'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6641253786007545009</id><published>2011-04-14T21:40:00.000-07:00</published><updated>2011-05-06T20:46:49.860-07:00</updated><title type='text'>Another customer service tale: "Your system connects me to the wrong number, please refund!"</title><content type='html'>An early Monday morning at my company, which offers budget international calls via &lt;a href="http://en.wikipedia.org/wiki/Callback_%28telecommunications%29"&gt;callback&lt;/a&gt;, I received a call from a user complaining he was connected to the wrong number and demanded a refund. Below is the conversation. The story is true with some details removed and/or altered to protect privacy.&lt;br /&gt;&lt;br /&gt;....&lt;br /&gt;&lt;b&gt;User:&lt;/b&gt; Please help me, your system connects me to the wrong number.&lt;br /&gt;&lt;b&gt;Me:&lt;/b&gt; Can you describe what exactly happened?&lt;br /&gt;&lt;b&gt;User:&lt;/b&gt; I called your callback hotline at 6XXX XXXX, the system called me back, I answered the call and keyed in the number to call. The destination rang but the person picking up the call told me I had called the wrong number. Please refund the credit.&lt;br /&gt;&lt;b&gt;Me:&lt;/b&gt; Can I have your username and the number you wished to call?&lt;br /&gt;&lt;b&gt;User:&lt;/b&gt; My username is ..... and the number is +84XXXXX&lt;br /&gt;&lt;b&gt;Me:&lt;/b&gt; (after checking his account activity) According to our record, you have called +7484XXXXX, did you happen to key in the wrong number?&lt;br /&gt;&lt;b&gt;User:&lt;/b&gt; No, I entered it correctly.&lt;br /&gt;&lt;b&gt;Me:&lt;/b&gt; Can you tell me what you did exactly when the system prompted you to enter the destination number?&lt;br /&gt;&lt;b&gt;User:&lt;/b&gt; I entered +74 first, then realized it should have been +84, so I pressed &lt;b&gt;Clear Display&lt;/b&gt; on my phone and re-entered the correct number.&lt;br /&gt;&lt;b&gt;Me:&lt;/b&gt; (almost started to laugh) I am sorry sir, the &lt;b&gt;Clear Display &lt;/b&gt;only clears the display screen on you phone for your convenience and does not reset what you have entered into the system. Therefore you ended up calling the wrong number.&lt;br /&gt;&lt;b&gt;User:&lt;/b&gt; But I am the user and I don't care how your systems works. Please refund my credit!&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;This conversation should be normal and acceptable for a first time callback service user. However, I later found it to be disturbing once I knew that he is a frequent callback user with a PhD degree in computing. All &lt;a href="http://en.wikipedia.org/wiki/Interactive_voice_response"&gt;Interactive Voice Response&lt;/a&gt; (IVR) system works based on &lt;a href="http://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling"&gt;DTMF&lt;/a&gt; which does not support a DELETE key or similar. All digits entered locally will be registered with the server, which is why sometimes you are asked to confirm sensitive information (via 'Press 1 to confirm or Press 2 to change') before any action is made. In any case, I believe it doesn't take a genius to know what he did (pressing the &lt;b&gt;'Clear Display'&lt;/b&gt; button) would not have worked. I have always thought that PhDs are supposed to be critical thinkers with good reasoning and whatnot, together with their professional skills. Oh well ...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;See also&lt;/b&gt;:&amp;nbsp; &lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://minhdanh2002.blogspot.com/2010/03/mobileone-not-m1.html"&gt;MobileOne not M1&amp;nbsp;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.techtales.com/1999_03_tftcontent.html"&gt;Some Technical Tales&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/oldnewthing/archive/2008/11/28/9148951.aspx"&gt;Just because a method is called Refresh doesn't mean that it refreshes what you want&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6641253786007545009?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6641253786007545009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/04/another-customer-service-tale-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6641253786007545009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6641253786007545009'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/04/another-customer-service-tale-your.html' title='Another customer service tale: &quot;Your system connects me to the wrong number, please refund!&quot;'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-177620641997255114</id><published>2011-03-23T05:34:00.000-07:00</published><updated>2011-09-26T03:01:34.272-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='General Programming'/><title type='text'>Interfacing Nokia 3510i and 5110 LCD with PIC Microcontroller</title><content type='html'>Recently I started to regain some interest in embedded systems, and start to experiment with PIC micro-controllers. After some successful attempts with standard character LCDs using using the HD44780 controllers, I decided to get some Nokia LCD modules from eBay to explore.&lt;br /&gt;&lt;br /&gt;The 2 LCD modules I purchased are for the &lt;a href="http://www.gsmarena.com/nokia_3510i-344.php"&gt;3510i&lt;/a&gt; and &lt;a href="http://www.gsmarena.com/nokia_5110-7.php"&gt;5110&lt;/a&gt; models. Both have built-in controllers which use &lt;b&gt;Serial Peripheral Interface&lt;/b&gt; (&lt;a href="http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus"&gt;SPI&lt;/a&gt;). The following are the pinout for my modules, notice that pin assignments may vary slightly. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;LCD pinout&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Nokia 5110:&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-DoZixT7OLx0/Tgxvge6bEdI/AAAAAAAAAJA/6h61KvI3cOY/s1600/pinout_5110.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="372" src="http://4.bp.blogspot.com/-DoZixT7OLx0/Tgxvge6bEdI/AAAAAAAAAJA/6h61KvI3cOY/s640/pinout_5110.jpg" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Nokia 3510i:&lt;/u&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-TVeq8P99Op0/TgxwDjMUA1I/AAAAAAAAAJE/LNaFHU2hWj4/s1600/pinout_3510i.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="374" src="http://4.bp.blogspot.com/-TVeq8P99Op0/TgxwDjMUA1I/AAAAAAAAAJE/LNaFHU2hWj4/s640/pinout_3510i.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The only different here is pin #5 which is used as data/command selection for the 5110, and unused for the 3510i. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Voltage difference: 5.5v vs&lt;/b&gt; &lt;b&gt;3V&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Both LCDs are designed to work with 3.3V, but due to an internal voltage clamp 5V can be used for SCLK, SDATA, REST, D/C and CS as long as a current limiting resistor (around 10k) is connected in series for each line. 3.3V should still be applied to VCC and the LED supply. I have tried using voltage dividers, which did not work, perhaps due to the LCD varying internal resistance and current consumption.&lt;br /&gt;&lt;br /&gt;With the above connections we can only write to the LCD but can't read back the LCD response because 3.3v is not high enough to register as logic '1' in the PIC. Luckily reading from the LCD is not required for basic operations; all that is needed is sufficient delay after each operation to make sure the LCD is ready for next command.&lt;br /&gt;&lt;br /&gt;I have chosen the PIC16f88 simply because it's available in my junk box. However, as the 16f88 does not have dedicated hardware SPI required by the LCD modules, &lt;a href="http://en.wikipedia.org/wiki/Bit_banging"&gt;bit-banging&lt;/a&gt; has to be used to simulate SPI. Although this usually means complicated code and lower throughput, it does not matter as all I wanted is to get the LCD to display something useful ;)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;LCD Memory Map&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The 5110 LCD is monochrome, uses the PCD8544  controller and has a resolution of 48 rows × 84 columns. Each 8 pixels on a single column consumes a single byte on the LCD memory map. It takes 504 bytes to fill the entire LCD.&lt;br /&gt;&lt;br /&gt;The 3510i LCD has 97x66 resolution and can operate  in either 256 or 4096 colors. Since there seems to be little difference between 256 and 4096 colors due to the small resolution, I have chosen 256 colors for simplicity. Each pixel on the LCD is represented by a single byte and filling the entire LCD takes 6402 bytes in 256-color (8-bit) mode.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Sample code: displaying test patterns&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The following code shows how to display all black pixels on the Nokia 5110 LCD. Notice that LCD initialization code is not shown.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt; lcd_5110_clear&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;int&lt;/span&gt; i&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt; i&lt;span style="color: #808030;"&gt;&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: purple;"&gt;&lt;/span&gt;&lt;span style="color: #008c00;"&gt;84&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;i&lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: maroon; font-weight: bold;"&gt;unsigned&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; row&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #808030;"&gt;(&lt;/span&gt;row&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;row&lt;span style="color: #808030;"&gt;&lt;span style="color: #008c00;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #008c00;"&gt;6&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;row&lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: dimgrey;"&gt;//all black pixels&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; data &lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: green;"&gt;0xFF&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;br /&gt;            lcd_5110_send&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: green;"&gt;0x40&lt;/span&gt; &lt;span style="color: #808030;"&gt;+&lt;/span&gt; row&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt; &lt;span style="color: dimgrey;"&gt;//Y address&lt;/span&gt;&lt;br /&gt;            lcd_5110_send&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: green;"&gt;0x80&lt;/span&gt; &lt;span style="color: #808030;"&gt;+&lt;/span&gt; i&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;   &lt;span style="color: dimgrey;"&gt;//X address&lt;/span&gt;&lt;br /&gt;            &lt;br /&gt;            &lt;span style="color: dimgrey;"&gt;//write to display memory&lt;/span&gt;&lt;br /&gt;            lcd_5110_send&lt;span style="color: #808030;"&gt;(&lt;/span&gt;data&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt;1&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;/pre&gt;&lt;br /&gt;The following code shows how to display a selected color on the 3510i LCD:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt; addset&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;unsigned&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; x1&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;unsigned&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; y1&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;unsigned&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; x2&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;unsigned&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; y2&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000;"&gt;send&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: green;"&gt;0x2a&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;span style="color: dimgrey;"&gt;//column address set&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000;"&gt;send&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;x1&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt; 1&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000;"&gt;send&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;x2&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt; 1&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000;"&gt;send&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: green;"&gt;0x2B&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt; 0&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;span style="color: dimgrey;"&gt;//page address set&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000;"&gt;send&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;y1&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt; 1&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000;"&gt;send&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;y2&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt; 1&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #400000;"&gt;send&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: green;"&gt;0x2C&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: #808030;"&gt; )&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;span style="color: dimgrey;"&gt;//memory write&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;void&lt;/span&gt; LCD_Clear&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;unsigned&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;int&lt;/span&gt; value&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;unsigned&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; Color&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;unsigned&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; x&lt;span style="color: #808030;"&gt;,&lt;/span&gt; y&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    addset&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt;97&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt;66&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;y &lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt; y &lt;span style="color: #808030;"&gt;&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span style="color: #008c00;"&gt;67&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt; y &lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;x &lt;span style="color: #808030;"&gt;=&lt;/span&gt; &lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt; x &lt;span style="color: #808030;"&gt;&lt;span style="color: purple;"&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt; &lt;span style="color: #008c00;"&gt;98&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt; x &lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;+&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #400000;"&gt;send&lt;/span&gt;&lt;span style="color: #808030;"&gt;(Color&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt;&lt;span style="color: #008c00;"&gt; 1&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% rgb(255, 255, 255); color: black;"&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Displaying text and graphics&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Up until now you can only display test patterns on the LCDs. The use of a bitmap font (and extra code) is required if you want to display any useful text. I have chosen a 8x12 font for the 3510i LCD, and a 5x8 font for the 5110 LCD. The font, together with any graphics to be displayed, will be stored in a 24C64 (8Kbytes) I2C EEPROM. To program the EEPROM, I use the I2C version of the &lt;a href="http://www.lancos.com/prog.html"&gt;PonnyProg &lt;/a&gt;programmer. Notice that this may not work on newer PCs where the available current from the serial port is limited and will never work with a USB-to-serial converter. In my experiment, I made a stupid mistake of adding a LED via a 470 ohm resistor to show activity during programming. This result in data corruption and verification errors after programming due to excessive current consumption. Changing the resistor to 2k worked fine, although the LED is much dimmer.&lt;br /&gt;&lt;br /&gt;With the EEPROM to store font and graphics, the 5110 LCD could now display text and some monochrome bitmap:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-jCBfMMLh-RU/TgyCG6CLVOI/AAAAAAAAAJI/q7cr_tP_3OY/s1600/IMG_20110409_105351.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-jCBfMMLh-RU/TgyCG6CLVOI/AAAAAAAAAJI/q7cr_tP_3OY/s320/IMG_20110409_105351.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/-fp43YYkjCRo/TgyCJgrx1dI/AAAAAAAAAJM/uC2BEMSBB1Y/s1600/IMG_20110409_105406.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/-fp43YYkjCRo/TgyCJgrx1dI/AAAAAAAAAJM/uC2BEMSBB1Y/s320/IMG_20110409_105406.jpg" width="320" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/-jCBfMMLh-RU/TgyCG6CLVOI/AAAAAAAAAJI/q7cr_tP_3OY/s1600/IMG_20110409_105351.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;The 3510i LCD could do a much better job ;)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-jx9C35LLSSI/TgyC3dbMTbI/AAAAAAAAAJU/C6btdYM5lh8/s1600/IMG_20110313_194610.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-jx9C35LLSSI/TgyC3dbMTbI/AAAAAAAAAJU/C6btdYM5lh8/s320/IMG_20110313_194610.jpg" width="240" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/-K2RhM-UEdaY/TgyCqIEhEyI/AAAAAAAAAJQ/Okrg8vsiicI/s1600/IMG_20110313_194631.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-K2RhM-UEdaY/TgyCqIEhEyI/AAAAAAAAAJQ/Okrg8vsiicI/s320/IMG_20110313_194631.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Notice that the serial port connector is for debugging purposes only.&lt;br /&gt;&lt;br /&gt;The entire source code is attached &lt;a href="http://dl.dropbox.com/u/5881137/NokiaLCD.zip"&gt;here&lt;/a&gt;. The contents of the EEPROM is included with the source code and named &lt;b&gt;eeprom.bin&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-177620641997255114?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/177620641997255114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/03/interfacing-nokia-3510i-and-5110-lcd.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/177620641997255114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/177620641997255114'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/03/interfacing-nokia-3510i-and-5110-lcd.html' title='Interfacing Nokia 3510i and 5110 LCD with PIC Microcontroller'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-DoZixT7OLx0/Tgxvge6bEdI/AAAAAAAAAJA/6h61KvI3cOY/s72-c/pinout_5110.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-4591203492101521354</id><published>2011-02-15T19:55:00.000-08:00</published><updated>2011-07-15T20:46:16.473-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>VGA output with PIC Microcontroller</title><content type='html'>I tried to use the instructions from &lt;a href="http://tinyvga.com/pic-vga"&gt;here &lt;/a&gt;to make a PIC16F84A display some test patterns on my monitor. The circuit diagram is simple:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-ecaUqi-8Oio/TiD-8LM7l7I/AAAAAAAAAJw/H764jaZ4nb4/s1600/vga-test.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-ecaUqi-8Oio/TiD-8LM7l7I/AAAAAAAAAJw/H764jaZ4nb4/s1600/vga-test.gif" /&gt;&lt;/a&gt;&lt;/div&gt;You should try with an old CRT monitor first, which is less sensitive to noises and will not be expensive to replace should you damage it due to connection errors. I tried to build this circuit on a breadboard and found out that it works every time with a CRT monitor but randomly will not work with my LCD monitor - the LCD simply stays in standby mode. Another important thing not mentioned in the article is that the monitor ID (pin #11) has to be grounded to indicate a low-resolution output (VGA 640X480) and the digital ground pin (pin #5) also needs to be grounded. The VGA pinout is detailed below for your reference:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-_-f4UznDvqM/TiEBGA10OUI/AAAAAAAAAJ0/3erDmJZcXV0/s1600/vga_pinout.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="221" src="http://4.bp.blogspot.com/-_-f4UznDvqM/TiEBGA10OUI/AAAAAAAAAJ0/3erDmJZcXV0/s320/vga_pinout.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I build the circuit on a veroboard and a breadboard:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-0_sOuW8LlLU/TiEEqiY_lbI/AAAAAAAAAKE/Qfj1RYd6pX8/s1600/IMG_20110412_200920.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://4.bp.blogspot.com/-0_sOuW8LlLU/TiEEqiY_lbI/AAAAAAAAAKE/Qfj1RYd6pX8/s320/IMG_20110412_200920.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Here is the result:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_JvtC8kKOfw/TiEDP9mH-vI/AAAAAAAAAKA/G4guVBngA6k/s1600/IMG_20110412_201248.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://2.bp.blogspot.com/-_JvtC8kKOfw/TiEDP9mH-vI/AAAAAAAAAKA/G4guVBngA6k/s320/IMG_20110412_201248.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;You can display different colors by connecting pin 1 (Red), pin 2 (Green), pin 3 (Blue) or any combinations of these to the 10k resistor.&lt;br /&gt;&lt;br /&gt;Here is the horizontal sync and vertical sync signals on my oscilloscope:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-QIvtXPGEJ9A/TiEGe72L8gI/AAAAAAAAAKM/qrahXf0CZGY/s1600/VSYNC+%2526+HSYNC.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://1.bp.blogspot.com/-QIvtXPGEJ9A/TiEGe72L8gI/AAAAAAAAAKM/qrahXf0CZGY/s320/VSYNC+%2526+HSYNC.jpg" width="320" /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Pin 7 output signal vs. horizontal sync: &lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-S5Uy_1EL1CM/TiEHUS2YydI/AAAAAAAAAKQ/vVGW2yZaUu0/s1600/Green+%2526+HSYNC.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://3.bp.blogspot.com/-S5Uy_1EL1CM/TiEHUS2YydI/AAAAAAAAAKQ/vVGW2yZaUu0/s320/Green+%2526+HSYNC.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Pin 7 output after the 10k resistor. The resistor is for brightness adjustment and can be omitted:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-lmw8kgt07Vo/TiEHi8eOdEI/AAAAAAAAAKU/QXdfSfUzyfU/s1600/G+Signal+after+resistor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://3.bp.blogspot.com/-lmw8kgt07Vo/TiEHi8eOdEI/AAAAAAAAAKU/QXdfSfUzyfU/s320/G+Signal+after+resistor.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href="http://1.bp.blogspot.com/--eN7qTpZtIw/TiECC2XWIQI/AAAAAAAAAJ8/MF8p0BSGuUA/s1600/IMG_20110412_201248.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-4591203492101521354?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/4591203492101521354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/02/vga-output-with-pic-microcontroller.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4591203492101521354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4591203492101521354'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/02/vga-output-with-pic-microcontroller.html' title='VGA output with PIC Microcontroller'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-ecaUqi-8Oio/TiD-8LM7l7I/AAAAAAAAAJw/H764jaZ4nb4/s72-c/vga-test.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-5982518582206820040</id><published>2011-02-08T20:13:00.000-08:00</published><updated>2011-07-09T00:58:20.114-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Experimenting with LCD modules and PIC microcontrollers</title><content type='html'>I recently got a PIC16LF84A (free sample from Microchip) and a few LCD modules at a cheap price from eBay. With some interests and time at hand, I have successfully made these LCD modules work and display some test patterns, just for fun :)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;16x2 Character LCD&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This LCD is using the standard HD44780 controller so sample source code can be found everywhere on the Internet. I got it to work within 15 minutes:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-sFt28zUmTE0/ThfIvEYKNWI/AAAAAAAAAJY/H0b78bRLZzA/s1600/IMG_20110326_210013.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-sFt28zUmTE0/ThfIvEYKNWI/AAAAAAAAAJY/H0b78bRLZzA/s320/IMG_20110326_210013.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;20x4 Character LCD&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This LCD is also using the standard HD44780 controller, but there is more display area, 20 columns and 4 lines. I also got it to work:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-IUAyYuXVkhQ/ThfQmNGs7_I/AAAAAAAAAJs/7BvZQ4_LeMQ/s1600/IMG_20110326_210142.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="167" src="http://3.bp.blogspot.com/-IUAyYuXVkhQ/ThfQmNGs7_I/AAAAAAAAAJs/7BvZQ4_LeMQ/s320/IMG_20110326_210142.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-5VpLLdAMTCs/ThfJBduqkSI/AAAAAAAAAJc/GVFxzpGYxs4/s1600/IMG_20110326_210142.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Download the source code to test the 16x2 and 20x4 character LCD &lt;a href="http://dl.dropbox.com/u/5881137/HD44780_lcd.c"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;122x32 Monochrome Graphics LCD&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This LCD is using the JHD12232D controller. I purchased it from &lt;a href="http://www.sure-electronics.net/"&gt;sure-electronics&lt;/a&gt;, an eBay &lt;a href="http://stores.ebay.com/Sure-Electronics"&gt;reseller&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-0j71rsFZTCc/ThfJzE5-cTI/AAAAAAAAAJg/-lp41Ux13P0/s1600/201010221244161830.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="170" src="http://3.bp.blogspot.com/-0j71rsFZTCc/ThfJzE5-cTI/AAAAAAAAAJg/-lp41Ux13P0/s320/201010221244161830.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Despite being a graphical LCD, its uses are pretty limited due to the small vertical resolution. The 32-pixel vertical resolution is divided into 2 blocks of 16 pixels each, having a space in between. This make it almost impractical to display any bitmaps or graphics on this LCD. The only graphical use for this LCD would be to display Chinese text, as demonstrated in the above picture.&lt;br /&gt;&lt;br /&gt;Using the datasheet and sample source code available from the seller website, I am able to make this LCD display some test patterns:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-vjZ5zqSvrEA/ThfK30V5K2I/AAAAAAAAAJk/R6_dlVof0NI/s1600/IMG_20110326_205802.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-vjZ5zqSvrEA/ThfK30V5K2I/AAAAAAAAAJk/R6_dlVof0NI/s320/IMG_20110326_205802.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Download the datasheet and source code &lt;a href="http://dl.dropbox.com/u/5881137/12232LCD.zip"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-5982518582206820040?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/5982518582206820040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/02/experimenting-with-lcd-modules-and-pic.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5982518582206820040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5982518582206820040'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/02/experimenting-with-lcd-modules-and-pic.html' title='Experimenting with LCD modules and PIC microcontrollers'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-sFt28zUmTE0/ThfIvEYKNWI/AAAAAAAAAJY/H0b78bRLZzA/s72-c/IMG_20110326_210013.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6077451791501947290</id><published>2011-01-18T15:45:00.000-08:00</published><updated>2011-03-04T08:39:22.766-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VB.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='General Programming'/><title type='text'>Programming Nostalgia: revisiting Mike Wiering's Mario game written in Pascal</title><content type='html'>I have always been a fan of Super Mario game (and its variants) ever since the first time I touched the computer keyboard. I remember the first time playing it on my old 80386 computer and could not get passed the big two fish in the middle of level 1:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-ce_86d0lEeM/TV8w5DwU4PI/AAAAAAAAAH0/J1KorWSO_wI/s1600/mario.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="255" src="http://1.bp.blogspot.com/-ce_86d0lEeM/TV8w5DwU4PI/AAAAAAAAAH0/J1KorWSO_wI/s400/mario.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;After I managed to jump through the lava and proceed to higher levels, it seemed that I could not get through level 4:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-peVE_68sAao/TV8xXmK-xGI/AAAAAAAAAH4/T4xEQqQoTVg/s1600/MARIO6.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="227" src="http://1.bp.blogspot.com/-peVE_68sAao/TV8xXmK-xGI/AAAAAAAAAH4/T4xEQqQoTVg/s400/MARIO6.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I decided to give up and did not attempt the game until years later when I had an Internet connection at home and soon figured out that I was playing on an uncompleted version of the game. By then (around the year 2000), Mike Wiering, the original author of the Mario game for MS-DOS, has released the source code on his &lt;a href="http://www.wieringsoftware.nl/mario/index.html"&gt;website&lt;/a&gt;. Unlike my version, which proceeds directly to level 1 upon startup, the full version supports 2 players (MARIO and LUIGI) and has a menu with some other options:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Vr5mUy9O_Ms/TV8ybl380lI/AAAAAAAAAH8/VtvW5wVTuR4/s1600/mariostartup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="255" src="http://4.bp.blogspot.com/-Vr5mUy9O_Ms/TV8ybl380lI/AAAAAAAAAH8/VtvW5wVTuR4/s400/mariostartup.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Compiling the source&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;After a few failed attempts due to a bug with Turbo Pascal CRT Unit that causes &lt;a href="http://en.wikipedia.org/wiki/Runtime_error_200"&gt;Runtime Error 200&lt;/a&gt; when running on fast computer, I managed to patch the CRT unit, recompiled the game, ran it properly and finished all 6 levels! However, when I migrated to a faster laptop (1Ghz) around 2004, the game again could not run - it stopped at a black screen upon startup, perhaps due to some illegal VGA function calls. It also cannot run on modern Windows such as Windows Vista and above, or 64-bit version of Windows, due to a lack of 16-bit compatibility as well as full-screen support. On these computers, and my current computer in particular, DosBox is the only option if I want to play the game. Interestingly, this MARIO game, and similar games by &lt;a href="http://www.wieringsoftware.nl/"&gt;Wiering Software&lt;/a&gt; such as Charlie II, Charlie the Duck or &lt;a href="http://www.wieringsoftware.nl/angelo/index.php?P=4&amp;amp;L=E"&gt;Super Angelo&lt;/a&gt; play fine on DosBox but seem to have timing issue (the speed is very fast) when run from inside a virtual machine such as Microsoft Virtual PC, VmWare or Sun VirtualBox.&lt;br /&gt;&lt;br /&gt;With some Pascal programming knowledge and time at hand, I decided to have a closer look at the &lt;a href="http://www.wieringsoftware.nl/mario/source.html"&gt;source code&lt;/a&gt;, to figure out how Pascal is used in game programming, and this article will discuss some interesting facts that I have found.&lt;br /&gt;&lt;br /&gt;The first thing I learned was that the released executable was packed (as described in the README.TXT provided with the source code) to reduce file size to 57KB, perhaps with some MS-DOS packing utility. The compiled executable can be as big as several hundreds KB. In those days with 360KB floppy disk, this was probably a huge concern. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Source code organization&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The source code is quite well organized into several Pascal unit files (*.PAS) and sprite include files (*.00?). Variables are well named and procedures are well structured. Although there are few inline comments provided since the code was never meant to release to public, the code can be understood and modified by anyone willing to do so.&lt;br /&gt;&lt;br /&gt;The description of the main source code files can be found below:&lt;br /&gt;&lt;br /&gt;MARIO.PAS: The main application&lt;br /&gt;&lt;br /&gt;WORLDS.PAS: All level data are hard-coded here&lt;br /&gt;&lt;br /&gt;BACKGR.PAS: Unit to support drawing the game background such as skylines.&lt;br /&gt;&lt;br /&gt;BLOCKS.PAS: Assists in the drawing of animation&lt;br /&gt;&lt;br /&gt;BUFFERS.PAS: Support reading of level and sprite data into buffers&lt;br /&gt;&lt;br /&gt;CPU286.PAS: Halt the program if a CPU older than 286 is detected&lt;br /&gt;&lt;br /&gt;ENEMIES.PAS: Define Mario's enemies, such as turtle, fish or moving objects&lt;br /&gt;&lt;br /&gt;FIGURES.PAS: Define behavior of objects along MARIO's way, except for enemies&lt;br /&gt;&lt;br /&gt;GLITTER.PAS and TMPOBJ.PAS: Display glitters such as stars that show when Mario hits coins or an object.&lt;br /&gt;&lt;br /&gt;JOYSTICK.PAS: Support the use of a joystick&lt;br /&gt;&lt;br /&gt;KEYBOARD.PAS: Process keyboard input &lt;br /&gt;&lt;br /&gt;MUSIC.PAS: Play sound using PC speaker&lt;br /&gt;&lt;br /&gt;PALETTES.PAS: The color palette used to draw the game&lt;br /&gt;&lt;br /&gt;PLAY.PAS: Main game logic, e.g. how MARIO interacts with enemies, objects, earn coins, etc.&lt;br /&gt;&lt;br /&gt;PLAYERS.PAS: Define the behavior of MARIO and LUJI. &lt;br /&gt;&lt;br /&gt;STARS.PAS: Draw the stars on the sky&lt;br /&gt;&lt;br /&gt;STATUS.PAS: The game status line&lt;br /&gt;&lt;br /&gt;TXT.PAS: Text processing unit&lt;br /&gt;&lt;br /&gt;VGA256.PAS: Custom Turbo Pascal VGA unit (Mode 13h, 320x200 256 colors)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Creating sprites &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Sprites are first created using GRED.EXE (see GRED.TXT included in the source code):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-UgiDHJeUF6A/TV9g02Ad8BI/AAAAAAAAAIE/YXAlhxKRgMQ/s1600/treeGRED.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="266" src="http://1.bp.blogspot.com/-UgiDHJeUF6A/TV9g02Ad8BI/AAAAAAAAAIE/YXAlhxKRgMQ/s400/treeGRED.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It will be saved as a binary file (*.000, e.g: TREE.000), and then exported to a Pascal file that looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-jgKRy3wECPE/TV9edjqdK_I/AAAAAAAAAIA/UmBRih1YnGg/s1600/tree000.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-jgKRy3wECPE/TV9edjqdK_I/AAAAAAAAAIA/UmBRih1YnGg/s1600/tree000.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The Pascal file is named TREE.$00. If a sprite has multiple states, as is the case for animated object, the extension is incremented, e.g. TREE.001 and TREE.$01. Sprites will be included as an include file in FIGURES.PAS:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{$I Tree.$00} {$I Tree.$01} {$I Tree.$02} {$I Tree.$03}&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;The point here is to store all sprites and level information into the code section, not the data section, of the program. The data segment in Pascal program can only contain up to 64K of data, and the game may grow beyond that. If slow read speed (earlier games ran on floppy disk) and having the game in multiple files was not an issue, an alternative would have been to store the data as external file. &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Code would then be written to access the disguised data stored in the code segment by means of procedures consisting entirely of DB directives. The following will draw TREE000 at the specified location:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;PutImage (XPos, YPos, W, H, &lt;/span&gt;TREE000&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;^);&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: inherit;"&gt;PutImage is defined in VGA256.PAS:&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;procedure PutImage (XPos, YPos, Width, Height: Integer; var BitMap);&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;b&gt;Level data&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;As mentioned in README.TXT, there is no level editor for this game. All levels are coded in WORLDS.PAS:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/-Ss7yClLVzvQ/TV9i5DdcRFI/AAAAAAAAAII/0yUzMrW5nXM/s1600/levelpas.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-Ss7yClLVzvQ/TV9i5DdcRFI/AAAAAAAAAII/0yUzMrW5nXM/s320/levelpas.png" width="235" /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;A typical level consists of 2 procedures, a level data file (Level_1a) and an option files (Options_1a). Similar to sprites, they are just assembler procedures having only DB directives to store data. The option file will define how the level data will be interpreted. Take a look at Intro_0 and Options_0, for the 'intro' level, which is the background shown behind the selection menu:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://2.bp.blogspot.com/-umf_uX5S8TA/TV9j0VjJIBI/AAAAAAAAAIM/NIqiLpKLAmM/s1600/level0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-umf_uX5S8TA/TV9j0VjJIBI/AAAAAAAAAIM/NIqiLpKLAmM/s320/level0.png" width="210" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/-G6l99Nxz2lg/TV9j6uEke9I/AAAAAAAAAIQ/EVOMT0TsEt0/s1600/options0.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="234" src="http://1.bp.blogspot.com/-G6l99Nxz2lg/TV9j6uEke9I/AAAAAAAAAIQ/EVOMT0TsEt0/s320/options0.png" width="320" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/-umf_uX5S8TA/TV9j0VjJIBI/AAAAAAAAAIM/NIqiLpKLAmM/s1600/level0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Ss7yClLVzvQ/TV9i5DdcRFI/AAAAAAAAAII/0yUzMrW5nXM/s1600/levelpas.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Each assembler directive defines each vertical portion of the screen. One DB is a string of 13 characters. Each character defines an object on the screen, from bottom to top. The character 0 marks the end of a level (e.g. DB 0). The same character may be interpreted differently in different levels if the level options are different - see function ReDraw() in FIGURES.PAS. All level data will be loaded into variable WorldMap (found in BUFFERS.PAS) using ReadWorld(). Some levels may have certain pipes where Mario can dive in to enter a different area - these are defined as sub levels, for example, see Level_1b. &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;b&gt;A modern approach&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;With some free time at hand, I decided to try out and see how the level data can be re-used to display an overview of each level, without re-writing everything from scratch. My first task is to save the sprites as an image file, which was easy since the GRED file format is documented. It wasn't long before I managed to write a tool in VB.NET that loads a sprite binary file and display in a PictureBox:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/--Wk92y5Bdcs/TV9nPzg2yfI/AAAAAAAAAIY/1s2p4GPMjLE/s1600/spriteview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="206" src="http://3.bp.blogspot.com/--Wk92y5Bdcs/TV9nPzg2yfI/AAAAAAAAAIY/1s2p4GPMjLE/s320/spriteview.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Xt6GoCev9Ks/TV9nI9YuQGI/AAAAAAAAAIU/4IyEU5JVpi8/s1600/spriteview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;All sprites will then be converted to VB.NET resources. The next challenge would be to export the level data. Based on function PlayWorld in WORLDS.PAS, I wrote my LVL2BIN.PAS which exports all level data to a binary file (*.LVL):&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-53CnklKIH-w/TV9n6B0u17I/AAAAAAAAAIc/Wb5DmYGGe0A/s1600/lvl2bin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-53CnklKIH-w/TV9n6B0u17I/AAAAAAAAAIc/Wb5DmYGGe0A/s1600/lvl2bin.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;It is used as follows:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WriteLevelToBin(@Level_1a^, 'Level1a.LVL');&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;For the&lt;/span&gt; level options, to facilitate modifications, I did not export it to binary file, but instead convert to an XML file:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-79XTjx2t3rs/TV9ooY-BSfI/AAAAAAAAAIg/PtL-bRiByvU/s1600/lvloptions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-79XTjx2t3rs/TV9ooY-BSfI/AAAAAAAAAIg/PtL-bRiByvU/s320/lvloptions.png" width="237" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Most of the code is available from function ReadWorld() in BUFFERS.PAS. I adapted them to VB.NET with some minor modifications to cater for zero-based array index in VB.NET (Pascal supports non-zero-based array) and the lack of &lt;a href="http://en.wikipedia.org/wiki/Pascal_%28programming_language%29#Set_types"&gt;set data types&lt;/a&gt; in VB.NET. For example, the following simple Pascal code:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;var Ch: Set of Char;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;.... &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Ch = [C] + [#1 .. #13]&lt;/span&gt;;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: inherit;"&gt;turns complicated and probably more expensive&lt;/span&gt; in VB.NET - a &lt;a href="http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx"&gt;List&lt;/a&gt; has to be used to emulate a set:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;Dim Ch As New List(Of Char)&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;Ch.Add(C)&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;For i As Integer = 1 To 13&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;If Not Ch.Contains(Chr(i)) Then Ch.Add(Chr(i))&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Next&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;The following shows the level viewer in actions. it reads level data (.LVL) and options (.XML) and display it on screen:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-RhFVSE_Mjw0/TV9qwxLKevI/AAAAAAAAAIk/YfcJhyT8Z8o/s1600/lvlviewer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="312" src="http://1.bp.blogspot.com/-RhFVSE_Mjw0/TV9qwxLKevI/AAAAAAAAAIk/YfcJhyT8Z8o/s400/lvlviewer.png" width="400" /&gt; &lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;(For simplicity, enemies and background are not yet drawn)&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;When I was writing the code, there was something which surprised me. Despite the different look of the bricks between intro level (level 0) and level 2 (see image below), they actually come from the same sprite (BRICK0.000).&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/--WKbMm72hV8/TV9r97ORQiI/AAAAAAAAAIo/ITl5vLRmqCc/s1600/level2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="246" src="http://4.bp.blogspot.com/--WKbMm72hV8/TV9r97ORQiI/AAAAAAAAAIo/ITl5vLRmqCc/s400/level2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;The tricks are in the following 2 functions in FIGURES.PAS:&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;procedure ReColor (P1, P2: Pointer; C: Byte);&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;procedure ReColor2 (P1, P2: Pointer; C1, C2: Byte);&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Both were written in assembly:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-29BePM0E4fc/TV9shVpnjvI/AAAAAAAAAIs/8lqPdYj0DZQ/s1600/recolor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://2.bp.blogspot.com/-29BePM0E4fc/TV9shVpnjvI/AAAAAAAAAIs/8lqPdYj0DZQ/s400/recolor.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;All that the seeming complicated assembler code above will do is to loop through every pixel in the image and modify its color by 1 (for ReColor) or 2 (for ReColor2) constants to make the new image look different. This allows the same image to be used for 2 different levels yet still look different. I converted both of them to VB.NET:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; text-align: left;"&gt;Private Function ReColor(ByVal fig As Bitmap, ByVal factor As Integer) As Bitmap&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Private Function ReColor2(ByVal fig As Bitmap, ByVal factor1 As Integer, ByVal factor2 As Integer) As Bitmap&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;However, despite using the exact same constant and same color palette, my resulting display of level 2 does not look exactly the same:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-2Qh1ePY-j4o/TV9tlBn47LI/AAAAAAAAAIw/siuyOA6T8GI/s1600/lvl2viewer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="312" src="http://2.bp.blogspot.com/-2Qh1ePY-j4o/TV9tlBn47LI/AAAAAAAAAIw/siuyOA6T8GI/s400/lvl2viewer.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;I am unable to locate the exact problem and can only assume it's due to something I might have overlooked.&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;At this point I can proceed to draw the background, animated sprites (turtles, fish, ...) and implement the proper game if I want. &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;b&gt;Easter eggs &lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;The game has some Easter eggs which can be found in PLAY.PAS. To activate cheat mode, press P to pause the game, then press TAB. Pressing 2305 while in cheat mode will get you through the next level. Also if you prefer to play in grayscale, press MONO:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/--dK4VZbD6v8/TV9v0UeagzI/AAAAAAAAAI0/p9BZMODOTR8/s1600/lvl2mono.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="253" src="http://2.bp.blogspot.com/--dK4VZbD6v8/TV9v0UeagzI/AAAAAAAAAI0/p9BZMODOTR8/s400/lvl2mono.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;b&gt;Similar games: Charlie the Duck, Charlie II and Super Angelo&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;According to Wiering Software, these 3 games are developed based on the original Mario source code; however, their source code was never released. Charlie II (my favorite game) also has a Windows version which was perhaps written in C++. As of 2011, it's pretty clear that no future DOS versions of these games will ever be created, and any future version will perhaps only be in Flash. Click &lt;a href="http://www.wieringsoftware.nl/flash/charlie/"&gt;here&lt;/a&gt; and &lt;a href="http://www.wieringsoftware.nl/flash/angelo/"&gt;here &lt;/a&gt;if you want to try out. Nevertheless, I hope this article will be useful for those who want to port the game to other platforms, or to learn something about game development in Pascal.&lt;br /&gt;&lt;br /&gt;By the way, if you're playing Charlie II and receive an error  "Unexpected error no XXXX, please contact Wiering Software", don't think  it's a bug with the game. Most likely you're using an activation key  generated by a crack tool which does not satisfy all the requirements.  In this &lt;a href="http://forums.indiegamer.com/archive/index.php?t-2104.html"&gt;discussion&lt;/a&gt;, Mike Wiering said that several checkings of the activation code are done at various places using various different algorithms in the game and a cracker may not have located all those places. So if you got the error, simple try a different key.&lt;br /&gt;&lt;br /&gt;The full .NET source code to convert sprites and view the levels can be downloaded &lt;a href="http://dl.dropbox.com/u/5881137/MarioTest.zip"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;References:&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://www.identicalsoftware.com/ogs/2001/mario.html"&gt;Open Game Source: Mario Clone&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://www.wieringsoftware.nl/coding/"&gt;Wiering Software - Creating Games&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://www.wieringsoftware.eu/2007/01/platform-games-in-flash/"&gt;Using haXe for Platform Games&lt;/a&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6077451791501947290?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6077451791501947290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2011/01/programming-nostalgia-revisiting-mike.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6077451791501947290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6077451791501947290'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2011/01/programming-nostalgia-revisiting-mike.html' title='Programming Nostalgia: revisiting Mike Wiering&apos;s Mario game written in Pascal'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-ce_86d0lEeM/TV8w5DwU4PI/AAAAAAAAAH0/J1KorWSO_wI/s72-c/mario.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-5934740430658257656</id><published>2010-12-20T20:49:00.000-08:00</published><updated>2010-12-20T21:57:05.576-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Embedded'/><title type='text'>Relisys RWT200EM (Exilis TR333) Thin Client</title><content type='html'>A few months ago I was given a Relisys RWT200EM (also known as Exilis TR333) thin client (see detailed specs and review &lt;a href="http://www.parkytowers.me.uk/thin/RelisysRWT200EM/index.shtml"&gt;here&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAlQoeQRxI/AAAAAAAAAF0/5Kc6Ep25MwU/s1600/31572-sl1mou_l.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAlQoeQRxI/AAAAAAAAAF0/5Kc6Ep25MwU/s1600/31572-sl1mou_l.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I was expecting to "jailbreak" the thin client and get to install some  sort of OS (DOS, Linux, early version of Windows on it). However, upon  further testing, my disappointment soon came.&lt;br /&gt;&lt;br /&gt;The &lt;span class="highlight"&gt;thin&lt;/span&gt; &lt;span class="highlight"&gt;client&lt;/span&gt; was manufactured by Exilis (also known as Relisys RWT200EM, see &lt;a href="http://www.parkytowers.me.uk/thin/RelisysRWT200EM/index.shtml" rel="nofollow" target="_blank"&gt;Relisys &lt;span class="highlight"&gt;Thin&lt;/span&gt; &lt;span class="highlight"&gt;Client&lt;/span&gt;&lt;/a&gt;) as shown in the splash screen:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRAl82JPHXI/AAAAAAAAAF4/PzL2km_gT0Q/s1600/IMG_20101204_130736.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRAl82JPHXI/AAAAAAAAAF4/PzL2km_gT0Q/s320/IMG_20101204_130736.jpg" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It was re-branded by &lt;a href="http://www.toaei.com/"&gt;TOA E&amp;amp;I&lt;/a&gt;, a Singapore company, and manufactured in 2000 as shown in the about page:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TRAqqAj1VKI/AAAAAAAAAGM/5Rv6f98E4Zk/s1600/about_client.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TRAqqAj1VKI/AAAAAAAAAGM/5Rv6f98E4Zk/s320/about_client.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;All it will do is to boot up to a Windows CE Remote Desktop &lt;span class="highlight"&gt;client&lt;/span&gt;:&lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAmPviQGyI/AAAAAAAAAGA/ukoZCGyFkZc/s1600/IMG_20101204_130625.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAmPviQGyI/AAAAAAAAAGA/ukoZCGyFkZc/s320/IMG_20101204_130625.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Upon pressing F2 to enter terminal settings, it prompts me for a password. I tried all default passwords and common passwords, only to be replied with an error message. I guess whoever last used the client has set an unknown password.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TRApl95T22I/AAAAAAAAAGE/bIcTyjvFqSc/s1600/wrong_password.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="100" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TRApl95T22I/AAAAAAAAAGE/bIcTyjvFqSc/s320/wrong_password.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Without the password, the connection settings cannot be changed. And the default connection settings is so odd that the client won't connect via a normal network using DHCP:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TRAqKlPbRHI/AAAAAAAAAGI/1AxlhWZNM6A/s1600/network_settings.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TRAqKlPbRHI/AAAAAAAAAGI/1AxlhWZNM6A/s320/network_settings.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;About the only way to get this unit to do something is use a router and setup a network with the expected parameters, then create a remote desktop session from the client to other computers in the network, which seems pretty useless.&lt;br /&gt;&lt;br /&gt;The keyboard settings follow Windows CE standard:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRAq9Wzxe2I/AAAAAAAAAGQ/--LFGGnG6QA/s1600/keyboard_settings.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRAq9Wzxe2I/AAAAAAAAAGQ/--LFGGnG6QA/s320/keyboard_settings.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It supports up to 1280x1024 @ 60Hz display resolution. However, changing the resolution again asks me for the password,which I do not know:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TRArorkwcOI/AAAAAAAAAGY/RDc8Mo5atwU/s1600/display_settings.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TRArorkwcOI/AAAAAAAAAGY/RDc8Mo5atwU/s320/display_settings.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRArPhl_bMI/AAAAAAAAAGU/KPqaivQaDQ0/s1600/display_settings.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;Apparently it supports remote firmware update if the correct password is provided. Where to find firmware, I don't know:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRArrW9HVGI/AAAAAAAAAGc/Z7nfIjdceQc/s1600/firmware_update.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRArrW9HVGI/AAAAAAAAAGc/Z7nfIjdceQc/s320/firmware_update.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Again, the password cannot be changed if the original password is not provided:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRAr6zRjghI/AAAAAAAAAGg/hGrO57VldY8/s1600/change_password.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TRAr6zRjghI/AAAAAAAAAGg/hGrO57VldY8/s320/change_password.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;All this seems to be a dead end. I tried to enter the BIOS to see if there's an option to reset the password there. The website provided at the beginning of this article suggests pressing F1 to enter BIOS,which doesn't work. What works is to connect a  PS2 keyboard (a USB keyboard is only detected by Windows CE and not by BIOS) and press DEL repeatedly AFTER the power button is pressed  but BEFORE the text "Starting System... please wait" appears. Pressing  F1 during the "Starting system" phase will hang the boot process, with  the keyboard still responsive - pressing Ctrl-Alt-DEL again will reboot  the set. Probably reserved for some recovery ROM, etc. which was never  implemented.&lt;br /&gt;&lt;br /&gt;The unit is using the standard PC award BIOS:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAssZEruqI/AAAAAAAAAGk/cTTc8VDWCLk/s1600/bios_setup.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAssZEruqI/AAAAAAAAAGk/cTTc8VDWCLk/s320/bios_setup.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Much like a PC BIOS, this bios has options to detect hard disks and set up floppy disk drives:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TRAt0csVOmI/AAAAAAAAAGo/zItIX3teHPY/s1600/disk_setup.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TRAt0csVOmI/AAAAAAAAAGo/zItIX3teHPY/s320/disk_setup.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;The motherboard also has empty connectors to solder an IDE connector (and also floppy connector, not shown)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TRAu0RQOTgI/AAAAAAAAAGs/qxaDL7g2egM/s1600/connector_back.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAu0yzCfeI/AAAAAAAAAGw/q0WwvrYxNBk/s1600/connector_front.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAu0yzCfeI/AAAAAAAAAGw/q0WwvrYxNBk/s320/connector_front.jpg" width="320" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TRAu0RQOTgI/AAAAAAAAAGs/qxaDL7g2egM/s1600/connector_back.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TRAu0RQOTgI/AAAAAAAAAGs/qxaDL7g2egM/s320/connector_back.jpg" width="320" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAu0yzCfeI/AAAAAAAAAGw/q0WwvrYxNBk/s1600/connector_front.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;/div&gt;I guess luck was not on my side. Unlike the website author's unit which has empty connector holes, my holes are pre-filled with existing solder. I tried with a 60W soldering iron to clear the solder from the holes but the temperature was not hot enough to melt the solder. The same thing applies for the floppy connector. So installing a hard disk or a floppy disk is out of the question.&lt;br /&gt;&lt;br /&gt;I also tried booting from USB or LAN without success. The only option now would have been to upgrade the firmware on board.  The Windows CE firmware is stored on a 16MB M-System DiskOnChip 2000.  Up to 64MB DOC is available on eBay. However, no programmer/reader for  these DOC seems publicly available. My research reveals the following possible methods to read/write the DOC, none of which I can do myself:&lt;br /&gt;&lt;br /&gt;1. You can use an old ISA network card, enable Boot ROM, insert the DOC  to the socket on the network card. The system can boot from the DOC and  see it as a disk drive.&lt;br /&gt;&lt;br /&gt;My system does not have an ISA slot and I do not have any ISA network card.&lt;br /&gt;&lt;br /&gt;2. Build your own ISA card to access the DOC. I found the PCB &lt;a href="http://www.electronicsinfoline.com/Top_Picks/Computer_Projects/an_isa_card_for_the_diskonchip_2000.shtml" target="_blank"&gt;here&lt;/a&gt; but however no schematics or software is provided.&lt;br /&gt;&lt;br /&gt;3. Use the DOC evaluation board (available for ISA and PCI), see &lt;a href="http://media.digikey.com/pdf/Data%20Sheets/M-Systems%20Inc%20PDFs/PCI-G%20Eval%20Board.pdf" target="_blank"&gt;this&lt;/a&gt; and &lt;a href="http://www.tri-m.com/products/sandisk/files/manual/isafor3vdip_man.pdf" target="_blank"&gt;this&lt;/a&gt;. However, it seems that the evaluation board is no longer in production (M-Systems was eventually taken over by Sandisk)&lt;br /&gt;&lt;br /&gt;4. Use a programmer. A user guide is available &lt;a href="http://tigger.smu.edu.sg/software/nanocube/cd.orig/Disk_On_Chip/M-Sys/Manuals_doc_UM_DIMM2000_GANG_B-4.2.pdf" target="_blank"&gt;here&lt;/a&gt; but it seems the programmer is rather expensive. It is also unknown to me how to create the image to be programmed.&lt;br /&gt;&lt;br /&gt;5. There seems to be an SDK of some sort for the M-Systems DiskOnChip 2000 such as &lt;a href="http://download.cnet.com/M-Systems-DiskOnChip-2000/3000-2110_4-69955.html" target="_blank"&gt;this&lt;/a&gt; but there seems to be no good tutorial.&lt;br /&gt;&lt;br /&gt;With all possible methods leading to a dead end, I decided to give up on the unit, package it and find someone who is willing to buy it. The board also does not have a lot of components useful for hobby projects. Among these few are a speaker and some audio/LAN connectors but the time taken to desolder these components would definitely outweigh any savings they may offer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-5934740430658257656?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/5934740430658257656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/12/relisys-rwt200em-exilis-tr333-thin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5934740430658257656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5934740430658257656'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/12/relisys-rwt200em-exilis-tr333-thin.html' title='Relisys RWT200EM (Exilis TR333) Thin Client'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TRAlQoeQRxI/AAAAAAAAAF0/5Kc6Ep25MwU/s72-c/31572-sl1mou_l.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6777779610085826722</id><published>2010-12-02T21:02:00.000-08:00</published><updated>2010-12-31T23:08:56.393-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Casio PB-700 and FA-11 Printer &amp; Tape Recorder</title><content type='html'>I recently acquired an New Old Stock (&lt;a href="http://en.wikipedia.org/wiki/New_old_stock"&gt;NOS&lt;/a&gt;) &lt;a href="http://pocket.free.fr/html/casio/pb-700_e.html"&gt;Casio PB-700&lt;/a&gt; with the &lt;a href="http://pocket.free.fr/html/casio/fa-11_e.html"&gt;FA-11&lt;/a&gt; printer &amp;amp; tape recorder and an &lt;a href="http://pocket.free.fr/html/casio/or-4_e.html"&gt;OR-4 &lt;/a&gt;memory module (4KB) from an eBay &lt;a href="http://myworld.ebay.com.sg/shamram_singh/"&gt;seller&lt;/a&gt; for a very cheap price. I know sometimes it's fun to play with old technology, and this article will share some of my findings.&lt;br /&gt;&lt;br /&gt;The PB-700 packaging is still intact ever since 1984:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR66c1fEboI/AAAAAAAAAG4/52_HfvtzH1g/s1600/PB-700+box.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR66c1fEboI/AAAAAAAAAG4/52_HfvtzH1g/s320/PB-700+box.jpg" width="235" /&gt;&lt;/a&gt;&lt;/div&gt;And so is the printer box. The left one is the paper cover, the right one is the plastic container for the printer and&amp;nbsp; accessories:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR66ucp4hNI/AAAAAAAAAG8/afrjojdG3Fs/s1600/Fa-11++box.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="282" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR66ucp4hNI/AAAAAAAAAG8/afrjojdG3Fs/s320/Fa-11++box.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The user manuals for the two units:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TR665CeAPjI/AAAAAAAAAHA/cGmTAcrAFD8/s1600/all+user+manual.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="233" src="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TR665CeAPjI/AAAAAAAAAHA/cGmTAcrAFD8/s320/all+user+manual.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The scanned PDF copy can be downloaded from &lt;a href="http://www.usersmanualguide.com/casio/calculators/pb-700"&gt;here &lt;/a&gt;(for PB-700) and &lt;a href="http://www.ledudu.com/images/pockets/casio/broche/fa11.pdf"&gt;here&lt;/a&gt; (for FA-11). More user manuals of similiar early computers can be downloaded &lt;a href="http://www.ledudu.com/pockets.asp?type=127&amp;amp;serie=20&amp;amp;lg=eng"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However, when I first powered up the set, it did not work properly. The PB-700 LCD was not displaying properly (perhaps due to aging). The computer still seemed functional and responded to  basic command such as BEEP.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TR68NTUYymI/AAAAAAAAAHE/jheWbQoamPA/s1600/spoilted+LCD.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TR68NTUYymI/AAAAAAAAAHE/jheWbQoamPA/s320/spoilted+LCD.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The FA-11 did not seem to power up at all. Perhaps the rechargable battery inside the unit had died due to aging. I tried to leave it charging for 2 days and it still could not turn on. The AC adapter provided 8.5V, way beyond its specifications of 6V DC output. Some research suggests that the AC adapter is unregulated, so it may produce higher voltage when no load is applied. Whatever it was, the seller was nice enough to exchange a working set for me.&lt;br /&gt;&lt;br /&gt;This time everything is working - the LCD is fine and the printer is able to print, although with difficulty (more on that later). The following photo shows the complete setup:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR69BB0p0kI/AAAAAAAAAHI/puV67wwWxeE/s1600/complete+setup+with+printer+output.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="273" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR69BB0p0kI/AAAAAAAAAHI/puV67wwWxeE/s320/complete+setup+with+printer+output.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;My first "&lt;a href="http://en.wikipedia.org/wiki/Hello_world_program"&gt;Hello World&lt;/a&gt;" program on this device works fine, so I attempt to write a program to plot the graph of a sine wave. Luckily a sample is given in the user manual:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR69pYdZAfI/AAAAAAAAAHM/PSPHPCgCGPU/s1600/sine+wave+program+from+user+manual.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR69pYdZAfI/AAAAAAAAAHM/PSPHPCgCGPU/s640/sine+wave+program+from+user+manual.jpg" width="402" /&gt;&lt;/a&gt;&lt;/div&gt;Take note that the line numbers must be keyed into the actual program. They are not there just for demonstration. If you don't key in the line number, many control commands (FOR, WHILE, IF) will not work.&lt;br /&gt;&lt;br /&gt;It took me 10 minutes to key in this program and modify it slightly to display the graph title. Here is the execution result:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR691FIoOZI/AAAAAAAAAHQ/7m0UgUarRio/s1600/sine+wave+graph.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="243" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR691FIoOZI/AAAAAAAAAHQ/7m0UgUarRio/s320/sine+wave+graph.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If you have never worked with early computers before, you''ll be surprised at the execution speed. The following video shows you why:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe frameborder="0" height="344" src="http://www.youtube.com/embed/kz1OvQonp80?fs=1" width="425"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;It takes 20 seconds to plot the graph - you can literally see every pixels being drawn. Nowadays, modern computer can plot this graph in less than a second.&lt;br /&gt;&lt;br /&gt;My next try is to use a FOR loop with LPRINT to repeatedly print text to test the printer. The following video shows the printer in action:&lt;br /&gt;&lt;br /&gt;&lt;iframe frameborder="0" height="344" src="http://www.youtube.com/embed/6riRoc5p45w?fs=1" width="425"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;It takes around 3 seconds to finish printing a single line of text, a slow speed thanks to the pen assembly. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR6_Pp7mgbI/AAAAAAAAAHU/dPI-kQmwFo4/s1600/pen+assembly.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="207" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR6_Pp7mgbI/AAAAAAAAAHU/dPI-kQmwFo4/s320/pen+assembly.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;There are a total of 4 pens, supporting 4 different colors. The horizontal stepper motor moves the pen assembly from left to right, a rotor will rotate the assembly to select the correct color, and a pin will push the required pen, touching the paper thus "plotting" the required text onto the screen. A very sophisticated piece of engineering! Unfortunately, this is an &lt;a href="http://en.wikipedia.org/wiki/Open-loop_controller"&gt;open-loop system&lt;/a&gt; - the printer does not have any ideas whether the pen assembly is correctly aligned. After a while, the pen assembly will no longer be calibrated causing the pen not to touch the paper and nothing will be printed. When this happens, I will have to stop the printing process and re-align. With care, the re-alignment can be done during printing when the pen assembly moves closer to the right.&lt;br /&gt;&lt;br /&gt;Here is the printer output:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR7AeS-qWsI/AAAAAAAAAHY/d7LC0VFBcoo/s1600/printer+output+close+view.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="189" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR7AeS-qWsI/AAAAAAAAAHY/d7LC0VFBcoo/s320/printer+output+close+view.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Because the pen slightly touches the paper when it moves from right to left during a carriage return and line feed, every line is underlined! The spacing between the lines is also not exactly equal thanks to the paper roller which doesn't care what happens to the paper during rolling. I am not sure if this is how the quality is supposed to be. Or perhaps I have an old unit...&lt;br /&gt;&lt;br /&gt;My next try is to use the tape recorder to read and write programs:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TR7BRPAK5wI/AAAAAAAAAHc/ygK1vusxzKg/s1600/cassette+assembly.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="214" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TR7BRPAK5wI/AAAAAAAAAHc/ygK1vusxzKg/s320/cassette+assembly.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The tape is just the normal cassette tape, used in the days of the &lt;a href="http://en.wikipedia.org/wiki/Walkman"&gt;Walkman&lt;/a&gt;. Program are stored as audio tones, with different tones for binary 0 and binary 1. Some more information is available &lt;a href="http://www.pisi.com.pl/piotr433/fa2.htm#fa4"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This is a closer look at the cassette tape. Interestingly, the tape comes with the erase prevention tab removed (thus the REC button can't be pressed). I have to put some paper in the holes to allow recording.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR7BvR8EfMI/AAAAAAAAAHg/CI1W6saWgP4/s1600/cassette+close+view.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="206" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR7BvR8EfMI/AAAAAAAAAHg/CI1W6saWgP4/s320/cassette+close+view.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Using the &lt;b&gt;SAVE &lt;/b&gt;command will store the current program as tones on the tape, to be retrieved later. The recorder plays the tones to be recorded during the process, making a sound similar to a dial-up modem connecting. Download the audio &lt;a href="http://dl.dropbox.com/u/5881137/FA-11%20recorder%20tone.mp3"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Unfortunately, I am unable to read back the saved program using the &lt;b&gt;LOAD&lt;/b&gt; command. The command simply hangs and I have to stop it. The recorder plays the tones of the saved program, which sound significantly different from what was recorded. Perhaps the audio head has malfunctioned due to aging, or the magnetic tape has degraded over the years and no longer suitable for recording.&lt;br /&gt;&lt;br /&gt;Hope you will learn something new about old computer technology after reading this article. Except for having fun while testing it, the unit is not very useful to me. I have not even figured out how to insert a new line when editing a program (it's not mentioned in the manual). Therefore, after writing this article, the unit will probably soon be put in my closet. &lt;br /&gt;&lt;br /&gt;More technical information about the Casio PB-700 computer series and accessories is available &lt;a href="http://www.pisi.com.pl/piotr433/index.htm#pb700"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6777779610085826722?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6777779610085826722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/12/casio-pb-700-and-fa-11-printer-tape.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6777779610085826722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6777779610085826722'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/12/casio-pb-700-and-fa-11-printer-tape.html' title='Casio PB-700 and FA-11 Printer &amp; Tape Recorder'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR66c1fEboI/AAAAAAAAAG4/52_HfvtzH1g/s72-c/PB-700+box.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-5904952479396931377</id><published>2010-11-30T23:29:00.000-08:00</published><updated>2011-08-27T21:45:26.466-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS'/><category scheme='http://www.blogger.com/atom/ns#' term='VmWare'/><title type='text'>iPhone SDK on Mac OS X 10.6.4 under VmWare - Tips and Tricks</title><content type='html'>This articles describes some common problems when using running Mac OS X 10.6.4&amp;nbsp; under VmWare using the instructions from my previous &lt;a href="http://minhdanh2002.blogspot.com/2010/10/iphone-sdk-on-mac-os-x-1064-under.html"&gt;post&lt;/a&gt;&amp;nbsp;and provides possible solutions/workarounds.&lt;br /&gt;&lt;br /&gt;1. If you get an "rtclock_init panic" (shown below) and the system hangs while booting up:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TM-O11-yqKI/AAAAAAAAAFw/gse8kXePrAo/s1600/rtclock_init.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="496" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TM-O11-yqKI/AAAAAAAAAFw/gse8kXePrAo/s640/rtclock_init.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;press TAB at the Chameleon bootloader, select the Mac partition and enter -v busratio=18. OSX should then be able to boot. To make the busratio=18 permanent,&amp;nbsp; edit /Library/Preferences/SystemConfiguration/com.apple.Boot.plist using nano/pico from Terminal (remember to do &lt;b&gt;su/sudo&lt;/b&gt; to get admin right first), then look for the Kernel Flags section (add it in if it's not there). The final plist should look like the following:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt; &amp;lt;key&amp;gt;Kernel Flags&amp;lt;/key&amp;gt;&lt;br /&gt;  &lt;br /&gt; &amp;lt;string&amp;gt;-v busratio=18&amp;lt;/string&amp;gt;  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Other useful&amp;nbsp;bootloader parameters:&lt;br /&gt;&lt;b&gt;-v:&lt;/b&gt; verbose mode, which will show all boot messages on the screen. Without this you will only see the loading logo while booting up.&lt;br /&gt;&lt;b&gt;-x&lt;/b&gt;: boot in safe mode. Only kext critical for the system will be loaded.&lt;br /&gt;&lt;b&gt;-s:&lt;/b&gt; boot into single user mode, e.g. command line only.&lt;br /&gt;&lt;b&gt;acpi=off:&lt;/b&gt; turn off ACPI support.&lt;br /&gt;&lt;b&gt;cpus=1:&lt;/b&gt; tell the virtual machine to boot with only 1 CPU. &lt;br /&gt;&lt;b&gt;-x32&lt;/b&gt; or &lt;b&gt;arch=i386&lt;/b&gt;: boot in 32-bit mode&lt;br /&gt;&lt;br /&gt;2. You may notice that some graphics applications won't be able to display graphics properly. In particular, the &lt;b&gt;Preview&lt;/b&gt; application won't be able to display images, and pressing Apple-Shift-3 or Apple-Shift-4 (Apple key is mapped to Windows key) to capture screenshot will just return an empty black image. This is due to the lack of &lt;a href="http://www.insanelymac.com/forum/index.php?showtopic=24431"&gt;QE/CI&lt;/a&gt; support on the graphics card emulated by VmWare. Unfortunately, I found no workaround for it. &lt;br /&gt;&lt;br /&gt;3. By default, the Apple key will map to the Windows key. If you want to map it something else (for example, the Alt key), follow the following steps:&lt;br /&gt;&lt;br /&gt;* Go to System Preferences &amp;gt; Keyboard &amp;gt; Modifier keys&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://doenges.fluidhosting.com/blog/wp-content/uploads/systempreferences-keyboardmouse-keyboard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="287" n4="true" src="https://doenges.fluidhosting.com/blog/wp-content/uploads/systempreferences-keyboardmouse-keyboard.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;* Switch option key to command key (dropdown) and command key to option key (dropdown) - optional&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_4lqpYueSvbA/TFTRtxHy9kI/AAAAAAAAABs/nOYvtD_o8OI/s1600/change_microsoft_layout_to_apple.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="224" n4="true" src="http://4.bp.blogspot.com/_4lqpYueSvbA/TFTRtxHy9kI/AAAAAAAAABs/nOYvtD_o8OI/s320/change_microsoft_layout_to_apple.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;4. For some reasons the hard disk image will be corrupted after some activity, and the virtual machine could not boot up, showing the following hard disk error: &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR7cXhc3BLI/AAAAAAAAAHo/dv0YOW-GBf8/s1600/vmware_mac_bootfail.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" n4="true" src="http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TR7cXhc3BLI/AAAAAAAAAHo/dv0YOW-GBf8/s1600/vmware_mac_bootfail.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I have not found out the root cause of this and therefore could not find any fix. A workaround is to set up a perfect working virtual machine that requires no further changes and set up the hard disk as non-persistent, which will discard all changes upon shutdown as per the following screenshot:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://communities.vmware.com/servlet/JiveServlet/downloadImage/2-1636229-11287/75-75/HDIndyNonpers.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="393" n4="true" src="http://communities.vmware.com/servlet/JiveServlet/downloadImage/2-1636229-11287/75-75/HDIndyNonpers.JPG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;You may also want to add another persistent hard disk to virtual machine and only make change to the added hard disk. The main hard disk remains non-persistent. Alternatively, once you get the machine working as desired, take a snapshot and revert back to it should any problem occur.&lt;br /&gt;&lt;br /&gt;5. To get sound working, install &lt;a class="name" href="http://sourceforge.net/projects/vmsvga2/files/Audio/EnsoniqAudioPCI_v1.0.3_Common_Installer.pkg/download" title="Click to download EnsoniqAudioPCI_v1.0.3_Common_Installer.pkg"&gt;EnsoniqAudioPCI_v1.0.3_Common_Installer.pkg&lt;/a&gt; and reboot the virtual machine. Software updates will also work fine and I have used it to update successfully to 10.6.8 without any hassle.&lt;br /&gt;&lt;br /&gt;I hope this helps those with similar problems. I will add to this list any other tricks that may be useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-5904952479396931377?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/5904952479396931377/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/11/iphone-sdk-on-mac-os-x-1064-under.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5904952479396931377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5904952479396931377'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/11/iphone-sdk-on-mac-os-x-1064-under.html' title='iPhone SDK on Mac OS X 10.6.4 under VmWare - Tips and Tricks'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_w4YbCKQ5wkQ/TM-O11-yqKI/AAAAAAAAAFw/gse8kXePrAo/s72-c/rtclock_init.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2202385095074262952</id><published>2010-11-18T19:28:00.000-08:00</published><updated>2010-12-20T21:11:11.010-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General Programming'/><title type='text'>Singapore Bus Stop Database</title><content type='html'>Attached to this post is something that developers for location-aware applications in Singapore may find useful - the location database of all bus stops in Singapore and the bus route. These databases were created some time back and may not be up-to-date, but should still serve as a good starting point for developers who wish to have local access to bus stop and bus route information without accessing the Internet.&lt;br /&gt;&lt;br /&gt;The bus stop database is XML-formatted, and looks like this&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: url(&amp;quot;http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif&amp;quot;) repeat scroll 0% 0% rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;   &amp;lt;lon&amp;gt;103.671627904274&amp;lt;/lon&amp;gt;  &lt;br /&gt;   &amp;lt;lat&amp;gt;1.30877958711704&amp;lt;/lat&amp;gt;  &lt;br /&gt;   &amp;lt;name&amp;gt;Opp Gul Way&amp;lt;/name&amp;gt;  &lt;br /&gt;   &amp;lt;road&amp;gt;Pioneer Rd&amp;lt;/road&amp;gt;  &lt;br /&gt;   &amp;lt;code&amp;gt;23229&amp;lt;/code&amp;gt;  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;For each bus stop, its geocode (expressed as latitude and longitude), name, road, and code is provided.&lt;br /&gt;&lt;br /&gt;The bus route database is also XML-formatted, and looks like this&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: url(&amp;quot;http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif&amp;quot;) repeat scroll 0% 0% rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;   &amp;lt;busService&amp;gt;002&amp;lt;/busService&amp;gt;  &lt;br /&gt;   &amp;lt;busRoute1&amp;gt;99009 99131 99049 99039 99029 99019 98079 98069 97099 97089 97079 97069 97209 97059 97049 97039 97019 96069 96059 96049 96099 96089 96079 85079 85089 85069 85059 85099 84069 84059 84049 84039 84029 84019 83099 83079 83059 83049 83029 82069 82049 82029 82109 81069 81049 81029 80089 80069 80049 80039 80029 01319 01219 01129 01059 01119 01019 04159 04149 04229 04239 05059 05049 05039 05019 10589&amp;lt;/busRoute1&amp;gt;  &lt;br /&gt;   &amp;lt;busRoute2&amp;gt;10589 10017 05013 05023 04222 04142 01012 01113 01121 01211 01311 80011 80031 80051 80071 80091 81011 81031 81051 82011 82032 82061 83011 83031 83062 83081 84011 84021 84031 84041 84051 84061 85091 85051 85061 85081 85071 96071 96081 96091 96041 96051 96061 97011 97031 97041 97051 97201 97061 97071 97081 97091 98061 98071 99011 99021 99031 99041 99139 99009&amp;lt;/busRoute2&amp;gt;  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Routes are provided in terms of the codes of the bus stops that the bus service calls at. Usually each service has 2 routes (&lt;b&gt;busRoute1 &lt;/b&gt;and &lt;b&gt;busRoute2&lt;/b&gt;), but for looping services, only 1 route is provided.&lt;br /&gt;&lt;br /&gt;Download the XML databases &lt;a href="http://dl.dropbox.com/u/5881137/BusStopDb.rar"&gt;here &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;See also:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://minhdanh2002.blogspot.com/2009/09/google-maps-api-on-windows-mobile.html"&gt;Google Maps API on Windows Mobile&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://minhdanh2002.blogspot.com/2009/11/gotheresgs-location-api.html"&gt;Reverse-engineering gothere.sg API&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2202385095074262952?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2202385095074262952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/11/singapore-bus-stop-database.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2202385095074262952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2202385095074262952'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/11/singapore-bus-stop-database.html' title='Singapore Bus Stop Database'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2161164699473460534</id><published>2010-11-10T23:13:00.000-08:00</published><updated>2010-12-31T23:23:33.231-08:00</updated><title type='text'>My 5V home-made battery</title><content type='html'>Inspired by various posts on how to create a battery from household items, I decided to create my version. here is the result:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://static.electro-tech-online.com/imgcache/10862-img20101231142319.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://static.electro-tech-online.com/imgcache/10862-img20101231142319.jpg" width="267" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;There are a total of 11 cells - 10 slices of lemon and a bowl of Coke. Each cell provides around 0.47V. The 2 electrodes are the aluminum strip from the Coke can, and Singapore $1 coin.&lt;br /&gt;&lt;br /&gt;Although it provides a 5V, the current is only enough to light up an LED briefly. The LED can light up brightly with a single 1.5V AAA cell.&lt;br /&gt;&lt;br /&gt;I posted on &lt;a href="http://electro-tech-online.com/"&gt;electro-tech-online.com&lt;/a&gt;, my favorite electronics forum, and got some interesting replies from other members who have also made similar batteries. This is another version that provides around 2V:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR7U-sGxGyI/AAAAAAAAAHk/eddPaDKbeZA/s1600/49541d1293794326-my-5v-home-made-battery-lemons3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="265" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR7U-sGxGyI/AAAAAAAAAHk/eddPaDKbeZA/s400/49541d1293794326-my-5v-home-made-battery-lemons3.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This is a video showing a lemon battery and a salt-water batter in operation:&lt;br /&gt;&lt;br /&gt;&lt;iframe frameborder="0" height="344" src="http://www.youtube.com/embed/Yx9dMFaUQO4?fs=1" width="425"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;This &lt;a href="http://sci-toys.com/scitoys/scitoys/echem/batteries/batteries.html"&gt;website &lt;/a&gt;shows you how to make a Coke battery that can run a calculator:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://sci-toys.com/scitoys/scitoys/echem/batteries/small_clock.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://sci-toys.com/scitoys/scitoys/echem/batteries/small_clock.jpg" width="265" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://sci-toys.com/scitoys/scitoys/echem/batteries/small_copper_zinc_coke_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;and a battery from Soda water:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://sci-toys.com/scitoys/scitoys/echem/batteries/small_copper_zinc_vinegar_overnight.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="283" src="http://sci-toys.com/scitoys/scitoys/echem/batteries/small_copper_zinc_vinegar_overnight.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2161164699473460534?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2161164699473460534/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/11/my-5v-home-made-battery.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2161164699473460534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2161164699473460534'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/11/my-5v-home-made-battery.html' title='My 5V home-made battery'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TR7U-sGxGyI/AAAAAAAAAHk/eddPaDKbeZA/s72-c/49541d1293794326-my-5v-home-made-battery-lemons3.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-7180688286064201199</id><published>2010-10-29T06:11:00.000-07:00</published><updated>2011-12-21T18:47:52.446-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Tips'/><title type='text'>Dual booting Mac OS X Snow Leopard 10.6.4 and Windows XP on Asus 1000HE netbook</title><content type='html'>This guide shows you how to install both Windows XP and Mac OS X 10.6.4 (retail version) on your Asus 1000HE netbook, with Chameleon bootloader to allow selection between these two OSes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Pre-requisites:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. Asus 1000 HE netbook with 2GB of RAM. Windows XP will work well with 1GB but Mac OS X will boot very slowly, making the whole process pointless.&lt;br /&gt;&lt;br /&gt;2. A USB DVD drive (optional). Although you can install Windows XP and Snow Leopard from USB, certain troubleshooting steps (not mentioned here) will be easier if you have a DVD drive.&lt;br /&gt;&lt;br /&gt;3. Windows XP SP2/SP3 installation CD. You will need to slipstream the Intel ICH7 &lt;a href="http://www.mediafire.com/?mdzjjnndmkvmmir"&gt;drivers &lt;/a&gt;into the original installation CD using &lt;a href="http://www.nliteos.com/"&gt;nLite&lt;/a&gt;, otherwise you'll get a blue screen during installation due to error INACCESSIBLE_BOOT_DEVICE. Read the instructions &lt;a href="http://www.getpcmemory.com/user-guide/how-to-integrate-sata-drivers-into-win-xp-bootable-cd-setup-slipstreaming-xp-guide-using-nlite/"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;4. Mac OS X 10.6.0 and above retail installation DVD. &lt;br /&gt;&lt;br /&gt;5. Mac OS X v10.6.4 Update (Combo) download from &lt;a href="http://support.apple.com/kb/DL1048"&gt;Apple&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;6. Mac OS X 10.6.4 Atom Kernel patch from &lt;a href="http://www.insanelymac.com/forum/index.php?showtopic=197020&amp;amp;st=0"&gt;here.&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;7. A USB keyboard. This is needed as the onboard PS2 keyboard may require extra driver and will not be recognized by OS X after installation.&lt;br /&gt;&lt;br /&gt;You'll also need some other patches and tools described in the section below.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Partition Table: GUID, Prototective MBR and Hybrid MBR&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Before we start, let's get some facts clear first. All Mac OSX versions since 10.6.0 (Snow Leopard) by default will only install on &lt;a href="http://en.wikipedia.org/wiki/GUID_Partition_Table"&gt;GUID partition table&lt;/a&gt; (GPT) as opposed to Windows XP, which only supports booting from &lt;a href="http://en.wikipedia.org/wiki/Master_boot_record"&gt;MBR partition table&lt;/a&gt;. There are ways to make Snow Leopard install on MBR, but in all my attempts I could not get a stable system, so let's stick with GPT.&lt;br /&gt;&lt;br /&gt;GPT provides backwards compatibility with MBR using something known as &lt;b&gt;protective MBR&lt;/b&gt;. With protective MBR, GPT hard disks will appear to non-GPT aware tools as having an unknown partition table, thus preventing these tools from altering and damaging the partition structure.&lt;br /&gt;&lt;br /&gt;Protective MBR is not enough to install Windows XP on a GPT hard disk, so we'll need something called &lt;b&gt;hybrid MBR&lt;/b&gt;. Up to 4 GPT partitions can be added to the hybrid MBR and can be seen by non-GPT aware tools. To create a hybrid MBR, you'll need something like &lt;a href="http://www.rodsbooks.com/gdisk/"&gt;GPT FDisk&lt;/a&gt; (gdisk). Disk Utility on OS X will also write a hybrid MBR by default. There is also another tool called &lt;a href="http://www.insanelymac.com/forum/index.php?showtopic=177505&amp;amp;mode=threaded&amp;amp;pid=1229682"&gt;GPTSync&lt;/a&gt; which is however less flexible and did not work properly in all my attempts.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The bootloader&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Windows XP uses the NT bootloader (&lt;a href="http://en.wikipedia.org/wiki/NTLDR"&gt;NTLDR&lt;/a&gt;) which will not load OS X. For XP and OSX to run smoothly together, we'll need the &lt;a href="http://chameleon.osx86.hu/"&gt;Chameleon 2 &lt;/a&gt;bootloader. Before we continue, you should get familiar with installing the Chameleon bootloader.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Partitioning the hard disk&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Interestingly, Windows XP can only be installed on either the first or the last partition of a hard disk. For this reason, we partition the hard disk as below:&lt;br /&gt;&lt;br /&gt;1. EFI Partition (FAT32). This is where Chameleon 2 bootloader wil be installed.&lt;br /&gt;&lt;br /&gt;2. OSX Partition (Mac OS Extended Journaled). This is where Snow Leopard will be installed.&lt;br /&gt;&lt;br /&gt;3. DATA Partition (optional). This is where we will store all the data to be shared between OSX and Windows XP once the dual boot has been set up. FAT32 (supported by both OS) is recommended. If you use HFS, you'll need &lt;a href="http://www.mediafour.com/products/macdrive"&gt;MacDrive&lt;/a&gt; to access it from Windows. If you use NTFS, you'll need &lt;a href="http://www.tuxera.com/"&gt;NTFS-3G&lt;/a&gt; to access it from Snow Leopard.&lt;br /&gt;&lt;br /&gt;4. WINXP partition (NTFS). This is where Windows XP will be installed.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Installing Snow Leopard&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;There are plenty of guides on the Internet to install Snow Leopard on ASUS 1000HE using &lt;a href="http://code.google.com/p/netbook-installer/"&gt;NetbookBootMaker&lt;/a&gt; so I will not repeat it here. Use the tool to create a USB installer boot disk and follow the guides to install OS X.&lt;br /&gt;&lt;br /&gt;If the Asus 1000HE does not boot from USB, press F2 during startup to enter SETUP.&amp;nbsp; Select the "Boot" menu, select "Boot Device Priority", and move the USB drive to the top of the list. Still under the "Boot" menu, select "Hard Disk Drives", and also move the USB drive to the top of the list. Save changes and your netbook should boot from USB.&lt;br /&gt;&lt;br /&gt;If you get the error "The bless tool was unable to set the current boot disk" at the end of the installation process, ignore it. &lt;br /&gt;&lt;br /&gt;Next, install Chameleon bootloader to EFI partition using this &lt;a href="http://www.ihackintosh.com/2009/04/how-to-install-chameleon-20-rc1/"&gt;guide&lt;/a&gt;. When you reboot, Chameleon should show OSX as one of the partitions and you can boot from it.&lt;br /&gt;&lt;br /&gt;If OSX boots up complaining that it cannot find a keyboard/mouse, connect a USB keyboard first in order to complete the boot process. We will install the driver for onboard keyboard (PS2) later.&lt;br /&gt;&lt;br /&gt;Once Snow Leopard has finished booting, install the 10.6.4 Combo update from Apple. After the installation, it is expected that OSX will no longer boot up, since 10.6.4 does not officially support Intel Atom processor. You will see the following error message:&lt;br /&gt;&lt;br /&gt;&lt;b style="color: #444444;"&gt;panic(cpu 0 caller 0x1c2a7459): "Unsupported CPU: family = 0x6, model = 0x17, stepping = 0x2"@/SourceCache/AppleIntelCPUPowerManagement/AppleIntelCPUPowerManagement-90/pnProcessor.c:210&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You'll need to patch the kernel by booting from the installation media, launch Terminal, and replace the current mach_kernel on the OSX partition with the patched one that you downloaded earlier. &lt;br /&gt;&lt;br /&gt;Once Snow Leopard 10.6.4 has booted up, install the following &lt;a href="http://dl.dropbox.com/u/5881137/ASUS1000HE_SnowLeopard.zip"&gt;kexts &lt;/a&gt;with the help of &lt;a href="http://cheetha.net/"&gt;KextHelper&lt;/a&gt;. This is needed to get the basic hardware working:&lt;br /&gt;&lt;br /&gt;1. Display: AppleIntelGMA950.kext and AppleIntelIntegratedFramebuffer.kext. This is technically the same as the default driver, except that it has been modified to support Intel GMA950 chipset that has 0x27ae as the hardware ID.&lt;br /&gt;&lt;br /&gt;If after installing the kext, OSX boots up to a blue screen, make sure you're using the correct DSDT files for your computer. In the same zip file you downloaded, there are 2 files for 1GB and 2GB of RAM.&lt;br /&gt;&lt;br /&gt;2. Ethernet: install AttansicL1eEthernet.kext&lt;br /&gt;&lt;br /&gt;3. Audio: VoodooHDA.kext and Voodoo.PrefPane. This is taken from &lt;a href="http://www.insanelymac.com/forum/index.php?showtopic=175372"&gt;here &lt;/a&gt;to solve the low volume issues.&lt;br /&gt;&lt;br /&gt;4. Battery Indicator and Power Management: VoodooBattery.kext, VoodooPower.kext, VoodooPowerMini.kext.&lt;br /&gt;&lt;br /&gt;5. Bluetooth: the default installation will support bluetooth but will have problem turning it on or off. to fix this, install IOBluetoothFamily.kext&lt;br /&gt;&lt;br /&gt;6. Onboard mouse or keyboard: please install VoodooPS2Controller.kext.&lt;br /&gt;&lt;br /&gt;7. Card Reader: install VoodooSDHC.kext&lt;br /&gt;&lt;br /&gt;For Wifi to work, you'll need to install the &lt;a href="http://driverscollection.com/?H=RT2860&amp;amp;By=Ralink"&gt;RT2860 &lt;/a&gt;drivers for OS X. This will launch a tool called WirelessUtilityCardBusPCI which scans for Wifi network at startup. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Creating the Hybrid MBR&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Boot from the installation media into Terminal, unmount the disk first and run gdisk. Make sure your device identifier (e.g. /dev/disk0) is correct. Select &lt;b&gt;p &lt;/b&gt;to &lt;b&gt;print the partition table&lt;/b&gt;. Select &lt;b&gt;r &lt;/b&gt;for &lt;b&gt;recovery and transformation options&lt;/b&gt;, follow by &lt;b&gt;h &lt;/b&gt;for &lt;b&gt;make hybrid MBR &lt;/b&gt;and choose to add the Windows XP, OSX and DATA partitions. When prompted to set the boot flags, select NO. (If you select YES, somehow the partition table is corrupted, and Chameleon will hang at "boot0: done" when your system reboots. To recover, you must format the EFI partition as FAT32 and reinstall Chameleon). Finally, type &lt;b&gt;w&lt;/b&gt; to write the hybrid MBR.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Installing &lt;/b&gt;&lt;b&gt;Windows XP&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is straight forward, just keep in mind that Windows XP will install the NTLDR on the first partition that it recognizes, which is the DATA partition. If this happens, after installation is done, you will need to select the DATA partition at the bootloader to boot to Windows XP! To avoid this, during Windows XP installation, format the DATA partition as HFS (you can reformat it to FAT32 later after everything is done).&lt;br /&gt;&lt;br /&gt;After Windows XP is installed, reboot the computer and make sure that Chameleon bootloader can boot to both Windows and OSX. If it can boot to OSX but not to Windows XP, check the boot.ini file on the Windows XP partition to make sure the correct partition number is set.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Finalizing the Installation&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;At this point we are done, you can dual boot between Windows XP and Snow Leopard 10.6.4 without issues. You can customize the bootloader by editing /Library/Preferences/SystemConfiguration/com.apple.Boot.plist. The more useful keys are "Default Partition" to set default to either OSX or Windows XP and "Hide Partition" to exclude the DATA partition from the boot menu.&lt;br /&gt;&lt;br /&gt;To backup the setup so that you won't have to repeat the process again in case of a failure, you'll need &lt;a href="http://clonezilla.org/downloads.php"&gt;CloneZilla&lt;/a&gt; Live CD. Backup all EFI, Windows XP and OSX partitions in advanced mode, be careful to select the correct set of options. When restoring, remember to restore in advanced mode with the same set of options selected during backup. Also remember to re-write the hybrid MBR via GPT fdisk every time you make changes to the partition table such as adding/removing partitions. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Performance&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;With this dual boot configuration, Windows XP performs smoothly (it should!) while OSX encounters some strange behaviour despite booting up in less than 30 seconds. First, it would not wake up from sleep properly despite trying several sleepenabler.kext patches. Occasionally, especially after an improper shutdown, it would also hang at "Waiting for DSMOS" for around 3 minutes during boot up. Although applications such as Safari, iTunes, MSN/Yahoo/Skype Messenger and TextEdit are reasonably fast, office applications like Open Office, Microsoft Office 2011 or even &lt;a href="http://www.abisource.com/"&gt;AbiWord&lt;/a&gt; are too slow to be usable; you will only see what you type after almost a second! You can play MP3 smoothly, but playing videos via VLC or QuickTime is too slow. Surprisingly, xCode with iPhone SDK runs fast enough to develop some simple iPhone applications. To me, it isn't about the processor not being fast enough for the job, it's more likely many Snow Leopard applications are never optimized for the Intel Atom processor.&lt;br /&gt;&lt;br /&gt;You may notice that some graphics applications won't be able to display graphics properly. In particular, the &lt;b&gt;Preview&lt;/b&gt; application won't be able to display images, and pressing Apple-Shift-3 or Apple-Shift-4 (maps to Windows key) to capture screenshot will just return an empty black image. This is due to the lack of &lt;a href="http://www.insanelymac.com/forum/index.php?showtopic=24431"&gt;QE/CI&lt;/a&gt; support on the graphics card drivers. I have tried several kexts for Intel GMA 950 which claim support for QE/CI without success.&lt;br /&gt;&lt;br /&gt;On a side note, if you install Microsoft Office 2011 on Snow Leopard on Asus 1000HE, it's not easy to get past the welcome screen the first time Word/Excel/PowerPoint is started after installation. The "Close" button is beyond the bottom of the screen due to the low 1024x600 resolution - you'll need an external monitor!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I hope this guide is useful for those interested in dual booting Windows and Snow Leopard. Except for the installation of the drivers which is specific to the Asus 1000HE, the rest of the guide should work for any computer. For simplicity, some troubleshooting steps in installing OSX has been left out. In case of any problems, you can search the InsanelyMac &lt;a href="http://www.insanelymac.com/forum/"&gt;forum&lt;/a&gt; or leave a comment here and I will try to help if possible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-7180688286064201199?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/7180688286064201199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/dual-booting-mac-os-x-1064-and-windows.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7180688286064201199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7180688286064201199'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/dual-booting-mac-os-x-1064-and-windows.html' title='Dual booting Mac OS X Snow Leopard 10.6.4 and Windows XP on Asus 1000HE netbook'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2845888028399418634</id><published>2010-10-19T18:43:00.000-07:00</published><updated>2011-12-21T04:33:18.718-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blogger'/><title type='text'>Web pages linking to my blog articles</title><content type='html'>&amp;nbsp;This post lists some of the web pages that link to my blog articles. I came across them during random Google searches, and via &lt;a href="http://statcounter.com/"&gt;StatCounter&lt;/a&gt;'s "Recent Came From" list.&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://minhdanh2002.blogspot.com/search/label/VoIP"&gt;VoIP&lt;/a&gt; linked from &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.broadbandreports.com/forum/r23765535-Faxing-over-VoIP-using-Kapanga-softphone"&gt;Faxing over VoIP using Kapanga softphone&lt;/a&gt; (6 Feb 2010)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dslreports.com/forum/r23762006-Future9-some-fax-calls-on-Trunk-25-missing-pages"&gt;some fax calls on Trunk 25&lt;/a&gt; (6 Feb 2010)&lt;/li&gt;&lt;/ul&gt;2. &lt;a href="http://minhdanh2002.blogspot.com/2009/10/free-auto-expiring-us-did-numbers.html"&gt;Free auto-expiring US DID numbers&lt;/a&gt; linked from &lt;a href="http://www.magicjacksupport.com/please-help-with-callerid-spoof-t931-15.html"&gt;Please help with CallerId Spoof&lt;/a&gt; (8 Feb 2010)&lt;br /&gt;&lt;br /&gt;3. &lt;a href="http://minhdanh2002.blogspot.com/2009/04/retrieve-icc-id-printed-on-sim-card_11.html"&gt;Retrieve ICC-ID (printed on SIM card) using SIM APIs&lt;/a&gt; linked from &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/vssmartdevicesvbcs/thread/d13d75ce-70be-479d-a28a-dcb5fa840429"&gt;Retrieve ICC ID in Windows CE without cellcore.dll&lt;/a&gt; (20 April 2010)&lt;br /&gt;&lt;br /&gt;4. &lt;a href="http://minhdanh2002.blogspot.com/2009/05/windows-mobile-pocket-pcs-auto-suspend.html"&gt;Windows Mobile Pocket PC’s auto-suspend mode&lt;/a&gt; linked from &lt;a href="http://groups.yahoo.com/group/FutureFAST/message/5360"&gt;Keeping GPRS alive in Windows Mobile App&lt;/a&gt; (7 June 2010)&lt;br /&gt;&lt;br /&gt;5. &lt;a href="http://minhdanh2002.blogspot.com/2010/06/serializabledictionary-and.html"&gt;SerializableDictionary and System.InvalidOperationException&lt;/a&gt; linked from &lt;a href="http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx"&gt;XML Serializable Generic Dictionary&lt;/a&gt; (19 June 2010)&lt;br /&gt;&lt;br /&gt;6. &lt;a href="http://minhdanh2002.blogspot.com/2008/11/read-write-call-history.html"&gt;Read Write Call History&lt;/a&gt; linked from &lt;a href="http://social.msdn.microsoft.com/Forums/en/windowsmobiledev/thread/c620dfe4-afb9-4a4a-8b58-e5f198e82d88"&gt;How can i Delete a entry in call history in Window mobile 6 using .Net ?&lt;/a&gt; (28 June 2010)&lt;br /&gt;&lt;br /&gt;7. &lt;a href="http://minhdanh2002.blogspot.com/2008/09/webexception-on-httpwebrequest-with-ssl.html"&gt;WebException on HTTPWebRequest with SSL connection: "Unable to read data from the transport connection"&lt;/a&gt; linked from &lt;a href="http://social.msdn.microsoft.com/Forums/en/netfxcompact/thread/9d87a3c9-63fc-4df7-9efa-4be33c1d6a8c"&gt;CF 2.0/3.5 WebException when doing POST to any HTTPS server at certain intervals&lt;/a&gt; (4 July 2010)&lt;br /&gt;&lt;br /&gt;8. &lt;a href="http://minhdanh2002.blogspot.com/search/label/Windows%20Mobile"&gt;Windows Mobile&lt;/a&gt; linked from &lt;a href="http://www.hjgode.de/wp/"&gt;Windows CE Programming&lt;/a&gt; (15 July 2010)&lt;br /&gt;&lt;br /&gt;9. &lt;a href="http://minhdanh2002.blogspot.com/2010/06/wikipedia-in-mobipocket-ebook-prc.html"&gt;Wikipedia in MobiPocket ebook (PRC) format&lt;/a&gt; linked from &lt;a href="http://www.e-thuvien.com/forums/showthread.php?t=37870"&gt;Pocket Wikipedia&lt;/a&gt; (23 Sept 2010)&lt;br /&gt;&lt;br /&gt;10. &lt;a href="http://minhdanh2002.blogspot.com/2010/05/identifying-used-and-unused-resources.html"&gt;Identifying used and unused resources in a Visual Studio's project Resources.resx file&lt;/a&gt; linked from&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/245956/find-unused-resources-in-a-net-solution"&gt;Find Unused Resources in a .NET Solution&lt;/a&gt; (5 Oct 2010)&lt;/li&gt;&lt;li&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en/vssourcecontrol/thread/e9d5294e-b216-4475-84ff-e314ee55e4f6"&gt;Detecting un-needed resources in a solution&lt;/a&gt; (24 Jan 2011)&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2286405-remove-unused-resources-automatically"&gt;Remove unused resources automatically&lt;/a&gt; (12 Nov 2011) &lt;/li&gt;&lt;/ul&gt;11. &lt;a href="http://minhdanh2002.blogspot.com/2010/07/intercept-incoming-sms-message-on-htc.html"&gt;Intercept incoming SMS message on HTC Phones with HTC Sense&lt;/a&gt; linked from &lt;a href="http://stackoverflow.com/questions/2138650/messageinterceptor-is-not-called-on-htc-hd2"&gt;MessageInterceptor is not called on HTC HD2&lt;/a&gt; (31 Oct 2010)&lt;br /&gt;&lt;br /&gt;12. &lt;a href="http://minhdanh2002.blogspot.com/2010/10/restoring-sms-backup-from-csv-to.html"&gt;Restoring SMS Backup from CSV to Blackberry devices&lt;/a&gt; linked from &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://forums.overclockers.com.au/showthread.php?t=919263"&gt;Backing up sms messages&lt;/a&gt; (20 Nov 2010)&lt;/li&gt;&lt;li&gt;&lt;a href="http://kb.adeptsbit.com.au/doku.php/ran/transfersmsfromnokiatobb"&gt;Transferring SMS messages from a Nokia to a Blackberry&lt;/a&gt; (28 Jan 2011)&lt;/li&gt;&lt;/ul&gt;13. &lt;a href="http://minhdanh2002.blogspot.com/2010/10/dual-booting-mac-os-x-1064-and-windows.html"&gt;Dual booting Mac OS X Snow Leopard 10.6.4 and Windows XP on Asus 1000HE netbook&lt;/a&gt; linked from:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://osx86.co/f47/my-asus-eeepc-1000he-and-how-i-installed-t6316/page4.html"&gt;My Asus EeePC 1000HE and how I installed OS X on it&lt;/a&gt; (23 Nov 2010)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.kexts.com/software-windows/7174-can-chameleon-boot-windows-xp-x86-gpt-partition.html"&gt;Can Chameleon boot Windows XP (x86) from GPT partition?&lt;/a&gt; (11 Jan 2011)&lt;/li&gt;&lt;li&gt;&lt;a href="http://technotesandthings.blogspot.com/2011/01/dual-booting-xp-and-mac-snow-leopard-on.html"&gt;Dual booting XP and Mac Snow Leopard on Asus EEE 1000he pc - and getting to 10.6.6&lt;/a&gt;&amp;nbsp; (23 Jan 2011)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.insanelymac.com/forum/index.php?showtopic=244798&amp;amp;mode=linear"&gt;[Guide] - Dual booting XP and Mac Snow Leopard on Asus EEE 1000he pc - and getting to 10.6.6&lt;/a&gt; (23 Jan 2011)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.bikingbrian.com/2011/01/27/installing-mac-os-10-6-4-on-a-asus-eeepc-1000he/"&gt;Installing Mac OS 10.6.4 on a Asus EeePC 1000HE&lt;/a&gt; (29 Jan 2011)&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.tonymacx86.com/viewtopic.php?f=7&amp;amp;t=23160"&gt;Dual Boot XP and Snow Leopard&lt;/a&gt; (26 Jun 2011) &lt;/li&gt;&lt;/ul&gt;14. &lt;a href="http://minhdanh2002.blogspot.com/2010/08/migrate-sms-from-windows-mobile-to.html"&gt;Migrate SMS from Windows Mobile to Android&lt;/a&gt; linked from &lt;a href="http://www.teniescu.ro/linkuri-1/"&gt;here&lt;/a&gt; (14 Dec 2010)&lt;br /&gt;&lt;br /&gt;15. &lt;a href="http://minhdanh2002.blogspot.com/2010/03/transferring-sms-messages-from-windows.html"&gt;Transferring SMS messages from Windows Mobile to Blackberry devices&lt;/a&gt; linked from &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://forums.hardwarezone.com.sg/showthread.php?s=35b87a1dfe8a428657ae85da7f37cbdc&amp;amp;p=51070453#post51070453"&gt;[How to] - Transfer SMS from Windows Mobile to Blackberry&lt;/a&gt; (10 Dec 2010)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.kaskus.us/showthread.php?t=5958470&amp;amp;page=314"&gt;Thread Diskusi khusus untuk Bold 9780 aka ONYX2&lt;/a&gt; (10 Jan 2011)&lt;/li&gt;&lt;/ul&gt;16. &lt;a href="http://minhdanh2002.blogspot.com/2008/11/mac-os-system-80-on-basilisk.html"&gt;MAC OS System 8.0 on Basilisk&lt;/a&gt; linked from &lt;a href="http://macintoshgarden.org/apps/quark-xpress-40-passport"&gt;Quark XPress 4.0 + Passport + 4.11 updates&lt;/a&gt;&lt;br /&gt;See comment by themacmeister, on 16 January 2011, 11:47pm &lt;br /&gt;&lt;br /&gt;17. &lt;a href="http://minhdanh2002.blogspot.com/2010/07/rtf-editor-control-for-net-compact.html"&gt;An RTF Editor Control for .NET Compact Framework&lt;/a&gt; linked from &lt;a href="http://www.experts-exchange.com/Programming/Handhelds_-_PDAs/Windows_Mobile/Q_26750814.html%20"&gt;How to add RichTextBox control to Smartphone Device Application in vb.net2005?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I found this article linked from an &lt;a href="http://www.experts-exchange.com/"&gt;experts-exchange&lt;/a&gt; answer on 19 Jan 2011. Previously you will be able to view answers to questions on their website without a paid account just by scrolling to the bottom of the page. But that is no longer the case. To view the answers now, you will need a tool such as &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/user-agent-switcher/"&gt;User Agent Switcher&lt;/a&gt; for Firefox and switch the default user agent to Google bot. This way, many other online content such as forum posts can also be viewed without registering an account.&lt;br /&gt;&lt;br /&gt;18. &lt;a href="http://minhdanh2002.blogspot.com/2009/02/accessing-win32-api-functions-from-c.html"&gt;Accessing WIN32 API functions from C++ CLI&amp;nbsp;&lt;/a&gt; linked from &lt;a href="http://forum.vingrad.ru/forum/topic-323282.html"&gt;SendMessage в VS2010Exp для Windows Forms&lt;/a&gt; (24 Feb 2011)&lt;br /&gt;&lt;br /&gt;19. &lt;a href="http://minhdanh2002.blogspot.com/2009/09/google-maps-api-on-windows-mobile.html"&gt;Google Maps API on Windows Mobile&lt;/a&gt; linked from &lt;a href="http://forums.asp.net/p/1661088/4336748.aspx/1?Re%20Windows%20Mobile%20Maps%20Application"&gt;Windows Mobile Maps Application&lt;/a&gt; (10 March 2011)&lt;br /&gt;&lt;br /&gt;20. &lt;a href="http://minhdanh2002.blogspot.com/2010/12/casio-pb-700-and-fa-11-printer-tape.html"&gt;Casio PB-700 and FA-11 Printer &amp;amp; Tape Recorder&lt;/a&gt; linked from &lt;a href="http://casio.ledudu.com/pockets.asp?type=24&amp;amp;serie=5"&gt;Ordinateurs de poche &amp;amp; Calculatrice Casio - PB FX CFX- Pockets : Casio PB-700-Casio PB-700-Casio PB-700-Casio PB-700&lt;/a&gt; (30 March 2011)&lt;br /&gt;&lt;br /&gt;21. &lt;a href="http://minhdanh2002.blogspot.com/2011/01/programming-nostalgia-revisiting-mike.html"&gt;Programming Nostalgia: revisiting Mike Wiering's Mario game written in Pascal&lt;/a&gt; linked from&lt;a href="http://dark-faust.blogspot.com/2011/05/clone-di-super-mario-bros-con-codice.html"&gt; Clone di Super Mario Bros con codice sorgente&lt;/a&gt; &lt;i&gt;(&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;Super&lt;/span&gt; &lt;span class="hps" title="Click for alternate translations"&gt;Mario&lt;/span&gt; &lt;span class="hps" title="Click for alternate translations"&gt;Bros&lt;/span&gt; &lt;span class="hps" title="Click for alternate translations"&gt;clone&lt;/span&gt; &lt;span class="hps" title="Click for alternate translations"&gt;with&lt;/span&gt; &lt;span class="hps" title="Click for alternate translations"&gt;source code) &lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;(23 May 2011)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;22. &lt;a href="http://minhdanh2002.blogspot.com/2008/03/acer-aspire-launch-manager.html"&gt;Acer Aspire Launch Manager&lt;/a&gt; linked from &lt;a href="http://www.techtalkz.com/windows-7/523356-there-way-emulate-combination-keystrokes.html"&gt;Is there a way to emulate combination of keystrokes&lt;/a&gt;? (7 July 2011)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;23. &lt;a href="http://minhdanh2002.blogspot.com/2008/08/customize-listview-item-forecolor.html"&gt;Customize Listview Item Forecolor &amp;amp; Backcolor&lt;/a&gt; linked from &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/05abd05d-0188-4630-8ccc-baf2daa1d623"&gt;Custom ListView with possibility to zoom in/out images&lt;/a&gt; (12 July 2011)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;24. &lt;a href="http://minhdanh2002.blogspot.com/2010/03/net-forms-on-windows-7-at-125-zoom.html"&gt;.NET forms on Windows 7 at 125% zoom level&amp;nbsp;&lt;/a&gt; linked from &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=671611"&gt;Bug 671611 - increased spacing of lines in folder and thread pane, filters, compose and address book on ms-windows for TB6&lt;/a&gt; (17 Sept 2011)&lt;br /&gt;&lt;br /&gt;&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;25. &lt;a href="http://minhdanh2002.blogspot.com/2011/03/interfacing-nokia-3510i-and-5110-lcd.html"&gt;Interfacing Nokia 3510i and 5110 LCD with PIC Microcontroller&lt;/a&gt; linked from &lt;a href="http://psychoul.com/electronics/pic-and-5110-interface-with-spi-hardware-pr3"&gt;PIC and 5110 Interface with SPI hardware&lt;/a&gt; (26 September 2011)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;26. &lt;a href="http://minhdanh2002.blogspot.com/2009/10/tcpmp-and-ac3-codec-for-windows-mobile.html"&gt;TCPMP and AC3 codec for Windows Mobile 6.1&lt;/a&gt; linked from &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;&lt;a href="http://forum.xda-developers.com/showthread.php?t=704283"&gt;HTC HD2 - CorePlayer Audio Codec (AC-3) support&amp;nbsp;&lt;/a&gt; (21 Oct 2011)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;&lt;a href="http://aurum79.tistory.com/53"&gt;HD2 application&lt;/a&gt; (9 Dec 2011) &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span class="short_text" id="result_box" lang="en"&gt;&lt;span class="hps" title="Click for alternate translations"&gt;27. &lt;a href="http://minhdanh2002.blogspot.com/2010/07/rtf-editor-control-for-net-compact.html"&gt;An RTF Editor Control for .NET Compact Framework&lt;/a&gt; linked from &lt;a href="http://social.msdn.microsoft.com/Forums/en/netfxcompact/thread/c4d00b15-1025-4bb0-9a34-b0968418945a"&gt;RTF on Windows CE &lt;/a&gt;&lt;/span&gt;&lt;/span&gt; (7 Nov 2011)&lt;br /&gt;&lt;br /&gt;28. &lt;a href="http://minhdanh2002.blogspot.com/2008/12/attached-debugger-to-running-net.html"&gt;Attached the debugger to a running .NET Compact Framework process&lt;/a&gt; linked from &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/944c1422-9681-4a32-9a68-768606227d89"&gt;Is it possible to debug my C# program Through LAN&lt;/a&gt; (8 Nov 2011)&lt;br /&gt;&lt;br /&gt;29. &lt;a href="http://www.androidtablets.net/forum/freescale-based/8881-synrgic-dreambook-w7-61.html"&gt;Dreambook W7: Cheap and apparently features-packed but unusable Chinese-made Android tablet&lt;/a&gt;&amp;nbsp; linked from &lt;a href="http://www.androidtablets.net/forum/freescale-based/8881-synrgic-dreambook-w7-61.html"&gt;Synrgic Dreambook W7&lt;/a&gt; (3 Dec 2011)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2845888028399418634?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2845888028399418634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/website-that-links-to-my-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2845888028399418634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2845888028399418634'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/website-that-links-to-my-blog.html' title='Web pages linking to my blog articles'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-8107121131086944339</id><published>2010-10-08T07:41:00.000-07:00</published><updated>2011-08-27T21:25:27.194-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS'/><category scheme='http://www.blogger.com/atom/ns#' term='iPhone'/><category scheme='http://www.blogger.com/atom/ns#' term='VmWare'/><title type='text'>iPhone SDK on Mac OS X 10.6.4 under VmWare</title><content type='html'>This guide shows you how to get the latest iPhone SDK running on Mac OS X 10.6.4 under VmWare.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Pre-requisites:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. A computer whose CPU supports hardware virtualization. You can check if your computer supports this by using &lt;a href="http://www.cpuid.com/softwares/cpu-z.html"&gt;CPUZ&lt;/a&gt; and check if your CPU supports VT-X instructions.&lt;br /&gt;2. At least 3GB of RAM on host with at least 2GB of RAM allocated to VMWare image.&lt;br /&gt;3. OS X 10.6.4 VMWare disk image which can be downloaded &lt;a href="http://fullrshare.com/software/mac-osx/53538-mac-os-x-snow-leopard-10.6.4-amdintel-2010engrus.html"&gt;here&lt;/a&gt;&lt;br /&gt;4. The latest iPhone SDK downloaded from &lt;a href="http://developer.apple.com/devcenter/ios/index.action"&gt;here&lt;/a&gt;&lt;br /&gt;5. A Windows tool to create ISO file, such as &lt;a href="http://www.magiciso.com/%20"&gt;MagicISO &lt;/a&gt;or &lt;a href="http://www.winiso.com/"&gt;WinISO&lt;/a&gt;&lt;br /&gt;6. A file splitter tool for Windows such as &lt;a href="http://www.jaist.ac.jp/%7Ehoangle/filesj/"&gt;FFSJ &lt;/a&gt;or &lt;a href="http://www.freebyte.com/hjsplit/"&gt;HJSplit&lt;/a&gt;&lt;br /&gt;7. A file joiner tool for Mac such as &lt;a href="http://www.macupdate.com/info.php/id/19590/ajoiner"&gt;AJoiner&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Steps:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Download and start the VMX virtual machine.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The machine should boot up from the emulated CD-ROM, showing the Chameleon bootloader. Wait at least 15 seconds before pressing F5 and select the Apple icon to boot into Mac OS X from the virtual hard disk.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TK_MeDH_kNI/AAAAAAAAAEY/PT7ntPmHcu8/s1600/darwin.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="358" src="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TK_MeDH_kNI/AAAAAAAAAEY/PT7ntPmHcu8/s640/darwin.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you select the icon too soon, for some reason, the bootloader will not see the hard disk and you will be stuck at the loading screen forever. If VmWare reports no disk activity a few seconds after the loading screen comes up, reset the machine and try again. Try to wait longer and press F5 a few times before selecting the Apple icon.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK_MpuN5o3I/AAAAAAAAAEc/IoDYXDp32oE/s1600/loading.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="358" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK_MpuN5o3I/AAAAAAAAAEc/IoDYXDp32oE/s640/loading.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. Configure Mac OS X&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The default language of the downloaded OS X image will be Russian. To change to English, you'll need to open the Preferences tab by clicking the top-left Apple logo and trying the various menu options until you get a panel that looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.creativetechs.com/iq/tip_images/RCDefaultApp-Preference.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="302" src="http://www.creativetechs.com/iq/tip_images/RCDefaultApp-Preference.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Click on the International icon (it should be in the first row). After that, select English and drag it to the top of the list. It should look like the following:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://mactrainingguide.com/wp-content/uploads/mac_os_x_international.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="271" src="http://mactrainingguide.com/wp-content/uploads/mac_os_x_international.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;After that, switch to Formats and Input menu and change everything to English (optional)&lt;br /&gt;&lt;span id="goog_87848707"&gt;&lt;/span&gt;&lt;span id="goog_87848708"&gt;&lt;/span&gt;&lt;a href="http://www.blogger.com/"&gt;&lt;/a&gt;&lt;br /&gt;&lt;span id="goog_87848707"&gt;Disable Software Updates, Sleep (under Energy Saver), Screen Saver and Time &lt;/span&gt;Machine.&lt;br /&gt;&lt;br /&gt;Also, go to Date &amp;amp; Time preferences, disable time synchronization and select a timezone so that the Mac system time is the same as what is displayed by Windows. This is needed because OS X assumes system time to be in GMT.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Increasing the hard disk size to 40 GB&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The default hard disk size is too small (20GB) for the iPhone SDK. However, expanding the hard disk is not as simple as using VmWare to expand it to 40 GB and run Disk Utility to grow the partition. If you try it, you will get the "mediaKit reports partition map too small" error message. GParted also won't help as it can only shrink, &lt;a href="http://gparted.sourceforge.net/features.php"&gt;not grow&lt;/a&gt; HFS+ partition.&lt;br /&gt;&lt;br /&gt;I even tried to use &lt;a href="http://clonezilla.org/"&gt;CloneZilla&lt;/a&gt; to backup the original HFS+ partition from the 20GB hard disk, and restore it to the new HFS+ partition on the 40GB hard disk. This time, although Disk Utility shows the HFS+ partition size correctly as 40GB, Finder still reports the size as 20GB. Attempting to repair the disk under Disk Utility fails with error "invalid b-tree node size". A Google search suggests &lt;a href="http://www.alsoft.com/diskwarrior/"&gt;DiskWarrior&lt;/a&gt; which unfortunately does not boot up under VmWare using the Chameleon  bootloader.&lt;br /&gt;&lt;br /&gt;The solution (unbelievably simple) that I found was&lt;br /&gt;&lt;br /&gt;a. Add a new virtual IDE (not SCSI) 40GB hard disk to the original OS X image.&lt;br /&gt;b. Boot up from the original hard disk and use Disk Utility to create a single HFS+ partition on the 40GB hard disk.&lt;br /&gt;c. Use Disk Utility to restore the original OSX partition to the newly created partition.&lt;br /&gt;d. Shutdown OSX. Under the properties of the virtual machine, remove the newly created hard disk (not the image) and change the original hard disk to point to the new image.&lt;br /&gt;e. Reboot. OSX should now see the hard disk as 40GB.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. Getting the iPhone SDK installer on OSX&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is the tricky part. I have tried the following but failed:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;a. Use Safari inside OS X to download the SDK.&amp;nbsp;&lt;/i&gt;&lt;br /&gt;For some reason the download was successful but the resulting DMG file was corrupted.&lt;br /&gt;&lt;i&gt;b. Download it under Windows to an external hard disk drive and use the Vmware's VM menu to map the drive to OS X. &lt;/i&gt;&lt;br /&gt;OS X would recognize the file and seemed to be able to copy it over. The copy process however would hang Finder prematurely and I had to resort to a reboot.&lt;br /&gt;&lt;i&gt;c. Same as (b) but splitted the file to smaller parts before copying.&lt;/i&gt;&lt;br /&gt;OS X would still hang while copying, no matter how small the size of each segment is. This seems to be a problem with how VmWare manages the hardware.&lt;br /&gt;&lt;br /&gt;The solution I found is&lt;br /&gt;&lt;br /&gt;a. On Windows, split the DMG file to many segments around 100 MB each using HJSplit/FFSJ.&lt;br /&gt;b. Use MagicISO/WinISO to create an ISO file with all the splitted segments&lt;br /&gt;c. Use VmWare to add a new virtual CD-ROM drive to the OS X which points to the ISO file.&lt;br /&gt;d. Open the emulated drive in OS X and copy the segments over.&lt;br /&gt;e. Use AJoiner to merge all the segments to create the installer DMG file.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;5. Installing the iPhone SDK&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;This step is straight forward and should take around 30 minutes to 1 hour, depending on the speed of your computer.&lt;br /&gt;&lt;br /&gt;That's all. You can now enjoy iPhone development on your PC. In my computer, I allocate 4GB of RAM to OSX and it's really fast. Except that there's no sound support, the rest is just fine:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK_Nf6yzZRI/AAAAAAAAAEk/eG-XP0tatiQ/s1600/xcode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="326" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK_Nf6yzZRI/AAAAAAAAAEk/eG-XP0tatiQ/s640/xcode.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TK_NGZz3GFI/AAAAAAAAAEg/lqOmsg1gFt4/s1600/xcode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I hope this guide will help those who want to develop iPhone apps but do not have a Mac. If you encounter problems setting up the virtual machine, refer to this &lt;a href="http://minhdanh2002.blogspot.com/2010/11/iphone-sdk-on-mac-os-x-1064-under.html"&gt;post&lt;/a&gt;.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-8107121131086944339?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/8107121131086944339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/iphone-sdk-on-mac-os-x-1064-under.html#comment-form' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/8107121131086944339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/8107121131086944339'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/iphone-sdk-on-mac-os-x-1064-under.html' title='iPhone SDK on Mac OS X 10.6.4 under VmWare'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_w4YbCKQ5wkQ/TK_MeDH_kNI/AAAAAAAAAEY/PT7ntPmHcu8/s72-c/darwin.png' height='72' width='72'/><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-5367234191067581133</id><published>2010-10-01T06:02:00.000-07:00</published><updated>2012-01-20T06:59:21.200-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blackberry'/><category scheme='http://www.blogger.com/atom/ns#' term='SMS Migration'/><title type='text'>Restoring SMS Backup from CSV to Blackberry devices</title><content type='html'>&lt;b&gt;UPDATE (20 Jan 2012): &lt;/b&gt;Better support for Unicode characters. Sample CSV files with Unicode messages in various languages are included in the download. CSV2IPD will also report the number of successfully imported messages at the end of the conversion, not just the number of invalid records.&lt;br /&gt;&lt;b&gt;UPDATE (18 Nov 2011): &lt;/b&gt;Use .NET DateTime class instead VB6 &lt;a href="http://msdn.microsoft.com/en-us/library/s2dy91zy%28v=vs.80%29.aspx"&gt;CDate &lt;/a&gt;function to parse date strings (which may fail on non-English systems). Also added a log file (CSV2IPD.log) that can be used for debugging.&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;UPDATE (7 May 2011):&lt;/b&gt; Following a request from a reader, the program has been updated to handle CSV more robustly, supporting multi-line messages and messages having semicolons. It also reports the number of invalid records in the CSV file after the conversions. The source code and binary files have been updated. &lt;br /&gt;&lt;br /&gt;Following my previous &lt;a href="http://minhdanh2002.blogspot.com/2010/03/transferring-sms-messages-from-windows.html"&gt;post&lt;/a&gt; on a Windows Mobile tool called SMS2IPD that would run on a Windows Mobile device and creates and IPD backup of all the SMS that can be restored to a Blackberry device via Blackberry Desktop Manager, a German reader contacted me asking how he could do the same for his Nokia phone.&lt;br /&gt;&lt;br /&gt;Being no Symbian expert who could write a similiar tool running on Symbian phone, I advised him to use Nokia PC Suite to create a CSV backup of all his SMS. After that, I have written a &lt;a href="http://dl.dropbox.com/u/5881137/CSV2IPD.zip"&gt;tool &lt;/a&gt;that will help create an IPD from the CSV file.&lt;br /&gt;&lt;br /&gt;The program, called CSV2IPD, accepts 2 CSV input files for Incoming SMS and Outgoing SMS, as demonstrated in the following screenshot:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8TfSAJ7SI/AAAAAAAAAEI/xQyOWFKxNE4/s1600/CSV2IPD.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8TfSAJ7SI/AAAAAAAAAEI/xQyOWFKxNE4/s1600/CSV2IPD.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The CSV for Inbox looks like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;sms;deliver;"+987654321";"";"";"2010.08.25 15:14";"";"Message 1"&lt;br /&gt;sms;deliver;"+123456789";"";"";"2010.08.25 15:15";"";"Message 2"&lt;br /&gt;sms;deliver;"+111111111";"";"";"2010.08.25 15:17";"";"Message 3"&lt;/pre&gt;&lt;br /&gt;The CSV for Sent Items looks like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;sms;submit;"";"+0123456789";"";"2010.08.25 15:15";"";"Hello world 1."&lt;br /&gt;sms;submit;"";"+0123456789";"";"2010.08.25 15:16";"";"Hello world 2."&lt;br /&gt;sms;submit;"";"+0123456789";"";"2010.08.25 15:17";"";"Hello world 3."&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If your exported CSV file via Nokia PC Suite does not look exactly as above, you can use a text editor tool such as &lt;a href="http://notepad-plus-plus.org/"&gt;Notepad++&lt;/a&gt;  then use Find/Replace, perhaps with the help of regular expressions, to  modify it. Make sure you do not have extra quotation marks at the  beginning and the end of each line. If the delimiter is comma and not  semicolon, use &lt;a href="http://csved.sjfrancke.nl/"&gt;CSVEd&lt;/a&gt; to change it. Finally, if your time column is in a different format, try to tweak your Regional Settings (in Control Panel).&lt;br /&gt;&lt;br /&gt;The generated IPD file can be imported using Blackberry Desktop Manager for Windows. It may not work on the Mac version of Blackberry Desktop Software. You will need .NET Framework 2.0 (already included with Windows Vista and above) to run the program. If you are using Windows XP, you can download .NET &lt;a href="http://www.microsoft.com/download/en/details.aspx?id=19"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Unicode text messages are supported, just make sure that your CSV files are saved using UTF8 encoding. As always, remember to backup all data on your phone prior to proceeding.&lt;br /&gt;&lt;br /&gt;The source code for the tool can be downloaded &lt;a href="http://dl.dropbox.com/u/5881137/CSV2IPD_source.zip"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-5367234191067581133?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/5367234191067581133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/restoring-sms-backup-from-csv-to.html#comment-form' title='63 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5367234191067581133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/5367234191067581133'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/restoring-sms-backup-from-csv-to.html' title='Restoring SMS Backup from CSV to Blackberry devices'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8TfSAJ7SI/AAAAAAAAAEI/xQyOWFKxNE4/s72-c/CSV2IPD.png' height='72' width='72'/><thr:total>63</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6385792727958757160</id><published>2010-09-18T05:27:00.000-07:00</published><updated>2010-10-08T09:14:52.894-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Tips'/><title type='text'>FINDSTR and Unicode strings</title><content type='html'>Recently I had another look at my old &lt;a href="http://minhdanh2002.blogspot.com/2010/05/identifying-used-and-unused-resources.html"&gt;post&lt;/a&gt; on finding unused resources in a .NET project, and realized that it would not work if any of the resource strings contain Unicode characters. The culprit turns out to be the FINDSTR command, which doesn't support Unicode text files. To solve the problem, I replace FINDSTR with FIND.EXE (which supports Unicode). However, all is lost when my usage of FOR to tokenize the input files stops working with Unicode input. I also tried a few suggestions &lt;a href="http://blogs.msdn.com/b/michkap/archive/2006/09/27/773448.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/dneimke/archive/2004/02/29/81675.aspx"&gt;here&lt;/a&gt; to no avail. &lt;br /&gt;&lt;br /&gt;My simple conclusion is that, batch script was not designed with Unicode in mind. Perhaps &lt;a href="http://msdn.microsoft.com/en-us/library/aa973757%28VS.85%29.aspx"&gt;Windows Powershell&lt;/a&gt; can probably do a better job...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6385792727958757160?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6385792727958757160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/findstr-and-unicode-strings.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6385792727958757160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6385792727958757160'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/findstr-and-unicode-strings.html' title='FINDSTR and Unicode strings'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6093273629964061155</id><published>2010-09-07T05:23:00.000-07:00</published><updated>2010-09-07T05:33:29.166-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Tips'/><title type='text'>Re-partitioning the HP G42 laptop</title><content type='html'>I recently purchased a &lt;a href="http://www.shopping.hp.com/webapp/series/category/notebooks/G42t_series/3/computer_store"&gt;HP G42&lt;/a&gt; laptop having an Intel Core i5 processor and 4GB DR3 RAM. Everything was good until I failed to create a few more partitions on the built in hard disk drive for software, documents, etc. The problem was with the default partition structure:&lt;br /&gt;&lt;br /&gt;* SYSTEM (200MB hidden). This was apparently created during Windows 7 setup when the hard disk has no other partitions. The partition only contains the bootloader and its various language packs.&lt;br /&gt;* WINDOWS (NTFS). This is where Windows 7 is installed.&lt;br /&gt;* RECOVERY (NTFS hidden). If you press F11 during boot time, BIOS will boot from this partition to begin the recovery process. &lt;br /&gt;* HP_TOOLS (hidden). Some BIOS utilities will require tools on this partition. &lt;br /&gt;&lt;br /&gt;There are already 4 primary partitions so creating another one is impossible unless you have an extended partition. If you want to dual boot with another OS, you will have to delete one of the existing partitions as most OS cannot boot from an extended partition.&lt;br /&gt;&lt;br /&gt;It's actually easy to delete the SYSTEM partition if you know how to do it correctly:&lt;br /&gt;&lt;br /&gt;1. Use &lt;a href="http://neosmart.net/dl.php?id=1"&gt;EasyBCD &lt;/a&gt;to write the bootloader to the Windows partition (and not the SYSTEM partition). Reboot the system and make sure that Windows can start.&lt;br /&gt;&lt;br /&gt;If Windows fails to start, set the SYSTEM partition back to Active (boot) and there should be no damage. During my experiment, I used &lt;a href="http://gparted.sourceforge.net/"&gt;GParted &lt;/a&gt;Live CD for this purpose.&lt;br /&gt;&lt;br /&gt;2. If step 1 is successful, delete the SYSTEM partition. As it's no longer in use, Windows should still boot properly.&lt;br /&gt;&lt;br /&gt;Reclaiming the space occupied by the SYSTEM partition is tricky. My first attempt was to use GParted to extend the Windows partition to cover the free space. This process took almost half a day and eventually failed with an unspecified error, making the whole hard disk unusable with a partition table error. Only a low-level format would help. As of now, I am still not sure of the cause.&lt;br /&gt;&lt;br /&gt;The solution was to use Norton Ghost, which only took around 1 hour:&lt;br /&gt;&lt;br /&gt;1. Create an image of the working Windows partition (after the SYSTEM partition has been deleted).&lt;br /&gt;2. Delete the Windows partition and create a new partition covering the original SYSTEM partition and the just deleted Windows partition.&lt;br /&gt;3. Restoring the ghost image to the newly created partition in step 2 and the system should be able to boot into Windows&lt;br /&gt;&lt;br /&gt;Why can't I simply just delete the SYSTEM and the Windows partition and use the HP recovery program to restore? Unfortunately it wasn't that simple, since the HP Recovery program does not ask you where you want your Windows partition to be and simply recreates the SYSTEM, WINDOWS and HP_TOOLS partition. It does not, however, re-create the RECOVERY partition if this partition does not already exist (e.g. the recovery program was launched from a USB or DVD backup).&lt;br /&gt;&lt;br /&gt;The entire HP_TOOLS partition contents is stored on the RECOVERY partition, which is hidden from Windows Explorer and is only accessible via a third party file explorer such as &lt;a href="http://www.freecommander.com/"&gt;Free Commander&lt;/a&gt;. This partition contains the pre-installed Windows 7 image, with a .wim compressed file (readable via 7Zip) that has installers to some bundled programs. The device drivers can also be extracted from a a folder named SWSetup in this .wim file. &lt;br /&gt;&lt;br /&gt;One last thing about the HP Recovery Manager program is that it only allows you to backup the recovery image to DVD/USB once. In my case, I backup to a USB thumbdrive, which can later be restored to a bootable hard disk partition by simply copying all the files over and use EasyBCD to write the bootloader. If you backup to DVDs, be sure to make ISO copies of the disks.&lt;br /&gt;&lt;br /&gt;Once you have finished re-partitioning the system and set up all your software, simple use Norton Ghost to backup/restore your setup. Do not ever use HP Recovery Manager again as it will destroy all your hard work!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6093273629964061155?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6093273629964061155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/09/re-partitioning-hp-g42-laptop.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6093273629964061155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6093273629964061155'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/09/re-partitioning-hp-g42-laptop.html' title='Re-partitioning the HP G42 laptop'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-8480693321786816484</id><published>2010-08-28T06:58:00.000-07:00</published><updated>2010-10-08T08:57:46.820-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Singtel'/><title type='text'>Singtel Caller Alert</title><content type='html'>Recently while checking my call divert settings, I noticed a strange number "+6519454" in my "Forward when unreachable" settings, which would always revert itself despite my several attempts to clear the settings:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8hcYfJdEI/AAAAAAAAAEU/9a1Xj_f8-7E/s1600/singtel+caller+alert.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8hcYfJdEI/AAAAAAAAAEU/9a1Xj_f8-7E/s320/singtel+caller+alert.png" width="192" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It turned out that the number belongs to the free &lt;a href="http://info.singtel.com/large-enterprise/products/mobile/communication/caller-alert"&gt;Singtel Caller Alert&lt;/a&gt; service, which sends you a free notification SMS if somebody tries to call you when your phone is unreachable. Although it's a nice thing to have, your caller will be charged for the call since the call is taken as connected, which is odd for Singtel since may other telcos provide the service for free. What's more, the setup is weird - why must Singtel enforce an always-on divert settings in order to activate this free service? Why can't they do it on their side?&lt;br /&gt;&lt;br /&gt;Interestingly, if you try to call 19454 from a Singtel mobile phone, you'll hear the same announcement as if you were calling somebody with the free Caller Alert service and you will still be charged for the call!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-8480693321786816484?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/8480693321786816484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/singtel-caller-alert.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/8480693321786816484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/8480693321786816484'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/10/singtel-caller-alert.html' title='Singtel Caller Alert'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8hcYfJdEI/AAAAAAAAAEU/9a1Xj_f8-7E/s72-c/singtel+caller+alert.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-959468365082873178</id><published>2010-08-15T01:36:00.000-07:00</published><updated>2011-01-19T21:36:56.731-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Telerik'/><title type='text'>Allowing only numeric input in a TextBox</title><content type='html'>You may have seen a Windows forms textbox that would disallow non-numeric input, showing an error message like in the following screenshot:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8cY91AemI/AAAAAAAAAEM/kLTLnRu2hQg/s1600/ES_NUMBER.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8cY91AemI/AAAAAAAAAEM/kLTLnRu2hQg/s320/ES_NUMBER.jpeg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;This can be easily accomplished from .NET by applying the ES_NUMBER style to the textbox:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Public Sub SetNumericInputMode(ByVal txtBox As TextBox)&lt;br /&gt;    Dim style As Int32 = GetWindowLong(txtBox.Handle, GWL_STYLE)&lt;br /&gt;    SetWindowLong(txtBox.Handle, GWL_STYLE, style Or ES_NUMBER)&lt;br /&gt;End Sub&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Of course, SetWindowLong has to be declared properly:&lt;br /&gt;&lt;br /&gt;&amp;lt;DllImport("user32.dll")&amp;gt; &lt;br /&gt;&lt;pre&gt;Private Shared Function SetWindowLong( _&lt;br /&gt;     ByVal hWnd As IntPtr, _&lt;br /&gt;     ByVal nIndex As Integer, _&lt;br /&gt;     ByVal dwNewLong As IntPtr) As Integer&lt;br /&gt;End Function&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now what if you're using the RadTextBox control from the &lt;a href="http://www.google.com.sg/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CBkQFjAA&amp;amp;url=http%3A%2F%2Fwww.telerik.com%2Fproducts%2Fwinforms.aspx&amp;amp;ei=eB2vTOWjJIWlcdKF1eMN&amp;amp;usg=AFQjCNEV46mZ8o-3YQeBw68lvSCQqi4HBw&amp;amp;sig2=dJfgR522kWq2_gN9uNjEBA"&gt;Telerik RadControls for WinForms&lt;/a&gt;? The following code works for a normal textbox, compiles but will not work for a RadTextBox: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;SetNumericInputMode(textBox1.Handle);&lt;/pre&gt;&lt;br /&gt;The reason is that the RadTextBox is just a container for the native Win32 textbox. Any style changes have to be applied directly to the actual textbox, not the container. The following will work:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Public Sub SetNumericInputMode(ByVal txtBox As RadTextBox)&lt;br /&gt;  'special handling for RadTextbox as the actual Win32 textbox is hidden underneath&lt;br /&gt;  Dim hwnd As IntPtr = CType(txtBox.TextBoxElement.Children(0), RadTextBoxItem).HostedControl.Handle&lt;br /&gt;  Dim style As Int32 = GetWindowLong(hwnd, GWL_STYLE)&lt;br /&gt;  SetWindowLong(hwnd, GWL_STYLE, style Or ES_NUMBER)&lt;br /&gt;End Sub&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice that ES_NUMBER only prevents user from entering non-numeric (0..9) input for the textbox. It does not stop user from pasting random text. For more advanced features, I suggest something like &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx"&gt;MaskedTextBox&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-959468365082873178?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/959468365082873178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/08/allowing-only-numeric-input-in-textbox.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/959468365082873178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/959468365082873178'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/08/allowing-only-numeric-input-in-textbox.html' title='Allowing only numeric input in a TextBox'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_w4YbCKQ5wkQ/TK8cY91AemI/AAAAAAAAAEM/kLTLnRu2hQg/s72-c/ES_NUMBER.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6551854193573126568</id><published>2010-08-08T06:05:00.000-07:00</published><updated>2011-08-11T23:50:26.425-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='SMS Migration'/><title type='text'>Migrate SMS from Windows Mobile to Android</title><content type='html'>To migrate SMS from Windows Mobile to Android, you will need the &lt;a href="http://android.riteshsahu.com/tips/importexportmove-sms-messages-from-windows-mobile-to-android"&gt;SMS Exporter&lt;/a&gt; tool, which will export all SMS to an XML file that can be imported to Android using &lt;a href="http://android.riteshsahu.com/apps/sms-backup-restore"&gt;SMS Backup Restore&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Same as my &lt;a href="http://minhdanh2002.blogspot.com/2010/03/transferring-sms-messages-from-windows.html"&gt;SMS2IPD &lt;/a&gt;tool that migrates SMS from Windows Mobile to Blackberry, SMS Exporter uses MAPIDotNet library found on &lt;a href="http://www.codeproject.com/KB/windows/PocketPCandSmartphone.aspx"&gt;codeproject&lt;/a&gt;, written by &lt;a href="http://www.codeproject.com/Members/rwt33" id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_memberProfileLink"&gt;rwt33&lt;/a&gt;. The export speed on Windows Mobile is fast, but the import speed is very slow. On my &lt;a href="http://www.htc.com/www/product/g1/overview.html"&gt;HTC Dream&lt;/a&gt; flashed to Android 2.1, it took almost 2 hours to import 3000 messages - the process became slower towards the end and the phone would go to standby mode during the process. After the painful import , the message application is still responsive despite the huge message database.&lt;br /&gt;&lt;br /&gt;SMS Exporter also supports backing up SMS to XML, which is useful if you want to read your SMS on a computer, or migrate your SMS to other phones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6551854193573126568?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6551854193573126568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/08/migrate-sms-from-windows-mobile-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6551854193573126568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6551854193573126568'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/08/migrate-sms-from-windows-mobile-to.html' title='Migrate SMS from Windows Mobile to Android'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2880593647574827314</id><published>2010-07-23T20:58:00.000-07:00</published><updated>2010-08-20T20:52:09.491-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Compact Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>An RTF Editor Control for .NET Compact Framework</title><content type='html'>As you may have known, there is no &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.richtextbox.aspx"&gt;RichTextBox &lt;/a&gt;control in .NET Compact Framework. This creates a lot of headaches for developers who want to display RTF-formatted text in their program. The only way is to use the &lt;a href="http://msdn.microsoft.com/en-us/library/ms834457.aspx"&gt;RichInk &lt;/a&gt;control. However, there is no good free managed wrapper for it, even the OpenNetCF's &lt;a href="http://community.opennetcf.com/forums/p/8892/8992.aspx#8992"&gt;InkX&lt;/a&gt; wrapper is still untidy and requires a lot of P/Invoke calls to make it work properly. &lt;a href="http://www.intelliprog.com/"&gt;IntelliProg&lt;/a&gt;&lt;b&gt;&lt;span class="f"&gt;&lt;cite&gt;&lt;/cite&gt;&lt;/span&gt;&lt;/b&gt; used to provide a working control but the company has seemingly disappeared (their domain is parked). The only commecial solution available now is provided by &lt;a href="http://www.dsrtech.net/richink/"&gt;dsrtech&lt;/a&gt; but it is expensive.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;AgileNotesTouch with RichInk control&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;After some research, I found a freeware called &lt;a href="http://www.agilitylab.com/"&gt;AgileNotes Touch&lt;/a&gt; which allows user to write notes and save it into TXT, &lt;a href="http://filext.com/file-extension/PWI"&gt;PWI&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Rich_Text_Format"&gt;RTF&lt;/a&gt;. Its interface is similiar to Pocket Word:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.agilitylab.com/images/screens3/AgileNotesTouch_small.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.agilitylab.com/images/screens3/AgileNotesTouch_small.png" /&gt;&lt;/a&gt;&lt;/div&gt;Since the source code is not available, I decided to go ahead decompiling the executable using &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Reflector&lt;/a&gt;. This was an easy task - the decompiled source code, with only some minor modifications, compiled and ran as if it were the original. It turned out AgilesNotes Touch also uses the RickInk control, with some nice managed .NET wrappers which can be re-used easily.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Creating RTF programmatically: NRtfTree&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Since I need to create the RTF document programmatically, I decided to use the open source project &lt;a href="http://sourceforge.net/projects/nrtftree/"&gt;NRtfTree&lt;/a&gt;. Some basic formatting worked well until I tried to create an RTF document with images such as &lt;a href="http://www.mediafire.com/?wctgl6sphi23b2e"&gt;this&lt;/a&gt;. The document was created properly but to my disappointment the image was not displayed when the document was open with my program and with Pocket Word. On the other hand, Wordpad, and Office Word, displayed the image just fine. It took me a long time before I figured out the cause - the RichInk control (and the RichEd50W control used by Pocket Word) only supports binary images, and not hex images. For example the following picture will be discarded:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{\pict\pngblip\picw10449\pich3280\picwgoal5924\pichgoal1860 &lt;i&gt;hex data&lt;/i&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;but the following will work:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;{\pict\pngblip\picw10449\pich3280\picwgoal5924\pichgoal1860\bin &lt;i&gt;binary data&lt;/i&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And since NRtfTree only supports hex image, I had to modify the library to support binary image. What a hassle, but in the end everything worked well and images are displayed properly. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;From RichInk to RichEdit50W&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Next, I noticed that my control could not display images on the same line as text and seem to drop tables, while Pocket Word displayed them just fine. This is a hint that Pocket supports higher RTF &lt;a href="http://en.wikipedia.org/wiki/Rich_Text_Format#Version_timeline"&gt;versions &lt;/a&gt;then RichInk, so I use Remote Spy to find out which control Pocket is using:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TEpgee-QP8I/AAAAAAAAAD4/428SIKKygKc/s1600/pWordRichEd50w.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TEpgee-QP8I/AAAAAAAAAD4/428SIKKygKc/s320/pWordRichEd50w.PNG" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;PocketWord never used RichInk, but RichEd50W, similiar to what RichTextBox is using. I changed my code to use this window class (it stays in RichEd20.dll):&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;WindowsAPIs.LoadLibrary("RichEd20.dll");&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;this.m_RichInk = new WindowHost("RICHEDIT50W", 0, 0);&lt;/div&gt;&lt;br /&gt;and images are displayed as intended. Surprisingly that's all I need - my program is now as good as Pocket Word.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Making the document read-only&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;My main purpose was to display documents - and not allowing user to modify them so I applied ES_READONLY to the window style:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;this.m_RichInk = new WindowHost("RICHEDIT50W", 0, ES_READONLY);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There is still a minor problem: the window display may be distorted or incomplete after some extensive usage. I have yet to figure out the cause of the problem or how to fix it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Source code&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The sample source code is &lt;a href="http://www.mediafire.com/?w4n1duv1n61n5c1"&gt;here&lt;/a&gt;. It includes the modified NRtfTree library, the decompiled source code of AgilesNotes Touch, and a sample form showing you how to read and write RTF files. NRtfTree was modified to insert binary images, instead of hex, and to support unicode characters. I have commented clearly where I modified the code. &lt;br /&gt;&lt;br /&gt;I hope this will help other developers facing the same problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2880593647574827314?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2880593647574827314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/rtf-editor-control-for-net-compact.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2880593647574827314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2880593647574827314'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/rtf-editor-control-for-net-compact.html' title='An RTF Editor Control for .NET Compact Framework'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TEpgee-QP8I/AAAAAAAAAD4/428SIKKygKc/s72-c/pWordRichEd50w.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2852699676044050141</id><published>2010-07-17T08:59:00.000-07:00</published><updated>2010-10-08T08:14:19.990-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='General Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET Compact Framework'/><title type='text'>Beware when using DES/TripleDES for data encryption</title><content type='html'>I recently worked on a secure device application which requires a PIN code to be entered as startup.The application database also needs to be encrypted. My first approach was to use a DESCryptoServiceProvider, which is among the few supported encryption methods in the .NET Compact Framework,&amp;nbsp; to encrypt the database using the PIN code itself as the secret key.&lt;br /&gt;&lt;br /&gt;My full code can be found &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/71306b6c-639c-41f9-8e1d-c28a6637ddde/#238d9517-8a2c-49e1-8473-53f14bda06ae"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Soon after, I discovered the problem. The encrypted database can be decrypted if the secret key provided is slightly wrong. For example, if the  secret key I used when encrypting is 12345678, the decryption will work  with both 12345678 and 12345778 (wrong value). Thinking that this was almost certainly a bug, I went ahead to file a report at &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/569168/data-encrypted-with-descryptoserviceprovider-can-be-decrypted-when-secret-key-is-wrong?wa=wsignin1.0"&gt;Microsoft Connect.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I did not have to wait until Microsoft responsed me (which was 3 days later) for an answer. Soon after I read the Wikipedia &lt;a href="http://en.wikipedia.org/wiki/Data_Encryption_Standard"&gt;article&lt;/a&gt; on DES, I immediate realized my mistake.  The key ostensibly consists of 64 bits; however, only 56 of these are  actually used by the algorithm. Eight bits are used solely for checking parity, and  are thereafter discarded. This explains why the wrong secret key can be used to decrypt the data as described above.&lt;br /&gt;&lt;br /&gt;I changed to &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledes.aspx"&gt;TripleDES&lt;/a&gt; only to observe the same behaviour. As &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aes.aspx"&gt;AES&lt;/a&gt; is not supported on the compact framework, I end up encrypting the database using an &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx"&gt;MD5 hash&lt;/a&gt; of the PIN code. Although you may argue that MD5 has some chance of collision, the above hash + encryption combination will ensure, at least with ultimate possibility, that there is no way for the database to be decrypted without the correct password.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2852699676044050141?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2852699676044050141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/beware-when-using-destripledes-for-data.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2852699676044050141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2852699676044050141'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/beware-when-using-destripledes-for-data.html' title='Beware when using DES/TripleDES for data encryption'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-9087597220033700844</id><published>2010-07-14T20:29:00.000-07:00</published><updated>2010-09-14T22:50:57.721-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Compact Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Intercept incoming SMS message on HTC Phones with HTC Sense</title><content type='html'>In my previous &lt;a href="http://minhdanh2002.blogspot.com/2010/06/net-cf-messageinterceptor-class-fails.html"&gt;post&lt;/a&gt; I have explained the problem with &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.windowsmobile.pocketoutlook.messageinterception.messageinterceptor.aspx"&gt;MessageInterceptor&lt;/a&gt; on new HTC Phones and how to temporary fix it it by installing the &lt;a href="http://handheld.softpedia.com/get/Tweaks/Zenyee-Disable-HTC-Messaging-82632.shtml"&gt;patch&lt;/a&gt;. Although this allows existing applications to work without any code changes, user will have to use Pocket Outlook, which has an inferior user interface compared to HTC Messages, to send SMS. MMS are not supported until the &lt;a href="http://www.1800pocketpc.com/2008/05/27/arcsoft-mms-50317.html"&gt;Arcsoft  MMS client&lt;/a&gt; is installed. HTC Sense will not be able to show new incoming text messages, which is a major limitation. &lt;br /&gt;&lt;br /&gt;Luckily there is a way to intercept incoming text messages without installing any patch. However, you will have to make some code changes to your application. The idea is that, although the .NET MessageInterceptor class does not work, the SDK &lt;a href="http://msdn.microsoft.com/en-us/library/aa446561.aspx"&gt;MapiRule &lt;/a&gt;sample (C:\Program Files\Windows Mobile 6.5.3 DTK\Samples\Common\CPP\Win32\MapiRule) works just fine. This post shows you how to modify the MAPIRule sample code to integrate it with your .NET project&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Modifying MAPIRule.dll&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You will not have to touch most of the MAPIRule code, except for modifying the GUID (important!) and the ProcessMessage() function (the sample just displays the incoming text message received in a MessageBox). Although you can parse the incoming message and process it directly inside ProcessMessage(), I decided on the following to make things clearer:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;When MapiRule.dll received a new SMS message in ProcessMessage(), it simply send a Win32 message via SendMessage to the host application.&lt;/li&gt;&lt;li&gt;Upon received the specific Win32 message, host application, which is a .NET application, will decide on whether or not to &lt;b&gt;intercept &lt;/b&gt;the new SMS message (it will not appear in phone Inbox) or let the default messaging application handle it.&lt;/li&gt;&lt;li&gt;Based on the result of SendMessage(), MapiRule.dll will act accordingly. &lt;/li&gt;&lt;/ol&gt;This interprocess communication can be easily done by using the Win32 API SendMessage() and the .NET Compact Framework's MessageWindow class. Although you can specify your own message ID, I have chosen WM_COPYDATA since MapiRule.dll needs to send the SMS text and sender number to the host application, otherwise string pointers to message text and sender numbers cannot be shared. The sample code is below. Notice that &lt;span style="color: black;"&gt;newMsgWin is the handle to the host application's window. The sender number and message text is concatenated into a single string to be sent out.&lt;/span&gt; &lt;br /&gt;&lt;div style="color: #666666;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: #666666;"&gt;HRESULT CMailRuleClient::ProcessMessage(IMsgStore *pMsgStore, ULONG cbMsg, LPENTRYID lpMsg, ULONG cbDestFolder, LPENTRYID lpDestFolder, ULONG *pulEventType, MRCHANDLED *pHandled)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;{&lt;/span&gt;&lt;br /&gt;............&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; TCHAR msgInfo[500];&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; COPYDATASTRUCT cds;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // we concatenate the sender number and the message text, to be sent to the host application&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; memset(msgInfo, 0, sizeof(msgInfo));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; wcscpy(msgInfo, pspvEmail-&amp;gt;Value.lpszW);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; wcscat(msgInfo, L"\n");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; wcscat(msgInfo, pspvSubject-&amp;gt;Value.lpszW);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //length for the recipient to know&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; cds.dwData = wcslen(pspvEmail-&amp;gt;Value.lpszW) + wcslen(pspvSubject-&amp;gt;Value.lpszW) + 1;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; cds.cbData = sizeof(msgInfo);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //msg size in bytes&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; cds.lpData = &amp;amp;msgInfo;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; //pointer to the information to be sent&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // tell the main app about the text message&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if (SendMessage(newMsgWin, WM_COPYDATA, 0, (LPARAM) &amp;amp;cds) == (LRESULT) 1)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // a LRESULT of 1 means that the message was processed by parent application&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // so we delete the message and mark it as handled so it won't show up in Inbox&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; hr = DeleteMessage(pMsgStore, pMsg, cbMsg, lpMsg, cbDestFolder, lpDestFolder, pulEventType, pHandled);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // other LRESULT means message not handled by main app, pass it on&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; *pHandled = MRC_NOT_HANDLED;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;............&lt;span style="color: #666666;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;div style="color: #666666;"&gt;}&lt;/div&gt;&lt;br /&gt;Everything is straightforward, except that the lpData member of COPYDATASTRUCT structure has to be part of the structure memory area. This explains why an array of TCHAR, an not LPWSTR is used. If this is not followed, application may work or crash randomly without any indication why. &lt;br /&gt;&lt;br /&gt;The .NET code is as follows:&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [StructLayout(LayoutKind.Sequential)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private struct CopyDataStruct&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int IntData;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int Length;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [MarshalAs(UnmanagedType.LPWStr)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Data;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div style="color: #666666;"&gt;public class NewMsgWindow : MessageWindow&lt;br /&gt;{&lt;/div&gt;&lt;div style="color: #666666;"&gt;.......... &lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override void WndProc(ref Message m)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (m.Msg == WM_COPYDATA) //we received a message telling us that there is an incoming SMS &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CopyDataStruct cs = (CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(CopyDataStruct));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (cs.Data.Contains(delim))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string sender = cs.Data.Split(delim)[0];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string messageText = cs.Data.Split(delim)[1];&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (true)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // a LRESULT of 1 marks message as processed. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and native msg app will not show msg in Inbox&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m.Result = new IntPtr(1);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Other LRESULT indicates we did not intercept the message&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // and the message will be passed on to native messaging application.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m.Result = new IntPtr(0);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;.......&lt;/div&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The challenge is to receive the WM_COPYDATA message and marshal it back to a string. Most sample codes use GetLParam(), but as this is not supported by .NET CF, we have to use Marshal.PtrToStructure(). As commented, the .NET code will response with a result of either 1 or 0.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Source code&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The sample code is &lt;a href="http://www.mediafire.com/?q3wav3012hopk1i"&gt;here&lt;/a&gt;. Some part of the code was taken from the &lt;a href="http://remotetracker.sourceforge.net/"&gt;Remote Tracker&lt;/a&gt; open source project which also intercepts incoming text messages. Remote Tracker source code, however, parses the text message directly inside MapiRule.dll. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Setting up&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Some registry keys need to be modified for MapiRule.dll to be used. This can either be done via a CAB file, or via the CreateInterceptorMethod2() method in the code. A reboot is needed for changes to take effect. If you need to change MapiRule.dll, you will have to remove the registry keys via RemoveInterceptorMethod2(), reboot the device, update the dll, call CreateInterceptorMethod2() and reboot again! Terminating poutlook.exe and tmail.exe may also help to reduce the number of restarts on some devices. This makes the development process very time consuming. Debugging MapiRule.dll is possible by attaching the debugger to  tmail.exe. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Issues&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;There are still some minor issues yet to be solved. On HTC HD2, for some reasons, all text messages received will have the string " - GSM" appended at the end (refer to &lt;a href="http://inthehand.com/forums/t/2867.aspx"&gt;this&lt;/a&gt; discussion). Also, the total length of the sender name and the message text cannot exceed 500 since the TCHAR array length is hard coded. If you need to receive longer text message, the interprocess communication algorithm has to be modified to send and receive the text message part by part. You cannot simply increase the array length, as it will cause a stack fault.&lt;br /&gt;&lt;br /&gt;Last but not least, the approach described here works on all devices, including HTC Devices. So it can be used as a replacement for the MessageInterceptor class. In a sense, it's better as you can decide, at the point of receiving, which message to be processed, instead of pre-creating a set of MessageInterceptor conditions and re-creating them should the interception conditions change.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-9087597220033700844?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/9087597220033700844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/intercept-incoming-sms-message-on-htc.html#comment-form' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/9087597220033700844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/9087597220033700844'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/intercept-incoming-sms-message-on-htc.html' title='Intercept incoming SMS message on HTC Phones with HTC Sense'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-3559688518341672781</id><published>2010-07-06T14:57:00.000-07:00</published><updated>2010-07-17T03:10:55.924-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Compact Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Common problems with  .NET CF WebBrowser controls</title><content type='html'>Although most .NET developers will immediately think of the WebBrowser control when it comes to displaying HTML-formatted document, that seems to be more true for the full .NET framework rather than the compact framework. In fact, if your smart device application has to support a wide variety of devices, below are some reasons why the use of the WebBrowser control is discouraged:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. Inconsistent HTML support across different devices&lt;/b&gt;. Although simple formatting like bold, italic, underline and tables tend to work well, more complicated constructs (css, javascripts) will be dropped or simplified by many devices. There is no way to know for sure except for testing.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. WebBrowser.Navigate() opens a new window. &lt;/b&gt;On many devices, especially on devices where Opera is the default web browser, calling WebBrowser.Navigate() on a local file will simply open a new Opera browser window and leave the application. This will prevent many applications relying on the WebBrowser control from working.&lt;br /&gt;&lt;br /&gt;A workaround is to set back IE as the default web browser by modifying registry key, see &lt;a href="http://social.answers.microsoft.com/Forums/en-US/windowsmobile/thread/61605679-1086-4c81-a7a4-1c1e0f2f896e"&gt;this&lt;/a&gt;. Another workaround is not to use the extension ".htm" or ".html" when calling .Navigate(). For example, instead of&lt;br /&gt;&lt;br /&gt;WebBrowser1.Navigate("\\test.htm");&lt;br /&gt;&lt;br /&gt;use:&lt;br /&gt;&lt;br /&gt;WebBrowser1.Navigate("\\test.tmp");&lt;br /&gt;&lt;br /&gt;The document contents will still be rendered properly despite the ".tmp" extension. This trick, however, does not help if you want to the web browser to navigate to an external URL, e.g. http://www.google.com.&lt;br /&gt;&lt;br /&gt;Also, on many devices, the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.navigating.aspx"&gt;WebBrowser.Navigating &lt;/a&gt;event never fires, which I could not find a workaround for it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. Local images not rendered when DocumentText is set.&lt;/b&gt; This may seem a trivial problem with image path or format, but it's actually not. The problem is particular to .NET Compact Framework 3.5 running on Windows Mobile 6.5. The web browser control will refuse to render any local images and only display placeholder if the HTML is set via the DocumentText properly. Strangely it will display remote images from a web server. Images are also displayed correctly if the DocumentText is written to a file and loaded by calling Navigate(). The problem never appears on older .NET Compact Framework or Windows Mobile versions.&lt;br /&gt;&lt;br /&gt;All the above seemingly trivial problems are just making life harder for the Windows Mobile developers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-3559688518341672781?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/3559688518341672781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/common-problems-with-net-cf-webbrowser.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3559688518341672781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3559688518341672781'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/common-problems-with-net-cf-webbrowser.html' title='Common problems with  .NET CF WebBrowser controls'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2691231726182771811</id><published>2010-07-02T09:22:00.000-07:00</published><updated>2010-10-08T09:18:23.217-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blackberry'/><title type='text'>Blackberry and phone numbers with text</title><content type='html'>Recently I received an advertisement SMS from &lt;a href="http://www.standardchartered.com.sg/"&gt;Standard Chartered Bank&lt;/a&gt; having "StanChart" as the Sender ID. I accidentally pressed the dial (green) key and to my surprise my phone started to call 782624278. All I could get was, however, an automatic IVR announcement saying that the number is invalid. For a moment I wondered where the phone retrieved the number from, as I did not have an entry name 'StanChart' in my phonebook, and certainly would never store an invalid number in my phone book.&lt;br /&gt;&lt;br /&gt;The answer is that, Blackberry supports auto-detection of text in phone numbers, For &lt;a href="http://www.brighthub.com/mobile/blackberry-platform/articles/33299.aspx"&gt;example&lt;/a&gt;, you can have a contact with &lt;i&gt;1800-CALL-LTA&lt;/i&gt; as its number, and the phone will automatically call 1800-2255582&amp;nbsp; (Singapore &lt;a href="http://www.lta.gov.sg/"&gt;Land Transport Authority&lt;/a&gt;) for you. My case was a similiar example, the phone automatically translated "StanChart" to 782624278 and dialled the number for me.&lt;br /&gt;&lt;br /&gt;Although the first case (&lt;i&gt;1800-CALL-LTA) &lt;/i&gt;is no doubt very useful to assist users in memorising the phone number, automatically conversion of an SMS sender ID to a phone number is sort of an overkill and result in the wrong number being called.&lt;br /&gt;&lt;br /&gt;The same behaviour can be seen on iPhone as well. Windows Mobile, however, does not support the feature.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2691231726182771811?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2691231726182771811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/blackberry-and-phone-numbers-with-text.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2691231726182771811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2691231726182771811'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/07/blackberry-and-phone-numbers-with-text.html' title='Blackberry and phone numbers with text'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2696046815838409492</id><published>2010-06-29T05:01:00.000-07:00</published><updated>2010-07-23T08:10:19.435-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Compact Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>.NET CF MessageInterceptor class fails to intercept incoming messages</title><content type='html'>If you're writing an SMS application that intercepts incoming text messages using the &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.windowsmobile.pocketoutlook.messageinterception.messageinterceptor.aspx"&gt;MessageInterceptor&lt;/a&gt; class and observe that your application does not work on a particular phone, below is a list of things to check:&lt;br /&gt;&lt;br /&gt;1. Most new HTC Phones will choose HTC Messages (part of &lt;a href="http://en.wikipedia.org/wiki/HTC_Sense"&gt;HTC Sense&lt;/a&gt;), and not &lt;a href="http://www.microsoft.com/windowsmobile/en-us/meet/applications/office-outlook-mobile.mspx"&gt;Pocket Outlook&lt;/a&gt;, as the default messaging spplication. HTC Message does not implement the MessageInterceptor class. To overcome this problem, you'll need to set Pocket Outlook as the default messaging application by using this &lt;a href="http://handheld.softpedia.com/get/Tweaks/Zenyee-Disable-HTC-Messaging-82632.shtml"&gt;patch&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note:&lt;/b&gt; You may not be able to send/receive MMS after installing the patch. To use MMS, please install the &lt;a href="http://www.1800pocketpc.com/2008/05/27/arcsoft-mms-50317.html"&gt;Arcsoft MMS client&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (19 July 2010):&lt;/b&gt; I have found a way to intercept incoming messages on affected HTC phones without installing any patch by using MAPI Rule. For more information, see &lt;a href="http://minhdanh2002.blogspot.com/2010/07/intercept-incoming-sms-message-on-htc.html"&gt;this &lt;/a&gt;post.&lt;br /&gt;&lt;br /&gt;2. Some phones have a specific registry key to manually enable MessageInterceptor. Check HKEY_LOCAL_MACHINE\Software\Microsoft\Inbox\Svc\SMS\Rules and look for a key branch that looks like a GUID, e.g. {1000BC1C-F4A3-4210-B197-4AEBF2CEE6F5} Open that key, set the default value to 0 and reboot the phone to allow message interception.&lt;br /&gt;&lt;br /&gt;3. You may have conflicting message interceptor rules left-over from other applications. To fix this, go to HKey_Local_Machine\Software\Microsoft\Inbox\Rules\, delete all sub-entries and reboot the phone. To avoid this from happening in the future, always call Dispose() on a MessageInterceptor when you finish using it or when your application closes.&lt;br /&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://social.msdn.microsoft.com/Forums/en/vssmartdevicesvbcs/thread/e56f6db2-70d6-43a9-b3f2-7d476aabfa7e"&gt;http://social.msdn.microsoft.com/Forums/en/vssmartdevicesvbcs/thread/e56f6db2-70d6-43a9-b3f2-7d476aabfa7e&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2. &lt;a href="http://stackoverflow.com/questions/2138650/messageinterceptor-is-not-called-on-htc-hd2"&gt;http://stackoverflow.com/questions/2138650/messageinterceptor-is-not-called-on-htc-hd2&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2696046815838409492?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2696046815838409492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/net-cf-messageinterceptor-class-fails.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2696046815838409492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2696046815838409492'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/net-cf-messageinterceptor-class-fails.html' title='.NET CF MessageInterceptor class fails to intercept incoming messages'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-4918250747036621253</id><published>2010-06-23T20:54:00.000-07:00</published><updated>2010-10-08T08:44:37.559-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wikipedia'/><title type='text'>Wikipedia in MobiPocket ebook (PRC) format</title><content type='html'>Following my previous &lt;a href="http://minhdanh2002.blogspot.com/2008/11/pocketwikipedia-wikipedia-on-pocketpc.html"&gt;post &lt;/a&gt;on a version of Wikipedia for Windows Mobile improved from the &lt;a href="http://download.cnet.com/Pocket-Wikipedia/3000-2056_4-10859974.html"&gt;original&amp;nbsp;&lt;/a&gt;&lt;span class="title"&gt; Pocket Wikipedia 1.0 &lt;/span&gt;version by free-soft.ro, I decided to find a MobiPocket (PRC) version, to read on my Blackberry phone, Unfotunately I could not find a usable version - many versions I found, including PRC, are incomplete, with images stripped off, and not suitable for mobile viewing. There is also an &lt;a href="http://www.wikipock.com/"&gt;expensive Wikipedia software &lt;/a&gt;for most mobile platforms. TomeRaider also offers a few free versions of wikipedia (&lt;a href="http://www.tomeraider.com/#getBookDetails:616"&gt;with images&lt;/a&gt;,&amp;nbsp; and compact &lt;a href="http://www.tomeraider.com/ebooks/reference/encyclopedias/download_wikipedia_compact_no_images_ebook--DLD652.php"&gt;without images&lt;/a&gt; around 50MB) of Wikipedia in its propietary format. As none of these suit my needs, I decided to go ahead with creating my own PRC version of Wikipedia.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The article database&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I decided to use the same article database (Wikipedia.wi) as &lt;span class="title"&gt;Pocket Wikipedia 1.0, which turns out to be the &lt;a href="http://www.soschildrensvillages.org.uk/charity-news/archive/2007/05/wikipedia-for-schools"&gt;2007 School Wikipedia selection&lt;/a&gt;. Although the source code was never released, the binary was not obfuscated and after a bit of decompiling using .NET Reflector, I was able to extract the articles and images from the 180MB &lt;a href="http://sourceforge.net/projects/sevenzip/"&gt;SevenZip&lt;/a&gt;-compressed database.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="title"&gt;&lt;b&gt;Building the PRC ebook&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="title"&gt;My first thought was to rely on the &lt;a href="http://www.mobipocket.com/en/downloadsoft/productdetailscreator.asp"&gt;MobiPocket Creator&lt;/a&gt;&lt;/span&gt; user interface. However, its UI is terrible - there is no way to add multiple HTML/image files at a time, you have to add them one by one. Even if drag and drop is supported, the application stops responding when a lot of files are added. I then decided to create the &lt;a href="http://www.mobipocket.com/dev/article.asp?BaseFolder=prcgen&amp;amp;File=mobiformat.htm"&gt;OPF&lt;/a&gt; file myself, then feed it into &lt;a href="http://www.mobipocket.com/soft/prcgen/mobigen.zip"&gt;mobigen&lt;/a&gt; or &lt;a href="http://www.amazon.com/gp/feature.html?ie=UTF8&amp;amp;docId=1000234621"&gt;kindlegen&lt;/a&gt; in order to create the final PRC file.&lt;br /&gt;&lt;br /&gt;The source code to extract the articles and create the OPF file was written in .NET and can be downloaded &lt;a href="http://www.mediafire.com/?mtmnwy3qklg"&gt;here&lt;/a&gt;. Once the OPF is created, as there are more than 5000 articles and 24,000 images, kindlegen/mobigen takes more than 15 minutes on a 3Ghz processor to create the final PRC file.&lt;br /&gt;&lt;br /&gt;Some of the articles contain Unicode characters (for example, various currency symbols) but were extracted and saved in ASCII format. I have tried various methods in System.Text.Encoding to convert to Unicode before saving without success. The only resolution I found is to use &lt;a href="http://www.rotatingscrew.com/utfcast.aspx"&gt;UTFCast Express&lt;/a&gt; (freeware) to convert the HTML files to Unicode before feeding them into kindlegen/mobigen.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The product: Wikipedia on a 214MB PRC file&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The final compressed PRC file can be downloaded here. It's a multi-part RAR file, so &lt;b style="color: red;"&gt;you will need to download both parts &lt;/b&gt;to the same directory and use WinRar to extract the PRC file.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mediafire.com/download.php?zmoyznlmjtu/"&gt;PocketWikipedia.part1.rar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a class="foldername" href="http://www.mediafire.com/download.php?jzmt22qnrin" id="ancfilename14" target="_blank"&gt;PocketWikipedia.part2.rar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It contains all articles and images as in the original version, with a subject list, and an index where the titles of all articles can be looked up. As the title list is generated automatically by guessing the few words of the article, there are cases where the title are not retrieved properly, which can be resolved by editing the index manually in the OPF file before calling kindlegen to generate the PRC file.&lt;br /&gt;&lt;br /&gt;Due to the large file size, some desktop versions of MobiPocker ebook reader may fail to open the file due to a Win32 exception. Mobile versions, in particular Blackberry and Windows Mobile, seem to open the PRC file properly.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;UPDATE (8 Oct 2010):&lt;/b&gt; A Vietnamese &lt;a href="http://www.e-thuvien.com/forums/showthread.php?t=37870"&gt;reader&lt;/a&gt;  has used my instructions to create an improved version of the Wikipedia  ebook in PRC format. The new version, which fixes some font problems  and has improved search support, can be downloaded &lt;a href="http://www.mediafire.com/?irjz8ane4dojcbh"&gt;here&lt;/a&gt; and &lt;a href="http://www.mediafire.com/?xs5p43xb9hqts6b"&gt;here&lt;/a&gt;. It's a multi-part RAR file, so &lt;b style="color: red;"&gt;you will need to download both parts &lt;/b&gt;to the same directory and use WinRar to extract the original PRC file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-4918250747036621253?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/4918250747036621253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/wikipedia-in-mobipocket-ebook-prc.html#comment-form' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4918250747036621253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4918250747036621253'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/wikipedia-in-mobipocket-ebook-prc.html' title='Wikipedia in MobiPocket ebook (PRC) format'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6139532890154398812</id><published>2010-06-19T06:08:00.000-07:00</published><updated>2010-06-20T20:51:54.857-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET Compact Framework'/><title type='text'>SerializableDictionary and System.InvalidOperationException</title><content type='html'>I recently attempted to use Paul Welter's &lt;a href="http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx"&gt;SerializableDictionary&lt;/a&gt; in one of my Windows Mobile projects, Everything seems to work well with no code motifications, until when I need to serialize a class containing 2 dictionaries: &lt;br /&gt;&lt;br /&gt;&lt;div style="color: #666666;"&gt;public class AppConfig&lt;/div&gt;&lt;div style="color: #666666;"&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public SerializableDictionary&lt;string, string=""&gt; Dictionary1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public SerializableDictionary&lt;string, string=""&gt; Dictionary2;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/string,&gt;&lt;/string,&gt;&lt;/div&gt;&lt;span style="color: #666666;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Attempt to serialize the above class will fail with a &lt;b&gt;System.InvalidOperationException: Two mapping for dictionary.&lt;/b&gt; Searching the web for the exact error message returns no useful result, except for a &lt;a href="http://software.itags.org/software-application/238226/"&gt;posting&lt;/a&gt; which described a similiar problem (&lt;b&gt;Two mappings for SourceTree.DTO.InventoryItemCollection.&lt;/b&gt;) but did not provide a solution. The posting also explicitly mentioned that the error occurred only on .NET Compact Framework, and not on the full framework.&lt;br /&gt;&lt;br /&gt;The root cause of the error is at the first few lines of the SerializableDictionary source code:&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #666666;"&gt;[XmlRoot("dictionary")]&lt;/div&gt;&lt;span style="color: #666666;"&gt;public class SerializableDictionary&lt;tkey, tvalue=""&gt;&lt;/tkey,&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Dictionary&lt;tkey, tvalue=""&gt;, IXmlSerializable&lt;/tkey,&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With this declaration, when 2 SerializableDictionary stay in the same class (which will be serialized), there will perhaps be a conflict somewhere as both of them are set up to use the same XmlRoot element ("dictionary").&lt;br /&gt;&lt;br /&gt;A workaround is not to define XmlRoot inside SerializableDictionary class, but to create another class inheriting from SerializableDictionary and define XmlRoot in this class:&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #666666;"&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;//parent class: SerializableDictionary&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;public class  SerializableDictionary&lt;tkey, tvalue=""&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; :  Dictionary&lt;tkey, tvalue=""&gt;, IXmlSerializable { .... }&lt;/tkey,&gt;&lt;/tkey,&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;//dictionary 1 &lt;/div&gt;&lt;div style="color: #666666;"&gt;[XmlRoot("SerializableDictionary1")]&lt;/div&gt;&lt;div style="color: #666666;"&gt;public class SerializableDictionary1&lt;tkey, tvalue=""&gt; : SerializableDictionary&lt;tkey, tvalue=""&gt; { }&lt;/tkey,&gt;&lt;/tkey,&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;//dictionary 2&lt;/div&gt;&lt;div style="color: #666666;"&gt;[XmlRoot("SerializableDictionary2")]&lt;/div&gt;&lt;div style="color: #666666;"&gt;public class SerializableDictionary2&lt;tkey, tvalue=""&gt; : SerializableDictionary&lt;tkey, tvalue=""&gt; { }&lt;/tkey,&gt;&lt;/tkey,&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;//the class to be serialized&lt;/div&gt;&lt;div style="color: #666666;"&gt;public class AppConfigNew&lt;/div&gt;&lt;div style="color: #666666;"&gt;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public SerializableDictionary1&lt;string, string=""&gt; Dictionary1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public  SerializableDictionary2&lt;string, string=""&gt; Dictionary2;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/string,&gt;&lt;/string,&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;}&lt;/div&gt;&lt;br /&gt;This requires a few more lines of code, but is the cleanest workaround I have found. Also, I have yet to figure out why the full framework does not have such a problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6139532890154398812?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6139532890154398812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/serializabledictionary-and.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6139532890154398812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6139532890154398812'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/serializabledictionary-and.html' title='SerializableDictionary and System.InvalidOperationException'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-8145835174120617921</id><published>2010-06-13T08:37:00.000-07:00</published><updated>2010-07-16T20:21:00.192-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VB.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET Framework'/><title type='text'>Extension method and VB.NET With construct</title><content type='html'>Recently I came across a codeproject &lt;a href="http://www.codeproject.com/KB/vb/BeginnerExtensionMethods.aspx"&gt;article&lt;/a&gt; about extension methods in VB.NET, where one reader &lt;a href="http://www.codeproject.com/Messages/3059174/Be-aware-of-working-with-extensions-and-With-End-W.aspx"&gt;complained &lt;/a&gt;that he could not get it to work when using VB.NET's &lt;a href="http://msdn.microsoft.com/en-us/library/wc500chb%28VS.80%29.aspx"&gt;&lt;span id="goog_698897187"&gt;&lt;/span&gt;With &lt;/a&gt;construct. The comment by the reader is very long and contains irrelevant code, but the issue is valid. This post will demonstrate the issue and summarize some of my findings.&lt;br /&gt;&lt;br /&gt;Suppose you have the following code:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Snippet #1:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;system.runtime.compilerservices.extension()&gt;&amp;lt;System.Runtime.CompilerServices.Extension()&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Public Sub ModifyString(ByRef source As String)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; source += " modified"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sub Main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim str As String = "original"&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; str.ModifyString()&lt;/system.runtime.compilerservices.extension()&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.WriteLine(str)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&amp;nbsp;&lt;/div&gt;&lt;br /&gt;When the code is run, you will get the value "original modified" as expected. Now change the extension method call to be inside a With construct:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Snippet #2:&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt; &lt;br /&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sub Main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim str As String = "original"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; With str&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .ModifyString()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; End With&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.WriteLine(str)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&lt;/div&gt;&lt;br /&gt;You will now get "original", e.g. the string "temp" is never modified! This is clearly a bug in the framework itself so no workaround is available. Neverthess, let's look at the IL code for the above 2 code samples. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Snippet #1 in IL (No 'With' is used):&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .method public static void Main() cil managed&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .entrypoint&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .maxstack 1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .locals init (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [0] string str)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0000: nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0001: ldstr "original"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0006: stloc.0 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0007: ldloca.s &lt;b&gt;str&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0009: call void ConsoleApplication1.Module1::ModifyString(string&amp;amp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_000e: nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_000f: nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0010: ret &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Snippet #2 in IL ('With' is used):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #999999;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .method public static void Main() cil managed&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .custom instance void [mscorlib]System.STAThreadAttribute::.ctor()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .entrypoint&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .maxstack 1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .locals init (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [0] string str,&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [1] string str2&lt;/b&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0000: nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0001: ldstr "original"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0006: stloc.0 &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0007: ldloc.0 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0008: stloc.1 &lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0009: ldloca.s &lt;b&gt;str2&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_000b: call void ConsoleApplication1.Module1::ModifyString(string&amp;amp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0010: nop &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0011: ldnull &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0012: stloc.1 &lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0013: nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0014: ret &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;div style="color: #999999;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: black;"&gt;The different is obvious when a text comparison tool such as &lt;a href="http://www.prestosoft.com/ps.asp?page=edp_examdiffpro/"&gt;ExamDiff&lt;/a&gt; is used. When a With construct is used, the compiler generates extra code to create a copy of the string variable (&lt;b&gt;str&lt;/b&gt; is copied to &lt;b&gt;str2&lt;/b&gt;) and pass it to the extension method ModifyString! So whatever changes made to the string have no effect on the original variable, in spite of the ByRef keywork to pass the string by reference. This explains why we get the original value of the string variable.&lt;/div&gt;&lt;div style="color: black;"&gt;&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="color: black;"&gt;Now change the code to:&lt;/div&gt;&lt;div style="color: black;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: black;"&gt;&lt;b&gt;Snippet #3:&lt;/b&gt; &lt;/div&gt;&lt;div style="color: black;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: black;"&gt;&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Sub Main()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim str  As String = "original"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; With str&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;  &lt;b&gt;str&lt;/b&gt;.ModifyString()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; End With&lt;/div&gt;&lt;div style="color: #666666;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.WriteLine(str)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End Sub&lt;/div&gt;&lt;div style="color: #666666;"&gt;&lt;br /&gt;&lt;/div&gt;We still use the With construct, but instead of using shorthand to call the extension method, we explicitly refer to the string variable. Guess what, now you'll get the correct result "original modified"! Let's look at the IL code to see what happened:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Snippet #3 in IL:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #999999;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .method public  static void Main() cil managed&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .custom  instance void [mscorlib]System.STAThreadAttribute::.ctor()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  .entrypoint&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .maxstack 1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .locals  init (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [0] string str,&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  [1] string str2&lt;/b&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0000: nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  L_0001: ldstr "original"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0006: stloc.0 &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  L_0007: ldloc.0 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0008: stloc.1 &lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0009: ldloca.s &lt;b style="color: red;"&gt;str&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  L_000b: call void  ConsoleApplication1.Module1::ModifyString(string&amp;amp;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  L_0010: nop &lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0011: ldnull &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0012: stloc.1 &lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; L_0013: nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  L_0014: ret &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;br /&gt;A copy of the original string variable (&lt;b&gt;str2&lt;/b&gt;) is created as usual, but it was never used. Instead, the original string variable (&lt;b&gt;str&lt;/b&gt;) is passed to the extension method. This explains why everything works as intended.&lt;br /&gt;&lt;br /&gt;The conclusion is to never use With...End With together with extension method as you may get unexpected results. As for the solution, well, I'll leave it up to whoever designs the .NET framework...&lt;br /&gt;&lt;br /&gt;UPDATE (17 June 2010): The issue was submitted to Microsoft Connect &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/569057/problem-with-extension-method-and-vb-net-with-construct?wa=wsignin1.0"&gt;here&lt;/a&gt;. They acknowledge the issue, yet decided to do nothing, not even adding a compilation warning.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-8145835174120617921?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/8145835174120617921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/extension-method-and-vbnet-with.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/8145835174120617921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/8145835174120617921'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/extension-method-and-vbnet-with.html' title='Extension method and VB.NET With construct'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-3826853200790085728</id><published>2010-06-03T04:13:00.000-07:00</published><updated>2010-06-19T06:09:09.882-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft Visual Studio'/><title type='text'>Error accessing VC80.idb during compilation of VC++ project</title><content type='html'>If you're getting the following error&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;&lt;i&gt;Could not delete file  ‘c:\project\obj\release\vc80.idb &lt;br /&gt;Make sure that the file is not  open by another process and is not write-protected.&lt;/i&gt;&lt;/b&gt;&lt;/blockquote&gt;while building large VS solution with many VC++ projects, in a random and inconsitent manner, most likely you have just hit another Visual Studio bug. VS, by default, attempts to build multiple projects concurrently on system with multiple processors, which may cause the above error if different projects share the same IDB (VC++ Minimum Rebuild Dependency) file.&lt;br /&gt;&lt;br /&gt;There are several &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/100564/vc-can-not-delete-vc80-idb-during-compile"&gt;solutions &lt;/a&gt;for this, but the simplest one would be to tell VS not to build multiple projects concurrently. To do this, open Tools&amp;gt;Options&amp;gt;Projects and Solutions&amp;gt;Build and Run, and set the value of &lt;b&gt;Maximum  number of parallel project builds&lt;/b&gt; to 1. However, with this method, your solution will take longer to build.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-3826853200790085728?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/3826853200790085728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/error-accessing-vc80idb-during.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3826853200790085728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3826853200790085728'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/06/error-accessing-vc80idb-during.html' title='Error accessing VC80.idb during compilation of VC++ project'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-3476040080120584701</id><published>2010-05-31T06:01:00.000-07:00</published><updated>2011-12-12T07:40:23.295-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blogger'/><title type='text'>Full RSS feed for blogger posts/comments</title><content type='html'>The official RSS feeds given by Google (&lt;a href="http://www.google.com/support/blogger/bin/answer.py?hl=en&amp;amp;answer=97933"&gt;http://www.google.com/support/blogger/bin/answer.py?hl=en&amp;amp;answer=97933&lt;/a&gt;) only retrieve the latest 50 posts and 20 comments, even if the settings under &lt;b&gt;Site Feed &lt;/b&gt;has been set to &lt;b&gt;Full&lt;/b&gt;. This default behaviour is useful as readers are usually only interested in latest posts, but will be a problem if you somehow want the RSS feed to show your entire blog.&lt;br /&gt;&lt;br /&gt;The solution is simple, just add a HTTP GET parameter to the official RSS URL. For example, if your RSS feed is:&lt;br /&gt;&lt;br /&gt;http://blogname.blogspot.com/feeds/posts/default?alt=rss&lt;br /&gt;&lt;br /&gt;The feed that returns the full blog is:&lt;br /&gt;&lt;br /&gt;http://blogname.blogspot.com/feeds/posts/default?alt=rss&lt;b&gt;&amp;amp;max-results=N&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Same for comments, add the &lt;b&gt;max-results&lt;/b&gt; parameter to retrieve all comments:&lt;br /&gt;&lt;br /&gt;http://blogname.blogspot.com/feeds/comments/default?alt=rss&lt;b&gt;&amp;amp;max-results=N&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;where N is the maximum number of posts/comments you want to retrieve.&lt;b&gt; &lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-3476040080120584701?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/3476040080120584701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/05/full-rss-feed-for-blogger-postscomments.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3476040080120584701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3476040080120584701'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/05/full-rss-feed-for-blogger-postscomments.html' title='Full RSS feed for blogger posts/comments'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-4292184396948170413</id><published>2010-05-02T20:22:00.000-07:00</published><updated>2010-05-08T22:06:59.008-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft Visual Studio'/><title type='text'>Identifying used and unused resources in a Visual Studio's project Resources.resx file</title><content type='html'>If you often use project resources in a Visual Studio project, be it VB or C#, eventually you will end up with a big resource file (e.g. Resources) containing many unused items. This is because, when you remove the code that uses the resoure, very often you will forget to remove the actual resource item.&lt;br /&gt;&lt;br /&gt;There are &lt;a href="http://www.google.com.sg/search?q=Resources.resx+identify+unused&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=org.mozilla:en-GB:official&amp;amp;client=firefox-a"&gt;solutions&lt;/a&gt; to this problems such as using commercial code refactoring tool or making some minor modifications to Resources.Designer.vb/Resources.Designer.cs and relying on the compiler to generate warnings about unused resources. In this post, I choose to take a different approach: &lt;b&gt;use a batch script&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;My complete &lt;a href="http://www.mediafire.com/?th25ykzt1dd"&gt;batch script&lt;/a&gt; will accept 4 parameters from the command line, listed from left to right:&lt;br /&gt;&lt;br /&gt;1. Path to the VB.NET source code files, e.g. WindowsApplication1\*.vb&lt;br /&gt;2. Name of project resource file, e.g. WindowsApplication1\My Project\Resources.resx&lt;br /&gt;3. Name of file where all resources' usage are written, e.g. all_resources.txt&lt;br /&gt;4. Name of file where all unused resources are written, e.g. unused_resources.txt&lt;br /&gt;&lt;br /&gt;It makes use of the FOR extended syntax (FOR /F) to parse the resource file and FINDSTR to find where all the resources are referred to. It will only work properly with VB source code files, where most developers often use My.Resources.XXXX to access the resources. As FINDSTR simply performs a string search, the batch script will not care about code that are commented out, as well as resources that are accessed not by using the Vb's &lt;b&gt;My&lt;/b&gt; namespace. If you want to use this with C# source code, you'll need to edit the call to FINDSTR to match your method of accessing the resources, e.g. Project1.Resources.Resource1 instead of My.Resources.Resource1.&lt;br /&gt;&lt;br /&gt;The rest of this post will analyse some interesting points I encountered when writing it - hope this will be useful for those having similiar problems.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Batch script - powerful despite being crude&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Many people may think that batch script is a thing of the past, since there are so many alternatives today - Windows PowerShell, Perl, or a .VBS file. Yet sometimes I still use it due to its powerful but simple nature. Take a look at the code to search for the resource:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;FOR /F "tokens=*" %%a IN (%TMPFILE%) DO (&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;.........&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; FINDSTR /S /P /N /C:"My.Resources.%%c" %SRCPATH% &amp;gt;&amp;gt; %OUT_ALLTOKENS%&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; REM FindStr returns an errorlevel of 0 if the string was found, 1 and above if it was not found.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; IF ERRORLEVEL 1 (&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;.........&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;............. &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;span style="font-family: Arial,Helvetica,sans-serif;"&gt;The call to &lt;b&gt;FOR /F&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;b&gt;FINDSTR&lt;/b&gt; can easily translate into 10-20 lines of .NET code, unless you use some existing text processing libraries. Here, almost everything is done, just simply remember the syntax, available via &lt;b&gt;FOR /?&lt;/b&gt; or &lt;b&gt;FINDSTR /?&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;Another example is how to generate a random file name:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;:GETTEMPNAME&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;set TMPFILE=%TMP%\mytempfile-%RANDOM%-%TIME:~6,5%.tmp&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if exist "%TMPFILE%" GOTO :GETTEMPNAME &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The equivalent .NET code would be:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt; filename = Path.GetTempFileName()&lt;/pre&gt;&lt;br /&gt;However, batch scripts are still very crude. For example, although Windows XP batch scripts allow the use of block statement via (........), don't expect everything to work as they do in a modern programming language. The following would cause problem:&lt;br /&gt;&lt;div style="font-family: Arial,Helvetica,sans-serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;IF (%1) == () (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ECHO Missing first parameter: path to the VB.NET source code files (e.g. WindowsApplication1\*.vb)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXIT /B 1&lt;br /&gt;) ELSE (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET SRCPATH=%1&lt;br /&gt;)&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Execution would terminate shortly upon reaching &lt;b&gt;ECHO&lt;/b&gt;, without any indication why. I believe it would take many people some time to figure out what causes it and fix it. The following will work:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;IF (%1) == () (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ECHO Missing first parameter: path to the VB.NET source code files, &lt;b&gt;e.g. WindowsApplication1\*.vb&lt;/b&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; EXIT /B 1&lt;br /&gt;) ELSE (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SET SRCPATH=%1&lt;br /&gt;)&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;Also the above example demonstrates how to check for missing parameter. This would have made more sense in C# or VB.NET, just compare against an empty string (e.g. &lt;b&gt;""&lt;/b&gt;). &lt;br /&gt;&lt;br /&gt;There are many other useful code snippets in this batch script, for example, how to use &lt;a href="http://ss64.com/nt/setlocal.html"&gt;delayed environment variable expansion&lt;/a&gt;, or how to use &lt;a href="http://www.computing.net/answers/programming/how-to-specify-quotes-as-delimiter/15313.html"&gt;double quotes as delimiters&lt;/a&gt; in FOR /F. I will not explain it in details - the code is well commented, take some time to study it yourself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-4292184396948170413?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/4292184396948170413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/05/identifying-used-and-unused-resources.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4292184396948170413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4292184396948170413'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/05/identifying-used-and-unused-resources.html' title='Identifying used and unused resources in a Visual Studio&apos;s project Resources.resx file'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-7642221980607190471</id><published>2010-04-30T21:41:00.000-07:00</published><updated>2010-04-30T23:51:39.707-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Tips'/><title type='text'>1440x900 resolution on Intel 945GM Express Chipset</title><content type='html'>My laptop is using a Intel 945GM Express Chipset graphics card. Recently I purchased a 19" LCD with 1440x900 &lt;a href="http://en.wikipedia.org/wiki/Native_resolution"&gt;naive resolution&lt;/a&gt;. Believe it or not, it was very difficult to set the correct resolution for the LCD as my graphics card is quite old and does not officially support 16:10 resolution. The closest it supports is 1440x1050, causing distortion on the LCD.&lt;br /&gt;&lt;br /&gt;I solved the problem by using PowerStrip. With some simple configuration as per &lt;a href="http://www.freakygaming.com/tutorials/how_to_configure_custom_resolutions_in_windows.html"&gt;this,&lt;/a&gt; I am able to add a new custom resolution and get it to work:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/S9uuwmXL86I/AAAAAAAAADY/-0sKzu0fhVo/s1600/resolution.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="472" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/S9uuwmXL86I/AAAAAAAAADY/-0sKzu0fhVo/s640/resolution.PNG" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;However, with this I encountered the next challenge. Media Player Classic, which is my favourite media player, is unable to play video on my LCD monitor when configured as the secondary monitor. I always got the error message&lt;br /&gt;&lt;br /&gt;&lt;b&gt;"Due to limitations of your computer's display device, this video can  only play back on one of your monitors. Please move the video window  completely onto that monitor"&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;whenever I attempt to play videos on the LCD.&lt;br /&gt;&lt;br /&gt;After some research, I found out that the problem has to do with &lt;a href="http://en.wikipedia.org/wiki/Hardware_overlay"&gt;hardware overlay&lt;/a&gt; (see &lt;a href="http://www.rage3d.com/board/archive/index.php?t-33602201.html"&gt;this&lt;/a&gt;). Media Play Classic seems to attempt hardware overlay on both the primary and secondary monitors, which, unfortunately, is not within the capabilities of the graphics card.&lt;br /&gt;&lt;br /&gt;I decided to change to VLC media player. However, VLC, by default, uses software rendering and does not play HD movies smoothly. When configure to playback using hardware overlay, VLC encounters the same problem as Media Player Classic. Even worse, there is no clear error message - the application simply crashes or plays videos with huge delay/distortion. Windows Media Player works for some simple movies (.avi, .wmv, ...) but fails to play many other formats.&lt;br /&gt;&lt;br /&gt;Finally, some googling on the best free media player leads me to &lt;a href="http://www.bsplayer.org/"&gt;BS Player&lt;/a&gt;. I switch to it and everything seems good so far. Sometimes, the player would crash upon closing but that does not seem to be a big problem for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-7642221980607190471?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/7642221980607190471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/04/1440x900-resolution-on-intel-945gm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7642221980607190471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7642221980607190471'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/04/1440x900-resolution-on-intel-945gm.html' title='1440x900 resolution on Intel 945GM Express Chipset'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_w4YbCKQ5wkQ/S9uuwmXL86I/AAAAAAAAADY/-0sKzu0fhVo/s72-c/resolution.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-3623775343067214805</id><published>2010-04-27T21:02:00.000-07:00</published><updated>2010-08-20T19:13:58.955-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VoIP'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Native SIP on Windows Mobile 6.1 and 6.5</title><content type='html'>Although Windows Mobile 6.1 and above supports SIP natively, the user does not always have the ability to configure SIP settings. In particular, SIP (a.k.a Internet Call) needs to be enabled in the device firmware, and SIP server configuration needs to be set via registry. This post summarizes the step needed to enable SIP and make Internet Calls from the phone's native dialer.&lt;br /&gt;&lt;br /&gt;First, you must check if your firmware enables Internet Call. There should be an Internet Call item on your Today Screen:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/S9ujfDTlReI/AAAAAAAAADA/p6GSQcfLTLU/s1600/Screen01.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/S9ujfDTlReI/AAAAAAAAADA/p6GSQcfLTLU/s320/Screen01.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you are not using the standard Today screen plugin, check your Phone settings, there should be a tab for Internet Call:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/S9ukGv9fORI/AAAAAAAAADI/ePUCdU-gL3E/s1600/Screen02.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_w4YbCKQ5wkQ/S9ukGv9fORI/AAAAAAAAADI/ePUCdU-gL3E/s320/Screen02.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Your operator may have bundled the SIP configuration settings with the phone. If so, you're good to go, just select either "Whenever Available" or "Only if cellular is not available" from the drop down. The phone will attempt SIP registration whenever a connection is available and you'll see "Internet Call: Available" on the Today screen when SIP is registered. If SIP is not registered, you'll see "Internet Call: No Service".&lt;br /&gt;&lt;br /&gt;If your phone does not have bundled SIP configuration settings, you will need to configure it yourself. You can do this manually, but I'd recommend using a tool called &lt;a href="http://handheld.softpedia.com/get/System-Utilities/Enhancements/SIP-Config-Tool-43588.shtml"&gt;Sip Config Tool&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/S9ulK40IlVI/AAAAAAAAADQ/ZfkVFM95sME/s1600/Screen03.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_w4YbCKQ5wkQ/S9ulK40IlVI/AAAAAAAAADQ/ZfkVFM95sME/s320/Screen03.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Input your SIP server configuration and choose to save. This will overwrite any existing configuration. By default, SIP over a cellular connection is disabled, but you can enable it via the menu if you want to.&lt;br /&gt;&lt;br /&gt;You may need some configuration to make sure that the number you dial from the dialpad gets translated into a proper SIP address. Check \windows\ipdialplan.xml and you'll see something like this:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;rule pattern="(\d+)"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/rule&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;&lt;rule pattern="(\d+)"&gt;!-- International --&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/rule&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;&lt;rule pattern="(\d+)"&gt;rule pattern='(\d+)'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dial='sip:\1@$host$'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; display='\1'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; transfer='sip:\1@$host$'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; /&amp;gt;&lt;/rule&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;pattern:&lt;/b&gt; the number you dial in the dialpad&lt;br /&gt;&lt;b&gt;dial: &lt;/b&gt;the actual SIP address where INVITE request is sent to&lt;br /&gt;&lt;b&gt;display:&lt;/b&gt; the number to be displayed during the call&lt;br /&gt;&lt;br /&gt;The default configuration is only suitable for US number so you may need to change them as appropriate according to your country's telephone nunbering plan. In my case, I remove everything except one entry in the International section. To dial a number, I simple enter the full format, country code + area code + telephone number.&lt;br /&gt;&lt;br /&gt;If your device does not support playing audio on the &lt;a href="http://minhdanh2002.blogspot.com/2009/05/switch-between-loudspeaker-earpiece.html"&gt;earpiece &lt;/a&gt;via &lt;a href="http://msdn.microsoft.com/en-us/library/aa923031.aspx"&gt;RIL_SetAudioDevices&lt;/a&gt;, don't expect Internet calls to work with your earpiece. In my case (Acer F900), audio is played via loudspeaker unless a headset is connected, with a lower volume to simulate the earpiece. At the beginning of every call, a beep tone will be played to indicate an Internet call.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-3623775343067214805?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/3623775343067214805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/04/native-sip-on-windows-mobile-61-and-65.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3623775343067214805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3623775343067214805'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/04/native-sip-on-windows-mobile-61-and-65.html' title='Native SIP on Windows Mobile 6.1 and 6.5'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_w4YbCKQ5wkQ/S9ujfDTlReI/AAAAAAAAADA/p6GSQcfLTLU/s72-c/Screen01.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-4801084422821950039</id><published>2010-04-15T20:33:00.000-07:00</published><updated>2010-04-30T23:31:55.947-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Framework'/><title type='text'>"csc.exe - Application Error" when shutting Windows with a .running  NET application</title><content type='html'>Recently a friend reported to me that my application written in .NET prevents his computer from shutting down. If the application is running when Windows tries to shut down, the following error message appears and Windows cannot shut down:&lt;br /&gt;&lt;br /&gt;&lt;div align="left"&gt;&lt;i&gt;&lt;b&gt;csc.exe - Application Error&lt;/b&gt;&lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt;The application failted to initialize properly  (0xc0000142). Click on OK to terminate the application.&lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="left"&gt;Some investigation reveals that the issue has to do with the .NET class XmlSerializer. My application stores user data into an XML file, which gets saved when the application is closed. In particular, the following code seems to cause the problem:&lt;br /&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt; &lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt;Dim serializer As New XmlSerializer(ConfigObj.GetType())&lt;br /&gt;Dim writer As New StreamWriter(datafile)&lt;br /&gt;serializer.Serialize(writer, ConfigObj)&lt;br /&gt;writer.Close()&lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;The error occurs as soon as &lt;i&gt;XmlSerializer.Serialize()&lt;/i&gt; is called. A file system monitor tool such as &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx"&gt;Process Monitor&lt;/a&gt; shows me that &lt;b&gt;csc.exe &lt;/b&gt;is creating temporary files in C:\Windows\Temp, which is perhaps interrupted by the shutdown process, causing the above problem. I am not even sure why csc.exe (the microsoft C# compiler) gets called even though I am using VB.NET!&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="left"&gt;Not sure how to fix the problem, I have to avoid calling &lt;i&gt;XmlSerializer &lt;/i&gt;when&lt;i&gt; &lt;/i&gt;Windows&lt;i&gt; &lt;/i&gt;is shutting down by using: &lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;...&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt;If e.CloseReason &amp;lt;&amp;gt; CloseReason.WindowsShutDown &lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim serializer As New  XmlSerializer(ConfigObj.GetType())&lt;br /&gt;&amp;nbsp;&amp;nbsp; Dim writer As New StreamWriter(datafile)&lt;br /&gt;&amp;nbsp;&amp;nbsp; serializer.Serialize(writer, ConfigObj)&lt;br /&gt;&amp;nbsp;&amp;nbsp; writer.Close()&lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;i&gt;End If&lt;/i&gt;&lt;br /&gt;&lt;i&gt;... &lt;/i&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;b&gt;&lt;i&gt;End Sub&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="left"&gt;This way, user data may be lost, but at least my application does not prevent the system from shutting down. I have to find another way to save user data more frequently...&lt;/div&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;b&gt;Reference:&lt;/b&gt;&lt;/div&gt;&lt;div align="left"&gt;&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/netfxremoting/thread/fddb5072-f84b-432a-945a-607e183e1da3"&gt;Problem with CSC.EXE&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-4801084422821950039?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/4801084422821950039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/04/cscexe-application-error-when-shutting.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4801084422821950039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/4801084422821950039'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/04/cscexe-application-error-when-shutting.html' title='&quot;csc.exe - Application Error&quot; when shutting Windows with a .running  NET application'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2975561700085069511</id><published>2010-03-30T07:50:00.000-07:00</published><updated>2011-05-05T22:09:07.649-07:00</updated><title type='text'>MobileOne not M1</title><content type='html'>This entry seems a bit "off", considering the technical nature of the blog. But nevertheless I decided to post it here. Enjoy :)&lt;br /&gt;&lt;br /&gt;&lt;small&gt;For those not familiar with the Singapore telecommunication industry, there are 3 telcos in Singapore, namely Singtel, Starhub and MobileOne. The last is also known as M1 by most people.&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;A friend of mine who is a fan of Google Products (GMail, Google  Docs, Google Talk, Google Calendar, etc) recently told me that he  changed his phone number. I asked him why, and he told me he needs to  change from M1 to Starhub. "Why do you need to? All telcos in Singapore  have good call quality, well, at least, for most of the time." I said.  He then told me he could not get Google Calendar SMS notifications to  work with his previous M1 SIM card. I said "Why not? It should be  straight forward, just enable it in your Google calendar settings and  enter your phone number." He replied "I have tried everything, and  concluded that Google does not support my provider, that's why I need to  change. And everything works fine now." &lt;br /&gt;&lt;br /&gt;I was surprised as I  used this feature with M1 SIM card before. So I checked &lt;a class="postlink" href="http://www.google.com/support/calendar/bin/answer.py?answer=37226#S" onclick="this.target='_blank';" rel="nofollow"&gt;http://www.google.com/support/calendar/bin/answer.py?answer=37226#S&lt;/a&gt;  and of course M1 is listed in the supported provider list. I gave him  the link, to which he said "Well I checked it before, it shows "&lt;span class="posthilit"&gt;MobileOne&lt;/span&gt;" but I am using M1."&lt;br /&gt;&lt;br /&gt;It turned  out that he only enabled Phone Notifications under his Google account  settings after he purchased the new Starhub SIM card, and simply  concluded that he was right, since it works with Starhub, and not M1.&lt;br /&gt;&lt;br /&gt;FYI,  he's planning to do an MBA in US, and needless to say, I am surprised  that somebody who wants to do an MBA would rather go through the trouble  of switching providers and changing phone numbers, instead of spending a  few minutes checking if M1 and &lt;span class="posthilit"&gt;MobileOne&lt;/span&gt;  are somehow related. I doubt he would ever be able to pass his MBA  course with that kind of mindset...&lt;br /&gt;&lt;br /&gt;&lt;b&gt;See also:&lt;/b&gt; &lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://minhdanh2002.blogspot.com/2011/04/another-customer-service-tale-your.html"&gt;Your system connects me to the wrong number, please refund!&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.techtales.com/1999_03_tftcontent.html"&gt;Some Technical Tales&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2975561700085069511?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2975561700085069511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/03/mobileone-not-m1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2975561700085069511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2975561700085069511'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/03/mobileone-not-m1.html' title='MobileOne not M1'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-7415068786573746936</id><published>2010-03-15T05:50:00.000-07:00</published><updated>2010-10-08T08:56:44.708-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blackberry'/><category scheme='http://www.blogger.com/atom/ns#' term='SMS Migration'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Transferring SMS messages from Windows Mobile to Blackberry devices</title><content type='html'>UPDATE (8 October 2010): For a more generic tool to restore SMS to a Blackberry device from a CSV backup, refer to &lt;a href="http://minhdanh2002.blogspot.com/2010/10/restoring-sms-backup-from-csv-to.html"&gt;this&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This may seem an easy task - one may immediately think of using the Device Switch Wizard in Blackberry Desktop Manager or do a quick search for some SMS backup/restore software which will do the job. However, while I was doing it, I came across some challenges which turns this into a difficult job:&lt;br /&gt;&lt;br /&gt;1. The Device Switch Wizard found in the Blackberry Desktop Manager simply does not migrate the SMS messages.&lt;br /&gt;&lt;br /&gt;2. There are plenty of applications that perform SMS backup/restore for Windows Mobile but there are none for Blackberry. &lt;br /&gt;&lt;br /&gt;The first challenge is expected as many users simply do not need to migrate text messages to their new phones and it is therefore understandable that the Device Switch Wizard ignores SMS during the migration process but the second challenge disappoints me. I was realistic - I never expected to find a tool that transfers text messages on-the-fly, perhaps with the tool running on Windows, the Blackberry connected via Blackberry Desktop Manager and the Windows Mobile device connected via ActiveSync. BUT I was hoping to find some software that can restore Blackberry SMS from a backup, perhaps XML-formatted, which can be created by a tool running on Windows Mobile.&lt;br /&gt;&lt;br /&gt;I was wrong - there are no such applications for Blackberry. This is explained by the fact that RIM does not provide an API for  Blackberry applications to programmatically access the SMS messages  store (there are, however, APIs to access email messages).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;My approach&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;My ideas come from the fact that Blackberry Desktop Manager allows user to backup device memory (including contacts, calendar and SMS) into an IPD file, and restore from the IPD backup. Although the IPD file format is not documented by RIM, it is easy to reverse engineer (for example, by using a hex-comparison tool) due to its unencrypted and tokenized nature. There are previous attempts to do this, for example &lt;a href="http://code.google.com/p/ipddump/"&gt;ipddump&lt;/a&gt; and &lt;a href="http://code.google.com/p/magicberry/"&gt;MagicBerry&lt;/a&gt;. The latter is extremely useful as it allows you to view, edit, merge and split IPD files.&lt;br /&gt;&lt;br /&gt;Keeping the above in mind, I came up with a tool that runs on Windows Mobile device and backs up all text messages into an IPD file. The file created can later be opened using Blackberry Desktop Manager and the text messages can be restored back onto the Blackberry device.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Final product&lt;/b&gt;: &lt;b&gt;SMS2IPD&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In the lack of a better name, let me call it SMS2IPD, short for SMS to IPD Converter. Here's how to use it:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TK8gDAaB92I/AAAAAAAAAEQ/yzNfGSCnvY8/s1600/sms2ipd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TK8gDAaB92I/AAAAAAAAAEQ/yzNfGSCnvY8/s320/sms2ipd.png" width="226" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;1. Run the tool on your Windows Mobile device. You will need .NET Compact Framework 3.5 and above.&lt;br /&gt;&lt;br /&gt;2. Select the correct time offset so that SMS timestamps will be correctly displayed. For example, if you are in GMT+8, select -8 for the time offset. The selection is needed as I am not sure which field to set to specify the timezone of the SMS messages.&lt;br /&gt;&lt;br /&gt;3. Click on Start, choose the location to save the IPD file. Give the application some time to run, when completed, it will produce the IPD file.&lt;br /&gt;&lt;br /&gt;4. Connect your Blackberry and start Desktop Manager, choose Backup/Restore, then click on Restore again. Select the IPD file created in step 1 and Desktop Manager will proceed to transfer all SMS to the device.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Note: &lt;/b&gt;this process may take a long time during which Desktop Manager may seem to hang. It will also overwrite all existing text messages on the Blackberry device, so back them up and merge them to the IPD first using MagicBerry. MagicBerry may also seem to hang when loading a large IPD file, so be patient.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Limitations and future improvements&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I myself reverse engineer the IPD file format by using a hex editor, a hex comparison tool and MagicBerry, with some references to ipddump and MagicBerry source code, so there will be cases not handled properly. These include SMS with special characters, unicode SMS, and SMS sent from a timezone different from your device timezone.&lt;br /&gt;&lt;br /&gt;Upon imported on the Blackberry device, all messages may appear as unread. You can mark all as read by scrolling to the top of the messages list (which displays the date), press the Blackberry key and choose Mark Prior Opened.&lt;br /&gt;&lt;br /&gt;Some Blackberry devices by default will delete text messages older than 30 days. This behaviour can be changed by opening Options in Messages, choose General Options, and select a longer period for "Keep Messages".&lt;br /&gt;&lt;br /&gt;I attached the source code for those interested to improve the application. You can modify and re-distribute the application and its source code as you like, but please mention that the source code was taken from my blog. You may not, however, use the source code and/or the application for any commercial purposes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Credits&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To read the SMS messages from a Windows Mobile device, I am using MAPIDotNet library found on &lt;a href="http://www.codeproject.com/KB/windows/PocketPCandSmartphone.aspx"&gt;codeproject&lt;/a&gt;, written by &lt;a href="http://www.codeproject.com/Members/rwt33" id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_memberProfileLink"&gt;rwt33&lt;/a&gt;. The version I used was downloaded some time back, so it may differ significantly from the current version found in the project article.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Downloads&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Source code:&lt;br /&gt;&lt;a href="http://www.mediafire.com/?ezj0eaa9kj5vqzk"&gt;http://www.mediafire.com/?ezj0eaa9kj5vqzk&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;SMS2IPD CAB Installer for Pocket PC and Smartphone, Windows Mobile 5 and above with .NET Compact 3.5 (updated 10 Oct 2010)&lt;br /&gt;&lt;a href="http://dl.dropbox.com/u/5881137/SMS2IPD_CAB.CAB"&gt;&lt;span id="goog_1004441454"&gt;http://dl.dropbox.com/u/5881137/SMS2IPD_CAB.CAB&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-7415068786573746936?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/7415068786573746936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/03/transferring-sms-messages-from-windows.html#comment-form' title='43 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7415068786573746936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7415068786573746936'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/03/transferring-sms-messages-from-windows.html' title='Transferring SMS messages from Windows Mobile to Blackberry devices'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_w4YbCKQ5wkQ/TK8gDAaB92I/AAAAAAAAAEQ/yzNfGSCnvY8/s72-c/sms2ipd.png' height='72' width='72'/><thr:total>43</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-7512079748956028996</id><published>2010-02-23T18:51:00.000-08:00</published><updated>2010-03-06T06:54:52.814-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft Virtual PC'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Tips'/><title type='text'>Windows Virtual PC vs. Microsoft Virtual PC 2007</title><content type='html'>In an attempt to run Windows XP applications on Windows 7 via Windows XP Mode, I recently tried out Windows Virtual PC. However, while Windows Virtual PC is the next version of Microsoft Virtual PC and has some remarkably new features, the software as a whole still disappoints me. Here's why.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Improvements in Windows Virtual PC&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. Seamless integration with Windows Explorer. User can now browse through the list of virtual machines using an Explorer-like interface, instead of the ugly-looking window that can only support a maximum of 3 virtual machines (without scrolling) in the old Microsoft Virtual PC.&lt;br /&gt;&lt;br /&gt;2. Support USB devices. USB devices plugged into the host machine can be detected by the guest operating system. This feature has long been present on other emulators (VMware, Sun Virtual Box, etc.) but is not present in Microsoft Virtual PC 2007.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What make it worse despite the improvements&lt;/b&gt;...&lt;br /&gt;&lt;br /&gt;1. Windows Virtual PC requires hardware virtualization and will not run without it, even though it does not always use this feature. In other words, many older computers that can run Windows 7 smoothly will not be able to run Windows Virtual PC. Since Microsoft Virtual PC refuses to install on Windows 7, owners of these computers will have no choice but to use other emulator software, unless they plan to downgrade to Windows XP.&lt;br /&gt;&lt;br /&gt;2. While I may not have used Windows Virtual PC extensively, the newly so-called Integration Features seems to be worse than its predecessor, Virtual Machine Additions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Limited file sharing capabilites: Integration features only support sharing of entire hard disk disk; user cannot share a specific folder as they could in Microsoft Virtual PC 2007.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Integration Features is implemented as a remote desktop session into the Virtual Machine. This will make it unusable in many other older guest OS'es such as Windows 98 and will also reduce the speed. &lt;br /&gt;&lt;br /&gt;This explains why the sharing settings look similiar to that of the Remote Desktop client that comes with every version of Windows - maybe Microsoft is just too lazy to re-write the code in a different way...&lt;br /&gt;&lt;br /&gt;The older Virtual Machine Additions does not need a Remote Desktop session to communicate with the virtual machine; it instead uses some special communication mechanism, see &lt;a href="http://www.codeproject.com/KB/system/VmDetect.aspx"&gt;this&lt;/a&gt; for more information.&lt;/li&gt;&lt;/ul&gt;3. No official support for OSes ealier than Windows XP.&lt;br /&gt;&lt;br /&gt;In particular, Integration Features will not work with ealier OSes such as Windows 98 or DOS. Linux is out of the questions, too. In Microsoft Virtual PC 2007, even though DOS is not supported, one could still enable file and folder sharing by using the virtual machine addition floppy image that comes with Microsoft Virtual PC 2004.&lt;br /&gt;&lt;br /&gt;4. Floppy Disk and parallel port emulations are removed.&lt;br /&gt;&lt;br /&gt;While I seldom use the parallel port emulation and I doubt anyone is still using it frequently, unless they need to print to a parallel port printer or interface some parallel port peripherals from a virtual machine, the floppy disk emulation should not have been removed as it is still needed for some older operating system such as DOS.&lt;br /&gt;&lt;br /&gt;5. Finally, it's overall slower than Microsoft Virtual PC and other emulators, when running on the same system configuration.&lt;br /&gt;&lt;br /&gt;For example, using the same VHD image that comes with Windows XP mode, Sun VirtualBox starts the virtual machine within 5 seconds, while Windows Virtual PC spends 15 seconds staying at the "Starting the virtual machine..." screen.&lt;br /&gt;&lt;br /&gt;Enough said... I have uninstalled Windows Virtual PC from my Windows 7 machine and use Sun VirtualBox or VMware for emulation purposes. If there is a need, I will just boot to Windows XP and use Microsoft Virtual PC 2007.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-7512079748956028996?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/7512079748956028996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/02/windows-virtual-pc-vs-microsoft-virtual.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7512079748956028996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/7512079748956028996'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/02/windows-virtual-pc-vs-microsoft-virtual.html' title='Windows Virtual PC vs. Microsoft Virtual PC 2007'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6637414899038625882</id><published>2010-02-04T07:19:00.000-08:00</published><updated>2010-04-30T21:48:09.665-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Tips'/><title type='text'>.NET forms on Windows 7 at 125% zoom level</title><content type='html'>If you have ever tried to personalize your Windows 7 desktop and chose to zoom to 125%, as per the following screenshot, you'll perhaps notice that some applications do not display so well:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img.technospot.net/windows-7-display.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://img.technospot.net/windows-7-display.png" /&gt;&lt;/a&gt;&lt;/div&gt;Believe it or not, the 125% or 150% zoom mode does not simply decrease the &lt;b&gt;dpi &lt;/b&gt;of the display and make it look bigger, unlike the advanced display settings in Windows XP:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/S5EdipIcvxI/AAAAAAAAAC0/aHHu89gcmPU/s1600-h/display.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/S5EdipIcvxI/AAAAAAAAAC0/aHHu89gcmPU/s640/display.JPG" width="579" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;In fact, when the 125% or 150% zoom mode is set, Windows 7 does (at least) the following two things:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Increase the default font size&lt;/li&gt;&lt;li&gt;Tell every window (including child window) to increase its size&lt;/li&gt;&lt;/ol&gt;It's up to the application to handle the change in font size and window size gracefully. If it does not, the application interface may look distorted, with text truncated or displayed outside its designated area and graphics being tiled up or stretched.&lt;br /&gt;&lt;br /&gt;Interestingly the 125% or 150% zoom mode cannot be used during a Remote Desktop session.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Effects on .NET forms&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Under 125% or 150% zoom, the size of a .NET form will increase proportionally. The following changes will have to be made for the form to display properly:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;All form controls should have their Anchor property set appropriately.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Most importantly, the AutoScaleMode property of every form should be set to &lt;b&gt;Dpi&lt;/b&gt; and not &lt;b&gt;Font&lt;/b&gt;. AutoScaleMode of user controls can be set to either &lt;b&gt;Dpi&lt;/b&gt; or &lt;b&gt;Inherit.&amp;nbsp;&lt;/b&gt;&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;If set inappropriately, only the form will resize while the controls do not resize, causing display distortion.&lt;br /&gt;&lt;br /&gt;Also, do not open the form designer from inside Visual Studio 2008 under 125% or 150% zoom mode. Otherwise, Visual Studio will "zoom" the form (perhaps in an attempt to obey the Windows settings faithfully) by increasing its Size property and forgets (or is unable) to restore the original size when the zoom mode is set to 100%. If this happens, you'll have to manually resize every form back to their original size.&lt;br /&gt;&lt;br /&gt;I am not sure if it's a Visual Studio bug, or it's just supposed to be that way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6637414899038625882?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6637414899038625882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/03/net-forms-on-windows-7-at-125-zoom.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6637414899038625882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6637414899038625882'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/03/net-forms-on-windows-7-at-125-zoom.html' title='.NET forms on Windows 7 at 125% zoom level'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_w4YbCKQ5wkQ/S5EdipIcvxI/AAAAAAAAAC0/aHHu89gcmPU/s72-c/display.JPG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6511691461909569059</id><published>2010-01-17T01:17:00.000-08:00</published><updated>2010-02-07T01:37:35.022-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET Compact Framework'/><title type='text'>ArgumentOutOfRangeException when calling DateTime.ToString()</title><content type='html'>Recently I encountered a strange problem with one of my .NET applications when running on phones having the language set to Chinese. If started by clicking the executable file, the program would just crash without warning at startup. If started via Visual Studio debugger, the debugging session will be terminated shortly with the error message "The remote connection to the device has been lost" and the program crashes with no further error messages.&lt;br /&gt;&lt;br /&gt;For the device to show a more detailed error message, I uninstalled the .NET Compact Framework version 2.0 that comes bundled with the device and let Visual Studio automatically install the framework before debugging in started. With this change, the exact error message pops up, showing an ArgumentOutOfRangeException when the program tries to call DateTime.ToString().&amp;nbsp; With some further investigation, I realized this seems to be an issue with the .NET Compact Framework when running on phones where the user has changed the default language in &lt;b&gt;Regional Settings&lt;/b&gt; to Chinese. In all my test devices, the problem seems to only happen on HTC phones with the language set to &lt;b&gt;Chinese (Singapore)&lt;/b&gt; and strangely does not occur when a different Chinese dialect (e.g. &lt;b&gt;Chinese (Taiwan)&lt;/b&gt;) is used.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;To use &lt;b&gt;Chinese (Singapore)&lt;/b&gt; as the phone's default localization, a workaround is to open &lt;b&gt;Region Settings&lt;/b&gt;, in the &lt;b&gt;Date &lt;/b&gt;tab, under &lt;b&gt;Calendar Type&lt;/b&gt;, select another type of calendar such as 西历, instead of &lt;b&gt;Gregorian Calendar&lt;/b&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/S26H83VSolI/AAAAAAAAACs/8O7c2CQk67k/s1600-h/Screen02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/_w4YbCKQ5wkQ/S26H83VSolI/AAAAAAAAACs/8O7c2CQk67k/s400/Screen02.jpg" width="300" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The problem may have to do with the fact that HTC phones allow user to switch between 西历 and &lt;b&gt;Gregorian Calendar&lt;/b&gt;. On other phones that do not have this problem the option &lt;b&gt;Calendar Type&lt;/b&gt; is grayed out, default to 西历, and thus cannot be changed if the localization is set to Chinese.&lt;br /&gt;&lt;br /&gt;Interestingly, when this problem happens, a Try/Catch around the related code section does not always prevent the crash. If it does, further execution of the program may have erratic behaviour such as throwing&amp;nbsp; mysterious ArgumentOutOfRangeException or returning wrong results when calculating date/time values.&lt;br /&gt;&lt;br /&gt;Upgrading to .NET Compact 3.5 does not fix the problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6511691461909569059?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6511691461909569059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/01/argumentoutofrangeexception-when.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6511691461909569059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6511691461909569059'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/01/argumentoutofrangeexception-when.html' title='ArgumentOutOfRangeException when calling DateTime.ToString()'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_w4YbCKQ5wkQ/S26H83VSolI/AAAAAAAAACs/8O7c2CQk67k/s72-c/Screen02.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-3036270598368265789</id><published>2010-01-08T22:03:00.000-08:00</published><updated>2010-05-24T02:24:10.287-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Just because you call it 'preprocessor directives', doesn't mean it is.</title><content type='html'>A few months ago, one of my friends, a soon-to-be team leader in a software company, had a chance to assist me in debugging the C++ source code of a Windows application. The application could be configured&amp;nbsp; (via a #define in a C++ header), to compile in either HOME_NETWORK or PUBLIC_IP mode. The first mode was used when we test it within our LAN, whereas the second one was needed to access the application remotely. Although what the application actually did is probably of little interest, it helps to know that my friend has a  3-year J2ME experience.&lt;br /&gt;&lt;br /&gt;During the debugging process we needed to change some of the hard-coded IP addresses inside the application when running under HOME_NETWORK mode. Too busy with something else, I asked him to help me make the changes. I would assume that this would be an easy task for him without the need for any C++ experience. "Just edit the code, change the IP address, and re-compile", I told him.&lt;br /&gt;&lt;br /&gt;Ten minutes later, he reported the job done. I tested it, and everything seemed to work fine, so I said "Thank you.". He then replied, "You're welcome. I have not touched C++ for a long time. You actually help me to revive my C++ knowledge. I also help you in commenting &lt;i&gt;out &lt;/i&gt;old codes."&lt;br /&gt;&lt;br /&gt;I did hear him fully, and actually questioned why he mentioned "commenting &lt;i&gt;out&lt;/i&gt;". But as I was still busy debugging, I soon forgot about it and moved on to something else.&lt;br /&gt;&lt;br /&gt;Three days later when I changed the compilation mode from HOME_NETWORK to PUBLIC_IP, the application suddenly stopped working. I started to check every single thing, including Windows firewall, antivirus prorgram, DNS, .... but could not find the reason why. Finally, suspecting that some typos must have been made while changing the IP addresses a few days back, I decide to check the source code. As soon as I re-compiled the source code, I noticed hundreds of warnings about unused variables and methods. Taking a further look, I could not believe that my source code had been changed to:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;#ifdef HOME_NETWORK&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; /* Perform preparation while running in our LAN */&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PerformHomeNetworkCheck();&lt;b&gt;&lt;br /&gt;#else&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #666666; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* Perform preparation while running in public IP mode */&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp; &amp;nbsp; /* &lt;/span&gt;&lt;/div&gt;&lt;div style="color: #666666; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PerformPublicIPCheck();&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #666666; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .....&lt;/span&gt;&lt;/div&gt;&lt;div style="color: #666666; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;b&gt;#endif&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In every single #ifdef block that checked if either HOME_NETWORK or PUBLIC_IP is defined, the section for PUBLIC_IP mode was commented &lt;i&gt;out&lt;/i&gt;! This reminded of my friend mentioning "commenting &lt;i&gt;out&lt;/i&gt;", so I called him to ask why. He told me "Well, those code sections were inactive but not commented out, so I thought your IDE must have forgotten to do that, and I helped you. My IDE, with &lt;a href="http://antenna.sourceforge.net/"&gt;Antenna&lt;/a&gt;, does a better job."&amp;nbsp; Not having a single word to say, I hung up. &lt;br /&gt;&lt;br /&gt;It turned out that he has always been using Antenna for pre-processing in J2ME, as Java does not have&lt;a href="http://www.developer.com/java/other/article.php/1567101/Case-for-Preprocessing-Capabilities-in-the-Java-Language.htm"&gt; native pre-processing ability&lt;/a&gt;. In order to hide the inactive pre-processor block from the compiler, Antenna comments it &lt;i&gt;out. &lt;/i&gt;My friend, a 3-year J2ME developer, was too familiar with this behaviour to assume the same thing for C++ preprocessor and commented out almost every single inactive pre-processor block in my C++ code, ignoring those where commenting out would cause compilation errors!&lt;br /&gt;&lt;br /&gt;This reminds me of a few years ago when I saw a group of children in a supermarket, pointing at the frozen chicken (labelled 'CHICKEN') asking their parents "Why aren't those chicken clucking?" Those children had never seen a chicken alive before and thought what they saw was a real chicken!&lt;br /&gt;&lt;br /&gt;But at least the children knew how to ask question. My friend did not even ask! I wanted to say "Well, thank you, maybe your boss should  re-consider your promotion to be a team-leader". But, I'm polite.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-3036270598368265789?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/3036270598368265789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/05/just-because-you-call-it-preprocess.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3036270598368265789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/3036270598368265789'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/05/just-because-you-call-it-preprocess.html' title='Just because you call it &apos;preprocessor directives&apos;, doesn&apos;t mean it is.'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-6815084053805051797</id><published>2009-12-26T13:18:00.000-08:00</published><updated>2010-02-07T01:36:52.992-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Built-in card reader on Acer Aspire 5550</title><content type='html'>In case you haven't known it, the built-in 5-in-1 card reader on the Acer Aspire 5550 can only support SD but not SDHC (high-capacity) cards. Although this wikipedia &lt;a href="http://en.wikipedia.org/wiki/Secure_Digital"&gt;article&lt;/a&gt; shows that normal SD card can be as large as 4GB, most of my 4GB SD cards are high-capacity, which can't be read by the built-in card reader. The same applies for the free USB SD card reader that comes with unit - both can only support SD cards up to 2GB. For the built-in card reader, nothing will happen when you insert an unsupported card. For the USB card reader, attempting to use an unsupported card will result in a continuously flashing red light. On the other hand, when the USB reader does not detect any card, the indicator will flash for 3 seconds, pause for 1 second and flash again.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-6815084053805051797?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/6815084053805051797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2010/01/built-in-card-reader-on-acer-aspire.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6815084053805051797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/6815084053805051797'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2010/01/built-in-card-reader-on-acer-aspire.html' title='Built-in card reader on Acer Aspire 5550'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-1870673086800507000</id><published>2009-12-16T16:19:00.000-08:00</published><updated>2010-05-13T18:19:41.966-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows Mobile'/><title type='text'>Using USSD on Windows Mobile to set call forwarding</title><content type='html'>In one of my recent projects, I need to set the call forwarding programmatically. My first attempt was to use the &lt;a href="http://msdn.microsoft.com/en-us/library/aa922990.aspx"&gt;RIL_AddCallForwarding&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/aa919145.aspx"&gt;RIL_GetCallForwardingSettings &lt;/a&gt;APIs provided by RIL. However, on all phones I tested, these API mysteriously failed with either E_FAIL, E_NOTIMPLEMENTED or E_INVALIDARG. After a few attempts, I gave up and concluded that these APIs are supported only on Windows CE, but not Windows Mobile (or at least MSDN says so).&lt;br /&gt;&lt;br /&gt;My next attempt&amp;nbsp; is to send USSD via &lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=2&amp;amp;ved=0CAsQFjAB&amp;amp;url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Faa923063.aspx&amp;amp;ei=VZxSS-ekJcuIkAWA49C0Cg&amp;amp;usg=AFQjCNFmgSJ0zSnwigGJJgjadC6lSBv9mw&amp;amp;sig2=RbrTqGkCw_r1kXOFXYwSgQ"&gt;lineSendUSSD&lt;/a&gt;() method. For example, to divert all incoming calls to another number, use &lt;b&gt;**21*«dest number»#&lt;/b&gt;. Since the USSD codes to set call forwarding status are fixed, this methos should work for all phones (see this for the &lt;a href="http://www.truteq.com/tips/ussd/"&gt;exact &lt;/a&gt;USSD codes). However, after some testing, this method is not as reliable as it sounds. It works perfectly on some phones. On some others&amp;nbsp; the call to lineSendUSSD() returns E_FAIL when I passed in the code to set call forwarding but the same API works fine for 'normal' USSD code (e.g. *100# to check account info). On other phones, I received a response from the mobile operator saying that the service code is invalid - it seems as if the phone literally sends the USSD string to the mobile operator, instead of processing it and gives me the call forwarding status.&lt;br /&gt;&lt;br /&gt;On a side note, using the .NET method Phone.Talk() on &lt;u&gt;&lt;b&gt;any&lt;/b&gt;&lt;/u&gt; USSD string will simply display an error message, saying that the signal is unavailable. Also, lineSendUSSD() are not supported on all phones. On phones where it is supported, not all USSD codes are accepted and the response cannot always be retrieved easily. It will most likely fail if the mobile operator returns a menu response for your USSD code (e.g. Reply with '1' for account balance, '2' for expiry date), in which case I haven't figured out how to reply programmatically, or even to retrieve the response text. It looks as if it has to do with the registry branch &lt;b&gt;HKEY_LOCAL_MACHINE\Services\USSD\&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;At the moment, I have no ideas why Microsoft makes it so difficult for developers just to send a USSD code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-1870673086800507000?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/1870673086800507000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2009/12/using-ussd-on-windows-mobile-to-set.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/1870673086800507000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/1870673086800507000'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2009/12/using-ussd-on-windows-mobile-to-set.html' title='Using USSD on Windows Mobile to set call forwarding'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-2480389889608838161</id><published>2009-11-27T23:51:00.000-08:00</published><updated>2009-11-27T23:58:27.513-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General Programming'/><title type='text'>Useful country information database</title><content type='html'>If you need a database of useful information on different countries in the world, e.g. country name, population, capital city, area, country code, timezone, etc, you can download from &lt;a href="http://download.geonames.org/export/dump/"&gt;http://download.geonames.org/export/dump&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Each country's information is provided as a text file compressed into ZIP format. The text file is tab-separated and can be easily converted into some spreadsheet or database format such as Excel, Access or SQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8632654884908323411-2480389889608838161?l=minhdanh2002.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://minhdanh2002.blogspot.com/feeds/2480389889608838161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://minhdanh2002.blogspot.com/2009/11/useful-country-information-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2480389889608838161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8632654884908323411/posts/default/2480389889608838161'/><link rel='alternate' type='text/html' href='http://minhdanh2002.blogspot.com/2009/11/useful-country-information-database.html' title='Useful country information database'/><author><name>MD</name><uri>http://www.blogger.com/profile/05235484501475351120</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8632654884908323411.post-3029272522376066143</id><published>2009-11-07T23:11:00.000-08:00</published><updated>2010-04-09T18:49:16.588-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General Programming'/><title type='text'>Reverse-engineering gothere.sg API</title><content type='html'>If you haven't known it, &lt;a href="http://www.gothere.sg/"&gt;gothere.sg&lt;/a&gt; is a free service allowing you to find your way around Singapore. For developers, it has free &lt;a href="http://www.gothere.sg/api"&gt;API &lt;/a&gt;provide accessing to Gothere's web services, such as viewing maps, address/nearby amenities search as well as public transport and driving directions.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Background&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Just like Google Maps &lt;a href="http://code.google.com/apis/maps/"&gt;API&lt;/a&gt;, gothere.sg's API is purely JavaScript, which means it can only be used in a web browser. To use it in an application, you would (officially) have to embed an ActiveX WebBrowser control and call the JavaScript API from there. That said, this post will show you the primitive way to achieve the same functionality as gothere.sg API from any application without having to use call its JavaScript API from a web browser.&lt;br /&gt;&lt;br /&gt;It is important to know that all gothere.sg (as well as Google Maps API) JavaScript function calls will eventually translate into HTTP POST request sent to the server. The response will be parsed using JavaScript and useful information will be returned by the API. Unfortunately, all JavaScript files have been obfuscated and it is not easy to figure out how the web browser communicates with the server just by looking at the JavaScript code.&lt;br /&gt;&lt;br /&gt;At first I tried to use a packet sniffer such as Ethereal to reverse engineer the API. However, the network traffic was soon flooded by the downloading of images and JavaScript source code files (to be executed on the client). Most importantly, the HTTP traffic created by gothere API is gzip encoded and I could not find an efficient tool to decode it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The solution: FireFox Live HTTP Headers add-on.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I ended up using a FireFox add-on,&lt;span style="font-weight: bold;"&gt; &lt;a href="http://livehttpheaders.mozdev.org/"&gt;Live HTTP Headers, &lt;/a&gt;&lt;/span&gt;which allows me to view all HTTP conversations sent from my browser. So as not to be overwhelmed by unnecessary HTTP traffic, I decided to use the gothere.sg &lt;a href="http://www.gothere.sg/api/maps/examples.html"&gt;example pages&lt;/a&gt;, and not the main website, for further analysis.&lt;br /&gt;&lt;br /&gt;The following shows you how to reverse engineer the gothere simple search API and retrieve the HTTP POST URL to which the search request was sent. Once you've gotten the URL, you can post your search request to the URL directly without having to call the JavaScript API.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;gothere.sg Simple Search&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Open &lt;a href="http://www.gothere.sg/api/maps/examples/geocoding-simple.html"&gt;http://www.gothere.sg/api/maps/examples/geocoding-simple.html&lt;/a&gt; on your web browser and turn on the Live HTTP Header monitor window. Close all other web pages so that the monitor window won't be flooded too soon.&lt;br /&gt;&lt;br /&gt;Enter an address and click on 'Find'. The monitor window will start to display a few HTTP reques
