Thursday, June 20, 2019

CP/M - screen saver / screen lock

Our precious vintage CP/M machines aren't getting any younger. The same goes for CRT displays. If you are a CP/M programmer, you may be in need of a utility program which will either blank the screen or display random content on the screen to prevent the burnout while you are away from the console taking a break from your project. You may also want a password protected screen lock function with it to protect your precious code from prying eyes.

Here I present something I created out of my own need.
In the process I learned a bit of CP/M system programming in C.

Some interesting problems that I needed to solve due to deficiencies in the standard library of Aztec C 1.05 compiler:

- generating random numbers
- non-blocking keyboard reading
- reading time from the system
- direct cursor addressing

long next = 1;
/*
* Aztec C 1.05 doesn't have random generator in the library of functions.
* Here is something I found on the internet.
* Will return value 0 - 32767.
*/
unsigned rand()
{
next = next * 1103515245 + 12345;
return (unsigned)(next / 65536) % 32768;
}
/*
* Clear the screen (ADM31).
*/
BlankScr()
{
putchar(ESC);
putchar('*');
}
/*
* Cursor positioning (absolute cursor addressing) for ADM31.
*/
GotoXY(col, row)
char col, row;
{
putchar(ESC);
putchar('=');
putchar(' '+row);
putchar(' '+col);
}
/*
* Non-blocking character input.
* Return 0 if no character is waiting.
* return a character without echoing if one is waiting.
*/
int KeyPress()
{
return (bdos (0x06, 0xFF));
}
/*
* Get date / time (for rand seed initialization).
* Returns # of seconds (packed BCD), tptr - address of time stamp.
* The format of time stamp:
* DW day ;Day 1 is Jan 1-st 1978
* DB hr ;Packed BCD
* DB min ;Packed BCD
*/
int GetDtTm(tptr)
int *tptr;
{
return (bdos (0x69, tptr));
}
/*
* Get time string in format hh:mm:ss
*/
char *GetTimeStr()
{
long dtm;
char buf[10], hr[3], min[3];
int sec;
static char ret[10];
clear(buf, 10, 0);
clear(ret, 10, 0);
hr[2] = 0;
min[2] = 0;
sec = GetDtTm(&dtm);
sprintf(buf, "%08x", dtm >> 16);
strncpy(hr, buf+6, 2);
strncpy(min, buf+4, 2);
sprintf(ret, "%s:%s:%02x", hr, min, sec);
return (ret);
}

Program is short and well commented.

Enjoy!

MK'6/20/2019