News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

PEEK function in SDCC ?

Started by Baptiste, 17:40, 13 August 14

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Baptiste

Hello,


What's the SDCC function similar at : PEEK address ?


I want a function as like :


char _peek(unsigned char _adr){
        return peek_function(_adr);
}



Thanks




arnoldemu

Quote from: Baptiste on 17:40, 13 August 14
Hello,


What's the SDCC function similar at : PEEK address ?


I want a function as like :


char _peek(unsigned char _adr){
        return peek_function(_adr);
}



Thanks


char peek_function(unsigned char *addr)
{
return *addr;
}


or

char peek_function(unsigned char *addr)
{
return addr[0];
}


call it like this:


peek_function((unsigned char *)0x0a000);



My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

zogo

It is a pity the poor assembler code generated (I miss the z88dk fastcall attribute)

#include <stdint.h>

uint8_t peek(const uint8_t *const addr)
{
    return *addr;
}

uint8_t foo = 99U;

void main(void)
{
    if (peek(&foo) == 0U) {
        while(1);
    }
    while(1);
}



   0000                      52 _peek_start::
   0000                      53 _peek:
                             54 ;main.c:5: return *addr;
   0000 C1            [10]   55         pop     bc
   0001 E1            [10]   56         pop     hl
   0002 E5            [11]   57         push    hl
   0003 C5            [11]   58         push    bc
   0004 6E            [ 7]   59         ld      l,(hl)
   0005 C9            [10]   60         ret
   0006                      61 _peek_end::
                             62 ;main.c:10: void main(void)
                             63 ;       ---------------------------------
                             64 ; Function main
                             65 ; ---------------------------------
   0006                      66 _main_start::
   0006                      67 _main:
                             68 ;main.c:12: if (peek(&foo) == 0U) {
   0006 21r00r00      [10]   69         ld      hl,#_foo+0
   0009 E5            [11]   70         push    hl
   000A CDr00r00      [17]   71         call    _peek
   000D F1            [10]   72         pop     af
   000E 7D            [ 4]   73         ld      a,l
   000F B7            [ 4]   74         or      a, a
   0010 20 02         [12]   75         jr      NZ,00107$
                             76 ;main.c:13: while(1);
   0012                      77 00102$:
   0012 18 FE         [12]   78         jr      00102$
                             79 ;main.c:15: while(1);
   0014                      80 00107$:
   0014 18 FE         [12]   81         jr      00107$
   0016                      82 _main_end::


zogo

Not all is lost. If one use static inline in the declaration of the function, the following code is generated which is pretty much ok

                             65 ;main.c:12: if (peek(&foo) == 0U) {
                             66 ;main.c:5: return *addr;
   0006 3Ar00r00      [13]   67     ld    a, (#_foo + 0)
                             68 ;main.c:12: if (peek(&foo) == 0U) {
   0009 B7            [ 4]   69     or    a, a
   000A 20 02         [12]   70     jr    NZ,00107$



arnoldemu

note on some C compilers you are reading from a variable you set, or reading from a memory address you may need to declare it volatile.
If you don't the compiler may think the value doesn't change and does not do as you want.

e.g.


volate int flag = 0;
.
.
.
while (flag!=0)
{
}


And perhaps:


peek((volatile unsigned char *)0x0a000)


If you want to do in/out I think you need to use assembler.

My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

pelrun

You only need volatile when the value can change somewhere other than the primary C execution thread - this usually means either via hardware (CPC doesn't have memory-mapped registers, but an add-on could) or an interrupt handler. In those cases it's mandatory. But if you know only the main thread C code changes the variable, volatile would slow your code down unnecessarily.


IN/OUT requires either an asm block or a compiler-specific directive; SDCC has the __sfr directive which can define a variable that does IN/OUT when you read or write to it.

Baptiste


Powered by SMFPacks Menu Editor Mod