home *** CD-ROM | disk | FTP | other *** search
- /* pilot-debug.c: Pilot debugging console, with optional graphics support
- *
- * This is free software, licensed under the GNU Public License V2.
- * See the file COPYING for details.
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <signal.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include "pi-source.h"
- #include "pi-socket.h"
- #include "pi-dlp.h"
- #include "pi-syspkt.h"
-
- /* Definitions for functions in pd-tty.c */
-
- extern void do_readline(void);
-
- /* Display text asynchronously, and make sure it doesn't interfere with
- the current prompt */
- extern void display(char * text, char * tag, int type);
-
- #ifndef LIBDIR
- # define LIBDIR "."
- #endif
-
- #ifdef TK
- int usetk;
- # include "tk.h"
- #else
- # include "tcl.h"
- #endif
-
- #ifndef TCL_ACTIVE
- # define TCL_ACTIVE TCL_READABLE
- #endif
-
- /*
- * The following variable is a special hack that is needed in order for
- * Sun shared libraries to be used for Tcl.
- */
-
- extern int matherr();
- int *tclDummyMathPtr = (int *) matherr;
-
- int done = 0;
-
- int Interactive = 1;
-
- Tcl_Interp * interp;
- struct Pilot_state state;
-
- int debugger = 0; /* If non-zero, then debugger is thought to be active */
- int console = 0; /* If non-zero, then console is thought to be active
- Note: if both console and debugger are thought to be
- active, only the debugger will be usable. If
- execution is continued, the console be
- be usable again. */
- int stalestate = 1; /* If non-zero, then the current Pilot state (in particular the registers)
- should be assumed out-of-date */
-
- int port = 0;
-
-
- int tty; /* Non-zero means standard input is a
- * terminal-like device. Zero means it's*/
-
-
- /* Misc utility */
- void SetLabel(const char * label, const char * value)
- {
- #ifdef TK
- if (usetk)
- Tcl_VarEval(interp, label, " configure -text \"", value, "\"",NULL);
- #endif
- }
-
- char * itoa(int val) {
- static char buf[20];
- sprintf(buf,"%d",val);
- return buf;
- }
-
- char * htoa(int val) {
- static char buf[9];
- sprintf(buf,"%8.8X",val);
- return buf;
- }
-
- char * h4toa(int val) {
- static char buf[5];
- sprintf(buf,"%4.4X",val);
- return buf;
- }
-
- int SayInteractive(char * text)
- {
- Tcl_DString d;
-
- if (!Interactive)
- return 0;
-
- Tcl_DStringInit(&d);
-
- #ifdef TK
- if (usetk) {
- Tcl_DStringAppendElement(&d, ".f.t");
- Tcl_DStringAppendElement(&d, "insert");
- Tcl_DStringAppendElement(&d, "insert");
- Tcl_DStringAppendElement(&d, text);
- Tcl_Eval(interp, Tcl_DStringValue(&d));
- Tcl_DStringFree(&d);
- Tcl_DStringAppendElement(&d, ".f.t");
- Tcl_DStringAppendElement(&d, "see");
- Tcl_DStringAppendElement(&d, "insert");
- Tcl_Eval(interp, Tcl_DStringValue(&d));
- Tcl_DStringFree(&d);
- } else {
- #endif
- Tcl_DStringAppendElement(&d, "puts");
- Tcl_DStringAppendElement(&d, text);
- Tcl_Eval(interp, Tcl_DStringValue(&d));
- Tcl_DStringFree(&d);
-
- #ifdef TK
- }
- #endif
- Tcl_Eval(interp, Tcl_DStringValue(&d));
- Tcl_DStringFree(&d);
-
- return 0;
- }
-
- int Say(char * text)
- {
- Tcl_DString d;
-
- if (Interactive) {
- Tcl_DStringInit(&d);
- #ifdef TK
- if (usetk) {
- Tcl_DStringAppendElement(&d, ".f.t");
- Tcl_DStringAppendElement(&d, "insert");
- Tcl_DStringAppendElement(&d, "insert");
- Tcl_DStringAppendElement(&d, text);
- Tcl_Eval(interp, Tcl_DStringValue(&d));
- Tcl_DStringFree(&d);
- Tcl_DStringAppendElement(&d, ".f.t");
- Tcl_DStringAppendElement(&d, "see");
- Tcl_DStringAppendElement(&d, "insert");
- Tcl_Eval(interp, Tcl_DStringValue(&d));
- Tcl_DStringFree(&d);
- } else {
- #endif
- Tcl_DStringAppendElement(&d, "puts");
- Tcl_DStringAppendElement(&d, text);
- Tcl_Eval(interp, Tcl_DStringValue(&d));
- Tcl_DStringFree(&d);
-
- #ifdef TK
- }
- #endif
- } else
- Tcl_AppendResult(interp, text, NULL);
-
- return 0;
- }
-
- int Error(char * text)
- {
- Tcl_SetResult(interp, text, TCL_STATIC);
- return TCL_ERROR;
- }
-
- void SetModeLabel(void)
- {
- SetLabel(".state.halted",debugger ? "Debugger" :
- console ? "Console" :
- "None");
- }
-
-
- /* Workhorse function to read input from the Pilot. Called both via Tcl event loop on serial input,
- and explicitly by any function has thinks there should be a packet ready. */
-
- void Read_Pilot(ClientData clientData, int mask) {
- unsigned char buf[4096];
- int l;
-
- memset(buf,0,4096);
- l = pi_read(port, buf, 4096);
-
- if (l < 6)
- return;
-
- /*puts("From Pilot:");
- dumpdata((unsigned char *)buf, l);*/
-
- if(buf[2] == 0) { /* SysPkt command */
- if(buf[0] == 2) { /* UI */
- if ((!console) || debugger) {
- Say("Console active\n");
- console = 1;
- debugger = 0;
- SetModeLabel();
- Tcl_VarEval(interp, "checkin 25",NULL);
- }
- if(buf[4] == 0x0c) { /* Screen update */
- #ifdef TK
- if (usetk) {
- int i, x1, y1, sx, sy, w, h, bytes;
- int y,x;
- char buffer[8192];
- Tk_PhotoImageBlock block;
- Tk_PhotoHandle handle;
-
- bytes = get_short(buf+6);
- y1 = get_short(buf+8);
- x1 = get_short(buf+10);
- sy = get_short(buf+12);
- sx = get_short(buf+14);
- h = get_short(buf+16);
- w = get_short(buf+18);
-
- block.width = w+x1;
- block.height =h;
- block.pitch = w+x1;
- block.pixelSize = 1;
- block.offset[0] = 0;
- block.offset[1] = 0;
- block.offset[2] = 0;
- block.pixelPtr = buffer;
-
- handle = Tk_FindPhoto("Case");
-
- i = 0;
- l = 0;
- for (y=0;y<h;y++) {
- l = 20 + (y*bytes);
- for(x=0;x<(w+x1);x++) {
- int mask = 1<<(7-(x%8));
- buffer[i++] = (buf[x/8+l] & mask) ? 0 : 0xff;
- }
- }
-
- /*for(i=0;i<((l-20)*8);i++) {
- int p = i/8+20;
- int b = 1<<(7-(i%8));
- buffer[i] = (buf[p] & b) ? 0 : 0xff;
- }*/
- Tk_PhotoPutBlock(handle, &block, 32+sx-x1, 33+sy-y1, w+x1, h);
-
- /*Tcl_VarEval(interp, "global show; set show(.remote) 1; update", NULL); */
- }
- #endif
- return;
- }
-
- } else if(buf[0] == 1) { /* Console */
- if(buf[4] == 0x7f) { /* Message from Pilot */
- int i;
-
- for(i=6;i<l;i++)
- if(buf[i] == '\r')
- buf[i] = '\n';
- /* Insert message into both debug and console windows */
- #ifdef TK
- if (usetk) {
- Tcl_VarEval(interp,".console.t insert end \"",buf+6,"\"",NULL);
- Tcl_VarEval(interp,".console.t mark set insert end",NULL);
- Tcl_VarEval(interp,".console.t see insert",NULL);
- }
- #endif
- display(buf+6, "Console: ", 2);
-
- return;
- }
- } else if (buf[0] == 0) { /* Debug */
- if (!debugger) {
- debugger = 1;
- SetModeLabel();
- Tcl_VarEval(interp, "checkin 25",NULL);
- }
- if (buf[4] == 0x7f) { /* Message */
- int i;
- for(i=6;i<l;i++)
- if(buf[i] == '\r')
- buf[i] = '\n';
-
- display(buf+6, "Debug: ", 1);
-
- return;
- }
- else if (buf[4] == 0x8c) { /* Breakpoints set */
- Say("Breakpoint set\n");
- return;
- }
- else if (buf[4] == 0x80) { /* State response */
-
- sys_UnpackState(buf+6,&state);
-
- if (stalestate) {
- char buffer[40];
- sprintf(buffer, "Pilot halted at %8.8lX (function %s) with exception %d\n",
- state.regs.PC, state.func_name, state.exception);
- display(buffer, "Debug: ", 1);
- stalestate = 0;
- }
-
- SetLabel(".state.exception",itoa(state.exception));
- SetLabel(".state.funcname",state.func_name);
- SetLabel(".state.funcstart",htoa(state.func_start));
- SetLabel(".state.funcend",htoa(state.func_end));
- SetLabel(".state.d0",htoa(state.regs.D[0]));
- SetLabel(".state.a0",htoa(state.regs.A[0]));
- SetLabel(".state.d1",htoa(state.regs.D[1]));
- SetLabel(".state.a1",htoa(state.regs.A[1]));
- SetLabel(".state.d2",htoa(state.regs.D[2]));
- SetLabel(".state.a2",htoa(state.regs.A[2]));
- SetLabel(".state.d3",htoa(state.regs.D[3]));
- SetLabel(".state.a3",htoa(state.regs.A[3]));
- SetLabel(".state.d4",htoa(state.regs.D[4]));
- SetLabel(".state.a4",htoa(state.regs.A[4]));
- SetLabel(".state.d5",htoa(state.regs.D[5]));
- SetLabel(".state.a5",htoa(state.regs.A[5]));
- SetLabel(".state.d6",htoa(state.regs.D[6]));
- SetLabel(".state.a6",htoa(state.regs.A[6]));
- SetLabel(".state.d7",htoa(state.regs.D[7]));
-
- SetLabel(".state.ssp",htoa(state.regs.SSP));
- SetLabel(".state.usp",htoa(state.regs.USP));
- SetLabel(".state.sr",h4toa(state.regs.SR));
- SetLabel(".state.pc",htoa(state.regs.PC));
-
- SetLabel(".state.reset",state.reset ? "Yes" : "No");
-
- SetLabel(".state.b1",htoa(state.breakpoint[0].address));
- SetLabel(".state.b1a",(state.breakpoint[0].enabled) ? "Yes" : "No");
- SetLabel(".state.b2",htoa(state.breakpoint[1].address));
- SetLabel(".state.b2a",(state.breakpoint[1].enabled) ? "Yes" : "No");
- SetLabel(".state.b3",htoa(state.breakpoint[2].address));
- SetLabel(".state.b3a",(state.breakpoint[2].enabled) ? "Yes" : "No");
- SetLabel(".state.b4",htoa(state.breakpoint[3].address));
- SetLabel(".state.b4a",(state.breakpoint[3].enabled) ? "Yes" : "No");
- SetLabel(".state.b5",htoa(state.breakpoint[4].address));
- SetLabel(".state.b5a",(state.breakpoint[4].enabled) ? "Yes" : "No");
- SetLabel(".state.b6",htoa(state.breakpoint[5].address));
- SetLabel(".state.b6a",(state.breakpoint[5].enabled) ? "Yes" : "No");
-
- /* Show the state window if it is hidden */
- Tcl_VarEval(interp, "set show(.state) 1", NULL);
- return;
- }
- }
- }
- }
-
-
-
- /* Workhorse function to turn an address string into a numeric value. Ideally, it should
- also know about traps, function names, etc. As it is, it just assumed the text is
- a hexadecimal number, with or with '0x' prefix. */
- unsigned long ParseAddress(char * address) {
- return strtoul(address, 0, 16);
- }
-
- /* Utility function to modify breakpoint table */
- int SetBreakpoint(int bp, unsigned long address, int enabled) {
-
- state.breakpoint[bp].address = address;
- state.breakpoint[bp].enabled = enabled;
-
- SetLabel(".state.b1",htoa(state.breakpoint[0].address));
- SetLabel(".state.b1a",(state.breakpoint[0].enabled) ? "Yes" : "No");
- SetLabel(".state.b2",htoa(state.breakpoint[1].address));
- SetLabel(".state.b2a",(state.breakpoint[1].enabled) ? "Yes" : "No");
- SetLabel(".state.b3",htoa(state.breakpoint[2].address));
- SetLabel(".state.b3a",(state.breakpoint[2].enabled) ? "Yes" : "No");
- SetLabel(".state.b4",htoa(state.breakpoint[3].address));
- SetLabel(".state.b4a",(state.breakpoint[3].enabled) ? "Yes" : "No");
- SetLabel(".state.b5",htoa(state.breakpoint[4].address));
- SetLabel(".state.b5a",(state.breakpoint[4].enabled) ? "Yes" : "No");
- SetLabel(".state.b6",htoa(state.breakpoint[5].address));
- SetLabel(".state.b6a",(state.breakpoint[5].enabled) ? "Yes" : "No");
-
-
- sys_SetBreakpoints(port, &state.breakpoint[0]);
-
- Read_Pilot(0, 0);
-
- return 0;
- }
-
- /* Attempt to verify a connection to either the debugger or console */
- int DbgAttach(int verify)
- {
- struct RPC_params p;
-
- if (!port) {
- Error("No serial port selected, use 'port' command to choose one.\n");
- return 0;
- }
-
- again:
- if (verify || (!debugger && !console)) {
- int old = debugger;
- sys_QueryState(port);
- debugger = 0;
- Read_Pilot(0,0);
- if (debugger && !old)
- if (verify > 1)
- Say("Attaching to Pilot debugger\n");
- else
- SayInteractive("(attaching to Pilot debugger)\n");
- }
-
- if (!debugger && (verify || !console)) {
- int err;
- int old = console;
- console = 0;
- PackRPC(&p, 0xA09E, RPC_IntReply, RPC_End); /* TaskID, a harmless call */
- DoRPC(port, 1, &p, &err);
- if (err == 0)
- console = 1;
- else
- console = 0;
- if (console && !old)
- if (verify > 1)
- Say("Attaching to Pilot console\n");
- else
- SayInteractive("(attaching to Pilot console)\n");
-
- }
-
- if (!debugger && !console && !verify) {
- verify = 1;
- goto again;
- }
-
- SetModeLabel();
-
- return (debugger || console);
- }
-
- int DbgAttachDebugger(int verify)
- {
- if (!port) {
- Error("No serial port selected, use 'port' command to choose one.\n");
- return 0;
- }
-
- if (!debugger || verify) {
- int old = debugger;
- debugger = 0;
- sys_QueryState(port);
- Read_Pilot(0,0);
- SetModeLabel();
- if (debugger && !old)
- SayInteractive("(attaching to Pilot debugger)\n");
- }
-
- if (!debugger) {
- Error("Unable to attach to debugger on Pilot. Is the Pilot connected and in debugging mode?\n");
- }
- return debugger;
- }
-
- int DbgAttachConsole(int verify)
- {
- int err;
- struct RPC_params p;
-
- if (!port) {
- Error("No serial port selected, use 'port' command to choose one.\n");
- return 0;
- }
-
- if (verify || debugger || !console) {
- int old = console && !debugger;
- PackRPC(&p, 0xA09E, RPC_IntReply, RPC_End); /* TaskID, a harmless call */
- DoRPC(port, 1, &p, &err);
- if (err == 0) {
- console = 1;
- debugger = 0;
- SetModeLabel();
- } else {
- if (!debugger)
- console = 0;
- }
- if ((console && !debugger) && !old)
- SayInteractive("(attaching to Pilot console)\n");
- }
-
- if (!console || debugger) {
- Error("Unable to attach to console on Pilot. Is the Pilot connected, in console mode, and not in debugger mode?\n");
- }
-
- return console;
- }
-
- unsigned long DbgRPC(struct RPC_params * p, int * error)
- {
- unsigned long result = 0;
- int err = -1;
-
- if (!port) {
- Error("No serial port selected, use 'port' command to choose one.\n");
- return 0;
- }
-
- if (p->reply == RPC_NoReply) {
- /* If the RPC call will normally generate no reply (as in a call that reboots the machine)
- then we need to do some special work to verify that the connection is active */
- DbgAttach(1);
- if (!debugger && !console) {
- if (error)
- *error = -1;
- Error("Unable to invoke RPC on Pilot. Is the Pilot connected and in debugging or console mode?\n");
- return 0;
- }
- }
-
- if (debugger) {
- result = DoRPC(port, 0, p, &err);
- if ((err < 0) && (p->reply != RPC_NoReply)) /* Failure, assume no response */ {
- debugger = 0;
- SetModeLabel();
- }
- } else if (console) {
- result = DoRPC(port, 1, p, &err);
- if ((err < 0) && (p->reply != RPC_NoReply)) /* Failure, assume no response */ {
- console = 0;
- SetModeLabel();
- }
- }/* else {
- Say("(attaching to Pilot)\n");
- }*/
-
- if (!console && !debugger) {
- DbgAttach(0);
- if (debugger) {
- result = DoRPC(port, 0, p, &err);
- } else if (console) {
- result = DoRPC(port, 1, p, &err);
- } else {
- /* complete failure to attach */
- Error("Unable to invoke RPC on Pilot. Is the Pilot connected and in debugging or console mode?\n");
- }
- }
-
- if (error)
- *error = err;
-
- return result;
- }
-
- unsigned char buffer[0xffff];
-
-
- /* Go, restart execution */
- int proc_g(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- /* Use verify since the sys_Continue command produces no return value */
-
- if (!DbgAttachDebugger(1))
- return TCL_ERROR;
-
- if (argc==2) {
- /* argv[1] is address to start execution at */
- state.regs.PC = ParseAddress(argv[1]);
- SetLabel(".state.pc",htoa(state.regs.PC));
-
- /*SetBreakpoint(port, 5, ParseAddress(argv[1]), 1);*/
- }
-
- sys_Continue(port, &state.regs, 0);
-
- Say("Resuming execution\n");
-
- /* Assume the Pilot is no longer halted */
-
- debugger = 0;
- console = 0;
- stalestate = 1;
- SetModeLabel();
-
- Tcl_VarEval(interp, "checkupin 25",NULL);
- Tcl_ResetResult(interp);
-
- return TCL_OK;
- }
-
- /* Till, restart execution */
- int proc_t(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- /* Use verify since the sys_Continue command produces no return value */
-
- if (!DbgAttachDebugger(1))
- return TCL_ERROR;
-
- if (argc>=2) {
- /* argv[1] is address to stop execution at */
- SetBreakpoint(5, ParseAddress(argv[1]), 1);
- }
-
- if (argc>=3) {
- /* argv[2] is address to start execution at */
- state.regs.PC = ParseAddress(argv[2]);
- SetLabel(".state.pc",htoa(state.regs.PC));
- }
-
- sys_Continue(port, &state.regs, 0);
-
- Say("Resuming execution\n");
-
- /* Assume the Pilot is no longer halted */
-
- debugger = 0;
- console = 0;
- stalestate = 1;
- SetModeLabel();
-
- Tcl_VarEval(interp, "checkupin 25",NULL);
- Tcl_ResetResult(interp);
-
- return TCL_OK;
- }
-
- /* Attach to a Pilot that has already crashed into the debugger without notifying us */
- int proc_attach(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- DbgAttach(2); /* Two means explicit verify, as opposed to implicit */
-
- if (!debugger && !console) {
- Say("Unable to attach to to Pilot. Is the Pilot connected and in debugging or console mode?\n");
- }
-
- return TCL_OK;
- }
-
- int proc_sendscreen(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- struct RPC_params p;
-
- PackRPC(&p, 0xA0F1, RPC_IntReply, RPC_Short(0), RPC_Short(0), RPC_Short(160), RPC_Short(160), RPC_End);
- DbgRPC(&p, 0);
-
- return TCL_OK;
- }
-
- int proc_coldboot(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- struct RPC_params p;
-
- PackRPC(&p, 0xA08B, RPC_NoReply, RPC_Long(0),RPC_Long(0),RPC_Long(0),RPC_Long(0), RPC_End);
- DbgRPC(&p, 0);
-
- /* And sever attachment */
- debugger = 0;
- console = 0;
- stalestate = 1;
- SetModeLabel();
-
- Tcl_VarEval(interp, "checkupin 25",NULL);
- Tcl_ResetResult(interp);
-
- return TCL_OK;
- }
-
- int proc_warmboot(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- struct RPC_params p;
-
- PackRPC(&p, 0xA08C, RPC_NoReply, RPC_End);
- DbgRPC(&p, 0);
-
- /* And sever attachment */
- debugger = 0;
- console = 0;
- stalestate = 1;
- SetModeLabel();
-
- Tcl_VarEval(interp, "checkupin 25",NULL);
- Tcl_ResetResult(interp);
-
- return TCL_OK;
- }
-
- int proc_battery(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- int err;
- int warn, critical, maxTicks;
- int v, kind, pluggedin;
- char buffer[30];
- struct RPC_params p;
-
- if (!DbgAttach(0))
- return TCL_ERROR;
-
- warn = 0x1234;
- critical = 0x2345;
- maxTicks = 0x3456;
- kind = 2;
- pluggedin = 3;
-
- PackRPC(&p,0xA0B6, RPC_IntReply,
- RPC_Byte(0), RPC_ShortPtr(&warn), RPC_ShortPtr(&critical),
- RPC_ShortPtr(&maxTicks), RPC_BytePtr(&kind), RPC_BytePtr(&pluggedin), RPC_End);
-
-
-
- v = DbgRPC(&p, &err);
-
- if (err)
- return TCL_ERROR;
-
- /* printf("Volts = %f, crit = %f, warn = %f, ticks = %d, kind = %d, pluggedin= %d, err = %d\n",
- (float)v/100, (float)critical/100, (float)warn/100,
- maxTicks, kind, pluggedin, err);*/
-
- sprintf(buffer,"%.2f %s%s", (float)v/100, (kind == 0) ? "Alkaline" :
- (kind == 1) ? "NiCd" :
- (kind == 2) ? "Lithium" :
- "",
- pluggedin ? " Ext" : "" );
-
- Say(buffer);
-
- SetLabel(".state.battery",buffer);
-
-
- #ifdef TK
- if (usetk)
- Tcl_VarEval(interp,".state.battery configure -fg ", (v <= critical) ? "red" :
- (v <= warn) ? "darkred" :
- "blue" , NULL);
- #endif
-
- Say((v <= critical) ? " power critical!\n" : (v <= warn) ? " power low\n" : "\n");
-
- return TCL_OK;
- }
-
- int proc_mirror(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- struct RPC_params p;
- unsigned long addr;
- int e1,e2;
- int active;
-
- if (!DbgAttachConsole(0))
- return TCL_ERROR;
-
-
- /* Fetch scrGlobals ptr */
- PackRPC(&p,0xA026, RPC_IntReply, RPC_LongPtr(&addr), RPC_Long(356), RPC_Long(4), RPC_End);
- e1=DbgRPC(&p, &e2);
-
- /* Fetch current drawnotify setting */
- PackRPC(&p,0xA026, RPC_IntReply, RPC_BytePtr(&active), RPC_Long(addr+18), RPC_Long(1), RPC_End);
- e1=DbgRPC(&p, &e2);
-
- /*printf("addr=%d\nactive=%d\n", addr, active);*/
-
- /* Change setting */
- if (argc<2)
- active = !active;
- else
- if (Tcl_GetBoolean(interp, argv[1], &active)!=TCL_OK)
- return TCL_ERROR;
-
- /* Put it back */
- PackRPC(&p,0xA026, RPC_IntReply, RPC_Long(addr+18), RPC_BytePtr(&active), RPC_Long(1), RPC_End);
- e1=DbgRPC(&p, &e2);
-
- if (Interactive) {
- if (active)
- Say("Mirroring is active.\n");
- else
- Say("Mirroring is inactive.\n");
- }
-
- if (active) {
- /* Try to prod Pilot into immediately giving us a screen update */
- PackRPC(&p,0xA0F1, RPC_IntReply, RPC_Short(0), RPC_Short(0), RPC_Short(160), RPC_Short(160), RPC_End);
- e1=DbgRPC(&p, &e2);
- }
-
- return TCL_OK;
- }
-
- #define DB 0xFFFF0000
- #define LSSA 0xFA00
-
- int proc_getdisplay(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- #ifndef TK
- Say("getdisplay is not available due to pilot-debug being compiled without Tk support");
- return TCL_ERROR;
-
- #else
- char buffer[0xffff];
- char buffer2[0xffff];
- Tk_PhotoImageBlock block;
- Tk_PhotoHandle handle;
- struct RPC_params p;
- unsigned long addr;
- int e1,e2;
- int l;
-
-
- if (!usetk) {
- Say("getdisplay is not usable when graphical display is disabled");
- return TCL_ERROR;
- }
-
- if (!DbgAttach(0))
- return TCL_ERROR;
-
-
- if (debugger) {
- l = sys_ReadMemory(port, DB+LSSA, 4, buffer);
- addr = get_long(buffer);
- l = sys_ReadMemory(port, addr, 160*160/8, buffer);
- } else {
- PackRPC(&p,0xA026, RPC_IntReply, RPC_LongPtr(&addr), RPC_Long(DB+LSSA), RPC_Long(4), RPC_End);
- e1=DbgRPC(&p, &e2);
- for (l=0;l<160*160/8;l+=64) {
- PackRPC(&p,0xA026, RPC_IntReply, RPC_Ptr(buffer+l, 128), RPC_Long(addr+l), RPC_Long(128), RPC_End);
- e1=DbgRPC(&p, &e2);
- }
- }
-
- block.width = 160;
- block.height = 160;
- block.pitch = 160;
- block.pixelSize = 1;
- block.offset[0] = 0;
- block.offset[1] = 0;
- block.offset[2] = 0;
-
- handle = Tk_FindPhoto("Case");
-
- for(l=0;l<160*160;l++) {
- int p = l/8;
- int b = 1<<(7-(l%8));
- buffer2[l] = (buffer[p] & b) ? 0 : 0xff;
- }
- block.pixelPtr = buffer2;
- Tk_PhotoPutBlock(handle, &block, 32, 33, 160, 160);
-
- return TCL_OK;
- #endif
- }
-
- int proc_transmit(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- if (argc < 2)
- return TCL_OK;
-
- if (!DbgAttachConsole(0))
- return TCL_ERROR;
-
- buffer[0] = 1;
- buffer[1] = 1;
- buffer[2] = 0;
- buffer[3] = 0;
- buffer[4] = 0x7f;
- buffer[5] = 0;
- strcpy(buffer+6, argv[1]);
- strcat(buffer+6, "\n");
-
- pi_write(port, buffer, 6+strlen(argv[1])+2);
-
- return TCL_OK;
- }
-
- int proc_pushbutton(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- struct RPC_params p;
- unsigned int key=0, scan=0, mod=0;
-
- if (!DbgAttachConsole(0))
- return TCL_ERROR;
-
- sys_RPCerror = 0;
- switch(atoi(argv[1])) {
- case 1: /* Power */
- key = 0x0208;
- mod = 0x08;
- break;
-
- case 2: /* Datebook */
- key = 0x0204;
- mod = 0x08;
- break;
- case 3: /* Address */
- key = 0x0205;
- mod = 0x08;
- break;
- case 6: /* ToDo */
- key = 0x0206;
- mod = 0x08;
- break;
- case 7: /* Memo */
- key = 0x0207;
- mod = 0x08;
- break;
-
- case 4: /* Page Up */
- key = 0x000b;
- mod = 0;
- break;
- case 5: /* Page Down */
- key = 0x000c;
- mod = 0;
- break;
- default:
- return Error("Button number out of range (1-7)");
- }
-
- PackRPC(&p, 0xA12D, RPC_IntReply, RPC_Short(key),RPC_Short(scan),RPC_Short(mod), RPC_End);
-
- DbgRPC(&p, 0);
-
- return TCL_OK;
- }
-
- /* Tcl procedure to simulate a pen tap -- primarily used by Remote UI bindings */
- int proc_pen(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- int x = atoi(argv[1])-32, y = atoi(argv[2])-33, pen = atoi(argv[3]);
-
- /* Transmit Pen event to Pilot */
-
- /*printf("Pen %d, %d, %d\n", x, y, pen);*/
-
- if (!DbgAttachConsole(0))
- return TCL_ERROR;
-
- sys_RemoteEvent(port, pen, x, y, 0, 0,0,0);
-
- return TCL_OK;
- }
-
- /* Tcl procedure to simulate a key press -- primarily used by Remote UI bindings */
- int proc_key(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- /*struct RPC_params p;*/
- int key = argv[1][0];
-
- /* Transmit ASCII key to Pilot */
-
- /*printf("Key %d\n", key);*/
-
- /*PackRPC(&p, 0xA12D, RPC_IntReply, RPC_Short(key),RPC_Short(0),RPC_Short(0x0), RPC_End);
-
- if (key != 0)
- DbgRPC(&p, 0);*/
-
- if (!DbgAttachConsole(0))
- return TCL_ERROR;
-
- sys_RemoteEvent(port, 0, 0, 0, 1, 0, key, 0);
-
- /* int sd, int penDown, int x, int y, int keypressed,
- int keymod, int keyasc, int keycode)*/
-
-
- return TCL_OK;
- }
-
- int proc_port(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- static struct pi_sockaddr laddr;
- static Tcl_Channel channel;
- int fd;
-
- if (argc<2) {
- if(port)
- Tcl_SetResult(interp, laddr.pi_device, TCL_STATIC);
- return TCL_OK;
- }
-
- if (port) {
- Tcl_DeleteChannelHandler(channel, Read_Pilot, (ClientData)port);
- Tcl_UnregisterChannel(interp, channel);
- pi_close(port);
- port = 0;
- }
-
- if (strcmp(argv[1],"close")==0) {
- return TCL_OK;
- }
-
- port = pi_socket(PI_AF_SLP, PI_SOCK_RAW, PI_PF_SLP);
-
- laddr.pi_family = PI_AF_SLP;
- strcpy(laddr.pi_device,argv[1]);
-
- if (pi_bind(port, &laddr, sizeof(laddr))==-1) {
- Say("Unable to open port '");
- Say(argv[1]);
- Say("': ");
- Say(Tcl_ErrnoMsg(errno));
- Say("\n");
- port = 0;
- return TCL_ERROR;
- }
-
- fd = port;
-
- channel = Tcl_MakeFileChannel((ClientData)fd, 0, TCL_READABLE);
- Tcl_RegisterChannel(interp, channel); /* And register it to TCL */
- Tcl_CreateChannelHandler(channel, TCL_READABLE, Read_Pilot, (ClientData)port);
-
- Tcl_SetResult(interp, laddr.pi_device, TCL_STATIC);
- return TCL_OK;
- }
-
- int proc_inittkdbg(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- #ifndef TK
- Say("This executable does not contain Tk support!\n");
- return TCL_ERROR;
- #else
- static int created = 0;
- if (created) {
- Say("Graphical debugger already initialized.\n");
- return TCL_OK;
- }
-
- Tcl_VarEval(interp,"\
-
- ### /*** Generate remote UI window ***/
-
- set tkdbg 1
-
- toplevel .remote
- wm title .remote {Pilot Remote UI}
-
- catch {
- if {[file exists {pix/case.gif}]} {
- set dir {pix}
- } elseif {[file exists {",LIBDIR,"/pix/case.gif}]} {
- set dir {",LIBDIR,"/pix}
- } else {
- error {No pix}
- }
- image create photo Case -format gif -file \"$dir/case.gif\"
- image create photo B1 -format gif -file \"$dir/b1.gif\"
- image create photo B2 -format gif -file \"$dir/b2.gif\"
- image create photo B3 -format gif -file \"$dir/b3.gif\"
- image create photo B4 -format gif -file \"$dir/b4.gif\"
- image create photo B5 -format gif -file \"$dir/b5.gif\"
- image create photo B6 -format gif -file \"$dir/b6.gif\"
- image create photo B7 -format gif -file \"$dir/b7.gif\"
- }
-
- canvas .remote.c -width 221 -height 337
-
- .remote.c create rectangle 27 29 196 260 -outline {red} -tag screen -fill {blue}
- .remote.c create rectangle 0 280 18 306 -outline {red} -tag button1 -fill {blue}
- .remote.c create oval 23 276 52 307 -outline {red} -tag button2 -fill {blue}
- .remote.c create oval 63 276 92 307 -outline {red} -tag button3 -fill {blue}
- .remote.c create rectangle 97 277 127 294 -outline {red} -tag button4 -fill {blue}
- .remote.c create rectangle 97 300 127 317 -outline {red} -tag button5 -fill {blue}
- .remote.c create oval 133 276 162 307 -outline {red} -tag button6 -fill {blue}
- .remote.c create oval 171 276 200 307 -outline {red} -tag button7 -fill {blue}
-
- .remote.c create rectangle 33 32 187 253 -outline black -tag screen
- .remote.c create rectangle 33 200 61 225 -outline black -tag screen
- .remote.c create rectangle 33 225 61 253 -outline black -tag screen
- .remote.c create rectangle 160 200 187 225 -outline black -tag screen
- .remote.c create rectangle 160 225 187 253 -outline black -tag screen
- .remote.c create rectangle 62 200 159 253 -outline black -tag screen
-
- .remote.c bind button1 <ButtonPress-1> {.remote.c itemconfigure button1 -fill green; update; pushbutton 1}
- .remote.c bind button1 <ButtonRelease-1> {.remote.c itemconfigure button1 -fill blue}
-
- .remote.c bind button2 <ButtonPress-1> {.remote.c itemconfigure button2 -fill green; update; pushbutton 2}
- .remote.c bind button2 <ButtonRelease-1> {.remote.c itemconfigure button2 -fill blue}
-
- .remote.c bind button3 <ButtonPress-1> {.remote.c itemconfigure button3 -fill green; update; pushbutton 3}
- .remote.c bind button3 <ButtonRelease-1> {.remote.c itemconfigure button3 -fill blue}
-
- .remote.c bind button4 <ButtonPress-1> {.remote.c itemconfigure button4 -fill green; update; pushbutton 4}
- .remote.c bind button4 <ButtonRelease-1> {.remote.c itemconfigure button4 -fill blue}
-
- .remote.c bind button5 <ButtonPress-1> {.remote.c itemconfigure button5 -fill green; update; pushbutton 5}
- .remote.c bind button5 <ButtonRelease-1> {.remote.c itemconfigure button5 -fill blue}
-
- .remote.c bind button6 <ButtonPress-1> {.remote.c itemconfigure button6 -fill green; update; pushbutton 6}
- .remote.c bind button6 <ButtonRelease-1> {.remote.c itemconfigure button6 -fill blue}
-
- .remote.c bind button7 <ButtonPress-1> {.remote.c itemconfigure button7 -fill green; update; pushbutton 7}
- .remote.c bind button7 <ButtonRelease-1> {.remote.c itemconfigure button7 -fill blue}
-
- catch {
- .remote.c create image 0 282 -image B1 -anchor nw -tag downbutton1
- .remote.c create image 22 274 -image B2 -anchor nw -tag downbutton2
- .remote.c create image 60 275 -image B3 -anchor nw -tag downbutton3
- .remote.c create image 93 278 -image B4 -anchor nw -tag downbutton4
- .remote.c create image 95 298 -image B5 -anchor nw -tag downbutton5
- .remote.c create image 131 275 -image B6 -anchor nw -tag downbutton6
- .remote.c create image 169 274 -image B7 -anchor nw -tag downbutton7
-
- .remote.c create image 0 0 -image Case -anchor nw
-
- .remote.c bind button1 <ButtonPress-1> {.remote.c raise downbutton1; update; pushbutton 1}
- .remote.c bind button1 <ButtonRelease-1> {.remote.c lower downbutton1}
-
- .remote.c bind button2 <ButtonPress-1> {.remote.c raise downbutton2; update; pushbutton 2}
- .remote.c bind button2 <ButtonRelease-1> {.remote.c lower downbutton2}
-
- .remote.c bind button3 <ButtonPress-1> {.remote.c raise downbutton3; update; pushbutton 3}
- .remote.c bind button3 <ButtonRelease-1> {.remote.c lower downbutton3}
-
- .remote.c bind button4 <ButtonPress-1> {.remote.c raise downbutton4; update; pushbutton 4}
- .remote.c bind button4 <ButtonRelease-1> {.remote.c lower downbutton4}
-
- .remote.c bind button5 <ButtonPress-1> {.remote.c raise downbutton5; update; pushbutton 5}
- .remote.c bind button5 <ButtonRelease-1> {.remote.c lower downbutton5}
-
- .remote.c bind button6 <ButtonPress-1> {.remote.c raise downbutton6; update; pushbutton 6}
- .remote.c bind button6 <ButtonRelease-1> {.remote.c lower downbutton6}
-
- .remote.c bind button7 <ButtonPress-1> {.remote.c raise downbutton7; update; pushbutton 7}
- .remote.c bind button7 <ButtonRelease-1> {.remote.c lower downbutton7}
-
-
- .remote.c itemconfigure button1 -outline {} -fill {}
- .remote.c raise button1
- .remote.c itemconfigure button2 -outline {} -fill {}
- .remote.c raise button2
- .remote.c itemconfigure button3 -outline {} -fill {}
- .remote.c raise button3
- .remote.c itemconfigure button4 -outline {} -fill {}
- .remote.c raise button4
- .remote.c itemconfigure button5 -outline {} -fill {}
- .remote.c raise button5
- .remote.c itemconfigure button6 -outline {} -fill {}
- .remote.c raise button6
- .remote.c itemconfigure button7 -outline {} -fill {}
- .remote.c raise button7
- .remote.c itemconfigure screen -outline {} -fill {}
- .remote.c raise screen
- }
-
- pack .remote.c -side top
-
- .remote.c bind screen <ButtonPress-1> {pen %x %y 1}
- .remote.c bind screen <B1-Motion> {pen %x %y 1}
- .remote.c bind screen <ButtonRelease-1> {pen %x %y 0}
-
- bind .remote <KeyPress> {key %A}
-
- ##### /*** Generate remote console window ***/
-
- toplevel .console
- wm title .console \"Pilot Remote Console\"
- scrollbar .console.y -orient vertical -command {.console.t yview}
- text .console.t -yscrollcommand {.console.y set}
- pack .console.t -fill both -expand yes -side left
- pack .console.y -fill y -side right
- focus .console.t
-
- #### /*** Generate pilot state window ***/
-
- toplevel .state
- wm title .state {Pilot State}
- label .state.l1 -text {Active mode:}
- label .state.l1x -text {Battery:}
- label .state.l2 -text {Exception:}
- label .state.l25 -text {Reset:}
- label .state.l3 -text {Function:}
- label .state.l4 -text {F-start:}
- label .state.l5 -text {F-end:}
- label .state.l6 -text {D0:}
- label .state.l7 -text {A0:}
- label .state.l8 -text {D1:}
- label .state.l9 -text {A1:}
- label .state.l10 -text {D2:}
- label .state.l11 -text {A2:}
- label .state.l12 -text {D3:}
- label .state.l13 -text {A3:}
- label .state.l14 -text {D4:}
- label .state.l15 -text {A4:}
- label .state.l16 -text {D5:}
- label .state.l17 -text {A5:}
- label .state.l18 -text {D6:}
- label .state.l19 -text {A6:}
- label .state.l20 -text {D7:}
-
- label .state.l21 -text {PC:}
- label .state.l22 -text {SR:}
- label .state.l23 -text {USP:}
- label .state.l24 -text {SSP:}
-
- label .state.halted -text {None}
- label .state.battery -text {Unknown}
- label .state.exception -text {0}
- label .state.reset -text {No}
- label .state.funcname -text {}
- label .state.funcstart -text {00000000}
- label .state.funcend -text {00000000}
- label .state.d0 -text {00000000}
- label .state.a0 -text {00000000}
- label .state.d1 -text {00000000}
- label .state.a1 -text {00000000}
- label .state.d2 -text {00000000}
- label .state.a2 -text {00000000}
- label .state.d3 -text {00000000}
- label .state.a3 -text {00000000}
- label .state.d4 -text {00000000}
- label .state.a4 -text {00000000}
- label .state.d5 -text {00000000}
- label .state.a5 -text {00000000}
- label .state.d6 -text {00000000}
- label .state.a6 -text {00000000}
- label .state.d7 -text {00000000}
- label .state.pc -text {00000000}
- label .state.sr -text {0000}
- label .state.usp -text {00000000}
- label .state.ssp -text {00000000}
-
- grid .state.l1 -column 0 -row 0 -sticky e -columnspan 2
- grid .state.halted -column 2 -row 0 -sticky w -columnspan 2
-
- grid .state.l1x -column 0 -row 1 -sticky e -columnspan 2
- grid .state.battery -column 2 -row 1 -sticky w -columnspan 2
-
- grid .state.l2 -column 0 -row 2 -sticky e -columnspan 2
- grid .state.exception -column 2 -row 2 -sticky w -columnspan 2
-
- grid .state.l25 -column 0 -row 3 -sticky e -columnspan 2
- grid .state.reset -column 2 -row 3 -sticky w -columnspan 2
-
- grid .state.l3 -column 0 -row 4 -sticky e -columnspan 2
- grid .state.funcname -column 2 -row 4 -sticky w -columnspan 2
-
- grid .state.l4 -column 0 -row 5 -sticky e -columnspan 2
- grid .state.funcstart -column 2 -row 5 -sticky w -columnspan 2
-
- grid .state.l5 -column 0 -row 6 -sticky e -columnspan 2
- grid .state.funcend -column 2 -row 6 -sticky w -columnspan 2
-
- frame .state.rule1 -relief raised -bd 2 -height 4
- grid .state.rule1 -column 0 -row 7 -columnspan 4 -sticky ew
-
- grid .state.l6 -column 0 -row 8 -sticky e
- grid .state.d0 -column 1 -row 8 -sticky w
- grid .state.l7 -column 2 -row 8 -sticky e
- grid .state.a0 -column 3 -row 8 -sticky w
-
- grid .state.l8 -column 0 -row 9 -sticky e
- grid .state.d1 -column 1 -row 9 -sticky w
- grid .state.l9 -column 2 -row 9 -sticky e
- grid .state.a1 -column 3 -row 9 -sticky w
-
- grid .state.l10 -column 0 -row 10 -sticky e
- grid .state.d2 -column 1 -row 10 -sticky w
- grid .state.l11 -column 2 -row 10 -sticky e
- grid .state.a2 -column 3 -row 10 -sticky w
-
- grid .state.l12 -column 0 -row 11 -sticky e
- grid .state.d3 -column 1 -row 11 -sticky w
- grid .state.l13 -column 2 -row 11 -sticky e
- grid .state.a3 -column 3 -row 11 -sticky w
-
- grid .state.l14 -column 0 -row 12 -sticky e
- grid .state.d4 -column 1 -row 12 -sticky w
- grid .state.l15 -column 2 -row 12 -sticky e
- grid .state.a4 -column 3 -row 12 -sticky w
-
- grid .state.l16 -column 0 -row 13 -sticky e
- grid .state.d5 -column 1 -row 13 -sticky w
- grid .state.l17 -column 2 -row 13 -sticky e
- grid .state.a5 -column 3 -row 13 -sticky w
-
- grid .state.l18 -column 0 -row 14 -sticky e
- grid .state.d6 -column 1 -row 14 -sticky w
- grid .state.l19 -column 2 -row 14 -sticky e
- grid .state.a6 -column 3 -row 14 -sticky w
-
- grid .state.l20 -column 0 -row 15 -sticky e
- grid .state.d7 -column 1 -row 15 -sticky w
-
- grid .state.l21 -column 0 -row 16 -sticky e
- grid .state.pc -column 1 -row 16 -sticky w
- grid .state.l22 -column 2 -row 16 -sticky e
- grid .state.sr -column 3 -row 16 -sticky w
-
- grid .state.l23 -column 0 -row 17 -sticky e
- grid .state.usp -column 1 -row 17 -sticky w
- grid .state.l24 -column 2 -row 17 -sticky e
- grid .state.ssp -column 3 -row 17 -sticky w
-
- label .state.bl2 -text {B1:}
- label .state.bl4 -text {B2:}
- label .state.bl6 -text {B3:}
- label .state.bl8 -text {B4:}
- label .state.bl10 -text {B5:}
- label .state.bl12 -text {B6:}
-
- label .state.b1 -text {00000000}
- label .state.b1a -text {Off}
- label .state.b2 -text {00000000}
- label .state.b2a -text {Off}
- label .state.b3 -text {00000000}
- label .state.b3a -text {Off}
- label .state.b4 -text {00000000}
- label .state.b4a -text {Off}
- label .state.b5 -text {00000000}
- label .state.b5a -text {Off}
- label .state.b6 -text {00000000}
- label .state.b6a -text {Off}
-
- frame .state.rule2 -relief raised -bd 2 -height 4
- grid .state.rule2 -column 0 -row 18 -columnspan 4 -sticky ew
-
- grid .state.bl2 -column 0 -row 19 -sticky e
- grid .state.b1 -column 1 -row 19 -sticky w
- grid .state.b1a -column 2 -row 19 -sticky w
-
- grid .state.bl4 -column 0 -row 20 -sticky e
- grid .state.b2 -column 1 -row 20 -sticky w
- grid .state.b2a -column 2 -row 20 -sticky w
-
- grid .state.bl6 -column 0 -row 21 -sticky e
- grid .state.b3 -column 1 -row 21 -sticky w
- grid .state.b3a -column 2 -row 21 -sticky w
-
- grid .state.bl8 -column 0 -row 22 -sticky e
- grid .state.b4 -column 1 -row 22 -sticky w
- grid .state.b4a -column 2 -row 22 -sticky w
-
- grid .state.bl10 -column 0 -row 23 -sticky e
- grid .state.b5 -column 1 -row 23 -sticky w
- grid .state.b5a -column 2 -row 23 -sticky w
-
- grid .state.bl12 -column 0 -row 24 -sticky e
- grid .state.b6 -column 1 -row 24 -sticky w
- grid .state.b6a -column 2 -row 24 -sticky w
-
- ### /*** Generate debugger console window ***/
-
- wm title . \"Pilot Debugger Console\"
- catch {
- wm iconbitmap . {@pix/case.xbm}
- wm iconbitmap .remote {@pix/case.xbm}
- wm iconbitmap .console {@pix/case.xbm}
- wm iconbitmap .state {@pix/case.xbm}
- #wm iconmask . {@pix/casemask.xbm}
- }
-
- frame .m -relief raised
- frame .f
- scrollbar .f.y -orient vertical -command {.f.t yview}
- text .f.t -yscrollcommand {.f.y set} -wrap word
- pack .f.t -fill both -expand yes -side left
- pack .f.y -fill y -side right
- pack [menubutton .m.file -text {File} -menu .m.file.m] -side left
- #pack [menubutton .m.edit -text {Edit} -menu .m.edit.m] -side left
- pack [menubutton .m.windows -text {Windows} -menu .m.windows.m] -side left
- #pack [menubutton .m.help -text {Help} -menu .m.help.m] -side right
-
- menu .m.file.m
- menu .m.windows.m
- #menu .m.edit.m
- #menu .m.help.m
-
- #wm iconify .remote
- #wm iconify .console
- #wm iconify .state
-
-
- proc ShowWindow {name1 name2 op} {
- global show
- if {$show($name2)} {
- if {[wm state $name2] != \"normal\"} {
- wm deiconify $name2
- }
- } else {
- if {[wm state $name2] == \"normal\"} {
- wm withdraw $name2
- }
- }
- }
-
-
- trace variable show w {ShowWindow}
-
- bind .remote <Unmap> { set show(.remote) 0 }
- bind .console <Unmap> { set show(.console) 0 }
- bind .state <Unmap> { set show(.state) 0 }
-
- bind .remote <Map> { set show(.remote) 1 }
- bind .console <Map> { set show(.console) 1 }
- bind .state <Map> { set show(.state) 1 }
-
- wm protocol .remote WM_DELETE_WINDOW { set show(.remote) 0 }
- wm protocol .console WM_DELETE_WINDOW { set show(.console) 0 }
- wm protocol .state WM_DELETE_WINDOW { set show(.state) 0 }
-
- set show(.remote) 0
- set show(.console) 0
- set show(.state) 0
-
-
- .m.file.m add command -label {Exit} -command {exit}
-
- .m.windows.m add checkbutton -label {Remote UI} -var show(.remote)
- .m.windows.m add checkbutton -label {Remote Console} -var show(.console)
- .m.windows.m add checkbutton -label {Remote State} -var show(.state)
-
- pack .m -side top -fill x
- pack .f -side top -fill both -expand yes
- focus .f.t
-
- ### /*** Configure console bindings ***/
-
- bind .console.t <Shift-KeyPress-Return> {tkTextInsert .console.t \"\\n\" ; break}
- bind .f.t <Shift-KeyPress-Return> {tkTextInsert .f.t \"\\n\" ; break}
-
- bind .console.t <Control-KeyPress-Return> {tkTextInsert .console.t \"\\n\" ; break}
- bind .f.t <Control-KeyPress-Return> {tkTextInsert .f.t \"\\n\" ; break}
-
- bind .console.t <KeyPress-Return> {Console [.console.t get {insert linestart} {insert lineend}] ; break}
- bind .f.t <KeyPress-Return> {
- set line [.f.t get {insert linestart} {insert lineend}]
- set f [string first \">\" $line]
- incr f
- set line [string range $line $f end]
- .f.t mark set insert {insert lineend}
- .f.t insert insert \\n
- Debugger $line
- if {[.f.t compare insert != {insert linestart}]} {
- .f.t insert insert \"\\n\"
- }
- .f.t insert insert \"pilot-debug> \"
- .f.t see insert
- break
- }
-
- proc Console {cmd} {
- .console.t mark set insert {insert lineend}
- tkTextInsert .console.t \\n
- transmit $cmd
- }
-
- proc Debugger {cmd} {
- #.f.t mark set insert {insert lineend}
- #tkTextInsert .f.t \\n
- if {[string length [string trim $cmd]]!=0} {
- set code [catch {eval $cmd} message]
- if {[string length $message]} {
- set message [string trimright $message]
- Say \"$message\\n\"
- #if {[.f.t compare insert != {insert linestart}]} {
- # Say \"\\\n\"
- #}
- }
- }
- }
-
- proc Say {text} {
- global Interactive
- if {$Interactive} {
- .f.t insert insert \"$text\"
- .f.t see insert
- } else {
- upvar result result
- set result \"$result$text\"
- }
- }
-
- ", NULL);
- puts(interp->result);
-
- created = 1;
- usetk = 1;
-
- return TCL_OK;
- #endif
- }
-
- int proc_help(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
- {
- Say("\
- --- Help ---\n\
- g [<addr>]\tGo: Resume execution (if address is supplied, will start at that point)\n\
- t <addr1> [<addr2>}\tTill: Resume execution until addr1 (if addr2 is supplied, will start at that point)\n\
- coldboot\n\
- warmboot\n\
- pushbutton <button number>\tSimulate button push\n\
- mirror [bool]\tContinually view the Pilot's screen in the Remote UI window (if bool supplied, can turn on or off mirroring, otherwise toggles)\n\
- getdisplay\tShow the Pilot's display in the Remote UI window\n\
- ");
- return TCL_OK;
- }
-
- struct { char * name; Tcl_CmdProc * proc; } cmds[] = {
- { "coldboot", proc_coldboot },
- { "warmboot", proc_warmboot },
- { "sendscreen", proc_sendscreen },
- { "pushbutton", proc_pushbutton },
- { "pen", proc_pen },
- { "key", proc_key },
- { "g", proc_g },
- { "t", proc_t },
- { "attach", proc_attach },
- { "transmit", proc_transmit },
- { "getdisplay", proc_getdisplay },
- { "mirror", proc_mirror },
- { "battery", proc_battery },
- { "port", proc_port },
- { "help", proc_help },
- { "inittkdbg", proc_inittkdbg },
- { 0, 0}
- };
-
- int
- Tcl_AppInit(myinterp)
- Tcl_Interp *myinterp; /* Interpreter for application. */
- {
- int i;
-
- interp=myinterp;
-
- if (Tcl_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
- #ifdef TK
- if (usetk) {
- if (Tk_Init(interp) == TCL_ERROR) {
- return TCL_ERROR;
- }
- Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL);
- }
- #endif
-
- /*** Load custom Tcl procedures ***/
-
-
- for (i=0;cmds[i].name;i++) {
- Tcl_CreateCommand(interp, cmds[i].name, cmds[i].proc, 0, NULL);
- }
-
- Tcl_VarEval(interp,"\
- proc Say {text} {
- global Interactive
- if {$Interactive} {
- puts \"$text\"
- } else {
- upvar result result
- set result \"$result$text\"
- }
- }
-
- proc interactive {args} {
- global Interactive
- global errorInfo
- set hold $Interactive
- set Interactive 1
- set code [catch $args message]
- set Interactive $hold
- error $message $errorInfo $code
- }
-
- proc noninteractive {args} {
- global Interactive
- global errorInfo
- set hold $Interactive
- set Interactive 0
- set code [catch $args message]
- set Interactive $hold
- error $message $errorInfo $code
- }
-
- set Interactive 1
-
-
- proc bgerror {msg} {
- Say $msg
- }
-
- proc checkup {} {
- catch {noninteractive battery}
- after 10000 checkup
- }
-
- after 1000 checkup
-
- proc checkupin {time} {
- after $time {catch {noninteractive battery}}
- }
-
- ",NULL);
-
- Tcl_LinkVar(interp, "Interactive", (char*)&Interactive, TCL_LINK_INT);
-
-
- #ifdef TK
- if (usetk)
- Tcl_VarEval(interp,"inittkdbg",NULL);
- else
- Tcl_VarEval(interp,"set tkdbg 0", NULL);
- #endif
-
- Say("\tWelcome to pilot-debug!\n\nType 'help' for further information.\n\n");
-
- #if 0
- Say("\tWelcome to pilot-debug!\n\n\
- Please connect your Pilot and start console or debugging mode.\n\n(Console mode is a background \
- task that can respond to a few commands, most importantly RPC which lets any function on the \
- Pilot be invoked. The Pilot operates as usual while console mode is active, except that \
- since the serial port is help open, HotSync and other applications that use the serial port \
- will not work. Debug mode is activated on demand or when the Pilot crashes. In debug mode, the \
- CPU is halted, and no commands may be executed, except via a debugging console like this one.)\n\n\
- In the absence of special utilities, the console can be started by \
- the \".2\" shortcut, and debugging via \".1\". To clear either mode, \
- reboot via the reset button. If console mode is active, you may \
- also reboot via the \"coldboot\" or \"warmboot\" commands.\n\n\
- The Remote UI window lets you manipulate the Pilot if console mode is active. By clicking the \
- mouse button on the screen or buttons, you can simulate pen taps, and if you type anything \
- while the window has the focus, the Pilot will receive the keystrokes.\n\n \
- The Remote Console window is specifically for the transmission and reception of console \
- packets. Pressing Return on a line will transmit it, and any incoming packets will be \
- displayed here in addition to the Debug Console.\n\n\
- The Remote State window shows the current Pilot CPU state. It is only updated on request or \
- when the Pilot halts.\n\n\
- The Debugging Console window is the primary interface for pilot-debug. Pressing Return on a \
- line that contains text will execute that line as a Tcl command. (Try 'expr 3+4'.) All of \
- the usual Tcl and Tk commands are available, as well as some special-purpose ones, including \
- 'help', 'coldboot', 'warmboot', 'attach', 't', and 'g', (the last one continues after the Pilot halts.)\n\n\
- Execute 'help' for the list of commands currently implemented.\n\
- ");
- #endif
-
- /*
- * Specify a user-specific startup file to invoke if the application
- * is run interactively. Typically the startup file is "~/.apprc"
- * where "app" is the name of the application. If this line is deleted
- * then no user-specific startup file will be run under any conditions.
- */
-
- Tcl_SetVar(interp, "tcl_rcFileName", "~/.pdebugrc", TCL_GLOBAL_ONLY);
-
- Tcl_VarEval(interp,"\
- set tcl_prompt1 myprompt
- proc myprompt {} {
- puts -nonewline \"pilot-debug> \"
- }
-
- ",NULL);
-
- /* Deal with command-line arguments */
-
- Tcl_VarEval(interp,"\
- if {$argc > 0} {
- set p [lindex $argv 0]
- set argv [lrange $argv 1 end]
- port $p
- } else {
- Say \"As you have not entered a serial port on the command like, you might like to \
- set one with 'port /dev/something'\\n\\n\"
- }
- ",NULL);
-
- return TCL_OK;
- }
-
- int main(int argc, char *argv[])
- {
- char *args, *fileName;
- char buf[20];
- int code;
- size_t length;
- int exitCode = 0;
- Tcl_Channel errChannel;
-
- Tcl_FindExecutable(argv[0]);
- interp = Tcl_CreateInterp();
-
- fileName = NULL;
- if (argc > 2) {
- length = strlen(argv[1]);
- if ((length >= 2) && (strncmp(argv[1], "-file", length) == 0)) {
- fileName = argv[2];
- argc-=2;
- argv+=2;
- }
- }
-
- #ifdef TK
- usetk = 1;
- #endif
-
- if (argc > 1) {
- length = strlen(argv[1]);
- if ((length >= 2) && (strncmp(argv[1], "-notk", length) == 0)) {
- #ifdef TK
- usetk = 0;
- #endif
- argc--;
- argv++;
- }
- }
-
- /*
- * Make command-line arguments available in the Tcl variables "argc"
- * and "argv".
- */
-
- args = Tcl_Merge(argc-1, argv+1);
- Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
- ckfree(args);
- sprintf(buf, "%d", argc-1);
- Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY);
- Tcl_SetVar(interp, "argv0", (fileName != NULL) ? fileName : argv[0],
- TCL_GLOBAL_ONLY);
-
- /*
- * Set the "tcl_interactive" variable.
- */
-
- tty = isatty(0);
- Tcl_SetVar(interp, "tcl_interactive",
- ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY);
-
-
- #ifdef TK
- if (!getenv("DISPLAY") || (strlen(getenv("DISPLAY"))==0))
- usetk = 0;
- #endif
-
- /*
- * Invoke application-specific initialization.
- */
-
- if (Tcl_AppInit(interp) != TCL_OK) {
- errChannel = Tcl_GetStdChannel(TCL_STDERR);
- if (errChannel) {
- Tcl_Write(errChannel,
- "application-specific initialization failed: ", -1);
- Tcl_Write(errChannel, interp->result, -1);
- Tcl_Write(errChannel, "\n", 1);
- }
- }
-
- /*
- * Invoke the script specified on the command line, if any.
- */
-
- if (fileName != NULL) {
- code = Tcl_EvalFile(interp, fileName);
- if (code != TCL_OK) {
- errChannel = Tcl_GetStdChannel(TCL_STDERR);
- if (errChannel) {
- /*
- * The following statement guarantees that the errorInfo
- * variable is set properly.
- */
-
- Tcl_AddErrorInfo(interp, "");
- Tcl_Write(errChannel,
- Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY), -1);
- Tcl_Write(errChannel, "\n", 1);
- }
- exitCode = 1;
- }
- goto done;
- }
-
- /* Tcl 7.5 did not support this command */
- #if (TCL_MAJOR_VERSION > 7) || (TCL_MINOR_VERSION > 5)
-
- /*
- * We're running interactively. Source a user-specific startup
- * file if the application specified one and if the file exists.
- */
-
- Tcl_SourceRCFile(interp);
- #endif
-
- /*
- * Loop infinitely, waiting for commands to execute. When there
- * are no windows left, Tk_MainLoop returns and we exit.
- */
-
- #ifdef TK
- if (!usetk) {
- #endif
-
- /*
- * Process commands from stdin until there's an end-of-file. Note
- * that we need to fetch the standard channels again after every
- * eval, since they may have been changed.
- */
-
- do_readline();
-
-
- #ifdef TK
- }
- #endif
-
- done:
-
- #ifdef TK
- if (usetk) {
- Tcl_VarEval(interp, ".f.t insert end {pilot-debug> }; .f.t set mark insert end",0);
- Tk_MainLoop();
- Tcl_DeleteInterp(interp);
- Tcl_Exit(0);
- }
- #endif
- return 0;
- }
-
-