Zymosis and ZXEmuT

Struggling with Fuse or trying to find an emulator with a specific feature. Ask your questions here.
Post Reply
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Zymosis and ZXEmuT

Post by ketmar »

hi. just found this site (yes, i am that slow), and thought that i can share my Z80 CPU Emulation library with you.

libzymosis (Zymosis) is a standalone Z80 emulation library that can be used when you need to emulate one or more Z80 CPUs. it has almost-perfect emulation (the only test it failed is SCF/CCF, and i'm planning to [eventually] fix that too), and i used it in my ZXEmuT Speccy emulator.

interesting Zymosis features:
* written in C (yet it may contain some UBs due to integer wraparound and bit patterns, so you'd better compile it with gcc -fwrapv for now; i may fix that later);
* written from scratch, doesn't use code from other projects, and licensed as WTFPL (this is basically means "public domain");
* not table-generated: Zymosis does opcode decoding almost like real CPU could, by inspecting various opcode bits, and using common code for common opcode groups;
* due to the previous bullet, Zymosis is small (only about 50 KB of C source code) and self-contained;
* uses callbacks for port and memory i/o, so you can implement anything you need;
* supports contention tables, so you can emulate contention effects (ZXEmuT can run multicolor software without any problems, for example);
* passes all FUSE CPU tests;
* comes with small supplemental library to ease code analysis (determine if opcode does any memory/port IO, is conditional jump, and so on).


ZXEmuT is ZX Spectrum emulator based on Zymosis. i don't think that it is that interesting by itself (it was written mostly as a testbed for CPU emulator), it is not very user-friendly (and GNU/Linux only), but it is quite capable:
* can emulate 48K/128K Spectrums (with memory contention);
* emulates Pentagon (and partially Pentagon border effects);
* supports Beta-Disk emulation;
* has built-in debugger.
yes, nothing really special here, but hey, it works!


i consider both projects as "mostly finished" (i.e. no major new features are planned). still, you may be interested in (fairly) small, but feature-complete Z80 CPU emulator for your projects.


p.s.: oops. just noticed that i forgot to link source code repository. the link is in my signature, of course, but just in case somebody turned signatures off... ;-)
User avatar
utz
Microbot
Posts: 113
Joined: Wed Nov 15, 2017 9:04 am
Contact:

Re: Zymosis and ZXEmuT

Post by utz »

Ah yes, I studied Zymosis quite extensively when I wrote my own z80 emulation library a few years ago. It's an excellent piece of code. Glad to see you're still working on it.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

thank you! i'm basically just playing games with ZXEmuT these days (and as you can see i never really put my hands on fixing SCF/CCF emulation), so not much work is going into the code. but Zymosis is "feature complete" anyway, and ZXEmuT is pending Yet Another Rewrite (as i am not happy with the architecture).

i also ported Zymosis to D, but managed to break MEMPTR (and prolly something else) along the way. ;-) despite that, DZXEmuT (D rewrite) is working quite good.

p.s.: oh, i forgot about liburasm! as i can't append it to the starting topic, i'll do it here.

in the repository you can also find liburasm, table-driven assembler/disassembler library. it is "UR" becase it was inspired by the code from Unreal Spectrum, but i ended up creating the table (and all the code) from scratch. you can use it to easily add disasm dump and asm input to your Z80 debuggers.

also, there is slightly newer version of the library in my standalone assembler project UrAsm. i used that assembler to (cross-)write some Speccy software. it doesn't have macro support, but does have support for forward/backward labels (a-la fasm), and local labels (".name:"). it also has simple "module" system: modules exports all their non-local labels prefixed with module name. it also can generate relocatable code (along with fixup table). of course, it is absolutely undocumented, so i doubt that anybody will find it useful, but who knows? ;-)
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

so, i fixed SCF/CCF bug (it was actually a bug in interrupt acknowledge code) -- now Zymosis pass all z80test tests!

i also removed C UBs (i hope), so the code should be standard-compliant. and replaced conditional checks in branch/call opcodes with branch-less computations.

thank you all for this forum, without it i would prolly never return to Speccy coding again. ;-)
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

and just for fun, i added ZXNext Z80N support to liburasm (and to UrAsm assembler).
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

added disassembler library to Zymosis. it is based on the same instruction decoding logic as Zymosis itself, so it is only 20 kb of source code, and quite fast. now you can skip importing heavyweight liburasm if you only need to show some disassembly in your debugger.

it lives in separate source file, so if you don't need it, you can simply copy "zymosis.h" and "zymosis.c" to your project, ignoring other libzymosis sources.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

oh, it's fun to code for Speccy again! while experimenting with various game engine ideas, i fixed several bugs in UrAsm assembler, added label file output from UrAsm and loading labels to ZXEmuT (yeah 8-years-back me did his coding without that), added some colors to ZXEmuT debug window, added tstate counter, upgraded WD1739 emulator to the actual version from SAM style, fixed bugs in SZX loader, and so on.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

added simple ZXEmuT console command reference. ZXEmuT is fairly advanced emulator, but it is hard to know, because the only way to control it is built-in command console! ;-)
User avatar
utz
Microbot
Posts: 113
Joined: Wed Nov 15, 2017 9:04 am
Contact:

Re: Zymosis and ZXEmuT

Post by utz »

Is it possible to control ZXEmuT through stdin? If so, I could actually use it as an alternative to MAME in my Bintracker music editor.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

utz wrote: Sat Jul 04, 2020 9:42 am Is it possible to control ZXEmuT through stdin? If so, I could actually use it as an alternative to MAME in my Bintracker music editor.
no. but it has full-featured Jim Tcl interpreter, and it can load external scripts with "load" console command. you can also execute any console command from CLI using quake syntax, i.e.:

zxemut +quit

will immediately quit. ;-)

there is also undocumented feature to control ZXEmuT from Z80 code:

Code: Select all

  defb #ED,#FE  ; ZXEmuT trap code
  jr .skipdata
  defb controldata
.skipdata:
for other emulators this will do nothing, but ZXEmuT will detect this, and will execute some commands. for now, there are only very simple commands to activate debugger and pause/unpause the emulator, but i can add other commands if you'll need them.

p.s.: if you need some special feature, just ask here. i'm ok with adding features people may need (if it is not too hard ;-).

p.p.s.: ah, i see. you want ZXEmuT to run in background, and to control it from your app? this is doable too, but i prefer to use some named pipe or unix socket for that. unix socket will be the best choice for me. if it's ok, i can add unix socket interface, so you'll be able to send console commands with it.

p.p.p.s.: ;-) ZXEmuT is using BlipBuffer to render sound (the same code that is used in FUSE), so i believe that speaker sound quality is quite good.
User avatar
utz
Microbot
Posts: 113
Joined: Wed Nov 15, 2017 9:04 am
Contact:

Re: Zymosis and ZXEmuT

Post by utz »

A Tcl interpreter, you say? Excellent! That should be quite workable.
I'm controlling MAME through a stdio pipe. I could in theory do sockets, but it needs to work on Windows as well, so pipe is easier to do for me, I believe.

One feature that would be great to have is to be able to execute code on debugger breakpoints, so I can call back to the main app when certain breakpoints are hit. I guess that's what the trap code is for, but that's not feasible for me since I'd need handle this in Bintracker's compiler, which is supposed to be agnostic of the emulation back-end. I assume it'd be a lot of work to add a more general solution to ZXEmuT, though. Probably not worth it, at least not at this point. For the basic stuff I can get by without it.

Anyway, this will take some time since there are many other things in Bintracker that need to be finished first, but now that you said the magic T-word :mrgreen: I'm definitely interested in doing this at some point.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

utz wrote: Sat Jul 04, 2020 11:38 am but it needs to work on Windows as well
oops. ZXEmuT is GNU/Linux only. i may make it work on windows, but it will be mostly useless, as there will be no sound. ;-) when ZXEmuT is compled with sound support, timing is done by sound card queries. while i can rewrite it to use winmm timer, it will take some time.
utz wrote: Sat Jul 04, 2020 11:38 am One feature that would be great to have is to be able to execute code on debugger breakpoints, so I can call back to the main app when certain breakpoints are hit. I guess that's what the trap code is for, but that's not feasible for me since I'd need handle this in Bintracker's compiler, which is supposed to be agnostic of the emulation back-end. I assume it'd be a lot of work to add a more general solution to ZXEmuT, though. Probably not worth it, at least not at this point. For the basic stuff I can get by without it.
it is not hard to call Tcl command instead of opening the debugger when breakpoint is hit. actually, that feature was planned, i just didn't implemented it yet. the whole idea of embedding Tcl is that people could use it to automate any tasks they want. that's why all console commands are actually Tcl functions, and most of them returns some meaningful values. the API is not documented yet, but basically Tcl has full control over the emulator.
utz wrote: Sat Jul 04, 2020 11:38 am Anyway, this will take some time since there are many other things in Bintracker that need to be finished first, but now that you said the magic T-word :mrgreen: I'm definitely interested in doing this at some point.
no problems. ;-) i will happily add the features you need. windows may be the problem, tho, 'cause i don't have windows, and my windows programming skills are very... rusty. but there is some hope still... ;-)
User avatar
utz
Microbot
Posts: 113
Joined: Wed Nov 15, 2017 9:04 am
Contact:

Re: Zymosis and ZXEmuT

Post by utz »

On second thought, it actually doesn't need to work on Windows. MAME will stay the default for Spectrum emulation, with ZXEmuT being an additional option. Windows users will miss out on it then, but well, tough luck :D

If you could implement calling Tcl code on hitting breakpoints, that would be awesome. But as I said, take your time, I'm still a few months away from adding additional emulation backends.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

utz wrote: Sat Jul 04, 2020 1:02 pm If you could implement calling Tcl code on hitting breakpoints, that would be awesome. But as I said, take your time, I'm still a few months away from adding additional emulation backends.
i already did it. ;-) you can now either process a breakpoint with Tcl code, or leave it to ZXEmuT to process. i also added Tcl API to manupulate Z80 registers (including PC and MEMPTR). now i only have to document it (and add some more API; but remember that all console commands are Tcl procs! ;-).

actually, there is no "direct console command execution" at all there: to execute console command, ZXEmuT calls "conexec" Tcl proc (which you can override). so the console is extensible from Tcl code too. and of course, you can directly execute Tcl code from console by prefixing it with a dot.
User avatar
utz
Microbot
Posts: 113
Joined: Wed Nov 15, 2017 9:04 am
Contact:

Re: Zymosis and ZXEmuT

Post by utz »

Ha, you're a machine. Thanks a lot. I think with this setup, only minimal changes will be required on the Bintracker side, as I can send pretty much the same messages that I'm sending to MAME. Just need to write a Tcl script to decode them on ZXEmuT. That'll be fun.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

it was easy. the feature was planned from the beginning, so it was only a matter of writing several lines of code. ;-)

also, i added `proc usock_received {args}`, so you can process received commands without rewiring the console command handler.

also, "--usock -" can be used to read commands from stdin.

i will prolly document it all later. as you said that you're not in hurry right now, i will prolly play with this little more before finalising it. yet you can clone Zymosis repo at any time to test it out.

feel free to make additional feature requests when the time will come. ;-)

p.s.: ZXEmuT is still "one-user project" anyway -- while it has very rudimentary "jam install" option, it won't really work right. it will install the files, but ZXEmuT will not know where to find them. ;-) i pretty much dropped Speccy coding for years, and ZXEmuT was on hold too. i only resumed its development after i found this forum, so alot of things are not finished yet.

also, you can use any capitalisation you like. "zxemut" is fine too, or "ZXEmut", or even "zXeMuT". it is "EmuT" because it was "ZX Emulator Test", developed to test Zymosis. but the name stuck. ;-)
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

i added +3DOS support to ZXEmuT. only +2A model for now (started doing +3 model, but it doesn't work yet for some reason ;-). still, it is now possible to load DSK files. yay. now i can start adding +3DOS support to dsForth. ;-)
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

also, i removed half-finished Widgets Tcl API, and created much simplier "UI Overlay" API. internally, ZXEmuT has no widgets, it uses a simple canvas ("virtual overlay" in terms of its videosystem), on which you can draw pixels and text, and then it blits that canvas to the emulated Spectrum screen. yeah, it means that UI is restricted to 320x240 pixels, but i'm ok with it right now. it can be changed later if necessary.

anyway, overlay API is much simplier, and can be used to create various tools with Tcl. it is already used to integrate simple sprite viewer/exporter tool, but the possibilities are endless, because Tcl has access to most of the emulated machine internals. i will also export asm/disasm to Tcl, to ease writing various code analysis tools.

of course, one can use overlay API to create traditional widget-based UI too -- it can be easily written in Tcl.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

added alot of sanity checks to libfdc API, documented API a little, and almost done with +3DOS disk file i/o (not .dsk images, but files inside the images, on +3DOS file system).

ah, what is libfdc? (standalone ;-) part of ZXEmuT: WD1793/uPD765 emulator. it can also read and write alot of disk image formats, and have some simple API to access TR-DOS and +3DOS file systems.

libfdc is heavily based on the code written by SAM style for Xpeccy (thnx alot!), but i cleaned it up, created slightly better API, added at least several lines of comments to API calls and so on. emulated FDCs are working in nanosecond precision (at least this is what library is using to advance emulation ;-).

one emulated disk interface contains 4 floppy drives, and you can create alot of disk interface objects if you want too. you can also create standalone "floppy disk" object if all you want is read/write/modify disk images. if you need to add TR-DOS/+3DOS support to your emulator, libfdc may be what you are looking for. only $0.00!

p.s.: it depends only on libc, as usual.

p.p.s.: 'i consider both projects as "mostly finished"'. haha. ketmar's funny quotes.
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

just for fun, two screenshots of ZXEmuT in action:
debugger
Spoiler
Image
control console. you can see alot of loaded Tcl scripts there... ;-)
Spoiler
Image
User avatar
ketmar
Manic Miner
Posts: 610
Joined: Tue Jun 16, 2020 5:25 pm
Location: Ukraine

Re: Zymosis and ZXEmuT

Post by ketmar »

short news: replaced old libfdc with brand new libfusefdc. the code was exctracted from FUSE, and turned into standalone library; after that it was augmented with my modules to read/write TR-DOS and +3DOS file systems. libfusefdc has better emulation (all programs which refused to work with old libfdc are perfectly working now), and it also can be compiled without FDC emulation support, and used as a library to convert between different image formats, and work with TR-DOS/+3DOS disk images (list, extract, add, delete* files). also, no installed libspectrum needed, nor zlib (the code contains optional miniz deflate implementation).

there is experimental "turbo FDC" mode too, which reduces most delays. majority of programs (included protected +3DOS software) seems to work with this mode enabled. but of course, "turbo mode" can be toggled in runtime.

* deletion is only partially supported yet.
Post Reply