-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feedback from my practical testrun #1
Comments
Just feel free to create issues / PRs with ideas / added test results / documentation / HOWTOs / cleanups / code / whatever
if you think it fits in here. Please keep docs in markdown or text and everything as close to "source form"
as possible.
I intended this to be a couple of fun experiments on C-64 but with parts to be merged back upstream. However, as
already the MMU caching is divergent and it would only get worse with potentially more 8-bit specific optimizations,
I guess semu-c64 will likely stay a fork like it is.
|
Just four ideas/remarks that are quickly written:
|
Could the system be stripped down to somehow boot on a mere 2 MB of RAM? If so, not only would we get closer to an 80s Linux experience (90s as opposed to 2010s), but a Commander X16 port might potentially be feasible (its 65C02 CPU goes up to 8 MHz). |
I forgot that 2 Mhz mode on C128 isn't compatible with REU. |
Coming back to the topic of boot duration: 38 hours and 43 minutes. Timestamps are:
[1] In video at 66 minutes after recording start: https://www.youtube.com/watch?v=JBb90jnPGlY |
Yes, the UART emulation is quite lacking. All I do (if you look in uart.c) is to translate upper- and lowercase for PETSCII-/ASCII-translation. It doesn't implement color escape sequences either, which is why
Ok, I see. I have no real experience with the C-128 (nor with a REU to be honest - I have ordered one (Ultimate 64, which is in backorder) but never owned one :) I developed it all testing it out on Vice, assuming that Vice will be very close to reality. Which apparently, it is :D
The code in this respect is quite modular. Just replace the emulator RAM access functions in
What would you need for easier tuning?
Good question. I actually had to reduce the guest system to fit by tweaking the kernel configuration (and got the Linux kernel down from ~21MiB to ~5MiB), but I do not know whether there are further large optimizations possible on that front. My goal was to get it running at all. Yes, in earlier times, Linux/x86 could boot and run in 2MB (tomsrtbt etc.) but it might well be that you'd need to port an older version of Linux to RISCV for that to happen. In any case, the REU is the emulated RISCV-memory pretty much, meaning that 0x000000 to 0xffffff in REU space directly maps to the "physical" addresses 0x0000_0000 to 0x00ff_ffff in RISCV-32 space. I think it would be a great idea to keep a simple memory map, as this allows to cross-check with the PC implementation which allows to catch some bugs in the emulator before checking on 6502. Furthermore, a simple, direct memory map makes emulated RAM accesses simpler as no additional translation needs to happen, which will likely help performance. With the persistence patch I posted yesterday, the last page (4kiB) of the RISCV memory are taken to save CPU/peripheral state, so the memory map is actually not that simple anymore. But I think it especially makes sense to keep the low memory directly mapped to REU, as simply limiting the available memory to Linux should be enough to keep the guest from misbehaving and overwriting high memory (asssuming that Linux honors all memory settings). Linux simply boots from address 0x0, which is the beginning of the REU, which is then translated to 0xc000_0000 VM space as soon as the MMU is set up (by Linux itself, the emulator just does what it is supposed to). That all said, there is nothing keeping anyone from adjusting the constants to get Sure, this project could be extended in myriads of ways, such as loading compressed REU data from floppy, adding drivers for floppy disks, floppys as cache, network devices, VIC graphics etc. pp.. the ideas are endless ... :D But I think what makes most "sense" is to try to speed it up until it might be at remotely usable with a pre-booted linux state. With response time in hours or minutes for a simple shell command, I think it just stays a completely unusable curiosity. As I said, maaaaaaybe it is possible to get it so that you could edit a text file with the system reacting quickly enough? The very best bet for that would probably to have a native llvm-mos compiled linux that does all far memory accesses through MMU-emulating trampoline code. Then it is not really a "100% MMU" anymore, meaning you could of course do anything with native 6502 code. But it would still catch things like NULL-ptr derefs in pure C code and still give you some sort of virtual memory. As I wrote elsewhere, Linux RISCV32 uses about 95Megacycles to boot now. 95 Megacycles 6502 is about one and a half minutes. HOWEVER, that's just 8 bit and the 6502 is no RISC, coming in at ~3 cycles for each byte that has been processed. So if you just do adds, ands, ors etc. you need at least 15 or so instructions for 32 bit (moving in and out of ZP regs), meaning the 6502 needs at least ~50 cycles for each emulated RISCV instruction, even with perfect binary JIT translation or so (which is a pipedream ...). However, currently, the 6502 sits at about 1500 cycles per RISCV INSN, which seems like massive improvements are still possible. But could you actually use even a 10x faster system? Would you? :D Yes, maybe on 8MHz Commander X16 or so, maybe giving you 80x. But then, again, a native LLVM port would make most sense in the long term IMO. As others have pointed out, there is all kinds of overhead due to the LLVM compilation still. LLVM still routes quite a few accesses through indirect jumps, which seems unnecessary. (It does do an overall great job, however, to avoid that, as far as I can tell with the link time optimizations..). For that, it would probably be a good idea to modularize the code so that the RISCV emulation could run on a single instance of ZP variables (probably using some ugly kludge of lots of #include or so) instead of running on the
That is a bit faster than the boot times I calculated from a kernalemu/fake6502 run (~39.4h). So something might be off there, but maybe also on my side. I thought that my figures are actually optimistic, because Maybe I should emphasize it here, but you can actually compile the code to PC still by setting "C64=0" in the Makefile. You can then simply boot the absolutely identical images that go into the REU on the resulting PC- You can also test the 6502 code with the patched But before going into the details of tweaking 6502 assembly or similar, I think it makes sense to take a high level look at general Linux memory access patterns etc. to guide that. I have instrumented the PC code with instruction and memory traces to get a high level picture where it might make sense to optimize the MMU or memory code (on PC as well). Basically, write a huge file with all virtual and physical memory accesses (fetch, load, store) and then run some hacky Python/numpy code on top to calculate hit/miss ratios for different caching schemes etc. I have ideas with a modular semu on PC which have nothing to do with the C-64 at all, going into the direction of fuzzing, and maybe symbolic execution and similar. What kept me from exploring this direction with the other code that is out there that was the sheer complexity of the software that people developed to do such things on architectures like x86 etc. I really like to be able to understand and read myself and I like simple, non-complex code. I write that here so that you know where I am coming from. |
Thank you for this detailed response that I can read 10 times over the next months and still gain new thoughts out of I guess. ;-) I was reading your project README again and wanted to point out that although it is good to have the changelog at the top of the README I'm missing a project summary at the top of the README that includes the RISC and semu explanation. Basically you could move one or two paragraphs from "Further notes" to the top of EDIT: Same applies for the llvm-mos reference in Thanks. |
Dear @onnokort,
Thank you for mentioning my livestream attempts on your README! I am planning to give you some feedback on my testrun of semu-c64 but as the whole livestreaming action has taken so much time and energy I will only get around to do this in the next couple of days.
I wanted to do a table with timestamps for a start. But didn't have time for this yet.
By the way: If you don't like non-issues to be reported in "Issues" you could also open the "Discussions" tab in Github for more philosophical questions of people interested in this project. But this might only add to the complexity of maintaining this project.
Cheers,
@hpingel aka emulaThor
The text was updated successfully, but these errors were encountered: