Missing code in Z88dk C compilation

123 views
Skip to first unread message

Gordon Wainwright

unread,
Jun 21, 2024, 6:45:59 AM (8 days ago) Jun 21
to RC2014-Z80
Hello
I'm following up on an old conversation, "z88dk - RC2014 - IM 1 -tell the RST38 - how to  c-compiler vector? 


I have successfully compiled the source file, but when I inspect the disassembled code, I see that  the function:
 my_interrupt_handler()
has only a ret instruction.

The function 'my_interrupt_handler ()' is expected to contain some code to modify the variable' i'. However, this is not the case, as shown below.

Can anyone point out what I may be doing incorrectly here? Or that I have assumed.
Regards
Gordon

_my_interrupt_handler:
                    ret                                     ;[869e] c9

_main:
                    ld        bc,$869e                      ;[869f] 01 9e 86
                    ld        ($fe16),bc                    ;[86a2] ed 43 16 fe
                    ld        hl,$0000                      ;[86a6] 21 00 00
                    ret                                     ;[86a9] c9


#include <cpu.h>

// For using the SCM
// https://github.com/RC2014Z80/RC2014/wiki/Using-Z88DK#scm
#pragma output CRT_ORG_CODE = 0x8000
#pragma output CRT_REGISTER_SP = 0xFC00

// read and debug: zcc +rc2014 -subtype=basic -v --list -m -SO1 --c-code-in-asm --fverbose-asm --max-allocs-per-node10000 simple.c -o simple -create-app
// run: zcc +rc2014 -subtype=basic -v --list -m -SO3 --max-allocs-per-node200000 simple.c -o simple -create-app

void my_interrupt_handler(void)
{
    int i = 0;
    i++;
    i--;
    i+=2;
}

int main(void)
{
  uint16_t volatile * const interrupt_vector = (uint16_t *) 0xFE16;
  * interrupt_vector = (uint16_t) my_interrupt_handler;
  return 0;
}






Andrew Valencia

unread,
Jun 21, 2024, 10:16:12 AM (8 days ago) Jun 21
to RC2014-Z80
Is this an optimizing compiler?  That value isn't used, so the compiler would be free to not bother generating code for its calculation.

Gordon Wainwright

unread,
Jun 21, 2024, 11:21:54 AM (8 days ago) Jun 21
to RC2014-Z80
Andrew,

After looking at the page regarding Homebrew Quick Start

This compile line does create code in the my_interrupt_handler() function.

 zcc +z80 -clib=classic simple.c --list -create-app -m

+RC2014 and +z80. If I dig deep into the z88dk documentation, I may find what is required for the +rc2014 to generate code as one would expect.

For now, I'll stick with +z80 as I want a bare-metal build.

Gordon

Alan Cox

unread,
Jun 22, 2024, 5:00:53 AM (7 days ago) Jun 22
to rc201...@googlegroups.com
It won't work for a couple for a couple of reasons

1. Your routine optimizes to nothing. If you make it "volatile int i"
you'll do better as the compiler is then not allowed
to deduce that is not used and throw it away. Right now SDCC realizes
that i is local, never passed or has the address
taken and therefore optimizes it out entirely. For debugging you'd
perhaps do better with a global variable

volatile int testing = 0;

and set that in the routine. That way you can observe the value in the
monitor as well.

2. You need to declare your function to be an interrupt handler as it
has to save the registers and any internal temporaries the compiler
uses on entry and restore them on exit.
> --
> You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+...@googlegroups.com.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/rc2014-z80/055a8a8f-8faf-4640-9d75-3901335309e0n%40googlegroups.com.

Phillip Stevens

unread,
Jun 26, 2024, 2:43:37 AM (4 days ago) Jun 26
to RC2014-Z80
On Saturday 22 June 2024, Gordon Wainwright wrote:

After looking at the page regarding Homebrew Quick Start

This compile line does create code in the my_interrupt_handler() function.

 zcc +z80 -clib=classic simple.c --list -create-app -m

+RC2014 and +z80. If I dig deep into the z88dk documentation, I may find what is required for the +rc2014 to generate code as one would expect.

For now, I'll stick with +z80 as I want a bare-metal build.

Just some subtlety in the compile lines that you're using, and how this might result in different effects on your code.

The zcc tool will invoke different compilers, depending on how it is configured. The classic library and target (say zcc +z80 ...) will invoke the sccz80 compiler. To switch to use the sdcc compiler then add -clib=sdcc_iy. As a side effect this will also move from using the classic library to use the new library. Essentially they have been integrated and most standard functions are shared, but some things like the crt0 are still configured and built differently.

The +rc2014 target defaults to the sdcc_iy library and sdcc compiler, together with the new library crt0 and configurations.
This is the same as the +hbios and +scz180 targets.

The compiler selection has an impact for parameter passing between assembly and C. sdcc uses the normal right to left direction on the stack. sccz80 naturally uses left to right and will leave the last (rightmost) parameter in the dehl registers. If you've only one parameter then adding z88dk_fastcall will put the parameters in the dehl registers for both compilers. sccz80 can be forced to switch to std C parameter passing by giving it the -stdc option. You'll need to know this if you're mixing C and assembly functions.

sccz80 is very fast to compile but doesn't do any optimisation of the code. There are a lot of peephole rules that will make very good local optimisation though.
sdcc is optimising, but depending on how you configure it builds can take many (many) minutes to complete.

The best way to confirm what you're actually getting is to; use the --list option and then read the resulting assembly; and the -v option to track which tools are being invoked with which options.

Cheers
Reply all
Reply to author
Forward
0 new messages