Well recently I did manage to get some GREAT books on OS/2, going back to the Microsoft days.. And they contain a lot of information, which was actually quite substantial.
Although there is the impression after the fact that Microsoft really wasn’t that dedicated to OS/2 the wealth of information in these books seem to be otherwise..
Anyways there is four volumes in the set, 1-3 going over version 1.1, and volume 4 with the 1.2 release of OS/2.
As luck would have it, someone gave me a lead on an ISO that contained not only these, but all of the programming documentation of the time on a CD.  No doubt this was the predecessor to the excellent MSDN.
There of course, is just one catch. Â It uses the .hlp files, but not from Windows 3.00 its something much earlier and the only way to view the files is with an MS-DOS program.
I even tried it on OS/2 hoping it was a family api program (like so many of the era were) but no luck. Â I was then hoping maybe I could just ‘print’ the files to a virtual printer, and spool the whole job. Â BUT YOU CANT PRINT.
So I then wondered if I could put together a TSR that would scrape the screen, append it to a file, and just keep hitting page down.  A few hours of cobbling together some example programs, and remembering to compile with the LARGE memory model (FAR pointers! remember those?)  I could then finally unleash the TSR through the program and extract some of the texts.
For those wondering how to do this kind of thing from MS-DOS here is the source. Â While I wanted to use Scott’s program, there was the one drawback that almost everything grabs printscreen now so doing a REAL printscreen that hits interrupt 5 seems like it’d actually require a physical PC in MS-DOS. Â And my current ‘retro’ PC has no ethernet so I wasn’t going to go that route.
So there is a lot of hacks with this, you can’t even uninstall it, just reboot …. but this hooks the clock, gives you about a minute to go where you want to go, then it saves a portion of the screen to a file, waits a few seconds and hits pagedown, and repeats….
// Written by Scott Hall of the U. of Missouri - Columbia, USA.
// This program will redirect your print screen button so that
// it goes to a file. The file name is at the beginning of the
// start() function. It can easily be modified to print screens
// that are larger than 80x25.
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <dos.h>
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
char far *scr=(char far*)0xb0008000L;
#define VIDMEM 0Xb0008000L
#define INTR 0x1c
int busy=0;Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // mutual exclusion (MUTEX)
void interrupt (*oldhandler)(__CPPARGS);
char far *old_dta;
char fname[9];
void interrupt int_5();
void tsr(unsigned size);Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // standard tsr bios call
void write_char(int x, int y, char ch, int attrib);
void write_string(int x, int y, char *str, int attrib);
void start(void);
void interrupt handler(__CPPARGS);
int main(int argc, char*argv[])
{
if(argc==2)
sprintf(fname,argv[1]);
else
sprintf(fname,"log.txt");
printf ("installing\n");
disable();
oldhandler=getvect(INTR);
setvect(INTR,handler);
setvect(32,oldhandler);
enable();
printf("done\n");
tsr(1000);
return 0;
}
void tsr(unsigned size)Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // standard tsr bios call
{Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // you can also use keep()
union REGS r;
r.h.ah = 49;Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // function 0x31
r.h.al = 0;
r.x.dx = size;
int86(0x21,&r, &r);Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // last line executed
}Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // never get to this line
unsigned char j=0;
unsigned int tcount;
unsigned int dcount=0;
//void interrupt int_5()Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // print screen button starts here
void interrupt handler(__CPPARGS)
{
if(dcount>480)
{
if(!busy&&tcount>5)
{
char far *p;
union REGS r;
struct SREGS s;
p=scr;
*p+=6;
*p++=j;
*p++=0x4f;
j++;
busy = !busy;Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // mutex around tsr
start();
r.h.ah=0x5;
r.h.ch=0x51;Â Â Â //pagedown?
r.h.cl=0x0;
int86x(0x16,&r, &r, &s);
busy = !busy;
tcount=0;
}
tcount++;
}
else
dcount++;
}
void write_char(int x, int y, char ch, int attrib)
{Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // displays 1 character at (x,y)
char far *v;
v = (char far *) VIDMEM;
v += y*160 + x*2;
*v++ = ch;
*v = attrib;
}
void write_string(int x, int y, char *str, int attrib)
{Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // writes string str at (x,y)
for( ; *str; str++,x++)
write_char(x, y, *str, attrib);
}
int firsttime=0;Â Â Â Â Â Â Â //need to skip 3 lines after the first time we
//page down.
void start(void)
{
int fd,x,y;
char cr=0x0D, lf=0x0A;
old_dta=getdta();
setdta((char far *)MK_FP(_psp,0x80));
//if((fd =_open("c:\\temp\\log.txt",O_WRONLY))<0) // open the file
//Â Â Â Â Â Â Â if((fd =_creat("c:\\temp\\log.txt",_A_NORMAL))<0) // try to make new
//Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â write_string(1,1,"OOPS--write error1",0x8F);
if((fd =_open(fname,O_WRONLY))<0) // open the file
if((fd =_creat(fname,_A_NORMAL))<0) // try to make new
write_string(1,1,"OOPS--write error1",0x8F);
lseek (fd,0,SEEK_END);Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // jump to end of file
//for(y=0;y<25;y++)Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // grab lines 0 to 24
for(y=2+firsttime;y<24;y++)
{
//for(x=0;x<80;x++)Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // grab rows 0 through 79
for(x=1;x<79;x++)Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â //cut the bars from msl
if(_write(fd,(char far *)(VIDMEM+160*y+2*x),1)==-1)
write_string(1,2,"OOPS--write error2",0x8F);
if(_write (fd,&cr,1)==-1)Â Â Â Â Â Â Â Â Â Â Â Â Â Â // put a cr and lf at end
write_string(1,3,"OOPS--write error3",0x8F); // of line
if(_write (fd,&lf,1)==-1)
write_string(1,4,"OOPS--write error4",0x8F);
}
_close(fd);Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // close the file
setdta(old_dta);
if(firsttime==0)
firsttime=1;
}
Hopefully this will help someone in the distant future, maybe it’ll just serve as a warning on how not to build stuff … lol
Oh and I used Borland C++ 3.1, but compiled this as C for the LARGE memory model.