Search code examples
interruptz80sdcc

Can't figure out how to write interrupt handler for Z80 using SDCC


I'm developing a program in C for the Z80 and compiling using SDCC. I can't figure out how to create interrupt handlers for the NMI interrupt that starts at 0x0066 and the IM1 interrupt that starts at 0x0038. I'm using these calls:

void IM1_InterruptHandler(void) __interrupt 

and

void NMI_InterruptHandler (void) __critical __interrupt 

and the resulting assembly looks about right but they aren't located at the proper addresses. I did spot this thread:

https://sourceforge.net/p/sdcc/feature-requests/519/

but can't figure out how to use the above example crt0.s file with SDCC for a Z80 target. Using the --use-crt switch doesn't seem to work.

unknown compiler option '--use-crt=crt0.s' ignored

Anyone experienced with Z80 development with SDCC that can provide some guidance?

Edit: Still not quite there yet. My crt.s file looks like this:

.module crt0
    .globl  _main
    .globl  _IM1_InterruptHandler
    .globl  _NMI_InterruptHandler

    .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
    jp _IM1_InterruptHandler

    .org    0x66
    jp _NMI_InterruptHandler

    .org    0x100
init:
    ;; Stack at the top of memory.
    ld  sp,#0x8300

    call    _main


    ;; Ordering of segments for the linker.
    .area   _HOME
    .area   _CODE

    .area   _DATA

    .area   _CODE

And I'm doing the following:

sdasz80 -l -o mycrt.rel crt0.s
sdcc -mz80 --no-std-crt0 --code-loc 0x0000 --data-loc 0x8000 mycrt.rel ppclone_menu.c

Every thing seems to compile just fine but when I bring up the code in the disassembler I don't see any of the crt0 code being inserted above at locations 0x08 through 0x66.


Solution

  • To use a custom crt0 file you first need to compile it using sdasz80, which should be part of your SDCC install:

    sdasz80 -o crt0_int.rel crt0_int.asm
    

    Then you compile your program adding the following to the SDCC command line:

    --no-std-crt0 crt0_int.rel
    

    So the full command line would be something like:

    sdcc --code-loc 0xWhatever --data-loc 0xWhatever -mz80 --no-std-crt0 crt0_int.rel somelibrary.lib yoursource.c
    

    If you need examples of complete crt0 files, you have one in my MSX software repository.

    Edit: You are passing --code-loc 0x0000 to sdcc when compiling your source, this will cause the code section to overwrite whatever was defined in crt0. Change it to a more suitable value (for your crt0 looks like 0x0110 would be fine) or leave it out, so the compiler will choose an appropriate value by itself.