-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from koron-go/flagoperating-utilfuncs-18
add flag operating utility functions
- Loading branch information
Showing
2 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package z80 | ||
|
||
// Flag is the flag value used for GetFlag etc. | ||
// Each value can be combined with the OR (|) operator. | ||
type Flag uint8 | ||
|
||
const ( | ||
FlagC Flag = 0x01 // FlagC is carry flag. | ||
FlagN Flag = 0x02 // FlagN is subtract flag. | ||
FlagPV Flag = 0x04 // FlagPV is parity/overflow flag. | ||
FlagH Flag = 0x10 // FlagH is half carry flag. | ||
FlagZ Flag = 0x40 // FlagZ is zero flag. | ||
FlagS Flag = 0x80 // FlagS is sign flag. | ||
|
||
Flag3 Flag = 0x08 // Flag3 is undefined flag, at 3rd from LSB. | ||
Flag5 Flag = 0x20 // Flag5 is undefined flag, at 5th from LSB. | ||
) | ||
|
||
// GetFlag gets a flag status. For available flags, see Flag type. When | ||
// multiple flags are combined, if any one of them is true, this returns true. | ||
func (gpr GPR) GetFlag(f Flag) bool { | ||
return gpr.AF.Lo&uint8(f) != 0 | ||
} | ||
|
||
// SetFlag sets the specified flag to true. For available flags, see Flag | ||
// type. When multiple flags are combined, all flags are set to true. | ||
func (gpr *GPR) SetFlag(f Flag) { | ||
gpr.AF.Lo |= uint8(f) | ||
} | ||
|
||
// ResetFlag resets the specified flag to false. Fo available flags, see Flag | ||
// type. When multiple flags are combined, all flags are set to false. | ||
func (gpr *GPR) ResetFlag(f Flag) { | ||
gpr.AF.Lo &= ^uint8(f) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package z80_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/koron-go/z80" | ||
) | ||
|
||
func TestGetFlag(t *testing.T) { | ||
for i, c := range []struct { | ||
lo uint8 | ||
flag z80.Flag | ||
want bool | ||
}{ | ||
{0b00000001, z80.FlagC, true}, | ||
{0b00000000, z80.FlagC, false}, | ||
{0b11111110, z80.FlagC, false}, | ||
|
||
{0b00000010, z80.FlagN, true}, | ||
{0b00000000, z80.FlagN, false}, | ||
{0b11111101, z80.FlagN, false}, | ||
|
||
{0b00000100, z80.FlagPV, true}, | ||
{0b00000000, z80.FlagPV, false}, | ||
{0b11111011, z80.FlagPV, false}, | ||
|
||
{0b00010000, z80.FlagH, true}, | ||
{0b00000000, z80.FlagH, false}, | ||
{0b11100111, z80.FlagH, false}, | ||
|
||
{0b01000000, z80.FlagZ, true}, | ||
{0b00000000, z80.FlagZ, false}, | ||
{0b10111111, z80.FlagZ, false}, | ||
|
||
{0b10000000, z80.FlagS, true}, | ||
{0b00000000, z80.FlagS, false}, | ||
{0b01111111, z80.FlagS, false}, | ||
} { | ||
var cpu z80.CPU | ||
cpu.AF.Lo = c.lo | ||
got := cpu.GetFlag(c.flag) | ||
if got != c.want { | ||
t.Errorf("unexpected value: %d %+v: got=%t", i, c, got) | ||
} | ||
} | ||
} | ||
|
||
func TestSetFlag(t *testing.T) { | ||
for i, c := range []struct { | ||
prev uint8 | ||
flag z80.Flag | ||
want uint8 | ||
}{ | ||
{0b00000000, z80.FlagC, 0b00000001}, | ||
{0b00000001, z80.FlagC, 0b00000001}, | ||
{0b11111110, z80.FlagC, 0b11111111}, | ||
|
||
{0b00000000, z80.FlagN, 0b00000010}, | ||
{0b00000010, z80.FlagN, 0b00000010}, | ||
{0b11111101, z80.FlagN, 0b11111111}, | ||
|
||
{0b00000000, z80.FlagPV, 0b00000100}, | ||
{0b00000100, z80.FlagPV, 0b00000100}, | ||
{0b11111011, z80.FlagPV, 0b11111111}, | ||
|
||
{0b00000000, z80.FlagH, 0b00010000}, | ||
{0b00010000, z80.FlagH, 0b00010000}, | ||
{0b11101111, z80.FlagH, 0b11111111}, | ||
|
||
{0b00000000, z80.FlagZ, 0b01000000}, | ||
{0b01000000, z80.FlagZ, 0b01000000}, | ||
{0b10111111, z80.FlagZ, 0b11111111}, | ||
|
||
{0b00000000, z80.FlagS, 0b10000000}, | ||
{0b10000000, z80.FlagS, 0b10000000}, | ||
{0b01111111, z80.FlagS, 0b11111111}, | ||
} { | ||
var cpu z80.CPU | ||
cpu.AF.Lo = c.prev | ||
cpu.SetFlag(c.flag) | ||
got := cpu.AF.Lo | ||
if got != c.want { | ||
t.Errorf("unexpected value: %d {prev:%08b flag:0x%02x want:%08b}: got=%08b", i, c.prev, c.flag, c.want, got) | ||
} | ||
} | ||
} | ||
|
||
func TestResetFlag(t *testing.T) { | ||
for i, c := range []struct { | ||
prev uint8 | ||
flag z80.Flag | ||
want uint8 | ||
}{ | ||
{0b00000001, z80.FlagC, 0b00000000}, | ||
{0b00000000, z80.FlagC, 0b00000000}, | ||
{0b11111111, z80.FlagC, 0b11111110}, | ||
|
||
{0b00000010, z80.FlagN, 0b00000000}, | ||
{0b00000000, z80.FlagN, 0b00000000}, | ||
{0b11111111, z80.FlagN, 0b11111101}, | ||
|
||
{0b00000100, z80.FlagPV, 0b00000000}, | ||
{0b00000000, z80.FlagPV, 0b00000000}, | ||
{0b11111111, z80.FlagPV, 0b11111011}, | ||
|
||
{0b00010000, z80.FlagH, 0b00000000}, | ||
{0b00000000, z80.FlagH, 0b00000000}, | ||
{0b11111111, z80.FlagH, 0b11101111}, | ||
|
||
{0b01000000, z80.FlagZ, 0b00000000}, | ||
{0b00000000, z80.FlagZ, 0b00000000}, | ||
{0b10111111, z80.FlagZ, 0b10111111}, | ||
|
||
{0b10000000, z80.FlagS, 0b00000000}, | ||
{0b00000000, z80.FlagS, 0b00000000}, | ||
{0b11111111, z80.FlagS, 0b01111111}, | ||
} { | ||
var cpu z80.CPU | ||
cpu.AF.Lo = c.prev | ||
cpu.ResetFlag(c.flag) | ||
got := cpu.AF.Lo | ||
if got != c.want { | ||
t.Errorf("unexpected value: %d {prev:%08b flag:0x%02x want:%08b}: got=%08b", i, c.prev, c.flag, c.want, got) | ||
} | ||
} | ||
} |