aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCan2025-02-03 22:11:01 +0100
committerCan2025-02-03 22:11:01 +0100
commit114c376af7556af7f1b2158d5b4185a5f1e369dc (patch)
tree1883c5d07ade17c0c82b0c9f5f492632f78b02ab /src
parent13e41e69f7a10b819f77c2db0b9e5364ea51de2e (diff)
feat: some tests
Diffstat (limited to 'src')
-rw-r--r--src/cpu.effekt22
-rw-r--r--src/main.effekt2
-rw-r--r--src/renderers/js.effekt1
-rw-r--r--src/test.effekt69
4 files changed, 79 insertions, 15 deletions
diff --git a/src/cpu.effekt b/src/cpu.effekt
index c2a929e..bd441fd 100644
--- a/src/cpu.effekt
+++ b/src/cpu.effekt
@@ -17,7 +17,16 @@ CPU Cycle and Effects:
6. Wait for next cycle
*/
-extern io def getNow(): Int = jsWeb "Date.now()"
+extern io def getNow(): Int =
+ js "Date.now()"
+ chez "(current-milliseconds)"
+ llvm """
+ %time = call i64 @time(ptr null)
+ %ms = mul i64 %time, 1000
+ ret i64 %ms
+ """
+ vm "effekt::getNow()"
+
interface CPU {
def initCPU(rom: ByteArray): Unit
def cycleCPU(): Unit
@@ -75,7 +84,6 @@ def makeCPU() {r: Renderer} = {
val key_ = r.getKeyPressed().getOrElse { "P" }
if (key_ != "P") {
key = convertKey(key_)
- r.log("Key pressed: " ++ show(key))
}
last_key_update_time = currentTime
}
@@ -84,8 +92,6 @@ def makeCPU() {r: Renderer} = {
val h = ram.getAddr(pc)
val l = ram.getAddr(pc + 1)
val inst = bitwiseOr(bitwiseShl(h.toInt(), 8), l.toInt())
- r.log("PC: " ++ show(pc))
- r.log("Instruction: " ++ show(inst))
// Decode
val opcode = bitwiseShr(bitwiseAnd(inst, 61440), 12)
@@ -184,11 +190,9 @@ def makeCPU() {r: Renderer} = {
val vx = v.unsafeGet(x).toInt()
val vy = v.unsafeGet(y).toInt()
val sub = vx - vy
- r.log(show(vx) ++ "(" ++ show(x) ++ ") - " ++ show(vy) ++ "(" ++ show(y) ++ ") = " ++ show(sub) ++ "with borrow of " ++ show(if (vx > vy) 1 else 0))
+
v.unsafeSet(x, sub.toByte())
v.unsafeSet(15, (if (vx > vy) 1 else 0).toByte())
- r.log("vx is now " ++ show(v.unsafeGet(x)))
- r.log("vF is now " ++ show(v.unsafeGet(15)))
}
// Set VX = VX SHR 1 and VF = LSB of VX
case 6 => {
@@ -203,11 +207,9 @@ def makeCPU() {r: Renderer} = {
val vx = v.unsafeGet(x).toInt()
val vy = v.unsafeGet(y).toInt()
val sub = vy - vx
- r.log(show(vy) ++ "(" ++ show(y) ++ ") - " ++ show(vx) ++ "(" ++ show(x) ++ ") = " ++ show(sub) ++ "with borrow of " ++ show(if (vy > vx) 1 else 0))
+
v.unsafeSet(x, sub.toByte())
v.unsafeSet(15, (if (vy > vx) 1 else 0).toByte())
- r.log("vx is now " ++ show(v.unsafeGet(x)))
- r.log("vF is now " ++ show(v.unsafeGet(15)))
}
// Set VX = VX SHL 1 and VF = MSB of VX
case 14 => {
diff --git a/src/main.effekt b/src/main.effekt
index befe021..fd9f7c0 100644
--- a/src/main.effekt
+++ b/src/main.effekt
@@ -1,4 +1,4 @@
-module main // must be named same as the file!
+module main
import src/cpu
import src/renderers/js
diff --git a/src/renderers/js.effekt b/src/renderers/js.effekt
index 3292481..f1da8e6 100644
--- a/src/renderers/js.effekt
+++ b/src/renderers/js.effekt
@@ -23,6 +23,7 @@ extern jsWeb """
function log(msg) {
const message = new Date().toLocaleTimeString() + ' - ' + msg + ' \n'
console.log(message);
+ document.getElementById('logs').textContent += message;
}
function romCheck() {
diff --git a/src/test.effekt b/src/test.effekt
index f605d19..7048bab 100644
--- a/src/test.effekt
+++ b/src/test.effekt
@@ -1,10 +1,71 @@
module src/test
import test
-import src/lib
+import src/cpu
+import src/renderer
+import bytearray
+import array
-def main() = mainSuite("lib") {
- test("Hello world") {
- assertEqual("Hello, world!", "Hello, world!")
+// Mock renderer for testing
+def makeMockRenderer() = {
+ var screen: Array[Bool] = allocate(32 *64)
+ var lastKey: String = "P"
+ var beeping: Bool = false
+ new Renderer {
+ def init(run: (ByteArray) => Unit at {io, global}) = ()
+ def clear() = screen = allocate(32 *64)
+ def draw(x: Int, y: Int, color: String) = {
+ screen.get(y).set(x, color == "white")
+ }
+ def fill(color: String) = {
+ screen = allocate(32 *64, color == "white")
+ }
+ def get(x: Int, y: Int): Bool = screen(y)(x)
+ def update(f: () => Unit at {io, global}) = ()
+ def log(msg: String) = ()
+ def getKeyPressed() = Some(lastKey)
+ def beep() = { beeping = true }
+ def stopBeep() = { beeping = false }
}
}
+def main() = mainSuite("CHIP-8") {
+ // CPU Tests
+
+ test("Key conversion") {
+ assertEqual(convertKey("1"), 1)
+ assertEqual(convertKey("2"), 2)
+ assertEqual(convertKey("v"), 15)
+ assertEqual(convertKey("invalid"), -1)
+
+ test("CPU initialization") {
+ val renderer = makeMockRenderer()
+ val cpu = makeCPU() { renderer }
+ val testRom = allocate(10)
+ cpu.initCPU(testRom)
+ // Add assertions here for initial state
+ }
+
+ test("Basic instructions") {
+ val renderer = makeMockRenderer()
+ val cpu = makeCPU() { renderer }
+ val testRom = allocate(4)
+ // Set up a simple instruction in ROM
+ testRom.unsafeSet(0, 96) // 0x60
+ testRom.unsafeSet(1, 66) // 0x42
+ cpu.initCPU(testRom)
+ cpu.cycleCPU()
+
+ }
+ }
+
+ // Renderer Tests
+
+ test("Screen operations") {
+ val renderer = makeMockRenderer()
+ renderer.clear()
+ renderer.draw(0, 0, "white")
+ assert(renderer.get(0, 0))
+ renderer.draw(0, 0, "black")
+ assert(renderer.get(0, 0), false)
+ }
+} \ No newline at end of file