T according to the identity of the individual user.
.sp
.ix Unauthorized Access Protection
LOGOFF can be customized to match the needs of the local installation. If
LOGOFF is present, users should terminate their session by running it, so it
may guard the terminal against unauthorized access by the next user.
.in 0
.pa
SAMPLE PRIMITIVES IN M680C CODING STYLE
.ix 680C Coding Style Sample Primitives
.sp
.ix INTVECTOR
.ix SYSTEMSPACEINTPTR
.ix SDOS:IOINT
The word at INTVECTOR contains the address of the routine currently
servicing maskable interrupts. The word at SYSTEMSPACEINTPTR contains the
address of the routine which is to service interrupts in the system address
space-- this normally will point to SDOS:IOINT, but see the SDOS User's
Manual for more detail.
.sp
.lm 2
.im 3
     SPSAVE     EQU       $F1          ; in both user and system spaces

                ; The following variables need be present only in system space
.im 8
     REMAININGQUANTUM
                FCB       0            ; # CLOCK TICKS LEFT IN USER TIME SLICE
                          ; <0 --> OVERRUN OF USER TIME SLICE
     QUANTUM    FCB       0            ; ORIGINAL QUANTUM SET BY SETQUANTUM
     MINQUANTUM FCB       0            ; MINIMUM NUMBER OF TICKS A USER GETS
     CHEATEDQUANTUM
                FCB       0            ; HOW MUCH OF T/S USER WAS CHEATED OF

.im 11
     TIMEOUTBLOCK ; USED BY SETFUSE/TESTFUSE
                FDB       NEXTIMEOUT   TIMEOUT BLOCK USED FOR "xxxFUSE"
     TIMEOUTCOUNT
                FDB       0
                FDB       FUSEBURNEDUP

                IF        M6800!M6801
                RMB       7            space for NMI context block
                RMB       8            space for interrupt system to use
                RMB       7            space for IRQ context block
                RMB       16           space for COPYTOUSER,COPYTOSYSTEM
.im 6
     CONTINUESTACK ; STACK USED AS SUBSTITUTE FOR USER STACK
                FCB       $FF          DUMMY BYTE FOR 6800'S FUNNY SP
                FCB       $FF          DUMMY CC WITH INTERRUPTS DISABLED
                FCB       0,0          DUMMY B,A REGISTERS
                FDB       0            DUMMY X
                FDB       USERRTI      WHERE RETURN TO AFTER SERVICING INTERRUPT
.im 13
                ELSE      (M6809)
                RMB       12           space for NMI context block
                RMB       8            space for interrupt system to use
                RMB       12           space for IRQ context block
                RMB       16           space for efficient COPYTOUSER,
                                       ;COPYTOSYSTEM to use
     CONTINUESTACK ; STACK USED AS SUBSTITUTE FOR USER STACK
                FCB       $FF          dummy CC with IRQ, FIRQ disabled
                FCB       $0A,$0B,$00  dummy A, B and zero DPR register
                FDB       0,0,0        dummy X, U, and Y
                FDB       USERRTI      WHERE TO RETURN AFTER SERVICING
                                       INTERRUPT
                FIN
.im 3

     TIMESLICEUP ; HOLDS WHERE TO GO ON EXPIRED TIMESLICE
                RMB       2
.pa
.im 34
     USERSPACESYSCALL    ; USER SYSCALL TRANSFERS CONTROL HERE
                         ; PUSH REST OF CONTEXT BLOCK
                IF        M6800!M6801
                PSHX                   PUSH (X)
                LEAS      -2,S         PUSHED TRASH FOR (A,B)
                CLRA                   MAKE AN INTERRUPT-ENABLED CC
                PSHA                   PUSH (CC)
                IF        M6800
                NOP                    NO SURPRISES, PLEEZ...
                FIN
                SEI
                STS       SPSAVE       SAVE USER STACK IN HIS SPACE
                ELSE      (M6809)
                PSHS      A,B,DP,U,X,Y      PUSH MOST OF CONTEXT BLOCK
                LDA       #$80              SET 'ENTIRE' AND ZERO CARRY
                PSHS      A
                CLRA                   ENSURE DPR IS ZERO
                TFR       A,DP
                SEI
                STS       SPSAVE
                FIN
                LDS       #CONTINUESTACK    SWITCH TO A SAFE STACK POINTER
                JSR       TURNONSYSTEM      ENABLE THE SYSTEM SPACE
     ; NOTE: IF TURNONSYSTEM IS CODED INLINE, LDS CONTINUESTACK IS NOT NEEDED
                LDX       SYSTEMSPACEINTPTR TELL THE INTERRUPT SYSTEM
                STX       INTVECTOR
                LDS       SPSAVE       SWITCH TO SYSTEM TASK'S STACK POINTER
                CLI                    LET THE SUN SHINE AGAIN
                LDAA      REMAININGQUANTUM  TELL /MT HOW MUCH TIMESLICE...
                ADDA      CHEATEDQUANTUM    REMAINS FOR THIS USER
                RTS                    RETURN CONTROL TO SYSTEM TASK

     USERSPACEINTERRUPT ; AN INTERRUPT OCCURRING WHILE USER RUNNING COMES HERE
                STS       >SPSAVE       CONTEXT BLOCK IS PUSHED, SAVE USER SP
.IM 2
                                        ;EXTENDED STORE REQUIRED BECAUSE USER
                                        ;DPR IS UNDEFINED
.im 5
                LDS       #CONTINUESTACK SWITCH TO A SAFE STACK POINTER
                JSR       TURNONSYSTEM      ENABLE THE SYSTEM SPACE
                LDX       SYSTEMSPACEINTPTR TELL THE INTERRUPT SYSTEM
                STX       INTVECTOR
                JMP       0,X          GO TO SYSTEM SPACE INTERRUPT ROUTINE
.pa
.im 8
     RETURNTOUSER ; SYSTEM TASK PASSES CONTROL HERE TO LET USER CONTINUE EXECUTION
                STS       SPSAVE       SAVE SYSTEM TASK'S STACK POINTER
                IF        M6800
                NOP                    NO SURPRISES, PLEEZ...
                FIN
                SEI
                LDS       #CONTINUESTACK GET A SAFE STACK POINTER
                          ; (not necessary if TurnOnUser doesn't need stack)
.im 10
     USERRTI ; CONTROL PASSES HERE TO SWITCH ON USER SPACE
             ; AND CONTINUE AFTER USER SPACE INTERRUPT
             ; ASSERT: DPR IS ZERO
                LDA       REMAININGQUANTUM  ANY TIME LEFT FOR THIS USER ?
                BLE       TIMESLICEEXPIRED  B/ NO, KILL HIM!
                JSR       TURNONUSER        YES, FIRE HIM UP!
                LDX       #USERSPACEINTERRUPT LET THE INTERRUPT SYSTEM KNOW
                STX       INTVECTOR
                LDS       SPSAVE            PICK UP USER'S STACK POINTER
                RTI
.sp
.im 6
     TIMESLICEEXPIRED ; USERRTI OCCURRED, BUT QUANTUM IS EXPIRED
                LDS       SPSAVE       SWITCH TO SYSTEM TASK'S SP
                CLI
                ADDA      CHEATEDQUANTUM    tell/MT how much time left for user
                LDX       TIMESLICEUP       where to go...
                JMP       0,X               go there!

.im 20

     SETQUANTUM ; (A) = DESIRED USER T/S, (B) = MINIMUM USER T/S
     ;       (X) --> WHERE TO GO WHEN USER T/S COMPLETE
                STX       TIMESLICEUP
                STAB      MINQUANTUM
                STAA      QUANTUM
                CLR       CHEATEDQUANTUM    ; = TICKS USER WAS CHEATED OF
                STAA      REMAININGQUANTUM
                RTS

     CLOCKTICKED ; CLOCK INT COMES HERE INSTEAD OF SDOS:CLOCKTICKED
                TFR       A,B               = # TICKS PASSED
                LDAA      REMAININGQUANTUM  ; = TICKS REMAINING IN USER T/S
                SBA                         ; = # TICKS LEFT
                BVC       CLOCKTICKED2      ; B/ NO UNDERFLOW
                LDAA      #-128             ; UNDERFLOW, SET TO BEST ESTIMATE
     CLOCKTICKED2
                STAA      REMAININGQUANTUM  ; SAVE # TICKS LEFT IN USER T/S
                TFR       B,A               ; RESTORE (A)
                JMP       SDOS+SDOS:CLOCKTICKED
.pa
.im 5
     FUSEBURNEDUP ; COME HERE WHEN DELAY SET UP BY /MT EXPIRES
                BSR       ABORTQUANTUM      ; ABORT CURRENT USER TO ENSURE GOOD
                                              SERVICE
                JMP       SDOS+SDOS:RTI     ; TO USERS WHEN DID SYSCALL:DELAY

.im 20
     ABORTQUANTUM ; COME HERE TO ABORT USER TIME SLICE (TASK LEVEL)
                LDAB      QUANTUM           ; ALREADY ABORTED TIME SLICE ?
                BEQ       ABORTQUANTUMRTS   ; B/ YES, DON'T ABORT TWICE
                CLR       QUANTUM           ; NO, PREVENT 2ND EXECUTION
                LDAA      REMAININGQUANTUM  ; = REMAINING TICKS BEFORE T/S UP
                SUBB      REMAININGQUANTUM  ; SO (A) HOLDS TICKS USED IN T/S
                SUBB      MINQUANTUM        ; TICKS GIVEN > MINIMUM GAURANTEED ?
                BLO       ABORTQUANTUM2     ; B/ NO, GO ENSURE MIN QUANTUM
                STAA      CHEATEDQUANTUM    ; YES, SAVE LOST AMOUNT FOR GETQUANTUM
                CLR       REMAININGQUANTUM  ; FORCE USERRTI TO GO TO TIMESLICE UP
     ABORTQUANTUMRTS
                RTS

     ABORTQUANTUM2 ; USER HASN'T GOTTEN MINQUANTUM TICKS OF CPU YET
                NEGB                        ; # TICKS NEEDED TO GET MINQUANTUM
                STAB      REMAININGQUANTUM  ; SHORT USER T/S ACCORDINGLY
                SBA                         ; DEBIT ABORTED TIME
                STAA      CHEATEDQUANTUM    ; REMEMBER FOR GETQUANTUM
                RTS

.IM 6
     GETQUANTUM ; RETURN (A) = OFFICIAL REMAINING TIME LEFT FOR QUANTUM
                LDAA      REMAININGQUANTUM  ; = TIME LEFT...
                ADDA      CHEATEDQUANTRUM   ; + AMOUNT OF TIME CHEATED OF
                LDAB      REMAININGQUANTUM  ; SET 'N' OR 'Z' BIT IF T/S OVER *NOW*
                RTS

.im 4
     SETFUSE ; CHECK FUSE FOR TIMER
                STX       TIMEOUTCOUNT       SET TIMEOUT
                RTS

.im 3
     TESTFUSE ; CHECK FUSE FOR TIME OUT
                LDX       TIMEOUTCOUNT       SET Z IF TIMEOUT COMPLETE
                RTS
.sp
.im 1
     ; COPYxxx ROUTINES NOT SHOWN AS THEY ARE HARDWARE DEPENDENT
.sp
.lm 10
.pa
.tc
SYSCALLS UNIQUE TO SDOS/MT
.ix SYSCALLS Unique to /MT
.ix Application Program
.ix Null Operations
.sp 2
SDOS/MT provides additional services to enable an application program to
correctly operate in a multi-user environment.  These services are not
available under Single-User SDOS; they are treated as null operations.
.sp 2
.tc
SYSCALL:INTERLOCK
.ix SYSCALL:INTERLOCK
.ix Synchronize Usage
.ix INTERLOCK "Object"
.ix CAPABILITY
.IX Releasing the object
.sp
SYSCALL:JOBCONTROL
.ix SYSCALL:JOBCONTROL
.ix User Program Forbidden
.sp
This system call is reserved for use by the JOBCONTROL program. Its use by a
user program is forbidden and undefined <<should be documented, also need
DOC on JOBCONTROL program).
.pa
.pa
.tc
SDOS/MT SUPPORT
.ix SDOS/MT Support
.sp
.ix Control Function
.ix Status Function
The following control and status functions are included for complete
documentation only.  They are subject to change without notice.
.sp
Caveat Emptor!!
.sp 2
.tc
MULTIUSER CONTROL FUNCTIONS
.ix Control Function, Multiuser
.in 5
.sp
.tc
.un 5
CC:SETTIMESHARE
.ix CC:SETTIMESHARE
.ix SDOS/MT Flag
.ix ^C^C
.ix SDOS/MT Already Running
.ix RDBUG
.ix System-Dependent Linkage
.br
Sets the SDOS/MT flag, which results in different handling of the line flags
and ^C^C abort.  If the flag has already been set, an
"SDOS/MT~Already~Running" error is returned.  RDBUF is filled with
system-dependent linkage information for use by SDOS/MT.
.sp
.tc
.un 5
CC:STOPTIMESHARE
.ix CC:STOPTIMESHARE
.ix SYSTEM CRASH
.ix SDOS/MT Flag
.ix User Program
.ix WARNINGS
.br
Turns off the SDOS/MT flag.  SHOULD NOT BE EXECUTED BY USER PROGRAMS, OR A
SYSTEM CRASH WILL RESULT.
.sp
.tc
.un 5
CC:WRITEANOWAIT
.ix CC:WRITEANOWAIT
.ix WRBUF
.ix Asynchronous WRITEA
.ix WRLEN
.ix Source of Data
.ix RDBUF
.br
This defines, for the VT driver, WRBUF as the source of data for an
asynchronous WRITEA of WRLEN bytes.  RDBUF contains 3 bytes, the first of
which the VT driver will set to zero when the request is accepted, and set
to non-zero when WRLEN bytes have been written; the remaining two bytes will
contain either an error code, or zero if the operation had no errors. Note
that WRBUF must not be modified until the request is complete (the first
byte of RDBUF becomes non-zero).
.sp
.un 5
CC:WRITEBNOWAIT
.ix CC:WRITEBNOWAIT
.ix WRBUF
.ix Asynchronous WRITEB
.ix WRLEN
.br
This defines, for the VT driver, WRBUF as the source of data for an
asynchronous WRITEB of WRLEN bytes.  RDBUF contains 3 bytes, the first of
which the VT driver will set to zero when the request is accepted, and set
to non-zero when WRLEN bytes have been written; the remaining two bytes will
contain either an error code, or zero if the operation had no errors. Note
that WRBUF must not be modified until the request is complete (the first
byte of RDBUF becomes non-zero).
.sp
.in
.ll 65
.pa
.tc
MULTIUSER STATUS FUNCTIONS
.sp
.ll 60
.in 5
.tc
.un 5
SC:GETLINEFLAGSHINT
.ix SC:GETLINEFLAGSHINT
.ix Line Flag
.ix SC:GETLINEFLAGS
.ix True Line Flag
.br
Returns zero if no line flags have been collected since the last call to
SC:GETLINEFLAGS, otherwise returns non-zero value.  The value returned is
only intended as a hint; the program must call SC:GETLINEFLAGS to get the
true line flags and acknowledge their receipt. Don't ask why.
.sp
.tc
.un 5
SC:GETLINEFLAGS
.ix SC:GETLINEFLAGS
.ix Line Flag
.ix ^C^C
.ix SDOS/MT
.IX KILLPROOF Flag
.ix Program Killed
.br
Exchanges a zero with the line flags, and returns that byte. If ^C^C has
been seen while the SDOS/MT and KILLPROOF flags are set,  a "Program Killed"
error will be returned; otherwise, ^C^C will result in the program being
killed.
.sp
.tc
.un 5
SC:GETTIMESHARE
.ix SC:GETTIMESHARE
.IX SDOS/MT Running
.ix SDOS/MT Already Running
.br
This checks to see if SDOS/MT is running.  If it is, an
"SDOS/MT~Already~Running " error will be returned; otherwise, a normal return
will be made.
.sp
.tc
.un 5
SC:ALLSTATUS
.ix SC:ALLSTATUS
.ix SC:STATUSCK
.ix Status Has Changed
.br
This checks to see if an SC:STATUSCK status call issued to any VT device
would return a "Status Has Changed" error as a response; if so, a "Status
Has Changed" error is returned.  Note that this status call supplies only a
hint.
.in
.pa
/MT operation using special CONTROL/STATUS operations
.sp
READA to VTD
.br
.in 5
1.~Ready line
.br
2.~Put in waiting for input queue
.br
3.~Goto poll for user
.sp
.un 5
WRITEA to VTD
.br
1.~WRITEA no wait
.br
2.~Put in waiting for output queue
.br
3.~Goto poll for user
.sp
.un 5
Waiting for input
.br
1.~If linehere then (2) else return
.br
2.~Move data from system space to user space (may take several reads). Free
buffer space.
.br
3.~Put in ready to run queue
.sp
.un 5
Waiting for output
.br
1.~If there is room for more output then (2) else return
.br
2.~Output (no wait) more data if not done then return
.br
3.~free buffer space
.br
4.~Put in ready to run queue
.sp
.in 0
.pa
.tc
SDOS BOOT SEQUENCE
.ix Boot Sequence
.ix I/O Package
.ix Breakpoints
.ix Debugging I/O Package
.sp
This information is only needed by those who are going to modify an old or
build a new I/O package for SDOS, and concerns itself with the sequence of
events that occurs (this sequence can be used to determine where breakpoints
need to be inserted when debugging an I/O package).
.sp
.ix RESET
.ix IDB
.ix Bootstrap Process
.ix System-Dependent ROM Entry Point
After a RESET to the 6800 microprocessor, control is usually transferred to
the system debugger.  For many SDOS systems, this is IDB.  With IDB, the
bootstrap process is started by typing the letter "G" immediately after a
reset, or jumping to a system-dependent ROM entry point.  Other systems have
some scheme for starting the bootstrap program.
.sp
.ix ROM Boot Program
.ix Logical Sector Number Zero
.ix Control Transfer
The ROM boot program's only job is to read Logical Sector Number zero into
memory (usually at location $100) and transfer control to the first byte
(again, at location $100).
.sp
.ix LSN Zero
.ix Disk Map Algorithm
.ix Boot Program
.ix LCN Zero
LSN zero contains disk map algorithm information, and the SDOS boot program.
In several systems, the SDOS boot program is larger than the space allocated
in LSN 0 for it; in this case, the rest of the boot program is stored in
memory image (not SDOS load records!) in the remaining sectors of Logical
Cluster Number zero.  The first part of the SDOS boot reads the rest of the
SDOS boot into memory at successively higher memory locations.  SDOS has
been designed to reserve locations 0 to $1FFF for the SDOS boot program.
.sp
.ix Boot Program Function
.ix SDOS.SYS
.ix Contiguous Set of Clusters
.ix LCN1
The SDOS boot program's function is to load SDOS itself. SDOS is stored on
the disk in the file SDOS.SYS in SDOS load record format (not memory image).
Normally, locating all the data sectors of a file is a formidable task, but
SDOS.SYS must be allocated to the contiguous set of clusters starting with
Logical Cluster Number 1.  This means that the boot program, once it has
determined the LSN of the first sector in LCN #1, can find the LSN of the
next sector of the SDOS.SYS file by merely adding one to the LSN of the
previous sector.
.sp
.ix SDOS Load Format
.ix SDOS.SYS File
One of the records in an SDOS load format file is a start-address record. 
Once the SDOS boot has processed all the load records in the SDOS.SYS file,
it transfers control to SDOS at the specified start address.
.sp
.ix Initialization Routine
.ix SYSCALL:EXIT
.ix Boot Time
.ix Reset
.ix Normal System Operation
SDOS has an initialization routine that sets up the hardware and software
for operation under the system.  This code is executed once at boot time,
and then discarded.  This routine has code starting at $2000, and does not
use any memory above $3FFF, so it fits entirely within the address space
normally assigned to user programs.  After SDOS has been initialized, the
reset routine performs a normal user SYSCALL:EXIT, and normal system
operation commences.
.sp
******DESCRIBE INITIALIZE.SYS,INITIALIZE.DO,SERIALNUMBER.SYS**
.sp
.ix I/O Package
Here we describe the sequence of routines called that are listed in the
configuration (CNFG:xxx) tables in the I/O package.
.sp
.ix CNFG:DRIVERBASE
.IX DRIVER:RESET
.IX CNFG:DEVICEDCB
.IX DRIVER:DISKRESET
.IX DISKINFO
.IX DISKINFO:NLSN
.IX DISKINFO:NSPT
.IX DISKINFO:NTPC
.IX DISKINFO:NCYL
.IX CNFG:DISKDCB
.IX DRIVER:RESET
.IX DRIVER:DISKRESET
.ix Non-Disk Device Driver
.ix Disk Buffer Pool
.ix Initialize
First, SDOS sets the stack pointer to the value specified by CNFG:DRIVERBASE
(the end of the user's address space).  Next, the DRIVER:RESET routine of
each non-disk device driver is called.  These routines are called in the
order specified by the CNFG:DEVICEDCBs list.  Then the DRIVER:DISKRESET
routines are called, with the DISKINFO table completely initialized (in
particular, DISKINFO:NLSN has been calculated from DISKINFO:NSPT, :NTPC,
:NCYL).  These routines are called in the order specified by the
CNFG:DISKDCBs list.  Finally, the disk buffer pool is initialized (no I/O
package routines are needed for this!).  Since DRIVER:RESET and
DRIVER:DISKRESET are once-only routines, they usually are assembled into the
disk buffer pool as the buffer pool is not initialized by SDOS until after
all the device reset routines have been called, and they are no longer
needed.
.sp
.ix CNFG:TIMEOUTLIST
.IX CNFG:TASKQUEUE
.IX CNFG:INTSETUP
.ix Time-Out Blocks
.ix Timeout-Task
.ix I/O Package
Next, SDOS counts the number of time-out blocks as specified by
CNFG:TIMEOUTLIST.  It then adds its timeout-task and the user task to end of
the (CNFG:TASKQUEUE) list of tasks provided by the I/O package (so that the
time-out and user tasks have lower priority than I/O package defined tasks).
Finally, SDOS calls CNFG:INTSETUP to set up the interrupt system (all
execution from boot up to and including this point is done with INTERRUPTS
DISABLED!).
.sp
.ix INTSETUP
.IX CNFG:INTENABLE
Soon after the INTSETUP routine is executed, SDOS calls CNFG:INTENABLE and
system operation is in full swing.
.sp
.ix Boot
.ix Disk Identification
.ix SYSCALL:EXIT
.IX DEFAULTPROGRAM
Finally, the SDOS init routine displays a banner identifying the version of
SDOS, reads the boot sector from the disk again and displays the disk
identification.  Then SDOS init does a SYSCALL:EXIT, and the DEFAULTPROGRAM
is loaded.
.PA
SDOS SYSTEM GENERATION
.SP
***************IRA-REWRITE THIS SECTION**************:
.SP
SDOS System Generation (SYSGEN) is the process by which the SDOS system
modules are configured, combined, and placed on a particular hardware
configuration.  Typically, SYSGENs are performed to allow for new devices
and/or memory configurations.
.sp
The following program/files are necessary to perform a SDOS SYSGEN.  These
programs/files are supplied only when specially requested from SD.
.sp
.in 3
.un 3
1.~SDOSSYSGEN.  This program converts the SDOS system object files and places
them as necessary onto the SYSGENable disk.
.sp
.un 3
2.~SDOSIOPACK.ASM*.  This file contains the I/O drivers source to interface
to the systems devices.  It may be necessary to modify this package to allow
for new devices or different memory configurations.
.sp
.un 3
3.~SDOSIOPKDEFS.ASM*.  This file contains the SDOS definitions necessary to
provide for linkage between the SDOSIOPACKAGE and the SDOSSYSTEM.
.sp
.un 3
4. SDOSBOOT.MIK*.  This file contains the disk bootstrap driver.
.sp
.un 3
5. SDOSSYSddk.MIK*.  This file will contain the SDOS system object which has
been assembled to reside in the size system specified by "dd" (kilobytes).
.sp
.in 0
*Note:  The filenames given above may not exactly match the filenames as
provided.
.sp
Using the programs described above and the standard SDOS programs (EDIT, COPY,
ASM), the following procedure can be followed to perform a typical SDOS SYSGEN.
.SP
.in 3
.un 3
1.~If modifying or adding a device driver to SDOS, the SDOSIOPACK.ASM source
file is modified via the editor (EDIT) and then appended to the SDOSIOPKDEFS.ASM
file using the COPY command.  The resulting file is then assembled (ASM) with
its origin (ORG) set at the proper location and the appropriate device
selection flags set.
.sp
.in 0
.im 6
         .COPY SDOSIOPKDEFS.ASM,SDOSIOPACK.ASM TO JUNK
         .ASM
         Source File = JUNK <CR>
         .
         .
         .
.im 0
.pa
.in 3
.un 3
2. If SYSGENing a SDOS system with a new disk controller, then a new
bootstrap will be required.  This can usually be constructed by modifying
the existing SDOSBOOT.ASM and reassembling to form a new SDOSBOOT.MIK.
.SP
.un 3
3.~A formatted disk should now be initialized with the SDOSDISKINIT
program.  This program is responsible for placing a initialized Directory
and Map on the SYSGENable disk.  For details and operating instructions,
refer to SDOSDISKINIT.
.SP
.un 3
4. Now the SDOSSYSGEN program should be used to place the BOOT.SYS and
SDOS.SYS files on the SYSGENable disk (see the SDOSSYSGEN description).
.sp
.un 3
5. Now the default operator's program should be copied to the newly
SYSGENed disk.  After this is complete, the utility programs can be copied
individually or by use of the SDOSDISKBACKUP program.
.sp
.un 3
6. At this point, an SDOSDISKVALIDATE should be performed to check for any
file errors.
.in 0
.pa
.tc
SDOSSYSGEN ******:REVISE THIS SECTION**********
.ix SDOSSYSGEN
.ix Initialized Disk
.ix Object Files
.sp
The SDOSSYSGEN program is responsible for combining, converting, and placing
the SDOS system object files on an initialized disk, thereby producing a
working SDOS system.
.sp
The SDOSSYSGEN program is invoked by typing:
.sp
.im 1
        .SDOSSYSGEN
.sp
The program responds with its banner, a listing of the systems it can SYSGEN
onto, which is determined by its bootstrap offset and the question:
.sp
.im 1
        ENTER THE DISK TO SYSGEN ON?
.sp
The operator should reply with the drive specifier containing an initialized
disk on which the SYSGEN is to take place. Typically this would be "D1:" but
not necessarily.
.sp
.ix MIKBUG
.ix BOOT.SYS
.IX SDOS.SYS
.ix SYSGEN Disk
The program will now ask for the MIKBUG object files which will comprise the
BOOT.SYS and SDOS.SYS files on the SYSGEN disk.  The first file will be
placed in BOOT.SYS and all the others will be merged in the order given to
form SDOS.SYS. The proper order would appear as:
.sp
.im 5
        ENTER FILENAME #1? SDOSBOOT.MIK
        ENTER FILENAME #2? SDOSIOPACK.MIK    Rewrite***
        ENTER FILENAME #3? SDOSSYSddK.MIK    **Need new example**
        ENTER FILENAME #4? SDOSPATCH.MIK
        ENTER FILENAME #5?
.sp
.ix Filename, Null
(A null filename terminates input.)
.sp
.ix Files
.IX BOOT.SYS
.IX SDOS.SYS
.ix Error
Once all the files are entered, they are converted to the proper format, and
at the same time, placed in BOOT.SYS or SDOS.SYS.  As each file is
processed, its file number is displayed, so if an error occurs, the
offending file can be corrected and the SYSGEN program restarted.
.sp
.ix SYSGEN
.IX Exit
.ix BOOT.SYS
.IX DIRECTORY.SYS
.IX DISKMAP.SYS
.IX BADCLUSTERS.SYS
.IX DEFAULTPROGRAM
.ix Bootable Disk
.IX ERRORMSGS.SYS
At completion, the program prints the SYSGEN is complete and exits.  The
newly SYSGENed disk has only the files BOOT.SYS, DIRECTORY.SYS, DISKMAP.SYS,
BADCLUSTERS.SYS.  Other needed files (including the DEFAULTPROGRAM and
ERRORMSGS.SYS) need to be copied to the disk before it is bootable.
.sp
The SDOSSYSGEN program has been improved; version 1.0k now sorts the load
records into ascending order and merges ALL records in the SDOS.SYS file.
.sp
SLIST is a program to list files on LPT: or any other device.
.sp
********MAKEVTCNFG.BAS doc needed here**********
.pa
********** THE BALANCE OF THIS DOCUMENT IS WISH LISTS, NOT REALITY! *****
DISK DRIVERS
.sp
The operations required of a disk driver in the I/O
package are "do sector I/O (read/write/verify)", "commit to drive
technology", and "check for write protected".  There are also several
support routines that must be implemented.
.sp
Here we give an overview of the operation of the disk driver.
The driver performs only single sector read, write or verify operations at
SDOS's request, and signals success or failure on completion.
SDOS will issue a request by passing an RDSI (Resident Disk Sector Info)
block to DRIVER:DISKIO; the RDSI block specifies the type of request
desired.  The driver processes the request, and when complete, writes an
error code (if needed) into the RDSI (SDOS marks the RDSI as "no error"
before handing it to the driver.)  SDOS will eventually issue a
DRIVER:DISKWAITDONE request to wait for completion of the sector I/O; at
no time will SDOS issue a second I/O request to the driver without waiting
for the first to complete.  The driver makes only one attempt to perform
the I/O for each call by SDOS; if the attempt fails, it is SDOS's
responsibility is issue a new request (SDOS will try a finite number of
times before giving up).  By dividing the I/O requests up in this fashion,
it is possible for SDOS to issue multiple sequential writes from the disk
buffer pool, followed by multiple sequential verifies of the sectors just
written, minimizing the time to write data to floppy disk class devices. 
Single sector I/O also simplifies construction of the driver,
at the expense of being able to read continuously from the disk, which is
only useful when loading programs or copying large files.
Because SDOS has access to the physical cylinder number of a sector (in
the RDSI), it can ensure efficient buffer dumping by writing all dirty
sectors in a cylinder to a disk at once.
.sp
Its strategy is to follow the LRU chain of sectors in the disk buffer
pool until a sector is found which is not modified, comes from a different
disk, or whose RDSI:cylinder doesn't match the last one dumped.
.sp
A verify operation only causes verification that the sector buffer contents
arrived at the disk correctly, and is issued by SDOS only after a successful
write of that sector.  Successful completion should cause the RDSI to be
marked I/O completed, no error.  Unsuccessful verification should cause the
RDSI to be marked as completed with disk write error.  This will cause SDOS
to requeue the sector later for another write attempt.
.sp
To maximize the ability of the disk driver to read/write logically
sequential sectors, a MapAlgorithm is used to specify latency and spiral
tuning parameters.  This MapAlgorithm affects the logical sector number to
physical sector number mapping performed by the driver.  To minimize the
computation time required to perform "mapping", SDOS calls a special driver
entry point whenever the MapAlgorithm is changed, so that as much of the
mapping process can be precomputed as possible.  SDOS also calls the driver
to convert an LSN to its physical form when a sector is first read; because
the driver can store the results of the mapping in the RDSI for the sector,
the mapping process is unnecessary on a write or verify of that same sector
if it is later updated (for sectors which have never been read, but are
updated, SDOS also calls the mapping routine).
.sp
Application programs can read/write arbitrary format disks by using
CC:PHYSICALIO, which allows specification of all the physical parameters
necessary for the driver to fetch an arbitrary sector from a disk.
This operation uses a buffer supplied by the user as source/target.
.sp
Error statistics are kept by the driver as to how many read/write/seek
errors occur, the hardware status that accompanied the error, the last
erroring LSN and the total operation count, so that SC:GETERRORSTATS can
report statistics to a user.  The driver need only update the current
statistics; they are reset by SDOS when reported.
.sp
Write protect checking is accomplished by a special entry point to the
driver.  SDOS uses this check to ensure that users do not write on
write protected disks.
.sp
Start-up (DRIVER:SELECTTECHNOLOGY) and clean-up operations (CC:DISMOUNT)
allow the driver an opportunity to chose the appropriate physical parameters
for the type of disk inserted currently in a drive, and to perform disk door
locking and unlocking as necessary.
.sp
There is a CC:MOUNT operation, but it is handled entirely by SDOS and need
not concern the driver.  Typically, CC:MOUNT occurs immediately after
DRIVER:SELECTTECHNOLOGY is called.
.sp
Other, non-standard disk operations may be implemented via the
DRIVER:CONTROL and DRIVER:STATUS entry points as desired.
.pa
This section describes the disk driver entry points in detail.
.sp
Error handling and propogation for all routines is according to the standard
SDOS conventions.
.sp
DRIVER:DISKRESET (text from manual)
.sp
DRIVER:DISKSELECTTECHNOLOGY is called by SDOS when the disk device is first
opened and it discovers DSKINFO:NBPS is zero, and it needs to perform I/O
to the drive (driver zeros DSKINFO:NBPS when CC:DISMOUNT is requested by
a user program if drive has changeable technology).  This routine must
determine the technology of the disk platter currently in the disk drive,
set DSKINFO:NBPS, DSKINFO:NSPT, DSKINFO:NTPC, DSKINFO:NCYL, DSKINFO:NLSN,
DSKINFO:READRETRYCOUNT, and DSKINFO:WRITERETRYCOUNT to appropriate values.
This allows a driver to handle a drive which can deal with different
technology/capacity/format disk platters, such as single/double density
floppies, etc.  It is expected that a driver will have one or two preferred
technologies to select from; how it performs the selection is driver
dependent, although it should do it automatically if at all possible (SDOS
conventions prefer IBM format single-density 8" IBM format double-sided,
single-density first track, double density elsewhere; a driver could
determine how to commit by reading sector 1 on track one in single density
mode; if no error, it could commit to single density; if unreadable, it
could commit to double density). It may return an ERR:DISKNOTREADY instead
of committing to a technology; otherwise it MUST select a technology.
See CC:SETTECHNOLOGY.
.sp
DRIVER:DISKWRITEPROTECTCHECK is called by SDOS to determine whether a drive
is currently write protected.  It returns ERR:DISKNOTREADY if the disk is
not ready, ERR:DISKWRTPROT if the disk drive electronics indicate the drive
is currently write protected, otherwise it simply returns without error.
This is used by SDOS to check whether a file can safely be created or
updated on a disk.
.sp
DRIVER:DISKSETMAPALGORITHM is called by SDOS immediately after SDOS modifies
DSKINFO:MAPALGORITHM.  This routine should precompute as much of the latency
and spiral tuning computations as possible, and store for use by
DRIVER:DISKLSNTOPSN.
.sp
DRIVER:DISKLSNTOPSN is a routine called by SDOS to cause the disk driver to
convert the LSN in RDSI:LSN to physical cylinder, track, and sector,
according to the current DSKINFO:MAPALGORITHM.  The address of the RDSI is
passed in (X).  Must not return an error.  DRIVER:DISKSETMAPALGORITHM has
already been called and so its precomputed values are already set up.
SDOS ensures that only legal LSNs are passed to this routine.
.sp
DRIVER:DISKREAD/WRITE/VERIFY is used to initiate a single disk I/O operation
on the RDSI specified by DSKINFO:RDSI.  RDSI:STATE contains a code specifying
the desired operation.   RDSI:SECTOR, RDSI:TRACK, and RDSI:CYLINDER have
already been set by a call to DRIVER:DISKLSNTOPSN.  Driver must zero
DSKINFO:RDSI (both bytes) when operation attempt is complete.  The driver
should set a timeout on each physical I/O operation it performs, not on a set
of operations.  Driver must detect write protect during write operation and
issue ERR:WRITEPROTECTEDDATALOST.  Driver must set RDSI:ERROR (upper byte) to
$FF when I/O transaction is completed successfully, or to ERR:XXX if I/O
transaction fails.  Both these acts must be done with ints disabled.
.sp
DRIVER:DISKSTATUS (from manual)
.sp
DRIVER:DISKCONTROL (from manual)
.sp
DISKINFO:BADLSN is set by SDOS to RDSI:LSN when SDOS determines it is not
possible to perform sector IO to a sector.  It is reset by SDOS to :FFFFFF
when a CC:DISMOUNT is issued by a userprogram.
.sp
*****need DISKINFO:errorstats description
.sp
DRIVER:DISKSETTECHNOLOGY is passed a syscall block whose WRBUF specifies the
technology to choose; can override default choice made by
DRIVER:SETTECHNOLOGY.
.pa
CC:SETTECHNOLOGY is a special call to allow user programs to the technology
selected after DRIVER:DISKSELECTTECHNOLOGY is called.  This call is only
valid after a CC:DISMOUNT and before DRIVER:DISKSELECTTECHNOLOGY is next
issued by SDOS???  If no CC:SETTECHNOLOGY call is issued before
DRIVER:DISKSELECTTECHNOLOGY is invoked, the driver should commit to one of
the preferred technologies automatically. If CC:SETTECHNOLOGY is called
before DRIVER:COMMIT, then the technology selected must be that chosen by
the CC:SETTECHNOLOGY call.  The technology set stays in effect until
another CC:SETTECHNOLOGY call occurs.  An empty WRBUF says "set default"
technology.
.sp
CC:PHYSICALIO specifies density, cylinder, track, sector, sector size
TARGET, I/O OP (R/W,REG), # cylinders total on disk (used to tell driver
whether single or dbl track *******NEEDS WORK
.sp
CC:DISMOUNTDISK unlocks door, clears error stats, zero DSKINFO:NBPS if
disk driver technology is changeable.
.sp
SC:GETERRSTATS done by SDOS; info generated by driver when an I/O operation
fails.   SDOS will automatically zero the error stats when a CC:DISMOUNTDISK
occurs.
.sp
DCB:DONEFLAG is set when RDSI operation is finished. Error code is stored in
both the RDSI and the DCB.  Convenience, not requirement
DRIVER:DISKIOWAITDONE dependent
.sp
DSKINFO:NBPS contains the number of bytes per sector on a drive. This value
can be changed by the driver when DRIVER:SETTECHNOLOGY is called. If
DSKINFO:NBPS is zero, SDOS will call DRIVER:SELECTTECHNOLOGY before performing
any other I/O operation on the drive.  This field should be zeroed by a
driver on a DRIVER:RESET or CC:DISMOUNT if the disk technology can change.
.sp
DSKINFO:DESCRIPTOR is byte containing a description of the disk drive.
Currently, only DISKINFODESCRIPTOR::VERIFYREQUIRED is defined; this bit
indicates that SDOS must issue a verify after a write operation.
.sp
DSKINFO:READRETRYCOUNT/WRITERETRYCOUNT contains the number of read/write
attempts SDOS will make before deciding to give up on a sector transfer.
This value is used to set RDSI:RETRYCOUNT before the first I/O attempt.
.sp
DISKINFO:WRITEPROTECTED is a flag managed by SDOS that tells SDOS whether
the drive is write protected.  This flag is set to the results obtained from
a DRIVER:WRITEPROTECTCHECK call immediately after a drive is mounted. Fast,
common operations (such as SYSCALL:WRITEx) inspect the flag; if reset, the
write operation proceeds. If set, DRIVER:WRITEPROTECTCHECK is invoked to get
an update on the write protect status; if the drive is truly write
protected, an error is issued, otherwise the write proceeds normally.
Slower, uncommon operations such as SYSCALL:RENAME, and SYSCALL:CREATE
simply always call the driver to determine the drive write protect status.
.pa
RDSI:DISKINFO points to the DCB representing the drive from which the sector
(that this RDSI represents) came.  RDSI:DISKINFO contains zero if SDOS
manufactures a dummy "zeros" sector when working with a sparse file; no disk
driver will ever find this field zero.
.sp
RDSI:LSN holds the 24 bit LSN of the sector that this RDSI represents.
.sp
RDSI:SECTORBASE holds a pointer to a buffer for the content of the sector. 
The buffer is gauranteed to be large enough for the current value of NBPS in
the DCB.
.sp
RDSI:FLINK and RDSI:BLINK are forward and backward links, used by SDOS to
chain the RDSIs together in Least Recently Used order.
.sp
RDSI:STATE indicates what is currently happening to the RDSI.  A value of
RDSISTATE:RESIDENT indicates that a copy of the sector is currently in the
buffer selected by SECTORBASE, and is being used by SDOS.  RDSISTATE:MODIFIED
indicates the sector contents are resident in memory and have been changed,
so the sector will eventually need to be written to disk.  RDSISTATE:READING
indicates that the sector contents have not yet arrived from the disk;
RDSISTATE:WRITING indicates that the sector contents are being moved to
the disk; and RDSISTATE:VERIFYING indicates that the sector contents have
tentatively been written, and verification of the transfer is pending
(verifies occur only if DSKINFO:VERIFYREQUIRED indicates verify is required).
.sp
RDSI:CYLINDER holds the physical cylinder number (as determined by
DRIVER:DISKLSNTOPSN).  SDOS never changes this field; DRIVER:DISKLSNTOPSN
must set this field when called.  SDOS uses this field to determine which
sectors in the pool are all in the same cylinder when dumping the pool. 
Drivers dealing with intelligent controllers that are passed only LSNs need
to set this field according to an appropriate dump strategy; a reasonable
choice is to place the top "n" bits of the LSN (for some n) into
RDSI:CYLINDER.  This ensures a dumping strategy which is "cylinder-like".
.sp
RDSI:TRACK holds physical track number corresponding to RDSI:LSN.  It is set
by DRIVER:LSNTOPSN; SDOS never sets this field.
.sp
RDSI:SECTOR holds the physical sector number corresponding to RDSI:LSN.  It
is set by DRIVER:LSNTOPSN; SDOS never changes this field.
.sp
RDSI:ERROR is zeroed by SDOS before entering the driver.  It is set by the
drive to an appropriate error code if an error occurrs in reading, writing
or verifying the sector.  If the I/O operation completes successfully,
RDSI:ERROR upper byte must be set to $FF (a DEC instruction works nicely).
When an error occurs, the driver should set RDSI:DRIVERDATA so it knows how
to try again later.
.sp
RDSI:RETRYCOUNT is used by SDOS to keep track of the number of tries it has
made to perform the I/O specified by RDSI:STATE.  This retry count is set to
DSKINFO:READRETRYCOUNT or DSKINFO:WRITERETRYCOUNT before SDOS issues the
first I/O operation of a particular type, such as read or write (verify is
simply a second phase of write, and gets tried only once per write attempt).
SDOS decrements this counter each time it issues an I/O request for an RDSI
and gets an error; if the counter goes to zero, the SDOS gives up trying to
fetch/write the sector, issues a suitable error (taken from RDSI:ERROR), and
releases the RDSI for use for some other sector.
.sp
RDSI:DRIVERDATA is space reserved for use by driver for any purpose. It is
typically used to hold information about how the next retry on this sector
should be performed assuming no other intervening disk operations have
occurred.  The driver typically saves a LASTRDSI pointer; if a new I/O
request occurs with an RDSI the same as LASTRDSI and DSKINFO:RETRYCOUNT is
greater than RDSI:RETRYCOUNT, then this field is used to determine how to
perform a retry, otherwise a "first" time try is made to perform the I/O.
.sp
SDOS will not examine or modify the sector buffer contents until
RDSI:ERROR<>$FF00.  RDSI:VERIFYING indicates the sector needs to be verified
by the driver.  An error on a verify causes SDOS to change the state to
RDSI:WRITING after decrementing the RDSI:RETRYCOUNT.
.sp
SC:GETERRORSTATS.  Reads back error status stored in DCB by driver. Zeroed
only by CC:DISMOUNTDISK.  Handled entirely by SDOS;  driver will not see
call.  Driver must, however, keep error statistics up to date.
.sp
16 character device names, blank padded no colons
.sp
install contig file stuff
.br
instal rename device
.sp
Try sorting? -- insert on LSN increasing thread
.sp
Under SDOS/mt -- defaulted to floppy --- floppy driver suddenly goes not
ready because dummy took disk out--- he got error 1060, dummy realized his
mistake, inserted diskette and got "illlegal LSN" forever (no way out!)
.sp
For floppy disk drives, the error recovery strategy should be as follows:
.im 9
RDSI:RETRYCOUNT value          action
     xxxxx111                  seek to track, do I/O
          110                  seek to track, do I/O
          101                  seek to track, step out, step in
          100                  seek to track, do I/O
          011                  seek to track, step in, step out
          010                  seek to track, do I/O
          001                  seek to track, step in, step out, do I/O
          000                  restore to track 0, seek desired, then I/O
.sp
Rationale:  step in/out helps deal with head alignment problems.  Strategy
designed to allow 2 "normal" I/O attempts, plus 2 attempts after each
error recovery step.
.pa
.in 10
.sp
.un 5
CNFG:CACHERESET
.BR
(D) Has size of largest sector.
.sp
.un 5
CNFG:CACHESWAPSECTOR
.BR
This 3 byte entry contains a JMP to cache logic used by SDOS to manage a
large disk cache.  (D) points to a SECTORDB: block containing a description
(DISKINFO and LSN) of a sector which SDOS would like to retrieve: (X) points
to an RDSI: block in which to place the sector if found.  The cache logic
determines if it has that sector.  If the cache does not have the sector,
but there is room in the cache, the cache stores the sector, freeing the
RDSI, and returns carry set, Z bit set.  If cache does not have the sector,
but there is no room, exits with carry set, Z bit reset.  If the cache has
that sector, and the RDSI: has DISKINFO of 0 (i.e., dummy), then the sector
contents are transferred from the cache to RDSI:SECTORBUFFER, and the carry
is returned reset.  If the cache has that sector, and the RDSI:DISKINFO<>0
(i.e., RDSI contains a valid sector), then the cache swaps its sector
information with the contents of the RDSI, and returns carry reset.  In
both cases, the cache needs to fill the RDSI entirely; the cache then forgets
it had the desired sector.
.sp
.un 5
CNFG:CACHEFINDOLDEST
.br
This 3 byte entry contains a JMP to cache logic used by SDOS to help dump
the cache efficiently.  (X) points to RDSI.  Finds oldest, dirty sector in
cache; then finds lowest dirty LSN in same cylinder.  If not found (i.e., no
dirty LSNs anywhere in cache) returns carry set.  If found, sector is
traded as described under CNFG:BIGCACHESWAPSECTOR.  Exits with  carry set,
(X) = ERR:NOCACHE if not implemented.
.sp
.un 5
CNFG:CACHEFINDNEXTOLDEST
.br
This 3 byte entry contains a JMP to cache logic used by SDOS to help dump
the cache efficiently.  (X) points to an RDSI: block.  (D) points to an
RDSI: block with RDSI:CYLINDER filled in (by DRIVER:DISKLSNTOPSN) to match
RDSI:LSN.  Finds lowest LSN that is larger than RDSI:LSN specified by (D),
such that LSN is dirty and is in same cylinder.  If not found, returns carry
set.  If found, sector is traded as described under CNFG:BIGCACHESWAPSECTOR.
.sp
.un 5
CNFG:CACHEFINDDISK
.br
This 3 byte entry contains a JMP to cache logic used by SDOS to help flush
sectors from a particular drive to the cache.  (X) contains DISKINFO pointer.
Finds oldest, dirty sector in cache from drive with DCB matching DISKINFO;
then finds lowest dirty LSN in same cylinder for that drive.  Otherwise,
results and exits are identical to CNFG:BIGCACHEFINDOLDEST.
.sp
.un 5
CNFG:CACHEDISMOUNTDISK
.br
This 3 byte entry contains a JMP to cache logic used by SDOS to dismount
a particular drive from the cache.  (X) contains a DISKINFO pointer.
Scans cache, deleting any cached sectors from drive with DCB matching
DISKINFO pointer.  This routine will not be called until SDOS has cleared
all dirty LSNs from the cache.
.in 0
.pa
* PROPOSED DISK CACHE SOFTWARE
.ce
SDOS Mass LRU Specification
.sp
UNFINISHED
.sp
SDOS/MT systems service up to 16 users on machines that memory
capacities of 1 to 2 megabytes.  Since SDOS's need for memory is limited
to 512Kb, we would like to use the balance of the memory as a massive
LRU cache to enhance disk performance.
.sp
The LRU cache will store sectors of varying size.  Since all sectors are
a power of two, a buddy system space allocator seems quite appropriate;
thus, many more 128 byte sectors can be stored then 4kb sectors from
laser disks.
.sp
With 2Mb and 128 bytes per sector, up to 2^14 sectors could be stored in
the cache.  Each sector requires a descriptor of about 10 bytes to keep
track of the sector content, age, etc., so the cache logic will need to
handle up to 2^14 descriptors.  To keep the address arithmetic simple, we
arbitrarily limit the number of descriptors to 2^16-1.
.sp
Because the SDOS system space is cramped, we cannot afford to place the
descriptor information from the cache in the SDOS system space. We
therefore arbitrarily require the cache itself to store this descriptor
information, as well as the buddy system space allocation information,
and various bits of information required to keep track of the cache.
.sp
The cache maintains a hash table with which to efficiently look up
desired sectors.  The number of hash table slots is cache-specific but is
generally a power of two as the hashing function is usually "take the
bottom N bits of the desired LSN".  From each hash bucket there will be a
BALANCED tree of cache (sector) descriptor block, due to the possibility
of a large number descriptors hanging from a bucket, thus LOG2 search
times of the cache are assured.
.sp
Operations possible on the LRU cache:
.sp
LRUCACHE:FETCHSECTOR is given a sector descriptor block by SDOS, and
determines if the desired sector is present in the cache.  If it is, the
sector contents are transferred to the memory location specified by the
sector descriptor, and removed from the cache.  The "dirty" flag from the
cache is transferred to the dirty flag of the SDOS sector descriptor.
.sp
LRUCACHE:STORESECTOR is given a sector descriptor block by SDOS. An error
occurs if the sector is already in the cache (this is a bug). If there is
no room in the cache, an ERR:NOROOM error is returned; SDOS must then
write the sector to the source drive if it is dirty, and then must throw
the sector away.  If room can be found (the usual case), then the sector
contents are taken from the buffer specified by the sector descriptor and
squirreled away, along with the LSN of the sector, its source drive, and
whether or not it is dirty. The cache finds room by locating its oldest
"clean" sector, and releasing that, repeating the process until it has
enough room or there are no more "clean" sectors (a really rare event
with a cache this large).
.sp
LRUCACHE:DELETESECTOR is given a sector descriptor block by SDOS. If the
sector exists in the cache, whether dirty or not, it is immediately
deleted.  This operation allows the operating system to decide it no
longer needs certain disk blocks, and it can save the cache and drivers
time by telling them that those disk blocks are worthless.
.sp
NOTES ON MASTER:  COMMENT-SO WHO IS DOING THE FLUSH SDOS OR THE CACHE???????????????
.SP
LRUCACHE:FLUSH is given to the cache to cause it to immediately write all
dirty sectors for the specified drive onto that drive. The dirty sectors
are then marked as clean.  NOTES ON MASTER:  MAKE THIS ?????? FETCH SECTION,
BUT CLEAN DIRTY BIT ????????????????????????????????????????????????????????????????
.sp
LRUCACHE:DISMOUNT is given to the cache to cause it to remove all sectors
from the specified drive from its list. If there exists a dirty sector,
an error is issued, and the dismount operation is aborted.
.sp
NOTES ON MASTER:  ADD WRITE - THRU CACHE SWITCH?
.SP
LRUCACHE:OLDEST is given a sector descriptor block for a specific
drive by SDOS, and returns the lowest numbered LSN which is dirty and is
on the same cylinder as the oldest dirty LSN in cache for that drive. If
there is no such LSN, an error is returned.
HOW ABOUT OLDEST DIRTY LSN IN THE DIRECTION THE HEADS ARE MOVING?  NOTES ON
MASTER:  Presumes fused I/O on each DCB.
.sp
LRUCACHE:NEXT is given a sector descriptor block, and locates the next
dirty sector on the same drive with a larger LSN, but an identical
physical cylinder number. If no such LSN exists, an error is given,
otherwise, the information for the found sector is transferred to the
sector descriptor and the sector contents are transferred to the sector
buffer in SDOS, and the sector is deleted from the cache. It is expected
that the sector will be written back to its proper disk.
.pa
HOW DO I GET A CSCAN POLICY? cough up list of dirty sectors on 1stcylinder >=
specified, or <= specified, in LSN increasing order.  There ought to be
operations to cause the cache to drink or dump a track/cylinder if possible.
.br
Hardcopy edit zero depth full edit
.pa
.im 29
 input "Cache hit ratio (0-)? " h
 input "Disk I/O time in seconds? " d
 input "Time to write to cache? " c
 input "Ratio of writes to sum of reads and writes? " w
 print "write ratio","writeintocache","writethrucache","ratio"
 for w=0 to  step .1
     writethrucachetime=(h*c+(1-h)*d)*(1-w)+w*(c+d)
     writeintocachetime=(h*c+(1-h)*d)*(1-w)+w*c
     print w,writeintocachetime,writethrucacheetime,...
&          writeintocachetime/writethrucachetime
next w
end
.cache
Cache hit rationn (0-1)? .90
Disk I/O time in seconds? .050
Time to write to cache? .0002
write ratio       writeintocache      writethrucache      ratio
 0                 .00518              .00518              1
.1                 .004682             .009682             .4835777731
.2                 .004184             .014184             .2949802594
.3                 .003686             .018686             .1972599807
.4                 .003188             .023188             .1374849059
.5                 .00269              .02769              .0971469844
.6                 .002192             .032192             .0680914512
.7                 .001694             .036694             .0461655856
.8                 .001196             .041196             .0290319448
.9                 .000698             .045698             .0152741914
1                  .0002               .0502               .003984063745
.closelog
.sp
Ratio of .4835 indicates that "write thru cache" is best policy.
.fo
.in
.pa
.pc
.he
.sh
.ce
TABLE OF CONTENTS
.sp
*****COMPLETELY SCREWED UP******I G N O R E*******
.sp 3
ERROR CODES
VIRTUAL TERMINAL DEVICE DRIVER
.in 3
OPEN & CREATE
CLOSE
RENAME & DELETE
READA & WRITEA
READB
CONTROL
.in 6
CC:POSITION
CC:DUMPBUFFERS
CC:ECHO
CC:NOECHO
CC:WRAP
CC:NOWRAP
CC:IDLES
CC:TABS
CC:SETACTBLOCK
CC:CLRINPUT
CC:CLROUTPUT
CC:SETREADTIMEOUT
CC:SETPROFILE
CC:ALTERPROFILE
CC:WRITEEDITLINE
CC:SETFIELDSIZE
CC:SETPARAMS
CC:ACTIVATIONCK
CC:SETBAUDRATE
CC:COLORING
CC:BACKGROUND
CC:KILLPROOF
CC:KILLENABLE
CC:SETEXCEPTIONS
CC:SETOUTPUTTIMEOUT
.un 3
STATUS
SC:GETPOS
SC:GETCOL
SC:GETEOF
SC:GETTYPE
SC:GETPARAMS
SC:GETPROFILE
SC:GETPROFILENAME
SC:GETPROFILEALTERATION
SC:GETFREECOUNT
SC:GETDATACOUNT
SC:GETOUTPUTTIMEOUT
SC:GETBAUDRATE
SC:GETTABS
SC:GETIDLES
SC:GETWRAP
SC:GETCOLORING
SC:GETBACKGROUND
SC:GETACTCOL
SC:ATTENTIONCK
SC:STATUSCK
.in 3
CONTROL CHARACTERS
SWITCHES
SDOS/MT SUPPORT
.in 6
CONTROL
.in 9
CC:SETTIMESHARE
CC:WRITEANOWAIT
CC:WRITEBNOWAIT
.un 3
STATUS
SC:GETLINEGLAGSHINT
SC:GETLINEFLAGS
SC:CHECKTIMESHARE
SC:ALLSTATUS
.in
VT DRIVER SYSGEN INFORMATION
.in 3
DEVICE PROFILE BLOCK (DPB)
VT DRIVER LINKAGE
DEVICE CONTROL BLOCK (DCB)
CONFIGURATION TABLE
PROPOSED DISK DRIVER ENHANCEMENTS
PROPOSED DISK CACHE SOFTWARE
.en
