1 |
3 |
gdevic |
#!/usr/bin/env python
|
2 |
|
|
#
|
3 |
|
|
# This script simulates 'neg' calculation and generates values for numbers 0-255.
|
4 |
|
|
# These can be compared with a real Z80 run values.
|
5 |
|
|
#
|
6 |
|
|
import sys
|
7 |
|
|
|
8 |
|
|
for inA in range(0, 256):
|
9 |
|
|
# neg is: 0 - A
|
10 |
|
|
# or: 255 - inA + 1
|
11 |
|
|
# or: 255 - -(cpl(A)+1) + 1 (second complement of A; can change the sign)
|
12 |
|
|
# or: 255 + cpl(A)+1 + 1
|
13 |
|
|
# or: cpl(A) + 255 + 1 + 1
|
14 |
|
|
# or: cpl(A) + 0 + 1 (+CY)
|
15 |
|
|
# cplA = inA ^ 0xFF; # Bit-wise complement of A
|
16 |
|
|
# CYin = 1 # Carry in force to 1
|
17 |
|
|
# op2 = 0 # Load operand 2 with a constant value of 0
|
18 |
|
|
# finalA = cplA + op2 + CYin
|
19 |
|
|
|
20 |
|
|
acct = inA # ACCT is always loaded with A
|
21 |
|
|
op2 = inA # Load A again into OP2
|
22 |
|
|
mux1 = 0 # MUX1 selects 0 instead of ACCT
|
23 |
|
|
mux2 = op2 ^ 0xFF # MUX2 selects complement of OP2
|
24 |
|
|
CYin = 1 # Carry in force to 1
|
25 |
|
|
finalA = mux1 + mux2 + CYin
|
26 |
|
|
carry_ins = finalA ^ mux1 ^ mux2 # Bitfield of all internal carry-ins
|
27 |
|
|
carry_ins ^= 0x90 # !?!?! Need to invert both H and V carry-ins?
|
28 |
|
|
|
29 |
|
|
# Calculate CF while we have bit [9] available
|
30 |
|
|
cf = 0
|
31 |
|
|
if finalA > 255 or finalA < 0:
|
32 |
|
|
cf = 1
|
33 |
|
|
|
34 |
|
|
cf ^= 1 # Complement CY since we used cpl(A) and not A
|
35 |
|
|
nf = 1 # 1 for SUB operation
|
36 |
|
|
|
37 |
|
|
finalA = finalA & 0xFF # Clamp final value to 8 bits
|
38 |
|
|
|
39 |
|
|
#-------------------------------------------------------------------------------
|
40 |
|
|
# Flag calculation: SF, ZF, YF, HF, XF, VF/PF, NF, CF
|
41 |
|
|
#-------------------------------------------------------------------------------
|
42 |
|
|
# Carry and Overflow calculation on Z80 require us to use internal carry-ins
|
43 |
|
|
# http://stackoverflow.com/questions/8034566/overflow-and-carry-flags-on-z80
|
44 |
|
|
#carry_ins = finalA ^ inA ^ op2 # Bitfield of all internal carry-ins
|
45 |
|
|
|
46 |
|
|
sf = (finalA>>7) & 1 # SF = Copy of [7]
|
47 |
|
|
zf = finalA==0 # ZF = Set if all result bits are zero
|
48 |
|
|
yf = (finalA>>5) & 1 # YF = Copy of [5]
|
49 |
|
|
hf = (carry_ins>>4)&1 # HF = Internal carry from bit [3] to [4]
|
50 |
|
|
xf = (finalA>>3) & 1 # XF = Copy of [3]
|
51 |
|
|
# # PF = XOR all final bits to get odd parity value
|
52 |
|
|
pf = (((finalA>>7)^(finalA>>6)^(finalA>>5)^(finalA>>4)^(finalA>>3)^(finalA>>2)^(finalA>>1)^(finalA>>0))&1)^1
|
53 |
|
|
vf = (carry_ins>>7)&1 # VF = Internal carry from bit [6] to [7]
|
54 |
|
|
vf ^= cf # XOR'ed with the final carry out
|
55 |
|
|
|
56 |
|
|
flags = (sf<<7) | (zf<<6) | (yf<<5) | (hf<<4) | (xf<<3) | (vf<<2) | (nf<<1) | (cf<<0)
|
57 |
|
|
|
58 |
|
|
print '%0.2X -> %0.2X Flags = %0.2X' % ( inA, finalA, flags)
|