-
Notifications
You must be signed in to change notification settings - Fork 1
/
opc.go
67 lines (60 loc) · 1.27 KB
/
opc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package m68k
import "fmt"
// opAbcd implements ABCD (pg. 4-2)
func opAbcd(c *Processor) (t *stepTrace) {
t = &stepTrace{
addr: c.PC,
op: "abcd",
sz: noSize,
n: 1,
}
c.PC += 2
// read src and dst values
var vx, vy byte
rx, ry := c.op&0x0E>>9, c.op&0x07
x := byte(c.SR & StatusExtend >> 4)
mod := c.op & 0x08 >> 3
if mod == 0 {
// data register to data register
t.dst = fmt.Sprintf("D%d", rx)
t.src = fmt.Sprintf("D%d", ry)
vx, vy = byte(c.D[rx]), byte(c.D[ry])
} else {
// memory to memory with pre-decrement
t.dst = fmt.Sprintf("-(A%d)", rx)
t.src = fmt.Sprintf("-(A%d)", ry)
c.A[rx]--
c.A[ry]--
vx, t.err = c.M.Byte(int(c.A[rx]))
if t.err != nil {
return
}
vy, t.err = c.M.Byte(int(c.A[ry]))
if t.err != nil {
return
}
}
// reset satus
c.SR &= ^(StatusCarry | StatusExtend)
// packed bcd add
v := (uint16(vx) & 0x0F) + (uint16(vy) & 0x0F) + uint16(x)
if v > 9 {
v += 6
}
v += (uint16(vx) & 0xF0) + (uint16(vy) & 0xF0)
if v > 0x99 {
c.SR |= StatusCarry | StatusExtend
v -= 0xA0
}
if v != 0 {
// clear Z if result is non-zero
c.SR &= ^StatusZero
}
// write result
if mod == 0 {
c.D[rx] = (c.D[rx] & 0xFFFFFF00) | uint32(v&0xFF)
} else {
_, t.err = c.M.Write(int(c.A[rx]), []byte{byte(v)})
}
return
}