changeset 82:d76cc2119c4f

Bob Brose's driver for TC^3 Controller -- Thanks Bob!
author boisy
date Mon, 13 May 2002 03:59:20 +0000
parents 991471545e7b
children e213011408ad
files 3rdparty/drivers/tccc/defsfile 3rdparty/drivers/tccc/h4.asm 3rdparty/drivers/tccc/makefile 3rdparty/drivers/tccc/tccchd.asm
diffstat 4 files changed, 1646 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/drivers/tccc/defsfile	Mon May 13 03:59:20 2002 +0000
@@ -0,0 +1,4 @@
+Level	equ	2
+	use	os9defs
+        use     rbfdefs
+        use     systype
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/drivers/tccc/h4.asm	Mon May 13 03:59:20 2002 +0000
@@ -0,0 +1,104 @@
+*     TCCCHD descriptor: Hard disk driver descriptor for OS9
+*     Copyright (C) 1990,1991,1992,1993,1994,1995,1996 Robert E. Brose II
+*
+*     This program is free software; you can redistribute it and/or modify
+*     it under the terms of the GNU General Public License as published by
+*     the Free Software Foundation; either version 2 of the License, or
+*     (at your option) any later version.
+*
+*      This program is distributed in the hope that it will be useful,
+*      but WITHOUT ANY WARRANTY; without even the implied warranty of
+*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*      GNU General Public License for more details.
+*
+*      You should have received a copy of the GNU General Public License
+*      along with this program; if not, write to the Free Software
+*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+* DISTO version 124/125/126 descriptor h4 170 meg seagate drive
+
+         nam   disto.descriptor (h4)
+         ttl   device descriptor for seagate st2209n
+
+         ifp1  
+         use   defsfile
+         endc  
+
+verson   equ   $02
+         mod   endmod,hdnam,devic+objct,reent+verson,hdmgr,hddrv
+
+         fcb   $ff        mode
+         fcb   $07        port msb l2
+         fdb   $ff70      port lsb's
+         fcb   hdnam-*-1  init table size
+         fcb   $01        dev type 1=rbf
+         fcb   $00        logical drive number (0-3)
+         fcb   $00        step rate and retry options
+         fcb   $80        device type 80=hd
+         fcb   $11        media density
+* bit 7 = Enable PHYSICAL format = 1 (logical format always enabled).
+* bit 6 = Drive init = 1 (ONLY for st506 drives & wd1002/adaptec/xebec cont).
+* bit 5 = LUN (2nd drive = 1) (only on st506 drives with external controller)
+* bit 4 = Recal on first access = 1 (Needed for normal embeded scsi drives)
+* bits 0 - 3 = SCSI ID IN BINARY. ID0=1, ID1=2, ID2=4 (may change some day!)
+
+         fdb   $0ae5      tracks per drive, see below
+         fcb   $08        number of sides
+         fcb   $01        verify writes 1=no verify
+         fdb   $20        default sectors/track (32 sectors per physical track)
+         fdb   $20        track 0 sectors
+         fcb   $1         interleave
+         fcb   $20        default allocation in sectors
+
+* added definitions
+* actual drive charcteristics for init routine
+* NOT USED FOR EMBEDED DRIVES
+* First Physical Drive (lun 0)
+
+         fdb   $0         cylinders
+         fcb   $0         number of heads
+         fdb   $0         reduced write current starting cylinder
+         fdb   $0         write precomp starting cylinder
+         fcb   $0         max eec error burst length to be corrected
+
+* Second physical drive (lun 1)
+
+         fdb   $0
+         fcb   $0
+         fdb   $0
+         fdb   $0
+         fcb   $0
+
+* drive offsets (this is in GROUPS OF 256 SECTORS!)
+* can be used to logically partition 1 physical drive into up to
+* 4 logical drives.
+* I always use a least an offset of 1 to allow for possible os9 boot
+* track on the drive, also if it's a used PC drive, the first few
+* cyls are where all the errors are :-)
+
+         fdb   1          drive 0
+         fdb   1          drive 1
+         fdb   1          drive 2
+         fdb   1          drive 3
+
+* Multipak slot select (Only used for DISTO Host adapter)
+
+         fcb   1          slot for mpak scs 0=slot 1  1=slot 2  2=slot 3  3=slot4  $ff=no mapk
+
+* note that the drive name is unrelated to the physical or logical drive
+* number.
+
+HDNAM    fcs   "H4"
+HDMGR    fcs   "RBF"
+
+* note the name here. DI1024, DIS512 and DI256 are DISTO DRIVERS of various
+* sector sizes. TC1024, TCC512 and TCCCHD are the equivalents for the TC3 host
+* adapter. DBHSHD for 256 byte/sector st506 style external controllers which
+* require handshaking on each byte of a data transfer (i.e. adaptec). DIDBHS
+* for the same thing with a DISTO host adapter.
+
+HDDRV    fcs   "DIS512"
+         fdb   $0         room for patching
+         emod  
+endmod   equ   *
+         end   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/drivers/tccc/makefile	Mon May 13 03:59:20 2002 +0000
@@ -0,0 +1,12 @@
+include ../../../Makefile.rules
+
+DEPENDS		= ./Makefile
+DRVRS		= tccchd.dr
+DESCS           = h4.dd
+ALLOBJS		= $(DRVRS) $(DESCS)
+
+all:	$(ALLOBJS) $(DEPENDS)
+
+clean:
+	$(RM) $(ALLOBJS)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/3rdparty/drivers/tccc/tccchd.asm	Mon May 13 03:59:20 2002 +0000
@@ -0,0 +1,1526 @@
+*     TCCCHD: Hard disk driver/scsi host adapter driver for OS9
+*     Copyright (C) 1990,1991,1992,1993,1994,1995,1996 Robert E. Brose II  
+*
+*     This program is free software; you can redistribute it and/or modify
+*     it under the terms of the GNU General Public License as published by
+*     the Free Software Foundation; either version 2 of the License, or
+*     (at your option) any later version.
+*
+*      This program is distributed in the hope that it will be useful,
+*      but WITHOUT ANY WARRANTY; without even the implied warranty of
+*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*      GNU General Public License for more details.
+*
+*      You should have received a copy of the GNU General Public License
+*      along with this program; if not, write to the Free Software
+*      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+         opt   w131
+         nam   Hard Disk driver, flip-flop & latch version.
+         ttl   title page
+
+* experimental no DP version 9-11-90
+**************************************************************
+*     T C C C (TC^3)                                         *
+*     H A R D   D I S K       device driver for CoCo OS9     *
+*                             written by Robert E. Brose II  *
+*     uses Western digital WD 1002-shd or Xebec 5" controller*
+*     host adapter modeled after example in Xebec manual     *
+*     Allows use of 2 different drives with separate offsets *
+*     for partitioning (ms 13 bits of 21 bit sector #)       *
+**************************************************************
+*
+*
+* physical drive number stored in IT.DNS.
+*
+* revision history
+*------------------------------------
+* 2.0 Totally revamped 
+*     Controller number gotten from the PD (PD.DNS lower 4 bits).
+*     Avoids use of DP, it's faster without it.
+*     Most subroutines moved to inline code to increase speed
+*     Added time slice release if controller is busy 12/01/90
+*     set blocks in init instead of doing it on every packet 12/01/90
+* 2.1 Added adaptec conditional statements 02-23-92
+*     Uniform descriptors, params adaptec doesn't need are ignored 02-23-92
+* 2.2 init/don't init drive, bit 6 of PD.DNS. 1=don't init 1-15-94
+*     resets drive in setup routine 1-16-94
+*     locks scsi packet, elims conflict on multiple drives on the same
+*     host adapter. 1-16-94
+*     altered format to work with seagate drives. 1-16-94
+* 5/6.x changed revisn and versn below to match up with this history 1-19-94
+* 5.x 256 byte sectors version.
+* 6.x 1K HD sectors version. 1-19-94
+* 5/6.2 added HOG flag for maximum speed, to hog the cpu
+* 5/6/7/8.3 Added MEDSEC for 512 byte sectors
+* 5/6/7/8.4 much 6309 optimisation
+* 9.x Redid version/revision stuff again. Version is now 9, revision
+*     indicates sector size. 6809: 1=256 by/sec 2=512 by/sec 3=1024 by/sec
+*     Nitros 6309  4=256 by/sec 5=512 by/sec 6=1024 by/sec
+*10.x Changes to allow >1 drive with large sectors. 11-5-94
+*     UGH removed for now, flush is too complicated with BIGSEC
+*     changed 6309 block moves to I/O to allow for a gap to service serial
+*      interrupts every 256 moves (affects sector sizes >256 bytes). 3-25-95
+*11.x Optimizations from better understanding about when the driver can
+*     be interupted, thanks Alan DeKok. 1-7-96
+*     Handles inits of several scsi id'd devices. 1-7-96
+*     Fixed Calcsec, logread and logwrit to handle 512 bytes/sector 1-8-96
+*12.x Added DISTO HD II support 3-9-96
+*      notes: sleep causes the only possible reentrant situation (~HOG)
+*              in this case cmd block and cache buffer must be preserved.
+*             To make multiple drives/driver work for 512 and 1024 (BUFSEC)
+*              cases will require info like drive, lun, offset, etc to be
+*              save for the previous sector so a cache flush can be done. YUK!
+*     Added sector 0 cache because rbf accesses it all the darn time! 6-8-96
+
+H6309    equ   1          if 6309 cpu, 0=on!
+
+         ttl   equates
+DBHS     equ   1          data requires req handshake version 0=ON! (i.e. adaptec)
+BIGSEC   equ   1          use 1024 byte physical sectors (0=ON!)
+MEDSEC   equ   0          use 512 byte physical sectors (0=ON!)
+HOG      equ   1          hog the cpu on waits (speeds up disk access 0=ON!)
+DISTO    equ   1          use HD II ports and status bits (0=ON!) 
+MDRIVES  equ   1          can use more than 1 drive / driver in BUFSEC case (0=ON!)
+MPAK     equ   1          includes multipak switching code (needed for DISTO w/ MPAK 0=ON!)
+CANFORM  equ   0          drive formatting allowed (0=ON!)
+CACHE    equ   1          sector 0 cache (0=ON!).
+
+
+* BUFSEC below means a buffer is used when reading/writing physical secs
+* (0=on)
+
+         ifeq  BIGSEC
+BUFSEC   equ   $0
+m.smask  equ   %11111100
+m.nsmask equ   %00000011
+         else  
+
+         ifeq  MEDSEC
+BUFSEC   equ   $0
+m.smask  equ   %11111110
+m.nsmask equ   %00000001
+         else  
+
+BUFSEC   equ   $1
+         endc  
+         endc  
+
+         ifeq  H6309
+
+         ifeq  BIGSEC
+revisn   equ   6
+         else  
+         ifeq  MEDSEC
+revisn   equ   5
+         else  
+revisn   equ   4
+         endc  
+         endc  
+
+         else  
+
+         ifeq  BIGSEC
+revisn   equ   3
+         else  
+         ifeq  MEDSEC
+revisn   equ   2
+         else  
+revisn   equ   1
+         endc  
+         endc  
+
+         endc  
+
+verson   equ   12
+
+numdrvs  equ   4          number of drives supported by driver (logical)
+* status byte mask
+
+m.error  equ   %00000010  error flag
+
+* status register bit masks
+
+         ifeq  DISTO
+m.req    equ   %10000000  data request line
+m.busy   equ   %00000001  busy status line
+* broken on disto??? m.msg  equ %00000100 end of message status line
+m.msg    equ   %00000000  end of message status line
+m.cmd    equ   %01000000  command/data status line
+m.in     equ   %00100000  input/output status line
+* broken msg on disto ??? m.nnc  equ %11100101 unconnected lines = ignore mask
+m.nnc    equ   %11100001  unconnected lines = ignore mask
+
+         else  
+
+* normal TCCC defs
+m.req    equ   %00000001  data request line
+m.busy   equ   %00000010  busy status line
+m.msg    equ   %00000100  end of message status line
+m.cmd    equ   %00001000  command/data status line
+m.in     equ   %00010000  input/output status line
+
+         endc  
+
+m.phys   equ   %00100000  physical drive mask (LUN on Controller)
+m.init   equ   %01000000  initialize drive on change flag
+m.cont   equ   %00001111  controller address mask
+m.recal  equ   %00010000  do a recal (home) on 1st drive access
+m.format equ   %10000000  enable format command
+
+         ifeq  MPAK
+m.mpscs  equ   %11110000  Mpak slot select SCS clearing mask
+mpsel    equ   $FF7F      multipak select latch addr, used for disto.
+EXTPRM   equ   25         extra params in descriptor
+         else  
+EXTPRM   equ   24         extra params in descriptor
+         endc  
+
+* input and output ports offsets for HOST ADAPTER bus
+
+         ifeq  DISTO
+datapo   equ   3          read and write data
+rstpo    equ   1          software reset
+selpo    equ   2          controller select
+statpo   equ   1          read status
+         else  
+
+* Normal TCCC defines
+datapo   equ   0          read and write data
+rstpo    equ   1          software reset
+selpo    equ   2          controller select
+selrst   equ   3          reset of select (scuzzie adapters)
+statpo   equ   1          read status
+
+         endc  
+
+* controller opcodes
+
+o.ready  equ   $00        test for drive ready
+o.param  equ   $0c        set parameters for the drives
+o.read   equ   $08        read sector(s)
+o.write  equ   $0a        write sector(s)
+o.formt  equ   $04        format drive
+o.recal  equ   $01        recalibrate drive (head to track 0)
+
+         ifp1  
+         use   defsfile
+         endc  
+
+         ttl   data allocation
+
+         org   DRVBEG
+tables   rmb   DRVMEM*numdrvs reserve space for system tables
+
+* command packet for controller
+
+packet   equ   .
+
+opcode   rmb   1          command opcode
+lun      rmb   1          logical unit number : ms part of lsn
+lsn      rmb   2          logical sector number
+blocks   rmb   1          interleave or block count
+control  rmb   1          control byte set at packet send time
+plocked  rmb   1          above control block in use, locked
+blocked  rmb   1          buffer sector (caching) in use, locked
+
+* extra parameters read in from the descriptor.
+
+param    rmb   8          physical drive 0 params
+param1   rmb   8          physical drive 1 params
+
+* logical drive offsets
+
+offsd1   rmb   2
+offsd2   rmb   2
+offsd3   rmb   2
+offsd4   rmb   2
+
+         ifeq  MPAK
+* Multipak latch temp storage and slot.
+mpslot   rmb   1          From descriptor, FF = no mpak
+         endc  
+
+* end of extra params read in from descriptor
+
+         ifeq  MPAK
+mpstor   rmb   1          Current multipak value outside of this driver.
+         endc  
+didflag  rmb   1          read lsn 0 flag
+lastphy  rmb   1          last drive accessed (physical)
+sec0fl   rmb   numdrvs    (recal (home) completed flag)
+tempw1   rmb   2          word temp var
+tempw2   rmb   2          word temp var
+
+iniflg   rmb   numdrvs    whether or not the device has been initalized
+
+         ifeq  BUFSEC
+
+         ifeq  BIGSEC
+secbuf   rmb   1024       buffer for physical sector
+         else  
+secbuf   rmb   512        buffer for physical sector
+         endc  
+
+         ifeq  CACHE
+sec0     rmb   256*numdrvs optional sector 0 cache
+         endc  
+
+lastdrv  rmb   1          last LOGICAL drive accessed
+lsech    rmb   1          24 bit address, sector in buffer (logical w/o least sig 2 bits)
+lsecm    rmb   1          (part of above)
+lsecl    rmb   1          "
+physech  rmb   1          24 bit address, sector in buffer (physical sector in buffer)
+physecm  rmb   1          (part of above)
+physecl  rmb   1          "
+cached   rmb   1          cache is dirty flag
+secidx   rmb   1          index into physical sector
+         endc  
+
+endmem   equ   .
+
+         ttl   module entry
+
+         mod   endmod,name,drivr+objct,reent+verson,xferad,endmem
+mode     fcb   $ff        mode
+
+         ifeq  DISTO
+         ifeq  DBHS
+name     fcs   "DIDBHS"
+         else  
+         ifeq  BIGSEC
+name     fcs   "DI1024"
+         else  
+         ifeq  MEDSEC
+name     fcs   "DIS512"
+         else  
+name     fcs   "DISTHD"
+         endc  
+         endc  
+         endc  
+
+         else  
+
+         ifeq  DBHS
+name     fcs   "DBHSHD"
+         else  
+         ifeq  BIGSEC
+name     fcs   "TC1024"
+         else  
+         ifeq  MEDSEC
+name     fcs   "TCC512"
+         else  
+name     fcs   "TCCCHD"
+         endc  
+         endc  
+         endc  
+
+         endc  
+
+         fcb   revisn
+
+* rbf dispatch vectors
+
+xferad   lbra  INIT
+
+         ifeq  BUFSEC
+         lbra  LOGREAD
+         else  
+         bra   READ
+         nop   
+         endc  
+
+
+         ifeq  BUFSEC
+         bra   LOGWRIT
+         else  
+         bra   WRITE
+         endc  
+
+         nop   
+         lbra  GETSTA
+         lbra  SETSTA
+         lbra  TERM
+
+         ifeq  BUFSEC
+         ttl   logical sector write
+
+* logwrit
+*
+* input:
+* b = msb of os9 lsn
+* x = lsbs of os9 lsn
+* y = path descriptor
+* u = static storage
+*
+* output:
+* 256 bytes moved from the os9 buffer to the physical buffer. Any
+* necessary physical sector writing and reading is done also.
+*
+LOGWRIT        
+
+         ifne  HOG
+         pshs  u
+logwr01  tst   blocked,u  critical lock on this section
+         beq   logwr02    because of the buffer
+         pshs  b,x
+         ldx   #1
+         os9   F$Sleep    wait a while
+         puls  b,x
+         bra   logwr01    and check again
+logwr02  com   blocked,u  set it
+         endc  
+
+         pshs  b          save HSB
+         tfr   x,d        msb and lsb into d for manipulation
+         stb   secidx,u   save lsb for indexing into phys sec buf later
+         andb  #m.smask   zero indexing bits
+         cmpd  lsecm,u    lower part of logical sector
+         puls  b          get back HSB
+         bne   diffwr     if compare fails, new sector, need preread
+         cmpb  lsech,u    compare HSB's
+
+         ifne  MDRIVES
+         beq   cpysecw    ok, in buffer
+diffwr         
+
+         else  
+
+         bne   diffwr     failed new sec need preread
+         lda   PD.DRV,y   current drive
+         cmpa  lastdrv,u  = last drive?
+         beq   cpysecw    if same, log sector is in physical buffer
+diffwr         
+         sta   lastdrv,u  save logical drive for future compare
+         endc  
+
+         tst   cached,u   need to flush physical sector?
+         beq   cleanw     no, skip ahead
+         pshs  b,x,y,u    save new sector
+         ldb   physech,u  get current HSB
+         ldx   physecm,u  get current msb & lsb
+         lbsr  WRITE      do the physical write
+         puls  b,x,y,u    restore new sector
+         bcs   logwre     exit on write error
+
+cleanw   lbsr  calcsec
+         pshs  y
+         lbsr  READ       read the physical sector
+         puls  y
+         bcs   logwre     exit on read error
+
+cpysecw        
+         ldy   PD.BUF,y   os9 buffer
+         lda   secidx,u   index into physical buffer
+         anda  #m.nsmask  mask upper off
+         leax  secbuf,u   location of physical buffer
+         ldb   #128
+cpsw2    tsta             done calculating index?
+         beq   cpsw2b     yup, exit loop
+         abx              these 2 ins advance 256 bytes into physical buffer
+         abx   
+         deca  
+         bra   cpsw2
+
+cpsw2b   clr   cached,u
+         com   cached,u   set cache dirty flag
+
+         ifeq  H6309
+
+cpsw3    ldw   #256       bytes to copy
+         tfm   y+,x+
+
+         else  
+
+* 16 bit copy, 128 words from os9 buff to phys buff
+cpsw3    ldu   ,y++       get byte from os9 buffer
+         stu   ,x++       to phys sector
+         decb  
+         bne   cpsw3
+
+         endc  
+
+         clrb  
+
+logwre         
+
+         ifne  HOG
+         puls  u          restore static pointer
+         clr   blocked,u  clear lock on this section
+         endc  
+
+         rts   
+
+
+         ttl   logical sector read
+
+* logread
+*
+* input:
+* b = msb of os9 lsn
+* x = lsbs of os9 lsn
+* y = path descriptor
+* u = static storage
+*
+* output:
+* 256 bytes moved from the physical buffer to the os9 buffer. Any
+* necessary physical sector writing and reading is done first.
+*
+LOGREAD        
+
+         ifne  HOG
+         pshs  u
+logre01  tst   blocked,u  critical lock on this section
+         beq   logre02    because of the buffer
+         pshs  b,x
+         ldx   #1
+         os9   F$Sleep    wait a while
+         puls  b,x
+         bra   logre01    and check again
+logre02  com   blocked,u  set lock
+         endc  
+
+         pshs  b          save HSB
+         tfr   x,d        msb and lsb into d for manipulation
+         stb   secidx,u   save lsb for indexing into phys sec buf later
+         andb  #m.smask   zero indexing bits
+         cmpd  lsecm,u    lower part of phys sector
+         puls  b          get back HSB
+         bne   diffrd     if compare fails, new sector to read
+         cmpb  lsech,u    compare HSB's
+
+         ifne  MDRIVES
+         beq   cpysecr    ok, in buffer
+diffrd         
+
+         else  
+
+         bne   diffrd     failed new sec need preread
+         lda   PD.DRV,y   current drive
+         cmpa  lastdrv,u  = last drive?
+         beq   cpysecr    if same, log sector is in physical buffer
+diffrd         
+         sta   lastdrv,u  save logical drive for future compare
+         endc  
+
+         tst   cached,u   need to flush physical sector?
+         beq   cleanr     no, skip ahead
+         pshs  b,x,y,u    save new sector
+         ldb   physech,u  get current HSB
+         ldx   physecm,u  get current msb & lsb
+         lbsr  WRITE      do the physical write
+         puls  b,x,y,u    restore new sector
+         bcs   logrde     exit on write error
+
+cleanr   bsr   calcsec
+         pshs  y
+         lbsr  READ       read the physical sector
+         puls  y
+         bcs   logrde     exit on read error
+
+cpysecr        
+         ldy   PD.BUF,y   os9 buffer
+         lda   secidx,u   index into physical buffer
+         anda  #m.nsmask  mask upper off
+         leax  secbuf,u   location of physical buffer
+         ldb   #128
+cpsr2    tsta             done calculating index?
+         beq   cpsr3      yup, exit loop
+         abx              these 2 ins advance 256 bytes into physical buffer
+         abx   
+         deca  
+         bra   cpsr2
+
+         ifeq  H6309
+
+cpsr3    ldw   #256
+         tfm   x+,y+
+
+         else  
+
+* 16 bit copy, 128 words from phys buff to os9 buff
+cpsr3    ldu   ,x++       get byte from phys sec
+         stu   ,y++       to os9 buffer
+         decb  
+         bne   cpsr3
+
+         endc  
+
+         clrb  
+logrde         
+
+         ifne  HOG
+         puls  u          restore static pointer
+         clr   blocked,u  clear lock on this section
+         endc  
+
+         rts   
+
+* fast calcsec (see comments in 6809 code below)
+
+         ifeq  H6309
+calcsec  stb   lsech,u
+         tfr   x,w
+
+         tfr   f,a
+         anda  #m.smask
+         sta   lsecl,u
+         ste   lsecm,u
+
+*aim #m.smask,lsecl,u
+
+* 4x (256 x 4 =1k sector) or 2x (256 x 2 = 512 sector)
+
+         ifeq  BIGSEC
+         lsrb  
+         rorw  
+         endc  
+
+         lsrb  
+         rorw  
+         stb   physech,u
+         tfr   w,x
+         stx   physecm,u
+         rts   
+
+         else  
+
+calcsec  stb   lsech,u    save logical sec hsb for next compare
+         stb   physech,u  and in physec for shifting
+         tfr   x,d        get msb & lsb into d for shifting
+         andb  #m.smask   strip lower bits lsb sec #
+         std   lsecm,u    save it for compare
+         std   physecm,u  as above for shifting
+         lsr   physech,u  shift 24 bits right 2 bits, converts to physical sec # (1st 8)
+         ror   physecm,u  (2nd 8)
+         ror   physecl,u  (3rd 8)
+
+* 4x (256 x 4 =1k sector) or 2x (256 x 2 = 512 sector)
+         ifeq  BIGSEC
+         lsr   physech,u  (1st 8, second time)
+         ror   physecm,u  (2nd 8, second time)
+         ror   physecl,u  (3rd 8, second time)
+         endc  
+
+         ldx   physecm,u  for return value
+         ldb   physech,u  for return value
+         rts   
+
+         endc  (H6309)
+         endc  (bufsec)
+
+         ttl   write sector
+
+*  write
+*
+* input:
+*  b = msb of lsn
+*  x = lsb's of lsn
+*  y = path descriptor
+*  u = static storage
+*
+* output:
+*   b,x,y,u destroyed
+*   256 bytes written (512/1024 bufsec version)
+*   otherwise, carry set and b = error code
+* 
+*
+WRITE          
+         ifeq  MPAK
+         pshs  u          need for restore at end of write routine 
+         tst   mpslot,u   multipak in use? (1xxxxxxxb = no)
+         bmi   slotw2     hi bit set, skip
+         lda   >mpsel     get current value
+         sta   mpstor,u   save it
+         anda  #m.mpscs   clear scs bits
+         ora   mpslot,u   add in scs select
+         sta   >mpsel     put it to mpak
+slotw2         
+         endc  
+
+         lda   #o.write   controller write opcode
+         lbsr  setup      setup  packet, initiate command
+
+         ifeq  BUFSEC
+         leax  secbuf,u   get address of physical sector buffer
+         clr   cached,u   clear cache dirty flag
+         else  
+         ldx   PD.BUF,y   get buffer address into x
+         endc  
+
+         ldu   V.PORT,u
+         leay  statpo,U
+         leau  datapo,u   u points to data port
+         lda   #m.req
+
+         ifeq  HOG
+W0       bita  ,y         get req bit
+         beq   W0         wait till req
+
+         else  
+
+W00      clrb             256 tries
+W0       bita  ,y         get req bit
+         bne   W0B
+         decb  
+         bne   W0         keep trying
+         lbsr  doslp
+         bra   W00
+
+         endc  
+
+         ifeq  DBHS
+W0B      bra   W1         first req got already, skip ahead
+W0C      ldb   ,y         status port
+         bitb  #m.req     have req?
+         beq   W0C        wait till we do
+         bitb  #m.cmd     finished putting data?
+         bne   W2A        if so, skip ahead
+W1       lda   ,x+        get a byte from memory
+         sta   ,u         put it to the drive
+         bra   W0C        go again
+
+         else  
+
+* for 6309, use block transfer fixed size. Not really according to scsi
+* spec, but FAST!
+
+         ifeq  H6309
+W0B            
+         ifeq  BIGSEC
+         ldw   #1024
+         tfm   x+,u
+         else  
+         ifeq  MEDSEC
+         ldw   #512
+         tfm   x+,u
+         else  
+         ldw   #256
+         tfm   x+,u
+         endc  
+         endc  
+
+         else  
+
+         ifeq  DISTO
+W0B      bra   W2
+W1       lda   ,X+
+         sta   ,U
+W2       ldb   ,Y
+         andb  #m.nnc     and out the floating bits
+         cmpb  #m.req+m.busy still have data?
+         beq   W1         yup go for more
+
+         else  
+W0B      ldb   #m.req+m.busy status mask for command/data mode
+         bra   W2
+W1       lda   ,X+
+         sta   ,U
+W2       cmpb  ,Y
+         beq   W1
+         endc  
+
+* didn't work, don't know why. changed to make disto easier
+
+*W0B ldb #m.cmd command mode?
+* bra W2
+*W1 LDA ,X+
+* STA ,U
+*W2 BITB ,Y
+* BEQ W1 not command mode yet, go for more data
+
+         endc  
+         endc  
+
+         ifeq  DISTO
+
+W2A      ldb   ,y         get status bits
+         andb  #m.nnc     strip floating bits
+         cmpb  #m.req+m.busy+m.cmd+m.in
+         bne   W2A
+         lda   ,u         status data byte
+W2C      ldb   ,y         get status bits
+         andb  #m.nnc     strip floating bits
+         cmpb  #m.req+m.busy+m.msg+m.cmd+m.in
+         bne   W2C
+
+         else  
+
+W2A      ldb   #m.req+m.busy+m.cmd+m.in
+W2B      cmpb  ,y         get status
+         bne   W2B
+         lda   ,u         status data byte
+         ldb   #m.req+m.busy+m.msg+m.cmd+m.in
+W2C      cmpb  ,y
+         bne   W2C        get term byte
+
+         endc  
+
+         ldb   ,u         discard
+         anda  #m.error   isolate error bit
+         beq   w3         if no error
+         comb             flag error
+         ldb   #E$Write   error code for OS9
+         bra   w4
+
+w3       clrb             flag no errors
+
+w4             
+         ifeq  MPAK
+         puls  u          saved at top of routine
+         pshs  a,cc
+         lda   mpstor,u
+         sta   >mpsel     restore old mpak slot value
+         puls  a,cc
+         endc  
+
+         rts   
+
+
+         ttl   read sector
+
+*  read
+*
+* input:
+*  b = hsb of lsn
+*  x = lsb's of lsn
+*  y = path descriptor
+*  u = static storage
+* output:
+*  b,x,y destroyed, u preserved
+*  if no error, 256 bytes into sector buffer
+*   otherwise carry set and b = error
+*
+*
+READ           
+         ifeq  MPAK
+         tst   mpslot,u   multipak in use? (1xxxxxxxb = no)
+         bmi   slotr2     hi bit set, skip change
+         lda   >mpsel     get current value
+         sta   mpstor,u   save it
+         anda  #m.mpscs   clear scs bits
+         ora   mpslot,u   add in scs select
+         sta   >mpsel     put it to mpak
+slotr2         
+         endc  
+
+         tstb             hsb = 0
+         bne   rdnot0     no, skip
+         leax  ,x         msb & lsb =0?
+         bne   rdnot0
+
+         ifeq  BUFSEC
+         lda   secidx,u   least 2 bits are in here
+         anda  #m.nsmask
+         bne   rdnot0
+         endc  
+
+* first access to drive (implied) so recal the drive to home heads.
+
+         pshs  d,x
+         leax  sec0fl,u   get flag for this drive
+         lda   PD.DRV,y   get drive #
+         tst   a,x        drive LSN0 already read?
+         bne   sec0dn     yup, skip it
+         com   a,x        flag recal done now
+         clr   didflag,u
+         com   didflag,u  set disk id sec flag on
+         lda   PD.DNS,y
+         anda  #m.recal   should this drive be homed?
+         beq   sec0dn
+
+         ldx   #0         clear sector # back out (B is still clear)
+
+         lda   #o.recal
+         lbsr  setup
+
+         ifeq  DISTO
+
+recal0   ldb   statpo,x   (see comments at W2A)
+         andb  #m.nnc
+         cmpb  #m.req+m.busy+m.cmd+m.in
+         bne   recal0
+         lda   datapo,x
+recal1   ldb   statpo,x
+         andb  #m.nnc
+         cmpb  #m.req+m.busy+m.msg+m.cmd+m.in
+         bne   recal1
+
+         else  
+
+         ldb   #m.req+m.busy+m.cmd+m.in
+recal0   cmpb  statpo,x
+         bne   recal0
+         lda   datapo,x
+         ldb   #m.req+m.busy+m.msg+m.cmd+m.in
+recal1   cmpb  statpo,x
+         bne   recal1
+
+         endc  
+
+         lda   datapo,x
+sec0dn         
+         puls  d,x
+
+rdnot0   lda   #o.read    opcode for read operation
+         lbsr  setup      setup packet, initiate command 
+
+         ifeq  BUFSEC
+         leax  secbuf,u   physical buffer location
+         clr   cached,u
+         else  
+         ldx   PD.BUF,y   setup buffer loc in x
+         endc  
+
+         pshs  Y,U
+         ldu   V.PORT,u
+         leay  statpo,U
+         leau  datapo,u
+
+         lda   #m.req     wait for data request
+
+         ifeq  HOG
+
+R0       bita  ,y
+         beq   R0         wait for req
+
+         else  
+R00      clrb             256 tries for req
+R0       bita  ,y
+         bne   R0B
+         decb  
+         bne   R0         keep trying
+         lbsr  doslp
+         bra   R00
+
+         endc  
+
+         ifeq  DBHS
+
+R0B      bra   R1         first time have req, skip forward
+R0C      ldb   ,y         get status
+         bitb  #m.req     request bit
+         beq   R0C        no, go again
+         bitb  #m.cmd     finished with data?
+         bne   R2A        yes, skip ahead
+R1       lda   ,u         get data from the controller
+         sta   ,x+        to memory
+         bra   R0C        go again
+
+         else  
+
+R0B            
+* for 6309, use block transfer fixed size. Not really according to scsi
+* spec, but FAST!
+
+         ifeq  H6309
+         ifeq  BIGSEC
+         ldw   #256
+         orcc  #%01010000
+         tfm   u,x+
+         andcc  #%10101111
+         ldw   #256
+         orcc  #%01010000
+         tfm   u,x+
+         andcc  #%10101111
+         ldw   #256
+         orcc  #%01010000
+         tfm   u,x+
+         andcc  #%10101111
+         ldw   #256
+         orcc  #%01010000
+         tfm   u,x+
+         andcc  #%10101111
+         else  
+         ifeq  MEDSEC
+         ldw   #256
+         orcc  #%01010000
+         tfm   u,x+
+         andcc  #%10101111
+         ldw   #256
+         orcc  #%01010000
+         tfm   u,x+
+         andcc  #%10101111
+         else  
+         ldw   #256
+         orcc  #%01010000
+         tfm   u,x+
+         andcc  #%10101111
+         endc  
+         endc  
+
+         else  
+
+         ifeq  DISTO
+         bra   R2
+R1       lda   ,U
+         sta   ,X+
+R2       ldb   ,Y
+         andb  #m.nnc     and out floating bits
+         cmpb  #m.in+m.busy+m.req still more data?
+         beq   R1         yes, go for more
+         else  
+         ldb   #m.in+m.busy+m.req test bit for command/data mode
+         bra   R2
+R1       lda   ,U
+         sta   ,X+
+R2       cmpb  ,Y
+         beq   R1
+         endc  
+
+         endc  
+         endc  
+
+         ifeq  DISTO
+
+R2A      ldb   ,y         get status bits
+         andb  #m.nnc     strip floating bits
+         cmpb  #m.req+m.busy+m.cmd+m.in
+         bne   R2A
+         lda   ,u         status data byte
+R2C      ldb   ,y         get status bits
+         andb  #m.nnc     strip floating bits
+         cmpb  #m.req+m.busy+m.msg+m.cmd+m.in
+         bne   R2C
+
+         else  
+
+R2A      ldb   #m.req+m.busy+m.cmd+m.in
+R2B      cmpb  ,y         get status
+         bne   R2B
+         lda   ,u         status data byte
+         ldb   #m.req+m.busy+m.msg+m.cmd+m.in
+R2C      cmpb  ,y
+         bne   R2C        get term byte
+
+         endc  
+
+         ldb   ,u         discard
+         anda  #m.error   isolate error bit
+         puls  Y,U
+         beq   r3         if no error detected
+         comb             flag error to OS9
+         ldb   #E$Read    error code to be returned
+         bra   r6
+r3       lda   didflag,u
+         beq   r5         if lsn not 0
+         clr   didflag,u
+         lda   PD.DRV,y   get drive number
+         ldb   #DRVMEM    size of each entry
+         mul              calculate the offset into the table
+         leax  tables,u   get base address
+         leax  d,x        get record address
+
+         ifeq  BUFSEC
+         leay  secbuf,u   physical sector buffer
+         else  
+         ldy   PD.BUF,y   sector buffer address
+         endc  
+
+         ifeq  H6309
+
+         ldw   #DD.SIZ
+         tfm   y+,x+
+
+         else  
+
+         ldb   #DD.SIZ    number of bytes to copy
+r4       lda   ,y+        get a byte from the disk identification sector
+         sta   ,x+        put it into the drive table
+         decb             count bytes to copy
+         bne   r4
+
+         endc  
+
+r5       clrb  
+r6             
+         ifeq  MPAK
+         pshs  a,cc
+         lda   mpstor,u
+         sta   >mpsel     restore old mpak slot value
+         puls  a,cc
+         endc  
+
+         rts   
+
+         ttl   device init
+
+*  init
+*
+* input:
+*  y = device descriptor
+*  u = static storage
+*
+* output:
+*  carry set if error
+*  b = error code
+*
+*  y,u preserved. others destroyed
+
+INIT     pshs  y
+
+         ldx   V.PORT,u
+
+         ifne  DISTO
+         sta   selrst,x   reset select line
+         endc  
+
+* removed 1-16-94, multiple drives are now imbeded scsi, each has controller
+*  shouldn't do a scsi bus reset
+
+* ifne ADAPTEC
+* sta rstpo,x reset controllers (if more than one device, should be removed)
+* ldb #m.busy
+*iniw bitb statpo,x wait till not busy
+* bne iniw
+* endc
+
+         leay  $21,y      get start of params & offsets in descriptor
+         ldb   #EXTPRM    bytes to transfer
+         leax  param,u    start of drive parameters in static storage
+offload  lda   ,y+        get drive parameters from descriptor
+         sta   ,x+        put into static
+         decb  
+         bne   offload    if not done
+         puls  y
+         clr   didflag,u  sector 0 read flag=cleared
+         lda   #$ff       will set lastphy to undef
+         sta   lastphy,u  store it
+
+         ifeq  BUFSEC
+         sta   lastdrv,u  set last logical read to unknown
+         endc  
+
+         ldb   #numdrvs   number of drives controller supports
+         stb   V.NDRV,u   to the manager space
+         leax  tables,u
+         lda   #$ff
+fixtab   sta   DD.TOT,x   setup starting info in the tables until the first sector
+         clr   V.TRAK,x   of the device is read which will fill in the drive tables
+         sta   V.TRAK+1,x
+         leax  DRVMEM,x
+         decb  
+         bne   fixtab     if not done with both tables
+         lda   #1
+         sta   blocks,u   set up for normal read/write 1 sector
+         clr   blocked,u  extended buffer locked flag
+         clr   plocked,u  param block locked flag
+
+         ifeq  BUFSEC
+         clr   cached,u   cache dirty flag
+         clr   secidx,u   index into physical sector
+         ldb   #$ff
+         stb   lsech,u    set begin phy sec number to impossible value to force read
+         stb   lsecm,u
+         ldb   #m.smask
+         stb   lsecl,u
+         endc  
+
+         ldb   #numdrvs
+         leax  sec0fl,u   clean recal flags
+clnrecal       
+         clr   ,x+
+         decb  
+         bne   clnrecal
+
+         clrb             no errors
+         rts   
+
+         ttl   sleep for rest of tick. Switch mpak slot if necessary (during HW Access)
+
+
+* entry conditions:
+* U = static storage
+* exit conditions
+* registers preserved
+
+doslp          
+         pshs  b,x
+
+         ifeq  MPAK
+         tst   mpslot,u   multipak in use? (1xxxxxxxb = no)
+         bpl   doslp2     hi bit clear, do change
+         ldx   #1
+         os9   F$Sleep    wait a while
+         bra   doslp      exit
+doslp2   ldb   mpstor,u   get back old mpak sel value
+         stb   >mpsel     put it to mpak
+         endc  
+
+         ldx   #1
+         os9   F$Sleep    wait a while
+
+         ifeq  MPAK
+         ldb   >mpsel     get current value (could have changed)
+         stb   mpstor,u   save it again
+         andb  #m.mpscs   clear scs bits
+         orb   mpslot,u   add in scs select
+         stb   >mpsel     put it to mpak
+         endc  
+
+doslpo         
+         puls  b,x,pc
+
+
+         ttl   setup and initiate command
+
+* entry conditions:
+* Y = path descriptor
+* A = opcode to controller
+* B = MSB of disk logical sector number
+* X = LSB's of disk logical sector number
+* U = static storage
+*
+* setup command packet
+* select controller
+* initiate command
+*
+* exit conditions:
+* A = destroyed
+* B = destroyed
+* X = controller base
+* U = unchanged (static)
+* Y = unchanged (PD)
+*
+setup          
+set0           
+         ifne  HOG
+         tst   plocked,u  critical lock on this section
+         beq   set02
+* sleep was inline, now call
+         bsr   doslp      sleep for a while
+         bra   set0       and check again
+set02    com   plocked,u  set the lock
+         endc  
+
+         sta   opcode,u   put controller opcode into command packet
+         stb   lun,u
+         stx   lsn,u
+         lda   PD.DNS,y   get physical drive number (0 or 1 supported) and init flag
+         tfr   a,b
+         anda  #m.phys    (bit 5 is physical drive number)
+         andb  #m.init
+         beq   set25      skip init if not set in desc
+
+* changed 4-16-96, always check for init, based on descriptor
+*was ifne ADAPTEC adaptec handles drive parameter switches internally
+
+         cmpa  lastphy,u  current physical drive?
+         beq   set25      yes, continue
+
+         pshs  a,y
+         sta   lastphy,u
+         ldx   V.PORT,u
+
+* wait for controller to finish any previous command
+* needs x set to port base and y set to pd
+
+         ldb   #m.busy    busy status bit
+sel1     bitb  statpo,x   read status port
+
+         ifeq  HOG
+
+         bne   sel1       wait till not busy
+
+         else  
+
+         beq   sel1b      skip if not busy
+         bsr   doslp
+         bra   sel1
+
+         endc  
+
+sel1b    lda   PD.DNS,y   controller number (lower 4 bits of PD.DNS var)
+         anda  #m.cont    isolate controller number
+         sta   datapo,x   latch the controller select
+         sta   selpo,x    generate a select strobe
+sel2     bitb  statpo,x   read status port
+         beq   sel2       wait for controller to recognize select
+
+         ifne  DISTO
+         sta   selrst,x   reset select (scuzzie version)
+         endc  
+
+         lda   lastphy,u  get drive back
+         leay  param,U    Point to Drive 0 Params as Default
+         tsta             Is it Drive 0?
+         beq   setp2      yes, get drive 0 parameters
+         leay  param1-param,Y Point to Drive 1 Params
+setp2    lda   #m.req
+setp3    bita  statpo,x   get status
+         beq   setp3      wait till ready
+         lda   #o.param   set param command
+         sta   datapo,x   send it out
+         ldb   #5         rest of packet
+         clra  
+pakout   sta   datapo,x   dump em out!
+         decb  
+         bne   pakout     if not done
+         lda   #m.req
+setp4    bita  statpo,x
+         beq   setp4
+         ldb   #8         # of parameters to send out
+paramout lda   ,y+        get a parameter
+         sta   datapo,x   send it out
+         decb  
+         bne   paramout   if not done, go again
+
+         ifeq  DISTO
+setp5    ldb   statpo,x   get status bits
+         andb  #m.nnc     strip floating bits
+         cmpb  #m.req+m.busy+m.cmd+m.in
+         bne   setp5
+         lda   datapo,x   status data byte
+setp6    ldb   statpo,x   get status bits
+         andb  #m.nnc     strip floating bits
+         cmpb  #m.req+m.busy+m.msg+m.cmd+m.in
+         bne   setp6
+
+         else  
+
+         ldb   #m.req+m.busy+m.cmd+m.in
+setp5    cmpb  statpo,x   get status
+         bne   setp5
+         lda   datapo,x   status data byte
+         ldb   #m.req+m.busy+m.msg+m.cmd+m.in
+setp6    cmpb  statpo,x
+         bne   setp6      get term byte
+
+         endc  
+
+         ldb   datapo,x   discard
+         puls  a,Y
+
+set25          
+         ora   lun,u      or in physical drive with sector number top 8 of 24 bits
+         sta   lun,u      and put it back in place
+         lda   PD.STP,y   get step and options
+         sta   control,u  to the packet
+         lda   PD.DRV,y   drive # from path descriptor
+         lsla             byte to word offset
+         leax  offsd1,u   base of offsets
+         ldd   a,x        get offset
+         addd  lun,u      add in top 16 of 24 bit sector number
+         std   lun,u
+         ldx   V.PORT,u
+
+* wait for controller to finish any previous command
+* needs x set to port base and y set to pd
+
+set26    ldb   #m.busy    busy status bit
+sel3     bitb  statpo,x   read status port
+
+         ifeq  HOG
+
+         bne   sel3       wait till not busy
+
+         else  
+
+         beq   sel3b      skip ahead if not busy
+         lbsr  doslp
+         bra   sel3
+
+         endc  
+
+sel3b    lda   PD.DNS,y   controller number (lower 4 bits of PD.DNS var)
+         anda  #m.cont    isolate controller number
+         sta   datapo,x   latch the controller select
+         sta   selpo,x    generate a select strobe
+sel4     bitb  statpo,x   read status port
+         beq   sel4       wait for controller to recognize select
+
+         ifne  DISTO
+         sta   selrst,x   reset select (scuzzie version)
+         endc  
+
+         ttl   send command packet
+* sends the command packet to the disk controller
+* needs x set to V.PORT
+
+taskout  pshs  y
+         leay  packet,u   address of scsi packet
+         ldb   #6         number of bytes to transfer
+task00   lda   #m.req
+task0    bita  statpo,x
+         beq   task0
+
+* ifeq H6309
+*
+* orcc #%01010000
+* ldw #6
+* tfm y+,x
+* andcc #%10101111
+*
+* else
+
+task1    lda   ,y+        get a byte from the packet
+         sta   datapo,x   send it to the controller
+         decb             count the bytes
+
+         ifeq  DBHS
+         bne   task00     need to check req again
+         else  
+         bne   task1
+         endc  
+
+* endc
+
+         ifne  HOG
+         clr   plocked,u  clear critical section lock
+         endc  
+
+         puls  y,pc
+
+         ifeq  CANFORM
+
+         ttl   format the drive
+
+* format
+*
+* Called by setstat. Entire drive will be formatted.
+* 
+FORMAT   ldd   R$U,X      Get Track Number
+         lbne  nofrmerr   If Not Zero We are Done
+         ldd   R$Y,X      get sides
+         tsta  
+         lbne  nofrmerr
+
+         ifeq  MPAK
+         pshs  b
+         tst   mpslot,u   multipak in use? (1xxxxxxxb = no)
+         bmi   slotf2     hi bit set, skip change
+         ldb   >mpsel     get current value
+         stb   mpstor,u   save it
+         andb  #m.mpscs   clear scs bits
+         orb   mpslot,u   add in scs select
+         stb   >mpsel     put it to mpak
+slotf2         
+         puls  b
+         endc  
+
+         tfr   D,X        Set LSB's of Track # to Zero
+
+         lda   PD.ILV,y   get drive interleave
+*sta >$ff68 DEBUG
+         sta   blocks,u   put into packet (in place of blocks, restored below)
+
+* deal with the drive offset, needs to be zeroed for unit format
+         pshs  y
+* nitros adj
+
+         ifeq  H6309
+         lda   PD.DRV+2,y
+         else  
+         lda   PD.DRV,y
+         endc  
+
+         lsla             drive to index
+         leax  offsd1,u   offset table
+         stx   tempw1,u   save the offset location
+         ldy   a,x
+         sty   tempw2,u   save the offset value
+         ldy   #0
+         sty   a,x        set the offset temporarily to 0
+         puls  y
+
+         ifne  HOG
+format0  tst   plocked,u
+         beq   format1
+         lbsr  doslp
+         bra   format0
+         com   plocked,u
+format1        
+         endc  
+
+         lda   #o.formt   Get Format Command
+         clrb             sector high byte
+         ldx   #0         sector low word
+         lbsr  setup
+
+* restore the original offset
+
+         pshs  x
+         ldx   tempw1,u   offset loc
+         ldd   tempw2,u   offset value
+         std   ,x         put it back in the table
+         puls  x
+
+         lda   #1
+         sta   blocks,u   put 1 back to blocks
+
+         ifeq  DISTO
+format2  ldb   statpo,x   get status bits
+         andb  #m.nnc     strip floating bits
+         cmpb  #m.req+m.busy+m.cmd+m.in
+         beq   format2b
+         lbsr  doslp
+         bra   format2
+format2b lda   datapo,x   status data byte
+format3  ldb   statpo,x   get status bits
+         andb  #m.nnc     strip floating bits
+         cmpb  #m.req+m.busy+m.msg+m.cmd+m.in
+         bne   format3
+
+         else  
+
+         ldb   #m.req+m.busy+m.cmd+m.in
+format2  cmpb  statpo,x   get status
+         beq   format2b
+         lbsr  doslp
+         bra   format2
+format2b lda   datapo,x   status data byte
+         ldb   #m.req+m.busy+m.msg+m.cmd+m.in
+format3  cmpb  statpo,x
+         bne   format3    get term byte
+
+         endc  
+
+         ldb   datapo,x   discard
+         anda  #m.error
+         beq   nofrmerr   format sucessful
+         comb             indicate error
+         ldb   #E$Write
+         bra   formato
+
+         endc  
+
+nofrmerr clrb  
+formato        
+         ifeq  MPAK
+         pshs  a,cc
+         lda   mpstor,u
+         sta   >mpsel     restore old mpak slot value
+         puls  a,cc
+         endc  
+
+         ifne  HOG
+         clr   plocked,u
+         endc  
+
+         rts   
+
+SETSTA   ldx   PD.RGS,y   find the stacked values
+         cmpb  #SS.Reset
+         beq   nofrmerr
+
+         ifeq  CANFORM
+
+         cmpb  #SS.WTrk   is it the format command?
+         bne   noformat
+
+* is it ok to format this drive?
+         lda   PD.DNS,y
+         anda  #m.format
+         lbne  format
+noformat       
+         endc  
+
+GETSTA   comb  
+         ldb   #E$UnkSvc  unknown service request
+         rts   
+
+TERM     equ   nofrmerr
+
+         emod  
+endmod   equ   *
+         end