 // concatenated frames to the Gigatron. Between segments
 // it is communicating upstream with the serial port.
 
-void sendGt1File(byte *gt1, unsigned gt1Size)
-{
-  #define readNext() (gt1Size>0 ? (gt1Size--, *gt1++) : 0)
-
-  byte segment[300] = {0};
-  word address = readNext();
+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 = (address << 8) + readNext();
-
-    int len = readNext();
+    address = adr_gt1(seg_start);
+    int len = byte_gt1(seg_start + 2);
     if (!len)
       len = 256;
-
-    for (int i=0; i<len; i++)
-      segment[i] = readNext();
 
     // Check that segment doesn't cross page boundary
     if ((address & 255) + len > 256) {

void loop()
{
  Serial.println("Reset Gigatron");
  
  // In case we power on together with the Gigatron, this is a
  // good pause to wait for the video loop to have started
  delay(350);


  sendFirst(firstByte, 8);     // Protocol byte
  checksum += firstByte << 6;  // Keep Loader.gcl dumb
  sendBits(page_len, 6);       // Length 0, 1..60
  sendBits(address&255, 8);    // Low address bits
  sendBits(address>>8, 8);     // High address bits
  for (byte i=0; i<N; i++)     // Payload bytes
    sendBits(i < data_len ? message[i] : 0, 8);
  byte lastByte = -checksum;   // Checksum must come out as 0
  sendBits(lastByte, 8);
  checksum = lastByte;         // Concatenate checksums
