1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
z680k: The Tricky Bits
======================
For those following along at home, here's some explanation of the
tricky bits of z680k.
Flags
-----
Computing flags is hard, and can take a long time. So I avoid doing
it whenever possible. Flag computation is usually done only when an
instruction asks for it, and then generally a minimum amount of work
is done in order to maintain performance.
After every instruction that can influence flags, z680k notes down
what has changed. It records this information in one of several ways:
1. Simulated F register
The simplest to understand is the simulated F register, which is
composed of `flag_storage` and `flag_valid`. `flag_valid` is a
mask indicating what bits of `flag_storage` are part of the F
register. This storage space may be fully, partially, or not at
all valid. It is considered most authoritative.
2. Saved 68k Condition Code Register
After all operations that affect the Sign, Zero, Parity/oVerflow
(in the oVerflow mode), or Carry flags, the 68k condition code
register is saved in `f_host_ccr`. As necessary, this is looked up
in `lut_ccr` for a mapping to Z80 flags. The validity mask of this
table is at most `11000101`.
3. Saved Operands
After arithmetic operations that affect the half-carry (H) flag,
the operands are saved in `f_tmp_src_b` and `f_tmp_dst_b`.
(Instructions that affect the half-carry flag and operate on words
use `f_tmp_???_w` instead.)
4. Miscellany
Parity may be recorded immediately? I haven't written it yet.
`f_tmp_p_type` records whether it is parity or overflow, and
whether it's been calculated or not. Parity is looked up in
`lut_parity`, a table that was stolen^Wborrowed from some other
emulator. No malice intended; I simply forget which it was.
|