Code Monkey home page Code Monkey logo

sjasmplus's Introduction

sjasmplus

Build Status GitHub repo size in bytes BSD 3-Clause License Coverage Status CodeQL GNU/Linux FreeBSD NetBSD Raspberry Pi macOS Windows

Command-line cross-compiler of assembly language for Z80 CPU.

Supports many ZX-Spectrum specific directives, has built-in Lua scripting engine and 3-pass design.

For GNU/Linux, BSD, Raspberry Pi, macOS and Windows (click for exe).

GNU make or CMake installation methods for your convenience.

Online documentation (it is also included in the binary-release zip for offline viewing).

Post issues, feedback, feature requests, etc on github.

Main Features

  • Full source of assembler available under BSD license, modify and extend as you wish
  • Z80/R800/Z80N/i8080/LR35902 documented and undocumented opcodes support
  • Macro language, defines, array of defines
  • Built-in Lua scripting engine
  • Conditional assembly, block repeating
  • Modules (namespaces), local and temporary labels
  • Source and binary file inclusion, include paths
  • Multi file output, file updating, various types of exports
  • Structures to work easily with structured data in memory (STRUCT pseudo-op)
  • Relocation data generator to support SymbOS-like relocation of executables
  • Virtual device mode for common machines: ZX 128, ZX Next, Amstrad CPC, … (pseudo op DEVICE)
  • ZX Spectrum specific directives and pseudo ops (SAVESNA, SAVETAP, SAVEHOB, INCHOB, INCTRD…)
  • ZX Spectrum Next specific features and directives (Z80N, 8ki memory paging, SAVENEX)
  • Amstrad CPC 464/6128 specific directives (SAVECPCSNA)
  • Correctness is assured by Cirrus-CI with 380+ automated tests (that's also 380+ examples of usage!)
  • Fake instructions as LD HL,DE (LD H,D:LD L,E) and more
  • Code inlining through colon (LD A,C:INC A:PUSH AF:IFDEF FX:LD A,D:ENDIF…)
  • Very fast compilation: 1 million lines by 2-3 seconds on modern computer
  • Multiline block comments and user’s messages

This repository was created by import from original Aprisobal's repository @ https://sourceforge.net/projects/sjasmplus/.

Other useful tools for sjasmplus users

Some of these may be useful for sjasmplus users (depending on the platform and tools you are using):

Support for Z80 macro-assemblers in Visual Studio Code - syntax highlighting, "problem matcher" for assembler output, on hover info about labels, symbols, completion proposals, renaming provider, macro documenter and arguments definitions.

This can be further complemented by Z80 Assembly meter plugin for Visual Studio Code.

#CSpect is ZX Spectrum Next emulator with built-in debugger and map-files support to show labels from source code.

ZEsarUX is multi-machine emulator focusing on ZX Spectrum family of machines, including also ZX Spectrum Next, having many many options, lot of menus, and lot debugging capabilities - if you are particularly interested into ZX Spectrum Next SW development, the #CSpect is often a bit ahead in overall emulation fidelity, but ZEsarUX is often more accurate in subtle edge-case details, so you may want to have both of them around for different occasions. Also you may want to have ZEsarUX around for:

DeZog - Z80 Debugger (for Visual Studio Code) for debugging ZX Spectrum code, writing unit tests for it, time the execution, etc.

(if you are not excited about using VSC as IDE and want to try some alternative) Syntax highlight (only) for Kate iconKate editor is included directly in sjasmplus sources.


All product names, trademarks and registered trademarks are property of their respective owners. All company, product and service names used in this website are for identification purposes only. Use of these names,trademarks and brands does not imply endorsement.

sjasmplus's People

Contributors

alexanderk23 avatar catpainblack avatar cizo2000 avatar ckirby101 avatar dependabot[bot] avatar evolutional avatar hvge avatar jurajlutter avatar kborowinski avatar lordheavy avatar lvd2 avatar mborik avatar ped7g avatar serg-meus avatar sromeroi avatar unixb0y avatar z00m128 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sjasmplus's Issues

Comments in macros removed from list file

Hi,

The following code

    MACRO m1
    ; commentA
    nop ; comment1
    ; commentB
    nop ; comment2
    nop ; comment3
    ENDM 

    ORG 0x8000

    m1 

produces

30    0005                  ORG 0x8000
31    8000
32    8000                  m1
32    8000             >    ; commentA
32    8000 00          >    nop
32    8001             >    ; commentB
32    8001 00          >    nop
32    8002 00          >    nop

in the list file.

The comments that are single on a line are still there but
the comments after the instructions have vanished.

I would assume that either no comments or all comments are written.
Preferable all comments would be written because I use some comments for instrumentation.

I did some further investigation. It seems that sometimes the comment after the instruction is simply taken from the comment of the line the macro has been used. E.g.

135+ B3C1                  _nextreg  0x50+1    ; 0x2000-0x3FFF
 135+ B3C1 ED 92       >        defb 0xED, 0x92; 0x2000-0x3FFF
 135+ B3C3 51          >        defb 0x50+1    ; 0x2000-0x3FFF

The comment " ; 0x2000-0x3FFF" is simply repeated.

SAVETRD improvement

When using SAVETRD with existing trd image that already contains code file with same name, sjasmplus just adds another one (with the same name) to the end.
For example, there's image.trd containing mycode.C. Then if I use SAVETRD "image.trd","mycode.C",start,end-start, I'll have two mycode.C, one after another. TR-DOS allows that, but can access only the first one.
For some reason, I've a bunch of files on the image, so using EMPTYTRD and copy them all back is not a good idea.
It would be very useful to mark previous mycode.C as deleted before adding a new one. (this fork behaves like that as well https://github.com/sjasmplus/sjasmplus)

commandline: -D not working if more than one asm file

I tried to use a define on the commandline and this was working fine.
Then I added another source file and the define is not available in the files anymore.
E.g.

sjasmplus -DMY_DEFINE=1 a.asm

=> the define is available in a.asm

But

sjasmplus -DMY_DEFINE=1 a.asm b.asm

=> the define is not available in a.asm

Problem with macro and underscores

Version Platform Topic
v1.10.4 mac

Hi,
I have been running into a problem with macros.
It seems that certain number of argument and underscore combinations are not correctly parsed.
Loot at this example:

    ORG 0x0000

    MACRO MYMACRO addr, string, term
        ld de,addr 
    ENDM

test_result_string: defb 0

    MYMACRO test_result_string, 1, 0

This gives the error:
src/main.asm(19): error: Label not found: test_result_1

I.e. it seems that first and 2nd argument are somehow concatenated.

Almost the same macro with only 2 arguments works:

    ORG 0x0000

    MACRO MYMACRO addr, string
        ld de,addr 
    ENDM

test_result_string: defb 0

    MYMACRO test_result_string, 1

Also this macro with 3 arguments but first argument with only one underscore works.

    ORG 0x0000

    MACRO MYMACRO addr, string, term
        ld de,addr 
    ENDM

test_resultstring: defb 0

    MYMACRO test_resultstring, 1, 0

Please note: the arguments are not used inside the macro just for simplifying the problem. Of course I will use them in the real macro.

How to use NEX format and PAGE

Hi,

I'm trying to use the NEX file format and the ZXSPECTRUMNEXT device
but I somehow don't understand how this should work.
I have been playing aroung with the page/slot parameters but it never saves the page that I intend to save.

Here is some source code.

    DEVICE ZXSPECTRUMNEXT

    PAGE 10
    ORG 0x0000
    DEFB "MAIN_START",0


    SAVENEX OPEN "sjasm_test.nex", 0 
    ;SAVENEX BANK 2
    SAVENEX AUTO
    SAVENEX CLOSE

The hex output of the produced nex file shows that page 7 has ben used.

4E 65 78 74 56 31 2E 32 00 01 00 00 FE FF 00 00 
00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

It seems that no matter which PAGE I supply always bank 7 is used in the nex file.

How can I provide the correct information to the sources so that I create the assembly in the correct pages?

(SjASMPlus Z80 Cross-Assembler v1.13.3)

new macro syntax

This is strange.
I update to new version 1.13.1 (last commit 81dd0cb) and tried out the new macro syntax.

I took the code from the example

LabelAsMacroName    MACRO  arg1?, arg2?
                        ld  a,arg1?
                        ld  hl,arg2?
                    ENDM

                LabelAsMacroName 1,$1234

But get the following error followed by a segfault:

sjasmplus --zxnext --inc=src --lst=out/zxngfw.list --sym=out/zxngfw.labels --exp=src/zxngfw.inc -DDEBUG --fullpath -DZXNGFW_BIN_FILE=\"zxngfw.bin\" src/main.asm  src/exports.asm 
SjASMPlus Z80 Cross-Assembler v1.13.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
Pass 3 complete
Errors: 0, warnings: 0, compiled: 5938 lines, work time: 0.020 seconds
sjasmplus --zxnext -DDEBUG -DSNA_FILE=\"out/ut_dbg.sna\" --inc=src --lst=out/ut_dbg.list --sym=out/ut_dbg.labels -DZXNGFW_BIN_FILE=\"out/ut_dbg_zxngfw.bin\" --fullpath src/unit_tests.asm 
SjASMPlus Z80 Cross-Assembler v1.13.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
src/unit_tests/ut_sprites.asm(729): error: Unrecognized instruction: LabelAsMacroName 1,$1234
Pass 3 complete
make: *** [out/ut_dbg.sna] Segmentation fault: 11
make: *** Deleting file `out/ut_dbg.sna'
The terminal process terminated with exit code: 2

Before you ask, I did a

make clean
make
make install

Throw warnings on fake instructions

Modify the parser to throw warnings on fake instructions:

  • alternatively on those which are most suspicious, for example sub a,b, but I prefer all of them
  • probably there should be some kind of verbosity filter if there are too many fake instructions in source (so we need to throw it in the second pass)
  • implement another command line parameter --silentfakes which dismiss those warnings (in addition to already implemented --nofakes)

@ is ignored in label definitions inside macros

See the following example.

	MACRO setlabel1 name, val
@name = val
	ENDM

	MACRO setlabel2 name, val
name = val
@m.mac_lbl3 = 101
	ENDM


	MODULE m

@m.label1 = 42
m.label2 = 66
	setlabel1 m.mac_lbl1, 77
	setlabel2 m.mac_lbl2, 89

	ENDMODULE

The listing:

# file opened: macro-label.asm
 1    0000              	MACRO setlabel1 name, val
 2    0000 ~            @name = val
 3    0000              	ENDM
 4    0000
 5    0000              	MACRO setlabel2 name, val
 6    0000 ~            name = val
 7    0000 ~            @m.mac_lbl3 = 101
 8    0000              	ENDM
 9    0000
10    0000
11    0000              	MODULE m
12    0000
13    0000              @m.label1 = 42
14    0000              m.label2 = 66
15    0000              	setlabel1 m.mac_lbl1, 77
15    0000             >@m.mac_lbl1 = 77
16    0000              	setlabel2 m.mac_lbl2, 89
16    0000             >m.mac_lbl2 = 89
16    0000             >@m.mac_lbl3 = 101
17    0000
18    0000              	ENDMODULE
19    0000
# file closed: macro-label.asm

The list of labels:

m.label1: equ 0x0000002A
m.m.label2: equ 0x00000042
m.m.mac_lbl1: equ 0x0000004D
m.m.mac_lbl2: equ 0x00000059
m.m.mac_lbl3: equ 0x00000065

As can be seen, of the 3 labels that are defined inside the macros, two (m.mac_lbl1 and m.mac_lbl3) are supposed to be defined in the 'global' scope because of the '@', similar to m.label1. However, the effect of '@' is ignored, and it incorrectly defines those as labels m.m.mac_lbl1 and m.m.mac_lbl3 instead, similar to m.m.label2.

Documentation does not describe rules of MACRO and DEFINE substitution

Version Platform Topic
v1.10.4 all macro

There's almost zero description of how this process is done, which features are available and what results should be expected in various edge-cases.

There's feature of _ working as substitution delimiter documented by macro_test.asm.

There are some examples in documentation about macros and their expansion.

And there's reasonably detailed/formal documentation about labels.

Question/task: provide better formal description how the macro and define system should work.

If there already are Z80 assemblers with similar functionality, see if their definition is better, and if sjasmplus can converge to common behaviour of various assemblers.

And then fill the gaps where nobody formalized remaining edge-cases.

UNDEFINE pseudo-op is not working as expected

The manual says: UNDEFINE ... Removes the identifier defined by DEFINE, but it undefines all defines.

Bug indentified by busy in sjasm/tables.cpp. Proposed fix: insert
if (p && !strcmp(name, p->name)) {defs[(unsigned char)*name] = p->next;} else
before line 215 (starts with while (*p) {)

Cannot use LUA inside MACRO

This is a fairly old one that is also present in the base 1.07RC7 ver. Attempting to use LUA inside a macro produces various unrelated errors concerning LUA/ENDLUA.
Sample code:

	MACRO luatest
	 LUA
	  sj.warning('Macro LUA test')
	 ENDLUA
	ENDM

	luatest

Console output:

SjASMPlus Z80 Cross-Assembler v1.11.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
luatest.asm(8): error: [LUA] Unexpected end of lua script
luatest.asm(8): error: Unrecognized instruction: sj.warning('Macro LUA test')

luatest.asm(8): error: [ENDLUA] End of lua script without script
Pass 3 complete
Errors: 3, warnings: 0, compiled: 6 lines, work time: 0.000 seconds

Bad CRLF handling in parser

When CRLF line ending splits on 4k boundary (e.g. $1000, $2000 etc), line numbering goes wrong in listing (counts both 0D and 0A as separate lines).

Identified by mborik as bad buffer handling in sjasm/sjio.cpp.

DEVICE documentation

Hi,

first let me say that I really like to see the new ZXNEXT device. But I also have a few difficulties to understand how to use this new feature.

So this here is a request to enhance the sjasmplus documentation on the DEVICEs.

Could you please explain in more detail what the DEVICE directive (or real device emulation) especially for ZXSPECTRUMNEXT does.

I think that during compilation an address space bigger than 64k is used (virtual space), i.e. the 1.75MB of memory.
I guess this would then also be true for the list file, i.e. the list file would then also include addresses bigger than 0xFFFF, e.g. 0x1AB05, but this is not explicitly documented somewhere (I think).
What about ORG statements? Can I do "ORG 0x20000" or something.
It would also be nice if the default mapping (memory to slots) would be more clearly specified. E.g. the default mapping for ZXSPECTRUM128 is not found under ZXSPECTRUM128 but under ZXSPECTRUMNEXT.
The ZXSPECTRUMNEXT mapping is not explicitly given.

error: [IFDEF] No endif

Version Platform Topic
v1.10.4 linux

When building part of code:

       DEFINE  WC_PLUGIN 1

 ............................................ skip ...........................

	HALT

	IFDEF	WC_PLUGIN
	include "z80-sdk/wc_api/wind.a80"
	ELSE
	include "z80-sdk/windows_bmw/spkeyb40.a80"
	include "z80-sdk/windows_bmw/edznak.a80"
        include "z80-sdk/windows_bmw/wind.a80"
	include "z80-sdk/windows_bmw/dmm.a80"
        ENDIF
        include "main.asm"

Compiler get error:

startup.asm(88): error: [IFDEF] No endif
startup.asm(89): error: ENDIF without IF/IFN/IFUSED/IFNUSED/IFDEF/IFNDEF

Test scripts are not working properly on macOS/OS X

Version Platform Topic
v1.10.4 macOS

Test scripts in ./ContinuousIntegration are not working correctly. This is caused by old bash version (3.2.x) on Apple computers, in which globstar parameter is not supported at all. Upgrading bash with port or brew to newer versions is also not helping in the situation, because both binaries are built with globstar off.

So suggestion is to rewrite the test scripts using recursive directory search, to make them more compatible with older bash versions.

list file lines are one off in some cases

Let me first say that I'm a great fan of sjasmplus. It has so many cool features like fake-instructions, structures, local labels, good macro support.
So, I'm entering these bugs because I like to work with this assembler and hope that it will be improved further.
Please keep on the good work.

I now found a small problem with the listings file.
In some occasions the displayed line number is not correct, i.e. it is one-off and also all following lines are one off, too.
It happens when there is a local label used together with a ":"

This code here

l1:
    nop
.end:
    nop
    nop
    nop

Results in

001   0000             l1: 
002   0000 00              nop
003   0001             .end
004   0001              
005   0001 00              nop
006   0002 00              nop
007   0003 00              nop

I.e. there is an extra line introduced after the .end label: line 4.

I works correctly if the local label is used without ":"

l1:
    nop
.end:
    nop
    nop
    nop

Result is OK:

001   0000             l1: 
002   0000 00              nop
003   0001             .end
004   0001 00              nop
005   0002 00              nop
006   0003 00              nop

Sorry, I can imagine that this sounds very pedantic.
The problem for me is because I use the list file in one of my projects, a Z80 debugger for vscode
(see https://github.com/maziac/z80-debug).
And currently I'm adding support for sjasmplus.
If the lines are one off in the list file, the lines are also one-off when stepping through the code in the debugger.

Add also regular UnitTesting framework

Maybe something like UnitTest++, the goal is to not test absolutely everything through ASM source files. Technically that's not "unit testing", but "integration test", which I don't give shit. But the bad part is, that to test some code paths, the asm files has to be too much implementation-specific-hacked to trigger particular situations, and some code paths can't be exercised at all, as the input potentially triggering the code path is filtered out by upper layers of parser. Plus for TDD style of work writing C++ unit tests is slightly more natural, than starting with Z80 asm file.

  • check feasibility of UnitTest++ (if it didn't change too much, it should be perfect fit)
  • create first few tests with the framework selected

Add implementation of fake instructions in documentation

Currently the documentation of fake instructions only lists the instructions, but doesn't show the actual implementation.

It would be nice to add the implementation next to the instruction.

The test tests/z80/all_fake.asm can be used to generate snapshot containing all instructions, then you can use some emulator with debugger (like #CSpect) to see actual implementation, and edit the docs/documentation.xml text file, to add these.

(or maybe just save them as binary with some marker between like "nop", and use disassembler, if you want rather just fix formatting than typing it all by hand)

STRUCT example in documentation seems not to work

I tried the SCOLOR STRUCT example from the documentation:

	STRUCT SCOLOR
RED	BYTE 4
GREEN	BYTE 5
BLUE	BYTE 6
	ENDS

COLORTABLE
  SCOLOR 0,0,0
  SCOLOR 1,2,3
  SCOLOR ,2

but assembling it brings this error:

sjasmplus --inc=src --lst=out/zxngfw.list --sym=out/zxngfw.labels --raw=zxngfw.sna main.asm
SjASMPlus Z80 Cross-Assembler v1.10.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
main.asm(16): error: Unrecognized instruction: SCOLOR 0,0,0
main.asm(17): error: Unrecognized instruction: SCOLOR 1,2,3
main.asm(18): error: Unrecognized instruction: SCOLOR ,2
Pass 3 complete
Errors: 3, warnings: 0, compiled: 2081 lines, work time: 0.010 seconds

What am I doing wrong?

Refactoring of labels implementation

Rewrite the tables.cpp, using more of standard C++ features, and to create more versatile labels-API for internal purposes.

Goals of refactoring:

  • single set of code validating label characters
  • single set of code validating whole labels and parsing/extracting them
  • share that also between macro/struct/define naming (if it makes sense)
  • check if making dot strictly delimiter hurts too much (result: must stay)
  • if dot must stay, check if it's possible to delimit by something else (result: hidden delimiter formatted as dot in outputs, any user dot has to be combined to find if it's dot or delimiter)
  • labels operators (device-memory related)
  • case-insensitive option
  • keyword guarding by default (but optional)
  • usage/type flags for exporting (for tools like Maziac's stuff)

new label in labels file

I'm not sure if this is a bug or if I'm interpreting something wrong.
Anyhow I think that this behaviour is at least strange.

Look at the following code:

    ORG 0x8000

 MODULE ma 
lb: equ 6
 nop
 ld a,lb
 ld a,ma.lb
 ENDMODULE

The code compiles without warning.
I used the following commandline:

sjasmplus --lst=main.list --sym=main.labels --fullpath main.asm

The list file results into

12    8000               MODULE ma
13    8000              lb: equ 6
14    8000 00            nop
15    8001 3E 06         ld a,lb
16    8003 3E 06         ld a,ma.lb
17    8005               ENDMODULE

which seems correct.

But the labels file output seems strange:

ma.lb: equ 0x00000006
ma.ma.lb: equ 0x00000000

It generates a new label ma.ma.lb and initializes it to 0.

Temporary numeric labels bug

Hello. There is a bug which breaks the temporary numeric jump labels in some way. See the following example. In this situation, it says that the 'backwards 1' label is not found. It seems to be related to the number of 'asdf' lines because if one of them is removed, it will work as expected.

	DEVICE ZXSPECTRUM128

	ORG #8000


	MODULE M1

LABEL equ 0

	ENDMODULE


	MODULE M2

	 IFNUSED M1.LABEL
.tmp = M1.LABEL
;asdfasdfasdfasdf
;asdfasdfasdfasdf
	 ENDIF

	ENDMODULE

1
	jr 2f
	jr 1b
2

Fails to compile in Windows/MinGW environment

When I try to compile actual master repository in Windows/MinGW environment, the compilation fails with this error:

sjasm/sjasm.h:70:31: note: in expansion of macro 'MAX_PATH'
 extern char SourceFNames[128][MAX_PATH];
                               ^~~~~~~~
make: *** [sjasm/devices.o] Error 1

Older released versions are working correctly.

LUA function zx.trdimage_add_file broken

According to the documentation, it is a function of 4 arguments, given as: "[void] zx.trdimage_add_file("filename", "somenameC", startaddress, length)".
However, if it is used that way, then the following error is returned

"error: [LUA] error in function 'trdimage_add_file'. argument #5 is '[no object]'; 'number' expected."

You can reproduce it like this (it works fine in the basic 1.07 RC7 SjASMPlus):

DEVICE ZXSPECTRUM48

LUA
 zx.trdimage_create('test-trd.trd')
 zx.trdimage_add_file('test-trd.trd','test.C',16384,255)
ENDLUA

STRUCT skips negative number

If you use a negative number in a structure already defined, SJASM ignores this number and goes to the next line:

09   0000 00 11 22 33 all_ok  ss      #00,#11,#3322
10   0004 00          bad_1   ss      #00,-1,#3322
11   0005 00 11       bad_2   ss      #00,#11,-1
12   0007 00 11 00    bad_3   ss      #00,#11,-256
13   000A 00 11       bad_4   ss      #00,#11,-257

Which should be:

09   0000 00 11 22 33 all_ok  ss      #00,#11,#3322
10   0004 00 FF 22 33 bad_1   ss      #00,-1,#3322
11   0008 00 11 FF FF bad_2   ss      #00,#11,-1
12   000C 00 11 00 FF bad_3   ss      #00,#11,-256
13   0010 00 11 FF FE bad_4   ss      #00,#11,-257

Windows installation

Hello z00m,

one note about Windows installation. It is not necessary to delete and rename Makefile.
Just use:

mingw32-make -f Makefile.win clean
mingw32-make -f Makefile.win
mingw32-make -f Makefile.win install

Thank you for nice project.

Additional info in labels file

Hi,

currently the output for a labels file (--sym=) may look like:

main_start: equ 0x00000000
IM1_INTERRUPT_38H: equ 0x00000038
sound.music_main_interrupt: equ 0x00000477
IO_NEXTREG_REG: equ 0x0000243B
sprites.anim_counter: equ 0x00001900 

I use various programs/scripts that use this information e.g. to generate
documentation (see https://github.com/maziac/asm-api-doc-tool) or as additional input to a disassembler (see https://github.com/maziac/z80dismblr).

It would be very helpful if there would be additional information for each label about the type of label. I.e. how the label was generated. E.g. if the label was pointing to code (e.g. an opcode following the label) or if it was pointing to a data area or if it was created by an EQU.

I know that this is never 100%. Assembler code can be a bit ambiguous and, of course, definitions via EQU can mean anything.
Still it would be very helpful to have this kind of "hint" in the labels file.

The output could maybe look like:

main_start: equ 0x00000000    ; CODE
IM1_INTERRUPT_38H: equ 0x00000038    ; CODE
sound.music_main_interrupt: equ 0x00000477    ; CODE
IO_NEXTREG_REG: equ 0x0000243B        ; CONST
sprites.anim_counter: equ 0x00001900    ; DATA

Feature suggestion: Pseudo-op to know the "size" of a label

There are many places where we need to know the how many bytes were used under a label. For example, when we LDIR routines, or need to loop over a string.

Normally, we have to add extra labels to mark where the end is, and subtract endlabel-LABEL to find the size. But this ends up in the creation of a plethora of nearly useless labels that only clutter the symfiles and the debuggers.

It would be much easier if we had a pseudo-op like SIZEOF(label) that would count how many bytes that label has until the next label at the same or higher level is found.

For example:

FOO:
	ld	a,3
	call	BAR
	jr	c,.skip
	ld	a,1
	ret

.skip:	ld	a,2
	ret

BAR:
	cp	5
	ret

INSTRAM:
	ld	hl,FOO
	ld	de,MYRAM
	ld	bc,SIZEOF(FOO)
	ret

In the example above, SIZEOF(FOO) would return 13. Allows an easy LDIR to another location without hassle.

It would be useful for strings too:

CHKCHARS:
	ld	a,(MYCHAR)
	ld	hl,.charlist1
	ld	bc,SIZEOF(.charlist1)
	cpir
	ld	a,1
	ret	z
	ld	a,(MYCHAR)
	ld	hl,.charlist1
	ld	bc,SIZEOF(.charlist2)
	cpir
	ld	a,2
	ret	z
	ld	a,(MYCHAR)
	ld	hl,.charlist1
	ld	bc,SIZEOF(.charlist3)
	cpir
	ld	a,3
	ret

.charlist1:	db	"ABCD"
.charlist2: 	db	"EFG"
.charlist3:	db	"HIHKLMNO"


BAR:
	call	PRTCHAR
	or	a
	ret	z
	ld	a,9
	ret

Some of the CI tests fail with the latest sources on a Windows configuration

I'm using Git Bash + Mingw on Windows XP, and some CI tests fail on this machine currently with the latest sources. It appears to be mainly related to include/file functions like INCBIN, INCTRD and so on. This does not happen with the stable 1.12.0 sources+tests in releases (using the source snapshot in the zip).

I assume you're on Linux and probably not seeing this. As well, the Github Cirrus tests all seem to pass. Perhaps it's some sort of a Windows vs Linux problem...

I'm using the included Makefile.win to build sjasmplus, that I edited a bit to get the exe/compiler paths etc right. Likewise with the CI sh scripts.

Logs:
master current
master stable v1.12.0

Fail on current master builds compared to stable v1.12.0:

tests/macros/Issue45B_arg_substitution.asm
tests/misc/includebin/incbin.asm
tests/misc/includehob/inchob.asm
tests/misc/inctrd/inctrd.cli
tests/ifused_in_module.asm
tests/parsing/colon_vs_label_issue.asm
tests/struct/align.asm
tests/struct/fields_types.asm
tests/test build script and options/opt raw/raw_to_file.asm
tests/test build script and options/opt raw/raw_to_stdout.cli

Fails on both:
tests/sjasmplus_regressions/wrong_index_offset.asm

Change syntax defaults to be somewhat more strict

  • make the default syntax closer to --syntax=abflL in sjasmplus v1.x
  • research other assemblers and open issues to see what more makes sense
  • go through the current syntax one more time, and check for ambiguities and inconsistencies
  • make extra docs about breaking changes and how to migrate

list format, pluses

I found that the list format has slightly changed on the current master branch.
My z80-debug tool depends on this format and so I ran into problems.
This as such is not a big problem, I can adjust.
But I noticed that the number of possible "+"s has been reduced from 3 to 2.

The pluses indicate the nesting level e.g. for every include a "+" is added.
My z80-debug extension uses this information to determine the right source file name from the list file.

In the list file the number of pluses is restricted. So a maximum of 2 is now displayed.

In the past I saw 3 pluses as a maximum for the list file and this already was a bit problematic. It meant that with 4 nesting levels my extension might not choose right source file.
But now with 2 pluses only this situation is even more probable.

So, my request is:

  • Can you please not reduce the number of maximum pluses any further so that at least 2 pluses will be there
  • or maybe don't restrict the number of pluses at all
  • or make this configurable on the command line.

"Bytes lost"

Hi,

I had problems assembling some of my programs. I could drill it down to the following
problematic lines:
` ORG 32769

CHR: DEFW 0,0,0,0

HINA: LD DE,-CHR
ADD HL,DE`

sjasmplus gives the error:
SjASMPlus Z80 Cross-Assembler v1.10.3 (https://github.com/z00m128/sjasmplus) Pass 1 complete (0 errors) test.asm(5): error: Bytes lost Pass 2 complete (1 errors) test.asm(5): error: Bytes lost Pass 3 complete Errors: 2, warnings: 0, compiled: 7 lines, work time: 0.001 seconds

Note: if ORG is chosen lower or equal 32768 it assembles without a problem.

dot-label inside IFUSED = error

When dot-labels (labels starting with a dot) are used inside IFUSED pseudo-op blocks, sjasmplus doesn't recognise them and spits out "Label not found" errors.

For example, the following code:

BAR:
 IFUSED
	ld	h,1
	ret
 ENDIF

NOTHING:
	ld	a,1
	ret

MYROUTINE:
 IFUSED
	ld	a,2
	or	a
	jr	z,.quit
	cp	3
	jr	c,.jump
	jr	.quit


 IFUSED	BAR
.jump:	ld	c,3
	jp	.quit
 ELSE
	ld	a,1
.jump:	ld	c,2
	jr	c,.quit
 ENDIF ; IFUSED BAR
	call	FOO
.quit:	ret

 ENDIF ; IFUSED MYROUTINE

	call	MYROUTINE
FOO:	call	BAR
	call	NOTHING
	ret

Trying to compile this code will result in the following errors:

$ sjasmplus labelBug.asm 
SjASMPlus Z80 Cross-Assembler v1.10.1 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
labelBug.asm(15): error: Label not found: MYROUTINE.quit
labelBug.asm(17): error: Label not found: MYROUTINE.jump
labelBug.asm(18): error: Label not found: MYROUTINE.quit
Pass 3 complete
Errors: 3, warnings: 0, compiled: 52 lines, work time: 0.000 seconds

Even the .quit label, that is outside of the IFUSED blocks, results in an error.

Note: The code accomplishes nothing. It's just an example.
Note2: Probably this bug happens with IF and IFUNUSED too.

Continuous Integration for windows builds

The cirrus-ci has also some support for windows, but I'm not sure about availability for open source, plus can't be bothered to try to set it up, as I have basically no experience with MS windows.

If cirrus fails, it makes sense even to configure another CI service just for windows builds, AppVeyor maybe (isn't it directly connected to Microsoft, i.e. should be of reasonable standard?)?

N-pass assembling

Make it N-pass...

  • refactor the global state into nesting assembling context, to resolve includes/nesting/substitution and have the state-preserving for free in natural C++ way, without explicit code
  • categorize the state items per their life-cycle in 3-pass and N-pass, group it
  • modify pass3 things to wait for "final pass" instead
  • create checks to detect "pre-final" pass did happen
  • just enable N-pass as last step :)

ZX Next Device

Are you planning to support the ZX Next as DEVICE (similar to ZXSPECTRUM128) in the near future?

Argument substitution not working with DEFINE names inside MACRO

In a macro that sets a DEFINE with a name based on a macro argument, it appears that the argument is not being replaced with its value, and a define with the 'name of the macro argument' is set instead. In the following example, the define that ends up being set is 'name', not 'TESTD' as it should normally be. (The substitution seems to work correctly for the value of the define being set up).

	MACRO def name, val
	 DEFINE name val
	ENDM

	def TESTD, 12345
	
	IFDEF TESTD
	 DISPLAY /d, "'TESTD' is defined: ", TESTD
	ELSE
	 IFDEF name
	  DISPLAY /d, "'name' is defined: ", name
	 ENDIF
	ENDIF

DEFARRAY does not work in example from Documentation

http://z00m128.github.io/sjasmplus/documentation.html#po_defarray

The example doesn't work as described. Only the first value 0xC8 (10*20) is displayed for every DUP step.

If commit 1fea88f is reverted, this example will start to work (as the value C8 is not hard-wired into the line), but then DUP inside DUP inside MACRO will break (the line inside DUP can't find macro arguments dynamically).

As I'm not sure, how to fix this properly, I'm opening issue to keep track of this. I'm adding also test tests/docs_examples/po_defarray.asm which is currently suppressed (so it will not report failure), but once the bug will be fixed in code, rename the available bin file properly to make the test live.

Continuous Integration for MacOS

The cirrus-ci has also some support for MacOS, but I'm not sure about availability for open source, and I lack experience with MacOS.

If cirrus fails, maybe there's some other CI service where it may be set up with reasonably small effort?

LUA function sj.get_word returns byte instead

This example will print 255 instead of 65535:

	DEVICE ZXSPECTRUM48

	ORG #8000

TEST
	DEFW #FFFF

	LUA
	 sj.warning(sj.get_word(_c("TEST")))
	ENDLUA

I think the problem is this line in lua_sjasm.cpp ('char' should be 'int'):
unsigned char tolua_ret = (unsigned char) MemGetWord(address);

Wrong address count in listing when fake instructions are used.

The following small code

ORG 0x8000
ld hl,0x8123 
sub a,2
add a,a

produces the following list file:

024 0000
025 0000 ORG 0x8000
026 8000
027 8000 21 23 81 ld hl,0x8123
028 8004 97 D6 02 sub a,2
029 8006 87 add a,a
030 8007

Please have a look at line 28. The address is 8004 but it should be 8003.
Then at line 29 the addresses are OK again.

I'm not sure what is happening here. I have entered 'sub a,2' by mistake, I meant 'sub 2' but the assembler seems to make something meaningful of it. I.e. I tried:
sub c,2
which results into

sub c
sub 2

Is this some kind of pseudo instruction?

Anyhow, even if so the line numbering in the list file is wrong.

Allow calculation of pow(x,y)

Is your feature request related to a problem?
I would like to setup a frequency table for midi numbers to frequencies (AY8910 values).
Something like this:

midi_frequency_table:
midi_number=21
    dup 108-21+1
        defw (AY8910_CLOCK_FREQUENCY/16.0)/(pow(2,(midi_number-69)/12.0)*440)
midi_number=midi_number+1
    edup

Describe the suggested solution:
It would be nice if you could implement the power function, i.e.
pow(x,y) as x^y with floating point numbers.

Building fails if path contains spaces

Hi,
I used the most recent sources (23.3.2019) and now get a build error:

make clean 
make
...
g++ -o /Volumes/Macintosh HD 2/Projects/zesarux/sjasmplus/build/release/sjasmplus -std=gnu++14 -Wall -pedantic -DUSE_LUA -DLUA_USE_LINUX -DMAX_PATH=PATH_MAX -Ilua5.1 -Itolua++ -DNDEBUG -O2 	build/release/sjasm/lua_lpack.o build/release/sjasm/devices.o build/release/sjasm/directives.o build/release/sjasm/io_snapshots.o build/release/sjasm/io_tape.o build/release/sjasm/io_trd.o build/release/sjasm/lua_sjasm.o build/release/sjasm/parser.o build/release/sjasm/reader.o build/release/sjasm/sjasm.o build/release/sjasm/sjio.o build/release/sjasm/support.o build/release/sjasm/tables.o build/release/sjasm/z80.o 	build/release/lua5.1/lapi.o build/release/lua5.1/lauxlib.o build/release/lua5.1/lbaselib.o build/release/lua5.1/lcode.o build/release/lua5.1/ldblib.o build/release/lua5.1/ldebug.o build/release/lua5.1/ldo.o build/release/lua5.1/ldump.o build/release/lua5.1/lfunc.o build/release/lua5.1/lgc.o build/release/lua5.1/linit.o build/release/lua5.1/liolib.o build/release/lua5.1/llex.o build/release/lua5.1/lmathlib.o build/release/lua5.1/lmem.o build/release/lua5.1/loadlib.o build/release/lua5.1/lobject.o build/release/lua5.1/lopcodes.o build/release/lua5.1/loslib.o build/release/lua5.1/lparser.o build/release/lua5.1/lstate.o build/release/lua5.1/lstring.o build/release/lua5.1/lstrlib.o build/release/lua5.1/ltable.o build/release/lua5.1/ltablib.o build/release/lua5.1/ltm.o build/release/lua5.1/lundump.o build/release/lua5.1/lvm.o build/release/lua5.1/lzio.o 	build/release/tolua++/tolua_event.o build/release/tolua++/tolua_is.o build/release/tolua++/tolua_map.o build/release/tolua++/tolua_push.o build/release/tolua++/tolua_to.o -ldl -s
clang: error: no such file or directory: 'HD'
clang: error: no such file or directory: '2/Projects/zesarux/sjasmplus/build/release/sjasmplus'
make: *** [/Volumes/Macintosh] Error 1

I guess this is because the path where the sources are located (unfortunately) contains spaces:
/Volumes/Macintosh HD 2/Projects/zesarux/sjasmplus

This must have been introduced lately because I had no problems one (or maybe 2) weeks ago.

Mimick common GNU tools as much as reasonable (specifically gcc)

  • research the current trend in error reporting by gcc/clang, copycat the format
  • extend the internal error reporting API, try to see if it's possible to introduce also fix suggestions/etc
  • research current command line options of gcc/clang, copy syntax for the reasonably identical ones (include paths, version, help, warnings/errors, stdin/stdout piping (v1.x is already doing it correctly?), input/output files, exports, etc...
  • test with tools supporting gcc/clang, how much they recover from the sjasmplus output and what is confusing them
  • check predefined macro symbols like __FILE__ and __LINE__, etc... (https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html)

Nesting DUP problem

Hi,
I tried to nest 2 DUPs in a macro.
But without success.
This here:

    MACRO MCRH b_count, b_size     
        DUP b_count
CNT=0
            DUP b_size
                defb CNT
                CNT=CNT+1
            EDUP
        EDUP
    ENDM

tlabelh:
    MCRH 3, 4`

leads to

sjasmplus --inc=src --lst=out/zxngfw.list --sym=out/zxngfw.labels --raw=zxngfw.sna main.asm
SjASMPlus Z80 Cross-Assembler v1.10.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
utilities/memory.asm(33): error: Label not found: util.b_size
Pass 3 complete
Errors: 1, warnings: 0, compiled: 2102 lines, work time: 0.008 seconds

The error vanishes if I used only one nesting level, i.e.:

    MACRO MCRH b_count, b_size     
        ;DUP b_count
CNT=0
            DUP b_size
                defb CNT
CNT=CNT+1
            EDUP
        ;EDUP
    ENDM

tlabelh:
    MCRH 3, 4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.