Skip to content

Commit

Permalink
Merge pull request #19 from koron-go/flagoperating-utilfuncs-18
Browse files Browse the repository at this point in the history
add flag operating utility functions
  • Loading branch information
koron authored Jun 24, 2024
2 parents 87bb5cc + 723d0d3 commit 307c189
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 0 deletions.
35 changes: 35 additions & 0 deletions flag.go
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)
}
126 changes: 126 additions & 0 deletions flag_test.go
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)
}
}
}

0 comments on commit 307c189

Please sign in to comment.