Interrupts question [message #353905] |
Fri, 06 October 2017 11:45 |
anthonypaulo
Messages: 531 Registered: September 2013
Karma: 0
|
Senior Member |
|
|
I'm struggling to understand how a peripheral card can raise an IRQ/NMI. I know there's a line that can be pulled which the 6502 will detect and process the IRQ, one of the steps being to reset a flag that acks the IRQ, but what does that do? From an implementation standpoint, do the cards float the output to their (output) Interrupt pins and when it's time to issue an interrupt it pulls the line low for a cycle and then float it again? If someone could explain the flow, perhaps even with a simple serial port or mouse interrupt flow, I'd appreciate it.
|
|
|
Re: Interrupts question [message #353907 is a reply to message #353905] |
Fri, 06 October 2017 12:31 |
|
Originally posted by: R.Kiefer.SPAEM
Anthony Ortiz wrote:
> If someone could explain the flow, perhaps even with a simple serial port
> or mouse interrupt flow, I'd appreciate it.
See Jim Sather, "Understanding the Apple IIe", page 4-16
- Ralf
|
|
|
Re: Interrupts question [message #353914 is a reply to message #353907] |
Fri, 06 October 2017 14:03 |
anthonypaulo
Messages: 531 Registered: September 2013
Karma: 0
|
Senior Member |
|
|
I've read it and I'm still confused. For example, "the interrupt is acknowledged and IRQ goes high". Huh? How is it acknowledged? Who acknowledges it? What does that mean? Who pulls IRQ high?
|
|
|
Re: Interrupts question [message #353917 is a reply to message #353914] |
Fri, 06 October 2017 14:33 |
|
Originally posted by: MG
On Friday, October 6, 2017 at 11:03:56 AM UTC-7, Anthony Ortiz wrote:
> I've read it and I'm still confused. For example, "the interrupt is acknowledged and IRQ goes high". Huh? How is it acknowledged? Who acknowledges it? What does that mean? Who pulls IRQ high?
In the case of the 6502, which has no hardware interrupt acknowledge, this means:
The interrupting device may continue to hold IRQ low until it is told not to, or it may hold IRQ for a minimum number of clock cycles to guarantee a response from the CPU (or it may detect the vector pull, etc).
In both cases, servicing the interrupting device serves as acknowledging the interrupt. In the former case, this must include telling the device to de-assert the IRQ line.
In any case, provided nobody else is asserting it, when IRQ is de-asserted it goes high because it has a pull-up resistor.
MG
|
|
|
Re: Interrupts question [message #353919 is a reply to message #353914] |
Fri, 06 October 2017 14:40 |
|
Originally posted by: R.Kiefer.SPAEM
Anthony Ortiz wrote:
> I've read it and I'm still confused. For example, "the interrupt is
> acknowledged and IRQ goes high". Huh? How is it acknowledged? Who
> acknowledges it? What does that mean? Who pulls IRQ high?
Ah, ok. There is a pullup resistor which pulls up the IRQ line, another
the NMI line. Any device which wants to attract attention pulls this
signal to low.
For example: you have several Super Serial Cards in your Apple, means
several 6551. They are configured to generate IRQs when transmitter
buffer is empty and receiver buffer is full. One 6551 has received one
byte: your IRQ service will ask the first 6551 if this is the source of
the interrupt (bit 7 of the status register), if not your IRQ service
will ask the next, ... The first device which is a source of an
interrupt must be serviced. Your IRQ service reads the whole status
register of that 6551 and sees bit 3 is set. The next step is reading
the data from that receiver data register so the IRQ source is
automatically cleared. If there is no more source for an interrupt of
that 6551 bit 7 of the status register is automatically cleared.
The IRQ line is an open drain output, means that several devices can
signal an interrupt condition. After clearing the last IRQ source the
IRQ signal will go high again because of the pullup.
There are a lot of different devices and there a lot of different ways
to clear their IRQ request. The 6551 is easy to understand. Read the
manual :-)
- Ralf
|
|
|
Re: Interrupts question [message #353925 is a reply to message #353905] |
Fri, 06 October 2017 15:50 |
|
Originally posted by: James Davis
On Friday, October 6, 2017 at 8:45:47 AM UTC-7, Anthony Ortiz wrote:
> I'm struggling to understand how a peripheral card can raise an IRQ/NMI. I know there's a line that can be pulled which the 6502 will detect and process the IRQ, one of the steps being to reset a flag that acks the IRQ, but what does that do? From an implementation standpoint, do the cards float the output to their (output) Interrupt pins and when it's time to issue an interrupt it pulls the line low for a cycle and then float it again? If someone could explain the flow, perhaps even with a simple serial port or mouse interrupt flow, I'd appreciate it.
Hi Anthony,
Read: "Apple II Monitors Peeled," "Ch.3: Interrupt Processing." It explains both, what the Old Monitor and the Autostart Monitor do to handle all three types of interrups (IRQ, NMI, Reset). Read it along with assembly listings of the two Monitors.
Also: "Programming the 6502" by Rodney Zaks. It explains how the 6502 handles interrupts. No specific chapter; use its index to look up interrupts, IRQ, NMI, & Reset.
James Davis
|
|
|
Re: Interrupts question [message #353987 is a reply to message #353905] |
Sat, 07 October 2017 22:51 |
|
Originally posted by: Tom Porter
This is guarenteed to work on a mockingboard in slot4
DOS 3.3
.... i just recently figured it out myself, make sure all the
pokes in the basic program are present, i think they 'help fix'
the code below.
If you need prodos, the method is slightly different.
1 PRINT CHR$(4);"BLOAD INT1"
2 PRINT CHR$(4);"BLOAD INT2"
3 POKE 32000,0:POKE 32001,0
4 POKE 30069,255:POKE 30074,64
5 HOME:CALL 30040
6 VTAB 10:PRINT PEEK(32000);" ",PEEK(32001);" ":GOTO 6
INT1
7558- A9 00 LDA #$00
755A- 8D FE 03 STA $03FE
755D- A9 85 LDA #$85
755F- 8D FF 03 STA $03FF
7562- A9 40 LDA #$40
7564- 8D 0B C4 STA $C40B
7567- A9 7F LDA #$7F
7569- 8D 0E C4 STA $C40E
756C- A9 C0 LDA #$C0
756E- 8D 0D C4 STA $C40D
7571- 8D 0E C4 STA $C40E
7574- A9 FF LDA #$FF
7576- 8D 04 C4 STA $C404
7579- A9 40 LDA #$40
757B- 8D 05 C4 STA $C405
757E- 58 CLI
757F- 60 RTS
INT2
8500- A5 45 LDA $45
8502- 48 PHA
8503- 98 TYA
8504- 48 PHA
8505- 8A TXA
8506- 48 PHA
----this is code in middle of interrupts
8507- A9 7f LDA #$7f
8509- 8D 0D C4 STA $C40D
850C- EE 00 7D INC $7D00
850F- D0 03 BNE $8514
8511- EE 01 7D INC $7D01
----
8514- 68 PLA
8515- AA TAX
8516- 68 PLA
8517- A8 TAY
8518- 68 PLA
8519- 40 RTI
-----------DECIMAL BELOW...----------
IDIOT DISASEMBLER V.57
FILE: INT1
30040- A9 00 LDA #0
30042- 8D FE 03 STA 1022
30045- A9 85 LDA #133
30047- 8D FF 03 STA 1023
30050- A9 40 LDA #64
30052- 8D 0B C4 STA 50187
30055- A9 7F LDA #127
30057- 8D 0E C4 STA 50190
30060- A9 C0 LDA #192
30062- 8D 0D C4 STA 50189
30065- 8D 0E C4 STA 50190
30068- A9 FF LDA #255
30070- 8D 04 C4 STA 50180
30073- A9 40 LDA #64
30075- 8D 05 C4 STA 50181
30078- 58 CLI
30079- 60 RTS
IDIOT DISASEMBLER V.57
FILE: INT2
34048- A5 45 LDA 69
34050- 48 PHA
34051- 98 TYA
34052- 48 PHA
34053- 8A TXA
34054- 48 PHA
34055- A9 7f LDA #127
34057- 8D 0D C4 STA 50189
34060- EE 00 7D INC 32000
34063- D0 03 BNE 34068
34065- EE 01 7D INC 32001
34068- 68 PLA
34069- AA TAX
34070- 68 PLA
34071- A8 TAY
34072- 68 PLA
34073- 40 RTI
|
|
|
Re: Interrupts question [message #361112 is a reply to message #353987] |
Fri, 19 January 2018 06:06 |
|
Originally posted by: erangell
I found the following which clarifies why there is an LDA $45 before the RTI
From Apple II Monitors Peeled, page 61, IRQ Interrupt Handling
The handling of an IRQ interrupt is identical in both Monitors. The contents of the A-reg are stored at ACC ($45) for future reference. The processor status (P-reg) pushed onto the stack by the taking of the interrupt is popped into the A-reg, then pushed back onto the stack so that the stack and pointer are not changed. By shifting the A reg left 3 bits, the IRQ routine moves into the sign bit the bit which indicates (in this case by being a zero) that the interrupt is an IRQ interrupt rather than execution of a BRK instruction. The Monitor then executes a Jump Indirect instruction via location $03FE-$03FF to the user provided IRQ Interrupt Handler. Note that on an IRQ interrupt, the X, Y, and S registers are not saved by the Monitor. Also, the interrupt handler has the responsibility of clearing the $04 bit on exit to allow further interrupts.
So your interrupt handler only needs to save X and Y at the beginning (optionally PHP), then restore them at the end, and LDA $45, CLI (or PLP) if you disabled interrupts during your routine, then RTI.
So this is how I would code the interrupt handler:
PHP ; save state of all processor status flags for retrieval before exiting this routine
SEI ; if you want to prevent your interrupt handler from being interrupted
TYA ; save Y and X
PHA
TXA
PHA
check if the interrupt is from your device - if not, goto exit:
disable interrupt generating mechanism on your device while you service the interrupt
service the interrupt
re-enable interrupt generating mechanism on your device
exit:
PLA ; restore X and Y
TAX
PLA
TAY
LDA $45 ; A was automatically saved here by Apple monitor interrupt routine
PLP ; restores original processor status flags, which should have interrupt flag clear
RTI
This should work for non-Prodos operating systems. For Prodos I would use the MLI calls to allocate and deallocate interrupts using the protocols described in Beneath Apple Prodos.
|
|
|
Re: Interrupts question [message #361113 is a reply to message #361112] |
Fri, 19 January 2018 06:34 |
TomCh
Messages: 242 Registered: November 2012
Karma: 0
|
Senior Member |
|
|
On Friday, January 19, 2018 at 11:06:12 AM UTC, eran...@gmail.com wrote:
> I found the following which clarifies why there is an LDA $45 before the RTI
NB.
.. Apple //e ROM saves A at $45 (at $FA40).
.. Enhanced //e ROM does not save A at $45 (instead it's pushed to the stack)
So yes, you need the LDA $45 (on exit) to work with both ROMs.
Also on interrupt, the 6502 pushes P with I=1 (ints disabled). Since the ROM does not clear the I flag before calling your interrupt handler, there's no need to PHP/SEI on entry (nor PLP on exit).
|
|
|