6522 VIA emulation: IFR write vs. timer interrupt

want to talk about MESS/model b/beebem/b-em/electrem/elkulator? do it here!
Post Reply
User avatar
scarybeasts
Posts: 141
Joined: Tue Feb 06, 2018 7:44 am
Contact:

6522 VIA emulation: IFR write vs. timer interrupt

Post by scarybeasts » Mon Dec 31, 2018 8:02 am

Hi,

Test case: VIA.I2 in the attached SSD.
This test case clears the timer interrupt in the IFR register on the same VIA cycle that fires the timer interrupt. As usual, the emulators disagree. jsbeeb and beebem (an unusual combination of agreement) think that the timer interrupt is canceled. The rest fire the interrupt.

(beebem doesn't give stable results, very strange, unclear if it's something weird with beebem or my test case).

Anyone mind running the test case a few times on a real beeb? The last two numbers are the test results. Likely results are 1, 192 if the interrupt fires and the IFR flag remains raised; 0, 0 if no interrupt and no flag.


Cheers
Chris
Attachments
tests.ssd
(100 KiB) Downloaded 9 times

User avatar
BigEd
Posts: 2567
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: 6522 VIA emulation: IFR write vs. timer interrupt

Post by BigEd » Mon Dec 31, 2018 8:14 am

(If you can post the plain source I can readily paste it into a Beeb.)

User avatar
richardtoohey
Posts: 3713
Joined: Thu Dec 29, 2011 5:13 am
Location: Tauranga, New Zealand
Contact:

Re: 6522 VIA emulation: IFR write vs. timer interrupt

Post by richardtoohey » Mon Dec 31, 2018 8:20 am

Code: Select all

   10 REM RESULTS FROM DEC 2018
   20 PRINT "VIA TEST: DOES TIMER INTERRUPT FIRE IF IFR CLEARED AT SAME TIME?"
   30 DIM IRQ% 100
   40 DIM MC% 256
   50 DIM R% 16
   60 DIM BAK% 3
   70 P% = IRQ%
   80 [
   90 OPT 3
  100 INC R%
  110 RTI
  120 ]
  130 P% = MC%
  140 [
  150 OPT 3
  160 SEI
  170 LDA #&00
  180 STA R%
  190 LDA &0204
  200 STA BAK%
  210 LDA &0205
  220 STA BAK%+1
  230 LDA &FE4E
  240 STA BAK%+2
  250 LDA #(IRQ% MOD 256)
  260 STA &0204
  270 LDA #(IRQ% DIV 256)
  280 STA &0205
  290 LDA #&7F
  300 STA &FE6E
  310 STA &FE4E
  320 LDA #&C0
  330 STA &FE6E
  340 LDA #&00
  350 STA &FE6B
  360 LDA #&03
  370 STA &FE64
  380 LDA #&00
  390 LDX #&7F
  400 STA &FE65
  410 NOP
  420 NOP
  430 STX &FE6D
  440 LDA &FE6D
  450 STA R%+1
  460 CLI
  470 SEI
  480 LDA BAK%
  490 STA &0204
  500 LDA BAK%+1
  510 STA &0205
  520 LDA BAK%+2
  530 STA &FE4E
  540 LDA #&7F
  550 STA &FE6E
  560 CLI
  570 RTS
  580 ]
  590 PRINT ~MC%
  600 PRINT ~IRQ%
  610 CALL MC%
  620 REM B-EM: YES: 1, 192
  630 REM B2: YES: 1, 192
  640 REM BEEBEM: NO: 0, 0 SOMETIMES 1, 0 WTF
  650 REM JSBEEB: NO: 0, 0
  660 REM MAME: YES: 1, 192
  670 PRINT ?(R%)
  680 PRINT ?(R%+1)

User avatar
hoglet
Posts: 8366
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol
Contact:

Re: 6522 VIA emulation: IFR write vs. timer interrupt

Post by hoglet » Mon Dec 31, 2018 8:22 am

Edit: Snap!
BigEd wrote:
Mon Dec 31, 2018 8:14 am
(If you can post the plain source I can readily paste it into a Beeb.)
Here you go, extracted from the .ssd using Jon Welch's DFS Explorer:

Code: Select all

   10  REM RESULTS FROM DEC 2018
   20  PRINT "VIA TEST: DOES TIMER INTERRUPT FIRE IF IFR CLEARED AT SAME TIME?"
   30  DIM IRQ% 100
   40  DIM MC% 256
   50  DIM R% 16
   60  DIM BAK% 3
   70  P% = IRQ%
   80  [
   90  OPT 3
  100  INC R%
  110  RTI
  120  ]
  130  P% = MC%
  140  [
  150  OPT 3
  160  SEI
  170  LDA #&00
  180  STA R%
  190  LDA &0204
  200  STA BAK%
  210  LDA &0205
  220  STA BAK%+1
  230  LDA &FE4E
  240  STA BAK%+2
  250  LDA #(IRQ% MOD 256)
  260  STA &0204
  270  LDA #(IRQ% DIV 256)
  280  STA &0205
  290  LDA #&7F
  300  STA &FE6E
  310  STA &FE4E
  320  LDA #&C0
  330  STA &FE6E
  340  LDA #&00
  350  STA &FE6B
  360  LDA #&03
  370  STA &FE64
  380  LDA #&00
  390  LDX #&7F
  400  STA &FE65
  410  NOP
  420  NOP
  430  STX &FE6D
  440  LDA &FE6D
  450  STA R%+1
  460  CLI
  470  SEI
  480  LDA BAK%
  490  STA &0204
  500  LDA BAK%+1
  510  STA &0205
  520  LDA BAK%+2
  530  STA &FE4E
  540  LDA #&7F
  550  STA &FE6E
  560  CLI
  570  RTS
  580  ]
  590  PRINT ~MC%
  600  PRINT ~IRQ%
  610  CALL MC%
  620  REM B-EM: YES: 1, 192
  630  REM B2: YES: 1, 192
  640  REM BEEBEM: NO: 0, 0 SOMETIMES 1, 0 WTF
  650  REM JSBEEB: NO: 0, 0
  660  REM MAME: YES: 1, 192
  670  PRINT ?(R%)
  680  PRINT ?(R%+1)
Last edited by hoglet on Mon Dec 31, 2018 8:23 am, edited 1 time in total.

User avatar
richardtoohey
Posts: 3713
Joined: Thu Dec 29, 2011 5:13 am
Location: Tauranga, New Zealand
Contact:

Re: 6522 VIA emulation: IFR write vs. timer interrupt

Post by richardtoohey » Mon Dec 31, 2018 8:24 am

:D I've got a fudged beeb-em so when I press Control-B the "printer" output goes to my console window. Very useful!

User avatar
BigEd
Posts: 2567
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: 6522 VIA emulation: IFR write vs. timer interrupt

Post by BigEd » Mon Dec 31, 2018 8:28 am

From a Beeb: (Edit, ran it 10 times and always got 1,192)

Code: Select all

>RUN
VIA TEST: DOES TIMER INTERRUPT FIRE IF IFR CLEARED AT SAME TIME?
1D2F          
1D2F          OPT 3
1D2F EE 9E 1E INC R%
1D32 40       RTI
1D9D          
1D9D          OPT 3
1D9D 78       SEI
1D9E A9 00    LDA #&00
1DA0 8D 9E 1E STA R%
1DA3 AD 04 02 LDA &0204
1DA6 8D B9 1E STA BAK%
1DA9 AD 05 02 LDA &0205
1DAC 8D BA 1E STA BAK%+1
1DAF AD 4E FE LDA &FE4E
1DB2 8D BB 1E STA BAK%+2
1DB5 A9 2F    LDA #(IRQ% MOD 256)
1DB7 8D 04 02 STA &0204
1DBA A9 1D    LDA #(IRQ% DIV 256)
1DBC 8D 05 02 STA &0205
1DBF A9 7F    LDA #&7F
1DC1 8D 6E FE STA &FE6E
1DC4 8D 4E FE STA &FE4E
1DC7 A9 C0    LDA #&C0
1DC9 8D 6E FE STA &FE6E
1DCC A9 00    LDA #&00
1DCE 8D 6B FE STA &FE6B
1DD1 A9 03    LDA #&03
1DD3 8D 64 FE STA &FE64
1DD6 A9 00    LDA #&00
1DD8 A2 7F    LDX #&7F
1DDA 8D 65 FE STA &FE65
1DDD EA       NOP
1DDE EA       NOP
1DDF 8E 6D FE STX &FE6D
1DE2 AD 6D FE LDA &FE6D
1DE5 8D 9F 1E STA R%+1
1DE8 58       CLI
1DE9 78       SEI
1DEA AD B9 1E LDA BAK%
1DED 8D 04 02 STA &0204
1DF0 AD BA 1E LDA BAK%+1
1DF3 8D 05 02 STA &0205
1DF6 AD BB 1E LDA BAK%+2
1DF9 8D 4E FE STA &FE4E
1DFC A9 7F    LDA #&7F
1DFE 8D 6E FE STA &FE6E
1E01 58       CLI
1E02 60       RTS
      1D9D
      1D2F
         1
       192
>
Last edited by BigEd on Mon Dec 31, 2018 8:29 am, edited 1 time in total.

User avatar
scarybeasts
Posts: 141
Joined: Tue Feb 06, 2018 7:44 am
Contact:

Re: 6522 VIA emulation: IFR write vs. timer interrupt

Post by scarybeasts » Mon Dec 31, 2018 9:11 am

BigEd wrote:
Mon Dec 31, 2018 8:28 am
From a Beeb: (Edit, ran it 10 times and always got 1,192)
Thanks! Super interesting. Finally the mighty jsbeeb is defeated in a core VIA timing issue.

This result does kind of have a symmetry with Rich's results though: it seems any time there's a VIA cycle where the timer is firing at the same time as some register write that would tend to cancel the interrupt, the timer firing wins. This is now confirmed to apply to:

- Reads from T1CL.
- Writes to T1CH.
- [new] Writes to IFR.

Uhhuhh, this suggests yet another follow-up test to see what happens if an ACR write collides with timer expiry. This will show if there's some general rule about or if interrupts are special.


Cheers
Chris

Coeus
Posts: 1314
Joined: Mon Jul 25, 2016 11:05 am
Contact:

Re: 6522 VIA emulation: IFR write vs. timer interrupt

Post by Coeus » Mon Dec 31, 2018 12:33 pm

scarybeasts wrote:
Mon Dec 31, 2018 9:11 am
This result does kind of have a symmetry with Rich's results though: it seems any time there's a VIA cycle where the timer is firing at the same time as some register write that would tend to cancel the interrupt, the timer firing wins...
So that would explain this piece of B-Em code mentioned in the other thread:

Code: Select all

            case T2CH:
                /*Fix for Kevin Edwards protection - if interrupt triggers in cycle before write then let it run*/
                if ((v->t2c == TLIMIT && (v->ier & INT_TIMER2)) ||
                    (v->ifr & v->ier & INT_TIMER2))
                {
                        interrupt |= 128;
                }
Except that this talks about the interrupt having been raised in the previous cycle but that may just be to do with the way things are implemented in b-em, but thinking about this, a new question:

Is it possible to clear the timer interrupt while the timer counter still remains at the value that should be raising the interrupt? If it were not, would that explain the way this apparent clash is handled, i.e. once the signal to set the IFR but has gone the IFR bit can be reset, but whilst that signal is maintained the bit cannot be reset.

User avatar
scarybeasts
Posts: 141
Joined: Tue Feb 06, 2018 7:44 am
Contact:

Re: 6522 VIA emulation: IFR write vs. timer interrupt

Post by scarybeasts » Mon Dec 31, 2018 7:31 pm

Coeus wrote:
Mon Dec 31, 2018 12:33 pm
scarybeasts wrote:
Mon Dec 31, 2018 9:11 am
This result does kind of have a symmetry with Rich's results though: it seems any time there's a VIA cycle where the timer is firing at the same time as some register write that would tend to cancel the interrupt, the timer firing wins...
So that would explain this piece of B-Em code mentioned in the other thread:

Code: Select all

            case T2CH:
                /*Fix for Kevin Edwards protection - if interrupt triggers in cycle before write then let it run*/
                if ((v->t2c == TLIMIT && (v->ier & INT_TIMER2)) ||
                    (v->ifr & v->ier & INT_TIMER2))
                {
                        interrupt |= 128;
                }
Except that this talks about the interrupt having been raised in the previous cycle but that may just be to do with the way things are implemented in b-em, but thinking about this, a new question:

Is it possible to clear the timer interrupt while the timer counter still remains at the value that should be raising the interrupt? If it were not, would that explain the way this apparent clash is handled, i.e. once the signal to set the IFR but has gone the IFR bit can be reset, but whilst that signal is maintained the bit cannot be reset.
Yeah, I'm not a fan of that long B-Em condition for this case.

One of the things I'm hoping to get out of all these VIA test cases is a generic simple ordering rule that works without long if statements and special cases.

It's currently looking like we could order like this:
- Advance time to the VIA mid-cycle.
- Apply effects of any reads/writes hitting in current cycle.
- Apply effects of any timer expiries (IFR / IRQ).

I've got a couple of ACR vs. timer expiry cases to code up to see if this general rule holds.


Cheers
Chris

Post Reply