Low impedance load (NTSC video) on Digital 10-11

//***** part 2 ******

void grayPixel(byte x, byte y, byte plane)
{
if (plane == 0)
{
if (y < bufferHEIGHT) 
  {
    frameBuffer[x][y]= frameBuffer[x][y] & 0xFC;   // 11111100
    frameBuffer[x][y]= frameBuffer[x][y] |(_GRAY & 0x03); 
  }
else
  { 
    frameBuffer[x][y-16]= frameBuffer[x][y-16] & 0xF3;   // 11110011
    frameBuffer[x][y-16]= frameBuffer[x][y-16] | (_GRAY & 0x0C);   // mask with 00001100
  } 
}  
else if (plane == 1)
{
if (y < bufferHEIGHT) 
  {
    frameBuffer[x][y]= frameBuffer[x][y] & 0xCF;   
    frameBuffer[x][y]= frameBuffer[x][y] |(_GRAY & 0x30); 
  }
else
  { 
    frameBuffer[x][y-16]= frameBuffer[x][y-16] & 0x3F;   
    frameBuffer[x][y-16]= frameBuffer[x][y-16] | (_GRAY & 0xC0);   
  } 
}  
else 
{
if (y < bufferHEIGHT) 
  {
    frameBuffer[x][y]= _GRAY;
  }
else
  { 
    frameBuffer[x][y-16]= _GRAY;   // 11110011
  } 
}
}

// draw a black pixel to the buffer
void clearPixel(byte x,byte y,byte plane)
{
if (plane == 0)
{
if (y < bufferHEIGHT) 
  {
    frameBuffer[x][y]= frameBuffer[x][y] & 0xFC;   // 11111100
    frameBuffer[x][y]= frameBuffer[x][y] |(_BLACK & 0x03); 
  }
else
  { 
    frameBuffer[x][y-16]= frameBuffer[x][y-16] & 0xF3;   // 11110011
    frameBuffer[x][y-16]= frameBuffer[x][y-16] | (_BLACK & 0x0C);   // mask with 00001100
  } 
}  
else if (plane == 1)
{
if (y < bufferHEIGHT) 
  {
    frameBuffer[x][y]= frameBuffer[x][y] & 0xCF;   
    frameBuffer[x][y]= frameBuffer[x][y] |(_BLACK & 0x30); 
  }
else
  { 
    frameBuffer[x][y-16]= frameBuffer[x][y-16] & 0x3F;   
    frameBuffer[x][y-16]= frameBuffer[x][y-16] | (_BLACK & 0xC0);   // mask with 11000000
  } 
}  
else 
{
if (y < bufferHEIGHT) 
  {
    frameBuffer[x][y]= _BLACK;
  }
else
  { 
    frameBuffer[x][y-16]= _BLACK;   // 11110011
  } 
}
}

// read the value of a single pixel
// either bit plane can be read
// if a plane larger than 1 is specified, bit plane 1 is read
byte readPixel(byte x,byte y,byte plane)
{
if (plane == 0)
{
if (y < bufferHEIGHT) 
  {
    return (frameBuffer[x][y] & 0x03);
  }
else
  { 
    return ((frameBuffer[x][y-16] >>2) & 0x03);
  } 
}  
else if (plane >= 1)
{
if (y < bufferHEIGHT) 
  {
    return (frameBuffer[x][y] & 0x03);
  }
else
  { 
    return ((frameBuffer[x][y-16] >>4)& 0x03);
  } 
}  
}



// clear the screen
// clears both bit planes
void clearScreen()
{
for (index = 0; index < bufferWIDTH; index++)
for (index2=0;index2 < bufferHEIGHT;index2++)
{
 frameBuffer[index][index2] = _BLACK;
}
}

// Swaps the displayed bit plane (bit plane 0) with the hidden bit plane (bit plane 1)
// Draw new image on bit plane 1, then run swap to display
// Bit planes 0 and 1 can be cleared separately by clearScreen
void Swap()
{byte SwapTemp;
for (index = 0; index < bufferWIDTH; index++)
for (index2=0;index2 < bufferHEIGHT;index2++)
 {
 SwapTemp = frameBuffer[index][index2] << 4 ;
 frameBuffer[index][index2] = (frameBuffer[index][index2] >> 4)| SwapTemp;
 }
}

// draw video frame
extern void DrawFrame(void)
{
//moved cli out of setup - only necessary if horizontal timing gets funky
//uncomment if necessary
//cli();

for ( line =0;line< DISPLAY_LINES;++line)
{

// HSync
// front porch (1.5 us)
// writes BLACK on all 4 bits, forces to black regardless of which two bits are active
PORTC = _BLACK;
delayMicroseconds(1.5);
//sync (4.7 us)
PORTC = _SYNC;
delayMicroseconds(4.7);
// breezeway (.6us) + burst (2.5us) + colour back borch (1.6 us)
PORTC = _BLACK;
delayMicroseconds(0.6+2.5+1.6);

//calculate which line to draw to
// mask line to 4 bits, this will cause newlLine to repeat after 16 counts
// the effect is of two for loops running to a count of 16
// you cant start a second for loop in the middle of a screen paint because
// the startup delay will foul up the timing.  
newLine = (line >>3) & 0x0F;
delayMicroseconds(1);

//display the array for this line
// a loop would have been smaller, but it messes the timing up
PORTC = frameBuffer[0][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[1][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[2][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[3][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[4][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[5][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[6][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[7][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[8][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[9][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[10][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[11][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[12][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[13][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[14][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[15][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[16][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[17][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[18][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[19][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[20][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[21][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[22][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[23][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[24][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[25][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[26][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[27][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[28][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[29][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[30][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[31][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[32][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[33][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[34][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[35][newLine];
delayMicroseconds(1);
PORTC = frameBuffer[36][newLine];

// once all 16 lines in the array have been painted disable bits 0-1 on the port
// then enable bits 3-4 with DDRC command, then loop through array again.
if (line > 126)               //Note this is correct dont change to 127
 { 
   DDRC = 0x0C;
 }
else
 {
   DDRC = 0x03;
   DDRC = 0x03;
 }
 
// kludge to correct timings
// adjust as needed, can use inline NOP instructions for shorter delays
PORTC=PORTC;
PORTC=PORTC;
//PORTC=PORTC;
delayMicroseconds(2);
}
 
//vsync
//write 0 to all output bits
PORTC = _SYNC;

// wait for the remainder of the sync period
// old code used delayMicroseconds(565); 
// since this now uses a timer interrupt set by frequency2timer
// your main loop will execute for appx 565 Microseconds before the next interrupt

// sei is needed to enable interrupts
// sometimes interrupts seem to default to disabled
sei();
}

// *** end part 2 ***