mirror of
https://github.com/KarolS/millfork.git
synced 2024-05-31 18:41:30 +00:00
301 lines
7.4 KiB
Scala
301 lines
7.4 KiB
Scala
package millfork.test
|
|
|
|
import millfork.{Cpu, CpuFamily, OptimizationPresets}
|
|
import millfork.assembly.mos.opt.{AlwaysGoodOptimizations, DangerousOptimizations}
|
|
import millfork.test.emu._
|
|
import org.scalatest.{FunSuite, Matchers}
|
|
|
|
/**
|
|
* @author Karol Stasiak
|
|
*/
|
|
class ArraySuite extends FunSuite with Matchers {
|
|
|
|
test("Array assignment") {
|
|
val src =
|
|
"""
|
|
| array output [3] @$c000
|
|
| array input = [5,6,7]
|
|
| void main () {
|
|
| copyEntry(0)
|
|
| copyEntry(1)
|
|
| copyEntry(2)
|
|
| }
|
|
| void copyEntry(byte index) {
|
|
| output[index] = input[index]
|
|
| }
|
|
""".stripMargin
|
|
val m = EmuSuperOptimizedRun(src)
|
|
m.readByte(0xc000) should equal(5)
|
|
m.readByte(0xc001) should equal(6)
|
|
m.readByte(0xc002) should equal(7)
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(src) { m =>
|
|
m.readByte(0xc000) should equal(5)
|
|
m.readByte(0xc001) should equal(6)
|
|
m.readByte(0xc002) should equal(7)
|
|
}
|
|
|
|
}
|
|
test("Array assignment with offset") {
|
|
val src =
|
|
"""
|
|
| array output [8] @$c000
|
|
| void main () {
|
|
| byte i
|
|
| i = 0
|
|
| while i != 6 {
|
|
| output[i + 2] = i + 1
|
|
| output[i] = output[i]
|
|
| i += 1
|
|
| }
|
|
| }
|
|
""".stripMargin
|
|
EmuUltraBenchmarkRun(src) { m =>
|
|
m.readByte(0xc002) should equal(1)
|
|
m.readByte(0xc007) should equal(6)
|
|
}
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(src) { m =>
|
|
m.readByte(0xc002) should equal(1)
|
|
m.readByte(0xc007) should equal(6)
|
|
}
|
|
}
|
|
|
|
test("Array assignment with offset 1") {
|
|
val m = new EmuRun(Cpu.StrictMos, Nil, DangerousOptimizations.All ++ OptimizationPresets.Good)(
|
|
"""
|
|
| array output [8] @$c000
|
|
| void main () {
|
|
| byte i
|
|
| i = 0
|
|
| while i != 6 {
|
|
| output[i + 2] = i + 1
|
|
| output[i] = output[i]
|
|
| i += 1
|
|
| }
|
|
| }
|
|
""".stripMargin)
|
|
m.readByte(0xc002) should equal(1)
|
|
m.readByte(0xc007) should equal(6)
|
|
}
|
|
|
|
test("Array assignment through a pointer") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| array output [3] @$c000
|
|
| pointer p
|
|
| void main () {
|
|
| p = output.addr
|
|
| byte i
|
|
| byte ignored
|
|
| i = 1
|
|
| word w
|
|
| w = $105
|
|
| p[i]:ignored = w
|
|
| }
|
|
""".stripMargin) { m =>
|
|
m.readByte(0xc001) should equal(1)
|
|
}
|
|
|
|
}
|
|
|
|
test("Array in place math") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| array output [4] @$c000
|
|
| void main () {
|
|
| byte i
|
|
| i = 3
|
|
| output[i] = 3
|
|
| output[i + 1 - 1] *= 4
|
|
| output[3] *= 5
|
|
| }
|
|
""".stripMargin)(_.readByte(0xc003) should equal(60))
|
|
}
|
|
|
|
test("Array simple read") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| byte output @$c000
|
|
| array a[7]
|
|
| void main () {
|
|
| byte i
|
|
| i = 6
|
|
| a[i] = 6
|
|
| output = a[i]
|
|
| }
|
|
""".stripMargin)(_.readByte(0xc000) should equal(6))
|
|
}
|
|
|
|
test("Array simple read 2") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| word output @$c000
|
|
| array a[7]
|
|
| void main () {
|
|
| output = 777
|
|
| byte i
|
|
| i = 6
|
|
| a[i] = 6
|
|
| output = a[i]
|
|
| }
|
|
""".stripMargin){m =>
|
|
m.readByte(0xc000) should equal(6)
|
|
m.readByte(0xc001) should equal(0)
|
|
}
|
|
}
|
|
|
|
test("Pointers") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| byte output
|
|
| pointer a
|
|
| pointer b
|
|
| pointer c
|
|
| void main () {
|
|
| setup()
|
|
| reset()
|
|
| }
|
|
| void setup() {
|
|
| a = output.addr
|
|
| b = output.addr
|
|
| c = output.addr
|
|
| }
|
|
| void reset() {
|
|
| a[0] = 0
|
|
| b[0] = 0
|
|
| c[0] = 0
|
|
| }
|
|
""".stripMargin)(_.readByte(0xc000) should equal(0))
|
|
|
|
}
|
|
|
|
test("Pointer indexing test") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| array output [4] @$c000
|
|
| pointer a
|
|
| byte i
|
|
| void main () {
|
|
| setup()
|
|
| a[i + 1] = 55
|
|
| }
|
|
| void setup() {
|
|
| a = output.addr
|
|
| i = 2
|
|
| }
|
|
""".stripMargin)(_.readByte(0xc003) should equal(55))
|
|
}
|
|
|
|
test("Syntax") {
|
|
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| array a = [1, 2, 3]
|
|
| array b = "text" ascii
|
|
| array c = ["text" ascii, 5]
|
|
| void main () {
|
|
| }
|
|
""".stripMargin){m => ()}
|
|
|
|
}
|
|
|
|
test("Negative subindex") {
|
|
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
|
|
|
| array output [$fff] @$c000
|
|
| void main () {
|
|
| byte i
|
|
| output[$100] = 55
|
|
| i = one()
|
|
| output[1 - i] = 5
|
|
| }
|
|
| noinline byte one() {return 1}
|
|
""".stripMargin) { m =>
|
|
m.dump(0xbf00, 0x200)(println(_))
|
|
m.readByte(0xc100) should equal(55)
|
|
m.readByte(0xc000) should equal(5)
|
|
}
|
|
}
|
|
|
|
test("Word subindex 1") {
|
|
EmuBenchmarkRun(
|
|
"""
|
|
|
|
|
| array output [$fff] @$c000
|
|
| void main () {
|
|
| word i
|
|
| i = big()
|
|
| output[$64] = 55
|
|
| output[i] = 6
|
|
| output[i] = 5
|
|
| }
|
|
| noinline word big() {return $564}
|
|
""".stripMargin) {m =>
|
|
m.readByte(0xc064) should equal(55)
|
|
m.readByte(0xc564) should equal(5)
|
|
}
|
|
|
|
}
|
|
|
|
test("Word subindex 2") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
|
|
|
| array output [$fff] @$c000
|
|
| void main () {
|
|
| word i
|
|
| pointer o
|
|
| o = p()
|
|
| i = big()
|
|
| o[$164] = 55
|
|
| o[i] = 5
|
|
| }
|
|
| noinline word big() {return $564}
|
|
| noinline word p() {return output.addr}
|
|
""".stripMargin) {m =>
|
|
m.readByte(0xc164) should equal(55)
|
|
m.readByte(0xc564) should equal(5)
|
|
}
|
|
|
|
}
|
|
|
|
test("Array filters") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| array x = @word [$1144]
|
|
| byte output @$c000
|
|
| void main () {
|
|
| output = x[0]
|
|
| }
|
|
""".stripMargin) { m =>
|
|
m.readByte(0xc000) should equal(0x44)
|
|
}
|
|
}
|
|
|
|
test("Const arrays") {
|
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
|
|
"""
|
|
| const array square = [0, 1, 4, 9, 16, 25, 36, 49, 64]
|
|
| byte five() = 5
|
|
| byte output0 @$c000
|
|
| byte output1 @$c001
|
|
| void main () {
|
|
| output0 = square[3]
|
|
| output1 = square[five()]
|
|
| }
|
|
""".stripMargin) { m =>
|
|
m.readByte(0xc000) should equal(9)
|
|
m.readByte(0xc001) should equal(25)
|
|
}
|
|
}
|
|
|
|
test("Writing to const arrays should not compile") {
|
|
ShouldNotCompile(
|
|
"""
|
|
| const array a = [0]
|
|
| void main () {
|
|
| a[0] = 5
|
|
| }
|
|
""".stripMargin)
|
|
}
|
|
}
|