Classic Computer Magazine Archive A.N.A.L.O.G. ISSUE 63 / AUGUST 1988 / PAGE 46

Printscreen

by Justin E. Wilder

    Often, while a program is running in our computer, it would be handy if we could print the wording or data on the screen. Many programs provide a way to print certain information, but we might want to print some other text which appears on the screen. There are utilities that allow printing from the screen to a printer, but to access them we must stop execution of any program which may be running to give a command such as an immediate USR statement. What we need is the ability to print any text which is displayed, and still continue operation of the program. The PrintScreen utility allows this to be done with a single keystroke.

    The BASIC program in the accompanying listing can be entered and used in either of two ways to set up PrintScreen. (Be sure you save the program to disk or tape before running it, because one of the options clears the program from memory when it is finished.) If you use a disk drive, you may choose to have a binary (machine language) file set up on a disk. This file should have the name PRINTSCN.OBJ and will be loaded into memory with the binary load option of DOS before you run another program. You could also change the name of the PRINTSCN.OBJ file to AUTORUN.SYS (if you do not already have an AUTORUN.SYS file on that disk), and it will be installed in memory when you boot the computer. If you already have an AUTORUN.SYS file, you can probably add the PRINTSCN.OBJ code to the end of it using the COPY with append option of DOS. Be sure to have another copy of your program on disk before trying this in case it does not work properly.
    The BASIC program shown in Listing 1 can also be used to install directly into memory. It's installed as a machinelanguage function in Page 6 of RAM and initialized before the BASIC program is automatically deleted. In this way, you can use this utility whether you have a disk drive or not.
    Once PrintScreen in installed in memory, you can load and run another program. At any time you want a printout of the screen, you can make it by holding the control key and pushing the "?" key. It will work properly only with a Graphics 0 display and if the program does not use Page 6 of memory. Also, if the reset key is pushed, the initialization is lost. From BASIC, you can reinitialize this utility by entering the immediate mode command, which is X=USR(1591).

Be sure you save the
program to disk or tape
before running it,
because one of the
options clears the
program from
memory when it
is finished,

    PrintScreen can be used with any Atari 400, 800, XL or XE computer. It requires any Atari-compatible printer to be properly connected for the printout. Inverse video characters are printed as regular characters and control or graphics characters are represented by a period to avoid conflicts with printer features. Once installed in memory or in a disk file, it does not require BASIC and can be used with machine-language programs as well as BASIC programs.

What makes it work?
    PrintScreen uses the keyboard interrupt vector to get temporary control of the computer when CTRL-? is pushed. It uses memory locations 205, 206 and 207 in addition to the last 201 bytes of Page 6 in RAM. Referring to the assembly language listing, the first part is the initialization section which puts the address of the main routine into the keyboard interrupt vector. The previous contents of this vector are placed in a jump (JMP) instruction to send operation to the keyboard handler if a key other than CTRL-? is pushed. If any I/O operation to a device other than the screen or keyboard is in progress, the CTRL-? key is ignored.
    Before the microprocessor registers X and Y are used, their contents are saved on the hardware stack, so that they can be restored to their previous values before operation is returned to the program which was running when CTRL-? was pushed. The contents of the processor status register and acumulator are already on the stack. The interrupt mask has also been set, and since the input/output (I/O) operation to the printer involves interrupts, the mask must be cleared with a CLI instruction.
    Now, here's the tricky part. The Atari system provides eight I/O Control Blocks, so that up to eight I/O operations can be done at once, right? Wrong! Up to eight files or devices can be open for I/O, but during an actual I/O operation the contents of the associated I/O Control Block are transferred to one block in Page 0 RAM from where control of the operation is maintained. The Atari is thus designed to carry out only one I/O operation at a time. The usual time when a printout of the screen would be requested is when a program is waiting for input from the keyboard. This means that it is in the middle of an I/O to the screen editor. If the screen printing changes the values in the zero page I/O Control Block, they will not be right when the program resumes and the computer will run out of control (lock up). Therefore the contents of the zero page block are saved on the stack before printing the screen, and are restored to their previous values afterward.

If the screen printing
changes the values in
the zero page I/O
Control Block, they will
not be right when the
program resumes, and
the computer will run
out of control,

    The printing operation is carried out in the normal way through the Central I/O routines in ROM. A control block is first opened for output to the printer. The characters in screen memory are then converted to ASCII values and sent to the printer, one line at a time and finally the block is closed. I/O Control Block seven was chosen, because its other uses are in similar open, do and close operations and are not likely to cause any conflict. When the values which had been saved on the stack are returned to their proper places, control is passed back to the original program by a Return from Interrupt (RTI) instruction to continue as though nothing had happened.

Justin E. Wilder, a 1953 graduate of the University of Michigan, is a senior project engineer for Johnson Controls, Inc. He purchased his Atari 800 in 1980, and his Ultimate Renumber Utility was in the Atari Program Exchange. He is a member of the IndianaMichigan Atari Group Exchange (IMAGE) users' group.


LISTING 1: BASIC

KL 10 REM PRINTSCREEN --J.E. Wilder
WQ 11 REM COPYRIGHT 1988
XV 12 REM BY ANALOG COMPUTING
DI 20 REM To print GR.0 screen push CTRL-
   ?
HD 30 DIM AN$(1):PRINT "Set up PRINTSCREE
   N in:"
ZX 40 PRINT "ISK FILE or EMORY";:INPUT
   ANS:IF ANS="M" THEN 80
WA 50 IF ANS<>"D" THEN 40
NA 60 ? "CREATING BINARY FILE":OPEN #1,8,
   0,"D:PRINTSCN.OBJ"
DL 70 FOR X=1 TO 213:READ A:PRINT #1;CHR$
   (A);:NEXT X:END
CO 80 PRINT "INSTALLING PRINTSCREEN IN PA
   GE SIX OF MEMORY.  TO USE PUSH CTRL-?"
ZA 90 RESTORE 110:FOR X=1591 TO 1791:READ
    A:POKE X,A:NEXT X:X=USR(1591):NEW
LD 100 DATA 255,255,55,6,255,6
YY 110 DATA 104,173,8,2,141,97,6,173,9,2
KA 120 DATA 141,98,6,169,79,141,8,2,169,6
LA 130 DATA 141,9,2,96,173,9,210,201,166,
   208
QC 140 DATA 10,165,32,201,6,144,4,201,15,
   144
NG 150 DATA 3,76,0,0,152,72,138,72,162,15
WI 160 DATA 181,32,72,202,16,250,134,32,1
   65,88
UL 170 DATA 133,206,165,89,133,207,169,24
   ,133,205
GT 180 DATA 88,162,112,169,3,157,66,3,169
   ,253
LO 190 DATA 157,68,3,169,3,157,69,3,169,8
   0
XM 200 DATA 141,253,3,169,155,141,254,3,1
   57,72
MD 210 DATA 3,169,8,157,74,3,32,86,228,16
   9
GT 220 DATA 9,157,66,3,160,0,165,205,240,
   37
VG 230 DATA 177,206,41,127,201,123,176,4,
   201,97
UF 240 DATA 176,8,105,32,201,96,144,2,169
   ,46
JY 250 DATA 153,253,3,152,200,192,40,144,
   227,101
PK 260 DATA 206,133,206,144,2,230,207,169
   ,155,153
ZC 270 DATA 253,3,32,86,228,48,4,198,205,
   16
FV 280 DATA 199,169,12,157,66,3,32,86,228
   ,162
MX 290 DATA 0,198,205,134,205,16,140,104,
   149,32
SC 300 DATA 232,224,16,144,248,104,170,10
   4,168,104
ER 310 DATA 64,226,2,227,2,56,6


LISTING 2: ASSEMBLY

10 ;PRINTSCREEN --J.E. Wilder
15 ;COPYRIGHT 1988
16 ;BY ANALOG COMPUTING
20 ;Prints Gr. 0 screen with CTRL-?
30       *=  $0637
40       PLA
50 INIT  LDA $0208   VKEYBD
60       STA EXIT+1
70       LDA $0209
80       STA EXIT+2
90       LDA #INTRPT&255
0100     STA $0208   VKEYBD
0110     LDA #INTRPT/256
0120     STA $0209
0130     RTS
0140 INTRPT LDA 53769 KBCODE
0150     CMP #$A6    CTRL-?
0160     BNE EXIT
0170     LDA 32      Device in use
0180     CMP #6
0190     BCC EXIT    P: or C:
0200     CMP #15
0210     BCC PRINT   E:,S:or K:
0220 EXIT JMP $00
0230 PRINT TYA
0240     PHA
0250     TXA
0260     PHA
0270     LDX #15
0280 SAVE LDA 32,X   Page 0 IOCB
0290     PHA
0300     DEX
0310     BPL SAVE
0320     STX 32     No repeat CTRL-?
0330     LDA 88     Screen Mem
0340     STA 206    Pointer
0350     LDA 89
0360     STA 207
0370     LDA #24
0380     STA 205    Line count
0390     CLI
0400 OPEN LDX #$70   IOCB 7
0410     LDA #3      Open
0420     STA 834,X   Comd
0430     LDA #1021&255 CASBUF
0440     STA 836,X   Buf Adr
0450     LDA #1021/256
0460     STA 837,X
0470     LDA #80     P: Device
0480     STA 1021    CASBUF
0490     LDA #155    EOL
0500     STA 1022
0510     STA 840,X   Buf Len
0520     LDA #8      Output
0530     STA 842,X   AUX1
0540     JSR $E456   CIOV Open
0550     LDA #9      PUT REC
0560     STA 834,X   Cond
0570 NEXT LDY #0
0580     LDA 205     LINE
0590     BEQ EOL
0600 LOOP LDA (206),Y Screen Char
0610     AND #127    No inverse
0620     CMP #123
0630     BCS SHIFT>Z
0640     CMP #97
0650     BCS KEEP    >=a
0660 SHIFT ADC #32   To ASCII
0670     CMP #96
0680     BCC KEEP<=_
0690     LDA #46     Dot-Unprintable
0700 KEEP STA 1021,Y CASBUF
0710     TYA
0720     INY
0730     CPY #40
0740     BCC LOOP
0750     ADC 206     Screen pnter +40
0760     STA 206
0770     BCC *+4
0780     INC 207
0790 EOL LDA #155
0800     STA 1021,Y
0810     JSR $E456   CIOV Print line
0820     BMI ERROR
0830     DEC 205     Line
0840     BPL NEXT
0850 ERROR LDA #12   Close
0860     STA 834,X   Comd
0870     JSR $E456   CIOV
0880     LDX #0
0890     DEC 205     Line
0900     STX 205
0910     BPL OPEN    Clr printer
0920 REFIL PLA
0930     STA 32,X    Page 0 IOCB
0940     INX
8550     CPX #16
0960     BCC REFIL
0970     PLA
0980     TAX
0990     PLA
1000     TAY
1010     PLA
1020     RTI
1030     *=  $02E2 INITAD
1040     .WORD INIT
1050     .END