Creating a rotating 3D donut involves a more complex mathematical representation than a simple cube. Below is an example of a JavaScript program that generates a rotating 3D donut using HTML5 canvas and JavaScript. The code is based on a well-known donut algorithm called the "donut.c" by Andy Sloane.

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    canvas {
      display: block;
      margin: auto;
      border: 1px solid #000;
    }
  </style>
  <title>3D Rotating Donut</title>
</head>
<body>
  <canvas id="donutCanvas" width="800" height="800"></canvas>

  <script>
    const canvas = document.getElementById('donutCanvas');
    const ctx = canvas.getContext('2d');
    
    const donut = {
      chars: ".,-~:;=!*#$@", // characters to represent the donut
      thetaSpacing: 0.07,
      phiSpacing: 0.02,
      width: 40,
      height: 20,
      time: 0
    };

    function drawDonut() {
      const { chars, thetaSpacing, phiSpacing, width, height, time } = donut;
      const output = [];

      const cosTime = Math.cos(time);
      const sinTime = Math.sin(time);

      for (let j = 0; j < height; j++) {
        const phi = j * phiSpacing;
        const costheta = Math.cos(phi);
        const sintheta = Math.sin(phi);

        for (let i = 0; i < width; i++) {
          const theta = i * thetaSpacing;
          const costheta2 = Math.cos(theta);
          const sintheta2 = Math.sin(theta);

          const circleX = costheta2;
          const circleY = sintheta2;

          const x = circleX * (cosTime * 0.5 + 1) * 40;
          const y = circleY * (sinTime * 0.5 + 1) * 20;

          const z = circleX * (sinTime * 0.5 + 1) * 40 + circleY * (cosTime * 0.5 + 1) * 20;

          const ooz = 1 / z;
          const xp = Math.round(canvas.width / 2 + x * ooz);
          const yp = Math.round(canvas.height / 2 - y * ooz);

          const idx = Math.floor((theta + phi) * 0.01) % chars.length;
          const char = chars[idx];

          if (!output[j]) {
            output[j] = [];
          }

          output[j][i] = { xp, yp, char };
        }
      }

      ctx.clearRect(0, 0, canvas.width, canvas.height);

      for (let j = 0; j < height; j++) {
        if (output[j]) {
          for (let i = 0; i < width; i++) {
            if (output[j][i] && output[j][i].char !== ' ') {
              ctx.fillStyle = '#fff';
              ctx.fillText(output[j][i].char, output[j][i].xp, output[j][i].yp);
            }
          }
        }
      }
    }

    function update() {
      donut.time += 0.05;
      drawDonut();
      requestAnimationFrame(update);
    }

    update();
  </script>
</body>
</html>
```

This code generates a 3D donut and continuously rotates it on the canvas. The donut's shape is represented using ASCII characters. Adjust the parameters in the `donut` object to modify the donut's appearance and rotation speed.