1.
RESET
If the /RESET is released
while the clock is high, there will be 3 more full clock cycles before the
first instruction fetch:
Performing
a RESET
Starting
the clock
-----------------------------------------------------------+
#001H T1 AB:--- DB:-- |
#001L T1 AB:--- DB:-- |
#002H T2 AB:--- DB:-- |
#002L T2 AB:--- DB:-- |
#003H T3 AB:--- DB:-- |
#003L T3 AB:--- DB:-- |
-----------------------------------------------------------+
If the /RESET is released
while the clock is low, there will be 2 more full clock cycles before the first
instruction fetch:
Performing
a RESET
Starting
the clock
-----------------------------------------------------------+
#001H T1 AB:--- DB:-- |
#001L T1 AB:--- DB:-- |
#002H T2 AB:--- DB:-- |
#002L T2 AB:--- DB:-- |
-----------------------------------------------------------+
2.
Register values after the RESET
Initial known state after the reset:
PC = 0
IR = 0
Interrupts disabled.
No other registers are set or cleared.
This kind of test can only be done when you can
control the clocks and stop the execution. Reset sequence does not change
register values. Only PC, IR and IF are cleared. When the CPU is first powered
up, the registers tend to have values FFFF with flag being FD (bit 1 cleared).
That is likely caused by the inverted logic of the NMOS process and does not
indicate any special reset sequence being applied to it.
This sequence shows the interrupt bit being cleared
on a reset.
[reset] start:
ld a,i
push af -> F = 41h
or 40h
ei
ld a,i
push af -> F = 45h
or 44h
di
ld a,i
push af -> F = 41h
or 40h
bit[0] is a previous C flag unchanged.
That’s the only flag bit preserved after ld a,i. Strangely, flag register has
bit [1] (NF) cleared on a reset, as if the last operation was an addition. My
guess is that there is an internal flip flop storing the information that the
last operation was a subtraction. That flip-flop power-ups to 1. Then, the NF
flag bit is set after that bit is fed through a (bus amplifying?) inverter.
The rest of the register keep
their values. Here is a power-on with a reset:
[power on + reset] start:
push af -> FFFDh
push bc -> FFFFh
push de -> FFFFh
push hl -> FFFFh
push ix -> FFFFh
push iy -> FFFFh
ld bc, 55aah
push bc
pop af ld bc, 1122h
ld de, 3344h
ld hl, 5566h
ld ix, 7788h
ld iy, 99AAh
However, on the second run, without powering it on
and off and just issuing a reset, the register values remain what they’ve been
set before a reset:
push af -> 55AAh
push bc -> 1122h
push de -> 3344h
push hl -> 5566h
push ix -> 7788h
push iy -> 99AAh
SP behaves the same – its value keeps decreasing run after run and it
is not initialized in any way by the reset sequence. Initial power-on is FFFF
just as with every other NMOS based register. The first push decrements it to
FFFE.
3.
RST
This is the RST38 instruction cycle map; see the
extra 2 before pushing the PC --
#013H T1 AB:003 DB:-- M1 |
#014H T2 AB:003 DB:FF M1
MREQ RD |
Memory read from 003 -> FF
#015H T3 AB:001 DB:-- RFSH |
#016H T4 AB:001 DB:-- RFSH MREQ | Refresh address 001
#017H T5 AB:001 DB:-- |
#018H T6 AB:0FF DB:-- |
#019H T7 AB:0FF DB:00 MREQ |
#020H T8 AB:0FF DB:00 MREQ WR | Memory write to 0FF <- 00
#021H T9 AB:0FE DB:-- |
#022H T10 AB:0FE
DB:04 MREQ |
#023H T11 AB:0FE
DB:04 MREQ WR | Memory write to 0FE <- 04
4.
PUSH BC, see how the 5-3-3 clocks are distributed:
#003H T1 AB:000 DB:-- M1 |
#004H T2 AB:000 DB:C5 M1
MREQ RD | Opcode read from 000 -> C5
#005H T3 AB:000 DB:-- RFSH |
#006H T4 AB:000 DB:-- RFSH MREQ | Refresh address 000
#007H T5 AB:000 DB:-- |
#008H T6 AB:0FF DB:-- |
#009H T7 AB:0FF DB:FF MREQ |
#010H T8 AB:0FF DB:FF MREQ WR | Memory write to 0FF <- FF
#011H T9 AB:0FE DB:-- |
#012H T10 AB:0FE
DB:FF MREQ |
#013H T11 AB:0FE
DB:FF MREQ WR
| Memory write to 0FE <- FF
5.
PUSH IX just adds another 4-cycle prefix to it:
#014H T1 AB:001 DB:-- M1 |
#015H T2 AB:001 DB:DD M1
MREQ RD | Opcode read from 001 -> DD
#016H T3 AB:001 DB:-- RFSH |
#017H T4 AB:001 DB:-- RFSH MREQ | Refresh address 001
-----------------------------------------------------------+
#018H T1 AB:002 DB:-- M1 |
#019H T2 AB:002 DB:E5 M1
MREQ RD | Opcode read from 002 -> E5
#020H T3 AB:002 DB:-- RFSH |
#021H T4 AB:002 DB:-- RFSH MREQ | Refresh address 002
#022H T5 AB:002 DB:-- |
#023H T6 AB:0FD DB:-- |
#024H T7 AB:0FD DB:FF MREQ |
#025H T8 AB:0FD DB:FF MREQ WR | Memory write to 0FD <- FF
#026H T9 AB:0FC DB:-- |
#027H T10 AB:0FC
DB:FF MREQ |
#028H T11 AB:0FC
DB:FF MREQ WR | Memory write to 0FC <- FF
6.
This is a difference between 2 cycles of LDIR: the next to the last one
followed by the last one. The last one is shorter. While BC!=1,
there are 5 extra cycles.
-----------------------------------------------------------+
#054H T1 AB:009 DB:-- M1 |
#055H T2 AB:009 DB:ED M1
MREQ RD | Opcode read from 009 -> ED
#056H T3 AB:005 DB:-- RFSH |
#057H T4 AB:005 DB:-- RFSH MREQ | Refresh address 005
-----------------------------------------------------------+
#058H T1 AB:00A DB:-- M1 |
#059H T2 AB:00A DB:B0 M1
MREQ RD | Opcode read from 00A -> B0
#060H T3 AB:006 DB:-- RFSH |
#061H T4 AB:006 DB:-- RFSH MREQ | Refresh address 006
#062H T5 AB:031 DB:-- |
#063H T6 AB:031 DB:00 MREQ RD | Memory read from 031
-> 00
#064H T7 AB:031 DB:00 MREQ RD | Memory read from 031 -> 00
#065H T8 AB:041 DB:-- |
#066H T9 AB:041 DB:00 MREQ |
#067H T10 AB:041
DB:00 MREQ WR | Memory write to 041 <- 00
#068H T11 AB:041
DB:00
|
#069H T12 AB:041
DB:00
|
#070H T13 AB:041
DB:--
|
#071H T14 AB:041
DB:--
|
#072H T15 AB:041
DB:--
|
#073H T16 AB:041
DB:--
|
#074H T17 AB:041
DB:--
|
-----------------------------------------------------------+
#075H T1 AB:009 DB:-- M1 |
#076H T2 AB:009 DB:ED M1
MREQ RD | Opcode read from 009 -> ED
#077H T3 AB:007 DB:-- RFSH |
#078H T4 AB:007 DB:-- RFSH MREQ | Refresh address 007
-----------------------------------------------------------+
#079H T1 AB:00A DB:-- M1 |
#080H T2 AB:00A DB:B0 M1
MREQ RD | Opcode read from 00A -> B0
#081H T3 AB:008 DB:-- RFSH |
#082H T4 AB:008 DB:-- RFSH MREQ | Refresh address 008
#083H T5 AB:032 DB:-- |
#084H T6 AB:032 DB:00 MREQ RD | Memory read from 032 ->
00
#085H T7 AB:032 DB:00 MREQ RD | Memory read from 032
-> 00
#086H T8 AB:042 DB:-- |
#087H T9 AB:042 DB:00 MREQ |
#088H T10 AB:042
DB:00 MREQ WR | Memory write to 042 <- 00
#089H T11 AB:042
DB:00
|
#090H T12 AB:042
DB:00
|
-----------------------------------------------------------+
7.
ADD HL,ss seems to have
too many cycles. This is what they do (mostly nothing externally):
#003H T1 AB:000 DB:-- M1 |
#004H T2 AB:000 DB:19 M1
MREQ RD | Opcode read from 000 -> 19
#005H T3 AB:000 DB:-- RFSH |
#006H T4 AB:000 DB:-- RFSH MREQ | Refresh address 000
#007H T5 AB:000 DB:-- |
#008H T6 AB:000 DB:-- |
#009H T7 AB:000 DB:-- |
#010H T8 AB:000 DB:-- |
#011H T9 AB:000 DB:-- |
#012H T10 AB:000
DB:--
|
#013H T11 AB:000
DB:--
|
8.
This is an undocumented opcode sequence:
ld ix, 80h
srl (ix+20h),b
#007H T1 AB:001 DB:-- M1 |
#008H T2 AB:001 DB:21 M1
MREQ RD | Opcode read from 001 -> 21
#009H T3 AB:001 DB:-- RFSH |
#010H T4 AB:001 DB:-- RFSH MREQ | Refresh address 001
#011H T5 AB:002 DB:-- |
#012H T6 AB:002 DB:80 MREQ RD | Memory read from 002
-> 80
#013H T7 AB:002 DB:80 MREQ RD | Memory read from 002
-> 80
#014H T8 AB:003 DB:-- |
#015H T9 AB:003 DB:00 MREQ RD | Memory read from 003 -> 00
#016H T10 AB:003 DB:00 MREQ RD | Memory read from 003
-> 00
-----------------------------------------------------------+
#017H T1 AB:004 DB:-- M1 |
#018H T2 AB:004 DB:DD M1
MREQ RD | Opcode read from 004 -> DD
#019H T3 AB:002 DB:-- RFSH |
#020H T4 AB:002 DB:-- RFSH MREQ | Refresh address 002
-----------------------------------------------------------+
#021H T1 AB:005 DB:-- M1 |
#022H T2 AB:005 DB:CB M1
MREQ RD | Opcode read from 005 -> CB
#023H T3 AB:003 DB:-- RFSH |
#024H T4 AB:003 DB:-- RFSH MREQ | Refresh address 003
#025H T5 AB:006 DB:-- |
#026H T6 AB:006 DB:20 MREQ RD | Memory read from 006
-> 20
#027H T7 AB:006 DB:20 MREQ RD | Memory read from 006
-> 20
#028H T8 AB:007 DB:-- |
#029H T9 AB:007 DB:38 MREQ RD | Memory read from 007
-> 38
#030H T10 AB:007 DB:38 MREQ RD | Memory read from 007 -> 38
#031H T11 AB:007 DB:-- |
#032H T12 AB:007 DB:-- |
#033H T13 AB:0A0 DB:-- |
#034H T14 AB:0A0 DB:00 MREQ RD | Memory read from 0A0
-> 00
#035H T15 AB:0A0 DB:00 MREQ RD | Memory read from 0A0
-> 00
#036H T16 AB:0A0 DB:-- |
#037H T17 AB:0A0 DB:-- |
#038H T18 AB:0A0 DB:00 MREQ |
#039H T19 AB:0A0 DB:00 MREQ WR | Memory write to 0A0 <- 00
9.
This is what happens when interrupt hits in interrupt mode 2 (formal
documentation is really incomplete on this):
#029H T1 AB:007 DB:-- M1 |[INT]
#030H T2 AB:007 DB:-- M1 |[INT]
#031H T3 AB:007 DB:-- M1 |[INT]
#032H T4 AB:007 DB:-- M1 IORQ |[INT]
#033H T5 AB:005 DB:-- RFSH |[INT]
#034H T6 AB:005 DB:-- RFSH MREQ |[INT] Refresh
address 005
#035H T7 AB:005 DB:-- |[INT]
#036H T8 AB:0FE DB:-- |[INT]
#037H T9 AB:0FE DB:00 MREQ |[INT]
#038H T10 AB:0FE
DB:00 MREQ WR |[INT] Memory write to 0FE <- 00
#039H T11 AB:0FD
DB:--
|[INT]
#040H T12 AB:0FD
DB:07 MREQ |[INT]
#041H T13 AB:0FD
DB:07 MREQ WR |[INT] Memory write to 0FD <- 07
#042H T14 AB:083
DB:-- |[INT]
#043H T15 AB:083
DB:00 MREQ RD |[INT] Memory read from 083
-> 00
#044H T16 AB:083
DB:00 MREQ RD |[INT] Memory read from 083
-> 00
#045H T17 AB:084
DB:-- |[INT]
#046H T18 AB:084
DB:00 MREQ RD |[INT] Memory read from 084
-> 00
#047H T19 AB:084
DB:00 MREQ RD |[INT] Memory read from 084
-> 00
10. This is what happens when NMI
hits: the next instruction that was supposed to be run had DD opcode - which was fetched using a full M1 cycle, and then
ignored. That took 4T. At T5 there was an extra cycle before using 2 times 3T
to push PC. The next instruction started at address 66h, NMI handler.
#029H T1 AB:007 DB:-- M1 |[NMI]
#030H T2 AB:007 DB:DD M1
MREQ RD |[NMI] Opcode read from 007 -> DD
#031H T3 AB:005 DB:-- RFSH |[NMI]
#032H T4 AB:005 DB:-- RFSH MREQ |[NMI] Refresh
address 005
#033H T5 AB:005 DB:-- |[NMI]
#034H T6 AB:0F2 DB:-- |[NMI]
#035H T7 AB:0F2 DB:00 MREQ |[NMI]
#036H T8 AB:0F2 DB:00 MREQ WR |[NMI] Memory write to 0F2 <- 00
#037H T9 AB:0F1 DB:-- |[NMI]
#038H T10 AB:0F1
DB:07 MREQ |[NMI]
#039H T11 AB:0F1
DB:07 MREQ WR |[NMI] Memory write to 0F1 <- 07
-----------------------------------------------------------+
#040H T1 AB:066 DB:-- M1 |[NMI]