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:
- device number (DV)
- file name FL$
- address of file name; pointer in 68/69 gives address for 218/219
- length of file name.
- 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
- CBM User Manual (Upgrade) Monitor listing.
- Butterfield, BASIC4 Memory map and ROM routines, COMPUTE!, November/December 1980, #7.
- Butterfield, Upgrade Memory map, COMPUTE!, November/December 1979, #1.
- Micromon code where one gets load subroutine address.
- Butterfield disk utilities where one gets instructions about disk.
- 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--------------------------.