| |
TWW
Registered: Jul 2009 Posts: 545 |
Regarding Interrupts
I have some hypothetical questions regarding IRQ interrupts;
#1: If an IRQ event is pulsed (IRQ line pulled low) for a duration of 3-4 cycles and this happens during a 6-7 cycle instruction, can the IRQ be missed by the MPU?
#2: Are the IRQ-flags handled by the MPU or the chips in question (CIA#1/VICII) (I suspect the VIC/CIA)?
#3: If the answer to #1 is yes & #2 is CIA/VIC, would a "missed IRQ" still be flagged?
#4: If an IRQ remains unacknowledged will the latent IRQ event retrigger a interrupt on the CPU after an RTI?
#4.5 I have tested #4 and found it to re-trigger after 6 cycles. Can someone confirm and why 6 cycles?
#5: The interrupt initialization takes 7 cycles wheras the 2 first cycles are described as "internal functions" in a 6502 diagram I saw. What exactly is going on during these 2 clock cycles?
#6: If you ack CIA#1 with a LDA $dc0d, this operation takes 4 cycles. In whihc cycle does the flag(s) actually clear?
#7: Same as #6 just with LDA #$ff, STA $d019.
If there is some documentation around this I would be gratefull for some pointers. And yes I know some of these things could probably be tested and figgured out but hey what's a forum for^^ |
|
| |
Graham Account closed
Registered: Dec 2002 Posts: 990 |
Quoting TWWI have some hypothetical questions regarding IRQ interrupts;
#1: If an IRQ event is pulsed (IRQ line pulled low) for a duration of 3-4 cycles and this happens during a 6-7 cycle instruction, can the IRQ be missed by the MPU?
No, VIC/CIA will have their IRQ flags set until the CPU acknowledges them.
Quote:#2: Are the IRQ-flags handled by the MPU or the chips in question (CIA#1/VICII) (I suspect the VIC/CIA)?
VIC/CIA, then logically OR'ed into the CPU.
Quote:#3: If the answer to #1 is yes & #2 is CIA/VIC, would a "missed IRQ" still be flagged?
There is no "missed IRQs", since the CPU has to acknowledge IRQs.
Quote:#4: If an IRQ remains unacknowledged will the latent IRQ event retrigger a interrupt on the CPU after an RTI?
Yes.
Quote:#4.5 I have tested #4 and found it to re-trigger after 6 cycles. Can someone confirm and why 6 cycles?
RTI = 6 cycles.
Quote:#5: The interrupt initialization takes 7 cycles wheras the 2 first cycles are described as "internal functions" in a 6502 diagram I saw. What exactly is going on during these 2 clock cycles?
Probably fetching the next opcode + discarding the opcode and feed a BRK-like internal instruction.
Quote:#6: If you ack CIA#1 with a LDA $dc0d, this operation takes 4 cycles. In whihc cycle does the flag(s) actually clear?
The last one ofcourse. The previous cycles are needed to fetch the 3 bytes of the opcode itself.
Quote:#7: Same as #6 just with LDA #$ff, STA $d019.
same.
|
| |
Fresh
Registered: Jan 2005 Posts: 101 |
#1 IRQ lines are usually kept down until MPU ack them. So they usually last more then 3/4 cycles. I've not read anything about that but to me it makes sense that MPU loses such an IRQ as I think the line is not buffered and it is read only in specific cycles. Problem is you can't create such an IRQ with CIA or VIC.
#2 IRQ flags are handled by peripherals. MPU can only mask (don't care) the IRQ line but if something generates an IRQ while IRQ is masked out, the mpu will serve it as soon as you unmask it.
#3 Can't answer: IMHO VIC & CIA can't generate such a pulse-like IRQ.
#4 Read answer #2
#4.5 I guess it depends on RTI duration
#5
1 PC R fetch opcode, increment PC
2 PC R read next instruction byte (and throw it away), increment PC
3 $0100,S W push PCH on stack (with B flag zero), decrement S
4 $0100,S W push PCL on stack, decrement S
5 $0100,S W push P on stack, decrement S
6 $FFFE R fetch PCL
7 $FFFF R fetch PCH
Source: http://codebase64.org/doku.php?id=base:6510_instruction_timing
#6 the last cycle read the value so I *think* it should clear instantly the flag
#7 same as #6, write happens on fourth cycle
|
| |
TWW
Registered: Jul 2009 Posts: 545 |
Very nice. Thanx both of you.
Regarding the IRQ pulse stuff I read this somewhere(?) regarding IRQs triggering on low signal instead of high to low state (like the NMI). The theory was if the IRQ isn't kept low long enough for the current Instruction to complete executing the MPU would miss it.
However based on both your statements has to be wrong since the CIA/VIC (N)OR's it's IRQ flags onto the IRQ line.
How would this work regarding an external event from the expansionport f.ex. (If you push the freeze button really fast :-D)? |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Should you have the fastest finger of the world and make a pulse of... say... 3 cycles, you may definetely miss the IRQ: afaik the line is checked during last cycle of each instruction so, with the longest of them (6/7 cycles), if the pulse fall just 1-2 cycles after decoding, it will be too late for that instruction and it will end too soon for the next one. Imho It shouldn't be catched. |
| |
daison
Registered: May 2005 Posts: 90 |
Quote: Should you have the fastest finger of the world and make a pulse of... say... 3 cycles, you may definetely miss the IRQ: afaik the line is checked during last cycle of each instruction so, with the longest of them (6/7 cycles), if the pulse fall just 1-2 cycles after decoding, it will be too late for that instruction and it will end too soon for the next one. Imho It shouldn't be catched.
The ladies would love you instantly though =P |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Guess it's a bit too fast even for them; and then there won't be any fun having her reaching climax in less than a second. |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
Quote: Should you have the fastest finger of the world and make a pulse of... say... 3 cycles, you may definetely miss the IRQ: afaik the line is checked during last cycle of each instruction so, with the longest of them (6/7 cycles), if the pulse fall just 1-2 cycles after decoding, it will be too late for that instruction and it will end too soon for the next one. Imho It shouldn't be catched.
I guess this could be verified by acking the interrupt just when it is about to happen.
1. Start a timer that will trigger an IRQ.
2. wait using nops until around the time the IRQ should trigger.
3. perform an ack of the timer IRQ such that the IRQ is about to happen during the instruction doing the ACK.
4. profit!
Here you can experiment with different kinds of acks, e.g Read or RMW, to get the ack to happen at different parts of the instruction execution.
If it is adapted to using VIC-II interrupts a Store instruction can be used to ack. |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
This is just a (very!!) ugly code I've made up in a few minutes, I've tested it on Winvice 2.2. It would make sense to try it on a real machine.
Anyway, it looks like it's not possible to avoid an IRQ.
IRQ not fired: short white line
IRQ fired: long coloured (possibly white) line
rastline = $20 ;
*=$0801
word eoprg
word 2010
byte $9E,[intro]d,":",$8f,$20,"IRQ TEST"
byte 0
eoprg
word 0
intro
sei
jsr initIRQ
cli
jmp *
fstirq ; Line $20
pha
txa
pha
tya
pha
dec $fffd
inc $fffd
nop
nop
lsr $d019
inc $d012
lda #<secirq
sta $fffe
cli
nop
nop
nop
nop
nop
nop
brk
secirq ; Line $21
lsr $d019
lda #<thdirq
sta $fffe
dec $fffd
dec $fffd
inc $fffd
dec $fffd
inc $fffd
dec $fffd
lda #$21
eor $d012
beq synced ;+3
synced ; Synced - line $22
lda #$23 ; 2 -5
sta $d012 ; 4 -9
cli ; 2 -11
ldx #$00 ; 2 -13
sta $fffd ; 4 -17
dec $fffd ; 6 -23
inc $fffd ; 6 -29
inc $fffd ; 6 -35
dec $fffd ; 6 -41
inc $fffd ; 6 -47
dec $fffd ; 6 -53
; Choose how many cycle you need to wait by commenting/uncommenting (4-12)
; - ww IRQ - When?
;inc $ff ;
;inc $f500,x ; - 12 Yes - Before DEC
;sta $fffd ;
;inc $f500,x ; - 11 Yes - After DEC
;sta $fffd ;
;inc $f500 ; - 10 Yes - After DEC
;sta $fffd ;
;inc $f5 ; - 9 Yes - After DEC
;sta $fffd ;
;sta $fffd ; - 8 Yes - After DEC
;inc $f500,x ; - 7 Yes - After DEC
;inc $fffd ; - 6 Yes - After DEC
;inc $ff ; - 5 No
sta $fffd ; - 4 No
dec $d019,x
inc $fffd
inc $fffd
inc $d020
dec $d020
lsr $d019
end
pla
pla
pla
lda #rastline
sta $d012
lsr $d019
lda #<fstirq
sta $fffe
pla
tay
pla
tax
pla
rti
thdirq
tsx
inx
inx
lda $0100,x
sta $fe
sta $d020
pla
pla
pla
lda #$00
sta $d020
jmp end
initIRQ
sei
lda #$35
sta $01
lda #$7f
sta $dc0d
sta $dd0d
lda $dc0d
lda $dd0d
lda #$00
sta $d020
sta $d011
lda #rastline
sta $d012
lda #<fstirq
sta $fffe
lda #>fstirq
sta $ffff
lda #$01
sta $d01a
lsr $d019
rts
|
| |
Graham Account closed
Registered: Dec 2002 Posts: 990 |
On a flat C128 I get a short (6 cycles) white line.
EDIT: On C64 too. |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Sorry Graham, I didn't say that there are some line to comment/uncomment inside the code to do a real test.
The code as is doesn't interrupt because IRQ happens after DEC.
Look inside the code, instead of 4 cycles uncomment 9 cycles.
Anyway I think that CIA IRQ can give better results as acknowledge may be done before last instruction cycle (it only needs a read). |
| |
Fresh
Registered: Jan 2005 Posts: 101 |
I've written some more (a bit tidier) code to test IRQ on CIA.
It works by using the timer in one shot mode and trying to create interrupts in different positions "inside" an ASL $DC0D,x instruction.
The program prints 8 "*" or " " on the first row of the screen:
- "*" means an IRQ has been fired (after the ASL)
- " " means no IRQ has been fired
On winvice I get four *: this clearly means that you can't suppress interrupts.
If you try this on a real machine and get a different result, please post!
(sys 4096)
*=$1000
ldy #$01
loop
sei
lda #<irq
sta $0314
lda #>irq
sta $0315
lda #$7e
sta $dc0d
lda #$7f
sta $dd0d
lda $dc0d
lda $dd0d
lda #$00
sta $dc0e
ldx #$00
stx $dc0d
cli
sty $dc04
stx $dc05
lda #$09
sta $dc0e
sta $ff
asl $dc0d,x
lda #$20
Exit
sta $03FF,y
iny
cpy #$09
bne loop
lda #$31
sta $0314
lda #$ea
sta $0315
jsr $fda3
rts
irq
tsx
txa
clc
adc #$06
tax
txs
lda #$2A
jmp Exit
|
| |
Graham Account closed
Registered: Dec 2002 Posts: 990 |
Doesn't seem to work as supposed. No star.
|
| |
Fresh
Registered: Jan 2005 Posts: 101 |
Well, it looks like CIA irq needs to be revised.
No stars is what I was expecting: it means that the fourth cycle of ASL DC0D,x acks the interrupt and MPU doesn't get aware of the IRQ. Firing the IRQ in cycle 1,2 or 3 of ASL DC0D,x should indeed create a pulse like IRQ.
Edit: No stars with Hox64 with CIA 6526 (Not 6526A) |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Interesting. Different results on VICE and the real thing. I wanted to double check the theory around an unack'ed IRQ retriggers and put together the folowing code (raster compare IRQ initialized with $d012 to #00 and $d011 to #$0b and jmp * as async. code):
irq1:
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff // 44 cycles
dec $d020 // 6 cycles
rti // 6 cycles
No pushing or pulling since regs remain untouched.
Now this results in "stable" colour bars all over the screen (as one would expect). This gives a total of 56 cycles spendt and with 7 cycles for the MPU to trigger the next IRQ this fits beutifully on a PAL setup.
However if remove a cycle by replacing a bit $ffff to a bit $ff i get this:
So what's so strange about this?
If you can count the number of 1 cycle too short lines across it adds up to 48... why 48 , shoudn't it be 63? |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
There are some tests around this area here: http://vice-emu.svn.sourceforge.net/viewvc/vice-emu/testprogs/i..
I think emulation was improved in this respect after 2.2.
Posting binary versions of your test would be helpful.
|
| |
TWW
Registered: Jul 2009 Posts: 545 |
Here is the complete code for the straight lines:
sei
lda #$7f
sta $dc0d
sta $dd0d
lda $dc0d
lda $dd0d
lda #$01
sta $d01a
lda #$00
sta $d012
lda #$0b // Turn off screen
sta $d011
lda #$35
sta $01
lda #<irq
sta $fffe
lda #>irq
sta $ffff
cli
jmp *
irq1:
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
dec $d020
rti
And here it is for the messed up lines :)
sei
lda #$7f
sta $dc0d
sta $dd0d
lda $dc0d
lda $dd0d
lda #$01
sta $d01a
lda #$00
sta $d012
lda #$0b // Turn off screen
sta $d011
lda #$35
sta $01
lda #<irq
sta $fffe
lda #>irq
sta $ffff
cli
jmp *
irq1:
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ffff
bit $ff
dec $d020
rti
You can put it at $1000. Should be allowed to attach "small" binaries to the forums. would make things more easy^^ If you have problems compiling this, drop me a line (tww@[nofuckingspam]creators.no). |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
I've checked your screen shot. You are drawing the wrong conclusions.
Start on a line where the split is visible.
Count the number of lines until the next line with the split in the same horizontal spot.
This should be 63.
|
| |
TWW
Registered: Jul 2009 Posts: 545 |
Oh I agree to that fact.
I was only thinking since I removed one cycle from the IRQ code the collor bar should be shortened by 1 cycle and thus displaying 63 breaks. Now 48 is shown and I am curious where the 15 remaining splitts are and why (if this is correct) is the collor bar shortened with more then 1 cycle.
Is it the same on the real thang or (as usual) have i totally missed something? |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
@TWW: Do you have the "debug" borders option turned on? If not, turn it on. I guess the 48 columns you see are the 40 screen columns + 4 columns border on each side. There is a huge area of the border which is not visible on a standard C64 screen and which is normally also hidden in VICE and other emulators. So, as I said, turn the debug borders option on to see the rest of the border. |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
Exactly. All 63 cycles aren't in the visible area of a normal monitor. All 63 cycles aren't even in the output signal. |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Note to my self: I'm an idiot!
cheers I got it now thanx fellas. This is what a forum is all about! |
| |
iAN CooG
Registered: May 2002 Posts: 3195 |
Quote: Note to my self: I'm an idiot!
cheers I got it now thanx fellas. This is what a forum is all about!
Yeah, this is what this forum is about: letting someone to understand and admit he's an idiot!!11
;D |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
Back to the original issue:
I've done a slightly different test program...
http://vice-emu.svn.sourceforge.net/viewvc/vice-emu/testprogs/i..
It tests what happens if the IRQ is ACKed in cycle 2 of an LDA #<imm>, in cycle 3 of an ORA <abs> and cycle 2 of an LDY <abs>.
The results are indeed interesting. |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
@TLR: Would you mind summarizing what you found, in case it does not require an extremely complex explanation? :) I executed that program but since it was not obvious what the chars on the screen meant I didn't bother further. |
| |
Devia
Registered: Oct 2004 Posts: 401 |
maybe he didn't quite understand the numbers himself, thus the result was interresting ;-)
|
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
Well, I didn't necessarily mean to ask for a deeper explanation of *why* the computer/CPU behaves like it does, but rather an explanation of *what* the program says that the computer does. I hope TLR at least knows what his program is doing. :)
For example, in VICE (dunno if VICE is even relevant here) the output looks like this:
CIA-INT / TLR
DC0C: A9 XX 60
--BBBb------------------
AACC---IIIKK------------
DC0B: 0D A9 XX 60
--BBBBb-----------------
AAEEEE--KKKKMM----------
DC0C: AC XX A9 09 28 60
--BBBb------------------
AAEEE--HHMMMMMOO--------
Anyone? :) I understand that the hex numbers are various opcodes, but.. then what? :) |
| |
assiduous Account closed
Registered: Jun 2007 Posts: 343 |
the output from Vice looks wrong,the output from the old CIA 6526 looks like this:
CIA-INT / TLR
DC0C: A9 XX 60
--BBBb------------------
AACC--IIIIKK------------
DC0B: 0D A9 XX 60
--BBBBb-----------------
AAEEEE-KKKKKMM----------
DC0C: AC XX A9 09 28 60
--BBBb------------------
AA----HHHMMMMMOO-------- (if there`s no timer B hardware fault)
or like this:
CIA-INT / TLR
DC0C: A9 XX 60
--BBBb------------------
AACC---IIIKK------------
DC0B: 0D A9 XX 60
--BBBBb-----------------
AAEEEE--KKKKMM----------
DC0C: AC XX A9 09 28 60
--BBBb------------------
AA-----HHMMMMMOO-------- (with the timer B hardware fault in some chips)
Hoxs prints correct values for any selected setup. |
| |
tlr
Registered: Sep 2003 Posts: 1790 |
Quote: Well, I didn't necessarily mean to ask for a deeper explanation of *why* the computer/CPU behaves like it does, but rather an explanation of *what* the program says that the computer does. I hope TLR at least knows what his program is doing. :)
For example, in VICE (dunno if VICE is even relevant here) the output looks like this:
CIA-INT / TLR
DC0C: A9 XX 60
--BBBb------------------
AACC---IIIKK------------
DC0B: 0D A9 XX 60
--BBBBb-----------------
AAEEEE--KKKKMM----------
DC0C: AC XX A9 09 28 60
--BBBb------------------
AAEEE--HHMMMMMOO--------
Anyone? :) I understand that the hex numbers are various opcodes, but.. then what? :)
It works like this:
- start timer
- jsr $dc0b or $dc0c depending on test.
- show contents of $dc0d at the time of ack and if an IRQ occured.
The test is done for timer values of 0-23 (timer B used).
The top line of each test shows the contents of $dc0d.
(B=$82, b=$02, -=$00)
The bottom line shows the number of cycles since starting the test until an IRQ occured. (- means no IRQ)
Test 1: Ack in second cycle of 2 cycle imm instr.
DC0C A9 XX LDA #$xx
DC0E 60 RTS
Test 2: Ack in third cycle of 4 cycle abs instr.
DC0B 0D A9 XX ORA $xxA9 <-- memory prefilled to do ORA #$xx (mostly)
DC0E 60 RTS
Test 3: Ack in second cycle of 4 cycle instr.
DC0C AC XX A9 LDY $A9xx <-- memory prefilled to do LDY #$xx
DC0F 08 PHP <-- this can also be ORA #$28 if the timer hasn't expired yet.
DC10 28 PLP
DC11 60 RTS
No "EEE" in the last test seems to signify that there is a location where the interrupt never occurs.
Hoxs64 indeed does this 100% correctly. Nicely done!
|
| |
Graham Account closed
Registered: Dec 2002 Posts: 990 |
Should be mentioned that there are 2 different CIAs and Hoxs emulates a different one than Vice.
|
| |
Rubi Account closed
Registered: Apr 2002 Posts: 48 |
Quote: Should be mentioned that there are 2 different CIAs and Hoxs emulates a different one than Vice.
But both emulators can switch between 6526 and 6526A in their latest versions (x64sc in VICE). |