|★ CODING ★ LISTINGS ★ Dump routine for the 464 and Brother 1009 printer ★|
|Screen Dump: Routine for the 464 and Brother 1009 Printer|Popular Computing Weekly)||Coding Listings|
A machine code screen dump routine for the 464 and Brother 1009 printer by John Durst
When you have a dot-matrix printer connected to the Centronics port of your Amstrad, one of the things you almost certainly will want to do, is to print out the contents of the monitor screen; to do a "Screen Dump". In the ordinary way this is not directly possible - as can be done with the old ZX printer "Copy" command on the Spectrum. But almost any combination of printer and computer can be persuaded to execute a Screen Dump with the help of a short machine code routine.
The problem in every case is that of scanning the display file, so as to read the pixels that make it up, and then present these pixels to the printer in a form which it can deal with and transfer to paper.
Most dot-matrix printers have a "Graphic" option. sometimes called "Dot Image". In this mode, instead of printing out a complete character (which is usually a matrix of 8 columns by 8 vertical lines) it prints just a single vertical line for each byte input. The dot arrangement corresponds to the binary value of the byte, so that a byte containing "0001 1000" Binary will print out as a vertical line consisting of three blank spaces with two dots below them, followed by another three blanks. The software problem is to arrange to scan the screen (of the display file) in groups of eight vertical bits at a time and feed them in succession to the printer.
The thing that makes this not altogether straightforward, is the fact that display files store the information about the screen in horizontal lines of pixels; we have to arrange to sample the corresponding pixels in eight successive lines of the display file, and combine them into a byte to be output to the printer.
So far all this applies in general terms to all screen dump routines. But the Amstrad 464 has a further complication: bytes output to the printer ignore bit No 7, so instead of being able to send the complete depth of a character on every pass, you can only send a maximum of 7/8 of a character. In fact, because 7/8 is an awkward fraction, it is easier to implement the routine if it deals with just six lines of pixels on each pass - 3/4 of a character.
The Display File of the 464 - in common with most display files - is set out in an horrific address system; things don't follow one another at all as you might expect. Next door pixels are not necessarily m next door bytes and pixels above, or below, are not always in bytes the same distance from one another. The coward's way out is to make use of a ROM routine called "Scr Dot Position", which delivers the correct display file address in return for the X and Y co-ordinates of the screen pixel. This is fairly slow, as it means re-calculating the address for each pixel from
scratch, but it is very convenient, as it also returns the "pixel mask", which extracts the bits which code for the Ink in the pixel -something else which dodges about confusingly - as well as altering with the Mode in use.
So the technique is to get the co-ordinates of the first screen pixel (starting at top left), call the routine "Dot Position, find whether the pixel is set for Pen, or Paper and store the answer in the form of a set bit for a Pen Ink. or a reset bit for Paper. Then move the coordinates down one pixel - and store it too. Do this for six vertical pixels and output the composite result to the printer. After this, the routine moves on to the next horizontal pixel and does the same for that set of six vertical pixels . . . and so on through the whole display file.
The program shown generates the code for the routine. If you wanted to use an Epson printer, you would have to change Line 120 to "12,10,27,75,64,1,0,0". Also, the counter byte on Line 20. six position from the end - at present "7". should be changed to "6".
To use the program, Call #9000. You could set up an RSX command, "Copy", but I don't see much point. It involves extra coding - and you are much more likely to want to use the routine in the course of a program, to print out some piece of graphics. In that case you would have some line like; 1000 a$=lnkey$:IF a$="C" Then Call &9000.
One last word of caution: always reset the printer, by switching it off and on. after you have used the routine. The print-out is likely to end with the printer still in Graphics mode when it will garble the next bytes it receives including a "Reset" command!