Re: [cc65] simple assembly interrupt handler

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2006-01-03 00:57:01
Hi!

On Mon, Jan 02, 2006 at 04:24:51PM -0600, PH wrote:
>    As I understand it, $FFFA is the memory address where the interrupt
> looks for the handler to jump to.  In this case, I am mostly interested
> in the vblank isr, as I need to update the video ram buffer during the
> video blank interval.  In the original code, several things are updated
> in the handler by calling the 3 subroutines, but I think if I could just
> set a vblank flag variable in the handler and do the updates in my main
> code loop, that would be fine.  So, if I want to do this, I think I need
> to use a linker config file and a .segment command to place the handler
> address at $FFFA, but I'm not sure how to do that, since I don't know
> how I specify where I want to jump to.  Can someone help me out with a
> bit of example code or something?  Any help is appreciated.

You may want to look at groepaz NES config which is part of cc65. It does
exactly what you need (placing the hardware vectors at a specific address). If
I remember correctly, a copy is in the doc archive. If not, you may need to
download the cc65 sources and look into src/ld65/cfg/nes.cfg. The memory area
named ROMV contains the ROM vectors. The segment named VECTORS is placed into
this memory area. Using "fill=yes" on the memory areas will fill unused areas
in the file, so the contents of the file become an image dump of the real
memory.

Since you should not write interrupt handlers in C for reasons stated in the
FAQ, you need to add a small assembler module:

-----------------------------------------------------------------------------
        .export         _vblank_flag
        .import         reset

.bss

_vblank_flag:   .res    1

.code

vblank: pha
        lda     _vblank_flag
        eor     #$FF                    ; Toggle flag
        sta     _vblank_flag
        pla
irq:    rti

; The following segment is mapped to $FFFA
.segment        "VECTORS"

        .addr   vblank
        .addr   reset
        .addr   irq
-----------------------------------------------------------------------------

Using this declaration:

extern volatile unsigned char vblank_flag;

your main loop can then poll the flag like a normal C variable:

        unsigned char flag = vblank_flag;

        /* Wait for the flag to toggle */
        while (flag == vblank_flag) ;

        /* Go ahead */

Regards


        Uz


-- 
Ullrich von Bassewitz                                  uz@musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Tue Jan 3 00:57:18 2006

This archive was generated by hypermail 2.1.8 : 2006-01-03 00:57:21 CET