Copy Link
Add to Bookmark
Report
Ictari Issue 23
ICTARI USER GROUP ISSUE 23 June 1995
___ ______ ___ _________ _________ ___
\__\ \ __\ \ \__ \______ \ \ _____\ \__\
___ \ \ \ __\ _____\ \ \ \ ___
\ \ \ \ \ \ \ ____ \ \ \ \ \
\ \ \ \_____ \ \____ \ \__\ \ \ \ \ \
\ \ \ \ \ \ \ \ \ \ \ \
\__\ \_______\ \______\ \________\ \__\ \__\
* m a g a z i n e *
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I C T A R I U S E R G R O U P
63 Woolsbridge Road, Ringwood, Hants, BH24 2LX Tel. 01425-474415
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
INDEX FOR ISSUE 23
==================
ASSEMBLY Overscan routines.
STE 8 way hardware scrolling routines.
Blitter routines using A line $0007 call.
C Tim Oren GEM Tutorial. Part 12. GEM Events.
Replacement standard library functions with Alcyon C.
GFA Hi Rez format program.
Library Creator for GFA programmers.
STOS Menu Shell code.
Screen saver code.
STOS Extension selector.
MISC GDOS information file.
Character conversion tables (in Protext format).
Current membership list.
In next months issue of ICTARI (this may change) :-
ASSEMBLY Floating Point routines.
C Bouncing Ball demo program.
Tim Oren GEM Tutorial. Part 13. GEM Events.
GFA Formatting program.
STOS Variable to string converter code.
MISC Chain program.
Using the Atari clipboard.
---------------------------------------------------------------------
EDITORIAL
=========
UNIVERSAL PRINTER DRIVER
------------------------
The response to my proposal for a Universal Printer Driver has been
pretty underwhelming, only two members expressed any support for the
idea. Anyway, I still think it will be useful so I am going to
continue with the project in the hope that some more members will
help out later. I have included a draft specification for the Printer
Driver at the end of this document, please let me know if you have
any comments. Perhaps all members could check their own printers to
see if the Printer Driver facilities will cater for their printer and
let me know if there should be any amendments to the specs, if you
don't tell me what you want don't blame me if you can't use your
printer with it when it is the established standard.
CHARACTER CONVERSION
--------------------
Please note that we have left the Character Conversion article from
Mrten Lindstrm in Protext format since it contains a lot of non-
standard characters which may not display correctly on some text
editors.
---------------------------------------------------------------------
CORRESPONDENCE
==============
To: *.*
From: Martyn Wells
Hi there, can anybody help me with a routine to print in colour on
a Star LC-240C 24 pin colour printer. I can print graphics OK in mono
but can't get them to print in colour. I normally program in GFA
Basic but any code in another language would be OK.
*/ Perhaps you could send us a copy of the Star printer manual (just
the graphics printing section). ICTARI /*
---------------------------------------------------------------------
To: ICTARI
From: Raymond Reid
The idea for the printer program is good, will try and sort out
various sources for this if I can get time.
---------------------------------------------------------------------
To: ICTARI
From: Simon Rigby
ATTENTION ALL (SPEEDO)GDOS PROGRAMMERS!
***AS FAR AS I KNOW, THIS INFORMATION IS NOT AVAILABLE IN ANY BOOK***
The new breed of printer drivers have a button on the CPX panel that
dictates whether or not the driver has Print Area Offsets. What this
means in English is that if this button is set to On, V_opnwk will
return the size of the Page in pixels, NOT the Printable Area. If
your program uses this value (as most will) to find the maximum
number of pixels to print to, then you will find that some of your
image will be lost in the non-printable area. If Print Area Offsets
are turned off, then v_opnwk will return the correct printable area.
SOLUTIONS TO PROGRAMMERS
The big question is:-
How can I tell whether v_opnwk returns the true printable area or the
page size?
The answer is that vq_extnd has been extended to do just this:
The extra extended enquire values are :-
intout(19) = 1 for Print Area Offsets ON , else 0
ptsout(0) = Top Left X Co-ord of Printable Area
ptsout(1) = Top Left Y Co-ord of Printable Area
ptsout(2) = Bottom Right X Co-ord of Printable Area
ptsout(3) = Bottom Right Y Co-ord of Printable Area
ptsout(4) = 0
ptsout(5) = ? - I think it is print buffer size but don't
know
To: Steve Gale
Please find included an article on the clipboard format. I hope it
helps. */ See next month. ICTARI /*
To: Tony Harris
The LineA functions are still available on the Falcon and do still
work in ST compatible modes. They actually work in most other modes
too, but there are a couple of functions that fall apart in some
Falcon specific modes (get/putpix as I recall, but don't take my word
for that). All STE's/STFM's that DO NOT have special graphics cards
on them will work with LineA.
I'm beginning to wish my books were accessible (in the attic while we
decorate!) but what you need to do is find the TimerB interrupt
priority and make it a higher priority than the mouse/keyboard
interrupt.
To: Terry King
The Form_dial only redraws the screen if the area covered is less
than a quarter of the screen size (and sometimes not then). What it
does do is to send window redraw messages to anything it covered. If
that is the desktop, the desktop redraws its window (#0) which puts
the green background on your screen. I assume that you are not using
windows, so you are not processing redraw requests.
Your slider code does not appear to take account of the width of the
slider button, which should make your total travel (slider width -
button width). It should travel with its left edge from 0 to (slider
width-button width-1).
PRINTER DRIVERS
---------------
I will be commenting on your printer driver text in the order that I
come across things, so this will be best read alongside the original
article. In a simple world, it would be straightforward to do text
attributes for the printer fonts. However, most printers have access
to a number of internal fonts and some of these are proportional or
scaleable. This means that the driver must know the width of each
letter to know how much it can get on each line. Selecting bold,
italic, etc can change the width of each letter. Are you seriously
thinking of holding font width information for all printer fonts
within its driver? How do you pass internal font information to the
application. How does the application show it (if at all)?
Graphics routines are a fair bit easier, in my view, and I have only
come across a limited number of ways of sending image data to a
printer. Microline spacing is not as simple as you make out, however,
as to print on a 9-pin at 216 dpi (vertically) you send bytes made up
of eight scan lines each spaced 3 lines apart (i.e. the data is
interleaved) requiring 3 passes per 24 scan lines, each pass one dot
lower than the last and a 21/216 linefeed at the end of each 3 lines.
I think resolution (and aspect ratio) should be passed to the
application on opening the driver in the form of X-dpi and Y-dpi (is
there any application that doesn't use dpi? GDOS uses microns but
could be converted from the info given.) I also think that a
universal printer driver should be able to have a GDOS driver (even
if it is only used as a means of passing image data to the printer).
The only printers I know of are mono, RGB, CYM & CYMK. If screens are
to be viewed as a form of printer, we get more complicated. The most
common are mono and CYM(K). Colour should be represented on mono
printers as brightness levels.
As far as I know, only HP use compressed data streams. Certainly,
none of the Epson modes compress data. The only compression that
could be applied is not to send empty tails on scanlines.
I would envisage a printer driver to work on two levels; the printer
driver itself would have an open (get-info), close (free-resources)
and send-data (pixel/line/block of lines) routines. It should tie
into a higher level set of routines similar to GDOS for graphic text,
line drawing & image printing. The way that GDOS works is for the
driver to look like a program (without any mshrink, etc) and it is
loaded in by a pexec but not run. The program is then run like a sub-
routine by repeatedly calling it with d0 containing the op-code (like
any VDI routine). Only Text is handled by calls back into GDOS
itself.
Please note that 9-pin require up to 24 lines per pass. 24-pin
require up to 48 lines. I think that printer codes should use
[esc][control-code][...][esc] if you are going to use text, allowing
the full range of ASCII codes. [esc][esc] should be used to send the
[esc] code to the printer.
I personally think that an extension or alternative to GDOS is a
better way forward and do not think ASCII and graphics can easily be
mixed on the same page. I think graphics output only is the
reasonable approach to take.
I should also warn you that I looked at the wider problems of this
and left it as a backburner problem (although some code was written
and tested).
I wish you luck and will be glad to provide any routines you require.
*/ I think that any utility program which calls itself Universal has
to be a compromise to greater or lesser extent. As you say it is very
difficult to combine text printing and graphics images in a
comprehensive way such as a DTP program would do. I think the best
that we could achieve is a mixture of both in much the same way as
First Word Plus did, that is some text followed by an image (if that
is what the programmer wants). If a programmer wanted to make a true
DTP style program then the text would have to be formatted as bit
mapped images (using Calamus fonts maybe, ICTARI 20) and printed
entirely in graphics mode. Regarding font sizes, as you will see from
the article at the end of this document, I only intended using the
printers internal character set (albeit at a number of different
pitches) for text only type print-outs. If the programmer wants to
use a much wider range of character sizes he would again have to use
graphics modes and construct a bit image to be printed. I would
certainly be interested in the colour printing modes you mentioned
although if the programmer allows the end user to print a colour
image on a monochrome printer I think it is his responsibility to
render the colours into black and white shading rather than the
printer driver program. Some of your other observations may be
answered by the article later, please send any further comments in
when you have studied it. PDH /*
---------------------------------------------------------------------
To: Terry King
From: Mrten Lindstrm
RESTORING THE SCREEN WITH FORM_DIAL
-----------------------------------
All that FORM_DIAL(3, ...) does is to issue redraw requests to the
GEM process(es) responsible for the piece of screen in question.
And a GEM application isn't considered to be responsible for anything
else than the contents of windows opened by it. Everything else is
handled by the screen manager of the AES, which will do the desktop,
menu and any window borders. (The green box that you get is probably
simply a piece of desktop that the screen manager tries to
"restore".)
I thus suspect that your (or another?) program is using the screen
without having opened a (well-behaved) AES window onto it.
(After you have defined and opened a window with WIND_CREATE and
WIND_OPEN you must wait for window-related messages with EVNT_MULTI
(or EVNT_MESAG) or in GFA Basic you might alternatively use the "ON
MENU" command, which I assume makes an internal call of EVNT_MULTI.
Every time you get the redraw message (20) for a window you should
redraw the contents of the window concerned - see more about this
below.)
Alert boxes, on the other hand, are evidently physically saving and
restoring the used screen memory rather than using FORM_DIAL calls
for their restore, and this method could, of course, be used in your
own customised routines too. The advantage is not only that you may
make non-window output work (which shouldn't be used in a 100% clean
program anyway) but that you gain speed as well. The drawback is that
it requires memory. (I think alert boxes use the same internal memory
buffer as used by menu dropboxes.) A solution for a clean program is
to allocate memory only when it's needed for the save and free it
afterwards - calling FORM_DIAL when there isn't enough memory. The
100% clean way of saving/restoring image blocks is with the VDI call
VRO_CPYFM (or in GFA Basic terms BITBLT with THREE parameters).
By the way: FORM_DIAL(0, ...) should always be used before a code
section after which you intend to use FORM_DIAL(3, ...) to tidy up,
but this is purely for future compatibility reasons. (I could imagine
these calls in the future to cause the screen to be actually saved
and restored to/from a secret memory space.) Presently FORM_DIAL(0,
...) performs no function at all and thus cannot be the cause of your
problem.
UPDATING PARTIALLY COVERED WINDOWS
----------------------------------
Updating a window that is partially covered by other windows isn't
really much more difficult than updating a topped (completely
uncovered) window.
There is no need to keep track of the positions and extents of
windows and which ones are covering which, since the AES will do all
that for you.
The secret is WIND_GET with modes 11 and 12 which will give you all
visible rectangles of a window. (If the window is topped there will
be only one rectangle, and if completely covered there will be none
of course.) When you get a rectangle with both width and height = 0,
this means there aren't any more visible rectangles to draw.
For each rectangle you get, you should normally first set a VDI
clipping rectangle according to it (with VS_CLIP or in GFA Basic:
CLIP), before drawing. Neglecting this might earn you some speed
though you must then of course be certain that you don't draw outside
the rectangle.
If the updating is to be done in response to a redraw message (which
may, for instance, have been caused by a FORM_DIAL(3, ...) from
someone then in order to cut down on the drawing work you should,
before drawing each visible rectangle, calculate its intersection
with the redraw area given with the redraw message. (There even seems
to be a GFA Basic command RC_INTERSECT for this.)
I think a window updating routine in GFA Basic should look something
like this (though the variables I've called handle and x,y,w,h could
more efficiently be renamed handle& and x&,y&,w&,h& for GFA Basic
WORD format):
~WIND_UPDATE(1) ! Request permission from the AES to start drawing
~GRAF_MOUSE(256,0) ! Hide mouse to avoid corrupting drawing
~WIND_GET(handle,11,x,y,w,h) ! Get first visible rectangle
WHILE w OR h <> 0
' If in response to redraw msg. insert intersection calculation here.
CLIP x,y,w,h !Other languages require coordinate conversion to VDI
' Do the drawing here
WIND_GET(handle,12,x,y,w,h) ! Get next visible rectangle
WEND
~GRAF_MOUSE(257,0) ! Show mouse
~WIND_UPDATE(0) ! Allow other processes access to screen again
For the drawing itself to turn out right, you need of course to know
the coordinates not only of the visible rectangle but of the window
itself, which you may get from WIND_GET(handle,4,x,y,w,h) (for the
work area i.e. excluding borders). In fact you can, as long as you
are using VDI for output, completely disregard the visible rectangle
and always draw as if on the full window area, since the clipping
will make sure that only the visible rectangle is affected. For
faster output you may have to make some calculations to determine
what and where there actually needs to be drawn in the particular
visible rectangle.
NOTE: In a well-behaved GEM program ANY window updating routine is
REQUIRED to cope with partially covered windows.
CAN THE MEMORY OF A RESIDENT PROGRAM BE FREED?
----------------------------------------------
The answer to this question is generally NO. As far as GEMDOS is
concerned a program and its memory is completely and utterly gone as
soon as PTERMRES has been executed.
Under MiNT however, a would-be resident program could - as an
alternative to PTERMRES - start a background child process making use
of the same memory as itself and then terminate itself with PTERM.
I have no personal experience of MiNT but have an article on this by
Julian Reschke in the German "ST Magazin" 3/93. If somebody is
interested I could possibly try to get more details out of the C
source given with this article, but the general idea is to use PEXEC
with modes 5 and (MiNT specific) 104 to reserve a basepage for and
launch the child without waiting for its return.
The child should set the stack pointer and then go about its business
such as redirecting vectors (cleanly with use of XBRA protocol and
SETEXC) etc. Finally it should use (the MiNT call) Psignal to set a
termination routine for the SIGTERM (=15) signal, mask out all other
signals with Psigsetmask(L:1<<15) and start waiting with (the MiNT
call) Pause() for its termination.
The termination routine of the child could for instance try to
restore any redirected vectors and exit with PTERM if this succeeds
or PTERMRES if it fails (because some jerk has messed with the
vectors without using XBRA).
To: Mark Baker
Thank you very much for your info and example on how to use the MiNT
"_CLP" semaphore to avoid clashes on the clipboard. This is something
that so far had completely escaped me. When looking into the Atari
Compendium I furthermore found it very brief indeed on the subject of
MiNT semaphores, describing how to use them alright but not what for,
and not naming a single system defined semaphore.
Are there perhaps other standard MiNT semaphores - such as "_PRN" and
"_AUX" to avoid clashes on the printer and serial device?
I imagine that MiNT (or MultiTOS) isn't used by more than a tiny
fraction of today's TOS users (or even of Falcon users perhaps?), I
personally haven't really got the computer for it yet, and I have
zero experience of actually programming for it. But on the other
hand, if I - by squeezing in the odd MiNT call - can make my code
slightly more future-proof and compatible this is something I very
much would like to do.
Your idea - to write any internal memory clipboard buffer to the GEM
disk clipboard each time a program is ended or its window untopped
(which I assume means when it is receiving a WM_UNTOPPED (=30) window
message, or perhaps also if/when it is "bottoming" or iconifying a
window?) - is excellent I think. If the program maintains a "dirty
flag" for the internal memory buffer (set when the internal buffer is
updated and cleared when the disk clipboard is) so that it can avoid
unnecessary disk accesses, then I cannot see why everybody shouldn't
use it whenever a memory buffer is implemented. I still think there
may be a point in offering exclusive use of the disk-based clipboard,
through a "Use clipboard" toggle menu option, or/and a one-shot
"Update clipboard" option for those (us) who are using the old AES
which never sends any WM_UNTOPPED.
To: *.*
As Mark Baker could tell in Ictari 22, clashes during clipboard
accesses can possibly be avoided by the following MiNT calls:
In C:
-----
Psemaphore(2,'_CLP',-1); /* Request access to Clipboard ! */
/* Access here */
Psemaphore(3,'_CLP',0); /* Clipboard free for others to use */
I find this such a useful piece of knowledge that I (with the help of
the Atari Compendium) immediately made the translations of this into
assembler and GFA Basic, which I would like to share:
In assembler:
-------------
pea -1.W ; ( Wait indefinitely )
move.l #'_CLP',-(SP) ; Request access to Clipboard !
move.l #$1340002,-(SP) ; ( Psemaphore, mode 2 )
trap #1
lea 12(SP),SP
* Access here
clr.l -(SP) ; ( Dummy longword )
move.l #'_CLP',-(SP) ; Clipboard free for others to use
move.l #$1340003,-(SP) ; ( Psemaphore, mode 3 )
trap #1
lea 12(SP),SP
And in GFA Basic:
-----------------
~GEMDOS(308,2,L:CVL("_CLP"),L:-1) ! Request access to Clipboard !
' Access here
~GEMDOS(308,3,L:CVL("_CLP"),L:0) ! Clipboard free for others to use
NOTE: The above calls will work only under MiNT but I can see no real
harm in just making them and hope there is someone there who will
understand them. The old TOS will simply return a -32 = "Invalid
function number" and no harm will have been done.
(If you absolutely have to know that MiNT is there to react on the
calls, you should check for the presence of a "MiNT" cookie and, if
you are really paranoid, that the value (long) of the cookie is ò $92
- for MiNT v0.92+. That would bypass the theoretical problem of a
GEMDOS extension other than MiNT intruding on the MiNT function
numbers, but this is something that only an old and obsolete system
would do, since MiNT is THE official successor of GEMDOS and any
future extensions will have to build from there.)
To: *.*
PICPAC - THE NEXT GENERATION
----------------------------
I have now added GIF and TIFF unpacking to my PICPAC assembler
library and adapted it to be usable with GFA Basic too. But I am
convinced it must be possible to use with other languages as well. (I
noticed that there was an interest among Ictari C programmers for an
IMG packing routine.)
Since my ST programming experience is more or less limited to
assembler and GFA Basic, however, I have refrained from dabbling with
bindings for C or anything else. I merely send in the source for an
object file to be linked with C or other programs, plus info on the
format of the calls, and I very much hope that someone will be able
to make something out of that, perhaps comparing and translating the
GFA Basic bindings.
The PICPAC routines are tailored for use in clean GEM programs (but
with supplementary routines for non-GEM use) and can presently:-
PACK - IMG (including XIMG colour) and IFF ILBM (uncompressed,
Packbits compressed OR vertical word compressed).
UNPACK -ditto (plus HyperPaint IMG) plus GIF, TIFF, Degas and NEO.
The GIF and TIFF routines also sort palettes of 256 colours
to be (more or less) usable on ST screens with 16 colours.
CONVERT between palette formats: 24-bit, VDI and ST(E) hardware.
Associated routines given with the assembler and GFA Basic
bindings can set and get palettes cleanly under GEM and
translate palette indexes to VDI pen number on any palette
colour screen, also with graphics cards.
I would be very grateful indeed for any views and comments on this.
How well does it work. What functions are missing, etc.
THE 'BEST' PICTURE FILE FORMAT
------------------------------
By the way, I hope that no-one has become too excited about the LZW
compression used in GIF and TIFF. It is a very clever little
compression scheme indeed, amazingly good at compressing simple
pictures such as maps and charts (and the LZW unpacking code in
itself not taking up much space either; it is only a minor part of my
GIF and TIFF routines). But LZW is not all that impressive with near-
photographic images, which I think are the most common type among GIF
and TIFF images. I even came across one or two LZW-compressed 256-
colour images LARGER than when uncompressed - something much less
likely to occur with the simpler compression types of IMG and IFF
ILBM. The "Deluxe Paint IFF" vertical word compression in particular,
comes close if not beating GIF/TIFF LZW with most "normal" images.
Unpacking of GIF and TIFF unavoidably also takes more space and time
than of the image formats native to the ST (and Amiga).
So, in short, be happy with IMG or IFF ILBM! (Except for the purpose
of importing PC images.)
*/ The articles mentioned above will be published in later issues of
ICTARI. /*
---------------------------------------------------------------------
To : All
From: Paul Pickering
If any of the members would like to make regular contacts with me by
letter to swap ideas, tips and advice on software and hardware they
would be most welcome. Also if any members have any ST Format
Magazine issues Nos 1 to 58 with disks I could copy or buy or swap
please contact me. My name and address is listed in the MEMBERS.TXT
file. I also have some software I would like to swap or sell. I have
listed them below.
Another World #5 inc P&P or swap for Lemmings
Pirates #5 inc P&P or swap for Cruise for a Corpse
Dragons Of Flame #3 inc P&P or swap for GemView (PD)
Flames Of Freedom #5 inc P&P or swap for Thunderhawk AH-73M
Gods #5 inc P&P or swap for F-29 Retaliator
Hero Quest #5 inc P&P or swap for DEVPAC or GFA Basic
Maupiti Island #5 inc P&P or swap for Super Space Invaders
Panza Kick Boxing #3 inc P&P or swap for 3D Pool
Populous II #5 inc P&P or swap for Stereo Master
Rick Dangerous #3 inc P&P or swap Atari ST 3D Graphics
Strider II #3 inc P&P all three Programming by Braun
Terminator 2 #3 inc P&P for book
Indiana Jones #3 inc P&P or swap Musical Applications
Moonwalker #3 inc P&P both for of the Atari ST'S
Their Finest Hour #5 inc P&P or swap for Streetfighter 1 or 2
The Killing Cloud #5 inc P&P or swap for Your second Manual
To the Atari ST
(book or disc)
---------------------------------------------------------------------
To: *.*
From: J Chapman, 95 Heathfield Rd, Ferndown, Dorset, BH22 0DE.
Tel. 01202 895613
For Sale :-
Atari 520 STFM with 1Mb, Seikosha 9 pin printer, Colour Monitor/TV
Software- Timeworks, Flexidump, Protext, IMPrint.
Books- 'Your Second Manual' + disk, 'Get the best from your ST'
Mag disks-ST Format cover disks + PD, Clip Art, etc
150 or near offer for the lot.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
UNIVERSAL PRINTER DRIVER
========================
DRAFT SPECIFICATION
-------------------
GENERAL
-------
The object of the Universal Printer Driver (UPD) is to allow
programmers to write a program which requires a printed output (text
or graphics) without having to write their own printer code, the UPD
program handles all printing operations. This makes writing printer
dependent applications much easier and has the big advantage that the
program will then work with any type of printer providing a printer
driver text file has been written for the printer concerned.
UPD PROGRAM
-----------
The UPD system consists of two main parts, the UPD program itself and
a Printer Driver Text file for the printer being used. The UPD
program is a machine code program which is supplied as a pre-
assembled binary file (UPD_V100.BIN) and is 'included' in the
programmers code using one of two methods. The simplest way for
example, in a machine code program is to simply include the binary
file at the 'upd_driver' label with the 'incbin' pseudo-op :-
upd_driver incbin UPD_V100.BIN
For other computer languages a similar method will be required. The
second method is to allocate a RAM buffer and make the applications
program load the UPD_V100.BIN file from disk at start up time in the
same way as a Resource file is loaded. This method is slightly more
involved but has the advantage that if a later version of the UPD
program is issued, the end user can use it by substituting the new
program for the old one on disk.
When the user application is up and running, the program should ask
the program user to load in a Printer Driver Text file which is
appropriate for the printer he/she is about to use. The program
should load the driver file into a temporary buffer and then call the
UPD routine in Initialise mode. The UPD code scans the text file and
builds a table in RAM which holds the graphics information and text
attribute control code strings. The routine returns with the address
of this table in register d0 which can then be used by the main
program, when required. The Printer Driver Text file data in the
temporary buffer can then be discarded as it is no longer needed by
the UPD program.
Access to the UPD code is similar to the GEM system, any parameters
are pushed onto the stack and the UPD code called as a sub-routine
using the label at the buffer address. An error code (if applicable)
is returned in register d0. For example, using the machine code case
shown above, a typical call would be as follows :-
move.l #$0200,-(sp) ;reset code
move #UPD_TEXT,-(sp) ;text mode
bsr upd_driver ;call S/R
add #6,sp ;correct stk
tst.l d0 ;chk error ?
bmi error ;bra if error
...
The UPD routine has just the one entry point (the label
'upd_driver'), the required function is passed to the code along with
any other parameters via the stack. At present there are six basic
functions which are described below with their associated parameters
as follows :-
Value Mnemonic Parameter_1 Parameter_2 Function
0 UPD_INIT Driver_addr UPD_file_addr Initialise
1 UPD_TEXT Value+Control Send text
2 UPD_SGM Length+Rez Start graphic
3 UPD_SGD Graph_addr Send graphics
4 UPD_EGM End graphics
5 UPD_DELAY Period Set delay
A brief description of each function is shown below.
INITIALISATION
--------------
When the UPD program and the Printer Driver Text files have been
loaded into memory the UPD code should first be initialised. The UPD
program scans the UPD program code itself and relocates any absolute
addresses in the code using the 'upd_driver' address as the base
address which is passed to it as the second parameter. It then
generates a look up table in RAM which it uses to access the graphics
and text attribute strings whenever data is passed to the printer.
The RAM buffer for the look up table is allocated using the GEM
function Malloc so the application program should make sure that
there is sufficient RAM left in the TPA for this buffer. If there
were no errors the routine returns with the address of the look up
table in register d0 which should be stored by the applications
program for later use. In machine code, the initialisation call would
look like this :-
move.l #upd_file,-(sp) ;address of text file
move.l #upd_driver,-(sp) ;address of pgm code
move #UPD_INIT,-(sp) ;Initialise code
bsr upd_driver ;execute
add #10,sp ;correct stack
tst.l d0 ;chk for error
bmi error ;branch if error
move.l d0,upd_buff ;save upd table addr
...
where #UPD_INIT equals 0.
#upd_driver is the address of the UPD driver program.
#upd_file is the address of the UPD text file.
If another printer driver is to be used, the RAM for the first
printer should first be freed by using the GEM Mfree call with the
address stored in 'upd_buff'. Also, when the program is exited, the
RAM should first be freed.
The layout of the look up table is described in more detail below.
TEXT ATTRIBUTES
---------------
When the UPD code has been initialised, text characters, text
attributes or graphics data can be printed out via the UPD routine.
To send a normal text character to the printer the character code is
pushed on the stack and the routine called in a similar way to the
GEM Bconout function. The main difference is that a long word is used
to store the data to make the code easier to use. The character
should be stored in the low word and any additional values are stored
in the high word (see later for more details). For example, to output
the letter 'A' to the printer use the following code :-
move.l #'A',-(sp) ;chr A
move #UPD_TEXT,-(sp) ;text mode
bsr upd_driver ;execute
add #6,sp ;correct stk
tst.l d0 ;chk error
bmi error ;bra if error
...
The character code should be in the range 0-255 ($00-$FF) with bits
8-15 set to zero. The high word (bits 16-31) are ignored for normal
output of text characters. The character code is passed on to the
printer port without any further processing with the Bconout BIOS
function using Device No 0 (parallel port).
To output a text attribute code to the printer, use the same code
except that all attribute codes are in the range $0200-$FF00. For
example, to start underline mode in machine code use the following
code :-
move.l #$1800,-(sp) ;Underline on
move #UPD_TEXT,-(sp) ;text mode
bsr upd_driver ;execute
add #6,sp ;correct stk
tst.l d0 ;chk error
bmi error ;bra if error
...
Although it is not absolutely necessary to check for an error
condition every time the routine is called, it is advisable because
if the printer should go off-line during a printing session, some
printed data could be lost.
The high bits of the data longword sent to the printer can be used,
for some attributes, as an additional value. For example, the Print
Multiple Copies (PMC) attribute (used mainly on Laser printers) also
requires a numeric value for the number of copies to be printed.
Obviously this value cannot be stored in the Printer Driver Text file
so it is passed to the printer by the program together with the PMC
attribute code. In the Printer Driver Text file, the control codes
include a hash (#) character which tells the UPD code to use the
additional value in the high word of the attribute code. For example,
the PMC code in the Printer Driver Text file will be stored as
follows :-
PMC=27,38,108,#,88 ;Print multiple copies
To use this particular attribute a typical machine code program would
look like this :-
move #5,d0 ;5 copies
swap d0 ;move to high
move #$1E00,d0 ;PMC code
move.l d0,-(sp) ;Send code
move #UPD_TEXT,-(sp) ;text mode
bsr upd_driver ;execute
add #6,sp ;correct stk
tst.l d0 ;chk error
bmi error ;bra if error
...
The UPD code will send the codes 27,38,108,5,88 to the printer and
then return.
The complete list of current attribute codes is shown below, see
later for graphics modes.
HEX ATTR FUNCTIONS
CODE CODE
0200 RES Reset printer
0400 BLD1 Bold text enable
0600 BLD0 Bold text disable
0800 ITA1 Italics text enable
0A00 ITA0 Italics text disable
0C00 PPT1 Proportional text enable
0E00 PPT0 Proportional text disable
1000 SUB1 Subscript text enable
1200 SUB0 Subscript text disable
1400 SUP1 Superscript text enable
1600 SUP0 Superscript text disable
1800 ULN1 Underline text enable
1A00 ULN0 Underline text disable
1C00 CPB Clear printer buffer
1E00 PMC Print multiple copies #
2000 UNI1 Unidirectional printing on
2200 UNI0 Unidirectional printing off
2400 LP6 Print 6 lines per inch
2600 LP8 Print 8 lines per inch
2800 C05 Print 5 chars per inch
2A00 C06 Print 6 chars per inch
2C00 C09 Print 9.5 chars per inch
2E00 C10 Print 10 chars per inch
3000 C12 Print 12 chars per inch
3200 C15 Print 15 chars per inch
3400 C17 Print 17 chars per inch
3600 C20 Print 20 chars per inch
3800 NLQ1 Near Letter Quality enable
3A00 NLQ0 Near Letter Quality disable
3C00 GR0 Graphics resolution group 0
3E00 GR1 Graphics resolution group 1
4000 GR2 Graphics resolution group 2
4200 GR3 Graphics resolution group 3
4400 GR4 Graphics resolution group 4
4600 GR5 Graphics resolution group 5
4800 GR6 Graphics resolution group 6
4A00 GR7 Graphics resolution group 7
4C00 MF0 MicroLine feed group 0
4E00 MF1 MicroLine feed group 1
5000 MF2 MicroLine feed group 2
5200 MF3 MicroLine feed group 3
5400 MF4 MicroLine feed group 4
5600 MF5 MicroLine feed group 5
5800 MF6 MicroLine feed group 6
5A00 MF7 MicroLine feed group 7
5C00 COL Select colour code #
5E00 HLF Half Line Feed
GRAPHICS MODES
--------------
The graphics system has been designed to be as simple as possible for
the programmer. All the programmer needs to do is to construct the
image to be printed in a suitable RAM buffer and then send the data
to the printer via the UPD one raster line at a time. The UPD code
will convert the data into a suitable format for the printer and pass
it on to the printer in the correct format.
The graphics control codes are arranged in three functions, Start
Graphics Mode, Send Graphics Data and End Graphics Mode. To send a
graphics bit image to the printer the image should first be
constructed in a buffer of which the width (in bytes) and the height
(in scan lines) is known. For example, to print the screen image in
standard monochrome mode the width would be 80 bytes and the height
400 scan lines. To print the image the applications program should
first determine the printer resolution required which will, of
course, depend on the resolutions available in the printer. The
resolutions available can be obtained from the look up table which
has been built by the UPD program (see below for table layout).
To start graphics mode the Start Graphics Mode (SGM) control code is
first sent to the UPD routine together with the resolution code and
the width of the bit image in bytes. Assuming that an image on the
high rez screen is to be printed at printer resolution group 1 for a
HP LaserJet printer the call in machine code would look like this :-
move #80,d0 ;80 bytes
swap d0 ;move to high
move #1,d0 ;Rez group 1
move.l d0,-(sp) ;Send data
move #UPD_SGM,-(sp) ;SGM mode
bsr upd_driver ;execute
add #6,sp ;correct stk
tst.l d0 ;chk error
bmi error ;bra if error
...
The width of the image in bytes is placed in the high word of
register d0 and the resolution of the printer is placed in the low
word. The resolution code is a value between 0 and 7 and defines the
printing resolution of the printer. For example, in the HP LaserJet 3
driver shown below there are four possible resolutions, 75*75,
100*100, 150*150 and 300*300 dpi which are defined as groups 0, 1, 2
and 3 with the codes GM0, GM1, GM2 and GM3. By using a resolution
group code of 1 the applications program is telling the printer to
print the image at 100*100 dpi. In this example, since our image is
640 pixels wide by 400 pixels high, the printed image will be 6.4"
wide by 4" high. Since these figures can be read from the look up
table, the applications program can determine what size the images
will be and format the image data accordingly.
The SGM function also determines the type of graphics printing being
used which is defined by the graphics ident code which immediately
follows the GM code in the printer driver text file. For example, in
the HP Laser driver the ident code is 51 which defines the HP
LaserJet method of printing. Each type of printer has its own code as
shown below :-
1 9 pin Epson mode.
2 9 pin Microline mode.
11 16 pin Epson mode.
21 24 pin Epson mode.
31 48 pin Canon BJ mode.
41 HP InkJet mode.
51 HP LaserJet mode.
As can be seen from the codes there are plenty of spare codes which
may be added at a later date for any other types of graphics printing
modes. The SGM function also allocates some memory (with Malloc) from
the TPA as a temporary image buffer store. The programmer should
ensure that some RAM is still available to the UPD code when graphics
images are being printed. The actual amount needed varies with the
type of printer being used. HP Laser/InkJet printers use least and 48
pin printers need most because for 9/16/24/48 pin printers the single
raster lines are stored in the buffer until enough have been stored
to be output to the printer.
It is essential in this case to check for an error on return from
this function to make sure that there is sufficient memory available,
that the graphics mode is valid and that the printer is on line.
To output the image to the printer, the applications program sets a
pointer to the start of the image and then calls the Send Graphics
Data (SGD) function for each raster line. For example, to send the
screen image to the printer the following code would be used :-
move.l #screen_addr,a0 ;fetch addr
move #400-1,d1 ;400 lines
loop move.l a0,-(sp) ;Send addr
move #UPD_SGD,-(sp) ;SGD mode
bsr upd_driver ;execute
add #6,sp ;correct stk
tst.l d0 ;chk error
bmi error ;bra if error
add #80,a0 ;next line
dbra d1,loop ;repeat
...
When the complete image has been sent to the printer (or if the print
has been aborted because an error was detected) the End Graphics Mode
(EGM) function must be used. This function resets various stores and
releases the temporary memory buffer that was allocated in the TPA. A
typical example is as follows :-
move #UPD_EGM,-(sp) ;EGM mode
bsr upd_driver ;execute
add #2,sp ;correct stk
tst.l d0 ;chk error
bmi error ;bra if error
...
These three functions make the printing of graphics images very easy
for the programmer, the only difficult part is generating the images
in the first place at the required resolutions.
PRINTER ON-LINE DELAY
---------------------
Within the UPD program code the text/graphics data is output to the
printer via the GEM Bconout function using the parallel port (Device
Number 0). Before each value is sent to the port the Bcostat function
is called to check whether the printer is on line. If it is not on-
line the output is suspended and a delay period is started. If the
delay period expires with the printer still off-line, the routine
returns an error code in register d0.
Since this delay period can cause problems for some printers with or
without internal printer buffers, it can be changed from within the
applications program with the UPD_DELAY function. The delay is based
on the Vsync BIOS function and so will vary slightly depending on the
type of monitor being used (because of the different frame sync
periods). It defaults to approximately 40 seconds for a TV and about
28 seconds when used in Hi Rez monochrome mode which corresponds to a
value of 2000. To change the delay period the Delay function is
called with a value in the range 1-4000 as follows :-
move.l #200,-(sp) ;200 * Vsync
move #UPD_DELAY,-(sp) ;DELAY mode
bsr upd_driver ;execute
add #6,sp ;correct stk
tst.l d0 ;chk error
bmi error ;bra if error
...
The printer is normally sent to Device Number 0 (parallel port),
however the applications program may want to send the data to the
serial port (or even the screen). This can be done by changing the
Device Number which is stored in the UPD look-up table at offset 48
as shown in the look up table below.
PRINTER DRIVER TEXT FILE
------------------------
The Printer Driver Text (PDT) file itself is an ASCII text file which
can be written using most text editors such as Mortimer, Harlekin,
etc. The file information consists of a number of three letter
mnemonics followed by an 'equals' sign and then the appropriate
control codes. The attribute definitions can be placed anywhere in
the text file but all letters must be in capitals. Any numeric value
may be written in decimal or hexadecimal notation. Decimal numbers
may have any number of digits and hexadecimal values must have one or
two digits and be preceded by a dollar sign. For example the
following values are all valid :-
10, 0010, $A, $0A
Two typical attribute definitions could be written as follows :-
LP6=27,38,108,54,68 ;6 Lines/inch
LP8=$1B,$26,$6C,$38,$44 ;8 Lines/inch
which defines the codes for setting the printer to print six and
eight lines to the inch. LP6/LP8 are the mnemonics and the decimal or
hex codes follow the 'equals' sign, each code being separated by a
comma (actually almost any non-alphanumeric character will do). The
semicolon denotes an optional comment, all text after the semicolon
is ignored. Space characters ($20), tab characters ($09) and linefeed
characters ($0A) are ignored by the UPD program when the text file is
processed. A Carriage Return character ($0D) must terminate each line
and a NUL character ($00) must terminate the file.
The list of text attributes is more or less similar to the list shown
above with the following exceptions. In order to simplify the PDT
file a bit any attributes which operate in pairs are written on the
same line and separated by a 'colon'. For example, the BOLD type
attribute is written as :-
BLD=27,40,115,51,66 : 27,40,115,48,66 ;Bold on/off
The first group of codes turns the function on and the second group
turns the same function off and is equivalent to the attribute codes
BLD1 and BLD0 respectively. The only other 'reserved' symbol used in
these text files is the hash sign (#) which is used to denote that a
numeric value is passed to the UPD routine when the function is
invoked. For example, on some printers a colour code can be sent to
the printer to start printing in colour. This would be written down
as follows :-
COL=27,114,# ;Colour code
When this function is used the PDT file will supply the control codes
and the applications program will provide the colour number as
described earlier.
In addition to the text attributes listed above there are a number of
other codes which can (and in some cases must) be used in a PDT file.
These are as follows :-
UPD=1
This code identifies the text file as a valid Printer Driver Text
file and must be present somewhere in the file. The number following
the equals sign should be the digit 1 to denote version 1 of the UPD
program. This value may be used at a later date to differentiate
between later versions of the UPD program. If the UPD code is not
present the driver will return with an error code during the
initialisation phase.
PTS='string'
This code defines the Printer Title String and is followed by an
ASCII string within single quotes which gives the full title/name of
the printer. The string can be any length but should be limited to
less than 35 characters and could be used by the applications
program to display a full description of the printer on screen
when the file has been loaded.
GCM=2
Some modern HP printers can receive graphics data into the printer in
compressed mode which speeds up the data transfer. If the printer
supports this option this code is included in the PDT file followed
by the compression code used. At present only mode 2 (TIFF) is
supported by the UPD program although other modes may be added later.
GM0-GM7
These codes define which graphics modes and resolutions are available
in the printer, a maximum of eight can be used. Most printers allow
more than one graphics resolution and some printers can even print in
different graphics modes, i.e. 8 pin, 24 pin and 48 pin. Obviously
the UPD program has to know which resolution is to be used and which
graphics mode it needs to use. This group of codes defines the mode
and resolutions (in dpi) that are available.
For example, the Canon BJ300 Ink Jet printer can simulate 9 pin, 24
pin and 48 pin graphics at various resolutions, the Graphics Modes
would be written like this :-
GM0=1,120*72 ;120*72 dpi, 8 pin
GM1=1,240*72 ;240*72 dpi, 8 pin
GM2=21,180*180 ;180*180 dpi, 24 pin
GM3=21,360*180 ;360*180 dpi, 24 pin
GM4=31,120*360 ;120*360 dpi, 48 pin
GM5=31,180*360 ;180*360 dpi, 48 pin
GM6=31,240*360 ;240*360 dpi, 48 pin
GM7=31,360*360 ;360*360 dpi, 48 pin
The graphics modes (1, 21 and 31) are stored in the look up table and
are used by the UPD program to determine the method of sending
graphics data to the printer. The resolutions (120*72, 240*72, etc)
are also stored in the look up table and although these values are
not used by the UPD program, they are available to the applications
program which can find out what graphics resolutions can be used and
from that, what size any image will be when printed out. To print a
graphics image the applications program will first choose a
resolution code from the list (usually one which has the x and y axes
the same such as 180*180 or 360*360) and uses the associated GM code
(say 2 or 7 for 180*180 or 360*360).
GR0-GR7
In addition to the GM codes above, there are also a similar group of
Graphics Resolution codes (GR0-GR7) which define the actual control
codes required for each graphics resolution. There must be a GR code
for each GM code and they define the control codes used for the
corresponding graphics mode usually followed by a hash which
indicates the data stream for dot matrix printers. Laser and InkJet
printers are slightly different, in this case the codes will define
the graphics resolution codes (see two examples below).
MF0-MF7
For dot matrix printers it is necessary to move the print carriage
down a number of microlines after each line of graphics is printed so
that the image is continuous in the vertical axis. Since these may be
different for different resolutions, there is a MicrolineFeed code
for each resolution (MF0-MF7). HP Laser and InkJet printers do not
need this facility and so they can be omitted for these printers.
Two typical Printer Driver Text files are shown below.
Typical Printer Driver text file for a Laser printer.
---------------------------------------------------------------------
UPD=1 ;Version 1
PTS='HP LaserJet 3' ;Printer type
GM0=51,75*75 ;75*75 dpi
GM1=51,100*100 ;100*100 dpi
GM2=51,150*150 ;150*150 dpi
GM3=51,300*300 ;300*300 dpi
GCM=2 ;Compression mode 2
RES=27,69 ;Reset
BLD=27,40,115,51,66 : 27,40,115,48,66 ;Bold on/off
ITA=27,40,115,49,83 : 27,40,115,48,83 ;Italics on/off
PPT=27,40,115,49,80 : 27,40,115,48,80 ;Proportional on/off
SUB=27,38,97,43,48,46,50,53,82 : 27,38,97,45,48,46,50,53,82 ;Subscr
SUP=27,38,97,45,48,46,50,53,82 : 27,38,97,43,48,46,50,53,82 ;Super
ULN=27,38,100,48,68 : 27,38,100,64 ;Underline on/off
PMC=27,38,108,#,88 ;Print multiple copies
LP6=27,38,108,54,68 ;6 Lines/inch
LP8=27,38,108,56,68 ;8 Lines/inch
C10=27,38,107,48,83 ;10 cpi
C12=27,38,107,52,83 ;12 cpi
C17=27,38,107,50,83 ;16.67 cpi
GR0=27,42,116,55,53,82 ;75*75 dpi
GR1=27,42,116,49,48,48,82 ;100*100 dpi
GR2=27,42,116,49,53,48,82 ;150*150 dpi
GR3=27,42,116,51,48,48,82 ;300*300 dpi
HLF=26,61 ;Half Line Feed
---------------------------------------------------------------------
Typical Printer Driver text file for a 24pin printer.
---------------------------------------------------------------------
UPD=1 ;Version 1
PTS='Epson LQ2500 24 pin' ;Printer type
GM0=21,60*180
GM1=21,120*180
GM2=21,90*180
GM3=21,180*180
GM4=21,360*180
RES=27,64 ;Reset
BLD=27,69 : 27,70 ;Bold
ITA=27,52 : 27,53 ;Italics
PPT=27,112,1 : 27,112,0 ;Proportional
SUB=27,83,1 : 27,84 ;Subscript
SUP=27,83,0 : 27,84 ;Superscript
ULN=27,45,1 : 27,45,0 ;Underline
NLQ=27,120,1 : 27,120,0 ;NLQ
UNI=27,85,1 : 27,85,0 ;Unidirectional
LP8=27,48 ;8 Lines/inch
LP6=27,50 ;6
Lines/inch
C05=27,87,0,18,27,80,27,87,1 ;5 cpi
C06=27,87,0,18,27,77,27,87,1 ;6 cpi
C10=27,87,0,18,27,80 ;10 cpi
C12=27,87,0,18,27,77 ;12 cpi
C15=27,87,0,18,27,103 ;15 cpi
C17=27,87,0,18,27,80,15 ;17 cpi
C20=27,87,0,18,27,77,15 ;20 cpi
GR0=27,42,32,# ;60*180 dpi
GR1=27,42,33,# ;120*180 dpi
GR2=27,42,38,# ;90*180 dpi
GR3=27,42,39,# ;180*180 dpi
GR4=27,42,40,# ;360*180 dpi
MF0=27,51,24 ;Microfeed 24*180"
MF1=27,51,24 ;Microfeed 24*180"
MF2=27,51,24 ;Microfeed 24*180"
MF3=27,51,24 ;Microfeed 24*180"
MF4=27,51,24 ;Microfeed 24*180"
---------------------------------------------------------------------
UPD LOOK UP TABLE
-----------------
When the UPD program is first initialised it scans the PDT file and
generates a look-up table in a memory buffer in which it stores all
the relevant information required to print text and graphics data.
The start address of this table is returned by the UPD routine and
should be stored for later use. The applications program can then
read the data from the table to find the printer name, determine what
graphics resolutions are available, which text attributes are
available, etc.
The table is made up of three sections, section 1 holds miscellaneous
information, section 2 holds a list of offset values for each of the
text/graphics attributes and section 3 holds the control strings for
each attribute. The table layout is shown below with a (very) brief
description of each store, later documentation will go into more
detail on this.
Offset from Store Ref Function.
start address. size.
Section 1. Miscellaneous control information.
0 W - Offset to section 2.
2 W PTS Offset to Printer Title String.
4 B GM0 Graphics Group Mode 0
5 B GM1 Graphics Group Mode 1
6 B GM2 Graphics Group Mode 2
7 B GM3 Graphics Group Mode 3
8 B GM4 Graphics Group Mode 4
9 B GM5 Graphics Group Mode 5
10 B GM6 Graphics Group Mode 6
11 B GM7 Graphics Group Mode 7
12 L GM0 Graphics Resolution Group 0 x*y
16 L GM1 Graphics Resolution Group 1 x*y
20 L GM2 Graphics Resolution Group 2 x*y
24 L GM3 Graphics Resolution Group 3 x*y
28 L GM4 Graphics Resolution Group 4 x*y
32 L GM5 Graphics Resolution Group 5 x*y
36 L GM6 Graphics Resolution Group 6 x*y
40 L GM7 Graphics Resolution Group 7 x*y
44 W GCM Graphics Compression Mode (0 or 2)
46 W UPD Printer Driver Version code (1)
48 W - Output Device Number (0)
50 W - Printer Off-line delay period (2000)
52 W - }
54 W - }
56 W - }Spare
58 W - }
Section 2. Attribute stores.
Each store contains a 16 bit offset value (from the start address of
the file) to the associated control code string in section 3. If a
store contains zero, the attribute is not supported by the printer.
0 W - Not used
2 W RES Reset printer
4 W BLD1 Bold text enable
6 W BLD0 Bold text disable
8 W ITA1 Italics text enable
10 W ITA0 Italics text disable
12 W PPT1 Proportional text enable
14 W PPT0 Proportional text disable
16 W SUB1 Subscript text enable
18 W SUB0 Subscript text disable
20 W SUP1 Superscript text enable
22 W SUP0 Superscript text disable
24 W ULN1 Underline text enable
26 W ULN0 Underline text disable
28 W CPB Clear printer buffer
30 W PMC Print multiple copies #
32 W UNI1 Unidirectional printing on
34 W UNI0 Unidirectional printing off
36 W LP6 Print 6 lines per inch
38 W LP8 Print 8 lines per inch
40 W C05 Print 5 chars per inch
42 W C06 Print 6 chars per inch
44 W C09 Print 9.5 chars per inch
46 W C10 Print 10 chars per inch
48 W C12 Print 12 chars per inch
50 W C15 Print 15 chars per inch
52 W C17 Print 17 chars per inch
54 W C20 Print 20 chars per inch
56 W NLQ1 Near Letter Quality enable
58 W NLQ0 Near Letter Quality disable
60 W GR0 Graphics resolution group 0
62 W GR1 Graphics resolution group 1
64 W GR2 Graphics resolution group 2
66 W GR3 Graphics resolution group 3
68 W GR4 Graphics resolution group 4
70 W GR5 Graphics resolution group 5
72 W GR6 Graphics resolution group 6
74 W GR7 Graphics resolution group 7
76 W MF0 MicroLine feed group 0
78 W MF1 MicroLine feed group 1
80 W MF2 MicroLine feed group 2
82 W MF3 MicroLine feed group 3
84 W MF4 MicroLine feed group 4
86 W MF5 MicroLine feed group 5
88 W MF6 MicroLine feed group 6
90 W MF7 MicroLine feed group 7
92 W COL Select colour code #
94 W HLF Half Line Feed
96 W - Spare
98 W - Spare
Section 3. Control code strings.
This section consists of a group of control code strings, the first
byte of each string defines the length of the string minus one. The
strings for each attribute may be in any order depending on where
they are situated in the PDT file.
100 B 05,1B,3E,4D,44,97,A0
107 B 03, etc, etc, etc
The exact size of the table will, of course, depend on how many
attributes are used and how long the control code strings are.
ERROR CODES
-----------
When any UPD function is called the routine normally returns a value
of zero in register d0 (except for the initialisation function which
returns the look-up table start address). If an error is detected, a
negative error code is returned in d0 as shown below :-
-101 Invalid printer driver text file.
-102 Printer off-line.
-103 Invalid function code.
-104 Unused attribute code.
-105 Invalid attribute code.
-106 Insufficient RAM available or invalid address.
-107 Graphics mode not initialised correctly.
-108 Mismatch on multiple codes.
-109 Graphics mode already initialised.
-110 Invalid resolution requested.
-111 Invalid printer off-line delay period requested.
More details of these error codes will be published in future
documentation.
CONCLUSION
----------
The above notes are a brief description of the work I have done on
the Printer Driver so far. I have written the code to handle the
facilities listed and successfully tried the program out with several
dot matrix and Laser printers in machine code. When the program has
been finalised I will (with the help of some members I hope) provide
examples in other languages, i.e. C, GFA, STOS, Modula 2, Pascal and
Basic.
I have also written a test program which prints a test print of each
attribute and graphics mode at all available resolutions. One notable
omission from the current version is colour. I don't know how modern
ink jet colour printers work so if you want that option added, please
let me know how to do it or at least how colour printers work. I
could be wrong but I suspect that dot matrix colour printers would
not be capable of printing 'proper' colour pictures. When the test
program is complete I will put it on a future disk so that each
member can write a driver file for their own printer/s.
Also I have not taken into account any foreign (non English) users. I
would assume that a printer working in a non English speaking country
would already be set up to print the extra characters and so no
changes would need to be made to the driver code. One possible
exception could be the resolution definitions, presumably in Europe
these are defined as dots per centimetre.
If you have any comments on these notes please let me know as soon as
possible, I would like to finalise to code as quickly as possible and
issue it 'officially'. PDH.
------------------------------ End of file --------------------------