Making actual 3D games is basically impossible without a modelling program. That is why i never generate them runtime. 1) less to code, 2) faster loading times, 3) texture mapping and normals the way i like.

Anyway because i actually created my own modelling program (no longer developed cause its with Delphi), i do have some code to create different objects. This is cylinder for example, just to maybe give hints. If you want to we may try to see what your functions are doing...
Don't remember how that code made texture coordinates but there's a different function to generate normals based on smoothing groups.
Code:
function TWorld3D.MakeCylinder(radius,sy: single; sides,segs: integer): word;
var x,y,z: array[1..5] of single; x1,y1,i: integer;
    segA,segY: single;
begin
  result:=New3DObject;
  if sides<3 then sides:=3;
  if segs<1 then segs:=1;
  segA:=2*PI/sides; segY:=sy/segs;
  with o[result] do
    for x1:=0 to sides-1 do begin
      // Cylinder
      for y1:=0 to segs-1 do begin
        x[2]:=radius*cos(x1*segA);
        z[2]:=radius*sin(x1*segA);
        y[2]:=-sy/2+y1*segY;
        x[3]:=radius*cos(x1*segA);
        z[3]:=radius*sin(x1*segA);
        y[3]:=-sy/2+(y1+1)*segY;
        x[4]:=radius*cos((x1+1)*segA);
        z[4]:=radius*sin((x1+1)*segA);
        y[4]:=-sy/2+(y1+1)*segY;
        x[1]:=radius*cos((x1+1)*segA);
        z[1]:=radius*sin((x1+1)*segA);
        y[1]:=-sy/2+y1*segY;       
        o[result].AddFace(x,y,z,4);
      end;
      // Top - Bottom
      for y1:=0 to 1 do begin
        x[1]:=radius*cos(x1*segA);
        z[1]:=radius*sin(x1*segA);
        x[2]:=radius*cos((x1-y1*2+1)*segA);
        z[2]:=radius*sin((x1-y1*2+1)*segA);
        x[3]:=0; z[3]:=0;
        for i:=1 to 3 do y[i]:=-sy/2+y1*sy;
        TFace(f[o[result].AddFace(x,y,z,3)]).smoothGroup:=1;
      end;
    end;
  o[result].UpdateSize;
end;