VALHALLA REVISITED

Simon N Goodwin reports on the pros and cons of the 16 bit Thor system.

Thor updates
After a dozen variations, the Thor XVI seems to have settled on a standard ROM configuration. I have been using Argos 6.41 on my 1 megabyte Thor XVI since August 1989, and I'm used to it. As usual, I'm writing this in Xchange Quill, which comes with the machine.

The Thor XVI is a 'Super QL', first manufactured in 1987. It is based around a 68000 processor running at 8Mhz, like the Atari ST, so it is typically about three times faster than the QL.

The display format matches the default QL screen, but no Sinclair parts are used; in fact the Thor uses the same LSI chip as Acorn's BBC Micro. There is an extra graphics MODE 12, with the same 256 square resolution as MODE 8, but 16 colours, courtesy of a PC-style RGBI monitor.

The Thor XVI was designed by David Oliver and Graham Priestley, at CST in Stevenage. After a year production abruptly moved to Bruel and Kjaer in Denmark, leaving David's father out of pocket and Graham out of a job.

From the start the Thor's most ardent advocate has been Hellmuth Stuven, once Sinclair's main agent in Denmark. His companies Dansoft and Thor International have sold hundreds of XVIs, mainly to business users in Denmark, Germany, Italy and the Soviet Union, where Hellmuth hopes to establish a 'screwdriver factory' assembling machines under licence.

Chip swaps
Moscow firm YC Integral has reputedly offered to trade Soviet chips, power supplies, grinding wheels, pallets and potatoes for Thor components. Such 'barter trade' is commonplace - a rival business in Leningrad makes Spectrum clones in thousands for Soviet schools, bankrolled by sales of crystal Germanium to Switzerland - but the Thor deals have been slow to crystalise.

Meanwhile the XVI has undergone 'production engineering' to suit Bruel and Kjaer's computerised production line. The renowned Danish instrument-makers pride themselves on flexible automation. Press one button, it makes a Thor... press another and you get a microphone, a Geiger counter or Salami on Rye (possibly).

The re-design exercise pushed up the price of individual machines but meant that new two megabyte memory cards could be used in the three internal Sim slots, boosting the upper limit of memory capacity from 2 Megabytes to 6.5 Megs on Danish models. A SCSI software upgrade allows any Thor XVI to control eight hard disks of up to 100 Megs each, rather than the one or two 40 Meg drives that were the limit for early Thors.

The current 16 bit Thor XVI model is planned to be superceded by the Thor XX, a 68020 machine with four times the graphics resolution of a QL; I saw the specification a year ago, but have yet to see the product. This is the fourth 'fully designed' 32 bit QL clone I haven't seen. I hope they're all going to be compatible!

Whatever the outcome of Hellmuth's plans, many QL enthusiasts have upgraded to the Thor XVI. The main alternative is the Atari ST with Futura QL emulator, based on "JS" Qdos. The Thor boasts QL network and expansion connectors, and a port for up to eight SCSI devices.

The Thor system ROM has been stable for almost two years, so I have had time to get used to the peculiarities of Argos 6.41. This article charts my practical experience of Argos, much like my tours of Minerva, another close analogue of Sinclair's QL system. In fact I network them together, with Minerva serving the Thor, providing access to six drives 'QLd1' to 'QLd6', and any other devices I care to open over the net.

Like Minerva, Argos is inherently faster and more reliable than Sinclair's Qdos. Despite contrary protestations, both owe much to Sinclair "MG" ROMs, released late in 1985. They proclaim compatability, while adding features to existing Basic commands.

Most 'corrections' or changes bring deliberate advantages and accidental disadvantages. ROM-revisors have a tendency to be alternately reticent and self-congratulatory, but forewarned is forearmed. New features are great, as long as you know their good and bad points.

There's no point in feeling miserable about your "AH" ROM if you wouldn't use, or notice, the new bits or don't fancy dodging new pitfalls. Compared with version "FB", Qdos 1.00, they're all almost right; you are doing fine if your machine runs all the programs you like to use.

If I hadn't got my Thor, I'd have to buy another computer. That is saying a lot, as my desk layout owes a little to Rick Wakeman; I can reach six keyboards at the moment, and I'm typing on the Thor, which has a PC-style keyboard on a curly cable.

The Thor has no cartridge port, but there is an internal 8-bit expansion ROM socket. Mine contains a 64K Introm containing Talent's text editor, Speedscreen 6.24, Turbo Toolkit and parts of Toolkit 2. The Introm came with the machine, but it is no longer very useful: the Toolkit code is out of date and gets copied to RAM in order to run, while Speedscreen is slugged because it runs from 8-bit ROM.

CST advertised Introm to XVI owners, and it fits the socket, but it is intended for the Thor 8, and not really compatible with the latest ROMs. If I initialise either of the Toolkits after any program stops with an error in expression the machine crashes and must be reset.

Turbo Toolkit 1.42 was pretty good for its time (1986) but it does not communicate with versions of the Turbo compiler since version 2.01. The latest version 2.04 uses the Argos Thing list, which starts at PEEK_L(SYS_VARS+352), for communication between PARSER, CODEGEN, CHARGE and EXECUTE, and toolkit and compiler must match before Turbo can work.

I have had no dealings with Digital Precision since 1987, but do hear from Chas Dillon, who maintains the Turbo parser. The last version of Turbo Toolkit I have seen is Runtime 3.20. It is ROMable but has extra baggage in the form of microdrive access routines and other things Chas wants in everyone's computer. I re-coded DEFAULT_DEVICE to alias PROG_USE, so you should now be able to keep Turbo in a sub-directory.

The SuperToolkit extensions called up from the Thor's Introm by TK2 are convenient, if you're used to them on the QL, but many come as standard on the Thor. Argos 6.41 includes Toolkit 2 homonyms like LRESPR, CLOCK, SAVE_O, OPEN_OVER, OPEN_DIR and CLOSE without parameters. ALTKEY is not provided, and QJump's code will not run. However a tiny key-defining utility called FNKEY20Z is buried in the Quanta library, and that does work on the Thor.

Thor windows
QRam does not suit the Thor XVI, and locks the machine if you try to load it. The Thor family has its own windowing system, so that tasks do not necessarily over-write one another's windows; this uses an extra 16 bytes of data at the start of each window channel definition. EXTOP conceals the extras from add-on code, so DIY Toolkit functions work just as on a QL.

TurboQuill Plus is not happy on the Thor, although it invariably uses the Thor character set. This is little loss as Xchange has its own 'glossary' feature, and runs noticably faster than the original Quill.

QPac-2 does not work properly on the Thor XVI, but it is apparently happy on rare Thor 20 or Thor 21 systems. I think this could be fixed, if there was a demand; even on the XVI I understand that 'button functions' allow access to QPac utilities, and 'hot keys' can be accessed by tapping SYS REQ to swap to and from the controlling task, before pressing the required combination.

Thor windowing can be disabled with POKE SYS_VARS+133,-1. Subsequently-opened windows are not saved when tasks swap, and tasks continue to run even if their windows are obscured. I put this POKE in my BOOT program, so that Basic windows are protected but other tasks share the screen, QL style.

All the tasks I use continuously can easily be provoked into 're-drawing' their displays fast on the Thor; Devpac and Qlipboard repond to F4, like most text editors, while Psion programs expect F10 (Shift F5 on the QL). Overlapping windows allow continuous multi-tasking, and save hundreds of kilobytes that might otherwise be clogged by stored displays.

If free memory is really at a premium you can close and re-open the Thor Basic windows, to release their screen-stores. Put:

CLOSE #2:CLOSE #1:CLOSE #0:

on a single program line, before the POKE, and

:OPEN #0,CON:OPEN #1,CON:OPEN #2,CON:WMON 4

thereafter. Make sure all eight statements are on one line. Don't try this on the QL because Sinclair did not expect those channels to close; it won't help, anyway, in the absence of the windowing system.

Thor ROMs
The first Thor XVI ROM I encountered was version 6.30, which had many similarities with "MG" Qdos. It came in two 64K chips, with lots of empty space. Later ROMs show signs of large-scale re-coding in the BASIC interpreter, but still leave around 40K of ROM space fallow.

I was fairly happy with the original 6.30, although it would not run QMon; I guess it makes assumptions about the processor which suit the 68008, not the 68000, as it works at a very low level.

Investigations of the Thor ROM are handicapped by the fact that I still can't get QMon 2 to run on the XVI. The first versions were essentially "MG" ROMs with altered device drivers and modified tables. Earlier Thors used Sinclair "JS" ROMs.

Slowly Argos has taken on its own character, like Minerva. It works much as before - although intermediate versions contain howlers - but system calls are faster and often more reliable, or more powerful. The problem, as with all upgrades on an established standard, is that programs need to run on old QLs and Thors as well as XVIs if they are to be commercially sucessful. This means that new features are rarely used in published software.

Small ROM system improvements help to make the Thor seem even faster than benchmarks against the QL suggest, but in general the Thor will not run rare programs that expect a 68008, a 'key' cartridge, or particular Sinclair ROMs.

The vast majority of QL applications run perfectly on the Thor, and I'm most surprised if I manage to crash the machine; even if I do something daft Argos usually spots an 'exception' and suspends the task. Of course it is possible to crash it if you know how, so I've cited the methods I have found by accident, and said how I learnt to live with them.

Driving tests
There are some potentially fatal bugs in the current floppy disk driver. Direct sector access to DIM'd strings can crash the driver, as I noted in December; the same problem occurs if you try to load a sector into a LOCAL string with a preset maximum length, yet the target must match the sector size. The answer is to preset the length with FILL$, rather than DIM, as in FAST_FORMAT_BAS, or use Turbo's INPUT$ function. Compiled tasks seem to read sectors OK, thankfully.

Unformatted disks confuse the Thor, and may even make it crash. If you accidentally ask for the directory of a disk that has not been formatted Argos reports an error, but something gets into a muddle, because the machine crashes if you do it repeatedly. Similar problems may crop up if you swap disks without closing files. As long as you heed the initial warning, you should be alright.

My machine has two 720K floppy drives, and I'm saving up for a hard disk; my friend Chas Dillon has used hard drives from the start, and found the early version rather limited; it lacked direct sector access, and would only work with certain Rodime SCSI drives.

Version 6.37 introduced better SCSI, supporting more than two hard drives with a faster 1:2 sector interleave. This pushed the top speed past 200K per second, which is good news when you could have 800 Megabytes on-line. Even then it would take about an hour to read the lot, flat out.

Chas enthusiastically re-formatted his 40 Megabyte disk and discovered that 6.37 and 6.38 had Name Table inconsistencies that stopped them working with Turbo. After some frustrating phone calls 6.39 became the 'definitive' Thor ROM, for Chas and some others.

Thereafter Thor International embarked upon a major re-write. The short-lived Argos 6.4.0 was almost un-usable, with 225 bugs reported, but 6.4.1 seems stable.

Argos 6.40 had a terrible bug which could easily crash the Thor Basic interpreter. FILL$ used to clobber the maths stack when appending characters to any string containing an even number of characters. FILL$ was always OK under Turbo which has its own FILL$ code, but the bug affects QLib, which calls the ROM.

I am glad to report that multiplication by zero works in Argos 6.41, whereas 6.40 could get weird answers due to a errant 'optimisation'. This system bug should have upset Turbo tasks, as they call the affected routine, RI.MULT, but in practice Turbo already traps the special case and keeps it away from the ROM. In theory the bug could affect graphics, as they use RI.MULT internally, but in practice you should be OK as the scaling code should never try to multiply by zero.

6.40 could only manage Turtle graphics in the default window #1, but 6.41 works as happily as any QL, and a fair bit faster. Thor graphics still seem based on the Tortoise routines GST supplied to Sinclair in 1983; Argos has the CIRCLE bug which is in Lightning and Sinclair ROMs, and recently fixed by Minerva.

Another bug in 6.40 used to crash the Thor if the '!' separator was used by INPUT or PRINT to a non-console channel. I guess the Danes made a mess of picking up CH.WIDTH. Predictably, Turbo and Supercharge have their own way of doing this, so compiled programs are not affected. Thor Basic 6.41 is OK.

Latest bugs
Argos 6.41 has been with us for over a year, and now that the slim resources of Thor International are aimed at 32 bit horizons an imminent upgrade seems unlikely. This makes it important to know the bugs in the latest version, code-named "CS " - the third character is a space.

I am not sure what the "C" stands for, but would hazard a guess that "S" is for "Stuven". The first Thor XVI ROM was version "PT", presumably in honour of David Oliver's secretary and fiancee Penelope Tsatsaris. Early versions of 6.4.1 were version 'PO'; as far as I can tell messages are changed, but not code.

Current Thor XVI systems require version 1.07 of the 32K Eprom that controls the 6802 second processor. This handles the SCSI, network and serial ports, communicating with the main 68000 processor through 8K of static Ram at 68000 address 16744448. The shared ram is faster and more reliable than the serial protocol that links the QL's 68008 to the 8049 co-processor.

All sorts of interesting things are passed in the shared Ram; POKE -30976,VOL sets the DAC volume level used by BEEP, ranging from silent if VOL=128, via quiet at 129 and 130, to a car-alarm level that shakes the metal case, set with POKE -30976,255. IO ROM 1.07 has been current since the device driver upgrade of Argos 6.37.

I got my set of Eproms from Thor International in 1989, but have not been able to contact them recently to check availability. You should note that Danish and UK Thors have different Eprom pin assignments. The QL version used a QEP-3 gimmic to scramble the priorities of signals, simplifying the board layout, but the production engineers swapped address and data lines back to conventional assignments.

Thor International are proud of the Bootmenu program that they supply as a 'front end' to configure the system, but you don't have to use it. It does look nice in Russian, though.

At first the Thor XVI used to crash horribly if Scroll Lock was pressed before the BOOT file was found. Version 6.41 just gets its windows in a muddle, ending up with #0, #1 and #2 all full-sized and overlaid if you press Scroll Lock while the ROMs are initialising. WMON 4 soon sorts that out. The start-up time to initialise 1032K Ram and 188K ROM is about 14.5 seconds.

Another interesting bug cropped up when I loaded Taskforce on the Thor. The program stopped with an error because of the Basic definition of the function SYS_VARS. This over-rides the ROM resident function of the same name, so the command disappears from the Name Table if NEW or LOAD is entered thereafter.

Subsequent Resident procedures and functions in the Name List are re-numbered. This 'feature' means that you can delete resident procedure and functions, by defining them as BASIC, then deleting them. That can be useful, as long as you don't do it by accident!

There is something wrong with the network File Server in the Thor ROM; it works perfectly with the QL serving, but not the other way around. After a while the Thor falls over. I have not been able to try this with two XVIs; it may signal incompatability between the Thor and my version of the QL SuperToolkit ROM, at the other end of the net link.

Be careful not to read big tasks or other binary files into code that expects lines of data, like INPUT or VIEW. Thor Basic goes haywire unless it gets a new-line character before 32K is up. It's easy to end up with negative-length strings and other data-destroying situations, unless you make sure you get an end-of-line character every 32767 bytes.

A similar bug can affect machine code directly, as the SERIO routines get in a mess if asked to perform IO.FLINE for more than 32K. This can cause problems with devices like SER, PAR, MEM and PIPEs. The same bug is true of QL ROMs - the fix would slow down quite a few devices, so it's probably not worth it.
The new DIY Toolkit Qlipboard task avoids this problem.

The Thor has WHEN ERROR code similar to that in "MG" ROMs, but it does not seem to suffer from the serious bug that causes an infinite loop in the SuperBasic interpreter when you try to trap an error inside an expression, on a Sinclair ROM.

The Thor's implementation of 'WHEN Variable' is similar to that in "MG" ROMs. The condition after the WHEN is evaluated whenever an assignment changes the initial variable. WHEN X>5 runs successive statements up to the END WHEN whenever X gets set to a value greater than 5.

There are some limitations. INPUT, READ and other implicit parameter assignments do not activate WHEN. The system fails if 20 or more variables are monitored, like Sinclair ROMs. It works OK with 19, but "6.41" gives Exception 0 at 12F2 when it calls the twentieth block, or attempts to set up a twenty first.

The problem is the set-up code which allocates data for WHEN blocks. QView ace Laurence Reeves explains that space is allocated in lumps from the variable values area; each lump holds the details of up to 20 WHEN blocks, and Sinclair failed to test allocation of the second block.

There's a subtle difference in the way Thor Basic handles PRINT TO, compared with Sinclair systems.

PRINT "x"; TO 1;"y"

gives:

x y

(with a space between the letters) on a QL in SuperBASIC, whereas the revised Thor code prints:

xy

The bug stems from the Danes' ambitious re-write of the awful routine shared by PRINT and INPUT. Thor International had to re-write that code as it's a big, ugly, characteristic monolith. I re-wrote it for Supercharge because I couldn't understand it, and it wouldn't do everything I wanted. I ended up with 22 optional chunks of code in the library of routines the compiler uses to re-express PRINT and INPUT. Tony Tebby says the Sinclair code started life as a debugging routine, intended for sniffing around the Variable Values area.

The problem is that the TO separator always sends at least one space on the QL, as noted on page 58 of Jan Jones' definitive guide. Thor International's code sends nothing at all if the print position already matches the 'TO' parameter. That's quite logical, but not compatible.

This is not a big bug, as Turbo and Supercharge refuse to call either Sinclair's or Dansoft's code for PRINT and INPUT, so compiled tasks work consistently on QL and Thor. However, QLib tasks show the fault, as they always use resident procedure code.

The Thor's new code seems wrong to me, because I find it convenient that TO should separate columns. If the parameter is no more than the current position, one column has probably overflowed, but I still don't want it to run into the next one. I may be biased because Turbo works that way. It's a minor quirk, as long as we all know about it.

The Thor does offer one improvement over QL PRINT and INPUT. It lets you put new channel numbers part-way through a statement, so:

PRINT "Your Name "; : INPUT #0,name$ : PRINT "is ";name$

becomes:

INPUT "Your Name "; #0,name$ #1;" is ";(name$)

The Turbo library can handle this already, if the parser grammar is tweaked to recognise the new syntax. The library forms the majority of CODEGEN_TASK, and hasn't changed since 1987. Despite later parser improvements, it still holds un-tapped library routines and optimisations.

I have dispatched details of Turbo grammar changes that should allow the Thor's extended syntax for CLOSE, COPY, INPUT, PAUSE, PRINT, SDATE and WINDOW. A few other changes will allow similar improvements when programs are compiled on Minerva, but the resultant code may not work on other ROMs, as it might rely on the modified expectations of the resident procedure or function.

Even Supercharge runtimes support multiple channels in a single PRINT or INPUT, but other parameter variations will have to be passed on to the ROM for parsing. Whenever possible, Turbo checks the parameters of ROM and Turbo Toolkit commands while parsing, unlike Q-Liberator or the interpreter.

I believe that the true test of a compiler is how it copes with incorrect programs, so I aim to report potential problems whenever possible. Thus current versions of Turbo spot and reject parameter sequences that would upset Sinclair keywords.

Small changes should allow the new syntax, although programs using it may not work on Sinclair ROMs or emulators. Before the compiler re-compiles itself a separate program reads a textual description of known commands, their separators and parameters. This utility generates DATA statements which are MERGEd into the parser before compilation. The internal 'grammar' allows better checking, saves writing lots of ad hoc code, conserves memory and makes changes easy, if D.P. considers them worthwhile.

6.41 Extras
The Thor has real serial and parallel ports, much better than SER1 and SER2 on the QL. The protocol is now handled in hardware, as on all but the cheapest modern computers, and the SER device name has been extended with many new options, like SER2exb75b1200cf_32K !

The serial ports handle 5 to 8 bits per character, with optional parity generation and checking, XON-XOFF with or without handshaking, seperate input and output baud rates, optional translates and buffering.

The Thor has an extended TRAnslate facility to sort out printer and modem codes. You can specify a prologue or epilogue message up to 32K long, which will be sent when the channel is opened or closed.

Thors are designed for multi-national appeal, and the extensions SET_LANGUAGE and LANGUAGE$ build on TRA, offering ROM messages and display characters in 12 national variations, including British, French, Spanish, German, Greek and Russian.
The collating sequence used by INSTR and case-comparisons is still wrong for Greek and Russian letters, but nowhere near as wrong as it is in British QL roms.

The file transfer commands WCOPY and COPY have been rewritten to make better use of buffer memory, and they can now combine files as well as copy them.

Some Thor improvements are reminicent of Minerva. PAUSE now allows a channel parameter, while SDATE TO accepts a single parameter date, in seconds since 1961.

Some long-standing bugs fixed in Minerva still occur in 6.41. The Thor crashes if you allocate a negative amount of space with ALCHP, use more than 20 WHEN clauses, or try to PRINT "0" & 1/0. Graphics routines have the same bugs as Lightning and early QL ROMs: try CIRCLE 80,80,80,6,1 if you want a laugh!

The XVI emulates KEYROW and IPC calls to the second processor, although BEEP pitches rarely correspond. Thor-specific programs are encouraged to read keyboard data directly - this is much faster and more reliable than MT.IPCOM, which is provided for compatibility with QL tasks.

Two simple but useful functions SYS_VARS and NET_ID reveal the address of the system variables and the net station number. In practice you can find the later with the former, on QL or Thor: NET_ID reads SV.NETNR, like PEEK(SYS_BASE+55). 6.41 fixes one old inaccuracy, which I would hesitate to call a bug; at last COS(PI/2)=0, previously COS(PI/2)==0. Who cares?

SDATE now sets the battery backed clock; the old Thor command SET_CLOCK is still there, but you don't need to use it. NO_CLOCK gets rid of the multi-tasking CLOCK job.

The new function IO_TRAP is a passport to Argos - a variant of the CALL command which lets you pass register values to and from any device, via TRAP #3. I have given a example in recent DIY Toolkit conversion notes. This function is much-needed as undocumented parameters of CLS, PAN and SCROLL are now rejected, whereas they do useful things with cursors and file pointers on Sinclair systems. You can do all these tricks, and more, with IO_TRAP, but you have to change your program to suit the Thor.

The Thor CHR$ function only accepts parameters between 0 and 255. This correction stops CHARSET_BAS, on the Quanta library disk UTIL GEN1, as it tries to print character codes 256 to 259, which the QL happily prints as splodges, and some Minervae render as NUL to F5. Strictly this is a fix for a QL bug which a few programs exploit, but it could be the cause of otherwise inexplicable range errors.

Similarly the Thor's POKE rejects parameters beyond the range -128 to 255, allowing signed or unsigned byte values; the QL just POKEs the least significant byte of the integer supplied. Argos 6.41 limits POKE_W to values from -32768 to 65535, while QLs, Turbo and Supercharge tasks accept any long integer and store the low word.

The revised CSIZE only tests the least significant bit of the vertical size parameter, so CSIZE 2,-32768 has the same effect as CSIZE 2,0. Odd integers select double-height text - you don't get any new sizes.

The Thor's WINDOW allows border width & colour as two optional extra parameters. TOP_WINDOW tells the Thor screen shuffler which window should take precedence; peculiar 'windows', these.

The extra colours in MODE 12 are accessed by passing fractional colours to the Basic commands INK, PAPER and STRIP. INK 7 sets grey ink, and INK 7.5 is white. PAPER 7.25 and PAPER 7.75 select alternate grey and white stipples.

This convention confounds Turbo, which tries to use fast integer arithmetic as much as possible. Turbo minimises interpretation and parameter passing by converting sets of stipple values into composite integer colours, using its own code. This is great for QL MODEs, but means that the fractional part is ignored, even in MODE 12.

Even the Thor uses integers to represent colours internally. Halves and quarters are moved to bits 14 and 15 of D1 before calls to SD.INK or SD.PAPER, so you can use all the MODE 12 colours in compiled programs, as long as you select them with calls to IO_TRAP. This is little hardship as MODE 12 programs are inevitably Thor-specific.

Vintage Choice
This survey confirms that the biggest challenge for would-be ROM improvers is the pressing need for compatability with existing programs. There are two 'best' ROM sets for the Thor XVI: 6.39 and 6.41. If you have 6.40 you need an upgrade; if you use Thor Basic or Qlib you probably already know that! Both my recommendations have some annoying bugs, but they work better than intermediate versions of Argos, and include the vital SCSI improvements.



First published in Sinclair QL Wold magazine, March 1991

Copyright © 1991,2006 Simon N Goodwin. Thanks to Dilwyn Jones for help with the format conversion for online republication of this document.