mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-01-22 14:30:11 +00:00
Flags updated
This commit is contained in:
parent
de72112f90
commit
8208885df8
13
execute.go
13
execute.go
@ -21,7 +21,7 @@ const modeIndexedIndirectX = 7
|
|||||||
const modeIndirectIndexedY = 8
|
const modeIndirectIndexedY = 8
|
||||||
|
|
||||||
// https://www.masswerk.at/6502/6502_instruction_set.html
|
// https://www.masswerk.at/6502/6502_instruction_set.html
|
||||||
|
// http://www.emulator101.com/reference/6502-reference.html
|
||||||
func getWordInLine(line []uint8) uint16 {
|
func getWordInLine(line []uint8) uint16 {
|
||||||
return uint16(line[1]) + 0x100*uint16(line[2])
|
return uint16(line[1]) + 0x100*uint16(line[2])
|
||||||
}
|
}
|
||||||
@ -41,20 +41,22 @@ func buildOPTransfer(regSrc int, regDst int) opFunc {
|
|||||||
return func(s *state, line []uint8, opcode opcode) {
|
return func(s *state, line []uint8, opcode opcode) {
|
||||||
value := s.registers.getRegister(regSrc)
|
value := s.registers.getRegister(regSrc)
|
||||||
s.registers.setRegister(regDst, value)
|
s.registers.setRegister(regDst, value)
|
||||||
// TODO: Update flags (N, Z)
|
if regDst != regSP {
|
||||||
|
s.registers.updateFlagZN(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildOpIncDecRegister(reg int, inc bool) opFunc {
|
func buildOpIncDecRegister(reg int, inc bool) opFunc {
|
||||||
return func(s *state, line []uint8, opcode opcode) {
|
return func(s *state, line []uint8, opcode opcode) {
|
||||||
value := s.registers.getRegister(reg) + 1
|
value := s.registers.getRegister(reg)
|
||||||
if inc {
|
if inc {
|
||||||
value++
|
value++
|
||||||
} else {
|
} else {
|
||||||
value--
|
value--
|
||||||
}
|
}
|
||||||
s.registers.setRegister(reg, value)
|
s.registers.setRegister(reg, value)
|
||||||
// TODO: Update flags (N, Z) for all but TXS
|
s.registers.updateFlagZN(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,8 +95,7 @@ func buildOpLoad(addressMode int, regDst int) opFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.registers.setRegister(regDst, value)
|
s.registers.setRegister(regDst, value)
|
||||||
|
s.registers.updateFlagZN(value)
|
||||||
// TODO: Update flags (N, Z)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,16 @@ func TestLoad(t *testing.T) {
|
|||||||
t.Error("Error in LDA #")
|
t.Error("Error in LDA #")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
executeLine(&s, []uint8{0xA9, 0x00})
|
||||||
|
if s.registers.getP() != flagZ {
|
||||||
|
t.Error("Error in flags for LDA $0")
|
||||||
|
}
|
||||||
|
|
||||||
|
executeLine(&s, []uint8{0xA9, 0xF0})
|
||||||
|
if s.registers.getP() != flagN {
|
||||||
|
t.Error("Error in flags for LDA $F0")
|
||||||
|
}
|
||||||
|
|
||||||
executeLine(&s, []uint8{0xA0, 0xFE})
|
executeLine(&s, []uint8{0xA0, 0xFE})
|
||||||
if s.registers.getY() != 0xFE {
|
if s.registers.getY() != 0xFE {
|
||||||
t.Error("Error in LDY #")
|
t.Error("Error in LDY #")
|
||||||
@ -84,6 +94,9 @@ func TestTransfer(t *testing.T) {
|
|||||||
if s.registers.getX() != 0xB0 {
|
if s.registers.getX() != 0xB0 {
|
||||||
t.Error("Error in TAX")
|
t.Error("Error in TAX")
|
||||||
}
|
}
|
||||||
|
if s.registers.getP() != flagN {
|
||||||
|
t.Error("Error in TAX flags")
|
||||||
|
}
|
||||||
|
|
||||||
s.registers.setA(0xB1)
|
s.registers.setA(0xB1)
|
||||||
executeLine(&s, []uint8{0xA8})
|
executeLine(&s, []uint8{0xA8})
|
||||||
@ -114,3 +127,23 @@ func TestTransfer(t *testing.T) {
|
|||||||
t.Error("Error in TYA")
|
t.Error("Error in TYA")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIncDec(t * testing.T) {
|
||||||
|
var s state
|
||||||
|
|
||||||
|
s.registers.setX(0x7E)
|
||||||
|
executeLine(&s, []uint8{0xE8})
|
||||||
|
if s.registers.getX() != 0x7F {
|
||||||
|
t.Errorf("Error in INX %v", s.registers.getX())
|
||||||
|
}
|
||||||
|
|
||||||
|
s.registers.setY(0xFC)
|
||||||
|
executeLine(&s, []uint8{0x88})
|
||||||
|
if s.registers.getY() != 0xFB {
|
||||||
|
t.Error("Error in DEY")
|
||||||
|
}
|
||||||
|
if s.registers.getP() != flagN {
|
||||||
|
t.Error("Error in DEY flags")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
35
registers.go
35
registers.go
@ -9,6 +9,16 @@ const (
|
|||||||
regPC = 6 // 2 bytes
|
regPC = 6 // 2 bytes
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
flagN uint8 = 1 << 7
|
||||||
|
flagV uint8 = 1 << 6
|
||||||
|
flagB uint8 = 1 << 4
|
||||||
|
flagD uint8 = 1 << 3
|
||||||
|
flagI uint8 = 1 << 2
|
||||||
|
flagZ uint8 = 1 << 1
|
||||||
|
flagC uint8 = 1 << 0
|
||||||
|
)
|
||||||
|
|
||||||
type registers struct {
|
type registers struct {
|
||||||
data [8]uint8
|
data [8]uint8
|
||||||
}
|
}
|
||||||
@ -38,3 +48,28 @@ func (r *registers) setPC(v uint16) {
|
|||||||
r.data[regPC] = uint8(v >> 8)
|
r.data[regPC] = uint8(v >> 8)
|
||||||
r.data[regPC+1] = uint8(v)
|
r.data[regPC+1] = uint8(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *registers) getFlag(i uint8) bool {
|
||||||
|
return (r.data[regP] & i ) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *registers) setFlag(i uint8) {
|
||||||
|
r.data[regP] |= i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *registers) clearFlag(i uint8) {
|
||||||
|
r.data[regP] &^= i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *registers) updateFlag(i uint8, v bool) {
|
||||||
|
if v {
|
||||||
|
r.setFlag(i)
|
||||||
|
} else {
|
||||||
|
r.clearFlag(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *registers) updateFlagZN(t uint8) {
|
||||||
|
r.updateFlag(flagZ, t == 0)
|
||||||
|
r.updateFlag(flagN, t >= (1<<7))
|
||||||
|
}
|
||||||
|
@ -20,3 +20,50 @@ func TestRegPC(t *testing.T) {
|
|||||||
t.Error("Error storing and loading PC")
|
t.Error("Error storing and loading PC")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFlags(t *testing.T) {
|
||||||
|
var r registers
|
||||||
|
r.setP(0x23)
|
||||||
|
if r.getP() != 0x23 {
|
||||||
|
t.Error("Error storing and loading P")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.setP(0)
|
||||||
|
r.setFlag(flagD)
|
||||||
|
if !r.getFlag(flagD) {
|
||||||
|
t.Error("Error setting and getting flag")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.clearFlag(flagD)
|
||||||
|
if r.getFlag(flagD) {
|
||||||
|
t.Error("Error clearing flag")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.updateFlag(flagD, true)
|
||||||
|
if !r.getFlag(flagD) {
|
||||||
|
t.Error("Error update flag to true")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.updateFlag(flagD, false)
|
||||||
|
if r.getFlag(flagD) {
|
||||||
|
t.Error("Error updating flag to false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateFlagZN(t *testing.T) {
|
||||||
|
var r registers
|
||||||
|
r.updateFlagZN(0)
|
||||||
|
if r.getP() != flagZ {
|
||||||
|
t.Error("Error update flags ZN with 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.updateFlagZN(0x10)
|
||||||
|
if r.getP() != 0 {
|
||||||
|
t.Error("Error update flags ZN with 0x10")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.updateFlagZN(0xF2)
|
||||||
|
if r.getP() != flagN {
|
||||||
|
t.Error("Error update flags ZN with 0xF2")
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user