Classic Computer Magazine Archive COMPUTE! ISSUE 30 / NOVEMBER 1982 / PAGE 202

PET: Picture Files

Elizabeth Deal
Malvern, PA

A routine for Upgrade and 4.0 BASIC (except 4.0, 40-column model) PETs that saves screen images on disk and has other application.

PET knows four types of disk files. It's time we add another, except that it really isn't new – just a program file under a new name. The set of subroutines in the listing shows a way to use a disk as a storage device for screen images. The routine is for Upgrade PET. Conversions to BASIC 4 (80 column) are coded in.

The save/load method described here need not be limited to the screen; it can handle any area of memory. This opens up some interesting possibilities for BASIC, without touching machine code directly.

At present, if you or your children have ever wanted to save a picture from the screen onto a disk file, and bring it back by pressing one shifted key, then this routine is just for you. We use it as an instant subroutine with Power (Professional Software), but it can be used without Power. The code shows bare-bones essentials. You can customize it for your hardware setup or for different applications.

The Mechanics

The lines that actually do the work are 330-500. The code is a translation into BASIC from the machine language monitor save and load routines, which here function as such. The save command is particularly powerful, in that from within BASIC we can easily save any area of memory.

The subroutine in lines 330–500 needs only this information:

  1. device number (DV)
  2. file name FL$
  3. address of file name; pointer in 68/69 gives address for 218/219
  4. length of file name.
  5. start (S1-S2) and end (S3/S4) addresses for writing.

The picture files are program files, quick and compact. Code conversion is not needed. Characters in reverse, quotes, commas, colons, and other such nasties cause us no problem whatsoever. Loading does not cause a change in BASIC pointers, and, since it does not cause the automatic execution from the first line of text, you don't have to code around that issue.

Disk errors do not cause any problems. The curious necessity of pressing a STOP key in the event of FILE NOT FOUND condition has been eliminated (line 460). The message prints by itself if file does not exist, hence this code is more feasible for use within a program than the semi-direct Power-mode, a necessity for users without Power.

I have hard coded device 8 and drive 1. Most of you have interrogation routines on the demo disk; they can make the setup more flexible. The program does ask for a file name and permits you to gracefully get out (type X) before any disk activity takes place. Limit your input to 12 characters, and be careful not to push cursor-down and clear-screen during input. Once again, existing get/input routines are a neater solution.

Cautions

Do not change the business part of the program without first understanding it.

Screen images, if loaded via an ordinary LOAD command by mistake, cause a crash. For that reason, files saved by my routine have a clearly visible "P." (for picture) prefix. This overcomes the only (I think) dangerous feature of the program. If you have a habit of saying "LOAD "P*" ,8" then this is a good time to plan to stretch the habit to three letters. Of course, one experience guarantees fast learning. This program does not check the end-load address. It is unlikely you have a "P." file starting at the screen and going all the way into the interface chips.

The load command is tricky, in that it normally loads into the same place as where the code came from. This means that, unless you're careful, you may mess up a program in memory if you inadvertently ask for a display of a wrong file. The coding in lines 460-500 prevents this from happening. Your variations on this theme may exclude the starting address test in line 490, but be careful what you're doing.

The message end of line 490 is never executed by my program, as the failure to find a program file with a "P." prefix is actually detected in line 460. I keep line 490 for safety, in the event of skipping "P." in line 210 or in versions of the routine or in the event of an existing "P." file that is not a screen file.

For loading via this program you may, of course, use "*" for a file name, as "P.*" will result, bringing in the first picture file.

Do not add the "P." prefix when you are asking to write or read; the routine does it for you and prints it as an input prompt, but you can't change it. The only time "P." in "P.ELEPHANT*" is mandatory is when you want to load the elephant while in the monitor mode (and don't use Power!). Needless to say, "P." must be used when you save screen via the monitor if you plan to read by this code.

Consider the bottom line useless. It is saved, but is used by my routine for asking file name and for floppy error messages. Bottom line seldom is used anyway, so it shouldn't be too painful to forget it. You may change the end address to skip saving that line.

Go easy on the RETURN key after a picture has been displayed, if that picture happens to be a program text or if numbers exist on the left edge. You may or may not want to enter the lines into your program.

Power Mode

The code in lines 110-120 is my hookup to Power. Many of you are familiar with Charles Brannon's Keyprint routine, which dumps the screen to printer when a key is pressed. This Power hook-up works in a similar fashion: pressing a user designated shifted key dumps the screen image onto a floppy or brings an old image back. The shifted key does not print and, miracle of useful miracles, the cursor stays in place.

Program Mode Suggestions

Don't worry if you don't have Power. You can use the routine just about as listed. But it has to be done in a program. You have to arrange for starting and ending the procedure without scrolling the screen. The reason is that, in contrast to Power's instant subroutines, PET's direct "execute" type commands must be typed on the screen, and the cursor hops down. Both events usually mangle the picture.

The simplest thing is to transfer your picture to another area of the PET before saving. Changing top of the PET pointer will protect the picture.

You can then save the entire alternate screen area (change the addresses). After loading it by the quick load method, you can transfer the image back, for further work, or whatever.

Swapping the screen prior to input activity into an alternate area is a good idea anyway in very serious uses. You will then not need fancy user-proof input routines, your picture being safe elsewhere.

Some Applications For Picture Files

Many uses are obvious. Your child's masterpiece can be preserved (several times, while working). Graphs and other displays can be saved. Tiny sections of programs can be saved and brought back without disturbing a program in memory. You can save an annotated history of your floppy on the floppy. You can debug programs which are heavily screen oriented, by being able to quickly overlay and compare various outputs you've previously saved as picture files. Fixing the pointer chain can be a building block for a BASIC disk append routine. And more.

Non-Upgrade PETs

The table shows the system addresses used in the code so that if anything goes wrong you can track it down. Most addresses are identical in Upgrade and 4.0 BASIC. Addresses of two ROM routines differ. Provided that they function in the same way (the Micromon code seems to tell me they do), 4.0 users should experience no difficulty.

Upgrade BASIC #4 Meaning
SC = 32768 same screen
68/69 same last used variable (FL$)
212 same device
209 same length of file name
218/219 same address of file name
136/137 same temp.storage/rnd#
157 same load flag = 0
251/252 same save start address
201/202 same save end address
LR = 62242 62294 load routine $F356
SR = 63140 63203 save routine $F6E3

Additionally, 80-column PETs have a 2000-byte screen. This is reflected in the screen end address correction in line 300, as well as in longer strings of blanks. Be careful of three-way concatenation if memory is getting short.

References

  1. CBM User Manual (Upgrade) Monitor listing.
  2. Butterfield, BASIC4 Memory map and ROM routines, COMPUTE!, November/December 1980, #7.
  3. Butterfield, Upgrade Memory map, COMPUTE!, November/December 1979, #1.
  4. Micromon code where one gets load subroutine address.
  5. Butterfield disk utilities where one gets instructions about disk.
  6. Collins, "Host Equipment Test," The Microcomputer Magazine (Commodore-PA), also in the Transactor (Commodore-Canada).
110 REM "W 170 : WRITE PIC TO FLOPPY
120 REM "R 180 : READ TO SCREEN
130 STOP
170 LF = 0 : GOTO 190 : REM W (ON DEVICE 8
180 LF = 1 : REM R DRIVE 1)
190 DV = 8 : DR$ = "1" : FL$ = " "
200 IF LF = 0 THEN FL$ = "@"
210 FL$ = FL$ + DR$ + " : P."
220 GOSUB270 : GOSUB 550
230 E1 = 1 : GOSUB630 : IF E1 GOTO 250
240 FL$ = FL$ + I$ : GOSUB 330
250 PRINT H$; : RETURN
260 REM---SOME SYS CONSTANTS------
270 GOSUB 520 : IF TP = 0 THEN STOP
280 SC = 32768 : LR = 62242 : SR = 63140
290 S1 = 0 : S2 = 128 : S3 = 232 : S4 = 131
295 IF TP = 2 THEN LR = 62294 : SR = 63203
300 IF TP = 3 THEN LR = 62294 : SR = 63203 : S3 = 208 : S4 = 135
310 FF = 20 : RETURN
320 REM---READ/WRITE FILE---------
330 CLOSE 15 : OPEN 15, DV, 15
340 IF LF THEN GOSUB460 : IF E1 THEN RETURN
350 POKE 212, DV : POKE 209, LEN (FL$)
360 POKE 136, PEEK (68) : POKE 137, PEEK (69)
370 AD = PEEK (136) + 256 * PEEK (137) + 1
380 AD = PEEK (AD) + 256 * PEEK (AD + 1)
390 POKE 218, AD - 256 * INT (AD/256) : POKE 219, AD/256
400 IF LF THEN POKE 157, 0 : SYS (LR) : GOSUB 430 : CLOSE15 : RETURN
410 POKE 251, S1 : POKE 252, S2 : POKE 201, S3 : POKE 202, S4 : SYS (SR)
420 REM---FLOPPY STATUS-----------
430 INPUT# 15, E1, E$; E2; E3: IF E1 = 0 THEN PRINT H$M1$; : RETURN
440 PRINT H$BL$H$ " * " E1; E$, E2; E3; : CLOSE 15 : RETURN
450 REM---LEGAL TO LOAD?----------
460 CLOSE FF : OPEN FF, DV, 3, FL$ + ", P" : GOSUB 430 : IF E1 THEN RETURN
470 GET # FF, I$ : LA = ASC (I$ + CHR$ (0))
480 GET # FF, I$ : CLOSE FF : LA = LA + 256 * ASC (I$)
490 IF LA < > SC THEN PRINT H$M2$; : E1 = 1
500 RETURN
510 REM---J. COLLINS TYPE TEST-----
520 A = PEEK (57345) : TP = 0: IF A THEN P = 1 : IF A AND 1
    THEN TP = 3 : IF A AND 4 THEN TP = 2
530 RETURN : ORIG = 0, UPGR = 1, 4/40 = 2, 4/80 = 3
540 REM---MESSAGES----------------
550 H$ = " {HOME} {24 DOWN}" : REM [HOME, 24 DOWN]
560 BL$ = " ":REM[39 BLANKS]
570 IF TP = 3 THEN BL$ = BL$ + BL$ + CHR$ (32)
580 BL$ = BL$ + CHR$ (20) + " " : M1$ = " OK"
590 M2$ = " *  ??"
600 PRINT H$BL$; : REM CLEAR BOTTOM LINE
610 RETURN
620 REM---CONFIRM, ASK FILE NAME----
630 LL$ = "WRITE" : IF LF THEN LL$= "READ"
640 PRINT H$"{REV} X/FILE NAME {OFF} "LL$FL$; : GOSUB 680
650 IF ASC (I$) = 88 THEN PRINT H$M1$; : RETURN
660 E1 = 0 : RETURN
670 REM----INPUT-------------------
680 CLOSEFF : OPEN FF, 0 : INPUT # FF, I$ : CLOSE FF: RETURN
690 REM--------------------------.