Thursday, August 21, 2008

How to search for PDS members in ISPF

I've just discovered a really simple way to find stuff on the mainframe. Let's say you are looking for a file called INDEX and you only know the high level qualifier of the dataset it's in. After you do your DLIST (ISPF option 3.4) of the HLQ (hlq.** for example), you type

member index

at the command line. The system will show you all the data sets where a file called INDEX resides. You can also use wildcards. So, for example, let's say there are lots of files you want to find, all starting with INDEX (INDEX00, INDEX01, INDEX02, etc). Then you'd type

member index*

and you'll be shown all the files that begin with the word index. Cool huh? The only thing I've noticed is that if your data set has been migrated, this won't work. You'll have to recall the data set before you do your search.

Hope you find it useful :-)

Wednesday, August 6, 2008

Master the Mainframe and GDDM

The Master the Mainframe contest is just around the corner and as I'm on the contest team this year, I was asked to come up with a coding challenge. The one I came up with last year was a simple ISPF macro challenge I ripped from the pubs (ISRBOX) and added a few bugs too. This year I wanted to do something spectacular so I dug deep and dove into IBMs Graphical Data Display Manager, or GDDM for short.

What's so cool about GDDM? Well my friends, it allows the mainframe to display graphics and interact with things like mice and light pens and all sorts of other cool peripherals. ISPF can be made to act like a simple GUI with a point and click interface. It is also the means by which OS/2 displayed it's windows and such. With the advent of the web, however, this feature became somewhat depricated and nobody, to my knowledge, really uses it anymore.

So what am I doing messing around with this thing? Well, as fun as looking at endless streams of green text can be (and believe me, it's a hoot), I figured some colorful graphics might be a nice change of pace. I decided to create an implementation of Mandelbrot Set. The man who discovered this method, BenoƮt Mandelbrot, was an IBM fellow so it seemed fitting.

So I got to coding, pestered my co-workers when I got stuck or when the math got over my head, and finally I was able to get the thing working. It should be noted that I got some help, especially with the zooming bit, from here.

So I get the stupid thing working,


it looks amazing, it zooms (sortof) at the click of a mouse, I get my ooohs and aaaahs. After all that, it can't be included in the contest because none of the TN3270 emulators on the market (save the IBM one) can handle host graphics. No host graphics means no GGDM. The contestants won't be using the IBM TN3270 program so they won't be able to see the image.

...probably should've looked into that before I spent all that time coding the thing.

Oh well. As there isn't much good information on the web about GDDM I thought I'd post the code, written in C, for the Mandelbrot Generator. In order to use GDDM, you're going to have to play with your JCL and include some libraries so this compiles/links properly.

*NOTE* There are [] around the includes so Blogger doesn't think it's some sort of tag

#include [stdio.h]
#include [string.h]
#include [admucina.h]
#include [admtstrc.h]
#include [admucinf.h]
#include [admucing.h]
#include [admucins.h]


#pragma linkage(asread,OS)
#pragma linkage(chhatt,OS)
#pragma linkage(chhead,OS)
#pragma linkage(gsuwin,OS)
#pragma linkage(gschar,OS)
#pragma linkage(gsseg,OS)
#pragma linkage(gssati,OS)
#pragma linkage(gsscls,OS)
#pragma linkage(gsenda,OS)
#pragma linkage(gsarea,OS)
#pragma linkage(gsqcho,OS)
#pragma linkage(gsqloc,OS)
#pragma linkage(gspat,OS)
#pragma linkage(gsenab,OS)
#pragma linkage(gssaga,OS)
#pragma linkage(gsmove,OS)
#pragma linkage(gscol,OS)
#pragma linkage(gsline,OS)
#pragma linkage(gsview,OS)
#pragma linkage(gslw,OS)
#pragma linkage(gsflw,OS)
#pragma linkage(gsarc,OS)
#pragma linkage(fsinit,OS)
#pragma linkage(fsterm,OS)

#define width 320
#define height 200

main ()
{

/*SETUP THE GDDM ENVIRONMENT**********************/
float xoff, yoff, oldcx, oldcy;
int temp;
float scale;
int flag;
int number;
float cx = -0.5;
float cy = 0;
int inwin;
int type;
int val;
int count;
int id_type;
int id_id;
double x,y;
double xstart,xstep,ystart,ystep;
double xend, yend;
double z,zi,newz,newzi;
double colour;
int iter,input;
long col;
int i,j,k;
int inset;
int fd;

fsinit();
flag = 0;
gsenab (1,0,1);
gsenab (1,1,1);
gsenab (2,1,1);
gsuwin(0,640,0,480);
gsms(9);

xstart = -2;
xend = 1;
ystart = -1;
yend = 1;
xoff = 0;
yoff = 0;
iter = 200;
scale = 1;
xstep = ((xend-xstart)/width) * scale;
ystep = ((yend-ystart)/height) * scale;

/*DISPLAY AND ZOOM LOOP***************************/

while (flag == 0)
{
flag = 1;

x = xstart;
y = ystart;

for (i=0; i
{

for (j=0; j
{
z = 0;
zi = 0;
inset = 1;

for (k=0; k
{
/* z^2 = (a+bi)(a+bi) = a^2 + 2abi - b^2 */
newz = (z*z)-(zi*zi) + x;
newzi = 2*z*zi + y;
z = newz;
zi = newzi;

if(((z*z)+(zi*zi)) > 4)
{
inset = 0;
colour = k;
k = iter;
}

}

if (inset)
{
gscol(-1);
}
else
{

while (colour > 7)
{
colour = colour / 8;
}

gscol(colour);
}

x += xstep;

/*DRAW YOUR FRACTAL!******************************/
gsmark (j,i);

}

y += ystep;
x = xstart;

}

/*SEND THE GDDM DATA TO THE SCREEN****************/

gsread(1,&id_type,&id_id);

if (id_type == 2)
{

scale = scale * 0.75;
flag = 0;
oldcx = cx;
oldcy = cy;

gsqloc(&inwin,&cx,&cy);


if (cx > 320)
{
cx = 320;
}

if (cy > 200)
{
cy = 200;
}

cx = (cx * xstep) - 2 + xoff;
cy = (cy * ystep) - 1 + yoff;

xoff = (xoff + (cx - oldcx));
yoff = (yoff + (cy - oldcy));

xstart = cx + (-1.5 * scale);
xend = cx + 1.5 * scale;
ystart = cy + (-1 * scale);
yend = cy + 1 * scale;

xstep = xstep * scale;
ystep = ystep * scale;

}

}

fsterm();
}

Enjoy (and good luck to this years Master the Mainframe contestants!)