Difference between revisions of "Z80 Emulator Debugging Standard"
(blah) |
m (→Tracing Instructions) |
||
(5 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
Previously, emulators required users to manually enter breakpoints, and often had no way to load breakpoints from an external file, preventing them being loaded from an IDE or assembler. This standard specifies ways for emulators to load breakpoints, provide tracing and logging services, and load label names. | Previously, emulators required users to manually enter breakpoints, and often had no way to load breakpoints from an external file, preventing them being loaded from an IDE or assembler. This standard specifies ways for emulators to load breakpoints, provide tracing and logging services, and load label names. | ||
+ | |||
+ | There are two parts to this: An extended instruction set that allows breakpoints and tracing to be included in the instruction stream, and a file format that allows names for breakpoints and tracing events to be specified, and also allows breakpoints to be loaded from an external file. An emulator may implement either or both standards. An emulator supporting breakpoint instructions need not support loading them from a file. | ||
= Z80 Emulator Debugging Instruction Set = | = Z80 Emulator Debugging Instruction Set = | ||
Line 26: | Line 28: | ||
Tracing provides a means for users to track the execution of software logic without single-stepping. Each tracing event adds an entry to a log, which MUST include the group number and any arguments (e.g. A = 3C), and MAY include the PC address of the event and the time the event happened. | Tracing provides a means for users to track the execution of software logic without single-stepping. Each tracing event adds an entry to a log, which MUST include the group number and any arguments (e.g. A = 3C), and MAY include the PC address of the event and the time the event happened. | ||
+ | |||
+ | An event is simply a log that the code passed through that point. Event IDs are encoded with a single 8-bit argument. All events IDs are shared between groups. The 8-bit event ID allows the trace log to show, for example, a message saying that a loop was iterated again, instead of just logging register values without any indication about their context. A sufficiently smart assembler MAY allow the user to type a string instead of a number for the event ID, and automatically cross-reference the string into names file. | ||
== Instruction Reference (ZEDIS) == | == Instruction Reference (ZEDIS) == | ||
=== Specifying Group Names === | === Specifying Group Names === | ||
+ | |||
+ | It is recommended that assemblers support the following directives to simplify use. | ||
Per the file format specified below, the assembler may emit a file giving names to various groups. The exact syntax may be modified to suit each assembler. For example, changing <code>#</code> to <code>.</code>, or not requiring parentheses. | Per the file format specified below, the assembler may emit a file giving names to various groups. The exact syntax may be modified to suit each assembler. For example, changing <code>#</code> to <code>.</code>, or not requiring parentheses. | ||
Line 40: | Line 46: | ||
|Changes the debugging mode. Valid modes are <code>off</code>, <code>instr</code>, and <code>file</code>. | |Changes the debugging mode. Valid modes are <code>off</code>, <code>instr</code>, and <code>file</code>. | ||
|- | |- | ||
− | |<code># | + | |<code>#groupname(<i>x</i>, <i>name</i>)</code> |
− | |Defines that | + | |Defines that group <i>x</i> should be given <i>name</i>. |
− | + | ||
− | + | ||
− | + | ||
|- | |- | ||
|} | |} | ||
Line 80: | Line 83: | ||
|- | |- | ||
|<code>ED F<i>x</i></code> | |<code>ED F<i>x</i></code> | ||
− | |<code> | + | |<code>BREAK <i>x</i></code> |
|Breakpoint in group <i>x</i> | |Breakpoint in group <i>x</i> | ||
|} | |} | ||
Line 95: | Line 98: | ||
|Trace event in group <i>x</i> with no arguments | |Trace event in group <i>x</i> with no arguments | ||
|- | |- | ||
− | |<code>ED 1<i>x</i> ED <i> | + | |<code>ED 1<i>x</i> ED <i>imm8</i></code> |
|<code>TRACE <i>x</i>, <i>y</i></code> | |<code>TRACE <i>x</i>, <i>y</i></code> | ||
− | |Trace event in group <i>x</i> with event ID <i>y</i>, | + | |Trace event in group <i>x</i> with event ID <i>y</i>, see below for imm8 encoding |
|- | |- | ||
|<code>ED 2<i>x</i> ED <i>yy</i></code> | |<code>ED 2<i>x</i> ED <i>yy</i></code> | ||
|<code>TRACE <i>x</i>, <i>reg</i></code> | |<code>TRACE <i>x</i>, <i>reg</i></code> | ||
− | |Trace event in group <i>x</i>, logging the value of <i>reg</i>, see table below | + | |Trace event in group <i>x</i>, logging the value of <i>reg</i>, see table below |
|- | |- | ||
|<code>DD ED 2<i>x</i> ED <i>yy</i></code> | |<code>DD ED 2<i>x</i> ED <i>yy</i></code> | ||
|<code>TRACE <i>x</i>, <i>ixreg</i></code> | |<code>TRACE <i>x</i>, <i>ixreg</i></code> | ||
− | |Trace event in group <i>x</i>, logging the value of <i>ixreg</i>, where <i>ixreg</i> is IX, IXL, IXH, or (IX) | + | |Trace event in group <i>x</i>, logging the value of <i>ixreg</i>, where <i>ixreg</i> is IX, IXL, IXH, or (IX) |
|- | |- | ||
− | |<code>FD ED 2<i>x</i> ED <i> | + | |<code>FD ED 2<i>x</i> ED <i>yy</i></code> |
− | |<code>TRACE <i>x</i>, | + | |<code>TRACE <i>x</i>, <i>iyreg</i></code> |
− | |Trace event in group <i>x</i>, logging the value of <i>iyreg</i>, where <i>iyreg</i> is IY, IYL, IYH, or (IY) | + | |Trace event in group <i>x</i>, logging the value of <i>iyreg</i>, where <i>iyreg</i> is IY, IYL, IYH, or (IY) |
− | |<code>ED 3<i>x</i> ED <i>yy</i></code> | + | |- |
− | |<code>TRACE <i>x</i>, | + | |<code>ED 3<i>x</i> ED <i>yy</i> ED <i>length</i></code> |
− | + | |<code>TRACE <i>x</i>, <i>reg16</i>, <i>length</i></code> | |
− | + | |Trace event in group <i>x</i>, logging the value of all data between <i>reg16</i> and <i>length</i>, where length is a SIGNED 8-bit number, encoded as below. If <i>length</i> is negative, it logs bytes before the pointer, not after. A value of 0 logs 1 byte, a value of 7F logs 80 bytes. | |
− | |<code>ED 8<i>x</i> ED <i> | + | |- |
− | |<code> | + | |<code>ED 8<i>x</i> ED <i>imm8</i></code> |
− | | | + | |<code>TRACE <i>x</i>, (<i>imm8</i>)</code> |
− | + | |Trace event in group <i>x</i>, recording the value in port <i>imm8</i> without changing any state, see below for imm8 encoding | |
|} | |} | ||
+ | <code>DD</code> and <code>FD</code> can similarly be used with the <code>ED 3<i>x</i></code> set. | ||
− | ==== | + | ==== Immediate Values ==== |
Imm8 values are encoded prefixed with ED, followed by: | Imm8 values are encoded prefixed with ED, followed by: | ||
− | * If | + | * If imm8 <= 3F or imm8 >= C0, then imm8 is encoded as it is. |
− | * If | + | * If imm8 >= 40 && imm8 <= BF, then imm8 is encoded as <code>ED A5 ED <i>imm8</i>+80h</code>. So 40 becomes C0, 50 becomes D0, 7F becomes FF, 80 becomes 00, and BF becomes 3F. |
− | * If | + | <!--Imm16 values (if they were to exist) would be encoded similar to imm8 values. An imm16 in the form HH LL would be encoded as: |
− | + | * If both HH and LL are not between 40 and BF: <code>ED <i>LL</i> ED <i>HH</i></code> | |
− | + | ** <code>ED A4 ED <i>LL</i> ED <i>HH</i></code> is also a valid encoding | |
+ | * If LL is between 40 and BF: <code>ED A5 ED <i>LL</i>+80 ED <i>HH</i></code> | ||
+ | * If HH is between 40 and BF: <code>ED A6 ED <i>LL</i> ED <i>HH</i>+80</code> | ||
+ | * If both HH and LL are between 40 and BF: <code>ED A7 ED <i>LL</i>+80 ED <i>HH</i>+80</code> | ||
+ | In other words, the low two bits of the 101001xx byte specify which bytes are out of range.--> | ||
==== Register Codes ==== | ==== Register Codes ==== | ||
Line 221: | Line 229: | ||
= File Reference = | = File Reference = | ||
+ | |||
+ | Files are formatted like INI files. | ||
+ | |||
+ | === <code>[METADATA]</code> === | ||
+ | |||
+ | * fileversion=<i>number</i> | ||
+ | * platform=<i>platform</i>, values may be ti8x or ti84pcse | ||
+ | * programname="string", may be used for an app or a program | ||
+ | |||
+ | === <code>[GROUPS]</code> === | ||
+ | |||
+ | * name0="string" | ||
+ | * name1="string" | ||
+ | * ... | ||
+ | * name15="string" | ||
+ | |||
+ | === <code>[EVENTS]</code> === | ||
+ | |||
+ | * event0="string" | ||
+ | * ... | ||
+ | |||
+ | === <code>[BREAKPOINTS]</code> === | ||
+ | |||
+ | * breakpoint0=<i>groupID</i>,<i>address</i> | ||
+ | * ... |
Latest revision as of 16:17, 18 November 2014
This proposal specifies a standard for emulators to integrate breakpoint and tracing debugging features. There are two parts to the standard, an extension to the Z80 instruction set, and a file format that provides similar functionality.
Overview
Previously, emulators required users to manually enter breakpoints, and often had no way to load breakpoints from an external file, preventing them being loaded from an IDE or assembler. This standard specifies ways for emulators to load breakpoints, provide tracing and logging services, and load label names.
There are two parts to this: An extended instruction set that allows breakpoints and tracing to be included in the instruction stream, and a file format that allows names for breakpoints and tracing events to be specified, and also allows breakpoints to be loaded from an external file. An emulator may implement either or both standards. An emulator supporting breakpoint instructions need not support loading them from a file.
Z80 Emulator Debugging Instruction Set
Overview
The Z80 Emulator Debugging Instruction Set (ZEDIS) specifies debugging events in the instruction stream. This allows emulators to avoid checking every instruction fetch against a debug event list. Instead, they simply issue the event when they see the instruction.
All instructions occupy unused instruction slots in the ED xx
range. The unused instructions in this range function as 8-cycle NOPs, so software containing these instructions can be run on hardware without ill effect. Emulators MAY choose to count the ZEDIS instructions as 8-cycle NOPs for timing purposes. The following opcodes are USED in the Z80 instruction, and are NOT valid as debugging instructions: ED 40
- ED 76
, ED 78
- ED 7E
, ED A0
- ED A3
, ED A8
- ED AB
, ED B0
- ED B3
, ED B8
- ED BB
Some instructions take more than one ED xx
instruction. The additional arguments are also always of the form ED xx
.
Groups
Software often has many different subsystems, so ZEDIS divides all debugging events into groups. There are 16 defined groups, 0-15. The purpose of each group is up to the user. For example, the user might use group 0 for events in a tile mapping system, and group 1 for events in sprites. Thus, the user can separately debug the two systems. The emulator SHOULD provide a UI means of disabling and enabling groups. Tracing groups and breakpoint groups are the same logical group.
Breakpoints
A breakpoint causes the emulator to pause emulation, and open a debugger interface. The emulator pauses and opens the interface after PC has passed the breakpoint instruction.
Tracing
Tracing provides a means for users to track the execution of software logic without single-stepping. Each tracing event adds an entry to a log, which MUST include the group number and any arguments (e.g. A = 3C), and MAY include the PC address of the event and the time the event happened.
An event is simply a log that the code passed through that point. Event IDs are encoded with a single 8-bit argument. All events IDs are shared between groups. The 8-bit event ID allows the trace log to show, for example, a message saying that a loop was iterated again, instead of just logging register values without any indication about their context. A sufficiently smart assembler MAY allow the user to type a string instead of a number for the event ID, and automatically cross-reference the string into names file.
Instruction Reference (ZEDIS)
Specifying Group Names
It is recommended that assemblers support the following directives to simplify use.
Per the file format specified below, the assembler may emit a file giving names to various groups. The exact syntax may be modified to suit each assembler. For example, changing #
to .
, or not requiring parentheses.
Macro | Description |
#zedsmode(mode)
|
Changes the debugging mode. Valid modes are off , instr , and file .
|
#groupname(x, name)
|
Defines that group x should be given name. |
General Instructions
Instruction | Mnemonic | Description |
ED 77
|
ZEDISOFF
|
Disables all ZEDIS instructions (except ED 7F) |
ED 7F
|
ZEDISON
|
Enables all ZEDIS instructions |
ED Cx
|
GRPOFF x
|
Disables all events in group x |
ED Dx
|
GRPON x
|
Enables all events in group x |
Breakpoint Instructions
Instruction | Mnemonic | Description |
ED Fx
|
BREAK x
|
Breakpoint in group x |
Tracing Instructions
Instruction | Mnemonic | Description |
ED 0x
|
TRACE x
|
Trace event in group x with no arguments |
ED 1x ED imm8
|
TRACE x, y
|
Trace event in group x with event ID y, see below for imm8 encoding |
ED 2x ED yy
|
TRACE x, reg
|
Trace event in group x, logging the value of reg, see table below |
DD ED 2x ED yy
|
TRACE x, ixreg
|
Trace event in group x, logging the value of ixreg, where ixreg is IX, IXL, IXH, or (IX) |
FD ED 2x ED yy
|
TRACE x, iyreg
|
Trace event in group x, logging the value of iyreg, where iyreg is IY, IYL, IYH, or (IY) |
ED 3x ED yy ED length
|
TRACE x, reg16, length
|
Trace event in group x, logging the value of all data between reg16 and length, where length is a SIGNED 8-bit number, encoded as below. If length is negative, it logs bytes before the pointer, not after. A value of 0 logs 1 byte, a value of 7F logs 80 bytes. |
ED 8x ED imm8
|
TRACE x, (imm8)
|
Trace event in group x, recording the value in port imm8 without changing any state, see below for imm8 encoding |
DD
and FD
can similarly be used with the ED 3x
set.
Immediate Values
Imm8 values are encoded prefixed with ED, followed by:
- If imm8 <= 3F or imm8 >= C0, then imm8 is encoded as it is.
- If imm8 >= 40 && imm8 <= BF, then imm8 is encoded as
ED A5 ED imm8+80h
. So 40 becomes C0, 50 becomes D0, 7F becomes FF, 80 becomes 00, and BF becomes 3F.
Register Codes
If IX or IY is selected, then only H, L, HL, or (HL) are valid and H becomes IXH or IYH &c. You know the drill with index registers.
Value | Register | Value | Register |
00
|
B | 10
|
BC |
01
|
C | 11
|
DE |
02
|
D | 12
|
HL |
03
|
E | 13
|
AF |
04
|
H | 14
|
BC' |
05
|
L | 15
|
DE' |
06
|
(HL) | 16
|
HL' |
07
|
A | 17
|
AF' |
08
|
B' | 18
|
(BC) |
09
|
C' | 19
|
(DE) |
0A
|
D' | 1A
|
(BC') |
0B
|
E' | 1B
|
(DE') |
0C
|
H' | 1C
|
SP |
0D
|
L' | 1D
|
(SP) |
0E
|
(HL') | 1E
|
IR |
0F
|
A' | 1F
|
IFF |
File Reference
Files are formatted like INI files.
[METADATA]
- fileversion=number
- platform=platform, values may be ti8x or ti84pcse
- programname="string", may be used for an app or a program
[GROUPS]
- name0="string"
- name1="string"
- ...
- name15="string"
[EVENTS]
- event0="string"
- ...
[BREAKPOINTS]
- breakpoint0=groupID,address
- ...