Pascal (FPC), 128 125 125138 bytes
One recursive procedure takes care of everything. Call with m(9,9)
.
procedure m(i,j:int8);begin if i<1then Exit;if i=j then begin m(i-1,j-1);writeln;end;m(i-1,j);write(i,'x',j,'=',i*j,' ':2-i*j div 10);end;
Ungolfed:
procedure m(i, j: int8);
begin
if i<1 then
Exit;
if i=j then
begin
m(i-1, j-1);
writeln;
end;
m(i-1, j);
write(i,'x',j,'=',i*j,' ':2-i*j div 10);
end;
Try it online! The reason for the byte count going up: the output was not aligned correctly. It is fixed now.