3 Copyright (C) 2021-2022 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 1. Copy this file to project directory
22 2. Configure it commenting/uncommenting macros below or define DBG_CONFIGURED
23 and all required macros and then include this file to one of your C-source
25 3. Implement getDebugChar() and putDebugChar(), functions must not return
26 until data received or sent.
27 4. Implement all optional functions used to toggle breakpoints/watchpoints,
28 if supported. Do not write fuctions to toggle software breakpoints if
29 you unsure (GDB will do itself).
30 5. Implement serial port initialization routine called at program start.
31 6. Add necessary debugger entry points to your program, for example:
32 .org 0x08 ;RST 8 handler
35 .org 0x66 ;NMI handler
47 7. Compile file using SDCC (supported ports are: z80, z180, z80n, gbz80 and
48 ez80_z80), do not use --peep-asm option. For example:
49 $ sdcc -mz80 --opt-code-size --max-allocs-per-node 50000 z80-stub.c
51 /******************************************************************************\
53 \******************************************************************************/
54 #ifndef DBG_CONFIGURED
55 /* Uncomment this line, if stub size is critical for you */
56 //#define DBG_MIN_SIZE
58 /* Comment this line out if software breakpoints are unsupported.
59 If you have special function to toggle software breakpoints, then provide
60 here name of these function. Expected prototype:
61 int toggle_swbreak(int set, void *addr);
62 function must return 0 on success. */
63 //#define DBG_SWBREAK toggle_swbreak
66 /* Define if one of standard RST handlers is used as software
67 breakpoint entry point */
68 //#define DBG_SWBREAK_RST 0x08
70 /* if platform supports hardware breakpoints then define following macro
71 by name of function. Fuction must have next prototype:
72 int toggle_hwbreak(int set, void *addr);
73 function must return 0 on success. */
74 //#define DBG_HWBREAK toggle_hwbreak
76 /* if platform supports hardware watchpoints then define all or some of
77 following macros by names of functions. Fuctions prototypes:
78 int toggle_watch(int set, void *addr, size_t size); // memory write watch
79 int toggle_rwatch(int set, void *addr, size_t size); // memory read watch
80 int toggle_awatch(int set, void *addr, size_t size); // memory access watch
81 function must return 0 on success. */
82 //#define DBG_WWATCH toggle_watch
83 //#define DBG_RWATCH toggle_rwatch
84 //#define DBG_AWATCH toggle_awatch
86 /* Size of hardware breakpoint. Required to correct PC. */
87 #define DBG_HWBREAK_SIZE 0
89 /* Define following macro if you need custom memory read/write routine.
90 Function should return non-zero on success, and zero on failure
91 (for example, write to ROM area).
92 Useful with overlays (bank switching).
93 Do not forget to define:
94 _ovly_table - overlay table
95 _novlys - number of items in _ovly_table
97 _ovly_region_table - overlay regions table
98 _novly_regions - number of items in _ovly_region_table
100 _ovly_debug_prepare - function is called before overlay mapping
101 _ovly_debug_event - function is called after overlay mapping
103 //#define DBG_MEMCPY memcpy
105 /* define dedicated stack size if required */
106 //#define DBG_STACK_SIZE 256
108 /* max GDB packet size
109 should be much less that DBG_STACK_SIZE because it will be allocated on stack
111 #define DBG_PACKET_SIZE 150
113 /* Uncomment if required to use trampoline when resuming operation.
114 Useful with dedicated stack when stack pointer do not point to the stack or
115 stack is not writable */
116 //#define DBG_USE_TRAMPOLINE
118 /* Uncomment following macro to enable debug printing to debugger console */
121 #define DBG_NMI_EX EX_HWBREAK
122 #define DBG_INT_EX EX_SIGINT
124 /* Define following macro to statement, which will be exectuted after entering to
125 stub_main function. Statement should include semicolon. */
126 //#define DBG_ENTER debug_enter();
128 /* Define following macro to instruction(s), which will be execute before return
129 control to the program. It is useful when gdb-stub is placed in one of overlays.
130 This procedure must not change any register. On top of stack before invocation
131 will be return address of the program. */
132 //#define DBG_RESUME jp _restore_bank
134 /* Define following macro to the string containing memory map definition XML.
135 GDB will use it to select proper breakpoint type (HW or SW). */
136 /*#define DBG_MEMORY_MAP "\
138 <memory type=\"rom\" start=\"0x0000\" length=\"0x4000\"/>\
139 <!-- <memory type=\"flash\" start=\"0x4000\" length=\"0x4000\">\
140 <property name=\"blocksize\">128</property>\
142 <memory type=\"ram\" start=\"0x8000\" length=\"0x8000\"/>\
146 #endif /* DBG_CONFIGURED */
147 /******************************************************************************\
149 \******************************************************************************/
151 /* Enter to debug mode from software or hardware breakpoint.
152 Assume address of next instruction after breakpoint call is on top of stack.
153 Do JP _debug_swbreak or JP _debug_hwbreak from RST handler, for example.
155 void debug_swbreak (void);
156 void debug_hwbreak (void);
158 /* Jump to this function from NMI handler. Just replace RETN instruction by
160 Use if NMI detects request to enter to debug mode.
162 void debug_nmi (void);
164 /* Jump to this function from INT handler. Just replace EI+RETI instructions by
166 Use if INT detects request to enter to debug mode.
168 void debug_int (void);
170 #define EX_SWBREAK 0 /* sw breakpoint */
171 #define EX_HWBREAK -1 /* hw breakpoint */
172 #define EX_WWATCH -2 /* memory write watch */
173 #define EX_RWATCH -3 /* memory read watch */
174 #define EX_AWATCH -4 /* memory access watch */
179 #define EX_SIGSEGV 11
180 /* or any standard *nix signal value */
182 /* Enter to debug mode (after receiving BREAK from GDB, for example)
184 * program PC in (SP+0)
185 * caught signal in (SP+2)
188 void debug_exception (int ex
);
190 /* Prints to debugger console. */
191 void debug_print(const char *str
);
192 /******************************************************************************\
194 \******************************************************************************/
196 extern int getDebugChar (void);
197 extern void putDebugChar (int ch
);
200 #define DO_EXPAND(VAL) VAL ## 123456
201 #define EXPAND(VAL) DO_EXPAND(VAL)
203 #if EXPAND(DBG_SWBREAK) != 123456
204 #define DBG_SWBREAK_PROC DBG_SWBREAK
205 extern int DBG_SWBREAK(int set
, void *addr
);
210 #endif /* DBG_SWBREAK */
213 extern int DBG_HWBREAK(int set
, void *addr
);
217 extern void* DBG_MEMCPY (void *dest
, const void *src
, unsigned n
);
221 extern int DBG_WWATCH(int set
, void *addr
, unsigned size
);
225 extern int DBG_RWATCH(int set
, void *addr
, unsigned size
);
229 extern int DBG_AWATCH(int set
, void *addr
, unsigned size
);
232 /******************************************************************************\
234 \******************************************************************************/
239 # define NULL (void*)0
242 typedef unsigned char byte
;
243 typedef unsigned short word
;
246 #ifdef __SDCC_ez80_adl
250 #endif /* __SDCC_ez80_adl */
252 #define R_AF (0*REG_SIZE)
253 #define R_BC (1*REG_SIZE)
254 #define R_DE (2*REG_SIZE)
255 #define R_HL (3*REG_SIZE)
256 #define R_SP (4*REG_SIZE)
257 #define R_PC (5*REG_SIZE)
260 #define R_IX (6*REG_SIZE)
261 #define R_IY (7*REG_SIZE)
262 #define R_AF_ (8*REG_SIZE)
263 #define R_BC_ (9*REG_SIZE)
264 #define R_DE_ (10*REG_SIZE)
265 #define R_HL_ (11*REG_SIZE)
266 #define R_IR (12*REG_SIZE)
268 #ifdef __SDCC_ez80_adl
269 #define R_SPS (13*REG_SIZE)
270 #define NUMREGBYTES (14*REG_SIZE)
272 #define NUMREGBYTES (13*REG_SIZE)
273 #endif /* __SDCC_ez80_adl */
275 #define NUMREGBYTES (6*REG_SIZE)
277 #endif /*__SDCC_gbz80 */
278 static byte state
[NUMREGBYTES
];
280 #if DBG_PACKET_SIZE < (NUMREGBYTES*2+5)
281 #error "Too small DBG_PACKET_SIZE"
285 #define FASTCALL __z88dk_fastcall
288 /* dedicated stack */
289 #ifdef DBG_STACK_SIZE
291 #define LOAD_SP ld sp, #_stack + DBG_STACK_SIZE
293 static char stack
[DBG_STACK_SIZE
];
297 #undef DBG_USE_TRAMPOLINE
307 #define DBG_RESUME ret
310 static signed char sigval
;
312 static void stub_main (int sigval
, int pc_adj
);
313 static char high_hex (byte v
) FASTCALL
;
314 static char low_hex (byte v
) FASTCALL
;
315 static char put_packet_info (const char *buffer
) FASTCALL
;
316 static void save_cpu_state (void);
317 static void rest_cpu_state (void);
319 /******************************************************************************/
321 #ifdef DBG_SWBREAK_RST
322 #define DBG_SWBREAK_SIZE 1
324 #define DBG_SWBREAK_SIZE 3
327 debug_swbreak (void) __naked
330 ld (#_state + R_SP), sp
333 ld hl
, #-DBG_SWBREAK_SIZE
338 .globl _break_handler
339 #ifdef DBG_SWBREAK_RST
340 _break_handler
= DBG_SWBREAK_RST
342 _break_handler
= _debug_swbreak
346 #endif /* DBG_SWBREAK */
347 /******************************************************************************/
349 #ifndef DBG_HWBREAK_SIZE
350 #define DBG_HWBREAK_SIZE 0
351 #endif /* DBG_HWBREAK_SIZE */
353 debug_hwbreak (void) __naked
356 ld (#_state + R_SP), sp
359 ld hl
, #-DBG_HWBREAK_SIZE
366 #endif /* DBG_HWBREAK_SET */
367 /******************************************************************************/
369 debug_exception (int ex
) __naked
372 ld (#_state + R_SP), sp
378 ld hl
, #_state + R_SP
383 ld hl
, (#_state + R_SP)
395 /******************************************************************************/
398 debug_nmi(void) __naked
401 ld (#_state + R_SP), sp
415 /******************************************************************************/
417 debug_int(void) __naked
420 ld (#_state + R_SP), sp
434 /******************************************************************************/
437 debug_print(const char *str
)
442 for (; *str
!= '\0'; )
444 char c
= high_hex (*str
);
447 c
= low_hex (*str
++);
452 putDebugChar (high_hex (csum
));
453 putDebugChar (low_hex (csum
));
455 #endif /* DBG_PRINT */
456 /******************************************************************************/
457 static void store_pc_sp (int pc_adj
) FASTCALL
;
458 #define get_reg_value(mem) (*(void* const*)(mem))
459 #define set_reg_value(mem,val) do { (*(void**)(mem) = (val)); } while (0)
460 static char* byte2hex(char *buf
, byte val
);
461 static int hex2int (const char **buf
) FASTCALL
;
462 static char* int2hex (char *buf
, int v
);
463 static void get_packet (char *buffer
);
464 static void put_packet (const char *buffer
);
465 static char process (char *buffer
) FASTCALL
;
466 static void rest_cpu_state (void);
469 stub_main (int ex
, int pc_adj
)
471 char buffer
[DBG_PACKET_SIZE
+1];
472 sigval
= (signed char)ex
;
473 store_pc_sp (pc_adj
);
477 /* after starting gdb_stub must always return stop reason */
479 for (; process (buffer
);)
489 get_packet (char *buffer
)
495 #if DBG_PACKET_SIZE <= 256
496 byte count
; /* it is OK to use up to 256 here */
500 for (;; putDebugChar ('-'))
502 /* wait for packet start character */
503 while (getDebugChar () != '$');
508 count
= DBG_PACKET_SIZE
;
511 ch
= getDebugChar ();
531 if (ch
!= '#') /* packet is too large */
533 ch
= getDebugChar ();
534 if (ch
!= high_hex (csum
))
536 ch
= getDebugChar ();
537 if (ch
!= low_hex (csum
))
545 put_packet (const char *buffer
)
547 /* $<packet info>#<checksum>. */
551 char checksum
= put_packet_info (buffer
);
553 putDebugChar (high_hex(checksum
));
554 putDebugChar (low_hex(checksum
));
557 char c
= getDebugChar ();
572 put_packet_info (const char *src
) FASTCALL
581 if (ch
== '}' || ch
== '*' || ch
== '#' || ch
== '$')
583 /* escape special characters */
595 store_pc_sp (int pc_adj
) FASTCALL
597 byte
*sp
= get_reg_value (&state
[R_SP
]);
598 byte
*pc
= get_reg_value (sp
);
600 set_reg_value (&state
[R_PC
], pc
);
601 set_reg_value (&state
[R_SP
], sp
+ REG_SIZE
);
604 static char *mem2hex (char *buf
, const byte
*mem
, unsigned bytes
);
605 static char *hex2mem (byte
*mem
, const char *buf
, unsigned bytes
);
607 /* Command processors. Takes pointer to buffer (begins from command symbol),
608 modifies buffer, returns: -1 - empty response (ignore), 0 - success,
609 positive: error code. */
613 process_question (char *p
) FASTCALL
620 p
= byte2hex (p
, (byte
)sig
);
624 #else /* DBG_MIN_SIZE */
625 static char *format_reg_value (char *p
, unsigned reg_num
, const byte
*value
);
628 process_question (char *p
) FASTCALL
635 p
= byte2hex (p
, (byte
)sig
);
636 p
= format_reg_value(p
, R_AF
/REG_SIZE
, &state
[R_AF
]);
637 p
= format_reg_value(p
, R_SP
/REG_SIZE
, &state
[R_SP
]);
638 p
= format_reg_value(p
, R_PC
/REG_SIZE
, &state
[R_PC
]);
639 #if defined(DBG_SWBREAK_PROC) || defined(DBG_HWBREAK) || defined(DBG_WWATCH) || defined(DBG_RWATCH) || defined(DBG_AWATCH)
644 #ifdef DBG_SWBREAK_PROC
675 while ((*p
++ = *reason
++))
680 p
= int2hex(p
, addr
);
683 #endif /* DBG_HWBREAK, DBG_WWATCH, DBG_RWATCH, DBG_AWATCH */
687 #endif /* DBG_MINSIZE */
689 #define STRING2(x) #x
690 #define STRING1(x) STRING2(x)
691 #define STRING(x) STRING1(x)
692 #ifdef DBG_MEMORY_MAP
693 static void read_memory_map (char *buffer
, unsigned offset
, unsigned length
);
697 process_q (char *buffer
) FASTCALL
700 if (memcmp (buffer
+ 1, "Supported", 9) == 0)
702 memcpy (buffer
, "PacketSize=", 11);
703 p
= int2hex (&buffer
[11], DBG_PACKET_SIZE
);
705 #ifdef DBG_SWBREAK_PROC
706 memcpy (p
, ";swbreak+", 9);
710 memcpy (p
, ";hwbreak+", 9);
713 #endif /* DBG_MIN_SIZE */
715 #ifdef DBG_MEMORY_MAP
716 memcpy (p
, ";qXfer:memory-map:read+", 23);
722 #ifdef DBG_MEMORY_MAP
723 if (memcmp (buffer
+ 1, "Xfer:memory-map:read:", 21) == 0)
725 p
= strchr (buffer
+ 1 + 21, ':');
729 unsigned offset
= hex2int (&p
);
732 unsigned length
= hex2int (&p
);
735 if (length
> DBG_PACKET_SIZE
)
737 read_memory_map (buffer
, offset
, length
);
742 if (memcmp (&buffer
[1], "Attached", 9) == 0)
744 /* Just report that GDB attached to existing process
745 if it is not applicable for you, then send patches */
746 memcpy(buffer
, "1", 2);
749 #endif /* DBG_MIN_SIZE */
755 process_g (char *buffer
) FASTCALL
757 mem2hex (buffer
, state
, NUMREGBYTES
);
762 process_G (char *buffer
) FASTCALL
764 hex2mem (state
, &buffer
[1], NUMREGBYTES
);
771 process_m (char *buffer
) FASTCALL
772 {/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
773 char *p
= &buffer
[1];
774 byte
*addr
= (void*)hex2int(&p
);
777 unsigned len
= (unsigned)hex2int(&p
);
780 if (len
> DBG_PACKET_SIZE
/2)
787 unsigned tlen
= sizeof(tmp
);
790 if (!DBG_MEMCPY(tmp
, addr
, tlen
))
792 p
= mem2hex (p
, tmp
, tlen
);
798 p
= mem2hex (p
, addr
, len
);
804 process_M (char *buffer
) FASTCALL
805 {/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
806 char *p
= &buffer
[1];
807 byte
*addr
= (void*)hex2int(&p
);
811 unsigned len
= (unsigned)hex2int(&p
);
816 if (len
*2 + (p
- buffer
) > DBG_PACKET_SIZE
)
822 unsigned tlen
= sizeof(tmp
);
825 p
= hex2mem (tmp
, p
, tlen
);
826 if (!DBG_MEMCPY(addr
, tmp
, tlen
))
833 hex2mem (addr
, p
, len
);
843 process_X (char *buffer
) FASTCALL
844 {/* XAA..AA,LLLL: Write LLLL binary bytes at address AA.AA return OK */
845 char *p
= &buffer
[1];
846 byte
*addr
= (void*)hex2int(&p
);
850 unsigned len
= (unsigned)hex2int(&p
);
855 if (len
+ (p
- buffer
) > DBG_PACKET_SIZE
)
858 if (!DBG_MEMCPY(addr
, p
, len
))
861 memcpy (addr
, p
, len
);
868 #else /* DBG_MIN_SIZE */
870 process_X (char *buffer
) FASTCALL
875 #endif /* DBG_MIN_SIZE */
878 process_c (char *buffer
) FASTCALL
879 {/* 'cAAAA' - Continue at address AAAA(optional) */
880 const char *p
= &buffer
[1];
883 void *addr
= (void*)hex2int(&p
);
884 set_reg_value (&state
[R_PC
], addr
);
891 process_D (char *buffer
) FASTCALL
892 {/* 'D' - detach the program: continue execution */
898 process_k (char *buffer
) FASTCALL
899 {/* 'k' - Kill the program */
900 set_reg_value (&state
[R_PC
], 0);
907 process_v (char *buffer
) FASTCALL
910 if (memcmp (&buffer
[1], "Cont", 4) == 0)
912 if (buffer
[5] == '?')
914 /* result response will be "vCont;c;C"; C action must be
915 supported too, because GDB reguires at lease both of them */
916 memcpy (&buffer
[5], ";c;C", 5);
920 if (buffer
[5] == ';' && (buffer
[6] == 'c' || buffer
[6] == 'C'))
921 return -2; /* resume execution */
924 #endif /* DBG_MIN_SIZE */
929 process_zZ (char *buffer
) FASTCALL
930 { /* insert/remove breakpoint */
931 #if defined(DBG_SWBREAK_PROC) || defined(DBG_HWBREAK) || \
932 defined(DBG_WWATCH) || defined(DBG_RWATCH) || defined(DBG_AWATCH)
933 const byte set
= (*buffer
== 'Z');
934 const char *p
= &buffer
[3];
935 void *addr
= (void*)hex2int(&p
);
939 int kind
= hex2int(&p
);
943 #ifdef DBG_SWBREAK_PROC
944 case '0': /* sw break */
945 return DBG_SWBREAK_PROC(set
, addr
);
948 case '1': /* hw break */
949 return DBG_HWBREAK(set
, addr
);
952 case '2': /* write watch */
953 return DBG_WWATCH(set
, addr
, kind
);
956 case '3': /* read watch */
957 return DBG_RWATCH(set
, addr
, kind
);
960 case '4': /* access watch */
961 return DBG_AWATCH(set
, addr
, kind
);
963 default:; /* not supported */
971 do_process (char *buffer
) FASTCALL
975 case '?': return process_question (buffer
);
976 case 'G': return process_G (buffer
);
977 case 'k': return process_k (buffer
);
978 case 'M': return process_M (buffer
);
979 case 'X': return process_X (buffer
);
980 case 'Z': return process_zZ (buffer
);
981 case 'c': return process_c (buffer
);
982 case 'D': return process_D (buffer
);
983 case 'g': return process_g (buffer
);
984 case 'm': return process_m (buffer
);
985 case 'q': return process_q (buffer
);
986 case 'v': return process_v (buffer
);
987 case 'z': return process_zZ (buffer
);
988 default: return -1; /* empty response */
993 process (char *buffer
) FASTCALL
995 signed char err
= do_process (buffer
);
1006 p
= byte2hex (p
, err
);
1013 else if (*p
== '\0')
1019 byte2hex (char *p
, byte v
)
1021 *p
++ = high_hex (v
);
1027 hex2val (unsigned char hex
) FASTCALL
1031 hex
&= 0xdf; /* make uppercase */
1033 return (hex
>= 10 && hex
< 16) ? hex
: -1;
1037 hex2byte (const char *p
) FASTCALL
1039 signed char h
= hex2val (p
[0]);
1040 signed char l
= hex2val (p
[1]);
1043 return (byte
)((byte
)h
<< 4) | (byte
)l
;
1047 hex2int (const char **buf
) FASTCALL
1052 signed char a
= hex2val(**buf
);
1062 int2hex (char *buf
, int v
)
1064 buf
= byte2hex(buf
, (word
)v
>> 8);
1065 return byte2hex(buf
, (byte
)v
);
1069 high_hex (byte v
) FASTCALL
1071 return low_hex(v
>> 4);
1075 low_hex (byte v
) FASTCALL
1093 return v
+ 'a' - '0' - 10;
1096 /* convert the memory, pointed to by mem into hex, placing result in buf */
1097 /* return a pointer to the last char put in buf (null) */
1099 mem2hex (char *buf
, const byte
*mem
, unsigned bytes
)
1106 d
= byte2hex (d
, *mem
++);
1114 /* convert the hex array pointed to by buf into binary, to be placed in mem
1115 return a pointer to the character after the last byte written */
1118 hex2mem (byte
*mem
, const char *buf
, unsigned bytes
)
1124 *mem
++ = hex2byte (buf
);
1132 #ifdef DBG_MEMORY_MAP
1134 read_memory_map (char *buffer
, unsigned offset
, unsigned length
)
1136 const char *map
= DBG_MEMORY_MAP
;
1137 const unsigned map_sz
= strlen(map
);
1138 if (offset
>= map_sz
)
1144 if (offset
+ length
> map_sz
)
1145 length
= map_sz
- offset
;
1147 memcpy (&buffer
[1], &map
[offset
], length
);
1148 buffer
[1+length
] = '\0';
1152 /* write string like " nn:0123" and return pointer after it */
1153 #ifndef DBG_MIN_SIZE
1155 format_reg_value (char *p
, unsigned reg_num
, const byte
*value
)
1159 d
= byte2hex(d
, reg_num
);
1165 d
= byte2hex(d
, *--value
);
1171 #endif /* DBG_MIN_SIZE */
1174 /* saves all state.except PC and SP */
1176 save_cpu_state() __naked
1181 ld (#_state + R_HL + 0), a
1183 ld (#_state + R_HL + 1), a
1184 ld hl
, #_state + R_HL - 1
1201 /* restore CPU state and continue execution */
1203 rest_cpu_state() __naked
1207 ld a
, (#_state + R_SP + 0)
1209 ld a
, (#_state + R_SP + 1)
1212 ;push PC value as
return address
1213 ld a
, (#_state + R_PC + 0)
1215 ld a
, (#_state + R_PC + 1)
1219 ld hl
, #_state + R_AF
1242 /* saves all state.except PC and SP */
1244 save_cpu_state() __naked
1247 ld (#_state + R_HL), hl
1248 ld (#_state + R_DE), de
1249 ld (#_state + R_BC), bc
1252 ld (#_state + R_AF), hl
1253 ld a
, r
;R is increased by
7 or by
8 if called via RST
1259 #ifdef __SDCC_ez80_adl
1262 ld hl
, #_state + R_IR
1269 ld (#_state + R_AF+2), a
1274 ld (#_state + R_IR), hl
1275 #endif /* __SDCC_ez80_adl */
1276 ld (#_state + R_IX), ix
1277 ld (#_state + R_IY), iy
1280 ld (#_state + R_HL_), hl
1281 ld (#_state + R_DE_), de
1282 ld (#_state + R_BC_), bc
1285 ld (#_state + R_AF_), hl
1290 /* restore CPU state and continue execution */
1292 rest_cpu_state() __naked
1295 #ifdef DBG_USE_TRAMPOLINE
1296 ld sp
, _stack
+ DBG_STACK_SIZE
1297 ld hl
, (#_state + R_PC)
1298 push hl
/* resume address */
1299 #ifdef __SDCC_ez80_adl
1300 ld hl
, 0xc30000 ; use
0xc34000 for jp
.s
1304 push hl
/* JP opcode */
1305 #endif /* DBG_USE_TRAMPOLINE */
1306 ld hl
, (#_state + R_AF_)
1309 ld bc
, (#_state + R_BC_)
1310 ld de
, (#_state + R_DE_)
1311 ld hl
, (#_state + R_HL_)
1314 ld iy
, (#_state + R_IY)
1315 ld ix
, (#_state + R_IX)
1316 #ifdef __SDCC_ez80_adl
1317 ld a
, (#_state + R_AF + 2)
1319 ld hl
, (#_state + R_IR + 1) ;I register
1321 ld a
, (#_state + R_IR + 0) ; R register
1324 ld hl
, (#_state + R_IR)
1328 #endif /* __SDCC_ez80_adl */
1329 sub a
, #10 ;number of M1 cycles after ld r,a
1334 ld de
, (#_state + R_DE)
1335 ld bc
, (#_state + R_BC)
1336 ld hl
, (#_state + R_AF)
1339 ld sp
, (#_state + R_SP)
1340 #ifndef DBG_USE_TRAMPOLINE
1341 ld hl
, (#_state + R_PC)
1343 ld hl
, (#_state + R_HL)
1346 ld hl
, (#_state + R_HL)
1347 #ifdef __SDCC_ez80_adl
1348 jp
#_stack + DBG_STACK_SIZE - 4
1350 jp
#_stack + DBG_STACK_SIZE - 3
1352 #endif /* DBG_USE_TRAMPOLINE */
1355 #endif /* __SDCC_gbz80 */