-
Notifications
You must be signed in to change notification settings - Fork 171
-
Notifications
You must be signed in to change notification settings - Fork 171
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
z80asm: implement zx next opcodes as z80n (was: serving fpga z80 variants) #312
Comments
Yes. I'm currently working on the full Rabbit implementation, and it would be easy to add a new cpu-type to the input files. You can have a look at the still incomplete parser generator: |
So it's possible to do in mainline z80asm now? Then the assembler invoke would be "z80asm --cpu=cpuname". Have you thought of any naming to accommodate these devices? Maybe "z80asm --cpu=z80-zxn" (z80 variant of zx next). |
Yes. Give me a couple of days. I agree with your suggestion for the naming. I assume this z80-zxn CPU does not have any of the z180 and rabbit opcodes and it has all the undocumented z80 opcodes. Correct? |
Yes everything z80 is in there, it's just the additional instructions and ones yet to come. |
Just a note:
|
And, we're clear to use the The |
Yes z80asm has separate tables for z80, z80-zxn, z180, r2k and r3k. |
Another update... sorry this may be a frequent activity now but people find it helpful to get it in.
This post gives an example dma program and this link gives technical information. |
Any chance of an ld hl,(sp+dd) - that would be really useful. And yes, swapping round to use dehl would allow us to use it without an ex. |
They've changed the order to DEHL for us, very nice :) I'll update the instruction list above.
It sounds like they are open to that too. What is missing really? ld r,(sp+d) ld ix,sp ;; mirrors ld hl,sp already added add sp,nn |
That's brilliant. Creating a zxn_rules.1 along the lines of the rabbit version should be easy and allow us to use some of those opcodes in a trivial way. From the rabbit file there's these extra addressing modes that are useful for C code: ld hl,(sp+n) - n unsigned byte Supporting the other pairs instead of hl would be useful, but not hugely critical really. From the rabbit file, it looks like I made quite a lot of use of bool hl, this basically turns hl into a boolean and sets flags. Thus a comparison to zero is easy and a true boolean value is yielded. In the rabbit world, this is a single byte opcode which makes it particularly efficient. These are useful: and hl, de So: and|or|xor hl,NNNN to cut out the ld de,NNNN neg hl |
I've checked in a zxn_rules.1 file, but not hooked it in as of yet, you'll need to add:
to the zxn.cfg. Test file attached to show it working (probably only with sccz80 at the moment) |
There is only one emulator currently that is accepting the opcodes and it's only a partial emulation so I think we should wait a bit before enabling the opcodes outside the assembler. |
@pauloscustodio Any chance the new list up there can be included soon? A complete emulator (ZEsarUX) is going to implement the instructions so once that's there, I think it's safe to enable them in the entire toolchain. |
I'm on it...
|
I've committed the change to implement the current opcodes. |
We don't have any control of the opcode names... they should probably conform to existing instructions on other z80 derivatives where they are the same but all we can do is suggest. test should be tst (z180) I'm not sure if there are any others in there. |
I've committed the following variants of z80-zxn opcodes:
|
New instructions that would help most directly would include stack relative addressing. I looked at two sources for inspiration:
https://github.com/z88dk/techdocs/blob/master/rabbit/RabbitInstructions.pdf
See Appendix B page 228 for an alphabetical listing: Instructions that would help most for the c compilers, given constraints:
ld ix,sp more important if stack relative addressing isn't possible:
In the above "d" is a two's complement 8-bit number but "n" the rabbit constrained itself to these but the z380 goes whole hog andw hl,de negw hl The rabbit added this: bool hl (or rp) to convert non-zero value to 1. If you can wait another week I will be rewriting the integer math so maybe BTW, the "TEST" instruction seems to be the same as "TST" for z180 and later. |
A couple of new instructions also added to the main list above:
ldirscale is going to scale a source graphic up or down in size. If DE' > 1 then there will be an exploding effect in the destination (pixels will be skipped). ldpirx is intended as a pattern lookup for fills. |
The Z180 multiplication instructions also were quite useful in SDCC (or having at least one of them, preferably the one for hl). After all, often an 8x8->16 multiplication is sufficient. It seems even more useful than the 16x16->32 Rabbit one, since the 16x16->32 makes too many registers unavailable for other purposes. Philipp |
They have the one for de only, is that still useful without excessive shuffling to hl? We've started on some integer multiplies for the target library here. I would like to see them bring in signed versions of some of these instructions (add hl,a ; mul d,e) and return of the 16x16->32 bit multiply they dropped due to limited fpga space. But this is not likely to happen from the core team itself - more as a proposed patch from reviewers - so whether it will or can happen is a question. |
Where can I find the instruction set? mlt de is fine, the advantage of mlt hl over mlt de should be very small. Philipp |
The most accurate information is in z88dk. The wiki is maintained by the community who don't keep up / have access to some of the information. |
So here's my comment on the instruction in #312 (comment) from a compiler writer perspective (SDCC). I'll comment on how useful I consider the new instructions, and suggest to rename some (since they already exist in other Z80-derivatives under a different name). I will make a later post with suggestions for additional instructions.
This one is useful for speeding up some shifts. SDCC already emits this instruction for gbz80. For consistency with gbz80. I suggest to rename this instruction "swap" (as it is called on the GameBoy).
This one is very useful. Both for the very common 8x8->16 multiplications (either explicit or for array addressing) and as building block for the support routines for wider multiplications. SDCC already emits this instruction for z180. I suggest to rename this instruction "mlt de" (as it is called on the Z180).
I do not have experience with such instructions. But I believe they will be useful, e.g. for using an 8-bit index into a char array.
I don't see much point in those. The only point is reducing register pressure a bit. I don't see a godd use case in SDCC that benefits from not setting flags. So those are not really an advantage over something like
Which is the same code size as the first proposed new instruction, and via ex de, hl can also be used instead of the second proposed new instruction at just one byte of extra code size.
This one seems a bit more useful, since transferring the addition result from hl to bc would take two bytes. However, I again don't see an advantage for not setting flags. In fact, if this one would set flags (or wouldbe changed to adc) it could be even more useful as a building block for 32- and 64-bit additions.
I can see the point in this one, even though SDCC would not emit it (but it looks good for use in asm code).
I currently do not see the point in those. They look like made for some specific use case that I do not know about. Do they really just skip a byte if it is A (if they stopped instead they might be useful for string processing)?
Those don't look that useful to me. I can see that mirroring bits is hard to do without them in the Z80 instruction set. But the need for mirroring bits is very rare in my experience. And SDCC would not be able to detect C code mirroring bits easily, so it would not emit those.
I don't see much point in this one. The only advantage it provides is reducing register pressure. Otherwise it provides no advantage over
Which is also just 4 bytes of code.
I don't see the point at all.
Does exactly the same at exactly the same cost in code size.
Looks like stuff specific to the peripherals of the device. Is it really worth using opcodes as opposed to some I/O location?
This can be useful for some code, but such code is not that common. SDCC already emits this instruction for z180. I suggest to rename it "tst" (as it is called on the Z180). Summary: Great, very useful in SDCC: Useful for SDCC: Marginally useful for SDCC: Nearly useless for SDCC: |
Having worked on various SDCC backends, including all z80-related ones (gbz80, z180, r2k, r3ka, tlcs90) I noticed some instruction being particularly useful, and making a big difference in code size and code speed. In particular, there are some instructions in the Rabbit that are used by SDCC resulting in much lower code size for the r2k/r3ka backends vs. the z80 backend. If possible, I'd like to see some implemented in the zxn. ld hl, (hl+NN) Load hl with the value at the address sum of hl and an 8-bit offset (unsigned is preferable but it deosn't matter much). ld (sp+N), hl The ix variant is essentially an alternative to the sp variant. Implementing both probably doesn't make that much sense. These instruction are present in the Rabbit. For C, variables (and function arguments) that cannot be allocated to registers are placed on the stack. Using ix as a stack pointer is an okish way of accessing the stack for 8-bit variables, but it still comes with too much overhead. These instruction allow efficient transfer of 16-bit values between registers and the stack. bool hl This instruction present in the Rabbit casts the value in hl to bool and sets the flags accordingly (the z flag is what really matters). sex gg This instruction (not implemented in any of the architectures currently supported by SDCC) would for an 16-bit register gg, sign-extend the value in the lower 8 bits into the full 16-bit register. Even having this instruction for just one register pair out of hl, de, bc would be very useful. add sp, d This instruction present on the Rabbit adds a signed 8-bit value to the stack pointer. Philipp |
I've just done a quick test on how often some of the proposed instructions are actually used by SDCC (by compiling the SDCC regression tests for gbz80, z180, r2k). Of course for the total effect one needs to consider more than just their frequency (after all, a rare instruction could save a lot of code at each of the few places where it can be used). Still the data seems helpful. tst [z180]: 2 Philipp |
The special instructions:
are specifically for games and graphics. The ldix-family of instructions is for copying graphics while skipping over transparent bytes, ldirscale is for exploded sprites - the additions are implementing fixed point adjustments to display position and source address. mirror is for reversing images, pixeldn / pixelad / setae are very specialized for the spectrum's native display file organization. nextreg is for controlling the hardware state of the machine. These are very useful in practice - I would say it's one of the better additions. All the above I wouldn't expect the compiler to generate, however they would be present in the libraries and user code. I agree There are some other issues with, eg, the 8x8->16 multiply. There are requests for having a signed counterpart and for bringing back the 32-bit multiply which was found to be very useful for fixed point calculations. The added instructions do not affect flags because they are implemented outside the z80 alu but I do agree many would be more useful if they did affect flags. Available space on the fpga also cramps what can be added. We'll see what happens - there is a deadline approaching. |
There won't be much use for push NNNN as long as there is at least one free register pair. It is a 4-byte, 22T instruction. Using two old Z80 instructions (ld qq, NNNN; push qq) is 4 bytes, too and at 21T actually faster! Philipp |
And just to note (because it is buried in lots of comments) the @spth work showing the use of |
add sp,d would be usable from both sdcc and sccz80 and stop sccz80 from jumping through hoops to preserve the return value with a large frame. ld hl,(sp+n) and ld (sp+n),hl make significant improvements to the Rabbit generator in sccz80 and are also used by sdcc. On the Rabbit these instructions are very cheap (2 bytes and 11 or less Rabbit clocks so ~22T). I think @aralbrec has put forward a case for these on several occasions but has sadly been rejected. In terms of what's being used by sccz80, I think add hl,nnnn is the only one at the moment that's used (I think we do a ld bc,nnn, add hl, bc for structure access), I can see a rules file uses push nnnn, but this will be from the days when that was a quick instruction. |
I dislike the Whereas There seems to be no history of discussion about the instruction mnemonics on the SpecNEXT forum, or elsewhere. So, there seems no avenue to discuss this. Would it be appropriate to make For #837. |
Noted on the SpecNext Kickstarter - Update 41 that... Z80N has been enhanced with six more instructions: 5 x barrel shift/rotate and 1 JP. Is there any information on these additional 6 instructions, and their opcodes, etc? And, should/could they flow into z80asm and into sdcc, too? |
I can add them to z80asm, if someone tells which they are. |
I have the information; I'll put it here later today. I've been busy lately. I think we should settle on z?80 mnemonics as alternates where there are equivalents and the official mnemonics so there isn't a proliferation. So "mul de" becomes "mlt de" only, eg. |
The main list is updated: The additions are barrel shifts and a special jp(c) being used for instruction dispatch from disk streaming. It's important for video and other speculated uses.
I think we should prune away any instruction aliases except for ones that match other zilog related processors. So The list is updated to reflect these things too. |
There are other assemblers accepting |
z80asm will be updated. |
Fix #312: new barrel shift operators in z80-zxn
done
…On Sun, Dec 23, 2018 at 7:21 PM aralbrec ***@***.***> wrote:
There are other assemblers accepting mul de so maybe that one should be
kept.
—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
<#312 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAEUdUucX1bkaTme-CiBsCZJFrSn2gZMks5u79e6gaJpZM4O0DbA>
.
|
Paulo do you think there can be an easy way to define additional opcodes for the z80? I am thinking in general here as z80 implementations exist for fpgas and we now have a specific case where new opcodes are being added for a machine.
The zx next, which I am working on now, is adding these instructions:
That's a partial list as more is coming.
I have also been thinking about adding via m4 but that is not ideal because all asm would have to be in an m4 file and this would require changes in zcc. I could also do it in pre-processing with copt.
The text was updated successfully, but these errors were encountered: