Zeus assembler - code generation?

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
animaal
Microbot
Posts: 101
Joined: Sat Mar 09, 2019 5:14 pm

Zeus assembler - code generation?

Post by animaal »

I'm using the Zeus assembler to build a little program. It's about 3K in size so far.
The code runs works fine in Zeus' built-in emulator.
When I assemble it, the generated Z80 file won't work with Spin or Spectaculator.
The Z80 files load, but the results are corrupted. sometimes, I see a few of the graphics appear before the spectrum crashes hard.
For any particular z80 file generated, the results are identical in Spin and Spectaculator.
Generating TZX files produces similar results.

The code below shows the top of my main ASM file.
Can anybody please tell me what I'm doing wrong? I'm sure it's something simple but I don't see it.
Thanks.

Code: Select all

zeusemulate "48K"
Zeus_PC=Start
Zeus_SP=$0000
output_z80 "testapp.z80",$0000,Start

org $C350  ; 50000

attr_start equ #5800
stepsize equ 4
TIMER equ 23674



Start: di
       im 1
       ei
       ...
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Zeus assembler - code generation?

Post by djnzx48 »

Hmm, it works alright for me, in both Spin and Spectaculator. What version of Zeus are you using? Could it be the rest of the code that's affecting it? Does it work if you remove everything but those top few lines from the source?
animaal
Microbot
Posts: 101
Joined: Sat Mar 09, 2019 5:14 pm

Re: Zeus assembler - code generation?

Post by animaal »

Aha, problem solved. Or at least identified.

In my code, I had quite a few instances where I tried to increase HL by using e.g.:
ADD HL, 224

Zeus translates it to "ED 34 E0 00", which indicates that it's an extended instruction with extended opcode 34. This is not a valid instruction for the Spectrum, but is valid on the Spectrum Next.

So I'm trying to use Spectrum Next instructions on a 48K Spectrum, and only the embedded Zeus Spectrum emulator (or a Spectrum Next) could execute it.

Thanks for the suggestions.
dfzx
Manic Miner
Posts: 677
Joined: Mon Nov 13, 2017 6:55 pm
Location: New Forest, UK
Contact:

Re: Zeus assembler - code generation?

Post by dfzx »

animaal wrote: Sun Mar 10, 2019 11:51 am Zeus translates it to "ED 34 E0 00", which indicates that it's an extended instruction with extended opcode 34. This is not a valid instruction for the Spectrum, but is valid on the Spectrum Next.
Dumb question from the uninitiated: why would an invalid Z80 instruction work on a Spectrum Next? I haven't really followed the Spectrum Next story, but isn't a Z80 a Z80?
Derek Fountain, author of the ZX Spectrum C Programmer's Getting Started Guide and various open source games, hardware and other projects, including an IF1 and ZX Microdrive emulator.
animaal
Microbot
Posts: 101
Joined: Sat Mar 09, 2019 5:14 pm

Re: Zeus assembler - code generation?

Post by animaal »

My limited understanding is that the Spectrum Next is new hardware. The processor is a programmed FGPA rather than being a true Z80 chip. It's programmed to act like a Z80, and behave like a true Z80.

Since it is a relatively powerful device, acting like a Z80, the capability exists for the designers to extend it (e.g. increase its speed, add instructions), and that's what was done. It's backwards-compatible though, so a Spectrum game can still run on it.
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Zeus assembler - code generation?

Post by djnzx48 »

Wow, interesting. I'll have to watch out for that. I know there's an option to prevent extended instructions from being used, but I think it disables more sensible instructions like the ones operating on IXH and IXL, which you would usually want to have available.
User avatar
Seven.FFF
Manic Miner
Posts: 744
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Zeus assembler - code generation?

Post by Seven.FFF »

Yes, the Next has a smattering of Next-specific extended opcodes, all starting with the $ED prefix, chosen for compatibility because they execute as NOPs on a standard Z80.

They're chosen strategically to support some of the Spectrum Next features, such as calculating the screen addresses quickly and easily without worrying about row and screen third boundaries, drawing a single pixel strip down the side of the display after doing sideways hardware scrolling in the 256-colour mode, making uberfast jump tables for the streaming SD card feature, a bunch of LDIR variants with selective copying to support transparency and stenciling, and fast writes to registers (which are the Next's internal version of I/O ports for hardware and feature control, that aims to reduce clash with existing I/O ports). A few other more general things are also added, such as barrel shifts, fast 16 bit adds, fast 8 bit multiplication, etc.

Strategically, because only ones that could be implemented using a small amount of FPGA space were considered. Other perhaps more obvious extensions, like some found in the Z380 or Rabbit next-gen Z80s, weren't considered because they were space hogs.

So the Next has a quirky extended instruction set, mostly driven by developer feedback rather than being a grand unified design. A few people have criticised this, and it's broadly valid criticism. But rightly or wrongly, it's part of the Next's ecosystem now, and it's resulted in better released and WIP software, that really pushes the envelope. Standard Z80 code works 100% as expected, including all undocumented opcodes, but invalid opcodes that would produce NOPs might not. You'd really have to go out of your way to write a NOP that way on purpose in standard Z80 code, although of course anything's possible.

There will be an alternate FPGA core available that implements only standard Z80 and standard Speccy features, if people feel strongly enough to use that instead. And of course people can make their own core versions including mods of the official Next core. The mult-core nature of the Next means that switching cores for a particular task will be pretty quick and straightforward, so hopefully it's win/win and everyone is happy.

Having Zeus allow Next instructions when not in Next configuration was a temporary oversight, I recall, corrected by Simon in the latest test (bleeding-edge) versions. He doesn't generally publicise those, but I can attest the version at http://www.desdes.com/products/oldfiles/zeustest.exe seems as stable as the last official release.

Image
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Zeus assembler - code generation?

Post by djnzx48 »

Yes, I suppose that's one of my main criticisms of the Next ;) Some of the instructions they added seem really random with oddly specific behaviour. It does feel as though they were just added whenever somebody wanted an instruction for something, rather than designing them for general purpose use.

And some of the instruction timings seem a bit unrealistic. According to the wiki, MUL is a two-byte instructions that runs in 8 T-states and multiplies two 8-bit numbers. Assuming it takes 4 T-states to read the instruction prefix, that only leaves 4 T-states to read the opcode, perform the multiplication, and put the result back into the DE register. Which seems a little unfeasible on an 8-bit CPU? It's as if these instructions are doing some 'magic' to compute values faster than would normally be possible.

Oh well, this discussion has probably been done to death already, and it's too late to change things now. So we'll just have to accept that they're in there.
Seven.FFF wrote: Thu May 16, 2019 3:11 pm Standard Z80 code works 100% as expected, including all undocumented opcodes, but invalid opcodes that would produce NOPs might not.
Not according to these tests ;) Or have they fixed the inaccuracies by now? At least the Z80 core can be modified to fix bugs and add/remove instructions, so it isn't as big of a deal as if the hardware were static.
User avatar
Seven.FFF
Manic Miner
Posts: 744
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Zeus assembler - code generation?

Post by Seven.FFF »

The instructions are realistic in the sense that they’re implemented as fast as is possible with a 28MHz master clock and an extra 4Ts for the prefix fetch. Things can happen on every rising and falling edge of that clock, which the Z80 designers did not have access to in their design. They had four times fewer edges, and more limited internal space.

Is there really any point in artificially slowing them down to make them authentic to something that didn’t actually exist in the 70s?
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Zeus assembler - code generation?

Post by djnzx48 »

You're right, I guess there's no particular reason. But the more of these 'magic' instructions they add, it starts to look less like a Z80 and more like one of those fantasy architectures that only exist in software.

The new instructions are also inconsistent. Why is there OUTINB but no OUTDNB? Why PIXELDN but not PIXELUP? Why does TEST only operate on immediate values?

I get that these instructions are needed to make proper use of the new hardware and screen modes. But it doesn't seem like the most elegant solution.
User avatar
Seven.FFF
Manic Miner
Posts: 744
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Zeus assembler - code generation?

Post by Seven.FFF »

It isn’t! What’s already been added will
Stay for compatibility, and new instructions will be considered in a more unified way.

This is actually real hardware, not fantasy software, btw. I have one sitting on my desk right here, and I promise it is pure hardware:))
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Zeus assembler - code generation?

Post by djnzx48 »

Yeah, I know that it's real ;) I was just making a comparison.

Good to know that the current instruction set is fixed. It'd be a pain for compatibility if stuff kept getting changed.
User avatar
Seven.FFF
Manic Miner
Posts: 744
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Zeus assembler - code generation?

Post by Seven.FFF »

The philosophy so far has generally been to make things easier for newcomers to make programs and get involved, by pragmatic means. Jim will be happy to tell you this at length if you get talking to him.

I realise that there is also a competing purist approach, where people get satisfaction from recreating life in the 80s and living authentically. But if you look at the progression of the Sinclair, Timex, Amstrad, MGT and later Russian clones, nothing really ever stood still. The whole thing was a continuous progression of new developments with sometimes slightly flawed back-compatibility.

Any of those designers in the moment would find “future us” telling them their particular iteration is the one true authentic holy relic as very odd indeed :)
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
Seven.FFF
Manic Miner
Posts: 744
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Zeus assembler - code generation?

Post by Seven.FFF »

Yeah, it has to be fixed, because people started releasing physical games on SD early on, and tons of people have bought them.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
RMartins
Manic Miner
Posts: 776
Joined: Thu Nov 16, 2017 3:26 pm

Re: Zeus assembler - code generation?

Post by RMartins »

Seven.FFF wrote: Fri May 17, 2019 1:50 am The instructions are realistic in the sense that they’re implemented as fast as is possible with a 28MHz master clock and an extra 4Ts for the prefix fetch. Things can happen on every rising and falling edge of that clock, which the Z80 designers did not have access to in their design. They had four times fewer edges, and more limited internal space.

Is there really any point in artificially slowing them down to make them authentic to something that didn’t actually exist in the 70s?
But if new very fast instructions are being implemented using all the features of the FPGA, why then just the new instructions get this treatment ?
Specially, if there is going to be 2 distinct implementations, one that is pure Z80, and one that is not.

Probably for retro compatibility, in timing critical code, on old games.
But this seems like an exercise in trying to please everyone, without actually fully pleasing anyone.

This is starting to look more and more like the old days of Javascript Browser wars.
The ZX Next, is a moving target ... you never know if your game will run, in the next iteration ...
User avatar
Seven.FFF
Manic Miner
Posts: 744
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Zeus assembler - code generation?

Post by Seven.FFF »

You do, because backwards compatibility with earlier Next cores is being strictly maintained.

The early games that were published well over a year ago still work, no breaking changes are deliberately made, and every core build is tested quite rigorously against existing software to guard against accidental regressions or bad builds.

It’s not rocket science to do it this way and get it right, despite what you’re suggesting.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
User avatar
Seven.FFF
Manic Miner
Posts: 744
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Zeus assembler - code generation?

Post by Seven.FFF »

And yes, the original Z80 instructions have to be 100% timing critical, as does the other virtual hardware like ULA, divMMC, multiface, etc.

People are wanting these machines precisely because there are an exact number of Ts per line and lines per frame, with known instruction timings, for all the models that are simulated. And they’re wanting esxDOS to run just like it does on a physical divMMC, etc. Which it all currently does.

Slipping a perfectly Zilog-accurate Z380 in there might fit somebody’s purist idea of how a Z380 should behave, but for timing reasons it ain’t going to run Spectrum games and the machine is not going to behave as a Spectrum, even though the instruction set is binarily back-compatible.

Adding a small number of individual extra instructions that expedite working with specific hardware does nothing to detract from meaningful Z80 compatibility or Spectrum compatibility, OTOH.

For the entire lifetime of the Spectrum, additional hardware has always used custom mechanisms to talk to it, be that I/O address mappings, RAM address mappings, RAM/ROM execution traps, NMI, magic opcode sequences, magic BASIC variable usage, etc. All mechanisms have always had the potential to fail in environments where the hardware isn’t present, or to be theoretically incompatible with other hardware when the two hardware designers hadn’t considered mutual compatibility. Or when some earlier dev accidentally strayed into the control mechanism of a later piece of hardware like the Stampers did with the 128K paging port. Yet the entire affair has largely remained a non-issue for decades apart from a few edge cases.

You’re not obliged to use instructions, or the divMMC, multiface, RTC, UART, or NextBASIC if you want to stay living in 1982/1985/1987. Just as it should be. And quite honestly, the Next will still serve you well, and you wouldn’t know or care custom features were there if somebody hadn’t told you they were.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
szilvasyz
Drutt
Posts: 3
Joined: Thu Dec 12, 2019 1:00 pm

Re: Zeus assembler - code generation?

Post by szilvasyz »

Hi All,

I am new here, so please forgive me if my question is not at the most appropriate place, but I could not find better.
So I am working on hardware test program for a specific Z80 based microcomputer in order to help starting/troubleshooting the machine after building it from scratch.
One of the first test steps is checking if reading the ROM are is working without errors. I thought to write a macro to populate all the ROM area with pseudo-random data beyond my test code (this is already working), and my test code should read all ROM data for calculating somewhat CRC or similar and comparing it to a stored copy. My only problem is how I can generate such a CRC or other checking value with Zeus in compile time for example into the last 2 bytes of my ROM area. I see the main difficulty in calculating the checksum with also the compiler generated machine codes at the beginning of the ROM (the pseudo-random filled areas can be calculated within the macro that fills it).

Have you got any idea to solve the problem?

Thank you in advance,
Zoltan
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Zeus assembler - code generation?

Post by djnzx48 »

You could try using the two built-in functions, XOR_MEM and SUM_MEM for simple single-byte checksums. They take two arguments, the start address and the length of the memory area to be checksummed, and return the bytes XORed or ADDed together respectively.
szilvasyz
Drutt
Posts: 3
Joined: Thu Dec 12, 2019 1:00 pm

Re: Zeus assembler - code generation?

Post by szilvasyz »

djnzx48 wrote: Thu Dec 12, 2019 10:11 pm You could try using the two built-in functions, XOR_MEM and SUM_MEM for simple single-byte checksums...
Thank you very much, it might be useful. However, byte wide XOR and ADD do not perceive order of the bytes, therefore swapping of memory areas cannot be detected (for example swapped 2nd and 3rd 4k ROM within the 4x4k ROM area). I will think about how I can utilize these functions for my purpose.
User avatar
djnzx48
Manic Miner
Posts: 730
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Zeus assembler - code generation?

Post by djnzx48 »

If the basic checksum algorithms aren't enough, I suppose you could use XOR_MEM and SUM_MEM with a length of 1 to read individual bytes from memory, and utilise them in a loop to calculate a proper CRC. Or if ADD/XOR based checksums are adequate, calculate checksums of the four memory regions separately and store those.
szilvasyz
Drutt
Posts: 3
Joined: Thu Dec 12, 2019 1:00 pm

Re: Zeus assembler - code generation?

Post by szilvasyz »

you could use XOR_MEM and SUM_MEM with a length of 1 to read individual bytes from memory, and utilise them in a loop to calculate a proper CRC
It is a brilliant idea [thumbs up]
calculate checksums of the four memory regions separately and store those
Yes, the actual workaround had been programmed exactly this way. It works perfectly.
Post Reply