mirror of
https://github.com/irmen/ksim65.git
synced 2024-11-15 09:05:52 +00:00
cpu irq/nmi now via "pin assert" instead of pending statuses
This commit is contained in:
parent
c327c59c8b
commit
3f86d5185e
@ -92,8 +92,8 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address, val cpu:
|
||||
// timer A is enabled, assume system cycles counting for now
|
||||
timerAactual--
|
||||
if (timerAactual == 0 && timerAinterruptEnabled) {
|
||||
if (number == 1) cpu.irq()
|
||||
else if (number == 2) cpu.nmi()
|
||||
if (number == 1) cpu.irqAsserted = true
|
||||
else if (number == 2) cpu.nmiAsserted = true
|
||||
}
|
||||
if (timerAactual < 0) timerAactual = if (ramBuffer[0x0e].toInt() and 0b00001000 != 0) 0 else timerAset
|
||||
}
|
||||
@ -108,8 +108,8 @@ class Cia(val number: Int, startAddress: Address, endAddress: Address, val cpu:
|
||||
timerBactual--
|
||||
}
|
||||
if (timerBactual == 0 && timerBinterruptEnabled) {
|
||||
if (number == 1) cpu.irq()
|
||||
else if (number == 2) cpu.nmi()
|
||||
if (number == 1) cpu.irqAsserted = true
|
||||
else if (number == 2) cpu.nmiAsserted = true
|
||||
}
|
||||
if (timerBactual < 0) timerBactual = if (regCRB and 0b00001000 != 0) 0 else timerBset
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ class MainC64Window(title: String, chargen: Rom, val ram: MemoryComponent, val c
|
||||
override fun keyPressed(event: KeyEvent) {
|
||||
// '\' is mapped as RESTORE, this causes a NMI on the cpu
|
||||
if (event.keyChar == '\\') {
|
||||
cpu.nmi()
|
||||
cpu.nmiAsserted = true
|
||||
} else {
|
||||
keypressCia.hostKeyPressed(event)
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class VicII(startAddress: Address, endAddress: Address, val cpu: Cpu6502) : MemM
|
||||
interruptStatusRegisterD019 = if (currentRasterLine == rasterIrqLine) {
|
||||
// signal that current raster line is equal to the desired IRQ raster line
|
||||
// schedule an IRQ as well if the raster interrupt is enabled
|
||||
if ((ramBuffer[0x1a].toInt() and 1) != 0) cpu.irq()
|
||||
if ((ramBuffer[0x1a].toInt() and 1) != 0) cpu.irqAsserted = true
|
||||
interruptStatusRegisterD019 or 0b10000001
|
||||
} else interruptStatusRegisterD019 and 0b11111110
|
||||
}
|
||||
|
@ -190,8 +190,8 @@ class DebugWindow(private val vm: IVirtualMachine) : JFrame("Debugger - ksim65 v
|
||||
pauseBt.actionCommand = "pause"
|
||||
pauseBt.text = "Pause"
|
||||
}
|
||||
"irq" -> vm.cpu.irq()
|
||||
"nmi" -> vm.cpu.nmi()
|
||||
"irq" -> vm.cpu.irqAsserted = true
|
||||
"nmi" -> vm.cpu.nmiAsserted = true
|
||||
"quit" -> {
|
||||
dispatchEvent(WindowEvent(this, WindowEvent.WINDOW_CLOSING))
|
||||
}
|
||||
|
@ -92,6 +92,8 @@ open class Cpu6502 : BusComponent() {
|
||||
var regSP: Int = 0
|
||||
var regPC: Address = 0
|
||||
val regP = StatusRegister()
|
||||
var irqAsserted = false
|
||||
var nmiAsserted = false
|
||||
var currentOpcode: Int = 0
|
||||
protected set
|
||||
var currentOpcodeAddress: Address = 0 // the PC can be changed already depending on the addressing mode
|
||||
@ -100,7 +102,7 @@ open class Cpu6502 : BusComponent() {
|
||||
protected set
|
||||
val isLooping: Boolean get() {
|
||||
// jump loop detection
|
||||
return (previousOpcodeAddress == currentOpcodeAddress) && !(pendingNMI || pendingIRQ)
|
||||
return (previousOpcodeAddress == currentOpcodeAddress) && !(nmiAsserted || irqAsserted)
|
||||
}
|
||||
private var previousOpcodeAddress: Address = 0xffff
|
||||
|
||||
@ -115,9 +117,6 @@ open class Cpu6502 : BusComponent() {
|
||||
return State(regA.toShort(), regX.toShort(), regY.toShort(), regSP, status, regPC, totalCycles)
|
||||
}
|
||||
|
||||
protected var pendingIRQ = false
|
||||
protected var pendingNMI = false
|
||||
|
||||
// data byte from the instruction (only set when addr.mode is Accumulator, Immediate or Implied)
|
||||
protected var fetchedData: Int = 0
|
||||
|
||||
@ -262,7 +261,7 @@ open class Cpu6502 : BusComponent() {
|
||||
*/
|
||||
override fun clock() {
|
||||
if (instrCycles == 0) {
|
||||
if(pendingNMI || (pendingIRQ && !regP.I)) {
|
||||
if(nmiAsserted || (irqAsserted && !regP.I)) {
|
||||
handleInterrupt()
|
||||
return
|
||||
}
|
||||
@ -329,14 +328,6 @@ open class Cpu6502 : BusComponent() {
|
||||
instrCycles = 0
|
||||
}
|
||||
|
||||
fun nmi() {
|
||||
pendingNMI = true
|
||||
}
|
||||
|
||||
fun irq() {
|
||||
pendingIRQ = true
|
||||
}
|
||||
|
||||
protected fun getFetched() =
|
||||
if (currentInstruction.mode == AddrMode.Imm || currentInstruction.mode == AddrMode.Acc || currentInstruction.mode == AddrMode.Imp) fetchedData
|
||||
else read(fetchedAddress)
|
||||
@ -1079,7 +1070,7 @@ open class Cpu6502 : BusComponent() {
|
||||
protected open fun iBrk() {
|
||||
// handle BRK ('software interrupt')
|
||||
regPC++
|
||||
if(pendingNMI)
|
||||
if(nmiAsserted)
|
||||
return // if an NMI occurs during BRK, the BRK won't get executed on 6502 (65C02 fixes this)
|
||||
pushStackAddr(regPC)
|
||||
regP.B = true
|
||||
@ -1098,12 +1089,14 @@ open class Cpu6502 : BusComponent() {
|
||||
regP.I = true // interrupts are now disabled
|
||||
// NMOS 6502 doesn't clear the D flag (CMOS 65C02 version does...)
|
||||
|
||||
if(pendingNMI) {
|
||||
// jump to the appropriate irq vector and clear the assertion status of the irq
|
||||
// (hmm... should the cpu do that? or is this the peripheral's job?)
|
||||
if(nmiAsserted) {
|
||||
regPC = readWord(NMI_vector)
|
||||
pendingNMI = false
|
||||
nmiAsserted = false
|
||||
} else {
|
||||
regPC = readWord(IRQ_vector)
|
||||
pendingIRQ = false
|
||||
irqAsserted = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,14 +23,14 @@ class Cpu65C02 : Cpu6502() {
|
||||
when (waiting) {
|
||||
Wait.Normal -> super.clock()
|
||||
Wait.Waiting -> {
|
||||
if (pendingNMI || pendingIRQ) {
|
||||
if (nmiAsserted || irqAsserted) {
|
||||
// continue execution after hardware interrupt
|
||||
waiting = Wait.Normal
|
||||
instrCycles = 1
|
||||
}
|
||||
}
|
||||
Wait.Stopped -> {
|
||||
if (pendingNMI || pendingIRQ) {
|
||||
if (nmiAsserted || irqAsserted) {
|
||||
// jump to reset vector after hardware interrupt
|
||||
regPC = readWord(RESET_vector)
|
||||
}
|
||||
|
@ -33,8 +33,8 @@ class Timer(startAddress: Address, endAddress: Address, val cpu: Cpu6502) : MemM
|
||||
if (enabled && interval > 0) {
|
||||
counter++
|
||||
if (counter == interval) {
|
||||
if (nmi) cpu.nmi()
|
||||
else cpu.irq()
|
||||
if (nmi) cpu.nmiAsserted = true
|
||||
else cpu.irqAsserted = true
|
||||
counter = 0
|
||||
}
|
||||
}
|
||||
|
@ -96,19 +96,19 @@ class Test6502Klaus2m5Functional {
|
||||
1 -> {
|
||||
// println("IRQ at pc ${hexW(cpu.regPC)}")
|
||||
lastIRQpc = cpu.regPC
|
||||
cpu.irq()
|
||||
cpu.irqAsserted = true
|
||||
}
|
||||
2 -> {
|
||||
// println("NMI at pc ${hexW(cpu.regPC)}")
|
||||
lastNMIpc = cpu.regPC
|
||||
cpu.nmi()
|
||||
cpu.nmiAsserted = true
|
||||
}
|
||||
3 -> {
|
||||
// println("IRQ+NMI at pc ${hexW(cpu.regPC)}")
|
||||
lastIRQpc = cpu.regPC
|
||||
lastNMIpc = cpu.regPC
|
||||
cpu.nmi()
|
||||
cpu.irq()
|
||||
cpu.nmiAsserted = true
|
||||
cpu.irqAsserted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,7 +154,7 @@ class Test6502Klaus2m5Functional {
|
||||
bus.add(ram)
|
||||
cpu.reset()
|
||||
cpu.regPC = 0x0200
|
||||
cpu.breakpointForBRK = { cpu, address ->
|
||||
cpu.breakpointForBRK = { _, address ->
|
||||
if(address==0x024b) { // test end address
|
||||
val error=bus.read(0x000b) // the 'ERROR' variable is stored here
|
||||
if(error==0.toShort())
|
||||
@ -189,7 +189,7 @@ class Test6502Klaus2m5Functional {
|
||||
bus.add(ram)
|
||||
cpu.reset()
|
||||
cpu.regPC = 0x0200
|
||||
cpu.breakpointForBRK = { cpu, address ->
|
||||
cpu.breakpointForBRK = { _, address ->
|
||||
if(address==0x024b) { // test end address
|
||||
val error=bus.read(0x000b) // the 'ERROR' variable is stored here
|
||||
if(error==0.toShort())
|
||||
|
Loading…
Reference in New Issue
Block a user