diff --git a/iocBoot/iocCygwin/Makefile b/iocBoot/iocCygwin/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d8c64f01033c035defca080ba3f8e63b71656afa
--- /dev/null
+++ b/iocBoot/iocCygwin/Makefile
@@ -0,0 +1,5 @@
+TOP = ../..
+include $(TOP)/configure/CONFIG
+ARCH = cygwin-x86
+TARGETS = envPaths
+include $(TOP)/configure/RULES.ioc
diff --git a/iocBoot/iocCygwin/asynRecord.substitutions b/iocBoot/iocCygwin/asynRecord.substitutions
new file mode 100644
index 0000000000000000000000000000000000000000..26fb52c4e6c0f5dc6d475b4264d71368d3175588
--- /dev/null
+++ b/iocBoot/iocCygwin/asynRecord.substitutions
@@ -0,0 +1,9 @@
+file "$(ASYN)/db/asynRecord.db"
+{
+pattern
+{P        R         PORT    ADDR    OMAX  IMAX}
+{xxx:     asyn_1   serial1    0     256  256}
+{xxx:     asyn_2   serial2    0     256  256}
+{xxx:     asyn_3   serial3    0     256  256}
+{xxx:     asyn_4   serial4    0     256  256}
+}
diff --git a/iocBoot/iocCygwin/auto_positions.req b/iocBoot/iocCygwin/auto_positions.req
new file mode 100644
index 0000000000000000000000000000000000000000..5e89c536b6f99aea3213faf4af534427df4b4ee6
--- /dev/null
+++ b/iocBoot/iocCygwin/auto_positions.req
@@ -0,0 +1,16 @@
+$(P)m1.OFF
+$(P)m1.DVAL
+$(P)m2.OFF
+$(P)m2.DVAL
+$(P)m3.OFF
+$(P)m3.DVAL
+$(P)m4.OFF
+$(P)m4.DVAL
+$(P)m5.OFF
+$(P)m5.DVAL
+$(P)m6.OFF
+$(P)m6.DVAL
+$(P)m7.OFF
+$(P)m7.DVAL
+$(P)m8.OFF
+$(P)m8.DVAL
diff --git a/iocBoot/iocCygwin/auto_settings.req b/iocBoot/iocCygwin/auto_settings.req
new file mode 100644
index 0000000000000000000000000000000000000000..5219a6dff6bd4f6cde2e0482de8ce366d48d221c
--- /dev/null
+++ b/iocBoot/iocCygwin/auto_settings.req
@@ -0,0 +1,52 @@
+file motor_settings.req P=$(P),M=m1
+file motor_settings.req P=$(P),M=m2
+file motor_settings.req P=$(P),M=m3
+file motor_settings.req P=$(P),M=m4
+
+file pseudoMotor_settings.req P=$(P),M=pm1
+file pseudoMotor_settings.req P=$(P),M=pm2
+file pseudoMotor_settings.req P=$(P),M=pm3
+file pseudoMotor_settings.req P=$(P),M=pm4
+
+file scanParms_settings.req P=$(P),M=m1
+file scanParms_settings.req P=$(P),M=m2
+file scanParms_settings.req P=$(P),M=m3
+file scanParms_settings.req P=$(P),M=m4
+
+#file table_settings.req P=$(P),T=table1,Q=table1
+
+file scan_settings.req P=$(P),S=scan1
+file scan_settings.req P=$(P),S=scan2
+file scan_settings.req P=$(P),S=scan3
+file scan_settings.req P=$(P),S=scan4
+file scan_settings.req P=$(P),S=scanH
+
+# Kohzu monochromator
+##$(P)BraggHAO.VAL
+##$(P)BraggKAO.VAL
+##$(P)BraggLAO.VAL
+##$(P)BraggAAO.VAL
+##$(P)BraggTypeMO.VAL
+##$(P)KohzuMode2MO.VAL
+##$(P)Kohzu_yOffsetAO.VAL
+
+file userCalcs10_settings.req P=$(P)
+file userCalcN_settings.req P=$(P),N=I_Detector
+
+file saveData_settings.req P=$(P)
+
+file userTransforms10_settings.req P=$(P)
+
+file userStringCalcs10_settings.req P=$(P)
+
+# string-sequence records
+file sseq_settings.req P=$(P),S=Sseq1
+file sseq_settings.req P=$(P),S=Sseq2
+file sseq_settings.req P=$(P),S=Sseq3
+
+
+# 4-step measurement
+file auto_4step_settings.req P=$(P),Q=4step
+
+file userAve10_settings.req P=$(P)
+
diff --git a/iocBoot/iocCygwin/motor.substitutions b/iocBoot/iocCygwin/motor.substitutions
new file mode 100644
index 0000000000000000000000000000000000000000..c8d5a44bfab5f25c657f08887d1daae4ad77571a
--- /dev/null
+++ b/iocBoot/iocCygwin/motor.substitutions
@@ -0,0 +1,12 @@
+file "$(MOTOR)/db/motor.db"
+{
+pattern
+{P,		N,	M,		DTYP,			C,	S,	DESC,			EGU,		DIR,	VELO,	VBAS,	ACCL,	BDST,	BVEL,	BACC,	MRES,	PREC,	DHLM,	DLLM,	INIT}
+{xxx:,	1,	m$(N),	"MM4000",	0,	0,	"motor $(N)",	degrees,        Pos,    10,             0.,             1.,             0,              1,              .2,             1e-3,   3,              100,    -100,   ""}
+{xxx:,  2,     m$(N),  "MM4000",       0,      1,      "motor $(N)",   degrees,        Pos,    60,             0.,             1.5,            0,              1,              .2,             1e-3,   3,              100,    -100,   ""}
+{xxx:,  3,     m$(N),  "MM4000",       0,      2,      "motor $(N)",   degrees,        Pos,    60,             0.,             1.,             0,              1,              .2,             1e-3,   3,              100,    -100,   ""}
+{xxx:,  4,     m$(N),  "ACS MCB-4B",   0,      0,      "motor $(N)",   steps,          Pos,    1000.,          1,              .2,             0,              1,              .2,             1,      1,              1e6,    -1e6,   ""}
+{xxx:,  5,     m$(N),  "ACS MCB-4B",   0,      1,      "motor $(N)",   degrees,        Pos,    1000.,          1,              .2,             0,              1,              .2,             1,      1,              100,    -100,   ""}
+{xxx:,  6,     m$(N),  "ACS MCB-4B",   0,      2,      "motor $(N)",   degrees,        Pos,    1000.,          1,              .2,             0,              1,              .2,             1,      1,              100,    -100,   ""}
+{xxx:,  7,     m$(N),  "ACS MCB-4B",   0,      3,      "motor $(N)",   degrees,        Pos,    1000.,          1,              .2,             0,              1,              .2,             1,      1,              100,    -100,   ""}
+}
diff --git a/iocBoot/iocCygwin/pid_slow.substitutions b/iocBoot/iocCygwin/pid_slow.substitutions
new file mode 100755
index 0000000000000000000000000000000000000000..08b309fe1a980c996e034da917d463f970245f8c
--- /dev/null
+++ b/iocBoot/iocCygwin/pid_slow.substitutions
@@ -0,0 +1,9 @@
+# This file demonstrates slow feedback.  The initial INP and OUT assume the first channel
+# of an IP330 ADC connected to the first channel of a DAC128V DAC.
+file "$(STD)/stdApp/Db/pid_control.db"
+{
+pattern
+{P,      PID,              INP,        OUT, LOPR,   HOPR,  DRVL, DRVH,  PREC,      KP,  KI,   KD,  SCAN}
+{xxx:,   pid_slow, xxx:IP330_1, xxx:DAC3_1,    0,    100,     0,    5,     3,     0.2,  3.,   0.,  ".1 second"}
+}
+
diff --git a/iocBoot/iocCygwin/pseudoMotor.substitutions b/iocBoot/iocCygwin/pseudoMotor.substitutions
new file mode 100644
index 0000000000000000000000000000000000000000..990409145cda0045c8ad170e23439febc5968429
--- /dev/null
+++ b/iocBoot/iocCygwin/pseudoMotor.substitutions
@@ -0,0 +1,25 @@
+# Pseudo-motors
+# Note: This databases will be in the next release of motor, not in xxxApp
+
+# This is a simple example using the sumDiff2D database.  This takes 2 real motors and makes 2 soft motors,
+# SUM which moves both motors together, and DIFF which moves them in opposite directions.
+# It can be used for slits, for K/B mirror benders, etc.
+
+file "$(XXX)/xxxApp/Db/pseudoMotor.db"
+{
+pattern
+{P,       M,           DINP,                        OUT,                     RDBL,                          STOO,     DESC, EGU, DIR, VELO, VBAS, ACCL, BDST, BVEL,                    BACC, MRES,   RRES, PREC,  DHLM, DLLM}
+{xxx:,  pm1, "xxx:KBV:Done NPP NMS", "xxx:pm1DVAL.VAL PP MS", "xxx:KBV:Readback.G NPP NMS", "xxx:KBV:Stop PP MS",    "Vert. curvature",          mm,  Pos,   1,    .1,   .1,    0,    1,   .1, .1,     1.0,  3,    10000, -10000}
+{xxx:,  pm2, "xxx:KBV:Done NPP NMS", "xxx:pm2DVAL.VAL PP MS", "xxx:KBV:Readback.H NPP NMS", "xxx:KBV:Stop PP MS",    "Vert. Ellipticity",        mm,  Pos,   1,    .1,   .1,    0,    1,   .1, .1,     1.0,  3,    10000, -10000}
+{xxx:,  pm3, "xxx:KBH:Done NPP NMS", "xxx:pm3DVAL.VAL PP MS", "xxx:KBH:Readback.G NPP NMS", "xxx:KBH:Stop PP MS",    "Hor. curvature",          mm,  Pos,   1,    .1,   .1,    0,    1,   .1, .1,     1.0,  3,    10000, -10000}
+{xxx:,  pm4, "xxx:KBH:Done NPP NMS", "xxx:pm4DVAL.VAL PP MS", "xxx:KBH:Readback.H NPP NMS", "xxx:KBH:Stop PP MS",    "Hor. ellipticity",        mm,  Pos,   1,    .1,   .1,    0,    1,   .1, .1,     1.0,  3,    10000, -10000}
+}
+
+file "$(XXX)/xxxApp/Db/sumDiff2D.db"
+{
+pattern
+{P,      T,   SUM, DIFF,     M1DRV,    M1RBV,   M2DRV,   M2RBV,   M1STOP,   M1DONE,   M2STOP,   M2DONE,  PREC}
+{xxx:, KBV:,  pm1,  pm2,    m1.VAL,   m1.RBV,  m2.VAL,  m2.RBV,  m1.STOP,  m1.DMOV,  m2.STOP,  m2.DMOV,    1}
+{xxx:, KBH:,  pm3,  pm4,    m3.VAL,   m3.RBV,  m4.VAL,  m4.RBV,  m3.STOP,  m3.DMOV,  m4.STOP,  m4.DMOV,    1}
+}
+
diff --git a/iocBoot/iocCygwin/run b/iocBoot/iocCygwin/run
new file mode 100755
index 0000000000000000000000000000000000000000..04a16515c8efa695e2fedb568dc8460d51fcb5b1
--- /dev/null
+++ b/iocBoot/iocCygwin/run
@@ -0,0 +1 @@
+../../bin/cygwin-x86/xxx.exe st.cmd
diff --git a/iocBoot/iocCygwin/saveData.req b/iocBoot/iocCygwin/saveData.req
new file mode 100644
index 0000000000000000000000000000000000000000..6eaff4e171705167bd1c68f42c9db0cfcf4dc2c6
--- /dev/null
+++ b/iocBoot/iocCygwin/saveData.req
@@ -0,0 +1,40 @@
+[prefix]
+$(P)
+
+[status]
+$(P)saveData_status
+
+[message]
+$(P)saveData_message
+
+[filename]
+$(P)saveData_fileName
+
+[counter]	# scan counter
+$(P)saveData_scanNumber
+
+[fileSystem] # scan file system
+$(P)saveData_fileSystem
+
+[subdir]	# scan file subdirectory
+$(P)saveData_subDir
+
+[fullPathName]
+$(P)saveData_fullPathName
+
+[realTime1D] # if nonzero, write 1D data as it comes in
+$(P)saveData_realTime1D
+
+[scanRecord]	# specify scan records to be monitored
+$(P)scanH
+$(P)scan1
+$(P)scan2
+$(P)scan3
+$(P)scan4
+
+[extraPV]
+$(P)userCalc1.CALC	"string"
+$(P)saveData_realTime1D "enum"
+$(P)saveData_scanNumber	"long"
+$(P)saveData_fileSystem	"filesystem"
+$(P)scan1.P1SM		"scan mode"
diff --git a/iocBoot/iocCygwin/save_restore.cmd b/iocBoot/iocCygwin/save_restore.cmd
new file mode 100644
index 0000000000000000000000000000000000000000..57d62fa0867e6560920d1747a070750966b7dc24
--- /dev/null
+++ b/iocBoot/iocCygwin/save_restore.cmd
@@ -0,0 +1,57 @@
+### save_restore setup
+#
+# The rest this file does not require modification for standard use, but...
+# If you want save_restore to manage its own NFS mount, specify the name and
+# IP address of the file server to which save files should be written.
+# This currently is supported only on vxWorks.
+#save_restoreSet_NFSHost("oxygen", "164.54.52.4")
+
+# status-PV prefix
+save_restoreSet_status_prefix("xxx:")
+# Debug-output level
+save_restoreSet_Debug(0)
+
+# Ok to save/restore save sets with missing values (no CA connection to PV)?
+save_restoreSet_IncompleteSetsOk(1)
+# Save dated backup files?
+save_restoreSet_DatedBackupFiles(1)
+
+# Number of sequenced backup files to write
+save_restoreSet_NumSeqFiles(3)
+# Time interval between sequenced backups
+save_restoreSet_SeqPeriodInSeconds(300)
+
+# specify where save files should be
+set_savefile_path("$(STARTUP)", "autosave")
+
+# specify what save files should be restored.  Note these files must be
+# in the directory specified in set_savefile_path(), or, if that function
+# has not been called, from the directory current when iocInit is invoked
+set_pass0_restoreFile("auto_positions.sav")
+set_pass0_restoreFile("auto_settings.sav")
+set_pass1_restoreFile("auto_settings.sav")
+
+# specify directories in which to to search for included request files
+# Note cdCommands defines 'startup', but envPaths does not
+set_requestfile_path("$(STARTUP)", "")
+set_requestfile_path("$(STARTUP)", "autosave")
+set_requestfile_path("$(TOP)", "xxxApp/Db")
+set_requestfile_path("$(AUTOSAVE)", "asApp/Db")
+set_requestfile_path("$(CALC)", "calcApp/Db")
+#set_requestfile_path("$(CAMAC)", "camacApp/Db")
+set_requestfile_path("$(CCD)", "ccdApp/Db")
+set_requestfile_path("$(DAC128V)", "dac128VApp/Db")
+set_requestfile_path("$(DXP)", "dxpApp/Db")
+set_requestfile_path("$(IP)", "ipApp/Db")
+set_requestfile_path("$(IP330)", "ip330App/Db")
+set_requestfile_path("$(IPUNIDIG)", "ipUnidigApp/Db")
+#set_requestfile_path("$(LOVE)", "loveApp/Db")
+set_requestfile_path("$(MCA)", "mcaApp/Db")
+set_requestfile_path("$(MOTOR)", "motorApp/Db")
+set_requestfile_path("$(OPTICS)", "opticsApp/Db")
+set_requestfile_path("$(QUADEM)", "quadEMApp/Db")
+set_requestfile_path("$(SSCAN)", "sscanApp/Db")
+set_requestfile_path("$(STD)", "stdApp/Db")
+set_requestfile_path("$(VME)", "vmeApp/Db")
+
+dbLoadRecords("$(AUTOSAVE)/asApp/Db/save_restoreStatus.db", "P=xxx:")
diff --git a/iocBoot/iocCygwin/scanParms.substitutions b/iocBoot/iocCygwin/scanParms.substitutions
new file mode 100644
index 0000000000000000000000000000000000000000..cfe432b88291e917e8b9a8a6b493e024bf2a8d78
--- /dev/null
+++ b/iocBoot/iocCygwin/scanParms.substitutions
@@ -0,0 +1,46 @@
+file "$(SSCAN)/sscanApp/Db/scanParms.db"
+{
+{P=xxx:,SCANREC=xxx:scan1,Q=m1,POS=$(Q).VAL,RDBK=$(Q).RBV}
+{P=xxx:,SCANREC=xxx:scan1,Q=m2,POS=$(Q).VAL,RDBK=$(Q).RBV}
+{P=xxx:,SCANREC=xxx:scan1,Q=m3,POS=$(Q).VAL,RDBK=$(Q).RBV}
+{P=xxx:,SCANREC=xxx:scan1,Q=m4,POS=$(Q).VAL,RDBK=$(Q).RBV}
+{P=xxx:,SCANREC=xxx:scan1,Q=m5,POS=$(Q).VAL,RDBK=$(Q).RBV}
+{P=xxx:,SCANREC=xxx:scan1,Q=m6,POS=$(Q).VAL,RDBK=$(Q).RBV}
+{P=xxx:,SCANREC=xxx:scan1,Q=m7,POS=$(Q).VAL,RDBK=$(Q).RBV}
+{P=xxx:,SCANREC=xxx:scan1,Q=m8,POS=$(Q).VAL,RDBK=$(Q).RBV}
+
+{P=xxx:,SCANREC=xxx:scan1,Q=Table1X,POS=table1.X,RDBK=table1.XRB}
+{P=xxx:,SCANREC=xxx:scan1,Q=Table1Y,POS=table1.Y,RDBK=table1.YRB}
+{P=xxx:,SCANREC=xxx:scan1,Q=Table1Z,POS=table1.Z,RDBK=table1.ZRB}
+{P=xxx:,SCANREC=xxx:scan1,Q=Table1AX,POS=table1.AX,RDBK=table1.AXRB}
+{P=xxx:,SCANREC=xxx:scan1,Q=Table1AY,POS=table1.AY,RDBK=table1.AYRB}
+{P=xxx:,SCANREC=xxx:scan1,Q=Table1AZ,POS=table1.AZ,RDBK=table1.AZRB}
+
+#{P=xxx:,SCANREC=xxx:scan1,Q=BraggE,POS=BraggEAO.VAL,RDBK=BraggERdbkAO.VAL}
+#{P=xxx:,SCANREC=xxx:scan1,Q=BraggLambda,POS=BraggLambdaAO.VAL,RDBK=BraggLambdaRdbkAO.VAL}
+#{P=xxx:,SCANREC=xxx:scan1,Q=BraggTheta,POS=BraggThetaAO.VAL,RDBK=BraggThetaRdbkAO.VAL}
+
+#{P=xxx:,SCANREC=xxx:scan1,Q=HR1_E,POS=HR1_EAO.VAL,RDBK=HR1_ERdbkAO}
+#{P=xxx:,SCANREC=xxx:scan1,Q=HR1_A,POS=HR1_worldOffAO.VAL,RDBK=HR1_worldOffAO.VAL}
+
+# old slit
+{P=xxx:,SCANREC=xxx:scan1,Q=Slit1Hp,POS=Slit1Hxp.VAL,RDBK=Slit1Ht2.A}
+{P=xxx:,SCANREC=xxx:scan1,Q=Slit1Hn,POS=Slit1Hxn.VAL,RDBK=Slit1Ht2.B}
+{P=xxx:,SCANREC=xxx:scan1,Q=Slit1Hsize,POS=Slit1Hsize.VAL,RDBK=Slit1Ht2.C}
+{P=xxx:,SCANREC=xxx:scan1,Q=Slit1Hcenter,POS=Slit1Hcenter.VAL,RDBK=Slit1Ht2.D}
+{P=xxx:,SCANREC=xxx:scan1,Q=Slit1Vp,POS=Slit1Vxp.VAL,RDBK=Slit1Vt2.A}
+{P=xxx:,SCANREC=xxx:scan1,Q=Slit1Vn,POS=Slit1Vxn.VAL,RDBK=Slit1Vt2.B}
+{P=xxx:,SCANREC=xxx:scan1,Q=Slit1Vsize,POS=Slit1Vsize.VAL,RDBK=Slit1Vt2.C}
+{P=xxx:,SCANREC=xxx:scan1,Q=Slit1Vcenter,POS=Slit1Vcenter.VAL,RDBK=Slit1Vt2.D}
+
+# new soft-motor-based slit
+#{P=xxx:,SCANREC=xxx:scan1,Q=Slit2Hxn,POS=$(Q).VAL,RDBK=$(Q).RBV}
+#{P=xxx:,SCANREC=xxx:scan1,Q=Slit2Hxp,POS=$(Q).VAL,RDBK=$(Q).RBV}
+#{P=xxx:,SCANREC=xxx:scan1,Q=Slit2Hsize,POS=$(Q).VAL,RDBK=$(Q).RBV}
+#{P=xxx:,SCANREC=xxx:scan1,Q=Slit2Hcenter,POS=$(Q).VAL,RDBK=$(Q).RBV}
+#{P=xxx:,SCANREC=xxx:scan1,Q=Slit2Vxn,POS=$(Q).VAL,RDBK=$(Q).RBV}
+#{P=xxx:,SCANREC=xxx:scan1,Q=Slit2Vxp,POS=$(Q).VAL,RDBK=$(Q).RBV}
+#{P=xxx:,SCANREC=xxx:scan1,Q=Slit2Vsize,POS=$(Q).VAL,RDBK=$(Q).RBV}
+#{P=xxx:,SCANREC=xxx:scan1,Q=Slit2Vcenter,POS=$(Q).VAL,RDBK=$(Q).RBV}
+
+}
diff --git a/iocBoot/iocCygwin/serial.cmd b/iocBoot/iocCygwin/serial.cmd
new file mode 100644
index 0000000000000000000000000000000000000000..55dc38885b7f45327719cc13821d6fee55d0a6d7
--- /dev/null
+++ b/iocBoot/iocCygwin/serial.cmd
@@ -0,0 +1,149 @@
+
+# BEGIN serial.cmd ------------------------------------------------------------
+
+# Set up 2 local serial ports
+
+# serial 1 connected to Keithley2K DMM at 19200 baud
+#drvAsynSerialPortConfigure("portName","ttyName",priority,noAutoConnect,
+#                            noProcessEos)
+drvAsynSerialPortConfigure("serial1", "/dev/ttyS0", 0, 0, 0)
+asynSetOption(serial1,0,baud,19200)
+asynSetOption(serial1,0,parity,none)
+#asynOctetSetInputEos(const char *portName, int addr,
+#                     const char *eosin,const char *drvInfo)
+asynOctetSetInputEos("serial1",0,"\r\n")
+# asynOctetSetOutputEos(const char *portName, int addr,
+#                       const char *eosin,const char *drvInfo)
+asynOctetSetOutputEos("serial1",0,"\r")
+# Make port available from the iocsh command line
+#asynOctetConnect(const char *entry, const char *port, int addr,
+#                 int timeout, int buffer_len, const char *drvInfo)
+asynOctetConnect("serial1", "serial1")
+
+# serial 2 connected to Newport MM4000 at 38400 baud
+drvAsynSerialPortConfigure("serial2", "/dev/ttyS1", 0, 0, 0)
+asynSetOption(serial2,0,baud,38400)
+asynSetOption(serial2,0,parity,none)
+asynOctetConnect("serial2", "serial2")
+asynOctetSetInputEos("serial2",0,"\r")
+asynOctetSetOutputEos("serial2",0,"\r")
+
+# Set up ports 1 and 2 on Moxa box
+
+# serial 3 is connected to the ACS MCB-4B at 9600 baud
+#drvAsynIPPortConfigure("portName","hostInfo",priority,noAutoConnect,
+#                        noProcessEos)
+drvAsynIPPortConfigure("serial3", "164.54.160.50:4001", 0, 0, 0)
+asynOctetConnect("serial3", "serial3")
+asynOctetSetInputEos("serial3",0,"\r")
+asynOctetSetOutputEos("serial3",0,"\r")
+
+# serial 4 not connected for now
+drvAsynIPPortConfigure("serial4", "164.54.160.50:4002", 0, 0, 0)
+asynOctetConnect("serial4", "serial4")
+asynOctetSetInputEos("serial4",0,"\r")
+asynOctetSetOutputEos("serial4",0,"\r")
+
+# Newport MM4000 driver setup parameters:
+#     (1) maximum # of controllers,
+#     (2) motor task polling rate (min=1Hz, max=60Hz)
+MM4000Setup(1, 10)
+
+# Newport MM4000 driver configuration parameters:
+#     (1) controller
+#     (2) asyn port name (e.g. serial1 or gpib1)
+#     (3) GPIB address (0 for serial)
+MM4000Config(0, "serial2", 0)
+
+# Newport PM500 driver setup parameters:
+#     (1) maximum number of controllers in system
+#     (2) motor task polling rate (min=1Hz,max=60Hz)
+#PM500Setup(1, 10)
+
+# Newport PM500 configuration parameters:
+#     (1) controller
+#     (2) asyn port name (e.g. serial1 or gpib1)
+#PM500Config(0, "serial3")
+
+# McClennan PM304 driver setup parameters:
+#     (1) maximum number of controllers in system
+#     (2) motor task polling rate (min=1Hz, max=60Hz)
+#PM304Setup(1, 10)
+
+# McClennan PM304 driver configuration parameters:
+#     (1) controller being configured
+#     (2) MPF serial server name (string)
+#     (3) Number of axes on this controller
+#PM304Config(0, "serial4", 1)
+
+# ACS MCB-4B driver setup parameters:
+#     (1) maximum number of controllers in system
+#     (2) motor task polling rate (min=1Hz, max=60Hz)
+MCB4BSetup(1, 10)
+
+# ACS MCB-4B driver configuration parameters:
+#     (1) controller being configured
+#     (2) asyn port name (string)
+MCB4BConfig(0, "serial3")
+
+##### Pico Motors (Ernest Williams MHATT-CAT)
+##### Motors (see picMot.substitutions in same directory as this file) ####
+#dbLoadTemplate("picMot.substitutions")
+
+# Load asynRecord records on all ports
+dbLoadTemplate("asynRecord.substitutions")
+
+# send impromptu message to serial device, parse reply
+# (was serial_OI_block)
+dbLoadRecords("$(IP)/ipApp/Db/deviceCmdReply.db","P=xxx:,N=1,PORT=serial1,ADDR=0,OMAX=100,IMAX=100")
+dbLoadRecords("$(IP)/ipApp/Db/deviceCmdReply.db","P=xxx:,N=2,PORT=serial2,ADDR=0,OMAX=100,IMAX=100")
+dbLoadRecords("$(IP)/ipApp/Db/deviceCmdReply.db","P=xxx:,N=3,PORT=serial3,ADDR=0,OMAX=100,IMAX=100")
+
+# Stanford Research Systems SR570 Current Preamplifier
+#dbLoadRecords("$(IP)/ipApp/Db/SR570.db", "P=xxx:,A=A1,PORT=serial1")
+
+# Lakeshore DRC-93CA Temperature Controller
+#dbLoadRecords("$(IP)/ipApp/Db/LakeShoreDRC-93CA.db", "P=xxx:,Q=TC1,PORT=serial4")
+
+# Huber DMC9200 DC Motor Controller
+#dbLoadRecords("$(IP)/ipApp/Db/HuberDMC9200.db", "P=xxx:,Q=DMC1:,PORT=serial5")
+
+# Oriel 18011 Encoder Mike
+#dbLoadRecords("$(IP)/ipApp/Db/eMike.db", "P=xxx:,M=em1,PORT=serial3")
+
+# Keithley 2000 DMM
+dbLoadRecords("$(IP)/ipApp/Db/Keithley2kDMM_mf.db","P=xxx:,Dmm=D1,PORT=serial1")
+
+# Oxford Cyberstar X1000 Scintillation detector and pulse processing unit
+#dbLoadRecords("$(IP)/ipApp/Db/Oxford_X1k.db","P=xxx:,S=s1,PORT=serial4")
+
+# Oxford ILM202 Cryogen Level Meter (Serial)
+#dbLoadRecords("$(IP)/ipApp/Db/Oxford_ILM202.db","P=xxx:,S=s1,PORT=serial5")
+
+# Elcomat autocollimator
+#dbLoadRecords("$(IP)/ipApp/Db/Elcomat.db", "P=xxx:,PORT=serial8")
+
+# Eurotherm temp controller
+#dbLoadRecords("$(IP)/ipApp/Db/Eurotherm.db","P=xxx:,PORT=serial7")
+
+# MKS vacuum gauges
+#dbLoadRecords("$(IP)/ipApp/Db/MKS.db","P=xxx:,PORT=serial2,CC1=cc1,CC2=cc3,PR1=pr1,PR2=pr3")
+
+# PI Digitel 500/1500 pump
+#dbLoadRecords("$(IP)/ipApp/Db/Digitel.db","xxx:,PUMP=ip1,PORT=serial3")
+
+# PI MPC ion pump
+#dbLoadRecords("$(IP)/ipApp/Db/MPC.db","P=xxx:,PUMP=ip2,PORT=serial4,PA=0,PN=1")
+
+# PI MPC TSP (titanium sublimation pump)
+#dbLoadRecords("$(IP)/ipApp/Db/TSP.db","P=xxx:,TSP=tsp1,PORT=serial4,PA=0")
+
+# Heidenhain ND261 encoder (for PSL monochromator)
+#dbLoadRecords("$(IP)/ipApp/Db/heidND261.db", "P=xxx:,PORT=serial1")
+
+# Love Controllers
+#devLoveDebug=1
+#loveServerDebug=1
+#dbLoadRecords("$(IP)/ipApp/Db/love.db", "P=xxx:,Q=Love_0,C=0,PORT=PORT2,ADDR=1")
+
+# END serial.cmd --------------------------------------------------------------
diff --git a/iocBoot/iocCygwin/softMotor.substitutions b/iocBoot/iocCygwin/softMotor.substitutions
new file mode 100644
index 0000000000000000000000000000000000000000..988001da4f3a26428b16081b6c1bca356a034f0a
--- /dev/null
+++ b/iocBoot/iocCygwin/softMotor.substitutions
@@ -0,0 +1,15 @@
+file "$(STD)/stdApp/Db/softMotor.db"
+{
+pattern
+{P,		SM}
+{xxx:,	SM1}
+{xxx:,	SM2}
+{xxx:,	SM3}
+{xxx:,	SM4}
+{xxx:,	SM5}
+{xxx:,	SM6}
+{xxx:,	SM7}
+{xxx:,	SM8}
+{xxx:,	SM9}
+{xxx:,	SM10}
+}
diff --git a/iocBoot/iocCygwin/st.cmd b/iocBoot/iocCygwin/st.cmd
new file mode 100644
index 0000000000000000000000000000000000000000..e895a94d4f55fc7290ff2412174bf7ab71efee42
--- /dev/null
+++ b/iocBoot/iocCygwin/st.cmd
@@ -0,0 +1,172 @@
+# Cygwin startup script
+
+< envPaths
+
+# save_restore.cmd needs the full path to the startup directory, which
+# envPaths currently does not provide
+epicsEnvSet(STARTUP,$(TOP)/iocBoot/$(IOC))
+
+# Increase size of buffer for error logging from default 1256
+errlogInit(20000)
+
+# Specify largest array CA will transport
+# Note for N sscanRecord data points, need (N+1)*8 bytes, else MEDM
+# plot doesn't display
+epicsEnvSet EPICS_CA_MAX_ARRAY_BYTES 64008
+
+################################################################################
+# Tell EPICS all about the record types, device-support modules, drivers,
+# etc. in the software we just loaded (xxx.munch)
+dbLoadDatabase("../../dbd/iocxxx.dbd")
+iocxxxCygwin_registerRecordDeviceDriver(pdbbase)
+
+### save_restore setup
+# We presume a suitable initHook routine was compiled into xxx.munch.
+# See also create_monitor_set(), after iocInit() .
+< save_restore.cmd
+
+# serial support
+< serial.cmd
+
+# Motors
+#dbLoadTemplate("basic_motor.substitutions")
+dbLoadTemplate("motor.substitutions")
+dbLoadTemplate("softMotor.substitutions")
+dbLoadTemplate("pseudoMotor.substitutions")
+
+### Allstop, alldone
+# This database must agree with the motors and other positioners you've actually loaded.
+# Several versions (e.g., all_com_32.db) are in stdApp/Db
+dbLoadRecords("$(STD)/stdApp/Db/all_com_16.db","P=xxx:")
+
+### Insertion-device control
+#dbLoadRecords("$(STD)/stdApp/Db/IDctrl.db","P=xxx:,xx=02us")
+
+# sample-wheel
+dbLoadRecords("$(STD)/stdApp/Db/sampleWheel.db", "P=xxx:,ROWMOTOR=xxx:m7,ANGLEMOTOR=xxx:m8")
+
+### Scan-support software
+# crate-resident scan.  This executes 1D, 2D, 3D, and 4D scans, and caches
+# 1D data, but it doesn't store anything to disk.  (See 'saveData' below for that.)
+dbLoadRecords("$(SSCAN)/sscanApp/Db/scan.db","P=xxx:,MAXPTS1=8000,MAXPTS2=1000,MAXPTS3=10,MAXPTS4=10,MAXPTSH=8000")
+
+# A set of scan parameters for each positioner.  This is a convenience
+# for the user.  It can contain an entry for each scannable thing in the
+# crate.
+dbLoadTemplate("scanParms.substitutions")
+
+### Slits
+dbLoadRecords("$(OPTICS)/opticsApp/Db/2slit.db","P=xxx:,SLIT=Slit1V,mXp=m3,mXn=m4")
+dbLoadRecords("$(OPTICS)/opticsApp/Db/2slit.db","P=xxx:,SLIT=Slit1H,mXp=m5,mXn=m6")
+
+# under development...
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/2slit_soft.db","P=xxx:,SLIT=Slit2V,mXp=m13,mXn=m14")
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/2slit_soft.db","P=xxx:,SLIT=Slit2H,mXp=m15,mXn=m16")
+
+# X-ray Instrumentation Associates Huber Slit Controller
+# supported by a customized version of the SNL program written by Pete Jemian
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/xia_slit.db", "P=xxx:, HSC=hsc1:")
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/xia_slit.db", "P=xxx:, HSC=hsc2:")
+#dbLoadRecords("$(IP)/ipApp/Db/generic_serial.db", "P=xxx:,C=0,SERVER=serial7")
+
+
+### 2-post mirror
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/2postMirror.db","P=xxx:,Q=M1,mDn=m18,mUp=m17,LENGTH=0.3")
+
+### User filters
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/filterMotor.db","P=xxx:,Q=fltr1:,MOTOR=m1,LOCK=fltr_1_2:")
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/filterMotor.db","P=xxx:,Q=fltr2:,MOTOR=m2,LOCK=fltr_1_2:")
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/filterLock.db","P=xxx:,Q=fltr2:,LOCK=fltr_1_2:,LOCK_PV=xxx:DAC1_1.VAL")
+
+### Optical tables
+#tableRecordDebug=1
+dbLoadRecords("$(OPTICS)/opticsApp/Db/table.db","P=xxx:,Q=Table1,T=table1,M0X=m1,M0Y=m2,M1Y=m3,M2X=m4,M2Y=m5,M2Z=m6,GEOM=SRI")
+
+### Monochromator support ###
+# Kohzu and PSL monochromators: Bragg and theta/Y/Z motors
+# standard geometry (geometry 1)
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/kohzuSeq.db","P=xxx:,M_THETA=m9,M_Y=m10,M_Z=m11,yOffLo=17.4999,yOffHi=17.5001")
+# modified geometry (geometry 2)
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/kohzuSeq.db","P=xxx:,M_THETA=m9,M_Y=m10,M_Z=m11,yOffLo=4,yOffHi=36")
+
+# Spherical grating monochromator
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/SGM.db","P=xxx:,N=1,M_x=m7,M_rIn=m6,M_rOut=m8,M_g=m9")
+
+# 4-bounce high-resolution monochromator
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/hrSeq.db","P=xxx:,N=1,M_PHI1=m9,M_PHI2=m10")
+#dbLoadRecords("$(OPTICS)/opticsApp/Db/hrSeq.db","P=xxx:,N=2,M_PHI1=m11,M_PHI2=m12")
+
+# Load single element Canberra AIM MCA and ICB modules
+#< canberra_1.cmd
+
+# Load 13 element detector software
+#< canberra_13.cmd
+
+# Load 3 element detector software
+#< canberra_3.cmd
+
+### Stuff for user programming ###
+dbLoadRecords("$(CALC)/calcApp/Db/userCalcs10.db","P=xxx:")
+dbLoadRecords("$(CALC)/calcApp/Db/userCalcOuts10.db","P=xxx:")
+dbLoadRecords("$(CALC)/calcApp/Db/userStringCalcs10.db","P=xxx:")
+dbLoadRecords("$(CALC)/calcApp/Db/userTransforms10.db","P=xxx:")
+# extra userCalcs (must also load userCalcs10.db for the enable switch)
+dbLoadRecords("$(CALC)/calcApp/Db/userCalcN.db","P=xxx:,N=I_Detector")
+dbLoadRecords("$(CALC)/calcApp/Db/userAve10.db","P=xxx:")
+# string sequence (sseq) record
+dbLoadRecords("$(STD)/stdApp/Db/yySseq.db","P=xxx:,S=Sseq1")
+dbLoadRecords("$(STD)/stdApp/Db/yySseq.db","P=xxx:,S=Sseq2")
+dbLoadRecords("$(STD)/stdApp/Db/yySseq.db","P=xxx:,S=Sseq3")
+# 4-step measurement
+dbLoadRecords("$(STD)/stdApp/Db/4step.db", "P=xxx:")
+# interpolation
+dbLoadRecords("$(CALC)/calcApp/Db/interp.db", "P=xxx:,N=2000")
+# array test
+dbLoadRecords("$(CALC)/calcApp/Db/arrayTest.db", "P=xxx:,N=2000")
+
+# Slow feedback
+dbLoadTemplate "pid_slow.substitutions"
+
+# Miscellaneous PV's, such as burtResult
+dbLoadRecords("$(STD)/stdApp/Db/misc.db","P=xxx:")
+#dbLoadRecords("$(STD)/stdApp/Db/VXstats.db","P=xxx:")
+
+### Queensgate piezo driver
+#dbLoadRecords("$(IP)/ipApp/Db/pzt_3id.db","P=xxx:")
+#dbLoadRecords("$(IP)/ipApp/Db/pzt.db","P=xxx:")
+
+### Queensgate Nano2k piezo controller
+#dbLoadRecords("$(STD)/stdApp/Db/Nano2k.db","P=xxx:,S=s1")
+
+###############################################################################
+iocInit
+
+### startup State Notation Language programs
+#seq &kohzuCtl, "P=xxx:, M_THETA=m9, M_Y=m10, M_Z=m11, GEOM=1, logfile=kohzuCtl.log"
+#seq &hrCtl, "P=xxx:, N=1, M_PHI1=m9, M_PHI2=m10, logfile=hrCtl1.log"
+
+# Keithley 2000 series DMM
+# channels: 10, 20, or 22;  model: 2000 or 2700
+seq &Keithley2kDMM,("P=xxx:, Dmm=D1, channels=22, model=2700")
+
+# X-ray Instrumentation Associates Huber Slit Controller
+# supported by a SNL program written by Pete Jemian and modified (TMM) for use with the
+# sscan record
+#seq  &xia_slit, "name=hsc1, P=xxx:, HSC=hsc1:, S=xxx:seriala[6]"
+
+### Start up the autosave task and tell it what to do.
+# The task is actually named "save_restore".
+# Note that you can reload these sets after creating them: e.g., 
+# reload_monitor_set("auto_settings.req",30,"P=xxx:")
+#save_restoreDebug=20
+#
+# save positions every five seconds
+create_monitor_set("auto_positions.req",5,"P=xxx:")
+# save other things every thirty seconds
+create_monitor_set("auto_settings.req",30,"P=xxx:")
+
+### Start the saveData task.
+saveData_Init("saveData.req", "P=xxx:")
+
+dbcar(0,1)
+