<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rhythm and Gravy &#187; Code</title>
	<atom:link href="http://jakesprouse.net/category/code/feed" rel="self" type="application/rss+xml" />
	<link>http://jakesprouse.net</link>
	<description>Goings-on in the life of Jake</description>
	<lastBuildDate>Wed, 31 Mar 2010 18:45:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>I Can&#8217;t Use iPhone Ringtones In My App?</title>
		<link>http://jakesprouse.net/2009/01/12/i-cant-use-iphone-ringtones-in-my-app</link>
		<comments>http://jakesprouse.net/2009/01/12/i-cant-use-iphone-ringtones-in-my-app#comments</comments>
		<pubDate>Mon, 12 Jan 2009 06:50:53 +0000</pubDate>
		<dc:creator>Jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/?p=228</guid>
		<description><![CDATA[Dear Lazyweb,
When running in the foreground, my iPhone app occasionally uses an alert to get the user&#8217;s attention.  If the Ring/Silent switch is set to silent mode, the phone will vibrate (kSystemSoundID_Vibrate); otherwise a sound is played.
It appears as though the iPhone SDK limits me to playing audio supplied by my application only:

I was [...]]]></description>
			<content:encoded><![CDATA[<p>Dear Lazyweb,</p>
<p>When running in the foreground, my iPhone app occasionally uses an alert to get the user&#8217;s attention.  If the Ring/Silent switch is set to silent mode, the phone will vibrate (<tt>kSystemSoundID_Vibrate</tt>); otherwise a sound is played.</p>
<p>It appears as though the iPhone SDK limits me to playing audio supplied by my application only:</p>
<div style="text-align:center;"><img src="http://jakesprouse.net/wordpress/wp-content/uploads/2009/01/picture-31.png" alt="Picture 3.png" border="0" width="373" height="116" style="margin-top: 10px; margin-bottom: 10px;"/></div>
<p><img src="http://jakesprouse.net/wordpress/wp-content/uploads/2009/01/img-0001.png" alt="IMG_0001.PNG" border="0" width="160" height="240" align="left" style="margin-right: 10px" />I was unable to find any explanation for this limitation of the AudioToolbox Framework on the google.  Does anyone out there know what the justification might be?  Note that Apple&#8217;s applications seem to be able to use system sounds (presumably using the same <tt>AudioServicesPlaySystemSound</tt> or <tt>AudioServicesPlayAlertSound</tt> API calls exposed to us), as shown in this screenshot of the Alarm Clock application.</p>
<p><b>Update:</b></p>
<p>It looks like I&#8217;m able to use an <tt>NSDirectoryEnumerator</tt> to get the contents of <tt>/Library/Ringtones/</tt> on the phone, but if I try to load one of these files using <tt>AudioServicesCreateSystemSoundID()</tt> it fails with OSErr -1500 (Operation could not be completed).  Sandboxing&#8230;  Thanks to Steve Makofsky for his help.</p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2009/01/12/i-cant-use-iphone-ringtones-in-my-app/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Taking an App From the iPhone Simulator to a Physical Device</title>
		<link>http://jakesprouse.net/2008/12/23/taking-an-app-from-the-iphone-simulator-to-a-physical-device</link>
		<comments>http://jakesprouse.net/2008/12/23/taking-an-app-from-the-iphone-simulator-to-a-physical-device#comments</comments>
		<pubDate>Tue, 23 Dec 2008 23:43:43 +0000</pubDate>
		<dc:creator>jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/code/?p=20</guid>
		<description><![CDATA[Note to myself on going from the simulator to getting an application running on my iPhone:
1. Select &#8220;Get Info&#8221; for the target (not the project) and go to the Build tab.  Change the Code Signing Identity for Any iPhone OS Device to the provisioning profile you downloaded and installed from the Apple iPhone Developer [...]]]></description>
			<content:encoded><![CDATA[<p>Note to myself on going from the simulator to getting an application running on my iPhone:</p>
<p>1. Select &#8220;Get Info&#8221; for the target (not the project) and go to the Build tab.  Change the Code Signing Identity for Any iPhone OS Device to the provisioning profile you downloaded and installed from the Apple iPhone Developer Portal.</p>
<p>2. Edit the `Info.plist` for your project.  Change the Bundle Identifier to the App Identifier you registered with the Portal, minus the prefix.  For example, my App Identifier is `123456789A.net.jakesprouse.*`; I changed the Bundle Identifier to `net.jakesprouse.${PRODUCT_NAME:identifier}`.</p>
<p>3. Under the Project menu, set the active SDK to the Device entry with the desired OS.</p>
<p>4. Build and Go.</p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2008/12/23/taking-an-app-from-the-iphone-simulator-to-a-physical-device/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Codesigning Woes&#8230;</title>
		<link>http://jakesprouse.net/2008/12/22/codesigning-woes</link>
		<comments>http://jakesprouse.net/2008/12/22/codesigning-woes#comments</comments>
		<pubDate>Mon, 22 Dec 2008 22:44:58 +0000</pubDate>
		<dc:creator>jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/code/?p=16</guid>
		<description><![CDATA[Dear Lazyweb,
I finally got registered for the iPhone app developer program.  I created a certificate for &#8220;iPhone Developer: Jake Sprouse&#8221;, uploaded it to Apple, approved it, and downloaded it into my Keychain.  I registered the Device ID of my iPhone on the Apple website.  I created an App ID for all jakesprouse.net [...]]]></description>
			<content:encoded><![CDATA[<p>Dear Lazyweb,</p>
<p>I finally got registered for the iPhone app developer program.  I created a certificate for &#8220;iPhone Developer: Jake Sprouse&#8221;, uploaded it to Apple, approved it, and downloaded it into my Keychain.  I registered the Device ID of my iPhone on the Apple website.  I created an App ID for all jakesprouse.net applications (it&#8217;s of the form NNNNNNNNNN.net.jakesprouse.*).  And I created a provisioning profile with the certificate, Device ID, and App ID.</p>
<p>In my XCode project, I changed the &#8220;Code Signing Identity&#8221; field to &#8220;iPhone Developer: Jake Sprouse&#8221; under my provisioning profile in the drop-down.  And I changed the &#8220;Bundle identifier&#8221; field of my Info.plist to NNNNNNNNNN.net.jakesprouse.${PRODUCT_NAME:identifier}.</p>
<p>Now, when I build it, I get the error message: <tt>/Users/jakes/src/MyApp/build/Debug-iphoneos/MyApp.app: object file format invalid or unsuitable</tt>.</p>
<p>If I build a second time, it works, but when it goes to install the app, the Organizer window tells me &#8220;<tt>The Info.plist for application at /Users/jakes/src/Sac4iPhone/build/Debug-iphoneos/Sac4iPhone.app specifies a CFBundleExecutable of (null), which does not exist</tt>&#8220;.</p>
<p>If I build a third time, I get the object file format error again (and so on&#8230;).</p>
<p>Searching Google on <tt>codesign</tt> + <tt>"object file format"</tt> is not being very helpful.  Anyone out there have any ideas?</p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2008/12/22/codesigning-woes/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Integer promotion in C</title>
		<link>http://jakesprouse.net/2008/04/22/integer-promotion-in-c-3</link>
		<comments>http://jakesprouse.net/2008/04/22/integer-promotion-in-c-3#comments</comments>
		<pubDate>Wed, 23 Apr 2008 01:51:11 +0000</pubDate>
		<dc:creator>jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/code/2008/04/22/integer-promotion-in-c-3/</guid>
		<description><![CDATA[[c]
unsigned char t0, t1;
unsigned int diff;
t0 = 0;
t1 = 255;
diff = (unsigned int)(t0 &#8211; t1);
printf(&#8220;difference: %xn&#8221;, diff);
[/c]
Intuitively, I would think that the result of the subtraction would be an unsigned char with value 0x01, which then would get converted to an unsigned int with value 0&#215;00000001 (assuming a 32-bit platform).
Instead, when the program is compiled [...]]]></description>
			<content:encoded><![CDATA[<p>[c]<br />
unsigned char t0, t1;<br />
unsigned int diff;</p>
<p>t0 = 0;<br />
t1 = 255;</p>
<p>diff = (unsigned int)(t0 &#8211; t1);<br />
printf(&#8220;difference: %xn&#8221;, diff);<br />
[/c]</p>
<p>Intuitively, I would think that the result of the subtraction would be an <tt>unsigned char</tt> with value <tt>0x01</tt>, which then would get converted to an <tt>unsigned int</tt> with value 0&#215;00000001 (assuming a 32-bit platform).</p>
<p>Instead, when the program is compiled and run, the output is:</p>
<p><tt>difference: 0xffffff01</tt></p>
<p>Turns out that my compiler is actually doing the right thing here, but C is playing tricks on me.</p>
<p>The C standard has a concept of integer <em>rank</em>.  <tt>long long</tt> has greater rank than <tt>long</tt> which has greater rank than <tt>int</tt>, which has greater rank than <tt>short</tt>, which has greater rank than <tt>char</tt>.  Unsigned types have the same rank as their signed counterparts.  Note that even if two integral types have the same <em>size</em> in bits, their rank is different.</p>
<p>For arithmetic operations, the standard specifies that operands of integral data type are promoted to integer rank when their rank is less.  Historically, there were two ways of doing so, called <em>unsigned preserving</em> and <em>value preserving</em>.  The former simply converts all unsigned <tt>char</tt>s and <tt>short</tt>s into unsigned <tt>int</tt>s.  The latter converts them to signed <tt>int</tt>s if they are smaller and unsigned <tt>int</tt>s otherwise (i.e. if <tt>short</tt> and <tt>int</tt> are the same size, unsigned <tt>short</tt>s will be converted to unsigned <tt>int</tt>s).</p>
<p>In 1974, Kernighan and Richie&#8217;s <em>The C Programming Language</em> set the original C standard, and specified the unsigned preserving method.  But in 1989 the first ANSI C standard switched (after much debate) to the value preserving method, because it reduces the number of situations in which the result of an expression is <em>questionably signed</em>, meaning it could intuitively be interpreted either way.  More detail on this distinction can be found in <a href="http://www.lysator.liu.se/c/rat/c2.html#3-2">Section 3.2.1.1 of <em>Rational for the ANSI C Programming Language</em></a>.</p>
<p>So, in the example above, <tt>t0</tt> and <tt>t1</tt> are promoted to signed <tt>int</tt>s before being subtracted.  On my machine, <tt>int</tt>s are 32 bits, so the resulting difference is a signed <tt>int</tt> of value <tt>0xffffff01</tt> (-255).</p>
<p>This is then converted to <tt>unsigned int</tt>; the C standard specifies this conversion in an interesting way: &#8220;&#8230;the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.&#8221;  In a twos-complement system, this is equivalent to leaving the bits unchanged.  In our case, this means that the new value is -255 + 4294967296 = 4294967041 = <tt>0xffffff01</tt>.</p>
<p>The correct way to cause the desired wrap of in our example is to insert an explicit cast of the subtracted result back to <tt>unsigned char</tt>:</p>
<p><tt>diff = (unsigned int)(unsigned char)(t0 - t1);</tt></p>
<p>This produces the intended result:</p>
<p><tt>difference: 0x00000001</tt></p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2008/04/22/integer-promotion-in-c-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Search the Seattle Public Library catalog using Firefox</title>
		<link>http://jakesprouse.net/2007/08/05/search-the-seattle-public-library-catalog-using-firefox</link>
		<comments>http://jakesprouse.net/2007/08/05/search-the-seattle-public-library-catalog-using-firefox#comments</comments>
		<pubDate>Mon, 06 Aug 2007 00:22:18 +0000</pubDate>
		<dc:creator>Jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/2007/08/05/search-the-seattle-public-library-catalog-using-firefox/</guid>
		<description><![CDATA[This search engine for Firefox (and its ilk) browsers will search the Seattle Public Library&#8217;s catalog.
Click here to install the plug-in.

Happy searching!
]]></description>
			<content:encoded><![CDATA[<p>This search engine for Firefox (and its ilk) browsers will search the Seattle Public Library&#8217;s catalog.</p>
<p><a onclick="window.external.AddSearchProvider('http://jakesprouse.net/wordpress/wp-content/uploads/2007/08/spl_search.xml');" href="#">Click here to install the plug-in.</a></p>
<p><img  title="picture-3" src="http://jakesprouse.net/wordpress/wp-content/uploads/2007/08/picture-3.png" alt="picture-3" width="339" height="270" /></p>
<p style="text-align: left;">Happy searching!</p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2007/08/05/search-the-seattle-public-library-catalog-using-firefox/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>x86 Addressing and the Segment Descriptor Tables</title>
		<link>http://jakesprouse.net/2007/05/11/x86-addressing-and-the-segment-descriptor-tables</link>
		<comments>http://jakesprouse.net/2007/05/11/x86-addressing-and-the-segment-descriptor-tables#comments</comments>
		<pubDate>Fri, 11 May 2007 23:37:06 +0000</pubDate>
		<dc:creator>jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/code/2007/05/11/x86-addressing-and-the-segment-descriptor-tables/</guid>
		<description><![CDATA[It&#8217;s easy to think of a C pointer as containing a physical memory location; if my program calls int x = 42; int *p = &#038;x; printf("p = 0x%pn", p); and the output is p = 0xdeadbeef, I could imagine that dereferencing p would actually set the address bus to 11011110101011011011111011101111 = 0xdeadbeef to read [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s easy to think of a C pointer as containing a physical memory location; if my program calls <code>int x = 42; int *p = &#038;x; printf("p = 0x%pn", p);</code> and the output is <tt>p = 0xdeadbeef</tt>, I could imagine that dereferencing <code>p</code> would actually set the address bus to <tt>11011110101011011011111011101111 = 0xdeadbeef</tt> to read its value.  The real story of the x86 is a bit more complicated&#8230;</p>
<p>The <a href="http://en.wikipedia.org/wiki/Intel_8086">Intel 8086</a> has a 20-bit address bus, capable of addressing one megabyte (2^20 bytes) of memory, but only a 16-bit data bus &#8212; all registers are 16 bits wide.  To access the entire address space, then, an offset stored in one of the general purpose registers is added to the base address of a memory segment.  The segment number is stored in one of the segment registers (CS, where program code resides; SS, for the stack, DS, for global data, and ES, often used for extra program data like strings), and the final address is computed as segment*16 + offset.</p>
<p>The <a href="http://en.wikipedia.org/wiki/Intel_80286">80286</a> introduces a 16-bit <em><a href="http://my.execpc.com/~geezer/os/pm.htm">protected mode</a></em>, in which the segment registers no longer index physical locations in memory, but rather contain a 13-bit index into a table of 8-byte <em>segment descriptors</em>.  24 bits of these 8 bytes contain a base address, and physical addresses are computed by adding the offset directly to it, allowing 2^24 bytes = 16MiB to be addressed.  The descriptors also contain segment limits, allowing the kernel to detect when a piece of code addresses memory it&#8217;s not supposed to.</p>
<p>There are three table types: the <em>global descriptor table</em>, the <em>interrupt descriptor table</em>, and <em>local descriptor tables</em>.  There is a single global table which is available to all processes, but each process can have its own local table.  The tables can be located anywhere in memory, and there are special instructions (<code>lgdt</code>, <code>lidt</code>, and <code>lldt</code>) for setting them up.  These instructions tell the CPU about both the location and size of the tables; since the table index from the segment register is 13 bits, the maximum table length is 8192 entries.</p>
<p>In addition to the 13-bit table index, the segment register also contains a bit which selects between the global table or the current local table (the remaining two bits specify a privilege level, which I won&#8217;t discuss here).  The x86 architecture distinguishes between the <em>logical address</em> stored in the segment and offset registers visible to the programmer and the <em>linear address</em>, which the CPU forms using the segmentation table lookup.  Since we have 13 + 1 bits in the segment register used for addressing and 16 bits in the offset register, logical addresses in the 286 are 30 bits long.  The documentation for the 286 will refer to 1 GiB of <em>virtual address space</em>, which refers to logical addressing.  Of course, the address bus on the 286 is only 24 bits, and the mapping of logical addresses to linear addresses is not <a href="http://en.wikipedia.org/wiki/Bijection">bijective</a>, since the segments described in a descriptor table can overlap.  In practice, the CPU raises an exception when a segment register contains a table index which is out of bounds, and the kernel can trap this exception to retrieve the data from its virtual memory implementation.</p>
<p>When protected mode was introduced with the 80286, the old 8086-style of addressing was referred to as <em>real mode</em>.  To remain compatible with older code, the 80286 defaults to real mode and must be explicitly told to go into protected mode, from which it could not return without resetting the chip.</p>
<p>The <a href="http://en.wikipedia.org/wiki/Intel_80386">intel 80386</a> was introduced in 1985 and extended the data bus to 32 bits.  The segment registers were still 16 bits, but the segment descriptors they indexed were extended to allow 32-bit base addresses and handle 32-bit offset limits.  This scheme is known as <em>32-bit protected mode</em>.</p>
<p>Since the 386 allows each segment to address 2^32 = 4 Gib of linear address space, it is possible to set up one segment each for code and data, and not worry about segmentation; in fact, this is how the Linux kernel operates.  The nice protection features allowed by segment limits can be implemented using the hardware&#8217;s paging mechanisms, which are not so x86-specific.  I&#8217;ll write about paging in a future article.</p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2007/05/11/x86-addressing-and-the-segment-descriptor-tables/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How Computers Work, Part 1 &#8211; The Keyboard Interrupt Path</title>
		<link>http://jakesprouse.net/2007/05/09/how-computers-work-part-1-the-keyboard-interrupt-path</link>
		<comments>http://jakesprouse.net/2007/05/09/how-computers-work-part-1-the-keyboard-interrupt-path#comments</comments>
		<pubDate>Wed, 09 May 2007 19:40:40 +0000</pubDate>
		<dc:creator>jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/code/2007/05/09/how-computers-work-part-1-the-keyboard-interrupt-path/</guid>
		<description><![CDATA[I was talking with a friend the other day about questions we&#8217;ve used in interviews for programmers.  One of my pet peeves is the obscenely specific questions which boil down to &#8220;how would you solve this particular problem we have right now?&#8221;  If I were asked that kind of question in an interview, [...]]]></description>
			<content:encoded><![CDATA[<p>I was talking with a friend the other day about questions we&#8217;ve used in interviews for programmers.  One of my pet peeves is the obscenely specific questions which boil down to &#8220;how would you solve this particular problem we have right now?&#8221;  If I were asked that kind of question in an interview, I would have to wonder if the company was at all interested in the long-term effectiveness of their employees, and whether they care to let them learn and grow into more productive programmers.  Interviews need to establish a basic level of competence, but most importantly they need to determine whether the candidate knows what he doesn&#8217;t know and can learn on the job.</p>
<p>On the other hand, I always tried to avoid asking questions that had nothing to do with programming, such as <a href="http://blogs.msdn.com/bgroth/archive/2004/09/27/235071.aspx">why are manhole covers round?</a>.  My friend told me of a great one he uses: &#8220;if I type &#8216;<code>ping www.kqk4663.com</code>&#8216; into a terminal at a UNIX box and hit return, what happens?&#8221;  It&#8217;s been a while since I thought about the low-level hardware and software that makes <code>ping</code> possible, so as an exercise I wrote up the chain of events that occur on an 80&#215;86 box running Linux:</p>
<p><img src="http://jakesprouse.net/wordpress/wp-content/uploads/2007/05/wordpress/images/8059.png" border="0" height="51" width="60" alt="8059.png" align="right" />A typical <a href="http://www.computer-engineering.org/ps2protocol/">PS/2</a> keyboard has an onboard chip which detects keypresses and handles things like &#8220;debouncing&#8221; the switches.  Different keyboards have different key mechanisms, so there is a variety of encoder chips (the <a href="http://en.wikipedia.org/wiki/Intel_8048">Intel 8048</a> was popular early on), but the end result is a serial data signal sent through the keyboard cord to a controller chip on the motherboard.  This data consists of (possibly multibyte) sequences called &#8220;<a href="http://www.computer-engineering.org/ps2keyboard/scancodes2.html">scan codes</a>.&#8221;  For each key there are two unique scan codes: a &#8220;make code&#8221; which is sent when the key is pressed, and a &#8220;break code&#8221; which is sent when it is released.</p>
<p>The controller chip is an Intel 8042-compatible device which handles decoding the serial stream from the keyboard, and telling the CPU about keypresses.  It may also be integrated into the motherboard&#8217;s chipset.  The CPU talks to it via I/O space addressing at locations 0&#215;60 (data buffer) and 0&#215;64 (status/commands).</p>
<p>A typical PC contains two <a href="http://en.wikipedia.org/wiki/8259A">8259 Programmable Interrupt Controller</a> chips (which may be part of a <a href="http://en.wikipedia.org/wiki/Southbridge_%28computing%29">chipset</a>), or one of it&#8217;s <a href="http://en.wikipedia.org/wiki/Intel_APIC_Architecture">more advanced</a> descendants.<br />
<img src="http://jakesprouse.net/wordpress/wp-content/uploads/2007/05/wordpress/images/8259.png" border="0" height="340" width="300" alt="8259.png" align="left" /><br />
The first one which controls the <tt>INT</tt> line of the CPU.  It has eight interrupt inputs, <tt>IRQ0</tt> &#8211; <tt>IRQ7</tt>, each of which can be hooked up to a peripheral device, one of which is the second &#8220;cascaded&#8221; 8259 on <tt>IRQ2</tt>.  This allows for fifteen devices to interrupt the PC.  The keyboard controller&#8217;s interrupt line is connected to IRQ1.</p>
<p>When the <tt>INT</tt> line is raised, the processor immediately pushes the flags register and a return address onto the stack.  It then fetches the interrupt vector (which IRQ line generated the interrupt) by lowering the INTA line to retrieve it from the 8259.</p>
<p>Given the IRQ vector, it CPU must look up the address of the code which will handle the interrupt (a.k.a. the <em>interrupt service routine</em>, or ISR).  On the original 8086, the CPU expects to find a table of 32-bit ISR pointers at address 0&#215;0.  But the 80286 and later processors have a register called <code>idtr</code>, which points to the system&#8217;s <em>interrupt descriptor table</em> in memory.  Either way, the CPU uses the IRQ number as an index into these tables, retrieves a pointer to the ISR, pushes the flags register onto the stack, and jumps to that address. The ISR will return using the <code>IRET</code> instruction rather than <code>RET</code> to tell the processor to pop the flags register.</p>
<p>Now, assuming that it set up the interrupt vector table properly at bootup, the kernel software is handling the interrupt.  Next post, I&#8217;m going to dig into the Linux kernel and find out how it deals.</p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2007/05/09/how-computers-work-part-1-the-keyboard-interrupt-path/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging Apple&#8217;s LoginItemsAE.c on Intel Macs</title>
		<link>http://jakesprouse.net/2007/03/28/debugging-apples-loginitemsaec-on-intel-macs</link>
		<comments>http://jakesprouse.net/2007/03/28/debugging-apples-loginitemsaec-on-intel-macs#comments</comments>
		<pubDate>Thu, 29 Mar 2007 01:43:31 +0000</pubDate>
		<dc:creator>jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/code/?p=5</guid>
		<description><![CDATA[Came across some wackiness involving the Apple Event Manager and LoginItemsAE.c (Apple&#8217;s example code for manipulating a user&#8217;s list of login items).  In hopes that others dealing with similar problems will find this:
The &#8220;System Events&#8221; process can be accessed via an Apple Event (i.e. Applescript) dictionary which allow you to list, add, and delete [...]]]></description>
			<content:encoded><![CDATA[<p>Came across some wackiness involving the Apple Event Manager and <tt>LoginItemsAE.c</tt> (Apple&#8217;s <a href="http://developer.apple.com/samplecode/LoginItemsAE/index.html">example code</a> for manipulating a user&#8217;s list of login items).  In hopes that others dealing with similar problems will find this:</p>
<p>The &#8220;System Events&#8221; process can be accessed via an Apple Event (<em>i.e.</em> Applescript) dictionary which allow you to list, add, and delete login items.  Login items are described by two parameters, a path to the application to be launched when the user logs in, and a flag which specifies whether it should be hidden once launched.</p>
<p>In <tt>LoginItemsAE.c</tt>, retrieved login item paths are encoded as <tt>typeUnicodeText</tt> (native-endian UTF-16) and are converted to CFURLs for the user&#8217;s consumption, in three steps:</p>
<ol>
<li>Get a UTF8-converted string in a char buffer using <tt>AEGetKeyPtr</tt> (<tt>#defined</tt> to <tt>AEGetParam</tt>) to &#8220;coerce&#8221; the parameter to typeUTF8Text.</li>
<li>Make an <tt>FSPathRef</tt> from the character buffer using <tt>FSPathMakeRef</tt>.</li>
<li>Use <tt>CFURLCreateFromFileSystemRepresentation</tt> to get a <tt>CFURLRef</tt></li>
</ol>
<p>On my Powerbook (PPC), this worked fine, but when I sent my beta to testers, MacBook users reported that my &#8220;Start At Login&#8221; option wasn&#8217;t working.  In debugging, I found that <tt>AEGetKeyPtr</tt> was returning <tt>errAECoercionFail</tt> (-1700) &#8212; it couldn&#8217;t convert the Unicode path to UTF8.</p>
<p>A symmetric problem occurs when asking System Events to add a login item.  Here, <tt>LoginItemsAE.c</tt> uses <tt>AECoercePtr</tt> to create it&#8217;s path property in <tt>typeUnicode</tt> form from a UTF8 character buffer, but was seeing <tt>errAECoercionFail</tt> on Intel Macs.</p>
<p>Well, that sucks.  In Apple&#8217;s <a href="http://developer.apple.com/documentation/AppleScript/Conceptual/AppleEvents/appendix3_aepg/chapter_12_section_1.html"><em>Apple Events Programming Guide</em></a>, it says</p>
<blockquote><p>
Support for the following coercions was added in Mac OS X version 10.4:</p>
<p>Between these types:</p>
<ul>
<li><tt>typeStyledText, typeUnicodeText, typeUTF8Text, and typeUTF16ExternalRepresentation</tt></li>
<p>&#8230;
</ul>
</blockquote>
<p>In searching for a solution on the web, I noticed that the <a href="http://growl.info">Growl</a> project also uses <tt>LoginItemsAE.c</tt> to set their helper app as a login item.  The latest repository version shows no changes.  Have they not seen the same problem?</p>
<p>The workaround: instead of asking AE to coerce our data for us, we do it ourselves using <tt>CFString</tt>s.  I wrote a function which converts a char buffer between CF string representations:</p>
<pre>static int ConvertPathEncoding(char *path, int pathlen, int bufsize, int src_cftype, int dest_cftype)
{
  int ret = 0;
  CFStringRef cfpath = CFStringCreateWithBytes(NULL, (UInt8 *)path, pathlen, src_cftype, FALSE);
  if (cfpath == NULL) {
    ret = -1;
  }
  else {
    int len = CFStringGetLength(cfpath);
    Size actualLen;
    CFStringGetBytes(cfpath, CFRangeMake(0, len), dest_cftype, 0, false,
                    (UInt8 *)path, bufsize, &#038;actualLen);
    CFRelease(cfpath);
    ret = (int)actualLen;
  }
  return ret;
}</pre>
<p>Now I can ask <tt>AEGetKeyPtr</tt> to give me a <tt>typeUnicode</tt> string in my buffer, and then call <tt>ConvertPathEncoding</tt> to convert from <tt>kCFStringEncodingUnicode</tt> and <tt>kCFStringEncodingUTF8</tt>.  Similarly, instead of calling <tt>AECoercePtr</tt> to create my login item path parameter description, I call <tt>ConvertPathPathEncoding</tt> to convert from <tt>kCFStringEncodingUTF8</tt> and <tt>kCFStringEncodingUnicode</tt>.</p>
<p>In <tt>AEDataModel.h</tt>, we see that <tt>typeUnicodeText</tt> and some other types are &#8220;<tt>deprecated due to their lack of explicit encoding or byte order definition.  Please use typeUTF16ExternalRepresentation or typeUTF8Text instead.</tt>&#8221;  <tt>typeUTF16ExternalRepresentation</tt> is defined as &#8220;<tt>big-endian 16 bit unicode with optional byte-order-mark, or little-endian 16 bit unicode with required byte-order-mark,</tt>&#8220;, <em>i.e.</em> it is possible to check if the string has the correct byte-order for the system.   But apparently, the System Events API is still using UTf-16 with no BOM.</p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2007/03/28/debugging-apples-loginitemsaec-on-intel-macs/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Macnerd Gearheads needed</title>
		<link>http://jakesprouse.net/2007/02/03/macnerd-gearheads-needed</link>
		<comments>http://jakesprouse.net/2007/02/03/macnerd-gearheads-needed#comments</comments>
		<pubDate>Sat, 03 Feb 2007 19:22:22 +0000</pubDate>
		<dc:creator>Jake</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://jakesprouse.net/?p=28</guid>
		<description><![CDATA[If you rock the Mac, and you have an unhealthy habit for gear (backpacking, skiing, snowboarding, climbing, etc&#8230;) let me know, I&#8217;ve got some good work for you.
]]></description>
			<content:encoded><![CDATA[<p>If you rock the Mac, and you have an unhealthy habit for gear (backpacking, skiing, snowboarding, climbing, etc&#8230;) let me know, I&#8217;ve got some good work for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://jakesprouse.net/2007/02/03/macnerd-gearheads-needed/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
