mirror of
https://github.com/irmen/ksim65.git
synced 2025-04-22 11:37:45 +00:00
irq+nmi buttons in debug window
This commit is contained in:
parent
bbda51fdda
commit
b89d8bb755
@ -204,8 +204,10 @@ class DebugWindow(val vm: VirtualMachine) : JFrame("debugger"), ActionListener {
|
||||
|
||||
val resetBt = JButton("Reset").also { it.actionCommand = "reset" }
|
||||
val cycleBt = JButton("Step").also { it.actionCommand = "step" }
|
||||
val irqBt = JButton("IRQ").also { it.actionCommand = "irq" }
|
||||
val nmiBt = JButton("NMI").also { it.actionCommand = "nmi" }
|
||||
val quitBt = JButton("Quit").also { it.actionCommand = "quit" }
|
||||
listOf(resetBt, cycleBt, pauseBt, quitBt).forEach {
|
||||
listOf(resetBt, cycleBt, irqBt, nmiBt, pauseBt, quitBt).forEach {
|
||||
it.addActionListener(this)
|
||||
buttonPanel.add(it)
|
||||
}
|
||||
@ -235,6 +237,8 @@ class DebugWindow(val vm: VirtualMachine) : JFrame("debugger"), ActionListener {
|
||||
pauseBt.actionCommand = "pause"
|
||||
pauseBt.text = "Pause"
|
||||
}
|
||||
"irq" -> vm.cpu.irq()
|
||||
"nmi" -> vm.cpu.nmi()
|
||||
"quit" -> {
|
||||
dispatchEvent(WindowEvent(this, WindowEvent.WINDOW_CLOSING))
|
||||
}
|
||||
|
@ -107,7 +107,11 @@ open class Cpu6502(private val stopOnBrk: Boolean = false) : BusComponent() {
|
||||
get() = currentInstruction.mnemonic
|
||||
|
||||
// has an interrupt been requested?
|
||||
protected var pendingInterrupt: Pair<Boolean, BusComponent>? = null
|
||||
protected enum class Interrupt {
|
||||
IRQ,
|
||||
NMI
|
||||
}
|
||||
protected var pendingInterrupt: Interrupt? = null
|
||||
|
||||
// data byte from the instruction (only set when addr.mode is Accumulator, Immediate or Implied)
|
||||
protected var fetchedData: Int = 0
|
||||
@ -334,13 +338,13 @@ open class Cpu6502(private val stopOnBrk: Boolean = false) : BusComponent() {
|
||||
while (instrCycles > 0) clock()
|
||||
}
|
||||
|
||||
fun nmi(source: BusComponent) {
|
||||
pendingInterrupt = Pair(true, source)
|
||||
fun nmi() {
|
||||
pendingInterrupt = Interrupt.NMI
|
||||
}
|
||||
|
||||
fun irq(source: BusComponent) {
|
||||
fun irq() {
|
||||
if (!regP.I)
|
||||
pendingInterrupt = Pair(false, source)
|
||||
pendingInterrupt = Interrupt.IRQ
|
||||
}
|
||||
|
||||
fun logState(): String =
|
||||
@ -1092,19 +1096,17 @@ open class Cpu6502(private val stopOnBrk: Boolean = false) : BusComponent() {
|
||||
|
||||
protected open fun iBrk() {
|
||||
// handle BRK ('software interrupt') or a real hardware IRQ
|
||||
val interrupt = pendingInterrupt
|
||||
val nmi = interrupt?.first == true
|
||||
if (interrupt != null) {
|
||||
if (pendingInterrupt != null) {
|
||||
pushStackAddr(regPC - 1)
|
||||
} else {
|
||||
regPC++
|
||||
pushStackAddr(regPC)
|
||||
}
|
||||
regP.B = interrupt == null
|
||||
regP.B = pendingInterrupt == null
|
||||
pushStack(regP)
|
||||
regP.I = true // interrupts are now disabled
|
||||
// NMOS 6502 doesn't clear the D flag (CMOS 65C02 version does...)
|
||||
regPC = readWord(if (nmi) NMI_vector else IRQ_vector)
|
||||
regPC = readWord(if (pendingInterrupt==Interrupt.NMI) NMI_vector else IRQ_vector)
|
||||
pendingInterrupt = null
|
||||
}
|
||||
|
||||
|
@ -637,15 +637,14 @@ class Cpu65C02(stopOnBrk: Boolean = false) : Cpu6502(stopOnBrk) {
|
||||
|
||||
override fun iBrk() {
|
||||
// handle BRK ('software interrupt') or a real hardware IRQ
|
||||
val interrupt = pendingInterrupt
|
||||
val nmi = interrupt?.first == true
|
||||
if (interrupt != null) {
|
||||
val nmi = pendingInterrupt == Interrupt.NMI
|
||||
if (pendingInterrupt != null) {
|
||||
pushStackAddr(regPC - 1)
|
||||
} else {
|
||||
regPC++
|
||||
pushStackAddr(regPC)
|
||||
}
|
||||
regP.B = interrupt == null
|
||||
regP.B = pendingInterrupt == null
|
||||
pushStack(regP)
|
||||
regP.I = true // interrupts are now disabled
|
||||
regP.D = false // this is different from NMOS 6502
|
||||
|
@ -34,9 +34,9 @@ class Timer(startAddress: Address, endAddress: Address, val cpu: Cpu6502) : MemM
|
||||
counter++
|
||||
if (counter == interval) {
|
||||
if (nmi)
|
||||
cpu.nmi(this)
|
||||
cpu.nmi()
|
||||
else
|
||||
cpu.irq(this)
|
||||
cpu.irq()
|
||||
counter = 0
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
TIMER = $d200
|
||||
MOUSE = $d300
|
||||
KEYBOARD = $d400
|
||||
IRQVEC = $fffe
|
||||
SCREEN_WIDTH=640
|
||||
|
||||
* = $1000
|
||||
@ -13,8 +14,21 @@
|
||||
start
|
||||
sei
|
||||
ldx #$ff
|
||||
txs
|
||||
cli
|
||||
txs ; clear the stack
|
||||
; setup timer irq
|
||||
lda #<irq
|
||||
sta IRQVEC
|
||||
lda #>irq
|
||||
sta IRQVEC+1
|
||||
lda #<1000
|
||||
sta TIMER+1 ; every 1000 clock cycles an irq
|
||||
lda #>1000
|
||||
sta TIMER+2
|
||||
lda #0
|
||||
sta TIMER+3
|
||||
lda #1
|
||||
sta TIMER+0
|
||||
cli ; enable irqs
|
||||
|
||||
; ------- print stuff
|
||||
lda #10
|
||||
@ -127,3 +141,50 @@ done jmp done
|
||||
|
||||
|
||||
character .byte 0
|
||||
|
||||
; ---------- irq routine
|
||||
; this one simply read the RTC and prints it on the bottom of the screen.
|
||||
irq
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
; we don't check for BRK flag because we're lazy
|
||||
lda DISPLAY+0
|
||||
pha
|
||||
lda DISPLAY+1
|
||||
pha
|
||||
ldy #29
|
||||
sty DISPLAY+1
|
||||
ldy #0
|
||||
sty DISPLAY+0
|
||||
- lda _time_msg,y
|
||||
beq +
|
||||
sta DISPLAY+2
|
||||
inc DISPLAY+0
|
||||
iny
|
||||
bne -
|
||||
+ ; read the clock now
|
||||
ldx #0
|
||||
- lda RTC,x
|
||||
clc
|
||||
adc #32
|
||||
sta DISPLAY+2
|
||||
inc DISPLAY+0
|
||||
inx
|
||||
cpx #9
|
||||
bne -
|
||||
|
||||
pla
|
||||
sta DISPLAY+1
|
||||
pla
|
||||
sta DISPLAY+0
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
|
||||
_time_msg .text "The time is: ",0
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user