A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/harakas/llvm-z80 below:

GitHub - harakas/llvm-z80: LLVM for z80

LLVM/Clang targetting Z80 / ZX Spectrum

This is a fork from https://github.com/jacobly0/llvm-project

I've been hacking it for use with the ZX Spectrum. Most changes have been done with speed in mind but I'm in no way an expert on compilers or llvm. This is just for fun.

Aim is to use C++ to program toy games or demos for the ZX Spectrum. I treat Z80 as a "microcontroller with more memory than usual", so use of heap, standard library, exceptions or even stack/alloca is not really something I plan to support.

Main changes:

How to build:

$ sudo apt-get update && sudo apt-get -y install cmake ninja-build lzip
$ bash install.sh

This will download and install binutils and compile clang. The default installation directory is /opt/local/z80-none-elf.

There are some samples under z80/samples. Here's how you'd compile and run one under the fuse-gtk emulator:

$ cd z80/samples/hello_world/
$ make
/opt/local/z80-none-elf/bin/clang++ -target z80-none-elf -Wa,-march=z80+full -Wa,-sdcc -nostdinc -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -O3 -Wall -std=c++20   -c -o main.o main.cpp
/tmp/main-72edfc.s: Assembler messages:
/tmp/main-72edfc.s:92: Warning: unrecognized section type
/opt/local/z80-none-elf/bin/z80-none-elf-ld -T memory.ld -Map=hello_world.map --oformat ihex main.o -o hello_world.hex
python3 ../../utils/hex2tap.py hello_world.hex --include-loader
$ fuse-gtk hello_world.tap

The compiler is not really that stable. It breaks and crashes on lots of various code. But for some it works.

Some TAP files:

This is all the help you'll get from me with this. Have fun.

Some screenshots:

Example application:

namespace ZX {
    using int8_t = char;
    using uint8_t = unsigned char;
    using int16_t = int;
    using uint16_t = unsigned int;

    struct Console {
        static void putchar(char c) {
            uint16_t iy = 23610;
            __asm__ ("rst $10" : "=a"(c) : "a"(c), "iy"(iy) : "h", "l", "d", "e", "b", "c", "cc", "memory");
        }

        static void at(uint8_t x, uint8_t y) __attribute__((noinline)) {
            putchar(22);
            putchar(y);
            putchar(x);
        }

        static void print(const char *str) __attribute__((noinline)) {
            while (*str)
                putchar(*str++);
        }
    };
};

int main()
{
  ZX::Console::at(10, 12);
  ZX::Console::print("Hello, world!");
  return 0;
}

Assembly produced for the int main() function:

_main:
        ld      l, 10
        ld      h, 12
        call    __ZN2ZX7Console2atEhh
        ld      hl, _.str
        call    __ZN2ZX7Console5printEPKc
        ld      hl, 0
        ret

Assembly produced for the ZX::Console::print(const char*) function:

__ZN2ZX7Console5printEPKc:
        ld      a, (hl)
        or      a, a
        jr      z, .LBB2_3
        ld      iy, 23610
        inc     hl
        .local  .LBB2_2
.LBB2_2:
        ld      (__ZN2ZX7Console5printEPKc__variables), hl
        ;APP
        rst $10
        ;NO_APP
        ld      hl, (__ZN2ZX7Console5printEPKc__variables)
        ld      a, (hl)
        inc     hl
        or      a, a
        jr      nz, .LBB2_2
        .local  .LBB2_3
.LBB2_3:
        ret

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4