Another RetroChallenge Ends

My last week of RetroChallenge 2010 has been unbelievably busy.  Because of my PyOhio presentation, a golf tournament, and various other items which I’ve since forgotten, my time available for RetroChallenge was somewhat compressed. However, even with those obstacles, I’d call my RetroChallenge a success.

For the initial 2 weeks of the challenge, dabbled in the wonders of User RPL on an HP 48G calculator.  The product of this fun was not only familiarity with this oddball language but also two nontrivial programs.  I simply can’t get enough of the music player I authored.  While it is rather simple and restricted to one octave, it does in fact play arbitrary songs.  The math program was far more difficult to author, but perhaps not as novel.

Creating a boot sector for a Tandy 1000 was a terribly interesting project, at least to me.  By attempting to create a valid boot sector, I was able to get my hands dirty in x86 assembly, something I usually don’t get near.  On top of learning some additional assembly, I was introduced to PC bios calls which I had personally never seen before.  Fun stuff!  I was unable to bootstrap arbitrary code, but perhaps another time I’ll overcome that problem.

The RetroChallenge this year was a delight, although I didn’t devote nearly as much time to it as my last Warm Up, much to the joy of my wife.

Success! Congratulations to my other challengers as well!

I’m So Awful at JuMPing!

After showing how to display an image via the boot sector and some fancy disk loading, I decided to try my luck at actually starting a program from disk.  Reading from the disk is actually quite easy thanks to BIOS interrupts as long as one knows the location on the disk (in terms of tracks/sectors) where the data to load exists.  A logical extension of this idea is to load up a program from disk and execute the code.

Obviously I’m not attempting to implement an operating system of any sort, so the goal is actually to just execute some simple code that is easy to locate on a floppy disk.  To execute arbitrary code, however, one needs to understand what exactly they are attempting to execute.  In the MS-DOS world, we have two general types of executables, COMs and EXEs.  COM files are always rather small, while EXE files can span a wide variety of sizes.  After some mild research on Wikipedia, it turns out, as one might expect, that the COM format is rather simple. When a COM file is executed, MS-DOS loads the entire file into memory offset 0×0100 and allows the program to begin execution.  Easy!  The EXE format, also known as DOS MZ format apparently, is somewhat more complicated and way beyond the scope of this RetroChallenge.

Based on the code used to write data to a screen, I authored a slightly modified version that would load the contents of a COM file into memory at the correct offset.  Once loaded, the assembly would simply jump (JMP) to the address, 0×0100, and continue execution, thereby running the COM program.  While this sounds rather simple, there are some major caveats.

First of all, the COM program I was attempting to load was much bigger than the 4000 byte screen I was loading previously.  This larger size means that the data is spanning multiple tracks, which might or might not be a problem.  I chose to not actually think about this issue.

Second, the chosen COM file must not rely on any MS-DOS services to work properly.  While this seems like a simple, reasonable request, one must consider any and all calls to MS-DOS interrupts, which can be used for simple things like text output.   To be safe, the COM file I chose was previously a PC Booter, the game Zaxxon.  I made sure first that this game ran like a dream on the Tandy 1000 before proceeding with my experiments.  Because the game is purely graphics and was previously packaged as a PC Booter (it was converted to a COM file by pirates at some point), there should have been no reliance on DOS itself.

I’ve messed around all evening with trying to get the game to start directly via the boot sector to no avail.  The best result I seemed to arrive at was some garbage appearing, in text, in the upper left corner of my screen.  Since I can’t quite resolve the issue, I’ll try something different for my last little RetroChallenge project.

Reading the Disk

Thus far, my fabulous boot codes have done very simple operations.  My problem with assembly language, however, is that I’m not all that familar with it.  Even simple operations seem to become a task.  This challenge has improved my understanding of assembly language, but I’d still struggle with any type of substantial program.

The combination of my lack of assembly skills and the need to draw using strict assembly code has led to some rather dull boot blocks.  Displaying an interesting message, however, would require a lengthy development process, a significant amount of cursing NASM, and a lot of beer.  Instead, reading a message from disk and displaying it would be pretty easy, relatively speaking.

Those familar with BASIC on the PC will remember the fantastic BSAVE command and its conjugate, BLOAD.  These commands are often used to dump video memory and reload it.  My fantastic game, Castle of the Llamas, used BLOAD extensively for game screens to avoid the tedious task of laying out the game using BASIC.  In general, the user specifies the segment to dump in BASIC and executes BSAVE, which writes the contents of memory directly to a file.  This technique works like a charm on the PC where the video RAM is directly addressable.

While all this information is delightful, creating BSAVEd screens can be fun using some utilities.  Back in the day I used TheDraw extensively.  TheDraw is a ANSI drawing program, and it was popular in the BBS world for creating screens.  One fantastic feature is support for BSAVE format compatible with BASIC.  Because the BSAVE format is so simple, I decided to use TheDraw to generate a fun screen, which I would load via boot sector code.

Saving a text screen requires 4000 bytes, 25 rows by 80 columns by 2 bytes per character location.  Therefore, a pure memory dump should take up 4000 bytes.  TheDraw, however, generated a file measuring 4015 bytes long.  The BSAVE format, however, does contain a header which is useless in this application.  The header measures 7 bytes long, and the actual screen data follows said header.  After the screen data, the header is repeated for some reason.  Finally, a single byte that BASIC traditionally uses for some reason is left at the end of the file, making the file size 7+4000+7+1=4015.

I wrote the assembly code that would load the first 8 sectors falling after the boot sector.  Since each sector holds 512 bytes, 8 sectors would give 4096 bytes, enough for a single text screen.  The assembly also set the segment to 0xb800, the beginning of video memory on the PC architecture.  Reading the disk was rather simple as BIOS interrupt 0×13 provides the ability to directly read disk sectors.

Once the assembly was ready, I had to write the screen image to disk.  Again I chose to use MS-DOS’s debug utility to do so.  Recall that I needed to skip the 7 byte header when writing out to disk.  I used the following debug commands:

C:\SRC>debug rc2010.bsv
-w 107 1 1 8
-q
C:\SRC>

One consequence of writing to the first 9 disk sectors is that the file allocation table is destroyed in the process, making the disk unreadable to MS-DOS.  I’m personally not concerned about it, but it makes rewriting these sectors a pain as the disk needs to be formatted before debug can be used again.  The command above is rather simple.  The “w” is the write command, 107 is the address in memory to start retrieving data to write, 1 is the second disk drive (B: on my PC), the next 1 is the first sector to start writing, and 8 is the number of sectors to write.  The 107 is interesting because 100 seems to be the begining of any file loaded via the initial debug command.  By using 107, I skip the entire 7 byte header, outputting screen data and some garbage at the end.

I was happy to find out (after a few initial miswrites) that the assembly code worked perfectly:

A fun screen

This example opens the door to loading binaries or graphical screens from disk. I’ve included a link to a boot image if anyone wants to try this out.  The boot disk should work with any personal computer in theory, including emulators.

Graphics from the Boot Sector

The BIOS interrupt 0×10 functions on PC include a handful of input and output functions.  My last post talked about a successful boot block that printed out the alphabet.  However, I was interested in an additional function provided by this interrupt, namely 0×0C, writing a pixel.

I’m using mode 9, which is a Tandy and PCjr specific mode featuring 320×200 graphics and 16 colors.  The video mode switch is achieved by calling function 0×00 of interrupt 0×10.  This call is relatively simple as the mode desired is the low byte of the AX register, while the function number is the high byte.

After switching into a PCjr video mode, I tried relatively simple tasks like drawing single pixels or complete lines.  The function call is actually simple.  The high byte of AX is set to the function number, 0×0C.  The low byte is set to the desired color.  The values of CX and DX are the rows and columns respectively.  Easy!

To make things a bit more interesting, I decided to try some more impressive drawing functions.  I was able to fill the screen with alternating columns, each featuring another of the 16 available colors.  This impressive feat was all achieved using BIOS calls to interrupt 0×10, which is painfully slow.  A video below shows the Tandy booting this graphic program:

(Sorry about the audio… stiction in the tripod…)

The simple code is actually pretty neat.  I wasn’t sure I’d be able to figure this out in assembly, but x86 assembly isn’t all that horrible.  Ideally, to achieve something similar but fast, one would write directly to video RAM.  I still need to do my homework on that task.

While this code is neat, it still doesn’t do much interestng.  Hopefully my next post features a more interesting 512 bytes of boot code.

Tandy Success!

The last post documented to attack vectors for getting text onto the screen via a boot sector.  The first wrote directly to the video RAM, while the second made use of the of BIOS interrupt calls.  The first technique didn’t translate cleanly to NASM, which was entirely due to my inability to author assembly language, so I’ve decided to work with BIOS calls.

The PC bios provides some basic input and output routines via interrupt 0×10.  The example I had outlined in my last post displayed a string on the screen before rebooting the system.  Or at least it claimed to…  I had mentioned that I neglected to terminate the string, which I suspected was the reason why the Tandy displayed nothing at boot time.  It turns out that it wasn’t the problem.  I suspect that the Tandy’s BIOS simply doesn’t support the string operation.  In fact, glancing at online documentation concerning 0×10 didn’t reveal any function that should behave as such (ok, this reference does list function 0×13, so whatever…).

I decided to try a more basic function, notably 0×0E, which purports to output a single character to the display.  The steps toward success taught me some 8088 assembly syntax along the way.  Apparently the ?X registers can also be specified as two separate bytes by using the equivalent ?H and ?L bytes.  For example, to output the character ‘A’, you can either perform:

    MOV AX, 0x0E41
    MOV BX , 0x0000
    INT 0x10

or

    MOV AH, 0x0E
    MOV AL, 0x41
    MOV BH, 0x00
    MOV BL, 0x00
    INT 0x10

Either technique works.  Again, I spend very little time in assembly language in my daily life, but I occasionally need to make interrupt calls from C.  I believe I was aware of the high/low byte specification, but I may have forgotten over time.

I decided to push my luck by implementing some assembly to boot the system, display the alphabet, and wait for a keypress before reboot.  I had not attempted a loop in assembly before, but it was rather easy to implement.  I simply generated the character, incremented (INC) the letter starting at ‘A’, compared (CMP) it to ‘Z’, and jumped back to the beginning of the loop if it was less than or equal to (JLE) ‘Z’.  Since I wasn’t doing anything more fancy, I was able to perform all operations directly on AL.

The final test was to try this assembly program on the Tandy.  I compiled using NASM, a trivial task.  Then, to write the boot block, I fired up debug, provided with just about every version of MS-DOS.   To write the boot block, I used the commands:

C:\SRC>debug boot
-w 100 1 0 1
-q
C:\SRC>

My 486, oddly, has its 3.5 inch floppy as B:, which is what the first “1″ signifies in the command above.  For a 3.5 inch floppy on drive A:, this “1″ would be a “0.”

I was able to write the boot block to a 720KB disk image.  On the Tandy, I specified booting from floppy (it normally boots from ROM).  After a few milliseconds, I was greeted with the alphabet in all caps on the screen!

As RetroChallenge accelerates towards its conclusion, I plan on writing something slightly more interesting in the boot sector.  I don’t want to make any promises at this point as I don’t know what I can personally achieve.  However, I think this is a great start towards success.

A disk image is provided below for anyone interested:

This image should work with any emulator as well, like VirtualBox or QEMU.  An interesting bit about this disk is that the file system is still intact even though the boot sector is modified.  The image itself, in MS-DOS FAT format, contains the original assembly code.

Booting a PC

My second RetroChallenge task this month is to attempt to boot a Tandy 1000HX from scratch.  When I say I plan to boot it from scratch, I’m actually talking about writing boot code, copying the compiled code to the boot sector, and successfully getting the Tandy to run said code without using MS-DOS.  This task might seem pointless to some, especially since the 1000HX ships with MS-DOS in ROM, but most of RetroChallenge is rather pointless.

The Tandy 1000 HX, which I used during the Winter Warm Up, is an odd all-in-one machine.  The keyboard, motherboard, and 720KB 3.5 inch floppy drive are all housed in a single unit.  The system itself is powered by an 8088 CPU, and my system has a full 640KB RAM.  The Tandy 1000 series is especially interesting as they are IBM PCjr clones, not strictly PC clones.  This slight differentiation can lead to minor difficulties, but it shouldn’t affect my quest to successfully boot the system.

I personally have been interested in writing simple boot code since it is the basis for constructing an operating system.  As a teenager, I always thought authoring an operating system would be sweet, but I never had the knowledge and skills.  However, these days, after years of participating in development projects, I still don’t possess the knowledge and skills.  As an alternative, I’m attempting to write simplistic boot code.

The boot process of an IBM clone is rather simple.  When booting from a floppy disk, the BIOS loads in the first sector of the floppy, measuring 512 bytes, and stores the code at memory address 0×7C00.  If the sector ends in two specific bytes (0×55AA), the sector is identified as bootable, and the code present within the sector is executed.  Rather simple, right?

Because only 512 bytes are available, the code for the boot sector is usually written in assembly.  For a true operating system, the code normally loads in more substantial code and data from the floppy disk, which the original boot code subsequently executes.  This additional code does not have any limitaitons, and would often be the operating system itself.

That said, the 512 bytes can also be written to do something interesting.  My goal was to start with this simple task of creating a usable 512 byte boot sector.  Searching online revealed a dated article on creating said code, available here.  The suggested code is a simple bit of assembly that should, in theory, display an “A” on a blue background in the upper left-hand corner:

entry start
start:
      mov ax,#0xb800
      mov es,ax
      seg es
      mov [0],#0×41
      seg es
      mov [1],#0×1f
loop1: jmp loop1

This example is moderately easy to follow.  The second two lines set the current segment to 0xb800, the address where video RAM begins.  The “seg es” directives notify the compiler that the following statement are going to use the segment (0xb800) stored in the ES register.  The “mov [0],#0×41” code puts the captial “A” at memory location zero, or the first byte in video RAM.  The second similar move instruction sets the appropriate attribute.  Finally, a loop at the end is basically used to lock up the machine infinitely.

The big problem with the example is that the code is written for the as86 assembler, available on GNU/Linux.  After installing as86, I compiled the code and wrote the resultant 24 bytes into the first 24 bytes of a FreeDOS boot floppy.  The resultant image is actually bootable on VirtualBox, which is quite amazing.  However, I had hoped to work on a DOS system, my 486, as a development machine using TASM or MASM.  The code as is does not compile under either commercial assembler.  Specifically, the “seg es” lines are not supported by the compilers, and the directives that set the letter “A” and its attributes generate an error.  I tried yesterday and the day before to rewrite this handful of code to work with either MASM or TASM, but I failed miserably due to my lack of assembly language knowledge.

Today I gave in and transfered the as86-generated code to an actual 720KB floppy’s boot sector.  While I was worried that as86 might not be generating true 8088-compatible code, I was surprised to find an “A” on a blue background in the upper left corner of the screen.

My next goal was to possibly find an example written in some assembly syntax that is slightly more widespread in use.  Searches for “MASM boot sector” and TASM boot sector were relatively fruitless until I happened upon a similar set of instructions from a document on textfiles.com.  This document suggested the Turbo Assembler, TASM, as an option, but the code, sadly, was directed at NASM, the Netwide Assembler.  As NASM isn’t a historical DOS assembler in my mind, I had avoided it.  However, out of deep frustration, I decided to use it once I saw that a version for MS-DOS existed.

The new example is somewhat different than the original, shorter example in that it uses BIOS calls to achieve screen IO:

START:
     MOV AX,0x0003
     INT 0x10

PRINT_STRING:
     MOV AX,0x1301
     MOV BX,0x0007
     MOV CX,0x23

     MOV BP,MSG
     ADD BP,0x7C00

     INT 0x10

WAIT_FOR_KEY_PRESS:
     MOV AH,0x00
     INT 0x16

REBOOT:
     DB 0xEA
     DW 0x0000
     DW 0xFFFF

MSG  DB 'Press any key...',13,10

     TIMES 510-($-$$) DB 0

SIGNATURE DW 0xAA55

My version that I implemented at this point is actually wrong.  Specifically, I neglected to terminate the message string.  When I boot this code on the Tandy, I get no text at all.  However, the keyboard input and subsequent reboot work perfectly.  I must admit, though, that I don’t yet have a good handle on everything occurring in this implementation.

The last implementation should be an acceptable starting point.  My lack of assembly is really hurting me at this point, but I should be able to pick up enough to make this challenge interesting.

An Alternative to RPL: Saturn Assembly

I talked briefly about an alternative to RPL using a C-like compiler to generate RPL indirectly.  I wasn’t overly impressed as I originally thought the compiler would generate machine code, but it was my own fault for having too high an expectation.  While User RPL is fun, I didn’t want to delve into System RPL, a lower lever language that uses the same syntax but runs faster and has the potential to crash your calculator.  I decided to look into Saturn Assembly.

Scientific HP calculators up through the HP 48 series all used a custom CPU known as the Saturn.  This chip was designed for high-precision BCD mathematics while operating at extermely low power levels.  The fact that it uses BCD math means that the CPU is nibble-based; the basic unit on the HP is 4-bits rather than a full 8-bit byte.  The Saturn CPU can address 512KB RAM (apparently), and the implementations on the 48G series ran at a whopping 3.68MHz.  The fact that HP designed their own CPU makes their calculators somewhat more interesting in my opinion than the equivalent Texas Instruments calculators at the time, which relied on Z80 CPUs.  I’m sure that TI nuts will have exactly the opposite view, stating that using standard CPUs are the way to go.  These are the ridiculous arguments engineers regularly have.

Sadly, HP’s latest calculators no longer use true Saturn hardware.  Instead, they have switched to emulating the Saturn on an ARM processor.  Another wacky custom CPU dies.

Anyway, I decided to look into writing Saturn assembly.  HP provides an assembler, so finding the necessary tools was not going to be a problem.  Instead, my complete lack of assembly language programming is the real problem.  In past projects, I have stumbled through assembly language programming, mostly modifying existing code until it “worked.”  Learning even a bit of Saturn assembly was going to be quite the problem.

From hpcalc.org I downloaded a few tutorials on Saturn assembly.  Almost every single one started by explaining the Saturn architecture, which I didn’t think was so exciting.  One tutorial actually had a 5 line example of a valid program.  However, when I started reading the description, I was both baffled and disappointed.  Also, I was not particularly keen on moving nibbles around in memory.  The simple example appeared to use arithmetic operations too, which was a surprise based on my extremely limited x86 assembly experience.  It all seemed exhausting.

Intel x86 assembly seems a bit easier to handle.  It helps that there are fewer registers on an 8088 than on the Saturn processor (I think, I really only glanced over those parts of the tutorial).  The concept of a nibble is also a bit more difficult to understand, especially for math purposes.  With the 8088 too, I can completely ignore floating point math, whereas the Saturn is all floating point.

So my foray into Saturn assembly is a non-starter.  Having reached the near-midpoint of the RetroChallenge, I think I’m going to shift gears and start work on trying to boot a Tandy from scratch.  Booting the Tandy, of course, will require some assembly, but I feel a bit more confident working within the PC-like environment.

An Alternative to RPL: Not-Quite-C

When I first started researching this RetroChallenge and looking into programming the HP 48G, I was surprised to find an interesting piece of software called hp48cc.  I was excited to see a C compiler for the calculator, and I made a note to come back to it at some point for a little exploration.  I decided to jump directly into User RPL first and learn a new language.  After spending a short time with the “C compiler,” I’m very glad I looked into RPL first.

I’ve grown a bit tired of hand-typing RPL programs into the HP, especially since the on-board editor does not save white space.  Anything larger than my math game would be unmanageable.  That game itself took two days to key in.  Writing RPL on a PC would be much easier, but syntax checking would get old real fast since I’d have to download the program to check if it was valid each time.  In fact, the HP rejects downloads if the syntax isn’t correct, which is a nice touch.  I thought instead that I’d try my luck with C.

I naively set out to create my first program with hp48cc.  The compiler is actually available on Debian repositories, which made installation simple.  Opening a text editor, I keyed in a simple hello world program:

int main(int argc, char *argv[])
{
printf(”Hello World\n”);
return 0;
}

Easy enough! I launched hp48cc, and was immediately greeted with an error:

hp48cc: 1: syntax error

The above meant it didn’t like my main declaration.  That immediately set off alarms in my head.  I decided to wait another day to try it again.

The next day I downloaded the actual source distribution of the compiler in an effort to find documentation.  Luckily the archive had an examples folder full of .hpc files.  I opened a randomly selected one and was a little surprised by what I found:

// pi1.hpc -- Calculate the pi (Algorithm 1) -*- C -*-

// k is the number of iterations
declare pi1(k): s(0) {
	for (; k >= 0; --k)
		s += (-1)**k/(2 * k + 1);
	s * 4;		// Return value
}

The above code clearly is not C. Some stuff looks like C, but it isn’t C.  The declare statement is obviously declaring our pi1 function.  I believe the s(0) line is initializing the variable s to zero.  The rest of the code is similar to C, except the return value is simply the evaluation result of the last statement.

I decided to give this compiler a go with my own quick and easy program.  I wrote a simple function to calculate the hypotenuse of a triangle:

declare hyp(s1,s2): c(0)
{
        c = s1*s1+s2*s2;
        c = sqrt(c);
        c;
}

The program is overly verbose for illustrative purposes.  Running the compiler, I was presented with the following output:

%%HP: T(3)A(R)F(.);
\<<
\<< 0 \-> s1,s2,c \<< s1 s1 * s2 s2 * + 'c' STO
 c sqrt 'c' STO
c
 \>> \>> 'hyp' STO\>>

I had half expected the compiler to generate some sort of binary. To my surprise, it had translated the code in its quasi-C dialect into User RPL. The code is indeed correct, but I had really expected a bit more finesse from the compiler.  I don’t mean to belittle the usefulness of this compiler, I just had much higher expectations in my mind.

The compiler itself is mainly useful for people who don’t feel like trying to grasp User RPL directly.  I don’t personally see much benefit since I think User RPL is a fun break from the usual languages.  If you want to program in a style more like C or BASIC or any conventional procedural language, you should have purchased a Texas Instruments calculator.

A Simple Brain Game

While User RPL is a difficult language for the unfamilar itself, entering a program via the HP 48G directly is a pain.  The earlier program I wrote, which plays music, was entered directly into the calculator as was today’s much larger program.  After writing the music player, I wanted to author something that interacted with the user and was at least mildly interesting.

I’ve been entering the code directly into the calculator simply because it immediately complains if a syntax error has occurred.  Authoring a lengthy program on a PC followed by uploading to the calculator would be tedious in my case due to my unfamiliarity with the language, which guarantees plenty of syntax errors.  There are some emulation packages and code editors available, mostly from hpcalc.org, but I’ve had almost no luck with any of them.  The editors and emulators available are somewhat older, and almost all are for Windows (I’m more-or-less strictly GNU/Linux at home).  While their being Windows application isn’t inherently problematic necessarily thanks to Wine, these older programs often ship with older, non-standard installers.  Furthermore, a lot of packages are either an editor or an emulator.  What I’d really like is an integration of the two, but I couldn’t find a suitable package.  Therefore, I’ve stuck to typing programs directly into the calculator.

My new game is much larger than the music player, and it integrates some ideas that weren’t present in the music player.  Basically, the game is a simple math game that challenges the user to solve 10 addition problems as fast as possible.  The user simply presses the appropriate number to solve the problem.  I used the WAIT statement to retreive user input.  This statement takes a single argument, which specifies the amount of time to wait for a keypress.  Because I wanted the program to wait forever, I used the input 0.  The WAIT statement, when a key is pressed, returns a very oddly coded floating point number.  The number is 2 digits, a decimal point, and a final single digit.  The first digit, in the tens location, specifies the row of the key pressed starting from 1 at the row directly below the screen and ascending as distance from the screen increases.  The second digit is the column of the key pressed.  Finally, the digit after the decimal specifies whether one of the shift keys was also pressed.  It’s a neat technique for dealing with user input, but, when programming, it was difficult to process.  Since I only wanted numbers, it was solvable using HP’s CASE structure.

My other concern was concatenating strings, especially with numbers.  After perusing some documentation, I found no functions that claimed to do anything.  On a whim, I tried adding a number to a string.  Sure enough, this technique worked like a charm!

Another fun point is that only one input per problem is necessary, but often the additive result is greater than or equal to 10.  Rather than limit the problems, I decided to check if the two random number to add are greater than or equal to 10.  If so, I set a flag on the calculator.  Flags in User RPL are basically simple booleans that are always present in memory and can be referenced by integer.  For example, to set the first flag on the calculator, I would use the code:

1 SF

The SF statements sets the flag, essentially creating a true boolean state.  To unset the flag, or clear it, the CF statement is used.  Flags can then be queried using the SF? or CF? statements.  Sixty four flags are available to the user, while another sixty four store calculator settings.  Amusingly, the settings flags are not protected in any way, allowing programs to mess with the calculator easily.  Flags seem to be an odd inclusion in User RPL, but they are quite useful.

The game is mildly amusing to play.  I’ve made a video of it, as shown below.  My wife was able to complete the game in 19 seconds, which I still haven’t beat. Some problems cause brain farts, so I occasionally have to stop and think.  A video of the game is available below:

I think some people might notice my having a bit of trouble on one of the problems.  I like to think of the game as good brain exercise, similar to those Nintendo DS Brain Age games, only simpler. The source code, which I’ve cleaned up considerably by adding indentation (the HP 48G doesn’t bother with storing unnecessary whitespace in programs) and removing special characters:

I did notice a few things when transfering the program off the calculator.  First, the Rainbow 100 apparently does contain the double angled bracket character, which shows up fine on that computer.  Also, my Ubuntu box also displayed the double brackets properly.  The reason it doesn’t display properly on PC’s generally under MS-DOS is because of IBM’s poor implementation of the ANSI X3.64 standard.  The Rainbow implements this standard properly, which specifies escape sequences and extended characters.  However, IBM really dropped the ball on this, requiring the ANSI.SYS driver to be loaded.  Even with the driver, IBM PCs did not conform to the standard.  However, as IBM PCs became the defacto personal computer standard, the non-standard became the standard.

Anyway, I hope people enjoy this little game, even if it is only via the video.  I think at this point I may move on with my RetroChallenge.

A Magical Day for Hard Drives

Today I continued work on yet another HP 48G masterpiece, but I became sidetracked late this afternoon.  As an earlier post explained, I recently had two hard drives fail, one vintage and one rather new.  This afternoon I began to get frustrated with the broken computers surrounding my desk, so I decided to troubleshoot the Rainbow.  I pulled yet another working Rainbow 100B off the shelf in the hopes of testing the problematic hard drive in a different computer.  The errors produced by the Rainbow normally using the now-dead drive often blamed the “Main Board,” which made me suspect that I might have a dying motherboard.  I decided to investigate, and I opened up the two computers.

Please excuse the floor drain in the foreground…

The drive in question, an ancient Mitsubishi 535-U00, had been having read problems and poor performance.  Thankfully, the drives and almost any component in the Rainbow can be pulled without any tools whatsoever.  I popped the drive out and plugged it into the Rainbow on the floor.  I also plugged the existing video cable into the floor-based ‘bow so I could just use the keyboard and monitor on the E.T. stand.

The Mitsubishi booted without issue in the new Rainbow, but that usually worked in its original parent computer as well.  Next, I tried starting BinkleyTerm, which hadn’t been working in the original machine.  BinkleyTerm worked like a dream.  Finally, I tested Kermit on another partition, which had never worked on the other machine.  Kermit worked fine too.  Before writing off the hard disk controller as bad, I placed the Mitsubishi back into the original computer to try the same tests.

With the drive plugged in, I started up the original Rainbow.  I was surprised to find both BinkleyTerm and Kermit running fine!  In fact, the hard disk seemed to be running better all around!  My current guess is that there was a problem with the cable contacts.  Because the computer is kept in the basement and the cable’s contacts are most probably of the lowest quality, I would guess that the contacts corroded.  Simply reseating everything might have done the trick.  MFM drives like this Mitsubishi do transmit analog signals, so signal degradation might actually allow the drive to work somewhat acceptably without generating errors.

Anyway, after fixing my Rainbow, I decided to fire up the Athlon 64 which had developed a bad SATA hard drive.  The computer next to it, a dated Athlon XP running Debian Sarge, had been running slow.  I currently have a bit of a soft spot for the Haiku operating system, so I had a live CD lying around that I was going to use to browse the web for kicks.  I wasn’t quick enough, however, in getting the CD in, and I reached the GRUB menu on the hard disk before I could stop it.  On a whim, I decided to allow booting to continue.

After some loading, I hit the message that one partition had failed the file system check.  This partition, formatted in ReiserFS, was the culprit in blocking other boot attempts.  This time I simply hit Control-D, assuuming the computer would reboot.  Instead, all the daemons began starting, and I was eventually greeted with a login screen.  To my utter surprise, I could login!  My home directory appeared to be intact as well!

Today was full of hard disk miracles.  I’m still smiling knowing that both computers seem to be in working order again.  I realize that I should really move off the bad SATA drive in the Athlon 64 quickly, but I’m a lazy man.

I was able to achieve some sweetness on my HP 48G over the last few days.  More on that tomorrow…