Older blog entries for brouhaha (starting at number 82)

14 Jun 2005 (updated 14 Jun 2005 at 08:35 UTC) »
More Nonpareil printer work, especially on the GUI

There's some bug that prevents the printer simulation from working on my Fujitsu Lifebook subnotebook (800 MHz Crusoe processsor), but I haven't yet had a chance to try to debug it. It works fine on my other machines, aside from the problem I noted yesterday with use of the Paper Advance button when the calculator is in program mode.

I added the double-size mode, selectable by a menu item. Internally there's an integer for the scale, so it could have values greater than 2, but right now the UI only allows toggling between 1 and 2.

I can't decide whether to use radio buttons for the printer mode (NORM/TRACE/MAN), or a menu with radio items. I've got both in the code now, with defines to select at compile time. For radio buttons, I think I prefer the three radio buttons arranged vertically, with the Print and Paper Advance buttons arranged vertically to the right of the radio button group. Anyhow, if buttons are used (even just for Print and Paper Advance), some effort needs to be put into making the layout aesthetically pleasing.

The arrows on the scroll bars on the printer output menu weren't working, though dragging the ``thumb'' or clicking in the paging regions (between the thumb and arrows) worked fine. It turns out that the default step_increment in the adjustments used by the GtkScrolledWindow and GtkLayout are zero! I would have expected them to be one (pixel), though that wouldn't have been much better. Anyhow, I'd never dealt with GtkAdjustments before, but they're fairly simple. I set the horizontal and vertical step_increments to the size of one character. Now that I think about it, they really need to be the size of a scaled character, and updated if the scale changes.

And once I did that, I realized that the GtkAdjustment was the key to making the printer output window automatically scroll as new output is added. I wanted that to happen only if the window was already scrolled to the end, so that if the user manually scrolls to some other part of the output, newly generated output doesn't keep jumping it to the end. At the beginning of gui_printer_update(), I do something like this:

  bool was_at_end = ((p->v_adjustment->value + p->v_adjustment->page_size) >=
		     p->v_adjustment->upper);

Then at the end, I do:

  if (was_at_end)
      gtk_adjustment_set_value (p->v_adjustment,
				p->v_adjustment->upper - p->v_adjustment->page_size);

It seems to work quite well. It would be nice to have examples like this in the GTK+ API documentation or the tutorial.

P.S. To anyone with a lot of GTK+ experience this stuff probably seems blindingly obvious, but GUIs aren't really my area of expertise (despite having hacked Macintosh code since late 1984). In the Nonpareil project, my main interest is the guts of the simulation, and the reverse-engineering aspects (figuring out the internals of the old HP calculators). I'm doing the GTK+ work because I didn't think I could find anyone else willing to do it for me, but it's turned out to be quite fun. And maybe GTK+ expertise is a marketable skill. I wonder what percentage of GTK+-based development is done in C, vs. C++? I normally avoid C++, which is exactly why I chose GTK+ over Qt or WxWidgets.

82143A printer working in Nonpareil!

It's not ready for release yet, but I basically have the 82143A printer simulation in Nonpareil working now! You can see the result of PRA, PRP, and PRSTK in this screenshot.

There's not yet any way to save or copy the printer output, nor to change the printer mode (MAN/TRACE/NORM) or press the printer ADV or PRINT buttons. I also want to add a double-size view.

I'll make a new release available soon.

I'm missing one character in the font, code 123 (0x7b hex), because I couldn't make it out at all in the manual scan. I haven't the slightest idea what it's supposed to be. There are probably other errors in my transcription of the character set, so I'd like to get a better scan of either the actual printer output, or the page of the manual showing it.

Hmmm, maybe I need to add printer sound effects too! :-)

Nonpareil release 0.71

Keyboard operation has been fixed, and there are improved keyboard mappings for Voyager calculators. The 41C bank switching has been fixed so the 41CX Extended Functions now work correctly. The stopwatch mode now works.

Nonpareil release 0.68

Nonpareil now has much better looking LCD displays for the HP-41C and Voyager series calculators. Now instead of single-pixel-wide "stick digits", they have segments that look pretty much like the real thing, thanks to the scaling and compositing features of gdk-pixbuf. The Voyager annunciators are also now implemented.

The .png image files contain an oversized digit/character template, with each segment in a different color. The KML file specifies where the segment tempate is, how big it is, and what colors (RGB) the segments are. At startup, Nonpareil extracts the segments individually, changes their color to black, scales them, and converts the result to alpha channel data for compositing.

Display updates are also faster because display update requests now only invalidate the digits and annunciators that have actually changed, and the expose event handler uses the update region to determine which ones need to be repainted.

Updated the About box. Added some animation and an easter egg.

27 May 2005 (updated 27 May 2005 at 08:18 UTC) »
HP-41CX in Nonpareil

In release 0.67, the HP-41CX is now mostly working. I implemented the basic Phineas chip (Time Module) functionality, though apparently the stopwatch uses the TESTB mode which I haven't put in yet. The clock runs at real time, though it is not initialized from nor does it track the system time. Clock mode and alarms work, though there isn't yet sound support. There are various bug fixes and improvements under the hood.

Much thanks to Chris Roccati and Christophe Gottheimer for their work on making the Phineas chip and bank switching work in NSIM, and Thomas Olesen for doing the same for Nonpareil. I didn't incorporate much of their code due to planned infrastructure changes, but used it quite a bit for reference.

Thomas Olesen has been working on Nonpareil sound support using the SDL library, and Christophe Gottheimer has got the HEPAX module working in NSIM. I'll probably merge those changes in the near future.

Nonpareil - fixed it again

The Nonpareil bugs I introduced last night were easy to find by comparing traces captured with the last stable version against traces captured with the latest code. Fixes are checked into Subversion. I've started integrating Phineas chip support (real-time clock chip used in HP-41C Time Module and in HP-41CX), loosely based on the work of Thomas Olesen and Chris Roccati.

Howard Owen has a slightly earlier release of Nonpareil running on pdaXrom on a Sharp Zaurus C860. He found some trouble loading mod files with the latest code out of Subversion, so I added some debug output for him to try. He has expressed interest in porting to other Zaurus platforms, which use the Qt widget library. I have a Zaurus SL5500 and would love to run Nonpareil on it, but I don't like C++ programming so I'm not motivated to write a Qt-based front end.

Broke Nonpareil good

There's been an item on my Nonpareil TODO list for quite a while to refactor the low-level arithmetic and register operations out of the Nut processor simulation, and share them with the Classic and Woodstock processors. This is desirable because the Nut code turned out to be better organized and cleaner than the others. I finally got around to doing it tonight. I moved the code to src/digit_ops.[ch], and updated proc_{classic,woodstock,nut}.c to use it. Nut still works, but Classic and Woodstock are quite broken at the moment. I guess I should learn the adage ``if it ain't broke, don't fix it''.

I also implemented Nut bank switching in preparation for the HP-41CX, Advantage Module, and the HEPAX module. Did cursory testing with the Advantage module. Trivia of the day: during development HP was planning to package the Advantage Module in transparent plastic and call the ``Clear Advantage'', but clear plastic generally isn't as sturdy and durable as colored plastic, so it didn't meet HP standards.

The simulator now can load HP-41 ROMs from ``.mod'' files, the format Warren Furlow came up with for V41. The ``.mod'' file format is pretty good for representing HP-41 modules, but not so good for other calculators. I'm thinking about coming up with my own compressed-XML module file format for Nonpareil, but also supporting ``.mod''.

It appears that zlib doesn't provide any easy way to set the comment or extension fields of the zlib header. It would be nice to do that for state save and module files so that the ``file'' command could identify them. I could do it by munging the stream as it is written. What I'd really like to do is start the file with a ``#!/usr/bin/nonpareil'' line followed by the gzip-compressed data, so that executing a state save or module file would start Nonpareil automatically. The drawback is that other XML processing tools like xmllint that normally handle gzip-compressed XML files wouldn't be able to make heads or tails of it. I'm considering proposing a standard marker for use in a file that starts with a ``#!'' line to indicate that compressed XML content follows; then I could submit a patch to libxml2 to recognize the marker on input and Do The Right Thing.

Nonpareil 0.66

I started work on a RAM display window for Nonpareil's GUI debugger. The first attempt resulted in a window taller than the screen; I had to learn how to use a GTK viewport to get scrolling capability. Now the window starts out way to small, but at least is resizable. I'll have to figure out how to set the initial size to something reasonable.

Like the register display window, it isn't yet fully functional. Although they both use editable entry boxes for the display, if you edit them the change is not actually written back to the register or memory. And they don't update automatically, so you have to close the window and reopen it to see simulation changes. Still, it's been somewhat useful for debugging.

I'm not happy with the use of the standard GTK+ entry widget. I really want a widget that displays a number using a fixed base and digit count, in a monospaced font (or at least with the characters in fixed column positions), so that the digits in all the registers or RAM locations line up vertically, and there isn't extra empty space at the right side of the widget. Colored highlights for the P and Q pointer positions would also be useful. I'll have to write such a widget myself, and I probably won't get around to it for a while.

Google revealed that Adam Sampson has built a GARstow package for Nonpareil, and was frustrated with SCons. I discussed it with him by email, and all of his problems were really due to inadequacies in the way I used SCons, rather than with SCons per se. For instance, my SConstruct/SConscript files supported a "prefix" configuration option, but not "bindir" and "libdir" for more flexible filesystem layout, nor "DESTDIR" for a virtual filesystem root for installation packaging. Also, doing "scons install" was putting ".sconsign" files into the installation directories, which was resulting in file conflicts between various packages that use SCons.

I expect the same problems would affect almost any packaging system, including my own anticpated effort to offer RPMs for Fedora Core 3 and 4, so I've fixed them today for release 0.66. I added "bindir" and "libdir", as well as "destdir" (note lower case for consistency with other Nonpareil configuration options).

Also, by putting an "SConsignFile()" directive in the SConscript, it will put all of the signature information it uses for dependency analysis and tracking into a single ".sconsign.dblite" database file in the top directory, so it no longer puts .sconsign files into the install directories.

I added caching of the configuration options in "nonpareil.conf" to replace my previous "local.py" configuration file. And a "Help" directive so that "scons -h" will show all of the configuration options with their default and current values. To revert all options to the defaults, you can simply delete the "nonpareil.conf" file from the top directory.

I updated the INSTALL file as well as the credits in the README, added the people from the credits to the About dialog box, and moved the code for the About dialog box into separate about.c and about.h source files.

Thomas Olesen has sent me his patches to get the HP-41CX running, based on earlier modifications to nsim by Chris Roccati. I should have that integrated for the next release.

I sent Maciej Bartosiak email about the possibility of using POSIX threads in place of the glib thread support on MacOS X, and it turns out he'd already done that. He sent me his modified version of proc.c.

Nonpareil

Finally squashed a nasty bug. I thought I'd previously managed to fix the calculator state restoration bug, but it turns out that the bug only manifested on 32-bit machines and I was trying to debug it on a 64-bit machine. There was a call to strtoul() that should have been strtoull().

It's unfortunate that the C standard doesn't specify any replacement for those that is based on the actual size of the type (e.g., uint32_t, uint64_t) rather than the weakly defined ``unsigned long'' and ``unsigned long long''. I suppose the correct thing to do would either be to have a configuration test at build time to pick the right one, or to use sscanf() instead, since the C standard does provide size-appropriate format specifier strings in <inttypes.h>. Perhaps I'll add a strtouint64() function in my utility package, based on sscanf().

lcdtest

lcdtest release 1.01 has a new ``dots'' test pattern, and an on-screen help message.

Nonpareil

Release 0.63 of Nonpareil now simulates the HP-11C, HP-12C, and HP-15C calculators.

73 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!