Started implementing stack limit register
This commit is contained in:
@@ -42,7 +42,12 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) {
|
|||||||
} // RTI
|
} // RTI
|
||||||
0x0003 -> trap(0x0Cu) // BPT
|
0x0003 -> trap(0x0Cu) // BPT
|
||||||
0x0004 -> trap(0x10u) // IOT
|
0x0004 -> trap(0x10u) // IOT
|
||||||
0x0005 -> mbus.unibus.reset() // bus reset TODO: bus init
|
0x0005 -> {
|
||||||
|
stack_limit = 0u
|
||||||
|
pirq = 0u
|
||||||
|
core.reset()
|
||||||
|
mbus.unibus.reset()
|
||||||
|
} // bus reset TODO: bus init
|
||||||
0x0006 -> {
|
0x0006 -> {
|
||||||
// TODO: handle suspending the trace trap
|
// TODO: handle suspending the trace trap
|
||||||
pc = stack_pop()
|
pc = stack_pop()
|
||||||
@@ -225,7 +230,7 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) {
|
|||||||
when (opcode shr 6 and 3) {
|
when (opcode shr 6 and 3) {
|
||||||
0 -> { // MARK
|
0 -> { // MARK
|
||||||
val count = opcode and 0x3F
|
val count = opcode and 0x3F
|
||||||
sp = (pc + (2 * count).toUInt()).toUShort()
|
sp = check_sp((pc + (2 * count).toUInt()).toUShort())
|
||||||
pc = registers[5]
|
pc = registers[5]
|
||||||
registers[5] = stack_pop()
|
registers[5] = stack_pop()
|
||||||
} // MARK
|
} // MARK
|
||||||
@@ -712,6 +717,7 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) {
|
|||||||
private val registers = UShortArray(8)
|
private val registers = UShortArray(8)
|
||||||
private val general_registers = Array<UShortArray>(2) { UShortArray(6) }
|
private val general_registers = Array<UShortArray>(2) { UShortArray(6) }
|
||||||
private val shadow_r6 = UShortArray(4) //
|
private val shadow_r6 = UShortArray(4) //
|
||||||
|
private var stack_limit: UShort = 0u
|
||||||
val core = PagingUnit(mbus)
|
val core = PagingUnit(mbus)
|
||||||
|
|
||||||
var runState: RunState = RunState.HALTED
|
var runState: RunState = RunState.HALTED
|
||||||
@@ -1046,7 +1052,7 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) {
|
|||||||
0x3FFF4u -> 0x1170u // system ID
|
0x3FFF4u -> 0x1170u // system ID
|
||||||
0x3FFF6u -> cpu_err
|
0x3FFF6u -> cpu_err
|
||||||
0x3FFFAu -> pirq // PIRQ
|
0x3FFFAu -> pirq // PIRQ
|
||||||
0x3FFFCu -> 0x0u // stack limit
|
0x3FFFCu -> stack_limit // stack limit
|
||||||
0x3FFFEu -> psw
|
0x3FFFEu -> psw
|
||||||
else -> throw BusTimeoutError(addr)
|
else -> throw BusTimeoutError(addr)
|
||||||
}
|
}
|
||||||
@@ -1059,7 +1065,7 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) {
|
|||||||
0x3_FFF0u , 0x3_FFF2u , 0x3_FFF4u, 0x3_FFF8u -> {} // read-only registers
|
0x3_FFF0u , 0x3_FFF2u , 0x3_FFF4u, 0x3_FFF8u -> {} // read-only registers
|
||||||
0x3_FFF6u -> cpu_err = value
|
0x3_FFF6u -> cpu_err = value
|
||||||
0x3_FFFAu -> pirq = value
|
0x3_FFFAu -> pirq = value
|
||||||
0x3_FFFCu -> {} // stack limit
|
0x3_FFFCu -> stack_limit = value and 0xFF00u // stack limit
|
||||||
0x3_FFFEu -> psw = value or (cur_mode.toUShort() shl 14) // writing to PSW can only increase current mode
|
0x3_FFFEu -> psw = value or (cur_mode.toUShort() shl 14) // writing to PSW can only increase current mode
|
||||||
else -> {
|
else -> {
|
||||||
println("Bus error at ${addr.toString(16)}: ${value.toString(16)}")
|
println("Bus error at ${addr.toString(16)}: ${value.toString(16)}")
|
||||||
@@ -1068,6 +1074,22 @@ class CPU(val mbus: MemBus, var tracer: ITracer = NullTracer()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun check_sp(addr: UShort): UShort {
|
||||||
|
if (cur_mode != 0) return addr
|
||||||
|
if (sp < stack_limit + 224u) {
|
||||||
|
// setCPUERR(CPUE_RED)
|
||||||
|
// we can always assume that this is running in kernel mode, as no stack check occurs in exec or user mode
|
||||||
|
sp = 4u
|
||||||
|
throw Trap(0x04)
|
||||||
|
// stack limit red
|
||||||
|
} else if (sp < stack_limit + 256u) {
|
||||||
|
// stack limit yellow
|
||||||
|
// setTRAP(TRAP_YELLOW)
|
||||||
|
// setCPUERR(CPUE_YELLOW)
|
||||||
|
}
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
enum class RunState(val handleInterrupt: Boolean) {
|
enum class RunState(val handleInterrupt: Boolean) {
|
||||||
RUNNING(handleInterrupt = true),
|
RUNNING(handleInterrupt = true),
|
||||||
HALTED(handleInterrupt = false),
|
HALTED(handleInterrupt = false),
|
||||||
|
@@ -267,6 +267,17 @@ class PagingUnit(val pspace: PAddressSpace): VAddressSpace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
enable22bit = false
|
||||||
|
enableUnibusMap = false
|
||||||
|
modeVTabs[0].useDSpace = false
|
||||||
|
modeVTabs[1].useDSpace = false
|
||||||
|
modeVTabs[2].useDSpace = false
|
||||||
|
mmr[3] = 0u
|
||||||
|
updateMode()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private inner class UnibusMap: PAddressSpace {
|
private inner class UnibusMap: PAddressSpace {
|
||||||
// This implements an *18-bit* address space, for the view of unibus peripherals
|
// This implements an *18-bit* address space, for the view of unibus peripherals
|
||||||
|
Reference in New Issue
Block a user