COMPUTE! ISSUE 37 / JUNE 1983 / PAGE 256
Soft-16
For
Commodore 64
Douglas D. Nicoll
This program, "USR(PEEK)",
demonstrates several interesting concepts about managing the memory of
the 64. BASIC programs can be run essentially without BASIC, and you
can switch between ROM and RAM during a program RUN to access an
additional 16K of RAM for data storage. You'll also see how to use the
USR() statement.
An inexpensive 16K RAM expansion for the Commodore 64? Run BASIC
programs without BASIC or the kernal? Well, almost. The 6510 has the
capability of exchanging RAM data banks with the three ROM banks (BASIC
[AB] $A000-$BFFF; characters [D] $D000-$DFFF; and kernal [EF]
$E000-$F000). It switches between ROM and RAM with the use of a control
port located at $0001. Bit zero in $0001 controls EF, bit one controls
AB, and bit two controls D. Setting the bit to one switches in ROM (the
normal state), and zero switches in RAM memory.
In normal BASIC operation, it is possible to POKE
values to AB and EF locations, but PEEKing these locations will show
only the ROM data. POKEs and PEEKs to D work fine, but you can't PEEK
the character ROM without setting a number of switches so the system
won't crash. Thus, without the ability to PEEK the hidden RAM memory,
AB and EF locations are effectively eliminated from use in BASIC
programs.
USR(PEEK) is a valuable machine language utility
program that opens up the hidden RAM for use in BASIC programs, giving
the user 16K more memory cells for data storage. The program is loaded
into $C001-$C0E4, and uses $0000 as a temporary storage cell. The
vector for the USR() function is set (POKE 785,1:POKE 786,192). BASIC
programs are loaded normally, and any RAM location can be PEEKed by
using X = USR(N), where X is any variable and N is any number from 1 to
65535. Any number less than 0.5 will set X to -1, 0.5 to 1.9 evaluate
as 1, and all other decimal numbers are truncated to the integer. If a
negative number is given for N, the value returned is for ABS(N). If a
number is greater than 65535, then X is -1. If N is between 53248 and
57343, X is the value of data stored in character ROM (D).
Automatic Switching
How does USR(PEEK) work? The statement X = USR(N) in a BASIC program
loads N into the floating point accumulator and sends the computer to
the machine language program pointed to by the USR vector. The machine
language program evaluates the number in the FP accumulator, switches
out BASIC and kernal ROM, loads the desired RAM data into the FP
accumulator, switches BASIC and kernal ROM back in, and finally sets up
the FP accumulator so that X contains the values on return to the BASIC
program. When character ROM is desired, it is switched in for the
manipulation.
The techniques used to dynamically switch between
RAM and ROM have many other uses for hybrid programmers (people who use
both BASIC and machine language). For example, machine language
programs can be loaded under BASIC or kernal ROM and run with BASIC
programs - this leaves more space for BASIC programs and variable
storage. It is possible to envision loading a BASIC program editor
under BASIC ROM and calling it for renumbering, searching, etc.
Type in the program and, after saving a copy, RUN it
to see a demonstration of how easy it is to use. Then eliminate lines
10-540 and save it with the name USR(PEEK). To use with your programs,
LOAD and RUN USR(PEEK) and then LOAD and RUN your own BASIC programs
that can be constructed to utilize the additional 16K of RAM data
storage.
1 GOSUB1000:REM SET UP USR(PEEK)
10 PRINT"{CLEAR}USR(PEEK) AT
CHARACTER ROM"
20 V$="{HOME}(24 DOWN}"
30 H$=""+"{39 RIGHT}"
40 UC=53248:LC=55296:GC=53760
50 H=0:V=10:L=83*8+UC:GOSUB500
60 H=8:V=10:L=3*8+UC:GOSUB500
70
H=14:V=5:L=85*8+UC:GOSUB500:H=14:V=14:
L=74*8+UC:GOSUB500
80 H=22:V=10:L=54*8+UC:GOSUB500
90 H=30:V=10:L=52*8+UC:GOSUB500
100
PRINTLEFT$(V$,5);LEFT$(H$,18);"SC{UP}U
{02
DOWN}{LEFT}J{UP}64";LEFT$(V$,22)
110 PRINT"PRESS ANY KEY TO
CONTINUE";
120 GETA$:IFA$=""THEN120
130 PRINT"{CLEAR}USR(PEEK) INTO
BASIC HIDD
EN RAM"
140 PRINTLEFT$(V$,5);"INPUT 10
NUMERS(0-25
5) TO STORE IN
$A000TO $A00A :"
150 FORI=1TO10
160 PRINT"NUMBER ";I;":
";:INPUT"";X
170
IFINT(X)<>XORX<0ORX>255THENPRINT"INVAL
ID
ENTRY...":GOT0160
180 POKE40959+I,X:NEXT
190 PRINT"{CLEAR}USR(PEEK) INTO
HIDDEN BAS
IC RAM"
200
PRINT:PRINT:PRINT"LOCATION PEEK US
R(PEEK)"
205
PRINT"---------------------------"
210
FORI=1TO10:PRINTI+40959,PEEK(I+40959),
USR(I+40959):NEXT
220 PRINTLEFT$(V$,22);"PRESS ANY
KEY TO CO
NTINUE ";
230 GETA$:IFA$=""THEN230
240 PRINT"{CLEAR}USR(PEEK) INTO
KERNAL HID
DEN RAM"
250 PRINTLEFT$(V$,5);"INPUT 10
NUMERS(0-25
5) TO STORE IN
$F000TO $F00A :"
260 FORI=1TO10
270 PRINT"NUMBER ";I;":
";:INPUT"";X
280
IFINT(X)<>XORX<0ORX>255THENPRINT"INVAL
ID
ENTRY...":GOTO160
290 POKE61439+I,X:NEXT
300 PRINT"{CLEAR}USR(PEEK) INTO
HIDDEN KER
NAL RAM"
310
PRINT:PRINT:PRINT"LOCATION PEEK US
R(PEEK)"
320
PRINT"---------------------------"
330
FORI=1TO10:PRINTI+61439,PEEK(I+61439),
USR(I+61439):NEXT
340 END
500 FORD=LTOL+7:X$="":X=USR(J)
510
FORI=7TOHSTEP-1:IFX=>2↑tITHENX=X-2↑I:X$
=X$+"{WHT}{REV} {OFF}":GOTO530
520 X$=X$+"{RIGHT}"
530
NEXTI:IFJ=LTHENPRINTLEFT$(V$,V);
540
PRINTLEFT$(H$,H);X$:NEXT:RETURN
1000 POKE785,1:POKE786,192:REM
USR VECTOR
1010
FORI=49153TO49380:READX:POKEI,X:NEXT
1015 RETURN
1020
DATA173,97,0,201,144,208,3,76,188,192,
56,201,128,176,3,76,163,192,201,145
1030
DATA144,3,76,163,192,73,128,141,97,0,5
6,169,16,237,97,0,240,13,170,24
1040
DATA78,98,0,110,99,0,202,224,0,208,244
,173,98,0,141,78,192,173,99,0
1050
DATA141,77,192,173,1,0,141,0,192,120,7
3,7,141,1,0,173,255,255,141,98,0
1060
DATA173,0,192,141,1,0,88,173,98,0,201,
0,208,3,76,140,192,162,8,173,98,0
1070
DATA24,42,176,5,202,224,0,208,247,106,
141,98,0,73,128,141,102,0,138
1080
DATA9,128,141,97,0,169,0,141,99,0,141,
100,0,141,101,0,96,169,0,141,97,0
1090
DATA141,99,0,141,100,0,141,101,0,141,1
02,0,169,128,141,98,0,96,169,129
1100
DATA141,97,0,169,128,141,98,0,141,102,
0,169,0,141,99,0,141,100,0,141,101,0
1110
DATA96,56,173,98,0,201,224,144,3,76,22
3,192,201,208,176,3,76,223,192,169,4
1120
DATA141,72,192,173,97,0,32,26,192,169.
7,141,72,192,96,173,97,0,76,11,192