In article <1990Dec10.020018.5643@mercury> Sean@nacjack.gen.nz (Sean Fausett) writes:
>[stuff deleted]
>Has _anyone_ done any programming using SmartPort calls specific to the
>Apple 3.5 disk drive? More specifically, I am after more information on
>using the "SetHook" call. The firmware reference fails to give the
>details of entry/exit conditions for hooking in your own routines....
>[more stuff deleted]

A lot of stuff about the SetHook call, unfortunately, can only be learned
by disassembling the ROMs.

The good news is that the parameters for the various "hookable" routines
are exactly as described in the SmartPort chapter of the Firmware
Reference, in the section entitled "Passing parameters to a ROM disk."

The bad news is that these routines also use a LOT of variables in bank $E1
which don't seem to be documented anywhere.

More bad news:  The firmware calls the "hookable routines" with a JSR from
bank $FF, not a JSL.  This makes returning from the hooked routine a rather
non-trivial exercise.

There are some undocumented features of ROM 01 which make life slightly
easier (I have no idea if these features still exist in ROM 3).  Each hook
actually consists of TWO vectors, not one.  The first vector of each pair
is what gets patched by SetHook, while the second remains pointing at the
original ROM routine.  However, if SetHook is called with the high bit of
the hook reference number set, then the second vector of the pair will be
changed into a JMP to an RTS in bank $FF, making it possible to return
correctly from a hooked routine.

In ROM 01, the hooks are at the following addresses:

Hook No.  Address   Function
--------  -------   --------
1         $E1/0F6F  Read Address (1st vector)
              0F73  Read Address (2nd vector)
2             0F77  Read Data (1st vector)
              0F7B  Read Data (2nd vector)
3             0F7F  Write Data (1st vector)
              0F83  Write Data (2nd vector)
4             0F87  Seek (1st vector)
              0F8B  Seek (2nd vector)
5             0F8F  Format (1st vector)
              0F93  Format (2nd vector)
6             0F97  Write Track (1st vector)
              0F9B  Write Track (2st vector)
7             0F9F  Verify Track (1st vector)
              0FA3  Verify Track (2nd vector)
8             0FA7  (See below) (1st vector)
              0FAB  (See below) (2nd vector)

The undocumented hook reference number 8 is the command dispacher.  It is
responsible for insuring that the the command number is within the proper
range and for JMPing to the appropriate SmartPort command handler.

Some memory locations that might be useful (in ROM 01--I don't know if
these are in the same place in ROM 3):

$E1/0C00-$E1/0EFF  Most of this space is used as the raw data buffer.
$E1/0F1E           Standard/extended call flag.  0=standard, $40=extended.
$E1/0F22           Track number for drive 1 (hi bit set if position unknown).
$E1/0F23           Track number for drive 2 (hi bit set if position unknown).
$E1/0F26           Seek delay counter for drive 1 (?)
$E1/0F27           Seek delay counter for drive 2 (?)
$E1/0F28           Drive number (0 or 1).
$E1/0F29           Track number to seek to (0-$5F).
$E1/0F30           Checksum of block header most recently read.
$E1/0F31           "Format" field from header of block most recently read.
$E1/0F32           "Sides" field from header of block most recently read.
$E1/0F33           Sector number of block most recently read.
$E1/0F34           Track number of block most recently read.
$E1/0F44           Error bits.
$E1/0F45           Address field retry count.
$E1/0F4B           Error code.
$E1/0F57-$E1/0F6C  Mark table.

There are a number of other variables in the $E1/0F00-0FFF area which the
ROM uses, but I haven't been able to figure out their purposes yet.

Before using any of these variables or trying to patch any of the hooks I
recommend trying to disassemble and understand some of the ROM hook
routines.  You can find the starting addresses of these routines by looking
in the hook table.  It will also be instructive to examine the 3.5 driver
main entry point, which is at $FF/6500 in ROM 0 and $FF/5600 in ROM 01.

There are also a few SmartPort Status calls which aren't documented in the
references:

Stat call no.  Function
-------------  --------
5              Return error status in the same format as for UniDisk 3.5
               Status call 5.  This works by copying $E1/0F44...$E1/0F4B
	       into buffer+1...buffer+8.  The buffer should be big enough
	       to hold 9 return bytes.
6              Returns pointer to the standard/extended byte ($1E, $0F,
	       $E1, $00).  The buffer should be big enough to hold 4 return
	       bytes.
7              Returns pointer to the raw data buffer ($00, $0C, $E1, $00).
	       The buffer should be big enough to hold 4 return bytes.

The standard disclaimer:  The above information is not guaranteed in any
way.  Use it at you own risk.

	       - Neil Parker
--
Neil Parker                 No cute ASCII art...no cute quote...no cute
parkern@jacobs.cs.orst.edu  disclaimer...no deposit, no return...
parker@corona.uoregon.edu   (This space intentionally left blank:           )