changeset 1276:4e0afd4781a9

Removed "BLOB" fix from boot_1773 as it does not work with Level 2. cc3disk.asm is now back-ported from NitrOS-9
author boisy
date Wed, 27 Aug 2003 13:07:36 +0000
parents 6f49a2fa6c41
children 54ebe88fdc10
files level2/modules/boot_1773.asm level2/modules/cc3disk.asm
diffstat 2 files changed, 809 insertions(+), 593 deletions(-) [+]
line wrap: on
line diff
--- a/level2/modules/boot_1773.asm	Tue Aug 26 18:59:10 2003 +0000
+++ b/level2/modules/boot_1773.asm	Wed Aug 27 13:07:36 2003 +0000
@@ -10,8 +10,6 @@
 *        rate and disk timeout changes
 *   6r2  Added '.' output for each sector under NitrOS9 BGP 03/05/18
 *        for Mark Marlette (a special request :)
-*   6r3  Added BLOB-Stop code as per Robert Gault's     BGP 03/08/04
-*        suggestion.
 
          nam   Boot
          ttl   WD1773 Boot module
@@ -29,7 +27,7 @@
 
 tylg     set   Systm+Objct
 atrv     set   ReEnt+rev
-rev      set   $03
+rev      set   $02
 edition  set   6
 
          mod   eom,name,tylg,atrv,start,size
@@ -182,18 +180,17 @@
          lbsr  L01AA
          orb   #$80
          lda   #$02
-*L0111    bita  >$FF48
-*         bne   L0123
-*         leay  -$01,y
-*         bne   L0111
-*         lda   ,u
-*         sta   >$FF40
-*         puls  y
-*         bra   L0138
+L0111    bita  >$FF48
+         bne   L0123
+         leay  -$01,y
+         bne   L0111
+         lda   ,u
+         sta   >$FF40
+         puls  y
+         bra   L0138
 L0123    lda   >$FF4B
          sta   ,x+
-*         stb   >$FF40
-         nop
+         stb   >$FF40
          bra   L0123
 
 NMIRtn   leas  R$Size,s
--- a/level2/modules/cc3disk.asm	Tue Aug 26 18:59:10 2003 +0000
+++ b/level2/modules/cc3disk.asm	Wed Aug 27 13:07:36 2003 +0000
@@ -1,648 +1,867 @@
 ********************************************************************
-* CC3Disk - CoCo 3 WD1773 disk driver
+* CC3Disk - WD1773 Disk Controller Driver
 *
+* A lot of references to **.CYL or <u00B6 using 16 bit registers can be
+* changed to 8 bit registers with a +1 offset, since track #'s >255 are
+* ignored
+*
+* NOTE: 512 bytes is reserved as a physical sector buffer. Any reads/
+*  writes are done from this buffer to the controller. Copies of the 256
+*  byte chunk needed are done by a block memory move
+
 * $Id$
 *
 * Ed.    Comments                                       Who YY/MM/DD
 * ------------------------------------------------------------------
-* 9      Original Tandy distribution version
-* 12     Obtained from L2 Upgrade archive               BGP 98/10/12
+*  11    Special opts for TC9 to slow controller reads      93/05/12
+*        and writes
+*        TFM's between sector buffers & in drive table
+*        init/copies
+*        Changed software timing loop (drive spin-up) to
+*        F$Sleep for 32 ticks
+*        Shrunk (slowed slightly) error returns
+*        Added blobstop code
 
          nam   CC3Disk
-         ttl   CoCo 3 WD1773 disk driver
+         ttl   WD1773 Disk Controller Driver
 
-* Disassembled 98/08/24 22:57:22 by Disasm v1.6 (C) 1988 by RML
+TC9      equ   0              Set to 1 for TC9 special slowdowns
+PRECOMP  equ   0              Set to 1 to turn on write precompensation
 
-         ifp1
+         IFP1
          use   defsfile
-         endc
+         use   rbfdefs
+         ENDC
 
 tylg     set   Drivr+Objct   
 atrv     set   ReEnt+rev
 rev      set   $01
-edition  set   12
+edition  set   11
 
          mod   eom,name,tylg,atrv,start,size
 
-u0000    rmb   1
-u0001    rmb   3
-u0004    rmb   4
-u0008    rmb   7
-u000F    rmb   35
-u0032    rmb   29
-u004F    rmb   1
-u0050    rmb   58
-u008A    rmb   29
-u00A7    rmb   2
-u00A9    rmb   1
+u0000    rmb   DRVBEG+(DRVMEM*4)
+u00A7    rmb   2              Last drive table accessed (ptr)
+u00A9    rmb   1              Bit mask for control reg (drive #, side,etc)
 u00AA    rmb   1
-u00AB    rmb   2
+sectbuf  rmb   2              Ptr to 512 byte sector buffer
 u00AD    rmb   1
 u00AE    rmb   1
-u00AF    rmb   2
-u00B1    rmb   4
-u00B5    rmb   1
-u00B6    rmb   2
-u00B8    rmb   1
-u00B9    rmb   1
+FBlock   rmb   2          block number for format
+FTask    rmb   1          task number for format
+u00B1    rmb   2              Vi.Cnt word for VIRQ
+u00B3    rmb   2              Vi.Rst word for VIRQ
+u00B5    rmb   1              Vi.Stat byte for VIRQ (drive motor timeout)
+u00B6    rmb   2              OS9's logical sector #
+u00B8    rmb   1              PCDOS (512 byte sector) sector #
+
 size     equ   .
-         fcb   $FF 
+
+         fcb   DIR.+SHARE.+PEXEC.+PWRIT.+PREAD.+EXEC.+UPDAT.
 
 name     fcs   /CC3Disk/
          fcb   edition
 
-start    lbra  Init
-         lbra  Read
-         lbra  Write
-         lbra  GetStat
-         lbra  SetStat
-         lbra  Term
+
+L0028    fdb   $00f0          Initial count for VIRQ (240)
 
-L0028    fcb   $00,$f0
-L002A    fcb   $00,$01,$0a
+irqpkt   fcb   $00            Normal bits (flip byte)
+         fcb   $01            Bit 1 is interrupt request flag (Mask byte)
+         fcb   10             Priority byte
 
-Init     clra
-         sta   <D.MotOn clear out floppy disk timeout counter
-         ldx   u0001,u
-         leax  $08,x
-         lda   #$D0
-         sta   ,x
-         lbsr  L0412
-         lda   ,x
-         lda   #$FF
-         sta   >u00B8,u
-         sta   >u00B9,u
-         ldb   #$04
-         leax  u000F,u
-L004B    sta   ,x
-         sta   <$15,x
-         leax  <$26,x
-         decb  
-         bne   L004B
-         leax  >L0256,pcr
-         stx   <$00FC
-         pshs  y
-         leay  >u00B5,u
-         tfr   y,d
-         leay  >L050B,pcr
-         leax  >L002A,pcr
-         os9   F$IRQ    
-         puls  y
-         bcs   L0086
-         ldd   #$0200
-         pshs  u
-         os9   F$SRqMem 
-         tfr   u,x
-         puls  u
-         bcs   L0086
-         stx   >u00AB,u
-GetStat  clrb  
+* Entry: Y=Ptr to device descriptor
+*        U=Ptr to device mem
+INIT     clr   <D.MotOn   flag drive motor as not running
+         ldx   V.PORT,u       Get Base port address
+         leax  8,x            Point to Status/Command register
+         lda   #$D0           Force Interrupt command
+         sta   ,x             Send to FDC
+         lbsr  L0406          Time delay for ~ 108 cycles
+         lda   ,x             Eat status register
+         ldd   #$FF04         'Invalid' value & # of drives
+         sta   >u00B8,u       Set 512 byte sector # to bogus value
+         sta   >u00B8+1,u
+         leax  DRVBEG,u       Point to start of drive tables
+L004B    sta   ,x             DD.TOT MSB to bogus value
+         sta   <V.TRAK,x      Init current track # to bogus value
+         leax  <DRVMEM,x      Point to next drive table
+         decb                 Done all 4 drives yet?
+         bne   L004B          No, init them all
+         leax  >L024A,pc      Point to NMI service routine
+         stx   <D.NMI         Install as system NMI
+         pshs  y              Save device dsc. ptr
+         leay  >u00B5,u       Point to Vi.Stat in VIRQ packet
+         tfr   y,d            Make it the status register ptr for IRQ
+         leay  >irqsvc,pc     Point to IRQ service routine
+         leax  >irqpkt,pc     Point to IRQ packet
+         os9   F$IRQ          Install IRQ
+         puls  y              Get back device dsc. ptr
+         bcs   L0086          If we can't install IRQ, exit
+         ldd   #512           Request 512 byte sector buffer
+         pshs  u              Preserve device mem ptr
+         os9   F$SRqMem       Request sector buffer
+         tfr   u,x            Move ptr to sector buffer to x
+         puls  u              Restore device mem ptr
+         bcs   L0086          If error, exit with it
+         stx   >sectbuf,u     Save ptr to sector buffer
+
+GETSTA   clrb                 no GetStt calls - return, no error, ignore
 L0086    rts   
 
-Term     leay  >u00B1,u
-         ldx   #$0000
-         os9   F$VIRQ   
+TERM     leay  >u00B1,u       Point to VIRQ packet
+         IFNE  H6309
+         tfr   0,x        "remove"
+         ELSE
          ldx   #$0000
-         os9   F$IRQ    
-         pshs  u
-         ldu   >u00AB,u
-         ldd   #$0200
+         ENDC
+         os9   F$VIRQ         Remove VIRQ
+         IFNE  H6309
+         tfr   0,x        "remove"
+         ELSE
+         ldx   #$0000
+         ENDC
+         os9   F$IRQ          Remove IRQ
+         pshs  u              Save device mem ptr
+         ldu   >sectbuf,u     Get pointer to sector buffer
+         ldd   #512           Return sector buffer memory
          os9   F$SRtMem 
-         puls  u
-         clra  
-         sta   >$FF40
-         sta   <u0032
-L00AB    rts   
-L00AC    pshs  x,b
-         stx   >u00B6,u
-         lda   <$23,y
-         anda  #$04
-         bne   L00BB
-         bra   L00CA
-L00BB    puls  x,b
-         clrb  
-         tfr   x,d
-         rora  
-         rorb  
-         tfr   d,x
-         stx   >u00B8,u
-         clrb  
+         puls  u              Restore device mem ptr
+         clr   >$FF40     shut off drive motors
+         clr   <D.MotOn   Clear out drive motor timeout flag
+L00AB    rts                  return
+
+* Check if 512 byte sector conversion needed
+* Entry: B:X=LSN
+*          U=Static mem ptr
+*          Y=Path dsc. ptr
+* Exit:    X=New LSN (same as original for 256 byte sectors, 1/2 of original
+*            for 512 byte sectors
+L00AC    pshs  x,b            Save LSN
+         stx   >u00B6,u       Save OS9 LSN
+         lda   <PD.TYP,y      Get device type from path dsc.
+         anda  #%00000100     Mask out all but 512 byte sector flag
+         bne   L00BB          512 byte sectors, go process
+L00CA    puls  pc,x,b         Restore LSN & return
+
+* 512 byte sector processing goes here
+L00BB    puls  x,b            Get back LSN
+         clrb                 Clear carry for rotate (also high byte of LSN)
+         tfr   x,d            Move to mathable register
+         IFNE  H6309
+         rord             Divide LSN by 2
+         ELSE
+         rora
+         rorb
+         ENDC
+         tfr   d,x            Move new LSN back to X
+         stx   >u00B8,u       Save 'physical' LSN (for controller)
+         clrb                 No error & return
          rts   
-L00CA    puls  pc,x,b
-Read     bsr   L00AC
-         lda   #$91
-         pshs  x
-         lbsr  L0162
-         puls  x
-         bcs   L00AB
-         pshs  y,x
-         cmpx  #$0000
-         bne   L012D
-         puls  y,x
-         lda   <$23,y
-         bita  #$40
-         beq   L00F0
-         lbsr  L0526
-         pshs  y,x
+
+start    lbra  INIT
+         bra   READ
+         nop
+         lbra  WRITE
+         bra   GETSTA
+         nop
+         lbra  SETSTA
+         bra   TERM
+         nop
+* Entry: B:X = LSN
+*        Y   = path dsc. ptr
+*        U   = Device mem ptr
+READ     bsr   L00AC          Go check for 512 byte sector/adjust if needed
+         lda   #%10010001     Error flags (see Disto SCII source)
+         pshs  x              Preserve sector #
+         lbsr  L0162          Go read the sector
+         puls  x              Restore sector #
+         bcs   L00AB          If error, exit
+         pshs  y,x            Save path dsc ptr & LSN
+         leax  ,x         LSN0?
+         bne   L012D          No, go calculate normally
+         puls  y,x            Yes, restore path dsc ptr & LSN
+         lda   <PD.TYP,y      Get type from path dsc.
+         bita  #%01000000     Standard OS-9 format?
+         beq   L00F0          Yes, skip ahead
+         lbsr  L051A
+         pshs  y,x            save path dsc ptr
          bra   L012D
-L00F0    ldx   >u00AB,u
-         pshs  y,x
-         ldy   >u00A7,u
-         ldb   #$14
-L00FD    lda   b,x
-         sta   b,y
-         decb  
-         bpl   L00FD
-         lda   <$10,y
-         ldy   $02,s
-         ldb   <$24,y
-         bita  #$02
-         beq   L0115
-         bitb  #$01
-         beq   L0154
-L0115    bita  #$04
-         beq   L011D
-         bitb  #$02
-         beq   L0154
-L011D    bita  #$01
-         beq   L0128
-         lda   <$27,y
-         suba  #$02
-         bcs   L0154
-L0128    clrb  
-         puls  y,x
-         pshs  y,x
-L012D    ldy   $02,s
-         ldx   $08,y
-         lda   <$23,y
-         ldy   >u00AB,u
-         anda  #$04
-         beq   L014A
-         ldd   >u00B6,u
-         andb  #$01
-         beq   L014B
-         leay  >$0100,y
-L014A    clrb  
-L014B    lda   ,y+
+
+* LSN0, standard OS-9 format
+L00F0    ldx   >sectbuf,u     Get ptr to sector buffer
+         pshs  y,x            Preserve path dsc. ptr & sector buffer ptr
+         ldy   >u00A7,u       Get last drive table accessed ptr
+         IFNE  H6309
+         ldw   #DD.SIZ        # bytes to copy from new LSN0 to drive table
+         tfm   x+,y+          Copy them
+         ELSE
+         ldb   #DD.SIZ
+L00F0Lp  lda   ,x+
+         sta   ,y+
+         decb
+         bne   L00F0Lp
+         ENDC
+         ldy   >u00A7,u       Get drive table ptr back
+         lda   <DD.FMT,y      Get format for disk in drive
+         ldy   2,s            restore path descriptor pointer
+         ldb   <PD.DNS,y      Get path's density settings
+         bita  #%00000010     Disk in drive double density?
+         beq   L0115          No, all drives can read single, skip ahead
+         bitb  #%00000001     Can our path dsc. handle double density?
+         beq   erbtyp         No, illegal
+L0115    bita  #%00000100     Is new disk 96 tpi?
+         beq   L011D          No, all drives handle 48 tpi, so skip ahead
+         bitb  #%00000010     Can path dsc. handle 96 tpi?
+         beq   erbtyp         No, illegal
+L011D    bita  #%00000001     Is new disk double sided?
+         beq   L0128          No, all drives handle single sided, we're done
+         lda   <PD.SID,y      Get # sides path dsc. can handle
+         suba  #2             sides higher or equal to 2?
+         blo   erbtyp         Yes, exit with illegal type error
+L0128    clrb                 No error
+*        puls  y,x            ??? 2 USELESS LINES?
+*        pshs  y,x
+* LSN's other than 0 come straight here
+L012D    ldy   2,s            Get path dsc. ptr back??
+         ldx   PD.BUF,y       Get path dsc. buffer ptr
+         lda   <PD.TYP,y      Get path dsc. disk type
+         ldy   >sectbuf,u     Get ptr to sector buffer
+         IFNE  H6309
+         ldw   #256           OS9 sector size (even if physical was 512)
+         ENDC
+         anda  #%00000100     Mask out all but 512 byte sector flag
+         beq   L014B          If normal sector, just copy it
+         ldd   >u00B6,u       Get OS9's LSN (twice of the 'real' 512 sector)
+         andb  #$01           Mask out all but odd/even sector indicator
+         beq   L014B          Even, use 1st half of 512 byte sector
+         IFNE  H6309
+         addr  w,y            Odd, bump sector buffer ptr to 2nd half
+         ELSE
+         leay  256,y
+         ENDC
+L014B    equ   *
+         IFNE  H6309
+         tfm   y+,x+          Copy from physical sector buffer to PD buffer
+         puls  pc,y,x         restore path dsc & sector buffer ptrs & return
+         ELSE
+         pshs  d
+         clrb
+L014BLp  lda   ,y+
          sta   ,x+
-         decb  
-         bne   L014B
-         puls  pc,y,x
-L0154    comb  
-         ldb   #$F9
+         decb
+         bne   L014BLp
+         puls  pc,y,x,d       restore path dsc & sector buffer ptrs & return
+         ENDC
+
+erbtyp   comb  
+         ldb   #E$BTyp        Error - wrong type error
          puls  pc,y,x
-L0159    bcc   L0162
-         pshs  x,b,a
-         lbsr  SSRESET
-         puls  x,b,a
-L0162    pshs  x,b,a
-         bsr   L016F
-         puls  x,b,a
-         lbcc  L00AB
-         lsra  
-         bne   L0159
-L016F    lbsr  L02B8
-         lbcs  L00AB
-L0176    ldx   >u00AB,u
-         pshs  y,cc
-         ldb   #$80
-         bsr   L01A8
-L0180    bita  >$FF48
-         bne   L019E
-         nop   
-         nop   
-         leay  -$01,y
-         bne   L0180
-         lda   >u00A9,u
-         ora   #$08
-         sta   >$FF40
-         lda   #$D0
-         sta   >$FF48
-         puls  y,cc
-         lbra  L03D8
-L019E    lda   >$FF4B
-         sta   ,x+
-         stb   >$FF40
-         bra   L019E
-L01A8    orcc  #IntMasks
-         stb   >$FF48
-         ldy   #$FFFF
-         ldb   #$28
-         orb   >u00A9,u
-         stb   >$FF40
-         ldb   #$A8
-         orb   >u00A9,u
-         lbsr  L0412
-         lda   #$02
-         rts   
-Write    lbsr  L00AC
-         lda   #$91
-L01CB    pshs  x,b,a
-         bsr   L01EF
-         puls  x,b,a
-         bcs   L01DF
-         tst   <$28,y
-         bne   L01DD
-         lbsr  L0266
-         bcs   L01DF
-L01DD    clrb  
-L01DE    rts   
-L01DF    lsra  
-         lbeq  L03BB
-         bcc   L01CB
-         pshs  x,b,a
-         lbsr  SSRESET
-         puls  x,b,a
-         bra   L01CB
-L01EF    lbsr  L02B8
-         bcs   L01DE
-         pshs  y,b,a
-         lda   <$23,y
-         anda  #$04
-         beq   L0214
-         lda   #$91
-         lbsr  L0176
-         ldd   >u00B6,u
-         andb  #$01
-         beq   L0214
-         ldx   >u00AB,u
-         leax  >$0100,x
-         bra   L0218
-L0214    ldx   >u00AB,u
-L0218    ldy   $08,y
-         clrb  
-L021C    lda   ,y+
+
+* Read error - retry handler
+L0159    bcc   L0162          Normal retry, try reading again
+         pshs  x,d            Preserve regs
+         lbsr  sktrk0         Seek to track 0 (attempt to recalibrate)
+         puls  x,d            Restore regs & try reading again
+
+L0162    pshs  x,d            Preserve regs
+         bsr   L016F          Go read sector
+         puls  x,d            Restore regs (A=retry flags)
+         bcc   L01D7           No error, return
+         lsra                 Shift retry flags
+         bne   L0159          Still more retries allowed, go do them
+* otherwise, final try before we give up
+L016F    lbsr  L02AC          Do double-step/precomp etc. if needed, seek
+         bcs   L01D7          Error somewhere, exit with it
+L0176    ldx   >sectbuf,u     Get physical sector buffer ptr
+*         pshs  y,cc           Preserve timeout timer & CC
+         ldb   #$80           Read sector command
+         bsr   L01A1          Send to controller & time delay to let it settle
+*** Next few lines are commented out for blobstop patches
+*L0180    bita  >$FF48         Check status register
+*         bne   L0197          Eat it & start reading sector
+*         leay  -1,y           Bump timeout timer down
+*         bne   L0180          Keep trying until it reaches 0 or sector read
+*         lda   >u00A9,u       Get current drive settings
+*         ora   #%00001000     Turn drive motor on
+*         sta   >$FF40         Send to controller
+*         puls  y,cc           Restore regs
+*         lbra  L03E0          Exit with Read Error
+*** Blobstop fixes
+         stb   >$FF40     send command to FDC
+         nop              allow HALT to take effect
+         nop
+         bra   L0197      and a bit more time
+* Read loop - exited with NMI
+* Entry: X=ptr to sector buffer
+*        B=Control register settings
+L0197    lda   >$FF4B         Get byte from controller
+         sta   ,x+            Store into sector buffer
+*         stb   >$FF40         Drive info
+         nop              -- blobstop fix
+         bra   L0197          Keep reading until sector done
+
+L01A1    orcc  #IntMasks      Shut off IRQ & FIRQ
+         stb   >$FF48         Send command
+*         ldy   #$FFFF
+         ldb   #%00101000     Double density & motor on
+         orb   >u00A9,u       Merge with current drive settings
+         stb   >$FF40         Send to control register
+         ldb   #%10101000     Enable halt, double density & motor on
+         orb   >u00A9,u       Merge that with current drive settings
+         lbra  L0406          Time delay to wait for command to settle
+*         lda   #$02
+*L01BE    rts   
+
+WRITE    lbsr  L00AC          Go adjust LSN for 512 byte sector if needed
+         lda   #%1001001      Retry flags for I/O errors (see Disto SCII source)
+L01C4    pshs  x,d            Preserve LSN, retries
+         bsr   L01E8          Go write the sector
+         puls  x,d            Restore LSN, retries
+         bcs   L01D8          Error writing, go to write retry handler
+         tst   <PD.VFY,y      No error, do we want physical verify?
+         bne   L01D6          No, exit without error
+         lbsr  verify         Go re-read & verify 32 out of 256 bytes
+         bcs   L01D8          Error on verify, go to write retry handler
+L01D6    clrb                 No error & return
+L01D7    rts   
+
+* Write error retry handler
+L01D8    lsra                 Shift retry flags
+         lbeq  L03AF          Too many retries, exit with error
+         bcc   L01C4          Normal retry, attemp to re-write sector
+         pshs  x,d            Preserve flags & sector #
+         lbsr  sktrk0         Seek to track 0 (attempt to recalibrate)
+         puls  x,d            Restore flags & sector #
+         bra   L01C4          Try re-writing now
+
+* 512 byte sector write here
+L01E8    lbsr  L02AC          Go do double-step/write precomp if needed
+         bcs   L01D7          Error, exit with it
+         pshs  y,d            Preserve path dsc. ptr & LSN
+         lda   <PD.TYP,y      Get device type
+         anda  #%00000100     512 byte sector?
+         beq   L020D          No, skip ahead
+         lda   #$91           ??? appears to be useless
+         lbsr  L0176          Go read the sector in
+         ldd   >u00B6,u       Get OS9 LSN
+         andb  #$01           Even or odd?
+         beq   L020D          Even, skip ahead
+         ldx   >sectbuf,u     Get physical sector buffer ptr
+         leax  >$0100,x       Point to 2nd half
+         bra   L0211          Copy caller's buffer to 2nd half of sector
+
+L020D    ldx   >sectbuf,u     Get physical sector buffer ptr
+
+L0211    ldy   PD.BUF,y       Get path dsc. buffer ptr
+         IFNE  H6309
+         ldw   #256           Copy write buffer to sector buffer
+         tfm   y+,x+
+         ELSE
+         clrb
+L0211Lp  lda   ,y+
          sta   ,x+
-         decb  
-         bne   L021C
-         puls  y,b,a
-         ldx   >u00AB,u
-         ldb   #$A0
-L022B    pshs  y,cc
-         lbsr  L01A8
-L0230    bita  >$FF48
-         bne   L024C
-         leay  -$01,y
-         bne   L0230
-         lda   >u00A9,u
-         ora   #$08
-         sta   >$FF40
-         lda   #$D0
-         sta   >$FF48
-         puls  y,cc
-         lbra  L03BB
-L024C    lda   ,x+
-         sta   >$FF4B
-         stb   >$FF40
-         bra   L024C
-L0256    leas  $0C,s
-         puls  y,cc
-         ldb   >$FF48
-         bitb  #$04
-         lbne  L03EC
-         lbra  L03BE
-L0266    pshs  x,b,a
-         ldx   $08,y
-         pshs  x
-         ldx   >u00AB,u
-         stx   $08,y
-         ldx   $04,s
-         lbsr  L016F
-         puls  x
-         stx   $08,y
-         bcs   L02AF
-         lda   #$20
-         pshs  u,y,a
-         ldb   <$23,y
-         ldy   >u00AB,u
-         andb  #$04
-         beq   L0299
-         ldd   >u00B6,u
-         andb  #$01
-         beq   L0299
-         leay  >$0100,y
-L0299    tfr   x,u
-L029B    ldx   ,u
-         cmpx  ,y
-         bne   L02AB
-         leau  u0008,u
-         leay  $08,y
-         dec   ,s
-         bne   L029B
-         bra   L02AD
-L02AB    orcc  #Carry
-L02AD    puls  u,y,a
-L02AF    puls  pc,x,b,a
-L02B1    pshs  a
-         ldb   <$15,x
-         bra   L02F5
-L02B8    lbsr  L0382
-         lbsr  L0337
-         pshs  a
-         lda   >u00AD,u
-         beq   L02D0
-         lda   >u00A9,u
-         ora   #$40
-         sta   >u00A9,u
-L02D0    lda   <$23,y
-         bita  #$02
-         bne   L02D8
-         incb  
-L02D8    stb   >$FF4A
-         ldx   >u00A7,u
-         ldb   <$15,x
-         lda   <$10,x
-         lsra  
-         eora  <$24,y
-         anda  #$02
-         pshs  a
-         lda   $01,s
-         tst   ,s+
-         beq   L02F5
-         lsla  
-         lslb  
-L02F5    stb   >$FF49
-         ldb   #$15
-         pshs  b
-         ldb   <$24,y
-         andb  #$02
-         beq   L0305
-         lsl   ,s
-L0305    cmpa  ,s+
-         bra   L0313
+         decb
+         bne   L0211Lp
+         ENDC
+         puls  y,d            Get path dsc. ptr & LSN back
+         ldx   >sectbuf,u     Get physical sector buffer ptr again
+         ldb   #$A0           Write sector command
+
+* Format track comes here with B=$F0 (write track)
+*L0224    pshs  y,cc           Preserve path dsc. ptr & CC
+L0224     lbsr  L01A1          Send command to controller (including delay)
+*** Commented out for blobstop fixes
+*L0229    bita  >$FF48         Controller done yet?
+*         bne   L0240          Yes, go write sector out
+*         leay  -$01,y         No, bump wait counter
+*         bne   L0229          Still more tries, continue
+*         lda   >u00A9,u       Get current drive control register settings
+*         ora   #%00001000     Drive motor on (but drive select off)
+*         sta   >$FF40         Send to controller
+*         puls  y,cc           Restore regs
+*         lbra  L03AF          Check for errors from status register
+
+*** added blobstop
+         lda   FBlock+1,u get the block number for format
+         beq   L0230      if not format, don't do anything
+         sta   >$FFA1     otherwise map the block in
+
+L0230    stb   >$FF40     send command to FDC
+         bra   L0240      wait a bit for HALT to enable
+* Write sector routine (Entry: B= drive/side select) (NMI will break out)
+L0240    nop              --- wait a bit more
+         lda   ,x+            Get byte from write buffer
+         sta   >$FF4B         Save to FDC's data register
+* EAT 2 CYCLES: TC9 ONLY (TRY 1 CYCLE AND SEE HOW IT WORKS)
+         IFEQ TC9-1
+         nop
+         nop
+         ENDC
+*         stb   >$FF40         Set up to read next byte
+         bra   L0240          Go read it
+
+* NMI routine
+L024A    leas  R$Size,s       Eat register stack
+*         puls  y,cc           Get path dsc. ptr & CC
+         ldx   <D.SysDAT  get pointer to system DAT image
+         lda   3,x        get block number 1
+         sta   >$FFA1     map it back into memory
+         andcc #^IntMasks turn IRQ's on again
+         ldb   >$FF48         Get status register
+         bitb  #%00000100     Did we lose data in the transfer?
+*         lbne  L03E0          Yes, exit with Read Error
+         lbeq  L03B2          Otherwise, check for drive errors
+         comb             -- blobstop error code
+         ldb   #E$DevBsy  -- device busy
+         rts              -- and exit
+
+verify   pshs  x,d
+         ldx   PD.BUF,y       Get write buffer ptr
+         pshs  x              Preserve it
+         ldx   >sectbuf,u     Get sector buffer ptr
+         stx   PD.BUF,y       Save as write buffer ptr
+         ldx   4,s
+         lbsr  L016F          Go read sector we just wrote
+         puls  x              Get original write buffer ptr
+         stx   PD.BUF,y       Restore path dsc. version
+         bcs   L02A3          If error reading, exit with it
+         pshs  u,y            Preserve device mem, path dsc. ptrs
+         ldb   <PD.TYP,y      Get type from path dsc.
+         ldy   >sectbuf,u     Get sector buffer ptr
+         andb  #%00000100     512 byte sector?
+         beq   L028D          No, skip ahead
+         ldd   >u00B6,u       Get OS9's sector #
+         andb  #$01           Odd/even sector?
+         beq   L028D          Even; compare first half
+         leay  >$0100,y       Odd, compare second half
+L028D    tfr   x,u            Move PD.BUF ptr to U (since cmpx is faster)
+         lda   #32            # of 'spotty' checks to do
+L028F    ldx   ,u             Get 2 bytes from original write buffer
+         cmpx  ,y             Same as corresponding bytes in re-read sector?
+         bne   L029F          No, error & return
+         leau  8,u            Skip next 6 bytes
+         leay  8,y
+         deca                 Done our 'spotty' check?
+         bne   L028F          No, continue
+         fcb   $8C            skip the next 2 bytes
+
+L029F    orcc  #Carry
+L02A1    puls  u,y
+L02A3    puls  pc,x,d
+
+L02A5    pshs  a              Save Caller's track #
+         ldb   <V.TRAK,x      Get track # drive is currently on
+         bra   L02E9          Go save it to controller & continue
+
+L02AC    lbsr  L0376          Go set up controller for drive, spin motor up
+         bsr   L032B          Get track/sector # (A=Trk, B=Sector)
+         pshs  a              Save track #
+         lda   >u00AD,u       Get side 1/2 flag
+         beq   L02C4          Side 1, skip ahead
+         lda   >u00A9,u       Get control register settings
+         ora   #%01000000     Set side 2 (drive 3) select
+         sta   >u00A9,u       Save it back
+L02C4    lda   <PD.TYP,y      Get drive type settings
+         bita  #%00000010     ??? (Base 0/1 for sector #?)
+         bne   L02CC          Skip ahead
+         incb                 Bump sector # up by 1
+L02CC    stb   >$FF4A         Save into Sector register
+         ldx   >u00A7,u       Get last drive table accessed
+         ldb   <V.TRAK,x      Get current track # on device
+         lda   <DD.FMT,x      Get drive format specs
+         lsra                 Shift track & bit densities to match PD
+         eora  <PD.DNS,y      Check for differences with path densities
+         anda  #%00000010     Keep only 48/96 tpi differences
+         pshs  a              Save differences
+         lda   1,s            Get track # back
+         tst   ,s+            Are tpi's different?
+         beq   L02E9          No, continue normally
+         lsla                 Yes, multiply track # by 2 ('double-step')
+         lslb                 Multiply current track # by 2 ('double-step')
+L02E9    stb   >$FF49         Save current track # onto controller
+
+* From here to the line before L0307 is for write precomp, but is not used.
+* Unless write precomp is needed, all of this is useless
+* I think most (if not all) drives do NOT need precomp
+         IFEQ  PRECOMP-1
+         ldb   #21            Pre-comp track #
+         pshs  b              Save it
+         ldb   <PD.DNS,y      Get current density settings
+         andb  #%00000010     Just want to check track density
+         beq   L02F9          48 tpi, skip ahead
+         lsl   ,s             Multiply pre-comp value by 2 ('double-step')
+L02F9    cmpa  ,s+            Is track # high enough to warrant precomp?
+         bls   L0307          No, continue normally
          ldb   >u00A9,u
-         orb   #$10
+         orb   #%00010000     Turn on Write precomp
          stb   >u00A9,u
-L0313    ldb   >u00AA,u
-         bne   L0320
-         ldb   ,s
-         cmpb  <$15,x
-         beq   L032D
-L0320    sta   >$FF4B
-         ldb   <$22,y
-         andb  #$03
-         eorb  #$1B
-         lbsr  L03F0
-L032D    puls  a
-         sta   <$15,x
-         sta   >$FF49
-         clrb  
+         ENDC
+
+L0307    ldb   >u00AA,u       ??? Get flag (same drive flag?)
+         bne   L0314          No, skip ahead
+         ldb   ,s             Get track #
+         cmpb  <V.TRAK,x      Same as current track on this drive?
+         beq   L0321          Yes, skip ahead
+L0314    sta   >$FF4B         Save track # to data register
+         ldb   <PD.STP,y      Get stepping rate
+         andb  #%00000011     Just keep usable settings (6-30 ms)
+         eorb  #%00011011     Set proper bits for controller
+         lbsr  L03E4          Send command to controller & time delay
+L0321    puls  a              Get track # back
+         sta   <V.TRAK,x      Save as current track #
+         sta   >$FF49         Save to controller
+         clrb                 No error & return
+         rts   
+
+* Entry: B:X LSN
+* Exit:  A=Track #
+*        B=Sector #
+*   <u00AD=00 = Head 1 , $FF = Head 2
+L032B    tstb                 Sector # > 65535?
+         bne   L033F          Yes, illegal for floppy
+         tfr   x,d            Move sector # to D
+         leax  ,x         LSN 0?
+         beq   L0371          Yes, exit this routine
+         ldx   >u00A7,u       Get previous drive table ptr
+         cmpd  DD.TOT+1,x     Within range of drive spec?
+         blo   L0343          Yes, go calculate track/sector #'s
+L033F    comb                 Exit with Bad sector # error
+         ldb   #E$Sect
          rts   
-L0337    tstb  
-         bne   L034B
-         tfr   x,d
-         cmpd  #$0000
-         beq   L037D
-         ldx   >u00A7,u
-         cmpd  $01,x
-         bcs   L034F
-L034B    comb  
-         ldb   #$F1
+
+* Calculate track/sector #'s?
+L0343    stb   >u00AE,u       Save LSB of LSN
+         clr   ,-s            Clear track # on stack
+         ldb   <DD.FMT,x      Get drive format
+         lsrb                 Shift out # sides into carry
+         ldb   >u00AE,u       Get LSB of LSN again
+         bcc   L0367          Single sided drive, skip ahead
+         bra   L035D          Double sided drive, skip ahead
+* Double sided drive handling here
+L0355    com   >u00AD,u       ???? Odd/even sector track flag?
+         bne   L035D          Odd, so don't bump track # up
+         inc   ,s             Bump up track #
+
+L035D    subb  DD.TKS,x       Subtract # sectors/track
+         sbca  #$00
+         bcc   L0355          Still more sectors left, continue
+         bra   L036D          Wrapped, skip ahead
+* Single sided drive handling here
+L0365    inc   ,s             Bump track # up
+
+L0367    subb  DD.TKS,x       Subtract # sectors/track
+         sbca  #$00
+         bcc   L0365          Still more, go bump the track up
+L036D    addb  $03,x          Bump sector # back up from negative value
+         puls  a              Get the track #
+L0371    rts                  A=track #, B=Sector #, <u00AD=Odd
+
+* Drive control register bit mask table
+L0372    fcb   $01            Drive 0
+         fcb   $02            Drive 1
+         fcb   $04            Drive 2
+         fcb   $40            Drive 3 / Side select
+
+L0376    clr   >u00AA,u       ???
+
+chkdrv   lda   <PD.DRV,y      Get drive # requested
+         cmpa  #4             Drive 0-3?
+         blo   L0385          Yes, continue normally
+         comb                 Illegal drive # error
+         ldb   #E$Unit
          rts   
-L034F    stb   >u00AE,u
-         clr   ,-s
-         ldb   <$10,x
-         lsrb  
-         ldb   >u00AE,u
-         bcc   L0373
-         bra   L0369
-L0361    com   >u00AD,u
-         bne   L0369
-         inc   ,s
-L0369    subb  $03,x
-         sbca  #$00
-         bcc   L0361
-         bra   L0379
-L0371    inc   ,s
-L0373    subb  $03,x
-         sbca  #$00
-         bcc   L0371
-L0379    addb  $03,x
-         puls  a
-L037D    rts   
-L037E    fcb   $01,$02,$04,$40
-L0382    clr   >u00AA,u
-L0386    lda   <$21,y
-         cmpa  #$04
-         bcs   L0391
-         comb  
-         ldb   #$F0
+
+* Entry: A=drive #, X=LSN (Physical, not OS9 logical if PCDOS disk)
+L0385    pshs  x,d            Save sector #, drive # & B???
+         leax  >L0372,pc      Point to drive bit mask table
+         ldb   a,x            Get bit mask for drive # we want
+         stb   >u00A9,u       Save mask
+         leax  DRVBEG,u       Point to beginning of drive tables
+         ldb   #DRVMEM        Get size of each drive table
+         mul                  Calculate offset to drive table we want
+         leax  d,x            Point to it
+         cmpx  >u00A7,u       Same as Last drive table accessed?
+         beq   L03A6          Yes, skip ahead
+         stx   >u00A7,u       Save new drive table ptr
+         com   >u00AA,u       ??? Set flag
+L03A6    clr   >u00AD,u       Set side (head) flag to side 1
+         lbsr  L04B3          Go set up VIRQ to wait for drive motor
+         puls  pc,x,d         Restore sector #,drive #,B & return
+
+L03AF    ldb   >$FF48         Get status register from FDC
+L03B2    bitb  #%11111000     Any of the error bits set?
+         beq   L03CA          No, exit without error
+         aslb             Drive not ready?
+         bcs   L03CC          Yes, use that error code
+         aslb             Write protect error?
+         bcs   L03D0          Yes, use that error code
+         aslb             Write fault error?
+         bcs   L03D4          Yes, use that error code
+         aslb             Sector not found?
+         bcs   L03D8          Yes, use Seek error code
+         aslb             CRC error?
+         bcs   L03DC          Yes, use that error code
+L03CA    clrb                 No error & return
          rts   
-L0391    pshs  x,b,a
-         leax  >L037E,pcr
-         ldb   a,x
-         stb   >u00A9,u
-         leax  u000F,u
-         ldb   #$26
-         mul   
-         leax  d,x
-         cmpx  >u00A7,u
-         beq   L03B2
-         stx   >u00A7,u
-         com   >u00AA,u
-L03B2    clr   >u00AD,u
-         lbsr  L04BF
-         puls  pc,x,b,a
-L03BB    ldb   >$FF48
-L03BE    bitb  #$F8
-         beq   L03D6
-         bitb  #$80
-         bne   L03D8
-         bitb  #$40
-         bne   L03DC
-         bitb  #$20
-         bne   L03E0
-         bitb  #$10
-         bne   L03E4
-         bitb  #$08
-         bne   L03E8
-L03D6    clrb  
-         rts   
-L03D8    comb  
-         ldb   #$F6
-         rts   
-L03DC    comb  
-         ldb   #$F2
-         rts   
-L03E0    comb  
-         ldb   #$F5
-         rts   
-L03E4    comb  
-         ldb   #$F7
-         rts   
-L03E8    comb  
-         ldb   #$F3
+
+L03CC    ldb   #E$NotRdy      not ready
+         fcb   $8C        skip 2 bytes
+
+L03D0    ldb   #E$WP          write protect
+         fcb   $8C        skip 2 bytes
+
+L03D4    ldb   #E$Write       write error
+         fcb   $8C
+
+L03D8    ldb   #E$Seek        seek error
+         fcb   $8C
+
+L03DC    ldb   #E$CRC         CRC error
+*         fcb   $8C
+
+*L03E0    ldb   #E$Read        Read error
+         orcc  #Carry         set carry
          rts   
-L03EC    comb  
-         ldb   #$F4
+
+L03E4    bsr   L0404          Send command to controller & waste some time
+L03E6    ldb   >$FF48         Check FDC status register
+         bitb  #$01           Is controller still busy?
+         beq   L0403          No, exit
+         ldd   >L0028,pc      Get initial count value for drive motor speed
+         std   >u00B1,u       Save it
+         bra   L03E6          Wait for controller to finish previous command
+
+* Send command to FDC
+L03F7    lda   #%00001000     Mask in Drive motor on bit
+         ora   >u00A9,u       Merge in drive/side selects
+         sta   >$FF40         Turn the drive motor on & select drive
+         stb   >$FF48         Save command & return
+L0403    rts   
+
+L0404    bsr   L03F7          Go send command to controller
+
+* This loop has been changed from nested LBSRs to timing loop.
+* People with crystal upgrades should modify the loop counter
+* to get a 58+ us delay time.  MINIMUM 58us.
+L0406    pshs  a          14 cycles, plus 3*loop counter
+         lda   #29        (only do about a 100 cycle delay for now)
+L0409    deca             for total ~63 us delay (123 cycles max.)
+         bne   L0409
+         puls  a,pc       restore register and exit
+
+SETSTA   ldx   PD.RGS,y       Get caller's register stack ptr
+         ldb   R$B,x          Get function code
+         cmpb  #SS.WTrk       Write track?
+         beq   format         Yes, go do it
+         cmpb  #SS.Reset      Restore head to track 0?
+         lbeq  sktrk0         Yes, go do it --- beq
+         comb                 set carry for error
+         ldb   #E$UnkSvc      return illegal service request error
          rts   
-L03F0    bsr   L0410
-L03F2    ldb   >$FF48
-         bitb  #$01
-         beq   L041B
-         ldd   >L0028,pcr
-         std   >u00B1,u
-         bra   L03F2
-L0403    lda   #$08
-         ora   >u00A9,u
-         sta   >$FF40
-         stb   >$FF48
-         rts   
-L0410    bsr   L0403
-L0412    lbsr  L0415
-L0415    lbsr  L0418
-L0418    lbsr  L041B
-L041B    rts   
 
-SetStat  ldx   PD.RGS,y get caller register ptr
-         ldb   R$B,x	get func code
-         cmpb  #SS.WTRK
-         beq   SSWTRK
-         cmpb  #SS.RESET
-         lbeq  SSRESET
-         comb  
-         ldb   #E$UnkSvc
-         rts   
-SSWTRK   pshs  u,y
-         ldd   #$1A00
-         os9   F$SRqMem 
-         bcs   L0495
-         ldx   $02,s
-         stu   >$00AF,x
-         ldx   <u0050
-         lda   $06,x
-         ldb   <$00D0
+format   pshs  u,y            preserve register stack & descriptor
+*         ldd   #$1A00         Size of buffer to hold entire track image
+*         os9   F$SRqMem       Request memory from system
+*         bcs   L0489          Error requesting, exit with it
+
+*--- new code
+         ldb   #1         1 block to allocate
+         os9   F$AllRAM   allocate some RAM
+         bcs   L0489      error out if at all
+         leax  >FBlock,u   point to 'my' DAT image
+         std   ,x         save a copy of the block
+         os9   F$ResTsk   reserve a task number for the copy
+         bcs   FError     error out
+         stb   2,x        save temporary task number in FTask,u
+         lslb             2 bytes per entry
+         ldu   <D.TskIPt  get task image table pointer
+         stx   b,u        save pointer to the task's DAT image
+         lsrb             get the right number again
+         IFNE  H6309
+         tfr   0,u        destination is address 0
+         ELSE
+         ldu   #$0000
+         ENDC
+*--- end new code
+
+         ldx   2,s            get pointer to descriptor
+*         stu   >FBlock,x
+         ldx   <D.Proc        Get current process ptr
+         lda   P$Task,x       Get task # for current process
+*         ldb   <D.SysTsk      Get system task #
          ldy   ,s
-         ldx   $06,y
-         ldx   $04,x
-         ldy   #$1A00
-         os9   F$Move   
-         bcs   L0485
+         ldx   PD.RGS,y       Get register stack ptr
+         ldx   R$X,x          Get ptr to caller's track buffer
+         ldy   #$1A00         Size of track buffer
+         os9   F$Move         Copy from caller to temporary task
+         bcs   L0479          Error copying, exit
          puls  u,y
          pshs  u,y
-         lbsr  L0382
-         ldx   $06,y
-         ldb   $07,x
-         bitb  #$01
-         beq   L0471
+         lbsr  L0376          Go check drive #/wait for it to spin up
+         ldx   PD.RGS,y       Get caller's register stack ptr
+         ldb   R$Y+1,x        Get caller's side/density
+         bitb  #$01           Check side
+         beq   L0465          Side 1, skip ahead
          com   >u00AD,u
-         ldb   >u00A9,u
-         orb   #$40
-         stb   >u00A9,u
-L0471    lda   $09,x
-         ldx   >u00A7,u
-         lbsr  L02B1
-         bcs   L0495
-         ldb   #$F0
-         ldx   >u00AF,u
-         lbsr  L022B
-L0485    ldu   $02,s
-         pshs  b,cc
-         ldu   >u00AF,u
-         ldd   #$1A00
-         os9   F$SRtMem 
-         puls  b,cc
-L0495    puls  pc,u,y
+         ldb   >u00A9,u       Get current control register settings
+         orb   #%01000000     Mask in side 2
+         stb   >u00A9,u       Save updated control register
+L0465    lda   R$U+1,x        Get caller's track #
+         ldx   >u00A7,u       Get current drive table ptr
+         lbsr  L02A5          
+         bcs   L0489
+         ldb   #$F0           Write track command?
+*---
+*         ldx   >FBlock,u
+         ldx   #$2000     start writing from block 1
+         lbsr  L0224          Go write the track
+L0479    ldu   2,s
+         pshs  b,cc           Preserve error
 
-SSRESET  lbsr  L0386
+*         ldu   >FBlock,u       Get ptr to track buffer
+*         ldd   #$1A00         Return track buffer
+*         os9   F$SRtMem 
+
+         ldb   >FTask,u   point to task
+         os9   F$RelTsk   release the task
+         fcb   $8C        skip 2 bytes
+
+* format comes here when block allocation passes, but task allocation
+* gives error.  So er de-allocate the block.
+FError   pshs  b,cc       save error code, cc
+         ldx   >FBlock,u   point to block
+         ldb   #1         1 block to return
+         os9   F$DelRAM   de-allocate image RAM blocks
+         clr   FBlock+1,u ensure that the block # in FBlock is zero.
+         puls  b,cc           Restore error
+L0489    puls  pc,u,y         Restore regs & return
+
+* seek the head to track 0
+sktrk0   lbsr  chkdrv
          ldx   >u00A7,u
          clr   <$15,x
          lda   #$05
-L04A3    ldb   <$22,y
+L0497    ldb   <PD.STP,y
          andb  #$03
          eorb  #$4B
          pshs  a
-         lbsr  L03F0
+         lbsr  L03E4
          puls  a
          deca  
-         bne   L04A3
-         ldb   <$22,y
+         bne   L0497
+         ldb   <PD.STP,y
          andb  #$03
          eorb  #$0B
-         lbsr  L03F0
+         lbra  L03E4
+
+L04B3    pshs  y,x,d          Preserve regs
+         ldd   >L0028,pc      Get VIRQ initial count value
+         std   >u00B1,u       Save it
+         lda   >u00A9,u       ?Get drive?
+         ora   #%00001000     Turn drive motor on for that drive
+         sta   >$FF40         Send drive motor on command to FDC
+         lda   <D.MotOn       Get VIRQ flag
+         bmi   L04DE          Not installed yet, try installing it
+         bne   L04E0          Drive already up to speed, exit without error
+
+* Drive motor speed timing loop (could be F$Sleep call now) (was over .5 sec)
+         ldx   #32        wait for 32 ticks
+         os9   F$Sleep
+
+L04DE    bsr   insvirq        Install VIRQ to wait for drive motors
+L04E0    clrb                 No error & return
+         puls  pc,y,x,d
+
+insvirq  lda   #$01           Flag drive motor is up to speed
+         sta   <D.MotOn
+         ldx   #$0001         Install VIRQ entry
+         leay  >u00B1,u       Point to packet
+         clr   Vi.Stat,y      Reset Status byte
+         ldd   >L0028,pc      Get initial VIRQ count value
+         os9   F$VIRQ         Install VIRQ
+         bcc   virqout        No error, exit
+         lda   #$80           Flag that VIRQ wasn't installed
+         sta   <D.MotOn
+virqout  clra  
          rts   
-L04BF    pshs  y,x,b,a
-         ldd   >L0028,pcr
-         std   >u00B1,u
-         lda   >u00A9,u
-         ora   #$08
-         sta   >$FF40
-         lda   <u0032
-         bmi   L04EA
-         bne   L04EC
-         ldx   #$A000
-L04DB    nop   
-         nop   
-         lbrn  L04EA
-         lbrn  L04EA
-         nop   
-         leax  -$01,x
-         bne   L04DB
-L04EA    bsr   L04EF
-L04EC    clrb  
-         puls  pc,y,x,b,a
-L04EF    lda   #$01
-         sta   <u0032
-         ldx   #$0001
-         leay  >u00B1,u
-         clr   $04,y
-         ldd   >L0028,pcr
-         os9   F$VIRQ   
-         bcc   L0509
-         lda   #$80
-         sta   <u0032
-L0509    clra  
-         rts   
-L050B    pshs  a
-         lda   <u008A
-         beq   L0515
-         bsr   L04EF
-         bra   L0524
-L0515    sta   >$FF40
-         lda   >u00B5,u
+
+* IRQ service routine for VIRQ (drive motor time)
+* Entry: U=Ptr to VIRQ memory area
+irqsvc   pshs  a
+         lda   <D.DMAReq
+         beq   L0509
+         bsr   insvirq
+         bra   irqout
+L0509    sta   >$FF40
+         IFNE  H6309
+         aim   #$FE,>u00B5,u
+*         fcb   $62,$FE,%11001001
+         ELSE
+         lda   u00B5,u
          anda  #$FE
-         sta   >u00B5,u
-         clr   <u0032
-L0524    puls  pc,a
-L0526    pshs  x
-         ldx   >u00A7,u
+         sta   u00B5,u
+         ENDC
+*         fdb   u00B5      --- so changes in data size won't affect anything
+         clr   <D.MotOn
+irqout   puls  pc,a
+
+* Non-OS9 format goes here
+* Entry: X=LSN
+*        Y=Path dsc. ptr
+*        U=Device mem ptr
+L051A    pshs  x              Preserve Logical sector #
+         ldx   >u00A7,u       Get last drive table accessed ptr
+         clra
+         pshs  x,a            Save ptr & NUL byte
+         IFNE  H6309
+         ldw   #$14           Clear 20 bytes
+         tfm   s,x+
+         ELSE
          ldb   #$14
-L052E    clr   b,x
-         decb  
-         bpl   L052E
-         ldd   <$25,y
-         lda   <$27,y
-         mul   
+L051ALp  clr   ,x+
+         decb
+         bne   L051ALp
+         ENDC
+         puls  x,a            Eat NUL & get back drive table ptr
+         ldb   <PD.CYL+1,y    Get # cylinders on drive (ignores high byte)
+         lda   <PD.SID,y      Get # sides
+         mul                  Calculate # tracks on drive (1 per head)
+         IFNE  H6309
+         decd                 Adjust to ignore track 0
+         ELSE
          subd  #$0001
-         lda   <$2A,y
-         sta   $03,x
-         sta   <$12,x
-         mul   
-         pshs  x
-         tfr   d,x
-         lda   <$2C,y
-         leax  a,x
-         lda   <$23,y
-         anda  #$04
-         beq   L055C
+         ENDC
+         lda   <PD.SCT+1,y    Get # sectors/track
+         sta   DD.TKS,x       Save in drive table
+         sta   <DD.SPT+1,x    Save in other copy in drive table
+         mul                  Calculate # sectors on drive (minus track 0)
+         pshs  x              Preserve drive table ptr
+         tfr   d,x            Move # sectors on drive to X
+         lda   <PD.T0S+1,y    Get # sectors on track 0
+         leax  a,x            Add that many sectors to total
+         lda   <PD.TYP,y      Get device type settings
+         anda  #%00000100     Mask out all but 512 byte sector flag
+         beq   L0550          Not 512 byte sector, skip ahead
+         IFNE  H6309
+         addr  x,x        Multiply by 2 (convert to 256 byte OS9 sectors)
+         ELSE
          tfr   x,d
-         rolb  
-         rola  
-         tfr   d,x
-L055C    tfr   x,d
-         puls  x
-         std   $01,x
-         lda   #$07
-         sta   $0D,x
-         lda   <$24,y
-         lsla  
-         pshs  a
-         lda   <$27,y
-         deca  
-         ora   ,s+
-         sta   <$10,x
-         clrb  
-         puls  pc,x
+         leax  d,x
+         ENDC
+L0550    tfr   x,d            Move # sectors to D
+         puls  x              Get back drive table ptr
+         std   DD.TOT+1,x     Save # sectors allowed on drive
+         lda   #UPDAT.+EXEC.  Owner's read/write/exec attributes
+         sta   DD.ATT,x       Set attributes for disk
+         lda   <PD.DNS,y      Get density settings
+         lsla                 Shift for DD.FMT
+         pshs  a              Preserve it a sec
+         lda   <PD.SID,y      Get # sides
+         deca                 Adjust to base 0
+         ora   ,s+            Merge with density settings
+         sta   <DD.FMT,x      Save in device table
+         clrb                 No error?
+         puls  pc,x           Restore original LSN & return
 
          emod
 eom      equ   *