       }
     }
 
-    int readWord() {
+    int readWord(bool includeStartStopBits=false) {
       if (_inProgrammingMode) {
         writeCommand(0x04);
 
         pinMode(PROGRAMMING_DATA_PIN, INPUT);
-        delayMicroseconds(PROGRAMMING_MODE_COMMAND_DELAY);
+        micDelay(PROGRAMMING_MODE_COMMAND_DELAY);
 
         int result = 0;
         for (int i = 0; i < 16; i++) {
           digitalWrite(PROGRAMMING_CLOCK_PIN, HIGH);
-          delayMicroseconds(PROGRAMMING_MODE_COMMAND_DELAY);
+          micDelay(PROGRAMMING_MODE_COMMAND_DELAY);
           result = (result >> 1) & 0x7FFF | (((bool) digitalRead(PROGRAMMING_DATA_PIN)) ? 0x8000 : 0);
           digitalWrite(PROGRAMMING_CLOCK_PIN, LOW);
-          delayMicroseconds(PROGRAMMING_MODE_COMMAND_DELAY);
+          micDelay(PROGRAMMING_MODE_COMMAND_DELAY);
         }
 
         pinMode(PROGRAMMING_DATA_PIN, OUTPUT);
-        
-        return result;
+
+        if (includeStartStopBits) {
+          return result;
+        } else {
+          return (result >> 1) & 0x3FFF;
+        }
       }
       return -1;
     }
 
     bool writeWord(int w) {
-      w = (w & 0x3F) << 1;
+      w = (w & 0xFFF) << 1;
       
       if (_inProgrammingMode) {
         writeCommand(0x02);
-        delayMicroseconds(PROGRAMMING_MODE_COMMAND_DELAY);
-
-        for (int i = 0; i < 16; i++) {
-          digitalWrite(PROGRAMMING_CLOCK_PIN, HIGH);
-          digitalWrite(PROGRAMMING_DATA_PIN, (w & 1) == 1 ? HIGH : LOW);
-          Serial.print("Writing: "); Serial.println((w & 1) == 1 ? HIGH : LOW);
-          delayMicroseconds(PROGRAMMING_MODE_CLOCK_CYCLE_DELAY);
-          digitalWrite(PROGRAMMING_CLOCK_PIN, LOW);
-          delayMicroseconds(PROGRAMMING_MODE_CLOCK_CYCLE_DELAY);
-        }
+        micDelay(PROGRAMMING_MODE_COMMAND_DELAY);
+
+        pushOutBits(w, 16);
         
         digitalWrite(PROGRAMMING_DATA_PIN, LOW);
         return true;

#define PROGRAMMING_MODE_INPUT_LINE_SET_TIME 1       // Tset0
#define PROGRAMMING_MODE_HOLD_ACTIVATION_TIME 10     // Thld0
#define PROGRAMMING_MODE_EXIT_DELAY_TIME 2           // Texit
#define PROGRAMMING_MODE_PROGRAMMING_TIME 10000      // Tprog
#define PROGRAMMING_MODE_PROGRAMMING_END_TIME 1000   // Tdis

#define PROGRAMMING_MODE_CLOCK_CYCLE_DELAY 1         // Tset1, Thld1
#define PROGRAMMING_MODE_COMMAND_DELAY 5             // max(Tdly1, Tdly2, Tdly3)


const int POWER_PIN = 40;
const int PROG_POWER_PIN = 41;

  commands[4] = new ReadTextWordControl();
  commands[5] = new WriteTextWordControl();
  commands[6] = new BurnProgramControl();
  commands[7] = new EraseControl();
  commands[8] = new RewriteChipCommand();
  
  Serial.begin(57600);
  Serial.setTimeout(10);
