Вход

Просмотр полной версии : SjASMPlus от z00m



Страницы : 1 2 [3]

Dart Alver
24.09.2021, 23:21
there is more labels but i see only this
Попробовал компильнуть, (не для запуска естественно) - закомментил incbin ввиду отсутствия и пути залокалил.
В labelslist файле полный набор меток.



05:3FF1 starter
07:070D no_decrb
07:0707 no_decrg
07:0701 decrg
07:06F7 no_decrr
07:06E6 fade_prep0
07:06C9 fade_in0
07:06A3 fade_out0
07:06E2 fade_prep
07:068B wait_press
07:0695 fade_out
07:0682 wait_key
07:0000 pal_title_l
07:0725 pal_title
07:0668 loop
07:061B init_ports
07:0612 drop_title
07:0609 drop_sprite
07:0600 drop_pal
07:0400 sprites
07:0200 palette
07:00FF frameint
07:00FD lineint
07:0101 emptyint
07:00FB dmaint
07:0065 clear
07:005D drop_tsports0
07:005B drop_tsports
07:06BB fade_in
07:0646 start
02:0000 stek
07:2AAF INTMask
07:27AF DMAStatus
07:28AF DMANum
07:27AF DMACtrl
07:26AF DMALen
07:25AF INTVect
07:24AF VSINTH
07:23AF VSINTL
07:22AF HSINT
07:21AF MemConfig
07:20AF SysConfig
07:1FAF DMADAddrX
07:1EAF DMADAddrH
07:1DAF DMADAddrL
07:1CAF DMASAddrX
07:1BAF DMASAddrH
07:1AAF DMASAddrL
07:19AF SGPage
07:18AF T1GPage
07:17AF T0GPage
07:16AF TMPage
07:15AF FMAddr
07:14AF NWRAddr
07:13AF Page3
07:12AF Page2
07:11AF Page1
07:10AF Page0
07:00AF Status
05:07AF T1YOffsH
05:06AF T1YOffsL
05:05AF T1XOffsH
05:04AF T1XOffsL
05:03AF T0YOffsH
05:02AF T0YOffsL
07:29AF FDDVirt
05:01AF T0XOffsH
05:00AF T0XOffsL
07:0FAF Border
07:07AF PalSel
07:06AF TSConfig
07:05AF GYOffsH
07:04AF GYOffsL
07:03AF GXOffsH
07:02AF GXOffsL
07:01AF VPage
07:00AF VConfig
07:0010 title_page
07:00A0 map_page
07:0098 sprite_page
07:0090 tile_page
07:0080 bg_page

Ped7g
25.09.2021, 00:13
there is more labels but i see only this

The ROM-area labels were not exported in older versions of sjasmplus (you are using some older version or different fork).
Can't remember when I did change it, but in latest 1.18.3 version the ROM area labels are exported in LABELSLIST

But they will export as Bank7 "07:00FD lineint" because the bank7 is mapped in bottom area. sjasmplus has no "ROM" bank at this moment.

If you want just regular address values for visual check, I would rather suggest --lst --lstlab=sort options to get full listing with symbol table at end of it.

If you need it for emulator's debugger, I have no idea how the ROM area labels needs to be exported, but I guess some search+replace on "^07:" regex may fix that easily... (ie. `sed "s/^07:/something:/" user.l > romarea.l` to get "something:00FD lineint").
(if you have "sed" in your OS, if you have windows, then I guess you want to use some text editor anyway and you don't mind to do it in laborious manual way, like everything else...)

- - - Updated - - -


Объясните, как для bbb, как правильно пользоваться ключами директивы SAVETAP в последних версиях?

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

I guess you are using the snapshot-like variant, so sjasmplus does add also it's own loader and does guess how big snapshot is needed? I don't maintain that feature, I don't know how it exactly works and I don't care about it much. (it's doing lot of automatic stuff including some hard-coded loader and you have minimal control over it, so I don't find that option attractive, I want my TAP files to be exactly as I want them, down to last byte, with no magic)
(but feel free to create pull request with improvements if you have some idea how it can be improved)

You can check the "examples/TapLib" for one of possible ways how to build TAP file from sjasmplus from specific blocks, including own BASIC loader, etc.. (or you can even use the library from the example, if it suits your needs).
https://github.com/z00m128/sjasmplus/tree/master/examples/TapLib

(edit: or you can also kill the default device memory init to clear sysvars/stack ...


DEVICE ZXSPECTRUM48
ORG $5B00 : DS $10000-$,0 ; clear the unwanted sysvars/stack
ORG ...
start:
; your code...
SAVETAP "tapsnap.tap", start

^^ I didn't try it, so not sure if it works, or if it helps, but you can try and let me know, if it does help or make it worse)

Ped7g
25.09.2021, 10:30
Как говорится - Найдите различия.

Well, I see only the difference in the BASIC state after return? Which is "by design" with the snapshot TAP, it does put the loader and RAMTOP so low that it is unable to return to BASIC correctly, it's for asm-only, to give it maximum room.

The loader in 1.07RC8 probably leaves less room for asm code and preserves more of BASIC state.

Anyway, I really don't think using the snapshot format for releasing SW is good idea, I use snapshots during development a lot as I can load them quicker into emulator, but for final release you should produce correct TAP, not the snapshot one.

BTW, is this the new emulator-test from Mark Woodmass? I didn't check its source, but I believe this is one of those where you can use DEVICE with RAMTOP argument, and example/TapLib to produce that simple valid loader with valid sysvars. Should require minimal changes to source.

The question is, how should one know about this... and I have no good answer for this, ZX development always has a bit of "everybody knows this" parts, which may be surprising if you are not experienced with the platform and you don't know how it works.

Ped7g
25.09.2021, 14:26
yeah.

I don't have that version of test, but I have seen some halt2int.v1 zip recently, which looks quite similar (is also from Woody), but it has GPL license.
(MIT is more permissive, as you can distribute the binary-only and keep your changes secret, GPL requires you to provide also source with all your changes, if you distribute the binary)
(both licenses are very convenient for this kind of stuff, like tests/tutorials, as you can easily modify and publish it under the same license)

So checking the halt2int source, there's no BASIC loader, I guess pasmo could create TAP with loader, similar to what sjasmplus SAVETAP does, but the loaders differ a bit. The `SAVETAP "file",start` **is** like snapshot. You give the assembler task to produce own loader, which will restore the memory to the current "DEVICE" state in assembler, and start like that, letting all the work on the assembler (so the sjasmplus will also include loading-screen, if you modify the ULA screen area before SAVETAP, if I remember it correctly).

With test like this, it is IMO better to use own tape loader and keep BASIC state valid, or reuse the example TapLib macro directly.

If you will upload somewhere your sjasmplus-version of that test, I can try to modify it to use the TapLib example, so you can see how many changes are required to achieve that, and how-to do it. :)

Ped7g
27.09.2021, 05:03
zebest: version modified for sj

the ".sj.asm" files are modified, ".asm" are original
you can diff them to see my changes

As far as I can tell, the machine code is identical, only the tap loader is not provided by original author and the sjasmplus default loader for auto-savetap is not a good choice for calling small asm from basic and return back to it.

krt17
27.09.2021, 10:35
Я извиняюсь (на самом деле нет), вам делать нечего, как грузить других бредом?
Если интересно копаться в чужих глюках то копайтесь, если есть проблема сделайте синтетический тест и покажите.
Подобные кейсы возникают от непонимания того что вы делаете, и очень жаль что с такими тут продолжают сюсюкаться.

Ped7g
27.09.2021, 10:46
Или спишем на особенность?

sorry, I didn't pay attention to the numbers in the screenshot... next time rather put at least one example in the text...

seems like pasmo feature. It's the `ld de,-10000+38` line (line 93 in original source), which pasmo assembles as `11 ca d8` and sjasmplus as `11 16 d9`

According to my calculator -10000+38 is -9962, and that is in 16bit integer encoding $D916

Why pasmo does produce $D8CA instead.... I have no idea. ... oh, that's -10038 ... so it does evaluate it as -10000-38`?
Don't know, consult this feature of pasmo with authors of pasmo. Maybe it's intentional. I prefer regular math evaluation instead....

Anyway, so the sjasmplus version of that test does need `ld de,-10038` to get the same machine code as from pasmo.

Ped7g
27.09.2021, 11:16
It's math, not opinions.

-10000+38 is -9962 and that's 0xd916

If pasmo wants 2+2 equal to 5, it's their choice. sjasmplus will not evaluate math like that, until I'm contributing to it, you would need to fork it yourself and add bugs to the evaluator, if you need wrong math.

edit: I did ask Woody about it... he simply adjusted the numbers in source until the result of test was what he expected, so he was not aware of how the pasmo evaluates that, and that he wrote -10038 constant in the end. In later version he changed the code to not have this expression, and do `sbc` in the code instead.

edit2: https://pasmo.speccy.org/pasmodoc.html#opertable
and it's not a bug, just incompatible feature. Unary minus has lower precedence than binary plus in pasmo, so it does assemble the source as documented.
(and yes, I find this strange, but I would assume the original author had some good reasons why to do this... but I personally prefer the sjasmplus way ... and I should remember this whenever somebody has issues migrating from pasmo to sjasmplus, or the other way)

Ped7g
27.09.2021, 12:47
you are welcome to point out any issues/bugs or differences. It could have been also issue with sjasmplus, and then I would be glad you did post it.

(considering how bugged sjasmplus was in older versions, I wouldn't be shocked if you found out some another bug... even now with 1.18.3 I had two bug reports on github already)

0xDEAD
03.10.2021, 13:42
Из мануала SjasmPlus по структурам:

Warning
Do not use the offset labels in indirections like:

LD A,(SDOT.X)
This will conflict with futher 'improvements' ;-)

If this is absolutely necessary (why?) use something like this:

LD A,(+SDOT.X)
Вот тут не понял. Почему do not use, и чем конструкция LD A,(SDOT.X) отличается от описанного в том же мануале чуть выше примера ld a,(COLOR.GREEN)?

Ped7g
03.10.2021, 15:58
Почему do not use

I don't know. That comment is in the documentation since who-knows-when and no idea what the author had on mind.


отличается от

The difference is that "SDOT.X" is internal structure offset, like +4 for example (checking now docs, it's actually +0 in docs example 6.2). "COLOR.GREEN" is instance of structure somewhere in memory, so it's address like 0x1234. ("SCOLOR.GREEN" is the one to not use directly, that's part of structure definition)

I'm still confused what issue was author foreseeing and what improvements he had on mind, because as far as I can tell, there's nothing tricky about using the structure offset itself that way (except it makes little sense, why would you want to do `ld a,(SDOT.X)` .. to read ROM?)
Even if you really want to read the data from ROM 0x0000 area, you can create "instance at address" like `ROMDOT SDOT = 0x0000` and use `ld a,(ROMDOT.X)` instead to avoid the offset label. (or ORG 0x0000 and instance SDOT after that).

The warning is specifically about memory indirection "(address)", so `ld de,SDOT.X` is ok, no issue with that. But right now in current sjasmplus `ld de,(SDOT.X)` will work too, assembling as `ld de,(0)`. Maybe the original author did plan to add some warning in such case, to make sure you didn't forget `ix+` or something like that?

I don't know. :)

0xDEAD
03.10.2021, 16:14
In two words: can I use something like ld a,(COLOR.GREEN), or even like LD A,(SDOT.X) (!) in my code to get access to the strucrure's members, or not? :) I am confused.
Does it means that using ld de,(SDOT.X), i will not get in DE value of SDOT.X label pointed to, but, instead, value of (0)?

Tested it, at last, and it seems, it works as it should be: ld (label.field), a writes smtg to memory and ld a, (label.field) reads from it. No idea, what that warning means, but ok.

Ped7g
03.10.2021, 22:31
can I use something like ld a,(COLOR.GREEN)

you can use currently any of those symbols in all possible ways, it will get assembled "correctly", but using the structure offset as absolute address is probably not what you want, sounds like bug in your logic.

I tried to prepare example about basic usage of STRUCT (it has more extended stuff, but this should be enough to illustrate what the docs warning is about):


; structure definition (ie. like "struct" in C, defining structure)
STRUCT SCOLOR
RED BYTE 4 ; offset 0
GREEN BYTE 5 ; offset 1
BLUE BYTE 6 ; offset 2
ENDS

STRUCT SDOT
ID WORD 0 ; offset 0
C SCOLOR 0,0,0 ; offset 2
X BYTE 0 ; offset 5
Y BYTE 0 ; offset 6
ENDS

; this will assemble the same way as if you did define these symbols by EQU:
; (but sjasmplus will also remember default values of fields to create instances)
; (that part can't be replicated by EQU, only the symbol definitions)

; SCOLOR.RED EQU 0x0000
; SCOLOR.GREEN EQU 0x0001
; SCOLOR.BLUE EQU 0x0002
; SCOLOR EQU 0x0003 ; length of SCOLOR struct

; SDOT.ID EQU 0x0000
; SDOT.C EQU 0x0002 ; offset of SCOLOR struct inside SDOT struct
; SDOT.C.RED EQU 0x0002
; SDOT.C.GREEN EQU 0x0003
; SDOT.C.BLUE EQU 0x0004
; SDOT.X EQU 0x0005
; SDOT.Y EQU 0x0006
; SDOT EQU 0x0007 ; length of SDOT struct

; after structures are defined, you can create instances of them in memory
ORG $8000
myDot SDOT {0x1234, {11, 22, 33}, 44, 55} ; defines "myDot" with ID 0x1234, X=44, Y=55, and C=[11,22,33]

; using it in code
ld ix,myDot ; address of instance
ld c,(ix+SDOT.C.GREEN) ; C = 22 ; assembles as "ld c,(ix+3)"
ld a,(myDot.C.BLUE) ; A = 33 ; assembles as "ld a,(0x8004)"
ld de,SDOT.X ; DE = 5 ; offset inside SDOT struct to field X
ld de,(myDot.X) ; E = 44, D = 55 ; "ld de,(0x8005)"
; ^ this is using instance myDot label, not structure offset

; what docs warns against:
ld de,(SDOT.X) ; ld de,(0x0005) -> reading ROM
; but this doesn't make lot of sense, as you are reading memory from offset
; so it looks rather like bug, like missing "ix+", for example:
ld e,(ix+SDOT.X)
ld d,(ix+SDOT.Y) ; here using the +5 and +6 offsets makes sense


Try to build this with listing: sjasmplus --lst --lstlab example.asm
and check the symbol table and machine code emitted, hopefully this will make more sense.

0xDEAD
04.10.2021, 00:10
Who would use definition of structure in indirect addressing instead of declared one? But, who knows... :)
This was the source of my misunderstanding. Everything is clear now, thanks!

transman
25.10.2021, 13:26
Возможно ли реализовать передачу макросу строки в кавычках в качестве параметра или одного из параметров?

Пример применения
macroname "textstring"

macro macroname str
db ...some code...
db str
db ...some code...
endm

Ped7g
25.10.2021, 20:48
Возможно ли реализовать передачу макросу строки в кавычках в качестве параметра или одного из параметров?

да



$ sjasmplus --msg=lst -
macro macroname str
db 1,2,3
db str
db 3,2,1
endm

macroname "textstring"
# file opened: console_input
1 0000 macro macroname str
2 0000 ~ db 1,2,3
3 0000 ~ db str
4 0000 ~ db 3,2,1
5 0000 endm
6 0000
7 0000 macroname "textstring"
7 0000 01 02 03 > db 1,2,3
7 0003 74 65 78 74 > db "textstring"
7 0007 73 74 72 69 >
7 000B 6E 67 >
7 000D 03 02 01 > db 3,2,1
8 0010
# file closed: console_input


(should be working in all versions I remember, but to create the example output above I did use 1.18.3)

Weclemans
01.11.2021, 08:39
Здравствуйте!
Возможно ли использовать макро для загрузки регистров?
Например:
ld de, macroname 8084h
или
defw macroname 80A0h

Очень нужно реализовать что-то подобное, чтобы универсально править портируемые исходники.
Спасибо.

Ped7g
01.11.2021, 09:36
Возможно ли использовать макро для загрузки регистров?


unfortunately not, defining new functions is not possible. Macros could be used only in place of instructions, ie:


macro macroname instruction?, value?
instruction? value?
endm

; usage
macroname <ld de,>, 8084h ; will produce "ld de,8084h"
macroname defw, 80A0h ; will produce "defw 80A0h"

Weclemans
01.11.2021, 09:57
unfortunately not, defining new functions is not possible. Macros could be used only in place of instructions, ie:


macro macroname instruction?, value?
instruction? value?
endm

; usage
macroname <ld de,>, 8084h ; will produce "ld de,8084h"
macroname defw, 80A0h ; will produce "defw 80A0h"


Oh yeah, that's good option, too. Thanks a lot.

P.S. Hmm, how about a harder example?
ld (804Ah), a

Ped7g
01.11.2021, 10:38
not in direct way.

You can do macro which will EQU some global value, and use that in code, then you have something somewhat like function macro.

0xDEAD
03.11.2021, 15:19
Ped7g

1. Assembled file is saved in UTF8, font is in Win-1251 encoding, ENCODING "WIN" directive is enabled:

http://i.piccy_.info/i9/8c1023158cf7b0d7f2fd90e0d4c58c0d/1635941881/57636/1446979/64751VS_800.jpg (http://piccy_.info/view3/15132689/2bca5c42c098a1061ff90a7d2d9ef70a/orig/)http://i.piccy_.info/a3/2021-11-03-12-18/i9-15132689/800x418-r/i.gif (http://i.piccy_.info/a3c/2021-11-03-12-18/i9-15132689/800x418-r)


http://i.piccy_.info/i9/fa9ea81b00e7a1fb9dfc34a9db5fa9ae/1635941913/57605/1446979/font_800.jpg (http://piccy_.info/view3/15132690/16c5d759df69237e76af7de4669af980/1200/)http://i.piccy_.info/a3/2021-11-03-12-18/i9-15132690/800x458-r/i.gif (http://i.piccy_.info/a3c/2021-11-03-12-18/i9-15132690/800x458-r)


http://i.piccy_.info/i9/f88f343cd2240a38da7e2df806a58183/1635941927/128496/1446979/97503Emulator_800.jpg (http://piccy_.info/view3/15132691/c679a9d85b94dbd1b50133dda1279bd7/orig/)http://i.piccy_.info/a3/2021-11-03-12-18/i9-15132691/800x508-r/i.gif (http://i.piccy_.info/a3c/2021-11-03-12-18/i9-15132691/800x508-r)




ORG 40000
ENCODING "WIN"
ld hl, msg2
call print
..................
..................
msg2 ABYTEZ 0 "TEST test TEST\NZX-Spectrum.\NText can be written in english...\N\N...или по-русски"

2. Assembled file is saved in Win-1251, font is in Win-1251 encoding, ENCODING "WIN" directive is disabled:

http://i.piccy_.info/i9/3043813b19326ae404c06e43005290cf/1635942290/68634/1446979/Emulator_2.png (http://piccy_.info/view3/15132704/6c1de7b1e11fe1e6fd5ba2c8d27b6f58/)http://i.piccy_.info/a3/2021-11-03-12-24/i9-15132704/793x448-r/i.gif (http://i.piccy_.info/a3c/2021-11-03-12-24/i9-15132704/793x448-r)


http://i.piccy_.info/i9/764a8eb800399e9a729348c5a632e7b9/1635942310/68501/1446979/6887VS2.png (http://piccy_.info/view3/15132705/b86083bf56de801a415f801f43a48bf0/)http://i.piccy_.info/a3/2021-11-03-12-25/i9-15132705/786x491-r/i.gif (http://i.piccy_.info/a3c/2021-11-03-12-25/i9-15132705/786x491-r)


???

krt17
03.11.2021, 15:48
Даже интересно стало, а что вы ожидали?

0xDEAD
03.11.2021, 15:50
Я ожидал, что если в тексте присутствует директива

ENCODING <encoding>
Useful only for non English users

Set the current encoding, i.e. if you set "DOS", SjASMPlus will automatically convert strings from ANSI to DOS-866. Encoding may be "DOS"(DOS-866) or "WIN"(ANSI/Win-1251). Default is "WIN".
и текст набран в кириллице, и для печати используется фонт в кодировке Win-1251, то на экране я увижу именно то, что я и набирал в кодировке Win-1251, а не чёрти-что.

http://i.piccy_.info/i9/94b7ef531096b25693090db1e816bec3/1635944099/47179/1446979/Screenshot_2021_11_03_145405.png (http://piccy_.info/view3/15132729/66270f8fc565e5607411b0a418131389/)http://i.piccy_.info/a3/2021-11-03-12-55/i9-15132729/582x509-r/i.gif (http://i.piccy_.info/a3c/2021-11-03-12-55/i9-15132729/582x509-r)


http://i.piccy_.info/i9/0e514d77cf67a827f7ee60aa566ba3bc/1635944116/16612/1446979/Screenshot_2021_11_03_145426.png (http://piccy_.info/view3/15132730/5a3b45c9eadf0340f15b2415f11a9ce8/)http://i.piccy_.info/a3/2021-11-03-12-55/i9-15132730/620x99-r/i.gif (http://i.piccy_.info/a3c/2021-11-03-12-55/i9-15132730/620x99-r)

krt17
03.11.2021, 15:53
Ну ок, если бы текст был в 866 то наверное так бы и произошло, но utf8 это немного другое.

0xDEAD
03.11.2021, 15:57
Ясно, значит, директива ENCODING не нужна.
Я ж не знал.

krt17
03.11.2021, 16:08
Да, проще в редакторе выставить нужную кодировку сразу. Даже если из 866 в 1251 надо, лучше наверное вручную, по крайней мере ожидаемый результат.

- - - Добавлено - - -

По описанию в доках кстати не понятно что именно имелось, откуда в ANSI кириллица или возможно имелось ввиду KOI-7 или еще что то, непонятно.

0xDEAD
03.11.2021, 16:10
Я так и делаю, потому что по-другому просто не сделать, и вариантов нет. Но VS каждый раз при открытии проекта, открывает все файлы в UTF-8, и приходится каждый раз файлы, в которых находится текст, переоткрывать в другой кодировке, и это напрягает. Собственно говоря, я и не имею ничего против UTF-8, но против неё имеет против Спектрум.
Я-то думал, что ENCODING "WIN" как раз позволит ассемблировать текст в кодировке, которая будет указана, но раз это не работает, то не работает.

krt17
03.11.2021, 16:52
Немного потестил, по факту работает только если текст в 1251, то можно перевести в 866. Все остальные комбинации не заработали, либо я уже запутался.

- - - Добавлено - - -

Вот я туплю, в доках про это и написано же. Короче если DOS то из 1251 переводит в 866, во всех остальных случаях ничего не делает.

0xDEAD
03.11.2021, 21:10
А, понятно, в мануале несколько двусмысленно написано.
Получается, команда всего лишь из исходника в 866 или 1251 делает наоборот.

krt17
03.11.2021, 21:15
Нет, только из 1251 в 866. Там 1251 названа ANSI

0xDEAD
03.11.2021, 21:29
Нет, только из 1251 в 866. Там 1251 названа ANSI
Погоди. В мануале написано, что если указать "DOS", то ассемблер конвертит из 1251 в 866, и существует две опции - "DOS" и "WIN". Логично предположить, что раз опция "DOS" делает 1251 > 866, то опция "WIN" делает наоборот, просто в мануале приведён только один пример?

krt17
03.11.2021, 21:49
WIN типа по дефолту, значит не переводить. В любом случае я проверил, при WIN ничего не происходит.

- - - Добавлено - - -

Я думаю можно сменить кодировку по умолчанию. Не пользуюсь VSCODE и тем более VS, но в моем саблайме все меняется достаточно просто. 1251 в качестве дефолтной это нормальная практика, нам же не нужны иероглифы.

Ped7g
04.11.2021, 01:38
Ясно, значит, директива ENCODING не нужна.
Я ж не знал.

sjasmplus binary doesn't contain all possible encodings and locales (and that's why it is ~300-500kB executable, not 15MB :) ).

the `ENCODING` directive is some one-way hack to do 866->1251 conversion or something like that, I'm NOT familiar with these encodings, and it's year+ since I was writing tests for it, so I'm not 100% sure if it has also some other way, but I'm 100% sure it has no idea what UTF8 is.

If you want to edit sources in UTF8, add to your build process conversion by some tool which knows all encodings, for example I did shorten your example to UTF8:


db "\N...или по-русски"

and saved that as "test_utf8.asm"

Then I can in linux do with `iconv` this:


$ iconv -f utf8 -t cp1251 test_utf8.asm | sjasmplus - --msg=lst
# file opened: console_input
1 0000 0A 2E 2E 2E db "\N...��� ��-������"
1 0004 E8 EB E8 20
1 0008 EF EE 2D F0
1 000C F3 F1 F1 EA
1 0010 E8
2 0011
# file closed: console_input


(in my own project I would probably have special extension for all files with DB needing conversion like ".utf8.asm" and have implicit Makefile rule to convert those with iconv to ".1251.asm" and include from regular source those "something.1251.asm".
So then the build process would refresh them from the utf8 sources as needed, but sjasmplus would include the 1251 encoded ones ... but whatever works for you).

Why your VS/VSC doesn't remember encoding of project per file is kinda LOL, but I can't help with that, I don't use VS or VSC (in my favourite editor Kate I can open unknown file and it will try to auto-detect correct encoding, and if I manually switch it to correct encoding, it keeps the info in cache of recently opened files, so technically it will open with correct encoding forever on my local machine).

0xDEAD
04.11.2021, 08:39
Why your VS/VSC doesn't remember encoding of project per file
Well, actually it does. "Problem" happens mostly only when I switching from one PC to another editing the same source, or, when I pulling my sources from GitHub. Thus, this is not a big inconvenience at all.

breeze
17.11.2021, 23:03
Есть задачка:

Определяем define appName "testapp"

этот define используется как в макросе (например):

MACRO newApp aName
db aName
ENDM

так и в пути при сохранении SAVEBIN

Собственно вопрос в том, как склеить 2 строки, что-то типа:

SAVEBIN "/dir1/dir2/dir3" + appName

Можно конечно с помощью LUA продефайнить ещё одну переменную:

LUA PASS1
appName = sj.get_define("appName")
print(appName)
savePath = ("install/bin/" .. appName)
print(savePath)
ENDLUA

Только вот результат в savePath будет install/bin/"testapp"

Не понятно какого фига приклеившиеся кавычки. Если их убрать в define, то Savepath правильный, но тогда падает сборка макроса, потому что «Can't found label testapp»
То есть без кавычек db почему-то хочет сохранить значение label? o_O вот же ж дичь.

breeze
18.11.2021, 13:02
И всё-таки походу пьесы в sjasmplus косяк. Нашёл решение.

Определяем без кавычек define appName testapp

В макросе добавляем кавычки с помощью LUA:

LUA ALLPASS
sj.insert_define("_appName", '"' .. sj.get_define("appName") .. '"')
_pc("db _appName")
ENDLUA

Тут вопрос закрыли. Далее формируем путь для сохранения файла:

LUA ALLPASS
sj.insert_define("SAVEPATH", '"install/bin/' .. sj.get_define("appName") .. '"')
ENDLUA


DISPLAY "SavePath:",/A,SAVEPATH

Тут всё отлично получаем наконец нормальную строку:

> SavePath:install/bin/testapp

Пытаемся сохранить:

SAVEBIN SAVEPATH, appStart, appEnd-appStart

Но! Savebin выдаёт мутную ошибку:

appTemplate.asm(141): error: Error opening file: install/bin/testapp
testApp.asm(48): ^ emitted from here

И что это хз. Если вместо SAVEPATH написать "install/bin/testapp" всё сохраняется на ура.

- - - Добавлено - - -

Хех, поэкспериментировав немного получил вообще оооочень странную картину:

Если при формировании SAVEPATH добавить в конец 1:

LUA ALLPASS
sj.insert_define("SAVEPATH", '"install/bin/' .. sj.get_define("appName") .. '1"')
ENDLUA

то ошибка вообще фантастическая, оказывается приклеивается туева хуча пробелов :))))


> SavePath:install/bin/testapp 1

И стало понятно, что это из-за комментария, в конце define, нельзя так делать XD


define appName testapp ; Краткое название приложения

Солюшен найден!

krt17
18.11.2021, 14:30
Как я понял достаточно?


org 0x8000
define app appName
LUA ALLPASS
sj.insert_define("SAVEPATH", '"test/' .. sj.get_define("app") .. '.bin"')
_pc ('db "'..sj.get_define("app")..'"')
ENDLUA
savebin SAVEPATH,0x8000,$-0x8000

breeze
18.11.2021, 20:48
Как я понял достаточно?

Ну в принципе да, можно опустить пустые дефайны и сразу склеить :)

Ped7g
19.11.2021, 03:16
И стало понятно, что это из-за комментария, в конце define, нельзя так делать XD

those trailing spaces due to comment shouldn't happen since v1.18.2, so you are probably at older version of sjasmplus? It makes things easier when you specify version of sjasmplus when reporting some issue.

You can also trim/add quotes in lua script, but I never remember lua syntax from head, so I would have to google the lua tutorials to find the string operators and how to do it.

There also does exist:


--outprefix=<path> Prefix for save/output/.. filenames in directives

It's not super smart and it can break quite easily too but it may cover some use cases, so in your case something like `--outprefix=/dir1/dir2/dir3/` would affect the `SAVEBIN appName` from first post (notice the trailing slash in the option). But it would affect also many other output commands, so not sure if this is helpful in your case.

Let me know if I should produce some lua example doing also the quotes stripping/adding, maybe I even have it somewhere in tests, I think I recall something like that, but I'm not sure.

breeze
19.11.2021, 12:32
those trailing spaces due to comment shouldn't happen since v1.18.2, so you are probably at older version of sjasmplus?

nop. SjASMPlus Z80 Cross-Assembler v1.18.3
I think it physically cannot detect trailing spaces, since the text in this case is not in quotes.



It makes things easier when you specify version of sjasmplus when reporting some issue.


Well, this is not really an issue, rather a flaw.



You can also trim/add quotes in lua script, but I never remember lua syntax from head, so I would have to google the lua tutorials to find the string operators and how to do it.


Well, I'll keep in mind. But in this situation, it is easier to move the comment to another line.



There also does exist:


--outprefix=<path> Prefix for save/output/.. filenames in directives

It's not super smart and it can break quite easily too but it may cover some use cases, so in your case something like `--outprefix=/dir1/dir2/dir3/` would affect the `SAVEBIN appName` from first post (notice the trailing slash in the option). But it would affect also many other output commands, so not sure if this is helpful in your case.


As a single solution yes, but I have a multi-assembly and may have different paths and filenames.



Let me know if I should produce some lua example doing also the quotes stripping/adding, maybe I even have it somewhere in tests, I think I recall something like that, but I'm not sure.

Okay, I'll try to implement this solution.

It would be very nice to get closer interaction between variables inside a macro and the results of LUA execution.

- - - Добавлено - - -

Есть ещё вопрос по макросам. Как получить длину передаваемой строки внутри макроса?

Например:


print "Loooooooong text string!"

MACRO print text

вот чему тут равна длина строки text?

ENDM

Длину строки можно получить с помощью LUA:

string.len(text)

Но как получить доступ к переменной макроса?

Можно было бы временно сохранить с помощью:

DEFINE text_ text

и уже внутри LUA достучаться:

sj.get_define("text_")

но вместо значения переменной text, мы получаем просто слово «text».

Чёт прям замкнутый круг какой-то. Может есть какой-то спецсимволы, что бы передать значение?

krt17
19.11.2021, 12:47
Не совсем понятен общий вид, но вообще длину данных можно узнать


org 0x8000
macro ma1 parm1
temp = $
db parm1
tlen = $-temp
org temp
db tlen,parm1
endm
ma1 "test"
savebin "test.bin", 0x8000,$-0x8000

breeze
19.11.2021, 13:06
Не совсем понятен общий вид, но вообще длину данных можно узнать


org 0x8000
macro ma1 parm1
temp = $
db parm1
tlen = $-temp
org temp
db tlen,parm1
endm
ma1 "test"
savebin "test.bin", 0x8000,$-0x8000


Жоска :) Но вечером попробую эту идею.

Ped7g
19.11.2021, 14:21
nop. SjASMPlus Z80 Cross-Assembler v1.18.3
I think it physically cannot detect trailing spaces, since the text in this case is not in quotes.

I'm really failing to replicate this:


ped@ped7g-sb:~$ sjasmplus-1.18.3 --version
SjASMPlus Z80 Cross-Assembler v1.18.3 (https://github.com/z00m128/sjasmplus)
ped@ped7g-sb:~$ sjasmplus-1.18.3 - --msg=lst
define appName testapp ; Краткое название приложения
LUA ALLPASS
sj.insert_define("SAVEPATH", '"install/bin/' .. sj.get_define("appName") .. '1"')
ENDLUA
db SAVEPATH
# file opened: console_input
1 0000 define appName testapp ; Краткое название приложения
2 0000 LUA ALLPASS
3 0000 ~ sj.insert_define("SAVEPATH", '"install/bin/' .. sj.get_define("appName") .. '1"')
4 0000 ENDLUA
5 0000 69 6E 73 74 db "install/bin/testapp1"
5 0004 61 6C 6C 2F
5 0008 62 69 6E 2F
5 000C 74 65 73 74
5 0010 61 70 70 31
6 0014
# file closed: console_input


I know this is not important for you, but makes me wonder what is happening and if there is some other bug in sjasmplus, that's why I'm poking into this detail. The trailing spaces should be now removed from DEFINEs. Maybe you have the DEFINE in some other code path like IF/ENDIF block or inside MACRO, or I don't know... interesting. If you will find some time, can you try to produce full example where v1.18.3 fails to remove the trailing space? Thank you.

About string operators in sjasmplus - there are none, unfortunately. For any complex string manipulation the best way is to use lua script. The hack to figure out length by `ORG` macro is usable when in DEVICE mode, but would ruin the output in raw/OUTPUT mode (although you can open OUTPUT file for rewrite and rewind position back, I would probably rather opt for lua solution instead).

Macro arguments to lua -> definitely possible, there is some test/example somewhere... Check this test in particular and whole folder "lua_examples" and maybe also "macro_examples": https://github.com/z00m128/sjasmplus/blob/master/tests/lua_examples/lua_macro_arg2.asm
Not sure if it will answer all your questions/issues, but maybe you will be able to pick up some trick or two.

I'm following this conversation a bit half-minded as I'm focusing on some work stuff, so in case you are waiting for some example from me or you are stuck with final version of your attempt, post that as new post clearly saying you expect specific help from me, otherwise I may miss it (right now I think you are trying to resolve it all yourself, so I'm giving you just pointers where to look, not preparing any full example).

EDIT: actually going through that example, that's not useful for string manipulation... the older https://github.com/z00m128/sjasmplus/blob/master/tests/lua_examples/lua_macro_arg.asm is then probably more relevant, but I'm still not sure how well the string is passed through, I would have to write some actual code and test it to be 100% sure how it works. "It should be possible" is all I can say at this moment. :)

krt17
19.11.2021, 16:52
Жоска
Да я сам не люблю переставлять орг, по мне сам device режим это убожество.
В принципе нормально работает и так


org 0x8000
db tend -$-1
db "test"
tend
savebin "test.bin", 0x8000,$-0x8000

Нужно по обстановке смотреть. Просто помнить что = можно в макросах, а просто метки и equ нельзя.

Ped7g
19.11.2021, 19:27
Просто помнить что = можно в макросах, а просто метки и equ нельзя.

uhm... what exactly is not possible about labels in macros?
Regular label means the macro can be emitted only once (second emit would create duplicate label, at least in the same module), but you can define normal label in macro *once* (per module).

The local labels inside macro are automatically per-instance so every use of macro has its own independent labels.

And since v1.18.3 you can create non-macro local labels from inside macro by using "@" prefix ( https://github.com/z00m128/sjasmplus/blob/master/tests/macros/local_labels.asm ):


macro test
@.kip3 ; prevent macro-local label and create regular local label instead
kip0
.kip1
@.kip2
endm

module main
; should produce labels: main.hoi, main.kip0, 0>kip1, main.kip0.kip2, main.hoi.kip3
hoi test
endmodule


resulting listing:



# file opened: local_labels.asm
1 0000 macro test
2 0000 ~ @.kip3 ; prevent macro-local label and create regular local label instead
3 0000 ~ kip0
4 0000 ~ .kip1
5 0000 ~ @.kip2
6 0000 endm
7 0000
8 0000 module main
9 0000 ; should produce labels: main.hoi, main.kip0, 0>kip1, main.kip0.kip2, main.hoi.kip3
10 0000 hoi test
10 0000 >@.kip3 ; prevent macro-local label and create regular local label instead
10 0000 >kip0
10 0000 >.kip1
10 0000 >@.kip2
11 0000 endmodule
12 0000
# file closed: local_labels.asm

Value Label
------ - -----------------------------------------------------------
0x0000 X 0>kip1ing
0x0000 X main.hoi
0x0000 X main.hoi.kip3
0x0000 X main.kip0
0x0000 X main.kip0.kip2


So, labels in macros is just another available tool, should "work". It has somewhat specific rules and outcome, being affected by "inside macro", but I hope those rules are reasonably simple and usable.

If you have source where labels inside macros don't work as designed, let me know, then it may be bug or misunderstanding and we can usually resolve that together.

I'm not so into changing the rules, because every time I did some "fix" since 1.10.4 to today and the fix did some slight modification of old behaviour, even if technically it is now more correct, there are always some users with project which gets broken and requires fixing, and that's very annoying (sorry guys). So I'm trying hard to keep original behaviour and do only "fixes" and "extensions", if possible. But the current syntax of sjasmplus is quite powerful, like 7/10 IMHO. There're some things I would design a bit differently, if I was starting from scratch a new assembler. And there are definitely things I would implement differently. But overall the decent base quality was one of the reasons, why I did start fixing and extending sjasmplus, it was already quite good, just a bit bugged... :) (just my personal opinion, and I don't care if other people prefer other assembler, I just tried to make sjasmplus viable option)

edit: not even sure what I was trying to say with that last paragraph... I think the main point is:
reporting your issues and bugs with sjasmplus is welcome. I can't promise to answer/fix/extend everything as quickly as you need it, but I like to see sjasmplus used in your projects, so I will usually try to find some solution, if you have problem. :)

breeze
20.11.2021, 12:27
I'm really failing to replicate this:

Aw **** here we go again =)



DEVICE ZXSPECTRUM128


org #8000


appStart


define appName cursor ; comment


LUA ALLPASS
sj.insert_define("SAVEPATH", '"install/bin/' .. sj.get_define("appName") .. '"')
ENDLUA


db SAVEPATH


appEnd


SAVEBIN "test.bin", appStart, appEnd-appStart


result:



sjasmplus.exe test.asm --lst=test.lst
SjASMPlus Z80 Cross-Assembler v1.18.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
Pass 3 complete
Errors: 0, warnings: 0, compiled: 17 lines, work time: 0.015 seconds


test.lst



# file opened: test.asm
1 0000 DEVICE ZXSPECTRUM128
2 0000
3 0000 org #8000
4 8000
5 8000 appStart
6 8000
7 8000 define appName cursor ; comment
8 8000
9 8000 LUA ALLPASS
10 8000 ~ sj.insert_define("SAVEPATH", '"install/bin/' .. sj.get_define("appName") .. '"')
11 8000 ENDLUA
12 8000
13 8000 69 6E 73 74 db "install/bin/ cursor "
13 8004 61 6C 6C 2F
13 8008 62 69 6E 2F
13 800C 20 20 20 63
13 8010 75 72 73 6F
13 8014 72 09 09 09
13 8018 09
14 8019
15 8019 appEnd
16 8019
17 8019 SAVEBIN "test.bin", appStart, appEnd-appStart
# file closed: test.asm


now also got trailing space before appName =)

Ped7g
20.11.2021, 16:57
ahh... ok... now it makes sense to *me*... ;)

The space ahead is intentional, I don't expect value to be indented, so only one space is removed and following space is considered define value.
But the trailing stuff is tab vs space, I have space-as-tabs everywhere, and seems I forgot to test the trailing space trimming with tabulators...

I will take a look on it. (and I know the leading space preservation is not intuitive, but I'm not sure what to do about it... it's a bit unclear. In macro arguments I guess it's safe to trim everything, because you can use `<>` syntax to enclose argument value which contains leading/trailing space, but in DEFINE there's no delimiter syntax, everything is just new value for DEFINE (the trailing space trimming is a bit dubious extra, but nobody objected about it so far).

edit: or maybe I will just add to docs that DEFINE and macro arguments trim whitespace (and fix the code), and there will be no possible way to set up DEFINE value with leading/trailing white space.

breeze
22.11.2021, 01:23
Ped7g is it possible access to DEFARRAY's element from LUA?

Ped7g
22.11.2021, 14:49
is it possible access to DEFARRAY's element from LUA?

Hmm, had to look into source, but unfortunately, not.
If it is numeric value (32bit int result), you can at least evaluate it through `_c("test_array[2]")`, but if you need string, I was unable to find any decent workaround. I tried also some trick to define single temporary define from one element, but that doesn't substitute during evaluation the way how it would be needed for lua script.

breeze
28.11.2021, 12:29
Ped7g and AGAin very strange problem :)



db_u "Test"

macro db_u text
define _t text
lua allpass
local str = sj.get_define("_t")
print(type(str))
print(str)
str = str:gsub(".?$","")
str = str:gsub("^.?","")
print(str)
endlua
undefine _t
endm



Got error — (16): error: [LUA] attempt to call global 'gsub' (a nil value)

16 line → str = str:gsub("^.?","")

But if i add ; in begin like:



; str = str:gsub(".?$","")
; str = str:gsub("^.?","")


no error:



SjASMPlus Z80 Cross-Assembler v1.18.3 (https://github.com/z00m128/sjasmplus)
string
"Test"
Test
Pass 1 complete (0 errors)
string
"Test"
Test
Pass 2 complete (0 errors)
string
"Test"
Test


WTF???? :D

- - - Добавлено - - -

Solution found :D

replace code in style LUA 5.3:



str = string.gsub(str, ".?$","")
str = string.gsub(str, "^.?","")


Poof! and error was gone!

Ped7g
28.11.2021, 20:14
replace code in style LUA 5.3:

yes, sjasmplus has Lua 5.1.5 ( https://github.com/z00m128/sjasmplus/issues/73 )

And AFAIK that's the last easy-to-upgrade-to version, anything newer requires a bit more more effort on sjasmplus side, and also there's some stuff I never truly understood how it was produced, and I would need to learn more about lua to resolve it.

breeze
07.12.2021, 20:46
Another day, another intro… macro

try to create autoreplacement for JR/JP



macro _jpz to
if $-to<127 or to-$<127
jr z,to
else
jp z,to
endif
endm


if code like:



label
_jpz label


all ok.

if code like:



_jpz label

label


got warning — warning[fwdref]: [LUA] forward reference of symbol

code compiles without errors, but I don't like the warning messages also

Ped7g
08.12.2021, 19:07
You can suppress warning if you know the code works as intended, add comment fwdref-ok


macro _jpz to
if $-to<127 or to-$<127 ; fwdref-ok
jr z,to
else
jp z,to
endif
endm


and the "to-$<127" can be "to-$<129". Jr is relative to "$+2" and can be -128..+127

But I would recommend you to not do this, IMHO (and also in my experience), it's lot easier to just use JR everywhere, and then modify it to JP when assembling fails due to range.
Your macro may cause unstable machine code size and if two+ of these macros keep switching on/off each other, 3-pass assembling is not enough to stabilise the labels, and you may end with invalid machine code (especially with forward reference labels).

If you are using this, you should have some good way how to test every important build if it is correct and works, and unless you are using some kind of automated tests, it sounds to me like more extra work, than doing jr/jp manually in source. (then again, I usually write very small asm projects where I have no issue to modify 10-20 jump lines by hand and also I know where I want JR and where JP, so your mileage may vary).

Sayman
28.12.2021, 07:58
а есть ли возможность добавить поддержку команд и режимов памяти Rabbit 2000?

Ped7g
29.12.2021, 10:21
а есть ли возможность добавить поддержку команд и режимов памяти Rabbit 2000?

да

but you need somebody who will do it.

I can help, but I would need somebody with R2000 expertise to explain me differences, which opcodes to add and which to remove, write/check tests and help to design extra syntax to make it useful with the extended memory model, etc..
Ie. at least one very experienced R2000 coder willing to work on sjasmplus is missing right now.

From a quick look at docs I'm missing some simple "this is how it differs from Z80" condensed to 1-3 pages, the changes seems to be small, but non-trivial, and after reading like 10 pages of CPU user manual I haven't learned much, except that it's different enough to need serious work to implement.

jerri
27.02.2022, 09:57
hello

Is there a built-in text converter from Unicode to cp1251?

Ped7g
27.02.2022, 10:12
No, there's almost zero bytes in sjasmplus dealing with encoding, except hard-coded cp1251 to dos-866 conversion, and detection of UTF16/32 BOM bytes at beginning to reject file.

sjasmplus treats source files as 8bit extended ASCII, (0x00,0x0A,0x0D inside strings have to be encoded as \0,\n,\r and \ itself has to be \\), so what bytes you have in source will be outputted into binary too.

For converting your regular source editor encoding to target ZX encoding I would suggest using some tool like iconv as part of make rule (or using the target encoding directly in text editor).

breeze
27.02.2022, 12:21
hello

Is there a built-in text converter from Unicode to cp1251?

Use LUA, Luke!

Можешь воспользоваться моим «черновиком» из CLI2R :)
77069


Добавляешь макрос:



includelua "_u.lua"


macro db_u text
define _t text
lua ALLPASS
local str = sj.get_define("_t")
str = string.gsub(str, ".?$","")
str = string.gsub(str, "^.?","")
_u(str)
endlua
undefine _t
endm


Затем в коде:



db_u " © "


В результате получишь db 127



Большая часть символов реализована, русские буквы соответствуют cp866, но спецсимволы немного отличаются, при желании коды символов можно поменять на нужные.

Ped7g
27.02.2022, 18:47
That's very nice script, just minor detail:



str = string.gsub(str, ".?$","")
str = string.gsub(str, "^.?","")


that removes any first and last byte of the argument, if you want that, you can skip regex completely and do the simpler: str = string.sub(str,2,-2)

or if you want to remove only quotes and do no change to string without quotes, you can use more specific gsub regex: str = string.gsub(str,"^"(.*)"$","%1")

I would still rather use `iconv` which is more complete and can convert from many encodings to many encodings, and is available almost everywhere in *NIX world (not sure about windows, I guess with win10 and later you can just simply move everything to WSL and use linux inside windows, to avoid all the windows troubles and deficiencies in tools). But if you don't want to depend on external tool, this script is nice and easy to patch if one needs something new or non-standard.

Ped7g
29.03.2022, 22:09
https://github.com/z00m128/sjasmplus/releases/tag/v1.19.0

added Amstrad CPC devices (AMSTRADCPC464, AMSTRADCPC6128) - by Oli Wilkinson
added Amstrad CPC save snapshot and CDT (SAVECPCSNA, SAVECDT) - by Oli Wilkinson
added SAVE3DOS (like SAVEBIN with +3DOS header)
the deprecated "ok" warning suppression is removed, use "<warning-id>-ok" comment or -Wno-...
new temporary label suffix syntax _b and _f, enabling them for all expressions
fix --longptr mode to keep 32b address when DS 0 is used
added fake instructions adc|add|sbc|sub de,bc|de|hl|sp
dec|inc|pop|push will accept also single-comma multiarg in --syntax=a mode
DUP/REPT will now accept also zero count (skipping the block)
DEFL labels can be defined even as late as in last pass
bugfixes (macros, listing, file names in errors, SLD reversepop data)


So Neo can finally abuse the temporary labels to address backward/forward inside macros even with `ld (123_b+1),hl` ... :)

Have a great time, and looking forward to new ZX/GB/MSX/CPC/Next productions...

And thank you all for reporting issues and helping to steer the development, and your feedback. Really happy to read your messages. :)

krt17
03.05.2022, 14:45
Не могу понять что не так с if not exist. Без модулей все в порядке, в модуле не совсем. Проверял с 18.2 и 19

krt17
05.05.2022, 20:08
Наверное ped7g сюда больше не заходит, сделал иссуе на гитхабе, очень уж охота переопределяемость в асме без дефайнов.

Ped7g
06.05.2022, 19:03
sorry, busy with a newborn baby, so I didn't notice there's new post. Github surely works better. ( https://github.com/z00m128/sjasmplus/issues/177 )

But this issue is a bit puzzling to me, not sure what to do about it, technically it works "as designed", but in your example it is very counter-intuitive and feels wrong...

Also I'm a bit confused what you mean "Без модулей все в порядке"
If I do in empty asm file this:



IF !exist non_mod_l1
non_mod_l1 ds 1
ENDIF

it will do the conditional block only in first pass, creating the label "non_mod_l1", but not doing `ds 1` in pass 2 and 3, so this is broken logic even without modules.
(but the `exist` was not meant to be used like this, for conditional "linking" there is `IFUSED` which works a bit differently, and for replacing default definitions with external code I would suggest DEFINE + IFDEF)

krt17
06.05.2022, 19:54
Поздравляю с приятными хлопотами, рад за вас.
У меня была идея использовать в виде именно переопределяемых процедур и данных, возможно я немного не так подошел к функционалу. Допустим есть тематический модуль, но мы хотим изменить процедуру или данные в нем не переписывая его. Раньше я делал такое через define но exist показался прямо предназначенным для этого.
Возможно тут применима логика когда фактически exist проверяется только на первом проходе, слежение за ссылками вперед оставим на писателя, тут мне кажется это не применимо. Но в целом я понял, буду использовать define, если есть обходной путь овчинка не стоит выделки.
То что у меня сработало без модуля перепроверю, вполне возможно я ошибся.

Ped7g
07.05.2022, 00:05
I have been thinking about the issue for few more hours, and I think it will stay as is.

While your example is quite logical on first read, and I would sweat a bit to explain to new assembler users why this is a problem, it *is* a problem.

Generally assemblers collect symbol values over several passes, before they start emitting machine code, at that point the symbol values should be stable. So it's impossible to reset values before each pass, and EXIST targets symbols. (contrary to that DEFINEs are reset before each pass, and are re-created each pass, so IFDEF + DEFINE works the way how you expect).

Thinking about it, the assembler working like mdlz80optimizer doing lazy evaluation of labels and "single pass" (I think, not sure about how exactly it works, but it's not N-pass) would probably work for your example, but that's completely different architecture, not going there with sjasmplus.

(and for general library, the IFUSED can be used, although I personally prefer to have full source of project together, so even when I use some "library", I first copy the library source to the project, so I can then easily modify it only for the particular project and I don't need to worry about other projects using the same base library)

transman
09.06.2022, 21:42
Ограничение на длину строки в 128 байт для BYTE/DB/DC является очень важным, или лимит можно увеличить?

Ped7g
11.06.2022, 07:55
Ограничение на длину строки в 128 байт для BYTE/DB/DC является очень важным, или лимит можно увеличить?

All internal buffers are fixed size. read-line is 2048, define-substitution two buffers 2048, emit-bytes-values inside BYTE/DB/DC/DZ directive is 128+2, etc...

You can raise limits of all those buffers (and hope that you did find all relevant ones) and build version which will accept more, but there will be always some hard limit unless you rewrite the code to use dynamic memory allocation per line.

But even to reach 128 items in DB it must be super long source-code line which is difficult to read+edit in text editor, so I don't see 128 limit as an issue (in my own source I'm often limiting number values to 16 or 32 per line and quoted text to 64 chars).

For binary data like gfx consider `INCBIN` instead of converting it to source code, or patch the convertor to split it into multiple lines.

Ped7g
14.06.2022, 20:53
https://github.com/z00m128/sjasmplus/releases/tag/v1.20.0

Lua: upgrade to 5.4, replacing tolua++ bindings with LuaBridge2.6 library, extending some bindings
Lua: bindings slightly modified (required by upgrade), refreshed docs, added test coverage
Lua: the 3rd party extensions (BTW not working for many years) are obsolete in 5.4 and removed
Lua: more accurate errors/warning location reported even in complex cases
warnings: added -Wall, --help=warnings shows on/off status, rdlow off by default
Added HIGH mode to relocation data generator (MSB-only relocation mode)
many open-file "fatal" errors become "non-fatal", assembling will continue
deprecated features removed: --syntax=m, label abs in expressions
--color=auto will stay no-color when env.var. NO_COLOR is defined
refactorings, improving some error messages and parsing, small fixes in parsing logic
fix listing of Lua's sj.parse_code (eol-comments), minor memory leaks fixed
fix relocation of temporary labels in expressions
invalid CLI options are reported as regular errors (also changing exit code)
errors are colored similarly to gcc (only keyword has color), console input name is <stdin>


Please be aware the upgrade of Lua may break some older scripts:
- the sjasmplus bindings had been restricted to only documented API, removing some of the secret optional arguments (hopefully not used by many people, in case you did use them, use instead the _pl/_pc function producing required asm line as string and letting sjasmplus to parse it as regular piece of code).
- Lua 5.4 has several incompatible syntax changes compared to 5.1, some stuff is quite subtle (for example _pc("ld a," .. 4/2) will produce string "ld a,2.0" which will cause "Unexpected: .0" error in parser)
- check the docs and tests to see how I adjusted old source to assemble again in similar cases

Sayman
17.06.2022, 09:25
вопрос: можно ли как то переназначать переменную компилятора __DATE__. её формат YYYY-MM-DD не удобен.

Ped7g
17.06.2022, 14:49
https://devrant.com/rants/1791863/a-perfect-date-for-a-programmer

I can't imagine which else format would you want, the YYYY-MM-DD is perfect.

If you need different format, there are no string operators in sjasmplus, so Lua for the rescue:


LUA ALLPASS
date = sj.get_define("__DATE__")
year = date:sub(2,5)
month = date:sub(7,8)
day = date:sub(10,11)
wrong_format = "\""..day.."."..month.."."..year.."\""
sj.insert_define("WRONG_FORMATTED_DATE", wrong_format)
ENDLUA

DISPLAY WRONG_FORMATTED_DATE


but that's just wrong.

Sayman
17.06.2022, 15:53
Ped7g, вроде был простой вопрос и тут посыпались wrong, не wrong, для чего это навязывание своих стандартов? у вас дата с года рисуется, у нас день месяц год. куда лучше смотрелось бы переопределение формата. или ключём через аргументы или в листинге кода. Lua тут костыль (хоть и рабочий).

transman
17.06.2022, 17:40
Ped7g, Нет. Скомпилировать SJASM+ я не могу.
128+2 байт хватает, когда DB используется для стандартных сценариев. Но не хватает, когда пишутся или адаптируются под sjasm+ игровые скрипты, особенно содержащие в себе много текста. Тогда приходится проделывать множество ручной работы, компилируя скрипты, выявляя строки, не укладывающиеся в ограничения по длине и в ручную ограничивая их длину.
Почему нельзя задать буфер под DB с некоторым запасом например 512+2 или 1024+2 ? Это снимет все вопросы к данной директиве раз и на всегда.
У современных конфигураций компьютеров память может исчисляться десятками гигабайт и лишняя пара килобайт ничего не значит.

0xDEAD
17.06.2022, 20:33
wrong, не wrong, для чего это навязывание своих стандартов?
Так делается для того (в том числе), что если у тебя есть куча файлов с названием в формате YYYY-MM-DD, и вывести их список, сортируя по имени, они выведутся, к тому же, в правильном хронологическом порядке. Если называть файлы в формате DD-MM-YYYY, то при выполении dir в директории с миллиардом файлов в подобном формате, получим (при сортировке по имени) чушь, в которой сложно ориентироваться.


Directory of D:\test

17.06.2022 20:37 <DIR> .
17.06.2022 20:37 <DIR> ..
17.06.2022 20:34 0 01-01-2020.txt
17.06.2022 20:34 0 01-01-2021.txt
17.06.2022 20:34 0 01-01-2022.txt
17.06.2022 20:34 0 02-01-2020.txt
17.06.2022 20:34 0 02-01-2021.txt
17.06.2022 20:34 0 02-01-2022.txt
17.06.2022 20:34 0 03-01-2020.txt
17.06.2022 20:34 0 03-01-2021.txt
17.06.2022 20:34 0 03-02-2022.txt

vs


17.06.2022 20:40 <DIR> .
17.06.2022 20:40 <DIR> ..
17.06.2022 20:38 0 2020-01-01.txt
17.06.2022 20:38 0 2020-01-02.txt
17.06.2022 20:38 0 2020-01-03.txt
17.06.2022 20:38 0 2021-01-01.txt
17.06.2022 20:38 0 2021-01-02.txt
17.06.2022 20:38 0 2021-01-03.txt
17.06.2022 20:38 0 2021-01-04.txt
17.06.2022 20:38 0 2022-01-01.txt
17.06.2022 20:38 0 2022-01-02.txt
17.06.2022 20:38 0 2022-01-03.txt
17.06.2022 20:38 0 2022-01-04.txt
17.06.2022 20:38 0 2022-01-05.txt

Лично я полностью согласен, что DD-MM-YYYY is wrong, хотя у нас так исторически почему-то сложилось. Но, если у тебя есть дата, ты можешь отформатировать её в любом формате, что и показал Peg7g LUA-скриптом.

Sayman
18.06.2022, 05:44
0xDEAD, во1х, причём тут имена файлов, атрибут времени и ассемблер?
во2х, ты спутал разные понятия - атрибут времени и имя файла. твоя проблема решается сортировкой.
в3х, я говорил про ассемблер, компилятор. то. что оно wrong, оно только в разных странах по разному. у нас оно принято DD.MM.YYYY. и чтобы записать внутри собранного файла дату и вывести её на экран, мне нужен такой порядок. а ты полез в какие то дебри. мало ли для каких целей это нужно.
LUA скрипт не удобен. нет желания прибегать к нему.

0xDEAD
18.06.2022, 08:35
1. Ассемблер тут притом, что он применяет формат даты, который уже устоялся. По многим причинам.
2. А у меня проблем нет. А твоя проблема решается переформатированием даты, хотя бы, с помощью скрипта. Но он для тебя неудобен.
3. И я о том же говорил. Про ассемблер, компилятор. Да - в разных странах оно по-разному, у нас получилось DD-MM-YYYY, и по-моему мнению (и по мнению 3/4 планеты), это wrong. А для тебя YYYY-MM-DD wrong. И, в связи с этим, как раз не у меня проблемы возникли.

Dexus
18.06.2022, 09:13
Истины ради, не 3/4, а сильно меньше. Есть довольно распространённый MM-DD-YYYY, который ещё более нелогичный чем DD-MM-YYYY. А единственный рациональный и дружественный логике и соответственно компутерам YYYY-MM-DD (который используется повсеместно в IT) не особо «традиционен».
Вообще несмотря на нечастость надобности странных форматов даты было бы неплохо встроить функцию с human-readable строкой. Есть же стандартная функция форматирования. Просто её подцепить, с дюжиной пресетов. Скрипт - хорошо что есть и работает (отчасти), но это все-таки костыль.
(Лично мне для спектрума и YYYY-MM-DD ни разу не пригождался. Я вообще считаю что у сабжа достаточно куда более существенных недоработок и помимо «формата даты»)

Sayman
18.06.2022, 09:14
0xDEAD,
1. Ассемблер, точнее компилятор данного языка - это, инструмент, в первую очередь. применять он может разные форматы, данные и прочее. для этого есть его директивы и аргументы ком.строки.
1.1. где там что устоялось? https://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D0%BB%D0%B5%D0%BD%D0%B4%D0%B0%D1%80%D 0%BD%D0%B0%D1%8F_%D0%B4%D0%B0%D1%82%D0%B0#:~:text= %D0%9D%D0%B0%D0%B8%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5%2 0%D1%80%D0%B0%D1%81%D0%BF%D1%80%D0%BE%D1%81%D1%82% D1%80%D0%B0%D0%BD%D1%91%D0%BD%D0%BD%D1%8B%D0%B5%20 %D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D1%8B,-%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D1%82&text=%D0%B4%20%E2%80%94%20%D0%B4%D0%B5%D0%BD%D1%8C %2C%20%D0%9C%20%E2%80%94%20%D0%BC%D0%B5%D1%81%D1%8 F%D1%86,%D1%86%D0%B8%D1%84%D1%80%D1%8B%20%D0%B8%D0 %B7%20%D0%BF%D0%BE%D1%80%D1%8F%D0%B4%D0%BA%D0%BE%D 0%B2%D0%BE%D0%B3%D0%BE%20%D0%BD%D0%BE%D0%BC%D0%B5% D1%80%D0%B0%20%D0%B3%D0%BE%D0%B4%D0%B0.
ознакомься с устоями даты.
2. у меня тоже проблем нет. ни с сортировкой файлов ни тут с датой. я могу тупо build.exe использовать. но это внешний инструмент, так же как и LUA. sjasm+ единственный компилятор, который применяет данный костыль. использование данного костыля усложняет переносимость исходных текстов. это же очевидно, что тут не понятного может быть?
3. у нас принят формат даты как DD.MM.YYYY, через точку, если быть точнее. но это уже детали. с точки зрения хранения данных на компе, дата занимает 4 байта (в BIN формате). не имеет значения в каком формате она хранится.
тебе поспорить хочется или как? добавить в исходнике компилятора переопределение переменной невозможная задача? "не смешите мои тапочки" (с).

когда дело доходит до реализации какой то мелкой бредни, которой пользуются полтора человека на всей планете - автор тут как тут. как реализовать адекватный функционал - начинаются песни и танцы. я прекрасно помню отмазки вокруг формата REL и подобных... так и щас.

0xDEAD
18.06.2022, 09:19
Дело хозяйское. Проблем нет, но проблема есть.

Sayman
18.06.2022, 09:23
для тех у кого с восприятием проблемы, я ещё раз повторяю:
1. дату в программах выводят в удобном для местного населения формате. у нас в РФ принят формат даты, который по мнению 0xDEAD и Ped7g является wrong.
2. есть понятие - переносимость кода/исходников. LUA сильно сокращает эту самую переносимость.
3. автор компилятора жив, на связи, с исходниками на руках. в чём проблема добавить возможность переопределять?
вроде очевидные вещи пишу, нет, надо зайти и срач на пустом месте поднять.

Dexus
18.06.2022, 09:27
Sayman, тебе хотя бы костыль предложили и он работает. А в моем случае (выгрузка меток и метаинформации по типам данных) даже и костыльного варианта СОВСЕМ нет.

Sayman
18.06.2022, 09:38
Dexus, так выгрузка меток вроде была, через какой то экспорт?! или это другое? в evo sdk такое применяли.

- - - Добавлено - - -

ещё про дату. чтобы вопросов про формат не возникало, достаточно ввести переменные, вроде: __DATE__DAY__, __DATE__MONTH__, __DATE__YEAR__ и вопросы у всех исчезнут. каждый сможет реализовать дату в том формате, в котором ему лично хочется. а так, придётся залезать в исходник компилятора...

Dexus
18.06.2022, 10:42
Sayman, речь про xmap для xpeccy. Там нужно чтобы сохранялись типы db/dw и всякое такое. Свой компилятор из-за этого не очень хочется делать. Issue в трекере с прошлого года висит.

Ped7g
19.06.2022, 23:39
If you are experienced programmer, you know the YYYY-MM-DD is the only correct format. Czech and Slovak national formats are also wrong and confusing, just like Russian form. They are all wrong, and I'm right. It's so simple. People being wrong and me being right - story of my life. :)

About other changes to sjasmplus ... :v2_confu:

I do what I need for my own projects, or what I find enough fun or critical.

I really don't see any issue with 128 limit for DB, I don't understand how you can have problem with it. For specific text entering system supporting also non-programmers you can produce your own solution, there was somebody writing lot of dialogs for game, and we devised some lua script helping with that: https://github.com/z00m128/sjasmplus/blob/master/tests/lua_examples/lua_inctext.asm https://github.com/z00m128/sjasmplus/blob/master/tests/lua_examples/lua_inctext.lua

In similar way you can devise your own custom solution, without adjusting sjasmplus. Or just `sed` one-liner splitting long lines into multiple DB statements.

Dexus has issue which seems difficult to implement, haven't got simple idea how to do it, and doesn't seem very important to me.

Why can't you develop your own changes - I don't know, I did need changes, I did changes. Also I have seen bugs, so I fixed bugs. Now you can profit from my fixed version of sjasmplus, as I'm sharing it with everyone. Of course my usual way of developing things and my needs may not cater 100% for your ways and needs, but well, that's not my problem. My problem is, that I spent about 2 years of life fixing Z80 assembler, and now I need to fix my life... :)

Sayman
20.06.2022, 08:40
If you are experienced programmer, you know the YYYY-MM-DD is the only correct format. Czech and Slovak national formats are also wrong and confusing, just like Russian form. They are all wrong, and I'm right. It's so simple. People being wrong and me being right - story of my life.
ты не понимаешь, что тебе говорят? я разве говорил о том, что нужно файлы какие то хранить в формате даты (чтобы потом с сортировкой не парится) или что? я говорю про отображение даты текстом. вроде того, что при запуске идёт вывод в консоль приветствия от автора и версия программы. и вот тут отображается дата. и вот она как раз отображается в том формате, в котором привычно видеть глазу в той или иной стране. у себя вы там можете выводить в каком угодно формате. это ваше право. наше право выводить в нашем формате. машине (виндовс, компилятору и другим программам) всё ровно в каком виде хранится дата. это просто набор байт и бит для неё.
при этом ты предлагаешь использовать LUA, которого нет в других компиляторах. т.е. переносимость кода между разными машинами и компиляторами просто не возможна. например, без использования LUA я спокойно могу перенести исходник с sjasm+ под спринтер, на его компилятор orgasm. и всё хорошо компилируется. но стоит только заюзать lua и всё, досвидос остальные компиляторы.
если не хочешь делать. так и скажи - "идите нафиг со своими хотелками", все вопросы отпадут...

Bedazzle
20.06.2022, 09:18
Почему нельзя задать буфер под DB с некоторым запасом например 512+2 или 1024+2 ? Это снимет все вопросы к данной директиве раз и на всегда.

Уже проходили. 640кб хватит всем. :)


У современных конфигураций компьютеров память может исчисляться десятками гигабайт и лишняя пара килобайт ничего не значит.

Это если алгоритм не завязан на структуру. К примеру, в байт больше 256 значений не засунешь. :)

P.S.
Я просто поболтать, исходники ассемблера не смотрел.

- - - Добавлено - - -


Лично я полностью согласен, что DD-MM-YYYY is wrong

Хуже этого только месяц-день-год и АМ/РМ время.

Sayman
20.06.2022, 09:33
Microsoft Windows [Version 10.0.19042.1288]
(c) Корпорация Майкрософт (Microsoft Corporation). Все права защищены.

C:\WINDOWS\system32>date /T
20.06.2022


мне больше нечего тут добавить.

Ped7g
20.06.2022, 12:08
build.bat


date /T > bdate.txt
sjasmplus source.asm


source.asm:


...
build_date_txt:
INCBIN "bdate.txt"
; maybe extra DB 0
...


BTW, orgasm does have `__DATE__`?

BTW2: you don't understand. You should even display YYYY-MM-DD to users, to educate them about the best date format. :)

LW
20.06.2022, 12:15
You should even display YYYY-MM-DD to users
Why else should I display the date like this?

For example: FAR displays date in the format dd-mm-yy; Total commander displays dd-mm-yyyy.
This is understandable and familiar.

Ped7g
20.06.2022, 12:21
yes, there's ton of SW which does it wrong. Even GCC `__DATE__` is like "Feb 12 2022".

As I wrote, it's quite common that many people are wrong and I am right, I'm used to it. :)

Reobne
20.06.2022, 12:32
Ped7g, И как ты получишь следующий день, за данным? Сначала прибавишь единицу к дню, то есть начнёшь с конца.
Почему-же в Z80 "LD (8000),HL" запишет (8000):=L; (8001):=H ? Потому что начинать арифметические операции естественнее с младших байтов.
Да, операции сравнения, больше-меньше, часто быстрее выполнять со старших байтов. Но это не делает запись от старшего к младшему единственно верной записью.

LW
20.06.2022, 13:06
Do not implement your standards where they are not needed.

- - - Добавлено - - -


И как ты получишь следующий день, за данным? Сначала прибавишь единицу к дню, то есть начнёшь с конца.
Что-то вас не туда понесло. Эта переменная банальная строка формата 'YYYY-MM-DD".
Задается такой строчкой.


SPRINTF3(dateBuffer, 30, "\"%04d-%02d-%02d\"", now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday);

Самый простой вариант, если лень реализовывать задаваемый пользователем формат даты, банально завести еще одну переменную с другим форматом. (но это так моё имхо, сильно в исходники не углублялся).

А для расчета следующего дня (а нафик это надо в компиляторе?) к значению времени банально прибавляется 86400 секунд и всё.

Sayman
20.06.2022, 13:48
build.bat
это запись как string, в данном случае мне нужно как EQU. при этом если мне потребуется записать как стринг, я всегда смогу взять значение в кавычки. в общем build.bat не тот вариант.

You should even display YYYY-MM-DD to users, to educate them about the best date format.
я живу в России, у нас принят другой формат даты. Любой Русский пользователь будет матом крыть автора программы, который показывает дату в иностранном формате, чуждый Русскому человеку.

Ped7g
20.06.2022, 15:40
А для расчета следующего дня (а нафик это надо в компиляторе?) к значению времени банально прибавляется 86400 секунд и всё.

Oh no, not this, that's not how it works. One day is not 86400 seconds. Are you trying to annoy me by describing all the usual bugs and mistakes people do when dealing with time in programming? :v2_dizzy_facepalm:

Bedazzle
20.06.2022, 17:44
Потому что начинать арифметические операции естественнее с младших байтов.

И тут оказывается, что с порядком байтов в мире тоже есть путаница.

Dexus
21.06.2022, 08:37
я живу в России, у нас принят другой формат даты. Любой Русский пользователь будет матом крыть автора программы, который показывает дату в иностранном формате, чуждый Русскому человеку.
Ой зря в политоту, да еще и с такой агрессией полез. Никто тебе ничего не обязан. Делай свой форк, и правь как тебе надо. До этих пор эти даты вообще никого не волновали.

Ровно эта же текстовая форма (yyyy-mm-dd) во всех основных СУБД используется по-дефолту. Это международный ANSI стандарт.

Sayman
21.06.2022, 10:55
Dexus, это он полез, а не я. он начал "вы все должны за нами повторять".
про ANSI - я уже написал для чего это нужно. причём тут субд, причём тут файлы и команда dir, блин...

SuperMax
21.06.2022, 12:21
Dexus, это он полез, а не я. он начал "вы все должны за нами повторять".
про ANSI - я уже написал для чего это нужно. причём тут субд, причём тут файлы и команда dir, блин...

я вижу

я живу в России, у нас принят другой формат даты. Любой Русский пользователь будет матом крыть автора программы, который показывает дату в иностранном формате, чуждый Русскому человеку.
явная провокация политического срача (про последствия подобного надеюсь объяснять не надо?)
причем абсолютно на ровном месте!

ответ уже дан

If you are experienced programmer, you know the YYYY-MM-DD is the only correct format

Shadow Maker
21.06.2022, 12:46
Заканчивайте уже про дату. Автор не хочет вносить данные изменения и смотреть откуда вы там - с Китая или с России, и я его вполне понимаю. Сконвертить дату из YYYY-MM-DD сложностей не представляет вообще никаких, в линухе прям в командной строке можно через sed.

Sayman
21.06.2022, 17:44
я вижу
плохо видите:

BTW2: you don't understand. You should even display YYYY-MM-DD to users, to educate them about the best date format.
https://zx-pk.ru/threads/30314-sjasmplus-ot-z00m.html?p=1156351&viewfull=1#post1156351



явная провокация политического срача
не моё.



ответ уже дан
и ещё раз. ответ дан на что? на формат "ANSI"?
ещё раз, вот текст:
77486
так понятнее будет? я не в Швеции и не в Польше живу. мне не нужен такой формат даты.
мне не интересны СУБД на асме писать, всё смешалось - люди, кони.

с другой стороны, скачал исходник, сам воткну что надо. без форков...

Ped7g
21.06.2022, 19:55
It's really irrelevant what are the national customs. The YYYY-MM-DD is technically superior to any other format, and I'm on my quest to change the world.

Also usually it may help to remember that I may be trolling a bit and exaggerating... Usually when I sound serious I'm making a joke, and when it looks like I'm joking, I'm dead serious. Usually.

With regard to sjasmplus, it really is part of the package, that it should be easy to compile yourself, and patch some simple things yourself, that's one of the major points of FOSS license. You are assembler programmers, a bit of C/C++/Lua/... can't stop you. :)

And I really need to wind down time spent on sjasmplus, I think it's now very stable and quite "mature" tool. I don't have any big plans for v1.x and I don't see myself committing to work on "v2.x" any time soon. I'm still interested to improve sjasmplus over time, but the general issues affecting many users have higher priority than single-project customisation.

Also if you have particular Z80 asm project which is open source and has some issues with sjasmplus, send me git/svn/... url and I may try to help to patch the asm to work well with sjasmplus.

LW
21.06.2022, 20:04
It's really irrelevant what are the national customs. The YYYY-MM-DD is technically superior to any other format, and I'm on my quest to change the world.
This is just your opinion


And I really need to wind down time spent on sjasmplus, I think it's now very stable and quite "mature" tool. I don't have any big plans for v1.x and I don't see myself committing to work on "v2.x" any time soon.
And this is your right

Ped7g
29.07.2022, 18:14
https://github.com/z00m128/sjasmplus/releases/tag/v1.20.1

new directives: SAVEAMSDOS, DEFDEVICE
added "smart" SMC offset syntax: `value_addr+*: ld a,123`
parse+ignore decimal numeric constants (for easier migration to Lua5.4)

Ped7g
17.02.2023, 00:53
https://github.com/z00m128/sjasmplus/releases/tag/v1.20.2

added optional second argument for DUP to have index variable
option --exp will create file even when no EXPORT is used
fixing variable name-clash when compiling against musl-clib
LuaBridge updated, CMake and Makefile updated a bit
minor bugfixes/improvements in parser in specific edge cases

Bedazzle
18.02.2023, 09:54
added optional second argument for DUP to have index variable

Thanks specially for this one!

0xDEAD
19.02.2023, 19:01
Так и не понял, что это за index variable, и зачем она нужна.

Ped7g
19.02.2023, 21:46
Так и не понял, что это за index variable, и зачем она нужна.



DUP 128, some_index
DB some_index
EDUP


will produce 128 bytes: 0,1,2,...,127
So you don't need to have own index=index+1 inside DUP to track counter.

Biland
01.05.2023, 21:12
struct MedikitVTab /*виртуальная таблица для класса TMedikit*/
Metod dw #abcd
Metod1 dw fPick
ends

struct TMedikit /*класс*/
dw MyMedikitVTab /инкапсуляция!!!/
Coord dw #1f00 ; X
dw #1f00 ; Y
Count dw 55 ; Здоровье
ends

ORG #9e00

MyMedikit TMedikit /*экземпляр класса TMedikit (объект MyMedikit) объект класса */
MyMedikitVTab MedikitVTab

StartProg
ld bc,MyMedikit.+Coord
nop
ret

fPick ret


Есть магия, как получить смещение адрес по метке в инкапсуляции MyMedikitVTab из объекта MyMedikit?:

ld bc,MyMedikit.+Metod1

Ped7g
01.05.2023, 23:19
you mean something like this?


struct MedikitVTab /*виртуальная таблица для класса TMedikit*/
Metod dw #abcd
Metod1 dw fPick
ends

struct TMedikit /*класс*/
dw MyMedikitVTab /*инкапсуляция!!!*/
Coord dw #1f00 ; X
dw #1f00 ; Y
Count dw 55 ; Здоровье
ends

ORG #9e00

MyMedikit TMedikit /*экземпляр класса TMedikit (объект MyMedikit) объект класса */
MyMedikitVTab MedikitVTab

; DE = address of TMedikit instance
fPick:
ld hl,TMedikit.Count ; offset of Count in TMedikit struct
add hl,de ; HL = MyMedikit.Count #9e06
; ...
ret

; HL = object instance, BC = method offset in vtable
runVMetod:
ld de,(hl) ; DE = MyMedikitVTab #9e08 ; fake ld e,(hl) : inc hl : ld d,(hl) : dec hl
ex de,hl
add hl,bc ; HL = MyMedikitVTab.Metod1 #9e0a
ld a,(hl)
inc hl
ld h,(hl)
ld l,a ; HL = fPick #9e0c, DE = MyMedikit #9e00
jp (hl) ; jump to fPick

StartProg
ld hl,MyMedikit ; HL = MyMedikit instance address #9e00
ld bc,MedikitVTab.Metod1 ; offset of Metod1 in MedikitVTab struct #0002
call runVMetod ; `MyMedikit.Metod1();` alias `fPick(MyMedikit);`
jr $


also check listing with symbol table, or docs about structs, what values are available, you have all offsets, struct size and instance full addresses available at assembling time.
(sjasmplus --lst --lstlab=sort file.asm)

Ped7g
28.06.2023, 03:07
https://github.com/z00m128/sjasmplus/releases/tag/v1.20.3

added alias --define for -D
added string-literals suffixes Z and C to add zero or set high bit of last char
end of line backslash continues source line (limited support, not recommended)
Lua: minor version upgrade to 5.4.6 (from 5.4.4)
minor updates to Makefile

Deadly
08.09.2023, 12:29
https://youtu.be/Gerd209yR-M?si=pwIx2QP-Ae4N3QLs
мб кому пригодится VCode + sjasmplus

Dart Alver
21.01.2024, 17:42
v 1.20.3 Lua


[string] sj.get_define("name", "include_macro_args" = false)

Get define value, returns nil if define is not found. Can optionally search also macro arguments (with higher priority).

Я так понял появилась возможность забирать в lua-скрипт непосредственно значения макросов. Но без примеров нихрена непонятно как это работает.
Может кто разъяснить ?

- - - Добавлено - - -

До этого использовал v 1.19.0.
Там для прокидывания в Lua аргумент макроса делал как-то так :


MACRO LUT_ p00000000 ; проверочная макроса однако )))
DEFINE _p0000000 p00000000
LUA ALLPASS
local stra = sj.get_define("_p0000000")
sj.insert_define("_p0000000","'"..string.upper(stra).."'")
ENDLUA
DB _p0000000
UNDEFINE _p0000000
ENDM


Теперь вроде как можно делать напрямую sj.get_define("p0000000", "чето надо указать типа")
И вот второй параметр непонятен от слова совсем ))

Ped7g
22.01.2024, 01:40
Did you check the test accompanying the change?
One using the ", true" to enable macro argument search:
https://github.com/z00m128/sjasmplus/blob/master/tests/lua_examples/lua_macro_arg2.asm
https://github.com/z00m128/sjasmplus/blob/master/tests/lua_examples/lua_macro_arg.asm#L24

Let me know if this is not enough and what have you tried and does not work for you.
In your example I think this should work (but I didn't test it, just writing it here in forum live):


MACRO LUT_ p00000000 ; проверочная макроса однако )))
LUA ALLPASS
local stra = sj.get_define("p00000000", true)
_pc("DB '"..string.upper(stra).."'")
ENDLUA
ENDM

Let me know if this doesn't work for you, I will try harder. :)

Dart Alver
22.01.2024, 21:46
Let me know if this doesn't work for you, I will try harder.

Работает ! Похоже я что-то не так прописывал, видимо затупил. Спасибо. Теперь буду знать. :)

SAVC
07.04.2024, 11:48
Был бы очень благодарен авторам ассемблера, если бы они сделали схемы подсветки к двум моим любимым редакторам: NotePad ++ и EditPad Lite !

Black Cat / Era CG
07.04.2024, 14:09
Был бы очень благодарен авторам ассемблера, если бы они сделали схемы подсветки к двум моим любимым редакторамА причем здесь авторы? Я для NPP сам делал когда-то.

Ped7g
07.04.2024, 18:51
... NotePad ++ и EditPad Lite !

Hello, thanks for the feedback and idea. I'm personally not interested to work on the syntax highlight for these editors, as I prefer open source software, you can try Kate (it has also windows binary builds) - syntax highlight rules are directly in the sjasmplus git repository.

Or maybe somebody else will be interested in doing this, then I hope they will let me know about the result so I can mention it here or in the sjasmplus docs. Have a great time.

Xela
07.04.2024, 20:50
А причем здесь авторы?
Ну а что им, жалко что ли? Для любимого же редактора просят.

- - - Добавлено - - -


Я для NPP сам делал когда-то.
И до сих пор же доступно (http://era-cg.su/?name=articles&id=1), что примечательно)

SAVC
08.04.2024, 00:26
Ну а что им, жалко что ли? Для любимого же редактора просят.
Канеш!


И до сих пор же доступно (http://era-cg.su/?name=articles&id=1), что примечательно)
Там только для светлой темы :-) и для EditPad Lite нет.

- - - Добавлено - - -


Hello, thanks for the feedback and idea. I'm personally not interested to work on the syntax highlight for these editors, as I prefer open source software, you can try Kate (it has also windows binary builds) - syntax highlight rules are directly in the sjasmplus git repository.

Or maybe somebody else will be interested in doing this, then I hope they will let me know about the result so I can mention it here or in the sjasmplus docs. Have a great time.

Разобрался немного, как это делается в NotePad++, сделал пока подсветку комментариев, это сильно упростило жизнь!
Я всё-таки думаю, что авторам ассемблера сделать подсветку синтаксиса гораздо проще, чем мне, а чем больше редакторов поддерживаются - тем лучше!
Установил Kate под Windows 10 x64. К сожалению, убрать атрибут "только для чтения" с папки
C:\Program Files\WindowsApps\KDEe.V.Kate_24.201.6869.0_x64__7 vt06qxq7ptv8\bin\org\kde\syntaxhighlighting
не удаётся даже в Total Commander!
И сразу к этому, такой вопрос: если всё же удастся, нужно ли создавать в этой папке папку syntax ? или записывать файл, как есть?

- - - Добавлено - - -

Notepad++ is Free Software. This means that not only is it an open-source project, but you also have the right and the freedom to access the source code, modify it, and distribute the compiled binary along with the modified source code. These rights (the freedom) are protected by the GNU General Public License.

Notepad++ source code can be access via its repository on GitHub: https://github.com/notepad-plus-plus/notepad-plus-plus

https://notepad-plus-plus.org/resources/

Black Cat / Era CG
08.04.2024, 05:10
Там только для светлой темы :-)Ну можно под темную переделать же. Просто я щас пользуюсь связкой под VSCode. Там все помощнее получается.

не удаётся даже в Total Commander!А если запустить ТС от имени администратора?

SAVC
08.04.2024, 08:40
А если запустить ТС от имени администратора?
Не, не помогает! пробовал...


Ну можно под темную переделать же. Просто я щас пользуюсь связкой под VSCode. Там все помощнее получается.
А вот с этого места поподробнее... VS Code конечно тоже установлен в системе...

Black Cat / Era CG
08.04.2024, 12:11
А вот с этого места поподробнее...Подробнее тут и в комментариях ниже: https://hype.retroscene.org/blog/dev/946.html

0xDEAD
08.04.2024, 13:58
Не надо там ничего читать. Информация по ссылке давно устарела, описываемых плагинов доброй половины уже больше нет на VSCode marketplace, вместо них появились другие.
Для VSCode модно сейчас использовать DeZog. Этого вполне достаточно. Для удобства можно добавить ASM CodeLens, Hex Cover Converter, Z80 Assembly Meter, Z80 Instruction Set.

Ped7g
08.04.2024, 20:57
I either didn't know or forgot notepad++ is open source. Nice. I'm still not interested to work on syntax highlight for it now, but maybe in some distant future, now it makes more sense (although there's no linux binary, so I would have to run it with wine).

Kate: I'm not sure about windows, but in linux you put your customization files like syntax highlight or color schemes to folder local to the user, I have it in the comments of the file itself, as it's a bit hidden. I would expect the windows versions of KDE apps to have also configuration stored in some user directory, try to change few options and store the new config, it must be written somewhere. If you will find it, and compare the folder tree against what is used on linux, you will probably find where to put syntax highlight rules too. Or maybe it's even in documentation?

SAVC
08.04.2024, 23:53
Не надо там ничего читать. Информация по ссылке давно устарела, описываемых плагинов доброй половины уже больше нет на VSCode marketplace, вместо них появились другие.
Для VSCode модно сейчас использовать DeZog. Этого вполне достаточно. Для удобства можно добавить ASM CodeLens, Hex Cover Converter, Z80 Assembly Meter, Z80 Instruction Set.

Расскажите подробнее о программировании для Спектрума под VS Code, пожалуйста.

Deadly
09.04.2024, 00:08
https://youtu.be/Gerd209yR-M

0xDEAD
09.04.2024, 00:23
Расскажите подробнее о программировании для Спектрума под VS Code, пожалуйста.
Ничем не отличается от программирования в любом другом редакторе. Жмешь кнопки - пишется код.
Другое дело - компиляция и отладка. У DeZog есть огромная инструкция (https://github.com/maziac/DeZog/blob/main/documentation/Usage.md), как его настроить и использовать.

SAVC
09.04.2024, 00:43
Ничем не отличается от программирования в любом другом редакторе. Жмешь кнопки - пишется код.
Да, спасибо. Можно было просто послать на х.й

- - - Добавлено - - -

Deadly, спасибо! Больше видосов, полезных и разных!

Reobne
10.05.2024, 20:01
Попробовал VSCode, и есть вопросик.
1. Установил VSCode.
2. Поставил внутри VSCode все плагины, что и у тебя в видосике.
3. Закачал твой пример. Распаковал. В VSCode "выбрал папку".
4. Отредактировал пути к Unreal-у.
5. Раскомментировал запуск в анриле, и запустил (Ctr+Shift+B). Ура работает! Кружочек нарисовался!
6. Скопировал шаблон в новый тестовый проект, и начал его немного править.
И вот тут-то и небольшая запарка:

Редактирую я строчку. Сохраняю, запускаю -> в этой строчке ошибка. Исправляю, сохраняю, запускаю -> в этой строчке другая ошибка. НО и первая ошибка остаётся.
Наконец я окончательно исправляю строчку, сохраняю, запускаю, всё работает, ноль ошибок... Но всё равно те две ошибки, они есть, в списке проблем (который видно по Ctr+Shift+M).

Я что-то не так сделал? Или, надо просто это терпеть?

0xDEAD
10.05.2024, 22:48
Нет, это не надо терпеть. Уже не припомню точно, что именно - но что-то не так настроено либо в launch.json, либо в tasks.json. Вроде где-то здесь - ""problemMatcher": "$problem-matcher-sjasmplus"", но могу ошибаться. Было у меня такое, но давным-давно настроил, и теперь просто тягаю папку .vscode из проекта в проект, минимально редактируя файлы внутри.



{
"version": "0.2.0",
"configurations": [
{
"type": "dezog",
"request": "launch",
"name": "Internal Simulator",
"remoteType": "zsim",
"zsim": {
"visualMemory": true,
"memoryModel": "ZX48K",
"ulaScreen": true,
"zxBorderWidth": 20,
"vsyncInterrupt": true,
"zxKeyboard": true,
"zxBeeper": true
},
"sjasmplus": [
{
"path": "main.sld"
}
],
"history": {
"reverseDebugInstructionCount": 1000000,
"spotCount": 10,
"codeCoverageEnabled": true
},
"startAutomatically": false,
"disassemblerArgs": {
"esxdosRst": true
},
"rootFolder": "${workspaceFolder}",
"topOfStack": "stack_top",
"mainFile": "main.asm",
"load": "main.sna",
"smallValuesMaximum": 513,
"tmpDir": ".tmp"
},
]
}



{
"version": "2.0.0",
"tasks": [
{
"label": "Build project",
"type": "shell",
"command": "sjasmplus.exe",
"args": [
"--sld=main.sld",
"--color=on",
"--fullpath",
"main.asm"
],


"problemMatcher": "$problem-matcher-sjasmplus",



"group": {
"kind": "build",
"isDefault": true
},
"isBackground": false,
"presentation": {
"echo": false,
"reveal": "always",
"clear": true,
"focus": false,
"panel": "shared",
"showReuseMessage": true
},

},


]
}

Как-то так у меня.

Но подозреваю, что вопрос более подходящий скорее для этой темы: https://zx-pk.ru/threads/33549-programmirovanie-i-otladka-v-visualstudio-code.html

Здесь (https://1drv.ms/u/s!AhG34EgQoEqTg_Bmj9thPNOVN2uuUQ?e=1J2wOc) можно взять пример рабочего каталога с примером. Скорее всего, в конфигурационных файлах придется кое-что подредактировать (адрес, где лежит sjasmplus.exe, например, и т.п.).

himik
02.09.2024, 08:15
Собстна, как посчитать длину в секторах? Каким образом можно произвести деление с округлением до целого числа?

Shiny
02.09.2024, 08:31
Собстна, как посчитать длину в секторах? Каким образом можно произвести деление с округлением до целого числа?

(filelen+255)/256

Кстати, я тут слышал несколько жалоб - лень писать device zxspectrum48. А можно ли исключить эту строку, пусть будет 48й по умолчанию?

himik
02.09.2024, 08:49
Капец, а что так просто-то всё. Видать, я все же тупой дядя. :v2_dizzy_punk:

Shiny
02.09.2024, 09:22
Капец, а что так просто-то всё. Видать, я все же тупой дядя. :v2_dizzy_punk:

мы все такими были(:

Ped7g
02.09.2024, 22:27
лень писать device zxspectrum48. А можно ли исключить эту строку, пусть будет 48й по умолчанию?

without `DEVICE` you will be in "none" device mode. You can produce raw machine code and store the output with `OUTPUT` directive or `--raw` option on command line, but you can NOT do `SAVEBIN/SAVESNA/SAVEDEV/SAVETAP/SAVETRD/...` and similar, which save memory content after it is ready, as there is no memory in "none" device, machine code is emitted and gone.

Some people work with this mode on rather large projects (super mario bros for MSX producing 2MiB cartridge ROM file), but for ZX it's more common to use the virtual device and all the extra directives capable to work with the virtual memory.

Shiny
03.09.2024, 07:57
лол, те, кто жаловались, ниасилили почитать руководство. И я тоже xD

ZXMAK
02.12.2024, 18:03
интересует такой вопрос - каковы ортодоксальные правила z80 ассемблера для меток? :)

А именно:
- можно ли добавлять пробелы перед меткой (в обоих случаях - когда метка завершается : и без)?
- можно ли использовать метку без : и без инструкции в той-же строке?
- можно ли использовать метку с : и с инструкцией в той-же строке?
- можно ли использовать метку с : или без, в строке с безметочной директивой (например ORG)?

В си пробелы перед меткой допускаются, но в ассемблерах z80 я вижу это не везде допустимо.

Особенно интересен случай с разделителем инструкций :, т.к. ассемблер поддерживающий такой разделитель по идее должен иметь более строгие правила к меткам, т.к. иначе может ошибочно воспринимать макросы как метки и тихо игнорировать ошибки

LW
02.12.2024, 19:20
- можно ли добавлять пробелы перед меткой (в обоих случаях - когда метка завершается : и без)?
нет

- можно ли использовать метку без : и без инструкции в той-же строке?
можно

- можно ли использовать метку с : и с инструкцией в той-же строке?
можно

- можно ли использовать метку с : или без, в строке с безметочной директивой (например ORG)?
с оргом не пробовал, с ifdef/ifused иногда возникают баги, иногда работает нормально. хрен знает с чем связано

Dart Alver
02.12.2024, 23:11
- можно ли использовать метку с : или без, в строке с безметочной директивой (например ORG)?
Можно, но адрес метки будет последним адресом перед исполнением директивы ORG, так как она начинает работу после своего обьявления. Поймал такой ляп как-то ))

- - - Добавлено - - -


Особенно интересен случай с разделителем инструкций :, т.к. ассемблер поддерживающий такой разделитель по идее должен иметь более строгие правила к меткам, т.к. иначе может ошибочно воспринимать макросы как метки и тихо игнорировать ошибки
Не а. Метки начинаются исключительно с начала строки, после разделения ':' метку поставить нельзя.

ZXMAK
14.01.2025, 17:24
какие операторы в выражениях поддерживает SjASMPlus?

Также вопрос - есть ли ассемблеры z80, которые умеют ассемблировать код вроде такого:


leng1 equ 10
leng2 equ label2-label1

rept leng2*2
jr $+2 ; 12T
endm

label1:
rept leng1*2
jr $+2 ; 12T
endm
label2:

Dart Alver
14.01.2025, 21:36
какие операторы в выражениях поддерживает SjASMPlus?

Документация вам в помощь: http://z00m128.github.io/sjasmplus/documentation.html
Конкретнее : http://z00m128.github.io/sjasmplus/documentation.html#s_expressions


Также вопрос - есть ли ассемблеры z80, которые умеют ассемблировать код вроде такого:

Ну тот же SjASMplus вполне ассемблирует если правильно операторы писать, а не endm к rept прикручивать. ;)

Chwe
14.01.2025, 22:36
Ну тот же SjASMplus вполне ассемблирует если правильно операторы писать, а не endm к rept прикручивать. ;)

Внезапно, это нормальный синтаксис для чего-то почтенно архаичного, не помню уже, чего конкретно (pasmo?). Но, да, соглашусь, синтаксис странный, кто и зачем такое придумал...

Dart Alver
15.01.2025, 01:35
Внезапно, это нормальный синтаксис для чего-то почтенно архаичного, не помню уже, чего конкретно (pasmo?). Но, да, соглашусь, синтаксис странный, кто и зачем такое придумал...
Незнаю на счёт pasmo, а в ужасме используется rept ... endr (аналог также dup ... edup ), а endm это для макросов: macro ... endm

M80
15.01.2025, 11:18
Также вопрос - есть ли ассемблеры z80, которые умеют ассемблировать код вроде такого:


leng1 equ 10
leng2 equ label2-label1

rept leng2*2
jr $+2 ; 12T
endm

label1:
rept leng1*2
jr $+2 ; 12T
endm
label2:

Это М80 (MACRO-80) - классика. Только он под CP/M. Многие современные не могут похвастаться таким как REPT/IRP/IRPC и пр.

Chwe
15.01.2025, 19:42
Кстати, я тут проверил от нечего делать. sjasm-то этот синтаксис всё ещё понимает. Ругается, но понимает.

Dart Alver
15.01.2025, 21:26
Кстати, я тут проверил от нечего делать. sjasm-то этот синтаксис всё ещё понимает. Ругается, но понимает.
В смысле, что значит всё ещё ? И почему это он не должен ругаться если ктото не читает инструкцию и использует команды языка вопреки его правилам и грамматики ? На такое вообще любой компилятор ругаться будет.
Какие в этом претензии к SjASMplus ?

Замени endm на endr , как положено в правилах, и не будет никакой ругни, всё замечательно компилируется.

M80
16.01.2025, 09:07
Ну, а IRPC сделает?


BXlt equ 0a5h

DBS. MACRO str,stre
IRPC x,<str>
db '&x&' xor BXlt
ENDM
db '&stre&' or 128 xor BXlt
ENDM

5D33 OpNum: DspStr
5D33 DF + rst 18h
dbs. <operator:>,< >
5D34 CA + db 'o' xor BXlt
5D35 D5 + db 'p' xor BXlt
5D36 C0 + db 'e' xor BXlt
5D37 D7 + db 'r' xor BXlt
5D38 C4 + db 'a' xor BXlt
5D39 D1 + db 't' xor BXlt
5D3A CA + db 'o' xor BXlt
5D3B D7 + db 'r' xor BXlt
5D3C 9F + db ':' xor BXlt
5D3D 05 + db ' ' or 128 xor BXlt

Dart Alver
16.01.2025, 22:06
Ну, а IRPC сделает?

Насколько знаю IRP и IRPC готовых аналогов в SjASMplus нет, while есть, а этих не видел.

Если очень нужно чтото подобное, то можно как-то выкрутиться используя lua-скрипты, и даже более хитрую обработку строки провернуть, но это будет посложнее конечно, хотя и более универсально.
Но если честно я особо не припоминаю подобных функций и в других популярных у нас спектрумовских ассемблерах. И на практике даже и не знал что чтото такое зачемто нужно ))

Вообще в теме время от времени присутствует разработчик Ped7g, может быть если удастся обосновать необходимость данных фичь, то сможете уговорить их реализовать ))


Мне, если честно, более интересно было бы появление в SjASMplus возможности создания макросов с неопределённым количеством параметров, чтобы такой макрос можно было бы вызвать как вообще без параметра, так и с любым количеством.

Пусть это будет не macro , а например macro@ или macro$ или как-то по другому, параметры чтоб имели какое-то фиксированное название с порядковым номером, один со специальным именем (или нулевым номером) указывал номер последнего переданного, и их также можно было бы в lua перенаправить.

Вот тут можно было-бы неплохо развернуться. И тот же IRP например реализовать внешней библиотекой через lua, и много другого ))

Ped7g
17.01.2025, 01:43
sjasmplus doesn't have IRPC, you can get same machine code in some different way.

One of the options is to use virtual memory of DEVICE to post-process the string with xor like this:


BXlt equ 0a5h
DEVICE ZXSPECTRUM48 ; switch virtual device memory mode on
ORG $5D33 ; first do regular ASCII string
OpNum: rst $18 ; the "C literal suffix means
.str: DB "operator: "C ; to tag last byte with "or 128"
; now go over the ASCII string again and xor each byte:
.length equ $ - .str ; length for dot-repeater
ORG .str ; go back in virtual memory to start of str
.(.length) DB {b $} ^ BXlt ; .length-many-times xor content of virtual memory
SAVEBIN "temp.bin", OpNum, $-OpNum ; save resulting machine code


which assembles as this listing shows (notice the memory at 5D34 written twice, first getting regular ASCII chars, second time being xor-ed):



1 0000 BXlt equ 0a5h
2 0000 DEVICE ZXSPECTRUM48 ; switch virtual device memory mode on
3 0000 ORG $5D33 ; first do regular ASCII string
4 5D33 DF OpNum: rst $18 ; the "C literal suffix means
5 5D34 6F 70 65 72 .str: DB "operator: "C ; to tag last byte with "or 128"
5 5D38 61 74 6F 72
5 5D3C 3A A0
6 5D3E ; now go over the ASCII string again and xor each byte:
7 5D3E .length equ $ - .str ; length for dot-repeater
8 5D3E ORG .str ; go back in virtual memory to start of str
9 5D34 CA > DB {b $} ^ BXlt ; .length-many-times xor content of virtual memory
9 5D35 D5 > DB {b $} ^ BXlt
9 5D36 C0 > DB {b $} ^ BXlt
9 5D37 D7 > DB {b $} ^ BXlt
9 5D38 C4 > DB {b $} ^ BXlt
9 5D39 D1 > DB {b $} ^ BXlt
9 5D3A CA > DB {b $} ^ BXlt
9 5D3B D7 > DB {b $} ^ BXlt
9 5D3C 9F > DB {b $} ^ BXlt
9 5D3D 05 > DB {b $} ^ BXlt


and hexa dump of saved binary file:



$ hd ~/zx/ped/scratch/temp.bin
00000000 df ca d5 c0 d7 c4 d1 ca d7 9f 05 |...........|
0000000b


There are for sure more possible ways, but not a simple way to replicate the exact syntax of your example, you need to convert that source for sjasmplus, sorry.

M80
17.01.2025, 10:48
Спасибо Ped7g за ваше внимание.
Я начал работать с M80 с конца 80-х и тогда других вариантов не было. А уже ближе к 2000-м начал подумывать об использовании чего нибудь посовременнее. Но, тогда уже было много наработок на M80 с его IRP/IRPC, и требовалось много изменений. Тем более, что основная заповедь гласит: "работает, не трожь!" И даже сейчас, с вашим SjASMPlus, видно что это не просто.

Bedazzle
17.01.2025, 12:18
One of the options is to use virtual memory of DEVICE to post-process the string with xor like this:


Neat and cool! Good to know these tricks.

Chwe
18.01.2025, 14:45
Да, спасибо Ped7g.

P.S. как я понимаю, накрутить что-то подобное irp достаточно легко и с помощью DEFARRAY, там добавить локальные имена и всё, но можно и без этого. Синтаксис другой, менее удобный, но делать будет примерно то же самое, даже похожее макро можно набросать. А вот с irpc засада. Если я ничего не путаю, типа данных «массив байт» и, соответственно, выражения, имеющего такое значение нет.

- - - Добавлено - - -


Спасибо Ped7g за ваше внимание.
Я начал работать с M80 с конца 80-х и тогда других вариантов не было. А уже ближе к 2000-м начал подумывать об использовании чего нибудь посовременнее. Но, тогда уже было много наработок на M80 с его IRP/IRPC, и требовалось много изменений. Тем более, что основная заповедь гласит: "работает, не трожь!" И даже сейчас, с вашим SjASMPlus, видно что это не просто.

Я тут заинтересовался, откуда есть пошли IRP[C] и при чём там макросы. Конечно, не настоящее исследование но, вдруг кому интересно:

В общем, почитал документацию. В M80 всё оказалось логично, там REPT -- макро, поэтому оно ENDM и заканчивается. Сначала я подумал, что это у них там «как всегда», но потом что-то такое всплыло в памяти. Порылся в архиве и интернете (педивикия загажена сектой свидетелей святого x86, там ничего ценного не осталось, похоже). В общем, самое раннее, что я смог быстро найти -- 1975. Конечно, DEC. У них тоже IRP, IRPC и REPT, почему-то, макросами считаются. Для IRP? оно, наверное, некоторый смысл имеет. Но, для REPT оно не только меня смущало, но и авторов MACRO-11. Там для REPT есть ENDR, помимо допустимого ENDM.

Вот придумали это всё в DEC или ещё откуда скопировали, я сходу найти не смог. Наверное, скопировали, пара ENDR|ENDM для REPT намекает. В IBM'овском Autocoder'е эта штука, вроде, называлась CHAIN и была очень примитивной. Интересно, что там было для PDP-5 или 8...

Hunta
18.01.2025, 15:38
Вот придумали это всё в DEC или ещё откуда скопировали
Тоже не скажу.
Собственно, моё программирование для компов, а не для программируемых калькуляторов, началось именно с (аналога) PDP-11, там это было уже как данность.
Ну и всё это было настолько развито, что с использованием макросов, условной копиляции и блоков повторения позволило - первоначально разработчикам из DEC - создать набор структурных операторов-макросов (IF, DO, WHILE, REPEAT и так далее), а мне позже допилить. Основной плюс - стало меньше необходиомсти в метках и структура программы смотрится прозрачней. Плюс скорость написания повысилась примерно на порядок. Плата за удобства - копмилируется медленней.

Biland
16.03.2025, 13:59
MyMacros MyVar, MyStructure

;-------------------------------------------
MyMacros MACROS Name1, Name2

Name1_Addr EQU $
; its work (result: MyVar_Addr)

Name1.Addr EQU $
;not work (result: Name1.Addr)

Name1_Addr EQU Name2.SomeAddr
; not work (Name2.SomeLabels not replace Name2)
ENDM


С чем связано, что переменная макроса не преобразуется, если стоит точка после неё? Использование @ не помогает.

ZXMAK
17.03.2025, 11:27
точка недопустимый символ для имени, поэтому имя идет до точки, а дальше непонятный синтаксис

krt17
17.03.2025, 21:51
С чем связано, что переменная макроса не преобразуется, если стоит точка после неё? Использование @ не помогает.

Не только точка, тут парсер не делает макроподстановку, считается что ты просто написал Name2.SomeAddr


точка недопустимый символ для имени, поэтому имя идет до точки, а дальше непонятный синтаксис
очень даже допустимый, внутренние метки по факту просто <имя процедуры>.<внутренняя метка> их можно задать, при желании, снаружи процедуры

Ped7g
17.03.2025, 23:56
You are another person asking about this: https://github.com/z00m128/sjasmplus/issues/257

it's by design, macro arguments are similar to DEFINE, so they are substituted in raw text of line before parser starts parsing it as assembly, they are similar to C preprocessor stage. And the substitution is looking only for full name of macro argument/define, or for sub-word delimited by underscore `_`. Sub-words delimited by dot are not considered.

I'm considering to add substitution operator `_` to concatenate two sides during preprocessing step, so `Name2 _ .SomeAddr` would be then possible (at least one side of `_` would have to be actual define or macro argument name, otherwise the `_` would be considered regular char, so `ld hl,_` would still work as before, looking for symbol `_`. But I haven't even started with such enhancement.


Meanwhile there is new release, v1.21.0:
https://github.com/z00m128/sjasmplus/releases/tag/v1.21.0


- - - Updated - - -

Biland: but I'm a bit confused what do you need it for, I would expect such need to be rare and there is maybe some other way how to write your source to get desired result with reasonable simplicity, if you want to share bigger example of your problem and why you want macro like that, maybe I can propose some different way how to write the code with what sjasmplus offers (already now, without waiting for future enhancements).

Biland
18.03.2025, 01:25
В моём случае, я пытаюсь работать со структурами и макросами. Было бы удобнее использовать Object.X, Object.Y, Object.Size и так далее, чем Object_X, Object_Y, Object_Size. Но в моём случае, как я написал, я работаю со структурами и при присвоении [<label>] <struct_name> - я могу использовать смещения по имени структуры (<struct_name>.MyLabel). И хотел указать минимум для [<label>], например, Size, End, Start. Приходится делать после выполнения макроса [<label>].Size, [<label>].End, [<label>].Start. Хотя было бы удобнее в макросе.

При создании переменных было бы лучше через точку. Вариант, где было бы наглядней визуально, как в языках высокого уровня:

SETVAR MACRO NAME, NAMESIZE
NAME EQU INITVAR
IF NAMESIZE >= 0
NAME_Size EQU NAMESIZE
NAME_PEnd EQU INITVAR +NAMESIZE
INITVAR= INITVAR +NAMESIZE
ELSE
NAME_Size EQU 1
INITVAR= INITVAR +1
ENDIF
NAME_CurAdr EQU $
ENDM


Ещё, вопрос. Если я, например, вызову макрос с одной переменной SETVAR MyVar, то компилятор будет ругаться. Внутри макроса другие компиляторы позволяют проверять не переданные параметры, через IFNB и IFB. Это вызывает проблемы при адаптации исходников для sjasm.

Chwe
28.03.2025, 14:44
Вопрос, скорее, в качестве разминки для ума, так как я сам сходу могу придумать минимум два способа решения (lua и «чистый asm», навеянный дискуссией о IRPC). Но, интересно будет узнать другие решения, если они есть.

Итак, задача – самостоятельно генерировать PLUS3DOS заголовок, ну, который 128 байт в начале файла для +3DOS. Понятно, что вопрос, по сути, сводится к «как посчитать контрольную сумму?» Lua – ответ очевидный, а вот какие ещё ваши доказательства варианты?

P.S. свой вариант на «чистом» asm пока не привожу, там, скорее идея – работать оно, почему-то, работает, но не так, как я ожидал.

cafedead
10.05.2025, 15:29
sub a,32
Я тоже засел как-то с алгоритмом из-за того, что "SUB A,B" превратились этим ассемблером в два опкода - "SUB A" и затем "SUB B", что было ФАТАЛЬНО не тем, что мне нужно было. Главное, такие ошибки довольно трудно-отлавливаемые. Нахрена такие "фичи" добавлять, не понятно. Такие фичи должны быть включаемыми и по умолчанию выключенными, а не включенными и хрен знает как выключаемыми. Ну или они ХОТЯ БЫ должны быть корректно реализованы. В данном случае, по моему мнению, реализованы они некорректно, потому что мнемоникой предполагается синтаксис SUB [A,]B, и если конкретный ассемблер sjasm хочет как-то расширить синтаксис в этом месте, то должен учитывать необязательный неявный "A," вначале списка, а не тупо собирать кучу команд по списку регистров. Это мое мнение. Считаю, что здесь все же ошибка реализации. Вначале нужно удалить A из начала списка, затем уже реализовывать свои фантазии, и проблем ни у кого не возникло бы. И если кому-то нужно будет зачем-то получить ряд инструкций, начиная с регистра A (понятия не имею, зачем), то пусть пишет SUB A,A,B,C,D, и так далее, на здоровье, сколько угодно (т.е. все ноль раз), а не я вместе со всеми должен страдать, выискивая дизасмом, почему корректный алгоритм не работает. Ped7g пишет, что

(vs Zilog official syntax, which is ... unfortunate... in some cases).
но вместо того, чтобы помочь мне, программисту, создал еще больше проблем. Да нормальный тут у Зилога синтаксис. В SUB, AND, OR, XOR, CP не указывается A, потому что нет одноименных инструкций, работающих не с A. А у ADD, ADC, SBC указывается A, потому что есть еще ADD|ADC|SBC rp,rp, и возникла бы неопределенность. Обязан ли я помнить такие моменты, что SBC надо писать с A, а SUB - без A? Не обязан. Тут скорее неправильное трактование этого официального синтаксиса автором ассемблера, который В ПЕРВУЮ ОЧЕРЕДЬ должен был ПОМОЧЬ программисту с написанием программы, либо убрав "A,", либо, в крайнем случае, подсказывая ему о таких моментах предупреждениями или ошибками. Уж точно не мешать своими "фичами", трактуя код как-то по-своему, как какой-то сумасшедший. Ну два возможных варианта, автор. Тут не предусмотрено варианта - наассемблировать какой-то херни. Своими такими вот "фичами" "помогать" ассемблер должен где-то в десятую очередь, и то, если такой запрос поступил. А у нас тут в этом месте происходит конкретное такое вредительство, и иначе это не назвать. И, главное, куча человек уже написали о проблемах в этом месте, все опытные, уже с 30+ опытом программирования, но нет, "я - художник, я так вижу". Браво.

Решение проблемы двойными запятыми - костыльное, но да, работает. Добавил "OPT --syntax=abf", как рекомендует Ped7g, это работает. Но это костыль, потому что проблема, на мой взгляд, как я сказал, в реализации "фичи", а не в количестве запятых. Не понимаю, почему я должен добавлять какую-то хрень в код, чтобы наконец-таки получить чистый ассемблер. Ну окей, я свои личные проблемы решил добавлением директивы, но в ассемблере так и осталась некорректная реализация фичи. Ну это такова в целом философия автора, которая идет вразрез с моей философией. Я считаю, что база должна работать из коробки, а автор, очевидно, считает, что я вначале обязан использовать его выдуманные директивы, указать устройство, чтобы хотя бы что-то начало работать, например, зачем-то указать NOSLOT, чтобы ассемблировать по нулевому адресу, и что-то еще указывать, чтобы начать получать в итоге базовую базу, а не чьи-то фантазии на тему SUB A: SUB B.

И чего еще мне не хватило - это добавления \x## (16-чное 2-разрядное число) последовательностей в строковых параметрах для указания управляющих символов. И это для Спектрума, где куча управляющих символов, всякие управляющие AT, INK, PAPER, и т.д. Это я не понял, почему было не добавить. Серьезно, никому в голову не пришло сделать?! Очевидная же штука, казалось бы. Но нет.

В остальном, все супер, но я макросы не использовал, много в какие дебри не лез. ALIGN попользовал для выравнивания кода в паре мест - отлично подошло, DISP отлично работает. Какими-то другими изысками не пользовался. Половинками индексных регистров тоже, мне сподручнее было написать DEFB #FD и LD L,A, чем пользоваться фейками. В общем, мне вообще мало что нужно для счастья, так что я скорее всем доволен.

krt17
10.05.2025, 19:08
Обязан ли я помнить такие моменты, что SBC надо писать с A, а SUB - без A? Не обязан.


я вначале обязан использовать его выдуманные директивы, указать устройство, чтобы хотя бы что-то начало работать

Троля греть не хорошо, но ты реально мастер.

Ped7g
11.05.2025, 01:00
I don't understand the:
DEFB #FD : LD L,A
vs normal instruction
LD IYL,A ; or LD YL,A or LD LY,A, whichever way you prefer

Or how does it relates to "fakes"? These are regular undocumented opcodes. "fake" instructions are something different: https://z00m128.github.io/sjasmplus/documentation.html#s_fake_instructions.

The \x escapes are somewhere on my TODO list.

About default syntax... :shrug: I didn't design it, I'm not happy with multi-arg for `sub` myself. I may eventually switch defaults in some major-major version, but considering how much whining I get whenever I change something, I'm not in a hurry...

metamorpho
16.06.2025, 19:32
Подскажите SjASMPlus работает в Windows10 ?

Bedazzle
16.06.2025, 20:16
Подскажите SjASMPlus работает в Windows10 ?

Да, вполне.

metamorpho
16.06.2025, 22:19
Да, вполне.

Тогда как правильно настроить SjASMPlus (в Windows10) ?

Для редактирования текста на ассемблере использую NOTEPAD++, в нём по F5 запускаю .bat файл

В файле .bat для компиляции текста написано следующее:
start "" C:\DownLoad\QASW\sjasmplus.exe main107sova.asm


В тексте main107sova.asm вконце написано следующее:
SAVESNA "C:\DownLoad\ku.sna"

В итоге после запуска по F5 ничего не получается - файла ku.sna нет.
Похоже я что-то напутал или неправильно записал, подскажите как нужно сделать ?

andrews
16.06.2025, 22:44
Сделай dir >a и посмотри, сколько уровней у тебя до корневого директория, где расположен sjasmplus.exe .
Например, у меня исходник на ассемблере здесь h:\SJASMPLUS\zxcc
И поэтому мой командник compile.bat , расположенный в моем директории h:\SJASMPLUS\zxcc делает это


..\sjasmplus output.asm 1>err1
pause


в конце файла .asm должно быть
SAVESNA "output.sna", main
если он начинается так


DEVICE ZXSPECTRUM48
org 32768

main:
...
ld a, 2
...


Если у тебя исходник расположен глубже - количество ..\ увеличивается.
Других команд добавлять не требуется. Можешь конечно прописать path к sjasmplus и тогда просто запускать ассемблирование по
sjasmplus имя твоего исходника.asm

metamorpho
17.06.2025, 10:01
. Можешь конечно прописать path к sjasmplus и тогда просто запускать ассемблирование по
sjasmplus имя твоего исходника.asm

Не работает. Похоже он просто отказывается компилировать в моей Windows10.
Может sjasmplus какие-то библиотеки нужны или он всё что нужно в себе содержит ?

breeze
17.06.2025, 10:08
Похоже он просто отказывается компилировать в моей Windows10.

Ну куда уж проще, запусти командную строку с путём где у тебя лежит твой исходник и прям там запусти свой батник или прямо в ней напиши «sjasmplus "имя твоего исходника.asm"».
Если есть какие-то проблемы с запуском, нехваткой библиотек итд, сразу увидишь. А так можно гадать до второго пришествия.

metamorpho
17.06.2025, 10:31
Ну куда уж проще, запусти командную строку с путём где у тебя лежит твой исходник и прям там запусти свой батник или прямо в ней напиши «sjasmplus "имя твоего исходника.asm"».
Если есть какие-то проблемы с запуском, нехваткой библиотек итд, сразу увидишь. А так можно гадать до второго пришествия.

Именно так я и делаю :)
Видно что появляется окно и тут же исчезает, поэтому узнать что там не так не получается.

- - - Добавлено - - -

Меня вот это настораживает:

Цитата из описания к SjASMPlus: "SjASMPlus — это кросс-компилятор языка ассемблера Z80. Он доступен для систем Win32"

Обзор от ИИ: "Да, файл Win32 (32-разрядный) может работать в 64-разрядной версии Windows, но не всегда. 64-разрядные версии Windows включают среду совместимости под названием WoW64, которая позволяет запускать 32-разрядные приложения. Однако, есть некоторые ограничения и случаи, когда 32-разрядные приложения могут не работать или работать некорректно на 64-разрядной системе. "

Может ли так быть что у кого-то SjASMPlus работает в Windows10 а у кого-то нет ?

Bedazzle
17.06.2025, 11:09
Именно так я и делаю :)
Видно что появляется окно и тут же исчезает, поэтому узнать что там не так не получается.


Пробуем разобраться.

1. создаём новую папочку
2. кладём в папочку sjasm (взятый здесь https://github.com/z00m128/sjasmplus/releases/tag/v1.21.0 , нужен только sjasmplus.exe файл)
3. и файлик с исходником, который хотим компилить, например, mygame.asm
4. запускаем командную строку (в поиски винды пишем cmd , выскочит диалог выбора, там должно быть cmd.exe)
5. в появившемся чёрном окне с текстовым режимом переходим в нашу папочку
- узнать текущее место и рядом находящиеся файлы/папки можно написав команду dir и нажав enter
- перейти в папку при помощи cd имяпапки (если имя папки содержит пробел, то нужно писать в двойных кавычках)
- перейти на уровень выше при помощи cd .. (две точки)
- можно сразу перейти в нужное место, например cd "C:\work\my project"

6. находясь в нашей папочке даём команду sjasmplus.exe mygame.asm
7. наблюдаем, что ассемблер выплюнул в окно - там могут быть как сообщение, что всё хорошо, так и ошибки

SjASMPlus Z80 Cross-Assembler v1.21.0 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
Pass 3 complete
Errors: 0, warnings: 0, compiled: 15 lines, work time: 0.000 seconds
8. если всё хорошо, рядом с исходником должен появиться скомпилированный файл

P.S.
отключить лишний вывод при компиляции можно таким образом
sjasmplus.exe --msg=war --nologo mygame.asm

P.P.S.
пример исходника:


DEVICE ZXSPECTRUM48

org $8000
start:
ld hl, $4000
ld b, 0
loop:
ld (hl), l
inc hl
djnz loop

jr $

SAVESNA "mygame.sna", start

metamorpho
17.06.2025, 12:20
Пробуем разобраться. ..............
[/CODE]

Дело пошло лучше :)

Выдаёт следующее:

C:\DownLoad\sjasm> sjasmplus.exe output.asm
SjASMPlus Z80 Cross-Assembler v1.21.0 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
output.asm(1): error: Unrecognized instruction: ZXSPECTRUM48
output.asm(13): error: SAVESNA only allowed in real device emulation mode (See DEVICE)
Pass 3 complete
Errors: 2, warnings: 0, compiled: 13 lines, work time: 0.000 seconds
C:\DownLoad\sjasm>

файла .sna попрежнему нет

- - - Добавлено - - -

заменил DEVICE ZXSPECTRUM48 на device zxspectrum48
и всё получилось !! :) Спасибо всем кто помогал !!

- - - Добавлено - - -

До этого по сути делал тоже самое - только без информации компилятора.
Вот может кому-то пригодится - если вы используете оболочку например UnrealCommander или TotalCommander,
то там можно всё сделать быстрее (только при этом информации sjasmplus не выдаёт)

навести курсор на sjasmplus.exe и нажать Ctrl+Enter (в командной строке оболочки например UnrealCommander появится sjasmplus.exe),
потом навести курсор на ваш файл исходник name.asm и нажать Ctrl+Enter (в командной строке оболочки появится name.asm),
и далее нажать Enter - произойдёт компиляция и появится файл .sna

andrews
17.06.2025, 13:12
Просто DEVICE ZXSPECTRUM48 не должно начинаться в нулевом столбце. А регистр роли не играет. Для чего так сделано - это вопрос к разработчикам SJASMPLUS.

Black Cat / Era CG
17.06.2025, 17:13
потому что с 0 столбца расположена метка.

Biland
17.06.2025, 18:27
Для редактирования текста на ассемблере использую NOTEPAD++, в нём по F5 запускаю .bat файл



Можно скрипты прилепить без .bat, могу скинуть (модифицированные немного, через выделение имени) или в инете найти можно стандартные.

Но лучше переходи на vscode, намного удобнее, notepad++ и 10-ой части не делает. Если интересно, то могу скинуть настройки в vscode, самых дурных опций и скрипты запуска проекта.

Black Cat / Era CG
17.06.2025, 19:56
Если интересно, то могу скинуть настройки в vscode, самых дурных опций и скрипты запуска проекта.Кидай сюды, наверное, всем будет полезно. А то люди по моей в хлам устаревшей статье нпп прикручивают к сжасму, а там уже все не так.

Bedazzle
17.06.2025, 22:09
заменил DEVICE ZXSPECTRUM48 на device zxspectrum48
и всё получилось !!

Команда девайс часом не в начале строки была (без пробела или табуляции)?
Регистр символов не должен влиять.

Biland
18.06.2025, 14:34
Для vscode.
Установить не сложно, в документации к DeZog (https://github.com/maziac/DeZog?ysclid=mc1vkl6xnz679636414) есть рекомендации, какие надстройки подходят.

DeZog
To use DeZog in Visual Studio Code, simply install the "DeZog" extension (maziac.dezog) from the Visual Studio Code Marketplace. Although not required, there are several other helpful extensions available, including:

ASM Code Lens, which provides syntax highlighting for Z80 assembler, as well as completions, references, jump to label, and renaming functionality.
Z80 Instruction Set, which displays opcode, affected flags, and a description when hovering over a Z80 instruction.
Hex Hover Converter, which converts numbers to decimal, hexadecimal, and binary formats when hovering over them.
ZX SNA File Viewer/ZX NEX File Viewer, which allow viewing of ZX Spectrum snapshot (.sna) and ZX Spectrum Next (.nex) files (search for "snafile" and "nexfile" in the Marketplace).
ZX81 BASIC to P-File Converter and P-File Viewer, which converts ZX81 P-Files (.p) to ZX81 BASIC (.bas) and vice versa.
В приложении, скрипты, для запуска разных вариантов эмуляторов, с переключением страниц (64 страницы) для ZSim (ZSim Custom Memory), для режима debug. Псевдо-порты переключения страниц, прописаны в скриптах. Нужно только поменять пути к файлу запуска проекта и путь к sjasm.

Editor: Quick Suggestions Delay
Управляет длительностью задержки (в мс) перед отображением кратких предложений. (1000)

Editor › Hover: Delay
Определяет время задержки в миллисекундах перед отображением наведения. (1000)

Ctrl + Shift + P
Configure Display Language

Editor: Auto Closing Comments
Определяет, должен ли редактор автоматически закрывать комментарии,
при добавлении пользователем открывающего комментария. (never)

Autohide
Определяет, скрыта ли мини-карта автоматически. (Enable)

Editor: Selection Highlight
Определяет, должен ли редактор выделять совпадения, аналогичные выбранному фрагменту. (disable)

Editor: Occurrences Highlight
Определяет, следует ли выделять вхождения в открытых файлах. (off)

Editor: Color Decorators
Определяет, должны ли в редакторе отображаться внутренние декораторы цвета и средство выбора цвета. (disable)
(если написать текст и набрать позже #NNNNNN, то он прибавляет квадрат к тексту, где можно выбирать палитру)


Для Notepadplus.

Т.к. у меня исходники и бинарники разложены по разным папкам, стандартный скрипт не может уловить путь откуда запускать скомпилированный файл. Пришлось пойти на хитрость и просто выделять этот путь перед компиляцией и запуском. Пример, SAVESNA "..//BIN//main.sna" - здесь выделяется отрезок ..//BIN. Т.к. Notepadplus используется очень редко, то это не критично.



// [Ctrl+F9] Скрипт компиляции проекта
// Сохраняем все файлы
//REM/ npp_saveall
npp_save
// Сохраняем путь текущего редактируемого файла
set current = $(FULL_CURRENT_PATH)
// Переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
//REM/ npp_switch $(#1)
// Получаем полные имена файла меток и основного файла проекта
set symbol_name = "$(CURRENT_DIRECTORY)/$(SELECTED_TEXT)/$(NAME_PART).sym"
set project_full_name = "$(FULL_CURRENT_PATH)"
// возвращаемся на ранее открытую вкладку
//REM/ npp_switch $(current)
// компилируем проект
cd $(project_full_name)
"$(NPP_DIRECTORY)/../SJAsm/sjasmplus.exe" --fullpath --sym=$(symbol_name) $(project_full_name)


// [F9] Скрипт компиляции и запуска проекта
// Сохраняем все файлы
//REM/ npp_saveall
npp_save
// Сохраняем путь текущего редактируемого файла
set current = $(FULL_CURRENT_PATH)
// Переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
//REM/ npp_switch $(#1)
// Получаем необходимые имена файлов
//REM/ set image_name = "$(CURRENT_DIRECTORY)\$(NAME_PART).trd"
set image_name = "$(CURRENT_DIRECTORY)/$(SELECTED_TEXT)/$(NAME_PART).sna"
set image_dir = "$(CURRENT_DIRECTORY)/$(SELECTED_TEXT)/"
set symbol_name = "$(CURRENT_DIRECTORY)/$(SELECTED_TEXT)/$(NAME_PART).sym"
set project_full_name = "$(FULL_CURRENT_PATH)"
// Возвращаемся на ранее открытую вкладку
//REM/ npp_switch $(current)
// Компилируем проект
cd $(project_full_name)
"$(NPP_DIRECTORY)/../SJAsm/sjasmplus.exe" --fullpath --sym=$(symbol_name) $(project_full_name)
// запускаем откомпилированный проект
cd $(image_dir)
"$(NPP_DIRECTORY)/../Unreal/unreal.exe" $(image_name)


// [F10] Скрипт запуска проекта
// Сохраняем путь текущего редактируемого файла
set current = $(FULL_CURRENT_PATH)
// переключаемся на основной файл проекта (должен быть открыт в 1-ой вкладке!)
//REM/ npp_switch $(#1)
// Получаем полное имя образа диска с откомпилированным проектом для запуска
// (если вы компилируете в sna, поменяйте расширение на нужное)
set image_name = "$(CURRENT_DIRECTORY)/$(SELECTED_TEXT)/$(NAME_PART).sna"
set image_dir = "$(CURRENT_DIRECTORY)/$(SELECTED_TEXT)/"
// Возвращаемся на ранее открытую вкладку
//REM/ npp_switch $(current)
// Запускаем откомпилированный проект
cd $(image_dir)
"$(NPP_DIRECTORY)/../Unreal/unreal.exe" $(image_name)

metamorpho
18.06.2025, 16:41
Команда девайс часом не в начале строки была (без пробела или табуляции)?
Регистр символов не должен влиять.

Возможно да, я уже не помню, а файл уже изменён.

Dart Alver
18.06.2025, 22:32
Ped7g , а можете реализовать поддержку особых макросов с неопределённым количеством параметров, чтоб от ни одного до много-много ? ;)

Я тут подумал - в ZASM, в макрос можно передавать неопределённое количество параметров или не передавать вовсе, при этом доступ к ним осуществляется через =1 , =2 и т.д. Пример:

NAME macro : ld hl,=1 : ld de,=2 :endm

но там из-за многих ограничений эта фича преимуществ не даёт. А вот в SjASMplus с его Lua scripting , можно будет реализовывать довольно гибкие макросы, например реализовать какую-либо особую перекодировку строк символов в стиле записи в формате DEFB. Или что-то более сложное.

У нас конечно знак '=' не подойдёт, да и чтобы не ломать проверки, этот макрос лучше оформлять отдельной командой . Например использовать слово 'macro$' или 'macro+' или что-то подобное.

Типа :


macro$ <name>
....
endm

Чтобы данный макрос можно было бы использовать как без параметров, так и с параметрами, количество которых не ограничено.
Пусть например введённые параметры принимают имена по порядку p1 , p2 , ... , p10 , p11 , ... , p100 ... и так далее, а p0 , как в bash скриптах, показывает номер последнего параметра.
А если две запятые идут друг за другом или через пробел, то значит параметр пустая строка (без кавычек)

Lua функция sj.get_define("name", true) при отсутствии параметра в таком макросе пусть не орёт про ошибку, а выдаёт обычный nil

Как смотрите на такое возможное дополнение ?

CityAceE
01.07.2025, 14:20
Столкнулся с дурацкой ситуацией, которую пока не знаю как правильно решить. Прошу помощи!

Я переделывал код Z80 в код i8080. Отсутствующие у i8080 заменял макросами. А чтобы не плодить огромную кучу похожих макросов я сделал универсальные макросы, которые принимают на вход имя регистра. Внутри макроса по имени переданного регистра я выполняю определённые действия. Но проблема в том, что я не нашёл как делать условия правильно, чтобы оно срабатывало с передаваемым именем.

Пример:



macro instr reg1, reg2
if reg1 == A
; some code
if reg2 == H
; some code
endm


instr A, C


Ни одно из условий не выполнится. Я пробовал и кавычки и много чего ещё. Чаще всего получаю ошибку на отсутствующую метку.

В итоге после череды всевозможных проб и ошибок закостылил так:



macro instr reg1, reg2
if reg1 == A
; some code
if reg2 == H
; some code
endm

A: db "A"
B: db "B"
C: db "C"
D: db "D"
E: db "E"
H: db "H"
L: db "L"

instr A, C


Вот так работает, но в итоге имеем лишних 7 байт на константы. Причём в конец кода их перекинуть нельзя, так как они должны находится перед первым вызовом макроса.

b2m
01.07.2025, 15:33
Имена регистров, в данном случае, как символы не определены. Во втором случае им будут соответствовать адреса букв. Сравнивать можно только числа. Определи имена регистров как числа от 0 до 7. Удобнее будет если B=0, C=1, и т.д., тогда их можно будет прямо к коду операции 8080 добавлять.

CityAceE
01.07.2025, 17:10
Определи имена регистров как числа от 0 до 7. Удобнее будет если B=0, C=1, и т.д., тогда их можно будет прямо к коду операции 8080 добавлять.
Спасибо за подсказку. Работает, хотя наглядность, конечно, при сравнении пропала. Но для уже написанного особой разницы нет.

CityAceE
02.07.2025, 18:45
Существует ли какой-нибудь метод, который позволяет автоматически развернуть все макросы, подставить все данные и удалить из несработавшие условия?

Исходный макрос:



; LD reg,(IX+d)
macro macro_ld_reg_ix_d reg, data, no_stack
if reg != 0 ; A
ld (.tmp + 1), a
endif

if no_stack == 1 || reg == 5 || reg == 6 ; || H || L
if reg != 5
ld a, h
ld (TMP1 + 1), a
endif
if reg != 6
ld a, l
ld (TMP1), a
endif

else
push hl
endif

ld hl, (rIX)

if reg == 1 || reg == 2 ; B || C
if no_stack == 1
ld a, d
ld (TMP2 + 1), a
ld a, e
ld (TMP2), a
else
push de
endif
ld de, data
else
if no_stack == 1
ld a, b
ld (TMP2 + 1), a
ld a, c
ld (TMP2), a
else
push bc
endif
ld bc, data
endif

if reg == 1 || reg == 2 ; B || C
add hl, de
else
add hl, bc
endif

if reg == 1 || reg == 2 ; B || C

if no_stack == 1
ld a, (TMP2 + 1)
ld d, a
ld a, (TMP2)
ld e, a
else
pop de
endif
else
if no_stack == 1
ld a, (TMP2 + 1)
ld b, a
ld a, (TMP2)
ld c, a
else
pop bc
endif
endif

ld reg, (hl)

if reg == 0 ; A
ld (.tmp + 1), a
endif

if no_stack == 1 || reg == 5 || reg == 6 ; || H || L
if reg != 5
ld a, (TMP1 + 1)
ld h, a
endif
if reg != 6
ld a, (TMP1)
ld l, a
endif
else
pop hl
endif

.tmp ld a, 0
endm



А нужно, чтобы он развернулся, подставились все необходимые значения и убрались все несработавшие условия. То есть, чтобы в итоге в тексте вместо

macro_ld_reg_ix_d A,99-100,0

нарисовалось такое:



; macro_ld_reg_ix_d A,99-100,0
push hl
ld hl, (rIX)
push bc
ld bc, 99-100
add hl, bc
pop bc
ld a, (hl)
pop hl
;---------------------------------------

CityAceE
03.07.2025, 10:56
В общем, отвечаю сам себе, вдруг ещё кому-нибудь пригодится.

1. Создал листинг с помощью ключа --lst
2. Загрузил его в Excel и там разбил на колонки.
3. Удалил следующие строки, удовлетворяющие следующим условиям по двум колонкам:


Пустой код && >
Код ~ && >
Не пустой код && Пустой текст

4. Скопировал колонку с текстом в редактор.

В редакторе дополнительно вручную обработал вызов макросов и локальных меток, которые начинаются с точки.

krt17
03.07.2025, 11:57
а потом искать почему неправильно работает, а С то улетел

CityAceE
03.07.2025, 14:45
Я, естественно, сравнил получаемый бинарник до подобного преобразования и после него. Всё совпадает байт в байт.

krt17
03.07.2025, 15:31
Я про то что комманда ld R,(ix+D) на афектит флаг С, а замена еще как, да и не только С. Не знаю как часто, но думаю подобные ситуации встречаются.

cafedead
03.07.2025, 23:01
Ни одно из условий не выполнится. Я пробовал и кавычки и много чего ещё. Чаще всего получаю ошибку на отсутствующую метку.
Не знаю, как вы кавычки пробовали. Вот я попробовал:



macro instr reg1, reg2
if reg1 == "A"
DISPLAY "A"
; some code
if reg2 == "H"
DISPLAY "H"
; some code
endm

instr "A", "C"


Все нормально выполняется. Первое условие выполнилось, второе - нет, все корректно. Хотя я у этого кросс-ассемблера заметил какую-то лажу в приоритетах операций. Иногда довольно странные скобки приходится ставить.



SjASMPlus Z80 Cross-Assembler v1.21.0 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> A
macro.asm(11): error: [IF] No ENDIF
macro.asm(15): ^ emitted from here
macro.asm(11): error: [IF] No ENDIF
macro.asm(15): ^ emitted from here
Pass 3 complete
Errors: 2, warnings: 0, compiled: 23 lines, work time: 0.000 seconds

Ну и да, у вас второй иф вложен в первый, ENDIFов нет.

Или вы хотели в instr именно без кавычек писать имена регистров?

Dart Alver
03.07.2025, 23:55
Все нормально выполняется. Первое условие выполнилось, второе - нет, все корректно.
Кавычки в параметрах макроса по лексике не подходили.


Ну и да, у вас второй иф вложен в первый, ENDIFов нет.
Видимо просто схематично изобразил условия, ENDIFы в ' ; some code'е спрятались ))

- - - Добавлено - - -


Ни одно из условий не выполнится. Я пробовал и кавычки и много чего ещё. Чаще всего получаю ошибку на отсутствующую метку.
Ну ещё, если не юзать метки, то можно через lua решить вопрос, но телодвижений больше ))

cafedead
04.07.2025, 00:09
Существует ли какой-нибудь метод, который позволяет автоматически развернуть все макросы, подставить все данные и удалить из несработавшие условия?
Если честно, вы немного... непонятно формулируете вопрос и свою задачу, мне она не очень понятна. Впечатление, что проблемы именно с формулированием.

Вызов макроса формирует код. В теле макроса у вас выполняются или не выполняются отдельные условия, формируется код, размещенный в сработавших ветвях, код из несработавших ветвей не формируется. Что значит "метод, который позволяет автоматически развернуть все макросы, подставить все данные и удалить из несработавшие условия"? Откуда чего вы хотите удалить?! Я вас не понимать.

Добавил:


DEVICE ZXSPECTRUM48

ORG 32768

A EQU 0


и в конце:



rIX DEFW 0


(А почему я это должен писать?!)

В итоге, все нормально скомпилировалось, ваш макрос при таком вызове macro_ld_reg_ix_d A,99-100,0 сформировал вот такой код:



PUSH HL
LD HL,(#8012) ; это адрес вашей переменной rIX
PUSH BC
LD BC,#FFFF ; это ваша минус единица, 99-100=-1
ADD HL,BC
POP BC
LD A,(HL)
LD (#8011),A ; это не то, что вы хотели, но таков ваш макрос:
;if reg == 0 ; A
; ld (.tmp + 1), a
;endif
; исправляйте его, если хотите что-то другое
POP HL
LD A,0 ; это тоже не то, что вам нужно, но... вы же это написали в макросе


И что вы хотите? Поконкретнее плз. Потому что


А нужно, чтобы он развернулся, подставились все необходимые значения и убрались все несработавшие условия.
именно это и произошло.

- - - Добавлено - - -


Вот так работает, но в итоге имеем лишних 7 байт на константы. Причём в конец кода их перекинуть нельзя, так как они должны находится перед первым вызовом макроса.
Какие константы? Это реальные байты. Я не понимаю, зачем использовать для этого реальные байты памяти... Есть переменные. Вон я пример привел с EQU, определил A. Можете теперь сравнивать с A, а не с нулем. Ну вообще конечно плохо пересекаться с именами регистров, но если очень уж хочется, то можно. Но зачем?!

Ну и я просто не вполне понимаю задачу, которую вы делаете. Я так понял, вы хотите реализовать инструкцию работы с индексным регистром, обходясь регистрами HL и BC, этим обеспечив совместимость с другим процессором без поддержки таких инструкций. Вы хотите какие-то исходники преобразовать в такой вот измененный код, переассемблировать, что-то куда-то портировать? На какую машину? Что и откуда вам нужно удалить?!

И да, вам очень правильно указали, что ADD влияет на флаги, в отличие от загрузки в память/из памяти по адресу из индексного регистра плюс-минус смещение, вам придется об этом позаботиться.

Регистры и регистровые пары логичнее было бы нумеровать так, как они пронумерованы в опкодах, чтобы затем по возможности по приходящему значению вычислять нужный опкод, а не городить многоэтажные IFы.

cafedead
04.07.2025, 14:03
Кавычки в параметрах макроса по лексике не подходили.
Ну вот я как раз и говорю о том, что у автора вопроса проблемы с формулированием целей и задачи. Чтобы его понять, приходится какое-то время вникать в его макрос, пытаться понять, что он там настроил, да и вообще, что у него в голове за поток сознания, а не просто прочитать комментарий, написанный нормальным языком, мол стоит задача такая-то такая-то, проблема такая-то такая-то.

Посмотрел, что там у Интела с макросами, попробовал написать так же и тут, и это почти заработало, но, поскольку таких имен ни переменных, ни лейблов не существует, там специальный синтаксис для получения значений для сравнения таких вот псевдопеременных из имен регистров, и специальная директива для получения типа входящей переменной, чего в sjasm вроде бы нет. Не помешало бы добавить. Я немного взломал систему, если можно так выразиться, получилось вот так:



macro load8 l8, h8
display $h8
display $l8
ld l8, h8
endm

macro load16 l16, h16
display $h16
display $l16
if $h16 == $AF
display "h16=AF"
endif
if $l16 == $BC
display "l16=BC"
endif
push h16
pop l16
endm

load8 B,C

load16 DE,AF


Это почти работает, что-то можно сравнивать, но, понятное дело, только с теми регистрами и регистровыми парами, которые умещаются в 16-чную систему счисления. HL, SP, IX, IY, штрихи всякие в пролете. Но это чисто поржать, я не рекомендую так это использовать, т.к. явно тут вылезли какие-то недоработки в компиляторе, которые нужно устранить.

Ну не знаю, может Ped7g прокомментирует, может быть там есть возможности, о которых мы не знаем.

Upd: Хотя вот так все работает:


B equ 0
C equ 1
D equ 2
E equ 3
H equ 4
L equ 5
A equ 7
b equ 0
c equ 1
d equ 2
e equ 3
h equ 4
l equ 5
a equ 7
BC equ 0
DE equ 1
HL equ 2
SP equ 3
AF equ 3
bc equ 0
de equ 1
hl equ 2
sp equ 3
af equ 3

macro ld8 dst, src
display "LD8"
display src
display dst
if dst == H
display "dst = reg H"
endif
ld dst,src
ld a,b ; это проставит инструкцию с реальными регистрами A и B
endm

ld8 B,C
ld8 H,E




SjASMPlus Z80 Cross-Assembler v1.21.0 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> LD8
> 0x0001
> 0x0000
> LD8
> 0x0003
> 0x0004
> dst = reg H
Pass 3 complete
Errors: 0, warnings: 0, compiled: 208 lines, work time: 0.000 seconds


И никаких костылей, или байтов в памяти.

CityAceE
04.07.2025, 17:11
Я уже всё, что мне нужно сделал. О чём отписался. И, как я понял, на форуме нашлись люди, которые поняли, что что мне требовалось. На всякий случай разъясню ещё раз.

1. Проверки имени регистра в макросе:

Макрос (только для примера!)


macro test reg
if reg == H
ld h, reg
else
ld a, reg
endif
endm




test H


Скомпилироваться должно так:


ld h, H


2. По поводу разворачивания макросов. Мне хотелось бы получить текст программы, где на месте всех макросов будут подставлены готовые ассемблерные команды. То есть в тексте программы на месте test H я хотел видеть только ld h, H, без всяких if'ов и прочего.

Но, как я написал выше, это уже неактуально.

cafedead
04.07.2025, 19:31
И, как я понял, на форуме нашлись люди, которые поняли, что что мне требовалось.
Оу, ну да, нашлись люди, которые поняли, это я один, такой тупой, непонятливый, все правильно. Но я вам объясняю, что вас понять... трудно, потому что формулируете плохо. Понять-то и я вас понял, но сколько времени на это ушло. У тех людей тоже ушло на это время, просто раньше меня вас прочитали. Сами посмотрите на свой макрос, который вы написали типа для примера. Сколько в нем лишнего мусора, уводящего от сути вопроса. Десять этажей ифов с кучей условий... Ну это банальное неуважение. Сами посмотрите, что вы в ожидании ответа из него написали. Я же не телепат, чтобы угадывать, где вы ошиблись, в макросе, или в описании ожиданий от него. Наверное, найдутся телепаты...

Актуально это для вас, или нет, теперь не важно, раз уж я уже начал с этим ковыряться, и уже нашел решение. Может кому-то будет интересно, будет похожая задача, и он не захочет писать тонну лишнего мусора. Определяем значения переменных:


B equ 0
C equ 1
D equ 2
E equ 3
H equ 4
L equ 5
A equ 7
b equ 0
c equ 1
d equ 2
e equ 3
h equ 4
l equ 5
a equ 7
BC equ 0
DE equ 1
HL equ 2
SP equ 3
AF equ 3
bc equ 0
de equ 1
hl equ 2
sp equ 3
af equ 3

ix equ #180
iy equ #280
IX equ #180
IY equ #280


Макрос:


macro ldrx dst,src
push af
push hl
push bc
.iyt equ src-$280 & $FFFF
.ixt equ src-$180 & $FFFF
if src & $200
ld hl,(rIY)
ld bc,.iyt
elseif src & $100
ld hl,(rIX)
ld bc,.ixt
endif
add hl,bc
ld dst,(hl)
pop bc
pop hl
pop af
endm

Вызов макроса с разными пограничными значениями:


ldrx c,(IX+1)
ldrx a,(IY+1)
ldrx d,(IX-1)
ldrx e,(IY-1)
ldrx h,(IX+127)
ldrx l,(IY+127)
ldrx b,(IX-128)
ldrx d,(IY-128)

rIX DEFW 0
rIY DEFW 0


Все работает. Пожалуйста, вызов - как вы и хотели, даже еще лучше, максимально аутентично. Тут вам и любые регистры на выходе, и сразу оба индексных регистра на входе... Про no_stack стоит забыть, потому что AF необходимо сохранять, сохраняется через стек, как ни крути. Можно добавить проверку на -128-+127 с выбросом ошибки, но мне лень и не надо, сами справитесь.

Можно и имена регистров для проверок использовать, ветвления ассемблирования с этим связанные добавить, но мне, как видите, даже не пригодилось для поставленной задачи. И вот как раз поэтому сложно понять, сложно... Не знаешь никогда, что у другого специалиста в голове, что там за поток, и куда этот поток стремится. Поэтому нужно хотя бы стараться понятным языком излагать свои хотелки, чтобы другие люди не тратили время на расшифровку послания.

- - - Добавлено - - -
Вот вроде такого:

В общем, отвечаю сам себе, вдруг ещё кому-нибудь пригодится.

1. Создал листинг с помощью ключа --lst
2. Загрузил его в Excel и там разбил на колонки.
3. Удалил следующие строки, удовлетворяющие следующим условиям по двум колонкам:
Пустой код && >
Код ~ && >
Не пустой код && Пустой текст

Хотел пошутить, но не буду. Мне вряд ли пригодится. Я даже не понимаю, о чем идет речь, какой-то шифр, а расшифровки нет. И я вряд ли стану ковыряться в Экселе для решения подобных задач. Ну это уже перебор, как по мне. Очевидно, есть другие менее топорные способы:


OPT listmc


Файл lst:


# file opened: macro.asm
1 0000 DEVICE ZXSPECTRUM48
2 0000
3 0000 ORG 32768
4 8000
5 8000 OPT listmc
208 8000 41 { ld B,C
208 8001 78 { ld a,b
208 8002 78 { LD A,B
209 8003 63 { ld H,E
209 8004 78 { ld a,b
209 8005 78 { LD A,B
211 8006 F5 { push af
211 8007 E5 { push hl
211 8008 C5 { push bc
211 8009 2A 76 80 { ld hl,(rIX)
211 800C 01 01 00 { ld bc,.ixt
211 800F 09 { add hl,bc
211 8010 4E { ld c,(hl)
211 8011 C1 { pop bc
211 8012 E1 { pop hl
211 8013 F1 { pop af
212 8014 F5 { push af
212 8015 E5 { push hl
212 8016 C5 { push bc
212 8017 2A 78 80 { ld hl,(rIY)
212 801A 01 01 00 { ld bc,.iyt
212 801D 09 { add hl,bc
212 801E 7E { ld a,(hl)
212 801F C1 { pop bc
212 8020 E1 { pop hl
212 8021 F1 { pop af
213 8022 F5 { push af
213 8023 E5 { push hl
213 8024 C5 { push bc
213 8025 2A 76 80 { ld hl,(rIX)
213 8028 01 FF FF { ld bc,.ixt
213 802B 09 { add hl,bc
213 802C 56 { ld d,(hl)
213 802D C1 { pop bc
213 802E E1 { pop hl
213 802F F1 { pop af
214 8030 F5 { push af
214 8031 E5 { push hl
214 8032 C5 { push bc
214 8033 2A 78 80 { ld hl,(rIY)
214 8036 01 FF FF { ld bc,.iyt
214 8039 09 { add hl,bc
214 803A 5E { ld e,(hl)
214 803B C1 { pop bc
214 803C E1 { pop hl
214 803D F1 { pop af
215 803E F5 { push af
215 803F E5 { push hl
215 8040 C5 { push bc
215 8041 2A 76 80 { ld hl,(rIX)
215 8044 01 7F 00 { ld bc,.ixt
215 8047 09 { add hl,bc
215 8048 66 { ld h,(hl)
215 8049 C1 { pop bc
215 804A E1 { pop hl
215 804B F1 { pop af
216 804C F5 { push af
216 804D E5 { push hl
216 804E C5 { push bc
216 804F 2A 78 80 { ld hl,(rIY)
216 8052 01 7F 00 { ld bc,.iyt
216 8055 09 { add hl,bc
216 8056 6E { ld l,(hl)
216 8057 C1 { pop bc
216 8058 E1 { pop hl
216 8059 F1 { pop af
217 805A F5 { push af
217 805B E5 { push hl
217 805C C5 { push bc
217 805D 2A 76 80 { ld hl,(rIX)
217 8060 01 80 FF { ld bc,.ixt
217 8063 09 { add hl,bc
217 8064 46 { ld b,(hl)
217 8065 C1 { pop bc
217 8066 E1 { pop hl
217 8067 F1 { pop af
218 8068 F5 { push af
218 8069 E5 { push hl
218 806A C5 { push bc
218 806B 2A 78 80 { ld hl,(rIY)
218 806E 01 80 FF { ld bc,.iyt
218 8071 09 { add hl,bc
218 8072 56 { ld d,(hl)
218 8073 C1 { pop bc
218 8074 E1 { pop hl
218 8075 F1 { pop af
221 8076 00 00 {rIX DEFW 0
222 8078 00 00 {rIY DEFW 0
# file closed: macro.asm


Ну тут я, кстати, соглашусь, что не мешало бы настроечку иметь, чтобы метки заменялись на реальные значения, а не тупо копировался код из исходника.

krt17
04.07.2025, 20:35
211 8010 4E { ld c,(hl)
211 8011 C1 { pop bc
ПХАХХАХХАХАХА
не пей столько кафе

cafedead
04.07.2025, 20:38
ПХАХХАХХАХАХА
не пей столько кафе
:v2_dizzy_facepalm: Ну сорян)) И про старуху бывает порнуха) Ну пускай там как-нибудь разрулит эту ситуацию... А мне надо... Идти... )

- - - Добавлено - - -


торопыга прям как я в 15 лет, завидую
Не-не-не... У меня железобетонная уважительная причина. Он же сказал, что все порешал, ему ниче не надо. Вот я и выбросил так, как оно есть.)

Но если серьезно, суть моего спича как раз в том и заключается, что ни я, ни кто-либо еще и не должны окунаться в его проблематику с головой, чтобы ответить на простой вопрос, как ему имена регистров использовать. Не так ли?

- - - Добавлено - - -

Upd: Ну ладно... Не оставлять же так, а то совесть замучает, спать спокойно не смогу... Вот вам ваши этажи -)


macro ldrx dst,src
.iyt equ src-$280 & $FFFF
.ixt equ src-$180 & $FFFF

if dst != A
push af
endif

push hl
push bc

if src & $200
ld hl,(rIY)
ld bc,.iyt
elseif src & $100
ld hl,(rIX)
ld bc,.ixt
endif

if dst == A
push af
add hl,bc
pop af
else
add hl,bc
endif

pop bc

if dst == H
ld a,(hl)
pop hl
ld h,a
elseif dst == L
ld a,(hl)
pop hl
ld l,a
else
ld dst,(hl)
pop hl
endif

if dst != A
pop af
endif
endm


Вроде все разрулил, теперь все корректно:



# file opened: macro.asm
1 0000 OPT listoff
# listing file suspended...
7 8000 OPT reset
8 8000 OPT listmc
241 8000 41 { ld B,C
241 8001 78 { ld a,b
241 8002 78 { LD A,B
242 8003 63 { ld H,E
242 8004 78 { ld a,b
242 8005 78 { LD A,B
244 8006 F5 { push af ;LDRX B|C|D|E|H|L
244 8007 E5 { push hl
244 8008 C5 { push bc
244 8009 2A 78 80 { ld hl,(rIX) ;IX
244 800C 01 01 00 { ld bc,.ixt
244 800F 09 { add hl,bc
244 8010 C1 { pop bc
244 8011 4E { ld c,(hl)
244 8012 E1 { pop hl
244 8013 F1 { pop af
245 8014 E5 { push hl ;LDRX A
245 8015 C5 { push bc
245 8016 2A 7A 80 { ld hl,(rIY) ;IY
245 8019 01 01 00 { ld bc,.iyt
245 801C F5 { push af ;A
245 801D 09 { add hl,bc
245 801E F1 { pop af
245 801F C1 { pop bc
245 8020 7E { ld a,(hl)
245 8021 E1 { pop hl
246 8022 F5 { push af ;LDRX B|C|D|E|H|L
246 8023 E5 { push hl
246 8024 C5 { push bc
246 8025 2A 78 80 { ld hl,(rIX) ;IX
246 8028 01 FF FF { ld bc,.ixt
246 802B 09 { add hl,bc
246 802C C1 { pop bc
246 802D 56 { ld d,(hl)
246 802E E1 { pop hl
246 802F F1 { pop af
247 8030 F5 { push af ;LDRX B|C|D|E|H|L
247 8031 E5 { push hl
247 8032 C5 { push bc
247 8033 2A 7A 80 { ld hl,(rIY) ;IY
247 8036 01 FF FF { ld bc,.iyt
247 8039 09 { add hl,bc
247 803A C1 { pop bc
247 803B 5E { ld e,(hl)
247 803C E1 { pop hl
247 803D F1 { pop af
248 803E F5 { push af ;LDRX B|C|D|E|H|L
248 803F E5 { push hl
248 8040 C5 { push bc
248 8041 2A 78 80 { ld hl,(rIX) ;IX
248 8044 01 7F 00 { ld bc,.ixt
248 8047 09 { add hl,bc
248 8048 C1 { pop bc
248 8049 7E { ld a,(hl) ;H
248 804A E1 { pop hl
248 804B 67 { ld h,a
248 804C F1 { pop af
249 804D F5 { push af ;LDRX B|C|D|E|H|L
249 804E E5 { push hl
249 804F C5 { push bc
249 8050 2A 7A 80 { ld hl,(rIY) ;IY
249 8053 01 7F 00 { ld bc,.iyt
249 8056 09 { add hl,bc
249 8057 C1 { pop bc
249 8058 7E { ld a,(hl) ;L
249 8059 E1 { pop hl
249 805A 6F { ld l,a
249 805B F1 { pop af
250 805C F5 { push af ;LDRX B|C|D|E|H|L
250 805D E5 { push hl
250 805E C5 { push bc
250 805F 2A 78 80 { ld hl,(rIX) ;IX
250 8062 01 80 FF { ld bc,.ixt
250 8065 09 { add hl,bc
250 8066 C1 { pop bc
250 8067 46 { ld b,(hl)
250 8068 E1 { pop hl
250 8069 F1 { pop af
251 806A F5 { push af ;LDRX B|C|D|E|H|L
251 806B E5 { push hl
251 806C C5 { push bc
251 806D 2A 7A 80 { ld hl,(rIY) ;IY
251 8070 01 80 FF { ld bc,.iyt
251 8073 09 { add hl,bc
251 8074 C1 { pop bc
251 8075 56 { ld d,(hl)
251 8076 E1 { pop hl
251 8077 F1 { pop af
254 8078 00 00 {rIX DEFW 0
255 807A 00 00 {rIY DEFW 0
# listing file suspended...
# file closed: macro.asm


Upd: И да, можно написать еще более эффективный макрос, выигрывающий еще какие-то копейки для некоторых вариантов, но зачем мне это публиковать, если все всё уже порешали, а я просто всех раздражаю?! Поэтому пошел я на фиг, ищите сами... -)

Ped7g
08.07.2025, 13:01
Ped7g , а можете реализовать поддержку особых макросов с неопределённым количеством параметров, чтоб от ни одного до много-много ? ;)

...


varargs for macro are mentioned few times in various issues, like: https://github.com/z00m128/sjasmplus/issues/150

You are welcome to check current proposal/notes and add any new suggestion/syntax detail so it's not lost when finally somebody will want to work on it.
(I'm currently working very little at hobby stuff, too busy with newborn, work and running/fitness, ZX dev time shrink to few hours per month right now)

- - - Updated - - -


...
Вот так работает, но в итоге имеем лишних 7 байт на константы. Причём в конец кода их перекинуть нельзя, так как они должны находится перед первым вызовом макроса.

There's no good native support for what you are trying to do.
You can maybe hack it by doing DEFINE with numeric values, ie. DEFINE A 1 : DEFINE REG_A 1 : IF reg1 == REG_A ... but it will probably bite you badly in other ways because the defines like "A" are too short and generic. Other possible hack is to use lua script to check for value of macro argument reg1, that's less intrusive, but cumbersome.

Mind you, sjasmplus has the i8080 support the other-way, ie. you can write i8080 code in Zilog syntax and the assembler will warn you when you use Z80-specific instruction by accident. sjasmplus has also support for "M" register as `(hl)` alias.

You can add to source code:


; use --i8080 switch to 8080 instructions only
OPT --syntax=M ; enable "M" register as (hl) alias
LD A,B ; MOV A,B
LD A,M ; MOV A,M
LDIR ; error "Unrecognized instruction: LDIR"

and assemble it with --i8080 switch to get results like this:


$ sjasmplus --i8080 --msg=lstlab -
; use --i8080 switch to 8080 instructions only
OPT --syntax=M ; enable "M" register as (hl) alias
LD A,B ; MOV A,B
LD A,M ; MOV A,M
LDIR ; error "Unrecognized instruction: LDIR"
# file opened: <stdin>
1 0000 ; switch to 8080 instructions only
2 0000 OPT --syntax=M
3 0000 78 LD A,B ; MOV A,B
4 0001 7E LD A,M ; MOV A,M
<stdin>(5): error: Unrecognized instruction: LDIR
5 0002 LDIR ; error "Unrecognized instruction: LDIR"
6 0002
# file closed: <stdin>


But to do it the other way, ie. to support original i8080 syntax, you should probably look for other assembler, sjasmplus is not a good choice for that.

0xDEAD
03.11.2025, 14:28
Есть константы
iBlue = %00000001
pYellow = %00110000

Есть макрос, который вызывается как


MacroName arg1, arg2

Если вызывать его как


MacroName (iBlue + pYellow), arg2

в код передается значение #2A (%00101010)
Если вызывать его как


MacroName iBlue + pYellow, arg2

в код передается ожидаемое (по крайней мере, для меня), значение #31 (%00110001).
Почему?

SAM style
03.11.2025, 17:04
Почему?
Дай угадаю, в макросе есть ld a, param. Который в первом случае будет ld a, (iBlue + pYellow), а во втором ld a, iBlue + pYellow... Что есмь разные команды

0xDEAD
03.11.2025, 23:36
О как...

Ped7g
04.11.2025, 00:48
yes, macro arguments are text-substituted before the macro line is parsed, evaluated and assembled.

So `ld a, arg1` will become `ld a, (iBlue + iYellow)` and that will access memory from address #31 (ROM).

To avoid the similar issues like C macros have, you want to use macro arguments more like:
`ld a, +(arg1)` -> `ld a, +((iBlue + iYellow))` -> `ld a,#31`

Having parentheses around arguments in expressions helps to avoid stuff like:


macro m1 arg1, arg2
ld a, arg1 * arg2
ld a, +(arg1) * (arg2)
endm
m1 4<<2, 1+2
; ->
; ld a, 4<<2*1+2 -> ld a, #40 ; 4 << (2*1+2) -> 4 << 4 -> 64
; ld a, +(4<<2)*(1+2) -> ld a, #30 ; 16 * 3 -> 48


BTW when in doubt, try listing (--lst --lstlab). You may see the macro lines somewhat substituted there, quick example trying to mimic your question:


macro m1 arg1, arg2
ld a, arg1
ld a, +(arg1)
endm
iBlue = %00000001
pYellow = %00110000
m1 (iBlue + pYellow), 123
; btw "=" are not constants but "variables" or DEFL, so you can still modify them later, constants are EQU
iBlue = %00000010 ; check next result
m1 (iBlue + pYellow), 123


does produce this when using stdin as input and --msg=lst option:


$ sjasmplus --msg=lst -
macro m1 arg1, arg2
ld a, arg1
ld a, +(arg1)
endm
iBlue = %00000001
pYellow = %00110000
m1 (iBlue + pYellow), 123
; btw "=" are not constants but "variables" or DEFL, so you can still modify them later, constants are EQU
iBlue = %00000010 ; check next result
m1 (iBlue + pYellow), 123
# file opened: <stdin>
1 0000 macro m1 arg1, arg2
2 0000 ~ ld a, arg1
3 0000 ~ ld a, +(arg1)
4 0000 endm
5 0000 iBlue = %00000001
6 0000 pYellow = %00110000
7 0000 m1 (iBlue + pYellow), 123
7 0000 3A 31 00 > ld a, (iBlue + pYellow)
7 0003 3E 31 > ld a, +((iBlue + pYellow))
8 0005 ; btw "=" are not constants but "variables" or DEFL, so you can still modify them later, constants are EQU
9 0005 iBlue = %00000010 ; check next result
10 0005 m1 (iBlue + pYellow), 123
10 0005 3A 32 00 > ld a, (iBlue + pYellow)
10 0008 3E 32 > ld a, +((iBlue + pYellow))
11 000A
# file closed: <stdin>

So by reading the listing file you have chance to spot unexpected bytes/instructions or evaluation results.