/* LoadMeterIO.c
Stewart, January 12, 1984 2:29 PM, created
*/
#include "LoadMeter.h"
#define Disarm 0x00c0
#define SetLow 0x00e0
#define SetHigh 0x00e8
#define SetPointer 0x0000
#define Load 0x0040
#define Arm 0x0020
#define Save 0x00a0
#define SetPointerHold 0x0010
/* external variables */
extern int IPIO[2];
extern int ITimer[2];
/* local variables */
int rtc;
int oldClock;
int saved[3];
/* IO routines */
InitLMIO()
{
PortStr(IPIO);
PortStr(ITimer);
saved[0] = saved[1] = saved[2] = 0;
};
SetLeds(table, mode)
int table[], mode;
{
Bit(table[0], false);
Bit(table[1], false);
Bit(table[2], false);
Bit(table[3], false);
Bit(table[mode], true);
};
Bit(id, on)
int id, on;
{
int port, bp;
bp = id >> 8;
switch (bp) {
case 0: port = lmpioa; break;
case 1: port = lmpiob; break;
case 2: port = lmpioc; break;
default: return;
};
id &= 0x00ff;
if (on) saved[bp] |= id;
else saved[bp] &= (id ↑ 0x00ff);
OutByte(port, saved[bp]);
};
/* switch is a switch id from LoadMeter.h */
int GetSwitch(swi)
int swi;
{
swi = (InByte(lmpiob) >> swi) & 3;
return((swi == 1) ? true : false);
};
int GetClock()
{
return(GetCounter(5));
};
int GetPPS()
{
return(GetCounter(3));
};
int GetBPS()
{
return(GetCounter(4));
};
int GetCounter(counter)
int counter;
{
/* save the count value in the hold register
set the data pointer to the particular hold register
read the low and high bytes of the hold register
*/
OutByte(lmTimCtl, Save + (1 << (counter - 1)));
OutByte(lmTimCtl, SetPointerHold + counter);
counter = InByte(lmTimData) & 0x00ff;
counter |= InByte(lmTimData) << 8;
return(counter);
};
/* meter is either:
meterBPS: The bits/second meter
meterPPS: The packets/second meter
actually, meter is the timer channel, IN[1..5] !
value is IN [0..1000] which is 0 to 100% in .1 % steps
*/
SetMeter(meter, value)
int meter, value;
{
int meterBit;
if (value > 1000) return;
if (value < 0) return;
if (meter > 5) return;
if (meter < 1) return;
meterBit = (1 << (meter - 1));
if (value == 0) {
/* disarm timer and set the output low */
OutByte(lmTimCtl, Disarm + meterBit);
OutByte(lmTimCtl, SetLow + meter);
return;
};
if (value == 1000) {
/* disarm timer and set the output high */
OutByte(lmTimCtl, Disarm + meterBit);
OutByte(lmTimCtl, SetHigh + meter);
return;
};
/* the input to the timer channel is 5 MHz, the output
will be 5 KHz. The time low and the time high should
add up to 1000. value is the time high.
*/
OutByte(lmTimCtl, Disarm + meterBit); /* disarm */
OutByte(lmTimCtl, SetLow + meter); /* set output low */
OutByte(lmTimCtl, SetPointer + meter); /* set data pointer to counter group for meter */
OutByte(lmTimData, 0x0062); /* mode J, toggle out */
OutByte(lmTimData, 0x001b); /* clock F1 */
OutByte(lmTimData, (1000 - value) & 0x00ff); /* low lsb */
OutByte(lmTimData, (1000 - value) >> 8); /* low msb */
OutByte(lmTimData, value & 0x00ff); /* high lsb */
OutByte(lmTimData, value >> 8); /* high msb */
OutByte(lmTimCtl, Load + meterBit); /* load */
OutByte(lmTimCtl, Arm + meterBit); /* arm */
};
PollClock()
{
int clock;
clock = GetClock();
rtc += UpdateModFK(oldClock, clock);
oldClock = clock;
};
/* Utilities */
/* set the timer to expire at time now plus interval */
STimer(interval, timer)
int interval, *timer;
{
PollClock();
*timer = rtc;
*timer += interval;
};
/* returns boolean if timer has expired */
int Expired(timer)
int *timer;
{
PollClock();
if ((rtc - *timer) < 0) return(false);
return(true);
};
/* add a certain amount to the timer */
AddTimer(increment, timer)
int increment, *timer;
{
*timer += increment;
};
int UMin(a, b)
int a, b;
{
return((Ugt(a, b)) ? b : a);
};
int UpdateModFK(old, new)
int old, new;
{
int inc;
if (new > old) inc = old + (0x4000 - new);
else inc = old - new;
return(inc);
};
int ModN(n, lim)
int n, lim;
{
if ((n < 0) || (n >= lim)) return(0);
n += 1;
if (n == lim) return(0);
return(n);
};
CycleFive(modep, boolp)
int *modep, *boolp;
{
if (*boolp) {
*boolp = false;
*modep = 0;
};
else {
if (*modep == 3) *boolp = true;
else *modep = ModN(*modep, 4);
};
};
int Clip(low, val, high)
int low, val, high;
{
if (Ugt(low, val)) return(low);
if (Ugt(val, high)) return(high);
return(val);
};