mirror of
https://github.com/iKarith/beneath-apple-dos.git
synced 2024-06-08 01:29:43 +00:00
Dump all the documents to text files with markup
Looks like CH4 is somewhat hosed, a small amount of bit rot? Doesn't look like too much actually.
This commit is contained in:
parent
19a429d22c
commit
1d9b739d80
120
D1S1/CH1#064000.txt
Normal file
120
D1S1/CH1#064000.txt
Normal file
|
@ -0,0 +1,120 @@
|
|||
.ec ^
|
||||
.na
|
||||
.ll60
|
||||
.m11
|
||||
.m22
|
||||
.m48
|
||||
.fo ''-%-
|
||||
.pn 5
|
||||
.pi0
|
||||
.br
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 1 - INTRODUCTION
|
||||
.sp 2
|
||||
.pp
|
||||
Beneath Apple DOS is intended
|
||||
to serve as a companion to Apple's
|
||||
DOS Manual, providing additional
|
||||
information for the advanced
|
||||
programmer or
|
||||
the novice Apple user who wants to
|
||||
know more about the structure of
|
||||
diskettes.
|
||||
It is not the intent of this manual
|
||||
to replace the documentation provided
|
||||
by Apple Computer Inc.
|
||||
Although, for the
|
||||
sake of
|
||||
continuity, some of the material
|
||||
covered in the Apple manual is also
|
||||
covered here, it will be assumed that
|
||||
the reader is reasonably familiar
|
||||
with the
|
||||
contents of the DOS Manual. Since
|
||||
all chapters presented here may not
|
||||
be of use to each Apple owner, each
|
||||
has been written to stand on its own.
|
||||
.pp
|
||||
The information presented here is a
|
||||
result of intensive disassembly and
|
||||
annotation of various versions of DOS
|
||||
by the authors and by other
|
||||
experienced systems programmers.
|
||||
It also draws from application notes,
|
||||
articles, and discussions with
|
||||
knowledgeable people. This
|
||||
manual was not prepared with the
|
||||
assistance of Apple Computer Inc.
|
||||
Although no
|
||||
guarantee can be made concerning the
|
||||
accuracy of the information
|
||||
presented here, all of the material
|
||||
included in Beneath Apple DOS has
|
||||
been thoroughly researched and
|
||||
tested.
|
||||
.pp
|
||||
There were several reasons
|
||||
for writing Beneath Apple DOS:
|
||||
.SP1
|
||||
.nf
|
||||
To show direct assembly language access to DOS.
|
||||
.br
|
||||
To help you to fix clobbered diskettes.
|
||||
.br
|
||||
To correct errors and omissions in the Apple documentation.
|
||||
.br
|
||||
To allow you to customize DOS to fit your needs.
|
||||
.br
|
||||
To provide complete information on diskette formatting.
|
||||
.br
|
||||
.pp
|
||||
When Apple Computer Inc. introduced
|
||||
its Disk Operating System (DOS)
|
||||
version 3 in 1978 to support the
|
||||
new DISK II drive, very little
|
||||
documentation was provided. Later,
|
||||
when DOS 3.2 was released, a 178 page
|
||||
instructional and reference manual
|
||||
became available covering the
|
||||
use of DOS from BASIC in depth and
|
||||
even touched upon some of the
|
||||
internal workings of DOS. With the
|
||||
advent of DOS 3.3, the old 3.2 manual
|
||||
was updated but the body of
|
||||
information in it remained
|
||||
essentially intact. Beyond these
|
||||
Apple manuals,
|
||||
there have been no significant
|
||||
additions to the documentation on
|
||||
DOS,
|
||||
apart from a few articles in APPLE
|
||||
user group magazines and newsletters.
|
||||
This manual takes up
|
||||
where the
|
||||
Disk Operating System
|
||||
Manual leaves off.
|
||||
.bp
|
||||
.pp
|
||||
Throughout this manual, discussion
|
||||
centers primarily on DOS version
|
||||
3.3. The reasons for this are that 3.3
|
||||
was the most recent release of DOS at
|
||||
the time of this writing and that it
|
||||
differs less from DOS 3.2 than one
|
||||
would imagine. Wherever there is a
|
||||
major difference between the various
|
||||
DOS releases in a given topic, each
|
||||
release will be covered.
|
||||
.pp
|
||||
In addition to the DOS dependent
|
||||
information provided, many of the
|
||||
discussions also apply to
|
||||
other operating systems on the Apple
|
||||
II and Apple III. For example,
|
||||
disk formatting at
|
||||
the track and sector level is, for
|
||||
the most part, the same.
|
||||
.br
|
||||
.nx ch2
|
||||
\x00
|
249
D1S1/CH2#064000.txt
Normal file
249
D1S1/CH2#064000.txt
Normal file
|
@ -0,0 +1,249 @@
|
|||
.bp
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 2 - THE EVOLUTION OF DOS
|
||||
.sp 2
|
||||
.pp
|
||||
Since its introduction, Apple DOS has
|
||||
gone through three major versions.
|
||||
All of these versions look
|
||||
very much the same on the surface.
|
||||
All commands supported by DOS 3.3
|
||||
are also supported in 3.2 and 3.1.
|
||||
The need for additional versions has
|
||||
been more to fix errors in DOS and to
|
||||
make minor enhancements than to
|
||||
provide additional functionality.
|
||||
Only DOS 3.3 has offered any major
|
||||
improvement in function; an increase
|
||||
in the number of sectors that will
|
||||
fit on a track from 13 to 16.
|
||||
.sp1
|
||||
DOS 3 - 29 June 1978
|
||||
.br
|
||||
DOS 3.1 - 20 July 1978
|
||||
.pp
|
||||
The first release of DOS was
|
||||
apparently a victim of a rush at
|
||||
Apple to introduce the DISK II. As
|
||||
such, it had a number of bugs. With the
|
||||
movement towards the APPLE II PLUS
|
||||
and the introduction of the AUTOSTART
|
||||
ROM, a new release was needed.
|
||||
.SP1
|
||||
DOS 3.2 - 16 February 1979
|
||||
.pp
|
||||
Although DOS 3.2 embodied more
|
||||
changes from its
|
||||
predecessor than any other release of
|
||||
DOS, 90% of the basic structure of DOS 3.1
|
||||
was retained. The major differences
|
||||
between DOS 3.1 and 3.2 and later versions of DOS
|
||||
are listed below:
|
||||
.sp1
|
||||
.pi-2
|
||||
.in2
|
||||
.ps0
|
||||
.pp
|
||||
- NOMON C,I,O is the initial default
|
||||
under DOS 3.2. MON C,I,O was the
|
||||
default under DOS 3.1.
|
||||
.pp
|
||||
- Input prompts (>,],*) are echoed
|
||||
when MON O is in effect, not under
|
||||
MON I as was the case under 3.1.
|
||||
.pp
|
||||
- When a DOS command was entered from
|
||||
the keyboard, DOS executed it and
|
||||
then passed a blank followed by a
|
||||
carriage return to BASIC under 3.1. Under 3.2
|
||||
only a carriage return is passed.
|
||||
.pp
|
||||
- Under 3.2, certain commands may not
|
||||
be entered from the keyboard but may
|
||||
only be used within a BASIC program
|
||||
(READ, WRITE, POSITION, OPEN,
|
||||
APPEND).
|
||||
.pp
|
||||
- Under 3.2, when LOADing an APPLESOFT program,
|
||||
DOS automatically
|
||||
converts from APPLESOFT ROM format to
|
||||
APPLESOFT RAM format if the RAM version of
|
||||
BASIC is in use and vice versa.
|
||||
.pp
|
||||
- DOS 3.1 could not read lower case
|
||||
characters from a text file; DOS 3.2
|
||||
can.
|
||||
.pp
|
||||
.bp
|
||||
- Some DOS commands are allowed to
|
||||
create a new file, others will not.
|
||||
Under DOS 3.1, any reference to a
|
||||
file that didn't exist, caused it to
|
||||
be created. This forced DOS 3.1 to
|
||||
then delete it if a new file was not
|
||||
desired. (LOAD XYZ under 3.1 if XYZ
|
||||
did not exist, created XYZ, deleted
|
||||
XYZ, and then printed the file not
|
||||
found error message.) Under 3.2, OPEN
|
||||
is allowed to create a file if one
|
||||
does not exist, but LOAD may not.
|
||||
.pp
|
||||
- Under 3.1, exiting to the monitor
|
||||
required that the monitor status
|
||||
register location ($48) be set to
|
||||
zero before reentering DOS. Under DOS
|
||||
3.2 this is no longer necessary.
|
||||
.pp
|
||||
- The Read/Write-Track/Sector (RWTS)
|
||||
section of DOS disables interrupts
|
||||
while it is executing. Under 3.1,
|
||||
RWTS could be interrupted by a
|
||||
peripheral while writing to a disk,
|
||||
destroying the disk.
|
||||
.pp
|
||||
- The default for the B (byte offset) keyword is 0
|
||||
under 3.2.
|
||||
.pp
|
||||
- DOS was reassembled for 3.2 causing most of
|
||||
its interesting locations and
|
||||
routines to move slightly. This
|
||||
played havoc with user programs and
|
||||
utilities which had DOS addresses
|
||||
built into them.
|
||||
.pp
|
||||
- Additional file types (beyond
|
||||
T, I, A, and B) are defined within
|
||||
DOS 3.2, although no commands yet
|
||||
support them. The new types are S,
|
||||
R, a new A, and a new B.
|
||||
R has subsequently been used by the
|
||||
DOS TOOLKIT for relocatable object
|
||||
module assembler files. At present,
|
||||
no other use is made of these
|
||||
extra file types.
|
||||
.pp
|
||||
- Support was added under 3.2 for the
|
||||
AUTOSTART ROM.
|
||||
.pp
|
||||
- All files open when a disk full
|
||||
condition occurs are closed by DOS
|
||||
3.2.
|
||||
.pp
|
||||
- As with each new release of DOS,
|
||||
several new programs were added to
|
||||
the master diskette for 3.2. Among
|
||||
these was UPDATE 3.2, a replacement
|
||||
for MASTER.CREATE, the utility for
|
||||
creating master diskettes. UPDATE
|
||||
3.2 converts a slave into a master
|
||||
and allows the HELLO file to be
|
||||
renamed.
|
||||
.br
|
||||
.pi0
|
||||
.in0
|
||||
.ps1
|
||||
.sp1
|
||||
DOS 3.2.1 - 31 July 1979
|
||||
.PP
|
||||
DOS 3.2.1 was essentially a
|
||||
"maintenance release" of DOS 3.2.
|
||||
Minor patches were made to RWTS and
|
||||
the COPY program to correct a timing
|
||||
problem when a dual drive copy was
|
||||
done. Additional delays were added
|
||||
following a switch between drives.
|
||||
.bp
|
||||
DOS 3.3 - 25 August 1980
|
||||
.PP
|
||||
Introduced in mid 1980 as a
|
||||
hardware/software upgrade from DOS
|
||||
3.2.1, the DOS 3.3 package includes
|
||||
new bootstrap and state ROM chips for
|
||||
the disk controller card which
|
||||
provide the capability to
|
||||
format, read, and write a
|
||||
diskette with 16 sectors.
|
||||
(These ROMs are the
|
||||
same ones used with the LANGUAGE
|
||||
SYSTEM.)
|
||||
This improvement
|
||||
represents almost a 25% increase in
|
||||
available disk space over the old
|
||||
13 sector format.
|
||||
Also included in the 3.3
|
||||
package is an updated version of the
|
||||
DOS manual, a BASICS diskette (for 13
|
||||
sector boots), and a master diskette.
|
||||
Although the RWTS portion of DOS was
|
||||
almost totally rewritten, the rest of
|
||||
DOS was not reassembled and only
|
||||
received a few patches:
|
||||
.sp1
|
||||
.pi-2
|
||||
.in2
|
||||
.ps0
|
||||
.pp
|
||||
- The initial DOS bootstrap loader
|
||||
was moved to $800 under 3.3. It was
|
||||
at $300 under 3.2. In addition, as
|
||||
stored on the diskette (track 0
|
||||
sector 0) it is nibbilized in the
|
||||
same way as all other sectors under
|
||||
3.3.
|
||||
.pp
|
||||
- A bug in APPEND which caused it to
|
||||
position improperly if the file was a
|
||||
multiple of 256 bytes long was fixed
|
||||
under 3.3.
|
||||
.pp
|
||||
- A VERIFY command is internally
|
||||
executed after every SAVE or BSAVE
|
||||
under 3.3.
|
||||
.pp
|
||||
- All 4 bytes are used in the Volume
|
||||
Table Of Contents (VTOC) free sector bit map when
|
||||
keeping track of free sectors. This
|
||||
allows DOS to handle up to 32 sectors
|
||||
per track. Of course, RWTS will only
|
||||
handle 16 sectors due to hardware
|
||||
limitations.
|
||||
.pp
|
||||
- If a LANGUAGE CARD is present, DOS
|
||||
stores a zero on it at $E000 during
|
||||
bootstrap to force the HELLO program
|
||||
on the master diskette to reload
|
||||
BASIC.
|
||||
.pp
|
||||
- DOS is read into memory from the
|
||||
top down (backwards) under 3.3 rather than the
|
||||
bottom up. Its image is
|
||||
still stored in the same order on the
|
||||
diskette (tracks 0, 1, and 2),
|
||||
however.
|
||||
.pp
|
||||
- Additional programs added to the
|
||||
master diskette under 3.3 include
|
||||
FID, a generalized file utility which
|
||||
allows individual files or groups of
|
||||
files to be copied, MUFFIN, a
|
||||
conversion copy routine to allow 3.2
|
||||
files to be moved to 16 sector 3.3
|
||||
diskettes, BOOT 13, a program which
|
||||
will boot a 13 sector diskette,
|
||||
and a new COPY program
|
||||
which will also support single drive
|
||||
copies.
|
||||
.pp
|
||||
- Under 3.2, speed differences in
|
||||
some drives prevented their use
|
||||
together with the DOS COPY program.
|
||||
Because the COPY program was rewritten
|
||||
under 3.3, that restriction no longer
|
||||
applies.
|
||||
.br
|
||||
.pi0
|
||||
.in0
|
||||
.ps1
|
||||
.nx ch3.1
|
||||
\x00
|
578
D1S1/CH3.1#064000.txt
Normal file
578
D1S1/CH3.1#064000.txt
Normal file
|
@ -0,0 +1,578 @@
|
|||
.bp
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 3 - DISK II HARDWARE AND TRACK FORMATTING
|
||||
.sp 2
|
||||
.pp
|
||||
Apple Computer's excellent manual on
|
||||
the Disk Operating System (DOS)
|
||||
provides only very basic information
|
||||
about how diskettes are formatted.
|
||||
This chapter will explain in detail
|
||||
how information is structured on a
|
||||
diskette. The first section will
|
||||
contain a brief introduction to the
|
||||
hardware, and may be skipped by those
|
||||
already familiar with the DOS manual.
|
||||
.pp
|
||||
For system housekeeping, DOS divides
|
||||
diskettes into tracks and sectors.
|
||||
This is done during the
|
||||
initialization process. A track is a
|
||||
physically defined circular path
|
||||
which is concentric with the hole in
|
||||
the center of the diskette. Each
|
||||
track is identified by its distance
|
||||
from the center of the disk. Similar
|
||||
to a phonograph stylus, the
|
||||
read/write head of the disk drive may
|
||||
be positioned over any given track.
|
||||
The tracks are similar to the grooves
|
||||
in a record, but they are not
|
||||
connected in a spiral. Much like
|
||||
playing a record, the diskette is
|
||||
spun at a constant speed while the
|
||||
data is read from or written to its
|
||||
surface with the read/write head.
|
||||
Apple formats its diskettes into 35
|
||||
tracks. They are numbered from 0 to
|
||||
34, track 0 being the outermost track
|
||||
and track 34 the innermost. Figure
|
||||
3.1 illustrates the concept of
|
||||
tracks, although they are invisible
|
||||
to the eye on a real diskette.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.1 HERE ***
|
||||
.pp
|
||||
It should be pointed out, for the
|
||||
sake of accuracy, that the disk arm
|
||||
can position itself over 70 "phases".
|
||||
To move the arm past one track to the
|
||||
next, two phases of the stepper
|
||||
motor, which moves the arm, must be
|
||||
cycled. This implies that data might
|
||||
be stored on 70 tracks, rather than
|
||||
35. Unfortunately, the resolution of
|
||||
the read/write head and the accuracy
|
||||
of the stepper motor are such, that
|
||||
attempts to use these phantom
|
||||
"half" tracks create so much
|
||||
cross-talk that data is lost or
|
||||
overwritten. Although the standard
|
||||
DOS uses only even phases, some
|
||||
protected disks use odd phases or
|
||||
combinations of the two, provided
|
||||
that no two tracks are closer than
|
||||
two phases from one another. See
|
||||
APPENDIX B for more information on
|
||||
protection schemes.
|
||||
.bp
|
||||
.pp
|
||||
A sector is a subdivision of a track.
|
||||
It is the smallest unit of
|
||||
"updatable" data on the diskette.
|
||||
DOS generally reads or writes data a
|
||||
sector at a time. This is to avoid
|
||||
using a large chunk of memory as a
|
||||
buffer to read or write an entire
|
||||
track.
|
||||
Apple has used two different track
|
||||
formats
|
||||
to date. One divides the track into
|
||||
13 sectors, the other, 16 sectors. The
|
||||
sectoring does not use the index
|
||||
hole, provided on most diskettes, to
|
||||
locate the first sector of the track.
|
||||
The implication is that
|
||||
the software must be able
|
||||
to locate any given track and sector
|
||||
with no help from the hardware.
|
||||
This scheme, known as "soft sectoring",
|
||||
takes a little more space
|
||||
for storage but allows flexibility,
|
||||
as evidenced by the recent change
|
||||
from 13 sectors to 16 sectors per
|
||||
track. The following table
|
||||
catagorizes the amount of data stored
|
||||
on a diskette under both 13 and 16
|
||||
sector formats.
|
||||
.sp1
|
||||
.ne10
|
||||
.nf
|
||||
DISK ORGANIZATION
|
||||
.SP1
|
||||
TRACKS
|
||||
All DOS versions................35
|
||||
.SP1
|
||||
SECTORS PER TRACK
|
||||
DOS 3.2.1 and earlier...........13
|
||||
DOS 3.3.........................16
|
||||
.SP1
|
||||
SECTORS PER DISKETTE
|
||||
DOS 3.2.1 and earlier..........455
|
||||
DOS 3.3........................560
|
||||
.sp1
|
||||
BYTES PER SECTOR
|
||||
All DOS versions...............256
|
||||
.sp1
|
||||
BYTES PER DISKETTE
|
||||
DOS 3.2.1 and earlier.......116480
|
||||
DOS 3.3.....................143360
|
||||
.SP1
|
||||
USABLE* SECTORS FOR DATA STORAGE
|
||||
DOS 3.2.1 and earlier..........403
|
||||
DOS 3.3........................496
|
||||
.SP1
|
||||
USABLE* BYTES PER DISKETTE
|
||||
DOS 3.2.1 and earlier.......103168
|
||||
DOS 3.3.....................126976
|
||||
.SP2
|
||||
* Excludes DOS, VTOC, and CATALOG
|
||||
.bp
|
||||
TRACK FORMATTING
|
||||
.pp
|
||||
Up to this point we have broken down
|
||||
the structure of data to the track
|
||||
and sector level. To better
|
||||
understand how
|
||||
data is stored and retrieved, we will
|
||||
start at the bottom and work up.
|
||||
.pp
|
||||
As this manual is primarily concerned
|
||||
with software, no attempt will be
|
||||
made to deal with the specifics of
|
||||
the hardware. For example, while in
|
||||
fact data is stored as a continuous
|
||||
stream of analog signals, we will
|
||||
deal with discrete digital data, i.e.
|
||||
a 0 or a 1. We recognize that the
|
||||
hardware converts analog data to
|
||||
digital data but how this is
|
||||
accomplished is beyond the scope of
|
||||
this manual.
|
||||
.pp
|
||||
Data is recorded on the diskette
|
||||
using frequency modulation as the
|
||||
recording mode. Each data bit
|
||||
recorded on the diskette has an
|
||||
associated clock bit recorded with
|
||||
it. Data written on and read back
|
||||
from the diskette takes the form
|
||||
shown in Figure 3.2. The data
|
||||
pattern shown represents a binary
|
||||
value of 101.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.2 HERE ***
|
||||
.pp
|
||||
As can be seen in Figure 3.3, the
|
||||
clock bits and data bits (if present)
|
||||
are interleaved. The presence of a
|
||||
data bit between two clock bits
|
||||
represents a binary 1, the absence of
|
||||
a data bit between two clock bits
|
||||
represents a binary 0. We will
|
||||
define a "bit cell" as the period
|
||||
between the leading edge of one clock
|
||||
bit and the leading edge of the next
|
||||
clock bit.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.3 HERE ***
|
||||
.PP
|
||||
A byte would consist of eight (8)
|
||||
consecutive bit cells. The most
|
||||
significant bit cell is usually
|
||||
referred to as bit cell 7 and the
|
||||
least significant bit cell would be
|
||||
bit cell 0. When reference is made
|
||||
to a specific data bit (i.e. data bit
|
||||
5), it is with respect to the
|
||||
corresponding bit cell (bit cell 5).
|
||||
Data is written and read serially,
|
||||
one bit at a time. Thus, during a
|
||||
write operation, bit cell 7 of each
|
||||
byte would be written first, with bit
|
||||
cell 0 being written last.
|
||||
Correspondingly, when data is being
|
||||
read back from the diskette, bit cell
|
||||
7 is read first and bit cell 0 is
|
||||
read last. The diagram below
|
||||
illustrates the relationship of the
|
||||
bits within a byte.
|
||||
.bp
|
||||
*** INSERT FIGURE 3.4 HERE ***
|
||||
.PP
|
||||
To graphically show how bits are
|
||||
stored and retrieved, we must take
|
||||
certain liberties. The diagrams are
|
||||
a representation of what functionally
|
||||
occurs within the disk drive. For
|
||||
the purposes of our presentation, the
|
||||
hardware interface
|
||||
to the diskette will be
|
||||
represented as an eight bit "data latch".
|
||||
While the hardware involves
|
||||
considerably more complication, from a software
|
||||
standpoint it is reasonable to use
|
||||
the data latch, as it accurately
|
||||
embodies the function of data flow to
|
||||
and from the diskette.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.5 HERE ***
|
||||
.pp
|
||||
Figure 3.5 shows the three bits, 101,
|
||||
being read from the diskette data
|
||||
stream into the data latch. Of
|
||||
course another five bits would be
|
||||
read to fill the latch. As can be
|
||||
seen, the data is separated from the
|
||||
clock bits. This task is done by the
|
||||
hardware and is shown more for
|
||||
accuracy than for its importance to
|
||||
our discussion.
|
||||
.pp
|
||||
Writing data can be depicted in much
|
||||
the same way (see Figure 3.6).
|
||||
The clock bits which
|
||||
were separated from the data must now
|
||||
be interleaved with the data as it is
|
||||
written. It should be noted that,
|
||||
while in write mode, zeros are being
|
||||
brought into the data latch to
|
||||
replace the data being written. It
|
||||
is the task of the software to make
|
||||
sure that the latch is loaded and
|
||||
instructed to write in 32
|
||||
cycle intervals. If not, zero bits
|
||||
will continue to be written every four
|
||||
cycles, which is, in fact, exactly
|
||||
how self-sync bytes are created.
|
||||
Self-sync bytes will be covered in
|
||||
detail shortly.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.6 HERE ***
|
||||
.PP
|
||||
A "field" is made up of a group of
|
||||
consecutive
|
||||
bytes. The number of bytes varies,
|
||||
depending upon the nature of the
|
||||
field. The two types of fields
|
||||
present on a diskette are the Address
|
||||
Field and the Data Field. They are
|
||||
similar in that they both contain a
|
||||
prologue, a data area, a checksum, and
|
||||
an epilogue. Each field on a track is
|
||||
separated from adjacent fields by a
|
||||
number of bytes. These areas of
|
||||
separation are called "gaps" and are
|
||||
provided for two reasons. One, they
|
||||
allow the updating of one field
|
||||
without affecting adjacent fields (on
|
||||
the Apple, only data fields are
|
||||
updated). Secondly, they allow the
|
||||
computer time
|
||||
to decode the address field before
|
||||
the corresponding data field can pass
|
||||
beneath the read/write head.
|
||||
.pp
|
||||
All gaps are primarily alike in
|
||||
content, consisting of self-sync
|
||||
hexadecimal FF's, and vary only in
|
||||
the number of bytes they contain.
|
||||
Figure 3.7 is a diagram of a portion
|
||||
of a typical track, broken into its
|
||||
major components.
|
||||
.bp
|
||||
*** INSERT FIGURE 3.7 HERE ***
|
||||
.PP
|
||||
Self-sync or auto-sync bytes are
|
||||
special bytes that make up the three
|
||||
different types of gaps on a track.
|
||||
They are so named because of their
|
||||
ability to automatically bring the
|
||||
hardware into synchronization with
|
||||
data bytes on the disk. The
|
||||
difficulty in doing this lies in the
|
||||
fact that the hardware reads bits and
|
||||
the data must be stored as eight bit
|
||||
bytes. It has been mentioned that a
|
||||
track is literally a continuous
|
||||
stream of data bits. In fact, at the
|
||||
bit level, there is no way to
|
||||
determine where a byte starts or
|
||||
ends, because each bit cell is
|
||||
exactly the same, written in precise
|
||||
intervals with its neighbors. When
|
||||
the drive is instructed to read data,
|
||||
it will start wherever it happens to
|
||||
be on a particular track. That could
|
||||
be anywhere among the 50,000 or so
|
||||
bits on a track. Distinguishing
|
||||
clock bits from data bits,
|
||||
the hardware finds
|
||||
the first bit cell with data in it
|
||||
and proceeds to read the following
|
||||
seven data
|
||||
bits into the eight bit latch. In
|
||||
effect, it assumes that it had
|
||||
started at the beginning of a data
|
||||
byte. Of course, in reality, the
|
||||
odds of its having started at the
|
||||
beginning of a byte are only one in
|
||||
eight.
|
||||
Pictured in Figure 3.8 is a small
|
||||
portion of a track. The clock bits
|
||||
have been stripped out and 0's and
|
||||
1's have been used for clarity.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.8 HERE ***
|
||||
.pp
|
||||
There is no way from looking at the
|
||||
data to tell what bytes are
|
||||
represented, because we don't know
|
||||
where to start. This is exactly the
|
||||
problem that self-sync bytes
|
||||
overcome.
|
||||
.pp
|
||||
A self-sync byte is defined to be a
|
||||
hexadecimal FF with a special
|
||||
difference. It is, in fact, a 10 bit
|
||||
byte rather than an eight bit byte. Its
|
||||
two extra bits are zeros. Figure 3.9
|
||||
shows the difference between a normal
|
||||
data hex FF that might be found
|
||||
elsewhere on the disk and a self-sync
|
||||
hex FF byte.
|
||||
.bp
|
||||
*** INSERT FIGURE 3.9 HERE ***
|
||||
.pp
|
||||
A self-sync is generated by using a
|
||||
40 cycle (micro-second) loop while
|
||||
writing an FF. A bit is written
|
||||
every four cycles, so two of the zero bits
|
||||
brought into the data latch while the
|
||||
FF was being written are also
|
||||
written to the disk, making the 10
|
||||
bit byte. (DOS 3.2.1 and earlier versions use
|
||||
a nine bit byte due to the hardware's
|
||||
inability to always detect two
|
||||
consecutive zero bits.) It can be
|
||||
shown, using Figure 3.10, that five
|
||||
self-sync bytes are sufficient to
|
||||
guarantee that the hardware is
|
||||
reading valid data. The reason for
|
||||
this is that the hardware requires
|
||||
the first bit of a byte to be a 1.
|
||||
Pictured at the top of the figure is
|
||||
a stream of five auto-sync bytes. Each
|
||||
row below that demonstates what the
|
||||
hardware will read should it start
|
||||
reading at any given bit in the
|
||||
first byte. In each case, by the
|
||||
time the five sync bytes have passed
|
||||
beneath the read/write head, the
|
||||
hardware will be "synched" to read the
|
||||
data bytes that follow. As long as
|
||||
the disk is left in read mode, it
|
||||
will continue to correctly interpret
|
||||
the data unless there is an error on
|
||||
the track.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.10 ***
|
||||
.PP
|
||||
We can now discuss the particular
|
||||
portions of a track in detail. The
|
||||
three gaps will be covered first.
|
||||
Unlike some other disk formats, the
|
||||
size of the three gap types will vary
|
||||
from drive to drive and even from
|
||||
track to track. During the
|
||||
initialization process, DOS will
|
||||
start with large gaps and keep making
|
||||
them smaller until an entire track
|
||||
can be written without overlapping
|
||||
itself. A minimum of five self-sync
|
||||
bytes must be maintained for
|
||||
each gap type (as discussed earlier).
|
||||
The result is fairly uniform gap
|
||||
sizes within each particular track.
|
||||
.pp
|
||||
Gap 1 is the first data written to a
|
||||
track during initialization. Its
|
||||
purpose is twofold. The gap
|
||||
originally consists of 128 bytes of
|
||||
self-sync, a large enough area to
|
||||
insure that all portions of a track
|
||||
will contain data. Since the speed
|
||||
of a particular drive may vary, the
|
||||
total length of the track in bytes is
|
||||
uncertain, and the percentage
|
||||
occupied by data is unknown. The
|
||||
initialization process is set up,
|
||||
however, so that even on drives of
|
||||
differing speeds, the last data field
|
||||
written will overlap Gap 1, providing
|
||||
continuity over the entire physical
|
||||
track. Care is taken to make sure
|
||||
the remaining portion of Gap 1 is at
|
||||
as long as a typical Gap 3
|
||||
(in practice its length
|
||||
is usually more than 40),
|
||||
enabling it to serve
|
||||
as a Gap 3 type for Address Field
|
||||
number 0 (See Figure 3.7 for
|
||||
clarity).
|
||||
.bp
|
||||
.pp
|
||||
Gap 2 appears after each Address
|
||||
Field and before each Data Field.
|
||||
Its length varies from five to ten bytes
|
||||
on a normal drive. The primary
|
||||
purpose of Gap 2 is to provide time
|
||||
for the information in an Address
|
||||
Field to be decoded by the computer
|
||||
before a read or write takes place.
|
||||
If the gap were too short, the
|
||||
beginning of the Data Field might
|
||||
spin past while DOS was still
|
||||
determining if this was the
|
||||
sector to be read. The 240 odd
|
||||
cycles that six self-sync bytes provide
|
||||
seems ample time to decode an address
|
||||
field. When a Data Field is written
|
||||
there is no guarantee that the write
|
||||
will occur in exactly the same spot
|
||||
each time. This is due to the fact
|
||||
that the drive which is rewriting
|
||||
the Data Field may not be the one
|
||||
which originally INITed or wrote it.
|
||||
Since the speed of the drives can
|
||||
vary, it is possible that the write
|
||||
could start in mid-byte. (See Figure
|
||||
3.11) This is not
|
||||
a problem as long as the difference
|
||||
in positioning is not great. To
|
||||
insure the integrity of Gap 2, when
|
||||
writing a data field, five self-sync
|
||||
bytes are written prior to writing
|
||||
the Data Field itself. This serves
|
||||
two purposes. Since relatively
|
||||
little time is spent decoding an
|
||||
address field, the five bytes help place
|
||||
the Data Field near its original
|
||||
position. Secondly, and more
|
||||
importantly, the five self-sync bytes
|
||||
are the minimum number required to
|
||||
guarantee read-synchronization. It
|
||||
is probable that, in writing a Data
|
||||
Field, at least one sync byte will be
|
||||
destroyed. This is because, just as
|
||||
in reading bits on the track, the
|
||||
write may not begin on a byte
|
||||
boundary, thus altering an existing
|
||||
byte. Figure 3.12 illustrates this.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.11 HERE ***
|
||||
.SP1
|
||||
*** INSERT FIGURE 3.12 HERE ***
|
||||
.PP
|
||||
Gap 3 appears after each
|
||||
Data Field and before each Address
|
||||
Field. It is longer than Gap 2 and
|
||||
generally ranges from 14 to 24 bytes
|
||||
in length. It is quite similar in
|
||||
purpose to Gap 2. Gap 3 allows the
|
||||
additional time needed to manipulate
|
||||
the data that has been read before
|
||||
the next sector is to be read. The
|
||||
length of Gap 3 is not as critical as
|
||||
that of Gap 2. If the
|
||||
following Address
|
||||
Field is missed, DOS can always wait
|
||||
for the next time it spins around
|
||||
under the read/write head, at most
|
||||
one revolution of the disk. Since
|
||||
Address Fields are never rewritten,
|
||||
there is no problem with this gap
|
||||
providing synchronization, since only
|
||||
the first part of the gap can be
|
||||
overwritten or damaged. (See Figure
|
||||
3.11 for clarity)
|
||||
.bp
|
||||
.pp
|
||||
An examination of the contents of the
|
||||
two types of fields is in order.
|
||||
The Address Field contains
|
||||
the "address" or identifying
|
||||
information about the Data Field
|
||||
which follows it. The volume, track,
|
||||
and sector number of any given sector
|
||||
can be thought of as its "address",
|
||||
much like a country, city, and street
|
||||
number might identify a house. As
|
||||
shown previously in Figure 3.7, there
|
||||
are a number of components which make
|
||||
up the Address Field. A more
|
||||
detailed illustration is given in
|
||||
Figure 3.13.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.13 HERE ***
|
||||
.PP
|
||||
The prologue consists of three bytes
|
||||
which form a unique sequence, found
|
||||
in no other component of the track.
|
||||
This fact enables DOS to locate an
|
||||
Address Field with almost no
|
||||
possibility of error. The three
|
||||
bytes are $D5, $AA, and $96. The $D5
|
||||
and $AA are reserved (never written
|
||||
as data) thus insuring the uniqueness
|
||||
of the prologue. The $96, following
|
||||
this unique string, indicates that
|
||||
the data following constitutes an
|
||||
Address Field (as opposed to a Data
|
||||
Field). The address information
|
||||
follows next, consisting of the
|
||||
volume, track, and sector number and
|
||||
a checksum. This information is
|
||||
absolutely essential for DOS to know
|
||||
where it is positioned on a
|
||||
particular diskette. The checksum is
|
||||
computed by exclusive-ORing the first
|
||||
three pieces of information, and is
|
||||
used to verify its integrity.
|
||||
Lastly follows the epilogue, which
|
||||
contains the three bytes $DE, $AA and
|
||||
$EB. Oddly, the $EB is always written
|
||||
during initialization but is never
|
||||
verified when an Address Field is
|
||||
read. The epilogue bytes are
|
||||
sometimes referred to as "bit-slip
|
||||
marks", which provide added assurance
|
||||
that the drive is still in sync with
|
||||
the bytes on the disk. These bytes
|
||||
are probably unnecessary, but do
|
||||
provide a means of double checking.
|
||||
.pp
|
||||
The other field type is the Data
|
||||
Field. Much like the Address Field,
|
||||
it consists of a prologue, data,
|
||||
checksum, and an epilogue. (Refer to
|
||||
Figure 3.14) The prologue is
|
||||
different only in the third byte.
|
||||
The bytes are $D5, $AA, and $AD,
|
||||
which again form a unique sequence,
|
||||
enabling DOS to locate the beginning
|
||||
of the sector data. The data
|
||||
consists of 342 bytes of encoded
|
||||
data. The encoding scheme used will
|
||||
be discussed in the next section.
|
||||
The data is followed by a checksum
|
||||
byte, used to verify the integrity of
|
||||
the data just read. The epilogue
|
||||
portion of the Data Field is
|
||||
absolutely identical to the epilogue
|
||||
in the Address Field and it serves
|
||||
the same function.
|
||||
.bp
|
||||
.nx ch3.2
|
||||
\x00
|
563
D1S1/CH3.1T#040000.txt
Normal file
563
D1S1/CH3.1T#040000.txt
Normal file
|
@ -0,0 +1,563 @@
|
|||
.bp
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 3 - DISK II HARDWARE AND TRACK FORMATTING
|
||||
.sp 2
|
||||
.pp
|
||||
Apple Computer's excellent manual on
|
||||
the Disk Operating System (DOS)
|
||||
provides only very basic information
|
||||
about how diskettes are formatted.
|
||||
This chapter will explain in detail
|
||||
how information is structured on a
|
||||
diskette. The first section will
|
||||
contain a brief introduction to the
|
||||
hardware, and may be skipped by those
|
||||
already familiar with the DOS manual.
|
||||
.pp
|
||||
For system housekeeping, DOS divides
|
||||
diskettes into tracks and sectors.
|
||||
This is done during the
|
||||
initialization process. A track is a
|
||||
physically defined circular path
|
||||
which is concentric with the hole in
|
||||
the center of the diskette. Each
|
||||
track is identified by its distance
|
||||
from the center of the disk. Similar
|
||||
to a phonograph stylus, the
|
||||
read/write head of the disk drive may
|
||||
be positioned over any given track.
|
||||
The tracks are similar to the grooves
|
||||
in a record, but they are not
|
||||
connected in a spiral. Much like
|
||||
playing a record, the diskette is
|
||||
spun at a constant speed while the
|
||||
data is read from or written to its
|
||||
surface with the read/write head.
|
||||
Apple formats its diskettes into 35
|
||||
tracks. They are numbered from 0 to
|
||||
34, track 0 being the outermost track
|
||||
and track 34 the innermost. Figure
|
||||
3.1 illustrates the concept of
|
||||
tracks, although they are invisible
|
||||
to the eye on a real diskette.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.1 HERE ***
|
||||
.pp
|
||||
It should be pointed out, for the
|
||||
sake of accuracy, that the disk arm
|
||||
can position itself over 70 "phases".
|
||||
To move the arm past one track to the
|
||||
next, two phases of the stepper
|
||||
motor, which moves the arm, must be
|
||||
cycled. This implies that data might
|
||||
be stored on 70 tracks, rather than
|
||||
35. Unfortunately, the resolution of
|
||||
the read/write head and the accuracy
|
||||
of the stepper motor are such, that
|
||||
attempts to use these phantom
|
||||
"half" tracks create so much
|
||||
cross-talk that data is lost or
|
||||
overwritten. Although the standard
|
||||
DOS uses only even phases, some
|
||||
protected disks use odd phases or
|
||||
combinations of the two, provided
|
||||
that no two tracks are closer than
|
||||
two phases from one another. See
|
||||
APPENDIX B for more information on
|
||||
protection schemes.
|
||||
.bp
|
||||
.pp
|
||||
A sector is a subdivision of a track.
|
||||
It is the smallest unit of
|
||||
"updatable" data on the diskette.
|
||||
DOS generally reads or writes data a
|
||||
sector at a time. This is to avoid
|
||||
using a large chunk of memory as a
|
||||
buffer to read or write an entire
|
||||
track.
|
||||
Apple has used two different track
|
||||
formats
|
||||
to date. One divides the track into
|
||||
13 sectors, the other, 16 sectors. The
|
||||
sectoring does not use the index
|
||||
hole, provided on most diskettes, to
|
||||
locate the first sector of the track.
|
||||
The implication is that
|
||||
the software must be able
|
||||
to locate any given track and sector
|
||||
with no help from the hardware.
|
||||
This scheme, known as "soft sectoring",
|
||||
takes a little more space
|
||||
for storage but allows flexibility,
|
||||
as evidenced by the recent change
|
||||
from 13 sectors to 16 sectors per
|
||||
track. The following table
|
||||
catagorizes the amount of data stored
|
||||
on a diskette under both 13 and 16
|
||||
sector formats.
|
||||
.sp1
|
||||
.ne10
|
||||
.nf
|
||||
DISK ORGANIZATION
|
||||
.SP1
|
||||
TRACKS
|
||||
All DOS versions................35
|
||||
.SP1
|
||||
SECTORS PER TRACK
|
||||
DOS 3.2.1 and earlier...........13
|
||||
DOS 3.3.........................16
|
||||
.SP1
|
||||
SECTORS PER DISKETTE
|
||||
DOS 3.2.1 and earlier..........455
|
||||
DOS 3.3........................560
|
||||
.sp1
|
||||
BYTES PER SECTOR
|
||||
All DOS versions...............256
|
||||
.sp1
|
||||
BYTES PER DISKETTE
|
||||
DOS 3.2.1 and earlier.......116480
|
||||
DOS 3.3.....................143360
|
||||
.SP1
|
||||
USABLE* SECTORS FOR DATA STORAGE
|
||||
DOS 3.2.1 and earlier..........403
|
||||
DOS 3.3........................496
|
||||
.SP1
|
||||
USABLE* BYTES PER DISKETTE
|
||||
DOS 3.2.1 and earlier.......103168
|
||||
DOS 3.3.....................126976
|
||||
.SP2
|
||||
* Excludes DOS, VTOC, and CATALOG
|
||||
.bp
|
||||
TRACK FORMATTING
|
||||
.pp
|
||||
Up to this point we have broken down
|
||||
the structure of data to the track
|
||||
and sector level. To better
|
||||
understand how
|
||||
data is stored and retrieved, we will
|
||||
start at the bottom and work up.
|
||||
.pp
|
||||
As this manual is primarily concerned
|
||||
with software, no attempt will be
|
||||
made to deal with the specifics of
|
||||
the hardware. For example, while in
|
||||
fact data is stored as a continuous
|
||||
stream of analog signals, we will
|
||||
deal with discrete digital data, i.e.
|
||||
a 0 or a 1. We recognize that the
|
||||
hardware converts analog data to
|
||||
digital data but how this is
|
||||
accomplished is beyond the scope of
|
||||
this manual.
|
||||
.pp
|
||||
Data is recorded on the diskette
|
||||
using frequency modulation as the
|
||||
recording mode. Each data bit
|
||||
recorded on the diskette has an
|
||||
associated clock bit recorded with
|
||||
it. Data written on and read back
|
||||
from the diskette takes the form
|
||||
shown in Figure 3.2. The data
|
||||
pattern shown represents a binary
|
||||
value of 101.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.2 HERE ***
|
||||
.pp
|
||||
As can be seen in Figure 3.3, the
|
||||
clock bits and data bits (if present)
|
||||
are interleaved. The presence of a
|
||||
data bit between two clock bits
|
||||
represents a binary 1, the absence of
|
||||
a data bit between two clock bits
|
||||
represents a binary 0. We will
|
||||
define a "bit cell" as the period
|
||||
between the leading edge of one clock
|
||||
bit and the leading edge of the next
|
||||
clock bit.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.3 HERE ***
|
||||
.PP
|
||||
A byte would consist of eight (8)
|
||||
consecutive bit cells. The most
|
||||
significant bit cell is usually
|
||||
referred to as bit cell 7 and the
|
||||
least significant bit cell would be
|
||||
bit cell 0. When reference is made
|
||||
to a specific data bit (i.e. data bit
|
||||
5), it is with respect to the
|
||||
corresponding bit cell (bit cell 5).
|
||||
Data is written and read serially,
|
||||
one bit at a time. Thus, during a
|
||||
write operation, bit cell 7 of each
|
||||
byte would be written first, with bit
|
||||
cell 0 being written last.
|
||||
Correspondingly, when data is being
|
||||
read back from the diskette, bit cell
|
||||
7 is read first and bit cell 0 is
|
||||
read last. The diagram below
|
||||
illustrates the relationship of the
|
||||
bits within a byte.
|
||||
.bp
|
||||
*** INSERT FIGURE 3.4 HERE ***
|
||||
.PP
|
||||
To graphically show how bits are
|
||||
stored and retrieved, we must take
|
||||
certain liberties. The diagrams are
|
||||
a representation of what functionally
|
||||
occurs within the disk drive. For
|
||||
the purposes of our presentation, the
|
||||
hardware interface
|
||||
to the diskette will be
|
||||
represented as an eight bit "data latch".
|
||||
While the hardware involves
|
||||
considerably more complication, from a software
|
||||
standpoint it is reasonable to use
|
||||
the data latch, as it accurately
|
||||
embodies the function of data flow to
|
||||
and from the diskette.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.5 HERE ***
|
||||
.pp
|
||||
Figure 3.5 shows the three bits, 101,
|
||||
being read from the diskette data
|
||||
stream into the data latch. Of
|
||||
course another five bits would be
|
||||
read to fill the latch. As can be
|
||||
seen, the data is separated from the
|
||||
clock bits. This task is done by the
|
||||
hardware and is shown more for
|
||||
accuracy than for its importance to
|
||||
our discussion.
|
||||
.pp
|
||||
Writing data can be depicted in much
|
||||
the same way (see Figure 3.6).
|
||||
The clock bits which
|
||||
were separated from the data must now
|
||||
be interleaved with the data as it is
|
||||
written. It should be noted that,
|
||||
while in write mode, zeros are being
|
||||
brought into the data latch to
|
||||
replace the data being written. It
|
||||
is the task of the software to make
|
||||
sure that the latch is loaded and
|
||||
instructed to write in 32
|
||||
cycle intervals. If not, zero bits
|
||||
will continue to be written every four
|
||||
cycles, which is, in fact, exactly
|
||||
how self-sync bytes are created.
|
||||
Self-sync bytes will be covered in
|
||||
detail shortly.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.6 HERE ***
|
||||
.PP
|
||||
A "field" is made up of a group of
|
||||
consecutive
|
||||
bytes. The number of bytes varies,
|
||||
depending upon the nature of the
|
||||
field. The two types of fields
|
||||
present on a diskette are the Address
|
||||
Field and the Data Field. They are
|
||||
similar in that they both contain a
|
||||
prologue, a data area, a checksum, and
|
||||
an epilogue. Each field on a track is
|
||||
separated from adjacent fields by a
|
||||
number of bytes. These areas of
|
||||
separation are called "gaps" and are
|
||||
provided for two reasons. One, they
|
||||
allow the updating of one field
|
||||
without affecting adjacent fields (on
|
||||
the Apple, only data fields are
|
||||
updated). Secondly, they allow the
|
||||
computer time
|
||||
to decode the address field before
|
||||
the corresponding data field can pass
|
||||
beneath the read/write head.
|
||||
.pp
|
||||
All gaps are primarily alike in
|
||||
content, consisting of self-sync
|
||||
hexadecimal FF's, and vary only in
|
||||
the number of bytes they contain.
|
||||
Figure 3.7 is a diagram of a portion
|
||||
of a typical track, broken into its
|
||||
major components.
|
||||
.bp
|
||||
*** INSERT FIGURE 3.7 HERE ***
|
||||
.PP
|
||||
Self-sync or auto-sync bytes are
|
||||
special bytes that make up the three
|
||||
different types of gaps on a track.
|
||||
They are so named because of their
|
||||
ability to automatically bring the
|
||||
hardware into synchronization with
|
||||
data bytes on the disk. The
|
||||
difficulty in doing this lies in the
|
||||
fact that the hardware reads bits and
|
||||
the data must be stored as eight bit
|
||||
bytes. It has been mentioned that a
|
||||
track is literally a continuous
|
||||
stream of data bits. In fact, at the
|
||||
bit level, there is no way to
|
||||
determine where a byte starts or
|
||||
ends, because each bit cell is
|
||||
exactly the same, written in precise
|
||||
intervals with its neighbors. When
|
||||
the drive is instructed to read data,
|
||||
it will start wherever it happens to
|
||||
be on a particular track. That could
|
||||
be anywhere among the 50,000 or so
|
||||
bits on a track. Distinguishing
|
||||
clock bits from data bits,
|
||||
the hardware finds
|
||||
the first bit cell with data in it
|
||||
and proceeds to read the following
|
||||
seven data
|
||||
bits into the eight bit latch. In
|
||||
effect, it assumes that it had
|
||||
started at the beginning of a data
|
||||
byte. Of course, in reality, the
|
||||
odds of its having started at the
|
||||
beginning of a byte are only one in
|
||||
eight.
|
||||
Pictured in Figure 3.8 is a small
|
||||
portion of a track. The clock bits
|
||||
have been stripped out and 0's and
|
||||
1's have been used for clarity.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.8 HERE ***
|
||||
.pp
|
||||
There is no way from looking at the
|
||||
data to tell what bytes are
|
||||
represented, because we don't know
|
||||
where to start. This is exactly the
|
||||
problem that self-sync bytes
|
||||
overcome.
|
||||
.pp
|
||||
A self-sync byte is defined to be a
|
||||
hexadecimal FF with a special
|
||||
difference. It is, in fact, a 10 bit
|
||||
byte rather than an eight bit byte. Its
|
||||
two extra bits are zeros. Figure 3.9
|
||||
shows the difference between a normal
|
||||
data hex FF that might be found
|
||||
elsewhere on the disk and a self-sync
|
||||
hex FF byte.
|
||||
.bp
|
||||
*** INSERT FIGURE 3.9 HERE ***
|
||||
.pp
|
||||
A self-sync is generated by using a
|
||||
40 cycle (micro-second) loop while
|
||||
writing an FF. A bit is written
|
||||
every four cycles, so two of the zero bits
|
||||
brought into the data latch while the
|
||||
FF was being written are also
|
||||
written to the disk, making the 10
|
||||
bit byte. (DOS 3.2.1 and earlier versions use
|
||||
a nine bit byte due to the hardware's
|
||||
inability to always detect two
|
||||
consecutive zero bits.) It can be
|
||||
shown, using Figure 3.10, that five
|
||||
self-sync bytes are sufficient to
|
||||
guarantee that the hardware is
|
||||
reading valid data. The reason for
|
||||
this is that the hardware requires
|
||||
the first bit of a byte to be a 1.
|
||||
Pictured at the top of the figure is
|
||||
a stream of five auto-sync bytes. Each
|
||||
row below that demonstates what the
|
||||
hardware will read should it start
|
||||
reading at any given bit in the
|
||||
first byte. In each case, by the
|
||||
time the five sync bytes have passed
|
||||
beneath the read/write head, the
|
||||
hardware will be "synched" to read the
|
||||
data bytes that follow. As long as
|
||||
the disk is left in read mode, it
|
||||
will continue to correctly interpret
|
||||
the data unless there is an error on
|
||||
the track.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.10 ***
|
||||
.PP
|
||||
We can now discuss the particular
|
||||
portions of a track in detail. The
|
||||
three gaps will be covered first.
|
||||
Unlike some other disk formats, the
|
||||
size of the three gap types will vary
|
||||
from drive to drive and even from
|
||||
track to track. During the
|
||||
initialization process, DOS will
|
||||
start with large gaps and keep making
|
||||
them smaller until an entire track
|
||||
can be written without overlapping
|
||||
itself. A minimum of five self-sync
|
||||
bytes must be maintained for
|
||||
each gap type (as discussed earlier).
|
||||
The result is fairly uniform gap
|
||||
sizes within each particular track.
|
||||
.pp
|
||||
Gap 1 is the first data written to a
|
||||
track during initialization. Its
|
||||
purpose is twofold. The gap
|
||||
originally consists of 128 bytes of
|
||||
self-sync, a large enough area to
|
||||
insure that all portions of a track
|
||||
will contain data. Since the speed
|
||||
of a particular drive may vary, the
|
||||
total length of the track in bytes is
|
||||
uncertain, and the percentage
|
||||
occupied by data is unknown. The
|
||||
initialization process is set up,
|
||||
however, so that even on drives of
|
||||
differing speeds, the last data field
|
||||
written will overlap Gap 1, providing
|
||||
continuity over the entire physical
|
||||
track. Care is taken to make sure
|
||||
the remaining portion of Gap 1 is at
|
||||
as long as a typical Gap 3
|
||||
(in practice its length
|
||||
is usually more than 40),
|
||||
enabling it to serve
|
||||
as a Gap 3 type for Address Field
|
||||
number 0 (See Figure 3.7 for
|
||||
clarity).
|
||||
.bp
|
||||
.pp
|
||||
Gap 2 appears after each Address
|
||||
Field and before each Data Field.
|
||||
Its length varies from five to ten bytes
|
||||
on a normal drive. The primary
|
||||
purpose of Gap 2 is to provide time
|
||||
for the information in an Address
|
||||
Field to be decoded by the computer
|
||||
before a read or write takes place.
|
||||
If the gap were too short, the
|
||||
beginning of the Data Field might
|
||||
spin past while DOS was still
|
||||
determining if this was the
|
||||
sector to be read. The 240 odd
|
||||
cycles that six self-sync bytes provide
|
||||
seems ample time to decode an address
|
||||
field. When a Data Field is written
|
||||
there is no guarantee that the write
|
||||
will occur in exactly the same spot
|
||||
each time. This is due to the fact
|
||||
that the drive which is rewriting
|
||||
the Data Field may not be the one
|
||||
which originally INITed or wrote it.
|
||||
Since the speed of the drives can
|
||||
vary, it is possible that the write
|
||||
could start in mid-byte. (See Figure
|
||||
3.11) This is not
|
||||
a problem as long as the difference
|
||||
in positioning is not great. To
|
||||
insure the integrity of Gap 2, when
|
||||
writing a data field, five self-sync
|
||||
bytes are written prior to writing
|
||||
the Data Field itself. This serves
|
||||
two purposes. Since relatively
|
||||
little time is spent decoding an
|
||||
address field, the five bytes help place
|
||||
the Data Field near its original
|
||||
position. Secondly, and more
|
||||
importantly, the five self-sync bytes
|
||||
are the minimum number required to
|
||||
guarantee read-synchronization. It
|
||||
is probable that, in writing a Data
|
||||
Field, at least one sync byte will be
|
||||
destroyed. This is because, just as
|
||||
in reading bits on the track, the
|
||||
write may not begin on a byte
|
||||
boundary, thus altering an existing
|
||||
byte. Figure 3.12 illustrates this.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.11 HERE ***
|
||||
.SP1
|
||||
*** INSERT FIGURE 3.12 HERE ***
|
||||
.PP
|
||||
Gap 3 appears after each
|
||||
Data Field and before each Address
|
||||
Field. It is longer than Gap 2 and
|
||||
generally ranges from 14 to 24 bytes
|
||||
in length. It is quite similar in
|
||||
purpose to Gap 2. Gap 3 allows the
|
||||
additional time needed to manipulate
|
||||
the data that has been read before
|
||||
the next sector is to be read. The
|
||||
length of Gap 3 is not as critical as
|
||||
that of Gap 2. If the
|
||||
following Address
|
||||
Field is missed, DOS can always wait
|
||||
for the next time it spins around
|
||||
under the read/write head, at most
|
||||
one revolution of the disk. Since
|
||||
Address Fields are never rewritten,
|
||||
there is no problem with this gap
|
||||
providing synchronization, since only
|
||||
the first part of the gap can be
|
||||
overwritten or damaged. (See Figure
|
||||
3.11 for clarity)
|
||||
.bp
|
||||
.pp
|
||||
An examination of the contents of the
|
||||
two types of fields is in order.
|
||||
The Address Field contains
|
||||
the "address" or identifying
|
||||
information about the Data Field
|
||||
which follows it. The volume, track,
|
||||
and sector number of any given sector
|
||||
can be thought of as its "address",
|
||||
much like a country, city, and street
|
||||
number might identify a house. As
|
||||
shown previously in Figure 3.7, there
|
||||
are a number of components which make
|
||||
up the Address Field. A more
|
||||
detailed illustration is given in
|
||||
Figure 3.13.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.13 HERE ***
|
||||
.PP
|
||||
The prologue consists of three bytes
|
||||
which form a unique sequence, found
|
||||
in no other component of the track.
|
||||
This fact enables DOS to locate an
|
||||
Address Field with almost no
|
||||
possibility of error. The three
|
||||
bytes are $D5, $AA, and $96. The $D5
|
||||
and $AA are reserved (never written
|
||||
as data) thus insuring the uniqueness
|
||||
of the prologue. The $96, following
|
||||
this unique string, indicates that
|
||||
the data following constitutes an
|
||||
Address Field (as opposed to a Data
|
||||
Field). The address information
|
||||
follows next, consisting of the
|
||||
volume, track, and sector number and
|
||||
a checksum. This information is
|
||||
absolutely essential for DOS to know
|
||||
where it is positioned on a
|
||||
particular diskette. The checksum is
|
||||
computed by exclusive-ORing the first
|
||||
three pieces of information, and is
|
||||
used to verify its integrity.
|
||||
Lastly follows the epilogue, which
|
||||
contains the three bytes $DE, $AA and
|
||||
$EB. Oddly, the $EB is always written
|
||||
during initialization but is never
|
||||
verified when an Address Field is
|
||||
read. The epilogue bytes are
|
||||
sometimes referred to as "bit-slip
|
||||
marks", which provide added assurance
|
||||
that the drive is still in sync with
|
||||
the bytes on the disk. These bytes
|
||||
are probably unnecessary, but do
|
||||
provide a means of double checking.
|
||||
.pp
|
||||
The other field type is the Data
|
||||
Field. Much like the Address Field,
|
||||
it consists of a prologue, data,
|
||||
checksum, and an epilogue. (Refer to
|
||||
Figure 3.14) The prologue is
|
||||
different only in the third byte.
|
||||
The bytes are $D5, $AA, and $AD,
|
||||
which again form a
|
334
D1S1/CH3.2#064000.txt
Normal file
334
D1S1/CH3.2#064000.txt
Normal file
|
@ -0,0 +1,334 @@
|
|||
.SP2
|
||||
DATA FIELD ENCODING
|
||||
.pp
|
||||
Due to Apple's hardware, it is not
|
||||
possible to read all 256 possible
|
||||
byte values from a diskette.
|
||||
This is not a great problem, but it
|
||||
does require that the data written to
|
||||
the disk be encoded. Three different
|
||||
techniques have been used. The first
|
||||
one, which is currently used in
|
||||
Address Fields, involves
|
||||
writing a data byte as two disk
|
||||
bytes, one containing the odd bits,
|
||||
and the other containing the even
|
||||
bits. It would thus require 512
|
||||
"disk" bytes for each 256 byte sector
|
||||
of data. Had this technique been used
|
||||
for sector data, no more than 10
|
||||
sectors would have fit on a track.
|
||||
This amounts to about 88K of data per
|
||||
diskette, or roughly 72K of space
|
||||
available to the user; typical for 5
|
||||
1/4 single density drives.
|
||||
.pp
|
||||
Fortunately, a second technique for
|
||||
writing data to diskette was devised
|
||||
that allows 13
|
||||
sectors per track. This new method
|
||||
involved a "5 and 3" split of the
|
||||
data bits, versus the "4 and 4"
|
||||
mentioned earlier. Each byte written
|
||||
to the disk contains five valid bits
|
||||
rather than four. This requires 410
|
||||
"disk" bytes to store a 256 byte
|
||||
sector. This latter density allows
|
||||
the now well known 13 sectors per
|
||||
track format used by DOS 3 through
|
||||
DOS 3.2.1. The "5 and 3" scheme
|
||||
represented a hefty 33% increase over
|
||||
comparable drives of the day.
|
||||
.pp
|
||||
Currently, of course, DOS 3.3
|
||||
features 16 sectors per track and
|
||||
provides a 23% increase in disk
|
||||
storage over the 13 sector format.
|
||||
This was made possible by a hardware
|
||||
modification (the P6 PROM on the disk
|
||||
controller card) which allowed a "6
|
||||
and 2" split of the data. The change
|
||||
was to the logic of the "state
|
||||
machine" in the P6 PROM, now allowing
|
||||
two consecutive zero bits in data
|
||||
bytes.
|
||||
.pp
|
||||
These three different encoding
|
||||
techniques
|
||||
will now be covered in some detail.
|
||||
The hardware for DOS 3.2.1 (and
|
||||
earlier versions of DOS) imposed a
|
||||
number of restrictions upon how data
|
||||
could be stored and retrieved. It
|
||||
required that a disk byte have the
|
||||
high bit set and, in addition, no two
|
||||
consecutive bits could be zero.
|
||||
The odd-even "4 and 4" technique meets
|
||||
these requirements. Each data byte
|
||||
is represented as two bytes, one
|
||||
containing the even data bits and the
|
||||
other the odd data bits. Figure 3.15
|
||||
illustrates this transformation. It
|
||||
should be noted that the unused bits
|
||||
are all set to one to guarantee
|
||||
meeting the two requirements.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.15 HERE ***
|
||||
.PP
|
||||
No matter what value the original
|
||||
data data byte has, this technique
|
||||
insures that the high bit is set and
|
||||
that there can not be two consecutive
|
||||
zero bits. The "4 and 4" technique is
|
||||
used to store the information
|
||||
(volume, track, sector, checksum)
|
||||
contained in the Address Field. It
|
||||
is quite easy to decode the data, since the
|
||||
byte with the odd bits is simply
|
||||
shifted left and logically ANDed with
|
||||
the byte containing the even bits.
|
||||
This is illustrated in Figure 3.16.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.16 HERE ***
|
||||
.PP
|
||||
It is important that the least
|
||||
significant bit contain a 1 when the
|
||||
odd-bits byte is left shifted. The
|
||||
entire
|
||||
operation is carried out in the
|
||||
RDADR subroutine at $B944 in DOS
|
||||
(48K).
|
||||
.pp
|
||||
The major difficulty with the above
|
||||
technique is that it takes up a lot of
|
||||
room on the track. To overcome this
|
||||
deficiency the "5 and 3" encoding
|
||||
technique was developed. It is so named
|
||||
because, instead of splitting the
|
||||
bytes in half, as in the odd-even
|
||||
technique, they are split five and three. A
|
||||
byte would have the form 000XXXXX,
|
||||
where X is a valid data bit. The
|
||||
above byte could range in value from
|
||||
$00 to $1F, a total of 32 different
|
||||
values. It so happens that there are
|
||||
34 valid "disk" bytes, ranging
|
||||
from $AA up to $FF, which meet the
|
||||
two requirements (high bit set, no
|
||||
consecutive zero bits). Two bytes,
|
||||
$D5 and $AA, were chosen as reserved
|
||||
bytes, thus leaving an exact mapping
|
||||
between five bit data bytes and eight bit
|
||||
"disk" bytes. The process of
|
||||
converting eight bit data bytes to eight bit
|
||||
"disk" bytes, then, is twofold.
|
||||
An overview is diagrammed in Figure
|
||||
3.17.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.17 HERE ***
|
||||
.PP
|
||||
First, the 256 bytes that will make
|
||||
up a sector must be translated to
|
||||
five bit bytes. This is done by the
|
||||
"prenibble" routine at $B800. It is
|
||||
a fairly involved process, involving
|
||||
a good deal of bit rearrangement.
|
||||
Figure 3.18 shows the before and
|
||||
after of prenibbilizing. On the left
|
||||
is a buffer of eight bit data bytes, as
|
||||
passed to the RWTS subroutine
|
||||
package by DOS. Each byte in this
|
||||
buffer is represented by a letter (A,
|
||||
B, C, etc.) and each bit by a number
|
||||
(7 through 0). On the right side are
|
||||
the results of the transformation.
|
||||
The primary buffer contains five
|
||||
distinct areas of five bit bytes (the
|
||||
top three bits of the eight bit bytes
|
||||
zero-filled) and the secondary buffer
|
||||
contains three areas, graphically
|
||||
illustrating the name "5 and 3".
|
||||
.bp
|
||||
*** INSERT FIGURE 3.18 HERE ***
|
||||
.PP
|
||||
A total of 410 bytes are needed to
|
||||
store the original 256. This can be
|
||||
calculated by finding the total bits
|
||||
of data (256 x 8 = 2048) and dividing
|
||||
that by the number of bits per byte
|
||||
(2048 / 5 = 409.6). (two bits are
|
||||
not used) Once this process is
|
||||
completed, the data is further
|
||||
transformed to make it valid "disk"
|
||||
bytes, meeting the disk's
|
||||
requirements. This is much easier,
|
||||
involving a one to one look-up in the
|
||||
table given in Figure 3.19.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.19 HERE ***
|
||||
.pp
|
||||
The Data Field has a checksum much
|
||||
like the one in the Address Field,
|
||||
used to verify the integrity of the
|
||||
data. It also involves
|
||||
exclusive-ORing the information, but,
|
||||
due to time constraints during
|
||||
reading bytes, it is implemented
|
||||
differently. The data is
|
||||
exclusive-ORed in pairs before being
|
||||
transformed by the look-up table in
|
||||
Figure 3.19. This can best be
|
||||
illustrated by Figure 3.20 on the following page.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.20 HERE ***
|
||||
.PP
|
||||
The reason for this transformation
|
||||
can be better understood by examining
|
||||
how the information is retrieved from
|
||||
the disk. The read routine must read
|
||||
a byte, transform it, and store it --
|
||||
all in under 32 cycles (the time
|
||||
taken to write a byte) or the
|
||||
information will be lost. By using
|
||||
the checksum computation to decode
|
||||
data, the
|
||||
transformation shown in Figure 3.20
|
||||
greatly facilitates the time
|
||||
constraint. As the data is being
|
||||
read from a sector the accumulator
|
||||
contains the cumulative result of
|
||||
all previous bytes, exclusive-ORed
|
||||
together. The value of the
|
||||
accumulator after any exclusive-OR
|
||||
operation is the actual data byte
|
||||
for that point in the series.
|
||||
This process is diagrammed in Figure 3.21.
|
||||
.bp
|
||||
*** INSERT FIGURE 3.21 HERE ***
|
||||
.pp
|
||||
The third encoding technique, currently
|
||||
used by DOS 3.3, is similar to the "5
|
||||
and 3". It was made possible by a
|
||||
change in the hardware which eased
|
||||
the requirements for valid data
|
||||
somewhat. The high bit must still be
|
||||
set, but now the byte may contain one
|
||||
(and only one) pair of consecutive
|
||||
zero bits. This allows a greater
|
||||
number of valid bytes and permits the
|
||||
use of a "6 and 2" encoding technique.
|
||||
A six bit byte would have the form
|
||||
00XXXXXX and has values from $00 to
|
||||
$3F for a total of 64 different
|
||||
values. With the new, relaxed
|
||||
requirements for valid "disk" bytes
|
||||
there are 69 different bytes ranging
|
||||
in value from $96 up to $FF. After
|
||||
removing the two reserved bytes, $AA
|
||||
and $D5, there are still 67 "disk" bytes
|
||||
with only 64 needed. An additional
|
||||
requirement was introduced to force
|
||||
the mapping to be one to one, namely,
|
||||
that there must be at least two
|
||||
adjacent bits set, excluding bit 7.
|
||||
This produces exactly 64 valid "disk"
|
||||
values. The initial transformation
|
||||
is done by the prenibble routine
|
||||
(still located at $B800) and its
|
||||
results are shown in Figure 3.22.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.22 (20) HERE ***
|
||||
.PP
|
||||
A total of 342 bytes are needed,
|
||||
shown by finding the total number of
|
||||
bits (256 x 8 = 2048) and dividing by
|
||||
the number of bits per byte (2048 / 6
|
||||
= 341.33). The transformation from
|
||||
the six bit bytes to valid data bytes
|
||||
is again performed by a one to one
|
||||
mapping shown in Figure 3.23.
|
||||
Once again, the stream of data bytes
|
||||
written to the diskette are a product
|
||||
of exclusive-ORs, exactly as with the
|
||||
"5 and 3" technique discussed earlier.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.23 (21) HERE ***
|
||||
.sp1
|
||||
SECTOR INTERLEAVING
|
||||
.PP
|
||||
Sector interleaving is the staggering
|
||||
of sectors on a track to maximize
|
||||
access speed. There is usually a
|
||||
delay between the time DOS reads or
|
||||
writes a sector and the time it is
|
||||
ready to read or write another. This
|
||||
delay depends upon the application
|
||||
program using the disk and can vary
|
||||
greatly. If sectors were stored
|
||||
on the track
|
||||
sequentially, in ascending numerical
|
||||
order, unless the
|
||||
application was very quick indeed,
|
||||
it would
|
||||
usually be necessary to wait an
|
||||
entire revolution of the diskette
|
||||
before the next sector could be
|
||||
accessed. Rearranging the sectors
|
||||
into a different order or
|
||||
"interleaving" them can provide
|
||||
different access speeds.
|
||||
.bp
|
||||
On DOS 3.2.1 and earlier versions,
|
||||
the 13 sectors are physically
|
||||
interleaved on the disk. Since DOS
|
||||
resides on the diskette in ascending
|
||||
sequential order and files generally
|
||||
are stored in descending sequential
|
||||
order, no single interleaving scheme
|
||||
works well for both booting and
|
||||
sequentially accessing a file.
|
||||
.pp
|
||||
A different approach has been used in
|
||||
DOS 3.3 in an attempt to maximize
|
||||
performance. The interleaving is now
|
||||
done in software. The 16 sectors are
|
||||
stored in numerically ascending order
|
||||
on the diskette (0, 1, 2, ... , 15)
|
||||
and are not physically interleaved at
|
||||
all. A look-up table is used to
|
||||
translate the physical sector number
|
||||
into a "pseudo" or soft sector number
|
||||
used by DOS. For example, if the
|
||||
sector number found on the disk were a
|
||||
2, this is used as an offset into a
|
||||
table where the number $0B is found.
|
||||
Thus, DOS treats the physical sector
|
||||
2 as sector 11 ($0B) for all intents
|
||||
and purposes. This presents no
|
||||
problem if RWTS is used for disk
|
||||
access, but would become a
|
||||
consideration if access were made
|
||||
without RWTS.
|
||||
.pp
|
||||
To eliminate the access differences
|
||||
between booting and reading files,
|
||||
another change has been made. During
|
||||
the boot process, DOS is loaded
|
||||
backwards in descending sequential
|
||||
order into memory, just as files are
|
||||
accessed. This means one
|
||||
interleaving scheme can minimize disk
|
||||
access time.
|
||||
.pp
|
||||
It is interesting to point out that
|
||||
Pascal, Fortran, and CP/M diskettes
|
||||
all use software interleaving also.
|
||||
However, each uses a different
|
||||
sector order. A comparison of these
|
||||
differences is presented in Figure
|
||||
3.24.
|
||||
.sp1
|
||||
*** INSERT FIGURE 3.24 (22) HERE ***
|
||||
.br
|
||||
.nxch4
|
||||
\x00
|
664
D1S1/CH4#064000.txt
Normal file
664
D1S1/CH4#064000.txt
Normal file
|
@ -0,0 +1,664 @@
|
|||
.bp
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 4 - DISKETTE DATA FORMATS
|
||||
.pp
|
||||
As was described in CHAPTER 3, a 16
|
||||
sector diskette consists of 560 data
|
||||
areas of 256 bytes each, called
|
||||
sectors. These sectors are arranged
|
||||
on the diskette in 35 concentric
|
||||
rings or tracks of 16 sectors each.
|
||||
The way DOS allocates these tracks of
|
||||
sectors is the subject of
|
||||
this chapter.
|
||||
.pp
|
||||
A file (be it APPLESOFT,
|
||||
INTEGER, BINARY, or TEXT type)
|
||||
consists of one or more sectors
|
||||
containing data. Since the sector is
|
||||
the smallest unit of allocatable
|
||||
space on a diskette, a file will use
|
||||
up at least one sector even if it is
|
||||
less than 256 bytes long; the
|
||||
remainder of the sector is wasted.
|
||||
Thus, a file containing 400
|
||||
characters (or bytes) of data will
|
||||
occupy one entire sector and 144
|
||||
bytes of another with 112 bytes
|
||||
wasted. Knowing these facts, one
|
||||
would expect to be able to use up to
|
||||
16 times 35 times 256 or
|
||||
143,360 bytes of space on a diskette
|
||||
for files. Actually, the largest file
|
||||
that can be stored is about 126,000
|
||||
bytes long. The reason for this is
|
||||
that some o\x86PL@\x85TCESHWV\x87HK\x86PL@)ALUOCQP@\x85HQUS\x84DB\x85PUCA\x84@JW\x86PODQ\x84LU*FGIH@@\x87\x85HQAUOCGA\x85\x8b\x86\x84hSAVNCGB\x86UCDSHWV+EKKRDMI\x86PL@\x85LIEAC\x85HC\x86`hw\x87POLEO\x84LU+IHGA@A\x84PO@I*EJKSNJC\x86QMA\x87@OVNBSPC\x8a\x87E\x86KLVQ\x85JC\x85QM@)IFIAU\x87DIB\x84HHGGQLIKV\x87HC\x86PL@\x85@NI@U\x87HK*QL@\x85@LUOCQP@\x89\x84DIB\x87EI\x86EEDJPKPNIB\x87HC)RMB\x85VCGPKVW\x26 which are free for use
|
||||
with new files or expansions of
|
||||
existing files. An example of the way
|
||||
DOS uses sectors is given in Figure
|
||||
4.1.
|
||||
.SP1
|
||||
*** INSERT FIGURE 4.1 ***
|
||||
.sp1
|
||||
DISKETTE SPACE ALLOCATION
|
||||
.pp
|
||||
The map in Figure 4.1 shows that the
|
||||
first three tracks of each diskette
|
||||
are always reserved for the bootstrap
|
||||
image of DOS. In the exact center
|
||||
track (track 17) is the VTOC and
|
||||
catalog. The reason for placing the
|
||||
catalog here is simple. Since the
|
||||
greatest delay when using the disk is
|
||||
waiting for the arm to move from
|
||||
track to track, it is advantageous to
|
||||
minimize this arm movement whenever
|
||||
possible. By placing the catalog in
|
||||
the exact center track of the disk,
|
||||
the arm need never travel more than
|
||||
17 tracks to get to the catalog
|
||||
track.
|
||||
As files are allocated
|
||||
on a diskette, they occupy the tracks
|
||||
just above the catalog track first.
|
||||
When the last track, track 34, has been used, track 16,
|
||||
the track adjacent and below the
|
||||
catalog,
|
||||
is used next, then 15, 14, 13, and so
|
||||
on, moving away from the catalog
|
||||
again, toward the DOS image tracks.
|
||||
If there are very few files on
|
||||
the diskette, they will all be
|
||||
clustered, hopefully, near the
|
||||
catalog and arm movement will be
|
||||
minimized. Additional space for a
|
||||
file, if it is needed, is first allocated
|
||||
in the same track occupied by the file.
|
||||
When that track is full, another
|
||||
track is allocated elsewhere on the
|
||||
disk in the manner described above.
|
||||
.bp
|
||||
THE VTOC
|
||||
.pp
|
||||
The Volume Table Of Contents is the "anchor" of the
|
||||
entire diskette. On any diskette
|
||||
accessible by any version of DOS, the
|
||||
VTOC sector is always in the same
|
||||
place; track 17, sector 0. (Some protected
|
||||
disks have the VTOC at another location
|
||||
and provide a special DOS which can find it.)
|
||||
Since files can end up anywhere on the
|
||||
diskette, it is through the VTOC
|
||||
anchor that DOS is able to find them.
|
||||
The VTOC of a diskette has the
|
||||
following format (all byte offsets are
|
||||
given in base 16, hexadecimal):
|
||||
.np
|
||||
VOLUME TABLE OF CONTENTS (VTOC) FORMAT
|
||||
.SP1
|
||||
.un
|
||||
BYTE DESCRIPTION
|
||||
00 Not used
|
||||
01 Track number of first catalog sector
|
||||
02 Sector number of first catalog sector
|
||||
03 Release number of DOS used to INIT this diskette
|
||||
04-05 Not used
|
||||
06 Diskette volume number (1-254)
|
||||
07-26 Not used
|
||||
27 Maximum number of track/sector pairs which will fit
|
||||
in one file track/sector list sector (122 for 256
|
||||
byte sectors)
|
||||
28-2F Not used
|
||||
30 Last track where sectors were allocated
|
||||
31 Direction of track allocation (+1 or -1)
|
||||
32-33 Not used
|
||||
34 Number of tracks per diskette (normally 35)
|
||||
35 Number of sectors per track (13 or 16)
|
||||
36-37 Number of bytes per sector (LO/HI format)
|
||||
38-3B Bit map of free sectors in track 0
|
||||
3C-3F Bit map of free sectors in track 1
|
||||
40-43 Bit map of free sectors in track 2
|
||||
...
|
||||
BC-BF Bit map of free sectors in track 33
|
||||
C0-C3 Bit map of free sectors in track 34
|
||||
C4-FF Bit maps for additional tracks if there are more
|
||||
than 35 tracks per diskette
|
||||
.bp
|
||||
BIT MAPS OF FREE SECTORS ON A GIVEN TRACK
|
||||
.SP1
|
||||
A four byte binary string of ones and zeros,
|
||||
representing free and allocated sectors respectively.
|
||||
Hexadecimal sector numbers are assigned to bit
|
||||
positions as follows:
|
||||
.sp1
|
||||
BYTE SECTORS
|
||||
+0 FEDC BA98
|
||||
+1 7654 3210
|
||||
+2 .... .... (not used)
|
||||
+3 .... .... (not used)
|
||||
.sp1
|
||||
Thus, if only sectors E and 8 are free and all
|
||||
others are allocated, the bit map will be:
|
||||
.sp1
|
||||
41000000
|
||||
.sp1
|
||||
If all sectors are free:
|
||||
|
||||
FFFF0000
|
||||
.pp
|
||||
An example of a VTOC sector is given
|
||||
in Figure 4.2. This VTOC corresponds
|
||||
to the map of the diskette given in
|
||||
Figure 4.1.
|
||||
.SP1
|
||||
*** INSERT FIGURE 4.2 ***
|
||||
.bp
|
||||
THE CATALOG
|
||||
.ll30
|
||||
.pp
|
||||
In order for DOS to find a given
|
||||
file, it must first read the VTOC to
|
||||
find out where the first catalog
|
||||
sector is located. Typically, the
|
||||
catalog sectors for a diskette are
|
||||
the remaining sectors on track 17,
|
||||
following the VTOC sector. Of course,
|
||||
as long as a track/sector pointer
|
||||
exists in the VTOC and the VTOC is
|
||||
located at track 17, sector 0, DOS
|
||||
does not really care where the
|
||||
catalog resides.
|
||||
Figure 4.3 diagrams the catalog
|
||||
track. The figure shows the
|
||||
track/sector pointer
|
||||
in the VTOC at bytes 01 and 02 as an
|
||||
arrow pointing to track 17 (11 in
|
||||
hexadecimal)
|
||||
sector F. The last sector in the
|
||||
track is the first catalog sector and
|
||||
describes the first seven files on
|
||||
the diskette. Each catalog
|
||||
sector has a track/sector
|
||||
pointer in the same position (bytes
|
||||
01 and 02) which points to the next
|
||||
catalog sector. The last catalog
|
||||
sector (sector 1)
|
||||
has a zero pointer to indicate
|
||||
that there are no more catalog
|
||||
sectors in the chain.
|
||||
.SP1
|
||||
*** INSERT FIGURE 4.3 ***
|
||||
.PP
|
||||
In each catalog
|
||||
sector up to seven files may be
|
||||
listed and described. Thus, on a
|
||||
typical DOS 3.3 diskette, the catalog can
|
||||
hold up to 15 times
|
||||
7, or 105 files. A
|
||||
catalog sector is formatted as
|
||||
described on the following page.
|
||||
.br
|
||||
.ll60
|
||||
.sp1
|
||||
.np
|
||||
CATALOG SECTOR FORMAT
|
||||
.SP1
|
||||
.UN
|
||||
BYTE DESCRIPTION
|
||||
00 Not used
|
||||
01 Track number of next catalog sector (usually 11 hex)
|
||||
02 Sector number of next catalog sector
|
||||
03-0A Not used
|
||||
0B-2D First file descriptive entry
|
||||
2E-50 Second file descriptive entry
|
||||
51-73 Third file descriptive entry
|
||||
74-96 Fourth file descriptive entry
|
||||
97-B9 Fifth file descriptive entry
|
||||
BA-DC Sixth file descriptive entry
|
||||
DD-FF Seventh file descriptive entry
|
||||
.bp
|
||||
FILE DESCRIPTIVE ENTRY FORMAT
|
||||
.SP1
|
||||
RELATIVE
|
||||
.UN
|
||||
BYTE DESCRIPTION
|
||||
00 Track of first track/sector list sector.
|
||||
If this is a deleted file, this byte contains a hex
|
||||
FF and the original track number is copied to the
|
||||
last byte of the file name field (BYTE 20).
|
||||
If this byte contains a hex 00, the entry is assumed
|
||||
to never have been used and is available for use.
|
||||
(This means track 0 can never be used for data even
|
||||
if the DOS image is "wiped" from the diskette.)
|
||||
01 Sector of first track/sector list sector
|
||||
02 File type and flags:
|
||||
Hex 80+file type - file is locked
|
||||
00+file type - file is not locked
|
||||
00 - TEXT file
|
||||
01 - INTEGER BASIC file
|
||||
02 - APPLESOFT BASIC file
|
||||
04 - BINARY file
|
||||
08 - S type file
|
||||
10 - RELOCATABLE object module file
|
||||
20 - A type file
|
||||
40 - B type file
|
||||
(thus, 84 is a locked BINARY file, and 90 is a
|
||||
locked R type file)
|
||||
03-20 File name (30 characters)
|
||||
21-22 Length of file in sectors (LO/HI format).
|
||||
The CATALOG command will only format the LO byte of
|
||||
this length giving 1-255 but a full 65,535 may be
|
||||
stored here.
|
||||
.sp
|
||||
.pp
|
||||
Figure 4.4 is an example of a typical
|
||||
catalog sector. In this example there
|
||||
are only four files on the entire
|
||||
diskette, so only one catalog sector
|
||||
was needed to describe them. There
|
||||
are four entries in use and three
|
||||
entries which have never been used
|
||||
and contain zeros.
|
||||
.SP1
|
||||
*** INSERT FIGURE 4.4 ***
|
||||
.SP1
|
||||
THE TRACK/SECTOR LIST
|
||||
.PP
|
||||
Each file has
|
||||
associated with it a "Track/Sector
|
||||
List" sector. This sector contains a
|
||||
list of track/sector pointer pairs
|
||||
which sequentially list the data sectors
|
||||
which make up the file. The file
|
||||
descriptive entry in the catalog
|
||||
sector points to this T/S List sector
|
||||
which, in turn, points to each sector
|
||||
in the file. This concept is
|
||||
diagramed in Figure 4.5.
|
||||
.SP1
|
||||
*** INSERT FIGURE 4.5 ***
|
||||
.bp
|
||||
The format of a Track/Sector List
|
||||
sector is given below. Note that
|
||||
since even a minimal file requires
|
||||
one T/S List sector and one data
|
||||
sector, the least number of sectors a
|
||||
non-empty
|
||||
file can have is 2. Also, note that a
|
||||
very large file, having more than 122
|
||||
data sectors, will need more than one
|
||||
Track/Sector List to hold all the
|
||||
Track/Sector pointer pairs.
|
||||
.sp1
|
||||
.ne10
|
||||
.np
|
||||
TRACK/SECTOR LIST FORMAT
|
||||
.sp1
|
||||
.un
|
||||
BYTE DESCRIPTION
|
||||
00 Not used
|
||||
01 Track number of next T/S List sector if one was
|
||||
needed or zero if no more T/S List sectors.
|
||||
02 Sector number of next T/S List sector (if present).
|
||||
03-04 Not used
|
||||
05-06 Sector offset in file of the first sector described
|
||||
by this list.
|
||||
07-0B Not used
|
||||
0C-0D Track and sector of first data sector or zeros
|
||||
0E-0F Track and sector of second data sector or zeros
|
||||
10-FF Up to 120 more Track/Sector pairs
|
||||
.sp1
|
||||
.pp
|
||||
A sequential file will end when the first zero T/S List entry
|
||||
is encountered. A random file, however, can have spaces within
|
||||
it which were never allocated and therefore
|
||||
have no data sectors allocated
|
||||
in the T/S List. This distinction is not always handled
|
||||
correctly by DOS. The VERIFY command, for instance, stops when
|
||||
it gets to the first zero T/S List entry and can not be used
|
||||
to verify some random organization text files.
|
||||
.pp
|
||||
An example T/S List sector is given in Figure 4.6.
|
||||
The example file (HELLO, from our
|
||||
previous examples) has only one data
|
||||
sector, since it is less than 256
|
||||
bytes in length. Counting this data
|
||||
sector and the T/S List sector, HELLO
|
||||
is 2 sectors long, and this will be
|
||||
the value shown when a CATALOG
|
||||
command is done.
|
||||
.SP1
|
||||
*** INSERT FIGURE 4.6 ***
|
||||
.bp
|
||||
Following the Track/Sector pointer in
|
||||
the T/S List sector, we come to the
|
||||
first data sector of the file. As
|
||||
we examine the data sectors, the
|
||||
differences between the file types
|
||||
become apparent. All files (except,
|
||||
perhaps, a random TEXT file) are
|
||||
considered to be continuous streams
|
||||
of data, even though they must be
|
||||
broken up into 256 byte chunks to
|
||||
fit in sectors on the diskette.
|
||||
Although these sectors are not
|
||||
necessarily contiguous (or next to
|
||||
each other on the diskette), by using
|
||||
the Track/Sector List, DOS can read
|
||||
each sector of the file in the correct order so
|
||||
that the programmer need never know
|
||||
that the data was broken up into
|
||||
sectors at all.
|
||||
.SP1
|
||||
TEXT FILES
|
||||
.pp
|
||||
The TEXT data type is the least
|
||||
complicated
|
||||
file data structure. It consists of
|
||||
one or more records, separated from
|
||||
each other by carriage return
|
||||
characters (hex 8D's). This structure
|
||||
is diagrammed and an example file is
|
||||
given in Figure 4.7. Usually, the end
|
||||
of a TEXT file is signaled by the
|
||||
presence of a hex 00 or the lack of
|
||||
any more data sectors in the T/S List
|
||||
for the file. As mentioned
|
||||
earlier, if the file has random
|
||||
organization, there may be hex 00's
|
||||
imbedded in the data and even missing
|
||||
data sectors in areas where nothing
|
||||
was ever written. In this case, the
|
||||
only way to find the end of the file
|
||||
is to scan the Track/Sector List for
|
||||
the last non-zero Track/Sector pair.
|
||||
Since carriage return characters and
|
||||
hex 00's have special meaning in a
|
||||
TEXT type file, they can not be part
|
||||
of the data itself. For this reason,
|
||||
and to make the data accessible to
|
||||
BASIC, the data can only contain
|
||||
printable or ASCII characters
|
||||
(alphabetics, numerics or special
|
||||
characters, see p. 8 in the APPLE II
|
||||
REFERENCE MANUAL)
|
||||
This restriction makes
|
||||
processing of a TEXT file slower and
|
||||
less efficient in the use of disk space than
|
||||
with a BINARY type file, since each
|
||||
digit must occupy a full byte in the
|
||||
file.
|
||||
.SP1
|
||||
*** INSERT FIGURE 4.7 ***
|
||||
.bp
|
||||
BINARY FILES
|
||||
.pp
|
||||
The structure of a BINARY type file is
|
||||
shown in Figure 4.8. An exact copy of
|
||||
the memory involved is written to the
|
||||
disk sector(s), preceded by the
|
||||
memory address where it was found and
|
||||
the length (a total of four bytes).
|
||||
The address and length (in low order,
|
||||
high order format) are those given in
|
||||
the A and L keywords from the BSAVE
|
||||
command which created the file.
|
||||
Notice that DOS writes one extra byte
|
||||
to the file. This does not matter too
|
||||
much since BLOAD and BRUN
|
||||
will only read the
|
||||
number of bytes given in the length
|
||||
field. (Of course, if you BSAVE a
|
||||
multiple of 256 bytes, a sector will
|
||||
be wasted because of this error)
|
||||
DOS could be made to BLOAD or BRUN
|
||||
the binary image at a different
|
||||
address either by providing the A
|
||||
(address) keyword when the command is
|
||||
entered, or by changing the address
|
||||
in the first two bytes of the file on
|
||||
the diskette.
|
||||
.SP1
|
||||
*** INSERT FIGURE 4.8 ***
|
||||
.SP1
|
||||
APPLESOFT AND INTEGER FILES
|
||||
.pp
|
||||
A BASIC program, be it APPLESOFT or
|
||||
INTEGER, is saved to the diskette in
|
||||
a way that is similar to BSAVE. The
|
||||
format of an APPLESOFT file type is
|
||||
given in Figure 4.9 and that of
|
||||
INTEGER BASIC in 4.10. When the SAVE
|
||||
command is typed, DOS determines the
|
||||
location of the BASIC program image
|
||||
in memory and its length. Since a
|
||||
BASIC program is always loaded at a
|
||||
location known to the BASIC
|
||||
interpreter, it is not necessary to
|
||||
store the address in the file as with
|
||||
a BINARY file. The length is stored,
|
||||
however, as the first two bytes, and
|
||||
is followed by the image from memory.
|
||||
Notice that, again, DOS incorrectly
|
||||
writes an additional byte, even though
|
||||
it will be ignored by LOAD. The
|
||||
memory image of the program consists
|
||||
of program lines in an internal
|
||||
format which is made up of what are
|
||||
called "tokens". A treatment of the
|
||||
structure of a BASIC program as it
|
||||
appears in memory is outside the
|
||||
scope of this manual, but a
|
||||
breakdown of the example INTEGER
|
||||
BASIC program is given in Figure
|
||||
4.10.
|
||||
.SP1
|
||||
*** INSERT FIGURES 4.9 AND 4.10 ***
|
||||
.bp
|
||||
OTHER FILE TYPES (S,R,A,B)
|
||||
.pp
|
||||
Additional file types have been
|
||||
defined within DOS as can be seen in
|
||||
the file descriptive entry format,
|
||||
shown
|
||||
earlier. No DOS commands at present
|
||||
use these additional types so their
|
||||
eventual meaning is anybody's guess.
|
||||
The R file type, however, has been
|
||||
used with the DOS TOOLKIT assembler
|
||||
for its output file, a relocatable
|
||||
object module. This file type is used
|
||||
with a
|
||||
special form of BINARY file which can
|
||||
contain the memory image of a machine
|
||||
language program which may be
|
||||
relocated anywhere in the machine
|
||||
based on additional information
|
||||
stored with the image itself. The
|
||||
format for this type of file is given
|
||||
in the documentation accompanying the
|
||||
DOS TOOLKIT.
|
||||
It is recommended that if the
|
||||
reader requires more information
|
||||
about R files he should refer to that
|
||||
documentation.
|
||||
.sp1
|
||||
EMERGENCY REPAIRS
|
||||
.PP
|
||||
From time to time the information on
|
||||
a diskette can become damaged or
|
||||
lost. This can create various
|
||||
symptoms, ranging from mild side
|
||||
effects, such as the disk not
|
||||
booting, to major problems, such as
|
||||
an input/output (I/O) error in the catalog. A good
|
||||
understanding of the format of a
|
||||
diskette, as described previously,
|
||||
and a few program tools can allow any
|
||||
reasonably sharp APPLE II user to
|
||||
patch up most errors on his
|
||||
diskettes.
|
||||
.pp
|
||||
A first question would be, "how do
|
||||
errors occur". The most common cause
|
||||
of an error is a worn or physically
|
||||
damaged diskette. Usually, a diskette
|
||||
will warn you that it is wearing out
|
||||
by producing "soft errors". Soft
|
||||
errors are I/O errors which occur
|
||||
only randomly. You may get an I/O
|
||||
error message when you catalog a
|
||||
disk one time and have it catalog
|
||||
correctly if you
|
||||
try again. When this happens, the
|
||||
smart programmer immediately copies
|
||||
the files on
|
||||
the aged diskette to a brand new one
|
||||
and discards the old one or keeps it
|
||||
as a backup.
|
||||
.pp
|
||||
Another cause of damaged diskettes is
|
||||
the practice of hitting the RESET key
|
||||
to abort the execution of a program
|
||||
which is
|
||||
accessing the diskette. Damage will
|
||||
usually occur when the RESET signal
|
||||
comes just as data is being written
|
||||
onto the disk. Powering the machine
|
||||
off just as data is being written to
|
||||
the disk is also a sure way to
|
||||
clobber a diskette. Of course, real
|
||||
hardware problems in the disk drive
|
||||
or controller card and ribbon cable
|
||||
can cause damage as well.
|
||||
.bp
|
||||
If the damaged diskette can be
|
||||
cataloged, recovery is much easier.
|
||||
A damaged DOS image in the first
|
||||
three tracks can usually be corrected
|
||||
by running the MASTER CREATE program
|
||||
against the diskette
|
||||
or by copying all the files to
|
||||
another diskette. If only one file
|
||||
produces an I/O error when it is
|
||||
VERIFYed, it may be possible to copy
|
||||
most of the sectors of the file to
|
||||
another diskette by skipping over the
|
||||
bad sector with an assembler program
|
||||
which calls RWTS in DOS or with a
|
||||
BASIC program (if the file is a TEXT
|
||||
file). Indeed, if the problem is a bad
|
||||
checksum (see CHAPTER 3) it may be
|
||||
possible to read the bad sector and
|
||||
ignore the error and get most of the
|
||||
data.
|
||||
.pp
|
||||
An I/O error usually means that one
|
||||
of two conditions has occured. Either
|
||||
a bad checksum was detected on the
|
||||
data in a sector, meaning that one or
|
||||
more bytes is bad; or the
|
||||
sectoring is clobbered such that the
|
||||
sector no longer even exists on the
|
||||
diskette. If the latter is the case,
|
||||
the diskette (or at the very least,
|
||||
the track) must be reformatted,
|
||||
resulting in a massive loss of data.
|
||||
Although DOS can be patched to format
|
||||
a single track, it is usually easier
|
||||
to copy all readable sectors from the
|
||||
damaged diskette to another formatted
|
||||
diskette and then reconstruct the
|
||||
lost data there.
|
||||
.pp
|
||||
Many commercially available utilities
|
||||
exist which allow the user to
|
||||
read and display the contents of
|
||||
sectors. Some of these utilities also
|
||||
allow you to modify the sector data
|
||||
and rewrite it to the same or another
|
||||
diskette. A simple version of such a
|
||||
utility is provided in APPENDIX A.
|
||||
The ZAP program given there will read
|
||||
any track/sector into memory,
|
||||
allowing the user to examine it or
|
||||
modify the data and then, optionally,
|
||||
rewrite it to a diskette. Using such
|
||||
a program is very important when
|
||||
learning about diskette formats and
|
||||
when fixing clobbered data.
|
||||
.bp
|
||||
Using ZAP, a bad sector within a file
|
||||
can be localized by reading each
|
||||
track/sector listed in the T/S List
|
||||
sector for the file. If the bad
|
||||
sector is a catalog sector, the
|
||||
pointers of up to seven files may be
|
||||
lost. When this occurs, a
|
||||
search of the diskette can be made to
|
||||
find T/S List sectors which do not
|
||||
correspond to any files listed in the
|
||||
remaining "good" catalog sectors.
|
||||
As these
|
||||
sectors are found, new file
|
||||
descriptive entries can be made in the
|
||||
damaged sector which point to these
|
||||
T/S Lists. When the entire catalog is
|
||||
lost, this process can take hours,
|
||||
even with a good understanding of
|
||||
the format of DOS diskettes. Such an
|
||||
endeavor should only be undertaken if
|
||||
there is no other way to recover the
|
||||
data. Of course the best policy is to
|
||||
create backup copies of important
|
||||
files periodically to simplify
|
||||
recovery. More information on the
|
||||
above procedures is given in APPENDIX
|
||||
A.
|
||||
.pp
|
||||
A less significant form of diskette
|
||||
clobber, but very annoying, is the
|
||||
loss of free sectors. Since DOS
|
||||
allocates an entire track of sectors
|
||||
at a time while a file is open,
|
||||
hitting RESET can cause these sectors
|
||||
to be marked in use in the VTOC even
|
||||
though they have not yet been added
|
||||
to any T/S List. These lost sectors
|
||||
can never be recovered by normal
|
||||
means, even when the file is deleted,
|
||||
since they are not in its T/S List.
|
||||
The result is a DISK FULL message
|
||||
before the diskette is actually full.
|
||||
To reclaim the lost sectors
|
||||
it is necessary to
|
||||
compare every sector listed in every
|
||||
T/S List against the VTOC bit map to
|
||||
see if there are any discrepancies.
|
||||
There are utility programs which will
|
||||
do this automatically but the best
|
||||
way to solve this problem is to copy
|
||||
all the files on the diskette to
|
||||
another diskette (note that FID must
|
||||
be used, not COPY, since COPY copies
|
||||
an image of the diskette, bad VTOC
|
||||
and all).
|
||||
.pp
|
||||
If a file is deleted it can usually
|
||||
be recovered, providing that
|
||||
additional sector allocations have
|
||||
not occured since it was deleted.
|
||||
If another file was created after the
|
||||
DELETE command, DOS might have reused
|
||||
some or all of the sectors of the old
|
||||
file. The catalog can be quickly
|
||||
ZAPped to move the track number of the T/S
|
||||
List from byte 20 of the file
|
||||
descriptive entry to byte 0. The file
|
||||
should then be copied to another disk
|
||||
and then the original deleted so that
|
||||
the VTOC freespace bit map will
|
||||
be updated.
|
||||
.nx ch5
|
||||
\x00
|
375
D1S1/CH5#064000.txt
Normal file
375
D1S1/CH5#064000.txt
Normal file
|
@ -0,0 +1,375 @@
|
|||
.bp
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 5 - THE STRUCTURE OF DOS
|
||||
.sp 2
|
||||
DOS MEMORY USE
|
||||
.pp
|
||||
DOS is an assembly language program
|
||||
which is loaded into RAM memory when
|
||||
the user boots his disk. If the
|
||||
diskette booted is a master diskette,
|
||||
the DOS image is loaded into the last
|
||||
possible part of RAM memory,
|
||||
dependent upon the size of the actual
|
||||
machine on which it is run. By doing
|
||||
this, DOS fools the active BASIC
|
||||
into believing that there is
|
||||
actually less RAM memory on the
|
||||
machine than there is. On a 48K APPLE
|
||||
II wi\x17\x0b\x43\x27\x2fS\x2f##\x5c#?/g\x19\x72or instance, BASIC believes that
|
||||
there is only about 38K of RAM. DOS does
|
||||
this by adjusting HIMEM after it is
|
||||
loaded to prevent BASIC from using
|
||||
the memory DOS is occupying.
|
||||
If a slave diskette is booted, DOS is
|
||||
loaded into whatever RAM it occupied
|
||||
when the slave diskette was
|
||||
INITialized. If the slave was created
|
||||
on a 16K APPLE, DOS will be loaded in
|
||||
the 6 to 16K range of RAM, even if
|
||||
the machine now has 48K.
|
||||
In this case, the APPLE will appear,
|
||||
for all intents an purposes, to have
|
||||
only 6K of RAM.
|
||||
If the slave was created
|
||||
on a 48K system, it will not boot on
|
||||
less than 48K since the RAM DOS
|
||||
occupied does not exist on a smaller
|
||||
machine.
|
||||
.SP1
|
||||
*** INSERT FIGURE 5.1 ***
|
||||
.pp
|
||||
A diagram of DOS's memory for a 48K
|
||||
APPLE II is given in
|
||||
Figure 5.1. As can be seen, there are
|
||||
four major divisions to the memory
|
||||
occupied by DOS. The first 1.75K is
|
||||
used for file buffers. With the
|
||||
default of MAXFILES 3, there are
|
||||
three file buffers set aside here.
|
||||
Each buffer occupies 595 bytes and
|
||||
corresponds to one potentially
|
||||
open file. File
|
||||
buffers are also used by DOS to LOAD
|
||||
and SAVE files, etc. If MAXFILES is
|
||||
changed from 3, the space occupied by
|
||||
the file buffers also changes. This
|
||||
affects the placement of HIMEM,
|
||||
moving it up or down with fewer or
|
||||
more buffers respectively.
|
||||
.pp
|
||||
The 3.5K
|
||||
above the file buffers is occupied by
|
||||
the main DOS routines. It is here
|
||||
that DOS's executable machine language
|
||||
code begins. The main routines are
|
||||
responsible for initializing DOS,
|
||||
interfacing to BASIC, interpreting
|
||||
commands, and managing the file
|
||||
buffers. All disk functions are
|
||||
passed on via subroutine calls to the
|
||||
file manager.
|
||||
.bp
|
||||
The file manager,
|
||||
occupying about 4.3K, is a collection
|
||||
of subroutines which perform almost
|
||||
any function needed to access a disk
|
||||
file. Functions include: OPEN, CLOSE,
|
||||
READ, WRITE, POSITION, DELETE,
|
||||
CATALOG, LOCK, UNLOCK, RENAME, INIT,
|
||||
and VERIFY. Although the file manager
|
||||
is a subroutine of DOS it may also be
|
||||
called by a user written assembly
|
||||
lanaguage program which is not part
|
||||
of DOS. This interface is generalized
|
||||
through a group of vectors in page 3
|
||||
of RAM and is documented in the next
|
||||
chapter.
|
||||
.pp
|
||||
The last 2.5K of DOS is the
|
||||
Read/Write Track/Sector (RWTS)
|
||||
package. RWTS is the next step lower
|
||||
in protocol from the file manager -
|
||||
in fact it is called as a subroutine
|
||||
by the file manager. Where the file
|
||||
manager deals with files, RWTS deals
|
||||
with tracks and sectors on the
|
||||
diskette. A typical call to RWTS
|
||||
would be to read track 17 sector 0 or
|
||||
to write 256 bytes of data in memory
|
||||
onto track 5 sector E. An external
|
||||
interface is also provided for access
|
||||
to RWTS from a user written assembly
|
||||
language program and is described in
|
||||
the next chapter.
|
||||
.sp1
|
||||
.ne5
|
||||
THE DOS VECTORS IN PAGE 3
|
||||
.ll30
|
||||
.pp
|
||||
In addition to the approximately 10K
|
||||
of RAM occupied by DOS in high
|
||||
memory, DOS maintains a group of what
|
||||
are called "vectors" in page 3
|
||||
of low memory ($300
|
||||
through $3FF). These
|
||||
vectors allow access to certain
|
||||
places within the DOS collection of
|
||||
routines via a fixed location ($3D0
|
||||
for instance). Because DOS may be
|
||||
loaded in various locations,
|
||||
depending upon the size of the
|
||||
machine and whether a slave or master
|
||||
diskette is booted, the addresses of
|
||||
the externally callable subroutines
|
||||
within DOS will change. By putting
|
||||
the addresses of these routines in a
|
||||
vector at a fixed location,
|
||||
dependencies on DOS's location in
|
||||
memory are eliminated. The page 3
|
||||
vector table is also useful in
|
||||
locating subroutines within DOS which
|
||||
may not be in the same memory
|
||||
location for different versions of
|
||||
DOS. Locations $300 through $3CF were
|
||||
used by earlier versions of DOS
|
||||
during the boot process to load the
|
||||
Boot 1 program but are used by DOS
|
||||
3.3 as a data buffer and disk code
|
||||
translate table.
|
||||
Presumably, this change was made to
|
||||
provide more memory for the first
|
||||
bootstrap loader (more on this
|
||||
later). The vector
|
||||
table itself starts at $3D0.
|
||||
.br
|
||||
.ll60
|
||||
.bp
|
||||
DOS VECTOR TABLE ($3D0-$3FF)
|
||||
.NP
|
||||
ADDR USAGE
|
||||
3D0 A JMP (jump or GOTO) instruction to the DOS warmstart
|
||||
routine. This routine reenters DOS but does not
|
||||
discard the current BASIC program and does not reset
|
||||
MAXFILES or other DOS environmental variables.
|
||||
3D3 A JMP to the DOS coldstart routine. This routine
|
||||
reinitializes DOS as if it was rebooted, clearing the
|
||||
current BASIC file and resetting HIMEM.
|
||||
3D6 A JMP to the DOS file manager subroutine to allow a
|
||||
user written assembly language program to call it.
|
||||
3D9 A JMP to the DOS Read/Write Track/Sector (RWTS)
|
||||
routine to allow user written assembly language
|
||||
programs to call it.
|
||||
3DC A short subroutine which locates the input parameter
|
||||
list for the file manager to allow a user written
|
||||
program to set up input parameters before calling the
|
||||
file manager.
|
||||
3E3 A short subroutine which locates the input parameter
|
||||
list for RWTS to allow a user written program to set
|
||||
up input parameters before calling RWTS.
|
||||
3EA A JMP to the DOS subroutine which "reconnects" the DOS
|
||||
intercepts to the keyboard and screen data streams.
|
||||
3EF A JMP to the routine which will handle a BRK machine
|
||||
language instruction. This vector is only supported by
|
||||
the AUTOSTART ROM. Normally the vector contains the
|
||||
address of the monitor ROM subroutine which displays
|
||||
the registers.
|
||||
3F2 LO/HI address of routine which will handle RESET for
|
||||
the AUTOSTART ROM. Normally the DOS restart address is
|
||||
stored here but the user may change it if he wishes to
|
||||
handle RESET himself.
|
||||
3F4 Power-up byte. Contains a "funny complement" of the
|
||||
RESET address with a $A5. This scheme is used to
|
||||
determine if the machine was just powered up or if
|
||||
RESET was pressed. If a power-up occured, the
|
||||
AUTOSTART ROM ignores the address at 3F2 (since it has
|
||||
never been initialized) and attempts to boot a
|
||||
diskette. To prevent this from happening when you
|
||||
change $3F2 to handle your own RESETs, EOR (exclusive
|
||||
OR) the new value at $3F2 with a $A5 and store the
|
||||
result in the power-up byte.
|
||||
3F5 A JMP to a machine language routine which is to be
|
||||
called when the '&' feature is used in APPLESOFT.
|
||||
3F8 A JMP to a machine language routine which is to be
|
||||
called when a control-Y is entered from the monitor.
|
||||
3FB A JMP to a machine language routine which is to be
|
||||
called when a non-maskable interrupt occurs.
|
||||
3FE LO/HI address of a routine which is to be called when
|
||||
a maskable interrupt occurs.
|
||||
.bp
|
||||
WHAT HAPPENS DURING BOOTING
|
||||
.PP
|
||||
When an APPLE is powered on its
|
||||
memory is essentially devoid of any
|
||||
programs. In order to get DOS
|
||||
running, a diskette is "booted". The
|
||||
term "boot" refers to the process of
|
||||
bootstrap loading DOS into RAM.
|
||||
Bootstrap loading involves a series
|
||||
of steps which load successively
|
||||
bigger pieces of a program until all
|
||||
of the program is in memory and is
|
||||
running. In the case of DOS,
|
||||
bootstrapping occurs in four stages.
|
||||
The location of these stages on the
|
||||
diskette and a memory map are given
|
||||
in Figure 5.2 and a description of
|
||||
the bootstrap process follows.
|
||||
.SP1
|
||||
*** INSERT FIGURE 5.2 ***
|
||||
.pp
|
||||
The first boot stage (let's call it
|
||||
Boot 0) is the execution of the ROM
|
||||
on the disk controller card. When the
|
||||
user types PR#6 or C600G or 6(ctrl)P, for
|
||||
instance, control is
|
||||
.br
|
||||
.ll30
|
||||
.br
|
||||
transfered to
|
||||
the disk controller ROM on the card
|
||||
in slot 6. This ROM is a machine
|
||||
language program of about 256 bytes
|
||||
in length. When executed, it
|
||||
"recalibrates" the disk arm by
|
||||
pulling it back to track 0 (the
|
||||
"clacketty-clack" noise that is
|
||||
heard) and then reads sector 0 from
|
||||
track 0 into RAM memory at location
|
||||
$800 (DOS 3.3. Earlier versions used
|
||||
$300). Once this sector is read, the
|
||||
first stage boot jumps (GOTO's) $800
|
||||
which is the second stage boot (Boot
|
||||
1).
|
||||
.pp
|
||||
Boot 1, also about 256 bytes long,
|
||||
uses part of the Boot 0 ROM as a
|
||||
subroutine and, in a loop, reads the
|
||||
next nine sectors on track 0 (sectors
|
||||
1 through 9) into RAM. Taken
|
||||
together, these sectors contain the
|
||||
next stage of the bootstrap process,
|
||||
Boot 2. Boot 2 is loaded in one of
|
||||
two positions in memory, depending
|
||||
upon whether a slave or a master
|
||||
diskette is being booted. If the
|
||||
diskette is a slave diskette, Boot 2
|
||||
will be loaded 9 pages (256 bytes per
|
||||
page) below the end of the DOS under
|
||||
which the slave was INITed. Thus, if
|
||||
the slave was created on a 32K DOS,
|
||||
Boot 2 will be loaded in the RAM from
|
||||
$7700 to $8000. If a master diskette
|
||||
is being booted, Boot 2 will be
|
||||
loaded in the same place as for a 16K
|
||||
slave ($3700 to $4000). In the
|
||||
process of loading Boot 2, Boot 1 is
|
||||
loaded a second time in the page
|
||||
in memory
|
||||
right below Boot 2 ($3600
|
||||
for a master diskette). This is so
|
||||
that, should a new diskette be INITed,
|
||||
a copy of Boot 1 will be available in
|
||||
memory to
|
||||
be written to its track 0 sector 0.
|
||||
When Boot 1 is finished loading Boot
|
||||
2, it jumps there to begin execution
|
||||
of the next stage of the bootstrap.
|
||||
.br
|
||||
.ll60
|
||||
.bp
|
||||
Boot 2 consists of two parts: a
|
||||
loader "main program"; and the RWTS
|
||||
subroutine package. Up to this point
|
||||
there has been no need to move the
|
||||
disk arm since all of the necessary
|
||||
sectors have been on track 0. Now,
|
||||
however, more sectors must be loaded,
|
||||
requiring arm movement to access
|
||||
additional tracks. Since this
|
||||
complicates the disk access, RWTS is
|
||||
called by the Boot 2 loader to move
|
||||
the arm and read the sectors it needs
|
||||
to load the last part of the
|
||||
bootstrap, DOS itself. Boot 2 now
|
||||
locates track 2 sector 4 and reads
|
||||
its contents into RAM just below the
|
||||
image of Boot 1 (this would be at
|
||||
$3500 for a master diskette). In a
|
||||
loop, Boot 2 reads 26 more sectors
|
||||
into memory, each one 256 bytes
|
||||
before the last. The last sector
|
||||
(track 0 sector A) is read into $1B00
|
||||
for a master diskette. The 27 sectors
|
||||
which were read are the image of the
|
||||
DOS main routines and the file
|
||||
manager. With the loading of these
|
||||
routines, all of DOS has been loaded
|
||||
into memory. At this point, the
|
||||
bootstrap process for a slave
|
||||
diskette is complete and a jump is
|
||||
taken to the DOS coldstart address.
|
||||
If the diskette is a master, the
|
||||
image of DOS is only valid if the
|
||||
machine is a 16K APPLE II. If more
|
||||
memory is present, the DOS image must
|
||||
be relocated into the highest
|
||||
possible RAM present in the machine.
|
||||
To do this, the master version of
|
||||
Boot 2 jumps to a special relocation
|
||||
program at $1B03. This relocator is
|
||||
512 bytes in length and was
|
||||
automatically loaded as the two
|
||||
lowest pages of the DOS image. (In the
|
||||
case of a slave diskette, these pages
|
||||
contain binary zeros.) The relocator
|
||||
determines the size of the machine by
|
||||
systematically storing and loading on
|
||||
high RAM memory pages until it finds
|
||||
the last valid page. It then moves
|
||||
the DOS image from $1D00 to its final
|
||||
location ($9D00 for 48K) and, using
|
||||
tables built into the program, it
|
||||
modifies the machine language code so
|
||||
that it will execute properly at its
|
||||
new home. The relocator then jumps to
|
||||
the high memory copy of DOS and the
|
||||
old image is forgotten.
|
||||
.pp
|
||||
The DOS boot is completed by the DOS
|
||||
coldstart routine. This code
|
||||
initializes DOS, making space for the
|
||||
file buffers, setting HIMEM, building
|
||||
the page 3 vector table, and running
|
||||
the HELLO program.
|
||||
.bp
|
||||
Previous versions of DOS were
|
||||
somewhat more complicated in the
|
||||
implementation of the bootstrap. In
|
||||
these versions, Boot 1 was loaded at
|
||||
$300 and it, in turn, loaded Boot 2
|
||||
at $3600, as does version 3.3. Unlike
|
||||
3.3, however, 27 sectors of DOS were
|
||||
not always loaded. If the diskette
|
||||
was a slave diskette, only 25 sectors
|
||||
were loaded, and, on 13 sector
|
||||
diskettes, this meant the DOS image
|
||||
ended either with sector 8 or sector
|
||||
A of track 2 depending upon whether
|
||||
the diskette was a slave or master.
|
||||
In addition, Boot 1 had a different
|
||||
form of nibbilization (see chapter 3)
|
||||
than any other sector on the
|
||||
diskette, making its raw appearance
|
||||
in memory at $3600 non-executable.
|
||||
.pp
|
||||
The various stages of the bootstrap
|
||||
process will be covered again in greater
|
||||
detail in Chapter 8, DOS PROGRAM
|
||||
LOGIC.
|
||||
.SP1
|
||||
*** INSERT FIGURE 5.3 HERE ***
|
||||
.BR
|
||||
.NX CH6.1
|
||||
\x00
|
359
D1S1/CH6.1#064000.txt
Normal file
359
D1S1/CH6.1#064000.txt
Normal file
|
@ -0,0 +1,359 @@
|
|||
.bp
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 6 - USING DOS FROM ASSEMBLY LANGUAGE
|
||||
.sp1
|
||||
CAVEAT
|
||||
.PP
|
||||
This chapter is aimed at the advanced
|
||||
assembly language programmer who
|
||||
wishes to access the disk without
|
||||
resorting to the PRINT statement
|
||||
scheme used with BASIC.
|
||||
Accordingly, the
|
||||
topics covered here may be beyond the
|
||||
comprehension (at least for the
|
||||
present) of a programmer who has
|
||||
never used assembly language.
|
||||
.sp2
|
||||
DIRECT USE OF DISK DRIVE
|
||||
.PP
|
||||
It is often desirable or necessary to
|
||||
access the Apple's disk drives
|
||||
directly from assembly language,
|
||||
without the use of DOS. This is
|
||||
done using a section of 16 addresses
|
||||
that are latched toggles, interfacing
|
||||
directly to the hardware. There are
|
||||
eight two byte toggles that essentially
|
||||
represent pulling a TTL line high or
|
||||
low. Applications which could use
|
||||
direct disk access range from a
|
||||
user written operating system to DOS-independent
|
||||
utility programs. The
|
||||
device address assignments are given
|
||||
in Figure 6.1.
|
||||
.sp
|
||||
.nf
|
||||
ADDRESS LABEL DESCRIPTION
|
||||
---------------------------------------------------------------
|
||||
$C080 PHASEOFF Stepper motor phase 0 off.
|
||||
$C081 PHASEON Stepper motor phase 0 on.
|
||||
$C082 PHASE1OFF Stepper motor phase 1 off.
|
||||
$C083 PHASE1ON Stepper motor phase 1 on.
|
||||
$C084 PHASE2OFF Stepper motor phase 2 off.
|
||||
$C085 PHASE2ON Stepper motor phase 2 on.
|
||||
$C086 PHASE3OFF Stepper motor phase 3 off.
|
||||
$C087 PHASE3ON Stepper motor phase 3 on.
|
||||
$C088 MOTOROFF Turn motor off.
|
||||
$C089 MOTORON Turn motor on.
|
||||
$C08A DRV0EN Engage drive 1.
|
||||
$C08B DRV1EN Engage drive 2.
|
||||
$C08C Q6L Strobe Data Latch for I/O.
|
||||
$C08D Q6H Load Data Latch.
|
||||
$C08E Q7L Prepare latch for input.
|
||||
$C08F Q7H Prepare latch for output.
|
||||
.sp1
|
||||
Q7L followed by Q6L = Read
|
||||
Q7L followed by Q6H = Sense Write Protect
|
||||
Q7H followed by Q6L = Write
|
||||
Q7H followed by Q6H = Load Write Latch
|
||||
.sp1
|
||||
*** figure 6.1 ***
|
||||
.fi
|
||||
.bp
|
||||
The addresses are slot dependent and
|
||||
the offsets are computed by
|
||||
multiplying the slot number by 16.
|
||||
In hexadecimal this works out nicely
|
||||
and we can add the value $s0 (where s
|
||||
is the slot number) to the base
|
||||
address. If we wanted to engage disk
|
||||
drive number 1 in slot number 6, for
|
||||
example, we would add $60 to $C08A
|
||||
(device address assignment for
|
||||
engaging drive 1) for a result of
|
||||
$C0EA. However, since it is
|
||||
generally desirable to write code
|
||||
that is not slot dependent, one would
|
||||
normally use $C08A,X (where the
|
||||
X register contains the value $s0).
|
||||
.pp
|
||||
In general, the above addresses need
|
||||
only be accessed with any valid 6502
|
||||
instruction. However, in the case of
|
||||
reading and writing bytes, care must
|
||||
be taken to insure that the data will
|
||||
be in an appropriate register. All
|
||||
of the following would engage drive
|
||||
number 1. (Assume slot number 6)
|
||||
.sp1
|
||||
.nf
|
||||
LDA $C0EA
|
||||
BIT $C08A,X (where X-reg contains $60)
|
||||
CMP $C08A,X (where X-reg contains $60)
|
||||
.pp
|
||||
Below are typical examples
|
||||
demonstrating the use of the device
|
||||
address assignments. For more
|
||||
examples, see APPENDIX A. Slot 6 is
|
||||
assumed and the X-register contains
|
||||
$60.
|
||||
.sp1
|
||||
STEPPER PHASE OFF/ON:
|
||||
.PP
|
||||
Basically, each of the four phases
|
||||
(0-3) must be turned on and then off
|
||||
again. Done in ascending order, this
|
||||
moves the arm inward. In descending
|
||||
order, this moves the arm outward.
|
||||
The timing between accesses to these
|
||||
locations is critical, making this a
|
||||
non-trivial exercise. It is
|
||||
recommended that the SEEK command in
|
||||
RWTS be used to move the arm. See
|
||||
the section on using RWTS immediately
|
||||
following.
|
||||
.sp1
|
||||
MOTOR OFF/ON:
|
||||
.sp1
|
||||
.nf
|
||||
LDA $C088,X Turn motor off.
|
||||
.SP1
|
||||
LDA $C089,X Turn motor on.
|
||||
.SP1
|
||||
.FI
|
||||
NOTE: A sufficient delay should be
|
||||
provided to allow the motor time to
|
||||
come up to speed. Shugart recommends
|
||||
one second, but DOS is able to reduce
|
||||
this delay by watching the read latch
|
||||
until data starts to change.
|
||||
.bp
|
||||
.nf
|
||||
ENGAGE DRIVE 1/2:
|
||||
.SP1
|
||||
LDA $C08A,X Engage drive 1.
|
||||
.sp1
|
||||
LDA $C08B,X Engage drive 2.
|
||||
.sp1
|
||||
READ A BYTE:
|
||||
.SP1
|
||||
READ LDA $C08C,X
|
||||
BPL READ
|
||||
.SP1
|
||||
.FI
|
||||
NOTE: $C08E,X must already have been
|
||||
accessed to assure Read mode. The
|
||||
loop is necessary to assure that the
|
||||
accumulator will contain valid data.
|
||||
If the data latch does not yet
|
||||
contain valid data the high bit will
|
||||
be zero.
|
||||
.sp1
|
||||
.nf
|
||||
SENSE WRITE PROTECT:
|
||||
.SP1
|
||||
LDA $C08D,X
|
||||
LDA $C08E,X Sense write protect.
|
||||
BMI ERROR If high bit set, protected.
|
||||
.sp1
|
||||
WRITE LOAD AND WRITE A BYTE
|
||||
.SP1
|
||||
LDA DATA
|
||||
STA $C08D,X Write load.
|
||||
ORA $C08C,X Write byte.
|
||||
.sp1
|
||||
.FI
|
||||
NOTE: $C08F,X must already have been
|
||||
accessed to insure Write mode and a
|
||||
100 microsecond delay should be
|
||||
invoked before writing.
|
||||
.pp
|
||||
Due to hardware constraints, data
|
||||
bytes must be written in 32 cycle
|
||||
loops. Below is an example for an
|
||||
immediate load of the accumulator,
|
||||
followed by a write. Timing is so
|
||||
critical that different routines may
|
||||
be necessary, depending on how the
|
||||
data is to be accessed, and code can
|
||||
not cross memory page boundaries
|
||||
without an adjustment.
|
||||
.bp
|
||||
.nf
|
||||
LDA #$D5 (3 cycles)
|
||||
JSR WRITE9 (6)
|
||||
LDA #$AA (3)
|
||||
JSR WRITE9 (6)
|
||||
.
|
||||
.
|
||||
.
|
||||
WRITE9 CLC (2)
|
||||
WRITE7 PHA (3)
|
||||
PLA (4)
|
||||
WRITE STA $C08D,X (5)
|
||||
ORA $C08C,X (4)
|
||||
RTS (6)
|
||||
.SP2
|
||||
CALLING READ/WRITE TRACK/SECTOR (RWTS)
|
||||
.pp
|
||||
Read/Write Track/Sector (RWTS) exists
|
||||
in every version of DOS as a
|
||||
collection of subroutines, occupying
|
||||
roughly the top third of the DOS
|
||||
program. The interface to RWTS is
|
||||
standardized and thoroughly documented by Apple
|
||||
and may be called by a
|
||||
program running outside of DOS.
|
||||
.pp
|
||||
There are two subroutines which must
|
||||
be called or whose function must be
|
||||
performed.
|
||||
.pp
|
||||
JSR $3E3 - When this subroutine is
|
||||
called, the Y and A registers are
|
||||
loaded with the address of the
|
||||
Input/Output control Block (IOB) used
|
||||
by DOS when accessing RWTS. The low
|
||||
order part of the address is in Y and
|
||||
the high order part in A. This
|
||||
subroutine should be called to locate
|
||||
the IOB and the results may be stored
|
||||
in two zero page locations to allow
|
||||
storing values in the IOB and
|
||||
retrieving output values after a call
|
||||
to RWTS. Of course, you may set up
|
||||
your own IOB as long as the Y and A
|
||||
registers point to your IOB upon
|
||||
calling RWTS.
|
||||
.pp
|
||||
JSR $3D9 - This is the main entry to
|
||||
the RWTS routine. Prior to making
|
||||
this call, the Y and A registers must
|
||||
be loaded with the address of an IOB
|
||||
describing the operation to be
|
||||
performed. This may be done by first
|
||||
calling $3E3 as described above. The
|
||||
IOB must contain appropriate
|
||||
information as defined in the list
|
||||
on the facing page (offsets are given in hexadecimal):
|
||||
.bp
|
||||
.nf
|
||||
INPUT/OUTPUT CONTROL BLOCK - GENERAL FORMAT
|
||||
.SP1
|
||||
BYTE DESCRIPTION
|
||||
00 Table type, must be $01
|
||||
01 Slot number times 16 (s0: s=slot. Example: $60)
|
||||
02 Drive number ($01 or $02)
|
||||
03 Volume number expected ($00 matches any volume)
|
||||
04 Track number ($00 through $22)
|
||||
05 Sector number ($00 through $0F)
|
||||
06-07 Address (LO/HI) of the Device Characteristics Table
|
||||
08-09 Address (LO/HI) of the 256 byte buffer for
|
||||
READ/WRITE
|
||||
0A Not used
|
||||
0B Byte count for partial sector ($00 for 256 bytes)
|
||||
0C Command code $00 = SEEK
|
||||
$01 = READ
|
||||
$02 = WRITE
|
||||
$04 = FORMAT
|
||||
0D Return code - The processor CARRY flag is set upon
|
||||
return from RWTS if there is a
|
||||
non-zero return code:
|
||||
$00 = No errors
|
||||
$08 = Error during initialization
|
||||
$10 = Write protect error
|
||||
$20 = Volume mismatch error
|
||||
$40 = Drive error
|
||||
$80 = Read error (obsolete)
|
||||
0E Volume number of last access (must be initialized)
|
||||
0F Slot number of last access*16 (must be initialized)
|
||||
10 Drive number of last access (must be initialized)
|
||||
.sp1
|
||||
DEVICE CHARACTERISTICS TABLE
|
||||
.SP1
|
||||
BYTE DESCRIPTION
|
||||
00 Device type (should be $00 for DISK II)
|
||||
01 Phases per track (should be $01 for DISK II)
|
||||
02-03 Motor on time count (should be $EFD8 for DISK II)
|
||||
.bp
|
||||
RWTS IOB BY CALL TYPE
|
||||
.SP1
|
||||
SEEK Move disk arm to desired track
|
||||
.sp1
|
||||
Input: Byte 00 - Table type ($01)
|
||||
01 - Slot number * 16 (s0: s=slot)
|
||||
02 - Drive number ($01 or $02)
|
||||
04 - Track number ($00 through $22)
|
||||
06/07 - Pointer to the DCT
|
||||
0C - Command code for SEEK ($00)
|
||||
0F - Slot number of last access * 16
|
||||
10 - Drive number of last access
|
||||
.sp1
|
||||
Output: Byte 0D - Return code (See previous definition)
|
||||
0F - Current Slot number * 16
|
||||
10 - Current Drive number
|
||||
.sp1
|
||||
READ Read a sector into a specified buffer
|
||||
.sp1
|
||||
Input: Byte 00 - Table type ($01)
|
||||
01 - Slot number * 16 (s0: s=slot)
|
||||
02 - Drive number ($01 or $02)
|
||||
03 - Volume number ($00 matches any volume)
|
||||
04 - Track number ($00 through $22)
|
||||
05 - Sector number ($00 through $0F)
|
||||
06/07 - Pointer to the DCT
|
||||
08/09 - Pointer to 256 byte user data buffer
|
||||
0B - Byte count per sector ($00)
|
||||
0C - Command code for READ ($01)
|
||||
0E - Volume number of last access
|
||||
0F - Slot number of last access * 16
|
||||
10 - Drive number of last access
|
||||
.sp1
|
||||
Output: Byte 0D - Return code (See previous definition)
|
||||
0E - Current Volume number
|
||||
0F - Current Slot number * 16
|
||||
10 - Current Drive number
|
||||
.bp
|
||||
WRITE Write a sector from a specified buffer
|
||||
.sp1
|
||||
Input: Byte 00 - Table type ($01)
|
||||
01 - Slot number * 16 (s0: s=slot)
|
||||
02 - Drive number ($01 or $02)
|
||||
03 - Volume number ($00 matches any volume)
|
||||
04 - Track number ($00 through $22)
|
||||
05 - Sector number ($00 through $0F)
|
||||
06/07 - Pointer to the DCT
|
||||
08/09 - Pointer to 256 byte user data buffer
|
||||
0B - Byte count per sector ($00)
|
||||
0C - Command code for WRITE ($02)
|
||||
0E - Volume number of last access
|
||||
0F - Slot number of last access * 16
|
||||
10 - Drive number of last access
|
||||
.sp1
|
||||
Output: Byte 0D - Return code (See previous definition)
|
||||
0E - Current Volume number
|
||||
0F - Current Slot number * 16
|
||||
10 - Current Drive number
|
||||
.sp1
|
||||
FORMAT Initialize the diskette (does not put DOS on disk,
|
||||
create a VTOC/CATALOG, or store HELLO program)
|
||||
.sp1
|
||||
Input: Byte 00 - Table type ($01)
|
||||
01 - Slot number * 16 (s0: s=slot)
|
||||
02 - Drive number ($01 or $02)
|
||||
03 - Volume number ($00 will default to 254)
|
||||
06/07 - Pointer to the DCT
|
||||
0C - Command code for FORMAT ($04)
|
||||
0E - Volume number of last access
|
||||
0F - Slot number of last access * 16
|
||||
10 - Drive number of last access
|
||||
.sp1
|
||||
Output: Byte 0D - Return code (See previous definition)
|
||||
0E - Current Volume number
|
||||
0F - Current Slot number * 16
|
||||
10 - Current Drive number
|
||||
.bp
|
||||
.nx ch6.2
|
||||
\x00
|
522
D1S1/CH6.2#064000.txt
Normal file
522
D1S1/CH6.2#064000.txt
Normal file
|
@ -0,0 +1,522 @@
|
|||
CALLING THE DOS FILE MANAGER
|
||||
.pp
|
||||
The DOS file manager exists in every
|
||||
version of DOS as a collection of
|
||||
subroutines occupying approximately
|
||||
the central third of the DOS program.
|
||||
The interface to these routines is
|
||||
generalized in such a way that they
|
||||
may be called by a program running
|
||||
outside of DOS. The definition of
|
||||
this interface has
|
||||
never been published by APPLE (or
|
||||
anyone else, for that manner) but
|
||||
since the calls can be made through
|
||||
fixed vectors, and, the format of the
|
||||
parameter lists passed have not
|
||||
changed in all the versions of DOS,
|
||||
these routines may be relied upon as
|
||||
"safe". Indeed, the new FID utility
|
||||
program
|
||||
uses these routines to process files
|
||||
on the diskette.
|
||||
.pp
|
||||
There are
|
||||
two subroutines which must be called
|
||||
in order to access the file manager.
|
||||
.sp1
|
||||
JSR $3DC - When this subroutine is
|
||||
called, the Y and A registers are
|
||||
loaded with the address of the file
|
||||
manager parameter list. The low order
|
||||
part of the address is in Y and the
|
||||
high order part in A. This subroutine
|
||||
must be called at least once to
|
||||
locate this parameter list and the
|
||||
results may be stored in two zero page
|
||||
locations to allow the programmer to
|
||||
set input values in the parameter
|
||||
list and to locate output values
|
||||
there after file manager calls.
|
||||
.sp1
|
||||
JSR $3D6 - This is the main entry to
|
||||
the file manager. Prior to making
|
||||
this call the parameter list, located
|
||||
using the call described
|
||||
above, must be completed
|
||||
appropriately, depending upon the
|
||||
type of call, and the X register must
|
||||
be set to either zero or non-zero as
|
||||
follows:
|
||||
.sp1
|
||||
X = 0 - If file is not found, allocate it
|
||||
X # 0 - If file is not found, do not allocate one
|
||||
.sp1
|
||||
Normally,
|
||||
X should be zero on an OPEN call for a
|
||||
new file and non-zero for all other
|
||||
call types.
|
||||
.bp
|
||||
Three buffers must be provided to the
|
||||
file manager by the programmer,
|
||||
allocated by him in his memory. These
|
||||
buffers, together, occupy 557 bytes
|
||||
of RAM, and must be passed to the
|
||||
file manager each time their
|
||||
associated file is used. A separate
|
||||
set of these buffers must be
|
||||
maintained for each open file.
|
||||
DOS maintains buffers for this
|
||||
purpose, as described in earlier
|
||||
chapters, in high RAM. These buffers
|
||||
may be "borrowed" from DOS if care is
|
||||
taken to let DOS know about it. A
|
||||
method for doing this will be
|
||||
outlined later.
|
||||
.sp1
|
||||
A chart giving the required inputs
|
||||
for each call type to the file
|
||||
manager is given in Figure 6.2.
|
||||
The general format of the file
|
||||
manager parameter list is as follows:
|
||||
.bp
|
||||
FILE MANAGER PARAMETER LIST - GENERAL FORMAT
|
||||
.NP
|
||||
BYTE DESCRIPTION
|
||||
00 Call type: 01=OPEN 05=DELETE 09=RENAME
|
||||
02=CLOSE 06=CATALOG 0A=POSITION
|
||||
03=READ 07=LOCK 0B=INIT
|
||||
04=WRITE 08=UNLOCK 0C=VERIFY
|
||||
01 Sub-call type for READ or WRITE:
|
||||
00=No operation (ignore call entirely)
|
||||
01=READ or WRITE one byte
|
||||
02=READ or WRITE a range of bytes
|
||||
03=POSITION then READ or WRITE one byte
|
||||
04=POSITION then READ/WRITE a range
|
||||
02-09 Parameters specific to the call type used. See
|
||||
FILE MANAGER PARAMETER LIST BY CALL TYPE below.
|
||||
0A Return code (note: not all return codes can occur
|
||||
for any call type). The processor CARRY
|
||||
flag is set upon return from the file
|
||||
manager if there is a non-zero return code:
|
||||
00=No errors
|
||||
01=Not used ("LANGUAGE NOT AVAILABLE")
|
||||
02=Bad call type
|
||||
03=Bad sub-call type (greater than four)
|
||||
04=WRITE PROTECTED
|
||||
05=END OF DATA
|
||||
06=FILE NOT FOUND (was allocated if X=0)
|
||||
07=VOLUME MISMATCH
|
||||
08=DISK I/O ERROR
|
||||
09=DISK FULL
|
||||
0A=FILE LOCKED
|
||||
0B Not used
|
||||
0C-0D Address of a 45 byte buffer which will be used by the
|
||||
file manager to save its status between calls. This
|
||||
area is called the file manager workarea and need not
|
||||
be initialized by the caller but the space must be
|
||||
provided and this two byte address field initialized.
|
||||
(addresses are in low/high order format)
|
||||
0E-0F Address of a 256 byte buffer which will be used by the
|
||||
file manager to maintain the current Track/Sector List
|
||||
sector for the open file. Buffer itself need not be
|
||||
initialized by the caller.
|
||||
10-11 Address of a 256 byte buffer which will be used by the
|
||||
file manager to maintain the data sector buffer.
|
||||
Buffer need not be initialized by the caller.
|
||||
.SP1
|
||||
*** INSERT FIGURE 6.2 ***
|
||||
.bp
|
||||
FILE MANAGER PARAMETER LIST BY CALL TYPE
|
||||
.NP
|
||||
OPEN Locates or creates a file. A call to POSITION should
|
||||
follow every OPEN.
|
||||
.sp1
|
||||
Input: Byte 00 - 01
|
||||
02/03 - Fixed record length or 0000 if variable
|
||||
04 - Volume number or 00 for any volume
|
||||
05 - Drive number to be used (01 or 02)
|
||||
06 - Slot number to be used (01-07)
|
||||
07 - File type (used only for new files)
|
||||
$00 = TEXT
|
||||
$01 = INTEGER BASIC
|
||||
$02 = APPLESOFT BASIC
|
||||
$04 = BINARY
|
||||
$08 = RELOCATABLE
|
||||
$10 = S TYPE FILE
|
||||
$20 = A TYPE FILE
|
||||
$40 = B TYPE FILE
|
||||
08/09 - Address of file name (30 characters)
|
||||
(Low/high format)
|
||||
0C/0D - Address of file manager workarea buffer
|
||||
0E/0F - Address of T/S List sector buffer
|
||||
10/11 - Address of data sector buffer
|
||||
.sp1
|
||||
Output: Byte 07 - File type of file which was OPENed
|
||||
0A - Return code (see previous definitions)
|
||||
.sp2
|
||||
.ne5
|
||||
CLOSE Write out final sectors, update the Catalog.
|
||||
A CLOSE call is required eventually for every OPEN.
|
||||
.sp1
|
||||
Input: Byte 00 - 02
|
||||
0C/0D - Address of file manager workarea buffer
|
||||
0E/0F - Address of T/S List sector buffer
|
||||
10/11 - Address of data sector buffer
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.bp
|
||||
READ Read one or a range of bytes from the file to memory.
|
||||
WRITE Write one or a range of bytes from memory to the file.
|
||||
|
||||
Input: Byte 00 - 03 (READ) 04 (WRITE)
|
||||
01 - Subcode:
|
||||
00 = No operation
|
||||
01 = READ or WRITE one byte only
|
||||
02 = READ or WRITE a range of bytes
|
||||
03 = POSITION then READ/WRITE one byte
|
||||
04 = POSITION then READ/WRITE range
|
||||
02/03 - (Subcodes 03 or 04) Record number
|
||||
04/05 - (Subcodes 03 or 04) Byte offset
|
||||
06/07 - (Subcodes 02 or 04) Number of bytes in
|
||||
range to be read or written. (Note: for
|
||||
WRITE, this length must be one less
|
||||
than the actual length to be written)
|
||||
08/09 - (Subcodes 02 or 04) Address of range of
|
||||
bytes to be written or address of
|
||||
buffer to which bytes are to be read.
|
||||
08 - (WRITE, Subcodes 01 or 03) Single byte
|
||||
to be written.
|
||||
0C/0D - Address of file manager workarea buffer
|
||||
0E/0F - Address of T/S List sector buffer
|
||||
10/11 - Address of data sector buffer
|
||||
.sp1
|
||||
Output: Byte 02/03 - Record number of current file position
|
||||
04/05 - Byte offset of current position in file
|
||||
08 - (READ, Subcodes 01 or 03) Byte read
|
||||
0A - Return code
|
||||
.sp2
|
||||
.ne5
|
||||
DELETE Locate and delete a file, freeing its sectors.
|
||||
.sp1
|
||||
Input: Byte 00 - 05
|
||||
(remainder are the same as with OPEN call type)
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.bp
|
||||
CATALOG Produce a catalog listing on the output device.
|
||||
.sp1
|
||||
Input: Byte 00 - 06
|
||||
05 - Drive
|
||||
06 - Slot
|
||||
0C/0D - Address of file manager workarea buffer
|
||||
0E/0F - Address of T/S List sector buffer
|
||||
10/11 - Address of data sector buffer
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.sp2
|
||||
.ne5
|
||||
LOCK Lock a file.
|
||||
.sp1
|
||||
Input: Byte 00 - 07
|
||||
(remainder are the same as with OPEN call type)
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.sp2
|
||||
.ne5
|
||||
UNLOCK Unlock a file.
|
||||
.sp1
|
||||
Input: Byte 00 - 08
|
||||
(remainder are the same as with OPEN call type)
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.sp2
|
||||
.ne5
|
||||
RENAME Rename a file.
|
||||
.sp1
|
||||
Input: Byte 00 - 09
|
||||
02/03 - Address of new file name (30 bytes)
|
||||
(remainder are the same as with OPEN call type)
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.bp
|
||||
POSITION Calculate the location of a record and/or byte
|
||||
offset in the file. Position such that next READ or
|
||||
WRITE will be at that location in the file. A call
|
||||
to POSITION (either explicitly or implictly using
|
||||
subcodes of READ or WRITE) is required prior to the
|
||||
first READ or WRITE. Bytes 02 through 05 should be
|
||||
set to zeros for a normal position to the beginning
|
||||
of the file.
|
||||
.sp1
|
||||
Input: Byte 00 - 0A
|
||||
02/03 - Relative record number for files with a
|
||||
fixed length record size or zero. First
|
||||
record of file is record 0000.
|
||||
04/05 - Relative byte offset into record or of
|
||||
entire file if record number is zero.
|
||||
0C/0D - Address of file manager workarea buffer.
|
||||
0E/0F - Address of T/S List sector buffer.
|
||||
10/11 - Address of data sector buffer.
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.sp2
|
||||
.ne5
|
||||
INIT Initialize a slave diskette. This function formats a
|
||||
diskette and writes a copy of DOS onto tracks 0-2.
|
||||
A VTOC and Catalog are also created. A HELLO program
|
||||
is not stored, however.
|
||||
.sp1
|
||||
Input: Byte 00 - 0B
|
||||
01 - First page of DOS image to be copied to
|
||||
the diskette. Normally $9D for a 48K
|
||||
machine.
|
||||
04 - Volume number of new diskette.
|
||||
05 - Drive number (01 or 02)
|
||||
06 - Slot number (01-07)
|
||||
0C/0D - Address of file manager workarea buffer.
|
||||
0E/0F - Address of T/S List sector buffer.
|
||||
10/11 - Address of data sector buffer.
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.sp2
|
||||
VERIFY Verify that there are no bad sectors in a file by
|
||||
reading every sector.
|
||||
.sp1
|
||||
Input: Byte 00 - 0C
|
||||
(remainder are the same as the OPEN call type)
|
||||
.sp1
|
||||
Output: Byte 0A - Return code
|
||||
.bp
|
||||
DOS BUFFERS
|
||||
.pp
|
||||
Usually it is desirable to use one of DOS's buffers when
|
||||
calling the file manager to save memory. DOS buffers consist of
|
||||
each of the three buffers used by the file manager (file
|
||||
manager workarea, T/S List sector, and data sector) as well as
|
||||
a 30 byte file name buffer and some link pointers. All together
|
||||
a DOS buffer occupies 595 bytes of memory. The address of the
|
||||
first DOS buffer is stored in the first two bytes of DOS ($9D00
|
||||
on a 48K APPLE II). The address of the next buffer is stored in
|
||||
the first and so on in a chain of linked elements. The link
|
||||
address to the next buffer in the last buffer is zeros. If the
|
||||
buffer is not being used by DOS, the first byte of the file
|
||||
name field is a hex 00. Otherwise, it contains the first
|
||||
character of the name of the open file. The assembly language
|
||||
programmer should follow these conventions to avoid having DOS
|
||||
reuse the buffer while he is using it. This means that the
|
||||
name of the file should be stored in the buffer to reserve it
|
||||
for exclusive use (or at least a non-zero byte stored on the
|
||||
first character) and later, when the user is through with the
|
||||
buffer, a 00 should be stored on the file name to return it
|
||||
to DOS's use. If the later is not done, DOS will eventually
|
||||
run out of available buffers and will refuse even to do a
|
||||
CATALOG command. A diagram of the DOS
|
||||
buffers for MAXFILES 3 is given in
|
||||
Figure 6.3 and
|
||||
the format of a DOS buffer is given below.
|
||||
.SP1
|
||||
*** INSERT FIGURE 6.3 ***
|
||||
.sp1
|
||||
.ne10
|
||||
DOS BUFFER FORMAT
|
||||
.NP
|
||||
BYTE DESCRIPTION
|
||||
000/0FF Data sector buffer (256 bytes in length)
|
||||
100/1FF T/S List sector buffer (256 bytes in length)
|
||||
200/22C File manager workarea buffer (45 bytes in length)
|
||||
22D/24A File name buffer (30 bytes in length)
|
||||
First byte indicates whether this DOS buffer is
|
||||
being used. If hex 00, buffer is free for use.
|
||||
24B/24C Address (Lo/High) of file manager workarea buffer
|
||||
24D/24E Address of T/S List sector buffer
|
||||
24F/250 Address of data sector buffer
|
||||
251/252 Address of the file name field of the next buffer on
|
||||
the chain of buffers. If this is the last buffer on
|
||||
the chain then this field contains zeros.
|
||||
.bp
|
||||
THE FILE MANAGER WORKAREA
|
||||
.pp
|
||||
The file manager workarea contains
|
||||
the variables which, taken together,
|
||||
constitute all of the information the
|
||||
file manager needs to deal with an
|
||||
open file. Each time the file manager
|
||||
finishes processing a call, it copies
|
||||
all of its important variables into
|
||||
the file manager workarea buffer
|
||||
provided by the caller. Each
|
||||
subsequent time the file manager is
|
||||
called, the first thing it does is to
|
||||
copy the contents of the file manager
|
||||
workarea buffer back into its
|
||||
variables so that it may resume
|
||||
processing for the file where it left
|
||||
off on the previous call.
|
||||
Ordinarily, the programmer will have
|
||||
no need to worry about the contents
|
||||
of this workarea, since most of the
|
||||
useful information is present in the
|
||||
parameter list anyway. Occasionally,
|
||||
it is handy to know more about the
|
||||
open file. For these cases, the
|
||||
format of the file manager workarea
|
||||
is given below:
|
||||
.sp1
|
||||
FILE MANAGER WORKAREA FORMAT
|
||||
.np
|
||||
BYTE DESCRIPTION
|
||||
00/01 Track/Sector of first T/S List for file
|
||||
02/03 Track/Sector of current T/S List for file
|
||||
04 Flags:
|
||||
80=T/S List buffer changed and needs writing
|
||||
40=Data buffer has been changed and needs writing
|
||||
02=Volume freespace map changed and needs writing
|
||||
05/06 Track/Sector of current data sector
|
||||
07 Sector offset into catalog to entry for this file
|
||||
08 Byte offset into catalog sector to entry for file
|
||||
09/0A Maximum data sectors represented by one T/S List
|
||||
0B/0C Offset of first sector in current T/S List
|
||||
0D/0E Offset of last sector in current T/S List
|
||||
0F/10 Relative sector number last read
|
||||
11/12 Sector size in bytes (256)
|
||||
13/14 Current position in sectors (relative)
|
||||
15 Current byte offset in this sector
|
||||
16 Not used
|
||||
17/18 Fixed record length
|
||||
19/1A Current record number
|
||||
1B/1C Byte offset into current record
|
||||
1D/1E Length of file in sectors
|
||||
1F Next sector to allocate on this track
|
||||
20 Current track being allocated
|
||||
21/24 Bit map of available sectors on this track (rotated)
|
||||
25 File type (80=locked) 0,1,2,4=T,I,A,B
|
||||
26 Slot number times 16 (example: $60=slot 6)
|
||||
27 Drive number (01 or 02)
|
||||
28 Volume number (complemented)
|
||||
29 Track
|
||||
2A/2C Not used
|
||||
.bp
|
||||
COMMON ALGORITHMS
|
||||
.PP
|
||||
Given below are several pieces of code
|
||||
which are used when working with DOS:
|
||||
.SP1
|
||||
.ne5
|
||||
LOCATE A FREE DOS BUFFER
|
||||
.PP
|
||||
The following subroutine may be used
|
||||
to locate an unallocated DOS buffer
|
||||
for use with the DOS file manager.
|
||||
.SP1
|
||||
.NP
|
||||
FBUFF LDA $3D2 LOCATE DOS LOAD POINT
|
||||
STA $1
|
||||
LDY #0
|
||||
STY $0
|
||||
*
|
||||
GBUF0 LDA ($0),Y LOCATE NEXT DOS BUFFER
|
||||
PHA
|
||||
INY
|
||||
LDA ($0),Y
|
||||
STA $1
|
||||
PLA
|
||||
STA $0
|
||||
BNE GBUF GOT ONE
|
||||
LDA $1
|
||||
BEQ NBUF NO BUFFERS FREE
|
||||
*
|
||||
GBUF LDY #0 GET FILENAME
|
||||
LDA ($0),Y
|
||||
BEQ GOTBUF ITS FREE
|
||||
LDY #36 ITS NOT FREE
|
||||
BNE GBUF0 GO GET NEXT BUFFER
|
||||
*
|
||||
GOTBUF CLC INDICATE-GOT A FREE BUFFER
|
||||
RTS RETURN TO CALLER
|
||||
NBUF SEC INDICATE-NO FREE BUFFERS
|
||||
RTS RETURN TO CALLER
|
||||
.bp
|
||||
IS DOS IN THE MACHINE?
|
||||
.PP
|
||||
The following series of instructions
|
||||
should be used prior to attempting to
|
||||
call RWTS or the file manager to
|
||||
insure that DOS is present on this
|
||||
machine.
|
||||
.sp1
|
||||
.NP
|
||||
LDA $3D0 GET VECTOR JMP
|
||||
CMP #$4C IS IT A JUMP?
|
||||
BNE NODOS NO, DOS NOT LOADED
|
||||
.SP2
|
||||
.ne5
|
||||
WHICH VERSION OF DOS IS ACTIVE?
|
||||
.pp
|
||||
In case the program has version dependent code, a check of
|
||||
the DOS version may be required:
|
||||
.sp1
|
||||
.np
|
||||
CLC
|
||||
LDA #0 ADD $16BE TO DOS LOAD POINT
|
||||
ADC #$BE
|
||||
STA $0
|
||||
LDA $3D2
|
||||
ADC #$16
|
||||
STA $1
|
||||
LDY #0
|
||||
LDA ($0),Y GET DOS VERSION NUMBER (2 OR 3)
|
||||
.sp2
|
||||
.ne5
|
||||
WHICH BASIC IS SELECTED?
|
||||
.PP
|
||||
Some programs depend upon either the
|
||||
INTEGER BASIC ROM or the APPLESOFT
|
||||
ROM. To find out which is active and
|
||||
select the one desired, the following
|
||||
subroutine can be called. First the A
|
||||
register is loaded with a code to
|
||||
indicate which BASIC is desired. $20
|
||||
is used for INTEGER BASIC and $4C is
|
||||
used for APPLESOFT. To set up for
|
||||
APPLESOFT, for example:
|
||||
.sp1
|
||||
.NP
|
||||
LDA #$4C CODE FOR APPLESOFT
|
||||
JSR SETBSC CALL SUBROUTINE
|
||||
BNE ERROR LANGUAGE NOT AVAILABLE
|
||||
.
|
||||
.
|
||||
.
|
||||
SETBSC CMP $E000 CORRECT BASIC ALREADY THERE?
|
||||
BEQ RTS YES
|
||||
STA $C080 NO, SELECT ROM CARD
|
||||
CMP $E000 NOW DO WE HAVE IT?
|
||||
BEQ RTS YES
|
||||
STA $C\x3f\x4f\x47\x57\x57\x57\x3b\x3b\x5b\x57\x23\x27Y ROM CARD OUT
|
||||
\x8cL\x8cL\x8cL\x88/\x19g_\x20_\x20_[\x8b\x8b\x8b\x9b\x9b\x9b\xffwo\x9bs
|
||||
\x2c\x40\x42\x5b\x33\x03\x61\x9fTS RTS IN ANY CASE, EXIT TO CALLER
|
||||
.bp
|
||||
SEE IF A BASIC PROGRAM IS IN EXECUTION
|
||||
.PP
|
||||
To determine if there is a BASIC program running or
|
||||
if BASIC is in immediate command mode, use the following
|
||||
statements:
|
||||
.np
|
||||
.sp1
|
||||
..IF INTEGER BASIC IS ACTIVE...
|
||||
LDA $D9
|
||||
BMI EXEC PROGRAM EXECUTING
|
||||
BPL NOEXEC PROGRAM NOT EXECUTING
|
||||
.sp1
|
||||
..IF APPLESOFT BASIC IS ACTIVE...
|
||||
LDX $76 GET LINE NUMBER
|
||||
INX
|
||||
BEQ NOEXEC PROGRAM NOT EXECUTING
|
||||
LDX $33 GET PROMPT CHARACTER
|
||||
CPX #$DD PROMPT IS A "]"?
|
||||
BEQ NOEXEC YES, NOT EXECUTING
|
||||
BNE EXEC ELSE, PROGRAM IS EXECUTING
|
||||
.br
|
||||
.nx ch7
|
||||
\x00
|
189
D1S1/CH7#064000.txt
Normal file
189
D1S1/CH7#064000.txt
Normal file
|
@ -0,0 +1,189 @@
|
|||
.bp
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 7 - CUSTOMIZING DOS
|
||||
.sp1
|
||||
.PP
|
||||
Although DOS usually provides most of
|
||||
the functionality needed by the BASIC
|
||||
or assembly language programmer, at
|
||||
times a custom change is required.
|
||||
Making changes to your copy of DOS
|
||||
should only be undertaken when
|
||||
absolutely necessary, since new
|
||||
versions of DOS are released from
|
||||
time to time, and the job of moving
|
||||
several patches to a new version of
|
||||
DOS every few months can become a
|
||||
burden. In addition, wholesale
|
||||
modification of DOS without a clear
|
||||
understanding of the full
|
||||
implications of each change can
|
||||
result in an unreliable system.
|
||||
.sp1
|
||||
SLAVE VS MASTER PATCHING
|
||||
.PP
|
||||
The usual procedure for making
|
||||
changes to DOS involves "patching"
|
||||
the object or machine language code
|
||||
in DOS. Once a desired change is
|
||||
identified, a few instructions are
|
||||
stored over other instructions within
|
||||
DOS to modify the program. There are
|
||||
three levels at which changes to DOS
|
||||
may be applied.
|
||||
.sp1
|
||||
1 - A patch can be made to the DOS
|
||||
in memory. If this is done, a later
|
||||
reboot will cause the change to "fall
|
||||
out" or be removed.
|
||||
.sp1
|
||||
2 - A patch of the first type can be
|
||||
made permanent by initializing a\x1f?O7O?K'7s';;\x44\x4d\x08\x5a\x5d\x46\x46\x41\x46\x4f\x08\x5c\x40\x4d\x08\x58\x497#+''O\x87\x8f\x93oc\x97++3c77+'##37#g'7#'3#7g'g7+'3#K#/7/#33#g3/3/g'g'+7?g+#g\x83\x8b\x97g++g37''/7Kwkgwkg'+#gwg3//'/g'++3'/+7g3/#g7'3'h.
|
||||
Each time this newly created diskette
|
||||
is booted the patched version of DOS
|
||||
will be loaded. Also, any slave
|
||||
diskettes created by that diskette
|
||||
will also contain the patched version
|
||||
of DOS.
|
||||
.bp
|
||||
3 - The patch is applied directly to
|
||||
a master diskette. This is somewhat
|
||||
more complicated. Either the patch
|
||||
may be made to the image of DOS on
|
||||
the first three tracks of a master
|
||||
diskette using a zap program, or
|
||||
MASTER CREATE may be used to write
|
||||
the changed copy of DOS to a new
|
||||
diskette. The following procedure may
|
||||
be followed to do this:
|
||||
.br
|
||||
BLOAD MASTER CREATE
|
||||
Get into the monitor (CALL -151)
|
||||
Store a $4C at location $80D (80D:4C)
|
||||
Execute MASTER CREATE (800G)
|
||||
When MASTER CREATE finishes loading the DOS image
|
||||
it will exit. You may use the monitor to make
|
||||
changes in the image. MASTER CREATE loads DOS
|
||||
into memory at $1200 such that Boot 2 (RWTS) is
|
||||
loaded first, followed by the main part of DOS
|
||||
starting at $1C00.
|
||||
When all patches have been made, reenter MASTER CREATE
|
||||
at location $82D (82DG).
|
||||
Complete the MASTER CREATE update normally. The
|
||||
resulting diskette will have the patches applied.
|
||||
.br
|
||||
This procedure will work for versions 3.2, 3.2.1, and 3.3 of
|
||||
DOS.
|
||||
.SP1
|
||||
.ne5
|
||||
AVOIDING RELOAD OF LANGUAGE CARD
|
||||
.PP
|
||||
A rather annoying addition to DOS 3.3
|
||||
was a patch to the Boot 2 code to
|
||||
store a binary zero in the first byte
|
||||
of the Language Card, forcing DOS to
|
||||
reload BASIC (either INTEGER or
|
||||
APPLESOFT) for every boot, whether or
|
||||
not the machine was just powered up.
|
||||
When the machine is first powered up
|
||||
this patch is not necessary, since
|
||||
the first byte of the Language Card
|
||||
does not appear to DOS to be either
|
||||
BASIC, and it will reload the card
|
||||
anyway. On subsequent reboots, more
|
||||
often than not, a good copy of BASIC
|
||||
already resides in the Language Card
|
||||
and this patch results in a LANGUAGE
|
||||
NOT AVAILABLE error message after
|
||||
booting a slave diskette. Presumably
|
||||
the patch was added for version 3.3
|
||||
to allow for the eventual possibility
|
||||
that a language like PASCAL whose
|
||||
first byte of code just happens to
|
||||
match one of the BASICs would cause
|
||||
strange results in DOS. If the user
|
||||
always powers the machine off and on
|
||||
between using DOS and any other
|
||||
system, the patch may be removed as
|
||||
follows.
|
||||
.bp
|
||||
At $BFD3 (48K) is a STA instruction which
|
||||
stores a zero on the Language Card.
|
||||
This instruction must be made into
|
||||
three no-operation instructions:
|
||||
BFD3:EA EA EA
|
||||
.br
|
||||
A slave diskette may then be INITed
|
||||
using this modified version of DOS
|
||||
and that diskette will have the
|
||||
patch in its DOS. The address of the
|
||||
store instruction for a 32K DOS is
|
||||
7FD3 and for a 16K DOS is 3FD3.
|
||||
.sp1
|
||||
INSERTING A PROGRAM BETWEEN DOS AND ITS BUFFERS
|
||||
.pp
|
||||
Once in a while it is useful to find
|
||||
a "safe" place to load a machine
|
||||
language program (a printer driver,
|
||||
perhaps) where BASIC and DOS
|
||||
can never walk over it, even if DOS
|
||||
is coldstarted. If the program is
|
||||
less than 200 bytes long, $300 is a
|
||||
good choice. For larger programs,
|
||||
it is usually better to "tuck" the
|
||||
program in between DOS and its
|
||||
buffers (assuming the program is
|
||||
relocatable and will run at that
|
||||
location). To do this, load the
|
||||
program into low RAM, copy it to high
|
||||
RAM right below $9D00 (for a 48K
|
||||
machine), over the top of DOS's
|
||||
buffers, change the first buffer
|
||||
address at $9D00 to point below your
|
||||
program, (remember to allow 38 extra
|
||||
bytes for the filename and link fields)
|
||||
and JMP to $3D3 (DOS
|
||||
COLDSTART). This will cause DOS to
|
||||
rebuild its buffers below your
|
||||
program and "forget" about the memory
|
||||
your program occupies until the next
|
||||
time DOS is booted. Of course, BASIC
|
||||
can not get at that memory either,
|
||||
since its HIMEM is below the DOS
|
||||
buffers.
|
||||
.bp
|
||||
BRUN OR EXEC THE HELLO FILE
|
||||
.pp
|
||||
Ordinarily, when DOS finishes booting
|
||||
into memory, it performs a RUN
|
||||
command on the HELLO file in its file
|
||||
name buffer (left there by the INIT
|
||||
command which wrote DOS to the
|
||||
diskette). To change the RUN command
|
||||
to a BRUN or an EXEC, apply the
|
||||
following patch to DOS (48K):
|
||||
.sp1
|
||||
9E42:34 (for BRUN)
|
||||
..or..
|
||||
9E42:14 (for EXEC)
|
||||
.sp1
|
||||
.ne5
|
||||
REMOVING THE PAUSE DURING A LONG CATALOG
|
||||
.pp
|
||||
Normally, when a CATALOG command is
|
||||
done on a disk with many files, DOS
|
||||
will pause every time the screen
|
||||
fills with names to allow the user
|
||||
time to see them all.
|
||||
By pressing any key
|
||||
the CATALOG continues. If this pause
|
||||
is undesirable, apply the following
|
||||
patch to DOS (48K):
|
||||
.sp1
|
||||
AE34:60
|
||||
.br
|
||||
.bp
|
||||
.st waiting for ch8 diskette
|
||||
.nx ch8
|
||||
\x00
|
380
D1S2/CH8#064000.txt
Normal file
380
D1S2/CH8#064000.txt
Normal file
|
@ -0,0 +1,380 @@
|
|||
.ec^
|
||||
.na
|
||||
.ll60
|
||||
.m11
|
||||
.m22
|
||||
.m48
|
||||
.fo ''-%-
|
||||
.pn 5
|
||||
.pi 0
|
||||
.br
|
||||
.np
|
||||
.ce
|
||||
CHAPTER 8 - DOS PROGRAM LOGIC
|
||||
.sp1
|
||||
.PP
|
||||
This chapter will take a detailed
|
||||
look at the operation of the DOS
|
||||
program itself to aid the APPLE user
|
||||
in understanding it and to help him
|
||||
to make intelligent use of its
|
||||
facilities. Each subroutine and group
|
||||
of variables or constants will be
|
||||
covered separately by storage
|
||||
address. The enterprising programmer
|
||||
may wish to create a disassembly of
|
||||
DOS on his printer and transfer the
|
||||
annotations given here directly to
|
||||
such a listing. Addresses used will
|
||||
be for DOS 3.3 and for a 48K master
|
||||
diskette version of DOS. Slot 6 is
|
||||
assumed. Unless specifically
|
||||
indicated by a $ character, lengths
|
||||
are given in decimal, addresses in
|
||||
hexadecimal (base 16).
|
||||
.sp1
|
||||
DISK II CONTROLLER CARD ROM - BOOT 0
|
||||
.SP1
|
||||
.pi0
|
||||
.ul
|
||||
ADDRESS
|
||||
.np
|
||||
C600-C65B This routine is the first code executed when a disk
|
||||
is to be booted. It receives control via PR#6 or
|
||||
C600G or 6 control-P.
|
||||
Dynamically build a translate table for converting
|
||||
disk codes to six bit hex at location $356-$3FF.
|
||||
Call an RTS instruction in the monitor ROM and
|
||||
extract the return address from the stack to find out
|
||||
the address of this controller card ROM.
|
||||
Use this address to determine the slot number of this
|
||||
drive by shifting $Csxx.
|
||||
Save the slot number times 16 ($s0)
|
||||
Clear disk I/O latches, set read mode, select drive
|
||||
1, turn disk drive on.
|
||||
Pull disk arm back over 80 tracks to recalibrate the
|
||||
arm to track zero.
|
||||
Set up parms to read sector zero on track zero to
|
||||
location $800.
|
||||
Execution falls through into a general sector read
|
||||
subroutine at C65C.
|
||||
.np
|
||||
C65C-C6FA This subroutine reads the sector number stored at
|
||||
$3D on the track indicated by $41 to the address
|
||||
stored at $26,$27.
|
||||
Look for D5/AA/96 sector address header on the disk.
|
||||
If D5/AA/AD is found and sector data was wanted, go
|
||||
to C6A6.
|
||||
C683 Handle a sector address block.
|
||||
Read three double bytes from the disk and combine
|
||||
them to obtain the volume, track, and sector number
|
||||
of the sector being read from the disk at this time.
|
||||
Store the track at $40.
|
||||
Compare the sector found to the sector wanted and the
|
||||
track found to the track wanted.
|
||||
If no match, go back to C65C.
|
||||
Otherwise, if sector is correct, go to C65D to find
|
||||
the sector data itself.
|
||||
C6A6 Handle sector data block.
|
||||
Read the 85 bytes of secondary data to $300-$355.
|
||||
Read 256 bytes of primary data to the address stored
|
||||
at $26,$27.
|
||||
Verify that the data checksum is valid.
|
||||
If not, start over at C65C.
|
||||
"Nibbilize" the primary and secondary data together
|
||||
into the primary data buffer ($26,$27).
|
||||
Increment $27 (address page of read data) and $3D
|
||||
(sector number to be read) and check against $800
|
||||
to see if additional sectors need to be read.
|
||||
If so, reload slot*16 and go back to C65C to read
|
||||
next sector. (This feature is not used when loading
|
||||
DOS but is used when loading from a BASICS diskette.)
|
||||
Otherwise, go to $801 to begin executing the second
|
||||
stage of the bootstrap.
|
||||
.sp1
|
||||
FIRST RAM BOOTSTRAP LOADER - BOOT 1
|
||||
.sp1
|
||||
.Ul
|
||||
ADDRESS
|
||||
.np
|
||||
0801-084C This routine loads the second RAM loader, Boot 2,
|
||||
including RWTS, into memory and jumps to it.
|
||||
If this is not the first entry to Boot 1, go to $81F.
|
||||
Get slot*16 and shift down to slot number.
|
||||
Create the address of the ROM sector read subroutine
|
||||
(C65C in our case) and store it at $3E,$3F.
|
||||
Pick up the first memory page in which to read Boot 2
|
||||
from location $8FE, add the length of Boot 2 in
|
||||
sectors from $8FF, and set that value as the first
|
||||
address to which to read (read last page first).
|
||||
081F Get sector to read, if zero, go to $839.
|
||||
Translate theoretical sector number into physical
|
||||
sector number by indexing into skewing table at $84D.
|
||||
Decrement theoretical sector number (8FF) for next
|
||||
iteration through.
|
||||
Set up parameters for ROM subroutine (C65C) and
|
||||
jump to it. It will return to $801 when the sector
|
||||
has been read.
|
||||
0839 Adjust page number at 8FE to locate entry point of
|
||||
Boot 2.
|
||||
Perform a PR#0 and IN#0 by calling the monitor.
|
||||
Initialize the monitor (TEXT mode, standard window,
|
||||
etc.)
|
||||
Get slot*16 again and go to Boot 2 ($3700 for a
|
||||
master disk, $B700 in its final relocated location).
|
||||
.sp1
|
||||
DOS 3.3 MAIN ROUTINES
|
||||
.SP1
|
||||
.Ul
|
||||
ADDRESS
|
||||
.np
|
||||
9D00-9D0F Relocatable address constants
|
||||
9D00 Address of first DOS buffer at its file name field.
|
||||
9D02 Address of the DOS keyboard intercept routine.
|
||||
9D04 Address of the DOS video intercept routine.
|
||||
9D06 Address of the primary file name buffer.
|
||||
9D08 Address of the secondary (RENAME) file name buffer.
|
||||
9D0A Address of the range length parameter used for LOAD.
|
||||
9D0C Address of the DOS load address ($9D00).
|
||||
9D0E Address of the file manager parameter list.
|
||||
.np
|
||||
9D10-9D1C DOS video (CSWL) intercept's state handler address
|
||||
table. States are used to drive the handling of DOS
|
||||
commands as they appear as output of PRINT statements
|
||||
and this table contains the address of the routine
|
||||
which handles each state from state 0 to state 6.
|
||||
.np
|
||||
9D1E-9D55 Command handler entry point table. This table
|
||||
contains the address of a command handler subroutine
|
||||
for each DOS command in the following standard order:
|
||||
INIT A54F
|
||||
LOAD A413
|
||||
SAVE A397
|
||||
RUN A4D1
|
||||
CHAIN A4F0
|
||||
DELETE A263
|
||||
LOCK A271
|
||||
UNLOCK A275
|
||||
CLOSE A2EA
|
||||
READ A51B
|
||||
EXEC A5C6
|
||||
WRITE A510
|
||||
POSITION A5DD
|
||||
OPEN A2A3
|
||||
APPEND A298
|
||||
RENAME A281
|
||||
CATALOG A56E
|
||||
MON A233
|
||||
NOMON A23D
|
||||
PR# A229
|
||||
IN# A22E
|
||||
MAXFILES A251
|
||||
FP A57A
|
||||
INT A59E
|
||||
BSAVE A331
|
||||
BLOAD A35D
|
||||
BRUN A38E
|
||||
VERIFY A27D
|
||||
.np
|
||||
9D56-9D61 Active BASIC entry point vector table. The addresses
|
||||
stored here are maintained by DOS such that they
|
||||
apply to the current version of BASIC running.
|
||||
9D56 Address of CHAIN entry point to BASIC.
|
||||
9D58 Address of RUN.
|
||||
9D5A Address of error handler.
|
||||
9D5C Address of BASIC coldstart.
|
||||
9D5E Address of BASIC warmstart.
|
||||
9D60 Address of BASIC relocate (APPLESOFT only).
|
||||
.np
|
||||
9D62-9D6B Image of the entry point vector for INTEGER BASIC.
|
||||
This image is copied to 9D56 if INTEGER BASIC is made
|
||||
active.
|
||||
.np
|
||||
9D6C-9D77 Image of the entry point vector for the ROM version
|
||||
of APPLESOFT.
|
||||
.np
|
||||
9D78-9D83 Image of the entry point vector for the RAM version
|
||||
of APPLESOFT.
|
||||
.np
|
||||
9D84-9DBE DOS coldstart entry routine.
|
||||
Get the slot and drive numbers and store as default
|
||||
values for command keywords.
|
||||
Copy APPLESOFT ROM or INTEGER BASIC entry point
|
||||
vector into current BASIC entry point vector.
|
||||
Remember which BASIC is active.
|
||||
Go to 9DD1.
|
||||
.np
|
||||
9DBF-9DE9 DOS warmstart entry routine.
|
||||
Get the remembered BASIC type and set the ROM card
|
||||
as necessary (calls A5B2).
|
||||
9DD1 Remember whether entry is coldstart or warmstart
|
||||
Call A851 to replace DOS keyboard and video
|
||||
intercepts.
|
||||
Set NOMON C,I,O.
|
||||
Set video intercept handler state to 0.
|
||||
Coldstart or warmstart the current BASIC (exit DOS).
|
||||
(DOS will next gain control when BASIC prints its
|
||||
input prompt character)
|
||||
.np
|
||||
9DEA-9E50 First entry processing for DOS. This routine is
|
||||
called by the keyboard intercept handler when the
|
||||
first keyboard input request is made by BASIC after
|
||||
a DOS coldstart.
|
||||
If RAM APPLESOFT is active, copy its entry point
|
||||
vector to the active BASIC entry point vector and
|
||||
blank out the primary file name buffer so that no
|
||||
HELLO file will be run.
|
||||
Set MAXFILES to 3 by default.
|
||||
Call A7D4 to build the DOS file buffers.
|
||||
If an EXEC was active, close the EXEC file
|
||||
Set the video intercept state to 0 and indicate
|
||||
warmstart status by calling A75B.
|
||||
If the last command executed was not INIT (this DOS
|
||||
was not just booted), go to 9E45.
|
||||
Otherwise, copy an image of the DOS jump vector to
|
||||
$3D0-$3FF.
|
||||
Point $3F2,$3F3 to DOS warmstart routine.
|
||||
Set the AUTOSTART ROM power-up byte since the RESET
|
||||
handler address was changed.
|
||||
Set the command index for RUN (to run the HELLO file)
|
||||
and go to A180 to execute it.
|
||||
9E45 See if there is a pending command.
|
||||
If so, go to A180 to execute it. Otherwise, return
|
||||
to caller.
|
||||
.np
|
||||
9E51-9E7F An image of the DOS 3-page jump vector which the
|
||||
above routine copies to $3D0-$3FF. See Chapter 5 for
|
||||
a description of its contents.
|
||||
.np
|
||||
9E81-9EB9 DOS keyboard intercept routine.
|
||||
Call 9ED1 to save the registers at entry to DOS.
|
||||
If not coldstarting or reading a disk file,
|
||||
go to 9E9E.
|
||||
Get value in A register at entry and echo it on the
|
||||
screen (erases flashing cursor).
|
||||
If in read state (reading a file) go to A626 to get
|
||||
next byte from disk file.
|
||||
Otherwise, call 9DEA to do first entry processing.
|
||||
Put cursor on screen in next position.
|
||||
If EXECing, call A682 to get the next byte from the
|
||||
EXEC file.
|
||||
Set the video intercept state to 3 (input echo).
|
||||
Call 9FBA to restore the registers at entry to DOS.
|
||||
Call the true keyboard input routine.
|
||||
Save the input character so that it will be restored
|
||||
with the registers in the A register.
|
||||
Do the same with the new X register value.
|
||||
Exit DOS via 9FB3.
|
||||
.np
|
||||
9EBA-9EBC A jump to the true KSWL handler routine.
|
||||
.np
|
||||
9EBD-9ED0 DOS video intercept routine.
|
||||
Call 9ED1 to save the registers at entry to DOS.
|
||||
Get the video intercept state and, using it as an
|
||||
index into the state handler table (9D11), go to
|
||||
the proper handler routine, passing it the character
|
||||
being printed.
|
||||
.np
|
||||
9ED1-9EEA Common intercept save registers routine.
|
||||
Save the A, X, Y, and S registers at AA59-AA5C.
|
||||
While in DOS, restore the true I/O handlers (KSWL and
|
||||
CSWL) to $36-$39.
|
||||
Return to caller.
|
||||
.np
|
||||
9EEB-9F11 State 0 output handler. --start of line--
|
||||
If a RUN command was interrupted (by loading RAM
|
||||
APPLESOFT) go to 9F78 to complete it.
|
||||
If read flag is on (file being read) and output is a
|
||||
"?" character (BASIC INPUT), go to state 6 to skip
|
||||
it.
|
||||
If read flag is on and output is prompt character
|
||||
($33) go to state 2 to ignore the line.
|
||||
Set state to 2 (ignore non-DOS command) just in case.
|
||||
If output character is not a control-D, go to
|
||||
state 2.
|
||||
Otherwise, set state to 1 (collect possible DOS
|
||||
command), set line index to zero, and fall through
|
||||
to state 1.
|
||||
.np
|
||||
9F12-9F22 State 1 output handler. --collect DOS command--
|
||||
Using line index, store character in input buffer at
|
||||
$200.
|
||||
Increment line index.
|
||||
If character is not a carriage return, exit DOS
|
||||
via 9F95 (echo character on screen if MON I).
|
||||
Otherwise, go to command scanner at 9FCD.
|
||||
.np
|
||||
9F23-9F2E State 2 output handler. --non-DOS command ignore--
|
||||
If the character is not a carriage return, exit DOS
|
||||
via 9FA4 (echo character on screen).
|
||||
Otherwise, set state back to 0 and exit DOS via
|
||||
9FA4.
|
||||
.np
|
||||
9F2F-9F51 State 3 output handler. --INPUT statement handler--
|
||||
Set state to 0 in case INPUT ends.
|
||||
If character is not a carriage return, echo it on
|
||||
screen as long as EXEC is not in effect with NOMON I
|
||||
but exit DOS in any case. (KSWL will set state=3)
|
||||
Otherwise, call A65E to see if BASIC is executing a
|
||||
program or is in immediate mode. If EXEC is running
|
||||
or if BASIC is in immediate mode, go to state 1 to
|
||||
collect the possible DOS command.
|
||||
Otherwise, exit DOS, echoing the character as
|
||||
appropriate.
|
||||
.np
|
||||
9F52-9F60 State 4 output handler. --WRITE data to a file--
|
||||
If the character is a carriage return, set state to
|
||||
5 (start of write data line).
|
||||
Call A60E to write the byte to the disk file.
|
||||
Exit DOS with echo on screen if MON O.
|
||||
.np
|
||||
9F61-9F70 State 5 output handler. --Start of WRITE data line--
|
||||
If the character is a control-D, go to state 0 to
|
||||
immediately exit write mode.
|
||||
If the character is a line feed, write it and exit,
|
||||
staying in state 5.
|
||||
Otherwise, set the state to 4 and go to state 4.
|
||||
.np
|
||||
9F71-9F77 State 6 output handler. --Skip prompt character--
|
||||
Set state to 0.
|
||||
Exit DOS via 9F9D (echo if MON I).
|
||||
.np
|
||||
9F78-9F82 Finish RUN command, interrupted by APPLESOFT RAM LOAD
|
||||
Reset the "RUN interrupted" flag.
|
||||
Call A851 to replace the DOS CSWL/KSWL intercepts.
|
||||
Go to A4DC to complete the RUN command.
|
||||
.np
|
||||
9F83-9F94 DOS command scanner exit to BASIC routine.
|
||||
If first character of command line is control-D,
|
||||
go to echo exit (9F95).
|
||||
Otherwise, set things up so BASIC won't see the DOS
|
||||
command by passing a zero length line (only a
|
||||
carriage return). Fall through to echo exit.
|
||||
.np
|
||||
9F95-9FB0 Echo character on screen (conditionally) and exit DOS
|
||||
9F95 Echo only if MON C set, otherwise, go to 9FB3.
|
||||
9F99 Echo only if MON O set, otherwise, go to 9FB3.
|
||||
9F9D Echo only if MON I set, otherwise, go to 9FB3.
|
||||
9FA4 Always echo character.
|
||||
Call 9FBA to restore registers at entry to DOS.
|
||||
Call 9FC5 to echo character on screen.
|
||||
Save contents of the registers after echoing.
|
||||
Fall through to DOS exit routine.
|
||||
.np
|
||||
9FB3-9FC4 DOS exit routine and register restore.
|
||||
Call A851 to put back DOS KSWL/CSWL intercepts.
|
||||
Restore S (stack) register from entry to DOS.
|
||||
9FBA DOS register restore subroutine.
|
||||
Restore registers from first entry to DOS and return
|
||||
to caller.
|
||||
.np
|
||||
9FC5-9FC7 A jump to the true CSWL routine.
|
||||
.np
|
||||
9FC8-9FCC Skip a line on the screen.
|
||||
Load a carriage return into the A register and
|
||||
call 9FC5 to print it.
|
||||
.np
|
||||
9FCD-A179 DOS command parse routine.
|
||||
.br
|
||||
.nx ch8.1
|
||||
\x00
|
166
D1S2/CH8.1#064000.txt
Normal file
166
D1S2/CH8.1#064000.txt
Normal file
|
@ -0,0 +1,166 @@
|
|||
Set the command index to -1 (none).
|
||||
Reset the pending command flag (none pending).
|
||||
9FD6 Add one to command index.
|
||||
If first charcater is a control-D, skip it.
|
||||
Flush to a non-blank (call A1A4).
|
||||
Compare command to command name in command name table
|
||||
at A884 for the current command index.
|
||||
If it doesn't match and if there are more entries
|
||||
left to check, go back to 9FD6.
|
||||
If it does match, go to A01B.
|
||||
Otherwise, if command was not found in the table,
|
||||
check to see if the first character was a control-D.
|
||||
If so, go to A6C4 to print "SYNTAX ERROR".
|
||||
Otherwise, call A75B to reset the state and warmstart
|
||||
flag and go to 9F95 to echo the command and exit.
|
||||
(the command must be for BASIC, not DOS)
|
||||
A01B Compute an index into the operand table for the
|
||||
command which was entered.
|
||||
Call A65E to see if a BASIC program is executing.
|
||||
If not, and the command is not a direct type command,
|
||||
(according to the operand table) go to A6D2 to print
|
||||
"NOT DIRECT COMMAND".
|
||||
Otherwise, if the command is RUN, make the prompt
|
||||
character ($33) non-printing.
|
||||
Check the operand table to see if a first filename
|
||||
is a legal operand for this command.
|
||||
If not, go to A0A0.
|
||||
Otherwise, clear the filename buffer (call A095).
|
||||
Flush to the next non-blank (call A1A4) and copy
|
||||
the filename operand to the first filename buffer.
|
||||
Skip forward to a comma if one was not found yet.
|
||||
If a second filename is legal for this command, use
|
||||
the code above to copy it into the second filename
|
||||
buffer.
|
||||
Check both filenames to see if they are blank.
|
||||
If one was required by the command but not given,
|
||||
give a syntax error or pass it through to BASIC.
|
||||
(As in the case of LOAD with no operands)
|
||||
If all is well, go to A0D1 to continue.
|
||||
A095 A subroutine to blank both filename buffers.
|
||||
A0A0 Indicate no filename parsed.
|
||||
Check operand table to see if a positional operand
|
||||
is expected.
|
||||
If not, go to A0D1 to continue.
|
||||
Otherwise, call A1B9 to convert the numeric operand.
|
||||
If omitted, give syntax error.
|
||||
If number converted exceeds 16, give "RANGE ERROR"
|
||||
If number is supposed to be a slot number, give
|
||||
"RANGE ERROR" if it exceeds 7.
|
||||
If number is not a slot number, give "RANGE ERROR" if
|
||||
it is zero. (MAXFILES 0 is a no-no)
|
||||
A0D1 Set defaults for the keyword operands (V=0,L=0,B=0)
|
||||
A0E8 Get the line offset index and flush to the next
|
||||
non-blank, skipping any commas found.
|
||||
If we are not yet to the end of the line, go to A10C.
|
||||
Check to see if any keywords were given which were
|
||||
not allowed for this command.
|
||||
If not, go to A17A to process the command.
|
||||
A10C Lookup the keyword found on the command line in the
|
||||
table of valid keywords (A940)
|
||||
If not in table, give "SYNTAX ERROR" message.
|
||||
Get its bit position in the keywords-given flag.
|
||||
If the keyword does not have an operand value, go to
|
||||
A164.
|
||||
Otherwise, indicate keyword found in flag.
|
||||
Convert the numeric value associated with keyword.
|
||||
Give "SYNTAX ERROR" message if invalid.
|
||||
Check to see if the number is within the acceptable
|
||||
range as given in the keyword valid range table at
|
||||
A955.
|
||||
Save the value of the keyword in the keyword values
|
||||
table starting at AA66.
|
||||
Go parse the next keyword. go to A0E8.
|
||||
A164 Indicate C, I, or O keywords were parsed.
|
||||
Update the MON value in the keyword value table
|
||||
appropriately.
|
||||
Go parse the next keyword. go to A0E8.
|
||||
.np
|
||||
A17A-A17F Call A180 to process the command, then exit via echo
|
||||
at 9F83.
|
||||
.np
|
||||
A180-A192 Do command.
|
||||
Reset the video intercept state to zero.
|
||||
Clear the file manager parameter list.
|
||||
Using the command index, get the address of the
|
||||
command handling routine from the command handler
|
||||
routine table at 9D1E and go to it.
|
||||
Command handler will exit to caller of this routine.
|
||||
.np
|
||||
A193-A1A3 Get next character on command line and check to see
|
||||
if it is a carriage return or a comma.
|
||||
.np
|
||||
A1A4-A1AD Flush command line characters until a non-blank is
|
||||
found.
|
||||
.np
|
||||
A1AE-A1B8 Clear the file manager parameter list at B5BA to
|
||||
zeros.
|
||||
.np
|
||||
A1B9-A1D5 Convert numeric operand from command line. Call
|
||||
either A1D6 (decimal convert) or A203 (hex convert)
|
||||
depending upon the presence or lack thereof of a
|
||||
dollar sign ($).
|
||||
.np
|
||||
A1D6-A202 Decimal convert subroutine.
|
||||
.np
|
||||
A203-A228 Hexadecimal convert subroutine.
|
||||
.np
|
||||
A229-A22D PR#n command handler.
|
||||
Load the parsed numeric value and exit via FE95 in
|
||||
the monitor ROM.
|
||||
.np
|
||||
A22E-A232 IN#n command handler.
|
||||
Load the parsed numeric value and exit via FE8B in
|
||||
the monitor ROM.
|
||||
.np
|
||||
A233-A23C MON command handler.
|
||||
Add new MON flags to old in AA5E and exit.
|
||||
.np
|
||||
A23D-A250 NOMON command handler.
|
||||
If C was given, put out a carriage return since this
|
||||
line was echoed but its CR was not.
|
||||
Turn off the proper bits in AA5E and exit.
|
||||
.np
|
||||
A251-A262 MAXFILES command handler.
|
||||
Turn off any EXEC file which is active.
|
||||
Close all open files (call A316).
|
||||
Set the new MAXFILES number at AA57.
|
||||
Go to A7D4 to rebuild the DOS file buffers and exit.
|
||||
.np
|
||||
A263-A270 DELETE command handler.
|
||||
Load the delete file manager opcode (05).
|
||||
Call the file manager open driver (A2AA) to perform
|
||||
the delete.
|
||||
Find the file buffer used to do the delete and free
|
||||
it (call A764).
|
||||
Exit to caller.
|
||||
.np
|
||||
A271-A274 LOCK command handler.
|
||||
Load the lock file manager opcode (07) and go to
|
||||
A277.
|
||||
.np
|
||||
A275-A27C UNLOCK command handler.
|
||||
Load the unlock file manager opcode (08).
|
||||
A277 Call the file manager open driver (A2AA) to perform
|
||||
the desired function.
|
||||
Exit to the caller via close (A2EA).
|
||||
.np
|
||||
A27D-A280 VERIFY command handler.
|
||||
Load the verify file manager opcode (0C) and go to
|
||||
A277 to perform function.
|
||||
.np
|
||||
A281-A297 RENAME command handler.
|
||||
Store address of second file name in file manager
|
||||
parameter list.
|
||||
Load the rename file manager opcode (09).
|
||||
Call the file manager driver at A2C8.
|
||||
Exit via close (A2EA).
|
||||
.np
|
||||
A298-A2A2 APPEND command handler.
|
||||
Call A2A3 to OPEN the file.
|
||||
Read the file byte by byte until a zero is found.
|
||||
If append flag is on, add one to record number
|
||||
and turn flag off.
|
||||
Exit via a call to POSITION.
|
||||
.nx ch8.2
|
||||
\x00
|
221
D1S2/CH8.2#064000.txt
Normal file
221
D1S2/CH8.2#064000.txt
Normal file
|
@ -0,0 +1,221 @@
|
|||
.np
|
||||
A2A3-A2A7 OPEN command handler.
|
||||
Set file type as TEXT.
|
||||
Go to A3D5 to open file.
|
||||
.np
|
||||
A2A8-A2E9 Command handler common file management code.
|
||||
Set opcode to OPEN.
|
||||
A2AA If no L value was given on the command, use 0001 and
|
||||
store record length value in file manager parmlist.
|
||||
A2C8 Close file if already open.
|
||||
Is there an available file buffer?
|
||||
If not, issue "NO FILE BUFFERS AVAILABLE" message.
|
||||
Point $40,$41 at the free file buffer.
|
||||
Copy filename to file buffer (allocates the buffer)
|
||||
(A743).
|
||||
Copy buffer pointers to file manager parmlist (A74E).
|
||||
Finish filling in the file manager parmlist (A71A).
|
||||
Set operation code in parmlist.
|
||||
Exit through the file manager driver.
|
||||
.np
|
||||
A2EA-A2FB CLOSE command handler.
|
||||
If no filename was given as part of command,
|
||||
go to A316 to close all files.
|
||||
Otherwise, find the open file buffer for filename
|
||||
(A764).
|
||||
If no such file open, exit to caller.
|
||||
Otherwise, close file and free buffer (A2FC).
|
||||
Go back through CLOSE command handler to make sure
|
||||
there are not more open buffers for the same file.
|
||||
.np
|
||||
A2FC-A315 Close a file and free its file buffer.
|
||||
Find out if this buffer is EXEC's (A7AF).
|
||||
If so, turn EXEC flag off.
|
||||
Release the buffer by storing a $00 on its filename
|
||||
field.
|
||||
Copy file buffer pointers to the file manager
|
||||
parmlist.
|
||||
Set file manager opcode to CLOSE.
|
||||
Exit through the file manager driver routine.
|
||||
.np
|
||||
A316-A330 Close all open files.
|
||||
Point to first file buffer (A792).
|
||||
Go to A320.
|
||||
A31B Point to next file buffer on chain (A79A).
|
||||
If at end of chain, exit to caller.
|
||||
A320 Is this file buffer EXEC's?
|
||||
If so, skip it and go to A31B.
|
||||
Is it not in use (open)?
|
||||
If so, skip it and go to A31B.
|
||||
Otherwise, close it and free it (A2FC).
|
||||
Go to A316 to start all over.
|
||||
.np
|
||||
A331-A35C BSAVE command handler.
|
||||
Insure that the A and L keywords were present on the
|
||||
command.
|
||||
If not, issue "SYNTAX ERROR" message.
|
||||
Open and verify a B type file (A3D5).
|
||||
Write the A keyword value as the first two bytes of
|
||||
the file.
|
||||
Write the L keyword value as the next two bytes of
|
||||
the file.
|
||||
Use the A value to exit by writing a range of bytes
|
||||
from memory to the file.
|
||||
.np
|
||||
A35D-A38D BLOAD command handler.
|
||||
Open the file, ignoring its type.
|
||||
Insure the type is B.
|
||||
If not, issue "FILE TYPE MISMATCH" message.
|
||||
Otherwise, open B type file and test file type (A3D5)
|
||||
Read the A value from the first two bytes of file.
|
||||
If A keyword was not given, use the value just read.
|
||||
Read L value as next two bytes in file.
|
||||
Go to A471 to read range of bytes to memory from file
|
||||
.np
|
||||
A38E-A396 BRUN command handler.
|
||||
Call BLOAD command handler to load file into memory.
|
||||
Replace DOS intercepts.
|
||||
Exit DOS by jumping to the A address value to begin
|
||||
execution of the binary program.
|
||||
.np
|
||||
A397-A3D4 SAVE command handler.
|
||||
Get the active BASIC type (AAB6).
|
||||
If INTEGER, go to A3BC.
|
||||
If APPLESOFT, test $D6 flag to see if program is
|
||||
protected.
|
||||
If so, issue "PROGRAM TOO LARGE" message.
|
||||
Otherwise, open and test for A type file (A3D5).
|
||||
Compute program length (PGMEND-LOMEM).
|
||||
Write this two byte length to file.
|
||||
Exit by writing program image from LOMEM as a range
|
||||
of bytes (A3FF).
|
||||
A3BC Open and test for I type file (A3D5).
|
||||
Compute program length (HIMEM-PGMSTART).
|
||||
Write this two byte length to file.
|
||||
Exit by writing program image from PGMSTART as a
|
||||
range of bytes (A3FF).
|
||||
.np
|
||||
A3D5-A3DF Open and test file type.
|
||||
Set file type wanted in file manager parmlist.
|
||||
Call A2A8 to open file.
|
||||
Go to A7C4 to check file type.
|
||||
.np
|
||||
A3E0-A3FE Write a 2 byte value to the open file.
|
||||
Store value to be written in file manager parmlist.
|
||||
Set write one byte opcodes.
|
||||
Call file manager driver.
|
||||
Call it again to write second byte and exit to caller
|
||||
.np
|
||||
A3FF-A40F Read/write a range of bytes.
|
||||
Set the address of the range in file manager parmlist
|
||||
Set subcode to read or write a range of bytes.
|
||||
Call the file manager driver.
|
||||
Close the file.
|
||||
Exit through the VERIFY command handler to insure
|
||||
data was written ok.
|
||||
.np
|
||||
A410-A412 Issue "FILE TYPE MISMATCH" message.
|
||||
.np
|
||||
A413-A479 LOAD command handler.
|
||||
Close all files (A316).
|
||||
Open the file in question.
|
||||
Is it an A or I type file?
|
||||
If not, issue "FILE TYPE MISMATCH" message.
|
||||
Which BASIC is active?
|
||||
If INTEGER, go to A450.
|
||||
Select APPLESOFT BASIC (A4B1). This call could result
|
||||
in DOS losing control if the RAM version must be
|
||||
run.
|
||||
Read first two bytes of file as length of program.
|
||||
Add length to LOMEM (program start) to compute
|
||||
program end.
|
||||
Is program end beyond HIMEM?
|
||||
If so, close file and issue "PROGRAM TOO LARGE".
|
||||
Set program end and start of variables pointers.
|
||||
Read program as range of bytes to program start.
|
||||
Replace DOS intercepts (A851).
|
||||
Go to BASIC's relocation routine to convert a RAM
|
||||
APPLESOFT program to ROM and vice versa as needed.
|
||||
A450 Select INTEGER BASIC (A4B1).
|
||||
Read length of program (first two bytes in file).
|
||||
Compute program start (HIMEM-LENGTH).
|
||||
If zero or less than LOMEM, issue "PROGRAM TOO LARGE"
|
||||
message and close file.
|
||||
Set program start pointers.
|
||||
Read program into memory as a range of bytes.
|
||||
Exit to caller.
|
||||
.np
|
||||
A47A-A4AA Read two bytes from file (Address or Length).
|
||||
Set up parmlist to read two bytes to range length
|
||||
field (AA60).
|
||||
Call file manager driver.
|
||||
Store value read as range length in file manager
|
||||
parmlist just in case it was a length.
|
||||
.np
|
||||
A4AB-A4B0 Close file and issue "PROGRAM TOO LARGE" message.
|
||||
.np
|
||||
A4B1-A4D0 Select desired BASIC.
|
||||
If desired BASIC is already active, exit to caller.
|
||||
Save current command index in case we must RUN
|
||||
APPLESOFT.
|
||||
If INTEGER, go to A59E to select it.
|
||||
Otherwise, copy primary file name to secondary
|
||||
buffer to save it in case RAM APPLESOFT is needed.
|
||||
Go to A57A to set APPLESOFT.
|
||||
.np
|
||||
A4D1-A4E4 RUN command handler.
|
||||
If APPLESOFT is active, set RUN intercepted flag so
|
||||
that RUN can complete after APPLESOFT is loaded.
|
||||
Call LOAD command handler to load the program.
|
||||
Skip a line on the screen.
|
||||
Put DOS intercepts back.
|
||||
Go to the RUN entry point in the current BASIC.
|
||||
.np
|
||||
A4E5-A4EF INTEGER BASIC RUN entry point intercept.
|
||||
Delete all variables (CLR equivalent).
|
||||
Go to the CHAIN entry point in INTEGER BASIC.
|
||||
.np
|
||||
A4F0-A4FB CHAIN command handler.
|
||||
Call the LOAD command handler to load the program.
|
||||
Skip a line.
|
||||
Replace DOS intercepts.
|
||||
Go to current BASIC's CHAIN entry point.
|
||||
.np
|
||||
A4FC-A505 APPLESOFT ROM RUN entry point intercept.
|
||||
Call APPLESOFT to clear variables.
|
||||
Reset ONERR.
|
||||
Go to RUN entry point.
|
||||
.np
|
||||
A506-A50D APPLESOFT RAM RUN entry point intercept.
|
||||
Call APPLESOFT to clear variables.
|
||||
Reset ONERR.
|
||||
Go to RUN entry point.
|
||||
.np
|
||||
A510-A51A WRITE command handler.
|
||||
Call READ/WRITE common code (A526).
|
||||
Set CSWL state to 5 (WRITE mode line start).
|
||||
Exit DOS (9F83).
|
||||
.np
|
||||
A51B-A525 READ command handler.
|
||||
Call READ/WRITE common code (A526).
|
||||
Set READ mode flag in status flags (AA51).
|
||||
Exit DOS (9F83).
|
||||
.np
|
||||
A526-A54E READ/WRITE common code.
|
||||
Locate the open file buffer for this file (A764).
|
||||
If not open, open it.
|
||||
Copy file buffer addresses to file manager parmlist.
|
||||
If R or B were given on command, copy to parmlist
|
||||
and issue a POSITION call to file manager.
|
||||
Exit to caller.
|
||||
.np
|
||||
A54F-A56D INIT command handler.
|
||||
If V was given, use it. Otherwise, use 254.
|
||||
Store first page number of DOS in file manager
|
||||
parmlist.
|
||||
Call file manager driver to INIT diskette.
|
||||
Exit through SAVE to store greeting program on disk.
|
||||
.np
|
||||
A56E-A579 CATALOG command handler.
|
||||
.nx ch8.3
|
||||
\x00
|
222
D1S2/CH8.3#064000.txt
Normal file
222
D1S2/CH8.3#064000.txt
Normal file
|
@ -0,0 +1,222 @@
|
|||
Call file manager with CATALOG opcode.
|
||||
Set new V value as default for future commands.
|
||||
Exit to caller.
|
||||
.np
|
||||
A57A-A59D FP command handler.
|
||||
Set ROM card, if any, for APPLESOFT (A5B2).
|
||||
If successful, coldstart DOS (9D84).
|
||||
Otherwise, set status flag to indicate INTEGER BASIC
|
||||
is active.
|
||||
Set primary filename buffer to "APPLESOFT".
|
||||
Set flags to indicate RAM APPLESOFT and coldstart.
|
||||
Go to RUN command handler.
|
||||
.np
|
||||
A59E-A5B1 INT command handler.
|
||||
Set ROM card, if any, for INTEGER BASIC (A5B2).
|
||||
If not successful, issue "LANGUAGE NOT AVAILABLE".
|
||||
Otherwise, clear RUN intercepted flag.
|
||||
Coldstart DOS (9D84).
|
||||
.np
|
||||
A5B2-A5C5 Set ROM to desired BASIC.
|
||||
(This routine is passed a $4C for APPLESOFT or a $20
|
||||
for INTEGER, since these bytes appear at $E000 in
|
||||
these BASICs. It will work regardless of which
|
||||
BASIC is onboard)
|
||||
If desired BASIC is already available, exit.
|
||||
Try selecting ROM card.
|
||||
If desired BASIC is now available, exit.
|
||||
Try selecting onboard ROM.
|
||||
If desired BASIC is now available, exit.
|
||||
Otherwise, exit with error return code.
|
||||
.np
|
||||
A5C6-A5DC EXEC command handler.
|
||||
Open the file (A2A3).
|
||||
Copy file buffer address to EXEC's buffer pointer at
|
||||
AAB4,AAB5.
|
||||
Set EXEC active flag (AAB3).
|
||||
Jump into POSITION command handler to skip R lines.
|
||||
.np
|
||||
A5DD-A60D POSITION command handler.
|
||||
Locate the open file buffer (A764).
|
||||
If not found, open one as a TEXT file.
|
||||
Copy buffer pointers to file manager parmlist.
|
||||
If R was not given on command, exit.
|
||||
A5F2 Otherwise, test R value for zero and exit if so.
|
||||
Decrement R value by one.
|
||||
Read file byte by byte until a carriage return (end
|
||||
of line - $8D) is reached.
|
||||
If at end of file, issue "END OF FILE" message.
|
||||
Otherwise, go to A5F2 to skip next record.
|
||||
.np
|
||||
A60E-A625 Write one data byte to file.
|
||||
Insure that BASIC is running a program (A65E).
|
||||
If not, close file and warmstart DOS.
|
||||
Set up file manager parmlist to write the data byte
|
||||
to the open file.
|
||||
Call file manager and exit.
|
||||
.np
|
||||
A626-A65B Read one data byte from file.
|
||||
Insure that BASIC is running a program (A65E).
|
||||
If not, close file and warmstart DOS.
|
||||
Set CSWL intercept state to 6 (skip prompt character)
|
||||
A630 Read next file byte (A68C).
|
||||
If not at end of file, go to A644.
|
||||
Otherwise, close file.
|
||||
If state is not 3 (EXEC) issue "END OF DATA" message.
|
||||
Exit to caller.
|
||||
A644 If data byte is lower case character, turn its most
|
||||
significant bit off to fool GETIN routine in monitor.
|
||||
Store data byte in A register saved at entry to DOS.
|
||||
Using line index, turn high bit back on in previous
|
||||
data byte stored at $200 (input line buffer) to make
|
||||
it lower case if necessary.
|
||||
Exit DOS (9FB3).
|
||||
.np
|
||||
A65E-A678 Test to see if BASIC is running a program or is in
|
||||
immediate command mode.
|
||||
If active BASIC is INTEGER, go to A672.
|
||||
If line number is greater than 65280 and prompt is
|
||||
"]" then APPLESOFT is in immediate mode.
|
||||
Otherwise, it is executing a program.
|
||||
Exit to caller with appropriate return code.
|
||||
A672 Check $D9 to determine whether BASIC is executing a
|
||||
program and exit with proper return code.
|
||||
.np
|
||||
A679-A681 Close current file and warmstart DOS.
|
||||
.np
|
||||
A682-A68B EXEC read one byte from file.
|
||||
Select EXEC file buffer.
|
||||
Copy file buffer addresses to file manager parmlist.
|
||||
Set state to 3 (input echo).
|
||||
Go to A62D to read a file byte.
|
||||
.np
|
||||
A68C-A69C Read next text file byte.
|
||||
Set up file manager parmlist to read one byte.
|
||||
Call file manager driver.
|
||||
Return to caller with the data byte.
|
||||
.np
|
||||
A69D-A6A7 Set $40,$41 to point to EXEC file buffer.
|
||||
.np
|
||||
A6A8-A6C3 File manager driver routine.
|
||||
Call the file manager itself (AB06).
|
||||
If no errors, exit to caller.
|
||||
Otherwise, point $40,$41 at file buffer.
|
||||
If found, release it by storing a zero on the file
|
||||
name field.
|
||||
If error was not "END OF DATA", print error message.
|
||||
Otherwise, pretend a $00 was read and return to
|
||||
caller.
|
||||
.np
|
||||
A6C4-A6D4 Miscellaneous error messages.
|
||||
A6C4 "COMMAND SYNTAX ERROR"
|
||||
A6C8 "NO FILE BUFFERS AVAILABLE"
|
||||
A6CC "PROGRAM TOO LARGE"
|
||||
A6D0 "FILE TYPE MISMATCH"
|
||||
.np
|
||||
A6D5-A701 Error handler.
|
||||
Set warmstart flag and clear status (BFE6).
|
||||
If APPLESOFT ONERR is active, go to A6EF.
|
||||
Otherwise, print RETURN BELL RETURN.
|
||||
Print text of error message (A702).
|
||||
Print another RETURN.
|
||||
A6EF Replace DOS intercepts.
|
||||
If a BASIC program is in execution, pass error code
|
||||
to BASIC's error handler.
|
||||
Otherwise, warmstart BASIC.
|
||||
.np
|
||||
A702-A719 Print text of error message.
|
||||
Using the error number as an index, print the message
|
||||
text from the message table (A971) byte by byte.
|
||||
Last character has most significant bit on.
|
||||
.np
|
||||
A71A-A742 Complete file manager parameter list.
|
||||
Copy Volume value to parmlist.
|
||||
Copy Drive value to parmlist.
|
||||
Copy Slot value to parmlist.
|
||||
Copy address of primary filename buffer to parmlist.
|
||||
Save file buffer address in $40,$41.
|
||||
Return to caller.
|
||||
.np
|
||||
A743-A74D Copy primary filename to file buffer filename field.
|
||||
.np
|
||||
A74E-A75A Copy current buffer pointers to file manager parmlist
|
||||
Copy file manager workarea buffer pointer.
|
||||
Copy T/S List sector buffer pointer.
|
||||
Copy data sector buffer address.
|
||||
Copy next file buffer link address.
|
||||
Return to caller.
|
||||
.np
|
||||
A75B-A763 Reset state to 0 and set warmstart flag.
|
||||
.np
|
||||
A764-A791 Locate an open or free file buffer.
|
||||
Assume there are no free file buffers by zeroing $45.
|
||||
Point $40,$41 at first buffer on chain.
|
||||
Go to A773.
|
||||
A76E Point $40,$41 at next buffer on chain.
|
||||
If at end of chain, exit with file not open code.
|
||||
A773 Get first byte of filename field.
|
||||
If zero (file buffer free), save file buffer address
|
||||
at $44,$45 as an available buffer and go to A76E.
|
||||
Otherwise, see if name in primary filename buffer
|
||||
matches the name in this file buffer.
|
||||
If not, go to A76E to get next buffer.
|
||||
If so, return to caller with open file found code.
|
||||
.np
|
||||
A792-A799 Point $40,$41 at first file buffer on chain.
|
||||
.np
|
||||
A79A-A7A9 Point $40,$41 at next file buffer on chain.
|
||||
.np
|
||||
A7AA-A7AE Get first byte of file name in file buffer.
|
||||
.np
|
||||
A7AF-A7C3 See if current buffer belongs to EXEC.
|
||||
Is EXEC active?
|
||||
If not, exit.
|
||||
If so, does current buffer address match EXEC's?
|
||||
Return to caller with appropriate code.
|
||||
.np
|
||||
A7C4-A7D3 Check file type.
|
||||
Does file type of open file match desired file type?
|
||||
If so, exit.
|
||||
Otherwise, turn lock bit off and test again.
|
||||
If ok, exit.
|
||||
Otherwise, close file and issue "FILE TYPE MISMATCH".
|
||||
.np
|
||||
A7D4-A850 Initialize (build) DOS file buffer chain.
|
||||
Set $40,$41 to point to first buffer.
|
||||
Set counter to MAXFILES value.
|
||||
A7E5 Store zero on filename field to mark as free.
|
||||
Set up link pointers in buffer to point to file
|
||||
manager workarea (45 bytes prior to filename field).
|
||||
Set up link pointer to T/S List sector buffer (-256
|
||||
bytes from file manager workarea buffer).
|
||||
Set up link pointer to data sector buffer 256 bytes
|
||||
before that.
|
||||
Decrement counter.
|
||||
If zero, go to A82D to set HIMEM.
|
||||
Otherwise, set link to next file buffer as 38 bytes
|
||||
prior to data sector buffer.
|
||||
Go to A7E5 to set up next buffer.
|
||||
A82D Set link of last buffer to $0000.
|
||||
If INTEGER BASIC is active, go to A846.
|
||||
Otherwise, set APPLESOFT's HIMEM and STRING START
|
||||
pointers in zeropage to point just below the last
|
||||
buffer.
|
||||
Exit to caller.
|
||||
A846 Set INTEGER BASIC's HIMEM and PROGRAM START pointers
|
||||
to point just below the last buffer.
|
||||
Exit to caller.
|
||||
.np
|
||||
A851-A883 Replace DOS keyboard/video intercept vectors.
|
||||
Is DOS keyboard (KSWL) vector still set?
|
||||
If so, go to A86A.
|
||||
Otherwise, save current KSWL vector ($38,$39) at
|
||||
AA55,AA56 and replace with DOS intercept routine's
|
||||
address.
|
||||
A86A Is DOS video (CSWL) vector still set?
|
||||
If so, exit to caller.
|
||||
Otherwise, save current CSWL vector ($36,$37) at
|
||||
AA53,AA54 and replace with DOS intercept routine's
|
||||
address.
|
||||
Exit to caller.
|
||||
.nx ch8.4
|
||||
\x00
|
256
D1S2/CH8.4#064000.txt
Normal file
256
D1S2/CH8.4#064000.txt
Normal file
|
@ -0,0 +1,256 @@
|
|||
.np
|
||||
A884-A908 DOS command name text table.
|
||||
This table consists of the ASCII name for each DOS
|
||||
command in order of command index values, with the
|
||||
last character of each indicated by the MSB being
|
||||
on. Commands in order are:
|
||||
INIT,LOAD,SAVE,RUN,CHAIN,DELETE,LOCK,UNLOCK,CLOSE,
|
||||
READ,EXEC,WRITE,POSITION,OPEN,APPEND,RENAME,
|
||||
CATALOG,MON,NOMON,PR#,IN#,MAXFILES,FP,INT,BSAVE,
|
||||
BLOAD,BRUN,VERIFY.
|
||||
Example: INIT is $49 $4E $49 $D4 (I N I T)
|
||||
.np
|
||||
A909-A940 Command valid keywords table.
|
||||
This table is used to determine which keywords are
|
||||
required or may be given for any DOS command.
|
||||
Each command has a two byte entry with 16 flags,
|
||||
indicating which keywords may be given. The flag
|
||||
bit settings are as follows:
|
||||
.ul
|
||||
BIT MEANING
|
||||
0 Filename legal but optional
|
||||
1 Command has no positional operand
|
||||
2 Filename #1 expected
|
||||
3 Filename #2 expected
|
||||
4 Slot number positional operand expected
|
||||
5 MAXFILES value expected as positional operand
|
||||
6 Command may only be issued from within a program
|
||||
7 Command may create a new file if file not found
|
||||
8 C, I, O keywords legal
|
||||
9 V keyword legal
|
||||
10 D keyword legal
|
||||
11 S keyword legal
|
||||
12 L keyword legal
|
||||
13 R keyword legal
|
||||
14 B keyword legal
|
||||
15 A keyword legal
|
||||
Thus, for a typical command, OPEN, where the value
|
||||
is $2378, bits 2, 6, 7, 9, 10, 11, and 12 are set so
|
||||
the command has one filename operand, may only be
|
||||
issued from within a program, may create a new file,
|
||||
and the V, D, S, and L keywords are legal.
|
||||
The command entries are:
|
||||
INIT 2170
|
||||
LOAD A070
|
||||
SAVE A170
|
||||
RUN A070
|
||||
CHAIN 2070
|
||||
DELETE 2070
|
||||
LOCK 2070
|
||||
UNLOCK 2070
|
||||
CLOSE 6000
|
||||
READ 2206
|
||||
EXEC 2074
|
||||
WRITE 2206
|
||||
POSITION 2204
|
||||
OPEN 2378
|
||||
APPEND 2270
|
||||
RENAME 3070
|
||||
CATALOG 4070
|
||||
MON 4080
|
||||
NOMON 4080
|
||||
PR# 0800
|
||||
IN# 0800
|
||||
MAXFILES 0400
|
||||
FP 4070
|
||||
INT 4000
|
||||
BSAVE 2179
|
||||
BLOAD 2071
|
||||
BRUN 2071
|
||||
VERIFY 2070
|
||||
.np
|
||||
A941-A94A Keyword name table.
|
||||
This table contains all the ASCII names of the DOS
|
||||
keywords in standard order. Each keyword name
|
||||
occupies one byte:
|
||||
V,D,S,L,R,B,A,C,I,O
|
||||
.np
|
||||
A94B-A954 Keyword flag bit positions table.
|
||||
This table gives the bit positions for each keyword
|
||||
into the second byte of the command valid keyword
|
||||
table above and in the flag (AA65) which indicates
|
||||
which keywords were present on the command line.
|
||||
The bit positions are:
|
||||
V - 40
|
||||
D - 20
|
||||
S - 10
|
||||
L - 08
|
||||
R - 04
|
||||
B - 02
|
||||
A - 01
|
||||
C - C0 ...
|
||||
I - A0 ... not used in valid keyword table
|
||||
O - 90 ...
|
||||
.np
|
||||
A955-A970 Keyword value valid range table.
|
||||
This table indicates the range any keyword value
|
||||
may legally have. Each keyword has a four byte entry,
|
||||
two bytes of minimum value, and two bytes of maximum
|
||||
value. Values are:
|
||||
.ul
|
||||
KEYWORD MIN MAX
|
||||
V 0 254
|
||||
D 1 2
|
||||
S 1 7
|
||||
L 1 32767
|
||||
R 0 32767
|
||||
B 0 32767
|
||||
A 0 65535
|
||||
C, I, and O do not appear in this table since they
|
||||
do not have numeric values.
|
||||
.np
|
||||
A971-AA3E Error message text table.
|
||||
This table contains the text for each error code in
|
||||
order of error code number:
|
||||
.ul
|
||||
NUMBER TEXT
|
||||
0 RETURN BELL RETURN
|
||||
1 "LANGUAGE NOT AVAILABLE"
|
||||
2 "RANGE ERROR" (Bad file manager opcode)
|
||||
3 "RANGE ERROR" (Bad file manager subcode)
|
||||
4 "WRITE PROTECTED
|
||||
5 "END OF DATA"
|
||||
6 "FILE NOT FOUND"
|
||||
7 "VOLUME MISMATCH"
|
||||
8 "I/O ERROR"
|
||||
9 "DISK FULL"
|
||||
10 "FILE LOCKED"
|
||||
11 "SYNTAX ERROR"
|
||||
12 "NO BUFFERS AVAILABLE"
|
||||
13 "FILE TYPE MISMATCH"
|
||||
14 "PROGRAM TOO LARGE"
|
||||
15 "NOT DIRECT COMMAND"
|
||||
.np
|
||||
AA3F-AA4F Error message text offset index table.
|
||||
This table contains the offset in bytes to the text
|
||||
of any given error message in the table above.
|
||||
Entries are one byte each for each error code number.
|
||||
.np
|
||||
AA4F-AA65 DOS main routines variables.
|
||||
AA4F Current file buffer address (2 bytes).
|
||||
AA51 Status flags: $01=READ state, $00=Warmstart,
|
||||
$80=Coldstart, $40=APPLESOFT RAM
|
||||
AA52 DOS CSWL intercept state number.
|
||||
AA53 Address of true CSWL handler (2 bytes).
|
||||
AA55 Address of true KSWL handler (2 bytes).
|
||||
AA57 MAXFILES value.
|
||||
AA59 Save area for S, X, Y, and A registers when DOS is
|
||||
entered (4 bytes).
|
||||
AA5D Command line index value (offset into line).
|
||||
AA5E MON flags: (C=$40, I=$20, O=$10)
|
||||
AA5F Index of last command times 2.
|
||||
AA60 Range length for LOAD and BLOAD (2 bytes).
|
||||
AA62 Index of pending command, if any.
|
||||
AA63 Scratch variable (counter, message index, etc.)
|
||||
AA64 Index of current keyword.
|
||||
AA65 Keywords present on command line flags.
|
||||
.np
|
||||
AA66-AA74 Keyword values parsed from command and defaulted.
|
||||
AA66 Volume (2 bytes)
|
||||
AA68 Drive (2 bytes)
|
||||
AA6A Slot (2 bytes)
|
||||
AA6C Length (2 bytes)
|
||||
AA6E Record (2 bytes)
|
||||
AA70 Byte (2 bytes)
|
||||
AA72 Address (2 bytes)
|
||||
AA74 MON value (one byte)
|
||||
.np
|
||||
AA75-AA92 Primary file name buffer
|
||||
.np
|
||||
AA93-AAB0 Secondary (RENAME) file name buffer
|
||||
.np
|
||||
AAB1-AAC0 DOS main routines constants and variables.
|
||||
AAB1 MAXFILES default ($03).
|
||||
AAB2 Control-D ($84).
|
||||
AAB3 EXEC file active flag ($00=not active).
|
||||
AAB4 EXEC file buffer address (2 bytes).
|
||||
AAB6 Active BASIC flag: $00=INTEGER, $40=APPLESOFT ROM,
|
||||
$80=APPLESOFT RAM
|
||||
AAB7 RUN intercepted flag.
|
||||
AAB8 "APPLESOFT" characters in ASCII (9 bytes)
|
||||
.np
|
||||
AAC1-AAC8 File manager constants.
|
||||
AAC1 Address of RWTS paramter list (B7E8).
|
||||
AAC3 Address of VTOC sector buffer (B3BB).
|
||||
AAC5 Address of directory sector buffer (B4BB).
|
||||
AAC7 Address of last byte of DOS plus one. (C000)
|
||||
.np
|
||||
AAC9-AAE4 File manager function routine entry point table.
|
||||
This table contains a two byte function handler
|
||||
routine address for each of the 14 file manager
|
||||
opcodes in opcode order.
|
||||
.np
|
||||
AAE5-AAF0 File manager read subcode handler entry point table.
|
||||
This table contains a two byte function handler
|
||||
routine address for each of the 6 read subcodes.
|
||||
.np
|
||||
AAF1-AAFC File manager write subcode handler entry point table.
|
||||
This table contains a two byte function handler
|
||||
routine address for each of the 6 write subcodes.
|
||||
.np
|
||||
AAFD-AB05 File manager external entry point (from $3D6).
|
||||
Is X register zero?
|
||||
If so, allow new files by simulating an INIT command
|
||||
index.
|
||||
Otherwise, require old file by simulating a LOAD
|
||||
command index.
|
||||
Fall through to main file manager entry point.
|
||||
.np
|
||||
AB06-AB1E File manager main entry.
|
||||
Save S register at B39B.
|
||||
Restore file manager workarea from file buffer (AE6A)
|
||||
Make sure opcode does not exceed 13.
|
||||
If it does, return with code=2 (invalid opcode).
|
||||
Use opcode as index into file manager function
|
||||
routine entry point table and go to proper handler
|
||||
via RTS.
|
||||
.np
|
||||
AB1F-AB21 Return with return code=2 (bad opcode).
|
||||
.np
|
||||
AB22-AB27 OPEN function handler.
|
||||
Call common open code (AB28).
|
||||
Exit file manager.
|
||||
.np
|
||||
AB28-ABDB Common open routine.
|
||||
Initialize file manager workarea by resetting
|
||||
variables to their defaults (ABDC).
|
||||
Set sector length to 256.
|
||||
Insure record length is non-zero. If zero, use 1.
|
||||
Store record length in file manager workarea.
|
||||
Locate or allocate a directory entry for the file
|
||||
(B1C9).
|
||||
If file already exists, go to ABA6.
|
||||
Otherwise, save directory index for free entry.
|
||||
Using last command index and valid keywords table,
|
||||
determine whether current command may create a new
|
||||
file.
|
||||
If so, go to AB64.
|
||||
Otherwise, if running "APPLESOFT", set return code
|
||||
to "LANGUAGE NOT AVAILABLE" and exit.
|
||||
If not running "APPLESOFT" set return code to "FILE
|
||||
NOT FOUND" and exit.
|
||||
AB64 Set sector count in directory entry to 1 (there will
|
||||
only be a T/S List sector initially).
|
||||
Allocate a sector for a T/S List (B244).
|
||||
Store sector number of this sector in directory
|
||||
entry and in first and current T/S List sector number
|
||||
in file manager workarea.
|
||||
Store track number in both places also.
|
||||
Move file type desired to directory entry.
|
||||
Write directory sector back to catalog (B037).
|
||||
Select T/S List buffer (AF0C).
|
||||
Zero it (B7D6).
|
||||
And write it back (AF3A).
|
||||
Set return code to 6 ("FILE NOT FOUND").
|
||||
.nx ch8.5
|
||||
\x00
|
281
D1S2/CH8.5#064000.txt
Normal file
281
D1S2/CH8.5#064000.txt
Normal file
|
@ -0,0 +1,281 @@
|
|||
ABA6 Place track/sector of T/S List in directory entry in
|
||||
first T/S List variable in file manager workarea.
|
||||
Copy file type from directory to parmlist to pass it
|
||||
back to caller and to file manager workarea.
|
||||
Copy number of sectors in file to workarea.
|
||||
Save directory offset to entry in workarea.
|
||||
Set end of data pointer to "infinity".
|
||||
Set number of data bytes represented by one T/S List
|
||||
sector to 122*256 (30.5K) in workarea.
|
||||
Go read first T/S List sector (AF5E).
|
||||
.np
|
||||
ABDC-AC05 Initialize file manager workarea.
|
||||
Zero entire 45 bytes of workarea.
|
||||
Save complemented volume number in workarea.
|
||||
Save drive number in workarea.
|
||||
Save slot*16 in workarea.
|
||||
Set track number to $11 (catalog track).
|
||||
Return to caller.
|
||||
.np
|
||||
AC06-AC39 CLOSE function handler.
|
||||
Checkpoint data buffer to disk if needed (AF1D).
|
||||
Checkpoint T/S List buffer if needed (AF34).
|
||||
Release any sectors which were preallocated but not
|
||||
used (B2C3).
|
||||
If VTOC does not need to be re-read, exit.
|
||||
Otherwise, re-read VTOC sector (AFF7).
|
||||
Flush through directory sectors in the catalog until
|
||||
we reach the one which contains the entry for this
|
||||
file.
|
||||
Get the index to the entry.
|
||||
Update the sector count in the entry to reflect the
|
||||
new file's length.
|
||||
Checkpoint the directory sector back to the disk.
|
||||
Exit file manager.
|
||||
.np
|
||||
AC3A-AC57 RENAME function handler.
|
||||
Call common code to locate/open the file.
|
||||
If file is locked, exit with "FILE LOCKED" return
|
||||
code.
|
||||
Set $42,$43 to point to new name.
|
||||
Copy new name to directory entry.
|
||||
Write back directory sector to disk.
|
||||
Exit file manager.
|
||||
.np
|
||||
AC58-AC69 READ function handler.
|
||||
Insure subcode does not exceed 5. If so, exit with
|
||||
return code=3.
|
||||
Use subcode as index into READ subcode handler entry
|
||||
point table.
|
||||
Go to proper handler of subcode.
|
||||
.np
|
||||
AC6A-AC6C Return code = 3, subcode bad
|
||||
.np
|
||||
AC6D-AC6F "FILE LOCKED" error return
|
||||
.np
|
||||
AC70-AC86 WRITE function handler.
|
||||
If file is locked, exit with "FILE LOCKED" error.
|
||||
Insure subcode does not exceed 5. If so, exit with
|
||||
return code=3.
|
||||
Use subcode as index into WRITE subcode handler entry
|
||||
point table.
|
||||
Go to proper handler of subcode.
|
||||
.np
|
||||
AC87-AC89 POSITION AND READ ONE BYTE subcode handler
|
||||
Call position routine.
|
||||
Fall through to next subcode handler.
|
||||
.np
|
||||
AC8A-AC92 READ ONE BYTE subcode handler.
|
||||
Read next file byte (ACA8).
|
||||
Store in parmlist for pass back to caller.
|
||||
Exit the file manager.
|
||||
.np
|
||||
AC93-AC95 POSITION AND READ A RANGE OF BYTES subcode handler.
|
||||
Call position routine.
|
||||
Fall through to next subcode handler.
|
||||
.np
|
||||
AC96-ACA7 READ A RANGE OF BYTES subcode handler.
|
||||
Decrement and check length (B1B5).
|
||||
Read a byte (ACA8).
|
||||
Point $42,$43 at range address and add one to address
|
||||
Store byte read at address.
|
||||
Loop back to AC96. (length check will exit file
|
||||
manager when length is zero.)
|
||||
.np
|
||||
ACA8-ACB8 Read a data byte.
|
||||
Read next data sector if necessary (B0B6).
|
||||
If at end of file, exit with "END OF DATA" error.
|
||||
Otherwise, load data byte from data sector buffer.
|
||||
Increment record number/byte offset into file (B15B).
|
||||
Increment file position offset (B194).
|
||||
Return with data byte read.
|
||||
.np
|
||||
ACBB-ACBD POSITION AND WRITE ONE BYTE subcode handler.
|
||||
Call position routine.
|
||||
Fall through to next subcode handler.
|
||||
.np
|
||||
ACBE-ACC6 WRITE ONE BYTE subcode handler.
|
||||
Find data byte to be written.
|
||||
Write it to file (ACDA).
|
||||
Exit file manager.
|
||||
.np
|
||||
ACC7-ACC9 POSITION AND WRITE A RANGE OF BYTES subcode handler.
|
||||
Call position routine.
|
||||
Fall through to next subcode handler.
|
||||
.np
|
||||
AACA-ACD7 WRITE A RANGE OF BYTES subcode handler.
|
||||
Copy and advance range address pointer.
|
||||
Get next byte to write.
|
||||
Write it to file (ACDA).
|
||||
Test and decrement length (B1B5).
|
||||
Loop back to AACA.
|
||||
.np
|
||||
ACDA-ACEC Write a data byte.
|
||||
Read the proper data sector (if necessary) (B0B6).
|
||||
Store data byte to be written in sector buffer.
|
||||
Flag data sector buffer as requiring rewrite.
|
||||
Increment record number/byte offset into file (B15B).
|
||||
Exit via file position offset increment routine
|
||||
(B194).
|
||||
.np
|
||||
ACEF-ACF5 LOCK function handler.
|
||||
Set mask byte to $80 (lock).
|
||||
Go to common code (ACFB).
|
||||
.np
|
||||
ACF6-ACFA UNLOCK function handler.
|
||||
Set mask byte to $00 (unlock).
|
||||
Fall through to common code.
|
||||
.np
|
||||
ACFB-AD11 LOCK/UNLOCK common code.
|
||||
Locate/open file (AB28).
|
||||
Get index into directory to entry.
|
||||
Update file type byte to lock ($8X) or unlock ($0X).
|
||||
Write directory sector back to disk.
|
||||
Exit file manager.
|
||||
.np
|
||||
AD12-AD17 POSITION function handler.
|
||||
Call position routine.
|
||||
Exit file manager.
|
||||
.np
|
||||
AD18-AD2A VERIFY function handler.
|
||||
Locate/open file (AB28).
|
||||
AD1B Read next data sector.
|
||||
If at end of file, exit file manager.
|
||||
Otherwise, increment sector position.
|
||||
And loop back to AD1B.
|
||||
.np
|
||||
AD2B-AD88 DELETE function handler.
|
||||
Locate/open file (AB28).
|
||||
Using directory index, determine if file is locked.
|
||||
If so, exit with "FILE LOCKED" error code.
|
||||
Copy T/S List sector's track number from directory to
|
||||
workarea and to last character of file name in the
|
||||
directory entry itself.
|
||||
Store a $FF over T/S List sector's track number in
|
||||
directory entry to mark file deleted.
|
||||
Copy T/S List sector's sector number to workarea.
|
||||
Write directory sector back to disk.
|
||||
AD54 Read next T/S List sector (AF5E).
|
||||
If no more exist, write VTOC and exit file manager.
|
||||
Otherwise, select T/S List buffer (AF0C).
|
||||
Index to first T/S pair.
|
||||
AD5E If track number is zero or minus, skip it.
|
||||
Otherwise, free the data sector by updating the VTOC
|
||||
bit map (AD89).
|
||||
Index to next T/S pair.
|
||||
If more, go to AD5E.
|
||||
Get T/S of next T/S List sector from this one.
|
||||
Free this T/S List sector (AD89).
|
||||
Go process next one, if any (go to AD54).
|
||||
Otherwise, write VTOC and exit file manager.
|
||||
.np
|
||||
AD89-AD97 Free a sector.
|
||||
Call B2DD to deallocate sector in VTOC bit map.
|
||||
Zero the sector allocation area of the workarea.
|
||||
Return to caller.
|
||||
.np
|
||||
AD98-AE2E CATALOG function handler.
|
||||
Initialize file manager workarea (ABDC).
|
||||
Set V value to zero (complimented=$FF).
|
||||
Read the VTOC sector (AFF7).
|
||||
Set up a counter for 22 lines before waiting for
|
||||
the keyboard.
|
||||
Skip 2 lines on the screen.
|
||||
Print "DISK VOLUME ".
|
||||
Convert Volume number and print it (AE42).
|
||||
Skip 2 more lines.
|
||||
ADCA Read next directory sector.
|
||||
If no more exist, exit file manager.
|
||||
Set index to first entry.
|
||||
ADD1 Get track number.
|
||||
If zero, exit file manager.
|
||||
If minus, skip entry (deleted file).
|
||||
Print "*" if file is locked (check file type byte).
|
||||
Use file type as index into file type name table at
|
||||
B3A7 and print single character found there.
|
||||
Print a blank.
|
||||
Convert and print the number of sectors in the file.
|
||||
Print a blank.
|
||||
Index to filename.
|
||||
Print file name.
|
||||
Skip to next line.
|
||||
Advance index to next directory entry.
|
||||
If there are more, go to ADD1.
|
||||
If not, go to ADCA to read next directory sector.
|
||||
Exit when finished.
|
||||
.np
|
||||
AE2F-AE41 Skip a line on CATALOG printout.
|
||||
Output a carriage return.
|
||||
Decrement line counter.
|
||||
If still nonzero, exit.
|
||||
Otherwise, wait for keyboard keypush.
|
||||
Then reset counter to 21 lines.
|
||||
And return to caller.
|
||||
.np
|
||||
AE42-AE69 Convert the number stored at $44 to a three character
|
||||
printable number and print it.
|
||||
.np
|
||||
AE6A-AE7D Restore file manager workarea from file buffer.
|
||||
Select file manager workarea buffer.
|
||||
Set return code in parmlist to zero initially.
|
||||
Copy 45 byte saved image of file manager workarea in
|
||||
file buffer to real file manager workarea.
|
||||
Exit to caller.
|
||||
.np
|
||||
AE7E-AE8D Save file manager workarea in file buffer.
|
||||
Select file manager workarea buffer.
|
||||
Copy 45 byte workarea to file buffer.
|
||||
Exit to caller.
|
||||
.np
|
||||
AE8E-AF07 INIT function handler.
|
||||
Initialize the file manager workarea (ABDC).
|
||||
Call RWTS to format the diskette (B058).
|
||||
Copy V value to VTOC buffer.
|
||||
Start track to allocate next value at $11.
|
||||
And direction of allocation as $01 (forward).
|
||||
Zero VTOC bit map (all sectors in use).
|
||||
Skipping the first three tracks and track $11, copy
|
||||
the 4 byte bit mask (B3A0) to each track entry in
|
||||
the VTOC bit map to free the sectors. This leaves the
|
||||
first three tracks and the catalog track marked in
|
||||
use.
|
||||
Zero the directory sector buffer.
|
||||
Point to directory sector buffer.
|
||||
Set track $11 in RWTS parmlist.
|
||||
Set up link from this directory sector to next (track
|
||||
$11, sector-1).
|
||||
Call RWTS to write directory sector.
|
||||
Write each sector on track in this way except for
|
||||
sector zero.
|
||||
On last sector (sector 1) zero link pointer.
|
||||
Point RWTS parms at DOS load point (B7C2).
|
||||
Write DOS image onto tracks 0-2 (B74A).
|
||||
Exit file manager.
|
||||
.np
|
||||
AF08-AF1C Select a buffer by setting $42,$43 to point to it.
|
||||
AF08 Select file manager workarea buffer in file buffer.
|
||||
AF0C Select T/S List sector buffer in file buffer.
|
||||
AF10 Select data sector buffer in file buffer.
|
||||
Exit to caller when $42,$43 are set.
|
||||
.np
|
||||
AF1D-AF33 Checkpoint write data sector buffer to disk.
|
||||
Test flag to see if buffer was changed since last
|
||||
read/write.
|
||||
If not, exit to caller.
|
||||
Otherwise, set up RWTS pointer (AFE4).
|
||||
Call RWTS to write sector.
|
||||
Reset flag to indicate data sector no longer in need
|
||||
of a checkpoint.
|
||||
Exit to caller.
|
||||
.np
|
||||
AF34-AF4A Checkpoint write T/S List sector buffer to disk.
|
||||
Test flag to see if buffer was changed since last
|
||||
read/write.
|
||||
If not, exit to caller.
|
||||
Otherwise, set up RWTS pointer (AF4B).
|
||||
Call RWTS to write sector.
|
||||
Reset flag to indicate T/S List sector no longer in
|
||||
need of checkpoint.
|
||||
Exit to caller.
|
||||
.nx ch8.6
|
||||
\x00
|
409
D1S2/CH8.6#064000.txt
Normal file
409
D1S2/CH8.6#064000.txt
Normal file
|
@ -0,0 +1,409 @@
|
|||
.np
|
||||
AF4B-AF5D Prepare for RWTS call with a T/S List sector.
|
||||
Copy address of T/S List buffer to RWTS parmlist.
|
||||
Get track/sector of sector.
|
||||
Exit to caller.
|
||||
.np
|
||||
AF5E-AFDB Read a T/S List sector to file buffer.
|
||||
(CARRY flag is set at entry to indicate whether the
|
||||
first T/S List for the file is wanted (C=0) or the
|
||||
next (C=1).
|
||||
Memorize carry flag entry code.
|
||||
Checkpoint current T/S List sector if necessary.
|
||||
Set up for RWTS (AF4B).
|
||||
Select T/S List buffer (AF0C).
|
||||
Is first or next wanted?
|
||||
If first, go to AFB5 to continue.
|
||||
Otherwise, get link to next T/S List from this one.
|
||||
If link is non-zero, use it to find next one and go
|
||||
to AFB5.
|
||||
Otherwise, we are out of T/S Lists for this file.
|
||||
If we are reading file, exit with error code.
|
||||
Otherwise, allocate a new sector (B244).
|
||||
Point old T/S List sector to new one's track/sector.
|
||||
Write old T/S List sector back to disk.
|
||||
Zero the buffer to form new T/S List sector.
|
||||
Compute and store the relative sector number of the
|
||||
first sector listed in this sector at +5,+6 into the
|
||||
buffer.
|
||||
Set RWTS opcode to write new T/S List sector to disk.
|
||||
AFB5 Set RWTS opcode to read old T/S List (unless we just
|
||||
allocated it above).
|
||||
Set track and sector and call RWTS to read old list
|
||||
or write new list.
|
||||
Compute relative sector number of last sector (plus
|
||||
one) in this list and store in workarea.
|
||||
Exit to caller with normal return code.
|
||||
.np
|
||||
AFDC-AFE3 Read a data sector.
|
||||
Set up for RWTS (AFE4).
|
||||
Set RWTS READ opcode and go to RWTS driver to do it.
|
||||
.np
|
||||
AFE4-AFF6 Prepare for RWTS with data sector.
|
||||
Copy address of data sector buffer to RWTS parmlist.
|
||||
Get its track/sector.
|
||||
And exit to caller.
|
||||
.np
|
||||
AFF7-B010 Read/write the VTOC buffer.
|
||||
AFF7 Read VTOC entry, go to AFFD.
|
||||
AFFB Write VTOC entry, fall through.
|
||||
AFFD Common code.
|
||||
Copy VTOC sector buffer address to RWTS parmlist.
|
||||
Get its track number and use sector $00.
|
||||
Exit through RWTS driver.
|
||||
.np
|
||||
B011-B036 Read a directory sector.
|
||||
(If CARRY flag is zero on entry, read first directory
|
||||
sector. If CARRY is one, read next)
|
||||
Memorize entry code.
|
||||
Set buffer pointers (B045).
|
||||
First or next?
|
||||
If first, get track/sector of directory sector from
|
||||
VTOC at offset +1,+2.
|
||||
Otherwise, get track/sector from directory sector at
|
||||
offset +1,+2. If track is zero, exit with error code
|
||||
(end of directory).
|
||||
Call RWTS to read sector.
|
||||
Exit with normal return code.
|
||||
.np
|
||||
B037-B044 Write directory sector.
|
||||
Set buffer pointers.
|
||||
Find its track/sector in workarea.
|
||||
Exit through RWTS to write it.
|
||||
.np
|
||||
B045-B051 Prepare for RWTS for directory buffer.
|
||||
Copy directory buffer address to RWTS parmlist.
|
||||
Exit to caller.
|
||||
.np
|
||||
B052-B0B3 Read/Write Track/Sector (RWTS) driver.
|
||||
Set track/sector in RWTS parmlist.
|
||||
B058 Set command code (read,write,etc.)
|
||||
If writing, set flag (B5D5).
|
||||
Set volume number expected in parmlist.
|
||||
Set slot*16 in parmlist.
|
||||
Set drive in parmlist.
|
||||
Set sector size in parmlist.
|
||||
Set IOB type in parmlist ($01).
|
||||
Call RWTS, passing parmlist pointer.
|
||||
Copy true volume found to file manager parmlist.
|
||||
Reset volume expected field in RWTS parmlist.
|
||||
If an error did not occur, exit to caller.
|
||||
Otherwise, get return code.
|
||||
Translate vol mismatch to rc=7, write protected to
|
||||
rc=4 and all other errors to rc=8 (I/O error).
|
||||
Exit file manager now.
|
||||
.np
|
||||
B0B6-B133 Read next data sector (if necessary).
|
||||
Is the current file position in the current data
|
||||
sector now in memory?
|
||||
If so, go to B12C.
|
||||
Otherwise, checkpoint data sector buffer.
|
||||
Is the current file position prior to or after this
|
||||
T/S List's domain?
|
||||
If not, go to B0F3.
|
||||
Otherwise, read each T/S List for the file, starting
|
||||
with the first, until the proper one is found.
|
||||
If it is never found, exit with error (ran off end of
|
||||
file reading).
|
||||
B0F3 Data is in this T/S List sector.
|
||||
Compute the displacement to the proper entry in this
|
||||
T/S List sector.
|
||||
Select the T/S List buffer.
|
||||
Get the track of the data sector wanted.
|
||||
If non-zero, go to B114.
|
||||
Otherwise, if not writing, exit with error (no data
|
||||
to read there).
|
||||
If writing, allocate a new sector and store its
|
||||
track/sector location in the list at this point
|
||||
(B134).
|
||||
Go to B120.
|
||||
B114 Read old data sector, using the track/sector found
|
||||
in the T/S List entry.
|
||||
B120 Save number of sector last read in workarea.
|
||||
B12C Select data buffer.
|
||||
Get byte offset and exit normally to caller.
|
||||
.np
|
||||
B134-B15A Add a new data sector to file.
|
||||
Allocate a sector (B244).
|
||||
Put track/sector numbers in T/S List entry.
|
||||
Select data buffer and zero it.
|
||||
Set flags to indicate that the T/S List sector and
|
||||
the data sector buffer require checkpoints.
|
||||
Exit to caller.
|
||||
.np
|
||||
B15B-B193 Increment record number and byte offset into file.
|
||||
Copy current record number and byte offset to file
|
||||
manager parameter list to pass back to caller.
|
||||
Increment byte offset in workarea.
|
||||
If byte offset equals record length, set byte offset
|
||||
back to zero and increment record number.
|
||||
Return to caller.
|
||||
.np
|
||||
B194-B1A1 Increment file position offset.
|
||||
Increment byte offset into current sector by one.
|
||||
If at end of sector, increment sector number by one.
|
||||
Return to caller.
|
||||
.np
|
||||
B1A2-B1B4 Copy and advance range address.
|
||||
Copy range address from file manager parmlist to $42.
|
||||
Increment range address in parmlist for next time
|
||||
through.
|
||||
Return to caller.
|
||||
.np
|
||||
B1B5-B1C8 Decrement range length.
|
||||
Decrement range length in file manager parmlist by
|
||||
one.
|
||||
If zero, exit file manager.
|
||||
Otherwise, exit to caller.
|
||||
.np
|
||||
B1C9-B21B Locate or allocate a directory entry in the catalog.
|
||||
Read the VTOC sector (AFF7).
|
||||
Set $42,$43 to point to file name we are looking for.
|
||||
Set pass number to one (locate file).
|
||||
B1D8 Initialize directory sector offset (first sector).
|
||||
B1E1 Increment sector offset.
|
||||
Read directory sector.
|
||||
If at end of directory, go to B23A.
|
||||
Set entry index to first file entry.
|
||||
B1EB Get track.
|
||||
If deleted, skip entry, go to B217.
|
||||
If empty, end of directory, go to B212.
|
||||
Advance index to filename in directory.
|
||||
Compare against filename wanted.
|
||||
If they match, return entry index and exit.
|
||||
If not, advance index to next entry in sector and
|
||||
loop back to B1EB.
|
||||
If at end of sector, go to B1E1 to get next sector.
|
||||
B212 If pass number is one, go to B1D8 to start second
|
||||
pass.
|
||||
B217 If pass number is one, go to B20B to skip entry.
|
||||
If second pass, fall through to allocate entry.
|
||||
.np
|
||||
B21C-B22F Copy file name to directory entry.
|
||||
Advance index to file name field in directory entry.
|
||||
Copy 30 byte filename to directory entry.
|
||||
Reload directory index and return to caller.
|
||||
.np
|
||||
B230-B239 Advance index to next directory entry in sector.
|
||||
Add 35 (length of entry) to index.
|
||||
Test for end of sector and return to caller.
|
||||
.np
|
||||
B23A-B243 Switch to second pass in directory scan.
|
||||
If on pass one, switch to pass 2 and go to B1D8.
|
||||
If on pass two, exit file manager with "DISK FULL"
|
||||
error.
|
||||
.np
|
||||
B244-B2C2 Allocate a disk sector.
|
||||
Is there a track currently allocated to this file?
|
||||
If not, go to B26A to find a track with free sectors.
|
||||
B249 Otherwise, decrement sector number to get next
|
||||
possible free sector number.
|
||||
If there are no more sectors on this track, go to
|
||||
B265 to find a new track.
|
||||
Otherwise, rotate the track bit mask by one position
|
||||
and get the bit for this sector.
|
||||
If the sector is in use, loop back to B249.
|
||||
Otherwise, add one to file's sector count.
|
||||
Pass back sector number (track number is at B5F1).
|
||||
And return to caller.
|
||||
B265 Indicate no track is being used at present.
|
||||
B26A Reset allocation flag to allow at least one complete
|
||||
search of all tracks for some space.
|
||||
Read VTOC sector.
|
||||
B272 Get last track allocated from and add direction value
|
||||
to get next track to examine (+1 or -1).
|
||||
Are we back to track 0?
|
||||
If so, go to B284.
|
||||
Otherwise, are we past track 34?
|
||||
If so, reverse direction and go to B28E.
|
||||
B284 Is this the second time we have come to track 0 ?
|
||||
(check allocation flag).
|
||||
If so, exit with "DISK FULL" error.
|
||||
Otherwise, set allocation flag to remember this.
|
||||
Set direction to forward (+1).
|
||||
B28E Begin at directory track (17 + or - 1).
|
||||
Compute bit map index (tracknumber*4).
|
||||
Copy track bit map from VTOC to workarea, watching
|
||||
to see if all four bytes are zero (track is full).
|
||||
In any case, set all four bytes in VTOC to zero
|
||||
(allocate all sectors).
|
||||
If no free sectors in the track, go to B272 to try
|
||||
next track.
|
||||
Otherwise, write VTOC to disk to insure file's
|
||||
integrity.
|
||||
Set sector number to last sector in track.
|
||||
Go to B249 to allocate one of its free sectors to
|
||||
the file.
|
||||
.np
|
||||
B2C3-B2DC Release pre-allocated sectors in current track and
|
||||
checkpoint the VTOC.
|
||||
Has a track been allocated to the file?
|
||||
If not, exit to caller.
|
||||
Otherwise, read VTOC.
|
||||
Get next sector which could have been used (number
|
||||
of times track map was shifted during allocation).
|
||||
Call B2DD to shift track bit map back and merge it
|
||||
back into the VTOC bit map.
|
||||
Indicate no track has been allocated.
|
||||
Exit to caller.
|
||||
.np
|
||||
B2DD-B2FF Free one or more sectors by shifting mask in file
|
||||
manager's allocation area back into VTOC bit map.
|
||||
(If CARRY is set, current sector is freed also)
|
||||
Rotate entire 4 byte track bit mask once.
|
||||
Repeat for as many sectors as were allocated.
|
||||
Compute index into VTOC for this track's map.
|
||||
If zero, exit.
|
||||
Merge ("OR") file manager's bits with those already
|
||||
in VTOC, freeing sectors which were never used by
|
||||
the file.
|
||||
Return to caller.
|
||||
.np
|
||||
B300-B35E Calculate file position.
|
||||
Set record number passed in file manager parmlist
|
||||
in workarea and in sector offsets.
|
||||
Clear sector offset high part.
|
||||
Perform a 16 bit multiply as follows:
|
||||
3 byte file position = record number times record
|
||||
length.
|
||||
Add the byte offset from the parmlist into the three
|
||||
byte file position value (B5E4,B5E5,B5E6).
|
||||
Return to caller.
|
||||
.np
|
||||
B35F-B37D Error exits.
|
||||
B35F RC=1 "LANGUAGE NOT AVAILABLE"
|
||||
B363 RC=2 "RANGE ERROR" (bad opcode)
|
||||
B367 RC=3 "RANGE ERROR" (bad subcode)
|
||||
B36B RC=4 "WRITE PROTECTED"
|
||||
B36F RC=5 "END OF DATA"
|
||||
B373 RC=6 "FILE NOT FOUND"
|
||||
B377 RC=9 "DISK FULL" (all files closed)
|
||||
B37B RC=A "FILE LOCKED"
|
||||
.np
|
||||
B37F-B396 Exit file manager.
|
||||
B37F Exit with no errors.
|
||||
Get return code of zero.
|
||||
Clear carry flag and go to B386.
|
||||
B385 Set carry flag to indicate error.
|
||||
B386 Save return code in parmlist.
|
||||
Clear monitor status register ($48) after RWTS has
|
||||
probably tromped on it.
|
||||
Save file manager workarea to file buffer (AE7E).
|
||||
Restore processor status and stack register.
|
||||
Exit to original caller of file manager.
|
||||
.np
|
||||
B397-B3A3 File manager scratch space.
|
||||
B397 Track/sector of current directory sector (2 bytes).
|
||||
B39B S register save area.
|
||||
B39C Directory index.
|
||||
B39D Catalog line counter/Directory lookup flag/Etc.
|
||||
B39E LOCK/UNLOCK mask/Allocation flag/Etc.
|
||||
B3A0 Four byte mask used by INIT to free an entire track
|
||||
in the VTOC bit map.
|
||||
.np
|
||||
B3A4-B3A6 Decimal conversion table (1,10,100).
|
||||
.np
|
||||
B3A7-B3AE File type name table used by CATALOG.
|
||||
File types are: T,I,A,B,S,R,A,B, corresponding to
|
||||
hex values: $00, $01, $02, $04, $08, $10, $20, and
|
||||
$40 respectively.
|
||||
.np
|
||||
B3AF-B3BA ASCII text "DISK VOLUME " backwards. Used by CATALOG.
|
||||
.np
|
||||
B3BB-B4BA VTOC sector buffer.
|
||||
B3BC Track/sector of first directory sector.
|
||||
B3BE DOS release number (1, 2, or 3).
|
||||
B3C1 Volume number of diskette.
|
||||
B3E2 Number of entries in each T/S List sector.
|
||||
B3EB Track to allocate next.
|
||||
B3EC Direction of track allocation (+1 or -1)
|
||||
B3EF Number of tracks on a disk.
|
||||
B3F0 Number of sectors on a disk.
|
||||
B3F1 Sector size in bytes (2 bytes)
|
||||
B3F3 Track 0 bit map
|
||||
B3F7 Track 1 bit map
|
||||
etc.
|
||||
B47B Track 34 bit map
|
||||
.np
|
||||
B4BB-B5BA DIRECTORY sector buffer.
|
||||
B4BC Track/sector of next directory sector.
|
||||
B4C6 First directory entry and
|
||||
Track of T/S List
|
||||
B4C7 Sector of T/S List
|
||||
B4C8 File type and lock bit
|
||||
B4C9 Filename field (30 bytes)
|
||||
B4E7 Size of file in sectors (including T/S List(s)).
|
||||
.np
|
||||
B5BB-B5D0 File manager parameter list.
|
||||
B5BB Opcode
|
||||
B5BC Subcode
|
||||
B5BD Eight bytes of variable parameters depending on
|
||||
opcode.
|
||||
B5C5 Return code.
|
||||
B5C7 Address of file manager workarea buffer.
|
||||
B5C9 Address of T/S List sector buffer.
|
||||
B5CB Address of data sector buffer.
|
||||
B5CD Address of next DOS buffer on chain (not used).
|
||||
.np
|
||||
B5D1-B5FD File manager workarea.
|
||||
B5D1 1st T/S List sector's track/sector.
|
||||
B5D3 Current T/S List sector's track/sector.
|
||||
B5D5 Flags: 80=T/S List needs checkpoint
|
||||
40=Data sector needs checkpoint
|
||||
20=VTOC sector needs checkpoint
|
||||
02=Last operation was write
|
||||
B5D6 Current data sector's track/sector.
|
||||
B5D8 Directory sector index for file entry.
|
||||
B5D9 Index into directory sector to directory entry for
|
||||
file.
|
||||
B5DA Number of sectors described by one T/S List.
|
||||
B5DC Relative sector number of first sector in list.
|
||||
B5DE Relative sector number +1 of last sector in list.
|
||||
B5E0 Relative sector number of last sector read.
|
||||
B5E2 Sector length in bytes.
|
||||
B5E4 File position (3 bytes) sector offset, byte offset
|
||||
into that sector.
|
||||
B5E8 Record length from OPEN.
|
||||
B5EA Record number.
|
||||
B5EC Byte offset into record.
|
||||
B5EE Number of sectors in file.
|
||||
B5F0 Sector allocation area (6 bytes).
|
||||
Next sector to allocate (shift count)
|
||||
Track being allocated
|
||||
Four byte bit map of track being allocated, rotated
|
||||
to next sector to allocate.
|
||||
B5F6 File type.
|
||||
B5F7 Slot number times 16.
|
||||
B5F8 Drive number.
|
||||
B5F9 Volume number (complemented).
|
||||
B5FA Track number.
|
||||
.np
|
||||
B5FE-B5FF Not used.
|
||||
.np
|
||||
B600-B6FF Start of Boot 2/RWTS image.
|
||||
B600 Boot 1 image which can be written to INITed disks
|
||||
on track 0, sector 0.
|
||||
B65D DOS 3.3 patch area.
|
||||
B65D APPEND patch flag.
|
||||
B65E APPEND patch. Come here when file manager driver
|
||||
gets an error other than end of data.
|
||||
Locate and free the file buffer.
|
||||
Clear the APPEND flag.
|
||||
Get the error number and go print error (A6D2).
|
||||
B671 APPEND patch. Come here from APPEND command handler
|
||||
to increment record number if APPEND flag is set and
|
||||
to clear the flag. Exit through POSITION.
|
||||
B686 VERIFY patch. Come here from I/O a range of bytes
|
||||
routine to exit through VERIFY after SAVE or BSAVE.
|
||||
B692 APPEND patch. Come here from file manager driver if
|
||||
return code was END OF DATA.
|
||||
Test the file position for zero.
|
||||
If non-zero, set APPEND flag on and return to caller.
|
||||
If zero (at start of file), copy record number and
|
||||
byte offset to file manager parmlist and return a
|
||||
zero data byte to caller.
|
||||
B6FE Page address of first page in Boot 2.
|
||||
B6FF Number of sectors (pages) in Boot 2.
|
||||
.br
|
||||
.nx ch8.7
|
||||
\x00
|
405
D1S2/CH8.7#064000.txt
Normal file
405
D1S2/CH8.7#064000.txt
Normal file
|
@ -0,0 +1,405 @@
|
|||
.np
|
||||
B700-B749 DOS 2nd stage boot loader.
|
||||
Set RWTS parmlist to read DOS from disk.
|
||||
Call Read/Write group of pages ($B793).
|
||||
Create new stack.
|
||||
Call SETVIC ($FE93) and SETKBD ($FE89).
|
||||
Exit to DOS coldstart ($9D84).
|
||||
.NP
|
||||
B74A-B78C Put DOS on tracks 0-2.
|
||||
Set RWTS parmlist to write DOS to disk.
|
||||
Call Read/Write group of pages ($B793).
|
||||
Exit to caller.
|
||||
.np
|
||||
B78D-B792 Unused.
|
||||
.np
|
||||
B793-B7B4 Read/Write a group of pages.
|
||||
call RWTS through external entry point ($B7B5).
|
||||
Exit to caller.
|
||||
.np
|
||||
B7B5-B7C1 Disable interrupts and call RWTS.
|
||||
.np
|
||||
B7C2-B7D5 Set RWTS parameters for writing DOS.
|
||||
.NP
|
||||
B7D6-B7DE Zero current buffer.
|
||||
Zero 256 bytes pointed to by $42,$43.
|
||||
Exit to caller.
|
||||
.np
|
||||
B7DF-B7E7 DOS 2nd stage boot loader parmlist.
|
||||
B7DF Unused.
|
||||
B7E0 Number of pages in 2nd DOS load.
|
||||
B7E1 Number of sectors to read/write.
|
||||
B7E2 Number of pages in 1st DOS load.
|
||||
B7E3 INIT DOS page counter.
|
||||
B7E4 Pointer to RWTS parmlist (2 bytes).
|
||||
B7E6 Pointer to 1st stage boot location (2 bytes).
|
||||
.np
|
||||
B7E8-B7F8 RWTS parmlist.
|
||||
B7E8 Table type. Must be $01.
|
||||
B7E9 Slot number times 16.
|
||||
B7EA Drive number ($01 or $02).
|
||||
B7EB Volume number expected (0 matches any volume).
|
||||
B7EC Track number ($00 to $22).
|
||||
B7ED Sector number ($00 to $0F).
|
||||
B7EE Pointer to Device Characteristics Table (2 bytes).
|
||||
B7F0 Pointer to user data buffer for READ/WRITE (2 bytes).
|
||||
B7F2 Unused.
|
||||
B7F3 Byte count for partial sector (use $00 for 256).
|
||||
B7F4 Command code: 0=SEEK, 1=READ, 2=WRITE, 4=FORMAT.
|
||||
B7F5 Error code:(valid if carry set) $10=Write protect,
|
||||
$20=Volume mismatch, $40=Drive error, $80=Read error.
|
||||
B7F6 Volume number found.
|
||||
B7F7 Slot number found.
|
||||
B7F8 Drive number found.
|
||||
.NP
|
||||
B7F9-B7FA Unused.
|
||||
.NP
|
||||
B7FB-B7FE Device Characteristics Table (DCT).
|
||||
B7FB Device type (should be $00).
|
||||
B7FC Phases per track (should be $01).
|
||||
B7FD Motor on time count (2 bytes - should be $EF, $D8).
|
||||
.NP
|
||||
B7FF Unused.
|
||||
.np
|
||||
B800-B829 PRENIBBLE routine.
|
||||
Converts 256 (8 bit) bytes to 342 (6 bit) "nibbles"
|
||||
of the form 00XXXXXX.
|
||||
Pointer to page to convert stored at $3E,$3F.
|
||||
Data stored at primary and secondary buffers.
|
||||
On entry: $3E,$3F contain pointer to user data.
|
||||
On exit: A-reg:unknown
|
||||
X-reg:$FF
|
||||
Y-reg:$FF
|
||||
Carry set
|
||||
Exit to caller.
|
||||
.np
|
||||
B82A-B8B7 WRITE routine.
|
||||
Writes prenibbilized data from primary and secondary
|
||||
buffers to disk.
|
||||
Calls Write a byte subroutine.
|
||||
Writes 5 bytes autosync, starting data marks
|
||||
($D5/$AA/$AD), 342 bytes data, one byte checksum, and
|
||||
closing data marks ($DE/$AA/$EB).
|
||||
Uses Write Translate Table ($ba29).
|
||||
On entry: X-reg:Slot number times 16
|
||||
On exit: Carry set if error
|
||||
If no error:
|
||||
A-reg:unknown
|
||||
X-reg:unchanged
|
||||
Y-reg:$00
|
||||
Carry clear
|
||||
Uses $26,$27,$678
|
||||
Exit to caller.
|
||||
.np
|
||||
B8B8-B8C1 Write a byte subroutine.
|
||||
Timing critical code used to write bytes at 32 cycle
|
||||
intervals.
|
||||
Exit to caller.
|
||||
.np
|
||||
B8C2-B8DB POSTNIBBLE routine.
|
||||
Converts 342 (6 bit) "nibbles" of the form 00XXXXXX
|
||||
to 256 (8 bit) bytes.
|
||||
Nibbles stored at primary and secondary buffers.
|
||||
Pointer to data page stored at $3E,$3F.
|
||||
On entry: X-reg:Slot number times 16
|
||||
$36,$37:pointer to user data
|
||||
$26:byte count in secondary buffer ($00)
|
||||
On exit: A-reg:unknown
|
||||
X-reg:unknown
|
||||
Y-reg:byte count in secondary buffer
|
||||
Carry set
|
||||
Exit to caller.
|
||||
.np
|
||||
B8DC-B943 READ routine.
|
||||
Read a sector of data from disk and store it at
|
||||
primary and secondary buffers. (First uses secondary
|
||||
buffer high to low, then primary low to high)
|
||||
On entry: X-reg:Slot times 16
|
||||
Read mode (Q6L,Q7L)
|
||||
On exit: Carry set if error.
|
||||
If no error:
|
||||
A-reg:$AA
|
||||
X-reg:unchanged
|
||||
Y-reg:$00
|
||||
Carry clear
|
||||
Uses $26
|
||||
Exit to caller.
|
||||
.np
|
||||
B944-B99F RDADR routine.
|
||||
Read an Address Field.
|
||||
Reads starting address marks ($D5/$AA/$96), address
|
||||
information (volume/track/sector/checksum), and
|
||||
closing address marks ($DE/$AA).
|
||||
On entry: X-reg:Slot number times 16
|
||||
Read mode (Q6L,Q7L)
|
||||
On exit: Carry set if error.
|
||||
If no error:
|
||||
A-reg:$AA
|
||||
X-reg:unchanged
|
||||
Y-reg:$00
|
||||
Carry clear
|
||||
$2F: Volume number found
|
||||
$2E: Track number found
|
||||
$2D: Sector number found
|
||||
$2C: Checksum found
|
||||
Uses $26,$27
|
||||
Exit to caller.
|
||||
.np
|
||||
B9A0-B9FC SEEKABS routine.
|
||||
Move disk arm to desired track.
|
||||
Calls arm move delay subroutine ($B9FD).
|
||||
On entry: X-reg:Slot number times 16
|
||||
A-reg:Desired track (halftrack for single
|
||||
phase disk).
|
||||
$478:Current track.
|
||||
On exit: A-reg:unknown
|
||||
X-reg:unchanged
|
||||
Y-reg:unknown
|
||||
$2A and $478:Final track
|
||||
$27:Prior track (if seek needed)
|
||||
Uses: $26,$27,$2A,$2B
|
||||
Exit to caller.
|
||||
.np
|
||||
B9FD-BA10 Arm move delay subroutine.
|
||||
Delays a specified number of 100 Usec intervals.
|
||||
On entry: A-reg:number of 100 Usec intervals.
|
||||
$46,$47:Should contain motor on time count
|
||||
($EF,$D8) from Device Characteristics Table
|
||||
$478:Current track.
|
||||
On exit: A-reg:$00
|
||||
X-reg:$00
|
||||
Y-reg:unchanged
|
||||
Carry set
|
||||
Exit to caller.
|
||||
.np
|
||||
BA11-BA28 Arm move delay table.
|
||||
Contains values of 100 Usec intervals used during
|
||||
Phase-on and Phase-off of stepper motor.
|
||||
.np
|
||||
BA29-BA68 Write Translate Table.
|
||||
Contains 6 bit "nibbles" used to convert 8 bit bytes.
|
||||
Values range from $96 to $FF.
|
||||
Codes with more than one pair of adjacent zeros or
|
||||
with no adjacent ones are excluded.
|
||||
.NP
|
||||
BA69-BA95 Unused.
|
||||
.np
|
||||
BA96-BAFF Read Translate Table.
|
||||
Contains 8 bit bytes used to convert 6 bit "nibbles".
|
||||
Values range from $96 to $FF.
|
||||
Codes with more than one pair of adjacent zeros or
|
||||
with no adjacent ones are excluded.
|
||||
.np
|
||||
BB00-BBFF Primary Buffer.
|
||||
BC00-BC55 Secondary Buffer.
|
||||
.np
|
||||
BC56-BCC3 Write Address Field during initialization.
|
||||
Calls Write double byte subroutine.
|
||||
Writes number of autosync bytes contained in Y-reg,
|
||||
starting address marks ($D5/$AA/$96), address
|
||||
information (volume/track/sector/checksum), closing
|
||||
address marks ($DE/$AA/$EB).
|
||||
On entry: X-reg:Slot number times 16
|
||||
Y-reg:number of autosync to write
|
||||
$3E: $AA
|
||||
$3F: sector number
|
||||
$41: volume number
|
||||
$44: track number
|
||||
On exit: A-reg:unknown
|
||||
X-reg:unchanged
|
||||
Y-reg:$00
|
||||
Carry set
|
||||
Exit to caller.
|
||||
.np
|
||||
BCC4-BCDE Write double byte subroutine.
|
||||
Timing critical code that encodes address information
|
||||
into even and odd bits and writes it at 32 cycle
|
||||
intervals.
|
||||
Exit to caller.
|
||||
.np
|
||||
BCDF-BCFF Unused.
|
||||
.np
|
||||
BD00-BD18 Main entry to RWTS.
|
||||
Upon entry, store Y-reg and A-reg at $48,$49 as
|
||||
pointers to the IOB.
|
||||
Initialize maximum number of recals at 1 and seeks
|
||||
at 4.
|
||||
Check if the slot number has changed. If not,
|
||||
branch to SAMESLOT at $BD34.
|
||||
BD19-BD33 Update slot number in IOB and wait for old drive
|
||||
to turn off.
|
||||
BD34-BD53 SAMESLOT
|
||||
Enter read mode and read with delays to see if disk
|
||||
is spinning.
|
||||
Save result of test and turn on motor just in case.
|
||||
BD54-BD73 Move pointers in IOB to zero page for future use.
|
||||
Device Characteristics Table pointer at $3C,$3D
|
||||
and data buffer pointer at $3E,$3F.
|
||||
Set up $47 (motor on time) with $D8 from DCT.
|
||||
Check if the drive number has changed. If not,
|
||||
branch to $BD74.
|
||||
If so, change test results to show drive off.
|
||||
BD74-BD8F Select appropriate drive and save drive being used
|
||||
as high bit of $35. 1=drive 1, 0=drive 2.
|
||||
Get test results. If drive was on, branch to $BD90.
|
||||
Wait for capacitor to discharge using MSWAIT
|
||||
subroutine at $BA00.
|
||||
BD90-BDAA Get destination track and go to it using MYSEEK
|
||||
subroutine at $BE5A.
|
||||
Check test result again and if drive was on,
|
||||
branch to TRYTRK at $BDAB.
|
||||
Delay for motor to come up to speed.
|
||||
BDAB-BDBB TRYTRK
|
||||
Get command code.
|
||||
If null, exit through ALLDONE at $BE46, turning drive
|
||||
off and returning to caller.
|
||||
If =4, branch to FORMDSK at $BE0D.
|
||||
Otherwise, move low bit into carry (set=read,
|
||||
clear=write) and save value on status reg.
|
||||
If write operation, data is prenibbilized via a call
|
||||
to PRENIB16 at $B800.
|
||||
BDBC-BDEC Initialize maximum retries at 48 and read an
|
||||
Address Field via RDADR16 at $B944.
|
||||
If read was good, branch to RDRIGHT at $BDED.
|
||||
If bad read, decrement retries, and, if still some
|
||||
left try again. Else, prepare to recalibrate.
|
||||
Decrement recal count. If no more, then indicate
|
||||
drive error via DRVERR at $BE04.
|
||||
Otherwise, reinitialize reseeks at 4 and recalibrate
|
||||
arm. Move to desired track and try again.
|
||||
BDED-BE03 RDRIGHT
|
||||
Verify on correct track. If so branch to RTTRK
|
||||
at $BE10.
|
||||
If not, set correct track via SETTRK subroutine at
|
||||
$BE95 and decrement reseek count.
|
||||
If not zero then reseek track. If zero, then recal.
|
||||
BE04-BE0A DRVERR
|
||||
Clean up stack and status reg.
|
||||
Load A-reg with $40 (drive error)
|
||||
Goto HNDLERR at $BE48.
|
||||
BE0B-BE0C Used to branch to ALLDONE at $BE46.
|
||||
BE0D-BF0F FORMDSK
|
||||
Jump to DSKFORM at $BEAF.
|
||||
BE10-BE25 RTTRK
|
||||
Check volume number found against volume number
|
||||
wanted.
|
||||
If no volume was specified, then no error.
|
||||
If specified volume doesn't match, load A-reg with
|
||||
$20 (volume mismatch error) and exit via HNDLERR
|
||||
at $BE48.
|
||||
BE26-BE45 CRCTVOL
|
||||
Check to see if sector is correct.
|
||||
Use ILFAV table at $BFB8 for software sector
|
||||
interleaving.
|
||||
If wrong sector, try again by branching back to
|
||||
TRYADR at $BDC1.
|
||||
If sector correct, find out what operation to do.
|
||||
If write, branch to WRIT at $BE51.
|
||||
Otherwise, read data via READ16 ($B8DC).
|
||||
If read is good, then postnibble data via POSTNB16
|
||||
($B8C2) and return to caller with no error.
|
||||
BE46-BE47 ALLDONE
|
||||
Skip over set carry instruction in HNDLERR.
|
||||
BE48-BE50 HNDLERR
|
||||
Set carry.
|
||||
Store A-reg in IOB as return code.
|
||||
Turn off motor.
|
||||
Return to caller.
|
||||
BE51-BE59 WRITE
|
||||
Write a sector using WRITE16 ($B82A).
|
||||
If the write was good, exit via ALLDONE ($BE46).
|
||||
If bad write, load A-reg with $10 (write protect
|
||||
error) and exit via HNDLERR ($BE48).
|
||||
BE5A-BE8D MYSEEK
|
||||
Provides necessary housekeeping before going to
|
||||
SEEKABS routine.
|
||||
Determines number of phases per track and stores
|
||||
track information in appropriate slot dependent
|
||||
location.
|
||||
BE8E-BE94 XTOY routine.
|
||||
Put slot in Y-reg by transferring X-reg divided
|
||||
by 16 into Y-reg.
|
||||
BE95-BEAE Set track number.
|
||||
BEAF-BF0C INIT command handler
|
||||
Provides setup for initializing a disk.
|
||||
Get the desired volume number from the IOB.
|
||||
Zero both the primary and secondary buffers.
|
||||
Recalibrate the disk arm to track 0.
|
||||
Set the number of sync bytes to be written between
|
||||
sectors to $28 (40.).
|
||||
Call TRACK WRITE routine for the actual formatting.
|
||||
Allow 48 retries during initialization.
|
||||
Double check that the first sector found is zero
|
||||
after calling TRACK WRITE.
|
||||
Increment the track number after successfully
|
||||
formatting a track.
|
||||
Loop back until 35 tracks are done.
|
||||
BF0D-BF61 TRACK WRITE routine.
|
||||
Start with sector zero.
|
||||
Preceed it with 128 self-sync bytes.
|
||||
Follow them with sectors 0 through 15 in sequence.
|
||||
Set retry count for verifying the track at 48.
|
||||
Fill the sector initilization map with positive
|
||||
numbers.
|
||||
Loop through a delay period to bypass most of the
|
||||
initial self-sync bytes.
|
||||
Read the first Address Field found.
|
||||
If the read is good and sector zero was found,
|
||||
enter the VERIFY TRACK routine.
|
||||
Decrement the sync count by 2 (until it reaches 16
|
||||
at which time it is decremented by 1).
|
||||
If sync count is greater than or equal to 5, exit
|
||||
via $BF71.
|
||||
If not, set carry and return to caller.
|
||||
BF62-BF87 VERIFY TRACK routine.
|
||||
This routine reads all 16 sectors from the track that
|
||||
was just formatted.
|
||||
If an error occurs during the read of either the
|
||||
Address Field or the Data Field, the number of
|
||||
retries is decremented.
|
||||
The routine continues reading until retries is zero.
|
||||
Calls Sector Map routine ($BF88).
|
||||
BF88-BFA7 Sector Map routine.
|
||||
This routine marks the sector initialization map as
|
||||
each sector is verified.
|
||||
If an error occurs, the routine exits through $BF6C,
|
||||
which decrements the number of retries and continues
|
||||
if that value is greater than zero.
|
||||
Upon completion of track zero, the sync count is
|
||||
decremented by two if it is at least 16.
|
||||
.NP
|
||||
BFA8-BFB7 Sector Initialization Map used to mark sectors as
|
||||
they are initialized.
|
||||
Contains a $30 prior to initialization of a track.
|
||||
Value changed to $FF as each sector is completed.
|
||||
.np
|
||||
BFB8-BFC7 Sector Translate Table
|
||||
Sector interleaving done with software.
|
||||
.np
|
||||
BFC8-BFD6 Patch area starts here.
|
||||
Patch from $B741 to zero language card during boot.
|
||||
Call SETVID ($FE93).
|
||||
Unprotect Language Card (if present).
|
||||
Store $00 at $E000.
|
||||
Exit through SETKBD ($FE89) and DOS coldstart.
|
||||
.np
|
||||
BFD9-BFDB Unused.
|
||||
.np
|
||||
BFDC-BFE5 Patch called from $A0E2.
|
||||
Set three additional defaults (Byte offset=0).
|
||||
Return to caller.
|
||||
.np
|
||||
BFE6-BFEC Patch called from $A6D5.
|
||||
Call $A75B to reset state and set warmstart flag.
|
||||
Mark RUN not interrupted.
|
||||
Return to caller.
|
||||
.np
|
||||
BFED-BFFF Patch called from $B377.
|
||||
Call $AE7E to save file manager workarea.
|
||||
Restore stack.
|
||||
Close all open files ($A316).
|
||||
Save stack again.
|
||||
Exit through $B385 ("DISK FULL ERROR").
|
||||
.br
|
||||
.nx ch8 zpage use
|
||||
\x00
|
53
D1S2/CH8.ZPAGE.USE#064000.txt
Normal file
53
D1S2/CH8.ZPAGE.USE#064000.txt
Normal file
|
@ -0,0 +1,53 @@
|
|||
.bp
|
||||
.nf
|
||||
.na
|
||||
DOS ZERO PAGE USAGE
|
||||
.SP1
|
||||
.un
|
||||
BYTE USE
|
||||
24 Cursor horizontal (DOS)
|
||||
26,27 Sector read buffer address (ROM)
|
||||
Scratch space (RWTS)
|
||||
28,29 BASL/BASH (DOS)
|
||||
2A Segment merge counter (ROM,BOOT)
|
||||
Scratch space (RWTS)
|
||||
2B BOOT slot*16 (ROM)
|
||||
Scratch space (RWTS)
|
||||
2C Checksum from sector header (RWTS)
|
||||
2D Sector number from sector header (RWTS)
|
||||
2E Track number from sector header (RWTS)
|
||||
2F Volume number from sector header (RWTS)
|
||||
33 Prompt character (DOS)
|
||||
35 Drive number in high bit (RWTS)
|
||||
36,37 CSWL,CSWH (DOS)
|
||||
38,39 KSWL,KSWH (DOS)
|
||||
3C Workbyte (ROM)
|
||||
Merge workbyte (BOOT)
|
||||
Device characteristics table address (RWTS)
|
||||
3D Sector number (ROM)
|
||||
Device characteristics table address (RWTS)
|
||||
3E,3F Address of ROM sector-read subroutine (BOOT)
|
||||
Buffer address (RWTS)
|
||||
40,41 DOS image address (BOOT)
|
||||
File buffer address (DOS)
|
||||
41 Format track counter (RWTS)
|
||||
42,43 Buffer address (DOS)
|
||||
44,45 Numeric operand (DOS)
|
||||
46,47 Scratch space (RWTS)
|
||||
48,49 IOB address (RWTS)
|
||||
4A,4B INTEGER BASIC LOMEM address (DOS)
|
||||
Format diskette workspace (RWTS)
|
||||
4C,4D INTEGER BASIC HIMEM address (DOS)
|
||||
67,68 APPLESOFT BASIC PROGRAM START (DOS)
|
||||
69,6A APPLESOFT BASIC VARIABLES START (DOS)
|
||||
6F,70 APPLESOFT BASIC STRING START (DOS)
|
||||
73,74 APPLESOFT BASIC HIMEM address (DOS)
|
||||
76 APPLESOFT BASIC line number high (DOS)
|
||||
AF,B0 APPLESOFT BASIC PROGRAM END (DOS)
|
||||
CA,CB INTEGER BASIC PROGRAM START (DOS)
|
||||
CC,CD INTEGER BASIC VARIABLES END (DOS)
|
||||
D6 APPLESOFT BASIC PROGRAM protection flag (DOS)
|
||||
D8,D9 INTEGER BASIC line number (DOS)
|
||||
APPLESOFT BASIC ONERR (DOS)
|
||||
.br
|
||||
\x00
|
115
D1S2/TABLE.OF.CONTEN#064000.txt
Normal file
115
D1S2/TABLE.OF.CONTEN#064000.txt
Normal file
|
@ -0,0 +1,115 @@
|
|||
.na
|
||||
.NF
|
||||
.ce
|
||||
TABLE OF CONTENTS
|
||||
.SP3
|
||||
CHAPTER 1
|
||||
.SP1
|
||||
.UL
|
||||
INTRODUCTION
|
||||
.SP3
|
||||
CHAPTER 2
|
||||
.SP1
|
||||
.UL
|
||||
THE EVOLUTION OF DOS
|
||||
.SP1
|
||||
DOS 3
|
||||
DOS 3.1
|
||||
DOS 3.2
|
||||
DOS 3.2.1
|
||||
DOS 3.3
|
||||
.SP3
|
||||
CHAPTER 3
|
||||
.SP1
|
||||
.UL
|
||||
THE DISK II HARDWARE AND TRACK FORMATTING
|
||||
.SP1
|
||||
DISK ORGANIZATION
|
||||
TRACK FORMATTING
|
||||
DATA FIELD ENCODING
|
||||
SECTOR INTERLEAVING
|
||||
.SP3
|
||||
CHAPTER 4
|
||||
.SP1
|
||||
.UL
|
||||
DISKETTE DATA FORMATS
|
||||
.SP1
|
||||
DISKETTE SPACE ALLOCATION
|
||||
THE VTOC
|
||||
THE CATALOG
|
||||
THE TRACK/SECTOR LIST
|
||||
TEXT FILES
|
||||
BINARY FILES
|
||||
APPLESOFT AND INTEGER FILES
|
||||
OTHER FILE TYPES (S,R,A,B)
|
||||
EMERGENCY REPAIRS
|
||||
.SP3
|
||||
CHAPTER 5
|
||||
.SP1
|
||||
.UL
|
||||
THE STRUCTURE OF DOS
|
||||
.SP1
|
||||
DOS MEMORY USE
|
||||
THE DOS VECTORS IN PAGE 3
|
||||
WHAT HAPPENS DURING BOOTING
|
||||
.SP3
|
||||
CHAPTER 6
|
||||
.SP1
|
||||
.UL
|
||||
USING DOS FROM ASSEMBLY LANGUAGE
|
||||
.SP1
|
||||
DIRECT USE OF DISK DRIVE
|
||||
CALLING READ/WRITE TRACK/SECTOR (RWTS)
|
||||
RWTS IOB BY CALL TYPE
|
||||
CALLING THE DOS FILE MANAGER
|
||||
FILE MANAGER PARAMETER LIST BY CALL TYPE
|
||||
THE FILE MANAGER WORKAREA
|
||||
COMMON ALGORITHMS
|
||||
.SP3
|
||||
CHAPTER 7
|
||||
.SP1
|
||||
.UL
|
||||
CUSTOMIZING DOS
|
||||
.SP1
|
||||
SLAVE VS MASTER PATCHING
|
||||
AVOIDING RELOAD OF LANGUAGE CARD
|
||||
INSERTING A PROGRAM BETWEEN DOS AND ITS BUFFERS
|
||||
BRUN OR EXEC A HELLO FILE
|
||||
REMOVING THE PAUSE DURING A LONG CATALOG
|
||||
.SP3
|
||||
CHAPTER 8
|
||||
.SP1
|
||||
.UL
|
||||
DOS PROGRAM LOGIC
|
||||
.SP1
|
||||
DISK II CONTROLLER CARD ROM - BOOT 0
|
||||
FIRST RAM BOOT STRAP LOADER - BOOT 1
|
||||
DOS 3.3 MAIN ROUTINES
|
||||
DOS FILE MANAGER
|
||||
READ/WRITE TRACK/SECTOR
|
||||
.BP
|
||||
APPENDIX A
|
||||
.SP1
|
||||
.UL
|
||||
EXAMPLE PROGRAMS
|
||||
.SP1
|
||||
HOW TO USE THE PROGRAMS
|
||||
DUMP - TRACK DUMP PROGRAM
|
||||
ZAP - DISK UPDATE PROGRAM
|
||||
FTS - FIND TRACK/SECTOR LISTS PROGRAM
|
||||
COPY - BINARY TO TEXT FILE CONVERT PROGRAM
|
||||
INIT - REFORMAT A SINGLE DISK TRACK
|
||||
.SP3
|
||||
APPENDIX B
|
||||
.SP1
|
||||
.UL
|
||||
DISK PROTECTION SCHEMES
|
||||
.SP3
|
||||
APPENDIX C
|
||||
.SP1
|
||||
.UL
|
||||
GLOSSARY
|
||||
.SP3
|
||||
INDEX
|
||||
.BR
|
||||
\x00
|
575
D2S1/APPENDIX.A#064000.txt
Normal file
575
D2S1/APPENDIX.A#064000.txt
Normal file
|
@ -0,0 +1,575 @@
|
|||
.ec^
|
||||
.m11
|
||||
.m22
|
||||
.m48
|
||||
.na
|
||||
.ll60
|
||||
.fo ''-%-
|
||||
.pn 5
|
||||
.pi 0
|
||||
.br
|
||||
.np
|
||||
.ce
|
||||
APPENDIX A - EXAMPLE PROGRAMS
|
||||
.sp1
|
||||
.PP
|
||||
This section is intended to supply
|
||||
the reader with utility programs
|
||||
which can be used to examine and
|
||||
repair diskettes. These programs are
|
||||
provided in their source form to
|
||||
serve as examples of the programming
|
||||
necessary to interface practical
|
||||
programs to DOS. The reader who
|
||||
does not know assembly language may
|
||||
also benefit from these programs by
|
||||
entering them from the monitor in
|
||||
their binary form and saving them to
|
||||
disk for later use. It should be
|
||||
pointed out that the use of 16 sector
|
||||
diskettes is assumed, although most of
|
||||
the programs can be easily modified
|
||||
to work under any version of DOS.
|
||||
It is recommended that, until the
|
||||
reader is completely familiar with
|
||||
the operation of these programs, he
|
||||
would be well advised to use them
|
||||
only on an "expendable" diskette.
|
||||
None of the programs can physically
|
||||
damage a diskette, but they can, if
|
||||
used improperly, destroy the data on
|
||||
a diskette, requiring it to be
|
||||
re-INITialized.
|
||||
.sp1
|
||||
Five programs are provided:
|
||||
.sp1
|
||||
.NF
|
||||
DUMP TRACK DUMP UTILITY
|
||||
.pi8
|
||||
.in8
|
||||
.pp
|
||||
This is an example of how to directly
|
||||
access the disk drive through its I/O
|
||||
select addresses. DUMP may be used
|
||||
to dump any given track in its raw,
|
||||
prenibbilized form, to memory for
|
||||
examination. This can be useful both
|
||||
to understand how disks are formatted
|
||||
and in diagnosing clobbered
|
||||
diskettes.
|
||||
.sp1
|
||||
.in0
|
||||
.nf
|
||||
ZAP DISK UPDATE UTILITY
|
||||
.pi8
|
||||
.in8
|
||||
.pp
|
||||
This program is the backbone of any
|
||||
attempt to patch a diskette directory
|
||||
back together. It is also useful in
|
||||
examining the structure of files
|
||||
stored on disk and in applying
|
||||
patches to files or DOS directly.
|
||||
ZAP allows its user to read, and
|
||||
optionally write, any sector on a
|
||||
diskette. As such, it serves as a
|
||||
good example of a program which calls
|
||||
Read/Write Track/Sector (RWTS).
|
||||
.sp1
|
||||
.in0
|
||||
.nf
|
||||
INIT REFORMAT A SINGLE TRACK
|
||||
.pi8
|
||||
.in8
|
||||
.pp
|
||||
This program will initialize a single
|
||||
track on a diskette. Any volume
|
||||
number ($00-$FF) may be specified.
|
||||
INIT is useful in restoring a track
|
||||
whose sectoring has been damaged
|
||||
without reinitializing the entire
|
||||
diskette. DOS 3.3 and 48K is assumed.
|
||||
.bp
|
||||
.in0
|
||||
.nf
|
||||
FTS FIND T/S LISTS UTILITY
|
||||
.pi8
|
||||
.in8
|
||||
.pp
|
||||
FTS may be used when the directory
|
||||
for a diskette has been destroyed.
|
||||
It searches every sector on a
|
||||
diskette for what appear to be
|
||||
Track/Sector Lists, printing the
|
||||
track and sector location of each it
|
||||
finds. Knowing the locations of the
|
||||
T/S Lists can help the user patch
|
||||
together a new catalog using ZAP.
|
||||
.sp1
|
||||
.in0
|
||||
.nf
|
||||
COPY CONVERT FILES
|
||||
.pi8
|
||||
.in8
|
||||
.pp
|
||||
COPY is provided as an example of
|
||||
direct use of the DOS File Manager
|
||||
package from assembly language. The
|
||||
program will read an input B-type
|
||||
file and copy its contents to an
|
||||
output T-type file. Although it
|
||||
could be used, for example,
|
||||
to convert files used
|
||||
by the Programma
|
||||
PIE editor for use by the
|
||||
Apple Toolkit assembler,
|
||||
it is not included as a utility
|
||||
program but rather as an example of
|
||||
the programming necessary to access
|
||||
the File Manager.
|
||||
.sp2
|
||||
.pi0
|
||||
.in0
|
||||
STORING THE PROGRAMS ON DISKETTE
|
||||
.pp
|
||||
The enterprising programmer may wish
|
||||
to type the source code for each
|
||||
program into an assembler and
|
||||
assemble the programs onto disk. The
|
||||
Apple Toolkit assembler was used to
|
||||
produce the listings presented here,
|
||||
and interested programmers should
|
||||
consult the documentation for that
|
||||
assembler for more information on the
|
||||
pseudo-opcodes used. For the
|
||||
non-assembly language programmer, the
|
||||
binary object code of each program
|
||||
may be entered from the monitor using
|
||||
the following procedure.
|
||||
.pp
|
||||
The assembly language listings
|
||||
consist of columns of information as
|
||||
follows:
|
||||
.sp1
|
||||
The address of some object
|
||||
code
|
||||
The object code which should
|
||||
be stored there
|
||||
The statement number
|
||||
The statement itself
|
||||
.sp1
|
||||
For example...
|
||||
.sp1
|
||||
.NF
|
||||
0800:20 DC 03 112 COPY JSR LOCFPL FIND PARMLIST
|
||||
.SP1
|
||||
.FI
|
||||
indicates that the binary code
|
||||
"20DC03" should be stored at 0800 and
|
||||
that this is statement 112. To enter
|
||||
a program in the monitor, the reader
|
||||
must type in each address and its
|
||||
corresponding object code. The
|
||||
following is an example of how to
|
||||
enter the DUMP program:
|
||||
.BP
|
||||
.nf
|
||||
CALL -151 (Enter the monitor from BASIC)
|
||||
0800:20 E3 03
|
||||
0803:84 00
|
||||
0805:85 01
|
||||
0807:A5 02
|
||||
.SP1
|
||||
...etc...
|
||||
.sp1
|
||||
0879:85 3F
|
||||
087B:4C B3 FD
|
||||
BSAVE DUMP,A$800,L$7E (Save program to disk)
|
||||
.pp
|
||||
Note that if a line (such as line 4
|
||||
in DUMP) has no object bytes
|
||||
associated with it, it may be
|
||||
ignored.
|
||||
When the program is to be run...
|
||||
.sp1
|
||||
.nf
|
||||
BLOAD DUMP (Load program)
|
||||
CALL -151 (Get into monitor)
|
||||
02:11 N 800G (Store track to dump, run program)
|
||||
.pp
|
||||
The BSAVE commands which must be used
|
||||
with the other programs are:
|
||||
.sp1
|
||||
BSAVE ZAP,A$900,L$6C
|
||||
.BR
|
||||
BSAVE INIT,A$800,L$89
|
||||
.BR
|
||||
BSAVE FTS,A$900,L$DC
|
||||
.BR
|
||||
BSAVE COPY,A$800,L$1EC
|
||||
.bp
|
||||
DUMP -- TRACK DUMP UTILITY
|
||||
.sp1
|
||||
.pp
|
||||
The DUMP program will dump any track
|
||||
on a diskette in its raw,
|
||||
pre-nibbilized format, allowing the
|
||||
user to examine the sector address
|
||||
and data fields and the formatting of
|
||||
the track. This allows the curious
|
||||
reader to examine his own diskettes
|
||||
to better understand the concepts
|
||||
presented in the preceeding chapters.
|
||||
DUMP may also be used to examine
|
||||
most protected disks to see how they
|
||||
differ from normal ones and to
|
||||
diagnose diskettes with clobbered
|
||||
sector address or data fields with
|
||||
the intention of recovering from disk
|
||||
I/O errors. The DUMP program serves
|
||||
as an example of direct use of the
|
||||
DISK II hardware from assembly
|
||||
language, with little or no use of
|
||||
DOS.
|
||||
.pp
|
||||
To use DUMP, first store the number
|
||||
of the track you wish dumped at
|
||||
location $02, then begin execution at
|
||||
$800. DUMP will return to the
|
||||
monitor after displaying the first
|
||||
part of the track in hexadecimal on
|
||||
the screen. The entire track image
|
||||
is stored, starting at $1000.
|
||||
For example:
|
||||
.sp1
|
||||
.nf
|
||||
CALL -151 (Get into the monitor from BASIC)
|
||||
BLOAD DUMP (Load the DUMP program)
|
||||
...Now insert the diskette to be dumped...
|
||||
02:11 N 800G (Store a 11 (track 17, the catalog
|
||||
track) in $02, N terminates the store
|
||||
command, go to location $800)
|
||||
.sp1
|
||||
The output might look like this...
|
||||
.sp1
|
||||
1000- D5 AA 96 AA AB AA BB AB (Start of sector address)
|
||||
1008- AA AB BA DE AA E8 C0 FF
|
||||
1010- 9E FF FF FF FF FF D5 AA (Start of sector data)
|
||||
1018- AD AE B2 9D AC AE 96 96 (Sector data)
|
||||
...etc...
|
||||
.pp
|
||||
Quite often, a sector with an I/O
|
||||
error will have only one bit which is
|
||||
in error, either in the address or
|
||||
data header or in the actual data
|
||||
itself. A particularly patient
|
||||
programmer can, using DUMP and
|
||||
perhaps a half hour of hand
|
||||
"nibbilizing" determine the location
|
||||
of the error and record the data on
|
||||
paper for later entry via ZAP. A
|
||||
thorough understanding of Chapter 3
|
||||
is necessary to accomplish this feat.
|
||||
.bp
|
||||
ZAP -- DISK UPDATE UTILITY
|
||||
.sp1
|
||||
.pp
|
||||
The next step up the ladder from DUMP
|
||||
is to access data on the diskette at
|
||||
the sector level. The ZAP program
|
||||
allows its user to specify a track
|
||||
and sector to be read into memory.
|
||||
The programmer can then make changes
|
||||
in the image of the sector in memory
|
||||
and subsequently use ZAP to write the
|
||||
modified image back over the sector
|
||||
on disk. ZAP is particularly useful
|
||||
when it is necessary to patch up a
|
||||
damaged directory. Its use in this
|
||||
regard will be covered in more detail
|
||||
when FTS is explained.
|
||||
.pp
|
||||
To use ZAP, store the number of the
|
||||
track and sector you wish to access
|
||||
in $02 and $03 respectively. Tracks
|
||||
may range from $00 to $22 and sectors
|
||||
from $00 to $0F. For example,
|
||||
the Volume Table of
|
||||
Contents (VTOC) for the diskette may
|
||||
be examined by entering $11 for the
|
||||
track and $00 for the sector. $04
|
||||
should be initialized with either a
|
||||
$01 to indicate that the sector is to
|
||||
be read into memory, or $02 to ask
|
||||
that memory be written out to the
|
||||
sector. Other values for location
|
||||
$04 can produce damaging results
|
||||
($04 in location $04 will INIT your
|
||||
diskette!). When these three memory
|
||||
locations have been set up, begin
|
||||
execution at $900. ZAP will read or
|
||||
write the sector into or from the 256
|
||||
bytes starting at $800. For example:
|
||||
.sp1
|
||||
.nf
|
||||
CALL -151 (Get into the monitor from BASIC)
|
||||
BLOAD ZAP (Load the ZAP program)
|
||||
...Now insert the diskette to be zapped...
|
||||
02:11 00 01 N 900G (Store a 11 (track 17, the catalog
|
||||
track) in $02, a 00 (sector 0) at $03,
|
||||
and a 01 (read) at $04. N ends the
|
||||
store command and 900G runs ZAP.)
|
||||
.sp1
|
||||
The output might look like this...
|
||||
.sp1
|
||||
0800- 04 11 0F 03 00 00 01 00 (Start of VTOC)
|
||||
0808- 00 00 00 00 00 00 00 00
|
||||
0810- 00 00 00 00 00 00 00 00
|
||||
0818- 00 00 00 00 00 00 00 00
|
||||
...etc...
|
||||
.pp
|
||||
In the above example, if the byte at
|
||||
offset 3 (the version of DOS which
|
||||
INITed this diskette) is to be
|
||||
changed, the following would be
|
||||
entered...
|
||||
.sp1
|
||||
.nf
|
||||
803:02 (Change 03 to 02)
|
||||
04:02 N 900G (Change ZAP to write mode and do it)
|
||||
.pp
|
||||
Note that ZAP will remember the
|
||||
previous
|
||||
values in $02, $03, and $04.
|
||||
.bp
|
||||
.pp
|
||||
If something is wrong with the sector
|
||||
to be read (an I/O error, perhaps),
|
||||
ZAP will print an error message of
|
||||
the form:
|
||||
.sp1
|
||||
RC=10
|
||||
.sp1
|
||||
A return code of 10, in this case,
|
||||
means that the diskette was write
|
||||
protected and a write operation was
|
||||
attempted. Other error codes are 20
|
||||
- volume mismatch, 40 - drive error,
|
||||
and 80 - read error. Refer to the
|
||||
documentation on RWTS given in
|
||||
Chapter 6 for more information on
|
||||
these errors.
|
||||
.bp
|
||||
INIT -- REFORMAT A SINGLE TRACK
|
||||
.sp1
|
||||
.pp
|
||||
Occasionally the sectoring information
|
||||
on a diskette can become damaged so
|
||||
that one or more sectors can no
|
||||
longer be found by DOS. To correct
|
||||
this problem requires that the sector
|
||||
address and data fields be
|
||||
re-formatted for the entire track
|
||||
thus affected. INIT can be used to
|
||||
selectively reformat a single track,
|
||||
thus avoiding a total re-INIT of the
|
||||
diskette. Before using INIT, the
|
||||
user should first attempt to write on
|
||||
the suspect sector (using ZAP). If
|
||||
RWTS refuses to write to the sector
|
||||
(RC=40),
|
||||
then INIT must be run on the entire
|
||||
track. To avoid losing data, all
|
||||
other sectors on the track should be
|
||||
read and copied to another diskette
|
||||
prior to reformatting. After INIT is
|
||||
run they can be copied back to the
|
||||
repaired diskette and data can be
|
||||
written to the previously damaged
|
||||
sector.
|
||||
.pp
|
||||
To run INIT, first store the number
|
||||
of the track you wish reformatted at
|
||||
location $02, the volume number of
|
||||
the disk at location $03, and then
|
||||
begin execution at $800. INIT will
|
||||
return to the monitor upon
|
||||
completion. If the track can not be
|
||||
formatted for some reason (eg.
|
||||
physical damage or problems with the
|
||||
disk drive itself) a return code is
|
||||
printed. For example:
|
||||
.sp1
|
||||
.nf
|
||||
CALL -151 (Get into the monitor from BASIC)
|
||||
BLOAD INIT (Load the INIT program)
|
||||
...Now insert the disk to be INIT-ed...
|
||||
02:11 FE N 800G (Store a 11 (track 17, the catalog
|
||||
track) in $02, a volume number of
|
||||
$FE (254) in $03, N terminates the
|
||||
store command, go to location $800)
|
||||
.sp1
|
||||
.fi
|
||||
WARNING: DOS 3.3 must be loaded in
|
||||
the machine before running INIT and a
|
||||
48K Apple is assumed. INIT will not work with other
|
||||
versions of DOS or other memory
|
||||
sizes.
|
||||
.bp
|
||||
FTS -- FIND T/S LISTS UTILITY
|
||||
.sp1
|
||||
.pp
|
||||
From time to time one of your
|
||||
diskettes will develop an I/O error
|
||||
smack in the middle of the catalog
|
||||
track. When this occurs, any attempt
|
||||
to use the diskette will result in an
|
||||
I/O ERROR message from DOS.
|
||||
Generally, when this happens, the
|
||||
data stored in the files on the
|
||||
diskette is still intact; only the
|
||||
pointers to the files are gone. If
|
||||
the data absolutely must be
|
||||
recovered, a knowledgeable Apple user
|
||||
can reconstruct the catalog from
|
||||
scratch. Doing this involves first
|
||||
finding the T/S Lists for each file,
|
||||
and then using ZAP to patch a catalog
|
||||
entry into track 16 for each file
|
||||
which was found. FTS is a utility
|
||||
which will scan a diskette for T/S
|
||||
Lists. Although it may flag some
|
||||
sectors which are not T/S Lists as
|
||||
being such, it will never miss a
|
||||
valid T/S List. Therefore, after
|
||||
running FTS the programmer must use
|
||||
ZAP to examine each track/sector
|
||||
printed by FTS to see if it is really
|
||||
a T/S List. Additionally, FTS will
|
||||
find every T/S List image on the
|
||||
diskette, even some which were for
|
||||
files which have since been deleted.
|
||||
Since it is difficult to determine
|
||||
which files are valid and which are
|
||||
old deleted files, it is usually
|
||||
necessary to restore all the files
|
||||
and copy them to another diskette,
|
||||
and later delete the duplicate or
|
||||
unwanted ones.
|
||||
.pp
|
||||
To run FTS, simply load the program
|
||||
and start execution at $900. FTS
|
||||
will print the track and sector
|
||||
number of each sector it finds which
|
||||
bears a resemblance to a T/S List.
|
||||
For example:
|
||||
.sp1
|
||||
.nf
|
||||
CALL -151 (Get into the monitor from BASIC)
|
||||
BLOAD FTS (Load the FTS program)
|
||||
...Now insert the disk to be scanned...
|
||||
900G (Run the FTS program on this diskette)
|
||||
.sp1
|
||||
The output might look like this...
|
||||
.sp1
|
||||
T=12 S=0F
|
||||
T=13 S=0F
|
||||
T=14 S=0D
|
||||
T=14 S=0F
|
||||
.bp
|
||||
.pp
|
||||
Here, only four possible files were
|
||||
found. ZAP should now be used to
|
||||
read track $12, sector $0F. At +$0C
|
||||
is the track and sector of the first
|
||||
sector in the file. This sector can
|
||||
be read and examined to try to
|
||||
identify the file and its type.
|
||||
Usually a BASIC program can be
|
||||
identified, even though it is stored
|
||||
in tokenized form, from the text
|
||||
strings contained in the PRINT
|
||||
statements. An ASCII conversion
|
||||
chart (see page 8 in the APPLE II
|
||||
REFERENCE MANUAL) can be used to
|
||||
decode these character strings.
|
||||
Straight T-type files will also
|
||||
contain ASCII text, with each line
|
||||
separated from the others with $8D
|
||||
(carriage returns). B-type files are
|
||||
the hardest to identify, unless the
|
||||
address and length stored in the
|
||||
first 4 bytes are recognizable. If
|
||||
you cannot identify the file, assume
|
||||
it is APPLESOFT BASIC. If this
|
||||
assumption turns out to be incorrect,
|
||||
you can always go back and ZAP the
|
||||
file type in the CATALOG to try
|
||||
something else. Given below is an
|
||||
example ZAP to the CATALOG to create
|
||||
an entry for the file whose T/S List
|
||||
is at T=12 S=0F.
|
||||
.SP1
|
||||
.NF
|
||||
CALL -151
|
||||
BLOAD ZAP
|
||||
...insert disk to be ZAPped...
|
||||
800:00 N 801<800.8FEM (Zero sector area of memory)
|
||||
80B:12 0F 02 (Track 12, Sector 0F, Type-A)
|
||||
:C1 A0 A0 A0 A0 A0 A0 (Name is "A")
|
||||
:A0 A0 A0 A0 A0 A0 A0 (fill name out with 29 blanks)
|
||||
:A0 A0 A0 A0 A0 A0 A0
|
||||
:A0 A0 A0 A0 A0 A0 A0
|
||||
:A0 A0
|
||||
02:11 0F 02 N 900G (Write new sector image out as
|
||||
first (and only) catalog sector)
|
||||
.pp
|
||||
The file should immediately be copied
|
||||
to another diskette and then the
|
||||
process repeated for each T/S List
|
||||
found by FTS until all of the files
|
||||
have been recovered. As each file is
|
||||
recovered, it may be RENAMEd to its
|
||||
previous name. Once all the files
|
||||
have been copied to another disk,
|
||||
and successfully tested, the
|
||||
damaged disk may be re-INITialized.
|
||||
.bp
|
||||
COPY -- CONVERT FILES
|
||||
.sp1
|
||||
.pp
|
||||
The COPY program demonstrates the use
|
||||
of the DOS File Manager subroutine
|
||||
package from assembly language. COPY
|
||||
will read as input a Binary type
|
||||
file, stripping off the address and
|
||||
length information, and write the
|
||||
data out as a newly created Text type
|
||||
file. The name of the input file is
|
||||
assumed to be "INPUT", although this
|
||||
could just as easily have been
|
||||
inputted from the keyboard, and the
|
||||
name of the output file is "OUTPUT".
|
||||
COPY is a single drive operation,
|
||||
using the last drive which was
|
||||
referenced.
|
||||
.pp
|
||||
To run COPY, load it and begin
|
||||
execution at $800:
|
||||
.sp1
|
||||
.nf
|
||||
CALL -151 (Get into the monitor from BASIC)
|
||||
BLOAD COPY (Load the COPY program)
|
||||
...Now insert the disk containing INPUT...
|
||||
900G (Run the COPY program)
|
||||
.pp
|
||||
When COPY finishes, it will return to
|
||||
BASIC. If any errors occur, the
|
||||
return code passed back from the File
|
||||
Manager will be printed. Consult the
|
||||
documentation on the File Manager
|
||||
parameter list in Chapter 6
|
||||
for a list of these return codes.
|
||||
.br
|
||||
.nx appendix b
|
||||
\x00
|
263
D2S1/APPENDIX.B#064000.txt
Normal file
263
D2S1/APPENDIX.B#064000.txt
Normal file
|
@ -0,0 +1,263 @@
|
|||
.bp
|
||||
.np
|
||||
.ce
|
||||
APPENDIX B - DISK PROTECTION SCHEMES
|
||||
.sp1
|
||||
.PP
|
||||
As the quantity and quality
|
||||
of Apple II software
|
||||
has increased, so has the incidence
|
||||
of illegal duplication of copyrighted
|
||||
software. To combat this, software
|
||||
vendors have introduced methods for
|
||||
protecting their software.
|
||||
Since most protection
|
||||
schemes involve a modified or custom
|
||||
Disk Operating System, it seems
|
||||
appropriate to discuss disk
|
||||
protection in general.
|
||||
.pp
|
||||
Typically, a protection scheme's
|
||||
purpose is to stop unauthorized
|
||||
duplication of the contents of the
|
||||
diskette, although it may also
|
||||
include, or be limited to, preventing
|
||||
the listing of the software (if it is
|
||||
in BASIC). This has been attempted
|
||||
in a variety of ways, all of which
|
||||
necessitate reading and writing
|
||||
non-standard formats on the disk. If
|
||||
the reader is unclear about how a
|
||||
normal diskette is formatted, he
|
||||
should refer to Chapter 3 for more
|
||||
information.
|
||||
.pp
|
||||
Early protection methods were
|
||||
primitive in comparison to what is
|
||||
being done now. Just as the methods
|
||||
of protection have improved, so have
|
||||
the techniques people have used to
|
||||
break them. The cycle seems endless.
|
||||
As new and more sophisticated schemes
|
||||
are developed, they are soon broken,
|
||||
prompting the software vendor to try
|
||||
to create even more sophisticated
|
||||
systems.
|
||||
.pp
|
||||
It seems reasonable at this time to
|
||||
say that it is impossible to protect
|
||||
a disk in such a way that it can't be
|
||||
broken. This is, in large part, due
|
||||
to the fact that the diskette must be
|
||||
"bootable"; i.e. that it must contain
|
||||
at least one sector (Track 0, Sector
|
||||
0) which can be read by the program
|
||||
in the PROM
|
||||
on the disk controller card. This
|
||||
means that it is possible to trace
|
||||
the boot process by disassembling the
|
||||
normal sector or sectors that must be
|
||||
on the disk. It turns out that it is
|
||||
even possible to protect these
|
||||
sectors. Because of a lack of space
|
||||
on the PROM (256 bytes), the software
|
||||
doesn't fully check either the
|
||||
Address Field or the Data Field. But
|
||||
potential protection schemes
|
||||
which take advantage of this
|
||||
are limited and must
|
||||
involve only certain changes which
|
||||
will be discussed below.
|
||||
.pp
|
||||
Most protected disks use a modified
|
||||
version of Apple's DOS. This is a
|
||||
much easier task than writing one's
|
||||
own Disk Operating System and will be
|
||||
the primary area covered by this
|
||||
discussion.
|
||||
.pp
|
||||
Although there are a vast array of
|
||||
different protection schemes, they
|
||||
all consist of having some portion of
|
||||
the disk unreadable by a normal Disk
|
||||
Operating System. The two logical
|
||||
areas to alter are the Address Field
|
||||
and the Data Field. Each include a
|
||||
number of bytes which, if changed,
|
||||
will cause a sector to be unreadable.
|
||||
We will examine how that is done in
|
||||
some detail.
|
||||
.pp
|
||||
The Address Field normally starts
|
||||
with the bytes $D5/$AA/$96. If any
|
||||
one of these bytes were changed, DOS
|
||||
would not be able to locate that
|
||||
particular Address Field, causing an
|
||||
error. While all three bytes can and
|
||||
have been changed by various schemes,
|
||||
it is important to remember that they
|
||||
must be chosen in such a way as to
|
||||
guarantee their uniqueness. Apple's
|
||||
DOS does this by reserving the bytes
|
||||
$D5 and $AA; i.e. these bytes are not
|
||||
used in the storage of data. The
|
||||
sequence chosen by the would-be disk
|
||||
protector can not occur anywhere else
|
||||
on the track, other than in another
|
||||
Address Field. Next comes the
|
||||
address information itself (volume,
|
||||
track, sector, and checksum). Some
|
||||
common techniques include changing
|
||||
the order of the information,
|
||||
doubling the sector numbers, or
|
||||
altering the checksum with some
|
||||
constant. Any of the above would
|
||||
cause an I/O error in a normal DOS.
|
||||
Finally, we have the two closing
|
||||
bytes ($DE/$AA), which are similar to
|
||||
the starting bytes, but with a
|
||||
difference. Their uniqueness is not
|
||||
critical, since DOS will read
|
||||
whatever two bytes follow the
|
||||
information field, using them for
|
||||
verification, but not to locate the
|
||||
field itself.
|
||||
.pp
|
||||
The Data Field is quite similar to
|
||||
the Address Field in that its three
|
||||
parts correspond almost identically,
|
||||
as far as protection schemes are
|
||||
concerned. The Data Field starts
|
||||
with $D5/$AA/$AD, only the third byte
|
||||
being different, and all that applies
|
||||
to the Address Field applies here
|
||||
also. Switching the third bytes
|
||||
between the two fields is an example
|
||||
of a protective measure. The data
|
||||
portion consists of 342 bytes of
|
||||
data, followed by a checksum byte.
|
||||
Quite often the data is written so
|
||||
that the checksum computation will be
|
||||
non-zero, causing an error. The
|
||||
closing bytes are identical to those
|
||||
of the Address Field ($DE/$AA).
|
||||
.pp
|
||||
As mentioned earlier, the PROM on the
|
||||
disk controller skips certain parts
|
||||
of both types of fields. In
|
||||
particular, neither trailing byte
|
||||
($DE/$AA) is read or verified
|
||||
nor is the checksum tested,
|
||||
allowing these bytes to be modified
|
||||
even in track 0 sector 0.
|
||||
However, this protection is easily
|
||||
defeated by making slight
|
||||
modifications to DOS's RWTS
|
||||
routines, rendering it
|
||||
unreliable as a protective measure.
|
||||
.pp
|
||||
In the early days of disk protection,
|
||||
a single alteration was all that was
|
||||
needed to stop all but a few from
|
||||
copying the disk. Now, with more
|
||||
educated users and powerful
|
||||
utilities available, multiple schemes
|
||||
are quite commonly used. The first
|
||||
means of protection was probably that
|
||||
of hidden control characters imbedded
|
||||
in a file name. Now it is common to
|
||||
find a disk using multiple
|
||||
non-standard formats written even
|
||||
.ul
|
||||
between
|
||||
tracks.
|
||||
.pp
|
||||
A state of the art protection scheme
|
||||
consists of two elements. First, the
|
||||
data is stored on the diskette in
|
||||
some non-standard way in order to
|
||||
make copying very difficult.
|
||||
Secondly, some portion of memory is
|
||||
utilized that will be altered upon a
|
||||
RESET. (For example, the primary
|
||||
text page or certain zero page
|
||||
locations) This is to prevent the
|
||||
software from being removed from
|
||||
memory intact.
|
||||
.pp
|
||||
Recently, several "nibble" or byte
|
||||
copy programs have become available.
|
||||
Unlike traditional copy programs
|
||||
which require the data to be in a
|
||||
predefined format, these utilities
|
||||
make as few assumptions as possible
|
||||
about the data structure. Ever since
|
||||
protected disks were first
|
||||
introduced, it has been asked, "why
|
||||
can't a track be read into memory and
|
||||
then written back out to another
|
||||
diskette in exactly the same way?".
|
||||
The problem lies with the self-sync
|
||||
or auto-sync bytes. (For a full
|
||||
discussion see Chapter 3) These
|
||||
bytes contain extra zero bits that
|
||||
are lost when read into memory. In
|
||||
memory it is impossible to determine
|
||||
the difference between a hexadecimal
|
||||
$FF that was data and a hex $FF that
|
||||
was a self-sync byte. Two solutions
|
||||
are currently being implemented in
|
||||
nibble copy programs. One is to
|
||||
analyze the data on a track with the
|
||||
hope that the sync gaps can be
|
||||
located by deduction. This has a
|
||||
high probability of success if 13 or
|
||||
16 sectors are present, even if they
|
||||
have been modified, but may not be
|
||||
effective in dealing with
|
||||
non-standard sectoring where sectors
|
||||
are larger than 256 bytes. In short,
|
||||
this method is effective but by no
|
||||
means foolproof. The second method
|
||||
is simple but likewise has a
|
||||
difficulty. It simply writes every
|
||||
hex $FF found on the track as if it
|
||||
were a sync byte. This, however,
|
||||
will expand the physical space needed
|
||||
to write the track back out, since
|
||||
sync bytes require 25% more room. If
|
||||
enough hex $FF's occur in the data,
|
||||
the track will overwrite itself.
|
||||
This can happen in general if the
|
||||
drive used to write the data is
|
||||
significantly slower than normal.
|
||||
Thus, we are back to having to
|
||||
analyze the data and, in effect, make
|
||||
some assumptions. It appears that,
|
||||
apart from using some
|
||||
hardware device to help find the sync
|
||||
bytes, a software program must make
|
||||
some assumptions about how the data
|
||||
is structured on the diskette.
|
||||
.pp
|
||||
The result of the
|
||||
introduction of nibble copy programs
|
||||
has been to "force the hand" of the
|
||||
software vendors. The initial
|
||||
response was to develop new
|
||||
protection schemes that defeated the
|
||||
nibble copy programs. More recent
|
||||
protection schemes, however,
|
||||
involve hardware
|
||||
and timing dependencies which
|
||||
require current
|
||||
nibble copy programs to rely heavily
|
||||
upon the user for direction. If the
|
||||
present trend continues, it is very
|
||||
likely that protection schemes will
|
||||
evolve to a point where automated
|
||||
techniques cannot be used to defeat
|
||||
them.
|
||||
.br
|
||||
.nx appendix c.1
|
||||
\x00
|
637
D2S1/APX.C.1#064000.txt
Normal file
637
D2S1/APX.C.1#064000.txt
Normal file
|
@ -0,0 +1,637 @@
|
|||
.ec]
|
||||
.bp
|
||||
.np
|
||||
.ce
|
||||
APPENDIX C - GLOSSARY
|
||||
.sp1
|
||||
.pn5
|
||||
.IN20
|
||||
.PI-20
|
||||
.PP
|
||||
ACCESS TIME]>The time required to
|
||||
locate and read or write data on a
|
||||
direct access storage device, such as
|
||||
a diskette drive.
|
||||
.pp
|
||||
ADDRESS]>The numeric location of a
|
||||
piece of data in memory. Usually
|
||||
given as a hexadecimal number from
|
||||
$0000 to $FFFF (65535 decimal). A
|
||||
disk address is the location of a
|
||||
data sector, expressed in terms of its
|
||||
track and sector numbers.
|
||||
.pp
|
||||
ALGORITHM]>A sequence of steps which
|
||||
may be performed by a program or
|
||||
other process, which will produce a
|
||||
given result.
|
||||
.pp
|
||||
ALPHANUMERIC]>An alphabetic character
|
||||
(A-Z) or a numeric digit (0-9). The
|
||||
term used to refer to the class of all
|
||||
characters and digits.
|
||||
.pp
|
||||
ANALOG]>As opposed to digital.
|
||||
Having a value which is continuous,
|
||||
such as a voltage or electrical
|
||||
resistance.
|
||||
.pp
|
||||
AND]>The logical process of
|
||||
determining whether two bits are both
|
||||
ones. 0 AND 1 results in 0 (false),
|
||||
1 AND 1 results in 1 (true).
|
||||
.pp
|
||||
ARM]>The portion of a disk drive
|
||||
which suspends the read/write head
|
||||
over the disk's surface. The arm can
|
||||
be moved radially to allow access to
|
||||
different tracks.
|
||||
.pp
|
||||
ASCII]>American Standard Code for
|
||||
Information Interchange. A
|
||||
hexadecimal to character conversion
|
||||
code assignment, such that the 256
|
||||
possible values of a single byte may
|
||||
each represent a alphabetic, numeric,
|
||||
special, or control character. ASCII
|
||||
is used when interfacing to
|
||||
peripherals, such as keyboards,
|
||||
printers, or video text displays.
|
||||
.pp
|
||||
ASSEMBLY LANGUAGE]>Also known as
|
||||
MACHINE LANGUAGE. The native
|
||||
programming language of the
|
||||
individual computer. Assembly
|
||||
language is oriented to the machine,
|
||||
and is not humanized, as is BASIC,
|
||||
PASCAL, or FORTRAN. An assembler is
|
||||
used to convert assembly language
|
||||
statements to an executable program.
|
||||
.pp
|
||||
BACKUP]>The process of making a copy
|
||||
of a program or data against the
|
||||
possibility of its accidental loss or
|
||||
destruction.
|
||||
.pp
|
||||
BASE]>The number system in use.
|
||||
Decimal is base 10, since each digit
|
||||
represents a power of 10
|
||||
(1,10,100,...). Hexadecimal is base
|
||||
16 (1,16,256,...). Binary is base 2
|
||||
(1,2,4,8,...).
|
||||
.pp
|
||||
BINARY]>A number system based upon
|
||||
powers of 2. Only the digits 0 and 1
|
||||
are used. 101 in binary, for
|
||||
example, is 1 units digit, 0 twos,
|
||||
and 1 fours, or 5 in decimal.
|
||||
.pp
|
||||
BIT]>A single binary digit (a 1 or a
|
||||
0). A bit is the smallest unit of
|
||||
storage or information in a computer.
|
||||
.PP
|
||||
BIT CELL]>The space on a diskette,
|
||||
between two clock pulses, which can
|
||||
hold the value of a single binary 0
|
||||
or 1 (bit).
|
||||
.pp
|
||||
BIT SLIP MARKS]>The epilogue of a
|
||||
disk field. Used to double check
|
||||
that the disk head is still in read
|
||||
sync and the sector has not been
|
||||
damaged.
|
||||
.pp
|
||||
BOOT/BOOTSTRAP]>The process of
|
||||
loading a very large program into
|
||||
memory by loading successively larger
|
||||
pieces, each of which loads its
|
||||
successor. The program loads itself
|
||||
by "pulling itself up by its
|
||||
bootstraps".
|
||||
.pp
|
||||
BRK]>BREAK. An assembly langauge instruction
|
||||
which can be used to force an
|
||||
interrupt and immediate suspension of
|
||||
execution of a program.
|
||||
.pp
|
||||
BUFFER]>An area of memory used to
|
||||
temporarily hold data as it is being
|
||||
transferred to or from a peripheral,
|
||||
such as a disk drive.
|
||||
.pp
|
||||
BUG]>A programming error. Faulty
|
||||
operation of a program.
|
||||
.pp
|
||||
BYTE]>The smallest unit of
|
||||
addressable memory in a computer. A
|
||||
byte usually consists of 8 bits and
|
||||
can contain a decimal number ranging
|
||||
from 0 to 255 or a single
|
||||
alphanumeric character.
|
||||
.pp
|
||||
CARRIAGE RETURN]>A control character
|
||||
which instructs the printer to end
|
||||
one line and begin another. When
|
||||
printing a carriage return is usually
|
||||
followed by a line feed.
|
||||
.pp
|
||||
CARRY FLAG]>A 6502 processor flag
|
||||
which indicates that a previous
|
||||
addition resulted in a carry. Also
|
||||
used
|
||||
as an error indicator by many system
|
||||
programs.
|
||||
.PP
|
||||
CATALOG]>A directory of the files on
|
||||
a diskette. See DIRECTORY.
|
||||
.pp
|
||||
CHAIN]>A linked list of data
|
||||
elements. Data is chained if its
|
||||
elements need not be contiguous in
|
||||
storage and
|
||||
each element can be found from its
|
||||
predecessor via an address pointer.
|
||||
.pp
|
||||
CHECKSUM/CRC]>A method for verifying
|
||||
that data has not been damaged. When
|
||||
data is written, the sum of all its
|
||||
constituent bytes is stored with it.
|
||||
If, when the data is later read, its
|
||||
sum no longer matches the checksum,
|
||||
it has been damaged.
|
||||
.pp
|
||||
CLOBBERED]>Damaged or destroyed. A
|
||||
clobbered sector is one which has
|
||||
been overwritten such that it is
|
||||
unrecoverable.
|
||||
.pp
|
||||
CODE]>Executable instructions to the
|
||||
computer, usually in machine
|
||||
language.
|
||||
.pp
|
||||
COLDSTART]>A restart of a program
|
||||
which reinitializes all of its
|
||||
parameters, usually erasing any work
|
||||
which was in progress at the time of
|
||||
the restart. A DOS coldstart erases
|
||||
the BASIC program in memory.
|
||||
.pp
|
||||
CONTIGUOUS]>Physically next to. Two
|
||||
bytes are contiguous if they are
|
||||
adjoining each other in memory or on
|
||||
the disk.
|
||||
.pp
|
||||
CONTROL BLOCK]>A collection of data
|
||||
which is used by the operating system
|
||||
to manage resources. Examples of a
|
||||
control block used by DOS are the
|
||||
file buffers.
|
||||
.pp
|
||||
CONTROL CHARACTER]>A special ASCII
|
||||
code which is used to perform a
|
||||
unique function on a peripheral, but
|
||||
does not generate a printable
|
||||
character.
|
||||
Carriage return, line feed, form
|
||||
feed, and bell are all control
|
||||
characters.
|
||||
.pp
|
||||
CONTROLLER CARD]>A hardware circuit
|
||||
board which is plugged into an APPLE
|
||||
connector which allows communication
|
||||
with a peripheral device, such as a
|
||||
disk or printer. A controller card
|
||||
usually contains a small driver
|
||||
program in ROM.
|
||||
.PP
|
||||
CSWL]>A vector in zero-page through
|
||||
which output data is passed for
|
||||
display on the CRT or for printing.
|
||||
.pp
|
||||
CYCLE]>The smallest unit of time
|
||||
within the central processor of the
|
||||
computer. Each machine language
|
||||
instruction requires two or more
|
||||
cycles to complete. One cycle (on
|
||||
the APPLE) is one micro-second or one
|
||||
millionth of a second.
|
||||
.pp
|
||||
DATA]>Units of information.
|
||||
.pp
|
||||
DATA SECTOR BUFFER]>On the APPLE, a
|
||||
256 byte buffer used by DOS to hold
|
||||
the image of any given sector on the
|
||||
diskette. As information is read
|
||||
from the file, data is extracted from
|
||||
the data sector buffer until it is
|
||||
exhausted, at which time it is
|
||||
refilled with the next sector image.
|
||||
.pp
|
||||
DATA TYPE]>The type of information
|
||||
stored in a byte. A byte might
|
||||
contain a printable ASCII character, binary
|
||||
numeric data, or a machine language
|
||||
instruction.
|
||||
.pp
|
||||
DCT]>Device Characteristics Table.
|
||||
Used as an input parameter table to
|
||||
Read/Write Track/Sector (RWTS) to
|
||||
describe the hardware characteristics
|
||||
of the diskette drive.
|
||||
.pp
|
||||
DECIMAL]>A number system based upon
|
||||
powers of 10. Digits range from 0 to
|
||||
9.
|
||||
.pp
|
||||
DEFERRED COMMANDS]>DOS commands which
|
||||
may (or must) be invoked from within
|
||||
an executing BASIC program. OPEN,
|
||||
READ, WRITE, and CLOSE are all
|
||||
examples of deferred commands.
|
||||
.pp
|
||||
DIGITAL]>As opposed to analog.
|
||||
Discrete values as opposed to
|
||||
continuous ones. Only digital values
|
||||
may be stored in a computer. Analog
|
||||
measurements from the real world,
|
||||
such as a voltage or the level of
|
||||
light outside, must be converted into
|
||||
a numerical value which, of
|
||||
necessity, must be "rounded off" to a
|
||||
discrete value.
|
||||
.pp
|
||||
DIRECT ACCESS]>Peripheral storage
|
||||
allowing rapid access of any piece of
|
||||
data, regardless of its placement on
|
||||
the medium. Magnetic tape is
|
||||
generally not considered direct
|
||||
access, since the entire tape must be
|
||||
read to locate the last byte. A
|
||||
diskette is direct access, since the
|
||||
arm may be rapidly moved to any
|
||||
track and sector.
|
||||
.pp
|
||||
DIRECTORY]>A catalog of all files
|
||||
stored on a diskette. The directory
|
||||
must contain each file's name and its
|
||||
location on the disk as well as other
|
||||
information regarding the type of
|
||||
data stored there.
|
||||
.pp
|
||||
DISK INITIALIZATION]>The process
|
||||
which places track formatting
|
||||
information, including sectors and
|
||||
gaps, on a blank diskette.
|
||||
During disk initialization, DOS also
|
||||
places a VTOC and directory on the
|
||||
newly formatted disk, as well as
|
||||
saving the HELLO program.
|
||||
.pp
|
||||
DISPLACEMENT]>The distance from the
|
||||
beginning of a block of data to a
|
||||
particular byte or field.
|
||||
Displacements are usually given
|
||||
beginning with 0, for the first byte,
|
||||
1 for the second, etc. Also known as
|
||||
an offset.
|
||||
.pp
|
||||
DRIVER]>A program which provides an
|
||||
input stream to another program or an
|
||||
output device. A printer driver
|
||||
accepts input from a user program in
|
||||
the form of lines to be printed, and
|
||||
sends them to the printer.
|
||||
.pp
|
||||
DUMP]>An unformatted or partially
|
||||
formatted listing of the contents of
|
||||
memory or a diskette in hexadecimal.
|
||||
Used for diagnostic purposes.
|
||||
.pp
|
||||
ENCODE]>To translate data from one
|
||||
form to another for any of a number
|
||||
of reasons. In DOS 3.3,
|
||||
Data is encoded from 8
|
||||
bit bytes to 6 bit bytes for storage
|
||||
on a DISK II.
|
||||
.pp
|
||||
ENTRY POINT (EPA)]>The entry point
|
||||
address is the location within a
|
||||
program where execution is to start.
|
||||
This is not necessarily the same as
|
||||
the load point (or lowest memory
|
||||
address in the program).
|
||||
.pp
|
||||
EOF]>End Of File. This mark signals
|
||||
the end of a data file. $00 for
|
||||
APPLE DOS text files.
|
||||
.pp
|
||||
EPILOGUE]>The last three bytes of a
|
||||
field on a track. These unique bytes
|
||||
are used to insure the integrity of
|
||||
the data which preceeds them.
|
||||
.pp
|
||||
EXCLUSIVE OR]>A logical operation
|
||||
which compares two bits to determine
|
||||
if they are different. 1 EOR 0
|
||||
results in 1. 1 EOR 1 results in 0.
|
||||
.pp
|
||||
FIELD]>A group of contiguous bytes
|
||||
forming a single piece of data, such
|
||||
as a person's name, his age, or his
|
||||
social security number. In disk
|
||||
formatting, a group of data bytes
|
||||
surrounded by gaps.
|
||||
.pp
|
||||
FILE]>A named collection of data on a
|
||||
diskette or other mass storage
|
||||
medium. Files can contain data or
|
||||
programs.
|
||||
.pp
|
||||
FILE BUFFERS]>In APPLE DOS, a
|
||||
collection of buffers used to manage
|
||||
one open file. Included are a data
|
||||
sector buffer, a Track/Sector List
|
||||
sector buffer, a file manager
|
||||
workarea buffer, the name of the
|
||||
file, and pointers. The DOS command,
|
||||
MAXFILES 3, causes 3 of these file
|
||||
buffers to be allocated.
|
||||
.pp
|
||||
FILE DESCRIPTOR]>A single entry in a
|
||||
diskette directory which describes
|
||||
one file. Included are the name of
|
||||
the file, its data type, its length,
|
||||
and its location on the diskette.
|
||||
.pp
|
||||
FILE MANAGER]>That portion of DOS
|
||||
which manages files. The file
|
||||
manager handles such general
|
||||
operations as OPEN, CLOSE, READ,
|
||||
WRITE, POSITION, RENAME, DELETE, etc.
|
||||
.pp
|
||||
FILE TYPE]>The type of data held by a
|
||||
file. Valid DOS file types are
|
||||
Binary, Applesoft, Integer-BASIC,
|
||||
Text, Relocatable, S, A, and B.
|
||||
.pp
|
||||
FIRMWARE]>A middle ground between
|
||||
hardware and software. Usually used
|
||||
to describe micro-code or programs
|
||||
which have been stored in read-only
|
||||
memory.
|
||||
.pp
|
||||
GAPS]>The spaces between fields of
|
||||
data on a diskette. Gaps on an APPLE
|
||||
diskette contain self-sync bytes.
|
||||
.pp
|
||||
HARD ERROR]>An unrecoverable
|
||||
Input/Output error. The data stored
|
||||
in the disk sector can never be
|
||||
successfully read again.
|
||||
.pp
|
||||
HARDWARE]>Physical computer
|
||||
equipment, as opposed to programs
|
||||
which run on the equipment.
|
||||
A disk drive is an example of a
|
||||
hardware component.
|
||||
.pp
|
||||
HEAD]>The read/write head on a
|
||||
diskette drive. A magnetic pickup,
|
||||
similar in nature to the head on a
|
||||
stereo tapedeck, which rests on the
|
||||
spinning surface of the diskette.
|
||||
.pp
|
||||
HEXADECIMAL/HEX]>A numeric system
|
||||
based on powers of 16. Valid hex
|
||||
digits range from 0 to 9 and A to F,
|
||||
where A is 10, B is 11, ... , and F
|
||||
is 15. B30 is 11 256's, 3 16's, and
|
||||
0 1's, or 2864 in decimal.
|
||||
Two hexadecimal digits can be used to
|
||||
represent the contents of one byte.
|
||||
Hexadecimal is used with computers
|
||||
because it easily converts with
|
||||
binary.
|
||||
.pp
|
||||
HIGH MEMORY]>Those memory locations
|
||||
which have high address values.
|
||||
$FFFF is the highest memory location.
|
||||
Also called the "top" of memory.
|
||||
.pp
|
||||
HIMEM]>APPLE's zero-page address
|
||||
which identifies the first byte past
|
||||
the available memory which can be
|
||||
used to store BASIC programs and
|
||||
their variables.
|
||||
.pp
|
||||
IMMEDIATE COMMAND]>A DOS command
|
||||
which may be entered at any time,
|
||||
especially when DOS is waiting for a
|
||||
command from the keyboard. Deferred
|
||||
commands are the opposite of
|
||||
immediate commands.
|
||||
.pp
|
||||
INDEX]>A displacement into a table or
|
||||
block of storage.
|
||||
.pp
|
||||
INSTRUCTION]>A single step to be
|
||||
performed in an assembly language or
|
||||
machine language program.
|
||||
Instructions perform such operations
|
||||
as addition, subtraction, store, or
|
||||
load.
|
||||
.pp
|
||||
INTEGER]>As opposed to floating
|
||||
point. A "whole" number with no
|
||||
fraction associated with it.
|
||||
.pp
|
||||
INTERCEPT]>A program which logically
|
||||
places itself in the execution path
|
||||
of another program, or pair of
|
||||
programs. A video intercept
|
||||
is used to re-direct program output
|
||||
from the screen to a printer,
|
||||
for example.
|
||||
.pp
|
||||
INTERLEAVE]>The practice of selecting
|
||||
the order of sectors on a diskette
|
||||
track to minimize access time due to
|
||||
rotational delay. Also called
|
||||
"skewing" or interlacing.
|
||||
.pp
|
||||
INTERRUPT]>A hardware signal which
|
||||
causes the computer to halt execution
|
||||
of a program and enter a special
|
||||
handler routine. Interrupts are used
|
||||
to service real-time clock
|
||||
time-outs, BRK instructions, and
|
||||
RESET.
|
||||
.pp
|
||||
IOB]>Input/Output Block. A
|
||||
collection of parameter data, passed
|
||||
to Read/Write Track/Sector,
|
||||
describing the operation to be
|
||||
performed.
|
||||
.pp
|
||||
I/O ERROR]>Input/Output Error.
|
||||
An error which occurs
|
||||
during transmission of data to or
|
||||
from a peripheral device, such as a
|
||||
disk or cassette tape.
|
||||
.pp
|
||||
JMP]>A 6502 assembly langauge
|
||||
instruction which causes the computer
|
||||
to begin executing instructions at a
|
||||
different location in memory.
|
||||
Similar to a GOTO statement in BASIC.
|
||||
.pp
|
||||
JSR]>A 6502 assembly langauge
|
||||
instruction which causes the computer
|
||||
to "call" a subroutine. Similar to a
|
||||
CALL statement in BASIC.
|
||||
.pp
|
||||
K]>A unit of measurement, usually
|
||||
applied to bytes. 1 K bytes is
|
||||
equivalent to 1024 bytes.
|
||||
.PP
|
||||
KSWL]>A vector in zero-page through
|
||||
which input data is passed for
|
||||
from the keyboard or a remote
|
||||
terminal.
|
||||
.pp
|
||||
LABEL]>A name associated with a
|
||||
location in a program or in memory.
|
||||
Labels are used in assembly langauge
|
||||
much like statement numbers are used
|
||||
in BASIC.
|
||||
.PP
|
||||
LATCH]>A component into which the
|
||||
Input/Output
|
||||
hardware can store a byte value,
|
||||
which will hold that value until the
|
||||
central processor has time to read
|
||||
it (or vice versa).
|
||||
.pp
|
||||
LINK]>An address pointer in an
|
||||
element of a linked chain of data or
|
||||
buffers.
|
||||
.pp
|
||||
LIST]>A one dimensional sequential
|
||||
array of data items.
|
||||
.pp
|
||||
LOAD POINT (LP)]>The lowest address
|
||||
of a loaded assembly language
|
||||
program -- the first byte loaded.
|
||||
Not necessarily the same as the entry
|
||||
point address (EPA).
|
||||
.pp
|
||||
LOGICAL]>A form of arithmetic which
|
||||
operates with binary "truth" or
|
||||
"false", 1 or 0. AND, OR, NAND, NOR,
|
||||
and EXCLUSIVE OR are all logical
|
||||
operations.
|
||||
.pp
|
||||
LOOP]>A programming construction in
|
||||
which a
|
||||
group of instructions or statements
|
||||
are repeatedly executed.
|
||||
.pp
|
||||
LOW MEMORY]>The memory locations with
|
||||
the lowest addresses. $0000 is the
|
||||
lowest memory location. Also called
|
||||
the "bottom" of memory.
|
||||
.pp
|
||||
LOMEM]>APPLE's zero-page address
|
||||
which identifies the first byte of
|
||||
the available memory which can be
|
||||
used to store BASIC programs and
|
||||
their variables.
|
||||
.pp
|
||||
LSB/LO ORDER]>Least Significant Bit
|
||||
or Least Significant Byte. The 1's
|
||||
bit in a byte or the second pair of
|
||||
hexadecimal digits forming an
|
||||
address. In the address $8030, $30
|
||||
is the LO order part of the address.
|
||||
.pp
|
||||
MASTER DISK]>A DOS diskette which
|
||||
will boot in an APPLE II of any size
|
||||
memory and take full advantage of it.
|
||||
.pp
|
||||
MICROSECOND]>A millionth of a
|
||||
second. Equivalent to one cycle of
|
||||
the APPLE II central processor.
|
||||
Also written as "Usec".
|
||||
.pp
|
||||
MONITOR]>A machine language program
|
||||
which always resides in the computer
|
||||
and which is the first to receive
|
||||
control when the machine is powered
|
||||
up. The APPLE monitor resides in ROM
|
||||
and allows examination and
|
||||
modification of memory at a byte
|
||||
level.
|
||||
.pp
|
||||
MSB/HI ORDER]>Most Significant Bit or
|
||||
Most Significant Byte. The 128's bit
|
||||
of a byte (the left-most) or the
|
||||
first pair of hexadecimal digits in
|
||||
an address. In the byte value $83,
|
||||
the MSB is on (is a 1).
|
||||
.pp
|
||||
NULL]>Empty, having no length or
|
||||
value. A null string is one which
|
||||
contains no characters. The null
|
||||
control character ($00) produces no
|
||||
effect on a printer (also called an
|
||||
idle).
|
||||
.pp
|
||||
NIBBLE/NYBBLE]>A portion of a byte,
|
||||
usually 4 bits and represented by a
|
||||
single hexadecimal digit. $FE
|
||||
contains two nibbles, $F and $E.
|
||||
.pp
|
||||
OBJECT CODE]>A machine language
|
||||
program in binary form, ready to
|
||||
execute. Object code is the output
|
||||
of an assembler.
|
||||
.pp
|
||||
OBJECT MODULE]>A complete machine
|
||||
language program in object code form,
|
||||
stored as a file on a diskette.
|
||||
.pp
|
||||
OFFSET]>The distance from the
|
||||
beginning of a block of data to a
|
||||
particular byte or field.
|
||||
Offsets are usually given
|
||||
beginning with 0, for the first byte,
|
||||
1 for the second, etc. Also known as
|
||||
a displacement.
|
||||
.pp
|
||||
OPCODE]>Operation Code. The three
|
||||
letter mnemonic representing a single
|
||||
assembly langauge instruction. JMP
|
||||
is the opcode for the jump
|
||||
instruction.
|
||||
.pp
|
||||
OPERATING SYSTEM]>A machine language
|
||||
program which manages the memory and
|
||||
peripherals automatically,
|
||||
simplifying the job of the
|
||||
applications programmer.
|
||||
.pp
|
||||
OR]>The logical operation comparing
|
||||
two bits to determine if either of
|
||||
them are 1. 1 OR 1 results in 1
|
||||
(true), 1
|
||||
OR 0 results in 1, 0 OR 0 results in
|
||||
0 (false).
|
||||
.pp
|
||||
OVERHEAD]>The space required by the
|
||||
system, either in memory or on the
|
||||
disk, to manage either. The disk
|
||||
directory and VTOC are part of a
|
||||
diskette's overhead.
|
||||
.br
|
||||
.nx appendix c.2
|
||||
\x00
|
328
D2S1/APX.C.2#064000.txt
Normal file
328
D2S1/APX.C.2#064000.txt
Normal file
|
@ -0,0 +1,328 @@
|
|||
.pp
|
||||
PAGE]>256 bytes of memory which share
|
||||
a common high order address byte.
|
||||
Zero page is the first 256 bytes of
|
||||
memory ($0000 through $00FF).
|
||||
.pp
|
||||
PARALLEL]>Opposite of serial. A
|
||||
communication mode which sends all of
|
||||
the bits in a byte at once, each over
|
||||
a separate line or wire.
|
||||
.pp
|
||||
PARAMETER LIST]>An area of storage
|
||||
set aside for communication between
|
||||
a calling program and a subroutine.
|
||||
The parameter list contains input and
|
||||
output variables which will be used
|
||||
by the subroutine.
|
||||
.pp
|
||||
PARITY]>A scheme, similar to
|
||||
checksums but on a bit level rather
|
||||
than a byte level, which allows
|
||||
detection of errors in a single data
|
||||
byte. An extra parity bit is
|
||||
attached to each byte which is a sum
|
||||
of the bits in the byte. Parity is
|
||||
used in expensive memory to detect or
|
||||
correct single bit failures, and when
|
||||
sending data over communications
|
||||
lines to detect noise errors.
|
||||
.pp
|
||||
PARSE]>The process of interpreting
|
||||
character string data, such as a
|
||||
command with keywords.
|
||||
.pp
|
||||
PATCH]>A small change to the object
|
||||
code of an assembly language program.
|
||||
Also called a "zap".
|
||||
.pp
|
||||
PERIPHERAL]>A device which is
|
||||
external to the computer itself, such
|
||||
as a disk drive or a printer. Also
|
||||
called an Input/Output device.
|
||||
.pp
|
||||
PHYSICAL RECORD]>A collection of data
|
||||
corresponding to the smallest unit of
|
||||
storage on a peripheral device.
|
||||
For disks, a physical record
|
||||
is a sector.
|
||||
.pp
|
||||
POINTER]>The address or memory
|
||||
location of a block of data or a
|
||||
single data item. The address
|
||||
"points" to the data.
|
||||
.pp
|
||||
PROLOGUE]>The three bytes at the
|
||||
beginning of a disk field which
|
||||
uniquely identify it from any other
|
||||
data on the track.
|
||||
.pp
|
||||
PROM]>Programmable Read Only Memory.
|
||||
PROMs are usually used on controller
|
||||
cards associated with peripherals to
|
||||
hold the driver program which
|
||||
interfaces the device to applications
|
||||
programs.
|
||||
.pp
|
||||
PROMPT]>An output string which lets
|
||||
the user know that input is expected.
|
||||
A "*" is the prompt character for the
|
||||
APPLE monitor.
|
||||
.pp
|
||||
PROTECTED DISK]>A diskette whose
|
||||
format or content has been modified
|
||||
to prevent its being copied. Most
|
||||
retail software today is distributed
|
||||
on protected disks to prevent theft.
|
||||
.pp
|
||||
PSEUDO-OPCODE]>A special assembly
|
||||
language opcode which does not
|
||||
translate into a machine instruction.
|
||||
A pseudo-opcode instructs the
|
||||
assembler to perform some function,
|
||||
such as skipping a page in an
|
||||
assembly listing or reserving data
|
||||
space in the output object code.
|
||||
.pp
|
||||
RANDOM ACCESS]>Direct access. The
|
||||
capability to rapidly access any
|
||||
single piece of data on a storage
|
||||
medium without having to sequentially
|
||||
read all of its predecessors.
|
||||
.pp
|
||||
RAM]>Random Access Memory. Computer
|
||||
memory which will allow storage and
|
||||
retrieval of values by address.
|
||||
.pp
|
||||
RECAL]>Recalibrate the disk arm so
|
||||
that the read/write head is
|
||||
positioned over track zero. This is
|
||||
done by pulling the arm as far as it
|
||||
will go to the outside of the
|
||||
diskette until it hits a stop,
|
||||
producing a "clacking" sound.
|
||||
.pp
|
||||
RECORD]>A collection of associated
|
||||
data items or fields. One or more
|
||||
records are usually associated with a
|
||||
file. Each record might correspond
|
||||
to an employee, for example.
|
||||
.pp
|
||||
REGISTER]>A named temporary storage
|
||||
location in the central processor
|
||||
itself. The 6502 has 5 registers;
|
||||
the A, X, Y, S, and P registers.
|
||||
Registers are used by an assembly
|
||||
language program to access memory and
|
||||
perform arithmetic.
|
||||
.pp
|
||||
RELEASE]>A version of a distributed
|
||||
piece of software. There have been
|
||||
several releases of DOS.
|
||||
.pp
|
||||
RELOCATABLE]>The attribute of
|
||||
an object module file
|
||||
which contains a machine language
|
||||
program and the information necessary
|
||||
to make it run at any memory
|
||||
location.
|
||||
.pp
|
||||
RETURN CODE]>A numeric value returned
|
||||
from a subroutine, indicating the
|
||||
success or failure of the operation
|
||||
attempted. A return code of zero
|
||||
usually means there were no errors.
|
||||
Any other value indicates the nature
|
||||
of the error, as defined by the
|
||||
design of the subroutine.
|
||||
.PP
|
||||
ROM]>Read Only Memory. Memory which
|
||||
has a permanent value. The APPLE
|
||||
monitor and BASIC interpreters are
|
||||
stored in ROM.
|
||||
.PP
|
||||
RWTS]>Read/Write Track/Sector. A
|
||||
collection of subroutines which allow
|
||||
access to the diskette at a
|
||||
track and sector level. RWTS is
|
||||
part of DOS and may be called by
|
||||
external assembly language programs.
|
||||
.pp
|
||||
SEARCH]>The process of scanning a
|
||||
track for a given sector.
|
||||
.PP
|
||||
SECTOR]>The smallest updatable unit
|
||||
of data on a disk track. One sector
|
||||
on an APPLE DISK II contains 256
|
||||
data bytes.
|
||||
.pp
|
||||
SECTOR ADDRESS]>A disk field which
|
||||
identifies the sector data field which
|
||||
follows in terms of its volume,
|
||||
track, and sector number.
|
||||
.pp
|
||||
SECTOR DATA]>A disk field which
|
||||
contains the actual sector data in
|
||||
nibbilized form.
|
||||
.pp
|
||||
SEEK]>The process of moving the disk
|
||||
arm to a given track.
|
||||
.pp
|
||||
SELF-SYNC]>Also called "auto-sync"
|
||||
bytes. Special disk bytes which
|
||||
contain more than 8 bits, allowing
|
||||
synchronization of the hardware to
|
||||
byte boundaries when reading.
|
||||
.pp
|
||||
SEQUENTIAL ACCESS]>A mode of data
|
||||
retreival where each byte of data is
|
||||
read in the order in which it was
|
||||
written to the disk.
|
||||
.pp
|
||||
SERIAL]>As opposed to parallel. A
|
||||
communication mode which sends data
|
||||
bits one at a time over a single line
|
||||
or wire.
|
||||
.pp
|
||||
SHIFT]>A logical operation which
|
||||
moves the bits of a byte either left
|
||||
or right one position, moving a 0
|
||||
into the bit at the other end.
|
||||
.pp
|
||||
SLAVE DISK]>A diskette with a copy of
|
||||
DOS which is not relocatable. The
|
||||
DOS image will always be loaded into
|
||||
the same memory location, regadless
|
||||
of the size of the machine.
|
||||
.pp
|
||||
SOFT ERROR]>A recoverable I/O error.
|
||||
A worn diskette might produce soft
|
||||
errors occasionally.
|
||||
.pp
|
||||
SOFTWARE]>Computer programs and data
|
||||
which can be loaded into RAM memory
|
||||
and executed.
|
||||
.pp
|
||||
SOURCE CODE]>A program in a form
|
||||
which is understandable to humans;
|
||||
in character form as opposed
|
||||
to internal binary machine format.
|
||||
Source assembly code must be
|
||||
processed by an assembler to
|
||||
translate it into machine or "object"
|
||||
code.
|
||||
.pp
|
||||
SKEWING]>The process of interleaving
|
||||
sectors. See INTERLEAVE.
|
||||
.pp
|
||||
STATE MACHINE]>A process (in software
|
||||
or hardware) which defines a
|
||||
unique target state, given an input
|
||||
state and certain conditions. A
|
||||
state machine approach is used in DOS
|
||||
to keep track of its video intercepts
|
||||
and by the hardware on the disk
|
||||
controller card to process disk data.
|
||||
.pp
|
||||
STROBE]>The act of triggering an I/O
|
||||
function by momentarily referencing a
|
||||
special I/O address. Strobing $C030
|
||||
produces a click on the speaker.
|
||||
Also called "toggling".
|
||||
.pp
|
||||
SUBROUTINE]>A program whose function
|
||||
is required repeatedly during
|
||||
execution, and therefore is called by
|
||||
a main program in several places.
|
||||
.pp
|
||||
TABLE]>A collection of data entries,
|
||||
having similar format, residing in
|
||||
memory. Each entry might contain the
|
||||
name of a program and its address,
|
||||
for example. A "lookup" can be
|
||||
performed on such a table to locate
|
||||
any given program by name.
|
||||
.pp
|
||||
TOGGLE]>The act of triggering an I/O
|
||||
function by momentarily referencing a
|
||||
special I/O address. Toggling $C030
|
||||
produces a click on the speaker.
|
||||
Also called "strobe".
|
||||
.pp
|
||||
TOKENS]>A method where human
|
||||
recognizable words may be coded to
|
||||
single binary byte values for memory
|
||||
compression and faster processing.
|
||||
BASIC statements are tokenized, where
|
||||
hex codes are assigned to words like
|
||||
IF, PRINT, and END.
|
||||
.pp
|
||||
TRACK]>One complete circular path of
|
||||
magnetic storage on a diskette.
|
||||
There are 35 concentric tracks on an APPLE
|
||||
diskette.
|
||||
.pp
|
||||
TRANSLATE TABLE]>A table of single
|
||||
byte codes which are to replace
|
||||
input codes on a one-for-one
|
||||
basis. A translate table is used to
|
||||
convert from 6 bit codes to disk
|
||||
codes.
|
||||
.PP
|
||||
T/S LIST]>Track/Sector List. A
|
||||
sector which describes the location
|
||||
of a file by listing the track and
|
||||
sector number for each of its data
|
||||
sectors in the order that they are to
|
||||
be read or written.
|
||||
.pp
|
||||
TTL]>Transistor to Transistor Logic.
|
||||
A standard for the interconnection of
|
||||
integrated circuits which also
|
||||
defines the which voltages
|
||||
represent 0's and 1's.
|
||||
.pp
|
||||
UTILITY]>A program which is used to
|
||||
maintain, or assist in the development
|
||||
of, other programs or disk files.
|
||||
.pp
|
||||
VECTOR]>A collection of pointers or
|
||||
JMP instructions at a fixed location
|
||||
in memory which allow access to a
|
||||
relocatable program or data.
|
||||
.pp
|
||||
VOLUME]>An identification for a
|
||||
diskette, disk platter, or cassette,
|
||||
containing one or more files.
|
||||
.pp
|
||||
VTOC]>Volume Table Of Contents.
|
||||
Based upon the IBM OS/VS VTOC. On
|
||||
the APPLE, a sector mapping the
|
||||
free sectors on the diskette and
|
||||
giving the location of the directory.
|
||||
.pp
|
||||
WARMSTART]>A restart of a program
|
||||
which retains, as much as is
|
||||
possible, the work which was in
|
||||
progress at the time. A DOS
|
||||
warmstart retains the BASIC program
|
||||
in memory.
|
||||
.PP
|
||||
WRITE PROTECTED]>A diskette whose
|
||||
write protect notch is covered,
|
||||
preventing the disk drive from
|
||||
writing on it.
|
||||
.pp
|
||||
ZAP]>From the IBM utility program,
|
||||
SUPERZAP. A program which allows
|
||||
updates to a disk at a byte level,
|
||||
using hexadecimal.
|
||||
.pp
|
||||
ZERO PAGE]>The first 256 bytes of
|
||||
memory in a 6502 based machine. Zero
|
||||
page locations have special
|
||||
significance to the central
|
||||
processor, making their management
|
||||
and assignment critical.
|
||||
.br
|
||||
\x00
|
133
D2S1/CHANGES.2ND.PRI#064c00.txt
Normal file
133
D2S1/CHANGES.2ND.PRI#064c00.txt
Normal file
|
@ -0,0 +1,133 @@
|
|||
.na
|
||||
.fi
|
||||
.ll60
|
||||
.br
|
||||
SECOND PRINTING CORRECTIONS
|
||||
.sp3
|
||||
3-3
|
||||
.sp1
|
||||
Data bits are recorded on the
|
||||
diskette in precise intervals. For
|
||||
the purposes of this discussion, the
|
||||
demarcation of these intervals will
|
||||
be depicted by a clock bit. Using
|
||||
this representation, data written to
|
||||
and read back from the diskette takes
|
||||
the form shown in Figure 3.2. The
|
||||
data pattern shown represents a
|
||||
binary value of 101.
|
||||
.sp3
|
||||
3-10
|
||||
.sp1
|
||||
at least as long as a typical Gap 3
|
||||
(in practice its length is usually
|
||||
more than 400 sync bytes, enabling it
|
||||
to serve as a Gap 3 type for Address
|
||||
Field number 0 (See Figure 3.7 for
|
||||
clarity).
|
||||
.sp3
|
||||
3-17
|
||||
.sp1
|
||||
page.*
|
||||
.sp1
|
||||
diagrammed in Figure 3.21.*
|
||||
.sp1
|
||||
*Figures 3.20 and 3.21 present the
|
||||
nibblizing process used by the "6 and
|
||||
2" encoding technique. However, the
|
||||
concept is the same for the "5 and 3"
|
||||
technique.
|
||||
.sp3
|
||||
4-17
|
||||
.sp1
|
||||
.nf
|
||||
occurred. Either a bad checksum was detected on the data in a
|
||||
.fi
|
||||
.sp1
|
||||
program given there will read any
|
||||
track/sector on an unprotected
|
||||
diskette into memory, allowing the
|
||||
user to examine it or modify the data
|
||||
and then, optionally, rewrite it to a
|
||||
diskette. Using such a program is
|
||||
very important when learning about
|
||||
diskette formats and when fixing
|
||||
clobbered data.
|
||||
.sp3
|
||||
5-2
|
||||
.sp1
|
||||
The file manager, occupying about
|
||||
2.8K, is a collection of
|
||||
.bp
|
||||
5-5 (note correction to correction - first $3F2 is ok)
|
||||
.sp1
|
||||
.nf
|
||||
change $3F2 to handle your own RESETs, EOR (exclusive
|
||||
OR) the new value at $3F3 with a $A5 and store the
|
||||
result in the power-up byte.
|
||||
.sp3
|
||||
.fi
|
||||
6-5
|
||||
.sp1
|
||||
NOTE: RWTS uses zero-page location
|
||||
$48, which is also used by the
|
||||
APPLE
|
||||
monitor to hold the P-register value.
|
||||
Location $48 should be set to zero
|
||||
after each call to RWTS.
|
||||
.sp3
|
||||
6-11
|
||||
.sp1
|
||||
.nf
|
||||
04/05 - Byte offset of current file position*
|
||||
.sp1
|
||||
.fi
|
||||
*The current file position is updated
|
||||
to point to the byte following the
|
||||
data read or written.
|
||||
.sp3
|
||||
8-5
|
||||
.sp1
|
||||
.nf
|
||||
9E51-9E7F An image of the DOS page 3 jump vector which the
|
||||
above routine copies to $3D0-$3FF. See Chapter 5 for
|
||||
a description of its contents.
|
||||
.sp3
|
||||
8-36
|
||||
.sp1
|
||||
B9A0-B9FF SEEKABS routine.
|
||||
Move disk arm to desired track.
|
||||
Calls arm move delay subroutine ($BA00).
|
||||
.sp3
|
||||
8-37
|
||||
.sp1
|
||||
BA00-BA10 Arm move delay subroutine.
|
||||
.sp3
|
||||
A-3
|
||||
.sp1
|
||||
.fi
|
||||
A diskette containing these five
|
||||
programs is available at a reasonable
|
||||
cost directly from Quality Software,
|
||||
6660 Reseda Blvd., Reseda, CA. or
|
||||
telephone (213) 344-6599.
|
||||
.bp
|
||||
A-12
|
||||
.sp1
|
||||
at location $03 (the volume number
|
||||
should match the volume number of the
|
||||
other tracks), and then begin
|
||||
execution at $800. INIT will return
|
||||
to the monitor upon completion. If
|
||||
the track can not be formatted for
|
||||
some reason (eg. physical damage or
|
||||
problems with the disk drive itself)
|
||||
a return code is printed. For
|
||||
example:
|
||||
.sp3
|
||||
A-20
|
||||
.sp1
|
||||
.nf
|
||||
800G (Run the COPY program)
|
||||
.br
|
||||
\x00
|
36
D2S1/CHANGES.3RD.PRI#064000.txt
Normal file
36
D2S1/CHANGES.3RD.PRI#064000.txt
Normal file
|
@ -0,0 +1,36 @@
|
|||
.na
|
||||
.fi
|
||||
.ll60
|
||||
.br
|
||||
THIRD PRINTING CORRECTIONS
|
||||
.sp3
|
||||
4-17
|
||||
.sp1
|
||||
Disk utilities, such as Quality
|
||||
Software's BAG OF TRICKS, allow the
|
||||
user to read and display the contents
|
||||
of sectors. BAG OF TRICKS will also
|
||||
allow you to modify the sector data
|
||||
and rewrite it to the same or another
|
||||
diskette. If you do not have BAG OF
|
||||
TRICKS or another commercial disk
|
||||
utility, you can use the ZAP program
|
||||
in APPENDIX A of this book. The ZAP
|
||||
program will read any track/sector on
|
||||
an unprotected diskette into memory,
|
||||
allowing the user to examine it or
|
||||
modify the data and then, optionally,
|
||||
rewrite it to a diskette. Using such
|
||||
a program is very important when
|
||||
learning about diskette formats and
|
||||
when fixing clobbered data.
|
||||
.sp3
|
||||
A-3
|
||||
.sp1
|
||||
Also available from Quality Software
|
||||
is an expanded version of these
|
||||
utilities called BENEATH APPLE DOS'
|
||||
BAG OF TRICKS. See the page facing
|
||||
1-1 for more details.
|
||||
.br
|
||||
\x00
|
126
D2S1/CORRECTIONS#064000.txt
Normal file
126
D2S1/CORRECTIONS#064000.txt
Normal file
|
@ -0,0 +1,126 @@
|
|||
.na
|
||||
.nf
|
||||
.ll60
|
||||
.br
|
||||
SIG 1-2
|
||||
.sp3
|
||||
3-13
|
||||
.sp1
|
||||
roughly 72K of space available to the user; typical for
|
||||
5 1/4 inch single density drives.
|
||||
.sp3
|
||||
4-6
|
||||
.sp1
|
||||
2E-50 Second file descriptive entry
|
||||
.sp3
|
||||
4-17
|
||||
.sp1
|
||||
user to read and display the contents of sectors. Some of
|
||||
.sp3
|
||||
6-2
|
||||
.sp1
|
||||
Q7L with Q6L = Read
|
||||
Q7L with Q6H = Sense Write Protect
|
||||
Q7H with Q6L = Write
|
||||
Q7H with Q6H = Load Write Latch
|
||||
.bp
|
||||
SIG 3-4
|
||||
.SP3
|
||||
8-5
|
||||
.sp1
|
||||
9E9E If EXECing, call A682 to get the next byte from the
|
||||
.sp3
|
||||
8-6
|
||||
.sp1
|
||||
index into the state handler table (9D10), go to
|
||||
.sp3
|
||||
8-8
|
||||
.sp1
|
||||
table of valid keywords (A941).
|
||||
.SP3
|
||||
8-9
|
||||
.SP1
|
||||
A1AE-A1B8 Clear the file manager parameter list at B5BB to
|
||||
.sp3
|
||||
8-13
|
||||
.sp1
|
||||
A4DC Skip a line on the screen.
|
||||
.sp3
|
||||
8-24
|
||||
.sp1
|
||||
ACA8-ACBA Read a data byte.
|
||||
.sp1
|
||||
AACA-ACD9 WRITE A RANGE OF BYTES subcode handler.
|
||||
.sp1
|
||||
ACDA-ACEE Write a data byte.
|
||||
.sp3
|
||||
8-27
|
||||
.SP1
|
||||
AF3A Otherwise, set up RWTS pointer (AF4B).
|
||||
.SP1
|
||||
next (C=1)).
|
||||
.sp3
|
||||
8-28
|
||||
.sp1
|
||||
B052-B0B5 Read/Write Track/Sector (RWTS) driver.
|
||||
.sp1
|
||||
Translate vol mismatch to RC=7, write protected to
|
||||
RC=4 and all other errors to RC=8 (I/O error).
|
||||
.sp3
|
||||
8-29
|
||||
.sp1
|
||||
B134-B15A Add a new data sector to file.
|
||||
.sp3
|
||||
8-30
|
||||
.sp1
|
||||
B20B If not, advance index to next entry in sector and
|
||||
.sp3
|
||||
8-34
|
||||
.sp1
|
||||
Call SETVID ($FE93) and SETKBD ($FE89).
|
||||
.SP3
|
||||
8-35
|
||||
.SP1
|
||||
$20=Volume mismatch, $40=Drive error, $08=INIT error.
|
||||
.sp1
|
||||
Uses Write Translate Table ($BA29).
|
||||
.SP3
|
||||
8-37
|
||||
.sp1
|
||||
Y-reg:number of autosyncs to write
|
||||
.sp3
|
||||
8-39
|
||||
.sp1
|
||||
Jump to DSKFORM at $BEAF.
|
||||
.SP1
|
||||
Use ILEAV table at $BFB8 for software sector
|
||||
.sp3
|
||||
8-41
|
||||
.sp1
|
||||
BFC8-BFD8 Patch area starts here.
|
||||
.bp
|
||||
SIG 5-6
|
||||
.SP3
|
||||
A-16
|
||||
.sp1
|
||||
using ZAP to patch a catalog entry into track 17 for each
|
||||
.sp3
|
||||
C-4
|
||||
.sp1
|
||||
DCT Device Characteristics Table. Used as an
|
||||
.sp3
|
||||
C-8
|
||||
.sp1
|
||||
subroutine. Similar to a GOSUB statement
|
||||
.sp1
|
||||
input data is passed from the
|
||||
.sp3
|
||||
C-10
|
||||
.sp1
|
||||
language instruction. JMP is the opcode
|
||||
.sp3
|
||||
C-15
|
||||
.sp1
|
||||
the voltages which represent 0's and
|
||||
.br
|
||||
\x00
|
|
@ -19,7 +19,13 @@ join in--send patches, help add stuff, etc.
|
|||
## The method
|
||||
|
||||
1. The DOS 3.3 disks were dumped using cppo
|
||||
2. There is no #2 yet.
|
||||
2. Apply the following transformations to each document file:
|
||||
* For characters 0xa0-0xfe, strip the high bit to get pure ASCII
|
||||
* Convert 0x0d and 0x8d (return) characters ti 0x0a (newline)
|
||||
* Escape all else in C-style
|
||||
|
||||
This has probably broken the .s files a bit, and I haven't bothered to decompile
|
||||
the five byte HELLO ... ;)
|
||||
|
||||
[dons-disks]: http://www.6502lane.net/2015/03/12/don-worths-beneath-apple-dos-original-text-files/
|
||||
[archive.org]: https://archive.org/
|
||||
|
|
Loading…
Reference in New Issue
Block a user