[Icc-avr] simple taskswitcher inc
BobGardner at aol.com
BobGardner at aol.com
Sat Apr 30 16:35:14 PDT 2005
Skipped content of type multipart/alternative-------------- next part --------------
//file taskswitcher32.c
//try to write a task switcher in c for ere co mega32
//16Mhz xtal, 38400 baud
//Apr 23 05 Bob G iitial edit
//Apr 24 05 Bob G
//todo: fp, rf
//save joycal in eeprom
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <macros.h>
#include <iom32v.h>
#define INTR_OFF() asm("CLI")
#define INTR_ON() asm("SEI")
//---ascii equates----------------
#define ESC 0x1b
#define CTLQ 0x11
#define CR 0x0d
#define LF 0x0a
#define PWMMAX 31
//----externs--------
extern void init_devices(void);
extern int _textmode;
//----struct used for rolling average------
#define NUMSAMP 8
typedef struct{
char ndx;
long int tot;
int avg;
int dat[NUMSAMP]; //avg over NUMSAMP readings
}Trollavg;
//------vars in bss-------
Trollavg rollavg[8];
unsigned int addat[8]; //internal 10 bit
unsigned char dispon;
unsigned char *pt;
unsigned char *pf;
unsigned char c;
signed char ch1,ch2,ch3,ch4; //+-32
unsigned char tics,ticsl;
unsigned int tocs,tocsl;
unsigned char os100ms;
unsigned char os1sec;
unsigned char hr,min,sec;
unsigned int left,fwd,back,right; //joystick
int fwdrise,fwdrun,backrise,backrun;
int leftrise,leftrun,rightrise,rightrun;
int fwdcen,leftcen;
int turnangdem; //+-45 deg
int turnangpos; //+-45 deg
int turnspddem; //speed demand due to turning
int throtpct; //+-100
int os100msaccum;
int os1secaccum;
int deltatms;
int deltattocs;
int deltatmsoff;
//int frntdem,frntpos,frnterr,reardem,rearpos,rearerr; //deg
//int frnterrl,rearerrl;
//------rom---------
const unsigned char banner[]={"taskswitcher32 Apr 23 05\n"};
//-------------------
void delnms(int n){
//delay n ms
int x;
while(n--){
// x=2400; //empirically determined fudge factor 14.7456 mhz
x=2600; //empirically determined fudge factor 16 mhz
// x=3000; //empirically determined fudge factor 18.432 mhz
while(x--);
}
}
//-------------------------
void initvars(void){
//init vars
fwdrun=1023;
leftrun=1023;
fwdcen=512;
leftcen=512;
back=0;
fwd=1023;
left=0;
right=1023;
fwdrun=back-fwd;
leftrun=left-right;
fwdrise= 200; //+-100
leftrise= 90; //+-45
}
//------RS232-----------------
unsigned char kbhit(void){
//return nonzero if char waiting polled version
unsigned char b;
b=0;
if(UCSRA & (1<<RXC)) b=1;
return b;
}
//-----------------------
int getchar(void){
//polled version...
unsigned char c;
while(!kbhit()){}; //wait for char
c=UDR; //get char from usart
return c;
}
//-----------------------
int putc(char c){
//put char to usart0... dont add lf after cr
while((UCSRA & 0x20)==0){}; //0x20 is UDRE0. ==0 means data register full
UDR=c; //send char
return c;
}
//----------------------
int putchar(char c) {
//adds lf after cr
if(c=='\n'){
putc('\r');
}
putc(c);
return c;
}
//------------------
void crlf(void){
//output cr then lf
putchar('\n');
}
//------------
void space(void){
//output a space
putc(' ');
}
#define ESC 0x1b
//----------------------
void gotoxy(int x, int y){
//ansi cursor positioning sequence E[y;xH
putc(ESC);
putc('[');
cprintf("%d",y);
putc(';');
cprintf("%d",x);
putc('H');
}
//-------------------------
unsigned char getche(void){
//get and echo a char from rs232
char c;
c=getchar();
putchar(c);
return(c);
}
//----------------------
void clrscr(void){
//clear ansi terminal screen
putc(ESC);
putc('[');
putc('2');
putc('J');
}
//------------------
void initscreen(void){
//clear screen and print banner
clrscr();
cprintf(banner);
}
#if 0 //used instead of printf with modifiers
//----------------------
void putnibhex(unsigned char c){
//output bin nib c in hex
c+=0x30; //cvt to ascii
if(c > 0x39) c+=7; //handle a-f
putc(c);
}
//-----------------------
void putbytehex(unsigned char c){
//output c as 2 hex chars
unsigned char nib;
nib=(c & 0xf0) >>4;
putnibhex(nib);
nib=c & 0x0f;
putnibhex(nib);
}
//-----------------------
void putwordhex(unsigned int w){
//output w as 4 hex chars
putbytehex(w >> 8); //hi byte
putbytehex(w); //lo byte
}
#endif
//------debug subs-----------
void dump256ram(unsigned char *n){
//dump 16 rows of 16 bytes
unsigned char r,c,ch;
unsigned char *p;
unsigned char *pa;
p=n;
crlf();
cprintf(" ");
for(c=0; c<16; c++){
cprintf("%02x ",c); //header
if(c==7) space();
}
crlf();
crlf();
for(r=0; r<16; r++){
cprintf("%04x ",p); //print addr at beg of line
pa=p; //remember p for ascii
for(c=0; c<16; c++){
cprintf("%02x ",*p++); //print hex
if(c==7) space();
}
for(c=0; c<16; c++){
ch=*pa++;
if((ch > 0x20) && (ch !=0x0a) && (ch != 0x8a)) //if printing char
putc(ch); //print ascii
else
putc('.');
if(c==7) space();
}
crlf();
}
}
//-------------------------
void dump256rom(const unsigned char *n){
//dump 16 rows of 16 bytes
unsigned char r,c,ch;
const unsigned char *p;
const unsigned char *pa;
p=n;
crlf();
cprintf(" ");
for(c=0; c<16; c++){
cprintf("%02x ",c); //header
if(c==7) space();
}
crlf();
crlf();
for(r=0; r<16; r++){
cprintf("%04x ",p); //print addr at beg of line
pa=p; //remember p for ascii
for(c=0; c<16; c++){
cprintf("%02x ",*p++); //print hex
if(c==7) space();
}
for(c=0; c<16; c++){
ch=*pa++;
if((ch > 0x20) && (ch !=0x0a) && (ch != 0x8a)) //if printing char
putc(ch); //print ascii
else
putc('.');
if(c==7) space();
}
crlf();
}
}
//-------------------------
unsigned char gethex(void){
//return a hex char from rs232
unsigned char b,c;
b=0xff; //error return value
c=toupper(getche());
if(isxdigit(c)) b=c-0x30; //if c ok, cvt ascii digit to binary
if((c >= 'A') && (c <= 'F')) b-=7; //if c hexcvt ascii A to binary 10
return(b);
}
//---------------------------
unsigned char getbyte(void){
//get 2 nibbles, return a binary byte from rs232
unsigned char n1,n2;
n1=gethex();
n2=gethex();
return((n1 << 4) + n2);
}
//----------------------------
unsigned int getaddr(void){
//return addr from rs232
unsigned int th,tl;
th=getbyte();
tl=getbyte();
return((th << 8) + tl);
}
#if 0 //use these to input a dec number
//---------------------
unsigned char getdecdig(void){
//return decimal digit 0..9 from rs232
//return ff (-1) of non hex, like carriage return
unsigned char b,c;
b=0xff; //error return value
c=toupper(getche());
if(isdigit(c)) b=c-0x30; //if c ok, cvt ascii digit to binary
return(b);
}
//-----------------
void gets(char *p){
//get a string
char c;
do{
c=getche();
*p++=c;
}while(c !=0x0d);
p--; //roll p back
*p=0x00; //add null over cr
}
//-----------------------
unsigned char getnum(void){
//return number 0..255 from rs232 -1 to exit
char dig,n;
dig=getdecdig();
if(dig == -1) return dig;
n=dig;
// if(n>2) n=2;
dig=getdecdig();
if(dig == -1) return dig;
n=n*10+dig;
// if(n>25) n=25;
dig=getdecdig();
if(dig == -1) return dig;
n=n*10+dig;
if(n>255) n=255;
return(n);
}
#endif
//------------------
void examineram(void){
//ask for mem range in ram and dump
unsigned char *from;
unsigned char c;
cprintf("from:");
from=(unsigned char *)getaddr();
while(c!='q'){
dump256ram(from);
cprintf("np or q...");
c=getchar();
if(c=='n') from+=0x100;
if(c=='p') from-=0x100;
}
}
//------------------
void examinerom(void){
//ask for mem range in rom and dump
const unsigned char *from;
unsigned char c;
cprintf("from:");
from=(const unsigned char *)getaddr();
while(c!='q'){
dump256rom(from);
cprintf("np or q...");
c=getchar();
if(c=='n') from+=0x100;
if(c=='p') from-=0x100;
}
}
//------------------
void deposit(void){
//ask for addr and data
unsigned char *at;
unsigned char c;
unsigned char nh,nl;
cprintf("at:");
at=(unsigned char *)getaddr();
while(1){
cprintf(" %02x ",*at);
nh=gethex();
if(nh==0xff) return;
nl=gethex();
if(nl==0xff) return;
c=((nh << 4) | nl);
*at++=c;
}
}
//------------------
void fill(void){
//ask for mem range and fill char and fill
unsigned char *from, *to, with;
cprintf("from:");
from=(unsigned char *)getaddr();
cprintf(" to:");
to=(unsigned char *)getaddr();
cprintf(" with:");
with=getbyte();
memset(from,with,to-from);
}
//-----------------------------
void (* fn)(void); //fn prototype
void dojsr(void){
//ask for addr, jsr to it
const unsigned char *to;
cprintf(" to:");
to=(const unsigned char *)getaddr();
fn=(void *)to;
(*fn)(); //call function fn and returns
}
//------------------
void debugmenu(void){
//monitor cmds
cprintf("cmds:\n"
" e examine ram\n"
" c examine rom\n"
" d deposit\n"
" f fill\n"
" j jsr\n"
" q quit\n");
}
//------------------
void debugloop(void){
//examine and deposit mem regs
char c;
debugmenu();
while(c != 'q'){
crlf();
cprintf("cmd:");
c=getchar();
crlf();
switch(c){
case 'e': examineram(); break;
case 'c': examinerom(); break;
case 'd': deposit(); break;
case 'f': fill(); break;
case 'j': dojsr(); break;
default: debugmenu();
}
}
}
//----end of debug subs----------
//--------------------
void initrollavg(Trollavg *p){
//init rollavg struct
char i;
p->ndx=0;
p->tot=0;
p->avg=0;
for(i=0; i < NUMSAMP; i++){
p->dat[i]=0;
}
}
//--------------------
int calcrollavg(Trollavg *p, int w){
//return rollavg of last NUMSAMP readings
p->tot-=p->dat[p->ndx]; //subtract old value from tot
p->tot+=w; //add in new value
p->dat[p->ndx++]=w; //remember new value, bump ndx
if(p->ndx==NUMSAMP) p->ndx=0; //rewind
p->avg=p->tot >> 3; //2^3=8=NUMSAMP; avg is tot/NUMSAMP
return p->avg;
}
//---------------------
int readadchan(char n){
//read ch n of internal 10 bit a/d
ADMUX=n; //select channel n
asm("nop");
asm("nop"); //mux settle time?
ADCSRA |=0x40; //init conversion
while((ADCSRA & 0x40) !=0){}; //wait for conv complete
return ADC;
}
//--------------------
void read2ads(void){
//read 2 a/d channels
char n;
int tmp;
for(n=0; n < 2; n++){
tmp=readadchan(n);
addat[n]=calcrollavg(&rollavg[n],tmp);
}
}
//--------------------
void readadloop(void){
//read internal 10 bit ad 0-0x3ff 0..1023
char c,n;
int tmp;
cprintf("a/d\n");
cprintf("0 1 2 3 4 5 6 7 \n");
c=0;
while(c != 'q'){
if(kbhit()){
c=getchar();
}
for(n=0; n < 8; n++){
tmp=readadchan(n);
addat[n]=calcrollavg(&rollavg[n],tmp);
cprintf("%03x ",addat[n]);
}
cprintf("\r");
}
}
//-----------------
void joycal(void){
//calibrate
char c;
cprintf("joystick centered press a key\n");
while(!kbhit()){
read2ads();
cprintf("%5d %5d\r",addat[0],addat[1]);
delnms(5);
}
c=getchar();
if(c=='q') return;
crlf();
fwdcen=addat[0];
leftcen=addat[1];
cprintf("joystick fwd, press key\n");
while(!kbhit()){
read2ads();
cprintf("%5d\r",addat[0]);
delnms(5);
}
c=getchar();
if(c=='q') return;
crlf();
fwd=addat[0];
cprintf("joystick back, press a key\n");
while(!kbhit()){
read2ads();
cprintf("%5d\r",addat[0]);
delnms(5);
}
c=getchar();
if(c=='q') return;
crlf();
back=addat[0]; //big
cprintf("joystick right, press a key\n");
while(!kbhit()){
read2ads();
cprintf("%5d\r",addat[1]);
delnms(5);
}
c=getchar();
if(c=='q') return;
crlf();
right=addat[1];
cprintf("joystick left, press a key\n");
while(!kbhit()){
read2ads();
cprintf("%5d\r",addat[1]);
delnms(5);
}
c=getchar();
if(c=='q') return;
crlf();
left=addat[1];
fwdrun=fwd-fwdcen; //ad
backrun=fwdcen-back;
leftrun=leftcen-left;
rightrun=right-leftcen;
fwdrise= 100; //+-100 //pct
backrise= 100; //+-100
leftrise= 45; //+-45 //deg
rightrise= 45; //+-45
cprintf("fwdrise backrise leftrise rightrise\n");
cprintf("%8d %8d %8d %8d\n",fwdrise,backrise,leftrise,rightrise);
cprintf("fwdrun backrun leftrun rightrun\n");
cprintf("%8d %8d %8d %8d\n",fwdrun,backrun,leftrun,rightrun);
cprintf("fwdcen leftcen\n");
cprintf("%8d %8d\n",fwdcen,leftcen);
cprintf("press a key");
c=getchar();
}
//-------------------
void pwmclip(void){
//clip pwm dem to max
if(ch1 > PWMMAX) ch1= PWMMAX;
if(ch1 < -PWMMAX) ch1= -PWMMAX;
if(ch2 > PWMMAX) ch2= PWMMAX;
if(ch2 < -PWMMAX) ch2= -PWMMAX;
// if(ch3 > PWMMAX) ch3= PWMMAX;
// if(ch3 < -PWMMAX) ch3= -PWMMAX;
// if(ch4 > PWMMAX) ch4= PWMMAX;
// if(ch4 < -PWMMAX) ch4= -PWMMAX;
}
//----------------
void joycalc(void){
//compute turn angle +-45 and throt pct +-100
//outside wheel is twice as fast as inside wheel at full turn
if(addat[0] > fwdcen){
throtpct= fwdrise* ((long)addat[0]-fwdcen)/fwdrun; //0-100
}else{
throtpct= backrise* ((long)addat[0]-fwdcen)/backrun; //0-100
}
if(addat[1] > leftcen){
turnangdem= rightrise*((long)addat[1]-leftcen)/rightrun; //+-45
}else{
turnangdem= leftrise*((long)addat[1]-leftcen)/leftrun; //+-45
}
// turnangpos=
turnspddem=turnangdem*31/45; //0 to 31
//compute 4 motor speeds
if(turnangdem > 0){ //pos
ch1=throtpct;
}else{
ch1=throtpct;
}
if(turnangdem > 0){ //pos
ch2=throtpct;
}else{
ch2=throtpct;
}
pwmclip();
// ch3=throtpct*turnpct;
// ch4=throtpct*turnpct;
}
//----------------------
void udtime(void){
//read tics, generate oneshots, update hr,min,sec
unsigned int tmptocs;
INTR_OFF(); //critical region
tmptocs=tocs; //read copy in case int hits
INTR_ON();
deltattocs=tmptocs-tocsl; //tocs since last pass
tocsl=tmptocs; //remember last pass
deltatms=deltattocs/5;
os100msaccum+=deltatms;
os100ms=0;
if(os100msaccum >= 100){
os100ms=1;
os100msaccum -= 100;
}
os1secaccum+=deltatms; //accumulate milliseconds
os1sec=0;
if(os1secaccum >= 1000){
os1sec=1;
os1secaccum -= 1000;
}
if(os1sec){
sec++;
if(sec > 59){
min++;
sec=0;
if(min > 59){
hr++;
min=0;
if(hr > 23){
hr=0;
}
}//min
}//sec
}//os1sec
}
//-------------------------
void pwmhbridge(void){
//do sw pwm on h-bridge pins, 4 pins 2 chanels 5khz it, 31 steps
//+-PWMMAX speeds
unsigned char tmp,spd;
signed char dir;
tics++; //pwm speed 0 to PWMMAX
if(tics > PWMMAX){
tics=0;
PORTB=0;
}
tmp=PORTB;
dir=ch1 >= 0; //0 or 1
spd=PWMMAX-abs(ch1); //0 to PWMMAX
if(dir){
if(tics > spd) PORTB= (tmp & 0x0fc) | 0x01; //1a1b=01=fwd
}else{
if(tics > spd) PORTB= (tmp & 0x0fc) | 0x02; //1a1b=02=rev
}
dir=ch2 >= 0;
spd=PWMMAX-abs(ch2);
if(dir){
if(tics > spd) PORTB= (tmp & 0x0f3) | 0x04; //1a1b=04=fwd
}else{
if(tics > spd) PORTB= (tmp & 0x0f3) | 0x08; //1a1b=08=rev
}
#if 0
dir=ch3 >= 0;
spd=PWMMAX-abs(ch3);
if(dir){
if(tics > spd) PORTB= (tmp & 0x0cf) | 0x10; //1a1b=10=fwd
}else{
if(tics > spd) PORTB= (tmp & 0x0cf) | 0x20; //1a1b=20=rev
}
dir=ch4 >= 0;
spd=PWMMAX-abs(ch4);
if(dir){
if(tics > spd) PORTB= (tmp & 0x03f) | 0x40; //1a1b=40=fwd
}else{
if(tics > spd) PORTB= (tmp & 0x03f) | 0x80; //1a1b=08=rev
}
#endif
}
//-------------------------------
#pragma interrupt_handler timer0_comp_isr:11
void timer0_comp_isr(void){
//compare occured TCNT0=OCR0 5khz
tocs++; //time of day
pwmhbridge();
}
//-----------------------
void pwmloop(void){
//sw pwm 8 bits 4 channels
char c;
c=' ';
cprintf("use wsx edc rfv tgb space=all stop\n");
while(c != 'q'){
if(kbhit()){
c=getchar();
switch(c){
case 'w': ch1++; break;
case 's': ch1=0; break;
case 'x': ch1--; break;
case 'e': ch2++; break;
case 'd': ch2=0; break;
case 'c': ch2--; break;
case 'r': ch3++; break;
case 'f': ch3=0; break;
case 'v': ch3--; break;
case 't': ch4++; break;
case 'g': ch4=0; break;
case 'b': ch4--; break;
case ' ': ch1=ch2=ch3=ch4=0; break;
}//switch
// cprintf("%02x ",tics);
pwmclip();
cprintf("%02x ",PORTB);
cprintf("%3d ",ch1);
cprintf("%3d ",ch2);
cprintf("%3d ",ch3);
cprintf("%3d \r",ch4);
}//if
}//while
}
#if 0
//-------------------------
void timing(void){
//time pwm routine
//1 million= 13 sec -> 13 usec -> 71 khz
long int n;
INTR_OFF();
n=100000;
cprintf("start 1,000,000 pwms");
while(n--){
pwmhbridge();
pwmhbridge();
pwmhbridge();
pwmhbridge();
pwmhbridge();
pwmhbridge();
pwmhbridge();
pwmhbridge();
pwmhbridge();
pwmhbridge();
}
cprintf("end\n");
INTR_ON();
}
#endif
//----------------
void _StackOverFlowed(char n){
cprintf("overflow! %d\n",n);
}
//-----------------------
void rtloop(void){
//rtloop
char c;
c=' ';
dispon=1;
cprintf("running.... q to quit\n");
cprintf("hr:mn:sc mson msof throt turn ch1 ch2\n");
while(c != 'q'){ //loop forever
if(kbhit()){ //if char waiting from pc
c=getchar(); //get the char
if(c=='p') dispon= !dispon;
}
udtime();
read2ads();
joycalc();
if(!dispon) deltatmsoff=deltatms;
if(dispon){
gotoxy(1,15);
cprintf("%02d:%02d:%02d %5d %5d ",hr,min,sec,deltatms,deltatmsoff);
cprintf("%5d %5d\n",throtpct,turnangdem,ch1,ch2);
delnms(5);
}
_StackCheck();
} //while 1
}
char task1regs[12]; //r10 11 12 13 14 15 20 21 22 23 28 29
int task1sp;
char task2regs[12];
int task2sp;
char curtask; //1 or 2; 0 means uninitialized
//---------------------
void switchtasks(void){
//switch tasks. Return addr to curtask is on stack
INTR_OFF();
if(curtask==1){
asm("sts _task1regs,r10"); //save task1 regs
asm("sts _task1regs+1,r11");
asm("sts _task1regs+2,r12");
asm("sts _task1regs+3,r13");
asm("sts _task1regs+4,r14");
asm("sts _task1regs+5,r15");
asm("sts _task1regs+6,r20");
asm("sts _task1regs+7,r21");
asm("sts _task1regs+8,r22");
asm("sts _task1regs+9,r23");
asm("sts _task1regs+10,r28");
asm("sts _task1regs+11,r29");
asm("sts _task1sp,r30"); //save task1 sp
asm("sts _task1sp+1,r31");
curtask=2;
asm("lds r10,_task2regs"); //restore task2 regs
asm("lds r11,_task2regs+1");
asm("lds r12,_task2regs+2");
asm("lds r13,_task2regs+3");
asm("lds r14,_task2regs+4");
asm("lds r15,_task2regs+5");
asm("lds r20,_task2regs+6");
asm("lds r21,_task2regs+7");
asm("lds r22,_task2regs+8");
asm("lds r23,_task2regs+9");
asm("lds r28,_task2regs+10");
asm("lds r29,_task2regs+11");
asm("lds r30,_task2sp"); //restore task2 sp
asm("lds r31,_task2sp+1");
INTR_ON();
return;
}
if(curtask==2){
asm("sts _task2regs,r10"); //save task2 state
asm("sts _task2regs+1,r11");
asm("sts _task2regs+2,r12");
asm("sts _task2regs+3,r13");
asm("sts _task2regs+4,r14");
asm("sts _task2regs+5,r15");
asm("sts _task2regs+6,r20");
asm("sts _task2regs+7,r21");
asm("sts _task2regs+8,r22");
asm("sts _task2regs+9,r23");
asm("sts _task2regs+10,r28");
asm("sts _task2regs+11,r29");
asm("sts _task2sp,r30"); //save task2 sp
asm("sts _task2sp+1,r31");
curtask=1;
asm("lds r10,_task1regs"); //restore task1 regs
asm("lds r11,_task1regs+1");
asm("lds r12,_task1regs+2");
asm("lds r13,_task1regs+3");
asm("lds r14,_task1regs+4");
asm("lds r15,_task1regs+5");
asm("lds r20,_task1regs+6");
asm("lds r21,_task1regs+7");
asm("lds r22,_task1regs+8");
asm("lds r23,_task1regs+9");
asm("lds r28,_task1regs+10");
asm("lds r29,_task1regs+11");
asm("lds r30,_task1sp"); //restore task1 sp
asm("lds r31,_task1sp+1");
INTR_ON();
return;
}
}
//----------------------
void task1(void){
//task1
while(c != 'q'){
if(kbhit()){
c=getchar();
}
cprintf("task 1\n");
delnms(500);
switchtasks();
}
}
//----------------------
void task2(void){
//task1
while(c != 'q'){
if(kbhit()){
c=getchar();
}
cprintf("task 2\n");
delnms(500);
switchtasks();
}
}
//--------------------------
void menu(void){
//cmds
initscreen();
cprintf("cmds:\n");
cprintf(" 1 task 1\n");
cprintf(" 2 task 2\n");
cprintf(" a a/d\n");
cprintf(" p pwm\n");
// cprintf(" t timing\n");
cprintf(" j joystick cal\n");
cprintf(" m monitor cmds\n");
cprintf(" r rt loop\n");
}
//--------------------------
void mainswitch(unsigned char c){
//parse char from keyboard
switch(c){
case '1': curtask=1; task1(); break;
case '2': curtask=2; task2(); break;
case 'a': readadloop(); break;
case 'm': debugloop(); break;
case 'p': pwmloop(); break;
// case 't': timing(); break;
case 'j': joycal(); break;
case 'r': rtloop(); break;
default: menu();
}
}
//-----------------
void main(void){
//main program
char c;
init_devices();
initvars();
task2sp=(int)&task2; //init task2 sp to point to start of task2
task1sp=(int)&task1; //init task1 sp to point to start of task1
_textmode=1;
initscreen(); //banner
while(1){ //main loop
menu();
crlf();
putc('>'); //prompt for input
c=getche();
crlf();
mainswitch(c);
}
}
//---strings embedded in rom--------------
const char copyrightstring[]={"taskswitcher32 computer code\
written by Bob Gardner 407-855-2586 bobgardner at aol.com"};
//--------eof-------------
More information about the Icc-avr
mailing list