Click Here To Go To The Your Computer Archive

Written By Fintan Culwin

Cover Art
Click Here To Enlarge Loading Screen

Loading Screen
Click Here To Enlarge Opening Screen

Opening Screen
Click Here To Enlarge Screenshot

Game Screenshot


Fintal Culwin explains a utility written in machine code which will allow ASCII files to be transferred from back store to printer

Professional micros and dedicated word processors have the ability to print a document "in the background", while the machine is actually being used for some other activity. I have always regarded the BBC as a professional machine and have produced this utility which allows ASCII files to be transferred from backing store to printer without causing too many problems for the machine's user.

The routine is written in machine code and assembles into just 253 bytes of memory, allowing it to be fitted into the cassette filing system's reserved page (&OD), or any extra page of memory for the disc system. The code is non-relocatable and will have to be reassembled if its location is to be moved. The routine has been written to Acorn's published standards for adding utilities and should cause no problems for other such systems. Unfortunately it appears to be incompatible with Wordwise. Possibly this is because Wordwise redirects screen output in an unusual way.

Once installed in memory the routine is activated by a call to its load address plus hex lA - &D1C in the page &OD version. It can also be installed on disc and accessed with a * Spool command - see your disc manual. The routine will clear the screen announce itself and await input of the file name and the number of copies.

The spooler will only cope with ASCII files. That is Basic listings which have been EXECed - see user guide page 402 - or text files which have been saved in a formatted state as in Wordwise option 8.

Non-User Friendly

In order to fit the routine into one page of memory some degree of user-friendliness has been sacrificed. The number of copies to be spooled and the name of the file to be spooled have to be given in one command. The first character is interpreted as the number of copies, and the remaining characters up to a maximum of 10 as the filename. The one character determining the number of copies is interpreted by subtracting &30 from its ASCII code. Conveniently this gives one copy for the character "1", two copies for "2" etc. If more than nine copies are required then the alphabetic characters

:; <=>?@ABC ....

onwards have to be used. Not friendly or convenient to use but it did save a few bytes.

For tape users the cassette relay will become active as the CFS - Cassette Filing System - looks to open the file on the tape; this could take some time and would require the tape to be rewound after each copy of the document had been spoiled. For disc users, the file - if it exists - will be opened; otherwise the Spool Error message will be output to the printer.

Once the file has been opened, one character will be sent from the file to the printer every time a character is sent to the screen. If you are not going to be using the micro for a period of time and want the spooling to continue, put in a dummy list or preview command. Spooling will slow the system down. This is especially noticeable for tape users every time an inter-block gap is met. This is not too much of a problem, as whilst spooling the micro can run faster than I can type. After each copy of the document has been spooled, a form-feed will be executed. After the last copy has been spooled the routine will disable itself and can be called again in the same way.

For those who have no wish to delve into the mysteries of the operating system or assembler code then all that needs to be noted about the listing is that the location of the routine is determined by the value of the variable Code in line 190 of the listing. I have used Basic I, the early part of the listing can be simplified by using the EQU assembler commands available in Basic2.

After the spooler has been installed by running the assembler program the utility can be saved directly by using the command: *SAVE"SPOOL" PPPP + FF (PPPP + &27) where PPPP is the hex page address of the code, +FF gives the length of the code and (PPPP + &27) is the execution address hex 27 bytes higher than the value of Code. When assembling into page &00 the first two bytes should be left unused as this area is polled by O.S. 1.2 and the Econet filing system. It is usually safe to start at the beginning of a page in other locations.

Vectored through RAM

The most obvious method to implement such a system would be to use the vectored interrupts of the BBC operating system. The spooler would then act totally independently of the front end of the system. For example, every second tenth of a second or so - which is no good for this application, as the interrupt routine must return within one to two milliseconds. When dealing with peripheral devices, even discs, this time limit cannot be guaranteed and other methods have to be used.

The other method of diverting the micro from its usual path is to use the vectored routines; the two most obvious are the Read character vector and the Write character vector. These are not time critical, and will cope with the long delays of the tape system. Every time the keyboard is read or a character is output to the screen the operating system and any other system which has been correctly written uses OSWRCH for writing and OSRDCH for reading.

The obvious place to put the routine would be via OSRDCH. But this would only send characters to the printer every time a key is pressed - which is slower than if it were every time a character was sent to the screen. The problem with using OSWRCH is that the routine itself should use OSWRCH to send characters to the printer.

Both these routines are vectored through the machine's RAM space, allowing them to be changed. If they exited solely in ROM then any changes would be impossible. By changing the address given in the RAM pan the routine can be redirected to the spool routine before being allowed to continue with its original task.

The code itself is in two pans. I will not give a complete description a the code is annotated. It is in two sections. The first part initialises the system by clearing the screen and then outputting the message pool. It then uses Osword to input the command into its own memory space. The number of copies now stored at location Count is convened from ASCII to absolute. The current channel number is set to zero, the vector stored and the vector set.

The OSWRCH routine vectors through location &20E/&20F usually labelled as WRCHV. The contents of this location are copied to a location labelled Storevect. WRCHV can now be changed to point to our own routine labelled by the variable Entry. With the vector set OSWRCH will indirect to our own routine which will terminate with a jump to the address stored in Storevect.

The initialising routine now returns control to the host system. The next time OSWRCH is used the actual routine which performs the spooling will be activated.

This routine commences by storing the accumulator, X and Y registers on the stack, and terminates by unstacking the information and jumping to the main OSWRCH routine via Storevect. In the interim OSWRCH will have to be used to output characters to the printer. If the vector was still active then it would re-enter the spool routine. 'A recursive situation which would never terminate I, To cope with this the vector is restored after the registers have been stacked and in most cases is set before exit. If the spooling is finished or an error has been detected then the exit is made without setting the vector, leaving the spooler inoperative.

To perform the spooling the routine first establishes if a file is active by examining the current channel number. Zero indicates that a file is not active and any other number should indicate an active file. If no file is active then one is opened, using OSFILE the channel number stored and the document count decremented. If the counter reaches zero then all copies have been spooled and the vector is left unset on exit.

If a file is active then the routine labelled Main will obtain the next character using OSBGET and send it directly to the printer. Error conditions can occur if the file cannot be opened or a character cannot be obtained from the file these are dealt with in the routine labelled Error.

The end of file is determined by OSBGET returning with the accumulator containing &FE and the carry bit set. This causes Channel to be set to zero indicating no file is open and a form feed is sent to the printer.

Errors detected by the spooler will result in the message "Spool Error" being printed by the printer and a form-feed. The spool routine is exited without the vector being set so the spooler is left inactive. Operating system errors are met with the vector reset also and will display an operating system error message.