diff --git a/.idea/misc.xml b/.idea/misc.xml
index d737538..5a452ce 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -20,7 +20,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 5ef9a49..4e91771 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -29,7 +29,7 @@ tasks.test {
}
kotlin {
- jvmToolchain(8)
+ jvmToolchain(19)
}
application {
diff --git a/settings.gradle.kts b/settings.gradle.kts
index f38c4ca..a37eb65 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -9,4 +9,4 @@ plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
}
-rootProject.name = "mc-pdp"
\ No newline at end of file
+rootProject.name = "jdp11"
\ No newline at end of file
diff --git a/src/main/kotlin/com/thequux/mcpdp/RT11Loader.kt b/src/main/kotlin/com/thequux/mcpdp/Loader.kt
similarity index 80%
rename from src/main/kotlin/com/thequux/mcpdp/RT11Loader.kt
rename to src/main/kotlin/com/thequux/mcpdp/Loader.kt
index 74e48c0..9889246 100644
--- a/src/main/kotlin/com/thequux/mcpdp/RT11Loader.kt
+++ b/src/main/kotlin/com/thequux/mcpdp/Loader.kt
@@ -4,18 +4,22 @@ import com.thequux.mcpdp.core.CPU
import com.thequux.mcpdp.core.PAddressSpace
import com.thequux.mcpdp.ext.bit.bit
import com.thequux.mcpdp.ext.bit.shl
+import org.slf4j.LoggerFactory
import java.io.File
+import kotlin.math.log
/// Loads an RT-11 object file into memory
fun CPU.loadAbs(infile: File) {
+
+ val logger = LoggerFactory.getLogger("AbsLoader")
+
val core = this.core.modeSpace
val inStream = infile.inputStream()
var buf = ByteArray(6)
- var offset = 0
- var addr: UShort = 0u
- var len: Int = 0
- var cksum: Int = 0
+ var addr: UShort
+ var len: Int
+ var cksum: Int
var pos = 0
@@ -53,20 +57,21 @@ fun CPU.loadAbs(infile: File) {
if (buf.size < len+1) {
buf = ByteArray(len+1)
}
- System.err.println("Reading ${len+1} bytes into ${buf.size}")
inStream.read(buf, 0, len+1)
for (i in 0..len) {
cksum += buf[i]
}
cksum = cksum and 0xFF
- // TODO: validate checksum == 0
- println("Loading 0x${len.toString(16)} bytes at 0x${addr.toString(16)}")
+ if (cksum != 0) {
+ throw Exception("Incorrect checksum: 0x${cksum.toString(16)}")
+ }
+ logger.debug("Loading 0x${len.toString(16)} bytes at 0x${addr.toString(16)}")
if (len == 0) {
// end of file
- println("Tape ended at ${pos+len+7}")
+ logger.debug("Tape ended at ${pos+len+7}")
if (!(addr bit 0)){
this.pc = addr
- println("Ready to run")
+ logger.debug("Ready to run at ${addr.toString(8)}")
}
return
} else {
diff --git a/src/main/kotlin/com/thequux/mcpdp/core/CPU.kt b/src/main/kotlin/com/thequux/mcpdp/core/CPU.kt
index b76e44f..3e351c8 100644
--- a/src/main/kotlin/com/thequux/mcpdp/core/CPU.kt
+++ b/src/main/kotlin/com/thequux/mcpdp/core/CPU.kt
@@ -3,6 +3,8 @@ package com.thequux.mcpdp.core
import com.thequux.mcpdp.ext.bit.*
import com.thequux.mcpdp.peripheral.MemBus
import com.thequux.mcpdp.util.ProgrammerError
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
/// The main CPU
///
@@ -12,6 +14,8 @@ import com.thequux.mcpdp.util.ProgrammerError
/// xxxx: rest
@OptIn(ExperimentalUnsignedTypes::class)
class CPU(val mbus: MemBus) {
+
+ val logger: Logger = LoggerFactory.getLogger(this.javaClass)
private val flagStr: String
get() {
val chars = CharArray(4) { '-' }
@@ -130,7 +134,7 @@ class CPU(val mbus: MemBus) {
val mode = operand shr 3
val reg = operand and 0x7
val increment = if (byte_mode && reg != 7) 1U else 2U
- return when (mode and 0x7) {
+ return 0x80_FFFFu and when (mode and 0x7) {
0 -> reg.toUInt() bis PADDR_REG_BIT
1 -> registers[reg].toUInt()
2 -> {
@@ -227,8 +231,11 @@ class CPU(val mbus: MemBus) {
when (opcode and 0xF000) {
0x0, 0x8000 -> when (opcode and 0xFF00) {
0x0000 -> when (opcode) {
- 0x0000 -> runState = RunState.HALTED
- 0x0001 -> runState = RunState.WAIT_FOR_INTERRUPT
+ 0x0000 -> {
+ if (cur_mode == 0)
+ runState = RunState.HALTED
+ } // HALT
+ 0x0001 -> runState = RunState.WAIT_FOR_INTERRUPT // WAIT
0x0002 -> { // RTI
pc = stack_pop()
psw = stack_pop() // TODO: check privilege on mode; check psw[11]
@@ -777,10 +784,10 @@ class CPU(val mbus: MemBus) {
// TODO: handle PIRQ
for (i in 7 downTo (psw_priority + 1)) {
- if (pirq bit 8+i) {
- trap(0xA0u)
- break
- }
+ if (pirq bit 8+i) {
+ trap(0xA0u)
+ break
+ }
val source = mbus.unibus.checkInterrupt(i)
if (source != null) {
// we might have been waiting for an interrupt
@@ -796,6 +803,11 @@ class CPU(val mbus: MemBus) {
// TODO: handle T bit
} catch (error: MemoryError) {
// TODO: fill in memory manager fields
+ cpu_err = when (error) {
+ is OddAddressError -> cpu_err or 0x40u
+ is NonExistentMemoryError -> cpu_err or 0x20u
+ is BusTimeoutError -> cpu_err or 0x10u
+ }
trap(4u)
} catch (_: InvalidOpcodeException) {
trap(10u)
@@ -820,23 +832,22 @@ class CPU(val mbus: MemBus) {
private inner class Registers: PAddressSpace {
override fun getw(addr: UInt): UShort = when (addr) {
- 0x3FFF0u -> (mbus.size shr 6).toUShort()
- 0x3FFF2u -> 0u // upper size
- 0x3FFF4u -> 0x1170u // system ID
- 0x3FFF6u -> cpu_err
- 0x3FFFAu -> pirq // PIRQ
- 0x3FFFCu -> 0x0u // stack limit
+ 0x3FFF0u -> (mbus.size shr 6).toUShort()
+ 0x3FFF2u -> 0u // upper size
+ 0x3FFF4u -> 0x1170u // system ID
+ 0x3FFF6u -> cpu_err
+ 0x3FFFAu -> pirq // PIRQ
+ 0x3FFFCu -> 0x0u // stack limit
0x3FFFEu -> psw
-
else -> throw BusTimeoutError(addr)
}
override fun setw(addr: UInt, value: UShort) = when (addr) {
- 0x3_FFF0u , 0x3_FFF2u , 0x3_FFF4u, 0x3_FFF8u -> {} // read-only registers
- 0x3_FFF6u -> cpu_err = value
- 0x3_FFFAu -> pirq = value
- 0x3_FFFCu -> {} // stack limit
- 0x3_FFFEu -> psw = value
+ 0x3_FFF0u , 0x3_FFF2u , 0x3_FFF4u, 0x3_FFF8u -> {} // read-only registers
+ 0x3_FFF6u -> cpu_err = value
+ 0x3_FFFAu -> pirq = value
+ 0x3_FFFCu -> {} // stack limit
+ 0x3_FFFEu -> psw = value or (cur_mode.toUShort() shl 14) // writing to PSW can only increase current mode
else -> {
println("Bus error at ${addr.toString(16)}: ${value.toString(16)}")
throw BusTimeoutError(addr)
diff --git a/src/main/kotlin/com/thequux/mcpdp/tools/Link11.kt b/src/main/kotlin/com/thequux/mcpdp/tools/Link11.kt
index 8530687..aa37b3e 100644
--- a/src/main/kotlin/com/thequux/mcpdp/tools/Link11.kt
+++ b/src/main/kotlin/com/thequux/mcpdp/tools/Link11.kt
@@ -2,12 +2,10 @@
package com.thequux.mcpdp.tools
-import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream
import picocli.CommandLine
import picocli.CommandLine.Option
import picocli.CommandLine.Parameters
import java.io.File
-import java.util.Hashtable
import java.util.concurrent.Callable
import java.util.function.Consumer
@@ -17,7 +15,6 @@ class Link11: Callable {
@Parameters()
lateinit var objects: Array
-
@Option(names = ["-o", "--out"], required = true, description = ["Output file"])
lateinit var outFile: File