2018-06-12 20:46:20 +00:00
|
|
|
package millfork.assembly.mos.opt
|
2018-03-05 18:14:42 +00:00
|
|
|
|
2018-06-12 20:46:20 +00:00
|
|
|
import millfork.assembly.mos.State
|
2018-06-17 00:01:35 +00:00
|
|
|
import millfork.assembly.opt._
|
2018-03-05 18:14:42 +00:00
|
|
|
|
2018-03-06 14:49:28 +00:00
|
|
|
object SourceOfNZ {
|
|
|
|
val A = SingleStatus(SourceOfNZ(a = true))
|
|
|
|
val AW = SingleStatus(SourceOfNZ(aw = true))
|
|
|
|
val X = SingleStatus(SourceOfNZ(x = true))
|
|
|
|
val Y = SingleStatus(SourceOfNZ(y = true))
|
|
|
|
val Z = SingleStatus(SourceOfNZ(iz = true))
|
|
|
|
val AX = SingleStatus(SourceOfNZ(a = true, x = true))
|
|
|
|
val AY = SingleStatus(SourceOfNZ(a = true, y = true))
|
|
|
|
val AZ = SingleStatus(SourceOfNZ(a = true, iz = true))
|
|
|
|
val XY = SingleStatus(SourceOfNZ(x = true, y = true))
|
2018-03-05 18:14:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case class SourceOfNZ(a: Boolean = false, aw: Boolean = false, x: Boolean = false, y: Boolean = false, iz: Boolean = false) {
|
2018-04-02 19:57:53 +00:00
|
|
|
def matches(state: State.Value): Boolean = state match {
|
|
|
|
case State.A => a
|
|
|
|
case State.X => x
|
|
|
|
case State.Y => y
|
|
|
|
case State.IZ => iz
|
|
|
|
case _ => throw new IllegalArgumentException
|
|
|
|
}
|
|
|
|
|
2018-03-06 14:49:28 +00:00
|
|
|
override def toString: String = {
|
2018-03-05 18:14:42 +00:00
|
|
|
val builder = new StringBuilder
|
|
|
|
if (a) builder += 'A'
|
|
|
|
if (aw) builder += 'C'
|
|
|
|
if (x) builder += 'X'
|
|
|
|
if (y) builder += 'Y'
|
|
|
|
if (iz) builder += 'Z'
|
|
|
|
if (builder.isEmpty) "?"
|
|
|
|
else builder.mkString
|
|
|
|
}
|
2019-11-04 13:28:36 +00:00
|
|
|
|
|
|
|
def swapAX: SourceOfNZ = copy(a = x, x = a)
|
|
|
|
def swapAY: SourceOfNZ = copy(a = y, y = a)
|
|
|
|
def swapXY: SourceOfNZ = copy(y = x, x = y)
|
2018-03-05 18:14:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//noinspection RedundantNewCaseClass
|
2018-03-06 14:49:28 +00:00
|
|
|
case class CpuStatus(a: Status[Int] = UnknownStatus,
|
|
|
|
ah: Status[Int] = UnknownStatus,
|
|
|
|
a0: Status[Boolean] = UnknownStatus,
|
|
|
|
a7: Status[Boolean] = UnknownStatus,
|
|
|
|
x: Status[Int] = UnknownStatus,
|
|
|
|
y: Status[Int] = UnknownStatus,
|
|
|
|
iz: Status[Int] = UnknownStatus,
|
2018-08-07 19:36:53 +00:00
|
|
|
r0: Status[Int] = UnknownStatus,
|
|
|
|
r1: Status[Int] = UnknownStatus,
|
|
|
|
r2: Status[Int] = UnknownStatus,
|
|
|
|
r3: Status[Int] = UnknownStatus,
|
2018-03-06 14:49:28 +00:00
|
|
|
src: Status[SourceOfNZ] = UnknownStatus,
|
2018-06-23 21:24:32 +00:00
|
|
|
eqSX: Boolean = false,
|
2018-12-14 21:01:52 +00:00
|
|
|
eqSpA: Boolean = false,
|
|
|
|
eqSpX: Boolean = false,
|
2018-03-06 14:49:28 +00:00
|
|
|
z: Status[Boolean] = UnknownStatus,
|
|
|
|
n: Status[Boolean] = UnknownStatus,
|
|
|
|
c: Status[Boolean] = UnknownStatus,
|
|
|
|
v: Status[Boolean] = UnknownStatus,
|
|
|
|
d: Status[Boolean] = UnknownStatus,
|
|
|
|
m: Status[Boolean] = UnknownStatus,
|
|
|
|
w: Status[Boolean] = UnknownStatus
|
2018-03-05 18:14:42 +00:00
|
|
|
) {
|
2018-12-14 21:01:52 +00:00
|
|
|
def overwriteSp(sp: Boolean): CpuStatus = if (sp && eqSpX) this.copy(eqSpX = false) else this
|
|
|
|
|
2018-03-09 23:07:40 +00:00
|
|
|
// assert(a ne null)
|
|
|
|
// assert(ah ne null)
|
|
|
|
// assert(x ne null)
|
|
|
|
// assert(y ne null)
|
|
|
|
// assert(iz ne null)
|
|
|
|
// assert(z ne null)
|
|
|
|
// assert(n ne null)
|
|
|
|
// assert(v ne null)
|
|
|
|
// assert(c ne null)
|
|
|
|
// assert(d ne null)
|
|
|
|
// assert(m ne null)
|
|
|
|
// assert(w ne null)
|
|
|
|
// assert(a0 ne null)
|
|
|
|
// assert(a7 ne null)
|
|
|
|
// (a, a7) match {
|
|
|
|
// case (SingleStatus(o), SingleStatus(b7)) => if (o.&(0x80).!=(0).!=(b7)) {
|
|
|
|
// println(a)
|
|
|
|
// println(a7)
|
|
|
|
// println(a0)
|
|
|
|
// ???
|
|
|
|
// }
|
|
|
|
// case _ =>
|
|
|
|
// }
|
|
|
|
// (a, a0) match {
|
|
|
|
// case (SingleStatus(o), SingleStatus(b0)) => if (o.&(1).!=(0).!=(b0)) {
|
|
|
|
// println(a)
|
|
|
|
// println(a7)
|
|
|
|
// println(a0)
|
|
|
|
// ???
|
|
|
|
// }
|
|
|
|
// case _ =>
|
|
|
|
// }
|
2018-03-05 18:14:42 +00:00
|
|
|
|
2018-08-07 19:36:53 +00:00
|
|
|
override def toString: String = s"A=$a,B=$ah,X=$x,Y=$y,Z=$iz; Z=$z,N=$n,C=$c,V=$v,D=$d,M=$m,X=$w; R0=$r0,R1=$r1,R2=$r2,R3=$r3; A7=$a7,A0=$a0,NZ:$src" +
|
2018-07-06 20:45:59 +00:00
|
|
|
(if (eqSX) "; S=X"
|
2018-12-14 21:01:52 +00:00
|
|
|
else /*-*/ " ") +
|
|
|
|
(if (eqSpX) "; SP=X"
|
|
|
|
else /*--*/ " ")
|
2018-03-05 18:14:42 +00:00
|
|
|
|
|
|
|
def aw: Status[Int] = (ah, a) match {
|
|
|
|
case (SingleStatus(h), SingleStatus(l)) => SingleStatus(h.&(0xff).<<(8).+(l&0xff))
|
2018-03-06 14:49:28 +00:00
|
|
|
case (UnknownStatus, UnknownStatus) => UnknownStatus
|
|
|
|
case _ => AnyStatus
|
2018-03-05 18:14:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def nz: CpuStatus =
|
2018-03-06 14:49:28 +00:00
|
|
|
this.copy(n = AnyStatus, z = AnyStatus)
|
2018-03-05 18:14:42 +00:00
|
|
|
|
|
|
|
def nz(i: Long): CpuStatus =
|
|
|
|
this.copy(n = SingleStatus((i & 0x80) != 0), z = SingleStatus((i & 0xff) == 0))
|
|
|
|
|
|
|
|
def nzw(i: Long): CpuStatus =
|
|
|
|
this.copy(n = SingleStatus((i & 0x8000) != 0), z = SingleStatus((i & 0xffff) == 0))
|
|
|
|
|
|
|
|
def ~(that: CpuStatus) = new CpuStatus(
|
|
|
|
a = this.a ~ that.a,
|
|
|
|
ah = this.ah ~ that.ah,
|
|
|
|
a7 = this.a7 ~ that.a7,
|
|
|
|
a0 = this.a0 ~ that.a0,
|
|
|
|
x = this.x ~ that.x,
|
|
|
|
y = this.y ~ that.y,
|
|
|
|
iz = this.iz ~ that.iz,
|
|
|
|
src = this.src ~ that.src,
|
2018-06-23 21:24:32 +00:00
|
|
|
eqSX = this.eqSX && that.eqSX,
|
2018-12-14 21:01:52 +00:00
|
|
|
eqSpX = this.eqSpX && that.eqSpX,
|
2018-03-05 18:14:42 +00:00
|
|
|
z = this.z ~ that.z,
|
|
|
|
n = this.n ~ that.n,
|
|
|
|
c = this.c ~ that.c,
|
|
|
|
v = this.v ~ that.v,
|
|
|
|
d = this.d ~ that.d,
|
|
|
|
m = this.m ~ that.m,
|
|
|
|
w = this.w ~ that.w,
|
|
|
|
)
|
|
|
|
|
|
|
|
def hasClear(state: State.Value): Boolean = state match {
|
|
|
|
case State.A => a.contains(0)
|
|
|
|
case State.AH => ah.contains(0)
|
|
|
|
case State.X => x.contains(0)
|
|
|
|
case State.Y => y.contains(0)
|
|
|
|
case State.IZ => iz.contains(0)
|
|
|
|
case State.Z => z.contains(false)
|
|
|
|
case State.N => n.contains(false)
|
|
|
|
case State.C => c.contains(false)
|
|
|
|
case State.V => v.contains(false)
|
|
|
|
case State.D => d.contains(false)
|
|
|
|
case State.M => m.contains(false)
|
|
|
|
case State.W => w.contains(false)
|
|
|
|
case _ => false
|
|
|
|
}
|
|
|
|
|
|
|
|
def hasSet(state: State.Value): Boolean = state match {
|
|
|
|
case State.Z => z.contains(true)
|
|
|
|
case State.N => n.contains(true)
|
|
|
|
case State.C => c.contains(true)
|
|
|
|
case State.V => v.contains(true)
|
|
|
|
case State.D => d.contains(true)
|
|
|
|
case State.M => m.contains(true)
|
|
|
|
case State.W => w.contains(true)
|
|
|
|
case _ => false
|
|
|
|
}
|
2018-08-07 19:36:53 +00:00
|
|
|
|
|
|
|
def reg(i: Int) : Status[Int] = i match {
|
|
|
|
case 0 => r0
|
|
|
|
case 1 => r1
|
|
|
|
case 2 => r2
|
|
|
|
case 3 => r3
|
|
|
|
case _ => AnyStatus
|
|
|
|
}
|
|
|
|
|
|
|
|
def getReg(i: Option[Int]) : Status[Int] = i match {
|
|
|
|
case Some(0) => r0
|
|
|
|
case Some(1) => r1
|
|
|
|
case Some(2) => r2
|
|
|
|
case Some(3) => r3
|
|
|
|
case _ => AnyStatus
|
|
|
|
}
|
|
|
|
|
|
|
|
def getRegHi(i: Option[Int]) : Status[Int] = i match {
|
|
|
|
case Some(0) => r1
|
|
|
|
case Some(1) => r2
|
|
|
|
case Some(2) => r3
|
|
|
|
case _ => AnyStatus
|
|
|
|
}
|
|
|
|
|
|
|
|
def setReg(i: Option[Int], status: Status[Int]): CpuStatus = {
|
|
|
|
i match {
|
|
|
|
case Some(0) => this.copy(r0 = status)
|
|
|
|
case Some(1) => this.copy(r1 = status)
|
|
|
|
case Some(2) => this.copy(r2 = status)
|
|
|
|
case Some(3) => this.copy(r3 = status)
|
2018-12-13 22:18:56 +00:00
|
|
|
case _ => this
|
2018-08-07 19:36:53 +00:00
|
|
|
}
|
|
|
|
}
|
2018-03-05 18:14:42 +00:00
|
|
|
}
|
2018-05-14 00:19:39 +00:00
|
|
|
|
|
|
|
object CpuStatus {
|
|
|
|
val initialStatusStandard = CpuStatus(
|
|
|
|
a = AnyStatus,
|
|
|
|
x = AnyStatus,
|
|
|
|
y = AnyStatus,
|
|
|
|
c = AnyStatus,
|
|
|
|
v = AnyStatus,
|
|
|
|
z = AnyStatus,
|
|
|
|
n = AnyStatus,
|
2019-10-23 09:52:42 +00:00
|
|
|
a0 = AnyStatus,
|
|
|
|
a7 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
d = SingleStatus(false),
|
|
|
|
m = SingleStatus(true),
|
|
|
|
w = SingleStatus(true),
|
2018-08-07 19:36:53 +00:00
|
|
|
iz = SingleStatus(0),
|
|
|
|
r0 = AnyStatus,
|
|
|
|
r1 = AnyStatus,
|
|
|
|
r2 = AnyStatus,
|
|
|
|
r3 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
)
|
|
|
|
val initialStatusCE = CpuStatus(
|
|
|
|
a = AnyStatus,
|
|
|
|
x = AnyStatus,
|
|
|
|
y = AnyStatus,
|
|
|
|
c = AnyStatus,
|
|
|
|
v = AnyStatus,
|
|
|
|
z = AnyStatus,
|
|
|
|
n = AnyStatus,
|
2019-10-23 09:52:42 +00:00
|
|
|
a0 = AnyStatus,
|
|
|
|
a7 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
d = SingleStatus(false),
|
|
|
|
m = SingleStatus(true),
|
|
|
|
w = SingleStatus(true),
|
2018-08-07 19:36:53 +00:00
|
|
|
iz = AnyStatus,
|
|
|
|
r0 = AnyStatus,
|
|
|
|
r1 = AnyStatus,
|
|
|
|
r2 = AnyStatus,
|
|
|
|
r3 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
val initialInterruptStatusStandard = CpuStatus(
|
|
|
|
a = AnyStatus,
|
|
|
|
x = AnyStatus,
|
|
|
|
y = AnyStatus,
|
|
|
|
c = AnyStatus,
|
|
|
|
v = AnyStatus,
|
|
|
|
z = AnyStatus,
|
|
|
|
n = AnyStatus,
|
2019-10-23 09:52:42 +00:00
|
|
|
a0 = AnyStatus,
|
|
|
|
a7 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
d = AnyStatus,
|
|
|
|
m = AnyStatus,
|
|
|
|
w = AnyStatus,
|
2018-08-07 19:36:53 +00:00
|
|
|
iz = SingleStatus(0),
|
|
|
|
r0 = AnyStatus,
|
|
|
|
r1 = AnyStatus,
|
|
|
|
r2 = AnyStatus,
|
|
|
|
r3 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
)
|
|
|
|
val initialInterruptStatusCmos = CpuStatus(
|
|
|
|
a = AnyStatus,
|
|
|
|
x = AnyStatus,
|
|
|
|
y = AnyStatus,
|
|
|
|
c = AnyStatus,
|
|
|
|
v = AnyStatus,
|
|
|
|
z = AnyStatus,
|
|
|
|
n = AnyStatus,
|
2019-10-23 09:52:42 +00:00
|
|
|
a0 = AnyStatus,
|
|
|
|
a7 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
d = SingleStatus(false),
|
|
|
|
m = AnyStatus,
|
|
|
|
w = AnyStatus,
|
2018-08-07 19:36:53 +00:00
|
|
|
iz = SingleStatus(0),
|
|
|
|
r0 = AnyStatus,
|
|
|
|
r1 = AnyStatus,
|
|
|
|
r2 = AnyStatus,
|
|
|
|
r3 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
)
|
|
|
|
val initialInterruptStatusCE = CpuStatus(
|
|
|
|
a = AnyStatus,
|
|
|
|
x = AnyStatus,
|
|
|
|
y = AnyStatus,
|
|
|
|
c = AnyStatus,
|
|
|
|
v = AnyStatus,
|
|
|
|
z = AnyStatus,
|
|
|
|
n = AnyStatus,
|
2019-10-23 09:52:42 +00:00
|
|
|
a0 = AnyStatus,
|
|
|
|
a7 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
d = SingleStatus(false),
|
|
|
|
m = AnyStatus,
|
|
|
|
w = AnyStatus,
|
2018-08-07 19:36:53 +00:00
|
|
|
iz = AnyStatus,
|
|
|
|
r0 = AnyStatus,
|
|
|
|
r1 = AnyStatus,
|
|
|
|
r2 = AnyStatus,
|
|
|
|
r3 = AnyStatus,
|
2018-05-14 00:19:39 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
val emptyStatusStandard = CpuStatus(iz = SingleStatus(0))
|
|
|
|
|
|
|
|
val emptyStatusCE = CpuStatus(iz = AnyStatus)
|
|
|
|
}
|