asie
What's a PC Engine?
Posts: 4
|
Post by asie on Jun 22, 2023 17:40:05 GMT
(This post will be edited with installation instructions and more once the target is officially released.) Hello! Having taken a break from the WonderSwan, for the past few weeks, I have been working on a new compiling/linking solution for the NEC PC Engine. This compiler is based on LLVM-MOS - a port of the latest version of LLVM and Clang to MOS 6502-based processors, with highly competitive optimization even compared to the most "modern" 6502 compilers. The following features have been introduced and will be supported in the initial release: - Full HuC6280 opcode support in the assembler
- Comprehensive register definitions and helper routines for timer, joypad, IRQ, VDC, SuperGrafx handling
- Support for ROMs of up to 1 MB in size
- "Virtual bank" system - manual but flexible allocation of physical banks as C linker sections
- Modern C and C++ standards support.
- Modern LLVM-based optimizations, including some support for emitting 65C02 and HuC6280 opcodes where appropriate (work in progress, of course)
- Support for Mesen 2-compatible symbols file output.
I'd like to add SF2 mapper and PC Engine CD support if there's interest, but these will require a bit more engineering consideration and architecture studying before I can implement a good approach. Documentation is available on the LLVM-MOS wiki, as well as - for the library routines - as a Doxygen export. The code currently exists in the form of a pull request and is being actively reviewed by LLVM-MOS's developers - but I'm also looking for feedback from other PC Engine developers. Thank you!
|
|
|
Post by spenoza on Jun 22, 2023 18:03:36 GMT
This is very cool. Will there by matching documentation to help guide potential developers in the best way to code to this compiler?
|
|
asie
What's a PC Engine?
Posts: 4
|
Post by asie on Jun 22, 2023 18:21:09 GMT
Regarding optimization, LLVM-MOS already has some documentation on its wiki - I recommend the Optimization guide as a start. Regarding compiler features, here are some of my recommendations: Regarding step-by-step tutorials - I'm not sure. They'd certainly be good to have, but I think that can wait until the routine library is more peer-reviewed and stabilized. Here's a trivial example C file, though.
|
|
|
Post by elmer on Jun 22, 2023 20:18:09 GMT
Brilliant, it's good to see another C compiler alternative pop up! I wonder how long it will be before someone turns up with an SDCC 6502 option for the PCE, since that's the other "new" 6502 compiler that's getting attention. My big question to you is about how you're handling banking, since on the PCE we're MUCH more sensitive to banking than the other 6502 platforms that the LLVM-MOS toolchain was created for, primarily because we do so much more of it. Getting a better 6502 C compiler than HuC isn't much of a problem with modern-day technology. Getting an environment that seamlessly handles multiple banks of code and multiple banks of data OTOH is more challenging, since the modern-day technology tends to assume a linear memory space. I see that LLVM-MOS provides mos24bank(), mos24segment(), mos24segmentlo() and mos24segmenthi(), which is an excellent basis to build from, even if I don't currently understand the subtle differences between those, yet. From your POV ... 1) How are C developers going to be calling code that's in a different bank? 2) How are C developers actually going to manage creating programs that use more than one bank of code? 3) How are C developers supposed to use/pass 24-bit pointers to code and data to different functions (whether they're C or assembly-language)? 4) How are C developers supposed to include/use large blocks of data that span multiple 8KByte banks?
|
|
asie
What's a PC Engine?
Posts: 4
|
Post by asie on Jun 22, 2023 20:45:31 GMT
All of this is answered in the documentation link above ( PCE target); but to provide quick answers for the questions presented: First, note that the mos24bank(), etc. functions you found are meant to be used for the 65816 - whenever it's fully supported. You can actually use mos24bank() and mos24segment() in the way you're thinking of, though, because of how the LMA is designed. - Unfortunately, at this time it has to be done manually, as with f.e. OVERLAY sections on GCC in the past. (SDCC will probably have an edge in the short-term here, as their GameBoy backend can distinguish between "far" and "near" calls at the compiler level, and I assume this is or can be adapted to the 6502.) There are two facilities provided for this:
- pce_vbankN_set();, which maps a virtual bank N (see point 4 or the documentation above) to memory
- pce_vbankN_call(function);, which acts as a "safe" call from one virtual bank to another through the fixed bank.
- By a mix of using the "virtual bank" facility, or a larger fixed bank than 8K, if they so wish.
- This is not currently resolved, though I think you can actually use mos24bank() in this way.
- By using "virtual banks". They are described in detail in the link above, but in short - one "virtual bank" maps to one or more contiguous physical banks, and - as a result - it can be allocated by the linker as a contiguous block. The limit of the current size is set to 40KB (the maximum that is contiguously addressable, as banks 0, 1 and 7 are fixed in the layout as planned).
I assume this is not as good as SDCC or HuC's status quo - there are some ideas on improving this, but I think it's a decent starting point. I'm more worried about handling the PC Engine CD...
|
|
|
Post by elmer on Jun 22, 2023 21:48:16 GMT
All of this is answered in the documentation link above ( PCE target); but to provide quick answers for the questions presented: Ah, thank you for the link, that really helps to explain your ideas in organizing the PCE target for LLVM-MOS! I assume this is not as good as SDCC or HuC's status quo - there are some ideas on improving this, but I think it's a decent starting point. I'm more worried about handling the PC Engine CD... It's an ABSOLUTELY excellent starting point, but there are a few things that I immediately see that you seem to be missing (at the moment). First, note that the mos24bank(), etc. functions you found are meant to be used for the 65816 - whenever it's supported - not the HuC6280 or 6502-based platforms. They're not relevant for this purpose. Errr .... OK, I guess? Y'all do know that both the C64, Atari 8-bit, NES, Lynx, etc support banked-memory, don't you? Having a good model for banking seems kinda important. - Unfortunately, at this time it has to be done manually, as with f.e. OVERLAY sections on GCC in the past. (SDCC will probably have an edge in the short-term here, as their GameBoy backend can distinguish between "far" and "near" calls at the compiler level, and I assume this is or can be adapted to the 6502.) There are two facilities provided for this:
- pce_vbankN_set();, which maps a virtual bank N (see point 4 or the documentation above) to memory
- pce_vbankN_call(function);, which acts as a "safe" call from one virtual bank to another through the fixed bank.
- By a mix of using the "virtual bank" facility, or a larger fixed bank than 8K, if they so wish.
- This is not currently resolved.
- By using "virtual banks". They are described in detail in the link above, but in short - one "virtual bank" maps to one or more contiguous physical banks, and - as a result - it can be allocated by the linker as a contiguous block. The limit of the current size is set to 40KB (the maximum that is contiguously addressable, as banks 0, 1 and 7 are fixed in the layout as planned).
Thanks for the clarification! I assume this is not as good as SDCC or HuC's status quo - there are some ideas on improving this, but I think it's a decent starting point. I'm more worried about handling the PC Engine CD... PCE-CD isn't really any more difficult than what you've already got, once you get passed the notion that MPR7 must always be mapped to bank 0. Various PCE-CD games remap MPR7 to a gamecode bank, and then just page the System Card back in temporarily when calling one of the System Card routines. The code to do this isn't much, and you'd be well-advised to design your runtime library around the capability. <EDIT> I have no idea if anyone is currently working on a PCE target for SDCC. The last time that I looked the main 6502 developer didn't seem interested in adding HuC6280 instructions to their toolchain.
|
|
asie
What's a PC Engine?
Posts: 4
|
Post by asie on Jun 22, 2023 22:46:41 GMT
It's an ABSOLUTELY excellent starting point, but there are a few things that I immediately see that you seem to be missing (at the moment). Other than a more proper facility for "far pointers" (as brought up above)? Yes, sorry. I edited my post later to clarify; essentially, before I started working on the PC Engine target, the only llvm-mos target which explored banked memory at all was the NES target. However, that exploration was done at the level of the linker script and helper functions (just like the PCE target does, though the PCE target is a bit more involved in this regard) - and not at the level of the compiler, which currently has no concept of banking whatsoever. The functions mos24bank(), etc. are essentially linker relocations designed by writing down all the relocations required for the 65816, without much more to them. The problem for far pointers on the PCE target is that with the introduction of the "virtual bank" system, these relocations don't tell the whole story as to which bank a given pointer is in (as a pointer has to be contiguous, but it spans multiple banks - so, unless you only define 8KB banks, you can't tell if a linker address 0x02A000 can point to bank 0x02 for a virtual bank mapped at 0xA000, or bank 0x03 for a virtual bank mapped at 0x8000). There are some solutions for that (for example, the 8086 port of GCC - gcc-ia16 - resolved it by introducing a separate symbol that denotes the starting segment, as per H. Peter Anvin's "segelf" suggestion), but they need to be discussed further with the LLVM-MOS creators, and analyzed in context of all the other banked-memory platforms, as well as the 65816. I've done as much as I could with what I have available at this time - both in experience and in compiler functionality. There is a catch, of sorts - effectively implementing an overlay system that swaps code in and out of the CD; it would be easy and map well to the existing system if every code binary was self-contained, but I'm not yet sure if it would be satisfactory.
|
|
|
Post by DarkKobold on Jul 5, 2023 22:55:22 GMT
First, note that the mos24bank(), etc. functions you found are meant to be used for the 65816 - whenever it's fully supported. You can actually use mos24bank() and mos24segment() in the way you're thinking of, though, because of how the LMA is designed. Does this mean this will be used for SNES? That processor stood out to me immediately.
|
|
|
Post by elmer on Jul 7, 2023 14:50:42 GMT
Does this mean this will be used for SNES? That processor stood out to me immediately. I believe that they'd really like to add support for the SNES at some point. At the moment, the biggest problem for LLVM-MOS on both the PCE and the SNES, is that it doesn't elegantly handle having more than 64KB of code or data ... but they're working on that. It *might* be possible to get LLVM-MOS to work with PCEAS in a similar way to KickC, and use that method to get easy-to-use support for large HuCARD or SCD/ACD on the PCE. DarkKobold IIRC you're a GBDK fan ... have you seen that the GBDK folk have pushed to get the SDCC compiler supporting 6502 so that they can use GBDK on the NES?
|
|
lunoka
Gun-headed
Diving into retrodev
Posts: 55
Homebrew skills: art, music
Fave PCE Shooter: Burning angels
Fave PCE Platformer: Ninja Spirit
Fave PCE Game Overall: Valis 3
Fave PCE RPG: Neutopia
|
Post by lunoka on Jul 18, 2023 5:46:01 GMT
I see there is a discord for people working on the compiler & SDK but is there any discord for people using the SDK?
|
|