Skip to content

Commit 8d58ddf

Browse files
committed
Source code comments.
1 parent 3023f63 commit 8d58ddf

File tree

2 files changed

+55
-26
lines changed

2 files changed

+55
-26
lines changed

sources/Z80.c

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,18 +2626,17 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles)
26262626
FLAGS = F & ~(zuint8)PF;
26272627
# endif
26282628

2629-
/*---------------------------------------------------------------------.
2630-
| The INT acknowledge cycle (INTA) indicates that the interrupting I/O |
2631-
| device can write to the data bus. 2 wait T-states are automatically |
2632-
| added to this M-cycle, allowing sufficient time to identify which |
2633-
| device must insert the interrupt response data (IRD). The first and |
2634-
| possibly sole byte of the IRD is read from the data bus during this |
2635-
| special M1 cycle. |
2636-
| |
2637-
| The value FFh is assumed when the `Z80::inta` callback is not used. |
2638-
| This is the most convenient default IRD, since an `rst 38h` will be |
2639-
| executed if the interrupt mode is 0. |
2640-
'=====================================================================*/
2629+
/*-----------------------------------------------------------------------.
2630+
| The INT acknowledge M-cycle (INTA) indicates that the interrupting I/O |
2631+
| device can write to the data bus. The CPU adds 2 wait T-states to this |
2632+
| M-cycle, allowing sufficient time to identify which device must insert |
2633+
| the interrupt response data (IRD). The first and possibly sole byte of |
2634+
| the IRD is read from the data bus during this special M1 cycle. |
2635+
| |
2636+
| The value FFh is assumed when the `Z80::inta` callback is not used. |
2637+
| This is the most convenient default IRD, since an `rst 38h` will be |
2638+
| executed if the interrupt mode is 0. |
2639+
'=======================================================================*/
26412640
R++;
26422641
ird = (self->inta != Z_NULL) ? self->inta(CONTEXT, PC) : 0xFF;
26432642

@@ -2651,15 +2650,15 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles)
26512650
| Interrupt Mode 0: Execute Instruction | T-states: 2*n + instruction |
26522651
|--------------------------------------------------------------------------|
26532652
| An instruction supplied via the data bus is executed. Its first byte is |
2654-
| read during the INT acknowledge cycle (INTA). If it is an opcode prefix, |
2655-
| additional M-cycles of this kind are produced until the final opcode of |
2656-
| the instruction is fetched [1]. Each INTA M-cycle takes as many T-states |
2657-
| as its normal M1 counterpart (the opcode fetch M-cycle) plus the 2 wait |
2658-
| T-states mentioned above [1]. Subsequent bytes of the instruction are |
2659-
| fetched by using normal memory read M-cycles [1, 2], during which the |
2660-
| interrupting I/O device must still supply the data [2]. The PC register, |
2661-
| however, remains at its pre-interrupt state, not being incremented as a |
2662-
| result of the instruction fetch [1, 2]. |
2653+
| read during the INTA M-cycle and, if it is an opcode prefix, additional |
2654+
| M-cycles of this kind are produced until the final opcode of the |
2655+
| instruction is fetched [1]. Each INTA M-cycle takes as many T-states as |
2656+
| its normal M1 counterpart (the opcode fetch M-cycle) plus the 2 wait |
2657+
| T-states mentioned in the previous comment [1]. Subsequent bytes of the |
2658+
| instruction are fetched by using normal memory read M-cycles [1, 2], |
2659+
| during which the interrupting I/O device must still supply the data [2]. |
2660+
| The PC register, however, remains at its pre-interrupt state, not being |
2661+
| incremented as a result of the instruction fetch [1, 2]. |
26632662
| |
26642663
| References: |
26652664
| 1. Checked with "Visual Z80 Remix". |
@@ -2901,9 +2900,9 @@ Z80_API zusize z80_run(Z80 *self, zusize cycles)
29012900
| of the interrupt response vector "must be a zero", since the address |
29022901
| formed "is used to get two adjacent bytes to form a complete 16-bit |
29032902
| service routine starting address and the addresses must always start |
2904-
| in even locations" [1]. However, Sean Young's experiments confirmed |
2905-
| that there is no such limitation [2]; any vector works regardless of |
2906-
| whether it is even or odd. |
2903+
| in even locations" [1]. However, Sean Young's confirmed that there |
2904+
| is no such limitation [2]; the CPU fetches the ISR pointer from the |
2905+
| specified location regardless of the value of bit 0 of the IRD. |
29072906
| |
29082907
| References: |
29092908
| 1. Zilog (2005-03). "Z80 CPU User Manual" rev. 5, pp. 25-26. |

sources/step-test-Z80.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,26 @@
3737
/* MARK: - Types */
3838

3939
typedef struct {
40+
/* Title of the member as shown in the mismatch reports. */
4041
char const *caption;
42+
43+
/* Key of the member as shown in the JSON files. */
4144
char const *key;
45+
46+
/* Offset of the member within the Z80 structure. */
4247
zusize offset;
48+
49+
/* Maximum value the member can hold. */
4350
zuint16 maximum_value;
4451
} Member;
4552

53+
/*-----------------------------------------------------------------------------.
54+
| `Cycle` and `Port` store information about a clock cycle and an I/O port |
55+
| operation, respectively. They are packed to avoid any padding bytes, so that |
56+
| the actual results can be compared directly with the expected ones read from |
57+
| the JSON test files. |
58+
'=============================================================================*/
59+
4660
typedef Z_PACKED_STRUCTURE_BEGIN {
4761
zuint16 address;
4862
zsint16 value;
@@ -109,6 +123,12 @@ static char const *field_separator = "";
109123
static zbool cpu_break;
110124

111125

126+
/*----------------------------------------------------------------------------.
127+
| `add_cycle` and `add_port` add entries to the lists of recorded cycles and |
128+
| I/O port operations, respectively. If memory reallocation fails, they break |
129+
| the CPU emulation and ignore further entries. |
130+
'============================================================================*/
131+
112132
static void add_cycle(zuint16 address, zsint16 value, char const *pins)
113133
{
114134
Cycle *c;
@@ -121,6 +141,7 @@ static void add_cycle(zuint16 address, zsint16 value, char const *pins)
121141
if ((c = realloc(cycles, cycles_size * sizeof(Cycle))) == Z_NULL)
122142
{
123143
z80_break(&cpu);
144+
cpu_break = Z_TRUE;
124145
return;
125146
}
126147

@@ -164,7 +185,7 @@ static void add_port(zuint16 port, zuint8 value, char direction)
164185
}
165186

166187

167-
/* MARK: - Callbacks */
188+
/* MARK: - CPU Callbacks */
168189

169190
static zuint8 cpu_fetch_opcode(void *context, zuint16 address)
170191
{
@@ -278,13 +299,16 @@ static zbool validate_test_state(cJSON *state)
278299
cJSON *item, *subitem;
279300
Member const *member;
280301

302+
/* The state object must contain all CPU members plus the `"ram"` array. */
281303
if ( !cJSON_IsObject(state) ||
282304
cJSON_GetArraySize(state) != (int)Z_ARRAY_SIZE(members) + /* "ram" */ 1 ||
283305
(item = cJSON_GetObjectItem(state, "ram")) == Z_NULL ||
284306
!cJSON_IsArray(item)
285307
)
286308
return Z_FALSE;
287309

310+
/* The `"ram"` array must contain arrays of two numbers: 16-bit address and
311+
8-bit value. */
288312
cJSON_ArrayForEach(subitem, item) if (
289313
!cJSON_IsArray(subitem) ||
290314
cJSON_GetArraySize(subitem) != 2 ||
@@ -293,14 +317,20 @@ static zbool validate_test_state(cJSON *state)
293317
)
294318
return Z_FALSE;
295319

320+
/* Each CPU member must be present and hold a valid number according to its type. */
296321
for (member = members; member != members + Z_ARRAY_SIZE(members) - 2; member++)
297322
if ( (item = cJSON_GetObjectItem(state, member->key)) == Z_NULL ||
298323
!is_number_between(item, 0, member->maximum_value)
299324
)
300325
return Z_FALSE;
301326

302327
return Z_TRUE;
303-
/* return 2.0 !=
328+
329+
/*-------------------------------------------------------------.
330+
| EI and P are mutually exclusive, as the previous instruction |
331+
| cannot be `ei` and `ld a,{i|r}` at the same time. |
332+
'=============================================================
333+
return 2.0 !=
304334
cJSON_GetNumberValue(cJSON_GetObjectItem(state, "ei")) +
305335
cJSON_GetNumberValue(cJSON_GetObjectItem(state, "p" ));*/
306336
}

0 commit comments

Comments
 (0)