October 24, 2009

Back to where I started

I removed or commented out most of the tainted code and re-wrote a lot of them, and the system is working about the same as before the branch. I still need to implement the low-level filesystem functions and vfork()/execv() functions to make a working Punix File System.

I also took the liberty of improving the tty driver. Previously this was based on crufty old code from V6 and V7, and it didn't support modern terminal standards and conventions. This code did most of the work in the ttyread() routine, where it handled the extra processing capabilites and end-of-line/end-of-file conditions. This code had a number of deficiencies, and I've been eager to rewrite it for some time now. I rewrote the tty based on code from 4.4BSD-Lite, where most of the work is done in the ttyinput() routine. This new version makes a line available in the canonical queue only when a "break" character is encountered (a break character is one of EOF (^D), EOL (\n), or EOT (also ^D)).

I also improved the virtual terminal driver by adding status indicators in the bottom-right corner of the screen for the Shift, 2nd, Diamond, Hand/Alpha, and Caps Lock modifiers. I drew a bitmap for a "bell" indicator too, but I haven't added it to the code yet.I added support for a bell indicator and started adding support for scroll lock. This can be seen in r160.

Speaking of modifiers, I really don't know what the "Hand" modifier should be used for in Punix. Maybe it could be scroll lock? Perhaps I could use it for the Compose feature instead of using the Mode key. Any ideas?

October 20, 2009

Some bad news

First of all, I want everyone to know that I'm still working on Punix, just at a near-glacial pace.

Secondly, several months ago I decided to clean up the license issue in Punix. The issue is that I'm releasing Punix under the GNU GPLv2—both by my own choice and because I'm using bits of code that are already under the GPLv2 (mostly from PedroM)—but some code is derived from UNIX V6, V7, or 2.11BSD. These latter ancient systems were released a few years ago by Caldera under an 4-clause BSD license. This license has an "advertising clause" which makes it incompatible with the GPL because it adds further restrictions to redistribution that are not allowed under the GPL.

So now I want to remove any "tainted" code. I performed a code audit on each and every function in each source file to determine whether the code was tainted or was ok to leave in Punix. Here are the files that have tainted code in them:

  • alloc.c
  • bio.c
  • fio.c
  • inode.c
  • namei.c
  • pipe.c
  • rdwri.c
  • tty.c

Unfortunately, this covers a lot of code that implements the buffer system and virtual file system (VFS). On the other hand, it's not very unfortunate because I hadn't fully integrated the VFS code yet anyway. Some of it didn't support modern UNIX standards and conventions either, and I was planning to rewrite it too.

All in all, this is only a minor setback. I have several files of code to re-implement to get a (somewhat) working system. I created a branch named "clean" for working on removing the "dirty" code. It doesn't compile as of r144, but I hope to fix that soon. :)

April 9, 2009

Screenshot goodness

Because I've made significant changes to the user process for testing, I feel it's appropriate to post a screenshot of the latest revision, currently r132 r141. This screenshot shows tests of the uname(2) system call, the tty (/dev/vt), the random device (/dev/random), the link device (/dev/link), and the audio device (/dev/audio). All of these features are working in this revision. Additionally, there's a demo of a simple version of the "top" utility, and most of the statistics in there are real.

In the test of the /dev/link device, I used another instance of TiEmu running PedroM to send a variable to this calculator. This could also be done with the "Send file to TiEmu..." menu option in TiEmu itself, but that blocks the use of the calculator while the variable is transferring (remember that Punix is a multi-tasking operating system, so that is kind of annoying).

For the test of /dev/audio, headphones or speakers are required, but only if you want to hear the stereo test tones. :)

I still just need to work on getting the filesystem and binary execution working, and then we'll be very close to a working system!

April 8, 2009

/dev/link works now

Since last post I've been trying to make the /dev/link device driver work properly.

To assist me in testing I wrote a simple version of the variable receiver function getcalc(), which implements part of the TI linking protocol and runs entirely in userspace (except for the read() and write() system calls themselves). For the most part the link device worked fine. When a byte comes in and the read queue is full, the driver disables receiving until the user program drains the queue (at least by one byte). However, I discovered that no additional interrupts were being triggered to indicate that a byte is available in the hardware's receive buffer, even after those interrupts were re-enabled.

I finally fixed this today by setting a flag to indicate overflow of the read queue and then, in the system call (non-interrupt) code, read from the hardware receive buffer if overflow is flagged. Then interrupts are enabled again at this point and receiving bytes continues as normal, until the read queue becomes full again of course.

You can check out this working code with demos from revision 132. Ok, I lied. I forgot to commit all of my local changes in this revision! You can get working code (hopefully) at least from r141.

April 6, 2009

It works, it works, it works!

No, Punix still doesn't have a filesystem, but it's getting closer. I've added tests of the various system calls in the user program, especially read() and write() on a few different devices (files under /dev/). This was achieved by modifying the open() system call to recognize those device names specifically, allowing read() and write() to operate as normal. The following is an incomplete list of features that I've tested and verified as working:

  • Audio device
  • Random device
  • TTY
  • uname()

The following are features I'm still testing but do not work completely yet:

  • Link device

Audio device

The audio device currently lives at /dev/audio in Punix. The driver for this is not very complicated, and the code that I wrote years ago needed only minor tweaks and tuning to make it work well. The audio output is in stereo, but given the limitations of the hardware, the sample rate is limited to 8192 Hz, and the sample size is one bit. Despite this, it can still produce decent sound, like those produced on 70's-era computers. :)

Random device

The random device is just what it sounds like: random. It produces a stream of random bytes that can be read using the standard read() system call. This implementation uses a a simple linear congruential pseudo-random number generator, meaning it should be sufficient for many applications like games but not for any type of cryptography. I suppose you could us it for the insecure type of cryptography, though.


The TTY is basically a wrapper around the terminal device, in this case the VT device as I've written about in the past. It basically makes terminal input and output "friendlier" to the application by supporting different modes of operation, such as "cooked" mode. "Cooked" mode is the most common mode for simple command-line programs that read input from the terminal. The TTY in Punix is still a little hackish, but it works pretty well now.

On a related note, I finally fixed a little issue with the vt device with regards to interrupts. Whenever a character is sent to the vt output, it would block all level 1 interrupts (by design), but this turned out to be a small problem because the vtoutput() function would often run longer than the duration of an level 1 interrupt. This means some interrupts would be lost, resulting in lost time since level 1 interrupts are used to maintain system time (along with the level 3 interrupt handler).


Here's an oddball system call that I implemented and tested. It's not oddball per se, but it simply doesn't follow the pattern of the previous features I tested. :D

This call just returns strings describing the system itself, including the name ("Punix"), release, version, and the machine ("m68k"). This isn't the least bit complicated, but I just wanted to make sure it's implemented.

Link device

The link device (/dev/link) is the device used to communicate over the I/O link port (2.5mm stereo jack) of the TI-92+. So far sending data seems to work flawlessly, but receiving data doesn't work at all. I've tested this by running two instances of TiEmu, one running Punix and the other running PedroM (which I know works). The program in Punix attempted to send a file (in the TI-92+ variable packet format) to the PedroM calculator, and the PedroM calculator initiated receiving the variable as soon as the Punix program started writing the data to the link device. However, after several seconds PedroM timed out because Punix was not reading its responses to the packet data. I'll need to figure out why the link device driver isn't receiving data.