While somehow trapping PR# and IN# Applesoft commands would be nice (to get
serial port support via the PC), it does not appear likely.
Most likely is a set of programs to emulate disk accesses from either the real
Apple or the emulated one. i.e. To be able to read emulated Apple disks on the
PC from the real Apple as if they were local disks. Both DOS and ProDOS would
be supported.

Also to be considered might be the emulator remotely operating hardware on the
Apple.

As a benchmark, I booted Summer Games 1. On the Apple, it took 11 seconds to
get to the opening ceremonies. Using the emulator and remote disk I/O it took
2 minutes 44 seconds. This is about right, given that the Apple disk drive
transfers at about 32K/sec and my comms at about 2K/sec.

Apple<-->Apple Emulator Disk I/O
================================

Overview
--------

This refers to the support for translation of local disk I/O (be it on the real
or emulated Apple) into remote disk I/O (on the emulated or real Apple).

There are two possible scenarios:
  1. The real Apple is the 'local' and the emulated Apple the 'remote'. In this
     case, disk I/O on the real Apple is actually performed by the emulated
     Apple. That is, a user might type CATALOG,S5,D1 on the real Apple, which
     accesses the disk file UTIL.DSK on the PC.
     The real Apple is acting as a data requester, and the emulated Apple is
     acting as a data provider. Note that the emulated Apple may simply be a
     server program running on the PC.
  2. The emulated Apple is the 'local' and the real Apple the 'remote'. In this
     case, disk I/O on the emulated Apple is actally performed by the real
     Apple. That is, a user might type CATALOG,S5,D1 on the emulated Apple,
     which accesses a disk in a Disk ][ drive connected to the real Apple.
     The emulated Apple is acting as a data requester, and the real Apple is
     acting as a data provider.

This is a classic Client/Server relationship: the Client being the data
requester and the Server being the data provider. It is always the Client (data
requester) that initiates communications, never the Server (data provider).

Implementation (Apple Server --> PC Client)
--------------

The real Apple is the data provider. The server program is continually running
and scanning the communications port for data requests. No other Apple programs
may run.

The PC is the data requester. The requester will usually be an emulated disk
controller card 'installed' in the emulated Apple. It may also be a disk/file
utility used to manage emulated Apple disks.

The PC may make requests for any form of information (i.e. sectors, blocks,
tracks). The server on the Apple must be able to provide the data in the
requested format, whatever the resident OS.

Implementation (PC Server --> Apple Client)
--------------

The real Apple is the data requester. This is achieved by intercepting
operating system disk requests and transmitting them to the PC. The PC replies
with the requested data which is passed back to the operating system.

DOS 3.3 support is achieved by redirecting RWTS calls to the requester. ProDOS
support is achieved by setting disk device vectors in the ProDOS Global Page to
point to the requester.

The disk I/O intercepter on the Apple must stay resident at all times. The PC
server program is likely to be a stand-alone program, separate from the Apple
emulator.

The data requester on the Apple will always request information in the form
required by the resident OS (i.e. a requester running under DOS 3.3 will always
request sectors, a requester running under ProDOS will always request blocks).

Communications Protocol
-----------------------

When data is requested by a Client, the format is specified (it will ask for a
particular sector, block or track). The Server must respond with the data in
the requested format.

Protocol Detection
------------------

To allow detection of the remote disk protocol, the following data may be sent:

RMTDISK?

If the remote computer is processing remote disk I/O requests, it will reply
with:

RMTDISK!

Block Format
------------

Data is transmitted separately from the requests and replies.

Note that some fields are always present, but unused. This means that all
fields are in absolute locations relative to the start of the data and is to
allow for easy future expansion.

Format of Data:
Offset - Description
  $0   - Bit    7: Type                  0=Request
                                         1=Acknowledge
         Bits 6-3: unused
         Bits 2-0: Command:            000=Read Track
                                       001=Write Track
                                       010=Read Write Protect
                                       011=Drive On
                                       100=Drive Off
                                       101=Recalibrate
                                       110=unused
                                       111=unused
  $1   - Bits 7-6: unused
         Bits 5-4: Disk Address Format: 00=DOS 3.3 Track/Sector
                                        01=ProDOS Block
                                        10=Disk ][ Track only
                                        11=unused
         Bit    3: Drive:                0=Drive 1
                                         1=Drive 2
         Bits 2-0: Slot:               001=Slot 1
                                       010=Slot 2
                                       011=Slot 3
                                       100=Slot 4
                                       101=Slot 5
                                       110=Slot 6
                                       111=Slot 7
  $2   - Track  #/Block(low byte)
  $3   - Sector #/Block(high byte)
            Always present, but unused in Track Only format.
  $4   - Error code $0=OK, data follows for Read Replies, otherwise no data
                    $1=I/O error
                    $2=no device
                    $3=write protected
            Always present, but only used in Read Replies and Write
            Acknowledgements.

Track/sector format data will always be 256 bytes long.
Block format data will always be 512 bytes long.
Track only format data will be in two parts (6656 bytes will not fit in the
maximum 4096 byte block size). The first part will be 4096 bytes, immediately
followed by the second part of 2560 bytes.

Protocol Examples
-----------------

In all the examples below, the slot is 6 and the drive is 1.

Separate blocks are delimited by []. xx denotes a fill-in byte which is
ignored, and ee denotes a non-zero error number.

The local program wants to read Track $11, Sector $F. The following is
transmitted to the remote:
[00 06 11 0F xx]
The remote should reply with:
[80 06 11 0F 00] [n1 n2 n3 ... n256]     on success, or
[80 06 11 0F ee]                         on error

The local program wants to read Block $6. The following is transmitted to the
remote:
[00 16 06 00 xx]
The remote should reply with:
[80 16 06 00 00] [n1 n2 n3 ... n512]     on success, or
[80 16 06 00 ee]                         on error

The local program wants to read Track $22. The following is transmitted to the
remote:
[00 26 22 xx xx]
The remote should reply with:
[80 26 22 xx 00] [n1 n2 n3 .. n4096] [n4097 .. n6656] on success, or
[80 26 22 xx ee]                         on error

The local program wants to write to Block $2. The following is transmitted to
the remote:
[01 16 02 00 xx] [n1 n2 n3 ... n512]
The remote should reply with:
[81 16 02 00 00]                         on success, or
[81 16 02 00 ee]                         on error

The remote requests a read from Track $0, Sector $0. The following is received
by the local:
[00 06 00 00 xx]
The local should respond with:
[80 06 00 00 00] [n1 n2 n3 ... n256]     on success, or
[80 06 00 00 ee]                         on error

The remote wants to write to Block $53. The following is received by the local:
[01 16 53 00 xx] [n1 n2 n3 ... n512]
The local should respond with:
[81 16 53 00 00]                         on success, or
[81 16 53 00 ee]                         on error

The remote wants to write to Track $16. The following is received by the local:
[01 26 16 xx xx] [n1 n2 n3 .. n4096] [n4097 .. n6250/n6566]
The local should respond with:
[81 26 16 xx 00]                         on success, or
[81 26 16 xx ee]                         on error
