1 1.1 christos /* Debug stub for Z80. 2 1.1 christos 3 1.1.1.2 christos Copyright (C) 2021-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos /* Usage: 21 1.1 christos 1. Copy this file to project directory 22 1.1 christos 2. Configure it commenting/uncommenting macros below or define DBG_CONFIGURED 23 1.1 christos and all required macros and then include this file to one of your C-source 24 1.1 christos files. 25 1.1 christos 3. Implement getDebugChar() and putDebugChar(), functions must not return 26 1.1 christos until data received or sent. 27 1.1 christos 4. Implement all optional functions used to toggle breakpoints/watchpoints, 28 1.1 christos if supported. Do not write fuctions to toggle software breakpoints if 29 1.1 christos you unsure (GDB will do itself). 30 1.1 christos 5. Implement serial port initialization routine called at program start. 31 1.1 christos 6. Add necessary debugger entry points to your program, for example: 32 1.1 christos .org 0x08 ;RST 8 handler 33 1.1 christos jp _debug_swbreak 34 1.1 christos ... 35 1.1 christos .org 0x66 ;NMI handler 36 1.1 christos jp _debug_nmi 37 1.1 christos ... 38 1.1 christos main_loop: 39 1.1 christos halt 40 1.1 christos call isDbgInterrupt 41 1.1 christos jr z,101$ 42 1.1 christos ld hl, 2 ;EX_SIGINT 43 1.1 christos push hl 44 1.1 christos call _debug_exception 45 1.1 christos 101$: 46 1.1 christos ... 47 1.1 christos 7. Compile file using SDCC (supported ports are: z80, z180, z80n, gbz80 and 48 1.1 christos ez80_z80), do not use --peep-asm option. For example: 49 1.1 christos $ sdcc -mz80 --opt-code-size --max-allocs-per-node 50000 z80-stub.c 50 1.1 christos */ 51 1.1 christos /******************************************************************************\ 52 1.1 christos Configuration 53 1.1 christos \******************************************************************************/ 54 1.1 christos #ifndef DBG_CONFIGURED 55 1.1 christos /* Uncomment this line, if stub size is critical for you */ 56 1.1 christos //#define DBG_MIN_SIZE 57 1.1 christos 58 1.1 christos /* Comment this line out if software breakpoints are unsupported. 59 1.1 christos If you have special function to toggle software breakpoints, then provide 60 1.1 christos here name of these function. Expected prototype: 61 1.1 christos int toggle_swbreak(int set, void *addr); 62 1.1 christos function must return 0 on success. */ 63 1.1 christos //#define DBG_SWBREAK toggle_swbreak 64 1.1 christos #define DBG_SWBREAK 65 1.1 christos 66 1.1 christos /* Define if one of standard RST handlers is used as software 67 1.1 christos breakpoint entry point */ 68 1.1 christos //#define DBG_SWBREAK_RST 0x08 69 1.1 christos 70 1.1 christos /* if platform supports hardware breakpoints then define following macro 71 1.1 christos by name of function. Fuction must have next prototype: 72 1.1 christos int toggle_hwbreak(int set, void *addr); 73 1.1 christos function must return 0 on success. */ 74 1.1 christos //#define DBG_HWBREAK toggle_hwbreak 75 1.1 christos 76 1.1 christos /* if platform supports hardware watchpoints then define all or some of 77 1.1 christos following macros by names of functions. Fuctions prototypes: 78 1.1 christos int toggle_watch(int set, void *addr, size_t size); // memory write watch 79 1.1 christos int toggle_rwatch(int set, void *addr, size_t size); // memory read watch 80 1.1 christos int toggle_awatch(int set, void *addr, size_t size); // memory access watch 81 1.1 christos function must return 0 on success. */ 82 1.1 christos //#define DBG_WWATCH toggle_watch 83 1.1 christos //#define DBG_RWATCH toggle_rwatch 84 1.1 christos //#define DBG_AWATCH toggle_awatch 85 1.1 christos 86 1.1 christos /* Size of hardware breakpoint. Required to correct PC. */ 87 1.1 christos #define DBG_HWBREAK_SIZE 0 88 1.1 christos 89 1.1 christos /* Define following macro if you need custom memory read/write routine. 90 1.1 christos Function should return non-zero on success, and zero on failure 91 1.1 christos (for example, write to ROM area). 92 1.1 christos Useful with overlays (bank switching). 93 1.1 christos Do not forget to define: 94 1.1 christos _ovly_table - overlay table 95 1.1 christos _novlys - number of items in _ovly_table 96 1.1 christos or 97 1.1 christos _ovly_region_table - overlay regions table 98 1.1 christos _novly_regions - number of items in _ovly_region_table 99 1.1 christos 100 1.1 christos _ovly_debug_prepare - function is called before overlay mapping 101 1.1 christos _ovly_debug_event - function is called after overlay mapping 102 1.1 christos */ 103 1.1 christos //#define DBG_MEMCPY memcpy 104 1.1 christos 105 1.1 christos /* define dedicated stack size if required */ 106 1.1 christos //#define DBG_STACK_SIZE 256 107 1.1 christos 108 1.1 christos /* max GDB packet size 109 1.1 christos should be much less that DBG_STACK_SIZE because it will be allocated on stack 110 1.1 christos */ 111 1.1 christos #define DBG_PACKET_SIZE 150 112 1.1 christos 113 1.1 christos /* Uncomment if required to use trampoline when resuming operation. 114 1.1 christos Useful with dedicated stack when stack pointer do not point to the stack or 115 1.1 christos stack is not writable */ 116 1.1 christos //#define DBG_USE_TRAMPOLINE 117 1.1 christos 118 1.1 christos /* Uncomment following macro to enable debug printing to debugger console */ 119 1.1 christos //#define DBG_PRINT 120 1.1 christos 121 1.1 christos #define DBG_NMI_EX EX_HWBREAK 122 1.1 christos #define DBG_INT_EX EX_SIGINT 123 1.1 christos 124 1.1.1.2 christos /* Define following macro to statement, which will be executed after entering to 125 1.1 christos stub_main function. Statement should include semicolon. */ 126 1.1 christos //#define DBG_ENTER debug_enter(); 127 1.1 christos 128 1.1 christos /* Define following macro to instruction(s), which will be execute before return 129 1.1 christos control to the program. It is useful when gdb-stub is placed in one of overlays. 130 1.1 christos This procedure must not change any register. On top of stack before invocation 131 1.1 christos will be return address of the program. */ 132 1.1 christos //#define DBG_RESUME jp _restore_bank 133 1.1 christos 134 1.1 christos /* Define following macro to the string containing memory map definition XML. 135 1.1 christos GDB will use it to select proper breakpoint type (HW or SW). */ 136 1.1 christos /*#define DBG_MEMORY_MAP "\ 137 1.1 christos <memory-map>\ 138 1.1 christos <memory type=\"rom\" start=\"0x0000\" length=\"0x4000\"/>\ 139 1.1 christos <!-- <memory type=\"flash\" start=\"0x4000\" length=\"0x4000\">\ 140 1.1 christos <property name=\"blocksize\">128</property>\ 141 1.1 christos </memory> -->\ 142 1.1 christos <memory type=\"ram\" start=\"0x8000\" length=\"0x8000\"/>\ 143 1.1 christos </memory-map>\ 144 1.1 christos " 145 1.1 christos */ 146 1.1 christos #endif /* DBG_CONFIGURED */ 147 1.1 christos /******************************************************************************\ 148 1.1 christos Public Interface 149 1.1 christos \******************************************************************************/ 150 1.1 christos 151 1.1 christos /* Enter to debug mode from software or hardware breakpoint. 152 1.1 christos Assume address of next instruction after breakpoint call is on top of stack. 153 1.1 christos Do JP _debug_swbreak or JP _debug_hwbreak from RST handler, for example. 154 1.1 christos */ 155 1.1 christos void debug_swbreak (void); 156 1.1 christos void debug_hwbreak (void); 157 1.1 christos 158 1.1 christos /* Jump to this function from NMI handler. Just replace RETN instruction by 159 1.1 christos JP _debug_nmi 160 1.1 christos Use if NMI detects request to enter to debug mode. 161 1.1 christos */ 162 1.1 christos void debug_nmi (void); 163 1.1 christos 164 1.1 christos /* Jump to this function from INT handler. Just replace EI+RETI instructions by 165 1.1 christos JP _debug_int 166 1.1 christos Use if INT detects request to enter to debug mode. 167 1.1 christos */ 168 1.1 christos void debug_int (void); 169 1.1 christos 170 1.1 christos #define EX_SWBREAK 0 /* sw breakpoint */ 171 1.1 christos #define EX_HWBREAK -1 /* hw breakpoint */ 172 1.1 christos #define EX_WWATCH -2 /* memory write watch */ 173 1.1 christos #define EX_RWATCH -3 /* memory read watch */ 174 1.1 christos #define EX_AWATCH -4 /* memory access watch */ 175 1.1 christos #define EX_SIGINT 2 176 1.1 christos #define EX_SIGTRAP 5 177 1.1 christos #define EX_SIGABRT 6 178 1.1 christos #define EX_SIGBUS 10 179 1.1 christos #define EX_SIGSEGV 11 180 1.1 christos /* or any standard *nix signal value */ 181 1.1 christos 182 1.1 christos /* Enter to debug mode (after receiving BREAK from GDB, for example) 183 1.1 christos * Assume: 184 1.1 christos * program PC in (SP+0) 185 1.1 christos * caught signal in (SP+2) 186 1.1 christos * program SP is SP+4 187 1.1 christos */ 188 1.1 christos void debug_exception (int ex); 189 1.1 christos 190 1.1 christos /* Prints to debugger console. */ 191 1.1 christos void debug_print(const char *str); 192 1.1 christos /******************************************************************************\ 193 1.1 christos Required functions 194 1.1 christos \******************************************************************************/ 195 1.1 christos 196 1.1 christos extern int getDebugChar (void); 197 1.1 christos extern void putDebugChar (int ch); 198 1.1 christos 199 1.1 christos #ifdef DBG_SWBREAK 200 1.1 christos #define DO_EXPAND(VAL) VAL ## 123456 201 1.1 christos #define EXPAND(VAL) DO_EXPAND(VAL) 202 1.1 christos 203 1.1 christos #if EXPAND(DBG_SWBREAK) != 123456 204 1.1 christos #define DBG_SWBREAK_PROC DBG_SWBREAK 205 1.1 christos extern int DBG_SWBREAK(int set, void *addr); 206 1.1 christos #endif 207 1.1 christos 208 1.1 christos #undef EXPAND 209 1.1 christos #undef DO_EXPAND 210 1.1 christos #endif /* DBG_SWBREAK */ 211 1.1 christos 212 1.1 christos #ifdef DBG_HWBREAK 213 1.1 christos extern int DBG_HWBREAK(int set, void *addr); 214 1.1 christos #endif 215 1.1 christos 216 1.1 christos #ifdef DBG_MEMCPY 217 1.1 christos extern void* DBG_MEMCPY (void *dest, const void *src, unsigned n); 218 1.1 christos #endif 219 1.1 christos 220 1.1 christos #ifdef DBG_WWATCH 221 1.1 christos extern int DBG_WWATCH(int set, void *addr, unsigned size); 222 1.1 christos #endif 223 1.1 christos 224 1.1 christos #ifdef DBG_RWATCH 225 1.1 christos extern int DBG_RWATCH(int set, void *addr, unsigned size); 226 1.1 christos #endif 227 1.1 christos 228 1.1 christos #ifdef DBG_AWATCH 229 1.1 christos extern int DBG_AWATCH(int set, void *addr, unsigned size); 230 1.1 christos #endif 231 1.1 christos 232 1.1 christos /******************************************************************************\ 233 1.1 christos IMPLEMENTATION 234 1.1 christos \******************************************************************************/ 235 1.1 christos 236 1.1 christos #include <string.h> 237 1.1 christos 238 1.1 christos #ifndef NULL 239 1.1 christos # define NULL (void*)0 240 1.1 christos #endif 241 1.1 christos 242 1.1 christos typedef unsigned char byte; 243 1.1 christos typedef unsigned short word; 244 1.1 christos 245 1.1 christos /* CPU state */ 246 1.1 christos #ifdef __SDCC_ez80_adl 247 1.1 christos # define REG_SIZE 3 248 1.1 christos #else 249 1.1 christos # define REG_SIZE 2 250 1.1 christos #endif /* __SDCC_ez80_adl */ 251 1.1 christos 252 1.1 christos #define R_AF (0*REG_SIZE) 253 1.1 christos #define R_BC (1*REG_SIZE) 254 1.1 christos #define R_DE (2*REG_SIZE) 255 1.1 christos #define R_HL (3*REG_SIZE) 256 1.1 christos #define R_SP (4*REG_SIZE) 257 1.1 christos #define R_PC (5*REG_SIZE) 258 1.1 christos 259 1.1 christos #ifndef __SDCC_gbz80 260 1.1 christos #define R_IX (6*REG_SIZE) 261 1.1 christos #define R_IY (7*REG_SIZE) 262 1.1 christos #define R_AF_ (8*REG_SIZE) 263 1.1 christos #define R_BC_ (9*REG_SIZE) 264 1.1 christos #define R_DE_ (10*REG_SIZE) 265 1.1 christos #define R_HL_ (11*REG_SIZE) 266 1.1 christos #define R_IR (12*REG_SIZE) 267 1.1 christos 268 1.1 christos #ifdef __SDCC_ez80_adl 269 1.1 christos #define R_SPS (13*REG_SIZE) 270 1.1 christos #define NUMREGBYTES (14*REG_SIZE) 271 1.1 christos #else 272 1.1 christos #define NUMREGBYTES (13*REG_SIZE) 273 1.1 christos #endif /* __SDCC_ez80_adl */ 274 1.1 christos #else 275 1.1 christos #define NUMREGBYTES (6*REG_SIZE) 276 1.1 christos #define FASTCALL 277 1.1 christos #endif /*__SDCC_gbz80 */ 278 1.1 christos static byte state[NUMREGBYTES]; 279 1.1 christos 280 1.1 christos #if DBG_PACKET_SIZE < (NUMREGBYTES*2+5) 281 1.1 christos #error "Too small DBG_PACKET_SIZE" 282 1.1 christos #endif 283 1.1 christos 284 1.1 christos #ifndef FASTCALL 285 1.1 christos #define FASTCALL __z88dk_fastcall 286 1.1 christos #endif 287 1.1 christos 288 1.1 christos /* dedicated stack */ 289 1.1 christos #ifdef DBG_STACK_SIZE 290 1.1 christos 291 1.1 christos #define LOAD_SP ld sp, #_stack + DBG_STACK_SIZE 292 1.1 christos 293 1.1 christos static char stack[DBG_STACK_SIZE]; 294 1.1 christos 295 1.1 christos #else 296 1.1 christos 297 1.1 christos #undef DBG_USE_TRAMPOLINE 298 1.1 christos #define LOAD_SP 299 1.1 christos 300 1.1 christos #endif 301 1.1 christos 302 1.1 christos #ifndef DBG_ENTER 303 1.1 christos #define DBG_ENTER 304 1.1 christos #endif 305 1.1 christos 306 1.1 christos #ifndef DBG_RESUME 307 1.1 christos #define DBG_RESUME ret 308 1.1 christos #endif 309 1.1 christos 310 1.1 christos static signed char sigval; 311 1.1 christos 312 1.1 christos static void stub_main (int sigval, int pc_adj); 313 1.1 christos static char high_hex (byte v) FASTCALL; 314 1.1 christos static char low_hex (byte v) FASTCALL; 315 1.1 christos static char put_packet_info (const char *buffer) FASTCALL; 316 1.1 christos static void save_cpu_state (void); 317 1.1 christos static void rest_cpu_state (void); 318 1.1 christos 319 1.1 christos /******************************************************************************/ 320 1.1 christos #ifdef DBG_SWBREAK 321 1.1 christos #ifdef DBG_SWBREAK_RST 322 1.1 christos #define DBG_SWBREAK_SIZE 1 323 1.1 christos #else 324 1.1 christos #define DBG_SWBREAK_SIZE 3 325 1.1 christos #endif 326 1.1 christos void 327 1.1 christos debug_swbreak (void) __naked 328 1.1 christos { 329 1.1 christos __asm 330 1.1 christos ld (#_state + R_SP), sp 331 1.1 christos LOAD_SP 332 1.1 christos call _save_cpu_state 333 1.1 christos ld hl, #-DBG_SWBREAK_SIZE 334 1.1 christos push hl 335 1.1 christos ld hl, #EX_SWBREAK 336 1.1 christos push hl 337 1.1 christos call _stub_main 338 1.1 christos .globl _break_handler 339 1.1 christos #ifdef DBG_SWBREAK_RST 340 1.1 christos _break_handler = DBG_SWBREAK_RST 341 1.1 christos #else 342 1.1 christos _break_handler = _debug_swbreak 343 1.1 christos #endif 344 1.1 christos __endasm; 345 1.1 christos } 346 1.1 christos #endif /* DBG_SWBREAK */ 347 1.1 christos /******************************************************************************/ 348 1.1 christos #ifdef DBG_HWBREAK 349 1.1 christos #ifndef DBG_HWBREAK_SIZE 350 1.1 christos #define DBG_HWBREAK_SIZE 0 351 1.1 christos #endif /* DBG_HWBREAK_SIZE */ 352 1.1 christos void 353 1.1 christos debug_hwbreak (void) __naked 354 1.1 christos { 355 1.1 christos __asm 356 1.1 christos ld (#_state + R_SP), sp 357 1.1 christos LOAD_SP 358 1.1 christos call _save_cpu_state 359 1.1 christos ld hl, #-DBG_HWBREAK_SIZE 360 1.1 christos push hl 361 1.1 christos ld hl, #EX_HWBREAK 362 1.1 christos push hl 363 1.1 christos call _stub_main 364 1.1 christos __endasm; 365 1.1 christos } 366 1.1 christos #endif /* DBG_HWBREAK_SET */ 367 1.1 christos /******************************************************************************/ 368 1.1 christos void 369 1.1 christos debug_exception (int ex) __naked 370 1.1 christos { 371 1.1 christos __asm 372 1.1 christos ld (#_state + R_SP), sp 373 1.1 christos LOAD_SP 374 1.1 christos call _save_cpu_state 375 1.1 christos ld hl, #0 376 1.1 christos push hl 377 1.1 christos #ifdef __SDCC_gbz80 378 1.1 christos ld hl, #_state + R_SP 379 1.1 christos ld a, (hl+) 380 1.1 christos ld h, (hl) 381 1.1 christos ld l, a 382 1.1 christos #else 383 1.1 christos ld hl, (#_state + R_SP) 384 1.1 christos #endif 385 1.1 christos inc hl 386 1.1 christos inc hl 387 1.1 christos ld e, (hl) 388 1.1 christos inc hl 389 1.1 christos ld d, (hl) 390 1.1 christos push de 391 1.1 christos call _stub_main 392 1.1 christos __endasm; 393 1.1 christos (void)ex; 394 1.1 christos } 395 1.1 christos /******************************************************************************/ 396 1.1 christos #ifndef __SDCC_gbz80 397 1.1 christos void 398 1.1 christos debug_nmi(void) __naked 399 1.1 christos { 400 1.1 christos __asm 401 1.1 christos ld (#_state + R_SP), sp 402 1.1 christos LOAD_SP 403 1.1 christos call _save_cpu_state 404 1.1 christos ld hl, #0 ;pc_adj 405 1.1 christos push hl 406 1.1 christos ld hl, #DBG_NMI_EX 407 1.1 christos push hl 408 1.1 christos ld hl, #_stub_main 409 1.1 christos push hl 410 1.1 christos push hl 411 1.1 christos retn 412 1.1 christos __endasm; 413 1.1 christos } 414 1.1 christos #endif 415 1.1 christos /******************************************************************************/ 416 1.1 christos void 417 1.1 christos debug_int(void) __naked 418 1.1 christos { 419 1.1 christos __asm 420 1.1 christos ld (#_state + R_SP), sp 421 1.1 christos LOAD_SP 422 1.1 christos call _save_cpu_state 423 1.1 christos ld hl, #0 ;pc_adj 424 1.1 christos push hl 425 1.1 christos ld hl, #DBG_INT_EX 426 1.1 christos push hl 427 1.1 christos ld hl, #_stub_main 428 1.1 christos push hl 429 1.1 christos push hl 430 1.1 christos ei 431 1.1 christos reti 432 1.1 christos __endasm; 433 1.1 christos } 434 1.1 christos /******************************************************************************/ 435 1.1 christos #ifdef DBG_PRINT 436 1.1 christos void 437 1.1 christos debug_print(const char *str) 438 1.1 christos { 439 1.1 christos putDebugChar ('$'); 440 1.1 christos putDebugChar ('O'); 441 1.1 christos char csum = 'O'; 442 1.1 christos for (; *str != '\0'; ) 443 1.1 christos { 444 1.1 christos char c = high_hex (*str); 445 1.1 christos csum += c; 446 1.1 christos putDebugChar (c); 447 1.1 christos c = low_hex (*str++); 448 1.1 christos csum += c; 449 1.1 christos putDebugChar (c); 450 1.1 christos } 451 1.1 christos putDebugChar ('#'); 452 1.1 christos putDebugChar (high_hex (csum)); 453 1.1 christos putDebugChar (low_hex (csum)); 454 1.1 christos } 455 1.1 christos #endif /* DBG_PRINT */ 456 1.1 christos /******************************************************************************/ 457 1.1 christos static void store_pc_sp (int pc_adj) FASTCALL; 458 1.1 christos #define get_reg_value(mem) (*(void* const*)(mem)) 459 1.1 christos #define set_reg_value(mem,val) do { (*(void**)(mem) = (val)); } while (0) 460 1.1 christos static char* byte2hex(char *buf, byte val); 461 1.1 christos static int hex2int (const char **buf) FASTCALL; 462 1.1 christos static char* int2hex (char *buf, int v); 463 1.1 christos static void get_packet (char *buffer); 464 1.1 christos static void put_packet (const char *buffer); 465 1.1 christos static char process (char *buffer) FASTCALL; 466 1.1 christos static void rest_cpu_state (void); 467 1.1 christos 468 1.1 christos static void 469 1.1 christos stub_main (int ex, int pc_adj) 470 1.1 christos { 471 1.1 christos char buffer[DBG_PACKET_SIZE+1]; 472 1.1 christos sigval = (signed char)ex; 473 1.1 christos store_pc_sp (pc_adj); 474 1.1 christos 475 1.1 christos DBG_ENTER 476 1.1 christos 477 1.1 christos /* after starting gdb_stub must always return stop reason */ 478 1.1 christos *buffer = '?'; 479 1.1 christos for (; process (buffer);) 480 1.1 christos { 481 1.1 christos put_packet (buffer); 482 1.1 christos get_packet (buffer); 483 1.1 christos } 484 1.1 christos put_packet (buffer); 485 1.1 christos rest_cpu_state (); 486 1.1 christos } 487 1.1 christos 488 1.1 christos static void 489 1.1 christos get_packet (char *buffer) 490 1.1 christos { 491 1.1 christos byte csum; 492 1.1 christos char ch; 493 1.1 christos char *p; 494 1.1 christos byte esc; 495 1.1 christos #if DBG_PACKET_SIZE <= 256 496 1.1 christos byte count; /* it is OK to use up to 256 here */ 497 1.1 christos #else 498 1.1 christos unsigned count; 499 1.1 christos #endif 500 1.1 christos for (;; putDebugChar ('-')) 501 1.1 christos { 502 1.1 christos /* wait for packet start character */ 503 1.1 christos while (getDebugChar () != '$'); 504 1.1 christos retry: 505 1.1 christos csum = 0; 506 1.1 christos esc = 0; 507 1.1 christos p = buffer; 508 1.1 christos count = DBG_PACKET_SIZE; 509 1.1 christos do 510 1.1 christos { 511 1.1 christos ch = getDebugChar (); 512 1.1 christos switch (ch) 513 1.1 christos { 514 1.1 christos case '$': 515 1.1 christos goto retry; 516 1.1 christos case '#': 517 1.1 christos goto finish; 518 1.1 christos case '}': 519 1.1 christos esc = 0x20; 520 1.1 christos break; 521 1.1 christos default: 522 1.1 christos *p++ = ch ^ esc; 523 1.1 christos esc = 0; 524 1.1 christos --count; 525 1.1 christos } 526 1.1 christos csum += ch; 527 1.1 christos } 528 1.1 christos while (count != 0); 529 1.1 christos finish: 530 1.1 christos *p = '\0'; 531 1.1 christos if (ch != '#') /* packet is too large */ 532 1.1 christos continue; 533 1.1 christos ch = getDebugChar (); 534 1.1 christos if (ch != high_hex (csum)) 535 1.1 christos continue; 536 1.1 christos ch = getDebugChar (); 537 1.1 christos if (ch != low_hex (csum)) 538 1.1 christos continue; 539 1.1 christos break; 540 1.1 christos } 541 1.1 christos putDebugChar ('+'); 542 1.1 christos } 543 1.1 christos 544 1.1 christos static void 545 1.1 christos put_packet (const char *buffer) 546 1.1 christos { 547 1.1 christos /* $<packet info>#<checksum>. */ 548 1.1 christos for (;;) 549 1.1 christos { 550 1.1 christos putDebugChar ('$'); 551 1.1 christos char checksum = put_packet_info (buffer); 552 1.1 christos putDebugChar ('#'); 553 1.1 christos putDebugChar (high_hex(checksum)); 554 1.1 christos putDebugChar (low_hex(checksum)); 555 1.1 christos for (;;) 556 1.1 christos { 557 1.1 christos char c = getDebugChar (); 558 1.1 christos switch (c) 559 1.1 christos { 560 1.1 christos case '+': return; 561 1.1 christos case '-': break; 562 1.1 christos default: 563 1.1 christos putDebugChar (c); 564 1.1 christos continue; 565 1.1 christos } 566 1.1 christos break; 567 1.1 christos } 568 1.1 christos } 569 1.1 christos } 570 1.1 christos 571 1.1 christos static char 572 1.1 christos put_packet_info (const char *src) FASTCALL 573 1.1 christos { 574 1.1 christos char ch; 575 1.1 christos char checksum = 0; 576 1.1 christos for (;;) 577 1.1 christos { 578 1.1 christos ch = *src++; 579 1.1 christos if (ch == '\0') 580 1.1 christos break; 581 1.1 christos if (ch == '}' || ch == '*' || ch == '#' || ch == '$') 582 1.1 christos { 583 1.1 christos /* escape special characters */ 584 1.1 christos putDebugChar ('}'); 585 1.1 christos checksum += '}'; 586 1.1 christos ch ^= 0x20; 587 1.1 christos } 588 1.1 christos putDebugChar (ch); 589 1.1 christos checksum += ch; 590 1.1 christos } 591 1.1 christos return checksum; 592 1.1 christos } 593 1.1 christos 594 1.1 christos static void 595 1.1 christos store_pc_sp (int pc_adj) FASTCALL 596 1.1 christos { 597 1.1 christos byte *sp = get_reg_value (&state[R_SP]); 598 1.1 christos byte *pc = get_reg_value (sp); 599 1.1 christos pc += pc_adj; 600 1.1 christos set_reg_value (&state[R_PC], pc); 601 1.1 christos set_reg_value (&state[R_SP], sp + REG_SIZE); 602 1.1 christos } 603 1.1 christos 604 1.1 christos static char *mem2hex (char *buf, const byte *mem, unsigned bytes); 605 1.1 christos static char *hex2mem (byte *mem, const char *buf, unsigned bytes); 606 1.1 christos 607 1.1 christos /* Command processors. Takes pointer to buffer (begins from command symbol), 608 1.1 christos modifies buffer, returns: -1 - empty response (ignore), 0 - success, 609 1.1 christos positive: error code. */ 610 1.1 christos 611 1.1 christos #ifdef DBG_MIN_SIZE 612 1.1 christos static signed char 613 1.1 christos process_question (char *p) FASTCALL 614 1.1 christos { 615 1.1 christos signed char sig; 616 1.1 christos *p++ = 'S'; 617 1.1 christos sig = sigval; 618 1.1 christos if (sig <= 0) 619 1.1 christos sig = EX_SIGTRAP; 620 1.1 christos p = byte2hex (p, (byte)sig); 621 1.1 christos *p = '\0'; 622 1.1 christos return 0; 623 1.1 christos } 624 1.1 christos #else /* DBG_MIN_SIZE */ 625 1.1 christos static char *format_reg_value (char *p, unsigned reg_num, const byte *value); 626 1.1 christos 627 1.1 christos static signed char 628 1.1 christos process_question (char *p) FASTCALL 629 1.1 christos { 630 1.1 christos signed char sig; 631 1.1 christos *p++ = 'T'; 632 1.1 christos sig = sigval; 633 1.1 christos if (sig <= 0) 634 1.1 christos sig = EX_SIGTRAP; 635 1.1 christos p = byte2hex (p, (byte)sig); 636 1.1 christos p = format_reg_value(p, R_AF/REG_SIZE, &state[R_AF]); 637 1.1 christos p = format_reg_value(p, R_SP/REG_SIZE, &state[R_SP]); 638 1.1 christos p = format_reg_value(p, R_PC/REG_SIZE, &state[R_PC]); 639 1.1 christos #if defined(DBG_SWBREAK_PROC) || defined(DBG_HWBREAK) || defined(DBG_WWATCH) || defined(DBG_RWATCH) || defined(DBG_AWATCH) 640 1.1 christos const char *reason; 641 1.1 christos unsigned addr = 0; 642 1.1 christos switch (sigval) 643 1.1 christos { 644 1.1 christos #ifdef DBG_SWBREAK_PROC 645 1.1 christos case EX_SWBREAK: 646 1.1 christos reason = "swbreak"; 647 1.1 christos break; 648 1.1 christos #endif 649 1.1 christos #ifdef DBG_HWBREAK 650 1.1 christos case EX_HWBREAK: 651 1.1 christos reason = "hwbreak"; 652 1.1 christos break; 653 1.1 christos #endif 654 1.1 christos #ifdef DBG_WWATCH 655 1.1 christos case EX_WWATCH: 656 1.1 christos reason = "watch"; 657 1.1 christos addr = 1; 658 1.1 christos break; 659 1.1 christos #endif 660 1.1 christos #ifdef DBG_RWATCH 661 1.1 christos case EX_RWATCH: 662 1.1 christos reason = "rwatch"; 663 1.1 christos addr = 1; 664 1.1 christos break; 665 1.1 christos #endif 666 1.1 christos #ifdef DBG_AWATCH 667 1.1 christos case EX_AWATCH: 668 1.1 christos reason = "awatch"; 669 1.1 christos addr = 1; 670 1.1 christos break; 671 1.1 christos #endif 672 1.1 christos default: 673 1.1 christos goto finish; 674 1.1 christos } 675 1.1 christos while ((*p++ = *reason++)) 676 1.1 christos ; 677 1.1 christos --p; 678 1.1 christos *p++ = ':'; 679 1.1 christos if (addr != 0) 680 1.1 christos p = int2hex(p, addr); 681 1.1 christos *p++ = ';'; 682 1.1 christos finish: 683 1.1 christos #endif /* DBG_HWBREAK, DBG_WWATCH, DBG_RWATCH, DBG_AWATCH */ 684 1.1 christos *p++ = '\0'; 685 1.1 christos return 0; 686 1.1 christos } 687 1.1 christos #endif /* DBG_MINSIZE */ 688 1.1 christos 689 1.1 christos #define STRING2(x) #x 690 1.1 christos #define STRING1(x) STRING2(x) 691 1.1 christos #define STRING(x) STRING1(x) 692 1.1 christos #ifdef DBG_MEMORY_MAP 693 1.1 christos static void read_memory_map (char *buffer, unsigned offset, unsigned length); 694 1.1 christos #endif 695 1.1 christos 696 1.1 christos static signed char 697 1.1 christos process_q (char *buffer) FASTCALL 698 1.1 christos { 699 1.1 christos char *p; 700 1.1 christos if (memcmp (buffer + 1, "Supported", 9) == 0) 701 1.1 christos { 702 1.1 christos memcpy (buffer, "PacketSize=", 11); 703 1.1 christos p = int2hex (&buffer[11], DBG_PACKET_SIZE); 704 1.1 christos #ifndef DBG_MIN_SIZE 705 1.1 christos #ifdef DBG_SWBREAK_PROC 706 1.1 christos memcpy (p, ";swbreak+", 9); 707 1.1 christos p += 9; 708 1.1 christos #endif 709 1.1 christos #ifdef DBG_HWBREAK 710 1.1 christos memcpy (p, ";hwbreak+", 9); 711 1.1 christos p += 9; 712 1.1 christos #endif 713 1.1 christos #endif /* DBG_MIN_SIZE */ 714 1.1 christos 715 1.1 christos #ifdef DBG_MEMORY_MAP 716 1.1 christos memcpy (p, ";qXfer:memory-map:read+", 23); 717 1.1 christos p += 23; 718 1.1 christos #endif 719 1.1 christos *p = '\0'; 720 1.1 christos return 0; 721 1.1 christos } 722 1.1 christos #ifdef DBG_MEMORY_MAP 723 1.1 christos if (memcmp (buffer + 1, "Xfer:memory-map:read:", 21) == 0) 724 1.1 christos { 725 1.1 christos p = strchr (buffer + 1 + 21, ':'); 726 1.1 christos if (p == NULL) 727 1.1 christos return 1; 728 1.1 christos ++p; 729 1.1 christos unsigned offset = hex2int (&p); 730 1.1 christos if (*p++ != ',') 731 1.1 christos return 2; 732 1.1 christos unsigned length = hex2int (&p); 733 1.1 christos if (length == 0) 734 1.1 christos return 3; 735 1.1 christos if (length > DBG_PACKET_SIZE) 736 1.1 christos return 4; 737 1.1 christos read_memory_map (buffer, offset, length); 738 1.1 christos return 0; 739 1.1 christos } 740 1.1 christos #endif 741 1.1 christos #ifndef DBG_MIN_SIZE 742 1.1 christos if (memcmp (&buffer[1], "Attached", 9) == 0) 743 1.1 christos { 744 1.1 christos /* Just report that GDB attached to existing process 745 1.1 christos if it is not applicable for you, then send patches */ 746 1.1 christos memcpy(buffer, "1", 2); 747 1.1 christos return 0; 748 1.1 christos } 749 1.1 christos #endif /* DBG_MIN_SIZE */ 750 1.1 christos *buffer = '\0'; 751 1.1 christos return -1; 752 1.1 christos } 753 1.1 christos 754 1.1 christos static signed char 755 1.1 christos process_g (char *buffer) FASTCALL 756 1.1 christos { 757 1.1 christos mem2hex (buffer, state, NUMREGBYTES); 758 1.1 christos return 0; 759 1.1 christos } 760 1.1 christos 761 1.1 christos static signed char 762 1.1 christos process_G (char *buffer) FASTCALL 763 1.1 christos { 764 1.1 christos hex2mem (state, &buffer[1], NUMREGBYTES); 765 1.1 christos /* OK response */ 766 1.1 christos *buffer = '\0'; 767 1.1 christos return 0; 768 1.1 christos } 769 1.1 christos 770 1.1 christos static signed char 771 1.1 christos process_m (char *buffer) FASTCALL 772 1.1 christos {/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ 773 1.1 christos char *p = &buffer[1]; 774 1.1 christos byte *addr = (void*)hex2int(&p); 775 1.1 christos if (*p++ != ',') 776 1.1 christos return 1; 777 1.1 christos unsigned len = (unsigned)hex2int(&p); 778 1.1 christos if (len == 0) 779 1.1 christos return 2; 780 1.1 christos if (len > DBG_PACKET_SIZE/2) 781 1.1 christos return 3; 782 1.1 christos p = buffer; 783 1.1 christos #ifdef DBG_MEMCPY 784 1.1 christos do 785 1.1 christos { 786 1.1 christos byte tmp[16]; 787 1.1 christos unsigned tlen = sizeof(tmp); 788 1.1 christos if (tlen > len) 789 1.1 christos tlen = len; 790 1.1 christos if (!DBG_MEMCPY(tmp, addr, tlen)) 791 1.1 christos return 4; 792 1.1 christos p = mem2hex (p, tmp, tlen); 793 1.1 christos addr += tlen; 794 1.1 christos len -= tlen; 795 1.1 christos } 796 1.1 christos while (len); 797 1.1 christos #else 798 1.1 christos p = mem2hex (p, addr, len); 799 1.1 christos #endif 800 1.1 christos return 0; 801 1.1 christos } 802 1.1 christos 803 1.1 christos static signed char 804 1.1 christos process_M (char *buffer) FASTCALL 805 1.1 christos {/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ 806 1.1 christos char *p = &buffer[1]; 807 1.1 christos byte *addr = (void*)hex2int(&p); 808 1.1 christos if (*p != ',') 809 1.1 christos return 1; 810 1.1 christos ++p; 811 1.1 christos unsigned len = (unsigned)hex2int(&p); 812 1.1 christos if (*p++ != ':') 813 1.1 christos return 2; 814 1.1 christos if (len == 0) 815 1.1 christos goto end; 816 1.1 christos if (len*2 + (p - buffer) > DBG_PACKET_SIZE) 817 1.1 christos return 3; 818 1.1 christos #ifdef DBG_MEMCPY 819 1.1 christos do 820 1.1 christos { 821 1.1 christos byte tmp[16]; 822 1.1 christos unsigned tlen = sizeof(tmp); 823 1.1 christos if (tlen > len) 824 1.1 christos tlen = len; 825 1.1 christos p = hex2mem (tmp, p, tlen); 826 1.1 christos if (!DBG_MEMCPY(addr, tmp, tlen)) 827 1.1 christos return 4; 828 1.1 christos addr += tlen; 829 1.1 christos len -= tlen; 830 1.1 christos } 831 1.1 christos while (len); 832 1.1 christos #else 833 1.1 christos hex2mem (addr, p, len); 834 1.1 christos #endif 835 1.1 christos end: 836 1.1 christos /* OK response */ 837 1.1 christos *buffer = '\0'; 838 1.1 christos return 0; 839 1.1 christos } 840 1.1 christos 841 1.1 christos #ifndef DBG_MIN_SIZE 842 1.1 christos static signed char 843 1.1 christos process_X (char *buffer) FASTCALL 844 1.1 christos {/* XAA..AA,LLLL: Write LLLL binary bytes at address AA.AA return OK */ 845 1.1 christos char *p = &buffer[1]; 846 1.1 christos byte *addr = (void*)hex2int(&p); 847 1.1 christos if (*p != ',') 848 1.1 christos return 1; 849 1.1 christos ++p; 850 1.1 christos unsigned len = (unsigned)hex2int(&p); 851 1.1 christos if (*p++ != ':') 852 1.1 christos return 2; 853 1.1 christos if (len == 0) 854 1.1 christos goto end; 855 1.1 christos if (len + (p - buffer) > DBG_PACKET_SIZE) 856 1.1 christos return 3; 857 1.1 christos #ifdef DBG_MEMCPY 858 1.1 christos if (!DBG_MEMCPY(addr, p, len)) 859 1.1 christos return 4; 860 1.1 christos #else 861 1.1 christos memcpy (addr, p, len); 862 1.1 christos #endif 863 1.1 christos end: 864 1.1 christos /* OK response */ 865 1.1 christos *buffer = '\0'; 866 1.1 christos return 0; 867 1.1 christos } 868 1.1 christos #else /* DBG_MIN_SIZE */ 869 1.1 christos static signed char 870 1.1 christos process_X (char *buffer) FASTCALL 871 1.1 christos { 872 1.1 christos (void)buffer; 873 1.1 christos return -1; 874 1.1 christos } 875 1.1 christos #endif /* DBG_MIN_SIZE */ 876 1.1 christos 877 1.1 christos static signed char 878 1.1 christos process_c (char *buffer) FASTCALL 879 1.1 christos {/* 'cAAAA' - Continue at address AAAA(optional) */ 880 1.1 christos const char *p = &buffer[1]; 881 1.1 christos if (*p != '\0') 882 1.1 christos { 883 1.1 christos void *addr = (void*)hex2int(&p); 884 1.1 christos set_reg_value (&state[R_PC], addr); 885 1.1 christos } 886 1.1 christos rest_cpu_state (); 887 1.1 christos return 0; 888 1.1 christos } 889 1.1 christos 890 1.1 christos static signed char 891 1.1 christos process_D (char *buffer) FASTCALL 892 1.1 christos {/* 'D' - detach the program: continue execution */ 893 1.1 christos *buffer = '\0'; 894 1.1 christos return -2; 895 1.1 christos } 896 1.1 christos 897 1.1 christos static signed char 898 1.1 christos process_k (char *buffer) FASTCALL 899 1.1 christos {/* 'k' - Kill the program */ 900 1.1 christos set_reg_value (&state[R_PC], 0); 901 1.1 christos rest_cpu_state (); 902 1.1 christos (void)buffer; 903 1.1 christos return 0; 904 1.1 christos } 905 1.1 christos 906 1.1 christos static signed char 907 1.1 christos process_v (char *buffer) FASTCALL 908 1.1 christos { 909 1.1 christos #ifndef DBG_MIN_SIZE 910 1.1 christos if (memcmp (&buffer[1], "Cont", 4) == 0) 911 1.1 christos { 912 1.1 christos if (buffer[5] == '?') 913 1.1 christos { 914 1.1 christos /* result response will be "vCont;c;C"; C action must be 915 1.1.1.2 christos supported too, because GDB requires at lease both of them */ 916 1.1 christos memcpy (&buffer[5], ";c;C", 5); 917 1.1 christos return 0; 918 1.1 christos } 919 1.1 christos buffer[0] = '\0'; 920 1.1 christos if (buffer[5] == ';' && (buffer[6] == 'c' || buffer[6] == 'C')) 921 1.1 christos return -2; /* resume execution */ 922 1.1 christos return 1; 923 1.1 christos } 924 1.1 christos #endif /* DBG_MIN_SIZE */ 925 1.1 christos return -1; 926 1.1 christos } 927 1.1 christos 928 1.1 christos static signed char 929 1.1 christos process_zZ (char *buffer) FASTCALL 930 1.1 christos { /* insert/remove breakpoint */ 931 1.1 christos #if defined(DBG_SWBREAK_PROC) || defined(DBG_HWBREAK) || \ 932 1.1 christos defined(DBG_WWATCH) || defined(DBG_RWATCH) || defined(DBG_AWATCH) 933 1.1 christos const byte set = (*buffer == 'Z'); 934 1.1 christos const char *p = &buffer[3]; 935 1.1 christos void *addr = (void*)hex2int(&p); 936 1.1 christos if (*p != ',') 937 1.1 christos return 1; 938 1.1 christos p++; 939 1.1 christos int kind = hex2int(&p); 940 1.1 christos *buffer = '\0'; 941 1.1 christos switch (buffer[1]) 942 1.1 christos { 943 1.1 christos #ifdef DBG_SWBREAK_PROC 944 1.1 christos case '0': /* sw break */ 945 1.1 christos return DBG_SWBREAK_PROC(set, addr); 946 1.1 christos #endif 947 1.1 christos #ifdef DBG_HWBREAK 948 1.1 christos case '1': /* hw break */ 949 1.1 christos return DBG_HWBREAK(set, addr); 950 1.1 christos #endif 951 1.1 christos #ifdef DBG_WWATCH 952 1.1 christos case '2': /* write watch */ 953 1.1 christos return DBG_WWATCH(set, addr, kind); 954 1.1 christos #endif 955 1.1 christos #ifdef DBG_RWATCH 956 1.1 christos case '3': /* read watch */ 957 1.1 christos return DBG_RWATCH(set, addr, kind); 958 1.1 christos #endif 959 1.1 christos #ifdef DBG_AWATCH 960 1.1 christos case '4': /* access watch */ 961 1.1 christos return DBG_AWATCH(set, addr, kind); 962 1.1 christos #endif 963 1.1 christos default:; /* not supported */ 964 1.1 christos } 965 1.1 christos #endif 966 1.1 christos (void)buffer; 967 1.1 christos return -1; 968 1.1 christos } 969 1.1 christos 970 1.1 christos static signed char 971 1.1 christos do_process (char *buffer) FASTCALL 972 1.1 christos { 973 1.1 christos switch (*buffer) 974 1.1 christos { 975 1.1 christos case '?': return process_question (buffer); 976 1.1 christos case 'G': return process_G (buffer); 977 1.1 christos case 'k': return process_k (buffer); 978 1.1 christos case 'M': return process_M (buffer); 979 1.1 christos case 'X': return process_X (buffer); 980 1.1 christos case 'Z': return process_zZ (buffer); 981 1.1 christos case 'c': return process_c (buffer); 982 1.1 christos case 'D': return process_D (buffer); 983 1.1 christos case 'g': return process_g (buffer); 984 1.1 christos case 'm': return process_m (buffer); 985 1.1 christos case 'q': return process_q (buffer); 986 1.1 christos case 'v': return process_v (buffer); 987 1.1 christos case 'z': return process_zZ (buffer); 988 1.1 christos default: return -1; /* empty response */ 989 1.1 christos } 990 1.1 christos } 991 1.1 christos 992 1.1 christos static char 993 1.1 christos process (char *buffer) FASTCALL 994 1.1 christos { 995 1.1 christos signed char err = do_process (buffer); 996 1.1 christos char *p = buffer; 997 1.1 christos char ret = 1; 998 1.1 christos if (err == -2) 999 1.1 christos { 1000 1.1 christos ret = 0; 1001 1.1 christos err = 0; 1002 1.1 christos } 1003 1.1 christos if (err > 0) 1004 1.1 christos { 1005 1.1 christos *p++ = 'E'; 1006 1.1 christos p = byte2hex (p, err); 1007 1.1 christos *p = '\0'; 1008 1.1 christos } 1009 1.1 christos else if (err < 0) 1010 1.1 christos { 1011 1.1 christos *p = '\0'; 1012 1.1 christos } 1013 1.1 christos else if (*p == '\0') 1014 1.1 christos memcpy(p, "OK", 3); 1015 1.1 christos return ret; 1016 1.1 christos } 1017 1.1 christos 1018 1.1 christos static char * 1019 1.1 christos byte2hex (char *p, byte v) 1020 1.1 christos { 1021 1.1 christos *p++ = high_hex (v); 1022 1.1 christos *p++ = low_hex (v); 1023 1.1 christos return p; 1024 1.1 christos } 1025 1.1 christos 1026 1.1 christos static signed char 1027 1.1 christos hex2val (unsigned char hex) FASTCALL 1028 1.1 christos { 1029 1.1 christos if (hex <= '9') 1030 1.1 christos return hex - '0'; 1031 1.1 christos hex &= 0xdf; /* make uppercase */ 1032 1.1 christos hex -= 'A' - 10; 1033 1.1 christos return (hex >= 10 && hex < 16) ? hex : -1; 1034 1.1 christos } 1035 1.1 christos 1036 1.1 christos static int 1037 1.1 christos hex2byte (const char *p) FASTCALL 1038 1.1 christos { 1039 1.1 christos signed char h = hex2val (p[0]); 1040 1.1 christos signed char l = hex2val (p[1]); 1041 1.1 christos if (h < 0 || l < 0) 1042 1.1 christos return -1; 1043 1.1 christos return (byte)((byte)h << 4) | (byte)l; 1044 1.1 christos } 1045 1.1 christos 1046 1.1 christos static int 1047 1.1 christos hex2int (const char **buf) FASTCALL 1048 1.1 christos { 1049 1.1 christos word r = 0; 1050 1.1 christos for (;; (*buf)++) 1051 1.1 christos { 1052 1.1 christos signed char a = hex2val(**buf); 1053 1.1 christos if (a < 0) 1054 1.1 christos break; 1055 1.1 christos r <<= 4; 1056 1.1 christos r += (byte)a; 1057 1.1 christos } 1058 1.1 christos return (int)r; 1059 1.1 christos } 1060 1.1 christos 1061 1.1 christos static char * 1062 1.1 christos int2hex (char *buf, int v) 1063 1.1 christos { 1064 1.1 christos buf = byte2hex(buf, (word)v >> 8); 1065 1.1 christos return byte2hex(buf, (byte)v); 1066 1.1 christos } 1067 1.1 christos 1068 1.1 christos static char 1069 1.1 christos high_hex (byte v) FASTCALL 1070 1.1 christos { 1071 1.1 christos return low_hex(v >> 4); 1072 1.1 christos } 1073 1.1 christos 1074 1.1 christos static char 1075 1.1 christos low_hex (byte v) FASTCALL 1076 1.1 christos { 1077 1.1 christos /* 1078 1.1 christos __asm 1079 1.1 christos ld a, l 1080 1.1 christos and a, #0x0f 1081 1.1 christos add a, #0x90 1082 1.1 christos daa 1083 1.1 christos adc a, #0x40 1084 1.1 christos daa 1085 1.1 christos ld l, a 1086 1.1 christos __endasm; 1087 1.1 christos (void)v; 1088 1.1 christos */ 1089 1.1 christos v &= 0x0f; 1090 1.1 christos v += '0'; 1091 1.1 christos if (v < '9'+1) 1092 1.1 christos return v; 1093 1.1 christos return v + 'a' - '0' - 10; 1094 1.1 christos } 1095 1.1 christos 1096 1.1 christos /* convert the memory, pointed to by mem into hex, placing result in buf */ 1097 1.1 christos /* return a pointer to the last char put in buf (null) */ 1098 1.1 christos static char * 1099 1.1 christos mem2hex (char *buf, const byte *mem, unsigned bytes) 1100 1.1 christos { 1101 1.1 christos char *d = buf; 1102 1.1 christos if (bytes != 0) 1103 1.1 christos { 1104 1.1 christos do 1105 1.1 christos { 1106 1.1 christos d = byte2hex (d, *mem++); 1107 1.1 christos } 1108 1.1 christos while (--bytes); 1109 1.1 christos } 1110 1.1 christos *d = 0; 1111 1.1 christos return d; 1112 1.1 christos } 1113 1.1 christos 1114 1.1 christos /* convert the hex array pointed to by buf into binary, to be placed in mem 1115 1.1 christos return a pointer to the character after the last byte written */ 1116 1.1 christos 1117 1.1 christos static const char * 1118 1.1 christos hex2mem (byte *mem, const char *buf, unsigned bytes) 1119 1.1 christos { 1120 1.1 christos if (bytes != 0) 1121 1.1 christos { 1122 1.1 christos do 1123 1.1 christos { 1124 1.1 christos *mem++ = hex2byte (buf); 1125 1.1 christos buf += 2; 1126 1.1 christos } 1127 1.1 christos while (--bytes); 1128 1.1 christos } 1129 1.1 christos return buf; 1130 1.1 christos } 1131 1.1 christos 1132 1.1 christos #ifdef DBG_MEMORY_MAP 1133 1.1 christos static void 1134 1.1 christos read_memory_map (char *buffer, unsigned offset, unsigned length) 1135 1.1 christos { 1136 1.1 christos const char *map = DBG_MEMORY_MAP; 1137 1.1 christos const unsigned map_sz = strlen(map); 1138 1.1 christos if (offset >= map_sz) 1139 1.1 christos { 1140 1.1 christos buffer[0] = 'l'; 1141 1.1 christos buffer[1] = '\0'; 1142 1.1 christos return; 1143 1.1 christos } 1144 1.1 christos if (offset + length > map_sz) 1145 1.1 christos length = map_sz - offset; 1146 1.1 christos buffer[0] = 'm'; 1147 1.1 christos memcpy (&buffer[1], &map[offset], length); 1148 1.1 christos buffer[1+length] = '\0'; 1149 1.1 christos } 1150 1.1 christos #endif 1151 1.1 christos 1152 1.1 christos /* write string like " nn:0123" and return pointer after it */ 1153 1.1 christos #ifndef DBG_MIN_SIZE 1154 1.1 christos static char * 1155 1.1 christos format_reg_value (char *p, unsigned reg_num, const byte *value) 1156 1.1 christos { 1157 1.1 christos char *d = p; 1158 1.1 christos unsigned char i; 1159 1.1 christos d = byte2hex(d, reg_num); 1160 1.1 christos *d++ = ':'; 1161 1.1 christos value += REG_SIZE; 1162 1.1 christos i = REG_SIZE; 1163 1.1 christos do 1164 1.1 christos { 1165 1.1 christos d = byte2hex(d, *--value); 1166 1.1 christos } 1167 1.1 christos while (--i != 0); 1168 1.1 christos *d++ = ';'; 1169 1.1 christos return d; 1170 1.1 christos } 1171 1.1 christos #endif /* DBG_MIN_SIZE */ 1172 1.1 christos 1173 1.1 christos #ifdef __SDCC_gbz80 1174 1.1 christos /* saves all state.except PC and SP */ 1175 1.1 christos static void 1176 1.1 christos save_cpu_state() __naked 1177 1.1 christos { 1178 1.1 christos __asm 1179 1.1 christos push af 1180 1.1 christos ld a, l 1181 1.1 christos ld (#_state + R_HL + 0), a 1182 1.1 christos ld a, h 1183 1.1 christos ld (#_state + R_HL + 1), a 1184 1.1 christos ld hl, #_state + R_HL - 1 1185 1.1 christos ld (hl), d 1186 1.1 christos dec hl 1187 1.1 christos ld (hl), e 1188 1.1 christos dec hl 1189 1.1 christos ld (hl), b 1190 1.1 christos dec hl 1191 1.1 christos ld (hl), c 1192 1.1 christos dec hl 1193 1.1 christos pop bc 1194 1.1 christos ld (hl), b 1195 1.1 christos dec hl 1196 1.1 christos ld (hl), c 1197 1.1 christos ret 1198 1.1 christos __endasm; 1199 1.1 christos } 1200 1.1 christos 1201 1.1 christos /* restore CPU state and continue execution */ 1202 1.1 christos static void 1203 1.1 christos rest_cpu_state() __naked 1204 1.1 christos { 1205 1.1 christos __asm 1206 1.1 christos ;restore SP 1207 1.1 christos ld a, (#_state + R_SP + 0) 1208 1.1 christos ld l,a 1209 1.1 christos ld a, (#_state + R_SP + 1) 1210 1.1 christos ld h,a 1211 1.1 christos ld sp, hl 1212 1.1 christos ;push PC value as return address 1213 1.1 christos ld a, (#_state + R_PC + 0) 1214 1.1 christos ld l, a 1215 1.1 christos ld a, (#_state + R_PC + 1) 1216 1.1 christos ld h, a 1217 1.1 christos push hl 1218 1.1 christos ;restore registers 1219 1.1 christos ld hl, #_state + R_AF 1220 1.1 christos ld c, (hl) 1221 1.1 christos inc hl 1222 1.1 christos ld b, (hl) 1223 1.1 christos inc hl 1224 1.1 christos push bc 1225 1.1 christos ld c, (hl) 1226 1.1 christos inc hl 1227 1.1 christos ld b, (hl) 1228 1.1 christos inc hl 1229 1.1 christos ld e, (hl) 1230 1.1 christos inc hl 1231 1.1 christos ld d, (hl) 1232 1.1 christos inc hl 1233 1.1 christos ld a, (hl) 1234 1.1 christos inc hl 1235 1.1 christos ld h, (hl) 1236 1.1 christos ld l, a 1237 1.1 christos pop af 1238 1.1 christos ret 1239 1.1 christos __endasm; 1240 1.1 christos } 1241 1.1 christos #else 1242 1.1 christos /* saves all state.except PC and SP */ 1243 1.1 christos static void 1244 1.1 christos save_cpu_state() __naked 1245 1.1 christos { 1246 1.1 christos __asm 1247 1.1 christos ld (#_state + R_HL), hl 1248 1.1 christos ld (#_state + R_DE), de 1249 1.1 christos ld (#_state + R_BC), bc 1250 1.1 christos push af 1251 1.1 christos pop hl 1252 1.1 christos ld (#_state + R_AF), hl 1253 1.1 christos ld a, r ;R is increased by 7 or by 8 if called via RST 1254 1.1 christos ld l, a 1255 1.1 christos sub a, #7 1256 1.1 christos xor a, l 1257 1.1 christos and a, #0x7f 1258 1.1 christos xor a, l 1259 1.1 christos #ifdef __SDCC_ez80_adl 1260 1.1 christos ld hl, i 1261 1.1 christos ex de, hl 1262 1.1 christos ld hl, #_state + R_IR 1263 1.1 christos ld (hl), a 1264 1.1 christos inc hl 1265 1.1 christos ld (hl), e 1266 1.1 christos inc hl 1267 1.1 christos ld (hl), d 1268 1.1 christos ld a, MB 1269 1.1 christos ld (#_state + R_AF+2), a 1270 1.1 christos #else 1271 1.1 christos ld l, a 1272 1.1 christos ld a, i 1273 1.1 christos ld h, a 1274 1.1 christos ld (#_state + R_IR), hl 1275 1.1 christos #endif /* __SDCC_ez80_adl */ 1276 1.1 christos ld (#_state + R_IX), ix 1277 1.1 christos ld (#_state + R_IY), iy 1278 1.1 christos ex af, af' ;' 1279 1.1 christos exx 1280 1.1 christos ld (#_state + R_HL_), hl 1281 1.1 christos ld (#_state + R_DE_), de 1282 1.1 christos ld (#_state + R_BC_), bc 1283 1.1 christos push af 1284 1.1 christos pop hl 1285 1.1 christos ld (#_state + R_AF_), hl 1286 1.1 christos ret 1287 1.1 christos __endasm; 1288 1.1 christos } 1289 1.1 christos 1290 1.1 christos /* restore CPU state and continue execution */ 1291 1.1 christos static void 1292 1.1 christos rest_cpu_state() __naked 1293 1.1 christos { 1294 1.1 christos __asm 1295 1.1 christos #ifdef DBG_USE_TRAMPOLINE 1296 1.1 christos ld sp, _stack + DBG_STACK_SIZE 1297 1.1 christos ld hl, (#_state + R_PC) 1298 1.1 christos push hl /* resume address */ 1299 1.1 christos #ifdef __SDCC_ez80_adl 1300 1.1 christos ld hl, 0xc30000 ; use 0xc34000 for jp.s 1301 1.1 christos #else 1302 1.1 christos ld hl, 0xc300 1303 1.1 christos #endif 1304 1.1 christos push hl /* JP opcode */ 1305 1.1 christos #endif /* DBG_USE_TRAMPOLINE */ 1306 1.1 christos ld hl, (#_state + R_AF_) 1307 1.1 christos push hl 1308 1.1 christos pop af 1309 1.1 christos ld bc, (#_state + R_BC_) 1310 1.1 christos ld de, (#_state + R_DE_) 1311 1.1 christos ld hl, (#_state + R_HL_) 1312 1.1 christos exx 1313 1.1 christos ex af, af' ;' 1314 1.1 christos ld iy, (#_state + R_IY) 1315 1.1 christos ld ix, (#_state + R_IX) 1316 1.1 christos #ifdef __SDCC_ez80_adl 1317 1.1 christos ld a, (#_state + R_AF + 2) 1318 1.1 christos ld MB, a 1319 1.1 christos ld hl, (#_state + R_IR + 1) ;I register 1320 1.1 christos ld i, hl 1321 1.1 christos ld a, (#_state + R_IR + 0) ; R register 1322 1.1 christos ld l, a 1323 1.1 christos #else 1324 1.1 christos ld hl, (#_state + R_IR) 1325 1.1 christos ld a, h 1326 1.1 christos ld i, a 1327 1.1 christos ld a, l 1328 1.1 christos #endif /* __SDCC_ez80_adl */ 1329 1.1 christos sub a, #10 ;number of M1 cycles after ld r,a 1330 1.1 christos xor a, l 1331 1.1 christos and a, #0x7f 1332 1.1 christos xor a, l 1333 1.1 christos ld r, a 1334 1.1 christos ld de, (#_state + R_DE) 1335 1.1 christos ld bc, (#_state + R_BC) 1336 1.1 christos ld hl, (#_state + R_AF) 1337 1.1 christos push hl 1338 1.1 christos pop af 1339 1.1 christos ld sp, (#_state + R_SP) 1340 1.1 christos #ifndef DBG_USE_TRAMPOLINE 1341 1.1 christos ld hl, (#_state + R_PC) 1342 1.1 christos push hl 1343 1.1 christos ld hl, (#_state + R_HL) 1344 1.1 christos DBG_RESUME 1345 1.1 christos #else 1346 1.1 christos ld hl, (#_state + R_HL) 1347 1.1 christos #ifdef __SDCC_ez80_adl 1348 1.1 christos jp #_stack + DBG_STACK_SIZE - 4 1349 1.1 christos #else 1350 1.1 christos jp #_stack + DBG_STACK_SIZE - 3 1351 1.1 christos #endif 1352 1.1 christos #endif /* DBG_USE_TRAMPOLINE */ 1353 1.1 christos __endasm; 1354 1.1 christos } 1355 1.1 christos #endif /* __SDCC_gbz80 */ 1356