Rick,
How about this one ? based on your 2x2 contingency table . It is also very fast.
I want know which one is faster between yours and mine.

proc iml;
/* first arg is row vector of sums of cols; second arg contains sums of rows */
start RandContingency2x2(_c, _r);
c = rowvec(_c);
r = colvec(_r);
tbl = j(nrow(r),ncol(c), 0);
if sum(c)^=sum(r) then
abort "sum of column is not equal with sum of row";

do i=1 to ncol(c);
sum=sum(r);
do j=1 to nrow(r);
if c[i]=0 | r[j]=0 then a=0;
else call randgen(a, "Hyper", sum, r[j], c[i]);
tbl[j,i]= a;sum=sum-r[j];c[i]=c[i]-a;
end;
r=r-tbl[,i];
end;

return( tbl );
finish;

call randseed(1);
/* marginals from PROC FREQ example */
c = {12 10 13 }; /* sum of columns */
r = {15, 8,12}; /* sum of rows */
do i = 1 to 100;
tbl = RandContingency2x2(c, r);
print tbl;
end;
quit;