OpenCores
URL https://opencores.org/ocsvn/a-z80/a-z80/trunk

Subversion Repositories a-z80

[/] [a-z80/] [trunk/] [tools/] [dongle/] [sbc/] [simulate-sbc.py] - Blame information for rev 21

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 gdevic
#!/usr/bin/env python3
2 3 gdevic
#
3
# This script simulates 'sbc' calculation and generates values for selected numbers.
4
# These can be compared with a real Z80 run values.
5
#
6
import sys
7
 
8
def printFlags(f):
9
    s = ''
10
    if f & (1 << 7):
11
        s += 'S'
12
    else:
13
        s += ' '
14
    if f & (1 << 6):
15
        s += 'Z'
16
    else:
17
        s += ' '
18
    if f & (1 << 5):
19
        s += 'Y'
20
    else:
21
        s += ' '
22
    if f & (1 << 4):
23
        s += 'H'
24
    else:
25
        s += ' '
26
    if f & (1 << 3):
27
        s += 'X'
28
    else:
29
        s += ' '
30
    if f & (1 << 2):
31
        s += 'P'
32
    else:
33
        s += ' '
34
    if f & (1 << 1):
35
        s += 'V'
36
    else:
37
        s += ' '
38
    if f & (1 << 0):
39
        s += 'C'
40
    else:
41
        s += ' '
42 8 gdevic
    print ('Flags =                           %s' % s)
43 3 gdevic
 
44
def sbc(inA, op2, CYin):
45 8 gdevic
    print ('------------------------------------------')
46
    print ('Input: %0.2X SBC %0.2X  CY = %0.2X' % ( inA, op2, CYin))
47 3 gdevic
 
48
    double_cpl = 0                  # Flag that we did a double 1's complement
49
    cplOp2 = op2 ^ 0xFF             # Bit-wise complement of OP2
50
 
51
    if CYin:                        # If CF was set, we'll also use complemented ACCT
52
        double_cpl = 1
53
        cplA = inA ^ 0xFF
54
        finalA = cplA + cplOp2 + CYin
55
        carry_ins = finalA ^ cplA ^ cplOp2   # Bitfield of all internal carry-ins
56
    else:                           # Otherwise, set CF to act as '+1' in NEG
57
        CYin = 1
58
        finalA = inA + cplOp2 + CYin
59
        carry_ins = finalA ^ inA ^ cplOp2    # Bitfield of all internal carry-ins
60
        carry_ins ^= 0xFF
61
 
62
    # Calculate CF while we have bit [9] available
63
    cf = 0
64
    if finalA > 255 or finalA < 0:
65
        cf = 1
66
 
67
    cf ^= 1                         # Complement CY since we used cpl(A) and not A
68
    if double_cpl:
69
        cf ^= 1
70
 
71
    nf = 1                          # 1 for SUB operation
72
 
73
    finalA = finalA & 0xFF          # Clamp final value to 8 bits
74
 
75
    #-------------------------------------------------------------------------------
76
    # Flag calculation: SF, ZF, YF, HF, XF, VF/PF, NF, CF
77
    #-------------------------------------------------------------------------------
78
    # Carry and Overflow calculation on Z80 require us to use internal carry-ins
79
    # http://stackoverflow.com/questions/8034566/overflow-and-carry-flags-on-z80
80
    #carry_ins = finalA ^ inA ^ op2  # Bitfield of all internal carry-ins
81
 
82
    sf = (finalA>>7) & 1            # SF = Copy of [7]
83
    zf = finalA==0                  # ZF = Set if all result bits are zero
84
    yf = (finalA>>5) & 1            # YF = Copy of [5]
85
    hf = (carry_ins>>4)&1           # HF = Internal carry from bit [3] to [4]
86
    xf = (finalA>>3) & 1            # XF = Copy of [3]
87
    #                               # PF = XOR all final bits to get odd parity value
88
    pf = (((finalA>>7)^(finalA>>6)^(finalA>>5)^(finalA>>4)^(finalA>>3)^(finalA>>2)^(finalA>>1)^(finalA>>0))&1)^1
89
    vf = (carry_ins>>7)&1           # VF = Internal carry from bit [6] to [7]
90
    vf ^= cf                        # XOR'ed with the final carry out
91
 
92
    flags = (sf<<7) | (zf<<6) | (yf<<5) | (hf<<4) | (xf<<3) | (vf<<2) | (nf<<1) | (cf<<0)
93
 
94 8 gdevic
    print ('Out:      A -> %0.2X    Flags = %0.2X' % ( finalA, flags))
95 3 gdevic
    printFlags(flags)
96
 
97
sbc(0, 0, 0)
98 8 gdevic
print ('Should be A -> 00    Flags = 42')
99 3 gdevic
printFlags(0x42)
100
sbc(0, 1, 0)
101 8 gdevic
print ('Should be A -> FF    Flags = BB')
102 3 gdevic
printFlags(0xBB)
103
 
104
sbc(0, 0, 1)
105 8 gdevic
print ('Should be A -> FF    Flags = BB')
106 3 gdevic
printFlags(0xBB)
107
sbc(0, 1, 1)
108 8 gdevic
print ('Should be A -> FE    Flags = BB')
109 3 gdevic
printFlags(0xBB)
110
 
111
sbc(0xAA, 0x55, 0)
112 8 gdevic
print ('Should be A -> 55    Flags = 06')
113 3 gdevic
printFlags(0x06)
114
sbc(0x55, 0xAA, 0)
115 8 gdevic
print ('Should be A -> AB    Flags = BF')
116 3 gdevic
printFlags(0xBF)
117
 
118
sbc(0xAA, 0x55, 1)
119 8 gdevic
print ('Should be A -> 54    Flags = 06')
120 3 gdevic
printFlags(0x06)
121
sbc(0x55, 0xAA, 1)
122 8 gdevic
print ('Should be A -> AA    Flags = BF')
123 3 gdevic
printFlags(0xBF)
124
 
125
sbc(0x0F, 0x03, 1)
126 8 gdevic
print ('Should be A -> 0B    Flags = 0A')
127 3 gdevic
printFlags(0x0A)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.