Hooray for SYS

Started by Blacklord, August 08, 2009, 08:53 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Blacklord

Harvey B. Herman
Department of Chemistry University of North Carolina at Greensboro
Greensboro, North Carolina 27412

The PET User's Club Newsletter (Vol. 1, Issue 3) reprinted an interesting article by Karl Hildon entitled "Probing PET's Memory". PETters were encouraged to experiment with the SYS command. Many of the routines in the PET are written as subroutines which terminate with the machine language instruction, RTS (return from subroutine). When a routine is initiated by the SYS command execution of the RTS instruction returns the PET to BASIC command mode or continues with the BASIC program. Using this idea we may be able to pick and choose useful segments of PET's Code and, in effect, make a new operating system.

This article describes three examples of tape operations which are not possible with just the normal BASIC commands. I hope readers will find them useful and are encouraged to develop similar ones on their own with the information supplied here. For convenience I have summarized in the Table the SYS calls and memory locations that I refer to in this article for both original and upgrade ROMs.

Occasionally I receive a tape of a machine language program with no information on its load limits. It is not possible to make a backup copy without this data. My first example is a BASIC program (see listing for TAPE DIRECTORY) which continually reads a tape and lists the start and end (+1) addresses for each program it finds. The idea behind this program and other examples here come from an article by Jim Butterfield, "Watching a Cassette Load", PET User Notes, Vol. 2, #1. He discussed several SYS commands in the article. The TAPE DIRECTORY program uses one of the SYS calls to load a tape header, containing among other information, the start and end addresses of the tape load. The addresses PEEKed from the beginning of the first cassette buffer are then converted to hexadecimal, using another Butterfield idea, and printed out. Note the use of the dynamic keyboard in statement 10 (cf., Mike Louder, "Best of PET Gazette") and the changes necessary for upgrade ROMs in statement 9.

More than once I have received a tape which would not load into my PET. For example, the program may have been saved from $4000 up in the originating PET and the highest location in my computer is $3FFF. My second BASIC example is a program (see listing for RELOCATE) which loads a cassette program into any area of RAM memory specified by the user. The loading addresses on the tape header are bypassed. I did the same trick manually in an article I wrote for MICRO ("MOVEIT", 16:17, with update 17:18). This program described here completely automates the procedure by using the dynamic keyboard idea. It asks for input of the starting location, loads the tape header, corrects the header information in the first cassette buffer, and completes the rest of the load. Note the changes necessary for upgrade ROMs (Statements 165, 330, and 345). After relocation machine language programs will probably need some changes to reflect the new location before executing successfully.

Appending one BASIC program to another is a very useful operation. The final BASIC example (see listing for APPEND) has appeared before in many different guises. For example, as a wedge (Commodore PET User's Club Newsletter, Vol. 1, #4-5, p. 24), or with a SYS call to a machine language program (PET User's Notes, Vol. 1, #7). The BASIC Programmer's Toolkit (Palo Alto ICs) also has a built in tape append function. The BASIC programs described here (APPEND and APPEND NEW PETS) uses a similar set of SYS calls as RELOCATE. The programs first determine the end of BASIC from pointers in page zero. After the header is loaded the start/end information in the tape buffer is updated to reflect a remaining load which starts at the end of the first BASIC program. The program can be run repeatedly to append as many programs as desired. However, each program should have successively higher line numbers with no overlap. The append program can be deleted manually after use or the task could be automated using the dynamic keyboard.

Several problems came up when I tried to adapt the append program for upgrade ROMs. Jim Butterfield was kind enough to send me the locations corresponding to "load next header" and "load rest of tape" However, the load next tape routine did not have exactly the same effect as in the older model PETs. The new routine did not correct the chaining (links between BASIC lines) and update various pointers (e.g., to end of BASIC program). My APPEND program for new PETs needed an additional SYS call to correct the chaining and a separate update POKE so BASIC can keep track of the larger merged program.

The examples given here were all for cassette tape operation. There is no reason why examples have to be limited to tape. In the future, I hope to read about other examples where selective parts of PET's code BASIC are utilized in BASIC programs. Most of us, including myself can understand BASIC more easily than machine language and as long as speed is not a requirement, I see no reason why we can't use the 14K bytes of code in ways never dreamed of originally.
TABLE (hex locations in parenthesis)
Function    Original ROMs    Upgrade ROMs
load header    62894 (F5AE)    62886 (F5A6)
pointer to end of BASIC program    124/125 (7C/7D)    42/43 (2A/2B)
Header Buffer    635-638 (27B-27E)    same
load rest of tape    62403 (F3C3)*    62393 (F3B9)
correct chaining    50224 (C430)    50233 (C439)
current device #    241 (F1)    212 (D4)
LOAD/verify flag    523 (20B)    157 (9D)
# Chars, in keyboard    525 (20D)    158 (9E)
start of keyboard buffer    527 (20F)    623 (26F)

Note: With original ROMs, the chaining is corrected and end of BASIC program pointer updated automatically after BASIC program load. With upgrade ROM, chaining and pointer update must be done manually.

2 REM TAPE DIRECTORY
5 REM HARVEY B. HERMAN
8 REM SET CURRENT DEVICE NUMBER TO TAPE 1 : LOAD NEXT HEADER USING DYNAMIC KEYBOARD
9 REM NEW PET-POKE212, 1 : SYS 62886 : POKE 158, 1 : POKE 623, 13
10 POKE 241, 1 : PRINT "â†"â†"â†"SYS 62894 : GOTO20 â†'â†'â†'" : POKE525, 1 : POKE527, 13 : END
19 REM 635-638 TAPE BUFFER START AND END LOCATION
20 A = PEEK (635) : B = PEEK (636)
30 GOSUB 110
35 PRINT
40 PRINT "TAPE START";
50 GOSUB 120
60 A = PEEK (637) : B = PEEK (638)
70 GOSUB 110
80 PRINT "TAPE END";
90 GOSUB 120
100 GOTO 10
109 REM CONVERT HIGH/LOW BYTES TO LOCATION
110 C = 256*B+A : RETURN
119 REM DECIMAL TO HEX CONVERSION-JIM B. IDEA
120 X = C/4096 : FOR J = 1 TO 4 : A = INT (X)
130 IFA > 9 THEN PRINT CHR$ (A + 55); : GOTO 150
140 PRINT CHR$ (A + 48);
150 X = (X-INT(X)) * 16 : NEXT J : PRINT : RETURN


100 REM RELOCATE
110 REM HARVEY B. HERMAN
120 REM INPUT START OF RELOCATION
130 INPUT "PROGRAM START LOCATION"; C
140 REM CONVERT TO HIGH/LOW BYTES : SAVE FOR LATER
150 GOSUB 400 : SL = A : SH = B : NS = C
160 REM SET CURR. DEVICE NUMBER TO TAPE 1 : LOAD NEXT HEADER USING DYNAMIC KEYBOARD
165 REM NEW PET-POKE 212, 1 : SYS 62886 : POKE 158, 1 : POKE 623, 13
170 POKE 241, 1 : PRINT "â†"â†"â†"SYS 62894 : GOTO 200â†'â†'â†'" : POKE 525, 1 : POKE 527, 13 : END
180 REM 635-638 TAPE BUFFER START AND END LOCATION
190 REM FIND TAPE START
200 A = PEEK(635) : B = PEEK(636)
210 REM SAVE FOR LATER
220 GOSUB 380 : S = C
230 REM FIND TAPE END + 1
240 A = PEEK (637) : B = PEEK (638)
250 REM SAVE FOR LATER
260 GOSUB 380 : F = C
270 REM CALCULATE NEW TAPE END
280 C = NS + (F-S) : GOSUB 400 : FL = A : FH = B
290 REM CORRECT TAPE BUFFER START AND END
300 POKE 635, SL : POKE 636, SH
310 POKE 637, FL : POKE 638, FH
320 REM FLAG-0/LOAD, 1/VERIFY
330 POKE 523, 0 : REM NEW PET-157
340 REM LOAD REST OF TAPE WITH DYNAMIC KEYBOARD
345 REM NEW PET-SYS 62393 : POKE 158, 1 : POKE 623, 13
350 PRINT : PRINT : PRINT "SYS 62403â†'â†'â†' : POKE 525, 1 : POKE 527, 13
360 END
370 REM CONVERT HIGH/LOW BYTES TO LOCATION
380 C = 256 * B + A : RETURN
390 REM CONVERT LOCATION TO HIGH/LOW BYTES
400 B = INT (C/256) : A = C-B*256 : RETURN


100 REM APPEND
110 REM HARVEY B. HERMAN
120 REM SET CURR. DEVICE NUMBER TO TAPE 1 : LOAD NEXT HEADER USING DYNAMIC KEYBOARD
130 POKE 241, 1 : PRINT "â†"â†"â†"SYS 62894 : GOTO 150â†'â†'â†'" : POKE 525, 1 : POKE 527, 13 : END
140 REM 635-638 TAPE BUFFER START AND END LOCATION
150 A = PEEK(635) : B = PEEK(636)
160 GOSUB 400
170 REM SAVE TAPE START
180 S = C
190 REM FIND END OF BASIC PROGRAM
200 A = PEEK(124) : B = PEEK (125)
210 GOSUB 400
220 REM CALCULATE NEW START LOAD
230 C = C-3 : T = C : IF PEEK (635) = 0 THEN C = C-1 : T = T-1
240 GOSUB 420
250 REM CORRECT LOAD POINT
260 POKE 635, A : POKE 636, B
270 REM FIND TAPE END (+1)
280 A = PEEK (637) : B = PEEK (638)
290 GOSUB 400
300 REM CALCULATE NEW TAPE END
310 C = C-S
320 C = T+C
330 GOSUB 420
340 REM CORRECT END LOAD : SET LOAD/VERIFY FLAG TO LOAD
350 POKE 637, A : POKE 638, B : POKE 523, 0
360 REM LOAD REST OF TAPE WITH DYNAMIC KEYBOARD
370 PRINT : PRINT "â†"â†"SYS 62403â†'â†'â†'" : POKE 525, 1 : POKE 527, 13
380 END
390 REM CONVERT HIGH/LOW BYTES TO LOCATION
400 C = 256*B + A : RETURN
410 REM CONVERT LOCATION TO HIGH/LOW BYTES
420 B = INT(C/256) : A = C - B*256 : RETURN


100 REM APPEND NEW PETS
110 REM HARVEY B. HERMAN
120 REM SET CURR. DEVICE NUMBER TO TAPE l : LOAD NEXT HEADER USING DYNAMIC KEYBOARD
130 POKE 212, l : PRINT "â†"â†"â†"SYS 62886 : GOTO 150 â†'â†'â†'" : POKE 158, l : POKE 623, 13 : END
140 REM 635-638 TAPE BUFFER START AND END LOCATION
150 A = PEEK (635) : B = PEEK(636)
160 GOSUB 400
170 REM SAVE TAPE START
180 S = C
190 REM FIND END OF BASIC PROGRAM
200 A = PEEK(42) : B = PEEK(43)
210 GOSUB 400
220 REM CALCULATE NEW START LOAD
230 C = C - 3 : T = C : IFPEEK(635) = 0THENC = C - 1 : T = T - 1
240 GOSUB 420
250 REM CORRECT LOAD POINT
260 POKE 635, A : POKE 636, B
270 REM FIND TAPE END (+1)
280 A = PEEK (637) : B = PEEK(638)
290 GOSUB 400
300 REM CALCULATE NEW TAPE END
310 C = C - S
320 C = T + C
330 GOSUB 420
340 REM CORRECT END LOAD : SET LOAD/VERIFY FLAG TO LOAD
350 POKE 637, A : POKE 638, B : POKE 157, 0
354 REM UPDATE ALL POINTERS
355 POKE 42, PEEK(637) : POKE43,PEEK(638): CLR
360 REM LOAD REST OF TAPE AND CORRECT CHAINING WITH DYNAMIC KEYBOARD
370 PRINT : PRINT "â†"â†"SYS 62393" : PRINT "â†"â†"â†"SYS 50233â†'â†'â†'â†'â†'â†'â†'"
371 POKE158,2 : POKE623, 13 : POKE624,13
380 END
390 REM CONVERT HIGH/LOW BYTES TO LOCATION
400 C = 256*B + A : RETURN
410 REM CONVERT LOCATION TO HIGH/LOW BYTES
420 B = INT(C/256) : A = C - B*256 : RETURN

Hooray for SYS (Correction)

Harvey B. Herman Greensboro, NC 27412

There is a problem with the APPEND programs (Jan. 1981 COMPUTE!) for "old" and "new" PETs. I recently learned that there are four kinds of PET cassette tapes. Unfortunately, in my ignorance, I only tested two types, both of which worked. The third very common PET tape, made with "new" ROMs, was ignored and, in fact, does not work. An easy fix which will cover most, but not all, cases is to change line 230, in both APPEND programs to:

230 C = C - 3 : T = C + 1 : IFPEEK(635) = 0 THEN
C = C - 1 : T = T - 2

The programs will now work with the PET tapes which users are most likely to encounter. It may be instructive to discuss the remaining problems in more detail as readers may not be aware of it and could come to grief, as I did.

Both versions of APPEND were designed to work with tapes made on "old" and "new" machines. There is a difference in tapes â€" original ROMs save starting at hex 400 (dec 1024) and upgrade ROMs save starting at hex 401 (dec 1025). The APPEND programs, as published, checked for start save at statement 230 and made a minor correction depending on which machine was used to make the tape. What I did not know was that new machines saved one byte less on either end. A short program which is written and saved on an "old" machine saves, for example, from hex 400 to hex 424 (call this case 1). The same program, if written and saved on a new machine (call this case 2) would be saved from hex 401 to hex 423 (one less on both ends). If the case 1 tape for the example program, is loaded into a "new" machine and saved, we get a tape which I will call case 3. This tape is a hybrid of cases 1 and 2. Locations saved are from hex 401 to hex 424. My tests for APPEND were done unwittingly with case 1 and case 3 tapes. The line 230 correction discussed above, will allow the program to work with case 2 tapes. Hybrid case 3 tapes will not work but can easily be converted to case 2 after loading by decrementing the location pointer at hex 28 and 29 (dec 42 and 43) and resaving the program. Thus, after loading our short example (case 3 or case 1 tape) change location hex 28 (dec 42) from hex 24 (dec 36) to hex 23 (dec 35) and save again. This new tape (now case 2) and the old one (if case 1) will both append properly. There is also a hybrid case 4 which requires the location pointer on old PETs to be incremented but I think you get the idea.