Gopher2600/hardware/cpu/registers.go
steve 4c530bf7a7 o initial commit
- 6502 implementation is basically correct but does not handle
        - interrupts
        - pre-fetch cycle
        - anything less fine grained than instruction stepping
      - memory sub-system sketched in

    o retroactive adding of GPL copyright notice
2020-01-05 18:58:12 +00:00

194 lines
4.5 KiB
Go

package cpu
import (
"fmt"
"log"
)
// Register is the bit representation of the all CPU registers (with the exception of
// the status register.
type Register []bit
// note that in the 6502, all arithmetic and bitwise operations are carried out on 8 bit
// registers, with a special increment for the PC register. for this emulation, those
// operations can be performed on 16 bit registers too, for convenience. principally, this
// means the PC register, but we also perform 16 bit addition on temporary registers when
// indexing. in the latter case, care must be taken to detect 8 bit overflow, or page-faults
// as we call them, manually.
//
// pageFault = indexedAddress & 0xFF00 != preIndexedAddress & 0xFF00
func (r Register) String() string {
return fmt.Sprintf("%s (%d)", r.ToBits(), r.ToUint())
}
// Load value into register
func (r Register) Load(v interface{}) {
b, err := generateRegister(v, len(r))
if err != nil {
log.Fatalln(err)
}
copy(r, b)
}
// Add value to register. Returns carry and overflow states
func (r Register) Add(v interface{}, carry bool) (bool, bool) {
b, err := generateRegister(v, len(r))
if err != nil {
log.Fatalln(err)
}
sign := r[0]
i := len(b) - 1
for i >= 0 {
if r[i] == false && b[i] == false && carry == false { // 0 0 0
r[i] = false
carry = false
} else if r[i] == false && b[i] == false && carry == true { // 0 0 1
r[i] = true
carry = false
} else if r[i] == false && b[i] == true && carry == false { // 0 1 0
r[i] = true
carry = false
} else if r[i] == false && b[i] == true && carry == true { // 0 1 1
r[i] = false
carry = true
} else if r[i] == true && b[i] == false && carry == false { // 1 0 0
r[i] = true
carry = false
} else if r[i] == true && b[i] == false && carry == true { // 1 0 1
r[i] = false
carry = true
} else if r[i] == true && b[i] == true && carry == false { // 1 1 0
r[i] = false
carry = true
} else if r[i] == true && b[i] == true && carry == true { // 1 1 1
r[i] = true
carry = true
}
i--
}
overflow := sign == true && b[0] == true && r[0] == false
return carry, overflow
}
// Subtract value from register. Returns carry and overflow states
//
// Note that carry flag is opposite of what you might expect when subtracting
// on the 6502/6507
func (r Register) Subtract(v interface{}, carry bool) (bool, bool) {
b, err := generateRegister(v, len(r))
if err != nil {
log.Fatalln(err)
}
// generate two's complement
i := 0
for i < len(b) {
b[i] = !b[i]
i++
}
b.Add(1, false)
return r.Add(b, !carry)
}
// EOR - XOR Register with value
func (r Register) EOR(v interface{}) {
b, err := generateRegister(v, len(r))
if err != nil {
log.Fatalln(err)
}
i := 0
for i < len(r) {
r[i] = (r[i] || b[i]) && r[i] != b[i]
i++
}
}
// ORA - OR Register with value
func (r Register) ORA(v interface{}) {
b, err := generateRegister(v, len(r))
if err != nil {
log.Fatalln(err)
}
i := 0
for i < len(r) {
r[i] = r[i] || b[i]
i++
}
}
// AND register with value
func (r Register) AND(v interface{}) {
b, err := generateRegister(v, len(r))
if err != nil {
log.Fatalln(err)
}
i := 0
for i < len(r) {
r[i] = r[i] && b[i]
i++
}
}
// ROR rotates register 1 bit to the right. Returns new carry status.
func (r Register) ROR(carry bool) bool {
rcarry := bool(r[len(r)-1])
copy(r[1:], r[:len(r)-1])
r[0] = bit(carry)
return rcarry
}
// ROL rotates register 1 bit to the left. Returns new carry status.
func (r Register) ROL(carry bool) bool {
rcarry := bool(r[0])
copy(r[:len(r)-1], r[1:])
r[len(r)-1] = bit(carry)
return rcarry
}
// ASL (Arithmetic shift Left) shifts register one bit to the left. Returns
// the most significant bit as it was before the shift. If we think of the
// ASL operation as a multiply by two then the return value is the carry bit.
func (r Register) ASL() bool {
rcarry := bool(r[0])
copy(r[:len(r)-1], r[1:])
r[len(r)-1] = bit(false)
return rcarry
}
// LSR (Logical Shift Right) shifts register one bit to the rigth.
// the least significant bit as it was before the shift. If we think of
// the ASL operation as a division by two then the return value is the carry bit.
func (r Register) LSR() bool {
rcarry := bool(r[len(r)-1])
copy(r[1:], r[:len(r)-1])
r[0] = bit(false)
return rcarry
}
// IsNegative checks the sign bit of the register
func (r Register) IsNegative() bool {
return bool(r[0])
}
// IsZero checks if register is all zero bits
func (r Register) IsZero() bool {
for b := range r {
if r[b] == true {
return false
}
}
return true
}