public boolean draw(int startX, int startY) {
		int tileNum;
		
		calculateFPS();
		if ((framesDrawn % frameSkip) != 0) {
			frameDone = true;
			framesDrawn++;
			
			backBuffer.getGraphics().drawImage(drawingBuffer, 0, 0, null);
			
			return false;
		} else {
			framesDrawn++;
		}
		
		Graphics back = drawingBuffer.getGraphics();

		/*  g.setColor(new Color(255,0,0));
  		g.drawRect(5,5, 10, 10);*/
		//  System.out.println("- Drawing");
		//  for (int r = 0; r < 384; r++) {
		//   if (!spriteTiles[r].valid) System.out.println("Generating image for tile " + r);
		//   tiles[r].validate(videoRam, r << 4, backgroundPalette, TILE_BKG);
		//  }

		/*  for (int r = 0; r < 20; r++) {
   bgTiles[r].draw(g, 8 * r, 0);
  }*/



		//  drawSprites(back, 1);


		// Draw bg layer
		/*
  int xTileOfs = unsign(dmgcpu.ioHandler.registers[0x43]) / 8;
  int yTileOfs = unsign(dmgcpu.ioHandler.registers[0x42]) / 8;
  int xPixelOfs = unsign(dmgcpu.ioHandler.registers[0x43]) % 8;
  int yPixelOfs = unsign(dmgcpu.ioHandler.registers[0x42]) % 8;

  int bgStartAddress;
  if (hiBgTileMapAddress) {
   bgStartAddress = 0x1C00;  /* 1C00 
  } else {
   bgStartAddress = 0x1800;
  }

  int tileAddress = 0;
  int attribs = 0;


  for (int y = 0; y < 19; y++) {
   for (int x = 0; x < 21; x++) {
    int attributeData = 0;


    tileAddress = bgStartAddress +
       (((y + yTileOfs) % 32) * 32) + ((x + xTileOfs) % 32);
    attributeData = unsign(videoRam[tileAddress + 0x2000]);

    if (bgWindowDataSelect) {
     tileNum = unsign(videoRam[tileAddress]);
    } else {
     tileNum = 256 + videoRam[tileAddress];
    }

    if (dmgcpu.gbcFeatures) {
     attribs = (attributeData & 0x07) << 2;

     if ((attributeData & 0x20) != 0) {
      attribs |= TILE_FLIPX;
     }
     if ((attributeData & 0x40) != 0) {
      attribs |= TILE_FLIPY;
     }

    } else {
     attribs = TILE_BKG;
    }

    if (tiles[tileNum + tileStart].invalid(attribs)) {
     tiles[tileNum + tileStart].validate(videoRam, tileNum << 4 + vidMemStart, attribs);
    }
    tiles[tileNum + tileStart].
       draw(back, (8 * x) - xPixelOfs, (8 * y) - yPixelOfs, attribs);
   }
  }
		


		/* Draw window */
		if (winEnabled) {
			int wx, wy;
			int windowStartAddress;

			if ((dmgcpu.ioHandler.getRegisters()[0x40] & 0x40) != 0) {
				windowStartAddress = 0x1C00;
			} else {
				windowStartAddress = 0x1800;
			}
			wx = LowLevelData.unsign(dmgcpu.ioHandler.getRegisters()[0x4B]) - 7;
			wy = LowLevelData.unsign(dmgcpu.ioHandler.getRegisters()[0x4A]);

			back.setColor(new Color(backgroundPalette.getRgbEntry(0)));
			back.fillRect(wx * mag, wy * mag, 160 * mag, 144 * mag);

			int tileAddress;
			int attribData, attribs, tileDataAddress;

			for (int y = 0; y < 19 - (wy / 8); y++) {
				for (int x = 0; x < 21 - (wx / 8); x++) {
					tileAddress = windowStartAddress + (y * 32) + x;

					//     if (!bgWindowDataSelect) {
					if (!savedWindowDataSelect) {
						tileNum = 256 + videoRam[tileAddress];
					} else {
						tileNum = LowLevelData.unsign(videoRam[tileAddress]);
					}
					tileDataAddress = tileNum << 4;

					if (dmgcpu.isGbcFeatures()) {
						attribData = LowLevelData.unsign(videoRam[tileAddress + 0x2000]);

						attribs = (attribData & 0x07) << 2;

						if ((attribData & 0x08) != 0) {
							tileNum += 384;
							tileDataAddress += 0x2000;
						}

						if ((attribData & 0x20) != 0) {
							attribs |= TILE_FLIPX;
						}
						if ((attribData & 0x40) != 0) {
							attribs |= TILE_FLIPY;
						}

					} else {
						attribs = TILE_BKG;
					}

					if (wy + y * 8 < windowStopLine) {
						if (tiles[tileNum].invalid(attribs)) {
							tiles[tileNum].validate(videoRam, tileDataAddress, attribs);
						}
						tiles[tileNum].draw(back, wx + x * 8, wy + y * 8, attribs);
					}
				}
			}
		}

		// Draw sprites if the flag was on at any time during this frame
		/* if (spritesEnabledThisFrame) */drawSprites(back, 0);

		if ((spritesEnabled) && (dmgcpu.isGbcFeatures())) {
			drawSprites(back, 1);
		}

		/*  back.setColor(new Color(255, 255, 255));
  back.fillRect(0, 0, 160, 144);
  for (int r = 0; r < 384; r++) {
   tiles[r].validate(videoRam, r << 4, TILE_BKG);
   tiles[r].draw(back, 8 * (r % 20), 8 * (r / 20), TILE_BKG);
  }*/


		//g.drawImage(backBuffer, startX, startY, null);

		/*  if (mag == 1) {
   g.drawImage(backBuffer, startX, startY, null);
  } else {
   g.drawImage(backBuffer, startX, startY, width, height, null);
  }*/

		frameDone = false;
		return true;
	}