Open ikskuh opened 4 years ago
My name is Michaël Larouche and I fully support this effort
May I pretty please have support for the 65c816 (the super-weird 16 bit version) too?
No, I refuse to wait for #65816 to propose it
This repo may be useful there: https://github.com/c64scene-ar/llvm-6502
@notCalle i think the next up would be #6800 and #68000, even though that is a bit far away
Too bad #80 is already gone, because Z80.
Also want to point out that the Nintendo Entertainment System (NES)(1983) ran on a modified 6502 so support for this arch could enable the writing of NES ROMs in Zig
cpu: https://wiki.nesdev.com/w/index.php/CPU rom format: https://wiki.nesdev.com/w/index.php/INES
Hehe, I came here looking to write Zig code to run on Minecraft computers :P
Hello, I've been working on this for a while. I came up with what we can maybe call a prototype of a backend for this architecture. Yesterday I basically rewrote the backend and today I was working on binary operations. Here's a pretty complicated example with lots of bin ops that it is able to compile:
pub fn main() void {
// pointer loads, stores, basic arithmetic...
var str = "@ETO".*;
str[0] += 8; // '@' -> 'H'
str[2] -= 8; // 'T' -> 'L'
printChar(str[0]);
// different ways of accessing the array...
var ptr = @ptrCast([*]u8, &str);
// pointer arithmetic...
ptr += 2;
ptr -= 1;
printChar(ptr[0]);
// adding and subtracting big integers...
var b: u64 = 0;
b += str[2];
b -%= 123456789;
b +%= 123456789;
printChar(@intCast(u8, b));
printChar(str[2]);
printChar((&str)[3]);
// wild pointer indirection stuff with big types
var x: u256 = 'X';
x = ' ';
printChar(@intCast(u8, x));
const y: *u256 = &x;
y.* = 'W';
printChar(@intCast(u8, x));
x = 'O';
printChar(@intCast(u8, y.*));
var z: *const *u256 = &y;
y.* = 'R';
printChar(@intCast(u8, z.*.*));
const w = &x;
z = &w;
z.*.* = 'L';
printChar(@intCast(u8, z.*.*));
var a = &z;
a.*.*.* = 'D';
printChar(@intCast(u8, w.*));
}
/// Writes the byte in the A register to the screen - "CHaR OUT".
const CHROUT = @intToPtr(*const fn () void, 0xFFD2);
/// Prints the character to the screen.
fn printChar(char: u8) void {
// Load the character into the 6502's A register.
asm volatile ("" // no assembly code
: // outputs (none)
// inputs (1):
: [a] // unused in the assembly code string but mandatory syntax
"{a}" // A register
(char), // loadee
);
CHROUT();
}
First, when using @import("std").debug.print("{c}", .{char});
in printChar
:
~/Desktop/zig@6502$ zig run hello.zig
HELLO WORLD~/Desktop/zig@6502$
And now for the Commodore 64:
~/Desktop/zig@6502$ stage3/bin/zig build-exe hello.zig -ofmt=prg -target 6502-c64 -O ReleaseSmall
error(gpa): Allocation size 3063 bytes does not match free size 2711. Allocation:
...
~/Desktop/zig@6502$ wc -c hello.prg
3393 hello.prg
For what it does, it compiles down to a pretty big Program (.prg) binary executable. It's mainly due to loops being inlined (to be improved) and some other unrelated bloat (not my fault; see #6256).
Despite all that, the Commodore 64 can run it:
Judging by the output, the behavior of this program seems to match other backends (compare with the output of the zig run
earlier).
For now my 6502 backend only really works with the PRG output format for the C64. NES support and other platforms and such can be investigated later, of course.
Anyway, this is mainly just a notice in case anyone else thought about working on this. It's all still in a highly experimental state and I can't promise I will even be able to try upstreaming it but you can find my work here: https://github.com/r00ster91/zig/commits/6502
Edit: little update. Since the above my backend has still improved quite a bit more than that but for now I haven't worked on it much more because I'm kind of waiting for the whole backend codegen infrastructure to mature more along with x86_64 to see how that turns out.
Also, at some point I thought AIR would go away eventually so I thought would have to rewrite the whole backend again, anyway, but this apparently turned out to be false and rather, in the future there might be a new "CFIR" stage added to the compiler pipeline but that stage is optional and a more Contributor-Friendly IR compared to AIR.
Apparently a backend will be able to choose whether to consume AIR or CFIR.
I think I would prefer still consuming AIR but I'm not yet sure about this but I would also like to see more code being shared between the codegen backends either way. Maybe we can still share much more code than now even between backends that consume AIR directly rather than CFIR in the future.
So I don't know when or if I'll get back to this or if someone else will take over.
Too bad #80 is already gone, because Z80.
Btw, how do we stand today (July2023) on Z80 support?
How would I express linking c64 data blocks on a specific memory location in zig? That is neccessary for a lot of things like charsets and sid-file music.
Something like const myCharset = @at(0x2000, @embedFile("my-charset.bin"));
?
@geon Linker scripts.
During this week, I have had an urge to add or contribute to NES compability to the compuler.
The MOS Technology 6502 is one of the most famous processors which was used in a lot of home computers in the 80ies. Even today it is mostly programmed in assembly. There aren't many compilers available, most prominent one is cc65, a C compiler.
Zig would be in a unique position to be a modern compiler for the 6502 processor family.
The 6502 does not have a huge instruction set, but has a lot of restrictions which makes code generation and optimization hard, but i think it's still worth a try.
Imagine programming your C64 in Zig!