Unexpected IRQ behaviour on a VIC-20

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Unexpected IRQ behaviour on a VIC-20

Ruud
Hallo allemaal,


I wanted to test the restore key of a VIC-20 so I connected pin PB7
of UBA1 (VIA2 in the program) with the CA1 input of same IC. To have
another mean to test things beside the monitor, I connected LEDs to
the userport, VIA1.

The Program:


; Test negative edge on CA1
        lda #$26
        sta ControlCode
        sta VIA1_DRB ; light LEDs according code

        lda #0
        sta VIA2_DRB ; negative edge on CA1

        nop
        nop

 lda #$77
 sta VIA1_DRB
Ly: jmp Ly


Original IRQ routine:

IRQroutine:  
        pla
        pla
        pla
NMIroutine:  
        lda #$33
        sta IrqNmiCheck

        sei ; disable interrupts

        rti


Routine with debug instructions and 'repair':

IRQroutine:  
        pla
        pla
        pla
NMIroutine:  
 lda #$AA
 sta VIA1_DRB
; lda VIA1_DRA
; lda VIA2_DRA ; dummy reads for clearing int. register

        lda #$33
        sta IrqNmiCheck

 nop
 nop
 nop
 nop
 nop
 nop
 lda #$55
 sta VIA1_DRB

        sei ; disable interrupts

        rti


The problem I encountered was that the computer just stopped. I
first thought that it some where else in the program but I soon
found out that it never reached the 'lda #$77' part because the LEDs
kept on showing $26. So I added the 'lda #$AA' part to the IRQ
routine. That proofed that the routine was executed.

To make a long story short:
- by adding the 'lda #$55' part I found out that the routine was
looping because all LEDs lighted up.
- by adding 'lda VIA2_DRA' I found out that the looping stopped and
that I got $77 on my LEDs.

I understand that the looping is caused by not clearing the
interrupt. But the idea was that 'sei' should have prevented that.

My question: why didn't 'sei' prevent the looping?


PS: I realised that I have to change the code anyway because 'sei'
won't work with NMI.


--
   
Kind regards / Met vriendelijke groet, Ruud Baltissen
www.Baltissen.org







       Message was sent through the cbm-hackers mailing list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Unexpected IRQ behaviour on a VIC-20

Marko Mäkelä
Hallo Ruud,

On Fri, Jul 28, 2017 at 09:04:43AM +0200, [hidden email] wrote:
> sei ; disable interrupts
> rti
[snip]
>I understand that the looping is caused by not clearing the
>interrupt. But the idea was that 'sei' should have prevented that.
>
>My question: why didn't 'sei' prevent the looping?

The SEI instruction inside an IRQ handler makes little sense, because
the interrupt flag would already be set upon entering the interrupt
handler.

Similarly, the RTI instruction would pop the P register from the stack,
which would clear the interrupt flag.

>PS: I realised that I have to change the code anyway because 'sei'
>won't work with NMI.

NMI is triggered on a falling edge of the signal. NMI can be effectively
disabled by letting the signal to be permanently pulled down, for
example by triggering an NMI from the VIA and then not clearing the
interrupt status.

        Marko

       Message was sent through the cbm-hackers mailing list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Unexpected IRQ behaviour on a VIC-20

Ruud
Hallo Marko,


> The SEI instruction inside an IRQ handler makes little sense, because
> ....

Thank you for the explanation!


--
   
Kind regards / Met vriendelijke groet, Ruud Baltissen
www.Baltissen.org







       Message was sent through the cbm-hackers mailing list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Unexpected IRQ behaviour on a VIC-20

Spiro Trikaliotis
In reply to this post by Ruud
Hello Ruud,

can you give a complete example?

* On Fri, Jul 28, 2017 at 09:04:43AM +0200 [hidden email] wrote:
 
 
> Original IRQ routine:
>
> IRQroutine:  
> pla
> pla
> pla

Why do you pop the status and the return address from the stack? Do you
want to return to the calling routine of your program above?

If yes, the RTI is wrong, because it expects status + return address on
the stack, but (most probably), you do not have the status, do you?


> NMIroutine:  
> lda #$33
> sta IrqNmiCheck
>
> sei ; disable interrupts

Why do you want to disable the interrupts? If my assumption above is
correct and you want to return to the caller of your code, then your
intention might be that you want to enable interrupts, don't you? In
this case, cli might be more appropriate (and that would make sense in
an interrupt routine, at least sometimes).

> rti

As said above, depending upon how you called your program and when the
IRQ is triggered, this will crash your machine as you do not have the
status register on the stack anymore.

At least, this will happen with your IRQRoutine.


As said, it would be best if you could give a complete, but as small as
possible, program code so we can see what you are doing, and tell us
what you are expecting.


Regards,
Spiro.

--
Spiro R. Trikaliotis
http://www.trikaliotis.net/

       Message was sent through the cbm-hackers mailing list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Unexpected IRQ behaviour on a VIC-20

Baltissen, GJPAA (Ruud)
Hallo Spiro,


> IRQroutine:  
> pla
> pla
> pla

I start my program from a cartridge ROM so the original IRQ routine is still effective. And that routine pushes A, X and Y on the stack before doing a "jmp ($0314)". I don't need them so I discarded them. The NMI doesn't push anything at all to stack before doing a "jmp ($0316)".


> NMIroutine:  
> lda #$33
> sta IrqNmiCheck
>
> sei ; disable interrupts
>
> Why do you want to disable the interrupts?

I wanted to check various 6522 registers to see if the interrupt occurred or not AFTER the routine. I knew that not reading the correct register would cause another interrupt immediately. The idea was that SEI would stop that. But Marko explained why it wouldn't work. And, as I realized my self, it wouldn't work with a NMI at all.


> As said, it would be best if you could give a complete, but as small as possible, program code so we can see what you are doing, and tell us what you are expecting.

Not yet because I'm sure I will be accused of inventing the wheel twice again :)


Met vriendelijke groet / With kind regards, Ruud Baltissen

www.Baltissen.org



De informatie in dit e-mailbericht is vertrouwelijk en uitsluitend bestemd voor de
geadresseerde. Wanneer u dit bericht per abuis ontvangt, verzoeken wij u contact op te
nemen met de afzender per kerende e-mail. Verder verzoeken wij u in dat geval dit
e-mailbericht te vernietigen en de inhoud ervan aan niemand openbaar te maken.
Wij aanvaarden geen aansprakelijkheid voor onjuiste, onvolledige dan wel ontijdige
overbrenging van de inhoud van een verzonden e-mailbericht, noch voor daarbij
overgebrachte virussen.

APG Groep N.V. is gevestigd te Heerlen en is ingeschreven in het
handelsregister van de Kamer van Koophandel Limburg onder nummer 14099617


The information contained in this e-mail is confidential and may be privileged.
It may be read, copied and used only by the intended recipient.
If you have received it in error, please contact the sender immediately by
return e-mail; please delete in this case the e-mail and do not disclose its
contents to any person. We don't accept liability for any errors, omissions,
delays of receipt or viruses in the contents of this message which arise as a
result of e-mail transmission.

APG Groep N.V. is registered in the trade register of the Chamber
of Commerce Limburg, The Netherlands, registration number: 14099617


       Message was sent through the cbm-hackers mailing list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Unexpected IRQ behaviour on a VIC-20

Marko Mäkelä-4
Hi Ruud,

>I wanted to check various 6522 registers to see if the interrupt
>occurred or not AFTER the routine.

The obvious solution would be to communicate via shared memory. For
example, set up a circular buffer for the latest interrupt events, and a
"cursor" variable to point to the latest event. Or just increment a
counter. The main program could poll the counter to determine if an
interrupt occurred.

My understanding is that the Atari 8-bit computers use a concept of
"shadow registers" in RAM to allow cleaner access to the chips from
BASIC. I do not know if this covers other chips than the video chip(s).

        Marko

       Message was sent through the cbm-hackers mailing list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Unexpected IRQ behaviour on a VIC-20

Baltissen, GJPAA (Ruud)
Hallo Marko,


> The obvious solution would be to communicate via shared memory. ...

Every test has its own identification. If an interrupt occurred, this code is written to a variable. If a test reads the correct code in this variable, then it knows that the interrupt has been executed as should (or not). That  works fine so far. I'm thinking about copying the IFR to another variable as well before it is reset by reading the A or B port.

What am I doing? I am creating my own tools to test the VIC-20 and C64. Indeed inventing the wheel twice but I have my reasons for it:
- the sources and schematics are free, as always.
- the idea is to use the same sources for a cart version and for a Kernal ROM replacement version.
- the two main reason for a new VIC-20 version
  - I had a VIC-20 that appeared broken but had a faulty video circuit. So the idea rose to connect LEDs to the userport: the first thing the program does is letting the user know through these LEDs that the computer is not dead.
  - I wanted a Kernal version. But the original code is a real mess. So I decided to write my own, not only for this reason but also for the fun and learning curve.
- the three main reason for a new C64 version:
  - the C64 tool uses extra ICs to test things. I prefer to keep it more simple by only making connections between existing pins.
  - the tool starts with using a subroutine when the RAM hasn't been tested at all !!! If the RAM is indeed broken, the tool simply won't work.
  - same reason as above.

Because I need the userport for the LEDs, I have to use another wiring scheme than the original tool. But if you want to have such a tool and cannot buy it (or what ever) then IMHO you have to solder your own set. Then why not choose to solder one that comes with free source codes? :)


Met vriendelijke groet / With kind regards, Ruud Baltissen

www.Baltissen.org






De informatie in dit e-mailbericht is vertrouwelijk en uitsluitend bestemd voor de
geadresseerde. Wanneer u dit bericht per abuis ontvangt, verzoeken wij u contact op te
nemen met de afzender per kerende e-mail. Verder verzoeken wij u in dat geval dit
e-mailbericht te vernietigen en de inhoud ervan aan niemand openbaar te maken.
Wij aanvaarden geen aansprakelijkheid voor onjuiste, onvolledige dan wel ontijdige
overbrenging van de inhoud van een verzonden e-mailbericht, noch voor daarbij
overgebrachte virussen.

APG Groep N.V. is gevestigd te Heerlen en is ingeschreven in het
handelsregister van de Kamer van Koophandel Limburg onder nummer 14099617


The information contained in this e-mail is confidential and may be privileged.
It may be read, copied and used only by the intended recipient.
If you have received it in error, please contact the sender immediately by
return e-mail; please delete in this case the e-mail and do not disclose its
contents to any person. We don't accept liability for any errors, omissions,
delays of receipt or viruses in the contents of this message which arise as a
result of e-mail transmission.

APG Groep N.V. is registered in the trade register of the Chamber
of Commerce Limburg, The Netherlands, registration number: 14099617


       Message was sent through the cbm-hackers mailing list
smf
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Unexpected IRQ behaviour on a VIC-20

smf
In reply to this post by Baltissen, GJPAA (Ruud)
NMI is $0318, brk is $0316

sei before rti won't work even with an irq, because rti pops the
interrupt state from the stack and that will have the interrupt enabled.
You could modify the value on the stack if you want to disable irq's
after an interrupt has occurred.

when you lower ca1 then the 6522 should lower the 6502's nmi input,
which will trigger your routine. Until you read from the data register
then it should be impossible to trigger the nmi again. The cpu's nmi's
can't be masked, even when you're in the middle of an nmi routine. So
I'm at a loss what you're seeing and why, which might be down to only
having a snippet of your code.

You should probably hack your hardware change into an emulator and run
your code through that, because then you can see exactly what it's
doing. Have you disabled vblank/timer irq's? You seem to be jumping into
the same code for both irq & nmi and that could be confusing if they are
still enabled.

On 29/07/2017 08:37, Baltissen, GJPAA (Ruud) wrote:
> The NMI doesn't push anything at all to stack before doing a "jmp
> ($0316)".


       Message was sent through the cbm-hackers mailing list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Unexpected IRQ behaviour on a VIC-20

Baltissen, GJPAA (Ruud)
Hallo smf,


> NMI is $0318, brk is $0316

You are right, just misread my own source.

sei before rti won't work even with an irq, because rti pops the interrupt state from the stack and that will have the interrupt enabled.
You could modify the value on the stack if you want to disable irq's after an interrupt has occurred.


> when you lower ca1 then the 6522 should lower the 6502's nmi input,

Depends on which CA1.


> So I'm at a loss what you're seeing and why, which might be down to only having a snippet of your code.

What I was seeing that the IRQ/NMI routine updated the LEDs with a given value but that another update, that should have had happened immediately after the routine had been finished, never was executed. Only later I found out, by means of a trick, that the routine was "looping". But as already said, by reading the various port A and B registers the problem was solved.

So far I was able to test all CA1 and CB1 inputs. Just have to write the routine for checking CB2 at the userport as input as well. I will keep you informed.


Met vriendelijke groet / With kind regards, Ruud Baltissen

www.Baltissen.org




De informatie in dit e-mailbericht is vertrouwelijk en uitsluitend bestemd voor de
geadresseerde. Wanneer u dit bericht per abuis ontvangt, verzoeken wij u contact op te
nemen met de afzender per kerende e-mail. Verder verzoeken wij u in dat geval dit
e-mailbericht te vernietigen en de inhoud ervan aan niemand openbaar te maken.
Wij aanvaarden geen aansprakelijkheid voor onjuiste, onvolledige dan wel ontijdige
overbrenging van de inhoud van een verzonden e-mailbericht, noch voor daarbij
overgebrachte virussen.

APG Groep N.V. is gevestigd te Heerlen en is ingeschreven in het
handelsregister van de Kamer van Koophandel Limburg onder nummer 14099617


The information contained in this e-mail is confidential and may be privileged.
It may be read, copied and used only by the intended recipient.
If you have received it in error, please contact the sender immediately by
return e-mail; please delete in this case the e-mail and do not disclose its
contents to any person. We don't accept liability for any errors, omissions,
delays of receipt or viruses in the contents of this message which arise as a
result of e-mail transmission.

APG Groep N.V. is registered in the trade register of the Chamber
of Commerce Limburg, The Netherlands, registration number: 14099617
1�,j�j���a�����^q��i��ɚ�X��X��
Loading...