I had a terrible time trying to work out the finer points of the Z80 interrupt 
handling with SDCC.

My tweaked crt0.s is below. I don't use the NMI so it's commented out. You can 
also see that I use ex and exx and call _isr. And, I don't re-enable interrupts 
in the immediate isr code.

Memory on my Z80 board is one 32K flash ROM and one 32K static RAM, so you can 
see how I set up the stack at 0x7FFF


;; Generic crt0.s for a Z80
;;
;; regenerate using "as-z80 -o crt0.o crt0.s"
;;
        .module crt0
        .globl  _main
        .globl  _isr
;;      .globl  _nmi_isr

        .area _HEADER (ABS)
        ;; Reset vector
        .org    0
        jp      init

        .org    0x08
        reti
        .org    0x10
        reti
        .org    0x18
        reti
        .org    0x20
        reti
        .org    0x28
        reti
        .org    0x30
        reti
        .org    0x38
        di
;        push    af
;        push    hl
    ex    af, af'
    exx
    call _isr
    exx
    ex    af, af'
;        pop     hl
;        pop     af
; disable enabling interrupts so that we can handle rtc interrupt better
;       ei
        reti
 
; commented out the NMI for now       
        .org    0x66
;       push    af
;       call    _nmi_isr
;       pop     af
        retn
        
        .org    0x100
init:
        ;; Stack at the top of memory.
        ld      sp,#0xffff        

    ;; enable interrupts
        im      1
        ei
    
        ;; Initialise global variables
        call    _main
        jp      _exit

        ;; Ordering of segments for the linker.
        .area   _HOME
        .area   _CODE
        .area   _GSINIT
        .area   _GSFINAL
        
        .area   _DATA
        .area   _BSS
        .area   _HEAP

        .area   _CODE
__clock::
        ld      a,#2
        rst     0x08
        ret
        
_exit::
        ;; Exit - special code to the emulator
        ld      a,#0
        rst     0x08
1$:
        halt
        jr      1$

        .area   _GSINIT
;;gsinit::        
;;
;;      .area   _GSFINAL
;;      ret


My interrupt comes from an RTC, so it's not extremely time critical thus the 
ISR sets a flag which is then tested in main.

//================================================================================
// the maskable interrupt service routine is here
// see crt0.s for the rest of ISR handler
//================================================================================
#pragma save
#pragma nooverlay

void isr (void)
{
    interrupted=1;
}

#pragma restore

Finally, since "interrupted" is volatile, it must be defined as such:

static volatile unsigned char interrupted;

Excuse my older pragma directives. I haven't updated this code to the newer 
standard (though I am working through that).

Hope this helps.

Mike
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Sdcc-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to