Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Z80.cs #1

Merged
merged 1 commit into from
Jan 3, 2018
Merged

Update Z80.cs #1

merged 1 commit into from
Jan 3, 2018

Conversation

lightfoot256
Copy link
Contributor

@lightfoot256 lightfoot256 commented Apr 27, 2017

Code generated from SDCC wasn't running correctly when JP NC was being used as the C flag wasn't being set on subtractions; example:

	ld	c,#0x00
loop:
	ld	a,c
	sub	a, #0x08
	jr	NC,loop

The c code for this was simply:

    unsigned char y=0;

        if(y<8){

And was immediately failing! I guess due to the way sub is used vs cp and nc is used vs nz this only presents itself with code generated from SDCC;

#1 Looking at the details at z80.info for subtraction:

Subtracting

The SUB group

There are two subtraction instructions, SUB which is the opposite
of ADD, and SBC which is subtract with borrow. Thus

LD A,6:SUB 2 gives A = 4.

SUB is used for 8 bit subtractions. The number or register is
subtracted from the A register and the result stored in the A
register. One of the idiosyncracities of the Z80 instrcution set
is that the A register is not written as it is with ADD, viz ADD
A C but SUB C. In addition although there are 16 bit ADD's there
are no 16 bit SUB's. (16 bit subtraction is done using the SBC
instruction.) The flags are set as follows

C or carry flag 1 if answer <0 else 0


The carry flag should be set if the result of the subtraction is less than 0; So it appears the C flag is just being incorrectly set;

#2 Looking at another emulator written in C; the following code is used:

#define SUB(x)                                                          \
{                                                                       \
        int     a, z, c, f;                                             \
                                                                        \
        a = A;                                                          \
        z = a - (x);                                                    \
                                                                        \
        c = a ^ (x) ^ z;                                                \
        f = Z80_N_FLAG | (c & Z80_H_FLAG);                              \
        f |= SZYX_FLAGS_TABLE[z & 0xff];                                \
        c &= 0x0180;                                                    \
        f |= OVERFLOW_TABLE[c >> 7];                                    \
        f |= c >> (8 - Z80_C_FLAG_SHIFT);                               \
                                                                        \
        A = z;                                                          \
        F = f;                                                          \
}

The logic is different; but ultimately results in C being set for my example; backing up the fact that there's an issue in this version;

Thanks,
Chris

Code generated from SDCC wasn't running correctly when JP NC was being used as the C flag wasn't being set on subtractions; example:

	ld	c,#0x00
loop:
	ld	a,c
	sub	a, #0x08
	jr	NC,loop

The c code for this was simply:

    unsigned char y=0;

        if(y<8){

And was immediately failing! I guess due to the way sub is used vs cp and nc is used vs nz this only presents itself with code generated from SDCC;

sklivvz#1

Looking at the details at z80.info for subtraction:
--------------------
 Subtracting

                          The SUB group

There are two subtraction instructions, SUB which is the opposite
of ADD, and SBC which is subtract with borrow. Thus

LD A,6:SUB 2  gives A = 4.

SUB  is  used for 8 bit subtractions.  The number or register  is
subtracted  from  the A register and the result stored in  the  A
register.  One of the idiosyncracities of the Z80 instrcution set
is that the A register is not written as it is with ADD,  viz ADD
A C but SUB C.  In addition although there are 16 bit ADD's there
are  no 16 bit SUB's. (16 bit subtraction is done using  the  SBC
instruction.) The flags are set as follows

C or carry flag          1 if answer <0 else 0

-------------------
The carry flag should be set if the result of the subtraction is less than 0; 

So it appears the C flag is just being incorrectly set;


sklivvz#2 

Looking at another emulator written in C; the following code is used:

#define SUB(x)                                                          \
{                                                                       \
        int     a, z, c, f;                                             \
                                                                        \
        a = A;                                                          \
        z = a - (x);                                                    \
                                                                        \
        c = a ^ (x) ^ z;                                                \
        f = Z80_N_FLAG | (c & Z80_H_FLAG);                              \
        f |= SZYX_FLAGS_TABLE[z & 0xff];                                \
        c &= 0x0180;                                                    \
        f |= OVERFLOW_TABLE[c >> 7];                                    \
        f |= c >> (8 - Z80_C_FLAG_SHIFT);                               \
                                                                        \
        A = z;                                                          \
        F = f;                                                          \
}

The logic is different; but ultimately results in C being set for my example; backing up the fact that there's an issue in this version;


Thanks,
Chris
@sklivvz sklivvz merged commit 16b957f into sklivvz:master Jan 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants