       return;
     }
 
+    // Read data out of PROGMEM
+    for (int i = 0; i < len; ++i) {
+      segment[i] = byte_gt1(seg_start + 3 + i);
+    }
+
     // Send downstream
     Serial.print("> Load ");
     Serial.print(len);
     Serial.println(" bytes");
-    sendGt1Segment(address, len, segment);
-
-    address = readNext();
-  } while (address != 0);
-
-  // Two bytes for start address
-  address = readNext();
-  address = (address << 8) + readNext();
+    int page_size = (address | 0xff) - address;
+    sendGt1Segment(address, page_size, len, segment);
+
+    // Adjust pointer to the start of the next segment
+    seg_start += len + 3;
+  } while (byte_gt1(seg_start) != 0);
+
+  seg_start++; // Skip over terminating byte
+
+  // Read start address
+  address = adr_gt1(seg_start);
   if (address != 0) {
     Serial.print("> Start $");
     Serial.println(address, HEX);
-    sendGt1Execute(address, segment+240);
+    sendGt1Execute(address, NULL);
   }
 }
 
 // Send a 1..256 byte code or data segment into the Gigatron by
 // repacking it into Loader frames of max N=60 payload bytes each.
-void sendGt1Segment(word address, int len, byte data[])
+void sendGt1Segment(word address, int page_size, int len, const byte data[])
 {
   noInterrupts();
   byte n = min(N, len);
-  resetChecksum(n, address, data);
+  byte pn = min(N, page_size);
+  resetChecksum(pn, n, address, data);
 
   // Send segment data
-  for (int i=0; i<len; i+=n) {
-    n = min(N, len-i);
-    sendFrame('L', n, address+i, data+i);
+  for (int i=0; i<page_size; i+=pn) {
+    pn = min(N, page_size-i);
+    n = (i >= len) ? 0 : min(N, len-i);
+    sendFrame('L', pn, n, address+i, data+i);
   }
   interrupts();
 }
 
 // Send execute command
-void sendGt1Execute(word address, byte data[])
+void sendGt1Execute(word address, const byte data[])
 {
   noInterrupts();
-  resetChecksum(0, address, data);  
-  sendFrame('L', 0, address, data);
+  resetChecksum(0, 0, address, data);
+  sendFrame('L', 0, 0, address, data);
   interrupts();
 }
 

  }
  checksum += value;
}


// concatenated frames to the Gigatron. Between segments
// it is communicating upstream with the serial port.

void sendGt1File(const byte *gt1, unsigned gt1Size)
{
  #define byte_gt1(x) (pgm_read_byte_near(gt1 + (x)))
  #define adr_gt1(x) (((word)byte_gt1(x) << 8) | byte_gt1((x) + 1))

  // Any number n > 0 of segments
  word address;
  int seg_start = 0;
  byte segment[256];
  do {
    address = adr_gt1(seg_start);
    int len = byte_gt1(seg_start + 2);
    if (!len)
      len = 256;

    // Check that segment doesn't cross page boundary
    if ((address & 255) + len > 256) {
