home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_2.iso
/
files
/
813b.lha
/
IdleLed_v2.0
/
IDLE_LED.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-28
|
3KB
|
127 lines
/*
Program: Idle Led
Version: 2.0a 26/10/93
Author: Lindsay Meek (meek@fizzy.csu.murdoch.edu.au)
Description: Whenever the CPU is busy, the power led goes on else it is off.
This is the second version that operates by attaching itself
to the vertical blanking interrupt. A low priority (-127)
task is active which increments a counter and turns off the
light. When this task does not run, the vblank irq detects
the non-incrementing counter and turns the light on.
This version is more system friendly than 1.0
The CPU must be busy for more than 1 vbi for the
light to activate
*/
#include <exec/nodes.h>
#include <exec/tasks.h>
#include <exec/interrupts.h>
#include <hardware/cia.h>
#include <hardware/custom.h>
#include <hardware/intbits.h>
#include <libraries/dos.h>
struct Task *FindTask(char *);
extern void IdleIrq(void);
/* various counters used to detect the idle state in the vblank */
ULONG idle_vbi_cnt_limit[3];
/* Run this as a process. It aborts when it detects a CTRL_C signal */
main(int argc,char **argv)
{
struct Task *met;
struct Interrupt mei;
BYTE oldpri;
mei.is_Node.ln_Type = NT_INTERRUPT;
mei.is_Node.ln_Pri = -127;
mei.is_Node.ln_Name = "Idle-Led-Off";
mei.is_Data = (APTR)idle_vbi_cnt_limit;
mei.is_Code = IdleIrq;
/* reset counter,last state */
AddIntServer(INTB_VERTB, &mei); /* Install IRQ server */
met=FindTask(NULL); /* Fetch this tcb */
oldpri=met->tc_Node.ln_Pri; /* Save old priority */
met->tc_Node.ln_Pri=40; /* Raise priority for calibration */
idle_vbi_cnt_limit[0]=0;
idle_vbi_cnt_limit[1]=0;
idle_vbi_cnt_limit[2]=0;
/* wait for next vbi */
while(idle_vbi_cnt_limit[0]==0) ;
/* count # of increments in one frame (for calibration) */
idle_vbi_cnt_limit[0]=0;
idle_vbi_cnt_limit[2]=0;
while(idle_vbi_cnt_limit[0] == 0)
idle_vbi_cnt_limit[2]++;
/* > 50 % load is busy */
idle_vbi_cnt_limit[2] /= 2;
met->tc_Node.ln_Pri=-127; /* Make priority VERY low for idle */
/* Busy loop for eating idle cpu cycles */
while((met->tc_SigRecvd & SIGBREAKF_CTRL_C)==0) /* Abort on CTRL_C */
{
/* Increment idle counter */
idle_vbi_cnt_limit[1]++;
}
RemIntServer(INTB_VERTB,&mei); /* Remove IRQ server */
met->tc_Node.ln_Pri=oldpri; /* Change priority back */
/* Turn on power light */
ciaa.ciapra &= -1-CIAF_LED;
return 0;
}
#asm
;
;Assembly section for vertical blanking interrupt server
;
;You may have to put this into a seperate .asm file and compile to get it working
;with your C compiler
;
include "hardware/cia.i"
_ciaa = $bfe001 ;i defined it here so i could use the small model!
public _IdleIrq
_IdleIrq:
addq.l #1,(a1)+
move.l (a1),d0 ;idle_cnt
clr.l (a1)+ ;=0
cmp.l (a1),d0 ;>=idle_limit
bge.s _IdleIrq1 ;yes - then its idle
bclr.b #CIAB_LED,_ciaa+ciapra ;turn on power light (cpu is busy)
moveq #0,d0 ;permit other servers to execute
rts
_IdleIrq1:
bset.b #CIAB_LED,_ciaa+ciapra ;turn off power light (cpu is idle)
moveq #0,d0 ;permit other servers to execute
rts
#endasm