I'm not going to say a lot about the very first RISC OS thing that I wrote, because there's not a lot to say. My GCSE Computer Science project was a Mandelbrot renderer. Originally for the BBC, I moved it to the A5000 at school and it ran a lot faster, and with more colours. I'm really only mentioning it because it was the first - and it got me a good grade on my GCSE as well
It wasn't particularly clever, although it used what I called the 'clever' algorithm to speed it up - it would know when the iterations exceeded the limit in the column it had previously processed and use that information to decide whether to not bother with calculations for the following row (and to go back again if it found others that could be rendered. Because there weren't any islands (that I know of) within the Mandelbrot set which required fewer iterations, this appeared to work out ok. It improved the speed significantly when examining areas that bordered the iteration limit.
The program allowed both a scan based render, and an iterative render, where it would draw increasingly higher resolution squares until it reached a limit, or the squares became only a pixel high.
Back when we first got the A5000 it was a family machine. Although I used it a lot, it was shared - Julian and Simon did school work on it, Dad had stuff for work, and occasionally we'd do things for Mum (as she wouldn't do it herself). Oh, and we played games on it a lot, too.
After a little while I began to set up the system so that it could isolate each user from one another. This made sense for a lot of reasons, not least because I wanted to play about with things and didn't want to break the system for everyone else - when Dad came to use the machine, it had to work. The basic application that controlled the log in was !WhoAreYou. This was a little application that I had written which would ensure that the system was set up for the user, and prevent you from going behind its back. Of course you could always use shift on boot to avoid the full boot, but you can't have everything.
(Larger version (54K))
The application would deal with resetting all the furniture, sprites, fonts and trying to restore the state back to a standard system after you logged out. Clicking on a user would load up the !AreaFiler and the main desktop for the user - together with a 'Thank you' and 'Initialising for user' banner. Areas could also be configured with a password so that you couldn't log in without it. You couldn't kill !WhoAreYou and trying to shutdown past it would be prevented and it would offer its own shutdown sequence.
When shutting down from !WhoAreYou it would also check whether there were any discs in the floppy drives (we had 3 floppy drives - the built in one, plus 2 external drives). The system had been known to do bad things if it was turned on or off with discs in the drives, so checking was useful. Plus it meant you probably put them back in the disc box.
The instructions at the bottom of the log in screen were actually useful (if you read them!). The machine was connected to an external amplifier and speakers, which made games a whole lot more impressive, so it necessary to remember how to get the sound out. A filter was installed separately on the TaskManager to catch the Adjust click and make it load the sound configuration tool. The tool wasn't that clever, just allowed the internal and external output to be controlled, along with the overall system volume.
The same filter would trap shift-ctrl-F12 (and the 'Shutdown' option on the TaskManager menu) and cause it to run the !Shutdown application, which would check whether you really meant to shutdown before doing so. Mainly because it was too easy to press shift-ctrl-F12 when you just meant ctrl-F12 to open a TaskWindow. Later, when doing work on the OS, the same feature was built in to the TaskManager directly.
The !WhoAreYou application would keep track of people that logged on, together with an entry in the CMOS which was updated by the !AreaFiler every 15 minutes. This meant that if the machine crashed the application could update the log with a reasonably accurate answer. The logs ended up something like:
Total log on time : 98 hours 48 minutes Total times logged on : 143 times ----------------------------------------------- 29 Oct 1995 : 21:59 - 22:04 (5 mins) 29 Oct 1995 : 22:09 - 22:17 (8 mins) 29 Oct 1995 : 13 mins 10 Nov 1995 : 21:26 - 22:00 (34 mins) 10 Nov 1995 : 22:36 - 23:30 (54 mins) 10 Nov 1995 : 88 mins ... and lots more
Once you select a user (you've got the password right if there was one), a little sample would play to wish you 'Good Morning' (or 'Evening' or 'Afternoon' depending on what time of day it was). Then !AreaFiler would be launched, and you would be able to use your files.
The !AreaFiler was the main part of the user system, once you had logged in. It ensured that you didn't access areas you weren't meant to, and provided most of the common things you'd need to do - run applications off the second filer icon, start up the printer drivers, control the configuration, and would do a host of other little things.
Stuff I'd forgotten about... oh so many little things. You could configure it to 'chime' the hour. Where 'chime' means load the Speech module and say something like "It's 12 pee em". As I've mentioned it would prevent you from accessing areas you weren't meant to - watching for the messages that Filer sent for opening directory windows and forcing them to close again (not amazingly secure but it at least kept people from straying into other people's stuff, not that I expect anyone would!).
Because it was meant to run on the A5000 it would regularly reduce the size of the RMA so that space was recovered where possible. It provided its own implementation of !Help as well, as a bubble pop up, using bulleted lists of items. It looked pretty decent for a simple help application, I think. The main reason for providing that itself was that the implementation wasn't all that hard, about 4K of commented BASIC code, and that saved having to load the real !Help application, which would be 32K minimum (as that was the page size on a 4MB A5000).
When Impression Style exited, it would automatically cause the user dictionary
to be saved as the default dictionary, so that it would be used next time.
!Style and many other
applications had all been patched so that instead of loading their default
configuration and documents from within themselves they would load them
<Area$Private>.appname' instead. The
Choices system didn't exist at that time, so this was the only way that
you could force the files to be stored in a different place. Games, as well,
had their configuration changed, so that (for example) playing Chocks Away
for one user didn't keep the progress from another and you could play with
your own saved games.
The filer itself was two icons on the IconBar. The left one was the user's
filer, and a Select click would open the main area, where you could put your
files. Clicking with Adjust would open the 'private' area, which contained
your configuration files and other bits and pieces, like screen grabs and
the like. A
!AutoBoot file could be placed in here to be run
when the area was first entered. Pinboard had a filter on it so that dropping
a file on the background would cause it to be saved to the private area and
then pinned to the backdrop, making it more like the desktop background on
I'd also configured !Larger to do the same thing, so that if you had configured your area to use !Larger (there were a bunch of different configuration options) it would work in the same way. !Larger itself had similar modifications to make it more friendly to the multi-user system.
The right hand icon could open the applications windows. Select click would open the applications (unless you held down shift, in which case it would tell you the time - I guess that must have been useful at the time!). Adjust click would open the games directory, and Menu click would open the clippings directory.
The menu on the user filer let you launch a number of applications, including !Config+ to configure your area. The different sprites used in the area were all configurable, from the filetypes through the tool sprites to the option and menu icons. The choice of backdrop tool (Pinboard or !Larger) could be made, and the screen saver type was configurable too (albeit just !DarkHorse or plain ScreenBlanker). The background image could be configured, and would work with either !Larger or Pinboard, whichever you chose, even if you reconfigured it.
The configuration tool had way more options than you would probably use, but it looked quite neat. The !Reminder application could be configured to start up when the area started, and you can see it in the top left of the screen grab above. If you clicked on the icon, a drop down window showed all the reminder lines you'd set, and you could remove them or add more. I haven't got a similar tool these days, although I think I probably ought to have something like that!
Every user could use the !Diary application, which allowed a shocking 320 characters to be entered per day (I think - 80 characters per line, for 4 lines). I'd also hacked a version of !Almanac, which had been provided as a demo on some disc, so that it could save entries, which made it very nice to use as a little Filofax for various details. It was a lovely application - as I got no pocket money I couldn't save up to buy it, but I did learn a lot about C code and reverse engineering the code to make it do what I wanted. Foolishly (!) they'd left in most of the code to do the saving, but it just wasn't hooked in - much of the 'hack' was to locate the place where the save functions would be called and put a jump in to call them. Not exactly rocket science, but it was great fun.
!NoteIt I wrote a little !NoteIt tool which could make some notes, and would be displayed in !Zap. Unlike the !Reminders application, the !NoteIt application was limited only by the memory that !Zap could use - because it just used the External Edit protocol to edit and view the notes. Later I came to use the !NoteIt tool far more for the notes in my University project, but it came from here.
One of the more important jobs that the !AreaFiler did was to manage the printer system. Ink was expensive, so we didn't want to use it unnecessarily; Paper, too. It was useful to use draft print outs before doing the 'final' print run, especially for project work at school. The drafts could be read through and annotated when printed on the fan-fold paper, before being corrected. Finally they could be printed at higher quality on proper A4 paper. The !AreaFiler would reconfigure the !Printers application for the right paper type (fan-fold, A4) and density (low, draft, normal, very high). Towards the end you could even configure it to use !ArcFax output to send faxes of the printouts. Once configured, the main !Printers application would be quit and my !Spooler loaded in its place.
The RISC OS printer drivers weren't too bad. They could be used from any application and they're not too hard to make work if you've got a sensible rendering routine - which you probably already have for the window redraw anyhow. On the other hand, for users setting printers up, it was a lot of pain. Aside from having lots of different printers configured with slightly different settings, you had to go into a quite complicated configuration window to change even simple things.
Added to that, the default way that the main application worked was to print directly to the printer. This meant that you had to wait until the printer had finished its work before you could do anything else. So if it took a couple of minutes to print a page, you had to wait a couple of minutes before the system would talk to you. That didn't seem very reasonable to me and I really couldn't see Dad hanging around to wait for jobs to print - he was busy and it would mean remembering to prepare everything to be printed at the end of an evening. Even still you had to be there to print from the next document.
This seemed quite silly to me; there had to be a better way. Initially we started out by configuring the printer drivers to write to a file, and dragging the file to !Printers, which would then send it to the printer. When configured to write to a file the print jobs finished in seconds. Maybe a minute when you printed a few multi-page documents, but much faster and more sensible for general use.
The !Spooler application managed this process. Each print job would write to a single file. The !Spooler would spot that this file had data in it and would move it away into the queue. If it couldn't move the file away, that's because it was still being written to by an application so it waited a bit until it was able to be moved. The files moved away were given an identifier and could be tagged with a job name for the queue. Jobs could be queued to be printed multiple times, which was the only way to print multiple copies on dot matrix or ink jet printers at the time (unlike PostScript where you'd just say 'print it 20 times' at the end of the job). The queue could be seen in a window, and the number of copies were visible in the list.
The !Spooler application would step through the queue throwing data at the output device (parallel or serial) as fast as the configured memory buffer allowed (with thresholds so that it wasn't constantly feeding 128 bytes into a 32K buffer as the printer removed them). Once the job completed it would move on to the next copy, or the next job. All the time the record would be kept on disc of where things were, so that the jobs could be restarted if they failed (machine crash, power cut, feline attack on the keyboard, etc).
Copies could also be reprinted whilst the job was still present, so that (for example) if the paper had jammed or some thing had gone wrong, the copy could be restarted. Multiple copies were useful for class sheets, duplicate review copies, or template forms, so this was pretty useful.
If you shut the system down, the !Spooler application would automatically select 'Pause next job', wait for the job to complete and only then shut down. That would mean that when you turned the machine on next time (and started the !Spooler) you would find that there were jobs in the queue, tagged with the user's name, so you could either print them, discard them, or ask whether they were important yourself (as wandering downstairs to check if someone wanted things printing was pretty easy!).
Like !WhoAreYou, the !Spooler would keep a record of the jobs that were printed, so you could see what you'd done:
Files printed using !Spooler ============================ Certificate For Me..... on A4 Maximum at 240x144 dpi 01 Jul 1995 C:1 Roa.................... on A4 Maximum at 240x144 dpi 02 Jul 1995 C:1 Julian's Roa........... on A4 Maximum at 240x144 dpi 02 Jul 1995 C:1 Jadis, Pend, Fc........ on Fanfold at 240x216 dpi 06 Aug 1995 C:1 Tape Covers............ on Fanfold at 240x216 dpi 10 Aug 1995 C:1 ... and more
There was an instructions booklet for answering questions about what to do when things go wrong, and how to do specific things. It was printed and bound, and sat beside the monitor so that it was easy to get to. If there was something up, I hoped that it would answer questions. However, I had often changed things so that the stuff that went wrong previously wouldn't happen again, or so that there were new features available. For example, as the features were added to the !Spooler, the users needed to know what had been done.
I kept a full record of the changes to the system and software - whether it was a new application installed, or a fix for something that had gone wrong. However, it wasn't always obvious that the change log had been updated. Because of this, and because it was often useful to transfer things between users, I wrote the !PostBox application. This allowed files to be sent to other users, and they would be notified when they logged on that there was new mail available.
The destination could be set by selecting the user to send to from the menu on the !PostBox application on the IconBar, or you could select 'All' to send to everyone. Text files would have a header prepended to them to indicate the sender, recipient and date/time it was sent. Opening the post box would let you copy the files out, and you could select options to remove items from the post box.
I used to use it to let people know that stuff had changed, or to pass anything interesting that I'd found to people. It was still possible to save files in other areas, like the Clippings: folder, but the post box directed attention to it.
The implementation wasn't particularly complex. There was a special
directory in each user's area called '
PostBox' which would
contain the files, and could be copied from. If you ran any of the files
in there, the application would pop up a save box to let you copy the file
somewhere else, or offer to run it, and tell you who sent it and when.
The metadata that stored the details about the files that had been sent
was stored in the '
I think I'd probably implement it differently these days, but the solution was pretty simple and did a reasonable job.
At one point I deleted a file I needed from a disc. That's generally a pretty foolish thing to do, and without David Gamble's !Undelete (which was still a few years away), or !Recyclone (which was a lot of years away) it was an annoyance that we just had to put up with. But no... there's usually a way, and I had a simple plan. A program that would read the 'free' sectors on the disc and try to associate them with known file signatures. After all, most files could be recognised from their content, even without the actual filetype information.
The main front end window. !FindFiles was an application born of this idea. Although it was controlled by an application, it was really just a command line tool which would do its job, usually writing to a spool file and storing its results on a different disc to that which it was recovering. It could read the usual sorts of removable discs (including Zip discs, as I had a Zip drive) either in their entirety, or just reading the free space (assuming you hadn't got a completely corrupted disc).
It was a two-pass process to find the files, to first work out the possible
locations of data that was interesting, and then to confirm the data it would search
for the length of the file. Once they'd been found by this passes,
the resulting data would be written to a recovery directory.
The first pass would look for signatures at the start
of every sector which would indicate the start of a file. Since many data
files had some form of signature this wasn't too tricky to do. For example,
a DrawFile would start with the word '
Draw' at the front.
!DataPower databases started '
!ArtWorks started '
Top!'. BASIC usually started 13, 0, 10
(if the file started at line 10, although it might be line 1 if the file
If we couldn't recognise a basic signature like this in the sector, we'd try some heuristics to see if it met some other basic criteria. If the first 6 4-byte words were all small (less than &80000), it could be a Module (allowing for the fact that the flags on initialisation and finalisation were seldom used). If 80% of the data was ASCII, the file was probably a text file, and if it started with a '|' character, it was probably an Obey file as these usually included a comment to say what they did at the start.
In this first pass we'd record a few simple details that we'd determined - the location on the disc (or image), the filetype we thought was there, any length that we've determined (or a lower limit on the size), and some flag about the determination we made. During the first pass the flags would be 0, but as we performed the second pass we'd update these.
The second pass would do more checks, possibly stepping through subsequent sectors for each file in order to get more information. For example, a SoundTracker module would need more data beyond the first sector to determine the type properly. BASIC and DrawFile files would need to step through the content in order to find the end, and in the case of the DrawFile that would still be a guess. Modules would be even more clever, checking the title, help and SWI string contents as generated by their offsets were consistent with common usage.
If the data looked strange it would be marked in the flags data so that we knew it might be very wrong. If the previous determination of a file length meant that this 'file' might be corrupt or just invalid, that would be flagged too. That happened quite regularly, particularly for 'text'. Consider a DrawFile containing a Text area. The signature would be correct for a DrawFile, but the second pass would determine that the file took many sectors. But the first pass might have identified any number of sectors as starting 'text files', because the text area in them looked right according to the heuristics. The text files in the second pass would be flagged as probably being overruns from the DrawFile that enclosed them.
The recovery at the end was quite trivial - the address and updated length were used to read the data to a recovery directory, written to a file given the name of the sector address they were found at, as we had no filename information for the file. The file would be given the determined filetype as well, so it could be examined. It would still be unwise to blindly execute anything that had been recovered in this way, but loading data files like DrawFiles or Sprites was usually safe enough and sufficient to determine if the recovery was good.
I retrieved quite a few things over time which I'd either deleted by accident, or the disc had become corrupt on. It was really a very simple program in essence, but it did a nice job. I don't see it on Arcade so I don't think it ever really went to anyone. Well it helped me a lot.
Whilst I was learning how RISC OS worked, and working with bits of !StrongHelp, I needed a way of finding things quickly. I didn't have any tools that did searches, so I wrote my own simple tool. I wrote a little bit of assembler to do the wildcard search (only simple wildcards, but this was mostly sufficient for what I needed). The code was based on one of the old Acorn utilities from the Econet systems which copied files - it had a very nice algorithm for handling the wildcards which didn't need a lot of memory.
It's one of the applications that I had published in Acorn User, although it did have a bug in that version, which meant that the wildcards didn't work properly. Oh well. It was actually quite a fast searcher, and used the throwback protocol with !Zap (or other editors) so that you could jump quickly to the found instance.
I used it for quite a few years, until I found a good copy of grep which handled everything that !TextScan did, including the throwback.