* It's sometimes hard to tell where the screen boundaries are. Annoying, if the cursor jumps the line or the screen scrolls when you don't want it to. Cheap solution: fill screen with the full white square character and put borders on the picture using 1/8" or 1/16" vinyl tape sold in stationary or art supply stores. Do it on the right and bottom edges of the screen. Watch for parallax!
* Don't use SYS4 within a running BASIC program (to get to the monitor). Location 4 is busy at that time and you'll crash. Use SYS 1024 or call the Monitor instead (64785 on Upgrade).
* Most, if not all, tape load errors are preventable. Keep tapes clean. Clean the cassette unit immediately after getting the first VERIFY ERROR or a bad ST value. Use Radio Shack freon head cleaner or grain alcohol and Q tip. No rubbing alcohol. Don't permit the Q-tip to get tangled up in moving parts inside.
* If you can't find any pencils in the house turn to your PET. They are all under there. A real "world computer" would have legs either too small for pencils to roll under or big enough for a person's hand, if you want my opinion.
* Recent Commodore printers (4022) have a trace of descenders and work quietly, but slower, than the old ones. It is easier to flip character sets than previously. They don't get stuck any more. Surprise â€" the values are opposite from those in the PET itself. Quote from the manual: to set text mode (upper and lower case) 10 poke59468,12 : open7,4,7 : print#7 : close7, and to set graphics mode (graphics and upper case) 10 poke59468,14: open8,4,8 : print#8 : close8. Note that two secondary addresses are used, 7 and 8.
* Both Osborne PET/CBM GUIDES, the red and white books, incorrectly describe several aspects of array storage on the PET. The general logic is all right, but many details have been mangled. BASIC 4 users should be aware of the fact that their character strings occupy two more bytes of storage per string than previous BASICs. All users should note that the Osborne books, in text and/or some illustrations, reverse the low-high order of addresses, and that the description of storage of character strings is in error.
* Update on Partitions: to set up partitions in the PET, it is always necessary to reset the "beginning of BASIC" pointer and to put zeros in the first three bytes of a partition (NEW). Assuming two partitions, the way to get going is via the monitor. For instance, to set up a partition at $6000 (24576 decimal), type SYS4 and:
.M 0028 0028
.: 0028 01 60 03 60 03 60 03 60
.M 6000 6000
.: 6000 00 00 00 xx xx xx xx xx
To reenter a previously established partition, it's a good idea to check the presence of that zero in the first position, otherwise BASIC can't work. Do the check while in the Monitor changing your pointers. Otherwise, if you exit with the zero missing, BASIC will not function and you probably won't be able to get back into the monitor without a reset (power turned off, then back on).
Existing program files can be loaded into a partition using "Toolkit" 's APPEND command (tape only). Existing programs in ASCII format can be so loaded via the XEC command of "Power" (tape and disk).
Saving programs from a partition has to be done by the Monitor's .S command in case of the Toolkit. In Power, saving a program as an ASCII file (relocateable, by definition) does the job automatically.
For many applications a method described in COMPUTE!, November, 1981, #18, "Inverse Partitioning" should simplify the task.
* Supermon (SM) [a machine language monitor extension program which appeared in COMPUTE!, December, 1981, #19] is handy in resetting the top of BASIC pointer in case of continuing shrinkage of your PET's memory while you POKE and rePOKE some undebugged machine code program. Assume that SM is the SYS address given by the loader during original setup. Doing SYS SM at any time will set the pointers to the original condition. By the same token, if you have some code below (lower address) Supermon, don't use its SYS command, use PET's SYS4. PET recognizes Supermon's commands by checking a pointer at $03FA-03FB. If you crash and reset the PET, this pointer has to be fixed by SYS SM.
* Wedge relocates itself to the top of the PET, next to the screen. The code uses ROM routines and contains no location-sensitive addresses. It can be block-moved anywhere in memory with the Supermon's Transfer command, so long as you notify the CHRGET routine of the move: change $0071-0072 (low byte-high byte of Wedge's address) to point to the new location.
While Wedge is loading itself it uses some screen area for working storage (evidenced by a quick flash on the screen). This can be deadly if you plan to put Wedge below some existing code, as the code will turn to mush. There are several ways around it: use the old DOS-Support program which doesn't jump its boundaries, or load the Wedge first to a lower location, followed by the desired program, or load the Wedge next to the screen and move it.
* Wedge is hard-coded to be available only with disk as device 8. Untested suggestion: it can be used with a differently numbered disk device if you poke the device number in two locations in the Wedge code. Use Supermon's Hunt command to find two 8's. They are in A9 08 (LDA #$08) code sequence. No other 8's exist in the code.
* Wedge's handy curiosity: you can quickly obtain the names of the floppies and bytes free from both drives by saying such things as >$10, or >$01, or >$55 or $>XX or whatever.
* While developing a long BASIC program (or when putting it away for some time) it's a good idea to document it. Otherwise, later it won't seem to resemble any of your thoughts. The meanest thing is the structure of the program â€" "what does it do and when?" You can't modify a program without knowing that you won't stick a line in a place that breaks up a subroutine or without knowing where it might even be executed.
A cross-reference program is a good thing to use, for instance Cursor (tape-magazine) published Jim Butterfield's fast, machine code Cross-ref routine for disk users (only, I think). It lists variables (in alphabetical order) and lines (in numeric order) indicating places where those variables or numbers are used.
Here is a halfway approach I sometimes use. It's good for tape people. And it can, of course, be used with Cross-reference for a complete picture.
Devoting some space at the end of a program to housekeeping, I can list all subroutine entry points and all GOTO references, like this:
2000 : ON S GOSUB 450, 500, 510, 320, 620, 800
2001 : ON G GOTO 60, 100, 150, 250, 455
The syntax in and guarantees against those lines ever executing, even if I were to lose control of the program, since a SYNTAX ERROR would result. ON X GO X, however, is seen by me, Cross-reference, Toolkit and Power as a perfectly valid list of addresses. They get renumbered correctly and, if I keep them clean and up to date, I stand a better chance of knowing how the program is built. It's primitive, but it works.
Somebody mentioned a way of removing the spaces in a BASIC listing, and that there is a ROM to do this? Is there a way to do it in a sub routine, or via the monitor? For instance, lets say I type:
10REM-BASIC EXAMPLE-
20PRINT"HELLO WORLD"
30END
This lists as:
10 REM-BASIC EXAMPLE-
20 PRINT"HELLO WORLD"
30 END
If I get rid of the unnecessary spaces, will it (1) save bytes and (2) still work?
Any tips would be very helpful here,
Regards,
Shaun.
The space between line number and statements is not saved in memory. It is only Basic's way to make the line more readable.
However if you write FOR I=1 TO 10, all the spaces are conserved and will take up valuable space. You may ask for a way to compact this kind of statement, which I am sure exists but don't know right now where to find. Usually Basic compilers were able to compact the program before compiling.
Thanks, that's very useful. So, no real way to save any more bytes, oh well!
Actually, I have a small screen-saver prg which I'm going to attach to my game so that it calls it if there isn't any input from the used after a set amount of time, but this will only be possible if people have the dizzy heights of 8K or more, so there'll be two versions if you like, a cost-reduced one and a better one ;-)
Regards,
Shaun.
Well, you can compact the line numbers:
10 REM PROGRAM
20 GOSUB100
...
100 REM SUBROUTINE 1
110 FORI=1TO20:PRINT"***":GOSUB200:NEXT
120 RETURN
...
200 REM SUBROUTINE 2
205 A=PEEK(32768)
210 ONAGOTO300,400,500,600
220 RETURN
...
While each line number itself will be stored as a two byte decimal number (0 - 63999), all references to a line number in GOTO and GOSUB statements are stored verbatim, as text. It means above we would have those strings "100", "200", "300" and so on in the listing. If the program is compacted to use as short line numbers as possible, you save space.
If you also reorder the program like this:
5 GOTO100
10 REM SUBROUTINE 1
...
19 RETURN
...
20 REM SUBROUTINE 2
...
29 RETURN
...
100 GOSUB10:GOSUB20
You will not only save memory (shorter line numbers in refences), the program will also run faster! This is due to Basic always starts from the beginning when it looks for a line number to jump to, whether it is a GOTO or GOSUB. If you place subroutines at the end, Basic will need to traverse the whole program to find it. If you place them at the beginning and use the GOTO trick to jump past the subroutines, you will make it execute faster.
There are a lot more tips like this. You could look for tips on VIC-20 and C64 Basics, since they use Basic V2 that to most part should be identical to PET Basic.
Thanks Mr Carlsson, I've already done this. I've also found out that ON X GOSUB saves some bytes as a pose to ON X GOTO because RETURN saves a couple of bytes over GOTO X when I need to get back to the main bit of the program.
Regards,
Shaun.
Quote from: Blacklord on July 28, 2009, 07:24 AM* Most, if not all, tape load errors are preventable. Keep tapes clean. Clean the cassette unit immediately after getting the first VERIFY ERROR or a bad ST value. Use Radio Shack freon head cleaner or grain alcohol and Q tip. No rubbing alcohol. Don't permit the Q-tip to get tangled up in moving parts inside.
Isopropanol, sold as denatured alcohol solvent in hardware stores and paint shops, is the ideal cleaning medium for tape heads. Also, watch out for bits of Q-Tip getting left behind.
Not only do you save a few bytes, you get much more logic into your program. A subroutine shouldn't jump back into middle of the program unless unavoidable. The main exception might be a program in which you constantly branch to one of many different parts, and they all have in common that the program should resume from beginning of the loop once the particular section is run.
Quote from: BigDumbDinosaur on August 23, 2010, 03:41 PM
... If the constant is an integer assign it to an integer variable (e.g.,A%=10), which only consumes two bytes and can be processed many timesfaster than a floating point variable. ...
Sorry my dear dino, but that is not true (unfortunately).
The use of variables like A% needs the same cbm memory space then a real value (7 bytes).
If you want to save memory space you have to use fields like A%(x). Only the integer values in fields uses 2 bytes of memory to store the value (and 5 bytes overhead for the simple field).
And if I remember well, then the math. routines are working with real values. Therefore integer variables are slower than real variables because the program have to to reformat the values from integer to real (and vice versa) and have also to check for overflows.
Only if you use a compiler all things changes and integers will be very fast.
Regards WTE
From "Commodore 128 Programming Secrets" chapter 4, 'The C128 BASIC 7.0 Interpreter':
"Each non-array variable declaration occupies seven bytes in RAM. The first two bytes of each entry contain the variable's name, and the next five bytes contain either a floating-point number, a two-byte integer, or a string descriptor consisting of a length value (one-byte) and a pointer (two-bytes).
In the case of true integer variables (those with a percent sign in their names), the first two bytes of the five-byte data field contain the integer in standard 6502 low-byte/high-byte format. The next three locations contain $00 filler bytes. Therefore, no space is saved by using integer variables. Use of integer variables also slows down a BASIC program's operation. Since BASIC usually works with floating-point numbers, integer variables have to be converted to floating-point format, which is a time-consuming task. Anytime the value of an integer variable needs to be updated, the floating-point number must be reconverted back to integer format, which takes even more time.
Generally, Commodore BASIC programs do not benefit from the use of integer variables."
Later, speaking of array variables, it adds:
"...storage of integer values requires only two bytes...This is the only case in which use of integer variables in Commodore BASIC actually reduces memory consumption. Remember, there is still a speed penalty (time taken for floating-point/integer conversion) associated with the use of any integer variable, array or not."
Any BASIC math operations use the FACs, and require integers to be converted to floating-point before they can be used.
That's what I said, isn't it?