Rough draft of CALL/EXEC support for the Monitor.
[goodfet] / firmware / apps / monitor / monitor.c
1 /*! \file monitor.c
2   \author Travis Goodspeed
3   \brief Local debug monitor.
4 */
5
6 #include "command.h"
7 #include "platform.h"
8 #include "monitor.h"
9
10 //! Call a function by address.
11 int fncall(unsigned int adr){
12   //TODO replace this with portable C.
13   //Preprocessor definition might help.
14   __asm__("call r15"); //r12 on IAR
15 }
16
17 //! Handles a monitor command.
18 void monitorhandle(unsigned char app,
19                    unsigned char verb,
20                    unsigned long len){
21   switch(verb){
22   case PEEK:
23     cmddata[0]=memorybyte[cmddataword[0]];
24     txdata(app,verb,1);
25     break;
26   case POKE:
27     //Todo, make word or byte.
28     memorybyte[cmddataword[0]]=cmddata[2];
29     cmddata[0]=memorybyte[cmddataword[0]];
30     txdata(app,verb,1);
31     break;
32   case CALL:
33     //Set the program counter to cmdword[0];
34     cmddataword[0]=fncall(cmddataword[0]);
35     txdata(app,verb,2);
36     break;
37   case EXEC:
38     //Execute the argument as code from RAM.
39     cmddataword[0]=fncall((u16) cmddataword);
40     txdata(app,verb,2);
41     break;
42   case MONITOR_SIZEBUF:
43     //TODO make the data length target-specific, varying by ram.
44     cmddataword[0]=0x100;
45     txdata(app,verb,2);
46     break;
47   case MONITOR_CHANGE_BAUD:
48     //This command, and ONLY this command, does not reply.
49     setbaud(cmddata[0]);
50     //txdata(app,verb,0);
51     break;
52   case MONITOR_RAM_PATTERN:
53     monitor_ram_pattern();//reboots, will never return
54     break;
55   case MONITOR_RAM_DEPTH:
56     cmddataword[0]=monitor_ram_depth();
57     txdata(app,verb,2);
58     break;
59   case MONITOR_DIR:
60     P5DIR=cmddata[0];
61     txdata(app,verb,1);
62     break;
63   case MONITOR_IN:
64     cmddata[0]=P5IN;
65     txdata(app,verb,1);
66     break;
67   case MONITOR_OUT:
68     P5OUT=cmddata[0];
69     txdata(app,verb,1);
70     break;
71   case MONITOR_SILENT:
72     silent=cmddata[0];
73     txdata(app,verb,1);
74     break;
75   }
76 }
77
78 //! Overwrite all of RAM with 0xBEEF, then reboot.
79 void monitor_ram_pattern(){
80   register int *a;
81   
82   //Wipe all of ram.
83   for(a=(int*)0x1100;a<(int*)0x2500;a++){//TODO get these from the linker.
84     *((int*)a) = 0xBEEF;
85   }
86   txdata(0x00,0x90,0);
87   
88   //Reboot
89   asm("br &0xfffe");
90 }
91
92 //! Return the number of contiguous bytes 0xBEEF, to measure RAM usage.
93 unsigned int monitor_ram_depth(){
94   register int a;
95   register int count=0;
96   for(a=0x1100;a<0x2500;a+=2)
97     if(*((int*)a)==0xBEEF) count+=2;
98   
99   return count;
100 }