| 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)
|