PROP-PRINT  v.1.0      Roelof Koning  1989
----------------------------------------------------------
User manual.
converted to RTF file 2002, as is.

PROPPRINT consists of a number of routines that are ment to extend
the normal printcapacities of the Spectrum. PROPPRINT emulates a.o. 
a non-existing command like: 
PRINT WINDOW 3; AT 2,2; INK 4; FONT 5; CSIZE 7; PAPER 7; "Hallo" 

In this version v.1.0 such commands are given by POKEing certain 
addresses and the printing of certain characters (CHR$ <32) to # 3. 
Example:
POKE 61270,3                          ( choose 3rd defined window) 
PRINT #3; CHR$ 3; CHR$ 160; "text"    ( font 160, =bold italics)
PRINT #3; CHR$ 2; CHR$ 6;"text"       ( csize 6,  =40 char/line)

The demo program shows what the PROPPRINT code can do for a programmer 
in BASIC. You only need to CLEAR 60935, load the code block 60936,4600 
and start your program with the initialising lines as given below.
Please note that propprint is born from the wish to test a piece of code
that finally just should reside in ROM and be connected to KEYWORDS. So 
the BASIC part of the implimentation presented here is rather crude and
just ment as motor for a demo. 

PROPPRINT uses the printerchannel 'P' at # 3. Normal 'PRINT' commands 
still use the normal screenchannel "S", while any 'PRINT # 3;' command 
will send the text via the PROPPRINT routines also to the screen but in  
a  different and more powerfull way.
The output-address of 'P', normally 2548, should be changed  to 60936, which
is the entrypoint of PROPPRINT. This 'vector' is held in the Spectrum 
system variables, in the 'CHANS' (channels) table.

Each program that uses PROPPRINT, should contain the next lines
in BASIC, and have these RUN first.

      LET adr = 15 +  PEEK 23631 + 256* PEEK 23632
      POKE adr,8 :POKE adr+1,238

The PROPPRINT address is inserted by these pokes, and for as long as
channel addresses are not changed by interfaces etc., this situation stays. 
The ZX-printer can't be used anymore, nor can a printer connected 
via DIScIPLE. But COPY, (COPY  SCREEN$) should still work with that IF.
SPECTRUM 128 uses the printerbuffer, (in 128 mode), this space
is  also  used  by  this  version  of  PROPPRINT,  so  use   the
SPECTRUM-128 only in 48-mode when using PROPPRINT.

PROPPRINT can print to 16 different user defined windows, nr. 0 -15, 
which have to be defined by POKEs into a table. Each window consists
of a number of character-positions of 8*8 pixels.
The "current" window, the window to which printing (into #3) is send,
must be chosen by POKING the window nr. to address 61270.
I.e. POKE 61270,0  chooses window 0 to print to.

Windows  must  be   defined   by   POKEs   into   a   'window-
information-table' before they can be used. This POKEing should be 
done carefully, as  PROPPRINT, as it is now, does not check on correct 
parameters. 
See also the routine at line 7000 in the demo program.

The WINDOW-INFORMATION-TABLE consists of 16 blocks of 16
adresses each. The first block is for window 0, the second for
window 1 etc.
  The first byte of each block is used as flag. When this adress
contains 255, then the parameters in the block are invalid, the
window is considered not defined. Any other number signals
"valid information". PROPPRINT tests this flag, before printing
to a window.

The addresses of the blocks are:

61000    Start param.block window 0
61016    -  -  -  -  -     window 1
61032    -  -  -  -  -     windos 2
61048    -  -  -  -  -     window 3
61064    -  -  -  -  -     window 4
61080    -  -  -  -  -     window 5
61096    -  -  -  -  -     windos 6
61112    -  -  -  -  -     window 7
61128    -  -  -  -  -     window 8
61144    -  -  -  -  -     window 9
61160    -  -  -  -  -     window 10
61176    -  -  -  -  -     window 11
61192    -  -  -  -  -     window 12
61208    -  -  -  -  -     window 13
61224    -  -  -  -  -     window 14
61240    -  -  -  -  -     window 15

  Inside each block the addresses have the following meaning:

Start + 0:   Valid/invalid flag         (255= invalid window)
      + 1:   not  used
      + 2:     ~    ~
      + 3:     ~    ~
      + 4:     ~    ~
      + 5:   Topline of window          (0 - 21)
      + 6:   left Column of window      (0 - 31)
      + 7:   hor. printcoordinate (xpos)  in pixels
      + 8:   vert. printcoordinate (ypos) in pixels
      + 9:   height of window, in Lines
      +10:   width of window, in Columns
      +11:   character-width in pixels,    (3 - 15)
      +12:   "font"nr. (heigth en shape)
      +13:   used for var. 'flags'          ( 0 )
      +14:   scrollcounter                  ( 1 )
      +15:   not used.

  A window should fit on the screen, so height and width must be
chosen so that added to  Topline  an  Leftcolumn,  they  do  not
exceed the max. screenvalues (22 and 32).
  The PRINTCOORDINATES xpos en ypos are startpositions, i.e. the
topleft corner of a window. These must be pixelpositions!
               xpos : 8 * leftcolumn
               ypos : 175 - (8 * topline)

"FONT" nr. : The contents of this address  is  checked  by  the
program bit by bit. It is simple  to poke a binary value here,
using the function BIN  ........  (8 bits)
The meaning of each bit:
   00......   : char. height = 1      (lines)
   01......   :     ~        = 2
   10......   :     ~        = 3
   11......   :     ~        = 4
   ..0.....   : wait for key when scroll is needed.
   ..1.....   : scrolls automaticly, no message
   ...00000   : normal  character shape
   ...1....   : strange          (see these for yourselves)
   ....1...   : shadowed
   .....1..   : double strike
   ......1.   : enhanced
   .......1   : italics

Any combination of bits is allowed, so any number between 0
and 255 can be poked.

Another way to change the "FONT" is to print a control character 
followed by the FONTNR. byte. This control character is chr$ 3.
  PRINT # 3;CHR$3;CHR$ BIN 10000001 ;"text"  - will print "text"
in italics , 3 * 8 pixels in size.
You cannot change the 'scroll-flag'-bit in this way, this flag
has his own controlcharacter, see the CONTROLCHAR table.
Changing of CHARACTER-WIDTH is also  possible  with  use  of  a
controlchar, chr$ 2.
  PRINT # 3;CHR$2;CHR$6;"text" - will print "text" in characters
6 pixels width.
Please remember to end printstatements with a semicolon if no
linefeed is wanted.

CONTROL-CHARACTERS
------------------
CHR$ 0 : This controlcode should be followed by 8 CHR$'s
         representing pixelpatterns. These patterns will be put
         on screen, in an UDGlike manner.
CHR$ 1 : This code should be followed by 9 CHR$'s, the last 8
         the same as at CHR$0, the first containing the ATTR-
            byte for the screenposition.
CHR$ 2 : One CHR$ should follow, representing CHAR.-width in
            in pixels.
CHR$ 3 : One CHR$ should follow,representing "FONT"nr.
CHR$ 4 : Wait for key when 'SCROLL?' appears.
CHR$ 5 : Scroll automaticly when window is full.
CHR$ 6 : Move printposition halfway window on line.(comma)
CHR$ 7 : Draw box/frame (around window).
CHR$ 8 : Move printpos. 1 char. to the left
CHR$ 9 :  ~     ~        ~     ~       right
CHR$ 10:  ~     ~      1 line down (use charheight)
CHR$ 11:  ~     ~         ~    up  (no charheight)
CHR$ 12: Delete char.
CHR$ 13t/m 29 : As usual, see SPECTRUM manual.
                Exeption: CHR$ 21, 'OVER'
               PROPPRINT always uses 'OVER 1'!
CHR$ 30 : clear window, move printpos. to topleftcorner.
CHR$ 31 : MENU-choice, see further.

CHR$ 0 en 1 can be used to construct a 'GRAPHIC' of a certain
size, and print this graphic in one go to the screen. An easy
way for doing so is putting the codes in a string.
An example:        (a figure of 16 * 16 pixels)
    10 LET g$="": RESTORE 100
    20 FOR f=1 TO 41
    30 READ a: LET g$=g$+ CHR$ a:
    40 NEXT f
    50 PRINT #3;g$
    100 DATA 0         :REM controlcode
    110 DATA 255,255,255,255,255,255,255,255  :REM 8 patterns
    120 DATA 1,184     :REM control + ATTRbyte (= FLASH)
    130 DATA 255,255,255,255,255,255,255,255  :REM 8 patterns
    140 DATA 10,8,8    :REM next line, left two times
    150 DATA 0         :REM controlcode
    160 DATA 255,255,255,255,255,255,255,255  :REM 8 patterns
    170 DATA 1,56      :REM controlcode +ATTRbyte
    180 DATA 255,255,255,255,255,255,255,255  :REM 8 patterns

Take notice of the position-controlcodes in line 140!
In this example is a characterwidth of 8 pixels assumed.
PROPPRINT can also handle GET-screens made with BetaBAsic.

MENUCHOICE
After printing a CHR$ 31, a 'menu-cursor' appears in the
current window,  in a different color. You can move this cursor
up and down (inside the window) using the cursorkeys.
When ENTER is pressed, the cursor stays put, and the number of
the chosen line (inside the window) can be fetched from address
61271. (PEEK 61271)
The value for the top-line of the window is 1, as value zero
is returned when 'DELETE' (CAPs + 0) was pressed. This means
no choice has been made. Should the window be cleared at that 
moment then a CHR$ 30 has to be printed, with semicolon.
In this way it should be very easy to make menudriven programs.
Example :     100 PRINT #3;CHR$ 30;"choice1"'"choice2"'"etc."
              110 PRINT #3;CHR$ 31;
              110 GO TO 1000 + 100* PEEK 61271
              1000  no choice made
              1100  choice1
              1200  choice2
              1300  etc.

UDG's and GRAPHICS.
These also are put onto screen by PROPPRINT, with this
restriction, that when using the small char.widths, not all
eigth bits are used (shown).
For your own small UDGs, use only the bits marked '-'.
Character Width 3 : 0---0000
                4 : ----0000
                5 : -----000
                6 : ------00
                7 : 0-------
For UDGs and characters more than 6 pixels wide, PROPPRINT uses
the tables of which the adresses are found in de Systemvariables
UDG and CHARS. LOADing of new charactersets is possible in the
usual way, as long as any new char.set does not overwrite the
PROPPRINT-code.
For characters of widths 3 t/m 6 there are special tables
inside PROPPRINT, of which the adresses are:
   3 & 4 : 63000 length 768
       5 : 63768 ~ ~
       6 : 64536 ~ ~

PAPER, INK, BRIGHT, FLASH, INVERSE
PROPPRINT uses the standard SPECTRUM systemvariables, so all
methods in printing colours will work as usual.
In this way it seemed not possible to have each window
remember his own ATTRs. So a change of 'current window' should
go together with a change of current colours. At least when the
'new' window should use different colours.
As known, on the SPECTRUM the ATTRIBUTEs go by character squares, 
so when using char.widths > 8, it may occur that not every 
ATTRIBUTE-file-adress is 'touched'. Using the background
colours when printing might prevent this.
A typical SPECTRUM feature is, that the BORDERcolour is used
when printing to #3 using the 'LPRINT' command instead of PRINT #3.

The DISCIPLE-interface reclaims the 'P'channel (#3) every
interrupt, when told so by POKE@ 11,0. When using PROPPRINT this
reclaiming  is  not  allowed,  so  POKE@  11,1  before   loading
PROPPRINT. Another small problem with DISCIPLE is that it uses
register IX without  restoring  the  contents.  So  to  make  it
possible to say 'CAT  #3;1',  a  DISCIPLE-version  of  PROPPRINT
should start with PUSH IX, en end with POP IX before RET.

*********************  end  ***********************************