-1

I'm a student at an engineering college, and I have encountered a problem while working on a project. In this project, I am designing a microcontroller. I opted to use the Z80 CPU due to its simplicity and popularity. However, the issue arises with the concept of controlling the pins through RAM addresses. While controlling RAM addresses through assembly code worked, transitioning to using C to manage the logic of the microcontroller proved challenging.

For instance, in the assembly code, I successfully managed to change the value of RAM at address 0x3FFF to 0x02.

.org $0000      ; Set origin to 0000h

START:

    LD HL, 0X3FFF  ; Load HL with the address 0x3FFF
    LD A, 0X02 ; Load register A with the value 0x02
    LD (HL), A     ; Store the value in register A at the address pointed to by HL

I utilized a retro assembler to generate the binary file, which I then employed in the virtual EEPROM within the simulation program, Proteus 8.

Since my setup is functioning properly, I opted to experiment with using a C code instead of assembly. I found a suitable C compiler online (z88dk) and proceeded to utilize the following code to control the RAM address

int main(){
     int *p = (int *)0x3FFF;
    *p |= 0x02;

    return 0;
}

https://github.com/z88dk/z88dk

And I used this command to generate the bin file

zcc +cpm -subtype=z80pack -compiler=sdcc mem.c -o mem.bin

and

zcc +cpm mem.c -create-app -subtype=z80pack -compiler=sdcc

I was able to use the bin file with the EEPROM simulation, but the code didn't work,what should I do to be able to control the ram addresses values with C?
Did I used it correctly or should I change the compiler?

6
  • 1
    What does the generated code contain? You haven't shown us the intermediate assembly. Commented Apr 1, 2024 at 6:52
  • 1
    It seems that the issue may be one or both of writing an int instead of a char, and building for cpm. I have never heard of this compiler. Had you been asking for a suitable compiler (which would have been off topic), I'd have suggested SDCC sdcc.sourceforge.net. Either way, the compiler should have an option to output the generated code as an assembly listing. Commented Apr 1, 2024 at 9:48
  • Aside from the wrong type note also that |= does a bitwise OR, not a write of an entire byte value like in your assembly example. Commented Apr 1, 2024 at 11:05
  • sorry i couldn't attach the bin file with the post and thanks for your help, but don't worry the last comment fixed the issue. thanks again Commented Apr 1, 2024 at 17:50
  • 1
    "In this project, I am designing a microcontroller" You mean designing a microcontroller program surely? Commented Apr 2, 2024 at 14:27

2 Answers 2

4

Note that LD (HL),A writes a byte to memory, not an integer. Try this code:

int main(){
     volatile unsigned char *p = (unsigned char *)0x3FFF;
    *p = 0x02;
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

@rcgldr In this case probably not, but generally if you e.g. have several writes with no intervening reads, the compiler can decide that all writes but the last are useless and remove them.
@n.m.couldbeanAI - without volatile, those intervening reads could be replaced by load immediates, and still only a single final write.
3

You are building a CP/M application here. Of course it wouldn't work on your barebones machine.

Your best bet with z88dk is to follow Embedded/Homebrew documentation, but it still wouldn't work for what you want it to do. See, this is a full fledged C compiler which gives you a standard C environment. That implies doing quite a lot of work prior to YOUR code ever being executed, including functions calls (so, stack accesses which are RAM accesses at some location it presumes is a RAM dedicated to stack) and some internal variables initialization (so, more RAM accesses at some location it presumes is a RAM dedicated to general data).

This can be fixed to some extent with some switches and custom initialization code. This is what I've managed to get in the resulting binary:

    jp        $0003                         ;[0000] c3 03 00
    ld        bc,($3fff)                    ;[0003] ed 4b ff 3f
    set       1,c                           ;[0007] cb c9
    ld        ($3fff),bc                    ;[0009] ed 43 ff 3f
    jr        $000d                         ;[000d] 18 fe

mem.c:

    int main(void) {
         unsigned short* p = (unsigned short*)0x3FFF;
         *p |= 0x02;
         for(;;);
    }

crt0.asm:

    EXTERN    _main
    defc    CRT_ORG_CODE = 0x0000
    org     CRT_ORG_CODE
start:
    jp      _main

Command line: zcc +z80 -O3 -clib=classic mem.c -o mem -crt0=crt0.asm -m -compiler=sdcc

1 Comment

thanks this did really work !! thanks for your help I've been stuck for a while now, thanks again 🥰🥰

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.