1130803Smarcel/* Remote target glue for the ROM68K ROM monitor. 2130803Smarcel Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001 3130803Smarcel Free Software Foundation, Inc. 4130803Smarcel 5130803Smarcel This file is part of GDB. 6130803Smarcel 7130803Smarcel This program is free software; you can redistribute it and/or modify 8130803Smarcel it under the terms of the GNU General Public License as published by 9130803Smarcel the Free Software Foundation; either version 2 of the License, or 10130803Smarcel (at your option) any later version. 11130803Smarcel 12130803Smarcel This program is distributed in the hope that it will be useful, 13130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 14130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15130803Smarcel GNU General Public License for more details. 16130803Smarcel 17130803Smarcel You should have received a copy of the GNU General Public License 18130803Smarcel along with this program; if not, write to the Free Software 19130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 20130803Smarcel Boston, MA 02111-1307, USA. */ 21130803Smarcel 22130803Smarcel#include "defs.h" 23130803Smarcel#include "gdbcore.h" 24130803Smarcel#include "target.h" 25130803Smarcel#include "monitor.h" 26130803Smarcel#include "serial.h" 27130803Smarcel#include "regcache.h" 28130803Smarcel#include "value.h" 29130803Smarcel 30130803Smarcel#include "m68k-tdep.h" 31130803Smarcel 32130803Smarcelstatic void rom68k_open (char *args, int from_tty); 33130803Smarcel 34130803Smarcel/* Return true if C is a hex digit. 35130803Smarcel We can't use isxdigit here: that is affected by the current locale; 36130803Smarcel ROM68K is not. */ 37130803Smarcelstatic int 38130803Smarcelis_hex_digit (int c) 39130803Smarcel{ 40130803Smarcel return (('0' <= c && c <= '9') 41130803Smarcel || ('a' <= c && c <= 'f') 42130803Smarcel || ('A' <= c && c <= 'F')); 43130803Smarcel} 44130803Smarcel 45130803Smarcel 46130803Smarcel/* Convert hex digit A to a number. */ 47130803Smarcelstatic int 48130803Smarcelhex_digit_value (int a) 49130803Smarcel{ 50130803Smarcel if (a >= '0' && a <= '9') 51130803Smarcel return a - '0'; 52130803Smarcel else if (a >= 'a' && a <= 'f') 53130803Smarcel return a - 'a' + 10; 54130803Smarcel else if (a >= 'A' && a <= 'F') 55130803Smarcel return a - 'A' + 10; 56130803Smarcel else 57130803Smarcel error ("Invalid hex digit %d", a); 58130803Smarcel} 59130803Smarcel 60130803Smarcel 61130803Smarcel/* Return true iff C is a whitespace character. 62130803Smarcel We can't use isspace here: that is affected by the current locale; 63130803Smarcel ROM68K is not. */ 64130803Smarcelstatic int 65130803Smarcelis_whitespace (int c) 66130803Smarcel{ 67130803Smarcel return (c == ' ' 68130803Smarcel || c == '\r' 69130803Smarcel || c == '\n' 70130803Smarcel || c == '\t' 71130803Smarcel || c == '\f'); 72130803Smarcel} 73130803Smarcel 74130803Smarcel 75130803Smarcel/* Parse a string of hex digits starting at HEX, supply them as the 76130803Smarcel value of register REGNO, skip any whitespace, and return a pointer 77130803Smarcel to the next character. 78130803Smarcel 79130803Smarcel There is a function in monitor.c, monitor_supply_register, which is 80130803Smarcel supposed to do this job. However, there is some rather odd stuff 81130803Smarcel in there (whitespace characters don't terminate numbers, for 82130803Smarcel example) that is incorrect for ROM68k. It's basically impossible 83130803Smarcel to safely tweak monitor_supply_register --- it's used by a zillion 84130803Smarcel other monitors; who knows what behaviors they're depending on. So 85130803Smarcel instead, we'll just use our own function, which can behave exactly 86130803Smarcel the way we want it to. */ 87130803Smarcelstatic char * 88130803Smarcelrom68k_supply_one_register (int regno, unsigned char *hex) 89130803Smarcel{ 90130803Smarcel ULONGEST value; 91130803Smarcel unsigned char regbuf[MAX_REGISTER_SIZE]; 92130803Smarcel 93130803Smarcel value = 0; 94130803Smarcel while (*hex != '\0') 95130803Smarcel if (is_hex_digit (*hex)) 96130803Smarcel value = (value * 16) + hex_digit_value (*hex++); 97130803Smarcel else 98130803Smarcel break; 99130803Smarcel 100130803Smarcel /* Skip any whitespace. */ 101130803Smarcel while (is_whitespace (*hex)) 102130803Smarcel hex++; 103130803Smarcel 104130803Smarcel store_unsigned_integer (regbuf, DEPRECATED_REGISTER_RAW_SIZE (regno), value); 105130803Smarcel supply_register (regno, regbuf); 106130803Smarcel 107130803Smarcel return hex; 108130803Smarcel} 109130803Smarcel 110130803Smarcel 111130803Smarcelstatic void 112130803Smarcelrom68k_supply_register (char *regname, int regnamelen, char *val, int vallen) 113130803Smarcel{ 114130803Smarcel int numregs; 115130803Smarcel int regno; 116130803Smarcel 117130803Smarcel numregs = 1; 118130803Smarcel regno = -1; 119130803Smarcel 120130803Smarcel if (regnamelen == 2) 121130803Smarcel switch (regname[0]) 122130803Smarcel { 123130803Smarcel case 'S': 124130803Smarcel if (regname[1] == 'R') 125130803Smarcel regno = PS_REGNUM; 126130803Smarcel break; 127130803Smarcel case 'P': 128130803Smarcel if (regname[1] == 'C') 129130803Smarcel regno = PC_REGNUM; 130130803Smarcel break; 131130803Smarcel case 'D': 132130803Smarcel if (regname[1] != 'R') 133130803Smarcel break; 134130803Smarcel regno = M68K_D0_REGNUM; 135130803Smarcel numregs = 8; 136130803Smarcel break; 137130803Smarcel case 'A': 138130803Smarcel if (regname[1] != 'R') 139130803Smarcel break; 140130803Smarcel regno = M68K_A0_REGNUM; 141130803Smarcel numregs = 7; 142130803Smarcel break; 143130803Smarcel } 144130803Smarcel else if (regnamelen == 3) 145130803Smarcel switch (regname[0]) 146130803Smarcel { 147130803Smarcel case 'I': 148130803Smarcel if (regname[1] == 'S' && regname[2] == 'P') 149130803Smarcel regno = SP_REGNUM; 150130803Smarcel } 151130803Smarcel 152130803Smarcel if (regno >= 0) 153130803Smarcel while (numregs-- > 0) 154130803Smarcel val = rom68k_supply_one_register (regno++, val); 155130803Smarcel} 156130803Smarcel 157130803Smarcel/* This array of registers need to match the indexes used by GDB. 158130803Smarcel This exists because the various ROM monitors use different strings 159130803Smarcel than does GDB, and don't necessarily support all the registers 160130803Smarcel either. So, typing "info reg sp" becomes a "r30". */ 161130803Smarcel 162130803Smarcelstatic const char * 163130803Smarcelrom68k_regname (int index) 164130803Smarcel{ 165130803Smarcel 166130803Smarcel static char *regnames[] = 167130803Smarcel { 168130803Smarcel "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", 169130803Smarcel "A0", "A1", "A2", "A3", "A4", "A5", "A6", "ISP", 170130803Smarcel "SR", "PC" 171130803Smarcel }; 172130803Smarcel 173130803Smarcel if ((index >= (sizeof (regnames) / sizeof(regnames[0]))) 174130803Smarcel || (index < 0) || (index >= NUM_REGS)) 175130803Smarcel return NULL; 176130803Smarcel else 177130803Smarcel return regnames[index]; 178130803Smarcel 179130803Smarcel} 180130803Smarcel 181130803Smarcel/* Define the monitor command strings. Since these are passed directly 182130803Smarcel through to a printf style function, we may include formatting 183130803Smarcel strings. We also need a CR or LF on the end. */ 184130803Smarcel 185130803Smarcelstatic struct target_ops rom68k_ops; 186130803Smarcel 187130803Smarcelstatic char *rom68k_inits[] = 188130803Smarcel{".\r\r", NULL}; /* Exits pm/pr & download cmds */ 189130803Smarcel 190130803Smarcelstatic struct monitor_ops rom68k_cmds; 191130803Smarcel 192130803Smarcelstatic void 193130803Smarcelinit_rom68k_cmds (void) 194130803Smarcel{ 195130803Smarcel rom68k_cmds.flags = MO_PRINT_PROGRAM_OUTPUT; 196130803Smarcel rom68k_cmds.init = rom68k_inits; /* monitor init string */ 197130803Smarcel rom68k_cmds.cont = "go\r"; 198130803Smarcel rom68k_cmds.step = "st\r"; 199130803Smarcel rom68k_cmds.stop = NULL; 200130803Smarcel rom68k_cmds.set_break = "db %x\r"; 201130803Smarcel rom68k_cmds.clr_break = "cb %x\r"; 202130803Smarcel rom68k_cmds.clr_all_break = "cb *\r"; 203130803Smarcel rom68k_cmds.fill = "fm %x %x %x\r"; 204130803Smarcel rom68k_cmds.setmem.cmdb = "pm %x %x\r"; 205130803Smarcel rom68k_cmds.setmem.cmdw = "pm.w %x %x\r"; 206130803Smarcel rom68k_cmds.setmem.cmdl = "pm.l %x %x\r"; 207130803Smarcel rom68k_cmds.setmem.cmdll = NULL; 208130803Smarcel rom68k_cmds.setmem.resp_delim = NULL; 209130803Smarcel rom68k_cmds.setmem.term = NULL; 210130803Smarcel rom68k_cmds.setmem.term_cmd = NULL; 211130803Smarcel rom68k_cmds.getmem.cmdb = "dm %x %x\r"; 212130803Smarcel rom68k_cmds.getmem.cmdw = "dm.w %x %x\r"; 213130803Smarcel rom68k_cmds.getmem.cmdl = "dm.l %x %x\r"; 214130803Smarcel rom68k_cmds.getmem.cmdll = NULL; 215130803Smarcel rom68k_cmds.getmem.resp_delim = " "; 216130803Smarcel rom68k_cmds.getmem.term = NULL; 217130803Smarcel rom68k_cmds.getmem.term_cmd = NULL; 218130803Smarcel rom68k_cmds.setreg.cmd = "pr %s %x\r"; 219130803Smarcel rom68k_cmds.setreg.resp_delim = NULL; 220130803Smarcel rom68k_cmds.setreg.term = NULL; 221130803Smarcel rom68k_cmds.setreg.term_cmd = NULL; 222130803Smarcel rom68k_cmds.getreg.cmd = "pr %s\r"; 223130803Smarcel rom68k_cmds.getreg.resp_delim = ": "; 224130803Smarcel rom68k_cmds.getreg.term = "= "; 225130803Smarcel rom68k_cmds.getreg.term_cmd = ".\r"; 226130803Smarcel rom68k_cmds.dump_registers = "dr\r"; 227130803Smarcel rom68k_cmds.register_pattern = 228130803Smarcel "\\(\\w+\\)=\\([0-9a-fA-F]+\\( +[0-9a-fA-F]+\\b\\)*\\)"; 229130803Smarcel rom68k_cmds.supply_register = rom68k_supply_register; 230130803Smarcel rom68k_cmds.load_routine = NULL; 231130803Smarcel rom68k_cmds.load = "dc\r"; 232130803Smarcel rom68k_cmds.loadresp = "Waiting for S-records from host... "; 233130803Smarcel rom68k_cmds.prompt = "ROM68K :-> "; 234130803Smarcel rom68k_cmds.line_term = "\r"; 235130803Smarcel rom68k_cmds.cmd_end = ".\r"; 236130803Smarcel rom68k_cmds.target = &rom68k_ops; 237130803Smarcel rom68k_cmds.stopbits = SERIAL_1_STOPBITS; 238130803Smarcel rom68k_cmds.regnames = NULL; 239130803Smarcel rom68k_cmds.regname = rom68k_regname; 240130803Smarcel rom68k_cmds.magic = MONITOR_OPS_MAGIC; 241130803Smarcel} /* init_rom68k_cmds */ 242130803Smarcel 243130803Smarcelstatic void 244130803Smarcelrom68k_open (char *args, int from_tty) 245130803Smarcel{ 246130803Smarcel monitor_open (args, &rom68k_cmds, from_tty); 247130803Smarcel} 248130803Smarcel 249130803Smarcelextern initialize_file_ftype _initialize_rom68k; /* -Wmissing-prototypes */ 250130803Smarcel 251130803Smarcelvoid 252130803Smarcel_initialize_rom68k (void) 253130803Smarcel{ 254130803Smarcel init_rom68k_cmds (); 255130803Smarcel init_monitor_ops (&rom68k_ops); 256130803Smarcel 257130803Smarcel rom68k_ops.to_shortname = "rom68k"; 258130803Smarcel rom68k_ops.to_longname = "Rom68k debug monitor for the IDP Eval board"; 259130803Smarcel rom68k_ops.to_doc = "Debug on a Motorola IDP eval board running the ROM68K monitor.\n\ 260130803SmarcelSpecify the serial device it is connected to (e.g. /dev/ttya)."; 261130803Smarcel rom68k_ops.to_open = rom68k_open; 262130803Smarcel 263130803Smarcel add_target (&rom68k_ops); 264130803Smarcel} 265