First of all, apologies for the attachment, but it's absolutely tiny and it
might help with investigating one of SimCoupe's remaining inaccuracies.

Basically, in one of the bits of code I've been doing recently I made a
very silly error in the interrupt handler, which by fluke works on a real
Sam but fails in SimCoupe (had it not worked at all, I would natuarally
have noticed and fixed the bug straight away...)

It seems my code was reading the status register, and jumping for LINEint
correctly, but performing the wrong test for FRAMEints and jumping to the
FRAMEint handler iff the corresponding status register bit was high.

My guess is that on a real Sam, this would work because (after deciding
that FRAME interrupts weren't interesting after all) the interrupt would
still be active and the code would immediately jump back to 56, and do it
all again, until eventually there comes a point when the FRAMEint bit goes
high again and the interrupt gets handled properly.

What we also found was that after a line interrupt had been properly
handled, in SimCoupe the frame interrupt routine was being called. So
presumably the interrupt must still have been active but the LINE bit of
the status register had gone high.

so...

I wrote a little program to test exactly how long the interrupts were
actually active for, and got a rather unexpected result. At a frame
interrupt, this program spins round a little interrupt handler incrementing
B for as long as interrupts are generated. At a line interrupt, B is stored
for display and reset for the next frame.

Load the code at the start of a page, and PRINT USR it. Press SPACE to exit.

On my Sam, the result displayed is 3. So we're running three full times
though that code before the interrupt goes away, which takes roughly 180
t-states (assuming, and I may be wrong, that the RET at the end of the
routine never gets executed until after the interrupt goes away, and that
jumping to an interrupt takes 12 tstates just like an RST.)

On SimCoupe (MacOS, 0.72v3) , the displayed result is 0. Which is rather
odd. Because it either means that B has never been incremented, or that B
was incremented exactly 256 times which I don't believe. (The line
interrupt has definitely been handled, because I can poke whatever I like
into the initial result field, and it will be overwritten by 0).

Have I missed something obvious? Why does it appear that frame interrupts
just aren't occurring? Perhaps someone with the unix version handy can do
some more detailed testing.

Here's the source of my test program

USEIX:         EQU  221
USEIY:         EQU  253

CLUT:          EQU  248
LINE:          EQU  249
STATUS:        EQU  249
LMPR:          EQU  250
HMPR:          EQU  251
VMPR:          EQU  252        ;constants

               ORG  32768

               DI

               IN   A,(VMPR)
               LD   (VMPRS),A

               IN   A,(LMPR)
               LD   (LMPRS),A

               IN   A,(HMPR)
               LD   (HMPRS),A
               AND  31
               OR   32
               OUT  (LMPR),A

               LD   (SPSTORE),SP

               JP   LMEM      ;setup (run in section A for mode 1 interrupts)

HMEM:

LMPRS:         EQU  $+1
               LD   A,00
               OUT  (LMPR),A
VMPRS:         EQU  $+1
               LD   A,00
               OUT  (VMPR),A
SPSTORE:       EQU  $+1
               LD   SP,0000

RESULT:        EQU  $+1
               LD   BC,0000

               EI
               RET

               ORG  $-32768



               DEFS 56-$

;instruction timings from David Zambonini's article in BOAI
;ts is a "usable clock cycle" rather than the more conventional t-state
;not that it makes much difference here, since we're mostly interested
;in counting instructions executed in the border area
;at frame interrupt we do not save time on * instructions

               EX   AF,AF'       ;4 ts
               IN   A,(STATUS)   ;16* ts
               RRA               ;4 ts
JPLINEINT:     EQU  $+1
               JP   NC,LINEINT   ;12 ts
               INC  B            ;4 ts
               EX   AF,AF'       ;4 ts
               EI                ;4 ts
               RET               ;12 ts


LMEM:
               LD   A,191
               OUT  (LINE),A    ; set up a line interrupt

               EI

MAINLOOP:

               LD   A,&7F
               IN   A,(&FE)
               RRA
               JR   C,MAINLOOP
                                   ; this loop only uses AF
                   ; so our interrupts can happily use everything else
               DI


               LD   A,255
               OUT  (LINE),A


HMPRS:         EQU  $+32769
               LD   A,00
               OUT  (HMPR),A
               JP   HMEM




LINEINT:
               LD   A,B
               LD   (RESULT),A      ; store the number of loops round frameint
               LD   B,0             ; reset for another count


               EX   AF,AF'

               EI
               RET


Good luck...

Andrew














Û¤¸2"Ĥ™2Ĥš2UÄÊ–
"™Ìs&ĈC
--
| Andrew Collier | email [EMAIL PROTECTED]       | Talk sense to a
| Part 2 NatSci  | http://carou.sel.cam.ac.uk/ | fool and he
+----------------+-----------------------------+ calls you foolish
| Selwyn College Student Computer Support Team |   -- Euripides

Reply via email to