PeterJ wrote: ↑Tue Mar 27, 2018 7:52 pm
[mention]Seven.FFF[/mention] apart from in your tutorial are there any documents that explains the configuration bits you put before the code?
Yes, for sure. The documentation is distributed on a non-linear fashion between
here and
here.
For a quick start, if you go
File >> New ZX Spectrum (48K) you get a commented template. But let's see. This is what I consider to be the minimum configuration for a new project:
The machine type and feature set to emulate. Corresponds to the options in the dropdown. "48K" or "128K' would be the primary machine choices. Things like "ULA" or "NOROM" would be typical features you could add as a comma-separated parameter. If you pick an option that doesn't exist, and assemble, it will tell you what the choices are.
A lot of the Zeus options can be specified in the UI or in code. Doing it in the UI is obviously simpler and more intuitive, but doing it in the code has the advantage of being able to open, assemble and run multiple projects without having to tweak settings.
If you're compiling pasmo code you'd want to set this to true, as pasmo it's own strange operator precedence rules. Having this not set to match the code you're assembling is a major cause of errors, so I always like to put this into my own projects so I reset back to a good known configuration.
This is also corresponds to one of the many checkboxes on the Config tab.
Just my personal preference; lets you write paths with single backslashes instead of double ones. You don't need to specify it at all, really.
Tells the emulator what PC and SP should be, right at the entry point. Unlike most emulators, Zeus boot the machine and phantom-type LOAD "" command. Instead it loads the initial machine state into memory and magically makes your assembled bytes appear in memory at the correct place(s), before jumping to your entry point. To do this, at the very least it needs to know what PC and SP are.
Conceptially, it's more like what happens at the point you finish loading a .z80 or .sna shapshot. The entire state of the machine is restored, before jumping to the entry point.
There are also other directives to set the registers, interrupt mode and enabled state, current 128K page, etc.
Instead of
Zeus_PC you can also use the pasmo syntax of
END $nnnn at the end of your code. For pasmo, that is an instruction to put a RANDOMIZE USR nnnnn command in the basic loader; for Zeus, it's an instruction for the emulator where to put the entry point.
It might seem like a pointless distinction, but having code injected directly makes 128K development a breeze - literally all eight 16K pages (or in the case of the Spectrum Next, all 223 8K pages!!) are in memory and ready to use right from the getgo, without the user having to write code to export them and merge them with a multipage loader.
Same as almost every assembler. Tells the assembler what address to put the next instruction. Often people only have one org at the beginnning, but you're able to write things like
which will assemble the following code to $2C000. $2C000-$2FFFF is the 24-bit address that 128K page 7 permanently lives at, in the Zeus assembler and emulator. Doing a standard address page by writing to I/O port $7FFD would page page 7 in at $C000-$FFFF as well as $2C000-$2FFFF. The CPU only knows about the addresses between $0000-$FFFF, only having got a 16-bit address bus. But Zeus has it all in there, and keeps track of it. Other emulators do as well, of course, but having programmatic control over everything in both the assembler and emulator is pretty sweet, espectially for RAD stuff.
Code: Select all
output_z80"..\bin\blah.z80", $0000, EntryPoint
output_sna"..\bin\blah.sna", $0000, EntryPoint
output_tap"..\bin\blah.tap", "LoaderProgramName", "Comment", StartAddress, BytesToSave, 2, EntryPoint
output_tzx "..\bin\blah.tzx", "LoaderProgramName", "Comment", StartAddress, BytesToSave, 2, EntryPoint
Makes standard snapshot or tape (mode 2) files.
Where this gets interesting is the 128K/sparse memory scatterloader (mode 3) tape files, for example:
Code: Select all
output_tap"..\bin\blah.tap", "LoaderProgramName", "Comment", StartAddressOfBlock, BytesOfBlockToSave, 3, EntryPoint, BorderColours
output_tap_block "..\bin\blah.tap",StartAddressOfSecondBlock, BytesOfSecondBlockToSave
output_tap_block "..\bin\blah.tap",StartAddressOfThirdBlock, BytesOfThirdBlockToSave
The block addresses are 24-bit, so specifying
$2C000, $2000 for example would load the first half of 128K page 7 directly into page 7. It's handled automatically - all the end user sees is the tape loading, while Zeus's custom loader code would do the necessary paging and copying to stuff everything into the right place.
If there's a loading screen at $4000-$5AFF (loaded with something like this):
then that gets progressively loaded in linear order (compensating for screen thirds) during the load of the rest of the data, like
Halls of the Things did back in the day.