diff --git a/hunks/adhoc/saturn.js b/hunks/adhoc/saturn.js
index 1c5f9378cc312df68de97538c2b1da200f48fb1a..3ee468fb6eaebb7ffff7015e613dcb95b205de1b 100644
--- a/hunks/adhoc/saturn.js
+++ b/hunks/adhoc/saturn.js
@@ -37,7 +37,6 @@ export default function Saturn() {
   let outy = this.output('number', 'outy')
   let outz = this.output('number', 'outz')
   let outp = this.output('array', 'posn')
-  let period = 0.100 // his.state('number', 'period', 50) // in ms,
 
   let allClear = () => {
     return (!outx.io() && !outy.io() && !outz.io())
@@ -53,6 +52,7 @@ export default function Saturn() {
   let deviation = 0.1 // virtual radius to junction about
   let accel = 980 // units/s/s (9.8m/s/s, 9800mm/s/s is 1G)
   let minSpeed = 0.01 // conspicuous, to debug for tails (indexing)
+  let period = 0.050 // his.state('number', 'period', 50) // in ms,
 
   // current states,
   let cruise = 200 // target, (units/s)
@@ -107,19 +107,10 @@ export default function Saturn() {
       if (debug) console.log(`reverse pass for ${i}\n`, positions[i], positions[i + 1])
       if (debug) console.log(`current entrance to calculate is`, speeds[i])
       if (debug) console.log(`the constraining exit is`, speeds[i + 1])
-
       // to calcluate the maximum entrance, given our exit, with pure acceleration:
       let d = vLen(math.subtract(positions[i + 1], positions[i]))
-      // with given period, how fast can we possibly go in one period? for small moves this is constraining
       let maxEntranceByAccel = Math.sqrt(Math.pow(speeds[i + 1], 2) + 2 * accel * d)
-
-      // to calculate the maximum entrance, given our exit, to make within one period of time:
-      // let t = 2 * d / (speeds[i] + speeds[i + 1]) // current t ...
-      // v2, where t = period (1.5 is a safety factor for later rounding)
-      let maxEntranceByPeriod = (period * 1.5) / (2 * d) - speeds[i]
-
-      // set the entrance speed to the min of jd or our Max Entrance, but no lower than the minspeed
-      let max = Math.max(minSpeed, Math.min(speeds[i], maxEntranceByAccel, maxEntranceByPeriod))
+      let max = Math.max(minSpeed, Math.min(speeds[i], maxEntranceByAccel))
       // just for logging
       let temp = speeds[i]
       // stay safe w/ current state at zero
@@ -132,6 +123,35 @@ export default function Saturn() {
     }
   }
 
+  // OK: *i think* the move might be to do this *first* and then never increase moves 
+
+  let periodPass = (speeds, debug) => {
+    for (let i = positions.length - 2; i > 0; i--) {
+      // distance to make,
+      let d = vDist(positions[i], positions[i+1])
+      // 'initial' velocity (final)
+      let vi = speeds[i]
+      let vf = speeds[i + 1]
+      // with maximum acceleration, and this distance, this takes this long:
+      let tMin = (2 * d) / (vi + vf)
+      if(tMin < period){
+        console.warn('vi, vf, distance, tMin')
+        console.log(speeds[i].toFixed(3), speeds[i + 1].toFixed(3))
+        console.log(d.toFixed(3))
+        console.log(tMin.toFixed(3))
+        // this is a reverse pass, so we actually want to modify vi
+        // such that ...
+        let nvi = period / (2 * d) - vf
+        console.log('propose', nvi.toFixed(3))
+        // ok then: given the d, what v for one period?
+        let v = d / period
+        console.log('flat at', v.toFixed(3))
+        // however: this might drive vf into the -ves - in that case, we need to walk forwards...
+        // this might actually be that sorting algo...
+      }
+    }
+  }
+
   let forwardPass = (speeds, debug) => {
     // link, walk forwards: can we accel to these velocities in time?
     for (let i = 0; i < positions.length - 2; i++) {
@@ -139,8 +159,8 @@ export default function Saturn() {
       if (debug) console.log(`current exit to calculate is`, speeds[i + 1])
       if (debug) console.log(`the constraining entrance is`, speeds[i])
       let d = vLen(math.subtract(positions[i + 1], positions[i]))
-      let maxExit = Math.sqrt(Math.pow(speeds[i], 2) + 2 * accel * d)
-      let max = Math.max(minSpeed, Math.min(speeds[i + 1], maxExit))
+      let maxExitByAccel = Math.sqrt(Math.pow(speeds[i], 2) + 2 * accel * d)
+      let max = Math.max(minSpeed, Math.min(speeds[i + 1], maxExitByAccel))
       let temp = speeds[i + 1]
       if (i === positions.length - 2) {
         // tail should always be minspeed, if not, trouble
@@ -154,292 +174,6 @@ export default function Saturn() {
     // here is assuming positions[0] is current position, for which speed is the current velocity
   }
 
-  let rampPass = (speeds, debug) => {
-    let ramps = []
-    for (let i = 0; i < positions.length - 2; i++) {
-      if (debug) console.log(`ramp pass for ${i}`)
-      let pi = positions[i]
-      let pf = positions[i + 1]
-      let vi = speeds[i]
-      let vf = speeds[i + 1]
-      let d = vDist(pi, pf)
-      let maxEntry = Math.sqrt(Math.pow(speeds[i + 1], 2) + 2 * accel * d)
-      let maxExit = Math.sqrt(Math.pow(speeds[i], 2) + 2 * accel * d)
-      if (debug) console.log(`entrance speed is ${vi}`)
-      if (debug) console.log(`exit speed is ${vf}`)
-      if (debug) console.log(`d is ${d}, maxEntry ${maxEntry}, maxExit ${maxExit}`)
-      // these are common and useful:
-      let writeUpTick = () => {
-        ramps.push({
-          vi: vi,
-          vf: vf,
-          t: (vf - vi) / accel,
-          pi: pi,
-          pf: pf
-        })
-      }
-      let writeDownTick = () => {
-        ramps.push({
-          vi: vi,
-          vf: vf,
-          t: (vi - vf) / accel,
-          pi: pi,
-          pf: pf
-        })
-      }
-      // big switch
-      if (maxExit <= vf) {
-        // the all-up and all-down segments should always be clear:
-        // since we already swept for these cases in the revpass
-        if (debug) console.log(`/`)
-        writeUpTick()
-      } else if (maxEntry <= vi) {
-        if (debug) console.log('\\')
-        writeDownTick()
-      } else if (vi === cruise && vf === cruise) {
-        // similarely, since we're not segmenting cruise any farther, it should also be OK
-        if (debug) console.log('--')
-        ramps.push({
-          vi: vi,
-          vf: vf,
-          t: d / vi,
-          pi: pi,
-          pf: pf
-        })
-      } else if (vi === cruise) {
-        if (debug) console.log('--\\')
-        let dcDist = (Math.pow(cruise, 2) - Math.pow(vf, 2)) / (2 * accel)
-        let pInter = math.add(pf, vScalar(vUnitBetween(pf, pi), dcDist))
-        // now, we need to tune accel / cruise phases so that neither t is < 1 period
-        let tSeg1 = (d - dcDist) / cruise
-        let tSeg2 = (cruise - vf) / accel
-        if(tSeg1 < period || tSeg2 < period){
-          // hopeless, write downtick
-          // there are other options here: adjust one to suit other, but we're not here for it
-          // and in these cases, the small segments, being small, can just get washed into a big ramp, ok
-          writeDownTick()
-        } else {
-          // and if we can't do that, we backtrack to '\\' type
-          // seg1
-          ramps.push({
-            vi: vi,
-            vf: cruise,
-            t: tSeg1,
-            pi: pi,
-            pf: pInter
-          })
-          // seg 2,
-          ramps.push({
-            vi: cruise,
-            vf: vf,
-            t: tSeg2,
-            pi: pInter,
-            pf: pf
-          })
-        }
-      } else if (vf === cruise) {
-        if (debug) console.log('/--')
-        let acDist = (Math.pow(cruise, 2) - Math.pow(vi, 2)) / (2 * accel)
-        let pInter = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist))
-        // I feel the same about this as I did above
-        let tSeg1 = (cruise - vi) / accel
-        let tSeg2 = (d - acDist) / cruise
-        if(tSeg1 < period || tSeg2 < period){
-          writeDownTick()
-        } else {
-          // seg1
-          ramps.push({
-            vi: vi,
-            vf: cruise,
-            t: tSeg1,
-            pi: pi,
-            pf: pInter
-          })
-          // seg2
-          ramps.push({
-            vi: cruise,
-            vf: vf,
-            t: tSeg2,
-            pi: pInter,
-            pf: pf
-          })
-        }
-      } else {
-        let dcDist = (Math.pow(cruise, 2) - Math.pow(vf, 2)) / (2 * accel)
-        let acDist = (Math.pow(cruise, 2) - Math.pow(vi, 2)) / (2 * accel)
-        let writeTriangle = () => {
-          if (debug) console.log('/\\')
-          let vPeak = Math.sqrt(((2 * accel * d + Math.pow(vi, 2) + Math.pow(vf, 2)) / 2))
-          let acDist = (Math.pow(vPeak, 2) - Math.pow(vi, 2)) / (2 * accel)
-          let pInter = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist))
-          // finally, we have to check here if either / or side is too small, then default to smallticks
-          let tSeg1 = (vPeak - vi) / accel
-          let tSeg2 = (vPeak - vf) / accel
-          if(tSeg1 < period || tSeg2 < period){
-            // bail hard,
-            if(vf > vi){
-              writeUpTick()
-            } else {
-              writeDownTick()
-            }
-          } else {
-            ramps.push({
-              vi: vi,
-              vf: vPeak,
-              t: tSeg1,
-              pi: pi,
-              pf: pInter
-            })
-            ramps.push({
-              vi: vPeak,
-              vf: vf,
-              t: tSeg2,
-              pi: pInter,
-              pf: pf
-            })
-          }
-        }
-        if (acDist + dcDist < d) {
-          if (debug) console.log('/--\\')
-          let pa = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist))
-          let pb = math.add(pf, vScalar(vUnitBetween(pf, pi), dcDist))
-          // ok,
-          let tSeg1 = (cruise - vi) / accel
-          let tSeg2 = (d - acDist - dcDist) / cruise
-          let tSeg3 = (cruise - vf) / accel
-          if(tSeg2 < period){
-            // for this case, contencating into a triangle is fine... it will be within ~ 50ms of extra accel time: not much
-            writeTriangle()
-          } else if (tSeg1 < period && tSeg3 < period){
-            // contencate to slow-up or slow-down
-            if(vf > vi){
-              writeUpTick()
-            } else {
-              writeDownTick()
-            }
-          } else if (tSeg1 < period){
-            // check that enough space to make slow triangle,
-            if(tSeg1 + tSeg2 < period){
-              // sweet lord there must be a better way
-              if(vf > vi){
-                writeUpTick()
-              } else {
-                writeDownTick()
-              }
-            } else {
-              // slow-triangle up,
-              ramps.push({
-                vi: vi,
-                vf: cruise,
-                t: 2 * vDist(pi, pb) / (vi + cruise),
-                pi: pi,
-                pf: pb
-              })
-              // and last seg. as normal
-              ramps.push({
-                vi: cruise,
-                vf: vf,
-                t: tSeg3,
-                pi: pb,
-                pf: pf
-              })
-            }
-          } else if (tSeg3 < period){
-            if(tSeg2 + tSeg3 < period){
-              // ibid
-              if(vf > vi){
-                writeUpTick()
-              } else {
-                writeDownTick()
-              }
-            } else {
-              // write first seg as normal,
-              ramps.push({
-                vi: vi,
-                vf: cruise,
-                t: tSeg1,
-                pi: pi,
-                pf: pa
-              })
-              // second as slow-loss from pa -> vf
-              ramps.push({
-                vi: cruise,
-                vf: vf,
-                t: 2 * vDist(pa, pf) / (cruise + vf),
-                pi: pa,
-                pf: pf
-              })
-            }
-          } else {
-            // 3 segs
-            ramps.push({
-              vi: vi,
-              vf: cruise,
-              t: tSeg1,
-              pi: pi,
-              pf: pa
-            })
-            ramps.push({
-              vi: cruise,
-              vf: cruise,
-              t: tSeg2,
-              pi: pa,
-              pf: pb
-            })
-            ramps.push({
-              vi: cruise,
-              vf: vf,
-              t: tSeg3,
-              pi: pb,
-              pf: pf
-            })
-          }
-        } else {
-          // the actual triangle case
-          writeTriangle()
-        }
-      } // end BIGSWITCH
-    } // end for-over-positions
-    return ramps
-  }
-
-  let roundPass = (ramps, debug) => {
-    for (let i = 0; i < ramps.length; i++) {
-      // try a forward walk through these things. adjust so that distance is equal for each,
-      let r = ramps[i]
-      // first, given current d, entrance and exit speeds, the time:
-      let d = vDist(r.pi, r.pf)
-      let t = 2 * d / (r.vi + r.vf)
-      // does this calc match the ramp time? yes
-      // so ...
-    }
-  }
-
-  let blockPass = (ramps, debug) => {
-    let blocks = []
-    for(let i = 0; i < ramps.length; i++){
-      let r = ramps[i]
-      let d = vDist(r.pi, r.pf)
-      // how many blocks are we going to split it to?
-      let count = r.t / period
-      let integer = Math.round(count)
-      if(integer < 1) {
-        console.warn(`small ramp during blockPass at ${i}`)
-        integer = 1
-      }
-      // the pos'ns to split to:
-      let vu = vUnitBetween(r.pi, r.pf)
-      // now just...
-      for(let b = 0; b < integer; b ++){
-        // percentage through,
-        let start = b / integer
-        let finish = (b + 1) / integer
-        blocks.push([math.add(r.pi, vScalar(vu, start)), math.add(r.pi, vScalar(vu, finish))])
-      }
-    }
-    return blocks
-  }
-
   let blockOnce = true
   let blocks = []
   let posNow = []
@@ -465,6 +199,9 @@ export default function Saturn() {
     // first we get all move final v's by jd:
     // we jd,
     if (positions.length > positionsBufferSize - 1 && blockOnce) {
+      for(let i = 0; i < positions.length - 2; i ++){
+        //console.log(vDist(positions[i], positions[i + 1]))
+      }
       blockOnce = false
       // ok, here's the lookahead routine:
       console.time('lookahead')
@@ -474,41 +211,13 @@ export default function Saturn() {
       // jd runs an algorithm that calculates maximum allowable
       // instantaneous accelerations at corners
       jd(speeds)
-      // we occasionally (rather, often) need to start decelerating (or accelerating) a few segments before
-      // the actual constraint: these passes link segments to one another by ensuring that a pass through
-      // the whole path does not require any accelerations outside of our range.
-      // the reversepass also sets minimum speeds such that we don't find any moves impossible to execute
-      // within one network period
+      // revpass to link by max. accel:
       reversePass(speeds)
+      // reverse again, checking that times are within periods...
+      periodPass(speeds)
       forwardPass(speeds)
       console.timeLog('lookahead')
-      // now have allowable maximum speeds at the junctions - the corners - between segments
-      // but we still need to consider how much acceleration we can do in between these minimum speeds
-      // i.e. we will now generate the individual accel- deccel- and cruise phases of each segment
-      // *now* since we are operating on a period basis, we also tune these segments such that
-      // (1) none are smaller than one period of time and (2) all take some integer division of periods to complete
-      let ramps = rampPass(speeds)
-      // or,
-      //let ramps = timeSegPass(speeds)
-      // we do one last check:
-      for (let r of ramps) {
-        //console.log(`${r.t.toFixed(3)}`)
-        if (r.vi < minSpeed || r.vf < minSpeed || r.vi > (cruise * 1.1) || r.vf > (cruise * 1.1) || r.t < period) {
-          console.warn(`troublesome ramp found on final check`, r)
-        }
-      }
-      // now we're done,
-      console.timeLog('lookahead')
-      console.log(`have ${ramps.length} ramps for ${positions.length} positions`)
-      // should see about writing out motion blocks:
-      blocks = blockPass(ramps, true)
-      console.log(`have ${blocks.length} blocks for ${ramps.length} ramps`)
-      console.timeEnd('lookahead') // 49ms ... to write ~ 3k blocks from 145 ramps from 64 positions
-      // OK: I think this is it... I'll wrap the loop again to do this once, then write those blocks out at the
-      // flowcontrol'd interval... and see how it looks. this is maybe even enough: if steppers just make these counts
-      // of steps, distance is preserved, but some jerk every 50ms... interpolation next
-      // run once,
-      //throw new Error('halt')
+      // re-hash from here
     }
 
     if(blocks.length > 0 && allClear()){
@@ -520,7 +229,7 @@ export default function Saturn() {
       outx.put(1)
       outy.put(1)
       outz.put(1)
-      // and,
+      // output in steps-space...
       posNow = vScalar(bl[0], spmm)
       posUpdated = true
     }
diff --git a/hunks/adhoc/tpath.js b/hunks/adhoc/tpath.js
index 5ed840add1856dcecd6fd2da5110c1323346ac01..651d610de479c813eb1056210466434a343cd24b 100644
--- a/hunks/adhoc/tpath.js
+++ b/hunks/adhoc/tpath.js
@@ -17,7 +17,7 @@ import {
 import * as expath from '../../test_files/example-path-sl2.js'
 import { vScalar } from '../../libs/smallvectors.js'
 
-let dpi = 600
+let dpi = 72
 
 export default function TPFCOUT(){
   Hunkify(this)
@@ -43,7 +43,9 @@ export default function TPFCOUT(){
   this.loop = () => {
     if(path.length > 0 && go){
       if(!outPosn.io()){
-        outPosn.put(vScalar(path.shift(), 600 / 25.4))
+        let op = vScalar(path.shift(), (1/dpi)*25.4)
+        //console.log(op[1])
+        outPosn.put(op)
       }
     }
   }
diff --git a/hunks/image/readpng.js b/hunks/image/readpng.js
index a1d5358a9feffafbe596998690cbef385a7b06ac..c71825d134d6f332d566c0b1eebafdb146623891 100644
--- a/hunks/image/readpng.js
+++ b/hunks/image/readpng.js
@@ -125,6 +125,11 @@ export default function UploadPNG() {
       }
       localDpi = ppx * 25.4 / 1000
       dpiUpdated = true
+      if(localImageInfo){
+        let width = localImageInfo.width * ((dpi*1000) / 25.4)
+        let height = localImageInfo.height * ((dpi*1000) / 25.4)
+        console.warn(`size in mm is w: ${width.toFixed(3)}, h: ${height.toFixed(3)}`)
+      }
       console.log('dpi', localDpi)
     }
     let headerReader = new FileReader()
diff --git a/scratch/ramppass.js b/scratch/ramppass.js
new file mode 100644
index 0000000000000000000000000000000000000000..a9a205b4999419c66f70b871e3e95b7d189599be
--- /dev/null
+++ b/scratch/ramppass.js
@@ -0,0 +1,274 @@
+let rampPass = (speeds, debug) => {
+  let ramps = []
+  for (let i = 0; i < positions.length - 2; i++) {
+    if (debug) console.log(`ramp pass for ${i}`)
+    let pi = positions[i]
+    let pf = positions[i + 1]
+    let vi = speeds[i]
+    let vf = speeds[i + 1]
+    let d = vDist(pi, pf)
+    let maxEntry = Math.sqrt(Math.pow(speeds[i + 1], 2) + 2 * accel * d)
+    let maxExit = Math.sqrt(Math.pow(speeds[i], 2) + 2 * accel * d)
+    if (debug) console.log(`entrance speed is ${vi}`)
+    if (debug) console.log(`exit speed is ${vf}`)
+    if (debug) console.log(`d is ${d}, maxEntry ${maxEntry}, maxExit ${maxExit}`)
+    // these are common and useful:
+    let writeUpTick = () => {
+      ramps.push({
+        vi: vi,
+        vf: vf,
+        t: (vf - vi) / accel,
+        pi: pi,
+        pf: pf
+      })
+    }
+    let writeDownTick = () => {
+      ramps.push({
+        vi: vi,
+        vf: vf,
+        t: (vi - vf) / accel,
+        pi: pi,
+        pf: pf
+      })
+    }
+    // big switch
+    if (maxExit <= vf) {
+      // the all-up and all-down segments should always be clear:
+      // since we already swept for these cases in the revpass
+      if (debug) console.log(`/`)
+      writeUpTick()
+    } else if (maxEntry <= vi) {
+      if (debug) console.log('\\')
+      writeDownTick()
+    } else if (vi === cruise && vf === cruise) {
+      // similarely, since we're not segmenting cruise any farther, it should also be OK
+      if (debug) console.log('--')
+      ramps.push({
+        vi: vi,
+        vf: vf,
+        t: d / vi,
+        pi: pi,
+        pf: pf
+      })
+    } else if (vi === cruise) {
+      if (debug) console.log('--\\')
+      let dcDist = (Math.pow(cruise, 2) - Math.pow(vf, 2)) / (2 * accel)
+      let pInter = math.add(pf, vScalar(vUnitBetween(pf, pi), dcDist))
+      // now, we need to tune accel / cruise phases so that neither t is < 1 period
+      let tSeg1 = (d - dcDist) / cruise
+      let tSeg2 = (cruise - vf) / accel
+      if (tSeg1 < period || tSeg2 < period) {
+        // hopeless, write downtick
+        // there are other options here: adjust one to suit other, but we're not here for it
+        // and in these cases, the small segments, being small, can just get washed into a big ramp, ok
+        writeDownTick()
+      } else {
+        // and if we can't do that, we backtrack to '\\' type
+        // seg1
+        ramps.push({
+          vi: vi,
+          vf: cruise,
+          t: tSeg1,
+          pi: pi,
+          pf: pInter
+        })
+        // seg 2,
+        ramps.push({
+          vi: cruise,
+          vf: vf,
+          t: tSeg2,
+          pi: pInter,
+          pf: pf
+        })
+      }
+    } else if (vf === cruise) {
+      if (debug) console.log('/--')
+      let acDist = (Math.pow(cruise, 2) - Math.pow(vi, 2)) / (2 * accel)
+      let pInter = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist))
+      // I feel the same about this as I did above
+      let tSeg1 = (cruise - vi) / accel
+      let tSeg2 = (d - acDist) / cruise
+      if (tSeg1 < period || tSeg2 < period) {
+        writeDownTick()
+      } else {
+        // seg1
+        ramps.push({
+          vi: vi,
+          vf: cruise,
+          t: tSeg1,
+          pi: pi,
+          pf: pInter
+        })
+        // seg2
+        ramps.push({
+          vi: cruise,
+          vf: vf,
+          t: tSeg2,
+          pi: pInter,
+          pf: pf
+        })
+      }
+    } else {
+      let dcDist = (Math.pow(cruise, 2) - Math.pow(vf, 2)) / (2 * accel)
+      let acDist = (Math.pow(cruise, 2) - Math.pow(vi, 2)) / (2 * accel)
+      let writeTriangle = () => {
+        if (debug) console.log('/\\')
+        let vPeak = Math.sqrt(((2 * accel * d + Math.pow(vi, 2) + Math.pow(vf, 2)) / 2))
+        let acDist = (Math.pow(vPeak, 2) - Math.pow(vi, 2)) / (2 * accel)
+        let pInter = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist))
+        // finally, we have to check here if either / or side is too small, then default to smallticks
+        let tSeg1 = (vPeak - vi) / accel
+        let tSeg2 = (vPeak - vf) / accel
+        if (tSeg1 < period || tSeg2 < period) {
+          // bail hard,
+          if (vf > vi) {
+            writeUpTick()
+          } else {
+            writeDownTick()
+          }
+        } else {
+          ramps.push({
+            vi: vi,
+            vf: vPeak,
+            t: tSeg1,
+            pi: pi,
+            pf: pInter
+          })
+          ramps.push({
+            vi: vPeak,
+            vf: vf,
+            t: tSeg2,
+            pi: pInter,
+            pf: pf
+          })
+        }
+      }
+      if (acDist + dcDist < d) {
+        if (debug) console.log('/--\\')
+        let pa = math.add(pi, vScalar(vUnitBetween(pi, pf), acDist))
+        let pb = math.add(pf, vScalar(vUnitBetween(pf, pi), dcDist))
+        // ok,
+        let tSeg1 = (cruise - vi) / accel
+        let tSeg2 = (d - acDist - dcDist) / cruise
+        let tSeg3 = (cruise - vf) / accel
+        if (tSeg2 < period) {
+          // for this case, contencating into a triangle is fine... it will be within ~ 50ms of extra accel time: not much
+          writeTriangle()
+        } else if (tSeg1 < period && tSeg3 < period) {
+          // contencate to slow-up or slow-down
+          if (vf > vi) {
+            writeUpTick()
+          } else {
+            writeDownTick()
+          }
+        } else if (tSeg1 < period) {
+          // check that enough space to make slow triangle,
+          if (tSeg1 + tSeg2 < period) {
+            // sweet lord there must be a better way
+            if (vf > vi) {
+              writeUpTick()
+            } else {
+              writeDownTick()
+            }
+          } else {
+            // slow-triangle up,
+            ramps.push({
+              vi: vi,
+              vf: cruise,
+              t: 2 * vDist(pi, pb) / (vi + cruise),
+              pi: pi,
+              pf: pb
+            })
+            // and last seg. as normal
+            ramps.push({
+              vi: cruise,
+              vf: vf,
+              t: tSeg3,
+              pi: pb,
+              pf: pf
+            })
+          }
+        } else if (tSeg3 < period) {
+          if (tSeg2 + tSeg3 < period) {
+            // ibid
+            if (vf > vi) {
+              writeUpTick()
+            } else {
+              writeDownTick()
+            }
+          } else {
+            // write first seg as normal,
+            ramps.push({
+              vi: vi,
+              vf: cruise,
+              t: tSeg1,
+              pi: pi,
+              pf: pa
+            })
+            // second as slow-loss from pa -> vf
+            ramps.push({
+              vi: cruise,
+              vf: vf,
+              t: 2 * vDist(pa, pf) / (cruise + vf),
+              pi: pa,
+              pf: pf
+            })
+          }
+        } else {
+          // 3 segs
+          ramps.push({
+            vi: vi,
+            vf: cruise,
+            t: tSeg1,
+            pi: pi,
+            pf: pa
+          })
+          ramps.push({
+            vi: cruise,
+            vf: cruise,
+            t: tSeg2,
+            pi: pa,
+            pf: pb
+          })
+          ramps.push({
+            vi: cruise,
+            vf: vf,
+            t: tSeg3,
+            pi: pb,
+            pf: pf
+          })
+        }
+      } else {
+        // the actual triangle case
+        writeTriangle()
+      }
+    } // end BIGSWITCH
+  } // end for-over-positions
+  return ramps
+}
+
+
+let blockPass = (ramps, debug) => {
+  let blocks = []
+  for (let i = 0; i < ramps.length; i++) {
+    let r = ramps[i]
+    let d = vDist(r.pi, r.pf)
+    // how many blocks are we going to split it to?
+    let count = r.t / period
+    let integer = Math.round(count)
+    if (integer < 1) {
+      console.warn(`small ramp during blockPass at ${i}`)
+      integer = 1
+    }
+    // the pos'ns to split to:
+    let vu = vUnitBetween(r.pi, r.pf)
+    // now just...
+    for (let b = 0; b < integer; b++) {
+      // percentage through,
+      let start = b / integer
+      let finish = (b + 1) / integer
+      blocks.push([math.add(r.pi, vScalar(vu, start)), math.add(r.pi, vScalar(vu, finish))])
+    }
+  }
+  return blocks
+}
diff --git a/typeset.js b/typeset.js
index 087e48d059c848c6cc1e719528736c0aea27d940..ca65b80927cf550921413ba46132d56be9881e2c 100644
--- a/typeset.js
+++ b/typeset.js
@@ -498,6 +498,9 @@ const TSET = [
           imageData.width,
           imageData.height
         ) //
+      },
+      reference: function(imageData){
+        return imageData
       }
     }
   },