***************************************************************************
NO Claim of "full accuracy" nor "liability" to the following - this is as
much "public" info as I have currently -- For the "guy, who wants or needs
to know"	B.E.
***************************************************************************
SUBJ:  MS-DOS Disk I/O control function

The  following document describes the disk interfaces for doing direct  disk
I/O.  The hard disk may be accessed by  the  normal  MS-DOS  IOCTL  function
calls.   The floppy disk interface is different depending upon which version
of MS-DOS you are using (V2.01 vs.  V2.05).


Hard Disk IOCTL function 44H (INT 21H):

	AH = 44H

	AL = function code; must = 4 or 5

	BL = Drive
		(0 = Default, 1 = A, 2 = B, etc.)
		(Drive E, F, G, H are for the Hard Disk)

	DS:DX = Block pointer



	BLOCK+0		DB	Function code
			0 - Read sector
			1 - Write sector
			2 - Write sector with verify
			3 - Format track
			4 - Media check
			5 - Verify disk

	BLOCK+1		DB	MS-DOS drive code or FF if physical unit
				(0 = drive A, 1 = B, etc. **Note 1**)
	BLOCK+2		DB	Sector number (**Note 2**)
	BLOCK+3		DB	Unit number in high nybble
				Head number in low nybble
				Ignored if drive code .NE. FF

	BLOCK+4		DW	Track number
	BLOCK+6		DW	Sector count
	BLOCK+8		DW	Offset of user buffer
	BLOCK+10	DW	Segment of user buffer
	BLOCK+12	DW	Returned data (**Hard disk only**)
				Error code returned by driver,
				else 00 if successfully.


NOTE 1:

Drive  code in BL is different from Drive code in BLOCK+1.  Drive code in BL
is to direct the MS-DOS BDOS to the appropriate disk driver.  Drive code  in
BLOCK+1 is the actual drive code that will be used.

NOTE 2:
	Logical operation (if drive code not equal to 0FFH)
1. first track number is offset relative to the partition
2. first sector number will be converted in skew table
3. multi-sector read/write uses the skew table
4. items 2 and 3 are not applied to the first 2 tracks
   on each partitiosk:

    RECOVER <drive-letter>:

    This will cause a scan to be made of the drive's  FAT  for
    chains of  allocation units (files).  A new root directory
    is then written that has entries  of  the  form  FILEnnnn.
    Each  FILEnnnn  will  point  to  the  head  of  one of the
    allocation unit chains.

    If there are more chains than  directory  entries  in  the
    root, RECOVER prints a message and leaves the un-RECOVERED
    chains in the FAT so that RECOVER can be  run  again  once
    some room has been made in the ROOT.




DEBUG ON MS-DOS 2.0


    When 2.0 DEBUG is invoked it  sets  up  a  program  header
atoffset 0  in its program work area.  On previous versions it
was OK to overwrite this header with impunity:  this  is  true
of  the  default  header  set  up if no <filespec> is given to
DEBUG.  If DEBUGging a .COM or .EXE file, however, you must be
careful  not  to  tamper  with the header of the program below
address 5CH, to do this will probably result in a  crash.   It
is  also  important that an attempt is not made to "restart" a
program once the  "program  terminated  normally"  message  is
given.  The program must be reloaded with the N and L commands
in order for it to run properly.

NEW FEATURES

The A (Assemble) Command

FORMAT:    A [<address>]

PURPOSE:   To assemble 8086/8087/8088 mnemonics directly into
           memory.

o   If a syntax error is encountered, DEBUG responds with

               ^ Error

    and redisplays the current assembly address.

o   All numeric  values  are  hexadecimal  and  may be entered
    as 1-4 characters.

o   Prefix mnemonics must be entered in front  of  the  opcode
    to  which  they  refer.   They  may  also  be entered on a
    separate line.

o   The segment override mnemonics  are  CS:,  DS:,  ES:,  and
    SS:

o   String manipulation  mnemonics  must  explictly  state the
    string size.  For example,  the  MOVSW  must  be  used  to
    move word  strings  and  MOVSB  must;; The following is a tiny Prolog interpreter in MacLisp
;; written by Ken Kahn and modified for XLISP by David Betz.
;; It was inspired by other tiny Lisp-based Prologs of
;; Par Emanuelson and Martin Nilsson.
;; There are no side-effects anywhere in the implementation.
;; Though it is VERY slow of course.

(defun prolog (database / goal) ;; a top-level loop for Prolog
  (while (setq goal (read))
    (prove (list (rename-variables goal '(0)))
           '((bottom-of-environment))
           database
           1)))

(defun prove (list-of-goals environment database level)
  ;; proves the conjunction of the list-of-goals
  ;; in the current environment
  (cond ((null list-of-goals)
         ;; succeeded since there are no goals
         (print-bindings environment environment)
          ;; the user answers "y" or "n" to "More?"
         (! (y-or-n-p "More?")))
        (t (try-each database database
                     (tail list-of-goals) (head list-of-goals)
                     environment level))))

(defun try-each (database-left database goals-left goal environment level
                 / assertion new-enviroment)
 (cond ((null database-left)
        ()) ;; fail since nothing left in database
       (t (setq assertion
                 ;; level is used to uniquely rename variables
                (rename-variables (head database-left)
                                   (list level)))
          (setq new-environment
                (unify goal (head assertion) environment))
          (cond ((null new-environment) ;; failed to unify
                 (try-each (tail database-left) database
                           goals-left goal
                           environment level))
                ((prove (append (tail assertion) goals-left)
                        new-environment
                        database
                        (+ 1 level)))
                (t (try-each (tail database-left) database
                             goals-left goal
                  