Home | History | Annotate | Line # | Download | only in stubs
      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