
4.
Connect
the
power
cord.
Check
the
ON/OFF
switch
on
the
back
of
the drive
(see
Figure
2)
and
make
sure
it's
OFF.
Connect
the
power
supply
where
indicated
in
Figure
2.
Plug
the
other
end
into
an
electrical
outlet.
Don't
turn
the
power
on
yet.
Figure2.ConnectionofPower
Cord
and
Interface
Cablesto1581
BACK
OF
C128
SERIAL
PORT
CONNECTOR
ON
C128
POWER
CORD
SOCKET
BACK
OF
1581
SERIAL
PORT
CONNECTORS
FOR
INTERFACE
CABLES
DIP
SWITCHES
FOR
CHANGING
DEVICE
NUMBER
ON/OFF
SWITCH
POWER
OUTLET

NOTE
Throughout
this
manual,
when
the
format
foracom
mand
is
giv^n,
it
will
followaparticular
style.
Anything
that
is
capitalized
must
be
typed
in
exactly
as
it
is
shown
(these
commands
are
listed
in
capital
letters
for
style
purposes,
DO
NOT
use
the
SHIFT
key
when
entering
these
com
mands).
Anything
in
lower
case
is
more
or
lessadefinition
of
what
belongs
there.
Anything
in
brackets
is
optional.
For
instance,
in
the
format
for
the
HEADER
command
given
on
the
following
page,
the
word
HEADER,
the
capital
I
in
lid,
the
capitalDin
Ddrive#,
and
the
capitalUin
Ude*-
vice#
must
all
be
typed
in
as
is
(Ddrive#
and
Udevice#
are
optional).
On
the
other
hand,
diskette
name
tells
you
that
you
must
enteraname
for
the
diskette,
but
it
is
up
to
you
to
decide
what
that
name
will
be.
Also,
the
id in
lid
is
left
to
your
discretion,
as
is
the
device#
in
Udevice#.
The
drive#
in
Ddrive#
is
always0on
the
1581,
but
could
be0or1on
a
dual
disk
drive.
Be
aware,
however,
that
there
are
certain
limits
placed
on
what
you
can
use.
In
each
case,
those
limits
are
explained
immediately
following
the
format
(for
in
stance,
the
diskette
name
cannot
be
more
than
sixteen
characters
and
the
device#
is
usually
8).
Also
be
sure
to
type
in
all
punctuation
exactly
where
and
how
it
is
shown
in
the
format.
Finally,
press
the
RETURN
key
at
the
end
of
each
command.
HOW
TO
PREPAREANEW
DISKETTE
A
diskette
needsapattern
of
circular
magnetic
tracks
in
order
for
the
drive's
read/write
head
to
find
things
on
it.
This
pattern
is
not
on
your
diskettes
when
you
buy
them,
but
you
can use
the
HEADER
command
or
the
NEW
command
to
add
it
toadiskette.
That
is
known
as
formatting
the
disk.
This
is
the
command
to
use
with
the
C128
in
C128
mode
or
Plus/4:
HEADER
"diskette
name",Iid,Ddrive#[,Udevice#]
Where:
"diskette
name"
is
any
desired
name
for
the
diskette,
up
to
16
charac-
10

ters
long
(including
spaces),
"id"
can
be
any
two
characters
as
long
as
they
don't
formaBASIC
keyword
(such
as
IF
or
ON)
either
on
their
own
or
with
the
capital
I
before
them.
"drive#"
is0.
"device#"
is
8,
unless
you
have
changed
it
as
per
instructions
in
AppendixA(the
1581
assumes8even
if
you
don't
type
it
in).
The
command
for
the
C64,
VIC
20,
or
C128
in
C64
mode
is
this:
OPEN
15,device#,15,"NEWdrive#:diskette
name,id"
CLOSE
15
The
device#,
drive#,
diskette
name,
and
id
are
the
same
as
described
above.
The
OPEN
command
is
explained
in
the
next
chapter.
For
now,
just
copy
it
as
is.
-NOTE
FOR
ADVANCED
USERS
If
you
want
to
use
variables
for
the
diskette
name
or
id,
the
format
is
as
follows:
C128,
Plus/4:
HEADER
(A$),I(B$),D0
C64:
OPEN
15,8,15:PRINT#15,"N0:"
+A$+","+B$:
CLOSE15
Where:
A$
contains
the
diskette
name
(16
character
limit)
B$
contains
the
id
(2
characters
long)
After
you
formataparticular
diskette,
you.
can
reformat
it
at
any
time.
You
can
change
its
name
and
erase
its
files
faster
by
omitting
the
id
number
in
the
HEADER
command.
DISKETTE
DIRECTORY
A
directory
isalist
of
the
files
onadiskette.
To
view
the
directory
on
the
C128
or
Plus/4,
type
the
word
DIRECTORY
onablank
line
and
press
the
RETURN
key
or
simply
press
the
F3
key
on
the
C128.
That
doesn't
erase
anything
in
memory,
so
you
can
call
upadirectory
11

CHAPTER
2
BASIC
2.0
COMMANDS
This
chapter
describes
the
disk
commands
used
with
the
VIC
20,
Commodore
64
or
the
Commodore
128
computer
in
C64
mode.
These
are
Basic
2.0
commands.
You
send
command
data
to
the
drive
through
something
called
the
command
channel.
The
first
step
is
to
open
the
channel
with
the
following
command:
OPEN15,8,15
The
first
15
isafile
number
or
channel
number.
Although
it
could
be
any
number
from1to
255,
we'll
use
15
because
it
is
used
to
match
the
secondary
address
of
15,
which
is
the
address
of
the
command
channel.
The
middle
number
is
the
primary
address,
better
known
as
the
device
number.
It
is
usually
8,
unless
you
change
it
(see
Appendix
A).
Once
the
channel
has
been
opened,
use
the
PRINT#
command
to
send
information
to
the
disk
drive
and
the
INPUT#
command
to
receive
information
from
the
drive.
You
must
close
the
channel
with
the
CLOSE15
command.
The
following
examples
show
the
use
of
the
command
channel
to
NEW
an
unformatted
disk:
OPEN15,8,15
PRINT#15,"NEWdrive#:diskname,id"
CLOSE15
You
can
combine
the
first
two
statements
and
abbreviate
the
NEW
command
like
this:
OPEN15,8,15,"Ndrive#
:diskname,id"
If
the
command
channel
is
already
open,
you
must
use
the
following
format
(trying
to
openachannel
that
is
already
open
results
ina"FILE
OPEN"
error):
PRINT#15,uNdrive#:diskname,id"
15

dangeradisaster
such
as
losing
power
midway
through
the
process
would
destroy
both
the
old
and
hew
copies
of
the
file.
Nothing
happens
to
the
old
copy
until
after
the
new
copy
is
saved
properly.
VERIFY
The
VERIFY
command
can
be
used
to
make
certain
thatapro
gram
file
was
properly
saved
to
disk.
It
works
much
like
the
LOAD
command,
except
that
it
only
compares
each
character
in
the
program
against
the
equivalent
character
in
the
computer's
memory,
instead
of
actually
being
copied
into
memory.
If
the
disk
copy
of
the
program
differs
evenatiny
bit
from
the
copy
in
memory,
"VERIFY
ERROR"
will
be
displayed,
to
tell
you
that
the
copies
differ.
This
doesn't
mean
either
copy
is
bad,
but
if
they
were
supposed
to
be
identical,
there
isaproblem.
Naturally,
there's
no
point
in
trying
to
VERIFYadisk
copy,
of
a
program
after
the
original
is
no
longer
in
memory.
With
nothing
to
compare
to,
an
apparent
error
will
always
be
announced,
even
though
the disk
copy
is
automatically
verified
as
it
is
written
to
the
diskette.
FORMAT
FOR THE
VERIFY
COMMAND:
VERIFY
"drive#:pattern",device#,relocate
flag
where
"drive#:"
is
an
optional
drive
number,
"pattern".is
any
string
expression
that
evaluates
toafile
name,
with
or
without
pattern-
matching
characters,
and
"device#"
is
the
disk
device
number,
nor
mally
8.
If
the
relocate
flag
is
present
and
equals
1,
the
file
will
be
verified
where
originally
saved,
rather
than
relocated
into
the
BASIC
text
area.
A
useful
alternate
form
of
the
command
is:
VERIFY"*",device
#
It
verifies
the
last
files
used
without
having
to
type
its
name
or
drive
number.
However,
it
won't
work
properly
after
SAVE-WITH-REPLACE,
because
the
last
file
used
was
the
one
deleted,
and
the
drive
will
try
to
compare
the
deleted
file
to
the
program
in
memory.
No
harm
will
result,
but
"VERIFY
ERROR"
will
always
be
announced.
To
use
VERIFY
after
@SAVE,
include
at
least
part
of
the
file
name
that
is
to
be
verified
in
the
pattern.
19

One
other
note
about
VERIFY—when
you
VERIFYarelocated
BASIC
file,
an
error
will
nearly
always
be
announced,
due
to
changes
in
the
link
pointers
of
BASIC
programs
made
during
relocation.
It
is
best
to
VERIFY
files
saved
from
the
same
type
of
machine,
and
identi
cal
memory
size.
For
example,
a
BASIC
program
saved
fromaPlus/4
can't
be
verified
easily
withaC64,
even
when
the
program
would
work
fine
on
both
machines.
This
shouldn't
matter,
as
the
only
time
you'll
be
verifying
files
on
machines
other
than
the
one
which
wrote
them
is
when
you
are
comparing
two
disk
files
to
see
if
they
are
the
same.
This
is
done
by
loading
one
and
verifying
against
the
other,
and
can
only
be
done
on
the
same
machine
and
memory
size
as
the
one
on
which
the
files
were
first
created.
SCRATCH
The
SCRATCH
command
allows
you
to
erase
unwanted
files
and
free
the
space
they
occupied
for
use
by
other
files.
It
can
be
used
to
erase
eitherasingle
file
or
several
files
at
once
via
pattern-matching.
FORMAT
FOR
THE
SCRATCH
COMMAND:
PRINT#15,"SCRATCH0:pattern"
or
abbreviate
it
as:
PRINT#15,"S0:pattern"
"pattern"
can
be
any
file
name
or
combination
of
characters
and
wild
card
characters.
As
usual,
it
is
assumed
the
command
channel
has
already
been
opened
as
file
15.
Although
not
absolutely
necessary,
it
is
best
to
include
the
drive
number
in
SCRATCH
commands.
If
you
check
the
error
channel
afteraSCRATCH
command,
the
value
for
ET
(error
track)
will
tell
you
how
many
files
were
scratched.
For
example,
if
your
diskette
contains
program
ftles
named
"TEST,"
"TRAIN,"
"TRUCK,"
and
"TAIL,"
you
may
SCRATCH
all
four,
along
with
any
other
files
beginning
with
the
letter
"T,"
by
using
the
command:
PRINT#15/S0:T*'
Then,
to
prove
they
are
gone,
you
can
type:
GOSUB
59990
20

Locked
Files
Occasionally,
a
diskette
will
containalocked
file;
one
which
cannot
be
erased
with
the
SCRATCH
command.
Such
files
may
be
recognized
by
the
"<"
character
which
immediately
follows
the
file
type
in
their
directory
entry.
If
you
wish
to
erase a
locked
file,
you
will
have
to
useasector
editor
program
to
clear
bit6of
the
file-type
byte
in
the
directory
entry
on
the
diskette.
Conversely,
to
lockafile,
you
would
set
bit6of
the
same
byte.
RENAME
The
RENAME
command
allows
you
to
alter
the
name
ofaprogram
or
other
file
in
the
diskette
directory.
Since
only
the
directory
is
affected,
RENAME
works
very
quickly.
FORMAT
FOR
RENAME
COMMAND:
PRINT#15,"RENAME0:new
name=old
name"
or
it
may
be
abbreviated
as:
PRINT#15,"R0:new
name=old
name"
where
"new
name"
is
the
name
you
want
the
file
to
have,
and
"old
name"
is
the
name
it
has
now.
"new name"
may
be
any
valid
file
name,
up
to
16
characters
in
length.
It
is
assumed
you
have
already
opened
file
15
to
the
command
channel.
One
caution—be
sure
the
file
you
are
renaming
has
been
proper
ly
closed
before
you
rename
it.
EXAMPLES:
Just
before
saving a
new
copy
ofa"calendar"
program,
you
might
type:
PRINT#15,"R0:CALENDAR/BACKUP
=
CALENDAR"
Or
to
moveaprogram
called
"BOOT,"
currently
the
first
program
on
a
diskette
to
someplace
else
in
the
directory,
you
might
type:
PRINT#15,"R0:TEMP
=
BOOT"
followed
byaCOPY
command
(described
later),
which
turns
"TEMP"
intoanew
copy
of
"BOOT,"
and
finishing
withaSCRATCH
command
to
get
rid
of
the
original
copy
of
"BOOT."
22

EXAMPLES:
After
renamingafile
named
"BOOT"
to
"TEMP"
in
the
last
section's
example,
you
can
use
the
COPY
command
to
makeaspare
copy
of
the
program
elsewhere
on
the
diskette,
under
the
original
name:
PRINT#15,"C0:BOOT
=
TEMP"
After
creating
several
small
sequential
files
that
fit
easily
in
mem
ory
along
withaprogram
we
are
using,
you
can
use
the
concatenate
option
to
combine
them
inamaster
file,
even
if
the
result
is
too
big
to
fit
in
memory.
(Be
sure
it
will
fit
in
remaining
space
on
the
diskette—it
will
be
as
big
as
the
sum
of
the
sizes
of
the
files
in
it.)
PRINT#15,"C0:A-Z=A-G,H-M,N-Z"
EXAMPLES:
After
renamingafile
named
"BOOT"
to
"TEMP"
in
the
last
section's
example,
you
can
use
the
COPY
command
to
makeaspare
copy
of
the
program
elsewhere
on
the
diskette,
under
the
original
name:
PRINT#15/'C0:BOOT
=
TEMP"
After
creating
several
small
sequential
files
that
fit
easily
in
mem
ory
along
withaprogram
we
are
using,
you
can
use
the
concatenate
option
to
combine
them
inamaster
file,
even
if
the
result
is
too
big
to
fit
in
memory.
(Be
sure
it
will
fit
in
remaining
space
on
the
diskette—it
will
be
as
big
as
the
sum
of
the
sizes
of
the
files
in
it.)
PRINT#15,"C0:A-Z=A-G,H-M,N-Z"
VALIDATE
The
VALIDATE
command
recalculates
the
Block
Availability
Map
(BAM)
of
the
current
diskette,
allocating
only
those
sectors
still
being
used
by
valid,
properly-closed
files
and
programs.
All
other
sectors
(blocks)
are
left
unallocated
and
free
for
re-use,
and
all
improperly
closed
files
are
automatically
scratched.
This
brief
description
of
its
workings
doesn't
indicate
either
the
power
or
the
danger
of
the
25

VALIDATE
command.
Its
power
is
in
restoring
to
good
health
many
diskettes
whose
directories
or
block
availability
maps
have
become
muddled.
Any
time
the
blocks
used
by
the
files
onadiskette
plus
the
blocks
shown
as
free
don't
add
up
to
the
3160
available
onafresh
diskette,
VALIDATE
is
needed,
with
one
exception
below.
Similarly,
any
timeadiskette
contains
an
improperly-closed
file
(splat
file),
indicated
by
an
asterisk
(*)
next
to
its
file
type
in
the
directory,
that
diskette
needs
to
be
validated.
In
fact,
but
for
the
one
exception,
it
is
a
good
idea
to
VALIDATE
diskettes
whenever
you
are
the
least
bit
concerned
about
their
integrity.
The
exception
is
diskettes
containing
direct
access
files,
as
de
scribed
in
Chapter
6.
Most
direct
access
(random)
files
do
not
allocate
their
sectors
inaway
the
VALIDATE
command
can
recognize.
Thus,
using
VALIDATE on
suchadiskette
may
result
in
un-allocating
all
direct
access
files,
with
loss
of
all
their
contents
when
other
files
are
added.
Unless
specifically
instructed
otherwise,
never
use
VALIDATE
onadiskette
containing
direct
access
files.
FORMAT
FOR
THE
VALIDATE
COMMAND
PRINT#15,"VALIDATE0"
or
.abbreviated
as
PRINT#15,"V0"
where
"0"
is
the
drive
number.
As
usual,
it
is
assumed
file
15
has
been
opened
to
the
command
channel
and
will
be
closed
after
the
com
mand
has
been
executed.
INITIALIZE
Whenadiskette
is
inserted
into
the
drive,
its
directory
is
auto
matically
re-read
intoadisk
buffer.
You
would
use
the
command
only
if
that
information
became
unreliable.
FORMAT
FOR
THE
INITIALIZE
COMMAND
PRINT#15,"INITIALIZEdrive#"
or
it
may
be
abbreviated
to
PMNT#15,"Idrive#"
26

communications
for
this
file
can
take
place.
The
possible
range
of
disk
channel
numbers
is
0-15,
but0is
reserved
for
program
loads,1for
program
saves,
and
15
for
the
disk
command
channel.
Also
be
sure
that
no
two
disk
files
have
the
same
channel
number
unless
they
will
never
be
open
at
the
same
time.
(One
way
to
do
this
is
to
make
the
channel
number
for
each
file
the
same
as
its
file
number.)
"drive
#"
is
the
drive
number,
always0on
the
1581.
Do
not
omit
it,
or
you
will
only
be
able
to
use
two
channels
at
the
same
time
instead
of
the
normal
maximum
of
three.
If
any
pre-existing
file
of
the
same
name
is
to
be
replaced,
precede
the
drive
number
with
the
"at"
sign
(@)
to
request
OPEN-WITH-REPLACE.
"file
name'1
is
the
file
name,
maximum
length
16
characters.
Pattern
matching
characters
are
allowed
in
the
name
when
accessing
existing
files,
but
not
when
creating
new
ones.
"file
type"
is
the
file
type
desired:
S=sequential,
P=program,
U=user,
A=append
andL=
length
ofarelative
file.
"direction"
is
the
type
of
access
desired.
There
are
three
possi
bilities:
R=read,
W=write,
andM=
modify.
When
creating
a
file,
use
"W"
to
write
the
data
to
diskette.
When
vie\^ing
a
completed
file,
use
"R"
to
read
the
data
from
diskette.
Only
use
the
"M"
(modify)
option
asalast
ditch
way
of
reading
back
data
from
an
improperly
closed
(Splat)
file.
If
you
try
this,
check
every
byte
as
it
is
read
to
be
sure
the
data
is
still
valid,
as
such
files
always
include
some
erroneous
data,
and
have
no
proper
end.
"file
type"
and
"direction"
don't
have
to
be
abbreviated.
They
can
be
spelled
out
in
full
for
clarity
in
printed
listings.
"file
#",
"device
#"
and
"channel
#"
must
be
valid
numeric
constants,
variables
or
expressions.
The
rest
of
the
command
must be
a
valid
string
literal,
variable
or
expression.
"w"
is
an
option
that
must be
specified
to
write
the
sequential
file,
or
the
file
will
be
opened
to
read.
The
maximum
number
of
files
that
may
be
open
simultaneously
is
10,
including
all
files
to
all
devices.
The
maximum
number
of
sequential
disk
files
that
can
be
open
at
once
is
three
(or
two
if
you
neglect
to
include
the
drive
number
in
your
OPEN
statement),
plus
the
command
channel.
EXAMPLES
OF
OPENING
SEQUENTIAL
FILES:
To
createasequential
file
of
phone
numbers,
you
could
use:
BASIC
7.0:
DOPEN#2,"PHONES",D0,U8,W
BASIC
2.0:
OPEN
2,8,2,"0:PHONES,SEQUENTIAL,WRITE"
or
OPEN
2,8,2,"0:PHONES,S,W"
40

To
get
those
same
variables
onto
sequential
disk
file
number5instead
of
the
screen,
the
best
approach
would
be
to
use
three
separate
PRINT#
statements,
as
follows:
400
PRINT#5,NAME$
410
PRINT#5,STREET$
420
PRINT#5,CITY$
If
you
need
to
combine
them,
here
isasafe
way
to
do
it:
400PRINT#5,NAME$;CHR$(13);STREET$;CHR$(13);CITY$
CHR$(13)
is
the
carriage
return
character,
and
has
the
same
effect
as
putting
the
print
items
in
separate
lines.
If
you
do
this
often,
some
space
and
time
may
be
saved
by
previously
defining
a
variable
as
equal
to
CHR$(13):
10CR$=CHR$(13)
400PRINT#5,NAME$;CR$;STREET$;CR$;CITY$
The
basic
idea
is
thataproper
sequential
disk-file
write,
if
redir
ected
to
the
screen,
will
display
only
one
data
item
per
line,
with
each
succeeding
item
on
the
next
line.
CLOSINGAFILE
After
you
finish
usingadata
file,
it
is
extremely
important
that
you
CLOSE
it.
During
the
process
of
writing
a
file,
data
is
accumulated
in
a
memory
buffer,
and
only
written
out
to
the
diskette
when
the
buffer
fills.
Working
this
way,
there
is
almost
alwaysasmall
amount
of
data
in
the
buffer
that
has not
been
written
to
diskette
yet,
and
which
would
simply
be
lost
if
the
computer
system
were
turned
off.
Similarly,
there
are
diskette
housekeeping
matters,
such
as
updating
the
BAM
(Block
Availability
Map)
of
sectors
used
by
the
current
file,
which
are
not
per
formed
during
the
ordinary
course
of
writing
a
file.
This
is
the
reason
for
havingaCLOSE
statement.
When
you
are
done
withafile,
the
CLOSE
statement
will
write the
rest
of
the
data
buffer
out
to
diskette,
update
the
BAM,
and
complete
the
file's
entry
in
the
directory.
Always
closeadata
file
when
you
are
done
using
it.
Failure
to
do
so
may
cause
loss
of
the
entire
file.
However,
do
not
close
the
disk
command
channel
until
all
other
files
have
been
closed.
The
command
channel
should
be
the
first
file
opened,
and
the
last
file
closed
in
any
program.
43

FORMAT
FOR
THE
INPUT#
STATEMENT
INPUT#file
#,variable
list
where
"file
#"
is
the
same
file
number
given
in
the
desired
file's
cur
rent
OPEN
statement,
and
"variable
list"
is
one
or
more
valid
BASIC
variable
names.
If
more
than
one
data
element
is
to
be
input
by
a par
ticular
INPUT#
statement,
each
variable
name
must
be
separated
from
others
byacomma.
EXAMPLES:
To
read
back
in
the
grades
written
with
the
PRINT#
example,
use:
300
FOR
CLASS=1
TO
COURSES
310
INPUT#1,GRADE$(CLASS)
320
GOSUB
59990:REM
CHECK
FOR
DISK
ERRORS
330
NEXT
CLASS
assuming
your
program
includes
an
error
check
subroutine
like
the
one
in
the
last
chapter.
To
read
back
in
the
address
data
written
by
another
PRINT#
ex
ample,
it
is
safest
to
use:
800
INPUT#5,NAME$
810
GOSUB
59990:REM
CHECK
FOR
DISK
ERRORS
820
INPUT#5,STREET$
830
GOSUB
59990:REM
CHECK FOR
DISK
ERRORS
840
INPUT#5,CITY$
850
GOSUB
59990:REM
CHECK FOR
DISK
ERRORS
but
many
programs
cheat
on
safetyabit
and
use
800
INPUT#5,NAME$,STREET$,CITY$
810
GOSUB
59990:REM
CHECK
FOR
DISK
ERRORS
This
is
done
primarily
when
top
speed
in
the
program
is
essential,
and
there
is
little
risk
of
reading
improper
data
from
the
file.
MORE
ABOUT
INPUT#
After
you
begin
using
data
files
regularly,
you
may
encounter
two
BASIC
error
messages.
They
are
"STRING
TOO
LONG
ERROR"
and
"FILE
DATA
ERROR".
Both
are
likely
to
halt
your
program
at
an
45

those
data
elements
to
be
read
back
intoanumeric
variable
by
INPUT#
later,
although
file
data
errors
may
be
avoided
by
reading
all
data
in
as
strings,
and
converting
to
numbers
using
the
VAL
()
function
after
the
information
is
inside
the
computer.
For
example,
"N$=RIGHT$(STR$(N)J£N(STR$(N))-1)"
will
convertapositive
numberNintoastring
N$
without
the
usual
leading
space
for
its
numeric
sign.
Then
instead
of
writing
PRINT#5,N,
you
would
use
PRINT#5,N$.
READING
FILE
DATA:
USING
GET#
The
GET#
statement
retrieves
data
from
the
disk
drive,
one
character
atatime.
Like
the
similar
keyboard
GET
statement
in
BASIC,
it
only
accepts
a
single
character
intoaspecified
variable.
However,
unlike
the
GET
statement,
it
doesn't
just
fall
through
to
the
next
statement
if
there
is
no
data
to
be
gotten.
The
primary
use
of
GET#
is
to retrieve
from
diskette
any
data
that
cannot
be
read
into
an
INPUT#
statement,
either
because
it
is
too
long
to
fit
in
the
input
buffer
or
because
it
includes
troublesome
characters.
FORMAT
FOR
THE
GET#
STATEMENT:
GET#file#,variable
list
where
"file
#"
is
the
same
file
number
given
in
the
desired
file's
current
OPEN
statement,
and
'Variable
list"
is
one
or
more
valid
BASIC
variable
names.
If
more
than
one
data
element
is
to
be
input
by
a
particular
GET#
statement,
each
variable
name
must
be
separated
from
others
byacomma.
In
practice,
you
will
almost
never
seeaGET
or
GET#
statement
containing
more
than
one
variable
name.
If
more
than
one
character
is
needed,aloop
is
used
rather
than
additional
variables.
Also
as
in
the
INPUT#
statement,
it
is
safer to
use
string
variables
when
the
file
to
be
read
might
containanon-numeric
character.
Data
inaGET#
statement
comes
in
byte-by-byte,
including
such
normally
invisible
characters
as
the
Carriage
Return,
and
the
various
cursor
controls.
All
but
one
will
be
read
properly.
The
exception
is
CHR$(0),
the
ASCII
Null
character.
It
is
different
from
an
empty
string
(one
of
the
form
A$=""),
even
though
empty
strings
are
often
re
ferred
to
as
null
strings.
Unfortunately,
inaGET#
statement,
CHR$(0)
is
converted
into
an
empty
string.
The
cure
is
to
test
for
an
empty
string
afteraGET#,
and
replace
any
that
are
found
with
CHR$(0)
instead.
The
first
example
below
illustrates
the
method.
48

DEMONSTRATIONOFSEQUENTIAL
FILES
(BASIC
7.0)
Use
the
following
program
for
your
first
experiments
with
sequen
tial files.
Comments
have
been
addedtohelp
you
better
understand
it.
150CR$=CHR$(13)
170
PRINT
CHR$(147):REM
CLEAR
SCREEN
190
PRINT
"**
WRITEAFILE
**"
210
PRINT
220
DOPEN
#2,"@SEQ
FILE",W
230
GOSUB
500
240
PRINT'ENTERAWORD,
THENANUMBER"
250
PRINT'OR
'END,0'TOSTOP"
260
PRINT
270
INPUT
A$,B
280
PRINT#2A$;CR$;B
290
GOSUB
500
300IFA$O"END"
THEN
270
310
PRINT
320
DCLOSE
#2
340
PRINT
"**
READ SAME
FILE
BACK
**"
360
PRINT
370
DOPEN
#2,"SEQ
FILE"
380
GOSUB
500
390
INPUT#2A$3
400RS=ST
410
GOSUB
500
420
PRINT
A$,B
430IFRS=0
THEN
390
440IFRSO64
THEN
PRINT"STATUS
=
";RS
450
DCLOSE
#2
460
END
480
REM**ERROR
CHECK
S/R
**
500IFDS>0
THEN
PRINT
DS$:STOP
510
RETURN
Makeacarriage
return
variable
Open
demo
file
with
replace
Check
for
disk
errors
Acceptastring&number
from
keyboard
Write
themtothe
disk
file
Until
finished
Tidy
up
Reopen
same
file
for
reading
Read
next
string&number
from
file
Remember
file
status
Display
file
contents
until
done,
unless
there'sanerror
Then
quit
51

where
"file
#"
is
the
file
number,
normally
an
integer
between1and
127;
"device
#"
is
the
device
number
to
be
used,
normally
8
on
the
1581;
"channel
#"
selects
a
particular
channel
along
which
communi
cations
for
this
file
can
take
place,
normally
between2and
14;
"drive
#"
is
the
drive
number,
always0on
the
1581;
and
"file
name"
is
the
name
of
the
file,
withamaximum
length
of
16
characters.
Pattern
matching
characters
are
allowed
in
the
name
when
accessing
an
existing
file,
but not
when
creating a
new
one.
The
record
length
is
the
size
of
each
record
within
the
file
in
bytes
used,
including
carriage
returns,
quotation
marks
and
other
special
characters.
-NOTE
•
Do
not
precede
the
file
name
(in
BASIC
7.0)
or
the
drive
number
(in
BASIC
2.0)
with
the
"at"
sign
(@);
there
is
no
reason
to
replacearelative
file.
•Lrecord
length
(in
BASIC
7.0)
or,L,"+CHR$(rec-
ord
length)
(in
BASIC
2.0)
is
only
required
whenarelative
file
is
first
created,
though
it
may
be
used
later,
so long
as
the
record
length
is
the
same
as
when
the
file
was
first
created.
Since
relative
files
may
be
read
from
or
written
to
alternately
and
with
equal
ease,
there
is
no
need
to
specify
Read
or
Write
mode
when
openingarelative
file.
•
"file
#",
"device
#"
and
"channel
#"
must
be
valid
numeric
constants,
variables
or
expressions.
The
rest
of
the
command
must
beavalid
string
literal,
variable
or
expres
sion.
In
BASIC
7.0
DOPEN,
wheneveravariable
or
expres
sion
is
used
asafile
name
it
must
be
surrounded
by
parentheses.
EXAMPLES:
To
create
or
reopenarelative
file
named
"GRADES",
of
record
length
100,
use:
N
BASIC
7.0:
DOPEN#2,"GRADES",L100,D0,U8
BASIC
2.0:
OPEN
2,8,2,"GRADES,L,"
+
CHR$(100)
To
reopen
an
unknown
relative
file
of
the
user's
choice
that
has
already
been
created,
use:
BASIC
7.0:
200
INPUT"WHICH
FILE";FI$
210
DOPEN#5,(FI$),D0,U8
55

inputsarecord
number
and
converts
it
into
the
required
low-byte/
high-byte
form:
450
INPUTRECORD
NUMBER
DESIRED";RE
460
IF
RE<1
OR
RE>65535
THEN
450
470RH=INT(RE/256)
480RL=RE-256*RH
490
PRINT#15,
"P"
+CHR$(98)+CHR$(RL)+CHR$(RH)
Assuming
RH
and
RL
are
calculated
as
in
the
previous
example,
programs
may
also
use
variables
for
the
channel,
record,
and
offset
required:
570
INPUT
"CHANNEL,
RECORD,&OFFSET
DESIRED";CH,RE,OF
630
PRINT#15,
"P"
+
CHR$
(CH+96)+CHR$(RL)+CHR$(RH)+CHR$(OF)
COMPLETING
RELATIVE
FILE
CREATION
Now
that
you
have
learned
how
to
use
both
the
Open
and
Re-
cord#
commands,
you
are
almost
ready
to
properly
createarelative
file.
The
only
additional
fact
you
need
to
know
is
that
CHR$(255)
is
a
special
character
inarelative
file.
It
is
the
character
used
by
the
DOS
to
fill
relative
records
as
they
are
created,
beforeaprogram
fills
them
with
other
information.
Thus,
if
you
want
to
write
the
last
record,
you
expect
to
need
in
your
file
with
dummy
data
that
will
not
interfere
with
your
later
work,
CHR$(255)
is
the
obvious
choice.
Here
is
how
it
works
in
an
actual
program
which you
may
copy
for
use
in
your
own
relative
file
programs.
BASIC
2.0:
1020
OPEN
15,8,15
Open
command
channel
1380
INPUT'ENTER
RELATIVE
FILE
NAME";FI$
Select
file
parameters
1390
INPUT'ENTER
MAX.#OF
RECORDS";NR
1400
INPUT'ENTER
RECORD
LENGTH";RL
1410
OPEN
l,8,2,"0:"
+
FI$+"JL,"+CHR$(RL)
Begintocreate
desired
file
1420
GOSUB
59990
Check
for
disk errors
1430RH=
INT(NR/256)
Calculate
length
values
144ORL=NR-256*RH
1450
PRINT#15,"P"
+
CHR$(96+2)
+
CHR$(RL)+CHR$(RH)
Positiontolast
record
number
1455
PRINT#15,"P"
+
CHR$(96+2)
+
Re-position
for
safety
CHR$(RL)+CHR$(RH)
1460
GOSUB
59990
1470
PRINT#1
,CHR$(255);
Send
default
character
to
it
58

180
INPUTCITY&STATE";
CS$
190IFLEN(CS$)>25
THEN
180
200
INPIITZIP
CODE";ZP$
210IFLEN(ZP$)>10
THEN
200
220
DA$=NA$+CR$+SA$+CR$+CS$+CR$;ZP$
230IFLEN(DA$)<88
THEN
260
240
PRINT'RECORD
TOO
LONG"
250
GOTO
140
260:
270:
280
RECORD#3,(RE),1
290
IFDS=50THENPRINT#3,CHR$(255):GOSUB1000:GOTO280
300
GOSUB1000
310
PRINT#3,DA$
320
GOSUB1000
330
RECORD#3,(RE),1
340
GOSUB1000
350
DaOSE3:END
1000
IFDS<20
THEN
RETURN
1002:
1010
PRINTDS$:DCLOSE3:END
BASIC
2.0:
100
INPUT'ENTER
RECORD
NUMBER";RE
110
OPEN
15,8,15
120
OPEN3,8,3,UMYRELFILE,L,"
+
CHR$(88)
130CR$=CHR$(13)
140
INPUT'NAME";
NA$
150IFLEN(A$)>30
THEN
140
160
INPUrSTREET";SA$
170IFLEN(SA$)>30
THEN
160
180
INPUT"CITY&STATE";
CS$
190IFLEN(CS$)>25
THEN
180
200
INPUT"ZIP
CODE";ZP$
210IFLEN(ZP$)>10
THEN
200
220
DA$=NA$+CR$+SA$+CR$+CS$+CR$;ZP$
230IFLEN(DA$)<88
THEN
260
240
PRINT"RECORD
TOO
LONG"
250
GOTO
140
260RH=INT(RE/256)
270RL=RE-256*RH
280
PRINT#15,"P"
+
CHR$(96+3)+CHR$(RL)
+
CHR$(RH)+CHR$(1)
290
GOSUB1000:IFEN=
50THENPRINT#3,CHR$(255):GOSUB1000:GOTO280
300
GOSUB1000
310
PRINT#3,DA$
320
GOSUB1000
330
PRINT#15,<<P"
+
CHR$(96+3)+CHR$(RL)+CHR$(RH)+CHR$(1)
340
GOSUB1000
350
CLOSE3:CLOSE15:END
1000
INPUT#15,EN,EM$,ET,ES
1002IFEN<20
THEN
RETURN
1010
PRINTEM$:CLOSE3:CLOSE15:END
62

To
use
the
above
program
lines
for
the
version
with
fixed
length
fields,
we
would
alterafew
lines
as
follows:
BASIC
7.0:
100
INPUT'ENTER
RECORD
NUMBER";RE
110:
120
DOPEN#3,"MYRELFILE",L88
130
BL$="(27
shifted
space
chars)"
140
INPUT'NAME";
NA$
145LN=LEN(NA$)
150IFLEN>27
THEN
140
155
NA$=NA$+LEFT$(BL$,27
-
IN)
160
INPUT"STREET";SA$
165LN=LEN(SA$)
170IFLEN>27
THEN
160
175
SA$=SA$+LEFT$(BL$,27
-
LN)
180
INPUrCITY&STATE";
CS$
185LN=LEN(CS$)
190IFLEN>23
THEN
180
195
CS$=CS$+LEFT$(BL$,23
-
LN)
200
INPUTZIP
CODE";ZP$
205LN=LEN(ZP$)
210IFLN>10THEN200
215
ZP$=ZP$+LEFT$(BL$,10-LN)
220
DA$=NA$+SA$+CS$+ZP$
260:
270:
280
RECORD#3,(RE),1
290
IFDS=50THENPRINT#3,CHR$(255):GOSUB1000:GOTO280
300
GOSUB1000
310
PRINT#3,DA$
320
GOSUB1000
330
RECORD#3,(RE),1
340
GOSUB1000
350
DCLOSE#3:END
1000
IFDS<20
THEN
RETURN
1002:
1010
PRINT'ERROR:"DS$:DCLOSE#):END
BASIC
2.0:
100
INPUT'ENTER
RECORD
NUMBER";RE
110
OPEN
15,8,15
120
OPEN#3,8,3,"MYRELFILE>L,"
+
CHR$(88)
130
BL$="(27
shifted
space
chars)"
140
INPUT"NAME";
NA$
145LN=LEN(NA$)
15OIFLEN>27THEN14O
155
NA$=NA$+LEFT$(BL$,27
-
LN)
160
INPUT"STREET";SA$
165LN=LEN(SA$)
63

170IFLEN>27
THEN
160
175
SA$=SA$+LEFT$(BL$,27
-
LN)
180
INPUT'CITY&STATE";
CS$
185LN=LEN(CS$)
190IFLN>23THEN180
195
CS$=CS$+LEFT$(BL$,23
-
LN)
200
INPtTTZIP
CODE";ZP$
205LN=LEN(ZP$)
210IFLN>10THEN200
215
ZP$=ZP$+LEFT$(BL$,10
-
LN)
220
DA$=NA$+SA$+CS$+ZP$
260RH=INT(RE/256)
270RL=RE-256*RH
280
PRINT#15,"P"
+
CHR$(96+3)+CHR$(RL)+CHR$(RH)+CHR$(1)
290
GOSUB1000:IFEN=
50THENPRINT#3)CHR$(255):GOSUB1000:GOTO280
300
GOSUB1000
310
PRINT#3,DA$
320
GOSUB1000
330
PRINT#15,"P"
+
CHR$(96+3)+CHR$(RL)
+
CHR$(RH)+CHR$(1)
340
GOSUB1000
350
GOSUB1000:aOSE3:aOSE15:END
1000
INPUT#15,EN,EM$,ET,E
1002IFEN<20
THEN
RETURN
1010PRINT"ERROR;"EM$:aOSE3:aOSE15:END
If
field
contents
vary
in
length,
variable
field
lengths
are
often
preferable.
On
the
other
hand,
if
the
field
lengths
are
stable,
fixed
field
lengths
are
preferable.
Fixed
length
fields
are
also
required
if
you
want
to
use
die
optional
offset
parameter
of
the
RECORD#
command
to
point
ataparticular
byte
withinarecord.
However,
when
any
part
of
a
record
is
written,
DOS
overwrites
any
remaining
spaces
in
the
record.
Thus,
if
you
must
use
the
offset
option,
never
update
any
field
inarecord
other
than
the
last
one
unless
all
succeeding
fields
will
also
be
updated
from
memory
later.
The
above
programs
are
careful
to
match
record
lengths
exactly
to
the
space
available.
Programs
that
don't
do
so
will
discover
that
DOS
pads
short
records
out
to
full
size
with
fill
characters,
and
truncates
overlong
records
to
fill
only
their
allotted
space.
When
a
record
is
truncated,
DOS
will
indicate
error
51,
"RECORD
OVER
FLOW,"
but
short
records
will
be
accepted
withoutaDOS
error
message.
READINGARELATIVE
RECORD
Oncearelative
record
has
been
written
properly
to
diskette,
reading
it
back
into
computer
memory
is
fairly
simple,
but
the
proce
dure
again
varies,
depending
on
whether
it
uses
fixed
or
variable
length
fields.
Here
are
the
program
lines
needed
to
read
back
the
64

variable
fields
created
above
from
record
number
RE
in
file
and
channel
3:
BASIC
7.0:
10:
20
DOPEN#3,"MYRELFILE",L88
30
INPUT'ENTER
RECORD
NUMBERM;RE
40:
50:
60
RECORD#3,(RE),1
70
GOSUB1000
80
INPUT#3,NA$,SA$,CS$,ZP$
90
GOSUB1000
100
RECORD#3,(RE),1
110GOSUB1000
120
PRINTNA$:PRINTSA$
130
PRINTCS$:PRINTZP$
140
DCLOSE#3:END
1000
IFDS<20
THEN
RETURN
1002:
1010
PRINTUERROR:"DS$:DCLOSE#3:END
BASIC
2.0:
10
OPEN
15,8,15
20
OPEN3,8,3,ttMYRELFILE,L;'
+CIIR$(88)
30
INPUT
ENTER
RECORD
NUMBER";RE
40RH=INT(RE/256)
50RL=RE-256*RH
60
PRINT#15,4<P"
+CIIR$(96+3)+CI
IR$(RL)+CI
IR$(RII)+CIIR$(
1)
70
GOSUB1000
80
INPUT#3,NA$,SAJ,CS$,ZPS
90
GOSUB1000
110GOSUB1000
120
PRINTNA$:PRINTSA$
130
PRINTCS$:PRINTZP$
140
CLOSE3:CLOSE15:END
1000
INPUT#15,EN,EM$,ET,ES
1002IFEN<20
THEN
RETURN
1002
PRINTI4ERROR:1'EM$:CLOSE3:CLOSE15:END
READY.
65

Here
are
the
lines
needed
to
read
back
the
version
with
fixed
length
fields:
BASIC
7.0:
10:
20
DOPEN#3,"MYRELFBLE'%88
30
INPUT'ENTER
RECORD
NUMBER";RE
40:
50:
60
RECORD#3,(RE),1
70
GOSUB1000
80
INPUT#3,DA$
90
GOSUB1000
100
RECORD#3,(RE),1
110GOSUB1000
112NA$=LEFT$(DA$,27)
114
SA$=MID$(DA$,28,27)
116
CS$=MID$(DA$,55,23)
118
ZP$=RIGHT$(DA$,10)
120
PRINTNA$:PRINTSA$
130
PRINTCS$:PRINTZP$
140
DCLOSE#3:END
1000
IFDS<20
THEN
RETURN
1002:
1010
PRINT"ERROR:"DS$:DCLOSE#3:END
BASIC
2.0:
10
OPEN
15,8,15
20 OPEN3,8,3,"MYRELFILE,L"
4-
CHR$(88)
30
INPUT'ENTER
RECORD
NUMBER";RE
40RH=INT(RE/256)
50RL=RE-256*RH
60
PRINT#15/lP"
+
CHR$(96+3)+CHR$(RL)+CHR$(RH)+CHR$(1)
70
GOSUB1000
80
INPUT#3,DA$
90
GOSUB1000
100
PRINT#
15,"?"+CHR$(96+3)+CHR$(RL)+CHR$(RII)4-CIIR$(
1)
110GOSUB1000
112
NA$=LEFT$(DA$,27)
114
SA$=MID$(DA$,28,27)
116CS$=MID$(DA$,55,23)
118
ZP$=RIGHT$(DA$,10)
120
PRINTNA$:PRINTSA$
130
PRINTCS$:PRINTZP$
140
CLOSE3:CLOSE15:END
1000
INPUT#15,EN,EM$,ET,ES
1002IFEN<20
THEN
RETURN
1002
PRINTltERROR:"EM$:CLOSE3:CLOSE15:END
READY.
66

As
the
loop
progresses,
the
contents
of
the
specified
track
and
sector
are
copied
into
computer
memory,
beginning
at
the
address
set
by
variable
MB
in
line
160,
and
may
be
examined
and
altered
there.
The
DOS
always
checks
that
the
track
and
sector
parameters
of
the
BLOCK-READ
command
are
within
the
proper
range.
If
they're
not,
a
"66
ILLEGAL
TRACK
AND
SECTOR"
error
occurs.
In
certain
instances
it
might
be
necessary
to
accessatrack
and
sector
that
are
not
within
what
the
DOS
considers
the
proper
bounds.
This
isaspecial
case
and,
un
less
absolutely
necessary,
should
be
avoided.
Nonetheless, there
is
a
command
identical
in
function
to
"Ul"
that
doesn't
check
to
see
if
the
track
and
sector
parameters
are.
within
bounds
before
attempting
to
read
it.
Its
format
is:
PRINT#15,"B-_";channel
#;track
#;sector
#
(The
character
following
the
B-
isashifted
R.)
or
PRINT#15,"B-";CHR$(210);channel
#;track
#;sector
#
BLOCK-WRITE
The
purpose
ofaBLOCK-WRITE
is
to
save
the
contents
ofafile
buffer
intoaspecified
sector.
It
is
thus
the
reverse
of
the
BLOCK-READ
command.
Although
the
BLOCK-WRITE
command
(B-W)
is
still
part
of
the
DOS
command
set,
it
is
nearly
always
replaced
by
the
U2
com
mand.
FORMAT FOR
THE
BLOCK-WRITE
COMMAND:
PRINT#15,"U2";channel
#;drive
#;track
#;sector
#
where
"channel
#"
is
the
channel
number
specified
when
the
file
into
which
the
block
will
be
read
was
opened;
"drive
#"
is
the
drive
number;
and
"track
#"
and
"sector
#"
are
respectively
the
track
and
sector
numbers
that
should
receive
the
block
of
data
being
saved
from
the
file
buffer.
ALTERNATE
FORMATS:
PRINT#15,"U2:"channel
#;drive
#;track
#;sector
#
PRINT#15,"UB:"channel
#;drive
#;track
#;sector
#
PRINT#15,"U2:channel
#,drive
#,track
#,sector
#"
71

EXAMPLES:
To
restore
track
40,
sector
3 of
the
directory
from
the
disk
buffer
filled
byaBLOCK-READ,
use:
PRINT#15,"U2";5;0;40;3
You'll
return
to
this
example
on
the
next
page,
after
you
learn
to
alter
the
directory
inauseful
way.
You
can
also
useaBLOCK-WRITE
to
write a
name
in
Track
1,
Sector
1,ararely-used
sector.
This
can
be
used
asaway
of
marking
a
diskette
as
belonging
to
you.
Here
isaprogram
to
do
it,
using
the
alternate
form
of
the
BLOCK-WRITE
command:
110
INPUT"YOUR
NAME";NA$
Enteraname.
120
OPEN
15,8,15
Open
command
channel.
130
OPEN
4,8,4,"#"
Open
direct
access
channel
140
PRINT#4,NA$
Write
name
to
buffer.
150
PRINT#15,"U2";4;0;l;l
Write
buffer
to
Track
1,
160
CLOSE
4
Sector1of
diskette.
170
CLOSE
15
Tidy
up
after.
180
END
As
with
the
BLOCK-READ
command,
there
isaBLOCK-WRITE
com
mand
identical
in
function
to
"U2"
that
does
not
check
the
track
and
sector
parameters
for
valid
bounds
before
attempting
to
write
the
sector.
Its
format
is:
PRINT#15,"B-on;channel
#;drive
#;track
#;sector
#
(The
character
after
the
B-
isashifted
W.)
or
PRINT#15,uB-";CHR$(215);channel
#;track
#;sector
#
THE
ORIGINAL
BLOCK-READ
AND
BLOCK-WRITE
COMMANDS
Although
the
BLOCK-READ
and
BLOCK-WRITE
commands
are
nearly
always
replaced
by
the
Ul
and
U2
commands
respectively,
the
original
commands
can
still
be
used,
as
long
as
you
fully
understand
their
effects.
Unlike
Ul
and
U2,
B-R
and
B-W
allow
you
to
read
or
write
less
thanafull
sector.
In
the
case
of
B-R,
the
first
byte
of
the
selected
sector
is
used
to
set
the
buffer
pointer
(see
next
section),
and
deter-
72

mines
how
many
bytes
of
that
sector
are
read
intoadisk
memory
buffer.
A
program
may
check
to
be
sure
it
doesn't
attempt
to
read
past
the
end
of
data
actually
loaded
into
the
buffer,
by
watching
for
the
value
of
the
file
status
variable
ST
to
change
from0to
64.
When
the
buffer
is
written
back
to
diskette
by
B-W,
the
first
byte
written
is
the
current
value
of
the
buffer
pointer.
Only
that
many
bytes
are
written
into
the
specified
sector.
B-R
and
B-W
may
thus
be
useful
in
working
with
custom-designed
file
structures.
FORMAT
FOR
THE
ORIGINAL
BLOCK-READ
AND
BLOCK-WRITE
COMMANDS:
PRINT#15,"BLOCK-READ";channel
#;drive
#;track
#;sector
#
abbreviated
as:
PRINT#15,UB-R";channel
#;drive
#;track
#;sector
#
and
PRINT#15,uBLOCK-WRITE";channel
#;drive
#;track
#;sector
#
abbreviated
as:
PWNT#15,"B-W";channel
#;drive
#;track
#;sector
#
where
"channel
#"
is
the
channel
number
specified
when
the
file
into
which
the
block
will
be
read
was
opened,
"drive
#"
is
the
drive
number,
and
"track
#"
and
"sector
#"
are
the
track
and
sector
numbers
containing
the
desired
block
of
data
to
be
partially
read
into
or
written
from
the
file
buffer.
-NOTE
Inatrue
BLOCK-READ,
the
first
byte
of
the
selected
sector
is
used
to
determine
how
many
bytes
of
that
sector
to
read
into
the
disk
memory
buffer.
It
thus
cannot
be
used
to
read
an
entire
sector
into
the
buffer,
as
the
first
data
byte
is
always
interpreted
as
being
the
number
of
characters
to
read,
rather
than
part
of
the
data.
Similarly,
inatrue
BLOCK-WRITE,
when
the
buffer
is
written
back
to
diskette,
the
first
byte
written
is
the
current
value
of
the
buffer
pointer.
Only
that
many
bytes
are written
into
the
specified
sector.
It
cannot
be
used
to
rewrite
an
entire
sector
onto
diskette
unchanged,
because
the
first
data
byte
is
overwritten
by
the
buffer
pointer.
73

THE
BUFFER
POINTER
The
buffer
pointer
points
to
where
the
next
READ
or
WRITE
will
begin
withinadisk
memory
buffer.
By
moving
the
buffer
pointer,
you
can
access
individual
bytes
withinablock
in
any
order.
This allows
you
to
edit
any
portion
ofasector,
or
organize
it
into
fields,
likearelative
record.
FORMAT
FOR THE
BUFFER-POINTER
COMMAND:
PRINT#15,uBUFFER-POINTERn;channel#;byte
usually
abbreviated
as:
PRINT#15,"B-P";channel
#;byte
where
"channel
#"
is
the
channel
number
specified
when
the
file
reserving
the
buffer
was
opened,
and
ubyte"
is
the
character
number
within
the
buffer
at
which
to
point
(from0through
255).
ALTERNATE
FORMATS:
PRINT#15,"B-P:"channel
#;byte
PRINT#15,"B-P:channel
#;byte"
EXAMPLE:
Here
isaprogram
that
locks
the
first
program
or
file
onadiskette.
It
works
by
reading
the
start
of
the
directory
(Track
40,
Sector
3)
into
disk
memory,
setting
the
buffer
pointer
to
the
first
file
type
byte
(see
AppendixCfor
details
of
directory
organization),
locking
it
by
setting
bit6and
rewriting
it.
110
OPEN
15,8,15
Open
command
channel.
120
OPEN
5,8,5,"#"
Open
direct
access
channel.
130
PRINT#15/'Ul";5;0;40;3
Read
Track
40,
Sector
3.
140
PRINT#15,"B-P";5;2
Point
to
Byte2of
the
buffer.
15OGET#5A$:IFA$
=
""
THEN
A$=CHR$(0)
Read
it
into
memory.
160
A=ASC(A$)
OR
64
Turn
on
bit6to
lock.
170
PRINT#15,"B-P";5;2
Point
to
Byte2again.
180
PRINT#5,CHR$(A);
Overwrite
it
in
buffer.
190
PRINT#15,uU2";5;0;40;3
Rewrite
buffer
to
diskette.
200
CLOSE
5
Tidy
up
after.
210
CLOSE
15
220
END
74

After
the
above
program
is
run,
the
first
file
on
that
diskette
can
no
longer
be
erased.
If
you
later
need
to
erase
that
file,
rerun
the
same
program,
but
substitute
the
revised
line
160
below
to
unlock
the
file
again:
160
A=ASC(A$)
AND
191
Turn
off
bit6to
unlock
ALLOCATING
BLOCKS
Once
you
have
written
something
inaparticular
sector
on
a
diskette
with
the
help
of
direct
access
commands,
you
may
wish
to
mark
that
sector
as
"already
used",
to
keep
other
files
from
being
written
there.
Blocks
thus
allocated
will
be
safe
until
the
diskette
is
validated.
FORMAT
FOR
BLOCK-ALLOCATE
COMMAND:
PRINT#15,uBLOCK-ALLOCATE";drive
#;
track
#;sector
#
usually
abbreviated
as:
PRINT#15,"B-A";drive
#;
track
#;sector
#
where
"drive
#"
is
the
drive
number,
and
"track
#"
and
"sector
#"
are
the
track
and
sector
containing
the
block
of
data
to
be
read
into
the
file
buffer.
ALTERNATE
FORMAT:
PRINT#15,"B-A:";drive
#;
track
#;sector
#
EXAMPLE:
If
you
try
to
allocate
a
block
that
isn't
available,
the
DOS
will
set
the
error
message
to
number
65,
NO
BLOCK,
and
set
the
track
and
block
numbers
in
the
error
message
to
the
next
available
track
and
block
number.
Therefore,
before
selecting
a
«block
to
write,
try
to
allocate
that
block.
If
the
block
isn't
available,
read
the
next
available
block
from
the
error
channel
and
allocate
it
instead.
However,
do
not
allocate
data
blocks
in
the
directory
track.
If
the
track
number
re
turned
is
0,
the
diskette
is
full.
Here
isaprogram
that
allocates
a
place
to
storeamessage
on
a
diskette.
100
OPEN15,8,15
Open
command
channel.
110
OPEN5,8,5,"#"
"
direct
access
"
75

120
PRINT#5,"I
THINK
THEREFOREIAM"
Writeamessage
to
buffer.
130T=1:S=1
Start
at
first
track§or.
140
PRINT#15,"B-A";0;T;S
Try
allocating
it.
150
INPUT#15,EN,EM$,ET,ES
See
if
it
worked.
160
IF
EN=0
THEN
210
If
so,
we're
almost
done.
170
IF
ENO65
THEN
PRINT
"NO
BLOCK"
EN,EM$,ET,ES:STOP
means
already
allocated.
180
IF
ET=0
THEN
PRINT
"DISK
FULL":STOP
If
next
track
is
0,
we're
out
of
room.
190
IF
ET=40
THEN
ET=4l:ES=0 Don't
allocate
the
directory.
200
T=ET:S=ES:GOTO
140 Try
suggested
track§or
next.
210
PRINT#15,"U2";5;0;T;S
Write
buffer
to
allocated
sector.
220
PRINT
"STORED
AT:",T,S
Say
where
message
went
230
CLOSE
5:CLOSE
15
and
tidy
up.
240
END
FREEING
BLOCKS
The
BLOCK-FREE
command
is
the
opposite of
BLOCK-ALLOCATE.
It
freesablock
that
you
don't
need
any
more,
for
re-use
by
the
DOS.
BLOCK-FREE
updates
the
BAM
to
showaparticular
sector
is
not
in
use,
rather
than
actually
erasing
any
data.
FORMAT
FOR
BLOCK-FREE
COMMAND:
PRINT#15,uBLOCK-FREE";drive
#;track
#;sector
#
abbreviated
as:
PRINT#15,"B-F";drive
#;track
#;sector
#
where
"drive
#"
is
the
drive
number,
and
"track
#"
and
"sector
#"
are
respectively
the
track
and
sector
numbers
containing
the
desired
block
of
data
to
be
read
into
the
file
buffer.
ALTERNATE
FORMAT:
PRINT#15,"B-F:'';drive
#;track
#;sector
#
EXAMPLE:
To
free
the
sector
in
which
we
wrote
our
name
in
the
BLOCK
WRITE
example,
and
allocated
in
the
first
BLOCK-ALLOCATE
example,
we
could
use
the
following
command:
PRINT#15/'B-F";0;l;l
76

PARTITIONS
and
SUB-DIRECTORIES
The
1581
allows
the
user
to
create
partition
areas
on
the
disk.
Partitions
were
originally
implemented
to
provideamechanism
for
easily
protecting
a
particular
section
of
the
disk.
That
is
useful
for
permanently
allocating
part
of
the
disk
for
things
such
as
BOOT
sectors,
CP/M
work
area,
or
reserving
space
for
user
defined
random
files.
Normally,
sectors
on
the
disk
can
be
marked
as
used by
setting
the
appropriate
bit
in
the
BAM
(most
easily
done
with
the
BLOCK-
ALLOCATE
command).
That
prevents
them
from
being
overwritten.
A
VALIDATE
command,
however,
will
de-allocate
this
area.
To
protect
these
special
blocks
from
being
de-allocated
duringaVALIDATE,
place
them
inauser
defined
partition
area.
The
VALIDATE
command
in
the
1581
automatically
skips
over
file
entries
that
are
partition
files
(file
type=CBM),
which
guarantees
the
intended
area
is,
and
remains,
allocated.
Partition
areas
are
given
names
by
the
user
when
first
created.
They
appear
in
the
main
directory
as
file
type
CBM.
A
partition
area
is
created
by
the
following
command
(file#
should
be
opened
to
the
command
channel):
PRINT#file#,"/0:partition
name,"+CHR$(starting
track)
+
CHR-
$(starting
sector)
+
CHR$(<#of
sectors)
+
CHR$(>#of
sec
tors)+",C"
Large
enough
partitions
can
also
be
used
as
sub-directories.
There
are,
however,
certain
limitations
ifapartition
area
is
to
be
used
asasub-directory
area:
1)
The
partition
area
must
be
at
least
120
sectors
in
size.
2)
The
starting
sector
must
be
0.
3)
The
ending
sector
must
beamultiple
of
40.
4)
The
area
to
be
allocated
cannot
contain
track
40
(the
original
system
track).
Partitions
can
also
be
created
withapartition.
This
means
that
sub-sub-directories
can
be
created
if
their
partitions
meet
the
above
rules.
Graphically,
it
looks
like
this:
77

FORMAT FOR THE
MEMORY-READ
COMMAND:
PRINT#15,uM-R"CHR$(<addfess)CHR$(>address)CHR$(#
of
bytes)
where
"<address"
is
the
low
order
part,
and
u>address"
is
the
high
order
part
of
the
address
in
disk
memory
to
be
read.
If
the
optional
"#
of
bytes"
is
specified,
it
selects
how
many
memory
locations
will
be
read
in,
from
1-256
(#
of
bytes=0
for
256).
Otherwise,
1
character
will
be
read.
The
next
byte
read
using
the
GET#
statement
through
channel
#15
(the
error
channel),
will
be
from
that
address
in
the
disk
control
ler's
memory,
and
successive
bytes
will
be
from
successive
memory
locations.
Any
INPUT#
from
the
error
channel
will
give
peculiar
results
when
you're
using
this
command.
This
can
be
cleared
up
by
sending
any
other
command
to
the
disk,
except
another
memory
command.
EXAMPLES:
To
see
how
many
tries
the
disk
will
make
to
readaparticular
sector,
and
whether
"bumps"
to
track
one
and
back
will
be
attempted
before
declaring the
sector
unreadable,
you
can use
the
following
lines.
They
will
readaspecial
variable
in
the
zero
page
of
disk
memory,
called
REVCNT.
It
is
located
at
$30
hexadecimal.
110
OPEN
15,8,15
Open
command
channel.
120
PRINT#15/'M-ira
IR$(48)CI
IR$(0)
SameasG=PEEK(
106).
130
GET#15,G$:IFG$=""THENG$=
CIIR$(0)
14OG=ASC(G$)
150B=GAND
128:B$="ON":IFBTIIENB$=
"OFF"
Check
bit
7.
170
T=G
AND
31:PRINT"#OF
TRIES
IS";T
Check
bits
0-5
180
PRINT
"BUMPS
ARE";B$
and
give
results.
200
CLOSE
15
Tidyupafter.
210
END
83

Here'samore
general
purpose
program
that
reads
one
or
more
locations
anywhere
in
disk
memory:
110
OPEN15,8,15
120
INPUT"#OFBYTESTOREAD(0=
END)";NL
130IFNL<1
THEN
CLOSE
15:END
140IFNL>255
THEN
120
150
INPUT'STARTING
AT
ADDRESS";AD
160AH=
INT(AD/256)AL=AD-AH*256
170
PRINT#15,"M-R"CHR$(AL)CHR$(AH)
CHR$(NL)
180
FOR
1=1TONL
190
GET#15A$:IFA$=""THENA$=
CHR$(0)
200
PRINT
ASC(A$);
210
NEXT
I
220
PRINT
230
GOTO
120
Open
command
channel.
Enter
numberofbytes
want
ed
unless
done,
or
way
outofline.
Enter
starting
address.
Convertitinto
disk
form.
Actual
Memory-Read.
Loop
until
have
all
the
data,
printingitaswego,
forever.
MEMORY-WRITE
The
MEMORY-WRITE
command
is
the equivalent
of
the
BASIC
Poke
command,
but
has
its
effect
in
disk
memory
instead
of
within
the
computer.
M-W
allows
you
to
write
up
to
35
bytes
atatime
into
disk
memory.
The
MEMORY-EXECUTE
and
some
User
commands
can
be
used
to
run
any
programs
written
this
way.
FORMAT FOR
THE
MEMORY-WRITE
COMMAND:
PRINT#15,"M-W"CHR$(<address)CHR$(>address)CHR$
(#
of
bytes)CHR$(data
byte(s))
where
"<address"
is
the
low
order
part,
and
">address"
is
the
high
or
der
part
of
the
address
in
disk
memory
to
begin
writing,
"#
of
bytes"
is
the
number
of
memory
locations
that
will
be
written
(from
1-35),
and
"data
byte"
is1or
more
byte
values
to
be
written
into
disk
memory,
each
asaCHR$()
value.
EXAMPLES:
We
can
use
this
line
to
turn
off
the
"bumps"
when
loading
DOS-pro
tected
programs
(i.e.,
programs
that
have
been
protected
against
being
copied
by
creating
and
checking
for
specific
disk
errors).
PRINT#15,"M-W"CHR$(48)CHR$(0)CHR$(1)CHR$(133)
84

The
following
line
can
be
used
to
recover
bad
sectors,
such
as
when
an
important
file
has
been
damaged
and
cannot
be
read
normally.
PRINT#15,"M-W"CHR$(48)CHR$(0)CHR$(1)CHR$(31)
These
two
examples
may
be
very
useful
under
some
circum
stances.
They
are
the
equivalent
of
POKE
48,133
and
POKE
48,31
re
spectively,
but
in
disk
memory,
not
inside
the
computer.
As
mentioned
in
the
previous
section's
first
example,
location
48
in
the
1581
disk
drive
signifies
two
separate
activities
to
the
drive,
all
related
to
error
recovery.
Bit7(the
high
bit),
if
set
means
no
"bumps"
(don't
move
the
read
head
to
track
1).
The
bottom
six
bits
are
the
count
of
how
many
times
the
disk
will
try
to
read
each
sector
before
and
after
trying
seeks
and
bumps
before
giving
up.
Since
31
is
the
largest
number
that
can
be
expressed
in six
bits,
that
is
the
maximum
number
of
tries
allowed.
From
this
example,
you
can
see
the
value
of
knowing
something
about
Peeks,
Pokes,
and
machine-language
before
using
direct-access
disk
commands,
as
well
as
their
potential
power.
MEMOFY-EXECUTE
Any
routine
in
disk
memory,
either
in
RAM
or
ROM,
can
be
ex
ecuted
with
the
MEMORY-EXECUTE
command.
It
is
the
equivalent
of
the
BASIC
Sys
call
toamachine
language
program
or
subroutine,
but
works
in
disk
memory
instead
of
within
the
computer.
FORMAT
FOR THE
MEMORY-EXECUTE
COMMAND:
PRINT#15,"M-E"CHR$(<address)CHR$(>address)
where
"<address"
is
the
low
order
part,
and
">address"
is
the
high
or
der
part
of
the
address
in
disk
memory
at
which
execution
is
to
begin.
Most
uses
require
intimate
knowledge
of
the
inner
workings
of
the
DOS,
and
preliminary
setup
with
other
commands,
such
as
MEMORY-WRITE.
The
routine
should
end
with
an
RTS
to
return
control
to
the
1581.
BLOCK-EXECUTE
This
rarely-used
command
will
loadasector
containing
a
machine
language
routine
intxra
memory
buffer
from
diskette,
and
execute
it
85