z00m128 / sjasmplus

Command-line cross-compiler of assembly language for Z80 CPU.
http://z00m128.github.io/sjasmplus/
BSD 3-Clause "New" or "Revised" License
383 stars 54 forks source link

Concern about instructions like add a,b #227

Closed silverfrost closed 10 months ago

silverfrost commented 10 months ago

sjasmplus interprets:

add a,32

as

add a
add 32

I presume this is a design decision. However, some code uses this convention; my old Z80 code does. I wonder if there could be a switch to either prevent the emitting of a double instruction or a warning when used.

I wrote this in documentation in 1986:

Astrum+ will assemble all the standard Zilog Z80 mnemonics, lists of which are easily available in various standard text books on the chip. Some of the other Spectrum assemblers depart from these standards; a list of the main deviations that you may encounter are listed here:

Astrum+   Variant
ADC A,r   ADC r
ADC A,n   ADC n
ADD A,r   ADD r
ADD A,n   ADD n
ADD A,(IX+0)  ADD A,(IX)
SBC A,r   SBC r
SBC A,n   SBC n
EX AF,AF' EX AF,A'F'     EX AF,AF     EX AF,AF"
IN A,(n)  IN A,n
OUT (n),A OUT n,A

Astrum+ will accept mnemonics typed in either upper or lower case letters, but the former is the customary style.

ped7g commented 10 months ago

Thank you for report, but seems a bit inaccurate.

add a,32 does produce C6 20 in default mode, so no, it does not produce two add instructions.

What you have maybe seen is sub a,32 which in official Zilog syntax should be sub 32 (add a,32 is Zilog syntax).

Anyway, you are hitting the "multi-argument" default, I added --syntax option to fine tune some of the default behaviour, because I didn't like it either. You can apply them directly from the source code by OPT directive, like this:

# file opened: <stdin>
1     0000              start:  ; default mode will produce this:
2     0000 97 D6 20       sub a,32
3     0003 06 00          ld b,(start)
4     0005 62 6B          ld hl,de
5     0007                OPT --syntax=abf ; multi-arg delimiter ",,", warn about extra parentheses and fake instr.
6     0007 D6 20          sub a,32
<stdin>(7): error: Illegal instruction (can't access memory): (start)
7     0009 06 00          ld b,(start)
<stdin>(8): warning[fake]: Fake instruction: ld hl,de
8     000B 62 6B          ld hl,de
9     000D
# file closed: <stdin>

I always suggest to use --syntax=abf for new projects, but I can't change the default without making several old users angry (already tried it :) ).

I hope this is sufficient for you and helps, let me know (close the issue if this is what you were looking for and works as needed).

Check http://z00m128.github.io/sjasmplus/documentation.html#s_cli for --syntax options list.

RobChaferDID commented 10 months ago

Ah, sorry, yes it was sub and not add. I tried your options and it didn't seem to produce any error for sub, even explicit in the source

CHARDATA PUSH DE
 OPT --syntax=abf ;
 SUB A,32
 LD H,0
 LD L,A
Executing task: c:\specnext\sjasmplus.exe C:\SpecNext\sources\Utility.asm --raw=c:\specnext\sources\scripts\Utility --zxnext=cspect --syntax=abf 

SjASMPlus Z80 Cross-Assembler v1.20.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
Utility.asm(107): warning[fake]: Fake instruction: SUB HL,DE
Utility.asm(327): warning[fake]: Fake instruction: LD IX,HL
Pass 3 complete
Errors: 0, warnings: 2, compiled: 375 lines, work time: 0.016 seconds
ped7g commented 10 months ago

It will not produce error, but it will produce only sub 32 accepting the explicit A silently.

To get multi-arg sub with the "--syntax=a" option you would have to write sub a,,32 (double comma), so you can't use the multi-arg by accident so easily. The only exception are push/pop/dec/inc which will accept single comma multi-arg even in syntax=a mode (as there's no ambiguity about these).

Whether you write the implicit A is optional, sjasmplus has pretty relaxed syntax to accept all common variants where possible and guess what you wanted to achieve.

Again see my example listing, the sub a,32 in default setting does produce machine code 97 D6 20 which is two sub instructions, after the OPT line it does produce only D6 20 which is the sub 32.

RobChaferDID commented 10 months ago

Thanks for the clarification ... and the excellent assembler.