31
Oct 07

mouse hacking for giggles

Optical mouse guts inside an old Apple ADB mouse

i’m thinking of hacking the guts of an old iBook into a classic Mac Plus case. In preparation, though, i thought i’d start small, by shoehorning the guts of an optical mouse into the Plus’ ADB mouse. i documented the process here.


04
Oct 07

MacinShelves

a project i built a few years back when i had too many classic Macs in my house, and no shelves to put them on.

two birds. one stone.

the bookshelves in my office

the bookshelves in my office.


08
Mar 07

jiggety jig

sigh… back home again, safe and sound.

no major delays in Rome, requiring us to extend our stay indefinitely. no international incidents, resulting in our claiming asylum in Italy.

back to the grind, such as it is.


05
Mar 07

we’re not coming back

so, we made it to the Cinque Terre a couple of days ago, and have been enjoying ourselves so much in this place that i haven’t found a moment to get online until now. i would encourage everyone to spend some time here – but be sure to come during the high season: leave the place nice and quiet during the winter for folks like me and Alli.

 anyhoo, we’re already contemplating shipping the animals here, selling off the house and all our stuff, and starting a little cafè with a computer repair shop in the back.

if you ever want to see us again, you’ll have to take a flight, a train, another train, a whole bunch of steps, and be sure to get here when we’re not on siesta.

sigh – back to reality, and back home in a few days.

 

 


02
Mar 07

florence

yep. we escaped Rome, and we’re in Florence now.

Duomo, gelatto, Uffizi, David – and finally a place for dinner that was so non-tourist, nobody spoke English.

 


28
Feb 07

buon giorno

hello from Rome.

we made it safely here, with no delays, cancellations, flight changes or other airport difficulties. based on my personal history with such things, it can only mean that we will face some major hurdles getting back to the US. no worries. an extra day or two in Italy wouldn’t be a hardship.

anyhoo, yesterday was a long day, due to the time change, and we crashed hard at the end of it. we managed to see a good bit of the ancient city, fueled by adrenaline and caffiene. today, the plan is to see the Vatican (hey Pope!)

more updates as time and access permit. if you don’t hear from us in a few days, wait a few more *_-


12
Feb 07

ipod cozy

why… what’s in that little knit cozy?

yep. i knit an ipod cozy. email me if you want the pattern :)

[update]
i’ve never actually written a pattern before. i’m even bad at following them, as i tend to try and experiment – sometimes with unpleasant results. anyhoo, for everyone that has requested it, here’s what i’ve got. it may be hard to follow, incomplete or totally inaccurate, but then, that’s true of most everything i write.

if you’re more of a “pro” knitter, and feel up to the task, feel free to adapt or rewrite these instructions in a proper format.

[pattern follows]

ipod cozy pattern:

begin by casting on 9, 11, or 13 stitches onto a double-ended needle. the number depends on the size of your needles (i use #7 / 4.5mm), the type of yarn (i’m using a “worsted” weight yarn this time), and whether you’re planning on using the resulting cozy on an ipod, ipod mini, cel phone, or other electronic gadget of similar size. full-sized ipods tend to fit the 11- or 13-stitch cozy, the mini is more of a 9-stitcher. in any case, the result should be plenty stretchy, so don’t be alarmed by a slightly small diameter.

the bottom:

so… 9 (or 11, or 13) stitches on a double-ended needle. knit one row. perl one row. knit one row. knit one last row.

form the circle:

beginning and ending with perls, alternate knit and perl for one row.

with three more double-pointed needles, complete the circle. cast on 4, then 9 (or 11, or 13), then another 4. you should now have a wide rectangle.

join the circle and, following your previous row, beginning and ending with perls, alternate knit and perl for the long sides.

for the short sides, perl one, knit two, then perl one.

rinse and repeat:

in this manner, continue to form the cozy, until you’ve reached the desired length.

add the drawstring:

bind off one of the short sides. continue around the three remaining sides, perl every stitch. turn around and knit a row. continue this – a row of perls, a row of knits – for six more rows.

finish up by sewing the resulting flap at the top such that you can pass a string or braided yarn through the hole and cinch up the opening at the top. i’m not describing this very well, but look at the photos and you should see what i did.

sew the bottom flap so you’ve got a closed off “sock” to slip your ipod into, then turn inside-out to hide the seams.

share and enjoy.


08
Jan 07

Kernel Notes (from Linux v0.1)

due to the continual popularity of this post from my old site, i’ve decided to repost it in the new WordPress site, so people can actually comment on it

comments and notes by Linus Torvalds included in the Linux Kernel
(version 0.01)

When looking through the kernel source, out of curiosity and in an effort to glimpse a piece of the history of this revolutionary operating system, as well as the personality behind it, I found myself fascinated by the irreverent comments and side notes that the author included with the code.

I felt that the comments in the code, the direct communication between the programmer and his peers, the kernel’s earliest users, was worthy of archiving as much as the operational code. Possibly moreso.

The following comments are contained in the source code of the original Linux kernel, version 0.01, from August 1991, by Linus Torvalds. Many of these survive in the latest developmental kernel, alongside those of the many open source contributors that have, since 1991, joined the, now monumental, effort.

from head.s:

/*
  *  setup_gdt
  *
  *  This routines sets up a new gdt and loads it.
  *  Only two entries are currently built, the same
  *  ones that were built in init.s. The routine
  *  is VERY complicated at two whole lines, so this
  *  rather long comment is certainly needed :-).
  *  This routine will be overwritten by the page tables.
  */

  /* This is the default interrupt "handler" :-) */
.align 2
ignore_int:
	incb 0xb8000+160		# put something on the screen
	movb $2,0xb8000+161		# so that we know something
	iret				# happened


/*
  * Setup_paging
  *
  * This routine sets up paging by setting the page bit
  * in cr0. The page tables are set up, identity-mapping
  * the first 8MB. The pager assumes that no illegal
  * addresses are produced (ie >4Mb on a 4Mb machine).
  *
  * NOTE! Although all physical memory should be identity
  * mapped by this routine, only the kernel page functions
  * use the >1Mb addresses directly. All "normal" functions
  * use just the lower 1Mb, or the local data space, which
  * will be mapped to some other place - mm keeps track of
  * that.
  *
  * For those with more memory than 8 Mb - tough luck. I've
  * not got it, why should you :-) The source is here. Change
  * it. (Seriously - it shouldn't be too difficult. Mostly
  * change some constants etc. I left it at 8Mb, as my machine
  * even cannot be extended past that (ok, but it was cheap :-)
  * I've tried to show which constants to change by having
  * some kind of marker at them (search for "8Mb"), but I
  * won't guarantee that's all :-( )
  */

from boot.s:

| well, that certainly wasn't fun :-(. Hopefully it works, and we don't
| need no steenking BIOS anyway (except for the initial loading :-).
| The BIOS-routine wants lots of unnecessary data, and it's less
| "interesting" anyway. This is how REAL programmers do it.


from buffer.c:

/* NOTE!! While we possibly slept in sync_dev(), somebody else might have
  * added "this" block already, so check for that. Thank God for goto's.
  */


from exec.c:

	eip[0] = ex.a_entry;		/* eip, magic happens :-) */


from file_dev.c:

/*
  * ok, append may not work when many processes are writing at the same time
  * but so what. That way leads to madness anyway.
  */


from memory.h:

/*
  *  NOTE!!! memcpy(dest,src,n) assumes ds=es=normal data segment. This
  *  goes for all kernel functions (ds=es=kernel space, fs=local data,
  *  gs=null), as well as for all well-behaving user programs (ds=es=
  *  user data space). This is NOT a bug, as any user program that changes
  *  es deserves to die if it isn't careful.
  */


  from config.h:

  /*
  * HD type. If 2, put 2 structures with a comma. If just 1, put
  * only 1 struct. The structs are { HEAD, SECTOR, TRACKS, WPCOM, LZONE, CTL }
  *
  * NOTE. CTL is supposed to be 0 for drives with less than 8 heads, and
  * 8 if heads >= 8. Don't know why, and I haven't tested it on a drive with
  * more than 8 heads, but that is what the bios-listings seem to imply. I
  * just love not having a manual.
  */


  from main.c:

  /*
  * Yeah, yeah, it's ugly, but I cannot find how to do this correctly
  * and this seems to work. I anybody has more info on the real-time
  * clock I'd be interested. Most of this was trial and error, and some
  * bios-listing reading. Urghh.
  */

  void main(void)		/* This really IS void, no error here. */
{			/* The startup routine assumes (well, ...) this */



from utime.h:

#include 	/* I know - shouldn't do this, but .. */


from string.h:

/*
  * This string-include defines all string functions as inline
  * functions. Use gcc. It also assumes ds=es=data space, this should be
  * normal. Most of the string-functions are rather heavily hand-optimized,
  * see especially strtok,strstr,str[c]spn. They should work, but are not
  * very easy to understand. Everything is done entirely within the register
  * set, making the functions fast and clean. String instructions have been
  * used through-out, making for "slightly" unclear code :-)
  *
  *		(C) 1991 Linus Torvalds
  */


from errno.h:

  /*
  * ok, as I hadn't got any other source of information about
  * possible error numbers, I was forced to use the same numbers
  * as minix.
  * Hopefully these are posix or something. I wouldn't know (and posix
  * isn't telling me - they want $$$ for their f***ing standard).
  *
  * We don't use the _SIGN cludge of minix, so kernel returns must
  * see to the sign by themselves.
  *
  * NOTE! Remember to change strerror() if you change this file!
  */


from vsprintf.c:

  /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
/*
  * Wirzenius wrote this portably, Torvalds fucked it up :-)
  */


from tty_io.c:

/*
  * Jeh, sometimes I really like the 386.
  * This routine is called from an interrupt,
  * and there should be absolutely no problem
  * with sleeping even in an interrupt (I hope).
  * Of course, if somebody proves me wrong, I'll
  * hate intel for all time :-). We'll have to
  * be careful and see to reinstating the interrupt
  * chips before calling this, though.
  */


from sys.c:

  /*
  * This needs some heave [sic] checking ...
  * I just haven't get the stomach for it. I also don't fully
  * understand sessions/pgrp etc. Let somebody who does explain it.
  */


from sched.c:

  /*
  *  'schedule()' is the scheduler function. This is GOOD CODE! There
  * probably won't be any reason to change this, as it should work well
  * in all circumstances (ie gives IO-bound processes good response etc).
  * The one thing you might take a look at is the signal-handler code here.
  *
  *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other
  * tasks can run. It can not be killed, and it cannot sleep. The 'state'
  * information in task[0] is never used.
  */


from printk.c:

  /*
  * When in kernel-mode, we cannot use printf, as fs is liable to
  * point to 'interesting' things. Make a printf with fs-saving, and
  * all is well.
  */


from mktime.c: 

  /*
  * This isn't the library routine, it is only used in the kernel.
  * as such, we don't care about years<1970 etc, but assume everything
  * is ok. Similarly, TZ etc is happily ignored. We just do everything
  * as easily as possible. Let's find something public for the library
  * routines (although I think minix times is public).
  */
/*
  * PS. I hate whoever though up the year 1970 - couldn't they have gotten
  * a leap-year instead? I also hate Gregorius, pope or no. I'm grumpy.
  */


from memory.c:

  /*
  *  Well, here is one of the most complicated functions in mm. It
  * copies a range of linerar addresses by copying only the pages.
  * Let's hope this is bug-free, 'cause this one I don't want to debug :-)
  *
  * Note! We don't copy just any chunks of memory - addresses have to
  * be divisible by 4Mb (one page-directory entry), as this makes the
  * function easier. It's used only by fork anyway.
  *
  * NOTE 2!! When from==0 we are copying kernel space for the first
  * fork(). Then we DONT want to copy a full page-directory entry, as
  * that would lead to some serious memory waste - we just copy the
  * first 160 pages - 640kB. Even that is more than we need, but it
  * doesn't take any more memory - we don't copy-on-write in the low
  * 1 Mb-range, so the pages can be shared with the kernel. Thus the
  * special case for nr=xxxx.
  */


from fork.c:

  /*
  *  'fork.c' contains the help-routines for the 'fork' system call
  * (see also system_call.s), and some misc functions ('verify_area').
  * Fork is rather simple, once you get the hang of it, but the memory
  * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'
  */

  


25
Sep 06

flash sudoku solver

my latest experiment in flash: an actionscript sudoku solver. given a valid puzzle, it attempts to parse it for its unique solution.

it’s still fairly rudimentary as solver programs go, but it’s getting better as i get better:

http://clickheredammit.com/sudokusolver.html

share and enjoy.


04
Sep 06

she said yes!

in case you haven’t heard, i’m engaged. w00t!