💾 Archived View for mirrors.apple2.org.za › archive › apple.cabi.net › Languages.Programming › OPIX.… captured on 2023-01-29 at 04:48:43.

View Raw

More Information

-=-=-=-=-=-=-

                     Documentation for

                         OPIX 1.00

   HyperC Operating Environment and Interpreter/Extended

      (c) 1992-93 by W. Hofbauer. All rights reserved.
         InterNet: wulf@cip.physik.uni-stuttgart.de



                         ----------
                         DISCLAIMER
                         ----------

   I (W. Hofbauer) make no warranties, either express or
implied, with respect to this documentation or the software
  it describes, its quality, correctness, performance, or
 fitness for anything. Running the software is entirely at
 the users own risk. In no event will I be held responsible
  for any damage resulting from the use of the software or
                    this documentation.


                         ---------
                         COPYRIGHT
                         ---------

  This documentation and the software it describes are the
 intellectual property of the author (me). You're free (and
    even encouraged) to use and distribute OPIX and this
 documentation, in its entirety and without modifications,
 without any royalties as long as you don't make any money
   out of it. If you want to use OPIX in a commercial or
shareware package or bundle it with one, you must ask me for
 explicit allowance first (I don't intend to make money out
           of OPIX, but then no one else should).

  Though this is unlikely to happen (after all, you're an
Apple II user!) it is nevertheless explicitly prohibited to
 use the software for programs promoting military actions,
 violence, discrimination of social, ethnic, religious, or
  sexual minorities, or actions in conflict with the human
                          rights.


                      Acknowledgements

   Writing OPIX wasn't possible without the help of other
     Apple II enthusiasts. Special thanks go to Gary F.
Desrochers and Andy Werner for their programming advice and
  constructive suggestions. Thanks also to all testers and
                   others not named here.


ProDOS, ProDOS 8, Apple ][, Apple ][+, Apple //e, Apple //c,
Apple //c+, Apple IIgs, and Apple Pascal are trade marks of
Apple Computer, Inc.
ZIP CHIP is a trade mark of ZIP Technology.




Introduction


OPIX is a runtime environment for the HyperC system. It  can
be used during program development with the HyperC tools  or
as a runtime  library for  stand alone  programs. For  those
familiar with  HyperC,  it  is  functionally  equivalent  to
OPSYS, but  fixes some  bugs and  offers some  new  features
like:

- eliminates some bugs present in OPSYS
- is about 10% faster than OPSYS
- offers an extended file system
- allows the user to install his/her own device drivers
- can reserve memory for special use
- can gain  usable memory by  decreasing number of  reserved
  file buffers
- allows for easy I/O redirection
- is configurable to support non-standard setups

As a companion to the OPIX kernel, there is the OPIX  shell.
It eliminates some minor problems with OPIX and the original
shell and has several extensions like:

- user-definable prompt
- extended file name parsing
- reports  failure  of  built-in  commands  (this  may  seem
  trivial, but it wasn't the case with the original shell)
- improved ls command
- additional commands like chmod, echo
- supports UNIX-style output redirection

The OPIX shell requires OPIX and won't run under OPSYS;  the
original WSM shell runs under OPIX with minor drawbacks.

This documentation assumes some familiarity with HyperC  and
65c02 assembly language programming;  it is not a  tutorial.
Most of the information contained  in this document is  only
of interest to programmers anyway.


Compatibility

OPIX makes use of the extended instruction set of the  65c02
processor (vs. a plain 6502).  This means that your  machine
must be equipped or upgraded with a 65c02 (65802,  65816...)
processor to  run  OPIX. Most  6502  based machines  can  be
upgraded with  a  65c02.  The ZipChips  also  support  65c02
instructions. Note  that there  are at  least two  different
flavors of the 65c02  with different instruction sets.  OPIX
should run on both, though this hasn't been tested.

OPIX, as the HyperC system in general, relies on the ability
to trap the 6502 BRK instruction. This is possible with  all
Apple II  models  except  the original  Apple  ][  with  the
"System Monitor" in ROM (if your machine boots automatically
on power-up, this doesn't apply to you). These machines  can
be upgraded to the "Autostart Monitor" by exchanging the "F8
ROM" chip. Applesoft BASIC in ROM isn't required, so you can
keep Integer Basic if you like.

As sent out, OPIX also requires an 80-column card in slot 3.
This is not too much  a restriction since some HyperC  tools
(most notably  the  editor)  are unusable  in  a  40  column
environment and most applications  blindly assume that  they
are running in an 80-column environment - before OPIX, there
were simply no provisions for HyperC programs to run without
an 80 column card. If  you install suitable device  drivers,
OPIX can run in 40-column mode, too. This would be useful in
creating stand alone programs  that don't require 80  column
displays.

OPIX uses  ProDOS 8  and  requires at  least 64K  of  memory
(ProDOS 1.0 ran on 48K machines, but you can't use it).

The following table describes what is needed on your machine
(without any guarantee for  completeness or correctness;  if
you find errors, please let me know):

Model                              Requirements

Apple ][                           1,2,3,4
Apple ][+                          2,3,4
Apple //e (original)               3,4,5
Apple //e (enhanced)               4
Apple //c
Apple //c+
Apple IIgs

Notes:
1. must be upgraded with autostart ROM
2. must be equipped with 64K RAM (48K on-board and  language
   card)
3. must be upgraded with 65c02 processor
4. should be equipped with 80-column card in slot 3
5. can be upgraded to enhanced //e (strongly recommended)


Installation and Use

To install  OPIX  on  your HyperC  work  disk,  perform  the
following steps:

1. Keep a BACKUP of your  original HyperC disk for the  case
   that something goes wrong (or  you decide that you  don't
   like OPIX). Remember Murphy: if anything can go wrong, it
   will.
2. Delete the  files C.SYSTEM,  OPSYS, and  SHELL from  your
   HyperC disk. This isn't  obligatory, but these files  are
   not needed with OPIX and take up valuable disk space.  If
   you've  been   using  GS.SYSTEM,   HC.SYSTEM,  or   other
   replacements for  C.SYSTEM,  you may  delete  them,  too.
   Newer versions of HC.SYSTEM are compatible with OPIX, but
   there is no advantage in using  them with OPIX - it's  up
   to you whether to use them or not.
3. Copy the files OPIX.SYSTEM and OPIX.SHELL to the disk. It
   is essential that both files reside in the same directory
   which will become the home directory for the shell.

To run OPIX, launch the OPIX.SYSTEM file from your selector.
That's all there is to it.

Note: OPSYS requires  the shell  to be  named "SHELL";  this
version of  OPIX  expects it  to  be named  "OPIX.SHELL"  by
default. This allows you to keep OPSYS and OPIX in the  same
directory if you like  to, each system  using its own  shell
without special precautions.

TIP: If  you're  programming  in HyperC  and  have  a  large
RAMdisk, run HyperC from it - it is MUCH faster. Personally,
I use ShrinkIt to unpack an archive containing a workdisk to
/RAM after startup. This not only makes it possible to  keep
the system on  a single 140K  disk but even  is much  faster
than copying an entire directory structure file by file.  If
you have a  small RAMdisk,  leave the HyperC  files on  your
startup disk, but make  the RAMdisk your working  directory.
Many HyperC tools generate a  LOT of temporary files in  the
working  directory;  doing   this  on  a   "real"  disk   is
slllooooowwwwww...


Description of the startup process

If OPIX doesn't  start correctly on  your machine, there  is
not too much you can do  about it yourself unless you're  an
assembly language  expert. This  paragraph  may be  of  help
however in localizing the  problem so I can  try to fix  it.
Please let  me know  if  you discover  incompatibilities  or
bugs, even if you're able to fix them yourself (someone else
might not be as clever as you!).

This   description   refers   to   OPIX   in   its   default
configuration. OPIX  may  behave differently  if  configured
(see below). It is mentioned in the copyright section, but I
want to  repeat  it: pass  OPIX  on only  in  its  original,
unconfigured state.

On startup,  OPIX  displays  a  title  screen  and  performs
several compatibility checks. If  any of these checks  fail,
an appropriate message is displayed  and - after pressing  a
key - OPIX terminates and returns to ProDOS.

If all  these  checks  are satisfied,  OPIX  checks  if  the
machine has the  original //e  ROMs and, if  so, installs  a
special  set  of  device  drivers.  This  feature  has  been
incorporated because the  original //e  ROMs contain  severe
bugs concerning the use of the 80 column card. OPIX as  sent
out uses  the BASIC  way of  accessing 80  column cards  for
several reasons (like speed and the possibility to switch to
the monitor); only on  the original //e the  Pascal/firmware
interface is used.

After this  the  OPIX  kernel  is  relocated  to  its  final
position where it stays  resident. Some initializations  are
made, and control is passed to the kernel itself.

The kernel tries to load and execute the shell. If it fails,
it will print an error message and try again.

From there on things are  controlled by the shell. Refer  to
the section describing the shell for further information.


The Extended File System

OPIX is very similar to OPSYS in many respects for the  sake
of compatibility. The  file system used  by OPSYS (which  is
really identical to ProDOS) has been extended  transparently
to include character oriented  devices like the screen,  the
keyboard, printers, modems, and so on.

Programs can  use  these  devices without  a  change.  These
so-called "device files"  are accessed in  exactly the  same
way as regular ProDOS files,  except that they have  special
file names of the form "/n" where n is an integer from 0  to
7. Earlier OPIX  prototype versions used  names of the  form
"#n" for device  files. This  has been  changed for  several
reasons.

If the I/O routines recognize a file name of this form, they
perform operations corresponding to what ProDOS would do for
disk based files.  If the  file name isn't  recognized as  a
device file name,  the I/O  request is simply  passed on  to
ProDOS (which  may report  an error  if the  file name  also
isn't a legal ProDOS name).

On opening device files, they are assigned a file descriptor
(just like ProDOS files). OPIX I/O routines that expect file
descriptors instead of file names can recognize device files
because the value range of the descriptors is disjunct  from
the ProDOS range. Don't make assumptions about the values of
these descriptors - they may change without notice.

There are  some differences  to  ProDOS files  however  that
result from the structure of character oriented devices: you
can't  seek  on  them  (they  are  purely  sequential   byte
streams), and you can't remove (delete) them. It is also not
allowed to rename them;  this could have  been added but  it
would certainly  not be  worth  the additional  overhead  in
implementing it.

A more subtle difference can cause problems however: several
programs read data until they encounter an end of file (EOF)
condition. For device files, there is never an EOF since  at
any time, new data could be entered.

Since there  is no  physical EOF,  it would  be possible  to
define one special character of the incoming byte stream  as
an EOF marker (like ctrl-C  under Apple Pascal). This  would
prohibit many  useful applications  however since  data  may
coincide with the  EOF marker. For  these reasons, there  is
never an EOF condition for device files. Keep this in mind!

One additional note: device files  don't use a file  buffer.
You can actually open more than 8 files if some of them  are
device files. You can also open the same device file several
times; there is no file locking. This could be  incorporated
into OPIX  with moderate  overhead  but I  guess it  is  not
really important in a single-tasking environment.

At the lowest level of I/O common to both ProDOS and  device
files are functions like  create(), open(), read(),  getl(),
write()  and  close().  These  functions  call  ProDOS   for
non-device files, and they call the device drivers  directly
for device files.  The structure  of the  device drivers  is
documented in a  separate chapter; you  can supply your  own
device drivers if you like to. For ProDOS files only,  there
are remove(), rename(), and seek().

All other I/O functions build up on these. There are several
such levels  of  I/O functions,  and  it is  recommended  to
always use the simplest I/O  function that will do the  job.
Above all,  escape  the habit  of  many programmers  to  use
printf() for  everything. The  putstr() function  calls  two
assembly-written functions  once; printf()  has to  parse  a
string  character  by  character  and  has  much  formatting
overhead, all in interpreted cp-code.

OPIX has  two standard  files opened  for use  by  programs:
_StdIn for  input, and  _StdOut for  output. Both  of  these
refer normally to the console, but  they can as well be  set
to different files  and such redirect  I/O. This is  similar
(though not identical) to  UNIX. Many I/O functions  operate
on these standard files; using them will often increase  the
usefulness of  programs and/or  take  some burden  off  your
shoulders as the  shell does  all the work  in selecting  an
output  file.  Changing  _StdIn  and  _StdOut  yourself   is
recommended to advanced programmers only; there are  several
more or  less obvious  caveats that  have to  be taken  into
account. The OPIX shell lets you specify _StdOut on starting
a program  and  cares  about possible  problems  in  setting
_StdOut.


BRK Trapping

The HyperC  system uses  the 65xxx  BRK instruction  (opcode
0x00)  to  activate  the  so-called  cp  interpreter   which
emulates a hypothetical  16 bit processor.  Compare this  to
the UCSD p machine. Using BRKs allows to mix native code and
cp code subroutines transparently.  It may lead to  problems
however if  for  some  reason a  "real"  BRK  (indicating  a
breakpoint) is encountered; this is of concern mainly on the
Apple IIgs where  some debugger may  be installed. For  this
reason,  BRK  handling  is  not  trivial.  There  are   some
rudimentary checks built in for the IIgs, but more  reliable
checks would  decrease the  efficiency of  the cp  code  too
much.  This is the way how OPIX traps BRKs:

On startup, OPIX  installs its  own BRK  vector at  location
0x03f0. The  old  BRK  vector is  saved  and  restored  when
leaving using  the _quit()  function. All  BRKs  encountered
will enter the cp interpreter unconditionally.

On the IIgs,  BRK handling is  more complicated for  several
reasons. OPIX installs  its own BRK  vector (in addition  to
the 8-bit BRK vector which is  set also) on the IIgs,  saves
the old vectors, and restores them on _quit(). To allow  the
use of debuggers, BRKs will enter the cp interpreter only if
the BRK occurred in 8  bit emulation mode; native mode  BRKs
will be passed on to  the routine installed before OPIX  was
started.

The BRK handling scheme for the IIgs has been contributed by
Gary F. Desrochers.

Note that you  can't get  around BRK trapping,  even if  you
compile your programs to native code. Many functions of  the
OPIX  kernel  are  in  cp  code  for  the  sake  of   memory
efficiency.


Other Differences to OPSYS

The resident functions in OPIX  are essentially the same  as
in OPSYS with  the entry addresses  unchanged. Most of  them
achieve the same overall result  as the OPSYS functions  but
differ in  some  details.  A  description  of  all  built-in
functions is supplied in a separate document.

OPIX works also differently under certain other aspects like
loading and executing programs. It also has some  structural
differences, mainly concerning the I/O functions. As long as
you're not using special tricks  in your programs that  make
keen assumptions  about  how things  work,  it is  not  very
likely that your programs  developed under OPSYS don't  work
under OPIX. Remember that the HyperC tools which are without
doubt quite complex programs run fine with OPIX.

There are very  few OPSYS functions  that are not  supported
any more  under  OPIX  for technical  reasons  (for  example
_prtvid()), and several others still work, but should not be
used any more because they're either considered bad style or
are inconsistent with other  related functions (for  example
_setPath()).  Refer  to  the   OPIX  docs,  and  don't   use
undocumented functions.


Configuring OPIX

In contrast to OPSYS, OPIX has some limited configurability.
The structure and working of  OPIX is largely determined  by
OPSYS for the sake of  compatibility, and there is not  much
to configure. There  are however  some aspects  that can  be
controlled by the user:

- You may  supply your  own device drivers  if the  standard
  ones are not compatible with your system or if you want to
  support additional devices.

-  You  may  specify  the  initial  values  of  some   flags
  concerning the printer driver.

- You may set aside some memory for special purposes limited
  only by your imagination.

- You may  specify how  much memory should  be reserved  for
  file buffering. For a given application, you can gain much
  memory (1K per  buffer) if  you lower the  number of  file
  buffers to the required minimum.

- You may  disable the installation  of special driver  code
  for the original //e if your own drivers can cope with all
  models.

- You may disable  the check for an  80 column card if  your
  drivers don't rely on one.

- You may specify the name of the startup program  (normally
  the shell).

- You may disable the title screen.

The greater part of these modifications is useful mainly for
creating  stand  alone  applications.  You  can  give   your
application a more  meaningful name  than "OPIX.SHELL"  (and
thus keep several applications  in the same directory);  you
can gain  memory; you  can  write programs  that run  in  40
column environments, and  you can  make sure  that the  OPIX
title screen doesn't look more impressive than your own.

If your  printer doesn't  work correctly  with the  standard
printer flag values  you also may  change their defaults  so
you don't have to modify them on every startup. These  flags
control whether line feeds are added after carriage  returns
and if TAB characters are expanded into spaces before  being
sent to the printer.

All these  modifications are  handled  by the  supplied  CFG
program. It is menu-driven and quite self-explanatory. It is
not further documented  in this  manual; if  you don't  know
what the options of the CFG program do after having read the
online hints, better leave your hands off. You CAN configure
OPIX in  a way  it  can't recover  from,  and a  minimum  of
technical knowledge is required to prevent this.

The configuration data is stored inside the OPIX.SYSTEM file
(or a copy of  it, which is  of course highly  recommended).
Don't let your owen programs mess around with the code.  The
locations of  the configuration  parameters may  change  and
they shouldn't be  accessed by  anything else  but CFG.  All
modifications that are less than a hack can be done with the
CFG program.

I've been  asked how  to install  different cp  interpreters
which would be useful on machines with 16 bit processors. As
of now, this  is not supported;  this would require  massive
patching and is highly version dependent. I'm thinking about
it however, and future versions of OPIX may have the ability
to link  your own  cp interpreter  to the  code (thank  you,
Andy!).


Writing Your Own Device Drivers

OPIX gives you  one page  (256 bytes) of  memory to  squeeze
your driver  code in.  This is  not too  much, but  it  will
suffice for most  setups (the standard  driver set  supports
the 80-column screen, a printer in slot 1, a device in  slot
2 and a null-device; there is still memory left). You  could
also reserve some memory above  the file buffers (using  the
CFG program) and install parts of your driver code there  if
you absolutely must.

After relocation,  the device  driver  code will  reside  at
0x1f00..0x1fff. You must assemble/link your code with  these
addresses in mind.

The driver for a specific device is called via a jump  table
at 0x1ff0..0x1fff. Each driver should support the  following
actions: initialization, reading a byte, writing a byte, and
a status request. In any case, you must return an error code
in the x register  (0 meaning "no  error"). The protocol  is
quite similar to the Pascal/firmware protocol for  interface
cards (no coincidence). Note that  the device number is  not
necessarily identical to the slot the device is in.

INIT:    To perform an INIT, your driver will be called with
         a 1 in the y register. Your driver should make some
         initializations if necessary to prepare the  device
         for reads/writes.

READ:    When  your driver gets called with  a value of 2 in
         the y  register, it  should read  a byte  from  the
         device and return it in the accumulator. ASCII data
         should be returned with bit 7 cleared.

WRITE:   To perform a WRITE, your driver will be called with
         a 3 in the y register. The byte to be written is in
         the accumulator. ASCII data has bit 7 cleared.

STATUS:     This  call   is  currently   not   used  by   OPIX.
         Nevertheless, you should implement it. Your  driver
         will be called with a value of 4 in the y register;
         the accumulator contains a one or a zero. If  a==1,
         return with the carry set if there is input  ready;
         if a==0, return with the carry set if the device is
         ready to accept output.

Your driver must in any case  return an error code in the  x
register. This code is used by  OPIX in the same way as  the
ProDOS MLI error code. Typical values are:



x=       meaning
0x00     no error
0x03     illegal request
0x28     no device connected

There are two other activities that are device dependent and
consequently up to your driver code: positioning the  cursor
and retrieving the  cursor position. I  expect the  standard
drivers to work on most machines, but there is no legal  way
to set and retrieve  the cursor position  in 80 column  mode
reliably, and Murphy dictates that you are the one hitten by
an incompatibility. The  cursor position will  be passed  on
the cp-stack  and  should  be returned  in  the  cp  machine
accumulator. It is encoded  as a word  with the LSB  meaning
the  x  coordinate  (starting  at  0)  and  the  MSB  the  y
coordinate (also starting at 0).

Your code must total  256 bytes, consist  of a TEXT  section
only, and be  linked to absolute  address 0x1f00;  otherwise
CFG won't let you install it. Several addresses are  defined
to interface your drivers to the kernel:

Address     Contents

0x1fec      jump vector to getcurs routine
0x1fee      jump vector to setcurs routine
0x1ff0      vector to /0 driver (must be the console)
0x1ff2        vector to  /1 driver (should  be the printer  if
one exists)
0x1ff4      vector to /2 driver
...         ...
0x1ffe      vector to /7 driver

It is essential that the vectors for unused devices point to
a routine returning an  error (0x28) in  the x register,  or
OPIX may crash if  you try to  access a non-existent  device
file. Take  a  look at  the  supplied source  code  for  the
standard drivers, I've commented it extensively.

To install your drivers, use the CFG program and follow  the
on-screen instructions. You can install both drivers for the
original //e and  the other machines  independent from  each
other.


OPIX Memory Usage

This section describes the  memory regions used or  reserved
by OPIX.  Take this  information into  account when  writing
assembly routines.

It is  recommended  to  have the  code  and  data  addresses
assigned by the linker to avoid memory conflicts. Zero  page
addresses can't  be  allocated  by the  linker;  it  is  not
recommended to keep any static data in page zero  therefore.
If  you  do  otherwise,  there  may  be  collisions  between
different routines. If  possible, use the  scratch space  at
0x00..0x1f for  local,  non-static data.  Be  prepared  that
other routines called may change these locations also.

ProDOS saves and restores parts of page zero, so you may not
use some locations in interrupt routines. Also, OPIX is  not
reentrant, so don't call it on interruptions.

Generally avoid  tweaking  system  variables.  If  you  must
change  them,  be  very  careful.  The  integrity  of   many
locations is  essential  for  the  operation  of  OPIX,  and
changing   these   without   complete   knowledge   of   the
implications this may  have is almost  certain to crash  the
system sooner or later.

The memory map as shown below refers to OPIX in first place.
For monitor or ProDOS locations, refer to the  documentation
available (?) from Apple.

The above recommendations  are somewhat restrictive.  You're
free to ignore them if you choose to, but keep in mind  that
these  rules  help  protect  you  from  many  annoying   and
difficult to find bugs.


Address           Usage

0x0000..0x001f    scratch space
0x0020..0x0055    used by the monitor and in part by OPIX
0x0056..0x00c5    unused
0x00c6..0x00e5    cp  machine  "display"  registers  for  16
                  lexical levels
0x00e6..0x00eb    cp machine work space & flags
0x00ec..0x00ed    cp machine b register
0x00ee..0x00ef    cp machine  accumulator;  return  function
                  results in it
0x00f0..0x00f1    cp machine program counter
0x00f2..0x00f3    cp machine frame pointer (base register)
0x00f4..0x00f5    cp machine stack pointer
0x00f6..0x00ff    unused
0x0100..0x01ff    65c02 machine stack
0x0200..0x023f    thrashed by the ProDOS clock routine
0x0240..0x027f    OPIX shell prompt string
0x0280            reserved
0x0281..0x02bf    shell pathname
0x02c0..0x02ff    shell search path
0x0300..0x037f    pointers for parameter passing
0x0380            _ioresult (I/O error code)
0x0381            _sysfd (file descriptor of running program
                  used by the overlay loader - DON'T CHANGE)
0x0382            _prtpos (horizontal position used by printer
                  driver)
0x0383            _pcrlf (printer driver flag, bit 7 set adds
                  LF to CR; bit 6 set expands TABs into
                  spaces)
0x0384..0x0385    _exitVal (exit value returned by program;
                  of little use to applications since
                  cleared on program startup)
0x0386..0x0387    _pname (pointer to pathname of current
                  program)
0x0388..0x0389    _errHdlr (pointer to error handling
                  routine; can be set to trap fatal errors
                  or user breaks)
0x038a..0x038b    _heapBase (for memory management - DON'T
                  CHANGE)
0x038c..0x038d    _heapTop (for memory management - DON'T
                  CHANGE)
0x038e            _StdIn (standard input file; setting it
                  correctly is involved)
0x038f            _StdOut (standard output file; setting it
                  correctly is involved)
0x0390            _cmdfd (file  descriptor of shell script
                  file - DON'T CHANGE)
0x0391            _cargc (script argument count - DON'T
                  CHANGE)
0x0392..0x03df    reserved for future use
0x03e0..0x03e1    _BrkSave (saved BRK vector - DON'T CHANGE)
0x03e2..0x03e5    _BrkSaveGS (saved IIgs BRK vector - DON'T
                  CHANGE)
0x03e6            _StkTop (first page above cp stack - DON'T
                  CHANGE)
0x03e7            _MemTop (first page above file buffers -
                  DON'T CHANGE)
0x03e8..0x03e9    _subVersion (minor OPIX version and
                  identification value)
0x03ea..0x03ec    reserved for future use
0x03ed..0x03ee    used by AuxMem XFER routine
0x03ef            reserved for future use
0x03f0..0x03f1    BRK vector - DON'T CHANGE
0x03f2..0x03f3    RESET vector
0x03f4            RESET vector validation byte
0x03f5..0x03f7    reserved for future use
0x03f8..0x03fa    JMP to monitor ctrl-y service routine
0x03fb..0x03fd    JMP to NMI routine
0x03fe..0x03ff    IRQ vector - DON'T CHANGE
0x0400..0x07ff    text video page #1 & screenholes
0x0800..0x1eff    resident OPIX kernel
0x1f00..0x1fff    OPIX device drivers
0x2000..0x9dff    available memory for programs & data
                  (upper bound configuration dependent)
0x9e00..0xbdff    OPIX file buffer pool (standard
                  configuration)
0xbe00..0xbeff    memory reserved for shells usage (standard
                  configuration)
0xbf00..0xbfff    ProDOS global page


The OPIX shell

The OPIX.SHELL file distributed with OPIX is a simple  shell
specifically written for OPIX. It isn't fancy, but at  least
as useful as the original WSM shell in working with HyperC.

On startup, the  OPIX shell displays  a welcome message  and
tries to execute a program or script file (see below)  named
"profile". You can use this to make your own initializations
on startup. If "profile" is  not found, you'll get an  error
message - just ignore it.

You communicate with  the shell by  entering command  lines.
Command lines follow some simple rules:

- A command line starting with  a ';' is regarded a  comment
  and will be ignored (this makes sense in script files).
- Blank lines are ignored.
- Command lines are separated into several items by  spaces.
  If you  want one  item to  include spaces,  enclose it  in
  quotes. You may  also precede characters  by a  backslash,
  and they will be taken  literally (and not interpreted  as
  delimiters). In addition,  the following conversion  codes
  are supported:
    \n      carriage return (0x0d)
    \r      carriage return (0x0d)
    \f      form feed (0x0c)
    \e      escape (0x1b)
    \b      backspace (0x08)
    \a      bell (0x07)
    \\      backslash (\)
    \"      quote (")
- If the last item of the command line begins with a '>', it
  will be removed and the screen output of the command  will
  be redirected to the file specified immediately behind the
  '>'. The output  file will  be created;  an existing  file
  with the same name will be lost.
- The first item is compared to a list of built-in commands.
  If  a  match  is  found,  the  internal  command  will  be
  executed, using  the remaining  items as  parameters.  All
  internal commands  are lower-case  only;  if you  want  to
  execute a  program  whose  file  name  coincides  with  an
  internal command, just type it in upper case.
- If the  first item is  not a built-in  command, the  shell
  tries to  execute a  file with  this name  and passes  the
  remaining items as  arguments. The shell  takes care of  a
  search path (see below).


Script files

Script  files  are  used   to  perform  often-used   command
sequences (such  as compiling,  assembling and  linking a  C
program) automatically.

Files that aren't recognized  as executable HyperC  programs
(by checking the first two bytes  of the file which must  be
0x00 and 0x01) are  treated as script  files when trying  to
execute them,  and the  subsequent command  lines are  taken
from them. Script files can't  nest; if you call one  script
file from another one, the old file will be closed, then the
new file will be executed.

Script files  can use  command  line arguments.  Whenever  a
dollar sign ($) followed by  an integer appears in a  script
line, it  is  literally  substituted  by  the  corresponding
command line argument when the  script file was invoked.  $0
is the script file name, $1 and on represent the  arguments.
If you specify less arguments that the script file  expects,
the undefined arguments are considered null strings. On  the
other hand, you can specify more arguments than are actually
used, and they will be ignored.


File specifications

The OPIX shell  does some  elementary file  name parsing  on
most commands. If you specify a full pathname (starting with
a slash), it is used without modification. Otherwise, it  is
concatenated to the current working directory path.

You can also specify  ".." as a  directory name anywhere  in
the path. This will step back one directory.

Example: when your current directory is  "/hd/hyperc/games",
the file specification  "../bin/test" will  access the  file
"/hd/hyperc/bin/test".


List of built-in commands

Command: version
Description: This command writes  shell version data to  the
standard output.

Command: ls {-{l}} {<directory>}
Description: This  command  lists  the files  of  the  given
directories,  or  of  the  working  directory  if  none   is
specified. If the -l flag is present, the file access  bits,
file size,  and creation/modification  dates and  times  are
listed, too. If no working directory (prefix) is set (or you
specify "/" as  directory name) all  online volumes will  be
listed.

Command: rm <file>
Description: This command removes (deletes) a file.

Command: md <directory>
Description: This command creates a new directory.

Command: ren <old> <new>
Description: This  command  renames  a file  from  <old>  to
<new>. This is not the same as an UNIX "mv" as the file must
remain in its old directory.

Command: cp <from> <to>
Description: This command copies a file from <from> to <to>.
The copies contents will be  identical to the original,  but
the file attributes aren't  copied. The resultant file  will
be a ProDOS TXT file.

Command: echo {<anything>}
Description: This  command  echoes  its  parameters  to  the
standard output. It is mainly used to display messages  from
within script files. Use "echo \f" to clear the screen.

Command: ?
Description: This command  lists the names  of all  built-in
commands as a quick reminder.

Command: bye
Description: This command terminates both the shell and OPIX
and returns to ProDOS.

Command: prompt <prompt>
Description: This command  sets the command  line prompt  to
what you like. Some  prompts aren't recommended... try  this
one: "prompt \f" ;-)

Command: path [<path>]
Description: This command sets  (if specified) and  displays
the current shell search path. The search path is a list  of
directory specifications or  null strings (meaning  "current
directory") separated  by vertical  bars  (|) that  will  be
searched consecutively for external commands.

Command: pwd
Description:  This  command  displays  the  current  working
directory (ProDOS prefix).

Command: cd [<directory>]
Description: This command selects  a new working  directory.
If no argument  is specified,  the OPIX  root directory  (in
which OPIX.SYSTEM and OPIX.SHELL reside) is used.

Command: chmod {+|-{rwnd}} <file>
Description: This command modifies  the file access bits  of
the specified ProDOS file. Options prefixed with a '+'  will
set the corresponding bit  (allow access); options  prefixed
with a '-' will clear  it (deny access). The option  letters
stand for Read,  Write, reName, and  Delete. You can  verify
these options with the "ls -l" command.

Error  messages  indicating  trouble  with  I/O   operations
generally give you an error  number in parentheses. This  is
the ProDOS MLI  return code  or the driver  return code  for
device files. It may be  helpful in identifying what  caused
the error.