changeset 2180:660cc987e18d

Added DriveWire 3 modules to distribution
author boisy
date Sat, 07 Mar 2009 20:04:42 +0000
parents 6a7746370ffd
children c34956608086
files defs/os9defs level1/coco/bootfiles/makefile level1/coco/makefile level1/coco/modules/makefile level1/modules/boot_dw3.asm level1/modules/clock2_dw3.asm level1/modules/dw3.asm level1/modules/dwcheck.asm level1/modules/dwdefs.d level1/modules/dwdesc.asm level1/modules/dwread.asm level1/modules/dwwrite.asm level1/modules/p_scdwp.asm level1/modules/rbdw3.asm level1/modules/scdwp.asm level2/coco3/bootfiles/makefile level2/coco3/makefile level2/coco3/modules/makefile level2/coco3_6309/bootfiles/makefile level2/coco3_6309/makefile level2/coco3_6309/modules/makefile rules.mak
diffstat 22 files changed, 1963 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/defs/os9defs	Mon Jan 12 01:32:08 2009 +0000
+++ b/defs/os9defs	Sat Mar 07 20:04:42 2009 +0000
@@ -420,6 +420,7 @@
                RMB       5
 D.COCOXT       RMB       1                   Busy flag for CoCo-XT driver (one drive at a time)
 D.DbgMem       RMB       2                   Debug memory pointer
+D.DWSUB        RMB       2                   DriveWire Subroutine Module entry point
 
                ORG       $20
 
--- a/level1/coco/bootfiles/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level1/coco/bootfiles/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -11,6 +11,9 @@
 KERNEL_1773	= $(MD)/rel $(MD)/krn $(MD)/krnp2 $(MD)/init \
 		$(MD)/boot_1773_6ms
 
+KERNEL_DW3	= $(MD)/rel $(MD)/krn $(MD)/krnp2 $(MD)/init \
+		$(MD)/boot_dw3
+
 IDE		= $(3PD)/ide
 SCSI		= $(3PD)/scsisys
 
@@ -50,6 +53,19 @@
 		$(MD)/clock_60hz $(MD)/clock2_soft \
 		$(MD)/sysgo_dd
 
+BOOTFILE_COVDG_DW3	= $(MD)/ioman \
+		$(MD)/rbdw3.dr $(MD)/dw3.sb \
+		$(MD)/ddx0.dd $(MD)/x1.dd $(MD)/x2.dd $(MD)/x3.dd \
+		$(MD)/rbf.mn $(MD)/rb1773.dr \
+		$(MD)/d0_80d.dd $(MD)/d1_40d.dd $(MD)/d2_40d.dd \
+		$(MD)/scf.mn \
+		$(MD)/vtio.dr $(MD)/covdg.io $(MD)/term32.dt \
+		$(MD)/scdwp.dr $(MD)/p_scdwp.dd \
+		$(MD)/scbbt.dr $(MD)/t1_scbbt.dd \
+		$(MD)/pipeman.mn $(MD)/piper.dr $(MD)/pipe.dd \
+		$(MD)/clock_60hz $(MD)/clock2_dw3 \
+		$(MD)/sysgo_dd
+
 BOOTFILE_COVDG_DS80	= $(MD)/ioman \
 		$(MD)/rbf.mn $(MD)/rb1773.dr \
 		$(MD)/d0_80d.dd $(MD)/d1_40d.dd $(MD)/d2_40d.dd \
@@ -62,6 +78,20 @@
 		$(MD)/clock_60hz $(MD)/clock2_soft \
 		$(MD)/sysgo_dd
 
+BOOTFILE_COHR_DW3	= $(MD)/ioman \
+		$(MD)/rbdw3.dr $(MD)/dw3.sb \
+		$(MD)/ddx0.dd $(MD)/x1.dd $(MD)/x2.dd $(MD)/x3.dd \
+		$(MD)/rbf.mn $(MD)/rb1773.dr \
+		$(MD)/d0_80d.dd $(MD)/d1_40d.dd $(MD)/d2_40d.dd \
+		$(MD)/ddd0_80d.dd \
+		$(MD)/scf.mn \
+		$(MD)/vtio.dr $(MD)/cohr.io $(MD)/term51.dt \
+		$(MD)/scdwp.dr $(MD)/p_scdwp.dd \
+		$(MD)/scbbt.dr $(MD)/t1_scbbt.dd \
+		$(MD)/pipeman.mn $(MD)/piper.dr $(MD)/pipe.dd \
+		$(MD)/clock_60hz $(MD)/clock2_dw3 \
+		$(MD)/sysgo_dd
+
 BOOTFILE_COHR_DS80	= $(MD)/ioman \
 		$(MD)/rbf.mn $(MD)/rb1773.dr \
 		$(MD)/d0_80d.dd $(MD)/d1_40d.dd $(MD)/d2_40d.dd \
@@ -74,8 +104,8 @@
 		$(MD)/clock_60hz $(MD)/clock2_soft \
 		$(MD)/sysgo_dd
 
-BOOTFILES	= bootfile_covdg bootfile_cohr bootfile_covdg_ds80 bootfile_cohr_ds80
-KERNELS		= kernel_1773
+BOOTFILES	= bootfile_covdg bootfile_cohr bootfile_covdg_dw3 bootfile_cohr_dw3 bootfile_covdg_ds80 bootfile_cohr_ds80
+KERNELS		= kernel_1773 kernel_dw3
 
 ALLOBJS		= $(BOOTFILES) $(KERNELS)
 
@@ -93,9 +123,15 @@
 bootfile_covdg_ds80: $(BOOTFILE_COVDG_DS80) $(DEPENDS)
 	$(MERGE) $(BOOTFILE_COVDG_DS80)>$@
 
+bootfile_covdg_dw3: $(BOOTFILE_COVDG_DW3) $(DEPENDS)
+	$(MERGE) $(BOOTFILE_COVDG_DW3)>$@
+
 bootfile_cohr_ds80: $(BOOTFILE_COHR_DS80) $(DEPENDS)
 	$(MERGE) $(BOOTFILE_COHR_DS80)>$@
 
+bootfile_cohr_dw3: $(BOOTFILE_COHR_DW3) $(DEPENDS)
+	$(MERGE) $(BOOTFILE_COHR_DW3)>$@
+
 # Dragon64 Disk boot
 bootfile_d64: $(BOOTFILE_D64) $(DEPENDS)
 	$(MERGE) $(BOOTFILE_D64)>$@
@@ -105,6 +141,11 @@
 	$(MERGE) $(KERNEL_1773)>$@
 	$(PADROM) 4608 $@
 
+# DriveWire 3 Kernel
+kernel_dw3: $(KERNEL_DW3) $(DEPENDS)
+	$(MERGE) $(KERNEL_DW3)>$@
+	$(PADROM) 4608 $@
+
 clean:
 	$(RM) $(ALLOBJS)
 
--- a/level1/coco/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level1/coco/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -14,8 +14,11 @@
 BOOTFILE_COVDG	= bootfiles/bootfile_covdg
 BOOTFILE_COHR	= bootfiles/bootfile_cohr
 BOOTFILE_COVDG_DS80	= bootfiles/bootfile_covdg_ds80
+BOOTFILE_COVDG_DW3	= bootfiles/bootfile_covdg_dw3
 BOOTFILE_COHR_DS80	= bootfiles/bootfile_cohr_ds80
+BOOTFILE_COHR_DW3	= bootfiles/bootfile_cohr_dw3
 KERNELFILE	= bootfiles/kernel_1773
+KERNELFILE_DW3	= bootfiles/kernel_dw3
 DIRS		= cmds modules defs sys bootfiles
 
 
@@ -35,6 +38,8 @@
 ROOTFILES	= startup
 
 PACKAGENAME	= $(DISTROVER).zip
+DSKDW3          = $(DISTROVER)_dw3.dsk
+LDSKDW3         = $(DISTRONAME)_dw3.dsk
 DSK360K_1       = $(DISTROVER)_40d_1.dsk
 LDSK360K_1      = $(DISTRONAME)_40d_1.dsk
 DSK360K_2       = $(DISTROVER)_40d_2.dsk
@@ -57,21 +62,74 @@
 	$(foreach dir, $(DIRS), ($(CD) $(dir); make clean);)
 
 dskclean:
-	-$(RM) $(PACKAGENAME) $(DSK360K_1) $(LDSK360K_1) \
+	-$(RM) $(PACKAGENAME) $(DSKDW3) $(DSK360K_1) $(LDSK360K_1) \
 	$(DSK360K_2) $(LDSK360K_2) $(DSK720K) $(LDSK720K)
 
 
 dsk: all $(PACKAGENAME)
 
 dskcopy: dsk
-	$(CP) $(DSK360K_1) $(DSK360K_2) $(DSK720K) $(PACKAGENAME) $(DSKDIR)
+	$(CP) $(DSKDW3) $(DSK360K_1) $(DSK360K_2) $(DSK720K) $(PACKAGENAME) $(DSKDIR)
 
 scp: dsk
 	scp $(PACKAGENAME) boisy@cvs.nitros9.org:/home/nitros9/public_html
 
-$(PACKAGENAME): $(DSK360K_1) $(DSK360K_2) $(DSK720K) ../../ReadMe ../../ChangeLog
+$(PACKAGENAME): $(DSKDW3) $(DSK360K_1) $(DSK360K_2) $(DSK720K) ../../ReadMe ../../ChangeLog
 	$(ARCHIVE) $@ $^
 
+$(DSKDW3):
+	$(RM) $@
+	$(OS9FORMAT_DW3) -q $@ -n"NitrOS-9/6809 Level 1"
+	$(OS9GEN) $@ -b=$(BOOTFILE_COVDG_DW3) -t=$(KERNELFILE_DW3)
+	$(MAKDIR) $@,CMDS
+	$(MAKDIR) $@,SYS
+	$(MAKDIR) $@,DEFS
+	$(CD) cmds; $(CP) $(CMDS) ../$@,CMDS
+	$(foreach file, $(CMDS), $(OS9ATTR_EXEC) $@,CMDS/$(file);)
+	$(CD) cmds; $(CP) $(CMDS_D2) ../$@,CMDS
+	$(foreach file, $(CMDS_D2), $(OS9ATTR_EXEC) $@,CMDS/$(file);)
+	$(OS9RENAME) $@,CMDS/$(WHICHSHELL) shell
+	$(CD) sys; $(CPL) $(SYS) ../$@,SYS
+	$(foreach file, $(SYS), $(OS9ATTR_TEXT) $@,SYS/$(file);)
+	$(CD) defs; $(CPL) $(DEFS) ../$@,DEFS
+	$(foreach file, $(DEFS), $(OS9ATTR_TEXT) $@,DEFS/$(file);)
+	$(CPL) $(ROOTFILES) $@,.
+	$(foreach file, $(ROOTFILES), $(OS9ATTR_TEXT) $@,$(file);)
+	$(MAKDIR) $@,NITROS9
+	$(MAKDIR) $@,NITROS9/6809L1
+	$(MAKDIR) $@,NITROS9/6809L1/CMDS
+	$(CD) cmds; $(CP) $(MODULECMDS) ../$@,NITROS9/6809L1/CMDS
+	$(foreach file, $(MODULECMDS), $(OS9ATTR_EXEC) $@,NITROS9/6809L1/CMDS/$(file);)
+	$(OS9RENAME) $@,NITROS9/6809L1/CMDS/$(WHICHSHELL) shell
+	$(MAKDIR) $@,NITROS9/6809L1/MODULES
+	$(MAKDIR) $@,NITROS9/6809L1/MODULES/BOOTTRACK
+	$(CD) modules; $(CP) $(BOOTTRACK) ../$@,NITROS9/6809L1/MODULES/BOOTTRACK
+	$(foreach file, $(BOOTTRACK), $(OS9ATTR_EXEC) $@,NITROS9/6809L1/MODULES/BOOTTRACK/$(file);)
+	$(MAKDIR) $@,NITROS9/6809L1/MODULES/KERNEL
+	$(CD) modules; $(CP) $(KERNEL) ../$@,NITROS9/6809L1/MODULES/KERNEL
+	$(foreach file, $(KERNEL), $(OS9ATTR_EXEC) $@,NITROS9/6809L1/MODULES/KERNEL/$(file);)
+	$(MAKDIR) $@,NITROS9/6809L1/MODULES/SYSMODS
+	$(CD) modules; $(CP) $(SYSMODS) ../$@,NITROS9/6809L1/MODULES/SYSMODS
+	$(foreach file, $(SYSMODS), $(OS9ATTR_EXEC) $@,NITROS9/6809L1/MODULES/SYSMODS/$(file);)
+	$(MAKDIR) $@,NITROS9/6809L1/MODULES/CLOCKS
+	$(CD) modules; $(CP) $(CLOCKS) ../$@,NITROS9/6809L1/MODULES/CLOCKS
+	$(foreach file, $(CLOCKS), $(OS9ATTR_EXEC) $@,NITROS9/6809L1/MODULES/CLOCKS/$(file);)
+	$(MAKDIR) $@,NITROS9/6809L1/MODULES/RBF
+	$(CD) modules; $(CP) $(RBF) ../$@,NITROS9/6809L1/MODULES/RBF
+	$(foreach file, $(RBF), $(OS9ATTR_EXEC) $@,NITROS9/6809L1/MODULES/RBF/$(file);)
+	$(MAKDIR) $@,NITROS9/6809L1/MODULES/SCF
+	$(CD) modules; $(CP) $(SCF) ../$@,NITROS9/6809L1/MODULES/SCF
+	$(foreach file, $(SCF), $(OS9ATTR_EXEC) $@,NITROS9/6809L1/MODULES/SCF/$(file);)
+	$(MAKDIR) $@,NITROS9/6809L1/MODULES/PIPE
+	$(CD) modules; $(CP) $(PIPE) ../$@,NITROS9/6809L1/MODULES/PIPE
+	$(foreach file, $(PIPE), $(OS9ATTR_EXEC) $@,NITROS9/6809L1/MODULES/PIPE/$(file);)
+	$(MAKDIR) $@,NITROS9/6809L1/BOOTLISTS
+	$(CD) bootlists; $(CPL) *.bl ../$@,NITROS9/6809L1/BOOTLISTS
+	$(MAKDIR) $@,NITROS9/6809L1/SCRIPTS
+	$(CD) scripts; $(CPL) mb* ../$@,NITROS9/6809L1/SCRIPTS
+	$(RM) $(LDSKDW3)
+	$(SOFTLINK) $@ $(LDSKDW3)
+
 $(DSK360K_1):
 	$(RM) $@
 	$(OS9FORMAT_DS40) -q $@ -n"NitrOS-9/6809 Level 1 Disk 1"
--- a/level1/coco/modules/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level1/coco/modules/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -20,25 +20,27 @@
 TPB		= $(3RDPARTY)/booters
 
 BOOTERS		= boot_1773_6ms boot_1773_30ms \
-		boot_burke boot_rampak boot_wd1002
+		boot_burke boot_rampak boot_wd1002 boot_dw3
 BOOTTRACK	= rel $(BOOTERS)
 KERNEL		= krn krnp2
 SYSMODS		= ioman init sysgo_dd sysgo_h0
 CLOCKS          = clock_60hz clock_50hz \
 		clock2_elim clock2_disto2 clock2_disto4 clock2_bnb \
                 clock2_smart clock2_harris clock2_cloud9 clock2_soft \
-		clock2_messemu clock2_jvemu
+		clock2_messemu clock2_jvemu clock2_dw3
 
 RBF		= rbf.mn \
+		rbdw3.dr dw3.sb \
 		rb1773.dr rb1773_scii_ff74.dr rb1773_scii_ff58.dr \
 		ddd0_35s.dd d0_35s.dd d1_35s.dd d2_35s.dd d3_35s.dd \
 		ddd0_40d.dd d0_40d.dd d1_40d.dd d2_40d.dd \
-		ddd0_80d.dd d0_80d.dd d1_80d.dd d2_80d.dd
+		ddd0_80d.dd d0_80d.dd d1_80d.dd d2_80d.dd \
+		ddx0.dd x0.dd x1.dd x2.dd x3.dd
 
 SCF		= scf.mn \
-		sc6551.dr vrn.dr scbbp.dr scbbt.dr sspak.dr vtio.dr \
+		sc6551.dr vrn.dr scbbp.dr scbbt.dr scdwp.dr sspak.dr vtio.dr \
 		covdg.io cohr.io \
-		nil.dd p_scbbp.dd pipe.dd ssp.dd \
+		nil.dd p_scbbp.dd p_scdwp.dd pipe.dd ssp.dd \
 		term_scbbt.dt term_sc6551.dt t1_scbbt.dd t2_sc6551.dd t3_sc6551.dd \
 		term32.dt term51.dt
 
@@ -129,6 +131,22 @@
 d2_80d.dd: rb1773desc.asm
 	$(AS) $< $(ASOUT)$@ $(AFLAGS) $(DSDD80) -aDNum=2
 
+# DriveWire 3 descriptors
+ddx0.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDD=1 -aDNum=0
+
+x0.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=0
+
+x1.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=1
+
+x2.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=2
+
+x3.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=3
+
 rel: rel.asm
 	$(AS) $(AFLAGS) $(ASOUT)$@ $< -aDragon64=0
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/boot_dw3.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,145 @@
+********************************************************************
+* Boot - DriveWire 3 Boot Module
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2008/02/09  Boisy G. Pitre
+* Created.
+
+               NAM       Boot
+               TTL       DriveWire Boot Module
+
+               IFP1      
+               USE       defsfile
+               USE       dwdefs.d
+               ENDC      
+
+tylg           SET       Systm+Objct
+atrv           SET       ReEnt+rev
+rev            SET       0
+edition        SET       1
+
+               MOD       eom,name,tylg,atrv,start,size
+
+* on-stack buffer to use
+               ORG       0
+seglist        RMB       2                   pointer to segment list
+blockloc       RMB       2                   pointer to memory requested
+blockimg       RMB       2                   duplicate of the above
+bootloc        RMB       3                   sector pointer; not byte pointer
+bootsize       RMB       2                   size in bytes
+LSN0Ptr        RMB       2                   LSN0 pointer
+size           EQU       .
+
+name           EQU       *
+               FCS       /Boot/
+               FCB       edition
+
+
+* Common booter-required defines
+LSN24BIT       EQU       1
+FLOPPY         EQU       0
+
+
+               USE       boot_common.asm
+
+
+************************************************************
+************************************************************
+*              Hardware-Specific Booter Area               *
+************************************************************
+************************************************************                   
+
+* HWInit - Initialize the device
+*   Entry: Y = hardware address
+*   Exit:  Carry Clear = OK, Set = Error
+*          B = error (Carry Set)
+HWInit                   
+* Set up DDR for side B
+*               ldx       #PIA1Base           get base address of PIA
+*               ldb       3,x
+*               andb      #%11111011
+*               stb       3,x
+*               lda       #%11111010
+*               sta       2,x
+*               orb       #%00000100
+*               stb       3,x
+
+* Set up DDR for side A
+*               ldb       1,x
+*               andb      #%11111011
+*               stb       1,x                 $FF20 is now Data Direction Register
+*               lda       #%11111110          data direction bits (1=out, 0=in)
+*               sta       ,x                  tell HW
+*               orb       #%00000100          reset $FF20 to I/O register
+*               stb       1,x                 $FF20 is now Data Direction Register
+HWTerm         clrb      
+               rts       
+
+
+* HWRead - Read a 256 byte sector from the device
+*   Entry: Y = hardware address
+*          B = bits 23-16 of LSN
+*          X = bits 15-0  of LSN
+* 		   blockloc,u = ptr to 256 byte sector
+*   Exit:  X = ptr to data (i.e. ptr in blockloc,u)
+HWRead         
+               pshs      cc,d,x
+* Send out op code and 3 byte LSN
+               lda       #OP_READEX           load A with READ opcode
+Read2          ldb       WhichDrv,pcr
+               std       ,s
+               leax      ,s
+               ldy       #5
+               lbsr      XMT56K             send it to server
+* Get 256 bytes of sector data
+               ldx       blockloc,u
+               lda       #255
+               bsr       RCV56K              read bytes from server
+               bcs       ReadEr               branch if framing error
+               cmpd     #256
+               bne      ReadEr2
+               
+* Send two byte checksum
+               pshs      y
+	 		      leax      ,s
+			      ldy       #2
+			      lbsr      XMT56K
+                              lda       #255
+			      bsr       RCV56K
+			      leas      2,s
+     			   bcs       ReadEx
+                           cmpd     #1
+                           bne      ReadEr2
+			      ldb       ,s
+			      beq       ReadEx
+			      cmpb      #E_CRC
+			      bne       ReadEr
+               lda       #OP_REREADEX
+               bra       Read2
+ReadEx         EQU       *
+               leas      5,s                 eat stack
+               ldx       blockloc,u
+               clrb      
+               rts
+ReadEr2        ldb       #E$Read
+ReadEr
+               leas      5,s                 eat stack
+               orcc      #Carry
+               rts
+
+               USE       dwread.asm
+               USE       dwwrite.asm
+
+               IFGT      Level-1
+Pad            FILL      $39,$1D0-3-2-1-*
+               ENDC      
+
+Address        FDB       $0000
+WhichDrv       FCB       $00
+               EMOD      
+eom            EQU       *
+               END       
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/clock2_dw3.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,71 @@
+********************************************************************
+* Clock2 - DriveWire 3 RTC Driver
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2004/08/18  Boisy G. Pitre
+* Separated clock2 modules for source clarity.
+
+         nam   Clock2
+         ttl   DriveWire 3 RTC Driver
+
+         ifp1            
+         use   defsfile  
+         endc            
+
+tylg     set   Sbrtn+Objct
+atrv     set   ReEnt+rev
+rev      set   $00
+edition  set   1
+
+
+RTC.Base equ   $0000     
+
+         mod   eom,name,tylg,atrv,JmpTable,RTC.Base
+
+name     fcs   "Clock2"  
+         fcb   edition
+
+subname  fcs   "dw3"
+
+* Three Entry Points:
+*   - Init
+*   - GetTime
+*   - SetTIme
+JmpTable                 
+         bra   Init
+         nop
+         bra   GetTime   	RTC Get Time
+         nop
+ex       rts			RTC Set Time
+
+GetTime  pshs  u,y,x
+         lda   #'#        Time packet
+	 pshs  a
+	 leax  ,s
+	 ldy   #$0001
+         ldu   >D.DWSUB
+	 jsr   6,u
+         puls  a        
+* Consider the following optimization
+*        ldx   #D.Year
+	 leax  D.Year,y	Note: Y = 0 after returning from XMT56K
+	 lda   #255
+         jsr   3,u
+UpdLeave puls  x,y,u,pc
+
+
+Init     leax    subname,pcr
+         clra
+         os9     F$Link
+         bcs     ex
+         sty     >D.DWSUB
+         jmp     ,y			call initialization routine
+
+         emod            
+eom      equ   *         
+         end             
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/dw3.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,94 @@
+********************************************************************
+* DW3 - DriveWire 3 Low Level Subroutine Module
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2008/01/26  Boisy G. Pitre
+* Started as a segregated subroutine module.
+
+         nam   DW3
+         ttl   DriveWire 3 Low Level Subroutine Module
+
+         ifp1
+         use   defsfile
+         use   dwdefs.d
+         endc
+
+tylg     set   Sbrtn+Objct   
+atrv     set   ReEnt+rev
+rev      set   $01
+
+         mod   eom,name,tylg,atrv,start,0
+
+name     fcs   /dw3/
+
+* DriveWire subroutine entry table
+start    lbra   Init
+         bra    Read
+	 nop
+         lbra   Write
+
+* Term
+*
+* Entry:
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Term
+         clrb				clear Carry
+         rts
+
+* Init
+*
+* Entry:
+*    Y  = address of device descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+* Initialize the serial device
+Init  
+         clrb				clear Carry
+         pshs  cc,x			then push CC on stack
+         orcc  #IntMasks
+         ldx   #PIA1Base		$FF20
+         clr   1,x			clear CD
+         lda   #%11111110
+         sta   ,x
+         lda   #%00110100
+         sta   1,x
+         lda   ,x
+         puls  cc,x,pc
+
+* Read
+*
+*  ON ENTRY:
+*    X = ADDRESS OF THE RECEIVE BUFFER
+*    A = TIMEOUT VALUE (182 = APPROX ONE SECOND @ 0.89 MHz)
+*
+*  ON EXIT:
+*    Y = DATA CHECKSUM
+*    D = ACTUAL NUMBER OF BYTES RECEIVED
+*    X AND U ARE PRESERVED
+*    CC.CARRY IS SET IF A FRAMING ERROR WAS DETECTED
+*
+Read  
+       use  dwread.asm
+         
+* Write
+*
+* Entry:
+Write    
+         use   dwwrite.asm
+
+         emod
+eom      equ   *
+         end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/dwcheck.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,230 @@
+         IFNE  1
+
+* Checksum routine - D returns as the sum of all bytes of the sector
+* Entry: X = address of sector
+* Exit : D = checksum value
+DoCSum   equ   *
+         clr   ,-s
+         clra
+         clrb
+c2@      addb  ,x+
+         adca  #0
+         dec   ,s
+         bne   c2@
+         leas  1,s
+*         exg   a,b		do endian conversion to match Server's checksum
+         rts
+
+
+* Weak but fast CRC Computation Routine
+* Entry: X = address of sector
+* Exit : D = crc value
+*DoCRC    equ   *
+*         IFNE  H6309
+*         clrd
+*         clre
+*CRC2     eord  ,x++
+*         ince
+*         bpl   CRC2
+*         ELSE
+*         clr   ,-s
+*         clra
+*         clrb
+*CRC2     eora  ,x+
+*         eorb  ,x+
+*         inc   ,s
+*         bpl   CRC2
+*         leas  1,s
+*         ENDC
+*         exg   a,b		do endian conversion to match PC's CRC
+*         rts
+
+
+         ELSE
+
+* CCITT CRC-16 Computation Routine
+*
+* Provided by Tim Lindner - 02/12/2003
+*
+* Entry: X = address of sector
+* Exit : D = crc value
+*CRC16    equ   *
+*         IFNE  H6309
+*         clrd
+*         clre
+*         ELSE
+*         clra
+*         clrb
+*         pshs  b		save as counter of 256 bytes
+*         ENDC
+*CRCLP    eora  ,x+
+*         IFNE  H6309
+*         lsld
+*         ELSE
+*         lslb
+*         rola
+*         ENDC
+*         bcc   CRCLp0
+*         IFNE  H6309
+*         eord  #$1021
+*         ELSE
+*         eora  #$10
+*         eorb  #$21
+*         ENDC
+*CRCLp0   equ   *
+*         IFNE  H6309
+*         lsld
+*         ELSE
+*         lslb
+*         rola
+*         ENDC
+*         bcc   CRCLp1
+*         IFNE  H6309
+*         eord  #$1021
+*         ELSE
+*         eora  #$10
+*         eorb  #$21
+*         ENDC
+*CRCLp1   equ   *
+*         IFNE  H6309
+*         lsld
+*         ELSE
+*         lslb
+*         rola
+*         ENDC
+*         bcc   CRCLp2
+*         IFNE  H6309
+*         eord  #$1021
+*         ELSE
+*         eora  #$10
+*         eorb  #$21
+*         ENDC
+*CRCLp2   equ   *
+*         IFNE  H6309
+*         lsld
+*         ELSE
+*         lslb
+*         rola
+*         ENDC
+*         bcc   CRCLp3
+*         IFNE  H6309
+*         eord  #$1021
+*         ELSE
+*         eora  #$10
+*         eorb  #$21
+*         ENDC
+*CRCLp3   equ   *
+*         IFNE  H6309
+*         lsld
+*         ELSE
+*         lslb
+*         rola
+*         ENDC
+*         bcc   CRCLp4
+**         IFNE  H6309
+**         eord  #$1021
+*         ELSE
+*         eora  #$10
+*         eorb  #$21
+*         ENDC
+*CRCLp4   equ   *
+*         IFNE  H6309
+*         lsld
+*         ELSE
+*         lslb
+*         rola
+*         ENDC
+*         bcc   CRCLp5
+*         IFNE  H6309
+*         eord  #$1021
+*         ELSE
+*         eora  #$10
+*         eorb  #$21
+*         ENDC
+*CRCLp5   equ   *
+*         IFNE  H6309
+*         lsld
+*         ELSE
+*         lslb
+*         rola
+*         ENDC
+*         bcc   CRCLp6
+*         IFNE  H6309
+*         eord  #$1021
+*         ELSE
+*         eora  #$10
+*         eorb  #$21
+*         ENDC
+*CRCLp6   equ   *
+*         IFNE  H6309
+*         lsld
+*         ELSE
+*         lslb
+*         rola
+*         ENDC
+*         bcc   CRCLp7
+*         IFNE  H6309
+*         eord  #$1021
+*         ELSE
+*         eora  #$10
+*         eorb  #$21
+*         ENDC
+*CRCLp7   equ   *
+*         IFNE  H6309
+*         dece
+*         ELSE
+*         dec   ,s
+*         ENDC
+*         bne   CRCLp
+*         IFEQ  H6309
+*         leas  1,s		eat counter on stack
+*         ENDC
+*         rts
+*
+*         ENDC
+*
+
+* calculate CCITT CRC 16
+* input:  X - Address of block
+*       Block is assumed to be 256 bytes
+* output: D - 16 bit CRC
+* uses: X, D, CC, and two bytes of stack
+
+DoCRC    equ   *
+         IFNE  H6309
+
+         clre
+         clrd
+nextbyte ldf   #8
+         eora  ,x+
+nextbit  lsld
+         bcc   loop
+         eord  #$1021
+loop     decf
+         bne   nextbit
+         dece
+         bne   nextbyte
+         rts
+
+         ELSE
+
+         clra
+         clrb
+         pshs  y,b
+nextbyte ldy   #8
+         eora  ,x+
+nextbit  lslb
+         rola
+         bcc   loop
+         eora  #$10
+         eorb  #$21
+loop     leay  -1,y
+         bne   nextbit
+         dec   ,s
+         bne   nextbyte
+         leas  1,s
+         puls  y,pc
+
+         ENDC
+         ENDC
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/dwdefs.d	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,40 @@
+********************************************************************
+* dwdefs - DriveWire Definitions File
+*
+* $Id$
+*
+* Ed.    Comments                                       Who YY/MM/DD
+* ------------------------------------------------------------------
+*   1    Started                                        BGP 03/04/03
+
+         nam   dwdefs
+         ttl   DriveWire Definitions File
+
+* Opcodes
+OP_NOP      equ    $00		No-Op
+OP_RESET1   equ    $FE		Server Reset
+OP_RESET2   equ    $FF		Server Reset
+OP_TIME     equ   '#	 	Current time requested
+OP_INIT     equ   'I		Init routine called
+OP_READ     equ   'R		Read one sector
+OP_REREAD   equ   'r		Re-read one sector
+OP_READEX   equ   'R+128	Read one sector
+OP_REREADEX equ   'r+128	Re-read one sector
+OP_WRITE    equ   'W		Write one sector
+OP_REWRIT   equ   'w		Re-write one sector
+OP_GETSTA   equ   'G		GetStat routine called
+OP_SETSTA   equ   'S		SetStat routine called
+OP_TERM     equ   'T		Term routine called
+OP_PRINT    equ   'P		PrintTerm routine called
+
+* WireBug opcodes (Server-initiated)
+OP_WIREBUG_MODE  equ   'B
+* WireBug opcodes (Server-initiated)
+OP_WIREBUG_READREGS   equ  'R	Read the CoCo's registers
+OP_WIREBUG_WRITEREGS  equ  'r	Write the CoCo's registers
+OP_WIREBUG_READMEM    equ  'M	Read the CoCo's memory
+OP_WIREBUG_WRITEMEM   equ  'm	Write the CoCo's memory
+OP_WIREBUG_GO         equ  'G	Tell CoCo to get out of WireBug mode and continue execution
+
+* Error definitions
+E_CRC      equ   $F3            Same as NitrOS-9 E$CRC
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/dwdesc.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,67 @@
+********************************************************************
+* DWDesc - DriveWire Device Descriptor Template
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   0      2003/03/28  Boisy G. Pitre
+* Created.
+
+         nam   DWDesc
+         ttl   DriveWire Device Descriptor Template
+
+         ifp1  
+         use   defsfile
+         endc  
+
+tylg     set   Devic+Objct
+atrv     set   ReEnt+rev
+rev      set   $01
+
+DNum     set   0
+Type     set   TYP.HARD
+Density  set   0
+Step     set   0
+Cyls     set   1024
+Sides    set   1
+Verify   set   1
+SectTrk  set   32
+SectTrk0 set   32
+Interlv  set   0
+SAS      set   8
+
+         mod   eom,name,tylg,atrv,mgrnam,drvnam
+
+         fcb   DIR.!ISIZ.!SHARE.!PEXEC.!PWRIT.!PREAD.!EXEC.!UPDAT. mode byte
+         fcb   HW.Page    extended controller address
+         fdb   $0000      physical controller address
+         fcb   initsize-*-1 initilization table size
+         fcb   DT.RBF     device type:0=scf,1=rbf,2=pipe,3=scf
+         fcb   dnum       drive number
+         fcb   Step       step rate
+         fcb   Type       drive device type
+         fcb   Density    media density:0=single,1=double
+         fdb   Cyls       number of cylinders (tracks)
+         fcb   Sides      number of sides
+         fcb   Verify     verify disk writes:0=on
+         fdb   SectTrk    # of sectors per track
+         fdb   SectTrk0   # of sectors per track (track 0)
+         fcb   Interlv    sector interleave factor
+         fcb   SAS        minimum size of sector allocation
+initsize equ   *
+
+         IFNE  DD
+name     fcs   /DD/
+         ELSE
+name     fcc   /X/
+         fcb   176+dnum
+         ENDC
+mgrnam   fcs   /RBF/
+drvnam   fcs   /rbdw3/
+
+         emod  
+eom      equ   *
+         end   
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/dwread.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,229 @@
+ IFNE H6309-1
+**
+** Rev 3 Notes:
+**
+**   For CoCo 1,2 or 3
+**   6809 Timing
+**   No Read Count in Receiver
+**
+
+
+******************************************************************************
+* COCO 57600 / 115.2K BAUD BIT-BANGER RECEIVER
+******************************************************************************
+*
+* WAITS FOR A SPECIFIED TIMEOUT PERIOD UNTIL A START-BIT APPEARS ON THE
+* BIT-BANGER INPUT. DATA RECEPTION IS INITIATED IF A START-BIT APPEARS
+* BEFORE THE TIMEOUT PERIOD EXPIRES. THE SERIAL DATA FORMAT MUST BE:
+*    1 START BIT, 8 DATA BITS, NO PARITY, 1..2 STOP BITS.
+*
+* DATA RECPEPTION TERMINATES WHEN:
+*   - A PERIOD OF APPROX 5.5 MS (2.75 MS) ELLAPSES WITHOUT A NEW START-BIT
+*   - A FRAMING ERROR IS DETECTED.
+*
+*  ON ENTRY:
+*    X = START ADDRESS FOR DATA STORAGE
+*    A = TIMEOUT VALUE (182 = APPROX ONE SECOND @ 0.89 MHZ)
+*
+*  ON EXIT:
+*    Y = DATA CHECKSUM
+*    D = ACTUAL NUMBER OF BYTES RECEIVED
+*    X AND U ARE PRESERVED
+*    CC.CARRY IS SET ONLY IF A FRAMING ERROR WAS DETECTED
+*
+******************************************************************************
+BBIN      EQU       $FF22               ; BIT-BANGER INPUT ADDRESS
+BCTR      EQU       1                   ; OFFSET TO BIT LOOP COUNTER ON STACK
+RCVSTA    EQU       2                   ; OFFSET TO CC VALUE ON THE STACK
+BUFBAS    EQU       4                   ; OFFSET TO STORAGE ADDRESS ON STACK
+
+DWRead
+RCV56K    CLRB                          ; CLEAR CARRY FLAG (NO FRAMING ERROR)
+          PSHS      U,X,DP,CC           ; PRESERVE REGISTERS
+          STA       ,--S                ; STORE INITIAL TIMEOUT DURATION
+          LDD       #$01FF              ; A = SERIAL INPUT MASK, B = $FF
+          ORCC      #$50                ; MASK INTERRUPTS
+          TFR       B,DP                ; SET DIRECT PAGE TO $FFXX
+          SETDP     $FF                 ; INFORM ASSEMBLER OF NEW DP VALUE
+          LEAU      ,X                  ; POINT U TO STORAGE ADDRESS
+          LDX       #0                  ; INITIALIZE CHECKSUM
+          BRA       WAIT1               ; GO WAIT FOR A START BIT
+
+BSTART    LEAU      1,U       5 \ 11    ; ADVANCE THE STORAGE PTR
+          CLR       ,S        6 /       ; RESET TIMEOUT MSB TO 1
+
+          LDB       <BBIN     4 \       ; BIT 0
+          LSRB                2  |
+          RORB                2  | 15
+          LDA       #3        2  |
+          STA       BCTR,S    5 /
+
+BLOOP     LDA       <BBIN     4 \       ; BITS 1,3 AND 5
+          LSRA                2  | 15
+          RORB                2  |
+          DEC       BCTR,S    7 /
+
+          LDA       <BBIN     4 \       ; BITS 2,4 AND 6
+          LSRA                2  |
+          RORB                2  | 16
+          LDA       BCTR,S    5  |
+          BNE       BLOOP     3 /
+
+          LDA       <BBIN     4 \       ; BIT 7
+          LSRA                2  |
+          RORB                2  | 16
+          ABX                 3  |      ; ACCUMULATE CHECKSUM
+          STB       -1,U      5 /       ; PUT BYTE INTO STORAGE
+
+          LDA       <BBIN     4 \       ; STOP BIT
+          ANDA      #1        2  | 9    ; MASK OUT ALL OTHER BITS (1-7)
+          BEQ       FINISH    3 /       ; BRANCH IF FRAMING ERROR
+
+WAIT1     BITA      <BBIN     4 \  7    ; TWO RAPID TESTS FOR NEXT START BIT
+          BEQ       BSTART    3 /
+          BITA      <BBIN     4 \
+          BEQ       BSTART    3  | 9
+          LDB       #$FF      2 /       ; INIT TIMEOUT LSB
+
+WAIT2     BITA      <BBIN     4 \
+          BEQ       BSTART    3  | 9
+          SUBB      #1        2 /       ; DECREMENT TIMEOUT LSB
+          BITA      <BBIN     4 \
+          BEQ       BSTART    3  | 10
+          BCC       WAIT2     3 /       ; LOOP UNTIL TIMEOUT LSB < 0
+
+          BITA      <BBIN     4 \
+          BEQ       BSTART    3  | 11
+          LDB       ,S        4 /       ; GET TIMEOUT MSB
+          BITA      <BBIN     4 \
+          BEQ       BSTART    3  | 9
+          SUBB      #1        2 /       ; DECREMENT TIMEOUT MSB
+          BITA      <BBIN     4 \
+          BEQ       BSTART    3  | 11
+          STB       ,S        4 /       ; STORE TIMEOUT MSB
+          BITA      <BBIN     4 \
+          BEQ       BSTART    3  | 10
+          BCC       WAIT1     3 /       ; LOOP IF TIMEOUT NOT EXPIRED
+
+FINISH    INCA                          ; IF FRAMING ERROR THEN A=1 ELSE A=2
+          ORA       RCVSTA,S            ; SET CARRY BIT IN CC VALUE ON..
+          STA       RCVSTA,S            ; ..THE STACK ONLY IF FRAMING ERROR
+          LEAY      ,X                  ; RETURN CHECKSUM IN Y
+          TFR       U,D                 ; CALCULATE ACTUAL NUMBER..
+          SUBD      BUFBAS,S            ; ..OF BYTES RECEIVED
+          LEAS      2,S                 ; POP TIMEOUT AND BIT LOOP COUNTERS
+          PULS      CC,DP,X,U,PC        ; RESTORE REGISTERS AND RETURN
+          SETDP     $00
+
+
+
+
+
+
+
+
+ ELSE
+
+
+
+** Rev 4 Notes:
+**
+**   For CoCo 2 or 3
+**   6309 Native Mode
+**   No Read Count in Receiver
+**
+
+******************************************************************************
+* COCO 57600 / 115.2K BAUD BIT-BANGER RECEIVER
+******************************************************************************
+*
+* WAITS FOR A SPECIFIED TIMEOUT PERIOD UNTIL A START-BIT APPEARS ON THE
+* BIT-BANGER INPUT. DATA RECEPTION IS INITIATED IF A START-BIT APPEARS
+* BEFORE THE TIMEOUT PERIOD EXPIRES. THE SERIAL DATA FORMAT MUST BE:
+*    1 START BIT, 8 DATA BITS, NO PARITY, 1..2 STOP BITS.
+*
+* DATA RECPEPTION TERMINATES WHEN:
+*   - A PERIOD OF APPROX 5.5 MS (2.75 MS) ELLAPSES WITHOUT A NEW START-BIT
+*   - A FRAMING ERROR IS DETECTED.
+*
+*  ON ENTRY:
+*    X = START ADDRESS FOR DATA STORAGE
+*    A = TIMEOUT VALUE (183 = APPROX ONE SECOND @ 0.89 MHZ)
+*
+*  ON EXIT:
+*    Y = DATA CHECKSUM
+*    D = ACTUAL NUMBER OF BYTES RECEIVED
+*    X AND U ARE PRESERVED
+*    E AND F ARE CLOBBERED
+*    CC.CARRY IS SET ONLY IF A FRAMING ERROR WAS DETECTED
+*
+******************************************************************************
+BBIN      EQU       $FF22               ; BIT-BANGER INPUT ADDRESS
+RCVSTA    EQU       0                   ; OFFSET TO CC VALUE ON THE STACK
+BUFBAS    EQU       1                   ; OFFSET TO STORAGE ADDRESS ON STACK
+
+DWRead
+RCV56K    CLRB                          ; CLEAR CARRY FLAG (NO FRAMING ERROR)
+          PSHS      U,X,CC              ; PRESERVE REGISTERS
+          LDU       #BBIN               ; POINT U TO BIT BANGER INPUT
+          TFR       A,F                 ; COPY INTITAL TIMEOUT TO F
+          LDD       #$01FF              ; A = SERIAL IN MASK, B = TIMEOUT LSB
+          LEAY      ,X                  ; POINT Y TO STORAGE ADDRESS
+          LDX       #0                  ; INITIALIZE CHECKSUM
+          ORCC      #$50                ; MASK INTERRUPTS
+*          LDMD      #1                  ; REQUIRES 6309 NATIVE MODE
+          BRA       WAIT1               ; GO WAIT FOR A START BIT
+
+BSTART    SEXW                4 \       ; 4-CYCLE DELAY (CLOBBERS D)
+          LDW       #$005A    4  | 11   ; PREP SHIFT COUNTER / TIMING FLAGS
+          BRA       BSAMP     3 /       ; ENTER THE LOOP
+
+BLOOP     BCC       BSAMP     3         ; BRANCH IF A 15-CYCLE BIT
+          NOP                 1         ; ONE MORE FOR A 16-CYCLE BIT
+BSAMP     LDA       ,U        4 \       ; SAMPLE DATA BIT
+          LSRA                1  |      ; SHIFT INTO CARRY
+          RORB                1  | 12   ; ROTATE INTO BYTE ACCUMULATOR
+          NOP                 1  |      ; DELAY CYCLE
+          LSRW                2  |      ; BUMP THE SHIFT COUNTER / TIMING FLAGS
+          BNE       BLOOP     3 /       ; LOOP UNTIL BIT 6 HAS BEEN SAMPLED
+          LEAU      ,U        4         ; CONSUME 4 CYCLES (16 TOTAL FOR BIT 6)
+
+          LDA       ,U        4 \       ; BIT 7
+          LSRA                1  |
+          RORB                1  | 15
+          STB       ,Y+       5  |      ; PUT BYTE INTO STORAGE
+          ABX                 1  |      ; ACCUMULATE CHECKSUM
+          LDD       #$01FF    3 /       ; A = SERIAL IN MASK, B = TIMEOUT LSB
+
+          ANDA      ,U        4 \ 7     ; STOP BIT
+          BEQ       FINISH    3 /       ; BRANCH IF FRAMING ERROR
+
+WAIT1     BITA      ,U        4 \  7    ; TWO RAPID TESTS FOR NEXT START BIT
+          BEQ       BSTART    3 /
+WAIT2     BITA      ,U        4 \
+          BEQ       BSTART    3  | 9
+          SUBB      #1        2 /       ; DECREMENT TIMEOUT LSB
+          BITA      ,U        4 \
+          BEQ       BSTART    3  | 10
+          BCC       WAIT2     3 /       ; LOOP UNTIL TIMEOUT LSB < 0
+
+          BITA      ,U        4 \  7 
+          BEQ       BSTART    3 /
+          BITA      ,U        4 \
+          BEQ       BSTART    3  | 10
+          SUBF      #1        3 /       ; DECREMENT TIMEOUT MSB
+          BITA      ,U        4 \
+          BEQ       BSTART    3  | 10
+          BCC       WAIT1     3 /       ; LOOP IF TIMEOUT NOT EXPIRED
+
+FINISH    INCA                          ; IF FRAMING ERROR THEN A=1 ELSE A=2
+          ORA       RCVSTA,S            ; SET CARRY BIT IN CC VALUE ON..
+          STA       RCVSTA,S            ; ..THE STACK ONLY IF FRAMING ERROR
+          TFR       Y,D                 ; CALCULATE ACTUAL NUMBER..
+          SUBD      BUFBAS,S            ; ..OF BYTES RECEIVED
+          LEAY      ,X                  ; RETURN CHECKSUM IN Y
+          PULS      CC,X,U,PC           ; RESTORE REGISTERS AND RETURN
+
+ ENDC
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/dwwrite.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,138 @@
+ IFNE H6309-1
+**
+** Rev 3 Notes:
+**
+**   For CoCo 1,2 or 3
+**   6809 Timing
+**   No Read Count in Receiver
+**
+
+
+******************************************************************************
+* COCO 57600 / 115.2K BAUD BIT-BANGER TRANSMITTER
+******************************************************************************
+*
+* TRNSMITS A SPECIFIED NUMBER OF DATA BYTES THROUGH THE BIT-BANGER PORT
+* AT HIGH SPEED. ALL OF THE DATA IS SENT IN A SINGLE BURST, NO HANDSHAKING
+* IS PROVIDED. THE TRANSMISSION FORMAT IS:
+*    1 START BIT, 8 DATA BITS, NO PARITY, 1 STOP BIT.
+*
+*  ON ENTRY:
+*    X = ADDRESS OF DATA TO TRANSMIT
+*    Y = NUMBER OF BYTES TO TRANSMIT
+*
+*  ON EXIT:
+*    X = ADDRESS OF LAST BYTE TRANSMITTED + 1
+*    Y = 0
+*    A, B AND U ARE PRESERVED
+*
+******************************************************************************
+BBOUT     EQU       $FF20               ; BIT-BANGER OUTPUT ADDRESS
+
+DWWrite
+XMT56K    PSHS      U,DP,D,CC           ; PRESERVE REGISTERS
+          LDD       #$04FF              ; A = LOOP COUNTER, B = $FF
+          ORCC      #$50                ; MASK INTERRUPTS
+          TFR       B,DP                ; SET DIRECT PAGE TO $FFXX
+          SETDP     $FF                 ; INFORM ASSEMBLER OF NEW DP VALUE
+          FCB       $8C                 ; SKIP NEXT INSTRUCTION
+
+OUTBYT    STB       <BBOUT    4 \       ; STOP BIT
+          LDB       ,X+       6  |      ; GET NEXT BYTE FROM STORAGE
+          NOP                 2  | 16   ; CONSUME 2 CYCLES
+          LSLB                2  |      ; BIT 7->CARRY .. BIT 0->B.1 ..'0'->B.0
+          ROLB                2 /       ; BIT 7 -> B.0 .. BIT 0->B.2 ..'0'->B.1
+
+ODDBIT    STB       <BBOUT    4 \       ; START BIT, DATA BITS 1,3 AND 5
+          RORB                2  | 16   ; MOVE NEXT BIT INTO POSITION
+          EXG       A,A       8  |      ; 8-CYCLE DELAY
+          NOP                 2 /       ; MORE DELAY
+
+          STB       <BBOUT    4 \       ; DATA BITS 0,2,4 AND 6
+          RORB                2  |      ; MOVE NEXT BIT INTO POSITION
+          LEAU      ,U        4  | 15   ; 4-CYCLE DELAY
+          DECA                2  |      ; DECREMENT LOOP COUNTER
+          BNE       ODDBIT    3 /       ; LOOP UNTIL BIT 6 HAS BEEN TRANSMITTED
+
+          STB       <BBOUT    4 \       ; DATA BIT 7
+          LDD       #$0402    3  | 16   ; A = LOOP COUNTER, B = STOP BIT VALUE
+          LEAY      ,-Y       6  |      ; DECREMENT BYTES REMAINING COUNT
+          BNE       OUTBYT    3 /       ; LOOP IF MORE TO TRANSMIT
+
+          STB       <BBOUT              ; FINAL STOP BIT
+          PULS      CC,D,DP,U,PC        ; RESTORE REGISTERS AND RETURN
+          SETDP     $00
+
+
+
+
+ ELSE
+
+
+
+
+** Rev 4 Notes:
+**
+**   For CoCo 2 or 3
+**   6309 Native Mode
+**   No Read Count in Receiver
+**
+
+
+******************************************************************************
+* COCO 57600 / 115.2K BAUD BIT-BANGER TRANSMITTER
+******************************************************************************
+*
+* TRNSMITS A SPECIFIED NUMBER OF DATA BYTES THROUGH THE BIT-BANGER PORT
+* AT HIGH SPEED. ALL OF THE DATA IS SENT IN A SINGLE BURST, NO HANDSHAKING
+* IS PROVIDED. THE TRANSMISSION FORMAT IS:
+*    1 START BIT, 8 DATA BITS, NO PARITY, 1 STOP BIT.
+*
+*  ON ENTRY:
+*    X = ADDRESS OF DATA TO TRANSMIT
+*    Y = NUMBER OF BYTES TO TRANSMIT
+*
+*  ON EXIT:
+*    X = ADDRESS OF LAST BYTE TRANSMITTED + 1
+*    Y = 0
+*    A, B, E, F AND U ARE PRESERVED
+*
+******************************************************************************
+BBOUT     EQU       $FF20               ; BIT-BANGER OUTPUT ADDRESS
+
+DWWrite
+XMT56K    PSHS      U,D,CC              ; PRESERVE REGISTERS
+          LDU       #BBOUT              ; POINT U TO BIT BANGER OUTPUT
+          ORCC      #$50                ; MASK INTERRUPTS
+*          LDMD      #1                  ; REQUIRES 6309 NATIVE MODE
+          BRA       XSTART              ; SKIP NEXT INSTRUCTION
+
+OUTBYT    STB       ,U        4 \       ; STOP BIT
+XSTART    LDB       ,X+       5  |      ; GET NEXT BYTE FROM STORAGE
+          LSLB                1  | 16   ; BIT 7->CARRY .. BIT 0->B.1 ..'0'->B.0
+          ROLB                1  |      ; BIT 7 -> B.0 .. BIT 0->B.2 ..'0'->B.1
+          LDA       #8        2  |      ; BIT COUNT (START BIT, DATA BITS 0-6)
+          BRA       BSEND     3 /       ; ENTER THE LOOP
+
+XLOOP     BITA      #1        2         ; BIT COUNTER EVEN OR ODD?
+          BEQ       BSEND     3         ; BRANCH IF EVEN (15-CYCLE BIT)
+          NOP                 1         ; ONE MORE FOR A 16-CYCLE BIT
+BSEND     STB       ,U        4 \       ; BIT OUTPUT
+          RORB                1  |      ; ROTATE NEXT BIT INTO POSITION
+          NOP                 1  | 10   ; DELAY CYCLE
+          DECA                1  |      ; DECREMENT BIT COUNTER
+          BNE       XLOOP     3 /       ; LOOP UNTIL BIT 6 HAS BEEN SAMPLED
+          LEAU      ,U++      6         ; CONSUME 6 CYCLES (16 TOTAL FOR BIT 6)
+
+          STB       ,U        4 \       ; BIT 7 OUTPUT
+          LDB       #2        2  |      ; PREPARE STOP BIT
+          NOP                 1  | 15   ; DELAY CYCLE
+          LEAY      -1,Y      5  |      ; DECREMENT BYTES REMAINING COUNT
+          BNE       OUTBYT    3 /       ; LOOP IF MORE TO TRANSMIT
+
+          STB       ,U                  ; FINAL STOP BIT
+          PULS      CC,D,U,PC           ; RESTORE REGISTERS AND RETURN
+
+ ENDC
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/p_scdwp.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,66 @@
+********************************************************************
+* P - CoCo DriveWire Printer Driver Device Descriptor
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*          ????/??/??
+
+         nam   P
+         ttl   CoCo DriveWire Printer Driver Device Descriptor
+
+* Disassembled 98/08/23 21:15:24 by Disasm v1.6 (C) 1988 by RML
+
+         ifp1  
+         use   defsfile
+         endc  
+
+tylg     set   Devic+Objct
+atrv     set   ReEnt+rev
+rev      set   $00
+
+         mod   eom,name,tylg,atrv,mgrnam,drvnam
+
+         fcb   UPDAT.     mode byte
+         fcb   HW.Page    extended controller address
+         fdb   $FF22      physical controller address
+         fcb   initsize-*-1 initilization table size
+         fcb   DT.SCF     device type:0=scf,1=rbf,2=pipe,3=scf
+         fcb   $00        case:0=up&lower,1=upper only
+         fcb   $00        backspace:0=bsp,1=bsp then sp & bsp
+         fcb   $01        delete:0=bsp over line,1=return
+         fcb   $00        echo:0=no echo
+         fcb   $00        auto line feed:0=off
+         fcb   $00        end of line null count
+         fcb   $00        pause:0=no end of page pause
+         fcb   66         lines per page
+         fcb   C$BSP      backspace character
+         fcb   C$DEL      delete line character
+         fcb   C$CR       end of record character
+         fcb   $00        end of file character
+         fcb   C$RPRT     reprint line character
+         fcb   C$RPET     duplicate last line character
+         fcb   C$PAUS     pause character
+         fcb   $00        interrupt character
+         fcb   $00        quit character
+         fcb   $5F        backspace echo character
+         fcb   C$BELL     line overflow character (bell)
+         fcb   $00        init value for dev ctl reg
+         fcb   B600       baud rate
+         fdb   name       copy of descriptor name address
+         fcb   $00        acia xon char
+         fcb   $00        acia xoff char
+         fcb   80         (szx) number of columns for display
+         fcb   66         (szy) number of rows for display
+initsize equ   *
+
+name     fcs   /p/
+mgrnam   fcs   /SCF/
+drvnam   fcs   /scdwp/
+
+         emod  
+eom      equ   *
+         end   
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/rbdw3.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,356 @@
+********************************************************************
+* rbdw3 - DriveWire 3 driver
+*
+* $Id$
+*
+* This driver works in conjuction with the DriveWire Server on Linux,
+* Mac or Windows, providing the CoCo with pseudo-disk access through
+* the serial port.
+*
+* It adheres to the DriveWire Version 3 Protocol.
+*
+* The baud rate is set at 115200 and the communications requirements
+* are set to 8-N-1.  For OS-9 Level One on a CoCo 2, the baud rate
+* is 57600.
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*   1      2008/02/08  Boisy G. Pitre
+* Started from drivewire.asm in DriveWire 2 Product folder.
+*
+*   2      2008/04/22  Boisy G. Pitre
+* Verified working operation on a CoCo 3 running NitrOS-9/6809 Level 1 @ 57.6Kbps
+
+         nam   rbdw3
+         ttl   DriveWire 3 driver
+
+NUMRETRIES equ  8
+
+         ifp1
+         use   defsfile
+         use   dwdefs.d
+         endc
+
+NumDrvs  set   4
+
+tylg     set   Drivr+Objct   
+atrv     set   ReEnt+rev
+rev      set   $01
+edition  set   2
+
+         mod   eom,name,tylg,atrv,start,size
+
+         rmb   DRVBEG+(DRVMEM*NumDrvs)
+driveno  rmb   1
+retries  rmb   1
+size     equ   .
+
+         fcb   DIR.+SHARE.+PEXEC.+PREAD.+PWRIT.+EXEC.+UPDAT.
+
+name     fcs   /rbdw3/
+         fcb   edition
+
+start    bra   Init
+         nop
+         bra   Read
+         nop
+         lbra  Write
+         lbra  GetStat
+         lbra  SetStat
+
+* Term
+*
+* Entry:
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Term
+* Send OP_TERM to the server
+         clrb				clear Carry
+         pshs  a,cc			then push CC on stack
+         lda   #OP_TERM
+         leax  1,s
+         sta   ,x
+         ldy   #$0001
+         IFGT  LEVEL-1
+         ldu   <D.DWSUB
+         ELSE
+         ldu   >D.DWSUB
+         ENDC
+         jsr   6,u
+         puls  a,cc,pc
+
+* Init
+*
+* Entry:
+*    Y  = address of device descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Init
+         ldb   #NumDrvs
+         stb   V.NDRV,u
+         leax  DRVBEG,u
+         lda   #$FF
+Init2    sta   DD.TOT,x			invalidate drive tables
+         sta   DD.TOT+1,x
+         sta   DD.TOT+2,x
+         leax  DRVMEM,x
+         decb
+         bne   Init2
+
+* Link to subroutine module
+         clra
+         leax  name+2,pcr
+         os9   F$Link
+         bcs   CpyLSNEx 
+         tfr   y,u		 
+         IFGT  LEVEL-1
+         stu   <D.DWSUB
+         ELSE
+         stu   >D.DWSUB
+         ENDC
+* Initialize the low level device
+         jsr   ,u
+         lda   #OP_INIT
+         pshs  a
+         leax  ,s
+         ldy   #$0001
+         jsr   6,u
+         clrb
+         puls  a,pc
+
+* Read
+*
+* Entry:
+*    B  = MSB of LSN
+*    X  = LSB of LSN
+*    Y  = address of path descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Read 
+         lda   #NUMRETRIES
+         sta   retries,u
+         cmpx  #$0000			LSN 0?
+         bne   ReadSect			branch if not
+         tstb	   			LSN 0?
+         bne   ReadSect			branch if not
+* At this point we're reading LSN0
+         bsr   ReadSect			read the sector
+         bcs   CpyLSNEx			if error, exit
+         leax  DRVBEG,u			point to start of drive table
+         ldb   <PD.DRV,y		get drive number
+NextDrv  beq   CopyLSN0			branch if terminal count
+         leax  <DRVMEM,x		else move to next drive table entry
+         decb				decrement counter
+         bra   NextDrv			and continue
+CopyLSN0 ldb   #DD.SIZ			get size to copy
+         ldy   PD.BUF,y			point to buffer
+CpyLSNLp lda   ,y+			get byte from buffer
+         sta   ,x+			and save in drive table
+         decb
+         bne   CpyLSNLp
+CpyLSNEx rts
+
+
+ReadSect pshs  cc
+         pshs  u,y,x,b,a,cc			then push CC and others on stack
+* Send out op code and 3 byte LSN
+         lda   PD.DRV,y			get drive number
+         cmpa  #NumDrvs
+         blo   Read1
+         ldb   #E$Unit
+         bra   ReadEr2
+Read1    sta   driveno,u
+         lda   #OP_READEX		load A with READ opcode
+         
+Read2
+         ldb   driveno,u
+         leax  ,s
+         std   ,x
+         ldy    #5 
+         IFGT  LEVEL-1
+         ldu   <D.DWSUB
+         ELSE
+         ldu   >D.DWSUB
+         ENDC
+         orcc  #IntMasks
+         jsr   6,u
+		 
+* Get 256 bytes of sector data
+         ldx   5,s
+         ldx   PD.BUF,x			get buffer pointer into X
+         lda   #255
+         jsr   3,u
+         bcs   ReadEr1
+         cmpd  #256
+         bne   ReadEr1
+         pshs  y
+         leax  ,s
+         ldy   #$0002
+         jsr   6,u				write checksum to server
+
+* Get error code byte
+         leax  ,s
+         lda   #255
+         jsr   3,u
+         puls  d
+         bcs   ReadEr1			branch if we timed out
+         tfr   a,b				transfer byte to B (in case of error)
+         tstb					is it zero?
+         beq   ReadEx			if not, exit with error
+         cmpb  #E$CRC
+         bne   ReadEr2
+         ldu   7,s				get U from stack
+         dec   retries,u		decrement retries
+         beq   ReadEr1
+         
+         lda   #OP_REREADEX		reread opcode
+         bra   Read2			and try getting sector again
+ReadEr1  ldb   #E$Read			read error
+ReadEr2  lda   9,s
+         ora   #Carry
+         sta   9,s
+ReadEx   leas  5,s
+         puls  y,u
+         puls  cc,pc
+
+* Write
+*
+* Entry:
+*    B  = MSB of LSN
+*    X  = LSB of LSN
+*    Y  = address of path descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Write    lda   #NUMRETRIES
+         sta   retries,u
+         pshs  cc
+         pshs  u,y,x,b,a,cc
+* Send out op code and 3 byte LSN
+         lda   PD.DRV,y
+         cmpa  #NumDrvs
+         blo   Write1
+         comb			set Carry
+         ldb   #E$Unit
+         bra   WritEx
+Write1   sta   driveno,u
+         lda   #OP_WRITE
+Write15
+         ldb   driveno,u
+         leax  ,s
+         std   ,x
+         ldy   #$0005
+         IFGT  LEVEL-1
+         ldu   <D.DWSUB
+         ELSE
+         ldu   >D.DWSUB
+         ENDC
+         orcc  #IntMasks
+         jsr   6,u
+
+* Compute checksum on sector we just sent and send checksum to server
+         ldy   5,s				get Y from stack
+         ldx   PD.BUF,y			point to buffer
+         ldy   #256
+         jsr   6,u
+         leax  -256,x
+         bsr   DoCSum
+         pshs  d
+         leax  ,s
+         ldy   #$0002
+         jsr   6,u
+
+* Await acknowledgement from server on receipt of sector
+*         ldy   #$0001
+         lda   #255
+         leax  ,s
+         jsr   3,u				read ack byte from server
+         puls  d				  
+         bcs   WritEx1
+         tsta
+         beq   WritEx			yep
+         tfr   a,b
+         cmpb  #E$CRC			checksum error?
+         bne   WritEx2
+         ldu   7,s				get U from stack
+         dec   retries,u		decrement retries
+         beq   WritEx1			exit with error if no more
+         lda   #OP_REWRIT		else resend
+         bra   Write15
+WritEx1  ldb   #E$Write
+WritEx2  lda   9,s
+         ora   #Carry
+         sta   9,s
+WritEx   leas  5,s
+         puls  y,u
+         puls  cc,pc
+ 
+         use   dwcheck.asm
+		 
+* SetStat
+*
+* Entry:
+*    R$B = function code
+*    Y   = address of path descriptor
+*    U   = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+SetStat  lda   #OP_SETSTA
+* Size optimization
+		 fcb   $8C  skip next two bytes
+
+
+* GetStat
+*
+* Entry:
+*    R$B = function code
+*    Y   = address of path descriptor
+*    U   = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+GetStat  
+         lda   #OP_GETSTA
+         clrb				clear Carry
+         pshs  cc			and push CC on stack
+         leas  -3,s
+         sta   ,s
+         lda   PD.DRV,y			get drive number
+         ldx   PD.RGS,y
+         ldb   R$B,x
+         std   1,s
+         leax  ,s
+         ldy   #$0003
+         IFGT  LEVEL-1
+         ldu   <D.DWSUB
+         ELSE
+         ldu   >D.DWSUB
+         ENDC
+         jsr   6,u
+         leas  3,s
+         puls  cc,pc
+		 
+         emod
+eom      equ   *
+         end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/level1/modules/scdwp.asm	Sat Mar 07 20:04:42 2009 +0000
@@ -0,0 +1,169 @@
+********************************************************************
+* scdwp.asm - CoCo DriveWire Printer Driver
+*
+* $Id$
+*
+* Edt/Rev  YYYY/MM/DD  Modified by
+* Comment
+* ------------------------------------------------------------------
+*  1       2009/03/06  Boisy G. Pitre
+* Started.
+
+         nam   scdwp
+         ttl   CoCo DriveWire Printer Driver
+
+         ifp1
+         use   defsfile
+         endc
+
+tylg     set   Drivr+Objct   
+atrv     set   ReEnt+Rev
+rev      set   $00
+edition  set   1
+
+         mod   eom,name,tylg,atrv,Start,Size
+
+         fcb   READ.+WRITE.
+
+name     fcs   /scdwp/
+         fcb   edition    one more revision level than the stock printer
+
+* Device memory area: offset from U
+         org   V.SCF      V.SCF: free memory for driver to use
+V.PAR    rmb   1          1=space, 2=mark parity
+V.BIT    rmb   1          0=7, 1=8 bits
+V.STP    rmb   1          0=1 stop bit, 1=2 stop bits
+V.COM    rmb   2          Com Status baud/parity (=Y from SS.Comst Set/GetStt
+V.COL    rmb   1          columns
+V.ROW    rmb   1          rows
+V.WAIT   rmb   2          wait count for baud rate?
+V.TRY    rmb   2          number of re-tries if printer is busy
+V.RTRY   rmb   1          low nibble of parity=high byte of number of retries
+V.BUFF   rmb   $80        room for 128 blocked processes
+size     equ   .
+
+start    equ   *
+         lbra  Init
+         lbra  Read
+         lbra  Write
+         lbra  GetStt
+         lbra  SetStt
+
+* Term
+*
+* Entry:
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code   
+*
+Term     equ   *
+         clrb
+         rts
+
+* Init
+*
+* Entry:
+*    Y  = address of device descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Init
+         rts
+
+* Write
+*
+* Entry:
+*    A  = character to write
+*    Y  = address of path descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code
+*
+Write    equ   *
+         tfr   a,b
+         lda   #'Q
+         pshs  d
+         leax  ,s
+         ldy   #$0002
+         ldu   >D.DWSUB
+         jsr   6,u
+         puls  d,pc
+
+
+* GetStat
+*
+* Entry:
+*    A  = function code
+*    Y  = address of path descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code 
+*
+GetStt   cmpa  #SS.EOF		end of file?
+         bne   L0112
+         clrb			if so, exit with no error
+         rts   
+
+L0112    ldx   PD.RGS,y
+         cmpa  #SS.ScSiz
+         beq   L0123
+         cmpa  #SS.ComSt
+         bne   L0173
+         clra
+         clrb
+         std   R$Y,x
+         clrb
+         rts
+
+* get screen size GetStt
+L0123    clra  
+         ldb   #80
+         std   R$X,x
+         ldb   #24
+         std   R$Y,x
+         clrb
+         rts
+
+* SetStat
+*
+* Entry:
+*    A  = function code
+*    Y  = address of path descriptor
+*    U  = address of device memory area
+*
+* Exit:
+*    CC = carry set on error
+*    B  = error code 
+*
+SetStt   
+Close    cmpa  #SS.Close	close the device?
+         bne   L0173
+         lda   #'F		send PrintQueue Flush Packet
+         pshs  a
+         ldy   #$0001
+         leax  ,s
+         ldu   >D.DWSUB
+         jsr   6,u
+         puls  a,pc
+
+
+Read     comb  
+         ldb   #E$BMode
+         rts
+
+L0173    comb
+         ldb   #E$UnkSVc
+         rts
+
+         emod
+eom      equ   *
+         end
--- a/level2/coco3/bootfiles/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level2/coco3/bootfiles/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -9,6 +9,24 @@
 
 KERNEL_1773	= $(MD)/rel_80 $(MD)/boot_1773_6ms $(MD)/krn
 KERNEL_1773_50HZ	= $(MD)/rel_80_50hz $(MD)/boot_1773_6ms $(MD)/krn
+KERNEL_DW3	= $(MD)/rel_80 $(MD)/boot_dw3 $(MD)/krn
+
+# NitrOS-9 disk bootfile to allow booting from DriveWire 3 server
+BOOTFILE_DW3	= $(MD)/krnp2 $(MD)/ioman $(MD)/init \
+		$(MD)/rbf.mn \
+		$(MD)/rbdw3.dr $(MD)/dw3.sb \
+		$(MD)/ddx0.dd $(MD)/x1.dd $(MD)/x2.dd $(MD)/x3.dd \
+		$(MD)/rb1773.dr $(MD)/d0_40d.dd $(MD)/d1_40d.dd \
+		$(MD)/d2_40d.dd $(MD)/ddd0_40d.dd \
+		$(MD)/scf.mn $(MD)/vtio.dr \
+		$(MD)/keydrv_cc3.sb $(MD)/joydrv_joy.sb $(MD)/snddrv_cc3.sb \
+		$(MD)/cowin.io $(MD)/covdg.io \
+		$(MD)/term_win80.dt \
+		$(MD)/w.dw $(MD)/w1.dw $(MD)/w2.dw $(MD)/w3.dw $(MD)/w4.dw \
+		$(MD)/w5.dw $(MD)/w6.dw $(MD)/w7.dw \
+		$(MD)/scdwp.dr $(MD)/p_scdwp.dd \
+		$(MD)/pipeman.mn $(MD)/piper.dr $(MD)/pipe.dd \
+		$(MD)/clock_60hz $(MD)/clock2_dw3
 
 # OS-9 disk bootfile to allow booting from WD1773 disk controller
 BOOTFILE_40D	= $(MD)/krnp2 $(MD)/ioman $(MD)/init \
@@ -63,8 +81,8 @@
 		$(MD)/pipeman.mn $(MD)/piper.dr $(MD)/pipe.dd \
 		$(MD)/clock_50hz $(MD)/clock2_soft
 
-BOOTFILES	= bootfile_40d bootfile_40d_50hz bootfile_80d bootfile_80d_50hz
-KERNELS		= kernel_1773 kernel_1773_50hz
+BOOTFILES	= bootfile_40d bootfile_40d_50hz bootfile_80d bootfile_80d_50hz bootfile_dw3
+KERNELS		= kernel_1773 kernel_1773_50hz kernel_dw3
 
 ALLOBJS		= $(BOOTFILES) $(KERNELS)
 
@@ -83,6 +101,9 @@
 bootfile_80d_50hz: $(BOOTFILE_80D_50HZ) $(DEPENDS)
 	$(MERGE) $(BOOTFILE_80D_50HZ)>$@
 
+bootfile_dw3: $(BOOTFILE_DW3) $(DEPENDS)
+	$(MERGE) $(BOOTFILE_DW3)>$@
+
 # Kernels
 kernel_1773: $(KERNEL_1773) $(DEPENDS)
 	$(MERGE) $(KERNEL_1773)>$@
@@ -90,6 +111,9 @@
 kernel_1773_50hz: $(KERNEL_1773_50HZ) $(DEPENDS)
 	$(MERGE) $(KERNEL_1773_50HZ)>$@
 
+kernel_dw3: $(KERNEL_DW3) $(DEPENDS)
+	$(MERGE) $(KERNEL_DW3)>$@
+
 clean:
 	$(RM) $(ALLOBJS)
 
--- a/level2/coco3/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level2/coco3/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -7,12 +7,14 @@
 DISTRO		= $(CPU)L$(LEVEL)
 DISTRONAME	= nos9$(CPU)l$(LEVEL)
 DISTROVER	= $(DISTRONAME)$(NITROS9VER)$(PORT)
+BOOTFILE_DW3	= bootfiles/bootfile_dw3
 BOOTFILE_40D	= bootfiles/bootfile_40d
 BOOTFILE_80D	= bootfiles/bootfile_80d
 BOOTFILE_40D_50HZ	= bootfiles/bootfile_40d_50hz
 BOOTFILE_80D_50HZ	= bootfiles/bootfile_80d_50hz
 KERNELFILE	= bootfiles/kernel_1773
 KERNELFILE_50HZ	= bootfiles/kernel_1773_50hz
+KERNELFILE_DW3	= bootfiles/kernel_dw3
 DIRS		= cmds modules defs sys bootfiles
 
 CMDS		= $(shell $(CD) cmds; make showobjs)
@@ -33,6 +35,8 @@
 SYSGO		= sysgo_dd
 
 PACKAGENAME	= $(DISTROVER).zip
+DSKDW3		= $(DISTROVER)_dw3.dsk
+LDSKDW3		= $(DISTRONAME)_dw3.dsk
 DSK360K_1	= $(DISTROVER)_40d_1.dsk
 LDSK360K_1	= $(DISTRONAME)_40d_1.dsk
 DSK360K_1_50HZ	= $(DISTROVER)_40d_1_50hz.dsk
@@ -60,21 +64,77 @@
 	$(foreach dir, $(DIRS), ($(CD) $(dir); make clean);)
 
 dskclean:
-	-$(RM) $(PACKAGENAME) $(DSK360K_1) $(LDSK360K_1) $(DSK360K_1_50HZ) \
-	 $(LDSK360K_1_50HZ) $(DSK360K_2) $(LDSK360K_2)  $(DSK720K) \
-	$(LDSK720K) $(DSK720K_50HZ) $(LDSK720K_50HZ)
+	-$(RM) $(PACKAGENAME) $(DSKDW3) $(DSK360K_1) $(LDSK360K_1) \
+	$(DSK360K_1_50HZ) $(LDSK360K_1_50HZ) \
+	$(DSK360K_2) $(LDSK360K_2) \
+	$(DSK720K) $(LDSK720K) $(DSK720K_50HZ) $(LDSK720K_50HZ)
 
 dsk: all $(PACKAGENAME)
 
 dskcopy: dsk
-	$(CP) $(DSK360K_1) $(DSK360K_1_50HZ) $(DSK360K_2) $(DSK720K) $(DSK720K_50HZ) $(PACKAGENAME) $(DSKDIR)
+	$(CP) $(DSKDW3) $(DSK360K_1) $(DSK360K_1_50HZ) $(DSK360K_2) $(DSK720K) $(DSK720K_50HZ) $(PACKAGENAME) $(DSKDIR)
 
 scp: dsk
 	scp $(PACKAGENAME) boisy@cvs.nitros9.org:/home/nitros9/public_html
 
-$(PACKAGENAME): $(DSK360K_1) $(DSK360K_1_50HZ) $(DSK360K_2) $(DSK720K) $(DSK720K_50HZ) ../../ReadMe ../../ChangeLog
+$(PACKAGENAME): $(DSKDW3) $(DSK360K_1) $(DSK360K_1_50HZ) $(DSK360K_2) $(DSK720K) $(DSK720K_50HZ) ../../ReadMe ../../ChangeLog
 	$(ARCHIVE) $@ $^
 
+$(DSKDW3):
+	-$(RM) $@
+	$(OS9FORMAT_DW3) -q $@ -n"NitrOS-9/$(CPU) Level 2"
+	$(OS9GEN) $@ -b=$(BOOTFILE_DW3) -t=$(KERNELFILE_DW3)
+	$(MAKDIR) $@,CMDS
+	$(MAKDIR) $@,SYS
+	$(MAKDIR) $@,DEFS
+	$(CP) modules/$(SYSGO) $@,sysgo
+	$(OS9ATTR_EXEC) $@,sysgo
+	$(CD) cmds; $(CP) $(CMDS) ../$@,CMDS
+	$(foreach file, $(CMDS), $(OS9ATTR_EXEC) $@,CMDS/$(file);)
+	$(CD) cmds; $(CP) $(CMDS_D2) ../$@,CMDS
+	$(foreach file, $(CMDS_D2), $(OS9ATTR_EXEC) $@,CMDS/$(file);)
+	$(CD) sys; $(CP) $(SYSBIN) ../$@,SYS
+	$(foreach file, $(SYSBIN), $(OS9ATTR_TEXT) $@,SYS/$(file);)
+	$(CD) sys; $(CPL) $(SYSTEXT) ../$@,SYS
+	$(foreach file, $(SYSTEXT), $(OS9ATTR_TEXT) $@,SYS/$(file);)
+	$(CD) defs; $(CPL) $(DEFS) ../$@,DEFS
+	$(foreach file, $(DEFS), $(OS9ATTR_TEXT) $@,DEFS/$(file);)
+	$(CPL) $(ROOTFILES) $@,.
+	$(foreach file, $(ROOTFILES), $(OS9ATTR_TEXT) $@,$(file);)
+	$(MAKDIR) $@,NITROS9
+	$(MAKDIR) $@,NITROS9/$(DISTRO)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/CMDS
+	$(CD) cmds; $(CP) $(MODULECMDS) ../$@,NITROS9/$(DISTRO)/CMDS
+	$(foreach file, $(MODULECMDS), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/CMDS/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/BOOTTRACK
+	$(CD) modules; $(CP) $(BOOTTRACK) ../$@,NITROS9/$(DISTRO)/MODULES/BOOTTRACK
+	$(foreach file, $(BOOTTRACK), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/BOOTTRACK/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/KERNEL
+	$(CD) modules; $(CP) $(KERNEL) ../$@,NITROS9/$(DISTRO)/MODULES/KERNEL
+	$(foreach file, $(KERNEL), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/KERNEL/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/SYSMODS
+	$(CD) modules; $(CP) $(SYSMODS) ../$@,NITROS9/$(DISTRO)/MODULES/SYSMODS
+	$(foreach file, $(SYSMODS), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/SYSMODS/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/CLOCKS
+	$(CD) modules; $(CP) $(CLOCKS) ../$@,NITROS9/$(DISTRO)/MODULES/CLOCKS
+	$(foreach file, $(CLOCKS), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/CLOCKS/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/RBF
+	$(CD) modules; $(CP) $(RBF) ../$@,NITROS9/$(DISTRO)/MODULES/RBF
+	$(foreach file, $(RBF), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/RBF/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/SCF
+	$(CD) modules; $(CP) $(SCF) ../$@,NITROS9/$(DISTRO)/MODULES/SCF
+	$(foreach file, $(SCF), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/SCF/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/PIPE
+	$(CD) modules; $(CP) $(PIPE) ../$@,NITROS9/$(DISTRO)/MODULES/PIPE
+	$(foreach file, $(PIPE), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/PIPE/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/BOOTLISTS
+	$(CD) bootlists; $(CPL) *.bl ../$@,NITROS9/$(DISTRO)/BOOTLISTS
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/SCRIPTS
+	$(CD) scripts; $(CPL) mb* ../$@,NITROS9/$(DISTRO)/SCRIPTS
+	$(RM) $(LDSKDW3)
+	$(SOFTLINK) $@ $(LDSKDW3)
+
 $(DSK360K_1):
 	-$(RM) $@
 	$(OS9FORMAT_DS40) -q $@ -n"NitrOS-9/$(CPU) Level 2 Disk 1"
--- a/level2/coco3/modules/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level2/coco3/modules/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -20,32 +20,34 @@
 TPB		= ../../3rdparty/booters
 
 BOOTERS		= boot_1773_6ms boot_1773_30ms \
-		 boot_burke boot_rampak boot_wd1002
+		 boot_burke boot_rampak boot_wd1002 boot_dw3
 BOOTTRACK	= rel_32 rel_40 rel_80 rel_32_50hz rel_40_50hz rel_80_50hz $(BOOTERS) krn
 KERNEL		= krnp2 krnp3_perr krnp4_regdump
 SYSMODS		= ioman init sysgo_h0 sysgo_dd
 CLOCKS          = clock_60hz clock_50hz \
 		clock2_elim clock2_disto2 clock2_disto4 clock2_bnb \
 		clock2_smart clock2_harris clock2_cloud9 clock2_soft \
-		clock2_jvemu clock2_messemu
+		clock2_jvemu clock2_messemu clock2_dw3
 
 RBF		= rbf.mn \
+		rbdw3.dr dw3.sb \
 		rb1773.dr rb1773_scii_ff74.dr rb1773_scii_ff58.dr \
 		d0_35s.dd d1_35s.dd d2_35s.dd d3_35s.dd \
 		d0_40d.dd d1_40d.dd d2_40d.dd d0_80d.dd \
 		d1_80d.dd d2_80d.dd \
 		ddd0_35s.dd ddd0_40d.dd ddd0_80d.dd \
 		rammer.dr r0_8k.dd r0_96k.dd r0_128k.dd r0_192k.dd \
-		ddr0_8k.dd ddr0_96k.dd ddr0_128k.dd ddr0_192k.dd md.dd
+		ddr0_8k.dd ddr0_96k.dd ddr0_128k.dd ddr0_192k.dd md.dd \
+		ddx0.dd x0.dd x1.dd x2.dd x3.dd
 		
 
 SCF		= scf.mn \
-		vtio.dr vrn.dr scbbp.dr scbbt.dr sspak.dr sc6551.dr \
+		vtio.dr vrn.dr scbbp.dr scbbt.dr scdwp.dr sspak.dr sc6551.dr \
 		cowin.io cogrf.io covdg.io covdg_small.io \
 		keydrv_cc3.sb snddrv_cc3.sb \
 		joydrv_joy.sb joydrv_6551L.sb joydrv_6552L.sb \
 		joydrv_6551M.sb joydrv_6552M.sb \
-		nil.dd p_scbbp.dd \
+		nil.dd p_scbbp.dd p_scdwp.dd \
 		t1_scbbt.dd t2_sc6551.dd t3_sc6551.dd \
 		ftdd.dd vi.dd ssp.dd term_scbbt.dt term_sc6551.dt \
 		term_vdg.dt term_win40.dt term_win80.dt w.dw w1.dw w2.dw \
@@ -188,6 +190,22 @@
 ddr0_192k.dd: r0.asm
 	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aRAMSize=192 -aDD=1
 
+# DriveWire 3 descriptors
+ddx0.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDD=1 -aDNum=0
+
+x0.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=0
+
+x1.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=1
+
+x2.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=2
+
+x3.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=3
+
 # VDGInt Modules
 covdg.io: covdg.asm
 	$(AS) $(AFLAGS) $(ASOUT)$@ $< -aCOCO2=1
--- a/level2/coco3_6309/bootfiles/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level2/coco3_6309/bootfiles/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -9,6 +9,24 @@
 
 KERNEL_1773	= $(MD)/rel_80 $(MD)/boot_1773_6ms $(MD)/krn
 KERNEL_1773_50HZ	= $(MD)/rel_80_50hz $(MD)/boot_1773_6ms $(MD)/krn
+KERNEL_DW3	= $(MD)/rel_80 $(MD)/boot_dw3 $(MD)/krn
+
+# NitrOS-9 disk bootfile to allow booting from DriveWire 3 server
+BOOTFILE_DW3	= $(MD)/krnp2 $(MD)/ioman $(MD)/init \
+		$(MD)/rbf.mn \
+		$(MD)/rbdw3.dr $(MD)/dw3.sb \
+		$(MD)/ddx0.dd $(MD)/x1.dd $(MD)/x2.dd $(MD)/x3.dd \
+		$(MD)/rb1773.dr $(MD)/d0_40d.dd $(MD)/d1_40d.dd \
+		$(MD)/d2_40d.dd $(MD)/ddd0_40d.dd \
+		$(MD)/scf.mn $(MD)/vtio.dr \
+		$(MD)/keydrv_cc3.sb $(MD)/joydrv_joy.sb $(MD)/snddrv_cc3.sb \
+		$(MD)/cowin.io $(MD)/covdg.io \
+		$(MD)/term_win80.dt \
+		$(MD)/w.dw $(MD)/w1.dw $(MD)/w2.dw $(MD)/w3.dw $(MD)/w4.dw \
+		$(MD)/w5.dw $(MD)/w6.dw $(MD)/w7.dw \
+		$(MD)/scdwp.dr $(MD)/p_scdwp.dd \
+		$(MD)/pipeman.mn $(MD)/piper.dr $(MD)/pipe.dd \
+		$(MD)/clock_60hz $(MD)/clock2_dw3
 
 # OS-9 disk bootfile to allow booting from WD1773 disk controller
 BOOTFILE_40D	= $(MD)/krnp2 $(MD)/ioman $(MD)/init \
@@ -63,8 +81,8 @@
 		$(MD)/pipeman.mn $(MD)/piper.dr $(MD)/pipe.dd \
 		$(MD)/clock_50hz $(MD)/clock2_soft
 
-BOOTFILES	= bootfile_40d bootfile_40d_50hz bootfile_80d bootfile_80d_50hz
-KERNELS		= kernel_1773 kernel_1773_50hz
+BOOTFILES	= bootfile_40d bootfile_40d_50hz bootfile_80d bootfile_80d_50hz bootfile_dw3
+KERNELS		= kernel_1773 kernel_1773_50hz kernel_dw3
 
 ALLOBJS		= $(BOOTFILES) $(KERNELS)
 
@@ -83,6 +101,9 @@
 bootfile_80d_50hz: $(BOOTFILE_80D_50HZ) $(DEPENDS)
 	$(MERGE) $(BOOTFILE_80D_50HZ)>$@
 
+bootfile_dw3: $(BOOTFILE_DW3) $(DEPENDS)
+	$(MERGE) $(BOOTFILE_DW3)>$@
+
 # Kernels
 kernel_1773: $(KERNEL_1773) $(DEPENDS)
 	$(MERGE) $(KERNEL_1773)>$@
@@ -90,6 +111,9 @@
 kernel_1773_50hz: $(KERNEL_1773_50HZ) $(DEPENDS)
 	$(MERGE) $(KERNEL_1773_50HZ)>$@
 
+kernel_dw3: $(KERNEL_DW3) $(DEPENDS)
+	$(MERGE) $(KERNEL_DW3)>$@
+
 clean:
 	$(RM) $(ALLOBJS)
 
--- a/level2/coco3_6309/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level2/coco3_6309/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -7,12 +7,14 @@
 DISTRO		= $(CPU)L$(LEVEL)
 DISTRONAME	= nos9$(CPU)l$(LEVEL)
 DISTROVER	= $(DISTRONAME)$(NITROS9VER)$(PORT)
+BOOTFILE_DW3	= bootfiles/bootfile_dw3
 BOOTFILE_40D	= bootfiles/bootfile_40d
 BOOTFILE_80D	= bootfiles/bootfile_80d
 BOOTFILE_40D_50HZ	= bootfiles/bootfile_40d_50hz
 BOOTFILE_80D_50HZ	= bootfiles/bootfile_80d_50hz
 KERNELFILE	= bootfiles/kernel_1773
 KERNELFILE_50HZ	= bootfiles/kernel_1773_50hz
+KERNELFILE_DW3	= bootfiles/kernel_dw3
 DIRS		= cmds modules defs sys bootfiles
 
 CMDS		= $(shell $(CD) cmds; make showobjs)
@@ -33,6 +35,8 @@
 SYSGO		= sysgo_dd
 
 PACKAGENAME	= $(DISTROVER).zip
+DSKDW3		= $(DISTROVER)_dw3.dsk
+LDSKDW3		= $(DISTRONAME)_dw3.dsk
 DSK360K_1	= $(DISTROVER)_40d_1.dsk
 LDSK360K_1	= $(DISTRONAME)_40d_1.dsk
 DSK360K_1_50HZ	= $(DISTROVER)_40d_1_50hz.dsk
@@ -60,21 +64,77 @@
 	$(foreach dir, $(DIRS), ($(CD) $(dir); make clean);)
 
 dskclean:
-	-$(RM) $(PACKAGENAME) $(DSK360K_1) $(LDSK360K_1) $(DSK360K_1_50HZ) \
-	 $(LDSK360K_1_50HZ) $(DSK360K_2) $(LDSK360K_2)  $(DSK720K) \
-	$(LDSK720K) $(DSK720K_50HZ) $(LDSK720K_50HZ)
+	-$(RM) $(PACKAGENAME) $(DSKDW3) $(DSK360K_1) $(LDSK360K_1) \
+	$(DSK360K_1_50HZ) $(LDSK360K_1_50HZ) \
+	$(DSK360K_2) $(LDSK360K_2) \
+	$(DSK720K) $(LDSK720K) $(DSK720K_50HZ) $(LDSK720K_50HZ)
 
 dsk: all $(PACKAGENAME)
 
 dskcopy: dsk
-	$(CP) $(DSK360K_1) $(DSK360K_1_50HZ) $(DSK360K_2) $(DSK720K) $(DSK720K_50HZ) $(PACKAGENAME) $(DSKDIR)
+	$(CP) $(DSKDW3) $(DSK360K_1) $(DSK360K_1_50HZ) $(DSK360K_2) $(DSK720K) $(DSK720K_50HZ) $(PACKAGENAME) $(DSKDIR)
 
 scp: dsk
 	scp $(PACKAGENAME) boisy@cvs.nitros9.org:/home/nitros9/public_html
 
-$(PACKAGENAME): $(DSK360K_1) $(DSK360K_1_50HZ) $(DSK360K_2) $(DSK720K) $(DSK720K_50HZ) ../../ReadMe ../../ChangeLog
+$(PACKAGENAME): $(DSKDW3) $(DSK360K_1) $(DSK360K_1_50HZ) $(DSK360K_2) $(DSK720K) $(DSK720K_50HZ) ../../ReadMe ../../ChangeLog
 	$(ARCHIVE) $@ $^
 
+$(DSKDW3):
+	-$(RM) $@
+	$(OS9FORMAT_DW3) -q $@ -n"NitrOS-9/$(CPU) Level 2"
+	$(OS9GEN) $@ -b=$(BOOTFILE_DW3) -t=$(KERNELFILE_DW3)
+	$(MAKDIR) $@,CMDS
+	$(MAKDIR) $@,SYS
+	$(MAKDIR) $@,DEFS
+	$(CP) modules/$(SYSGO) $@,sysgo
+	$(OS9ATTR_EXEC) $@,sysgo
+	$(CD) cmds; $(CP) $(CMDS) ../$@,CMDS
+	$(foreach file, $(CMDS), $(OS9ATTR_EXEC) $@,CMDS/$(file);)
+	$(CD) cmds; $(CP) $(CMDS_D2) ../$@,CMDS
+	$(foreach file, $(CMDS_D2), $(OS9ATTR_EXEC) $@,CMDS/$(file);)
+	$(CD) sys; $(CP) $(SYSBIN) ../$@,SYS
+	$(foreach file, $(SYSBIN), $(OS9ATTR_TEXT) $@,SYS/$(file);)
+	$(CD) sys; $(CPL) $(SYSTEXT) ../$@,SYS
+	$(foreach file, $(SYSTEXT), $(OS9ATTR_TEXT) $@,SYS/$(file);)
+	$(CD) defs; $(CPL) $(DEFS) ../$@,DEFS
+	$(foreach file, $(DEFS), $(OS9ATTR_TEXT) $@,DEFS/$(file);)
+	$(CPL) $(ROOTFILES) $@,.
+	$(foreach file, $(ROOTFILES), $(OS9ATTR_TEXT) $@,$(file);)
+	$(MAKDIR) $@,NITROS9
+	$(MAKDIR) $@,NITROS9/$(DISTRO)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/CMDS
+	$(CD) cmds; $(CP) $(MODULECMDS) ../$@,NITROS9/$(DISTRO)/CMDS
+	$(foreach file, $(MODULECMDS), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/CMDS/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/BOOTTRACK
+	$(CD) modules; $(CP) $(BOOTTRACK) ../$@,NITROS9/$(DISTRO)/MODULES/BOOTTRACK
+	$(foreach file, $(BOOTTRACK), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/BOOTTRACK/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/KERNEL
+	$(CD) modules; $(CP) $(KERNEL) ../$@,NITROS9/$(DISTRO)/MODULES/KERNEL
+	$(foreach file, $(KERNEL), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/KERNEL/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/SYSMODS
+	$(CD) modules; $(CP) $(SYSMODS) ../$@,NITROS9/$(DISTRO)/MODULES/SYSMODS
+	$(foreach file, $(SYSMODS), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/SYSMODS/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/CLOCKS
+	$(CD) modules; $(CP) $(CLOCKS) ../$@,NITROS9/$(DISTRO)/MODULES/CLOCKS
+	$(foreach file, $(CLOCKS), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/CLOCKS/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/RBF
+	$(CD) modules; $(CP) $(RBF) ../$@,NITROS9/$(DISTRO)/MODULES/RBF
+	$(foreach file, $(RBF), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/RBF/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/SCF
+	$(CD) modules; $(CP) $(SCF) ../$@,NITROS9/$(DISTRO)/MODULES/SCF
+	$(foreach file, $(SCF), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/SCF/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/MODULES/PIPE
+	$(CD) modules; $(CP) $(PIPE) ../$@,NITROS9/$(DISTRO)/MODULES/PIPE
+	$(foreach file, $(PIPE), $(OS9ATTR_EXEC) $@,NITROS9/$(DISTRO)/MODULES/PIPE/$(file);)
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/BOOTLISTS
+	$(CD) bootlists; $(CPL) *.bl ../$@,NITROS9/$(DISTRO)/BOOTLISTS
+	$(MAKDIR) $@,NITROS9/$(DISTRO)/SCRIPTS
+	$(CD) scripts; $(CPL) mb* ../$@,NITROS9/$(DISTRO)/SCRIPTS
+	$(RM) $(LDSKDW3)
+	$(SOFTLINK) $@ $(LDSKDW3)
+
 $(DSK360K_1):
 	-$(RM) $@
 	$(OS9FORMAT_DS40) -q $@ -n"NitrOS-9/$(CPU) Level 2 Disk 1"
--- a/level2/coco3_6309/modules/makefile	Mon Jan 12 01:32:08 2009 +0000
+++ b/level2/coco3_6309/modules/makefile	Sat Mar 07 20:04:42 2009 +0000
@@ -20,32 +20,34 @@
 TPB		= ../../3rdparty/booters
 
 BOOTERS		= boot_1773_6ms boot_1773_30ms \
-		 boot_burke boot_rampak boot_wd1002
+		 boot_burke boot_rampak boot_wd1002 boot_dw3
 BOOTTRACK	= rel_32 rel_40 rel_80 rel_32_50hz rel_40_50hz rel_80_50hz $(BOOTERS) krn
 KERNEL		= krnp2 krnp3_perr krnp4_regdump
 SYSMODS		= ioman init sysgo_h0 sysgo_dd
 CLOCKS          = clock_60hz clock_50hz \
 		clock2_elim clock2_disto2 clock2_disto4 clock2_bnb \
 		clock2_smart clock2_harris clock2_cloud9 clock2_soft \
-		clock2_jvemu clock2_messemu
+		clock2_jvemu clock2_messemu clock2_dw3
 
 RBF		= rbf.mn \
+		rbdw3.dr dw3.sb \
 		rb1773.dr rb1773_scii_ff74.dr rb1773_scii_ff58.dr \
 		d0_35s.dd d1_35s.dd d2_35s.dd d3_35s.dd \
 		d0_40d.dd d1_40d.dd d2_40d.dd d0_80d.dd \
 		d1_80d.dd d2_80d.dd \
 		ddd0_35s.dd ddd0_40d.dd ddd0_80d.dd \
 		rammer.dr r0_8k.dd r0_96k.dd r0_128k.dd r0_192k.dd \
-		ddr0_8k.dd ddr0_96k.dd ddr0_128k.dd ddr0_192k.dd md.dd
+		ddr0_8k.dd ddr0_96k.dd ddr0_128k.dd ddr0_192k.dd md.dd \
+		ddx0.dd x0.dd x1.dd x2.dd x3.dd
 		
 
 SCF		= scf.mn \
-		vtio.dr vrn.dr scbbp.dr scbbt.dr sspak.dr sc6551.dr \
+		vtio.dr vrn.dr scbbp.dr scbbt.dr scdwp.dr sspak.dr sc6551.dr \
 		cowin.io cogrf.io covdg.io covdg_small.io \
 		keydrv_cc3.sb snddrv_cc3.sb \
 		joydrv_joy.sb joydrv_6551L.sb joydrv_6552L.sb \
 		joydrv_6551M.sb joydrv_6552M.sb \
-		nil.dd p_scbbp.dd \
+		nil.dd p_scbbp.dd p_scdwp.dd \
 		t1_scbbt.dd t2_sc6551.dd t3_sc6551.dd \
 		ftdd.dd vi.dd ssp.dd term_scbbt.dt term_sc6551.dt \
 		term_vdg.dt term_win40.dt term_win80.dt w.dw w1.dw w2.dw \
@@ -188,6 +190,22 @@
 ddr0_192k.dd: r0.asm
 	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aRAMSize=192 -aDD=1
 
+# DriveWire 3 descriptors
+ddx0.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDD=1 -aDNum=0
+
+x0.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=0
+
+x1.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=1
+
+x2.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=2
+
+x3.dd: dwdesc.asm
+	$(AS) $< $(ASOUT)$@ $(AFLAGS) -aDNum=3
+
 # VDGInt Modules
 covdg.io: covdg.asm
 	$(AS) $(AFLAGS) $(ASOUT)$@ $< -aCOCO2=1
--- a/rules.mak	Mon Jan 12 01:32:08 2009 +0000
+++ b/rules.mak	Sat Mar 07 20:04:42 2009 +0000
@@ -75,6 +75,8 @@
 OS9FORMAT_SS80	= os9 format -t80 -ss -dd
 OS9FORMAT_DS40	= os9 format -t40 -ds -dd
 OS9FORMAT_DS80	= os9 format -t80 -ds -dd
+# DriveWire 3 format: 4096 256byte sectors (1,048,576 bytes)
+OS9FORMAT_DW3	= os9 format -l4096
 OS9GEN		= os9 gen
 OS9RENAME	= os9 rename
 OS9ATTR		= os9 attr -q