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 ***********************************