[PATCH v4] [gdb] Add basic Z80 CPU support

Sergey Belyashov sergey.belyashov@gmail.com
Tue Oct 6 10:17:02 GMT 2020


Hi,
There is instruction from Jakub Ladman on how to debug programs on the
Amstrad(Sinclair) ZX Spectrum +2B computer using GDB. Sources are
attached as an archive to the email.

howtouse.txt
 Created on: 4. 10. 2020
     Author: ladmanj

     This is demonstration how to use Small Devices C Compiler, with
GNU AS assembler and GDB to debug Z80 code

     Only assembler instructions stepping is possible at the time of
writing this text, because SDCC can't provide
     the symbols (and maybe other information) in the way gdb needs.

     The code being debugged is compiled and linked together with
GDB-STUB, which is relatively small piece of code
     running on the target machine and provides interface between it
and the GDB itself.

     This presentation is performed on the Amstrad(Sinclair) ZX
Spectrum +2B computer.

     The tools used are:
     z80-unknown-elf-as, z80-unknown-elf-ld z80-unknown-elf-objcopy
     from the Sergey Belyashov's source tree from
https://github.com/b-s-a/binutils-gdb

     bin2tap from https://sourceforge.net/projects/zxspectrumutils/

     taptoser From Pavel Vymetálek's https://vym.cz/download/taptoser.tar.gz
     to be used with Paul Farrow's modified 48k ROM-RS232
http://www.fruitcake.plus.com which redirects tape in&out to one
     of the three possible (software emulated serial) ports.

     The taptoser and the modified ROM isn't needed, the GDB-STUB and
the program to be debugged can also be loaded from
     the physical tape if you are not equipped with some user
modifiable ROM cartridge, but because the serial connection
     has to be used anyway for the stub/gdb communication it's a shame
not to use it also for the boot-up.

     The z80-stub.c file which comes from the gdb source tree is
connected with the serial channel via
     extern int getDebugChar (void) and extern void putDebugChar (int
ch) functions. These are in the thin wrapper file
     io.c, and from this place assembly routines for the RS-232 serial
line are called.

     The serial routines used here (rs232.s) are from this site:
     https://cygnus.speccy.cz/download/zx128k_rs232/rs232_paul_farrow_57600_data_sequence_with_cts_flow_control.html

     The binary file is built, converted to ZX Spectrum TAP file and
loaded to the target machine:
     $ make upload
     Reset ZX spectrum with Paul Farrow's RS232 ROM
     Press any key to continue
     Now run LOAD ""
     taptoser gdbstub.tap -d /dev/ttyUSB0
     Serial device: /dev/ttyUSB0, communication speed is: 57600 Bd

     Filename:   gdbstub
     Flag:    0 Type: 0 => program
     Program length:     93 bytes Runs from line    10       Length
without variables:    93 bytes
     Proceed bytes:     95/    95
[==================================================================================================]
100 %

     Filename:   gdbstub
     Flag:    0 Type: 3 => bytes  Start address: 32768       Length:
3056 bytes    3rd param: 32768
     Proceed bytes:   3058/  3058
[==================================================================================================]
100 %


     The whole code is started by the code in mycrt0.s. The bin2tap
utility has appended a machine code loader
     in basic to the tape file.
     The basic loader places the code at the address 0x8000 and there
the machine code is run from,
     the ROM cartridge (if present) is then switched off, the whole
code is copied from 0x8000
     (bank 2 where we are running now) to 0xc000 (bank 0)
     the ZX Spectrum +2 memory is switched to all-ram mode in such
way, the bank 0 is then at address 0x0000.

     Then the program jumps to address 0x0000 and is initialized as
any other sdcc compiled program.
     After initialization but before thi final jump to _main (to C
main function), the debug_exception function is called
     and there the gdb-stub is finally waiting for the connection of the gdb.

     When the z80-unknown-elf-gdb is run, the .gdbinit file is
examined and following commands are executed from it:
     set remoteflow on
     target remote /dev/ttyUSB0

     Note: The software emulated serial port in the remote can't work
without hardware handshake enabled on the PC side.

     The gdb prompt then looks like this:

     $ z80-unknown-elf-gdb
     GNU gdb (GDB) 10.0.50.20200317-git
     Copyright (C) 2020 Free Software Foundation, Inc.
     License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
     This is free software: you are free to change and redistribute it.
     There is NO WARRANTY, to the extent permitted by law.
     Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu
--target=z80-unknown-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
     <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
0x0000010d in ?? ()
(gdb)

     Then the memory can be examined this way:

     (gdb) x/20i 0x100
        0x100:       ld sp,0xff00
        0x103:       call 0x0146
        0x106:       ld hl,0x0005
        0x109:       push hl
        0x10a:       call 0x0210
     => 0x10d:       call 0x0af2
        0x110:       jp 0x015a
        0x113:       nop
        0x114:       nop
        0x115:       nop
        0x116:       nop
        0x117:       nop
        0x118:       nop
        0x119:       nop
        0x11a:       nop
        0x11b:       nop
        0x11c:       nop
        0x11d:       nop
        0x11e:       nop
        0x11f:       nop

     Displaying of the current instruction can be switched on:
     (gdb) display/i $pc
     1: x/i $pc
     => 0x10d:       call 0x0af2

     And then the instruction by instruction can be performed:

     (gdb) si
     warning: Unable to determine inferior's software breakpoint type:
couldn't find `_break_handler' function in the executable. Will be
used default software breakpoint instruction RST 0x08.
     0x00000af2 in ?? ()
     1: x/i $pc
     => 0xaf2:       call 0x0af8
     (gdb)
     0x00000af8 in ?? ()
     1: x/i $pc
     => 0xaf8:       ld b,0x00
     (gdb)
     0x00000afa in ?? ()
     1: x/i $pc
     => 0xafa:       ld a,b
     (gdb)
     0x00000afb in ?? ()
     1: x/i $pc
     => 0xafb:       out (0xfe),a
     (gdb)
     0x00000afd in ?? ()
     1: x/i $pc
     => 0xafd:       inc b
     (gdb)
     0x00000afe in ?? ()
     1: x/i $pc
     => 0xafe:       xor a
     (gdb)
     0x00000aff in ?? ()
     1: x/i $pc
     => 0xaff:       in a,(0xfe)
     (gdb)
     0x00000b01 in ?? ()
     1: x/i $pc
     => 0xb01:       cpl
     (gdb)
     0x00000b02 in ?? ()
     1: x/i $pc
     => 0xb02:       and 0x1f
     (gdb)
     0x00000b04 in ?? ()
     1: x/i $pc
     => 0xb04:       jp z,0x0afa
     (gdb)
     0x00000afa in ?? ()
     1: x/i $pc
     => 0xafa:       ld a,b
     (gdb)


     You can load your binary to any free location of the RAM and do
the debugging.

     If you lose control of the program (and it didn't overwrite
anything important), you can interrupt it
     by the NMI button, if your machine or ROM cartridge is equipped with one.

     (gdb) c
     Continuing.

     Program received signal SIGTRAP, Trace/breakpoint trap.
     0x00000aff in ?? ()
     1: x/i $pc
     => 0xaff:       in a,(0xfe)


     That's all folks!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: z80_debug.tar.gz
Type: application/gzip
Size: 14789 bytes
Desc: not available
URL: <https://sourceware.org/pipermail/gdb-patches/attachments/20201006/f669580c/attachment-0001.gz>


More information about the Gdb-patches mailing list