PART 1
HOW TO WRITE A VIEWSTORE UTILITY
by Mark Colton, author of VIEW, VIEWSHEET AND VIEWSTORE
Since the available space for ROM code is limited to 16k, ViewStore has
provision for extra programs or utilities that exist outside the ROM to be
used. ViewStore is supplied with several utilities that supplement the ROM,
and has an interface built into it to allow utility programs to use routines
inside the ROM. Certain areas of memory are also allocated for use by
utility programs. Given the knowledge of the interface and memory
allocation, it is possible to write extra utilities for ViewStore. The
purpose of this document is to define the utility interface to enable third
parties to write their own utilities. A good knowledge of ViewStore and
assembly language will be essential.
The Interface
Various routines within the ROM are available for use by utilities. The
routines provide the utility with the means to access format files and data
records and indexes and assorted useful functions. The ROM has a jump table
at the beginning which directs calls to the various routines in the ROM.
As well as access to the ROM routines, the utility has memory allocated to
it. Three areas of memory are available to a utility:
A section of zero page
A section of language absolute workspace
A section of main memory
The amount of zero page and language workspace available to a utility depend
upon which ROM routines the utility is going to use. The size and position
of the piece of main memory available can only be determined when the
utility is run: pointers to the start and end of the main workspace are
passed when the utility is started.
The zero page, language workspace and main memory not available to the
utility is used by the ViewStore ROM itself. A utility should not alter
this memory, but the addresses of some locations are defined to allow
utilities to read useful parameters.
Utility Format
The format of a utility must conform to certain rules. When a utility is
located and loaded from the filing system, ViewStore relocates the code to
run at a particular point in memory. This point varies according to the
size of the format file loaded and the MOS "high water mark". On machines
with second processors attached, ViewStore relocates the utility to run in
the space left above the ROM: from &C000 to &F800. Using this relocating
system, ViewStore make optimum use of the memory available.
Since it is not easy to write position independent code for the 6502, the
ROM includes a relocating system. The utility must provide certain
information about itself to enable this system to work. The format of a
utility is as follows:-
.start JMP code
EQUW bitmap-start
EQUW start
EQUS "version no/copyright string"
.code /utility code begins here
/end of utility code
.bitmap /relocation bitmap
/end of utility
The first word after the initial JMP gives the offset from the beginning of
the utility to the relocation bitmap.
Since the utility is relocated after being loaded, the actual assembly
address is not important, but ViewStore must be told at what address the
utility has been assembled, so that it can calculate how much needs to be
added or subtracted from the addresses to be relocated. The second word
after the JMP gives the assembly address. This &2000 for most of the
supplied utilities.
The version no/copyright string is not essential, but it's a good idea to
include one so that you can identify the code.
The main hurdle for anyone writing their own utilities will be the
generation of the relocation bitmap. This identifies the addresses that
must be relocated. There is a bit in the bitmap for every byte of code in
the utility, excluding the bitmap itself. A bit set to zero indicates that
an address is not to be relocated; a bit set to one indicates that an
address is to be relocated.
It is only possible to relocate addresses using this system, not single
bytes. This means that it is not possible to set up or move addresses using
immediate data:
LDA #place
STA var
LDA #place AND &FF
STA var+1
is not allowed. You must use the form:
LDA plcew
STA var
LDA placew+1
STA var+1
.placed EQUW place
In the bitmap, a bit which is set is taken to refer to a 16 bit address
within the program; it is therefore impossible to have two adjacent bits set
since the second bit it referring to the high byte of the address.
Given eight adjacent bytes, all represented by a single byte in the bitmap,
the most significant bit in the bitmap byte corresponds to the first code
byte, and the least significant bit to the last code byte.
As an example: the first byte of a relocation bitmap always corresponds to
the JMP and EQUW structure at the beginning of the utility. Assuming that
you have a copyright string (which contains no addresses to be relocated),
the first byte of the bitmap should always be &44. The bit string for this
is:
MSB LSB
0 1 0 0 0 1 0 0
The first three bits correspond to the three bytes of the JMP instruction.
The second two bytes of the JMP instruction contain the address to jump to,
which must be relocated. The first bit of the two bits for this address is
therefore set. The next two bits correspond to the bitmap offset word. This
remains constant for any load address, so these two bits are zero. The next
two bits are for the assembly address, which will alter as the utility is
relocated, and the first bit is a 1 accordingly. The last bit is for the
first byte of the copyright string; zero since this has no addresses to be
relocated.
The bitmaps for the utilities which are supplied with ViewStore were
generated automatically by an assembler which is not available on the
market. If you are going to write a utility for ViewStore, you must find a
way of generating relocation bitmaps. This could be done in one of three
ways:
1. Generate it by hand
2. Write a program to take an assembled utility and generate the
bitmap
3. Modify an assembler to generate relocation bitmaps
4. Assemble it at two different addresses and write a program to
compare the two resulting code files. Those locations which have changed
need a set bit in the bitmap.
For most people, the last option will be the simplest.
The Utility Environment
Most utilities will want to operate upon existing databases. It is
possible, though, to have a utility which does not operate on existing data,
but creates data, or doesn't act on data at all.
An example of this is the SETUP utility, which creates blank databases. It
doesn't refer to any existing data. Utilities which need to access either
format files or data files must first check that a database has been loaded,
and abort with an error message if there is no loaded database.
This is done by checking the location FILMOD. If FILMOD is non-zero, then a
database is loaded. If zero, there is no database loaded.
The normal sequence of operation will be to load a database in ViewStore,
with the LOAD command. This loads the format file into memory, and locates
the data file. A utility is then started with the UTILITY command. The
utility can read the format file as it requires, and can open and process
the information in the data file. It can use a subset of data identified by
the select file.
Once the utility is running, it can take control of the machine as it needs
to, using the memory available to it, and the ROM routines as required.
Naming of Addresses
In this document, all location and routine addresses will be referred to by
name. Tables of addresses and values are at the end of the document.
You will notice that the names of a block of addresses being with "TEMP".
These locations are available for use by the utility as temporary storage,
but some are used and altered by routines in the ROM.
Temporaries
The numbered temporaries are all either a single byte or two bytes long.
Those from TEMPFD to TEMP05 are all one byte long; those from TEMP06 to
TEMP14 are all two bytes long. The two byte temporaries are used to store
and pass addresses; the single byte temporaries are used to store one byte
quantities.
Often, values are passed to and from routines using temporaries, as well as
registers in the CPU. Many routines "corrupt" certain temporaries; a list
of the temporaries a routine corrupts is given in a summary at the end.
Utilities can use temporaries whenever they wish, but of course their use
must not clash with any routines that you call in the ROM.
Entry Parameters
When the utility is started, the following data is provided:
TEMP14 contains the start address of free main memory
VWSLIM contains the address of the byte after the last free
byte in main memory
VWSLIM will not change while the utility is running, and the utility must
not alter VWSLIM. TEMP14 may be altered by a ROM call, so it is best to
store it somewhere else for later reference.
The utility is called with a JSR instruction, and ViewStore expects the
utility to hand back control, when it is finished, with an RTS instruction.
.start TSX
STX stksav
.
.
.error LDX stksav
TXS
RTS
Zero Page
Zero page is divided up into four areas of different types:
ViewStore variables read only for utilities. Below &50.
Temporaries TEMPFD-TEMP
Floating point FACCxxand FWRKxx. Start at &6B. read/write for
accumulators utilities; if the floating point calls are not used
by the utility. this area can be used as general
workspace.
General workspace VWSXTZ-&8F inclusive.
Language Workspace
LWORK 16 byte parameter block used by ROM
routines.
FBLOCK 27 byte filename work area.
LINBUF 256 byte work area used by one or
two ROM routines.
VWSXTL-VWSITL area used by ISAM index system. Can
be used as general workspace if the
utility is not using indexes.
General workspace VWSITL-&7FF inclusive.
ROM Routines
I will describe the ROM routines in the categories that they fall into. The
routine addresses and parameters are summarised in table 1. All routines
should be called with a JSR instruction, except for CALUTI which should be
called with a JMP instruction, since returning control to the utility is not
usually sensible as the new utility will overwrite the old one in memory.
Data File Control
These routines give the utility access to the database data file, using the
current select file if required. It is only possible to read sequentially
through the data file using these calls, but the data will be returned in
sorted order if the selected data was sorted.
The utility should not close the intermediate file if it uses it. This is
done automatically when control is returned to the ROM.
INIIMF Initialise data sequence. Called to start the data
reading sequence.
MXTIMF Get next from data sequence. Each call returns the
next data record in the sequence.
INIIMF
This routine is called to initiate a sequence of data transfers. It opens
the main data file, and stores its handle in the location EFILE. According
to the state of the carry flag on entry, it asks the user if he wishes to
use a select file. The user responds with a yes or no, and ViewStore opens
the select file (S.database) accordingly. After this, the select file is
transparent to the utility; repeated calls to NXTIMF will either return all
the records in the data file if the select file is not being used, or the
subset of records in the select file, if specified.
On entry: CC Don't ask "Use select file (Y,N)?" question.
CS Ask select file question.
On exit: VC No error.
VS Error; error code in A.
NXTIME
After starting the sequence with a call to INIIMF, repeated calls to MXTIMF
return the records in the data file one by one.
On entry: A low byte of address to store record.
Y high byte of address to store
record.
TEMP13 address of the byte after the last
byte available to store the record.
On exit: VC No error.
VS Error; error code in A.
CC Not end of file.
CS End of file (returned on the call
after the last record has been
processed).
Errors
Many of the ROM routines can return an error status. An error is usually
indicated by either the Carry flag (C), or the Overflow flag (V). When an
error is indicated, the error code is in the A register. To report the
error to the user, call the routine REPERL with this code A. The various
error codes and messages are summarised later. A utility can use a ROM
error message by loading the appropriate code into A, and calling REPERL.
All file calls have the same error trapping system: after a call, V is set
to indicate an error, clear if there was no error. This includes errors
causing a BRK, that is control is returned to the calling routine even when
a BRK is occurred. When you call REPERL with the returned error code, the
BRK message will be reported as normal.
REPERL
Reports the error message for the error code in A:
On entry: A contains error code.
On exit: A,X,Y undefined.
Field and Record Control
Much of ViewStore's manipulation is on fields and records; accordingly,
there are several routines available to make this easier. There are some
routines to locate fields in the header, format file or current record;
routines to compare field values; and routines to find the size of a given
field.
Most of these routines use the two temporaries TEMP06 and TEMP07. TEMP06
points to either a field within the format file, or a field within the
current record. TEMP07 points to a field within the current record. The Y
indirect indexed addressing mode is used in conjunction with these
temporaries to access the field contents: the temporary points to the
beginning of the field, and the Y register gives the offset from there.
Remember that the format file itself is in the same format as a data file.
The same routines are used to process information in records of the database
as in the format file itself. For each field in the database, there is a
record in the format file, and this record details the characteristics of
its corresponding field in the database. The header record is the first
record in the format file.
Data Format
The data format is summarised in table 10 at the end of the document. All
fields in ViewStore are stored in ASCII, even numbers and dates; each field
ends with an end of field marker; each record ends with an end of record
marker; and the file ends with an end of file marker; after the end of file
marker, the file is padded up to the physical end of file with null
characters. If you are processing a field's contents, you should test for
the end of field using the CHKEOF and CHKEOR routines. These routines set
the flags according to the character that they find. Don't check for the
character value explicitly.
Generally, when you make a call to a routine that locates a field, the x
register indicates where the field is to be found:
X=0 Field in header; A has field number.
X=1 to 254 Field in format file; X gives format file record
number; A has field number. The field numbers of
the various format file fields are summarised below.
X=225 Field in current record; A has field number; Y has
record number.
Fields within a record are numbered from 1 to 254. If you ask for a field
which is not in the record, the routine will return with the Carry flag set.
Whereas ViewStore knows where the format file is located, the address of the
current record could be anywhere, and before fields within the current
record can be accessed, you must tell ViewStore its address with the SETDPS
routine.
GETFLD General field locate routine; can locate a field in
the header, format file or current record.
GETFRC Find the address of a field in the current record.
GETXFL Return first non-space character of a field in the A
register, folded to upper case if applicable.
SETDPS Set the address of the beginning of the current
record.
CHKEOF Check the character in the A register for an end of
field character.
CHKEOR Check the character in the A register for an end of
record character.
SIZFLD Return the size of a given field.
CMPFLD Compare two fields of the same type and set the
flags.
SCHFLD Return the number of a field, given its name.
SCHFLN Return the next field number, given a name, for an
ambiguous name specification.
GETWID Return the display width for a particular field.
GETKYW Return the key width for a particular field.
CALSBN Calculate the number of spaces required to be output
before a numeric field to right justify it within
the display width.
GETFLD
This routine locates a field in either the database header, the format file
or the current record. If the field is in the current record, the address
of the first character of the field is set into TEMP06 and also into TEMP07.
If the field is in the format file, TEMP07 is left unaltered, and the
address of the field is put into TEMP06.
If X is equal to 255, then the routine uses the value in the Y register to
locate a record in a list of current records. The list of records is
numbered from 0 onwards. The usual way to use this part of the routine will
be with Y set to zero, in order to locate a field within a single current
record. If you are using a list of records, then you must not set Y to too
high a value, so that the routine runs off the end of the list, unless you
have an end of file marker after the last record.
Before you use this routine, you must have set the position of the first
record in the list by using the SETDPS call.
On entry: A field number of field to locate;
field start at 1.
X=0 find field in header record.
X=1 to find field in format file record; X
X=254 gives the number of the format file
record.
X=255 find field in list of current
records; Y has the number of the
record to search, starting at zero.
Y only significant if X=255.
On exit: CS field or record not found; TEMP06
(and TEMP07 if X=255) point to the
end of record marker if field not
found, the end of file marker if
record not found.
CC field and record found; TEMP06
points to the beginning of the
field; if the call was made with
X=255 then TEMP07 also points to the
beginning of the field.
A,Y undefined.
X preserved.
GETFRC
This call first sets X to 255, and then calls the GETFLD routine. The entry
and exit conditions are as for GETFLD when X-255, except that X will always
return set to 255.
GETXFL
GETXFL returns the first non-space character in a field, folded to upper
case if alphabetic. It is intended primarily for reading the value of
single character fields in the format file, such as the "Field type" field.
GETXFL first calls the routine GETFLD. The entry conditions are the same as
GETFLD. If the call to GETFLD fails, ie the Carry flag is set, then the A
register is cleared, and the routine ends. If the field is found, then the
first character of the field is returned, folded to upper case if
alphabetic. If the field is blank, then the end of field marker will be
returned.
On entry: See GETFLD
On exit: TEMP06 and TEMP07 set as for GETFLD.
CS field or record not found, as GETFLD; A set
to zero.
CC field found; A contains first non-space
character, folded to upper case if
alphabetic.
X,Y See GETFLD.
SETDPS
This routine stores the address of the records to be used when using one of
the field locate routines with X set to 255. It should be called whenever
the address of one of the records in the list or of one of the fields in the
records has altered. It need not be called if none of the fields has moved,
since ViewStore will keep track of its position in the list of records, and
move backwards or forwards as necessary to find the field you have asked
for.
If you are reading records one by one using the NXTIMF call, for example,
then you must call SETDPS with their address of the record for each record
that you read: the alignment of the fields will alter for each record.
On entry: A contains low byte of the address of the first
record in the list.
Y contains the high byte of the address of the
first record in the list.
On exit: A,X,Y undefined.
CHKEOF
CHKEOF checks the character in the A register for an end of field marker.
It should be used rather than checking for the character explicitly since it
handles classes of characters rather than single values. Generally, it is
not necessary to detect illegal characters explicitly, it is enough to
detect them as an end of field marker.
On entry: A contains character value to be checked.
On exit: EQ end of field.
CS end of record (EQ also set).
VS illegal character (EQ also set).
A,X,Y preserved.
CHKEOR
CHKEOR checks the character in the A register for an end of record marker.
On entry: A contains character to be checked.
On exit: EQ end of record.
CS end of file (EQ also set).
VS space character (EQ also set).
A,X,Y preserved.
SIZFLD
SIZFLD is provided to allow you to determine the size of a field. First of
all you should locate the field, using one of the field locator routines
such GETFLD, which set up TEMP06. Then call SIZFLD.
On entry: TEMP06 points to the beginning of the
field.
On exit: A,Y have length of field in characters.
EQ zero length field.
X preserved.
TEMP06 preserved.
CMPFLD
CMPFLD compares the values of two fields of the same type, and sets the 6502
flags register like the CMP instruction. TEMP07 points to the first field
(equivalent to the contents of the 6502 A register in the CMP instruction),
and TEMP06 points to the second field. If the two fields being compared are
strings, then wildcards are allowed in the second string.
On entry: A contains the field type: A, N, D or Y; must
be in upper case.
TEMP07 points to field 1.
TEMP06 points to field 2.
On exit: VS error in one of the fields supplied: eg
illegal date; result not valid.
C flag set according to compare.
Z flag set according to compare.
A,X,Y undefined.
SCHFLD
SCHFLD is used to find the number of a field, given its name. It searches
the list of fields in the format file until it finds one that fits the name
given. The name that you specify can obtain wild cards: the single wildcard
"?", and the multiple wildcard "*" are both allowed. SCHFLD will always
return the first field in the format file that fits the name you have given.
You can either continue searching for more fields by using the SCHFLD call
described next.
The name of the field is set up in the 16 byte LWORK area. It should be
terminated by a null, or an end of field marker. It must not be longer then
16 bytes, including the delimiter.
On entry: LWORK contains name to search for; maximum of 16
bytes including delimiter; delimiter null
or end of field marker; wildcards "?" and
"*" valid.
On exit: CS no field found to match the name; A has
error code.
CC field found OK; field number in X.
SCHFLN
After calling SCHFLD, you can search for other fields which also fit the
field specification that you gave given, by making repeated calls to SCHFLN.
Before you call SCHFLN, you must have called SCHFLD first, to start the
sequence, and this call must have successfully found a field.
You can keep calling SCHFLN until the call returns with the Carry flag set
to indicate that it has found no more fields.
On entry: Must have called SCHFLD first, and this must have
returned with the Carry flag clear.
A Contains field number to start searching
from. This should be one more than the last value
that SCHFLD or SCHFLN returned in X.
On exit: CS no more fields found; A has error code (report only
if required).
CC field found; field number in X.
GETWID
GETWID returns the display width of a field, as defined in the format file.
If there is no display width defined, a series of defaults comes into
action.
Display width defined Display width
No display width, Sheet mode 18
No display width, Card mode 0
On entry: X contains number of field for which
width is required.
On exit: CS field doesn't exit.
CC field found; A has display width.
X preserved.
Y undefined.
GETKYW
This routine finds the key width for a given field. It uses the value
defined in the format file, if any; otherwise a system of defaults operates:
Key width defined Key width
No key width, display width defined Display width
No key width or display width 10
On entry: X contains number of field for which width is
required.
On exit: CS field doesn't exist.
CC field found; A has already width.
X preserved.
Y undefined.
GETKYW
This routine finds the key width for a given field. It uses the value
defined in the format file, if any; otherwise a system of defaults operates:
Key width defined Key width
No key width, display width defined Display width
No key width or display width 10
On entry: X contains the field number for which the key
width is required.
On exit: A contains key width; if field doesn't exist,
a default key width of 10 is returned.
X preserved.
Y undefined.
CALSBN
This routine is used when displaying numeric fields, to calculate the number
of spaces to be output before the number in order to right justify the
number within its field width. This also takes into account the decimal
places specified in the format file.
On entry: X contains the field number.
TEMP07 points to the beginning of the field in
question.
TEMP03 contains the field display width, as
returned by the GETWID routine.
On exit: A gives number of spaces to output, zero if
the number is wider than the field, or there
are too many decimal places.
X undefined.
Y undefined.
TEMP03 preserved.
TEMP07 preserved.
File Control
File handling in ViewStore is centred around three things: error handling,
FBLOCK and prefixes. Since the error handling provided by the normal filing
system interface provided is completely unsatisfactory for a program such as
ViewStore, I have developed a system which gives control of what happens
after a disc or filing system error. For the utility writer, this system is
transparent: you can forget about it as long as you use the calls provided,
and don't call the filing system directly. If you do this, you can forget
all about BRK errors and handlers.
The system is the same for all file calls: the state of the Overflow (V)
flag indicates after a call whether an error has occurred. If there has
been an error, then the V flag is set, and the A register contains the error
code. If you detect an error, you should unravel yourself from any
routines, report the error by calling the REPERL routine, and then close any
files that you have opened yourself, before returning to control of the ROM.
You shouldn't close the intermediate file: this is done automatically when
control is passed back to the ROM.
Filenames
FBLOCK is a small of memory used to store and manipulate filenames. Several
routines are provided which work on the filename in FBLOCK, altering
directories and prefixes.
A filename in ViewStore is made up of three parts:
Prefix
Directory
Name
ViewStore maintains a list of the current prefixes for each different file
type: data; format; sort and so on. A routine which adds a specified prefix
to a directory and name stored in FBLOCK is available. The maximum length
of a prefix is 13 characters, excluding delimiter. The current prefixes can
only be altered with the PREFIX command in ViewStore's Command Mode.
ViewStore considers directories to be single character; of course the prefix
can include multiple character directories, but the filenames of data and
format files, for example, begin with directories, and these are always
single character directory names, whatever the filing system. Directories
must be separated from the name itself by a dot, making the total size of
the directory section of a filename 2 characters.
The name part of the filename can be up to 10 characters long. This does
not include the directory and separator, or the delimiter. Names are always
delimited with a Carriage Return character.
Part Max. Size (exc. delimiter) Example
Prefix 13 :2.
Director 2 d.
Name 10 datafile
MOVFBK Moves a filename from the store area into FBLOCK.
MOVNAY Moves a filename out of FBLOCK into the store area.
CHKDIR Checks for the presence of a directory in a filename in
FBLOCK, and returns the directory character, if there is
one.
SETDIR Sets a directory into a filename in FBLOCK.
STXPRE Stores the required prefix with a filename in FBLOCK.
OPFILE Gives access to the filing system OSFIND call.
OSHCAL Gives access to the filing system OSFILE call.
XOSARG Vector with error trapping to OSARGS.
XOSBGE Vector with error trapping to OSBGET.
XOSBPU Vector with error trapping to OSBPUT.
XOSCLS Vector with error trapping to OSFIND with A=0; used to
close a file.
XOSGBP Vector with error trapping to OSGBPB.
CALUTI Loads and runs a utility format file.
MOVFBK
MOVFBK moves a filename from ViewStore's list into FBLOCK. A summary of the
filenames available and their offsets is given in table 8. Filenames are
not stored with prefixes attached, but they do include the directory. You
must use the routine STXPRE to add a prefix to the filename once it has been
moved to FBLOCK, before calling one of the file routines.
On entry: Y contains the offset of the filename to be
moved into FBLOCK.
On exit: A,X,Y undefined.
MOVNAY
This routine is the inverse of MOVFBK; it moves a filename from FBLOCK into
ViewStore's list of names. The filename in FBLOCK should not include the
prefix when this routine is called. The list of filename offset values is
given in table 8.
On entry: X contains the offset of the filename area in
which the name currently in FBLOCK is to be
stored.
On exit: A,X,Y undefined.
CHKDIR
CHKDIR checks whether the filename in FBLOCK has a directory, and if it
does, it returns the directory. The filename should not include the prefix
when this routine is called.
On entry: filename to check in FBLOCK.
On exit: CS filename contains directory;
directory character found returned
in A; offset from beginning of
FBLOCK to the directory character is
in X.
CC no directory found.
Y undefined.
SETDIR
SETDIR forces a directory into the filename in FBLOCK. It doesn't matter
whether the filename there contains a directory or not; SETDIR will make
space for it. The filename must not include a prefix when SETDIR is called.
On entry: A contains directory character to set into name
in FBLOCK.
On exit: A,X,Y undefined.
STXPRE
This is the routine that you use to add a prefix to a name. The name
itself, including directory, should be in FBLOCK. Normally, adding the
prefix to a name is the last thing you do before calling the filing system
to do some operation on the file: opening or deleting the file, for example.
Names themselves should be stored without prefix attached, the prefix being
added only when calling the filing system itself.
A list of the prefix offsets for different file types is given in table 7.
On entry: X contains the offset of the prefix required.
On exit: A,X,Y undefined.
OPFILE
OPFILE is an equivalent of the filing system "OSFIND" call, used for opening
files. It assumes, however, that the filename is ready in FBLOCK. OPFILE
cannot be used to close a file, as OSFIND can; use the XOSCLS call to close
a file. OPFILE also uses the ViewStore error trapping system.
On entry: A contains file open code, as for OSFIND; eg.
&40 is open for input.
On exit: VS error occurred; error code in A.
VC no error occurred; file handle is in both A
and Y registers; usual OSFIND error of file
handle being zero when the file can't be
found is trapped: V is set, and the
ViewStore "File not found" error code is in
A; Y is zero.
X undefined.
OSHCAL
OSHCAL gives the utility access to the filing system OSFILE routine. It
uses the OSFARA area as its control block. Note that this spills over into
the LWORK area, which will be corrupted after an OSHCAL call. OSHCAL
assumes that the filename (when required) is set up in FBLOCK. OSHCAL also
sets the high order addresses into the control block at OSFARA +4 and +5;
+&C and +&D; and at +&10 and +&11. ViewStore error trapping is also
enabled.
On entry: A contains reason code as for normal OSFILE
(see filing system manual).
OSFARA set up with whatever the reason code action
requires, eg. start and end addresses for
file save.
On exit: VS error occurred; error code in A.
VC completed successfully; file type in A when
relevant.
X,Y undefined.
XOSARG
XOSARG is equivalent to OSARGS, except that ViewStore error handling is
enabled.
On entry: See filing system manual for OSARGS.
On exit: VS error occurred; error code in A.
VC no error; see filing system manual for
results.
PART 2 IN THE NEXT 8BS ISSUE