OXYGENHUB
◆ main openmsx / doc / internal / exsphl.txt
3.8 KiB · Plain Text · last changed chore(): initial commit 1 month ago source blame history raw
1
2
EX (SP),HL
3
==========
4
5
This instruction does 5 memory transactions
6
7
 - 1 byte instruction fetch
8
 - 2 bytes data reads
9
 - 2 bytes data writes
10
11
The goal of this test is to find out the order of these 5 transactions.
12
Obviously the instruction fetch (F) is the first transaction.
13
14
There is one read from location SP+0, I'll call this R0. One read from
15
location SP+1 (R0). A write to SP+0 (W0) and a write to SP+1 (W1).
16
17
R0 must come before WO and R1 must come before W1. This leaves the
18
following possible orders (please check that I didn't miss some):
19
20
  a) F R0 W0 R1 W1
21
  b) F R0 R1 W0 W1
22
  c) F R0 R1 W1 W0
23
  d) F R1 W1 R0 W0
24
  e) F R1 R0 W1 W0
25
  f) F R1 R0 W0 W1
26
27
28
* Z80
29
30
In the document z80cpu_um.pdf you can find the number of cycles per M-cycle.
31
For the EX (SP),HL instruction it lists:
32
33
  5 M-cycles, 19 T-states, 4+3+4+3+5
34
35
  note: this doesn't include the extra wait-state introduced on MSX.
36
37
This can be explained like this (note, I'm guessing here, but it seems
38
to fit well on the number of T-states).
39
40
  M1:  fetch/decode opcode              4     cycles
41
  M2:  tmpL = read(SP)                  3     cycles
42
  M3:  ++SP ; tmpH = read(SP)           1+3   cycles
43
  M4:  write(SP, H)                     3     cycles
44
  M5:  --SP ; write(SP, L) ; HL = tmp   1+3+1 cycles
45
46
  fetching opcode (or prefix) takes 4 cycles in all Z80 instructions
47
  reading/writing memory takes 3 cycles on Z80
48
49
This corresponds with order c) [F R0 R1 W1 W0]
50
51
52
* R800
53
54
On R800, the instruction takes 7 cycles if SP+0 and SP+1 are in the same
55
256-byte page, 9 cycles if not (see r800test.txt for more details on this).
56
So it seems there are two extra page-breaks in the latter case, order a)
57
and d) need only 1 extra page-break (of course it's not impossible there
58
still are 2 page-breaks, or one page-break and some other extra cost).
59
In any case the timing doesn't give us enough information.
60
61
We need another test to be sure about the order. We'll do this by setting
62
the stack pointer to a memory-mapped IO region:
63
64
In the MSXTurboR, in slot 3-3, there's a ROM mapper. Writes to the region
65
0x6C00-0x6FFF will switch the ROM in region 0x6000-0x7FFF. The content
66
of the ROM is like this:
67
68
  page 0, address 0x6C80/0x6C81: F6 50
69
       1                         C3 3E
70
       2                         08 07
71
72
Now execute the following program, with slot 3-3 selected in page 1
73
(0x4000-0x7FFF).
74
75
-------------------------------
76
77
	org	#C000
78
79
	di
80
	ld	(save),sp
81
	ld	sp,#6C80
82
83
	xor	a
84
	ld	(#6C80),a
85
86
	ld	hl,#0201
87
	ex	(sp),hl
88
	ld	de,(#6C80)
89
90
	ld	sp,(save)
91
	ret
92
93
save	dw	0
94
95
------------------------------
96
97
After running this program the registers HL/DE contain these values
98
99
  HL = 50F6
100
  DE = 3EC3
101
102
Register DE contains the ROM content after both writes (W0,W1) are done.
103
The value of DE comes from ROM page 1, so writing of L=1 (=W0) must come
104
after writing of H=2 (=W1).
105
106
Both register H and L contain the content of the initial ROM page
107
(page 0), this means both reads are executed before either of the writes.
108
109
This leaves two possibilities:
110
111
  c) F R0 R1 W1 W0     [FRrww] [FRRwW]
112
  e) F R1 R0 W1 W0     [FRrww] [FRRWW]
113
114
I've also indicated the page-breaks when SP+0 and SP+1 are in the same or
115
in a different page (again see r800test.txt for details). Possibility e)
116
would require 10 cycles, possibility c) matches the measurement of 9
117
cycles.
118
119
120
* conclusion
121
122
Both Z80 and R800 use the same order [F R0 R1 W1 W0]. The result on R800
123
is based on measurements, for Z80 it's based on extrapolating T-state
124
documentation. It would be nice to also actually measure it on Z80.
125
126
127
The order [F R0 WO R1 W1] would have been better on R800: it would only
128
require 8 cycles in case of a SP+0 SP+1 page break. Though that would be
129
incompatible with Z80. Also most of the time it doesn't matter because
130
the top-stack-word doesn't cross a page boundary too often (even never
131
when the stack is two-bytes aligned).