Clipper Head needs help!

R

Rob

Hi,
I have been asked by a customer to try to resurrect a rather ancient
application their organisation uses that was written in Clipper.
This I am fine with. However, there is a module that was written in C. I
do not have a C compiler and was wondering if one of you fine people could
compile it into an .obj file so that I can link it in with the rest of the
Clipper .objs? If someone could, I would forever be in their debt and, if
they're ever on the Sunshine Coast in Australia, I'll buy them a beer!

This is the line in the .mak file:

cl /c /AL /Zl /Oalt /FPa /Gs /Tc$*.ccl

As you can see they refer to it as a .ccl file....

And this is the code:


#include "extend.h"
#include "bios.h"
#include "stdio.h"
#include "time.h"
#define Ignore
/* #define Debug */

/*ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
Í
Updated : 14/02/92 - 13:00
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ*
/
/* Port A
bits 1 to 4 for lamps
*/
#define AUDIO_BIT 5 /* Chime Activate */
#define PAG_TRX 6 /* Pager Transmitter Bit */
#define PAG_DAT 7 /* Pager Data bit */

#define PGR_AMBMAX 17 /* Maximum Amble Bytes */
#define PGR_BATMAX 17 /* maximum codewords in
batch */
#define PGR_BLKMAX 200 /* maximum number of blocks
*/
#define PGR_PREAMB 0xAAAAAAAA /* Preamble 10101010 */
#define PGR_SYNC 0x7CD215D8 /* Sync Codeword */
#define PGR_IDLE 0x7A89C197 /* Idle Codeword */

/* Port B
*/
#define PUL_BIT 0 /* bit 0 pulse bit */
#define FRQ_BIT 1 /* transmission frequency */
#define PUL_CNT 5 /* chime pulse count */


unsigned long check_sum (unsigned long);
void chim_delay (void);
void coms_init (int);
void coms_unit (unsigned, unsigned);
char *form_date (time_t);
void pagr_addablock (unsigned long);
void pagr_createadd (unsigned long, unsigned long);
void pagr_createamb (int);
void pagr_createmes (void);
void pagr_padbatch (void);
unsigned long parity_even (unsigned long);
void send_pagrblocks (void);


static char pgr_mess[100]; /* pager message buffer
*/
static int com_baud_rate = 1200, /* default baud rate */
com_tx_delay = 100, /* default tx delay */
com_ch_count = 2 * PUL_CNT, /* default chime count
*/
io_byte = 0, /* Port A: Control byte
*/
pgr_bit = (1 << PAG_DAT), /* Pager Bits */
pgr_bitI = (0xff ^ (1 << PAG_DAT)),
pgr_trx = (1 << PAG_TRX), /* Transmitter Bits */
pgr_trxI = (0xff ^ (1 << PAG_TRX)),
chm_bit = (1 << PUL_BIT), /* chime pulses */
frq_trx = (1 << FRQ_BIT), /* frequency for trans.
*/
frq_old = 0; /* last value */
pgr_blocks_ptr = 0, /* block buffer pointer
*/
pgr_blocks_cnt = 0, /* block counter */
mss_cnt = 0; /* message counter */
static unsigned long pgr_blocks[PGR_BLKMAX], /* 32 bit blocks buffer
*/
nxt_bit = (1 << 31); /* bit 31 first */
static time_t lTime; /* time of day */
static unsigned com_command_byte = 155, /* default coms. set */
com_port = 0, /* com1=0, com2=1, etc
*/
com_tx_stat = 0, /* transmission status
*/
com_rx_stat = 0, /* receive status */
com_rx_address, /* received address */
com_rx_data, /* received data byte */
io_base_add = 0x1b0, /* io card address */
io_port_b = 0x1b1; /* io card address + 1
*/

/***************************************************************************
*
Clipper interface functions.
/***************************************************************************
/

CLIPPER chime ()
{
io_byte |= (1 << AUDIO_BIT); /* turns chime on */
outp(io_base_add, io_byte);
chim_delay();
io_byte &= (0xff ^ (1 << AUDIO_BIT)); /* turns chime off */
outp(io_base_add, io_byte);
}

CLIPPER lamp_on ()
{
int lamp_num = 0;

if (_parinfo(1) == NUMERIC) {
lamp_num = _parni(1);
if (lamp_num > 0 && lamp_num < 6) {
lamp_num --;
io_byte |= (1 << lamp_num);
outp(io_base_add, io_byte);
}
}
}

CLIPPER lamp_off ()
{
int lamp_num = 0;

if (_parinfo(1) == NUMERIC) {
lamp_num = _parni(1);
if (lamp_num > 0 && lamp_num < 6) {
lamp_num --;
io_byte &= (0xff ^ (1 << lamp_num));
outp(io_base_add, io_byte);
}
}
}

CLIPPER pager_mess ()
{
if (mss_cnt == 0) {
pagr_createamb(PGR_AMBMAX); /* create preamble block */
pgr_blocks_cnt = PGR_BATMAX; /* initialise batch count */
}
pagr_createmes();
mss_cnt ++;
}

CLIPPER pager_send ()
{
io_byte |= pgr_trx; /* transmitter on */
outp(io_base_add, io_byte);
send_pagrblocks(); /* send all blocks */
io_byte &= pgr_bitI; /* Clear Data Line */
io_byte &= pgr_trxI; /* transmitter off */
outp(io_base_add, io_byte);
mss_cnt = 0;
}

CLIPPER poll_set ()
{
int iBaud = 1200; /* default rate setting */

if (_parinfo(1) == NUMERIC) {
iBaud = _parni(1);
}
if (_parinfo(2) == NUMERIC) {
com_tx_delay = _parni(2);
}
if (_parinfo(3) == NUMERIC) {
io_base_add = (unsigned) _parni(3);
io_port_b = io_base_add + (unsigned) 1;
}
if (_parinfo(4) == NUMERIC) {
com_ch_count = (unsigned) _parni(4) * PUL_CNT;
}

/* Set i/o Control Reg : Mode 0 - A Out - B In - Cmsb Out - Clsb In
*/
io_byte = 0; /* all = low */
outp(io_base_add+3, 0x83);
outp(io_base_add+0, io_byte); /* A low */
outp(io_base_add+2, 0); /* C low */

coms_init(iBaud); /* initialise serial port settings
*/
_retnl((long) com_tx_stat); /* return setup status */
}

CLIPPER poll_stat ()
{
_storc(form_date(lTime), 1);
_stornl((long) (com_rx_address & (unsigned) 0x7f), 2);
_stornl((long) com_rx_data, 3);
_stornl((long) com_rx_stat, 4);
}

CLIPPER poll_unit ()
{
int unit_num = 0, unit_data = 0;

if (_parinfo(1) == NUMERIC) {
unit_num = _parni(1);
}
if (_parinfo(2) == NUMERIC) {
unit_data = _parni(2);
}
coms_unit((unsigned) unit_num, (unsigned) unit_data);
_retnl((long) com_tx_stat);
}

CLIPPER time_stamp ()
{
static time_t lCurTime; /* time variable */
time(&lCurTime); /* get date/time */
_storc(form_date(lTime), 1); /* return as formatted string */
}

/***************************************************************************
*
C sub functions for above.
/***************************************************************************
/

unsigned long check_sum (ulBlock)
unsigned long ulBlock;
{
int iCnt = 31;
unsigned long ulCheckSum = 0;
while (iCnt --) {
ulCheckSum <<= 1; /* bring next bit down */
if ((ulBlock & 0x80000000) == 0x80000000) {
ulCheckSum |= 1;
}
ulBlock <<= 1; /* done */
if ((ulCheckSum & 0x400) == 0x400) { /* one yet ? */
ulCheckSum ^= 0x769; /* use divisor */
}
} /* repeat until done */
ulCheckSum <<= 1; /* leave room for parity */
return (ulCheckSum);
}

void chim_delay ()
{
int iCnt = 0;
unsigned uAdd = 0;


uAdd = io_base_add;
uAdd ++; /* +1 for for port B */
while (iCnt < com_ch_count) {
while ((inp(uAdd) & chm_bit) != chm_bit) {
}
while ((inp(uAdd) & chm_bit) == chm_bit) {
}
iCnt ++;
}
}

void coms_init (iBaud)
int iBaud;
{
com_command_byte = _COM_CHR8 | _COM_STOP1 | _COM_EVENPARITY;
if (iBaud == 110) {
com_command_byte |= _COM_110;
}
else if (iBaud == 150) {
com_command_byte |= _COM_150;
}
else if (iBaud == 300) {
com_command_byte |= _COM_300;
}
else if (iBaud == 600) {
com_command_byte |= _COM_600;
}
else if (iBaud == 1200) {
com_command_byte |= _COM_1200;
}
else if (iBaud == 2400) {
com_command_byte |= _COM_2400;
}
else if (iBaud == 4800) {
com_command_byte |= _COM_4800;
}
else if (iBaud == 9600) {
com_command_byte |= _COM_9600;
}
else { com_command_byte |= _COM_1200; /* default to 1200 Baud
*/
}
com_tx_stat = _bios_serialcom(_COM_INIT, com_port,
com_command_byte);
}

void coms_unit (uUnit, uData)
unsigned uUnit, uData;
{
int nDelay;

nDelay = com_tx_delay; /* set tx delay */
com_tx_stat = _bios_serialcom(_COM_SEND, com_port, uUnit);
while (nDelay -- > 0) {
}
com_tx_stat = _bios_serialcom(_COM_SEND, com_port, uData);

com_rx_address = _bios_serialcom(_COM_RECEIVE, com_port, uData);
com_rx_data = _bios_serialcom(_COM_RECEIVE, com_port, uData);
com_rx_stat = _bios_serialcom(_COM_STATUS , com_port, uData);
time(&lTime); /* save dat and time for accuracy */
}

char *form_date (l_time)
time_t l_time;
{
struct tm *newtime;
static char tim[30];

newtime = localtime(&l_time);
strcpy(tim, asctime(newtime));
tim[24] = ' ';
tim[25] = '\0';
return (tim);
}

void pagr_addablock (ulBlock)
unsigned long ulBlock;
{
if (pgr_blocks_cnt >= PGR_BATMAX) { /* sync needed ? */
pgr_blocks[pgr_blocks_ptr] = PGR_SYNC;
pgr_blocks_ptr ++;
pgr_blocks_cnt = 1;
}
/*
printf("Add A Block %3i : %8lx : %3i :\n", pgr_blocks_ptr, ulBlock,
pgr_blocks_cnt);
while ( ! kbhit());
getch();
*/
pgr_blocks[pgr_blocks_ptr] = ulBlock;
pgr_blocks_ptr ++;
pgr_blocks_cnt ++;
}

void pagr_createadd (ulPagId, ulFunc)
unsigned long ulPagId, ulFunc;
{
char *cPtr;
int iCnt = 8, iBitCnt, iChar;
unsigned long ulCodeWord, ulFrame, ulTmp;

ulFrame = ulPagId & 0x7; /* last 3 bits = frame */
ulCodeWord = ulPagId & 0xFFFFFFF8; /* get 18 sig. bits */
ulCodeWord <<= 10; /* shift left 10 */
ulCodeWord &= 0x7FFFF800; /* set top bit to 0 */
ulFunc &= 0x3; /* get last 2 bits */
ulFunc <<= 11; /* move to bits 20, 21 */
ulCodeWord |= ulFunc; /* add to code word */
ulCodeWord |= check_sum(ulCodeWord); /* checksum it */
ulCodeWord |= parity_even(ulCodeWord); /* even parity it */

while (ulFrame --) {
pagr_addablock(PGR_IDLE);
pagr_addablock(PGR_IDLE);
}
pagr_addablock(ulCodeWord); /* put in address */

iBitCnt = 20; /* 20 to do */
ulFrame = (unsigned) 1; /* message bit */
cPtr = pgr_mess; /* start of message */

while (*cPtr) {
iChar = *cPtr;
iCnt = 7; /* 7 bits to get */
while (iCnt --) {
ulTmp = (unsigned long) (iChar & 1); /* get bit
*/
if (iBitCnt < 1) {
ulFrame <<= 11; /* move to
position */
ulFrame |= check_sum(ulFrame);
ulFrame |= parity_even(ulFrame);
pagr_addablock(ulFrame);
iBitCnt = 20; /* reset count */
ulFrame = (unsigned) 1; /* message bit */
}
ulFrame <<= 1; /* shift data left
*/
ulFrame |= ulTmp; /* add bit */
iBitCnt --; /* one done */
iChar >>= 1; /* shift char right
*/
}
cPtr ++; /* next char */
}
/* when end of message arrives will contain eot's only */
/* so when can ignore last data block */
}

void pagr_createamb (iCnt)
int iCnt;
{
pgr_blocks_ptr = 0; /* clear table */
while (iCnt --) { /* create block */
pgr_blocks[pgr_blocks_ptr] = PGR_PREAMB;
pgr_blocks_ptr ++;
}
}

void pagr_createmes () /* gets stuff from clipper */
{
char *mess, *ptr;
int len;
long pag_id, pag_func;

if (_parinfo(1) == CHARACTER) {
mess = _parc(1); /* mess */
len = (int) _parclen(1); /* length */
ptr = pgr_mess;
while (len > 0) { /* transfer to buff
*/
*ptr ++ = *mess ++;
len --;
}
len = 4;
while (len > 0) { /* add 4 bytes of
eot */
*ptr ++ = '\4';
len --;
}
*ptr = '\0';
if (_parinfo(2) == NUMERIC) {
pag_id = _parnl(2); /* get pager id # */
if (_parinfo(3) == NUMERIC) {
pag_func = _parnl(3); /* get tone type */
pagr_createadd((unsigned long) pag_id, (unsigned long)
pag_func);
pagr_padbatch(); /* fill rest of
batch with idle */
}
}
}
}

void pagr_padbatch ()
{
while (pgr_blocks_cnt < PGR_BATMAX) { /* need a full batch
*/
pgr_blocks[pgr_blocks_ptr] = PGR_IDLE;
pgr_blocks_ptr ++;
pgr_blocks_cnt ++;
}
}

unsigned long parity_even (lBlock)
unsigned long lBlock;
{
int iCnt = 0; /* bit counter */
unsigned long lCnt = 0x0; /* parity count */

while (iCnt < 31) { /* 31 to do */
if ((lBlock & 0x80000000) == 0x80000000) {
lCnt ++; /* count one's */
}
lBlock <<= 1; /* shift left one bit */
iCnt ++; /* count it */
} /* and again */
lCnt &= 0x1; /* if odd - parity 1 */
return (lCnt); /* return for or'ing */
}

void send_pagrblocks ()
{
int iCnt = 0, /* bit count */
iFlgCur = 0,
iFlgNew = 0;
int iBlkCnt = 0;
unsigned long lBlock, *lBlkPtr;

iBlkCnt = pgr_blocks_ptr;
lBlkPtr = pgr_blocks;
frq_old = (inp(io_port_b) & frq_trx); /* get current state */
while (iBlkCnt --) {
iCnt = 32;
lBlock = *lBlkPtr;
while (iCnt --) { /* 32 to do */
iFlgCur = ((io_byte & pgr_bit) == pgr_bit);
iFlgNew = ((lBlock & nxt_bit) == nxt_bit);
if (iFlgNew) { /* output bit */
io_byte |= pgr_bit; /* Logic 1 */
}
else { io_byte &= pgr_bitI; /* Logic 0 */
}
while ((inp(io_port_b) & frq_trx) == frq_old) {
} /* wait for change */
frq_old = (inp(io_port_b) & frq_trx); /* save it
*/
outp(io_base_add, io_byte);
lBlock <<= 1; /* shift left one bit */
} /* and again */
lBlkPtr ++;
}
}

--

TIA,

Rob Grattan
R&D Software Pty. Ltd.
 
A

Arthur J. O'Dwyer

I have been asked by a customer to try to resurrect a rather ancient
application their organisation uses that was written in Clipper.
This I am fine with.

(Good, because Clipper [whatever it is] ain't topical here. The only
Clipper I've ever heard of was a U.S. government push for crypto
backdoors in computers - never got off the ground, at least overtly.)
However, there is a module that was written in C. I
do not have a C compiler and was wondering if one of you fine people could
compile it into an .obj file so that I can link it in with the rest of the
Clipper .objs?

No, nobody can. Reason: your compiler and linker system may be
*radically* different from anybody else's. Probably are, too, if
they are more than a decade old. While I *could* compile this code
with Turbo C and send you the object file, it wouldn't do you any good
because TCC only works on MS-DOS-based systems and uses Borland linking
conventions, whereas for all I know you're using VMS.
This is the line in the .mak file:

cl /c /AL /Zl /Oalt /FPa /Gs /Tc$*.ccl

Tells us absolutely nothing except that you're probably not using *nix
or the Borland system I mentioned above (which doesn't use the extension
..mak, last I checked).
As you can see they refer to it as a .ccl file....

I'd be willing to bet that .CCL stands for something CLipper.
Does your system have a C compiler?
And this is the code:

#include "extend.h"
#include "bios.h"
#include "stdio.h"
#include "time.h"
#define Ignore
/* #define Debug */

Really, nobody is going to compile this for you. As I pointed out,
even if this were standard C code (which it isn't), that wouldn't
help you fix your problem. And of course, the very first line tries
to #include a header that doesn't exist on any of the machines I've
ever used. Certainly not a standard header.
CLIPPER chime ()

And this is just silly. What's a CLIPPER? Even if someone else *did*
magically have the same compiler system that you did, this wouldn't
compile, because you haven't defined CLIPPER anywhere that I can see.
(I did skip a lot of junk, though - maybe I missed it.)

My best advice to you is to look in the company directory for the
oldest people in your department, and ask whether they remember
who wrote this pile of junk. Then phone that guy and ask him how
*he* compiled it originally.

-Arthur
 
R

Richard Bos

Arthur J. O'Dwyer said:
I have been asked by a customer to try to resurrect a rather ancient
application their organisation uses that was written in Clipper.
This I am fine with.

(Good, because Clipper [whatever it is] ain't topical here. The only
Clipper I've ever heard of was a U.S. government push for crypto
backdoors in computers - never got off the ground, at least overtly.)

It's a compiler XBase language.
Tells us absolutely nothing except that you're probably not using *nix
or the Borland system I mentioned above (which doesn't use the extension
.mak, last I checked).

Correct. Clipper needs a M$C compiler - that is, the text and simple
data moving thingies can use any .obj-compatible compiler, but the
floating point formats are M$'s.
My best advice to you is to look in the company directory for the
oldest people in your department, and ask whether they remember
who wrote this pile of junk.

Don't be a jerk. Just because it's specialised doesn't mean it's a load
of junk or geriatric. It's merely very system-specific and off-topic.
You'd be surprised at how many people still put Clipper to good use
every day of the week.

Rob: ask in comp.lang.clipper. They'll know exactly what you need, and
may be able to compile this for you. Arthur is right in so far that
comp.lang.c discusses ISO C only - comp.lang.clipper discusses
everything to do with Clipper. It can afford to, since Clipper is rather
more specialised than C.

Richard
 
R

Rob

Richard,
Thanks for your answer. I thought for a moment that everyone on this NG was
going to be as grumpy and unhelpful as Arthur! Just thought I'd try here
first as I assumed all the C knowledge on the planet would be available to
me...

Arthur - sorry for annoying you - I'll leave this NG immediately.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top