Просмотр полной версии : SjASMPlus от z00m
NEO SPECTRUMAN
06.04.2020, 00:20
`my_other_aaa_label: db 1234` will become `my_other_"abcd"_label: db 1234` and the assembling will fail.
про это нужно написать в инструкции
это крайне большие грабли
к примеру у меня все метки и переменные вида some_code_blah_blah_blah
пока заменил название define на СИЛЬНО унинальное чтоб работало
про это нужно написать в инструкции
это крайне большие грабли
Yes, indeed. It was one of the first thing I reported to the sjasmplus guys before I started contributing to the project:
https://github.com/z00m128/sjasmplus/issues/37
Then I "fixed" it, actually in the wrong way, it has kinda funny history...
There was some patch done by some guy with Russian-like nickname, to allow sub-word substitutions (I think around v1.04 or v1.07).
Then somebody added test to verify the sub-word substitutions are working (doing like `call aaa_bbb` in the test)
Then I asked about missing docs, because the code did contain some "this can't be correct" parts, and nobody could give me more info, so I fixed it.
About month later I finally understood the original idea of the patch author, it was meant to replace inside-word only strings starting with underscore (i.e. your "define aaa ...." would be safe in his original idea). But he didn't document it, didn't add test, and he had bug in the code, so sometimes it did replace even "aaa" inside strings like "call aaa_bbb").
And actually the old existing test was testing precisely the bug-state, which made it even harder to find+understand the original idea.
Unfortunately I fixed it in the completely opposite way, "aaa" now does substitute inside-words reliably (not only when bug is triggered), and to prevent inside substitution you have to add underscore.
lesson to take:
- send patches only with idea description, and tests showing correct behaviour
- or send patches without bugs
I think I will rewrite this part completely for v2.x, but I don't want to mess with it for v1.x ... consider using `define _aaa "abc"` instead of `define aaa ...`?
Собственно вот:
https://s.micp.ru/77Zi3.jpg
Строки 636,637. Не компиилит :(
Код из диз-асма IDA
справа тот же код в Unreal-дебагере. с минусом - компилит, как ни странно
в дебагере Спекулятора так:
ld (ix-$ffffff80), a
ld (iy-$ffffff80), a
так то жЕ не компилит. Это нормально?
NEO SPECTRUMAN
26.04.2020, 16:34
Код из диз-асма IDA
ну это кривизна иды
она чота не детектит отрицательные смещения... :v2_dizzy_facepalm:
- - - Добавлено - - -
Ped7g, а можно в emptytrd добавить установку названия диска?
указывается в байтах 245-252 8 сектора
сейчас при создании там пустота...
типа так
EMPTYTRD "test.trd","FCKNDSCK"
- - - Добавлено - - -
так же напрягает вот это сообщение
warning: zx.trdimage_add_file: invalid file extension, TRDOS
extensions are B, C, D and #.:
расширение у файла может быть любым
так же сильно не хватает функции добавление в TRD hobeta файлов
Строки 636,637. Не компиилит
Код из диз-асма IDA
Z80: "(ix+imm8)" and similar process the constant as `int8_t` (signed 8bit value), i.e. the valid range is (ix-128) to (ix+127).
(ix+128) is invalid instruction.
I guess the IDA does think the constant is `uint8_t` and disassembles like that -> needs fix on the IDA side.
`ld (ix-$ffffff80), a` ... well... I can imagine how this happens (-128 in `int32_t` is encoded as $ff'ff'ff'80), but I really fail to see why assembler should support this, IMO it's disassembler bug too.
The Unreal displays it correctly (in Zilog syntax), and sjasmplus does understand that too.
I.e. "vsjo normalno" as far as I am concerned, I don't see anything ill about this.
Ped7g, а можно в emptytrd добавить установку названия диска?
I will take a look, sounds good to me, and EMPTYTRD has currently only single argument, so I could extend it without big syntax change. But... see the following point...
расширение у файла может быть любым
так же сильно не хватает функции добавление в TRD hobeta файлов
I'm pretty sure I have seen some docs where those extensions were specified as valid ones (i.e. others are invalid).
But... the main issue is, that I'm totally unfamiliar with TRD/hobeta, and pretty much all disk systems for ZX (I have been using back in 199x era only TAP files and Didaktik D40 (D80), and I have seen Busy's MB-02 with BDOS). I have never seen TRD/beta/esxdos/... machines before I returned a bit to ZX world due to Next. And the Next itself has NextZXOS based on +3DOS ("+3e") with esxdos compatibility layer and I think all of this is somewhat divMMC inspired/partially compatible? I don't understand this either.
All of these systems are considerably complex (not a 10min read to become expert on them), plus all of them seem to be closed source, and technically not very impressive (compared to MB-02), so I'm learning about them only very slowly and reluctantly, mostly trying to avoid them as much as possible. And it doesn't help the best docs seems to be often in Russian language, slowing my progress further.
So, don't expect miracles from me - if you want TRD/hobeta support improved in sjasmplus, better provide really very detailed and precise info (like the info about disk name), ideally with some links to official system documentation, so I can double-check everything... or even better, prepare pull request with code changes and tests.
I'm always afraid to touch this part of sjasmplus, as I don't know how to test final result (like using the TRD image on real machine or emulator) and the code is not even well covered with automated tests.
So, if you give me simple and precise info, how to fix/improve something, or even write the code, I will try to help you. But outside of that these disk systems are not interesting for me.
NEO SPECTRUMAN
27.04.2020, 03:46
(ix+128) is invalid instruction.
ошибка ошибкой и ее нужно сообщать
но компилировать нужно при этом правильно $80...$FF
правда я не проверял как такое компилирует sjasm
- - - Добавлено - - -
I'm pretty sure I have seen some docs where those extensions were specified as valid ones (i.e. others are invalid).
это окаменевшие документы
злые русские используют и .J для jpg
и .H и .P и .S и .M
ну и я использую .S для SID-ов
вместо каких то документов вот скриншоты
https://jpegshare.net/images/a8/5c/a85c29b4a6fc678cc134f858f00794ef.png
а тут видно более активное использование расширений
https://jpegshare.net/images/4a/42/4a427888d65ab2851efda61b38ac6e1d.png
конечно их нельзя копировать средствами примитивного интерфейса tr-dos
но кому этот каменный век нужен?
когда можно так
https://jpegshare.net/images/07/ab/07ab729d0cdae5c303ec6bb6a5c19744.png
https://jpegshare.net/images/a1/76/a17686f9c11333e96a0d40932ffa72f1.png
правда я не проверял как такое компилирует sjasm
Main.asm(11): error: Offset out of range (+128)
11 6000 DD 77 80 ld (ix+128),a
Main.asm(12): error: Offset out of range (+255)
12 6003 DD 77 FF ld (ix+255),a
это окаменевшие документы
злые русские используют и .J для jpg
и .H и .P и .S и .M
If they are the only available documents, then it's maybe good time for somebody to do some grooming, and update some public docs. If the implementation is not open, at least docs should be kept up to date.
Of course I didn't hunt too hard for most-current correct docs, so maybe I just missed the correct place for them. Or maybe you are just using the TRD outside of its specs (that would sound a bit stupid if it would be like modern system, but as I guess the TRD world is petrified "as is", there's not much downside to exploit, except risking error message from sjasmplus which tends to go by docs instead of reality :P ).
I will take a look on the bad-extension message, if it's error, I will turn it down to warning and make it suppress-able by "; ok" comment then. I added it as issue #101 https://github.com/z00m128/sjasmplus/issues/101 ... when it's closed, it's done in source (and will be in next release).
NEO SPECTRUMAN
10.05.2020, 16:20
So to redirect the errors into log file use "sjasmplus file.asm 2> log.txt" (at least in linux/bash, not sure if this works in windows and in which shell, google how to capture STDERR in your shell, if the "2>" doesn't work).
но так не сохраняются сообщения от lua
и все таки при компиляции
постоянно нужна пауза для отладки
в lua тоже
крайне тяжело отлаживать генерацию таблиц
когда выводимые значения постоянно проскакивают
большая их часть потом теряется
в log это не выводиться
куча посторонних сообщений
нужна пауза во время компиляции
которую ставить прямо в коде
чтоб можно было в пошагов режиме проверять вот такое
https://jpegshare.net/images/51/81/518156957eb1f9414057e99a29ff7e62.png
- - - Добавлено - - -
в принципе полез
и изменил размер буфера для командной строки
но все равно пошаговый режим постоянно нужен
тк нужно ждать по 17 секунд пока закончиться компиляция
перед тем как лог можно будет начать смотреть
https://jpegshare.net/images/58/7a/587a6876d9560982e0f2843a04182048.png
но так не сохраняются сообщения от lua
? Hm, works for me?
LUA PASS3
io.stderr:write(string.format("write to stderr %d\n", 123))
ENDLUA
(obviously you must write to STDERR, if you are capturing STDERR)
But I still completely don't understand why you "debug" the tables by looking at assembler output, I find that really cumbersome and difficult to do, I would personally never do that...
I would just emit data file with the values (maybe having simple switch in code to emit either binary or ASCII data) and then use the hexa editor or diff to compare the data with expected results, after the assembling is done. How often do you need to debug table generator? I would expect to do it once correctly, and never look back, until some bug happens.
Also if you are interested into the stdout output for lua printouts, you can still capture the regular ">" stdout along with stderr "2>", just use different file, or `tee` command to copy it both to file and to output.
But I mostly think you should move your "debugging" from assembling time to checking the actual results.
About 19s compilation ... and checking logs.... but that looks like you are building whole disk image, why don't you split that task to two, building just player + tables, quickly, then adding hundreds of sid files using the output from previous step, if you want to make full-build.
Overall I don't know enough details about your projects to fully understand what you are doing, and if I understand you correctly, but I believe it should be possible to break your tasks a bit more and have better times...
The "invalid extension" warning will be suppress-able in next v1.15.0 with the "; ok" comment.
NEO SPECTRUMAN
10.05.2020, 17:38
But I still completely don't understand why you "debug" the tables by looking at assembler output, I find that really cumbersome and difficult to do, I would personally never do that...
а как делать по другому?
смотреть на результат нет смысла
так как видно только факт наличия ошибки
но не видно где и как она возникает
а так я вывожу в строку все переменные
и смотрю на каком этапе все идет не так как задумано
- - - Добавлено - - -
How often do you need to debug table generator?
я часто так отлаживаю таблицы
+ часто у меня таблицы с параметризацией
и могут меняться в зависимости от других настроек
я стараюсь рассчитывать все таблицы средствами sjasm
чтоб при необходимости их корректировать
не было необходимости пересчитывать их сторонними средствами
- - - Добавлено - - -
but that looks like you are building whole disk image, why don't you split that task to two, building just player + tables, quickly, then adding hundreds of sid files using the output from previous step, if you want to make full-build.
я делаю релиз в несколько шагов
но для отладки образ должен быть получен максимально быстро
поэтому я сразу добавляются все нужные файлы
выглядит так
я что то меняю
компилирую
и сразу смотрю как это работает
а не так
меняю
компилирую
открываю редактор трд
перекидываю файлы
и только потом смотрю
при этом забыв что я и для чего я менял до этого
конечно добавление файлов в trd можно автоматизировать
но у меня нет на примете такой программы
- - - Добавлено - - -
(obviously you must write to STDERR, if you are capturing STDERR)
а я вывожу простым print()
такое нельзя выводить в лог?
чтоб не расписывать длинное io.stderr:write
- - - Добавлено - - -
+ часто у меня таблицы с параметризацией
и могут меняться в зависимости от других настроек
например в начале исходника у меня часто такое
border = 254 ; Bits 5 and 3-0 hold border colour (output)
keyboard = 254 ; Main keyboard matrix (input)
lua allpass
ay_frq = 1750000 -- 1750000 pentagon
-- 1773450 128
zx_int_frq = 50
endlua
и часто в больших количествах
I'm not lua expert, so I have no idea if you can redirect print by default, but you can define lua function which will have shorter name and use that one instead of print. But you can still capture the regular stdout with ">" .. it's problem if you output both in lua and sjasmplus, then you have two logs and need to find between them.
But I'm not sure how to help with this, I don't want to redirect stdout of lua to stderr, I guess it would help you, but generally it's too specific and weird change.
About debugging tables... I don't know, I guess we would have to sit down together for a day or two, and go over your different projects in real life to see what I would try personally, maybe I just can't imagine what you are doing, or maybe I just have different approach which I personally find easier to do, while you would not like it (and maybe I have all kind of different tools around, which maybe you don't have at your system, etc...). But I guess a big part may be personal bias, what you like/dislike and what you find as simple/difficult, maybe we have different approach to asm programming (also it seems you are producing much larger projects than me lately, the sid player is great).
Anyway, I'm trying to help you and fix sjasmplus even more to cater for your needs, but it must make some sense to me from the general point of view. And I'm definitely not trying to make it harder for you, sorry if it happens, it's not intentional. Cheers.
NEO SPECTRUMAN
10.05.2020, 18:23
maybe we have different approach to asm programming
ну я придерживаюсь концепции
когда любой может взять мой исходник
и поменять в нем все что угодно
а не получить набор таблиц и данных с прибитыми адресами которые нельзя изменить
рассчитанными неизвестно чем и неизвестно где и как
хотя конечно тяжелые расчеты приходиться делать другими средствами
так же sjasm удобен тем,
что его можно ложить прям в исходник
и не нужно будет потом искать конкретную версию
под которой исходник правильно скомпилируется
- - - Добавлено - - -
вот например генератор таблиц я написал
и вынес параметром
lua allpass
filter_depth = 1
endlua
и меняя его в начале исходника
перестраиваются сразу все таблицы
https://jpegshare.net/images/6d/d4/6dd485b5d4451c6c9aaa2a9460b96c9e.gif
а теперь его этот параметр нужно подобрать brutal force-ом :)
конечно добавление файлов в trd можно автоматизировать
но у меня нет на примете такой программы
Раз ви savetrd не записывает в тот файл, который указал?? и не обязательно в пустой. ну накидай нужных файлов заранее, и компиль, по 17 секунд. Эх, мне бы столько, мои проЭкты в ISE по 8-10 мин собираюЦЦа :( И это еще быстро
NEO SPECTRUMAN
10.05.2020, 20:45
Раз ви savetrd не записывает в тот файл, который указал?? и не обязательно в пустой. ну накидай нужных файлов заранее,
ну надо же чтобы boot и программка были близко друг к другу
чтоб не дрыгать флоповодом на другой конец диска
ну и boot я добавляю тоже средствами sjasm-а
каждый раз создается новый trd
а не используется готовый :)
и бейсиковский загрузчик с кодом после rem тоже набран при помощи defb :)
или ты думал я буду из бейсика сохранять как в 90-е?
21 век на дворе
- - - Добавлено - - -
Эх, мне бы столько, мои проЭкты
ну это *****языки *****высокого *****уровня
продолжайте с ними трахаться сколько влезет
меня такое не устраивает :)
только асм
только хардкор
Ped7g, спрошу тут, все равно больше негде и не у кого :)))
Немного офф, но компилировано то в SJAsm-e /
https://s.micp.ru/2H2rH.jpg
Что не так???
Как это интерпретировать??
Красные квадраты - это я так понимаю ошибки??
Чего не хватает??
Полосы на бордюре высоко слишком. Это что, торможения не хватает медленной памяти??
Слишком быстро работает?
NEO SPECTRUMAN
11.05.2020, 00:03
the sid player is great)
ну а так
появлению sid плеера
очень поспособствовала ваша помощь
без allocate procedures
https://zx-pk.ru/threads/30314-sjasmplus-ot-z00m.html?p=1019616&viewfull=1#post1019616
что в конечном итоге превратилось в
https://zx-pk.ru/threads/30694-vyravnivanie-utrambovyvanie-i-vpikhivanie-koda-bystrye-tablitsy-perekhodov-i-sjasm.html
написание подобного
было бы сильно усложенно
а теперь оно у меня после каждого jp и ret :)
ch3_attack_end
ld a,(ch3_decay_h_frq)
;cp $00
and a
jp nz,ch3_attack_end_1
ld a,(ch3_sustain_1) ;
jp ch3_attack_end_2 ;
end_tampright_allocate_macro_pg01
;------------------------------------------------------------------------------
tampright_allocate_macro_pg01
;adsr_cnt ;
ch3_attack_end_1 ld a,$FF ;
ch3_attack_end_2 ld hl,$FFFF ;
ну и всякое многое другое я использую
defarray+ frq_decoder_calls sid_frq_2_ay_test ;_1_1 1___; test
defarray+ frq_decoder_calls sid_frq_2_ay_test ;_1_1 1__1; test
defarray+ frq_decoder_calls sid_frq_2_ay_test ;_1_1 1_1_; test
defarray+ frq_decoder_calls sid_frq_2_ay_test ;_1_1 1_11; test
defarray+ frq_decoder_calls sid_frq_2_ay_test ;_1_1 11__; test
defarray+ frq_decoder_calls sid_frq_2_ay_test ;_1_1 11_1; test
defarray+ frq_decoder_calls sid_frq_2_ay_test ;_1_1 111_; test
defarray+ frq_decoder_calls sid_frq_2_ay_test ;_1_1 1111; test
defarray+ frq_decoder_calls sid_frq_2_ay_2_4_duty ;_11_ ____; saw+pulse
defarray+ frq_decoder_calls sid_frq_2_ay_2_4_duty ;_11_ ___1; saw+pulse
defarray+ frq_decoder_calls sid_frq_2_ay_sync ;_11_ __1_; saw+pulse sync
defarray+ frq_decoder_calls sid_frq_2_ay_sync ;_11_ __11; saw+pulse sync
defarray+ frq_decoder_calls sid_frq_2_ay_2_4_duty ;_11_ _1__; saw+pulse no ring?
defarray+ frq_decoder_calls sid_frq_2_ay_2_4_duty ;_11_ _1_1; saw+pulse no ring?
defarray+ frq_decoder_calls sid_frq_2_ay_sync ;_11_ _11_; saw+pulse sync no ring?
defarray+ frq_decoder_calls sid_frq_2_ay_sync ;_11_ _111; saw+pulse sync no ring?
Что не так???
Как это интерпретировать??
Красные квадраты - это я так понимаю ошибки??
Чего не хватает??
Полосы на бордюре высоко слишком. Это что, торможения не хватает медленной памяти??
Слишком быстро работает?
Looks like you are running it in some emulator or weird machine.
1) If it's Next-like machine, that port $6B with core 3.1.1+ is zxnDMA, not Zilog => red squares in short transfers, because zxnDMA does transfer only "N" bytes, not "N+1" like Zilog DMA chip. The new Next cores now recognize port $0B for Zilog mode of DMA (press P to switch to 0B). (there is zxnDMA specific test called "!dma.sna" which expects the short "N" byte transfers.
2) the DMA transfers are almost instant on your machine, they should take 4T per byte, but they are like 6-7x faster. (or maybe you switched it to 28MHz? the test is designed for 3.5)
And make sure you have the latest version of test, if you are trying Next-like machine (it will use $0B by default even on Next).
Все же по тесту остался один вопрос.
https://github.com/MrKWatkins/ZXSpectrumNextTests/blob/develop/Tests/Misc/ZilogDMA/board_3.1.5_hdmi50Hz.jpg
Почему вверху бордюра цветные квадратики, а не красивая надпись??
Почему вверху бордюра цветные квадратики, а не красивая надпись??
Because the transfer init sequence is intentionally incorrect.
It should transfer bytes from "memory++" to fixed I/O port 254.
But for Zilog DMA chip you can load "fixed" type of address/port only into source port, so the DMA_LOAD command is executed when direction is set "from 254 to memory".
Then the direction is flipped back to correct "from memory to 254". (this is so far correct and required init sequence for original Zilog chip)
Then the transfer is enabled = error, second LOAD should be used to init the transfer fully correctly -> the damaged transfer is executed.
Now the effect of damage differs, zxnDMA in Next sends some noise to border (I think it's ROM bytes, but I'm not sure).
The original Zilog DMA chip will do almost correct transfer, except it starts with write phase and ends with read phase. So it sends to border first 0xFF (temporary buffer of chip is cleared by LOAD command), then it reads first byte from memory, etc... until it sends penultimate byte to border as last one, and reads the last byte from memory (not writing it anywhere). So the original Zilog chip produces the "DMA" letters in border, but the first byte is wrong and last byte is missing, and whole transfer is +1 byte late.
If you will add second LOAD after the direction change into the init sequence, both Zilog and zxnDMA will show the letters.
But the test is designed to exercise the invalid state, just for my curiosity, to see what different DMA chips do with the incorrect init.
(the zxnDMA doesn't require the opposite direction LOAD, when destination port is "fixed" type, zxnDMA will work with single LOAD, but it must be done with correct direction of transfer)
Спасибо за подробное объяснение. Теперь все стало на свои места.
Ну тогда еще один , заключительный вопрос по DMA. Видео работы известных DMA-demo c zxnDMA на NEXT есть в сети??
У меня первое демо с небольшими артефактами работает, и просмотр multitech-color-graphics лучше работает в режиме zxnDMA , чем в режиме zDMA.
https://s.micp.ru/t2Vo4.jpg
Что интересно - только на белых буквах. Это в режиме zDMA. Если переключаю в режим zxnDMA - то на тех же местах просто ничего нет. Или недоработка в DMA, или у меня :)
Видео работы известных DMA-demo c zxnDMA на NEXT есть в сети??
I don't know. I think I was trying it while testing my ZEsarUX emulator fork, and the dma1demo did work correctly only in zilog mode. In zxnDMA it did look initially almost correct, but it got damaged over time. I still haven't unbox my real Next, because I'm in the process of moving my flat, and also staying not at home for few weeks, so Next is still waiting for me.
У меня первое демо с небольшими артефактами работает, и просмотр multitech-color-graphics лучше работает в режиме zxnDMA , чем в режиме zDMA.
Well, the difference between zilog and zxnDMA mode on Next are very small, the major difference is the N+1 vs N length of transfer. On Next even Zilog DMA mode is lot more relaxed, allowing for shorter and simpler init than real Zilog chip.
So I'm a bit confused why zxnDMA would work better for legacy SW designed for Zilog DMA, maybe you are running them on the wrong display mode: zx48 vs zx128 vs zx128+3 (= native Next timing) vs Pentagon ("soviet" timing), all of these have slightly different timing of display signal, so if you pick timing which is incorrect for the demo, and incorrect DMA mode, maybe by accident they cancel out, and you get nice multicolors then...
I'm not familiar with the SW you are trying, so I don't know which HW you should select.
For me as SW author the important fact is, that both DMA modes work as described and I can choose which mode I want to use (in my recent "big picture scroll example" https://github.com/ped7g/ZXSpectrumNextMisc/tree/master/Layer2BigPic I'm using the zxnDMA mode, because I have already in B the length of transfer, which is always 256*n, so it's simpler for me to load the B directly into dma.length, then having to do "-1" for Zilog mode).
I still haven't unbox my real Next, because I'm in the process of moving my flat, and also staying not at home for few weeks, so Next is still waiting for me.
Для DMA не так много SW. И все оно собрано у Velesoft-a :
https://velesoft.speccy.cz/data-gear.htm
Интересует, как будет выглядеть на настоящем NEXT.
В эмуляторе у Цезаря действительно работает отвратительно.
Подождем. Жить еще долго.
NEO SPECTRUMAN
12.05.2020, 15:56
Ped7g, так же еще не хватает возможности дописывать один файл при помощи SAVETRD
по типу как это сейчас с defarray+
ну или нужна возможность
копировать блоки памяти
чтоб можно было собрать все нужное
и записать одним блоком
slot 0 : page 100
slot 1 : page 101
slot 2 : page 102
slot 3 : page 103
copy $0000,1,$0000,$200
copy $0000,3,$0200,$400 ;copy from $0000 page 3 to $0200 current memory map $400 bytes
copy $0000,3,$4000,$4000
SAVETRD "1.trd","2.C",$0000,$4600
Dart Alver
12.05.2020, 20:41
Ped7g, так же еще не хватает возможности дописывать один файл при помощи SAVETRD
Плюсую, это сильно бы облегчило жизнь для сборки монолоэдеров.
Хотя по мне проще было бы чтото типа:
ADDTOENDTRD "disk.trd", start_address, length_in_bytes
чтобы к последнему файлу в образе диска добавлялся новый блок (в конец файла начиная со следующего сектора диска) и соответственно увеличивался рамер файла в секторах (остальные параметры не менялись), а если количество добавленных секторов зашкалило за 255, или за размер диска вылезли, или в образе вообще файлов нет, то ругалась ошибками ))
А ещё было бы неплохо добавить в SAVETRD возможность записывать в каталоге TRD-образа изменённые стартовый адрес и длину в байтах, не трогая длину в секторах. Для коррекции BASIC - программ может быть полезно.
Например добавив ещё 2 необязательных параметра:
SAVETRD "disk.trd","boot.B", start_address , length {, catalogue_start_adress} {, catalogue_bytes_length}
Вообще последнее конечно можно и через LUA откорректировать, но всёже ;)
NEO SPECTRUMAN
12.05.2020, 20:44
Плюсую, это сильно бы облегчило жизнь для сборки монолоэдеров.
я для этого и прошу :)
я то гружу как monoloader
но файлы так и валяются друг за другом
I don't feel confident enough with TRD file format (which is mostly NOT covered by tests in current sjasmplus) for such big changes, so I'm not planning to touch this for v1.15.0, but maybe later in future.
I.e. if you want to accelerate this (still unlikely to hit 1.15.0, but maybe we can do it for 1.16.0), you are welcome to produce the patches, so I can review some particular implementation.
If you want to make it super friendly for me (sadly I'm lately doing 95% of sjasmplus contribution, but there *are* other contributors, so some of them may pick up your ideas and help you too, if you make it more visible, i.e. issue in english on github or pull requests with code), then please try to follow this order:
- add tests for current TRD (HOB belongs to this too?) code, so the code-coverage in tests is near 100% like it is with SAVETAP/SAVEBIN/... (if you will check the coverage reports, you will easily see which use-cases are covered by tests, and which one I keep ignoring as I don't care about those too much)
This is quite essential step to keep the quality of the future releases at "at least as good as previous version, or the change was intentional and documented". JFYI writing tests for directives like SAVE is not trivial, unfortunately it requires some understanding for how I designed the test runner and how I'm hacking it to check this kind of directives. You can learn it all from studying the current source + tests, but it's not beginner friendly, sorry (there was no time to write some nice docs or tutorial, plus nobody ever shown interested to write sjasmplus tests).
- add pull request for some reasonably small change with tests for the new behaviour included
It will be more difficult for me to ignore actual code provided (than to just remember that I have seen something on zx-pk forum, but pushing it for later in mind, because I have always something more important or more fun to do), so this would greatly increase the chance of getting the feature into mainline.
(also if you are already familiar with sjasmplus sources, build process, and testing, nobody can stop you for using your own fork with the proposed changes ahead of z00m's branch, actually reports from some experimental real-world usage will further help the cause, as you could then confirm the changes work well and files produced work on actual machine ... to avoid similar funny situations like the "mul" opcode for Z800 being in sjasmplus for a decade+ wrong, or the INCLUDETRD (or was it HOB?) with the "offset" argument being used wrongly ... probably also for decade+).
Meanwhile **I** really want to focus on v1.15.0, which for me means only to remove the alternative code for MSVS builds, to have binaries built by VS coming from the same source as GCC/CLANG builds, so I can enable the test-suite on windows builds fully, all the other changes are IMHO ready to be released and hopefully the release will be finished within week or two (I was hoping to release it already 2 months back, sigh :D )
edit: this is like frankly telling you, that I'm at this moment in time not interested to work on these requests. I'm not against them, just doesn't have enough priority for me (and I'm quite busy with other projects), so I don't want to keep you hanging here and waiting for next release hopefully. Rather telling you upfront I'm not working on these now. But they look good as possible future improvement. The overall QA work on TRD directives would be nice, as this area of sjasmplus is currently sub-par compared to the rest of the assembler.
Bedazzle
16.05.2020, 14:17
Интересует, как будет выглядеть на настоящем NEXT.
Что проверить нужно?
Что проверить нужно?
https://velesoft.speccy.cz/data-gear.htm
Желательно все, ну хотя бы как выглядят картинки в обоих режимах (тЕ что там на картинках, насколько точно и сколько артефактов), в первой демо у меня артефакты в буквах, думаю что тайминги не сходятся, в третьей демо есть ли "поддергивание" бегущего текста и насколько частое, в DNA Demo - там тоже картинка не вполне идеальная )
Думаю DNA вполне показательно было бы видео :) Чтобы судить о точности эмууляции.
Остальных хватит и пару картинок для оценки.
Bedazzle
16.05.2020, 20:06
https://velesoft.speccy.cz/data-gear.htm
Желательно все, ну хотя бы как выглядят картинки в обоих режимах (тЕ что там на картинках, насколько точно и сколько артефактов), в первой демо у меня артефакты в буквах, думаю что тайминги не сходятся, в третьей демо есть ли "поддергивание" бегущего текста и насколько частое, в DNA Demo - там тоже картинка не вполне идеальная )
Думаю DNA вполне показательно было бы видео :) Чтобы судить о точности эмууляции.
Остальных хватит и пару картинок для оценки.
По картинкам как-то совсем хреново.
Ч/б разваливаются, показываются как статическая картинка спека без атрибутов.
Цветные - нормально отображаются, но как просто ч/б картинки.
Демки дёргаются. Пробовал разные режимы переключать, хз, что нужно в настройках поставить.
У некста есть в конфиге переключение DMA - Z80 или ZXN.
Далее при запуске тапки (пробовал 3.5/7/14/28 мгц) выскакивает выбор режимов
128K / USR0 / 48K / Pentagon / Next (+3 mode)
и когда стартует сама программа, выбор порта, на котором DMA
port 107 (Data-gear) или port 11 (MB02+)
- - - Добавлено - - -
на 107 порту
в ч/б демках стало показывать рандомные атрибуты,
в цветных тоже атрибуты появились, но это явно не мультиколоры, а обычные спековские экраны
Научите, что надо тыкать - я дма впервые запускаю.
в последнем разпоследнем релизе два режима DMA, на 107 порту - zxnDMA висит, и на 11 порту - как бы прежний z80 DMA. По идее демки должны работать в обеих вариантах, с некоторой разницей - но работать. Так что пробовать по два раза запускать и выбирать порты по очереди. желательно в режиме zx128.
возможно DMA отключено глобально?
Если релиз ядра не самый крайний - тогда вЫбери в конфиге DMA Z80 и пробуй еще раз по обеим портам.
Yes, since core 3.1.5 (Next OS "distro" 1.3.2) the port $0B is only ZilogDMA mode, port $6B is only zxnDMA mode. The previously used config bit in NextReg 06 is now used for beeper configuration, not related to DMA any more.
The SW from Velesoft page should NOT work well with $6B (zxnDMA), there's not much point to even try that, the $0B port has better chance.
But there is one more issue with SW from Velesoft page. There's lot of CZ/SK community production, done with the UA880d DMA chip (East Germany clone of Zilog DMA chip), which does *NOT* react to the "WR3.enable" bit.
And by some unfortunate coincidence, lot of the early DMA SW does set this bit to "1" half-way into the init, there was even article in Czech paper magazine describing how to program DMA on ZX, which did contain the same bug writing to WR3.enable early.
But the original Zilog DMA and some other clones (*and* the FPGA implementation in ZX Next) do react to the WR3.enable, and will start the transfer (as if DMA_ENABLE $87 command was sent to WR6).
This issue was identified and known by the cz/sk community few years later after the first versions, and later versions of MB-02 disk system BIOS were patched to work correctly even with original Zilog chips, also some demos were patched, but I'm not sure if somebody did review all the SW on Velesoft page and mark which contain the WR3 bug and which is compatible with Zilog chip.
If you have SW which does work with original Zilog chip, and does use port $0B, and you did select the correct video timing of your Next (of course you need VGA mode, not HDMI) to simulate zx48/128/+3 machine, then I would expect most of the old demos to work correctly, the 48/128/+3 timings of Next are quite accurate AFAIK (demos doing multicolors like Shock work usually pixel perfect, there were few pieces like muco1k from Busy which were not completely correct on Next the last time I have seen it (back in early 2018), but it was not completely clear if muco1k is correct on real HW, as Busy did use emulator to tune the timing ... I'm not sure if somebody managed to do proper test of it, real HW vs Next HW and after all the timing fixes were applied to Next)
Actually, looking at (incomplete) changelog of Next core ( https://gitlab.com/SpectrumNext/ZX_Spectrum_Next_FPGA/-/blob/master/cores/zxnext/changelog.md ) there was small fix to timing even in core3.1.0, so I guess nobody did run side by side HW vs Next for these demos which are so critical on the timing accuracy.
So any precise input from people who can do the tests is welcome, but make sure you fully understand the complexity of Next setup and that you are testing in the correct mode and correct thing (with the extra bonus of some intros like muco1k containing machine-detection code, so it's better to avoid that and load the correct version explicitly, as the detection code may fail to pick the correct model too.
In ideal world it should be on Next (running with VGA mode at 50Hz) as easy as to select your video timing (48 / 128,+2 / +2A,+2B,+3 / Pentagon) and ROMs (this is what the TAP and SNA loader does, with TAP loader displaying menu to select the machine configuration by user, SNA reads snapshot type and modifies the HW config automatically based on the type), and just run the SW and all should work.
If it does not work correctly, and you can identify what is failing, please report it to the Next team, it's important piece of information. But it's also very tricky to find the true reason where is the problem, as there are many details contributing to the final result, as you can see from this post (it was supposed to be short 2-3 sentence post, and it's whole page instead, argh).
- - - Updated - - -
So, I downloaded the dma-demo-level_1.zip from velesoft page, added debug printf into ZESERUse (fork of ZEsarUX) to print every byte going to DMA port and this is the init sequence:
($0B) = $C3 RESET
($0B) = $C7 RESET port A
($0B) = $CB RESET port B
($0B) = $7D WR0 + port A adr + length, A->B, transfer
($0B) = $21 A.adr = 0x4021
($0B) = $40
($0B) = $BE length = 0x07BE
($0B) = $07
($0B) = $14 WR1, A++, memoryA
($0B) = $10 WR2, B++, memoryB
($0B) = $C0 WR3, enable=1
DMA Transfer with mode 0 (single byte) requested - ignored
($0B) = $AD
($0B) = $20
($0B) = $40
($0B) = $82
($0B) = $CF
($0B) = $B3
($0B) = $87
....
I added comments from beginning to the WR3 write, which wrongly enables the transfer (prematurely, before the DMA_LOAD command). So the demo works only on the UA880d cloned chip, which ignores this WR3 write.
If you are bored, you can try to disassemble the demo and find the init sequences and turn $C0 into $80 in each of them (writes all-zeroes to WR3, which is actually important on real Zilog DMA, because it somehow affects timing without the write to WR3 - it's still a bit mystery why/how, as the other bits are related to interrupts/etc which is not used on MB-02 + Zilog DMA, but by testing with real HW we did find that writing explicit zero to WR3 somehow makes the machine timings more stable).
But at this moment, Next with it's Zilog DMA emulation, can't run the SW which has the WR3.enable bug correctly, there's no such option on Next.
https://github.com/z00m128/sjasmplus/releases/tag/v1.15.0
v1.15.0 changelog:
* added `BPLIST` and `SETBP` to export breakpoints info from asm for Unreal and ZEsarUX emulators
* added ZX-like devices with 2/4/8 MiB of virtual memory
* the fake-sysvars/state of ZXSPECTRUM48/128/... devices reworked, moving stack down by default
* behaviour of `--fullpath` option unified across all platforms and compilers
* `DEFARRAY` has new operator `[#]` to retrieve current size of array.
* `MMU` has new optional third argument to set also address (like `ORG`)
* use of forward reference in `IF`/`IFN` emits only warning, and can be suppressed
* internal Lua updated to 5.1.5 (last official 5.1 version)
* STDIN can be read multiple times (per each "-" argument)
* new macro/lua examples: `sj_sysvars.i.asm`, `section.asm`, `lua_sin_table.asm`, `union_like_structures.asm`
* RAM limit exceeded warning/error reworked to report with more sense, fixed bug with missing labels
* `SAVETRD` warning about invalid extension can be suppressed by "; ok"
* `EMPTYTRD` takes as second argument disc label
* added `--outprefix` option to prefix any output-directive filename (issue #102)
Enjoy. :)
NEO SPECTRUMAN
19.05.2020, 22:15
* internal Lua updated to 5.1.5 (last official 5.1 version)
ВНЕЗАПНО adp полностью пережил переход на новую версию
готовый trd полностью совпал
название диска тоже работает
https://jpegshare.net/images/23/1b/231b0718a19fcf121258558819e4ad6b.png
Ped7g, снова требуется немного разъяснить:v2_confu:
Три ошибки:
https://s.micp.ru/PrXuN.jpg
и еще одна ошибка:
https://s.micp.ru/3mapm.jpg
я так понимаю next-команды процессора в основном работают??
Тогда что может быть не так с этими четырьмя??
Это не на NEXT, но процессор он него.
Или "и так сойдет..." ?
снова требуется немного разъяснить
If you click the letter of the particular test, it will show some debug values (usually the values which failed the test in the code).
With that info, check the test source code to figure out what precisely failed.
These four seems to be all I/O related, so it may be also the test does use some unlucky choice for port number to test against.
I don't remember the implementation details for these tests, it's long time since I wrote it.
If you can provide me with the debug info values of failed test, I may try to quickly look at the source what it means.
But yes, your Z80N seems to be mostly working correctly, if only these four are failing.
ну да, в этих кодах ошибок уж точно я ничего не пойму
https://s.micp.ru/By0K5.jpg
https://s.micp.ru/DPP2N.jpg
https://s.micp.ru/jc11J.jpg
https://s.micp.ru/6Yfem.jpg
https://s.micp.ru/sZq4l.jpg
Ну и регистры на всякий случай картинку.
Я думаю, что не хватает какого то жизненно важного регистра. Все то они мне не нужны.
Вот только с каким номером именно надо мне регистр))
в этих кодах ошибок уж точно я ничего не пойму
nextreg *r, *n:
It does test four NextRegister by writing/reading the value: LAYER2_XOFFSET_NR_16, VIDEO_INTERUPT_VALUE_NR_23, PALETTE_INDEX_NR_40, SPRITE_TRANSPARENCY_I_NR_4B
(it's enough just to store and then return the same value for the test, it's not testing if the next register actual functionality is implemented)
And your machine does also modify value written to I/O port 243B (value TRANSPARENCY_FALLBACK_COL_NR_4A is written there) - it should be not modified, "nextreg" instructions are independent from what is done directly to the $243B and $253B I/O ports.
So to simplify when the test did stop:
out ($243B),$4A
nextreg $16,$01
assert $4A == in ($243B) ; fails (is different)
assert $01 == nextreg_16 ; fails (is $00)
I guess the nextreg *r, A is the same issue.
-------------
OUTINB:
I/O port $243B is used for the test
out ($243B),$00
assert $00 == in ($243B) ; fails, reads $FF
-------------
JP (C):
Again depends on correct functionality of $243B / $253B, jumps to wrong address if port returns $FF instead of $00.
NEO SPECTRUMAN
18.06.2020, 02:19
Ped7g, а можно сделать такую команду
на подобии define но с безусловной заменой
и чтоб можно было менять даже пробелы
а то мощности define не хватает
например можно будет делать так
if aa = 0
replace "AAA BBB", "10 LD a"
replace "VERSION", "0001"
endif
if aa = 1
replace "AAA BBB", "10 LD (HL)"
replace "label", "lb"
replace "VERSION", "0002"
endif
if aa = 2
replace "labelAAA", "label"
replace "AAA BBB", "10 LD (HL)"
replace "VERSION", "0003"
endif
labelAAA BBB,B
SAVESNA "000-VERSION.sna", $8000
aa = 0
label10 LD a,B
SAVESNA "000-0001.sna", $8000
aa = 1
lb10 LD (HL),B
SAVESNA "000-0002.sna", $8000
aa = 2
label BBB,B
SAVESNA "000-0003.sna", $8000
This doesn't fit well with current sjasmplus code-base ... I guess the least problematic way would be to add extra search+replace step before substitutions (DEFINE) are parsed, so it's possible, but it will slow down assembling of everything and it will be completely new code ( = new bugs ).
But I'm also not sure if this is good addition to assembler, I would personally probably use `sed` as first step ahead of assembling (to create temporary asm file), as the sed can do all these string replacements in much better way, including regex syntax to precisely target certain constructs (I did use `sed` while fixing one MSX project wanting to migrate from tniassembler to sjasmplus, to fix many small details about syntax of their sources, you can find the article on sjasmplus github wiki).
I would use something like (Makefile):
.PHONY all
all : aa0.tap aa1.tap aa2.tap
aa0.tap : main.asm
sed -f sed_aa0_rules.txt main.asm > aa0.asm
sjasmplus -Daa=0 aa0.asm
aa1.tap : main.asm
sed -f sed_aa1_rules.txt main.asm > aa1.asm
sjasmplus -Daa=1 aa1.asm
aa2.tap : main.asm
sed -f sed_aa2_rules.txt main.asm > aa2.asm
sjasmplus -Daa=2 aa2.asm
... building all variants with one `make` command.
... or something like that... there are also options to use `m4`, `awk` or even `cpp` (C pre-processor, not C++), depending on what kind of syntax/features you are looking for, all of these can be applied to asm sources easily.
Whatever hack-ish solution I will add to sjasmplus, it will be nowhere near the power of these specialized tools (unless I re-implement whole tool inside sjasmplus), so I think I will rather leave these non-trivial cases to the specialized tools (also with 30+ year history, so almost everyone knows them and most of their bugs were already found + fixed... contrary to sjasmplus).
NEO SPECTRUMAN
19.06.2020, 00:54
I would use something like (Makefile):
все таки больше бы хотелось именно find&replace
средствами самого ассемблера
The SAVETRD refactoring and "&" for sector-append of files is now at master branch in github.
If you are using SAVETRD in your projects, testing them now would be nice to catch any regressions before the v1.15.1 will be released.
(for example how to use the "&" check "tests/misc/trd/savetrd4.asm" or "docs/documentation.xml" (html is not updated yet)).
(of course you must build sjasmplus from the latest sources to have the new SAVETRD implementation)
- - - Updated - - -
все таки больше бы хотелось именно find&replace
средствами самого ассемблера
I don't understand what's the point of either adding lame sub-par limited feature in days/weeks of work (and that's still too much time), or trying to compete with excellent SW which already exists (sed/m4/awk/... all of that available everywhere, with years of expertise and know-how baked into them) - that would eat probably months/years of my time, completely wasted on something what I can run in 10 seconds.
So far I have seen no factual justification for such demand (and I would be very surprised if you would come with something meaningful, because I can't even imagine anything reasonable).
NEO SPECTRUMAN
05.07.2020, 11:24
а сейчас можно как то сделать?
что то на подобии
if aaa = 1,2,3
nop
endif
чтобы не писать одинаковое
if aaa = 1
nop
endif
if aaa = 2
nop
endif
if aaa = 3
nop
endif
http://z00m128.github.io/sjasmplus/documentation.html#s_expressions
`if 1 <= aaa && aaa <= 3`
or
`if 1 == aaa || 2 == aaa || 3 == aaa`
NEO SPECTRUMAN
05.07.2020, 12:15
`if 1 <= aaa && aaa <= 3`
or
`if 1 == aaa || 2 == aaa || 3 == aaa`
нужно написать пример и пояснение в инструкции
я все время думал что это то же самое что и
& x&y bitwise and
and x and y bitwise and
| x|y bitwise or
or x or y bitwise or
нужно написать пример и пояснение в инструкции
hmm... it's right there in the operators list:
& x&y bitwise and
and x and y bitwise and
^ x^y bitwise xor
xor x xor y bitwise xor
| x|y bitwise or
or x or y bitwise or
&& x&&y logical and
|| x||y logical or
"bitwise" vs "logical" ... maybe it's confusing if you are not sure what that means.
Where would you put such example (= "where would you look for it")?
Would it help in the Conditional assembly section (http://z00m128.github.io/sjasmplus/documentation.html#s_conditional_assembly) under the IF/IFN as example? (I see there are examples of IFDEF and IFUSED, but no example for IF).
Any idea for example, what should I show there? (I guess the logical and/or is obvious candidate, but if you think there's something else tricky... I think the logical NOT is another interesting one as `!0` results in value 0xFF if I remember the implementation correctly, so I may double-check in the source and add some non-trivial example showing this.
Thank you for this kind of feedback, as I'm sort of "blind" toward the documentation, knowing the implementation quite well, so any help to point out which area can be improved and how is important.
NEO SPECTRUMAN
05.07.2020, 14:20
Would it help in the Conditional assembly section under the IF/IFN as example?
именно там оно и нужно
думаю достаточно будет указать в качестве примера
if aaa = 0 || aaa = 1
;some code
endif
и что это равносильно
if aaa = 0
;some code
endif
if aaa = 1
;some code
endif
и уже будет понятно
что можно использовать такие конструкции
Мне бы тоже каких-нибудь инструкций для конструкций:v2_dizzy_botan:
Посмотрел все примеры для работы с TRD. Не очень то и понял.
В примере для автостарта такая конструкция:
SAVETRD "autostart_warning.trd","ok.B",$C001,$100,$1234
$1234 - это номер строки Бейсика? или специальная такая уникальная метка??
Ладно, предположим это номер строки.
пишу простую конструкцию -
SAVETRD "my_test.trd","boot.B",$C000,$100
ожидаемо вижу файл размером в 256 байт. Логично??
пишу СЛОЖНУЮ конструкцию -
SAVETRD "my_test.trd","boot.B",$C000,$100,$1
По логике все то же самое, но автозапуск с первой строки??
Угадайте размер файла boot.B в контейнере. Мне лично хотелось бы прежний :(
Посмотрел все примеры для работы с TRD.
well.. I don't know anything about TRD except what I learned from the sjasmplus source (I have never seen TRD in real life or used such file), so I can easily answer you what the sjasmplus is doing, but whether it is correct thing to do, that's question for actual TRD experts.
The autostart argument is line number in BASIC, like `SAVE "boot" LINE 10` -> `SAVETRD "my.trd","boot.B",23755,256,10` (if your BASIC is 256 bytes long).
BTW, I find creating BASIC in sjasmplus very cumbersome and tedious, I would rather suggest to use working ZX or emulator to create disc with your BASIC loader, then turn this disc into TRD image file like "loader.trd", and have build script of project copying such empty disc with "boot.B" from "loader.trd" to "my.trd" before each assembling, so the SAVETRD of sjasmplus will add files after that. But if you don't mind produce the BASIC code in the sjasmplus, or you have hex-dump of it, then it makes sense to build it from ASM source from scratch too.
About size of file inside the TRD. The TRD operates with 256 bytes long sectors, so 256 bytes long "boot.B" will fit precisely into single sector without auto-start line! The auto-start line adds another four bytes of content after the BASIC program in the form of: { $80, $AA, low autostart, high autostart }, so the length of file goes from 256 to 260 and it will occupy two sectors on the disc.
Ну я как бы тоже не специалист по TRD, так, мимо проходил, но вот все равно бы сказал, что автозапуск Бейсик файлов как то странно сделан :)
Может на примере легче объяснить.
В аттаче два файла,
my_Dizzy_test_128.trd, который я собирал руками и бейсик загрузчик 256 байт, и работает правильно, автозапускается, и второй файл, My_test2.zip , который собран средствами исключительно SJAsm-a,
но тот же самый загрузчик уже два сектора занимает. Но как бы тоже все работает правильно.
Мне конечно ни разу не принципиально +1 сектор, но "как-то неаккуратненько, доктор" (с)
Второй файл собран вот так:
End:
savebin "my_test.bin",Start, End - Start
emptytrd "my_test.trd"
ORG $C000, 7 ; "page 7"
incbin "TRD/boot.B"
SAVETRD "my_test.trd","boot.B",$C000,$100,$1
ORG $C000, 7 ; "page 7"
incbin "my_test.bin"
SAVETRD "my_test.trd","my_test.C",$C000,End - Start
ORG $C000, 7 ; "page 7"
incbin "TRD/pent.scr"
SAVETRD "my_test.trd","pent.C",$C000,$1B00
ORG $C000, 7 ; "page 7"
incbin "TRD/dizzy00.pak"
SAVETRD "my_test.trd","dizzy00.C",$C000,$4000
ORG $C000, 7 ; "page 7"
incbin "TRD/dizzy01.pak"
SAVETRD "my_test.trd","dizzy01.C",$C000,$4000
ORG $C000, 7 ; "page 7"
incbin "TRD/dizzy02.pak"
SAVETRD "my_test.trd","dizzy02.C",$C000,$4000
ORG $C000, 7 ; "page 7"
incbin "TRD/dizzy03.pak"
SAVETRD "my_test.trd","dizzy03.C",$C000,$4000
ORG $C000, 7 ; "page 7"
incbin "TRD/dizzy04.pak"
SAVETRD "my_test.trd","dizzy04.C",$C000,$4000
ORG $C000, 7 ; "page 7"
incbin "TRD/dizzy05.pak"
SAVETRD "my_test.trd","dizzy05.C",$C000,$4000
ORG $C000, 7 ; "page 7"
incbin "TRD/press.scr"
SAVETRD "my_test.trd","press.C",$C000,$1B00
end
То есть я сперва компилирую свой код, сохраняю его, формирую пустой диск ,и начинаю
его заполнять строго по очереди, согласно купленным билетам.
И да, как видите в моей сборке расширения имен файлов трехбуквенные, Ваш компилятор только одну букву разрешает :)
Ну и если бы можно файлы сначала не incbin-ить, а потом записывать, а сразу добавлять в образ TRD, было бы вообще замечТательно :))
Dart Alver
07.07.2020, 00:05
И да, как видите в моей сборке расширения имен файлов трехбуквенные, Ваш компилятор только одну букву разрешает
В мастер ветке гита уже 3 буквы можно. И можно пробовать в моноблок куски памяти собирать с префиксом '&' :
SAVETRD "имя образа TRD",&"имя файла в образе",[адрес блока памяти], [длина блока памяти в байтах] ; Прибавляет блок памяти к указанному файлу, начиная со следующего за ним сектора. Изменяет в идентификаторе файла только размер в секторах. Ругается ошибкой если получилось больше 255 ))
Второй файл собран вот так:
Я х.з. как создаются автозапуски, но в первом случае длина 250 байт, во втором 256. А если будете 250 указывать для второго ? :v2_conf2:
А вообще есть от них смысл ? boot запустится хоть с авто хоть без, а прочие все всё равно через RUN заходят. Имеет смысл если строка запуска не первая, или с программой данные переменных хранятся, но подобный изврат явно не ассемблерное дело на мой взгляд.
В мастер ветке гита уже 3 буквы можно.
из гит-а мне скиллов не хватит собрать. Тем более автор вроде вообще под линь делает.
мастер ветке гита уже 3 буквы можно. И можно пробовать в моноблок куски памяти собирать с префиксом '&'
Мне бы в образ сразу файлы при сборке добавлять.
Я х.з. как создаются автозапуски, но в первом случае длина 250 байт, во втором 256. А если будете 250 указывать для второго ?
А вообще есть от них смысл ?
вот и я хз аналогично. Пробовал бут на -4 делать, да, тогда один сектор, но бут не работает :)
Бут не мой, как он работает тоже х.з., но грузит два сектора за ним и запускает. В моей поделке вполне устраивает.
Ручками через RUN можно, но зачем просто, если можно сложно?))
Dart Alver
07.07.2020, 01:35
Мне бы в образ сразу файлы при сборке добавлять.
Ну эт как бы не к ассемблеру, это вам тырдец или трдтул с батником в руки. ))
NEO SPECTRUMAN
07.07.2020, 02:26
Ну эт как бы не к ассемблеру,
а почему это не к ассемблеру?
зачем нужно разводить 100500 утилит и плясать с бубном
когда все может делать и один ассемблер?
при том более гибко, чем твои тырдец батники и прочие свистелки
по привыкали понимаешь к сборщикам, компоновщикам, хрензнаетчтоновщикам
а потом хрен скомпилируешь чужой сорец
тк у аффтара там 100500 утилит хлама гофна в процессе использовано
при том только автору известно каких версий...
- - - Добавлено - - -
И да, как видите в моей сборке расширения имен файлов трехбуквенные, Ваш компилятор только одну букву разрешает
а tr-dos может больше чем одну букву?
правда я где то читал про 3-х буквенные расширения но подтверждения так и не видел
другой вопрос если может то куда?
под все отведено 9 байт
если хотим три буквы
то под имя останется 5 байт...
от сюда напрашивается вопрос зачем?
хотя в принципе начало расширения можно указать установкой 7-го бита
и тогда будет целых 6 букв под имя :v2_dizzy_facepalm:
ну или опять же лезть в не используемые сектора
в которых одни хранят папки
другие еще неизвестно что...
и не стандартизовано ничего...
BTW, I find creating BASIC in sjasmplus very cumbersome and tedious, I would rather suggest to use working ZX or emulator to create disc with your BASIC loader
да еще лишний раз запускать эмулятор
проще набрать ручками
tr_dos_var_current_track_sector = $5CF4
emptytrd "disc.trd","TITLE"
org $00FC
boot_start
incbin "boot\small_mx.bin"
boot_end
savetrd "disc.trd","boot.B",$FC,$FC
org $0000
basic_start
defb $00,00 ;
defw end_basic_line_0 - basic_line_0
basic_line_0
defb $EA ;REM
di
xor a
out (border),a
ld sp,$C000
; ld hl,$C9F1 ;pop af : ret !!!!!!!!!!!!!!
; ld ($5CC2),hl ;
ld a,aaa_page_4_port
ld bc,$7FFD
out (c),a
ld bc,$2005 ;$20 sect 05 mode
ld de,(tr_dos_var_current_track_sector)
ld hl,$C000
di
im 1
call $3D13
di
ld a,bbb_page_4_port
ld bc,$7FFD
out (c),a
ld bc,$1005 ;$10 sect 05 mode
ld de,(tr_dos_var_current_track_sector)
ld hl,xxx
di
im 1
call $3D13
di
ld a,ccc_page_4_port
ld bc,$7FFD
out (c),a
ld bc,$4005 ;$40 sect 05 mode
ld de,(tr_dos_var_current_track_sector)
ld hl,$C000
di
im 1
call $3D13
di
ld a,ddd_page_4_port
ld bc,$7FFD
out (c),a
ld bc,$2505 ;$25 sect 05 mode
ld de,(tr_dos_var_current_track_sector)
ld hl,$DB00
di
im 1
call $3D13
di
jp start
defb $0D
end_basic_line_0
defb $00,10
defw end_basic_line_10 - basic_line_10
basic_line_10
defb $FD,$B0 ;CLEAR VAL
defb $22,"24575",$22
defb $3A ; :
defb $F9,$C0 ;RANDOMIZE USR
defb $28 ;(
defb "5" ;5
defb $0E,$00,$00,$05,$00,$00
defb $2B ;+
defb "256" ;256
defb $0E,$00,$00,$00,$01,$00
defb $2A ;*
defb $BE,$B0 ;PEEK VAL
defb $22,"23636",$22 ;"23636"
defb $2B ;+
defb $BE,$B0 ;PEEK VAL
defb $22,"23635",$22 ;"23635"
defb $29 ;)
defb $0D
end_basic_line_10
defb $80 ;autorun
defb $AA,10,0
basic_end
savetrd "disc.trd","vjdfvn.B",$0,basic_end-basic_start
slot 3
page aaa
savetrd "disc.trd","vjdfvn_1.C",$C000,$2000
slot 3
page bbb
savetrd "disc.trd","vjdfvn_2.C",$D000,$1000
slot 3
page ccc
savetrd "disc.trd","vjdfvn_3.C",$C000,$4000
slot 3
page ddd
savetrd "disc.trd","vjdfvn_4.C",$DB00,$2500
Dart Alver
07.07.2020, 08:00
Трдос больше 3-х букв не может, но кого это останавливает. Вы никогда спековскими утилитами не пользовались? Zasm, BGE, Real Commander и т. п. Исплльзуются байты стартового адреса для файлов где это не существенно.
NEO SPECTRUMAN
07.07.2020, 09:01
Исплльзуются байты стартового адреса для файлов где это не существенно.
в принципе логично
нужно будет такое поддерживать
Real Commander и т. п
ну когда я токое видел
я думал, что тупо вместо одно буквенного расширения подставляется 3-х
а так я бы лучше отдал эти 2 байта на 9-10 букву имени...
Ну и если бы можно файлы сначала не incbin-ить, а потом записывать, а сразу добавлять в образ TRD, было бы вообще замечТательно
why? I don't see much point... the way how you incbin+savetrd them looks OK to me, I don't see what direct support for files would improve on it. (if you are bothered by adding "org $c000, 7" every time, create a macro for it:
;SAVETRD <filename_of_trd_image>,<filename_in_trdos>,<address>,<length>[,<autostart_BASIC_line>]
SAVETRDFILE MACRO hostname?, trdname?, fname?
ORG 0
INCBIN hostname?
SAVETRD trdname?, fname?, 0, $
ENDM
;... then after your code
; (when you can destroy the memory content, or in separate ASM file used to build the TRD from final bas/bin/pak/scr files)
; the BAS autoline needs manual SAVETRD, as macros can't have variable amount of arguments
SAVETRDFILE "TRD/dizzy01.pak", "my_test.trd", "dizzy01.C"
SAVETRDFILE "TRD/dizzy05.pak", "my_test.trd", "dizzy05.C"
; I didn't test if this code works, just wrote it from head as example... if you want to use it, and it fails, let me know
There is one issue with your assembler. You do `SAVEBIN "my_test.bin"` and then in the same ASM you do `INCBIN "my_test.bin"`
This works only when the file my_test.bin already exists before you start assembling (with correct length, but content can be wrong), and generally this is not completely correct approach. So if you delete my_test.bin and try to assemble your code, it will fail.
You can build the final "bin" file on disk first, then you should have do this TRD-create.asm separately as next step (if you do it as Makefile rules, the make will rebuild only bin files that need refresh because their dependencies did change)
Or you can reorganize your code .. to first empty the trd, include the basic loader and other files which should be ahead of your bin, then do the source of the bin file, then instead of savebin you can do savetrd directly, without the "my_test.bin" file. Then add remaining files to the TRD to finalize it.
- - - Updated - - -
из гит-а мне скиллов не хватит собрать. Тем более автор вроде вообще под линь делает.
sorry, but that's just full of "I'm lazy" shit.
If you use git already, it's all about "git clone https://github.com/z00m128/sjasmplus.git" or if you already have repository on disk then `git pull master` to have the latest sources on disk (and also full set of tests, which often works as examples).
The build on windows is not as trivial (*), as you need either GNU-make (MSYS2, mingw or maybe even WSL on win10) or CMake working to build the project, and some C++ compiler (gcc/clang/MSCC - any of them in reasonably recent version supporting C++14). If you have Visual Studio and MSCC, then CMake will generate project files for it, and you can build sjasmplus yourself.
(*) that's not my fault, that people are masochists and use the most painful and obsolete OS which is making trivial tasks difficult... I don't feel sorry for this kind of pain, I find it just stupid.
NEO SPECTRUMAN
07.07.2020, 09:17
that's not my fault, that people are masochists and use the most painful and obsolete O
I find it just stupid.
это как бы форум про ретро компьютеры
и выглядит крайне странно то
как некоторые "не любят" старые ОС (почему то таких не мало)
лично я продолжаю принципиально использовать winXP
а все начиная с vista считаю не пригодным к использованию
зачем нужно разводить 100500 утилит и плясать с бубном
While I feel similar way like you when too much is too much, and I often use sjasmplus for things which it is not supposed to do (like file content processor to modify bytes of files), the point of separate small tools is, that each tool specializes on its own task, so it's easier to review + bugfix + improve the small tool.
Just ask yourself, do you want to read sjasmplus source and add search+replace feature? Or do you rather want to write your own preprocessor for your sources which will prepare them for sjasmplus? (or use the already existing one like sed/cpp/...).
How many of you have seen sjasmplus sources and understand how it works? :D ... and sjasmplus isn't bloated in my opinion, it's still very focused Z80 assembler, but I don't think it needs to supply also disk partition formatter, custom OS, IDE and video player.... ;) :D
(of course adding some small features really related to Z80 projects makes sense... I'm often picking your ideas and slowly adding them when they "ripe" in me, but I usually don't agree at beginning at all, and some ideas don't pass even after some time with me... I'm maybe too negative, sorry for that ... than again, nothing can stop you from patching your own sjasmplus version, if you really believe I am wrong :) )
NEO SPECTRUMAN
07.07.2020, 09:23
than again, nothing can stop you from patching your own sjasmplus version, if you really believe I am wrong
сначала нужно научиться ее компилировать :)
я тоже хочу свой 6502\x86\chip8 etc компилятор на основе sjasm
потому что только sjasm пригоден к использованию
все остальные ассемблеры сильно примитивные
и они не имеют того функционала который мне нужен
а tr-dos может больше чем одну букву?
правда я где то читал про 3-х буквенные расширения но подтверждения так и не видел
As far as I understand it (and how sjasmplus supports them), the 3-letter extension is total hack just leaking the one letter extension into the "file start address" field at offset 9 ... I don't think it does use any bit-7 mark, it's just the tools using the TRD use the other two bytes to display three letter extension.
This is the level of SW quality I don't want to deal with, so I just added the code to sjasmplus and I'm running away from anything TRD related... :)
NEO SPECTRUMAN
07.07.2020, 09:27
This is the level of SW quality I don't want to deal with, so I just added the code to sjasmplus and I'm running away
что поделать когда trdos, мягко говоря, не идеален... :)
что поделать когда trdos, мягко говоря, не идеален...
well.. replace it with something better? I would suggest to fork and fix it, but it's not open IIRC, the license is prohibitive... which brings me back to my lamenting about people using the most painful options available, causing harm to themselves and still even touting it as best/only option. Situations like this learned me to pick up my SW carefully and pay attention to licenses and source availability, and to value this strongly even over some neat features. Those help in short-term, but in long-term the closed stuff is just pain in ass, I definitely replace it whenever possible with more open options, even if I have to somewhat fix them (looking at you sjasmplus, costing me year+ of my life, instead of writing some ZXNext games ... sigh)
- - - Updated - - -
В аттаче два файла,
my_Dizzy_test_128.trd, который я собирал руками и бейсик загрузчик 256 байт, и работает правильно, автозапускается, и второй файл, My_test2.zip , который собран средствами исключительно SJAsm-a,
Ok, now back to those two TRD files... the first disk contains the "80 AA 01 00" autostart bytes after the 250th byte of BASIC.
So changing your:
ORG $C000, 7 ; "page 7"
incbin "TRD/boot.B"
SAVETRD "my_test.trd","boot.B",$C000,$100,$1
to
ORG $C000, 7 ; "page 7"
incbin "TRD/boot.B"
SAVETRD "my_test.trd","boot.B",$C000,250,$1
*should* work... ... I'm going to try myself and edit this post if I fail... but I don't see any reason why it would not work.
EDIT:
so your original trd (with three letter extensions and autostart) on my disk is "orig.trd" (I renamed it to keep track which is which), and your sjasmplus produced is "sjasmplus.trd" ... I can assemble the two disc together (with current git master) with this code:
DEVICE ZXSPECTRUM1024
EMPTYTRD "ped.trd"
ORG 0 : INCTRD "orig.trd", "boot.B"
SAVETRD "ped.trd", "boot.B", 0, 250, 1
ORG 0 : INCTRD "sjasmplus.trd", "my_test.C"
SAVETRD "ped.trd", "my_test.bin", 0, $ ; ok
ORG 0 : INCTRD "sjasmplus.trd", "pent.C"
SAVETRD "ped.trd", "pent.scr", 0, $ ; ok
ORG 0 : INCTRD "sjasmplus.trd", "dizzy00.C"
SAVETRD "ped.trd", "dizzy00.pak", 0, $ ; ok
ORG 0 : INCTRD "sjasmplus.trd", "dizzy01.C"
SAVETRD "ped.trd", "dizzy_0.pak", 0, $ ; ok
ORG 0 : INCTRD "sjasmplus.trd", "dizzy02.C"
SAVETRD "ped.trd", "dizzy_1.pak", 0, $ ; ok
ORG 0 : INCTRD "sjasmplus.trd", "dizzy03.C"
SAVETRD "ped.trd", "dizzy_2.pak", 0, $ ; ok
ORG 0 : INCTRD "sjasmplus.trd", "dizzy04.C"
SAVETRD "ped.trd", "dizzy_3.pak", 0, $ ; ok
ORG 0 : INCTRD "sjasmplus.trd", "dizzy05.C"
SAVETRD "ped.trd", "dizzy04.pak", 0, $ ; ok
ORG 0 : INCTRD "sjasmplus.trd", "press.C"
SAVETRD "ped.trd", "press.scr", 0, $ ; ok
This is the result:
73034
Please try if it works... it is different in four bytes, the disc label in original has extra two spaces (sjasmplus keeps it only 8 chars long, not 10), and the two bytes in boot.B sector after the auto-start mark are also "00 00" from assembler, but your original disc has "35 36" there ... should be just garbage, not affecting anything, as far as I know.
BTW, why I do use INCTRD over both trd files to create this example? Because INCTRD in sjasmplus does not support 3-letter extensions, so I can't easily include the original files...
:D :D :D ... irony..
Ok, that's maybe one more thing to fix before v1.15.1 release...
NEO SPECTRUMAN
07.07.2020, 11:34
well.. replace it with something better?
это звучит как
"выкинуть zx spectrum 128 toast rack
и купить вместо ibm pc with core i9"
+tr dos прошит в ПЗУ
и не каждый его вообще может как либо обновить
на реальном железе
приходиться использовать то что есть
менять что либо уже поздно
некоторые вообще продолжают упорно пытаться писать только под 48к
несмотря ни на что...
...а результат как правило плохой...
- - - Добавлено - - -
теперь я тоже поддерживаю 3-х буквенные расширения :v2_dizzy_indy:
https://jpegshare.net/images/57/6b/576b03b20eaf54275b8f7e47c9f9fd75.png
- - - Добавлено - - -
I would use something like (Makefile):
.PHONY all
all : aa0.tap aa1.tap aa2.tap
aa0.tap : main.asm
sed -f sed_aa0_rules.txt main.asm > aa0.asm
sjasmplus -Daa=0 aa0.asm
aa1.tap : main.asm
sed -f sed_aa1_rules.txt main.asm > aa1.asm
sjasmplus -Daa=1 aa1.asm
aa2.tap : main.asm
sed -f sed_aa2_rules.txt main.asm > aa2.asm
sjasmplus -Daa=2 aa2.asm
... building all variants with one `make` command.
у меня 54 версии программы
для этого нужно будет 54 rules.txt :v2_dizzy_facepalm:
нужен препроцессор который сам будет запускать 54 раза sjasm
по одному правилу
+ не которые варианты не всегда собираются (тк может не хватать памяти)
и нужно рассматривать и вникать в сообщения
а как внешний препроцессор заменит что либо во всех условно подключаемых include-ах ?
никак...
And INCTRD refactored too, now it supports the unofficial 3-letter extensions just like SAVETRD
I guess today (+-5 days) the v1.15.1 will be released, depends how z00m has time to build the binaries and verify the packages.
(but if no more problems appear, what is current last commit in git will become v1.15.1)
Please try if it works... i
Да, ваш пример работает верно, как задумывал аффтор :) Это же чисто для проверки, если по нажатию клавиш 1-7 на экране рисуются различные картинки из Диззи - значит файлы в образе расположены в правильном порядке. Это я учусь распихивать файлы по различным банкам памяти :v2_dizzy_indy:
Dart Alver
07.07.2020, 22:52
у меня 54 версии программы
для этого нужно будет 54 rules.txt
нужен препроцессор который сам будет запускать 54 раза sjasm
по одному правилу
Чтото средствами sjasm, что-то скриптами и внешними программами.
+ не которые варианты не всегда собираются (тк может не хватать памяти)
и нужно рассматривать и вникать в сообщения
Ну можно например сохранять логи в отдельных файлах или попытаться отслеживать "Pass 3 complete" и "Errors: 0,".
а как внешний препроцессор заменит что либо во всех условно подключаемых include-ах ?
никак...
Как запрограммируешь так и заменит.
NEO SPECTRUMAN
07.07.2020, 23:25
Как запрограммируешь так и заменит.
надо будет при программировать пол sjasm-а...
https://github.com/z00m128/sjasmplus/releases/tag/v1.15.1
- mostly TRD related changes
NEO SPECTRUMAN
08.07.2020, 13:47
новая версия выдает 100500 предупреждений на adp
adp.asm(417): warning: When lua script emits machine code bytes, use "ALLPASS" m
odifier
https://jpegshare.net/images/b3/87/b3877a89ca9a1583f69bb4655552cc4a.png
- - - Добавлено - - -
можно подробней про то
когда выдается такое предупреждение?
вариант делать allpass по моему не приемлемый
по моему я эксперементальным путем подбирал номера проходов чтоб все работало
чисто на вид полученный код работает
я уже совершенно не помню как это все работает :v2_dizzy_vodka:
и почему
;FAST TAB macro pg00
;по окончанию PASS2 уже установлен новый org!
macro fasttab_allocate_macro_pg00 _fasttab_alloc_page_for_table_pg00?, _fasttab_alloc_table_haddr_pg00?, _fasttab_alloc_procedure_number_pg00?
@__fasttab_allocate_page_for_table_pg00 = _fasttab_alloc_page_for_table_pg00?
@__fasttab_allocate_table_haddr_pg00 = _fasttab_alloc_table_haddr_pg00?
@__fasttab_allocate_procedure_number_pg00 = _fasttab_alloc_procedure_number_pg00?
@__fasttab_allocate_macro_current_addr_pg00 = $ ;бекап адреса
;display "fasttab_allocate_macro_current_addr_pg00 ",@__fasttab_allocate_macro_current_addr_pg00
;чтение состояния слотов
org $0000
@__fasttab_allocate_macro_current_slot0_pg00 = $$
;display "fasttab_allocate_macro_current_slot0_pg00 ",@__fasttab_allocate_macro_current_slot0_pg00
org $4000
@__fasttab_allocate_macro_current_slot1_pg00 = $$
;display "fasttab_allocate_macro_current_slot1_pg00 ",@__fasttab_allocate_macro_current_slot1_pg00
org $8000
@__fasttab_allocate_macro_current_slot2_pg00 = $$
;display "fasttab_allocate_macro_current_slot2_pg00 ",@__fasttab_allocate_macro_current_slot2_pg00
org $C000
@__fasttab_allocate_macro_current_slot3_pg00 = $$
;display "fasttab_allocate_macro_current_slot3_pg00 ",@__fasttab_allocate_macro_current_slot3_pg00
;
; ;востановление адреса
org @__fasttab_allocate_macro_current_addr_pg00
; display "current addr check ",$
lua pass1
lua_fasttab_allocate_procedure_start_addr_pg00[(_c("__fasttab_allocate_table_haddr_pg00"))][(_c("__fasttab_allocate_procedure_number_pg00"))] = _c("$")
endlua
lua allpass
lua_function_fasttab_allocate_pg00((_c("__fasttab_allocate_table_haddr_pg00")),(_c("__fasttab_allocate_procedure_number_pg00")))
endlua
lua pass2 ;copy
if lua_fasttab_allocator_page_finded_pg00 == 1 then
_pc("slot 0")
_pc("page @__fasttab_allocate_page_for_table_pg00 ")
_pc("slot 1")
_pc("page @__fasttab_allocate_page_for_table_pg00 ")
_pc("slot 2")
_pc("page @__fasttab_allocate_page_for_table_pg00 ")
_pc("slot 3")
_pc("page @__fasttab_allocate_page_for_table_pg00 ")
_pc(string.format("org $%04x", _c("__fasttab_allocate_table_haddr_pg00 * 256") + (_c("__fasttab_allocate_procedure_number_pg00"))))
_pc(string.format("defb $%02x", lua_fasttab_allocator_new_h_org_pg00))
_pc("slot 0")
_pc("page @__fasttab_allocate_macro_current_slot0_pg00")
_pc("slot 1")
_pc("page @__fasttab_allocate_macro_current_slot1_pg00")
_pc("slot 2")
_pc("page @__fasttab_allocate_macro_current_slot2_pg00")
_pc("slot 3")
_pc("page @__fasttab_allocate_macro_current_slot3_pg00")
_pc(string.format("org $%04x", lua_fasttab_allocator_new_h_org_pg00*256 + (_c("__fasttab_allocate_procedure_number_pg00"))))
end
endlua
lua pass3 ;
if lua_fasttab_allocator_page_finded_pg00 == 1 then
_pc("slot 0")
_pc("page @__fasttab_allocate_page_for_table_pg00 ")
_pc("slot 1")
_pc("page @__fasttab_allocate_page_for_table_pg00 ")
_pc("slot 2")
_pc("page @__fasttab_allocate_page_for_table_pg00 ")
_pc("slot 3")
_pc("page @__fasttab_allocate_page_for_table_pg00 ")
_pc(string.format("org $%04x", _c("__fasttab_allocate_table_haddr_pg00 * 256") + (_c("__fasttab_allocate_procedure_number_pg00"))))
_pc(string.format("defb $%02x", lua_fasttab_allocator_new_h_org_pg00))
_pc("slot 0")
_pc("page @__fasttab_allocate_macro_current_slot0_pg00")
_pc("slot 1")
_pc("page @__fasttab_allocate_macro_current_slot1_pg00")
_pc("slot 2")
_pc("page @__fasttab_allocate_macro_current_slot2_pg00")
_pc("slot 3")
_pc("page @__fasttab_allocate_macro_current_slot3_pg00")
_pc(string.format("org $%04x", lua_fasttab_allocator_new_h_org_pg00*256 + (_c("__fasttab_allocate_procedure_number_pg00"))))
end
endlua
endm
в принципе если это предупреждение представляет какую либо? ценность
и его можно будет убрать например так
lua pass1 ;ok
lua pass2 ;ok
lua pass3 ;ok
то можно будет заменить все авто заменой
чисто на вид полученный код работает
hmm... yeah, I guess you are very special case, when the warning is actually wrong, and your precise pass1/allpass is used as designed and correctly.
(usually missing "allpass" with machine code emitted is just simple bug, but your code is lot more complicated case).
I was trying to add "suppress warning" mechanics on the "endlua" area, but I failed there miserably (not so easy), so that's why the warning can't be suppressed in v1.15.1.
I will explore your idea of suppressing it at the beginning `lua` line, that may be possible.
meanwhile, if you have this construct in separate module, consider to switch off warnings globally by `--msg=err` level, producing only errors, or to use v1.15.0 for the moment. Sorry for the inconvenience, but I didn't think about such complex case, while the warning did help me to catch many common cases, where just add "allpass" is solution.
NEO SPECTRUMAN
08.07.2020, 16:10
meanwhile, if you have this construct in separate module, consider to switch off warnings globally by `--msg=err` level, producing only errors,
ну глобально я оно отключить не могу
так как у меня выводятся и мои важные предупреждения средствами lua (по крайней мере я так думаю : )
да и у меня тонны ошибок в коде...
так что я пока побуду на 1.15.0
пока не добавится ;ok
- - - Добавлено - - -
так же мне недавно попадалось
https://jpegshare.net/images/f6/4b/f64b184afad7c342ee6318b023af8aaf.png
на нескольких вот таких таблицах на 256 значений
pulse_frq2 = {}
pulse_frq2[0] = ((0.50001545147716300 * pulse_fundamental_mlt) + (0.54171988752370500 * pulse_harmonic_mlt))
pulse_frq2[1] = ((0.49965567733372600 * pulse_fundamental_mlt) + (0.51692156470823500 * pulse_harmonic_mlt))
pulse_frq2[2] = ((0.49929590319028900 * pulse_fundamental_mlt) + (0.51590447856727700 * pulse_harmonic_mlt))
....
правда все решилось
добавлением endlua lua allpass посредине
так же мне недавно попадалось
yes, the total buffer for lua text script to be executed is about 32kiB. I was refactoring this just for v1.15.1 to make it constant in the source, so if you are building sjasmplus from source, you should easily find the new constant and raise it (and disable the allpass warning), but I think you use only the binaries.
I'm not sure if, and by how much I should raise the script length limit, as I have little idea what limits are on the lua side (on sjasmplus side it's all about heap memory, so I can probably allocate also 10 or 100MB without issue on modern PC). Also the buffer is fixed size, allocating for every script in full length, but maybe I can check C++ `std::string` performance characteristics to see if it does deal with `append` effectively, not putting any fixed limit on the usage at all, leaving that to dynamic string allocator. Or maybe I can just use `std::vector` for this too.
There's lot of sjasmplus source which is not using basic C++ idioms and doing things manually like in C, but I never had time to rewrite some parts just to make them more C++, as I always have to hunt some bug or add feature, and also it took time to have enough test coverage to make such source rewrite reasonably safe (without test coverage the risk of breaking old stuff is too high). So maybe one day... :D ... in sjasmplus v2.x :D ...
NEO SPECTRUMAN
09.07.2020, 02:45
but I think you use only the binaries.
так и есть
собирать sjasm-ы пока не научились :)
NEO SPECTRUMAN
10.07.2020, 17:26
`if 1 <= aaa && aaa <= 3`
or
`if 1 == aaa || 2 == aaa || 3 == aaa`
это конечно хорошо
но хотелось бы использовать вот так
if super_mega_very_long_and_big_stupid_variable_maybe _not = 0 || 1 || 5 || 7
nop
endif
или так
if super_mega_very_long_and_big_stupid_variable_maybe _not = (0 || 1 || 5 || 7)
nop
endif
а приходится делать так
что абсолютно не читаемо
if super_mega_very_long_and_big_stupid_variable_maybe _not = 0 || super_mega_very_long_and_big_stupid_variable_maybe _not = 1 || super_mega_very_long_and_big_stupid_variable_maybe _not = 5 || super_mega_very_long_and_big_stupid_variable_maybe _not = 7
nop
endif
еще могу предположить что кому нибудь может понадобиться такая конструкция
if var_a || var_b || aaa || bbb = 1
- - - Добавлено - - -
так же только что нашел такую ошибку
коментарий написанный впритык уничтожает endif
сходу и не ясно где ошибка и почему
выдает такое
error: Label not found: label2
error: [IF] No ENDIF
aaa = 3
jp label
if aaa = 3
nop
endif
label
jp label2
if aaa = 0
nop
endif;
label2
так же только что нашел такую ошибку
коментарий написанный впритык уничтожает endif
thanks, I will take a look on it, I guess it's about the cloned-parser-code used to parse some special cases like `endif/endlua/....` and similar, not using the main regular parser, so I guess every of those cloned ones is small original and not behaving the same way as regular, I will have to review them all.
но хотелось бы использовать вот так
The proposed syntax is already valid in sjasmplus, but has different meaning. The logical or is logical or.
But I get your idea, I will try to search for some nice common way how these things are done, the C++ doesn't have built-in operator for this kind of calculation IIRC, but some languages have them...
I think possible syntax may be like:
IF long_expression isfrom(0, 1, 5, 7)
ENDIF
I just can't recall what are the common names in other languages for such operator, and I need to check what kind of "array" enclosing is best fit for sjasmplus syntax, I think I can even go with`isfrom[0, 1, 5]` using brackets (I'm a bit worried about parentheses), the brackets can clash only with DEFARRAY, which should be quite safe usage, unless you decide to do `DEFARRAY isfrom` :D
BTW, if your "very long label" contains only very limited amout of numbers, like 20 to 29, you can in current/old sjasmplus use the DEFARRAY lookup-table trick:
very_long_label = 20
DEFARRAY nextIfCheck 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 ; true for: 20, 21, 25, 26
DUP 10
IF nextIfCheck[very_long_label - 20]
DISPLAY /D, very_long_label, " -> true"
ELSE
DISPLAY /D, very_long_label, " -> false"
ENDIF
very_long_label = very_long_label + 1
EDUP
Tried to search for something similar in other languages, but nothing precisely fits sjasmplus current syntax, so I'm leaning toward "in_array" operator:
; "in_array" operator:
; variant with literal array directly in the expression
; syntax: <expression> in_array [0, 1, 4, 5]
; result is -1 when <expression> evaluates to 0, 1, 4, 5
; result is 0 when <expression> evaluates to anything else
; variant with array defined by DEFARRAY
; syntax: <expression> in_array <defarray name>
; result is -1 when <expression> does match (evaluated!) value in DEFARRAY
; result is 0 when <expression> evaluates to anything else
; examples:
IF (very_long_label % 33) in_array [0, 1, 5, 7]
ENDIF
DEFARRAY freeday 6, 7
weekday = 2 ; tuesday
IF weekday in_array freeday
; not hit
ENDIF
weekday = 7 ; sunday
IF weekday in_array freeday
; *hit*
ENDIF
I need to review it a bit more to make sure this doesn't clash with current syntax in any edge-case, but so far it looks good to me and should be possible to implement it.
Any comments before I add it? :D
Bedazzle
11.07.2020, 22:51
I just can't recall what are the common names in other languages for such operator
For example, Python:
if variable in (1,2,3):
...
For example, Python
Thinking about using "in" instead of "in_array" (this one is from PHP), but "in" is already Z80 instruction, so it's adding to the visual ambiguity when reading the source (it's not a direct clash for assembler, as it's instruction vs operator, but I think I will prefer "in_array" any way, to make it distinct even at first look).
Bedazzle
12.07.2020, 13:43
Thinking about using "in" instead of "in_array" (this one is from PHP), but "in" is already Z80 instruction, so it's adding to the visual ambiguity when reading the source (it's not a direct clash for assembler, as it's instruction vs operator, but I think I will prefer "in_array" any way, to make it distinct even at first look).
if variable from (1,2,3,4,5)
?
https://github.com/z00m128/sjasmplus/releases/tag/v1.16.0
* predefined defines extended with new ones (like __BASE_FILE__ or __LINE__)
* relocation data generator (inspired by SymbOS executables)
* some bugfixes/improvements in parser, some warnings are suppressible now
NEO: now the new lua warning about bytes emitted without "allpass" should be suppressible (you can put the "; ok" comment either at the beginning of lua block, or at the end of it, whichever way you prefer, both lines will count).
NEO SPECTRUMAN
11.08.2020, 19:45
- mostly TRD related changes
SAVETRD "test.trd",&"myfile1.C",$9000,$734 ;- sector-append new data to "myfile1.C"
на 1.16.0
при добавлении увеличивает только количество секторов файла
но не размер файла !
в итоге файл размером 40К
отображается как 150 байт
+ у меня загрузчик из за этого затирает все подряд
так как на вход поступают неверные данные о размере
и он думая что грузит 150 байт
грузит все 40К вместо блока в 16К
переходит через FFFF-0000 и затирает системные переменные да и сам загрузчик...
можно просто записывать в +11,+12 заголовка файла
(+13)*256
при этом
- - - Добавлено - - -
это тоже бессмысленное предупреждение
которое только занимает место
warning: Accessing low memory address 0x0001, is it ok?: ld a,($0001)
так компилироваться может и ROM
и программа для +3
и программа не под spectrum вообще где ROM по другим адресам...
если оно и оставлять
то оно должно быть по умолчанию выключено глобально
Dart Alver
11.08.2020, 23:55
на 1.16.0
при добавлении увеличивает только количество секторов файла
но не размер файла !
Если вы о размере файла в байтах, то так и должно быть. Эта фича для добавления блоков данных в файл-контейнер а не для побайтового расширения файла.
Описание:
Adding ampersand character "&" ahead of file name will make sjasmplus to look for existing file with the requested name (last of them, any earlier duplicates are deleted). The new content is appended to the file (sector aligned append) and the catalog entry gets only number of sectors patched, up to 255 sectors at most. This is special mode for single-file big-loaders.
Добавление символа амперсанда " & " перед именем файла заставит sjasmplus искать существующий файл с запрошенным именем (Последний из них, все более ранние дубликаты удаляются). Новый контент добавляется к файлу (добавление выравнивается по секторам), и в каталог производится запись только исправленного количества секторов, максимум до 255 секторов. Это специальный режим для однофайловых больших загрузчиков.
То бишь монолоэдеров.
+ у меня загрузчик из за этого затирает все подряд
так как на вход поступают неверные данные о размере
и он думая что грузит 150 байт
грузит все 40К вместо блока в 16К
переходит через FFFF-0000 и затирает системные переменные да и сам загрузчик...
А вот у меня отлично всё грузит как и должен )))
А вообще если вы загружаете контейнер как файл, то нахрена вам контейнер и опция с '&' соответственно ?
А если грузите как блоки из контейнера, то напишите нормальный загрузчик, как делают во всех играх с монолоэдерами.
можно просто записывать в +11,+12 заголовка файла
(+13)*256
при этом
Не слушайте NEO SPECTRUMANа )) Не дай бог. Весь смысл опции коту под хвост.
NEO SPECTRUMAN
12.08.2020, 00:07
Не дай бог. Весь смысл опции коту под хвост.
какой глубокий смысл?
в не соблюдении спецификации файловой системы на размер файла???
- - - Добавлено - - -
А вот у меня отлично всё грузит как и должен )))
ты больной или прикидываешься?
- - - Добавлено - - -
конечно будет грузить если использовать одно только количество секторов
я конечно видел упоминание в intrd что какие то долбоклюи пишут не правильный размер файла
вопрос только зачем?
(сразу отвечу
когда они делали моноблок ручками в редакторе диска на самом спектруме в 96 году
они просто не удосужились исправить за одно и размер файла
они просто вписали сумму секторов моноблока и все
и "удалили" остальные файлы из каталога)
что тебе дает знание размера первого блока?
стандартными средствами tr-dos моноблок все равно не раскалупать потом
после применения сжатия (то что move)
да и тем более если в моноблоке 15 частей...
- - - Добавлено - - -
Описание:
отлично ты процитировал зарубежный источник где tr-dos вообще не применяют
Dart Alver
12.08.2020, 00:25
отлично ты процитировал зарубежный источник где tr-dos вообще не применяют
Вообще идея данной доработки и первая реализация была моя, затем Ped7g полностью переписал код в более приемлемом виде сохранив функциональность.
какой глубокий смысл?
в не соблюдении спецификации файловой системы на размер файла
Да ладно ! 80 % трдос игр построены на полном несоблюдении вашей 'спецификации' которую никто никогда не соблюдал на постсоветском пространстве.
когда они делали моноблок ручками в редакторе диска на самом спектруме в 96 году
они просто не удосужились исправить за одно и размер файла
они просто вписали сумму секторов моноблока и все
Серьёзно ? Считаешь что в 96-м за компом ленивые дураки сидели ?
Допустим для чисто контейнера данных исправление байтового размера не скажется никак. Ну а если 'исправить' контейнер с бейсик-загрузчиком ?
NEO SPECTRUMAN
12.08.2020, 00:31
Да ладно ! 80 % трдос игр построены на полном несоблюдении вашей 'спецификации' которую никто никогда не соблюдал на постсоветском пространстве.
Серьёзно ?
отлично
опиши применение не правильного размера твоего контейнера
другими словами НАХРЕНА? размер в секторах и в байтах не должен совпадать?
я то конечно свои загрузчики на всякий пофикшу
а то мало ли еще где дебилы встречаются
(я то вообще планировал подтирать мусор в конце после загрузки
по размеру файла
чтоб не было лишнего)
- - - Добавлено - - -
на полном несоблюдении вашей 'спецификации'
одно дело когда чем то оправдано и для улучшение чего то
ладно ты бы сказал 2 байта под размер файла используется для какой то цели
тк применить их можно только для отображения размера файла
тут же они тупо не используются вообще...
и ТЫ говоришь что так и надо
- - - Добавлено - - -
Ну а если 'исправить' контейнер с бейсик-загрузчиком ?
могу предложить только подписывать херню в место размера с бейсик загрузчика
а лучше сразу в hex редакторе
Dart Alver
12.08.2020, 00:43
отлично
опиши применение не правильного размера твоего контейнера
другими словами НАХРЕНА? размер в секторах и в байтах не должен совпадать?
Описывать не буду, вот ссылки на пару игр с VT с единственным файлом монолоэдером, просто больше искать лень. Что будет если ты исправишь их размер ?
https://vtrd.in/full_ver/DIZZY-Y_.ZIP
https://vtrd.in/full_ver/BATCITFF.zip
- - - Добавлено - - -
могу предложить только подписывать херню в место размера с бейсик загрузчика
а лучше сразу в hex редакторе
А я могу предложить вообще не трогать размер бейсик загрузчика, как это делали практически все спектрумисты с 90-х годов.
NEO SPECTRUMAN
12.08.2020, 00:52
исправил
https://jpegshare.net/images/63/4d/634d82a3040c84895d27538456d88dc2.png
https://jpegshare.net/images/60/44/604439545c781c7c2786b849a2c549f7.png
на вид все работает
https://jpegshare.net/images/fd/36/fd36cd44e53f6a17711e57ef31cb4c42.png
даже на всякий случай перехваты трдоса отключил
- - - Добавлено - - -
А я могу предложить вообще не трогать размер бейсик загрузчика,
ну да с приклеенным бейсик загрузчиком
может загрузится и все остальное сзади
я чота погорячился...
ладно предположим что успешная загрузка выше это или чисто случайность
или не отключаемый перехват в эмуляторе (в придачу не в одном)
и если даже trdos ВНЕЗАПНО грузит бейсик файл постепенно до последней строки (в чем я лично сомневаюсь)
то этого могут не делать 100500 существующих boot-ов
и на это нельзя рассчитывать
бред зачеркнул
просто NEO SPECTRUMAN привык что обычно он знает всё :)
но его уверенность в этом иногда его ВНЕЗАПНО подводит :v2_dizzy_wall:
Dart Alver
12.08.2020, 01:27
ладно предположим что успешная загрузка это или чисто случайность
или не отключаемый перехват эмулятора
В принципе я проверил и на второй игре, она тоже запустилась. Но всё же не факт что так будет везде (просто нет у меня достаточно знаний чтобы утверждать это или обратное) и со всеми программами. Также не знаю как будет реагировать наличие в бейсике прилинкованных переменных бейсика или автозапуска с определённой строки и т.п. мелочи, поэтому и голосую за не трогать. Тем более что системные проги tr-dos (в том числе copy и move) и командеры вполне нормально работают с подобными файлами.
NEO SPECTRUMAN
12.08.2020, 01:30
Но всё же не факт что так будет везде (просто нет у меня достаточно знаний чтобы утверждать это или обратное)
просмотрел загрузку замедленно memory band-ом
и как то оно подозрительно выглядит
64К явно не грузится
за одно уточнил в начале бейсик файла своего размера нет
(так что нужно проверять начало каждой строки чтобы дойти до конца файла)
при наличии 100500 существующих запускалок
да и 100600 версий tr-dos-ов гуляет...
лучше правда это не трогать
еще проверял merge
пишет out of memory
но файл на все 64К все равно не грузит
но и в приmergeнный бейсик потом не получается зайти сразу сброс
https://github.com/z00m128/sjasmplus/releases/tag/v1.17.0
STRUCT has new TEXT pseudo-instruction to define "DB-like" data
STRUCT initializer block can be now multi-line (when correctly enclosed in curly braces)
EQU now allows for optional override of page number assigned to the new symbol
new $$$ and $$$$ operators to retrieve "physical" address/page inside DISP block
instruction out (c),0 now emits warning (can be suppressed by the "; ok" comment)
fixed listing of structures using long BLOCK fields (machine code was correct, but listing not)
fixed some memory leaks, undefined behaviour and unaligned memory access
Now things like this are possible:
STRUCT S_fileHeader
type BYTE
name TEXT 10, { ' ' }
adr WORD
len WORD
ENDS
file1head S_fileHeader {
FILE_TYPE_A,
{ "file1" },
data1_start,
data1_end - data1_start
}
file2head S_fileHeader {
FILE_TYPE_B,
{ "f2" },
data2_start,
data2_end - data2_start
}
; ... etc...
NEO SPECTRUMAN
13.08.2020, 15:31
instruction out (c),0 now emits warning (can be suppressed by the "; ok" comment)
а зачем плодить безсмысленные предупреждения? :v2_dizzy_facepalm:
скоро придется весь код закоментировать ;ok-ями чтоб он компилировался без предупреждений
на фоне предупреждений не видно серьезных ошибок
в одной программке у меня штук 400 out (c),0
если уже гадить без остановки
то нужна гадить разными цветами хотя бы
красным ошибки
желтым предупреждения
или нужно глабальное отключение не нужных предупреждений
ставить сплошные ;ok это не дело
- - - Добавлено - - -
new $$$ and $$$$ operators to retrieve "physical" address/page inside DISP block
звучит интересно :v2_dizzy_roll:
сейчас приходится отдельно его высчитывать
в одной программке у меня штук 400 out (c),0
ну у меня то завсегда побольше будет. Что ж, будем в старых версиях компилить :)
about warnings... I hear you and I will try to figure out something.
About your usage of `out (c),0|255` so.. you are fine with CMOS Z80 doing `out (c),255`? I was kinda surprised (not in nice way).
But one possible workaround with current v1.17.0 is to use different reporting level for different files. Put all your `out (c),0` to one file and use `--msg=err` there to see zero warnings... let other files assemble with regular `--msg` level as you need it.
Other workaround is to redirect assembler output through `sed` and just remove the warning you don't want to see.
I understand these workarounds are not trivial, and I don't like current situation too, just give me some time...
Well, the `out (c),0` warning is definitely enough to be displayed once-per-assembling, I guess one is enough to learn about the dangers of usage of it.
But I think the best solution would be to make these extra checks configurable, like the "low memory access is" (NEO: --syntax=m to switch it off completely)
But it means there will be many new switches, etc...
So if you use `--msg=err`, you are actually missing some useful warnings, right? Can you remember which warnings is useful for you? This info is very valuable for me, the stories from the real world. :)
(you can also easily comment out that warning in source and build your own patched v1.17.0 .. it's just single line patch, jeez... :P )
or a,e и or e - это развИ не равнозначнО?
Первый вариант вообще игнорит.
как то грустно еще и такие ошЫбки отлавливать :(((
and a,$e0
это вообще за две команды посчитал, в других асмах почемуу то одна команда.
sub a,32 :(
NEO SPECTRUMAN
16.08.2020, 00:33
это вообще за две команды посчитал, в других асмах почемуу то одна команда.
а это от мерзких любителей писать команды в виде
ld a,5,3,(hl),%;№;%,(ix+"ЫГЫГЫ"),a,b,hl,c
для таких в аду уже приготовлен отдельный котел
хорошо хоть до такой
ld a++,++c,d+=e,e--
мерзости не додумались
а то некоторые всё хотят притянуть сишные приблуды в асм
и было это актуально во времена компиляции на самом спектруме
когда нужно было экономить память и на исходнике
но можно полезть и отключить
Multi-argument
Fake instructions
может поможет
я несколько раз спотыкался об то что
компилятор компилил 2 инструкции вместо одной
когда я ПРАВИЛЬНО писал что операция происходит над регистром A
ну и конечно ничего не работало
а ошибки нигде не было видно
- - - Добавлено - - -
а так приучайся писать с пропуском a, там где это допускается
так надежней
а так приучайся писать с пропуском a, там где это допускается
ога, кабы еще я это писАл..
Это вообще не понятно под какой асм писано, думаю под z88dk, да еще под Линь.
Второй день перевожу с не нашего на не русский. Но вроде собрал. Сяс проверю как в хекс файл переведецца
yes... In default sjasmplus syntax `sub a,e` is `sub a : sub e` .... (but `sbc a,e` is `sbc a,e`!). That's multi-argument feature of sjasmplus (vs Zilog official syntax, which is ... unfortunate... in some cases).
I did add option `--syntax=a` to modify the "multi-argument" separator from "," to ",," ... then the `sub a,e` becomes single `sub e`.
But it's still possible to write multi-arg form with double-comma: `ld a,(hl) ,, (bc),a` ... still difficult to review such code and not recommended, but at least it makes it less surprising when converting asm from other syntax to sjasmplus.
I recommend to use "--syntax=abf" for new sjasmplus projects ... that means:
"a" for double-comma for multi-arg
"b" to report parentheses around expression when no memory access is allowed (`ld b,(mylabel+4)` is error, must be `ld b,mylabel+4` if it is not bug)
"f" is to report any fake instruction with warning (you can then suppress the warning with ";ok" or ";fake", if you really want the fake instruction)
That's mostly helpful for people who are returning to Z80 assembly after many years and they may not remember subtle details like that the official Zilog syntax is `sub e`, but `sbc a,e` and that `ld b,(adr)` or `sub hl,de` does not exist at all... but I'm using the same options even for my own sources, and I'm not complete Z80 beginner...
Anyway, pick it or leave it, it's your choice, but the `sub a,e` case was notorious issue among cz/sk Speccy coders, forgetting which of the two (sub vs sbc) requires two arguments. So after some thinking I decided to not modify default sjasmplus, but add extra option to add the double-comma way.
edit: if you are migrating old project from other assembler to sjasmplus, comparing the binary for different bytes is the simple way to verify if the conversion is correct... Then you can search in the listing file the area which is different and check what line is producing the different machine code. I did use this when I was helping to migrate one big MSX project from tniasm to sjasmplus.
NEO SPECTRUMAN
23.08.2020, 01:05
/D - out only in Decimal
/H - out only in Hexadecimal
Ped7g, а можно сделать чтоб DISPLAY выводил и в binary виде?
Bedazzle
23.08.2020, 18:32
Ped7g, а можно сделать чтоб DISPLAY выводил и в binary виде?
Кстати да, иногда полезно в двоичном виде выводить.
NEO SPECTRUMAN
23.08.2020, 21:06
Кстати да, иногда полезно в двоичном виде выводить.
ну и главное с нулями в начале
00000001
00000010
00100001
00000111
от сокращенной записи толку не будет
1
10
100001
111
так как не прослеживаются столбцы
конечно для себя я нагородил вот такое
но это не совсем то что хотелось бы
не сильно удобно использовать
tmp_var0 = ((tmp_out and %00000001)/%00000001)
tmp_var1 = ((tmp_out and %00000010)/%00000010)*$10
tmp_var2 = ((tmp_out and %00000100)/%00000100)*$100
tmp_var3 = ((tmp_out and %00001000)/%00001000)*$1000
tmp_var4 = ((tmp_out and %00010000)/%00010000)
tmp_var5 = ((tmp_out and %00100000)/%00100000)*$10
tmp_var6 = ((tmp_out and %01000000)/%01000000)*$100
tmp_var7 = ((tmp_out and %10000000)/%10000000)*$1000
tmp_varA = tmp_var0 + tmp_var1 + tmp_var2 + tmp_var3
tmp_varB = tmp_var4 + tmp_var5 + tmp_var6 + tmp_var7
display tmp_varB," ",tmp_varA," ",/D,tmp_cnt
Ped7g, а можно сделать чтоб DISPLAY выводил и в binary виде?
da, mozno. Tolko 8-bit ja dumaju? Kakda budet nuzno 16-bit, jest mozno ... split the value to high/low and print both of them ... (my Russian is too limited to make full sentence :D ... heh, sorry)
NEO SPECTRUMAN
24.08.2020, 00:10
Ped7g, нужна реализация
cnt = 0
ld a,b : cnt = cnt + 4
and $70 : cnt = cnt + 7
или
lua allpass
cnt = 0
endlua
ld a,b : lua allpass : cnt = cnt + 4 : endlua
and $70 : lua allpass : cnt = cnt + 7 : endlua
не то не то сейчас не работает
как то можно сейчас проделать подобное?
под ld a,b and $70
подразумевается много строк кода с условной компиляцией
для которых нужен счетчик
- - - Добавлено - - -
my Russian is too limited to make full sentence
тем кому надо
понимают и english
- - - Добавлено - - -
Tolko 8-bit ja dumaju?
ну по идеи 8 должно хватить всем :)
Code:
cnt = 0
ld a,b : cnt = cnt + 4
and $70 : cnt = cnt + 7
This should work, except `cnt` is symbol (label), so it must start at the beginning of line, like this:
cnt = 0
ld a,b
cnt = cnt + 4
and $70
cnt = cnt + 7
NEO SPECTRUMAN
24.08.2020, 00:22
like this:
это удвоит видимый размер кода в 2 раза
который и без того плохо читается
- - - Добавлено - - -
от такого код станет плохо читаемым \ редактируемым
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
хотя можно отодвинуть так
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
ld a,b
cnt_name = cnt_name + 4
and $70
cnt_name = cnt_name + 7
вроде немного лучше
это удвоит видимый размер кода в 2 раза
который и без того плохо читается
well... the original sjasmplus design has some limits... but in some cases (in your original example) you can swap the order:
cnt = 0
cnt = cnt + 4 : ld a,b
cnt = cnt + 7 : and $70
Because the `ld` and `and` does not use `cnt`, it doesn't matter if you have it ahead/after the instruction. (you can even remove the colon if you like it more without, the parser will parse only valid expression for the "=" (alias DEFL), and then it will try to parse instruction after, but I would personally use colon. (although colon will split it in listing file to two lines, if that is your problem)
If the ld would be using `cnt`, then you can't swap them easily, but you can do `ld a,cnt-4` to load the "old" value before +4 ... it's ugly, but should work too.
Wait a second, are you trying to count T-states of instructions? :-o
That's ... interesting ... looks a bit dumb approach at first sight, but actually may be valid approach. But seems really tedious, omg. :D I wouldn't want to create this manually.
But in such case you can leave the T-state counter at beginning of the line, if you indent the instructions enough, it may be even not-that-bad on reading the source.
But makes me wonder if it would be better to somehow calculate it, but there's no simple way. Even if you would create some horrible macro to calculate T-states of particular block reading the device memory, it's valid only in pass3, so for first two passes the calculated T-states would be 0 all the time, ruining the conditional assembling of later blocks.
Other option is to use the IDE/editor plugin to calculate the T-states for selected block (there's Z80 meter plugin for VSC doing this), and do the cnt = cnt + XYZ after full block adding just one total number.
Either way, feels a bit messy, but I have no better workaround for you.
-------------------------
About binary DISPLAY, how about:
DISPLAY "value ",/B,123
--> outputs:
> value %0111'1011
I'm not sure about the group-separator in the middle... the C++ syntax is apostrophe (also supported by sjasmplus), but if you will later parse such data in Excel or something, the apostrophes will probably derail the tool a lot... then again you can always use `sed` to remove them from the log before processing it further, and the separator helps to find the 4bit group... So I guess I will do it like this, with the separator.
NEO SPECTRUMAN
24.08.2020, 00:36
can swap the order:
Ооо
это выглядит приемлемо!
почему то я не подумал о таком варианте
oh.. WARNING .. the line:
cnt = cnt + 7 and $70
will understand the `and` as part of the expression! Not instruction! So it will do `cnt = (cnt + 7) & $70`.
So the colon is mandatory with such design... makes me wonder, if the "parse instruction after DEFL" is good idea... I should probably remove that feature, that's very confusing, losing and/or/xor instructions in this way, funny I haven't hit it yet, because I use similar code to define self-modify-code labels, like:
posX=$+1 ld hl,1234
... so I was just lucky to not use it with and/or/xor, that would be surprise.. (I was initially thinking there is bug in listing, because there was no instruction opcode for the `and $70`, took me a good minute to realize what happened)
(yeah, I guess when I remove it, there will be some user crying that I broke their old source... sigh .. but this is really dangerous syntax design :/ )
NEO SPECTRUMAN
24.08.2020, 00:46
> value %0111'1011
было бы лучше так
%0111 1011
но в приципе и такой вариант пойдет
%0111'1011
(also supported by sjasmplus
то есть уже давно можно вводить and %0000'0000 ?
а то я все хочу попросить реализацию чего то подобного
тк работать с 00000000000000000000 не удобно
- - - Добавлено - - -
cnt = 0 cnt = cnt + 4 : ld a,b cnt = cnt + 7 : and $70
правда это плохо сочетается с моим
cnt = $+1 : ld hl,$0000
frq = $+1 : ld de,$0123
правда таких строк обычно не много
странно я всегда этим пользуюсь
но чего то
cnt=cnt+1 : xxxx
не пришел в голову
то есть уже давно можно вводить and %0000'0000 ?
а то я все хочу попросить реализацию чего то подобного
тк работать с 00000000000000000000 не удобно
since v1.12.1:
(v1.12.1) Optional single quotes(') may be inserted between the digits as a separator (example: ld a,%11'01'11'00 ). They are ignored by the assembler.
(I really don't like the character picked by C++ commitee ... I would prefer personally underscore like `ld hl,$12_34`, but then again using the same syntax as C++ makes it less difficult to switch between syntax, so I did use the apostrophe too - but it's not my favourite)
NEO SPECTRUMAN
24.08.2020, 03:03
читаю инструкцию
нашел опечатку
[void] _pc("code")
Parse string of Z80 assembly. Example: _pc("ADD A,B")
[void] _pl("label code")
Parse line of Z80 assembly. Example: _pc("SOMELABEL ADD A,B")
[integer] sj.calc("expression")
Se
- - - Добавлено - - -
все равно метки получаются плохо различимыми
https://jpegshare.net/images/e7/b4/e7b401843d4af81993aef019069d4aa4.png
https://jpegshare.net/images/b4/27/b42799b354c3b5014a37b64fee85e69d.png
все равно метки получаются плохо различимыми
yes, doesn't look well.
I would maybe try to use the CN ahead of instruction, and real labels on separate line ahead:
frq = $+1
CN=CN+10 : ld de,$0123
BTW, the "=" (alias "DEFL") is more like variable, and allows redefinition of the value. If things like `frq` are used for self-modify code, I would suggest to use EQU instead, which creates "constant" (attempt to redefine it second time in source will emit error about different value assigned).
With a bonus of the EQU maybe creating different visual feel in this case too:
frq EQU $+1
CN=CN+10 : ld de,$0123
Or maybe use macro? But that will explode the listing file, but if you are not planning to use listing very often for this area of code, it may help with the source (you can disable listing for particular part of source, if you are using listing to check other areas).
countT MACRO cycles?
CN=CN+(cycles?)
ENDM
CN=0
ld a,b : countT 4
and $70 : countT 7
frq=$+1 ld de,$1234 : countT 10
IF CN < 26
.((26-CN+3)/4) nop
countT (26-CN+3)&-4
ENDIF
Полезно и в восьмеричном виде выводить числовую информацию. Вспомните, байты атрибутов экрана нагляднее именно в восьмеричном виде.
NEO SPECTRUMAN
24.08.2020, 04:43
But that will explode the listing file
а он и так у меня обычно не читаемый и весит мегабайтов 7 :)
например листинг NSID_Emu весит 15MB ;)
туда давно бесполезно заглядывать...
- - - Добавлено - - -
Or maybe use macro?
интересно
возможно оно даже будет работать с adp
а на каком pass-е уже будет результат?
так как полученные цифры еще будут передаваться lua для расчета таблиц
- - - Добавлено - - -
you can disable listing for particular part of source, if you are using listing to check other areas).
а как это делать?
- - - Добавлено - - -
ну и на верно только мои исходники компилируются столько времени в sjasm :rolleyes:
https://jpegshare.net/images/37/ab/37ab36908f99107ca0bada33ef7e4ccb.png
а на каком pass-е уже будет результат?
так как полученные цифры еще будут передаваться lua для расчета таблиц
Macros are like "includes", expanded upon instance in every pass (becoming part of source). Notice how inside my example macro "CN=CN+(cycles?)" -> the argument is in parentheses - that's because the macro arguments are substituted in C-preprocessor way, substituting the strings, doing the value evaluation as last step after all substitutions, so without parentheses the usage `countT (26-CN+3)&-4` does expand to `CN=CN+(26-CN+3)&-4` which will evaluate to different result as `CN=CN+((26-CN+3)&-4)`! So it's similar landmine field like C #defines ... :D
But the value of symbol CN is updated in every pass, just as if you would do the CN=CN+4 at beginning of line (but it happens after instruction, because macro is expanded after instruction).
---------------
listing disabling:
http://z00m128.github.io/sjasmplus/documentation.html#po_opt
OPT push listoff ; preserve current state of listing, and switch listing off
; some code without listing (only marked by "# listing disabled" and "# listing enabled" lines in listing)
...
OPT pop ; restore the listing to original state
(the disabling/enabling of listing is announced in the listing file, so this shortens listing for blocks of code, for single line this will explode listing even more)
the OPT state can be push/pop-ed, so you can even nest these in includes/etc... if the top level has listing enabled, and it will go through multiple nested blocks having this switch off, then the first will switch listing off, nested ones will make no visible change, and the final last `opt pop` will restore listing back to "on".
Similarly if you are doing sjasmplus library to be included as source code, and you want customize the syntax, but you don't want to affect project which is including your source, you can do `OPT push reset --syntax=aBf` to have your source going by these rules, then `OPT pop` at end of your library to restore the syntax of original project...
Sorry for spamming you with this info you didn't ask for, but I'm kinda proud of the OPT design... :P :D
NEO SPECTRUMAN
24.08.2020, 15:49
так намного лучше
https://jpegshare.net/images/26/cf/26cf53cf0179c268096d2eee76e23ed4.png
Bedazzle
24.08.2020, 16:46
da, mozno. Tolko 8-bit ja dumaju?
Да, 8 бит хорошо.
(my Russian is too limited to make full sentence :D ... heh, sorry)
Your Russian is quite well written for the novice!
NEO SPECTRUMAN
24.08.2020, 16:53
for the novice!
может потому что Ped7g из Чехии
что как бы тоже exUSSR :)
Black Cat / Era CG
24.08.2020, 16:56
А еще язык славянский.
NEO SPECTRUMAN
17.09.2020, 10:27
Ped7g, а сейчас как то можно организовать синонимы для макросов?
есть куча макросов которые для сохранения совместимости переименовать нельзя
ну и делать копию тоже нельзя
по смыслу должно работать так
macro aabb123 || blahblahblah_aa_bb_123_NOW111 aaa
defb aaa
...
100500 lines of code
...
endm
или так
macro aabb123 || blahblahblah_aa_bb_123_NOW111 aaa
defb aaa
...
100500 lines of code
...
endm
macro blahblahblah_aa_bb_123_NOW111 aaa
aabb123 aaa
endm
с результатом
aabb123 1
blahblahblah_aa_bb_123_NOW111 2
defb 1
...
100500 lines of code
...
defb 2
...
100500 lines of code
...
при этом на всех PASS-ах
синонимы должны вести себя так же как и оригинальный макрос
define-ом наверно будет опасно пользоваться для такого
хотя надо будет попробовать
So you want the same macro, but with the two different names?
The second way should work quite ok?
macro aabb123 aaa ; "main" version
defb aaa
...
100500 lines of code
...
endm
macro blahblahblah_aa_bb_123_NOW111 aaa ; "alias" version
aabb123 aaa ; call the "main" version of macro
endm
; usage
aabb123 1
blahblahblah_aa_bb_123_NOW111 2
Is this broken for you?
DEFINE is of course another option, but that works best with distinct names, like `DEFINE blahblahblah_aa_bb_123_NOW111 aabb123` .. seems unlikely you will have collision with such long string like "blahblahblah_aa_bb_123_NOW111" (although may happen, if you have "blahblahblah_aa_bb_123_NOW111_2" -> "aabb123_2" will be substituted.
NEO SPECTRUMAN
18.09.2020, 08:03
The second way should work quite ok?
еще не проверил
додумался до такого варианта только когда уже написал сообщение
да и есть некоторые сомнения
так как на PASS 1 уже в макросах прицеплена lua
The nested macros are possible and should generally work, although they will exercise some not pretty parts of the code, and the maximum depth of nesting is limited (like 20 probably). So I can't promise there's no hidden bug nobody reported yet, but try it, it should work. :)
NEO SPECTRUMAN
19.09.2020, 17:22
The nested macros are possible and should generally work, although they will exercise some not pretty parts of the code, and the maximum depth of nesting is limited (like 20 probably). So I can't promise there's no hidden bug nobody reported yet, but try it, it should work.
интересная информация
а так уже применил
сейчас тестирую
NEO SPECTRUMAN
27.10.2020, 22:00
меня периодически достает такая бага
или может быть я чего то не вижу?
SjASMPlus Z80 Cross-Assembler v1.17.0 (https://github.com/z00m128/sjasmplu
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
test.asm(34): error: [IF] No ENDIF
Pass 3 complete
Errors: 1, warnings: 0, compiled: 14 lines, work time: 0.000 seconds
mode = 1
if mode = 6
lua allpass
for temp_cnt = 0,255,2 do
var = 0
if var > 65535 then
var = 65535
end
end
endlua
endif
в исходнике из которого я эту конструкция скопировал (упрощенно)
ошибка происходит уже на pass 3
- - - Добавлено - - -
при этом если сделать
mode = 1
if mode = 6
include "fix.asm
endif
fix.asm
lua allpass
for temp_cnt = 0,255,2 do
var = 0
if var > 65535 then
var = 65535
end
end
endlua
то все работает...
SjASMPlus Z80 Cross-Assembler v1.17.0 (https://github.com/z00m128/sjasmplu
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
Pass 3 complete
Errors: 0, warnings: 0, compiled: 24 lines, work time: 0.000 seconds
так тоже без ошибок
mode = 1
if mode = 6
lua allpass
for temp_cnt = 0,255,2 do
var = 0
--if var > 65535 then
--var = 65535
--end
end
endlua
endif
меня периодически достает такая бага
или может быть я чего то не вижу?
I get "error: [IF] No ENDIF" too, and I also don't see anything wrong about the code you posted = bug in sjasmplus.
Thanks for reporting it (I will let you know later when I will have time to investigate, what is happening, seems like the lua part derails the parser in wrong way, but I don't see the reason).
NEO SPECTRUMAN
09.11.2020, 00:17
нужны нормальные временные метки с именами
типа
temp_label
ld hl,temp_label.f
jp temp_label.b
temp_label
или же нужно доделывание временных меток которые есть сейчас
так как сейчас такое не сделать
ld de,$5555
ld sp,$4555
ld ix,1f
jp some_procedure
1
ld de,$6666
ld sp,$4444
ld ix,1f
jp some_procedure
1
ld de,$7777
ld sp,$4333
ld ix,1f
jp some_procedure
1
например чтобы отличать от цифр можно было бы использовать какойто дополнительный символ
ld ix,1_f
1_f 100% not valid label
ld ix,1.f
но цифрами не очень удобно пользоваться
есть вероятность поставить ту что уже есть
и переход будет не туда
а с временной меткой у которой есть имя проблем бы не было...
сейчас случаем нет ограничения на максимально возможное число для временной метки?
сейчас случаем нет ограничения на максимально возможное число для временной метки?
It must be positive 32 bit integer (maybe zero works too? So non-negative 32b integer.), i.e. ~2e9 numbers.
но цифрами не очень удобно пользоваться
есть вероятность поставить ту что уже есть
You can use the same number multiple times, the relative position is important, i.e.:
1
daa
jr 1f ; to cpl
jr 1b ; to daa
1
cpl
jr 1b ; to cpl
About your suggestion... feels like quite a big departure from the original concept (whatever you may think about it ... I rarely use temporary labels, feels usually wrong, but I don't write very complex projects). I will think about it more, but I don't see any nice "fit" to the current syntax, so feels like something to be discussed again when/if v2.0 happens...
About your actual problem... maybe define juggling? I will try to prepare some example, what I have on mind (I need to verify first if it even works, my first simpler idea did NOT work).
test.asm(34): error: [IF] No ENDIF
fixed, the false IF-ENDIF block was reading lua script, finding the "if" inside lua, adding nest-level to the current conditional block.
In v1.17.0 use workaround, hide the lua script definition inside macro or include (as you figured out).
NEO SPECTRUMAN
11.11.2020, 02:25
You can use the same number multiple times, the relative position is important, i.e.:
Код:
1
daa
jr 1f ; to cpl
jr 1b ; to daa
1
cpl
jr 1b ; to cpl
проблема возникает когда
1
jr 2b ;not in view
... 100 lines of code
some code
... 100 lines of code
2
jr 1b ;not in view
при редактировании легко можно сделать ошибку
1
jr 2b ;not in view
... 100 lines of code
1
jr 3f
some code
jr 1b
... 100 lines of code
2
jr 1b ;not in view
;wrong jump !!!!!
и все перестнет работать...
- - - Добавлено - - -
feels like quite a big departure from the original concept
в оригинальном концепте
метки не могут начинаться с цифры
а шестнадцатеричные цифры должны обязательно начинаться с символа $ # 0x или заканчиваться на h
и по идеи любые *f *b не могут быть valid numbers-ами
почему такая конструкция это правильно
label
ld hl,label
jp label
а такая нет ?
1
ld hl,1b
jp 1b
выглядит как недоделка компилятора
когда добавляли временные метки
или не учли такого варианта использования
или просто забыли
в придачу если имеется в виду именно переход на $001b
и будет временная метка 1
то всё скомпилируется совершенно не так как нужно
изначальные вариант ставить B и F сразу после цифры
не есть правильным
нужен был символ разделитель
но его изначально не сделали...
конечно если добавлять все это сейчас
может возникнуть вероятность появления несовместимостей со старыми исходниками...
при редактировании легко можно сделать ошибку
и все перестнет работать...
Da. Temporary labels *smells*. ;) (but sometimes they may be handy, like in macro which is used many times, and you don't want to insert many new symbols into label table in the listing file)
ld hl,1b
that's a valid way how to write binary number in sjasmplus (suffix form with "b" at end).
It's actually super annoying to me, because:
1000
jp 1000b ; jumps back to the temporary label, not address 8
ld hl,1000b ; HL = 8
The risk of real collision in source is very low, but I dislike this feature, feels like it was added by somebody not foreseeing the ambiguity.
Anyway, the solution is simple, don't use temporary labels. ;)
But I guess your original problem is about generating some code by generator or what... making some "previous/next" label handy?
NEO SPECTRUMAN
11.11.2020, 05:57
But I guess your original problem is about generating some code by generator or what... making some "previous/next" label handy?
в данном случая я хотел использовать для имитация call
когда занят SP
я очень сильно не люблю конструкции типа
jp $+5
так как проблем от них когда нужно добавить даже 1 байт между...
поэтому хотел сделать с временными метками внутри dup цикла
по типу
dup 100500
;some code
ld ix,label
jp some_procedure
label
edup
some_procedure
;some code
push bc
jp (ix)
сделать макросами не получится так как вокруг сплошная LUA
делать макросами не получится так как вокруг сплошная LUA
dare you elaborate? This seems to me ok:
MACRO callNoSp returnReg?, procedureAdr?
ld returnReg?,.returnAfterJp
jp procedureAdr?
.returnAfterJp:
ENDM
DUP 100
callNoSp ix,someProcedure
EDUP
someProcedure:
push bc
jp (ix)
Where exactly Lua kills this approach?
NEO SPECTRUMAN
11.11.2020, 17:58
Where exactly Lua kills this approach?
странно на вид работает о_О
когда последний раз проверял макросы
по моему или неправильно находилась длина процедур и часть их потом затиралась
или jp вели на другие адреса
конечно еще нужно проверить в реальном коде
- - - Добавлено - - -
DUP 100 callNoSp ix,someProcedure EDUP
хотя это не выход из положения
мне нужна именно временная метка
так как
tamp_left_allocate_macro
callNoSp ix,someProcedure
end_tamp_left_allocate_macro
tamp_right_allocate_macro
callNoSp ix,someProcedure
end_tamp_right_allocate_macro
tamp_left_allocate_macro
jp $
end_tamp_left_allocate_macro
скомпилируется как
$8000 ld hl,$8006
jp procedure
$8006 jp $8006
$C300 ld hl,$C306
jp procedure
когда нужно
tamp_left_allocate_macro
ld hl,temp
jp procedure
end_tamp_left_allocate_macro
tamp_right_allocate_macro
temp
ld hl,temp
jp procedure
end_tamp_right_allocate_macro
tamp_left_allocate_macro
temp
jp $
end_tamp_left_allocate_macro
$8000 ld hl,$С300
jp procedure
$8006 jp $8006
$C300 ld hl,$8006
jp procedure
память может быть сильно фрагментированной
и такая конструкция работать не будет
dup 100
tamp_left_allocate_macro
callNoSp ix,someProcedure
end_tamp_left_allocate_macro
edup
- - - Добавлено - - -
наглядный пример
org_allocate_macro $C010
di : halt
end_org_allocate_macro
org_allocate_macro $C021
di : halt
end_org_allocate_macro
DUP 100
tamp_left_allocate_macro
callNoSp ix,someProcedure
end_tamp_left_allocate_macro
EDUP
https://jpegshare.net/images/da/b7/dab764b9c20d3052b3b1c9dbf222475c.png
так же невозможно организовать выход из такой процедуры
так как последний ix должен вести на выход
так же невозможно организовать выход из такой процедуры
так как последний ix должен вести на выход
That screenshot: so you did want "C019 ld ix,C023" to make "C00B" procedure return AFTER the "di:halt", right?
And the final "C046 ld ix,C04D" should be "ld ix,someExit"?
well, the second part is easy, just: ".100 callNoSp ix,proc" turns to ".99 callNoSp ix,proc" + "ld ix,exit : jp proc"
but the first part is changing the task completely, so you don't want to IX="after `jp proc`", but you need IX="ahead of next code block".
If I understand you correctly now.
NEO SPECTRUMAN
12.11.2020, 21:38
but you need IX="ahead of next code block".
да
и этот кодовый блок может быть где угодно в памяти
и этот кодовый блок может быть где угодно в памяти
what about this:
; helper macro to make __COUNTER__ sub-word substitution possible (hiding it in macro arg)
; ("FollowingCode___COUNTER__" would not substitute, but "FollowingCode_suffix?" does)
MACRO nextFollowingCodeLabel suffix?
IFDEF FollowingCodeLabel
FollowingCodeLabel:
UNDEFINE FollowingCodeLabel
ENDIF
DEFINE FollowingCodeLabel FollowingCode_suffix?
ENDM
MACRO tamp_left_allocate_macro
; ... some allocation done and final ORG
nextOrg=(nextOrg+$6789)&$FFFF ; for fun jump around memory (not real "allocate")
ORG nextOrg ; where next code block should land
; mark this new code-block with "FollowingCodeLabel" label, and advance it for next code-block
nextFollowingCodeLabel __COUNTER__
; ... other preamble shared code ...
ENDM
MACRO end_tamp_left_allocate_macro
; ...
ENDM
MACRO callNoSp returnReg?, procedureAdr?
ld returnReg?,FollowingCodeLabel
jp procedureAdr?
ENDM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; the memory location of code blocks is not important (could jump back and forth)
;
; the source code order of blocks is important - "FollowingCodeLabel:" is relative
; to where in source you currently are.
;
; And "tamp_left_allocate_macro" will advance it
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
nextOrg = $1234
DUP 100
tamp_left_allocate_macro
nop
callNoSp ix,someProcedure
end_tamp_left_allocate_macro
EDUP
; one manual block outside of DUP ...
nextFollowingCodeLabel __COUNTER__ ; define label for this block and advance it
daa ; manual block code
callNoSp ix,someProcedure
; exit-block manually added, just defining last FollowingCodeLabel label
FollowingCodeLabel: ; create one more "next code block" label for exit-block
; ... exit code (after last block)
di
halt
someProcedure:
; ...
jp ix
(took me couple of minutes of thinking to avoid Lua ... but in the end the extra helper macro did the trick :D )
NEO SPECTRUMAN
16.11.2020, 12:21
tamp_left_allocate_macro
это внешние макросы про которые мы ничего не знаем и которые мы не трогаем
это примерно как совет полезть редактировать C:\MinGW\include\stdio.h :)
:v2_dizzy_ok: (I don't see how that matters for that example, just extract the functionality and add it in the form valid for your use case - I can't produce your code, if you don't share it first, if you will re-read history of this topic, you keep coming with new bits of info after every response posting you working example fitting your previous rules - stops being fun after like third try, that you can't explain yourself clearly in the first post ;) .. so you have like one try left)
NEO SPECTRUMAN
16.11.2020, 13:15
I can't produce your code,
я написал 60+ уникальных меток руками
до того как написать тут о том что временные метки в sjasm не работают как нужно :)
хотя я периодически сталкиваюсь с этой проблемой и хотелось бы иметь решение
но то что предложено выше
больше похоже на убегание от проблем чем на их решение
yep. I have no plans to extend temporary digit-labels to work with all instructions, the current design of making them valid only with `jr/jp/call` is fine by me (I think I understand *why* Sjoerd Mastijn designed it like that... even current sjasm 0.42 has still the same design of "reusable labels") (while checking sjasm docs, I see somewhat adjusted rules for regular labels, this looks interesting, the "!" prefix would be nice to add into sjasmplus - not related to your issue, just taking note for myself).
There are two issues about extending temporary/reusable labels:
1) I don't have vision of clearly-better solution, when I gave it some short thought, I see only more mess and confusion
2) I have lot of other stuff to do on sjasmplus (SLD export and warnings-system improvements, then release), but little time for it
And for me the proposed solution in my last answer with code looks good, like valid solution, feels to me much more solid than some temporary label hack.
(of course anyone else can redesign the feature and ask me (and other contributors) if we like the new design, and implement a patch and create pull request... it's open project and I would feel bad to just reject it)
If I will have nothing else to do on sjasmplus and feel bored, I will certainly revisit any remaining suggestions and try to pick some good ones.
With regard to your current issue, I provided you working solution. I don't see what more you want, sorry.
https://github.com/z00m128/sjasmplus/releases/tag/v1.18.0
- some new/improved directives: WHILE<->ENDW, ELSEIF, DEFINE+, DISPLAY
- abs operator
- new warning system (with systematic suppression scheme)
- some bugfixes/implementation rewritten
- and more tiny details...
... I have a feeling this may be default setup of some guys here (but you may try first without and see if it's relevant)
; ... in source ...
OPT -Wno-rdlow -Wno-out0 -Wno-trdext -Wno-trdext3
Anyway, if you see some new warning with "warning[some_id]" form, then `-Wno-some_id` will switch it off completely, and line comment "; some_id-ok" will suppress it for particular line.
Have fun. :)
BTW, as a "stress test" and "eat your own dog food" exercise, I'm doing https://adventofcode.com/2020 in sjasmplus... not as Z80 machine code, but using sjasmplus macro scripting to resolve the puzzles during assembling-time...
For example the day 11 puzzle assembles like this (the asm file has 114 lines of "script"):
$ sjasmplus seating_system_p2.asm
SjASMPlus Z80 Cross-Assembler v1.18.0 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
include data: name=input.txt (9702 bytes) Offset=0 Len=9702
> Map size: 98x98 extending to 100x100
> Rounds to reach stability: 90
> Final state has **** seats occupied.
Pass 3 complete
Errors: 0, warnings: 0, compiled: 68000349 lines, work time: 55.454 seconds
(I will publish all scripts on github after the event will end, so if anyone is really bored, they may check how is it possible to do in sjasmplus - IIRC there's 0-1 lua scripts, all is regular sjasmplus mess ;) )
NEO SPECTRUMAN
15.12.2020, 01:01
Ped7g, а можно сделать дописывание файла при помощи SAVEBIN?
SAVEBIN "data.bin",$0000,$2000 ;data.bin size $2000
SAVEBIN "data.bin",&,$4000,$2000 ;data.bin size $4000
SAVEBIN "data.bin",&,$8000,$1000 ;data.bin size $5000
можно сделать дописывание файла при помощи SAVEBIN?
da, mozno, no nenada?
Let me try something...
; preparing data...
SAVEBIN "part1.bin",$0000,$2000
; preparing data...
SAVEBIN "part2.bin",$4000,$2000
; preparing data...
SAVEBIN "part3.bin",$8000,$1000
IF 3 == __PASS__
; would fail to open part1/part2/part3.bin in first/second pass (they exist after third pass)
DEVICE NONE : ORG 0 ; device none to not write part files into device memory, just output them
OUTPUT "data.bin"
INCBIN "part1.bin"
INCBIN "part2.bin"
INCBIN "part3.bin"
OUTEND
; you can also add SHELLEXEC to delete part files, if you want...
ENDIF
works already in 1.18.0+, no need to wait for me...
I'm not very happy about that "&" syntax, I know SAVETRD has now something similar, but... me not like.
The work-around above seems to me reasonable enough to not work on this.
(but if it would be my own project, I would actually have it as Makefile rules, with final:
data.bin : part1.bin part2.bin part3.bin
cat $^ > $@
- assuming you have GNU make and *NIX system, on windows the "cat 1.bin 2.bin 3.bin > data.bin" may not work? I think windows have some different way... copy /b ?? I don't remember.)
NEO SPECTRUMAN
15.12.2020, 02:09
надо будет попробовать
хотя это создает много лишних .bin-ов...
так можно будет делать файлы больше 64К ?
так можно будет делать файлы больше 64К ?
That's more tricky... if you can use separate asm file to build final large file, you can use `sjasmplus --longptr` and have 32bit addresses.
I don't remember if it's possible to mix DEVICE with --longptr (like ZX48 vs NONE using long), I think it's not possible, but as separate file it would work.
If your "part" bin are always less than 64k, you can do "ORG 0" ahead of every INCBIN in the final merge:
OUTPUT "data.bin"
ORG 0 : INCBIN "part1.bin"
ORG 0 : INCBIN "part2.bin"
ORG 0 : INCBIN "part3.bin"
OUTEND
This way you will avoid "$" to reach $10000.
хотя это создает много лишних .bin-ов...
^ and that's why I would use `make`, and probably split the bin files generators into separate groups .asm files, so it would recompile only files which did change... and output the bins into some `build/` directory, which would be in `.gitignore`, so I would not see them most of the time... :) (as I usually use "git-cola" to look at the project dir, so I see only modified files)
(BTW, I didn't try it, but I believe if you will do nothing, and keep INCBIN more than 64ki, it will output still correct file, but report warning when "$" wraps around $FFFF -> $0000, but no damage ... you can then ignore such warning.. but I hate warnings ;), so the "ORG 0" is then another option)
Bedazzle
15.12.2020, 12:20
Ped7g, а можно сделать дописывание файла при помощи SAVEBIN?
Мне кажется, что объединение нескольких бинарников - вообще не работа ассемблера.
Это нужно делать снаружи.
Мне кажется, что объединение нескольких бинарников - вообще не работа ассемблера.
Это нужно делать снаружи.
:v2_unsur: I'm trying to be not so fundamental, as in this regard sjasmplus already contains *ton* of questionable functionality (SAVETAP does lot of stuff what you can achieve with external tools for TAP files manipulation, and it would be enough to output from sjasmplus just the binary blob, etc..).
It's often convenient to have the extra features available already from the asm source (and without need to hunt down external tool), at least for lazy programmers like me. :)
But if the syntax is not complete clear win, and may break current syntax/old sources, then I'm reluctant to dive into it too quickly, I would discuss that stuff for few days/weeks first and check the examples against older projects...
Plus Neo's habit to build large binaries from single source with long assembling time (1+ sec) is at the edge of where he would probably benefit from splitting his projects a bit more and use advanced build tools like make... :)
(I don't claim my additions to sjasmplus are always good-taste and perfect .... for example the new "DEFINE+" feels now bad to me => so feel free to suggest new stuff, just have some patience plus examples and arguments, if I don't get it from first moment, I may need some time to think it through .. or maybe we can find even better design over time... but in the end, if you have real world project which suffers a lot, and there's no good work-around, I will rather add some dirty addition to sjasmplus to make real code work, than guard principal cleanness of assembler).
Bedazzle
15.12.2020, 13:34
It's often convenient to have the extra features available already from the asm source (and without need to hunt down external tool), at least for lazy programmers like me. :)
Lazy programmers use existing tools, that are well tested and widely used. :)
Why you need to implement new bicycle when good OS tools exist? :)
NEO SPECTRUMAN
15.12.2020, 13:40
Мне кажется, что объединение нескольких бинарников
а МНЕ не кажется
сплошное делание снаружи
приводит к большому количеству головной боли
а потом фиг скомпилируешь чужой исходник
потому что все снаружи...
- - - Добавлено - - -
в придачу ЕЩЕ РАЗ повторю
средства встроенные в ассемблер более гибкие
чем кучка мерзких make-ов которые не имеют никакого доступа к содержимому переменных компилятора и lua
- - - Добавлено - - -
long assembling time (1+ sec)
это все в прошлом :)
теперь у меня начиная от 10+ :v2_lol:
Bedazzle
15.12.2020, 21:49
а потом фиг скомпилируешь чужой исходник
потому что все снаружи...
Если использовать левые инструменты, а не то, что встроено в OS (о чём написано выше), то да, могут возникнуть нюансы.
средства встроенные в ассемблер более гибкие
чем кучка мерзких make-ов которые не имеют никакого доступа к содержимому переменных компилятора и lua
Гибкие велосипеды с глюками, да. :)
Если уж на то пошло, "никакого доступа" - это лукавство. При желании можно выгрузить значения в файлы, и снаружи обработать.
И более гибкие как раз мейкфайлы и скрипты снаружи, которые можно править как и когда тебе хочется, а не ждать, когда что-то внедрят в гибкий ассемблер.
NEO SPECTRUMAN
15.12.2020, 21:55
И более гибкие как раз мейкфайлы и скрипты снаружи, которые можно править как и когда тебе хочется, а не ждать, когда что-то внедрят в гибкий ассемблер.
мейки умеют плавающую запятую?
там логарифмы, степеня?
https://github.com/ped7g/ZXSpectrumNextMisc/blob/master/snippets/strings5bPacked.i.asm#L3
There was some ongoing discussion about packing 5bit 0..31 values (aka "strings" with limited charset) to bitstream, and how long the decoding routine has to be.
From the initial 22B by Busy we went down to 19B (thanks to Baze and Zilog), and I collected it all into my "code snippets" project (it's targetting ZX Next, but the particular 5b-decoding is classic Z80 only).
There's also sjasmplus macro to encode regular string literals... I'm so glad I did add WHILE in v1.18.0 ... it's becoming really handy :D (I could used `DUP inputdata_size` in this case too, but WHILE reads better to me, to understand what is happening).
Have fun. :) (I have some suspicion this is "old news" for you, but consider there are many newcomers trying to learn Z80 programming, the snippets are targetting those, as examples of small routines)
мейки умеют плавающую запятую?
там логарифмы, степеня?
Да. Всё что угодно через любое ПО.
Bedazzle
16.12.2020, 23:40
мейки умеют плавающую запятую?
там логарифмы, степеня?
Насколько помню, мы начинали с объединения нескольких бинарников в один.
Где здесь нужна степень или логарифм?
А если мы говорим просто о скриптах, то любой современный язык это умеет.
И да, он будет более гибкий, чем асм.
NEO SPECTRUMAN
17.12.2020, 02:38
Насколько помню, мы начинали с объединения нескольких бинарников в один.
Где здесь нужна степень или логарифм?
там где заявили, что компилятор ничего не должен делать
Bedazzle
17.12.2020, 17:14
там где заявили, что компилятор ничего не должен делать
Объединять три готовых бинарных куска в целое?
Да, хорошо зарекомендовавшая себя практика - делать это снаружи ассемблера.
there are several different approaches possible.
One MSX project I have seen sources of does this:
using `--longptr` option to have 24bit address space and `output -> outend` to produce binary 2MB file in one go (assembling machine code sequentially, emitting the file byte by byte). Then the mapping looks like `ld a,address>>14 ; bank num from long address` and `ld hl,address&$3FFF` to have offset into it (+ adjust to particular target area in memory) ... or something like that, I hope I remember it correctly.
I would personally go the virtual DEVICE route, making the virtual mapping match my runtime mapping, and using 16b labels (with page info):
DEVICE ZXSPECTRUMNEXT ; Next has 8ki pages
MMU 0 n, 26, $0000 ; map page 26 into $0000..$1FFF , org $0000, enable auto-wrap
spriteData1: incbin "spr1.bin" ; spriteData1 == $0000, $$spriteData1 == 26 (page num)
spriteData2: incbin "spr2.bin"
...
ORG $8000
; runtime mapping of data2 into $0000..$3FFF area (in case it does cross 8ki boundary while incbin)
nextreg $50,$$spriteData2 ; maps $0000..$1FFF to page of spriteData2 symbol
nextreg $51,$$spriteData2+1 ; maps $2000..$3FFF to page+1 (to cover for 8ki cross)
ld hl,spriteData2 ; some 0000-1FFF offset to the beginning of the data
prepare full 1/2 MB memory state, and then SAVENEX to the "NEX" file which works with this pattern well.
For multi-load one can prepare each block in virtual memory, SAVEBIN/SAVEDEV it, then ORG back at the beginning and start over with second part...
All of these DEVICE "SAVE" directives are saving *current* state - local to their position in code, so you can produce different binary blocks from the same virtual memory area in one assembling - contrary to OUTPUT way, where you are emitting stream of bytes, making it quite tricky to "go back" (it's possible by opening the OUTPUT for rewrite, and then FPOS to position where you want to overwrite data - possible, but cumbersome a bit)).
The script few messages back to merge several bin blocks together into one big file using OUTPUT + INCBIN should definitely work (if small parts are less than 64kiB, then you will not even cross $10000 boundary, so no warning, but even with larger files it should work.. or you can avoid warning by some other trick, like INCBIN into MMU wrap-around page while also having OUTPUT active, or by using separate asm file without code, just to build the final big ROM, being assembled with --longptr switch).
....
But it also depends what you need at runtime, and how you plan to address those data... The example in this answer is slightly Next-specific for NEX file output, where I know the loader ".nexload" did already load all banks into memory, and I can just switch banks and data are there. Although I believe the principle does apply also to regular zx128 (but loader is up to you).
- - - Updated - - -
If you are just asking the basic "can sjasmplus produce 1MB ROM files?", then the answer is simple yes.
It should not only be possible, but it should feel like well supported, by multiple possible approaches. If you hit some issue with that, surely report it.
If you have issue to choose initial approach, then describe better what you are trying to do, and add some examples what you expect while writing runtime code, and what is the form of input data you want to assemble together. :)
- - - Updated - - -
а можно сделать дописывание файла при помощи SAVEBIN?
Thinking about it second time, while answering the stuff above... you can also use DEVICE with large-enough memory, INCBIN everything into memory into continuous memory block, and SAVEDEV to big file. (I forgot to mention SAVEDEV before)
Shadow Maker
26.12.2020, 12:48
Ped7g just wanted to thank you for your continuing support of this assembler :) I believe you've spent hundreds of hours of your free time on it. Some people here were somewhat harsh, but you were always nice and sympathetic. Thank you! And keep up the good work :)
NEO SPECTRUMAN
27.12.2020, 22:30
SAVEBIN "part1.bin",$0000,$2000
а savebin происходит только во время pass 3 ?
а savebin происходит только во время pass 3 ?
Yes, it's saving bytes from DEVICE memory, which is not used in first passes during assembling, so it's completely zeroed in pass 1/2, and there's nothing to save.
The machine code production happens in third pass (also for OUTPUT/OUTEND/SAVETAP/... all the others).
(production = writing it... the machine code is "dry-simulated" in first 2 passes, ie. the assembler calculates how many bytes the instruction takes, to adjust labels, but then it throws away the opcode)
So in recent weeks I was abusing sjasmplus script a lot (as a form of test/exercise of the scripting implementation, some of the experience went into improving it just before v1.18.0 release)...
If you are serious about sjasmplus scripting, maybe you can pick up a trick or two from these:
https://github.com/ped7g/adventofcode
NEO SPECTRUMAN
05.01.2021, 01:54
tmp_cnt = 0
dup 10
if ((tmp_cnt = 0) || (tmp_cnt = 5) || (tmp_cnt = 7) || (tmp_cnt = 8))
display tmp_cnt," skip"
else
display tmp_cnt," ok"
endif
tmp_cnt = tmp_cnt +1
edup
display " "
tmp_cnt = 0
dup 10
if ((tmp_cnt != 0) || (tmp_cnt != 5) || (tmp_cnt != 7) || (tmp_cnt != 8))
display tmp_cnt," ok"
else
display tmp_cnt," skip"
endif
tmp_cnt = tmp_cnt +1
edup
display " "
tmp_cnt = 0
dup 10
if ((tmp_cnt =! 0) || (tmp_cnt =! 5) || (tmp_cnt =! 7) || (tmp_cnt =! 8))
display tmp_cnt," ok"
else
display tmp_cnt," skip"
endif
tmp_cnt = tmp_cnt +1
edup
display " "
tmp_cnt = 0
dup 10
if ((tmp_cnt <> 0) || (tmp_cnt <> 5) || (tmp_cnt <> 7) || (tmp_cnt <> 8))
display tmp_cnt," ok"
else
display tmp_cnt," skip"
endif
tmp_cnt = tmp_cnt +1
edup
> 0x0000 skip
> 0x0001 ok
> 0x0002 ok
> 0x0003 ok
> 0x0004 ok
> 0x0005 skip
> 0x0006 ok
> 0x0007 skip
> 0x0008 skip
> 0x0009 ok
>
> 0x0000 ok
> 0x0001 ok
> 0x0002 ok
> 0x0003 ok
> 0x0004 ok
> 0x0005 ok
> 0x0006 ok
> 0x0007 ok
> 0x0008 ok
> 0x0009 ok
>
> 0x0000 ok
> 0x0001 skip
> 0x0002 skip
> 0x0003 skip
> 0x0004 skip
> 0x0005 skip
> 0x0006 skip
> 0x0007 skip
> 0x0008 skip
> 0x0009 skip
>
test.asm(52): error: Syntax error: > 0) || (tmp_cnt <> 5) || (tmp_cnt <> 7) || (
tmp_cnt <> 8))
test.asm(52): error: ')' expected
почему не работает != ? o_O
почему =! дает какой то результат?
почему не работает != ? o_O
Looks all correct to me?
The first part is doing "skip" when cnt is 0 or 5 or 7 or 8
The second part is doing "ok" every time (first two "(cnt is not 0) or (cnt is not 5)" are enough to be always true for any cnt value)
The third part "=!" is parsed as: "=" is equivalence operator, "!" is logical not, so 0 becomes -1, and non-zero values become 0
That leads to "ok" when cnt is -1 or 0
Fourth is just syntax error, the "<>" operator doesn't exist in sjasmplus.
Did you want in second block negation of first block? Then: !(A || B) = (!A) && (!B)
(note the "logical or" becomes "logical and" when whole expression is negated)
tmp_cnt = 0
dup 10
if ((tmp_cnt != 0) && (tmp_cnt != 5) && (tmp_cnt != 7) && (tmp_cnt != 8))
display tmp_cnt," ok"
else
display tmp_cnt," skip"
endif
tmp_cnt = tmp_cnt +1
edup
NEO SPECTRUMAN
05.01.2021, 14:51
Looks all correct to me?
значит у меня не правильное понимание || и(людское) &&
и значит (|| людское and &&) != ((людское OR) людское and (людское AND)) :)
logical or (T = true [-1 in sj], F = false [0 in sj]):
F || F = F
T || F = T
F || T = T
T || T = T
logical and:
F && F = F
T && F = F
F && T = F
T && T = T
logical not:
!F = T
!T = F
And the general math rules for propagating logical not in complex expressions:
!(A < B) <=> A >= B
!(A == B) <=> A != B
!(A || B) <=> !A && !B
!(A && B) <=> !A || !B
...
https://en.wikipedia.org/wiki/Negation#Distributivity
sjamplus treats any non-zero value as true, and zero value as false, but when boolean-true is calculated, it is represented by ~0 (-1).
value = 4 ; value = 4
value = !4 ; value = 0
value = !!4 ; value = -1 (true)
( "людское ponimanje" => no idea what you are talking about, the math way is the only way I think about logic, even when talking in human language ... but there are many people not able to correctly negate predicate ... for example they ask you if you like blue colour, and you say "no", they will think you hate blue (which is incorrect negation "!like" is not "hate")) :)
NEO SPECTRUMAN
05.01.2021, 19:34
"людское ponimanje" => no idea what you are talking about,
не знаю как у вас
у нас когда люди говорят
если (if)
A не равно 1
или (or)
A не равно 5
тогда (then)
Ы = 7
если нет (else)
тогда Ы = 0
это имеется в виду (и это правильно)
if A <> 1
if A <> 5
Ы = 7
else
Ы = 0
endif
else
Ы = 0
endif
и ожидаемый результат
1 Ы=0
2 Ы=7
3 Ы=7
4 Ы=7
5 Ы=0
такое никогда не имеют в виду
if A <> 1
temp1 = 1
else
temp1 = 0
endif
if A <> 5
temp2 = 1
else
temp2 = 0
endif
if temp1 = 1
Ы = 7
else
if temp2 = 1
Ы = 7
else
Ы = 0
endif
endif
и такой рeзультат
1 temp1=0 or temp2=1 = Ы=7
2 temp1=1 or temp2=1 = Ы=7
3 temp1=1 or temp2=1 = Ы=7
4 temp1=1 or temp2=1 = Ы=7
5 temp1=1 or temp2=0 = Ы=7
совершенно неожиданный
людскими словами описывается совершенно другой процесс
а такой вариант правильный только с точки зрения машинной логики
и людскими словами описать его намного сложней (это будет достаточно много слов)
к вам претензий нет
просто это не совсем очевидный аспект
Bedazzle
06.01.2021, 23:51
это имеется в виду (и это правильно)
if A <> 1
Ы = 7
else
if A <> 5
Ы = 7
else
Ы = 0
endif
endif
Кривой код
else
Ы = 0
никогда не отработает
NEO SPECTRUMAN
07.01.2021, 00:24
никогда не отработает
пофиксил
поэтому и нужон долбанный список условий по типу if a=1,5,6
а не трехэтажные IF-ы
в которых можно чего то просмотреть
или нужны элементарные for и goto
чтоб не городить огород из dup-ов и if-ов
ТУПО пытаясь повторить их функционал
додо знаю щас ТЫ начнешь мне расказывать что
компилятор не должен это делать
это должен делать cpp, линкер, хренкер прочая ересь
и весь исходник должен состоят из батников
а компилятор должен только заменять nop на $00 и ничего более
и даже не должен делать переходы на метки вперед
и все метки для переходов должны быть предварительно объявлены в начале исходника
а то ж ведь компилятор еще не знает куда ему переходить когда код выглядит так
jp l1
l1
:v2_tong2:
не знаю как у вас
у нас когда люди говорят
если (if)
A не равно 1
или (or)
A не равно 5
тогда (then)
Ы = 7
если нет (else)
тогда Ы = 0
yeah, we say "if not equal to 1 and not equal to 5". I guess some people could use "or" there, but they are just using the language wrong, or not understanding the logic expressions. (mind you, while I didn't finish my university studies, I made it far enough to have all exams from math basics, like logic evaluation, so for me it's easy to use the language correctly in logic constructs ... but from my experience with people who didn't study it, it's common they don't understand the rules correctly, and say the wrong thing, while they think something else - very common by non-math people, it's not easy to formulate the rule correctly in human language, even by intelligent people, if they are missing the formal math teaching).
But I think your example is actually correct if read in certain way, like this: "if A not equal to (1 or 5), then B = 7, else B = 0" -> now this makes some sense also from math point of view, a bit like incomplete distribution of negation, so you end with something like "IF A != (1 || 5)", but if you expand it to simpler statements, it needs the || negation, so "IF A != 1 && A != 5"
Any way, you can in sjasmplus source always try to pick the "simpler to read", so if you are more familiar with "1 or 5", then do the positive form and negate the final result, like this:
IF !(A == 1 || A == 5 || A == 7)
;; other values of A (not 1 or 5 or 7)
ELSE
;; when A is 1 or 5 or 7
ENDIF
;; notice the "!" at beginning of the expression
;; flipping the final result of the test
NEO SPECTRUMAN
14.01.2021, 14:02
Ped7g, а можно добавить режим
чтоб при перезаписи выдавались предупреждения?
чтоб такой код
org $C000
xor a
xor b
xor c
xor d
org $C001
xor e
выдавал
warning $C001 was overwriten
ну и если не заводить отдельный массив для этого
то хотя бы проверять на $00 перед записью
nop-ов не так много в коде
и лучше хоть какая то проверка чем никакой...
Current status: no such feature
Future:
- not as default for sure, because there are projects using the pattern of device memory re-use to build different binary blocks at the same position (savebin/savetap between).
- as option: possible... sounds like some work, to develop some simple and fast code for it, as there is no simple test (except having usage-bitmap for whole device memory, but that sounds ugly. But maybe there is some other way, maybe some lists of ranges and checking for overlaps.
- workaround: use less `ORG`, use more `ds/align` to advance to next block of code, use ASSERT or MMU with "w" or "e" mode to guard you against making current section bigger than what you expected, etc...
But it sounds like non-trivial thing to add, and also you should be able to work-around it with ASSERT quite well. Switching one option ON would be even better, but doesn't feel to me like critical feature needed ASAP.
But I will keep it on mind... (maybe add enhancement-issue on github so I don't forget about it :D )
NEO SPECTRUMAN
16.01.2021, 02:59
- not as default for sure
это нужно только для отладочных проверочных целей
так как не всегда ясно правильно ли все расположено в памяти или нет
а проверить нет возможности
у меня 100% org-ов генерируется при помощи lua
а на сколько это правильно происходит в сочетании с макросами переменной длинны не ясно
- - - Добавлено - - -
use more `ds/align`
они не рационально расходуют память
NEO SPECTRUMAN
19.01.2021, 10:15
вот такая ошибочная конструкция не выдает ошибку и не генерирует никакой код
macro test
test
endm
org $8000
test
все что видно на экране
SjASMPlus Z80 Cross-Assembler v1.18.0 (https://github.com/z00m128/sjasmplus)
и найти эту ошибку трудно
с таким же успехом не работает такой не правильный код
macro exx
exx
endm
org $8000
exx
а вот такая конструкция прекрасно рабоатет
macro EXX
exx
endm
org $8000
EXX
я длительное время подобным пользовался и даже не замечал что это зацикленный макрос :)
For stuff like this - intentionally wanting to substitute legal instruction by your own macro:
macro exx
; exx ; infinite cycle
@exx ; Z80 exx, avoiding infinite cycle of macro calling
endm
you can use the "@" operator to prevent macro matching, ie. `@exx` inside macro definition to do real Z80 `exx`, and in your code you can then:
exx ; does the macro
@exx ; does the Z80 exx even if "exx" macro exists
The error messages and state recovery in case of infinite loops in DEFINE/MACRO definitions is really bad, sometimes it will raise max-nesting limit, sometimes it will just crash the assembler - I know about it, but I have currently no mood to work on this stuff
macro test
test
endm
org $8000
test
^^ this needs just few changes to be legit code, for example:
macro test
nesting = nesting - 1
IF 0 < nesting
test
ENDIF
endm
org $8000
nesting = 4
test
^^^ this is valid source, and will compile fine, but I don't see how you would consider it "different" from yours infinite example (except hitting some guardian-value to notice it's in cycle too much).
So it's not so easy to guard against it... there are some protections in sjasmplus which should catch infinite substitutions and loops, but they are not working that good at this moment, sorry. There's a room for improvement in this area, I agree.
https://github.com/z00m128/sjasmplus/releases/tag/v1.18.1
Big-Endian hosts support (experimental and not tested continuously)
added "listall", "listact" commands to OPT - to switch between listing types
WHILE has optional argument to set explicit guardian-counter
ASSERT has optional argument (to add description/notes for expression)
SLOT and MMU will now accept also starting address of slot instead of its number
fix: option --sym was not exporting labels starting with underscore
fix: SAVENEX BMP-loader bug when certain builds of sjasmplus were unable to open BMP files
fix: after STRUCT instance the "main" label is not polluted by last field of STRUCT
minor bugfixes in parser, windows cmake-builds have now icon
docs: adding "Index" section
docs: adding some missing information (__DATE__, __TIME__), fixing HTML anchor names
NEO SPECTRUMAN
09.02.2021, 10:50
13 0007 DD 8C ADC A,ixh ;* DD8C
14 0009
all_ops.asm(15): error: Label not found: IXh
15 0009 CE 00 ADC A,IXh ;* DD8C
yes, instructions and registers have to be same-case in sjasmplus. Labels are case sensitive.
NEO SPECTRUMAN
09.02.2021, 16:18
такой стиль написания используется в
The Undocumented Z80 Documented (Sean Young)
да и местами в оригинальной документации
https://jpegshare.net/images/97/92/9792631c8111f36bdddf2775351bf1e2.png
как то не хорошо получается...
- - - Добавлено - - -
я сначала подумал, что не все undoc opcodes поддерживаются...
I could be nitpicking that you are pointing onto "operation description", not source-syntax (that's "LD IY, (nn)")...
but I guess you are somewhat right, even the "IYh" in "operation" is unfortunate, and I see how you could expect sjasmplus to accept it.
But official documentation does only describe instruction, it does not define full syntax of "assembly" language, and it's quite common for assemblers to fill the gaps with their own rules. The same-case rule for instructions and registers is something I actually like, because then PascalCaseLabels can't be misunderstood as instructions by accident.
The most disturbing thing about your post is, that `OPT --syntax=i` will not accept "IYh" either, i.e. `Ld IYh,3` will fail even with `--syntax=i`, when `Ld iyh,3` works...
So I'm trying to make my mind, if this is bug or not. (do you have opinion?)
Otherwise what you see is "works as designed", not a bug.
But if we are talking about *you* writing *new* sjasmplus source, please just use same-case and avoid --syntax=i, I don't see how having mixed-case instructions/registers makes it better, IMO such source is harder to read. I know this is strongly personal and subjective topic, but I would suggest for new source style:
ORG $879A ; uppercase directives
PascalCaseLabelsWithColon:
ld iyh,3 ; lowercase instructions and registers
ld hl,12 ; HL = 12 (with uppercase reg in comments)
I can see how adding options to sjasmplus helps with legacy sources you don't want to edit, but for new sources I would stick to *some* style (even if you don't like my suggestion above, feel free to modify it to your liking, but I have difficult time to accept that all-case instructions+registers are a problem, especially as when writing assembly the actual writing of instructions usually takes very little time, so fixing formatting of source is just few seconds, compared to hours of thinking and debugging).
13 0007 DD 8C ADC A,ixh ;* DD8C
14 0009
all_ops.asm(15): error: Label not found: IXh
15 0009 CE 00 ADC A,IXh ;* DD8C
https://github.com/z00m128/sjasmplus/commit/7e184fdf3d9e0d78e8f1ea2a116ebadef44d6f9a
"parser: --syntax=i makes now also registers case insensitive"
... (listing)
12 0008 OPT --syntax=i ; test the syntax options "i"
13 0008 Label1:
14 0008 C3 08 00 Jp Label1
14 000B C3 08 00 jP Label1 ; instructions should be case insensitive
15 000E 00 00 Align 4
15 0010 aLiGN 4 ; directives too
16 0010 EB ex De,Hl ; registers should be also case insensitive
17 0011 DD 45 DD 4C ld b,IXl,c,IXh ; BTW this is actual way how Zilog describes half-ix regs
...
Still NOT recommended (by me), but possible, if you insist on it, and switch on the `--syntax=i` mode.
https://github.com/z00m128/sjasmplus/releases/tag/v1.18.2
new exist operator to check label existence
the --syntax=i mode makes now also register parsing case insensitive
minor bugfixes (predefined values, savenex BMP loader less strict about "colors used" content)
Dart Alver
14.03.2021, 15:28
Мне одному кажется что эту тему давно следовало бы пришпилить в "Важно:" , наравне с "SjASMPlus Z80 кросс ассемблер" или даже как более актуальную ?
Shadow Maker
18.03.2021, 00:56
Ped7g as a Linux user I am very interested in converting characters in "ENCODING" from UTF-8 to one of these (WIN/DOS). But unfortunately it does not work it seems. Is it possible to implement? Or maybe I am missing something here. Actually it would be nice to have a full-fledged iconv or similar, as now it is limited to russian encodings...
- - - Добавлено - - -
Мне одному кажется что эту тему давно следовало бы пришпилить в "Важно:" , наравне с "SjASMPlus Z80 кросс ассемблер" или даже как более актуальную ?
Да, готово. Просто ее постоянно поднимали, я и не заметил.
Ped7g as a Linux user I am very interested in converting characters in "ENCODING" from UTF-8 to one of these (WIN/DOS). But unfortunately it does not work it seems. Is it possible to implement? Or maybe I am missing something here. Actually it would be nice to have a full-fledged iconv or similar, as now it is limited to russian encodings...
I'm also on linux and used to utf-8 everywhere, so I do get your idea, but I'm not sure what/how to add to sjasmplus.
As ZX asm programmer I expect everything to be 8bit, so the utf8 -> 8bit conversion makes sense, but by what rules? In our ZX demos we often use custom encoding, not even some old DOS or win CP page, but completely custom one, so no generic tool will help much with that.
Maybe with Russian texts you have less mixing and use only few encodings, but I'm still not sure how to define one.
And finally the sjasmplus project currently doesn't contain any utf-8 implementation, so if I would link against iconv/similar, it will grow the dependencies list, so it should be rather something very well working feature, to make that cost worth it.
BTW if you need some standard win/dos encoding, I guess you can add into your makefile/build script the pre-build step using iconv itself, for example having .asm in utf8, and "building" .a80 files by implicit makefile rule using iconv similar to this:
$ echo "Мне одному кажется" | iconv -f UTF-8 -t CP1251 | hd
00000000 cc ed e5 20 ee e4 ed ee ec f3 20 ea e0 e6 e5 f2 |... ...... .....|
00000010 f1 ff 0a |...|
and then build the ".a80" with sjasmplus. If you use the utf-8 chars only within double quotes or comments, it should work.
So under linux, for general conversion like utf-8 -> cp1251 I don't feel sjasmplus needs any change, you can easily work around that (I have no idea if other OS have iconv and other powerful tools, maybe it's more difficult on other systems).
But if you guys have some cool ideas, how to bring into sjasmplus something even better, something what would do even things which iconv can't cover and|or makes life easier for people who use completely custom encoding, let me know.
But I can't imagine any particular nice syntax for some new directive covering these special cases, and when I recently was helping on one sjasmplus project which was "scrambling" text strings with custom xor-scheme to make strings hidden from simple view, I did end writing macro using the {b adr} memory read, changing the regular `db "some text"` into final scrambled bytes in DUP-loop produced by encoding macro. So even many of custom encodings (following some simple formula for 90% of chars and having only few special rules) could be done quite easily in sjasmplus with post-process macros.
Feels to me like it's not very difficult to resolve any of this use-cases even with current sjasmplus, but I have difficult time to imagine change which would help and be also elegant and worth implementing. (except the obvious utf8->cp1251 internal conversion, but that feels to me a bit useless, as I can use `iconv` for that already).
- - - Updated - - -
edit: to make that command line more complete, including the sjasmplus... :D (just for my own amusement and test)
$ echo "txt: db \"Мне одному кажется\"" | iconv -f UTF-8 -t WINDOWS-1251 | sjasmplus - --raw=- | hd
SjASMPlus Z80 Cross-Assembler v1.18.2 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
Pass 3 complete
Errors: 0, warnings: 0, compiled: 2 lines, work time: 0.001 seconds
00000000 cc ed e5 20 ee e4 ed ee ec f3 20 ea e0 e6 e5 f2 |... ...... .....|
00000010 f1 ff |..|
Shadow Maker
18.03.2021, 10:39
I'm also on linux and used to utf-8 everywhere, so I do get your idea, but I'm not sure what/how to add to sjasmplus.
Thanks for your detailed reply :) Yes, sure, I know how to do it without sjasmplus, but I feel shame that we have commands which are not really usable :)
In russian texts we usually use native dos or win russian encoding, custom encoding is also used, but it is not really common nowadays, when everyone have access to PC and code with sjasm, why invent something else :)
Only idea I have then is custom table approach (so basically a replacement list), so have it like:
replace_start "table1"
db "тест тест"
replace_end
or maybe this (but not sure what best way would be to select individual lines, so I added as a comment)
db "тест тест" ;replace "table1"
but not sure if it is really usable.
I'm not sure what you mean by those proposals.
Current sjasmplus reads source code in binary 8-bit mode, so whatever is inside double quotes in DB except few control codes which need to be escaped (`\0\n`) will be 1:1 assembled into machine code (I should probably do the test doing full 0..255 char string to be sure it works like that, yeah, I will add one).
So as ZX SW author, you have some encoding on mind (CP1251 or DOS-866 or some custom like 131 = "star" and 132-133-134 "group logo"), and you need to put those values (CP1251 azbuka chars or 131..134 bytes) into machine code, usually DB statement.
That's the result side. And the way how you edit those texts, for example Russian strings, is nice with UTF8 because of modern text editors using utf8 by default.
Current sjasmplus has this ENCODING directive, which makes possible auto-conversion from cp1251 to DOS-866 - it does nothing else, by default it does nothing, and if you do `ENCODING DOS` or use `--dos866` CLI option, any 128+ byte value in source code is transformed by hard-coded table converting CP1251 to DOS-866 (or "damaging" anything else, like UTF8).
So in case of Russian string, the task is "simple", do the utf8 -> cp1251 (or DOS-866) of source before the DB is assembled.
(BTW let's make clear one thing - I'm not going to add UTF8 support for symbol names, so anything outside of quotes does not need any extra support by sjasmplus, as anything non-ASCII is bug in source - the reasons are mostly overlapping with what I will write below, plus extra pain of sjasmplus processing source code heavily with custom implementation, not re-using common C++ library, so utf-8 symbols would cause major rewrite of parser - if somebody wants to do that, ok, but not me, the benefit of unreadable symbol names doesn't attract me at all, even if the code change would be simple)
But this "simple" case means the sjasmplus code will have to learn utf-8, and have the conversion table. And if there is Russian table, why not to add also some german, czech, etc...
... and you end up implementing `iconv` - which is by no means simple task, implementing utf-8 support correctly is major pain, I know of one C++ framework avoiding iconv and using custom code, and it took few years to polish that implementation enough to mostly work as expected.
And at that moment I don't see any benefit of putting iconv into sjasmplus, if I can call the iconv externally as I have shown in that example in previous post.
I can see some benefit of some magic directive which would allow me to define custom encoding, ie. that ★ is 130 and ☈☋☑ is 131,132,134, but I don't see any elegant and symple syntax for that, and the implementation again requires adding all the important parts of what iconv does, ie. understanding utf-8 encoding correctly.
So if you want just the "simple" utf-8 to cp1251 or dos-866 conversion, I'm failing to see why to bloat the sjasmplus code, and not call the external `iconv` as intermediate step before assembling. The result is same, but iconv is more robust and could handle all the common encodings, while sjasmplus will be always very limited in what it knows, unless I re-implement whole iconv into it (and go from ~300kB binary to ~5MB assembler).
- - - Updated - - -
So, I added the test to verify that "anything 8bit inside quotes (except the sensitive control codes) works":
https://github.com/z00m128/sjasmplus/blob/master/tests/misc/src_8bit_encoding.asm
The "sensitive control codes" contains three values: 0, 10 and 13 ("\0\n\r" escape sequences within double-quotes).
All the other 0..255 values are assembled 1:1 to machine code.
So this part of sjasmplus works "as intended" and there's no extra bug involved or any issue.
The [utf8 text source] -> [8bit source] conversion is IMO lot easier to handle externally, and I'm slightly against adding this functionality into sjasmplus (you can of course try to change my mind, but I don't see enough arguments at this moment).
I can see the convenience of such addition, but considering the current size of sjasmplus code and its build-dependencies, I find it not worth of adding utf-8 support, especially as the external usage of `iconv` is trivial in case of non-custom encoding, and does cover LOT MORE than just Russian encodings.
Maybe on non-linux OS the benefit of built-in conversion would be even bigger (if they don't have easy tool like `iconv`), but then again, it's lot more easier to install linux and use it for assembling ZX project, than to modify sjasmplus sources, so my general advice is to use modern OS, and not to reinvent the wheel again and again inside sjasmplus just because some other SW is obsolete. :v2_dizzy_snowball:
- - - Updated - - -
One more note... I was even going to propose to call `iconv` from the source with SHELLEXEC (to convert some small "strings.asm" and then INCLUDE the converted one), but it turns out that's not so easy. The SHELLEXEC does execute only in the last third pass, so the converted strings are not available in earlier passes. I guess you can still do this in lua-script, calling `iconv` in first pass to generate "strings.8b.asm" (cp1251 encoded) from "string.asm" (utf8 - what you edit in editor), and then INCLUDE the converted file - let me know if you need example how to do this.
But I generally prefer to not use lua scripts in my asm, so I would instead rather create Makefile with the rule to produce that converted file before assembling of main project. :)
Bedazzle
19.03.2021, 11:54
What about some kind of "translate" command, where you define two strings
source = "АБЦДЕФГ....."
target = "ABCDEFG...."
And later in code
call print_string
translate("АБЦД 123")
Sjasm is going to translate string char by char, and does put same symbol if it is not found in translator strings (like for 123 in example)?
Doesn't help that much until you implement utf-8 parsing. It could cover custom encodings 8bit -> 8bit, but then your syntax doesn't explain how you will define for example A -> 1, B -> 2, etc.. values which are not easy to enter into quotes.
Thinking about it, it's like two different issues. One is "utf-8 anything", and my answer is "no", I don't see how to add utf-8 support to sjasmplus without either adding lot of own code, or linking against some ICU-like library, but in either case raising the complexity and size of sjasmplus binary by whole order. And you can resolve the utf-8 by simply converting the source with `iconv` in the build script to some 8bit classic encoding, which then is assembled by sjasmplus correctly (I don't see anything problematic about this external way).
Second issue is "custom 8bit encoding" - I had to resolve few of these in my own ZX projects, and usually I enter the text in numbers or post-process the data by script written in sjasmplus macro. If the conversion would be even lot more complex, you can always do something very similar to what you propose with "translate(...)" in lua. So the status on this one is, that you can resolve it in current sjasmplus, but if somebody shows me more elegant syntax (to define custom encoding), I may implement that. Right now all the syntax I can imagine for such feature doesn't feel very attractive - I would have to study the docs before using it any way, to use it correctly, and in such case I could probably in similar time write the post-process macro changing the values in classic way in script code.
It just doesn't feel like I can add to sjasmplus something meaningful, what will help in most of the use cases and be easy to use, feels like I can add something what will work well for specific use-case, but will be mostly ignored by everyone else. Also I don't remember some nice solution from other assemblers to just copy it.
NEO SPECTRUMAN
22.03.2021, 13:12
тот же bug что и в define
macro coord_x x
var_x di : halt
data_x nop
sdfgj_x = var_x
endm
org $8000
coord_x ($5+1)
test.asm(8): error: Invalid labelname: var_($5
test.asm(17): ^ emitted from here
test.asm(8): error: Unrecognized instruction: ) di
test.asm(17): ^ emitted from here
test.asm(8): error: Unexpected: ) di
test.asm(17): ^ emitted from here
test.asm(9): error: Invalid labelname: data_($5
test.asm(17): ^ emitted from here
test.asm(9): error: Unrecognized instruction: ) nop
test.asm(17): ^ emitted from here
test.asm(9): error: Unexpected: ) nop
test.asm(17): ^ emitted from here
test.asm(10): error: Invalid labelname: sdfgj_($5
test.asm(17): ^ emitted from here
test.asm(10): error: Unrecognized instruction: ) = var_($5+1)
test.asm(17): ^ emitted from here
test.asm(10): error: Unexpected: ) = var_($5+1)
test.asm(17): ^ emitted from here
17 8000 coord_x ($5+1)
17 8000 >
test.asm(8): error: Invalid labelname: var_($5
test.asm(17): ^ emitted from here
test.asm(8): error: Unrecognized instruction: ) di
test.asm(17): ^ emitted from here
test.asm(8): error: Unexpected: ) di
test.asm(17): ^ emitted from here
17 8000 >var_($5+1) di
17 8000 76 > halt
test.asm(9): error: Invalid labelname: data_($5
test.asm(17): ^ emitted from here
test.asm(9): error: Unrecognized instruction: ) nop
test.asm(17): ^ emitted from here
test.asm(9): error: Unexpected: ) nop
test.asm(17): ^ emitted from here
17 8001 >data_($5+1) nop
test.asm(10): error: Invalid labelname: sdfgj_($5
test.asm(17): ^ emitted from here
test.asm(10): error: Unrecognized instruction: ) = var_($5+1)
test.asm(17): ^ emitted from here
test.asm(10): error: Unexpected: ) = var_($5+1)
test.asm(17): ^ emitted from here
17 8001 >sdfgj_($5+1) = var_($5+1)
17 8001 >
и если define это можно простить
то для macro это вообще недопустимое поведение
хотя отдельный replaceallmacro именно с этим же функционалом не помешал бы
кстати по ходу это уже давно
sjasmplus-1.11.0
# file opened: test.asm
test.asm(1): error: Invalid labelname:
6 0000 macro mcr x
7 0000 ~
8 0000 ~ label_x = 1
9 0000 ~
10 0000 endm
11 0000
15 0000 org $8000
16 8000
17 8000 mcr 4
17 8000 >
17 8000 >label_x = 1
17 8000 >
sjasmplus-1.12.0+
6 0000 macro mcr x
7 0000 ~
8 0000 ~ label_x = 1
9 0000 ~
10 0000 endm
11 0000
15 0000 org $8000
16 8000
17 8000 mcr 4
17 8000 >
17 8000 >label_4 = 1
17 8000 >
yes, the 1.11.0 (and older) had inconsistent behaviour, sometimes substituting `label_x` with "x" macro argument, sometimes not (I don't remember exact details how to trigger it, but it was fairly trivial to modify your example a tiny bit, and it would start substituting the `label_x` also in 1.11.0 ... IIRC all it takes is to have for example another label: `xmax` which doesn't get substituted, but will affect `label_x` ... or something like that... it's now two years since I fixed it, I would have to check the old code to be sure how to trigger the old bug.
The 1.12+ does consistently substitute sub-word (every time) - what you see is "fix". :D
To fix your source in later one, don't use trivial argument names like `x` ... I personally suggest `x?` for macro arguments, or you can add underscore to prevent mid-word substitution like `_x` for macro argument.
Unfortunately the current state is based on huge misunderstanding. The original patch (to one of 1.07 RC versions I think) had bug, causing it to substitute `x` also in `label_x` when certain conditions were met (in the define-hashtable, collision on the first letter, affecting size of "bucket" and making the "x" found even in case it should have been ignored). And there was test in old test suite, testing the bugged behaviour!
So initially I was confused by the inconsistency, and I fixed it, to make the substitution to work always, but I fixed it the way how the old test was verifying it. And the defines/macro-args starting with underscore can substitute only at beginning of identifier, not in the middle.
Few versions later I finally understood how the patch was originally meant, it was supposed to do sub-word substitution in the opposite way, only with identifiers which do start with underscore. But unfortunately the original author of the patch didn't put any comments into the code, and didn't provide any tests, and later somebody added the wrong test testing the bugged behaviour. If the original author would document his idea, I would fix it the correct way. :v2_confu:
NEO SPECTRUMAN
22.03.2021, 15:39
To fix your source in later one, don't use trivial argument names like `x`
я то не использую
а вот alone coder использует
и x и _ и __
и его исходники успешно не компилируются в z00m-овском sjasm
без подгонки кода напильником
macro ROTVERTEX2 x,z,y
if (xὀ)==0
;display "x>=0 x=",x
_x=(#1f-x)
_xsgn=0
else
;display "x<0 x=",x
_x=(#1f+x)
_xsgn=1
endif
_x=_x+#40
if (zὀ)==0 ;display "z>=0 z=",z
_z=(#1f-z)
_zsgn=0
else ;display "z<0 z=",z
_z=(#1f+z)
_zsgn=1
endif
_z=_z+#60
ld l,_x
endif
if _xsgn
sub (hl)
else
add a,(hl)
endif
endif
;z'
call div8xinch
push bc
__=$
endm
endif
if ((signὀ)==0)
if _==0
LD A,(HL)
else
ADD A,(HL)
endif
_=1
else ;((signὀ)!=0)
if _==0
xor a
sub (HL)
else
sub (HL)
endif
_=1
endif
endif ;sign
_hlneed=_hlneed+1
ENDM
а так мне иногда приходится жутко коверкать название меток
чтоб только обойти этот долбанный баг с define
а теперь еще таже гадость объявилась в макросах
...
Shadow Maker
22.03.2021, 16:20
I'm not sure what you mean by those proposals.
Basically I only want to see readable text inside same file. If we use some external convertor, then it would mean I have to:
1. Do a sh script which will compile everything
2. Do a generator, which will generate converted db "abwgde" strings.asm file and include that strings.asm file in main asm file
This is what I was actually wanted to avoid somehow. I would be happy, if you can give us some way to run shellexec and insert its results.
So like db #shellexec('iconv -f UTF8 -t CP866', 'КОНВЕРТИРУЙ ЭТО В 866') // obv this example will not work with real iconv, that's just to illustrate what I want to achieve
So results of shellexecuted script will be in DB. But this looks really bad, so it would be nice to have something like
strConvert equ 'iconv -t cp866'
and later in db would be something like
text1 db 'РУССКИЙ ТЕКСТ' | strConvert
So idea is to define a line for shellexec and by pipe send that text into shellexec for a defined line as a parameter. So above would mean, that you execute shellexec with 'iconv -t cp866 РУССКИЙ ТЕКСТ' (and as I told I understand that it would not work with iconv, but you can always write a wrapper for it or 3rd party convertor or maybe you can add some "convertor.exe" or anything, it does not matter much, if you can send and retrieve data the way I described, it would be really helpful, I think, not only for text conversions, but for many other things,
NEO SPECTRUMAN
22.03.2021, 17:03
I only want to see readable text inside same file.
lua power
lua allpass
string = "Ыячъэюф"
for temp = 1,string.len(string),1 do
sj.add_byte(string.byte(string,temp))
end
endlua
7 0000 lua allpass
8 0000 ~
9 0000 ~ string = "Ыячъэюф"
10 0000 ~
11 0000 ~ for temp = 1,string.len(string),1 do
12 0000 ~ sj.add_byte(string.byte(string,temp))
13 0000 ~ end
14 0000 ~
15 0000 DB FF F7 FA endlua
15 0004 FD FE F4
можно наверно запихнуть всё в одну функцию типа very_angry_russian_function("ЗлойРусскийТекст!!!")
и конвертировать на ходу во что угодно...
- - - Добавлено - - -
вот
lua allpass
function angry_russian_text(string)
for temp = 1,string.len(string),1 do
sj.add_byte(string.byte(string,temp))
end
sj.add_byte(0) --zero terminator
end
angry_russian_text("Злые русские пишут злые русские тексты")
angry_russian_text("несмотря ниначто!")
angry_russian_text("АХАХАХАХА АХАХАХАХА")
endlua
https://i.postimg.cc/qRv9k6qf/2021-03-22-161200.png
- - - Добавлено - - -
вот так делается масив
angry_array = {}
angry_array[1] = 0x0F
angry_array[2] = 0x0E
angry_array[3] = 0x1F
Basically I only want to see readable text inside same file. If we use some external convertor, then it would mean I have to:
1. Do a sh script which will compile everything
2. Do a generator, which will generate converted db "abwgde" strings.asm file and include that strings.asm file in main asm file
...
I would rather suggest option 1 for medium-large projects, as you can benefit from using tools like Make quite a bit. But let's assume you don't want to.
SHELLEXEC will execute first time in third pass, so any INCLUDE of results in first/second pass will have nothing to include. You can wrap INCLUDE in `IF 3 == __PASS__`, but that will probably cause different issues with labels changing values in final pass.
So if you really want to convert it from inside the .asm source, lua script is the only option (as lua script can execute already in first pass). I haven't tried it myself, but I guess you can call `iconv` from lua, cache the result for following passes, and add the bytes from the result every pass, like Neo shows with `sj.add_byte(...)`.
Also another option is to edit your sources in cp1251 or dos-866 encoding, depends on your editor, but I'm using Kate, and it does remember the encoding I was using for particular file, so once I switch it from utf-8 to something else, I can edit whole source in different encoding.
So with utf-8 files - in the end you can have macro `db_cp1251` and call it like:
db_cp1251 "some text"
which will call the lua script, and receive the converted bytes.
Syntax like "db 'РУССКИЙ ТЕКСТ' | strConvert" is problematic, as pipe is already binary-or operator, etc... plus you would have to wait until somebody creates the fix, while you can add macro+lua script with current sjasmplus (maybe not "easily", I would need to google a bit for lua syntax to write it, but should be like hour-two of work, let me know if you can't figure it out)
а так мне иногда приходится жутко коверкать название меток
чтоб только обойти этот долбанный баг с define
а теперь еще таже гадость объявилась в макросах
well, I'm pretty sure the macro arguments were sensitive to the old bug too. If Alone coder writes source like this, and it works in older sjasmplus versions (1.07), it may be just one change in label/macro argument away from breaking. The 1.12.0+ will break consistently always. :)
I guess you don't find it funny.... fair enough. But I'm not sure how to resolve it... maybe disabling mid-word substitution globally by some option? That sounds actually quite OK, it can help with importing project from different assemblers, and it would be optional change. - I can imagine adding this.
I don't like the idea of doing the "correct" fix (for "v1.x"), switching mid-word substitutions to identifiers with underscore only, it makes lot of sense on syntax level, but would break other sources which depend on the current substitution. (if I ever create some "v2.x", I'm definitely going to change the substitution rules, current situation is not good ... but I have currently no plans/timeline to work on "v2.x", not any time soon)
- - - Updated - - -
вот
Code:
lua allpass
function angry_russian_text(string)
But this works only if your current source encoding is cp1251? Lua doesn't do utf8->cp1251 conversion, right?? (too lazy to try)
But if you have source already in cp1251, you don't need to do anything, just use regular DB like `DB "Злые русские пишут злые русские тексты"` - it will work.
NEO SPECTRUMAN
22.03.2021, 17:41
But if you have source already in cp1251
DB like `DB "Злые русские пишут злые русские тексты"` - it will work.
у меня компилирует db и с utf8 (вроде бы)
а нужный конвертер можно написать на lua
у меня компилирует db и с utf8 (вроде бы)
yeah, of course sjasmplus will also assemble UTF8 source file, but then the resulting machine code is also UTF8 string, which is probably not what you want to process in Z80 assembly... :v2_dizzy_champagne:
Technically whatever binary values you have in source within quotes, the `DB` will emit 1:1 as is, nothing is damaged, except three values having special meaning: 0, 10 and 13. Those three must be escaped like "\0\n\r".
So the issue is how to write your source in utf8, but assemble into some other encoding like cp1251. And Czechs may want cp1250, etc, etc... there's hundreds of difference encodings.
The more we discuss it, the more I'm inclining toward these preferences (from the most simple and robust to worst):
1) edit the source in target encoding, if your text editor allows it
2) iconv the whole source as part of the build step (I'm usually building from text editor, where I can enter the whole sequence `iconv | sjasmplus ...` for single-file projects, or I tend to use makefiles for multi-file projects)
3) some lua script calling iconv from inside the asm (or implementing custom encoding which is not available in iconv set)
4) ??
10) enter in source the numbers instead of text like `msgTxt: HEX cc ed e5 20 ee e4 ed ee ec f3 20 ea e0 e6 e5 f2 f1 ff`
Anyway, at this moment of time I believe the encoding translations should be not part of sjasmplus, so I don't plan to add utf8->cp1251. If you prefer the lua script for that, but you don't know how to create such "db_1251" macro, let me know, I will create more complete example.
(^^ Shadow Maker ^^, but also anyone else struggling with it)
The 8bit->8bit transformations - some magic syntax to define and use the translation easily -> this one would be nice addition, but I'm failing to see that magic syntax which makes it considerably better than what sjasmplus already could do now (you can for example put the translation table into the DEVICE memory, and use `{b table+char}` to translate it in expressions, or just calculate the value for cases like ASCII -> 5 bit, similar to this https://github.com/ped7g/ZXSpectrumNextMisc/blob/master/snippets/strings5bPacked.i.asm#L26 (although this example also packs the 5bit values into bit-stream, so it's more complicated than just simple conversion).
But in summary, I have no plans to add anything to sjasmplus right now, in my eyes the current support is reasonable, and the missing bits can be filled in by iconv or macro/lua scripts.
-----------------------------------
NEO: so... how about the global option disabling mid-word substitution? Do you think that's a good idea? To enable macro/define identifiers like `x`, but not substitute them into `label_x` then.
NEO SPECTRUMAN
23.03.2021, 13:39
NEO: so... how about the global option disabling mid-word substitution? Do you think that's a good idea? To enable macro/define identifiers like `x`, but not substitute them into `label_x` then.
лично я сейчас нигде не использую замену внутри слов
а так как я пишу все слова через "_" и ненавижу unreadablewritestyle
эта внезапная замена вызывает только проблемы
тем более в командах от которых этого совершенно не ожидаешь
я бы сделал это отключение по умолчанию
но при этом было бы не плохо иметь midword_define midword_macro по отдельности
я уже много раз просил команды которые бы меняли все что угодно несмотря не на что
(как автозамена в любом текстовом редакторе)
по типу replaceall "44 l" "abc"
с результатом
label44 ldir
|
V
labelabcdir
:)
- - - Добавлено - - -
эта внезапная замена вызывает только проблемы
кстати
можно же писать все аргументы макроса вот так :v2_dizzy_roll:
macro maaacro X
label_x = X
endm
я уже пишу все что для difine через UPPERCASE чтоб не конфликтовало с ****_***
можно же такое делать и с макросами
но опять же
это лично я сижу в этой теме
и уже знаю некоторые не очевидные тонкости поведения sjasm
но другие же тут не сидят и не знают
и спотыкаются об это
Не верно компилирует метки из инклуд-файла.
Например, вместо #80D3 вставляет адрес #00D3.
75634
75635
https://cloud.mail.ru/public/RxiE/6xVeqhhnB
Dart Alver
18.06.2021, 20:48
Не верно компилирует метки из инклуд-файла.
Например, вместо #80D3 вставляет адрес #00D3.
Всё верно компилирует, вы неверно ORG выставили.
org ($+255)/256
а надо
($+255)/256*256
Ага. Точна.
Thanks.
Теперь работает.
75638
https://cloud.mail.ru/public/JQfk/MN7JxqR8A
SAM style
18.06.2021, 21:51
Всё верно компилирует, вы неверно ORG выставили.
org ($+255)/256
а надо
($+255)/256*256
Как только не извращаются люди, чтобы не делать align 256
не делать align 256
даже дерективу придумали чтобы не писать ds -$&0xff
it should be visible in listing, that the address after ORG is not what you expected... (I'm hinting to use listing files often, when you see unexpected result from assembler, often the listing shows where the wrong result start, and then you can search for real reason)
ALIGN 256 is probably least error prone, if I would be forced to use ORG, I would use probably something like `($+255)&$FF00`, but that's still a bit complex = more room for error. :)
Glad it works now, if you have further issue, post again. Have fun.
main.a80
org 50000
...
include "slave.a80"
Label1
....
slave.a80
...
org 30000
....
При компиляции Label1 возвращает адрес относительно slave.a80 (т.к. там org 30000). Есть какой нибудь механизм, чтобы включённый дополнительный исходный файл с частью кода выделенным адресом по ORG (здесь он стал от 30000) не влиял на Label1. А продолжал бы компилировать код от основного ORG, который был от 50000?
main.a80
org 50000
...
include "slave.a80"
Label1
....
slave.a80
...
org 30000
....
При компиляции Label1 возвращает адрес относительно slave.a80 (т.к. там org 30000). Есть какой нибудь механизм, чтобы включённый дополнительный исходный файл с частью кода выделенным адресом по ORG (здесь он стал от 30000) не влиял на Label1. А продолжал бы компилировать код от основного ORG, который был от 50000?
а что мешает разместить сначала include "slave.a80" и потом org 50000?
Вариант. Но если подключать нужно много разных сорцов, где много разных процедур, одноразовых или постоянных. Типа, как с "кучей" и "мусором" нужен механизм, хотя бы точка сборки.
И, ещё, тогда вопрос, как узнать при компиляции (в .sna) размер куска кода, либо того же slave.a80? Ещё бы в .sna это где-нибудь записать.
Black Cat / Era CG
28.06.2021, 20:55
Есть DISPLAY "Show len",/A,$-Start
Выдаст в консоль при компиляции.
Подробности в мануале.
Bedazzle
28.06.2021, 21:18
И, ещё, тогда вопрос, как узнать при компиляции (в .sna) размер куска кода, либо того же slave.a80? Ещё бы в .sna это где-нибудь записать.
device zxspectrum48
org $5B00
start_block:
....
end_block:
....
savebin "lode.bin", start_block, end_block-start_block ; сохраняем блок кода
savesna "lode.sna", game_start ; сохраняем снапшот со стартовым адресом
main.a80
org 50000
...
include "slave.a80"
Label1
....
slave.a80
...
org 30000
....
При компиляции Label1 возвращает адрес относительно slave.a80 (т.к. там org 30000). Есть какой нибудь механизм, чтобы включённый дополнительный исходный файл с частью кода выделенным адресом по ORG (здесь он стал от 30000) не влиял на Label1. А продолжал бы компилировать код от основного ORG, который был от 50000?
There is no "stack" to push/pop current address, but for simple code just to preserve/restore original address you can do either in main or in slave file:
org 50000
...
old_main_pc = $
include "slave.a80"
org old_main_pc
Label1
....
But I would rather consider moving `include "slave.a80"` to different part of source, like at beginning or end, so it's own `org` doesn't interefere with flow of main.
To get size of the piece of code, use labels and subtract them (`block_end-block_start` or `$-block_start` at the end of the block).
SAVESNA dumps "current" virtual memory of the device, all things assembled before the savesna line, but not the things assembled after.
\SJAsm\Source\main.a80(232): error: Unrecognized instruction: old_main_pc = $
\SJAsm\Source\main.a80(232): error: Label not found: old_main_pc
Что-то ему не нравится.
Что-то ему не нравится.
пробелы ему перед меткой не нравятся чтож еще
Black Cat / Era CG
10.07.2021, 02:24
а не знак =?
Bedazzle
10.07.2021, 10:21
а не знак =?
тоже подозреваю, что нужно EQU поставить
Dart Alver
10.07.2021, 10:41
Что-то ему не нравится.
Э-э-э А смысл конструкции 'old_main_pc = $' ? Это-ж всё равно что просто метку поставить. Нет, если там на выражение какое должно быть, то ещё смысл есть, а так ?
тоже подозреваю, что нужно EQU поставить
Ну вообще то как бы 'EQU' и '=' инструкции равнозначные. Нет скорее всего пробел виноват, как krt17 сказал.
in sjasmplus the EQU is like constant, = is like variable (it's a shortcut/alias for DEFL)
; this is possible/valid
var1 DEFL 0 ; var1 == 0
var1 DEFL var1+1 ; var1 == 1
var1 = var1+1 ; var1 == 2
; EQU is different
const1 EQU 10 ; const1 == 10
; this is invalid
const1 = 11 ; will raise error about different value assigned to label
So, in the upcoming v1.18.3 there will be `--syntax=s` switch to disable sub-word substitutions for particular piece of source... should make a bit easier to migrate from other assembler or other version of sjasmplus, if your old source has accidental substitutions in trivial define names.
Check at bottom test asm + lst to get exact idea what it does: https://github.com/z00m128/sjasmplus/commit/fbd29c5090f3a4efd4e96e988f2976ee36be3c11
(the default stays as it was, so you must explicitly to disable sub-word substitution by the new option)
Как использовать sjasм для компиляции для GB?
Как использовать sjasм для компиляции для GB?
To switch instruction set and syntax for GameBoy, use command line switch.
sjasmplus --lr35902 file.asm
The precise syntax of the instructions which differ between Z80 and LR35902 can be seen in the test files:
https://github.com/z00m128/sjasmplus/blob/master/tests/lr35902/LR35902_syntax_by_neo.asm
(will produce https://github.com/z00m128/sjasmplus/blob/master/tests/lr35902/LR35902_syntax_by_neo.lst )
That's about CPU instructions and their syntax.
How to build valid ROM for GB, with proper header, etc: I don't know, you need to know yourself what should be content of the ROM image, and build that with regular directives like DB/HEX/...
Maybe somebody here will have some helper macros to create ROM headers, or calculate checksum of ROM, if they already are using sjasmplus for GB, but I don't have such stuff for myself, and I never did GB stuff.
DUPL MACRO LEN,FILL
DUPL:
$$N EQU (LEN) / 1024
$$M EQU (LEN) # 1024
REPT $$N
DB 1024 DUP(FILL)
ENDM
IF $$M <> 0
DB $$M DUP(FILL)
ENDIF
ENDM
HIGH FUNCTION X,((X >> 8) & 0XFF)
LOW FUNCTION X,(X & 0XFF)
Это макросы из сорцов GSNEO (от savelij (http://svn.zxevo.ru/listing.php?repname=ngs&path=%2Fzx%2FNeo+Player+Light%2F&#ab26fb8aaba738ba3aa3861e67f0f4624)). Компилирует через asw (как я понял). В Sjasm ругается. Толком не пойму что здесь написано, макросы ещё не использовал. Можно это для sjasm привести в читаемый вид? Помогите.
Black Cat / Era CG
11.08.2021, 15:35
Для этих макросов, вроде в Сжасме есть готовые директивы.
Первый (DUPL), как я понял, просто заполняет LEN байт памяти байтом FILL.
Для этого есть BLOCK <length>[,<fill byte>] (DEFS <length>[,<fill byte>]).
Второе это старший/младший байты.
В Сжасме они есть тоже.
low low x low 8 bits of 16 bit value or lower part of register pair
high high x high 8 bits of 16 bit value or higher part of register pair
Не могу понять, как правильно работать с IFUSED?
DEVICE ZXSPECTRUM48
ORG 0x8000
main:
<code>
<code>
<code>
<code>
<code>
ret
include "address.asm" ; здесь объявлен модуль coords
include "out43.asm"
include "sto_rec.asm"
include "pause.asm"
include "windows.asm"
Главная программа.
module coords
ifused XxXxXxX
XxXxXxX <code>
<code>
<code>
<code>
ret
endif
Файл address.asm, в котором объявлен модуль coords.
module windows
CLS <code>
<code>
<code>
<code>
<code>
call coords.XxXxXxX
ret
Другой модуль, который ссылается на ссылку в модуле coords.
Pass 3 complete
Errors: 4, warnings: 0, compiled: 870 lines, work time: 0.015 seconds
The terminal process "C:\Program Files\PowerShell\7\pwsh.exe -Command sjasmplus --sld=test.sld --fullpath test.asm" terminated with exit code: 1.
Terminal will be reused by tasks, press any key to close it.
> Executing task: sjasmplus --sld=test.sld --fullpath test.asm <
SjASMPlus Z80 Cross-Assembler v1.18.2 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
windows.asm(91): error: Label not found: windows.coords.XxXxXxX
Результат...
Что неправильно?
upd
"Known bug: when code is using label inside module "moduleX", like call labelY, only usage of moduleX.labelY label is noted. Then if you define "labelY" outside of module and hide it inside IFUSED labelY block, the call from module will be unable to find the routine.
Workaround: you can use the global-label operator @: "call @labelY" to trigger usage of the global "labelY", or you can use the alternative IFUSED syntax "labelY: IFUSED" which does not only check condition, but also does define the label. Once the label is defined, the "call labelY" line inside module will find the global variant and mark it as "used" correctly."
Оно?
Вроде бы, оно...
Но новая беда - если написать
labelY: IFUSED
то не работают временные метки. :(
module n1
call @m1.used1
endmodule
module m1
ifused used1
used1
nop
jr 1F
nop
1
ret
endif
endmodule
Так работает, а с новым синтаксисом да, косяк.
Ну, у меня с @ не работает.
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
address.asm(25): error: [JR] Target out of range (+598)
address.asm(29): error: Local-labels flow differs in this pass (missing/new local label or final pass source difference)
address.asm(33): error: Local label not found: 4F
address.asm(36): error: Local-labels flow differs in this pass (missing/new local label or final pass source difference)
out43.asm(28): error: [JR] Target out of range (+434)
out43.asm(32): error: Local-labels flow differs in this pass (missing/new local label or final pass source difference)
windows.asm(18): error: Local-labels flow differs in this pass (missing/new local label or final pass source difference)
include data: name=font.fnt (768 bytes) Offset=0 Len=768
Pass 3 complete
Errors: 7, warnings: 0, compiled: 927 lines, work time: 0.031 seconds
The terminal process "C:\Program Files\PowerShell\7\pwsh.exe -Command sjasmplus --sld=test.sld --fullpath test.asm" terminated with exit code: 1.
Ну, у меня с @ не работает.
Не бывает у меня работает, у других нет. Значит ошибка в другом. Скорее всего ifused объявлен до использования, это в любом случае ошибка.
- - - Добавлено - - -
Хотя я проверял без инклюдов. В сиджасме они как выяснилось влияют не на совсем очевидные вещи.
Подпрограммы, которые я хочу использовать с ifused у меня в include лежат, которые размещены после ret главной программы. К меткам, которые объявлены в том модуле, который я хочу пометить как ifused, в любом случае, обращение происходит раньше по тексту программы, если это имеется в виду.
К тому же, непонятна связь между объявлением ifused и моментальной сразу же после этого потерей работоспособности временных меток.
address.asm(33): error: Local label not found: 4F
Хотя я проверял без инклюдов. В сиджасме они как выяснилось влияют не на совсем очевидные вещи.
Интересно, на какие, например?
Да это. Но то что вы написали в первом посту говорит о другом. Проверил с инклюдами, все в порядке.
Сделайте минимальный синтетический тест, будет попонятнее.
- - - Добавлено - - -
Интересно, на какие, например?
В старом обсуждении параллельной ветки был мой пример. Насколько я помню в этой ветке его вылечили, но помню я плохо, посему будем считать что проблем с инклюдом и ифюзед уже нет.
будем считать что проблем с инклюдом и ифюзед уже нет
В официальной документации к компилятору прямым текстом написано, что есть баг. С ifused. Про include, правда, там речь не идёт.
Да написано. Прочитали? Предложено пара воркараундов, один работает, во втором проблема с временными метками.
тест обеих случаев, Ped7g посмотрит разберется
device zxspectrum48
org 0x8000
start
module n1
call @m1.used1
call m2.used2
jr $
endmodule
module m1
ifused used1
used1
nop
jr 1F
nop
1
ret
endif
endmodule
module m2
used2: ifused
nop
jr 2F
nop
2
ret
endif
endmodule
savesna "usedtest.sna", start
the temporary number-labels may not work inside IFUSED, if the first pass doesn't already detect the label as used...
I did rewrite temporary label implementation in v1.11.1 I think? As it was not working correctly when amount of lines did change between passes, but thinking about it (not 100% sure), maybe now they don't mind changing amount of lines, but require to form the same list across all passes, so if some of them are missing because of IFUSED in first pass was false, then true later, the total list is different, and it maybe fails because of that.
If you have only few of them, consider to change them to local labels? Or include the libraries after the main code, when the IFUSED will already know in first pass, which routines are used?
Of course it would be better to fix sjasmplus, but that may take some time, or somebody else doing it, right now I'm waiting for z00m to release 1.18.3, not planning to work on sjasmplus this +-year.
Still, if you can produce some minimal failing example, it may help to target the bug easier.
About calling from one module to other ... the `call @other_module.function` is IMO best way, as that's what the source is really doing. Without "@" the label `my_module.other_module.function` is first-priority and other variants are searched only if that fails. Which usually still works for almost anything, except IFUSED. But I don't consider this 100% bug on sjasmplus side, it's heuristic, if you don't specify full global name, and as any heuristic - it's not perfect. (and there's no 100% correct fix for it, whatever you do, you can create anti-example where the new method will fail, as the whole concept is ambiguous).
... or you can try to zip your project and send it to me to see if I can quickly patch it to assemble with latest version (would be probably quicker to patch your sources, than sjasmplus... :D ...and maybe not).
- - - Updated - - -
ah, you (krt17 - thank you) did produce the minimal example. And seems I remember it correctly, the heuristic guessing what label you want to call at `call m2.used2` fails as the `n1.m2.used2` is first-priority in first pass, then the `used2: ifused` in first pass is "false", which makes the "2" temporary label non-existent in first pass.
You can fix such source either by being more explicit in the call using "@" to target the correct module `call @m2.used2`, or you can change the "2" temporary label to some local label. Using those number-labels inside IFUSED blocks is really bad idea since v1.11.1 ... and using them before is really bad idea too... Hmm... I guess it's just bad idea in any case. Use regular labels. :)
edit2: but I guess the temporary labels stuff is more like bug... maybe it could accept changes to the temporary labels list between first and second pass, but I'm not sure if that is enough to resolve this. I will keep that example around and maybe check it later, what can be done about it. 0xDEAD: anyway, thank you for reporting your issue, and sorry I don't have some perfect fix for you.
для сабжа временные метки это зло. никогда ими не пользовался. в плане обработки этих временных меток самый адекватный компилятор был от Microsoft - M80. Почему бы уважаемому Ped7g, не заглянуть в исходники M80 и не подчерпнуть некоторые методы там и не воткнуть в сабж? велосипед изобретать не нужно. всё давно украдено до нас...
hahaha... nice joke. :D
Let me check the M80 source and take those excellent routines directly into sjasmplus.... right after I will find the source... any minute now... :P :D
(or maybe I can disassemble it... and take a look at their IFUSED implementation... actually I got it's source right here:
Ok, that's a nice short source, also I don't see any obvious bugs, but I'm afraid it's not the best replacement for sjasmplus implementation, something is telling me sjasmplus is slightly better... )
Чё, проблема найти в интернете исходники M80?
ну держите...
дизасм, конечно, но довольно подробно комментированный.
Чё, проблема найти в интернете исходники M80?
the problem is the original author didn't give permissions to this, so it's useless. If they would want the M80 to survive and be useful, they would release the source themselves. Because they didn't release the source, they obviously want the M80 to be forgotten history, so the quicker it is lost, the better, to not fool some new users into wasting their time with dead and lost software.
In this way even if sjasmplus would be super bad implemented, it's still more valuable, because you can take not just binary of sjasmplus, but also any part of source, and use it for yourself any way you need.
But honestly, I'm not going even to read through that, usually when I read someone's else source, I see bugs, and then I try to fix them, and with M80 it's just waste of time. (I just finished review of expression evaluator of ZX Next assembler Odin, and it took me like 7 days to test it thoroughly and fix most of the bugs, see https://gitlab.com/next-tools/odin/-/merge_requests/42/diffs if you don't mind Z80N assembly - and that's only one file/functionality ... also I spent about 1.5 years fixing sjasmplus, not really wanting or planning, I was just in need of some Z80 assembler for myself, and instead of working on my Next projects, I did have a look at the source ... and what has been seen, can't be unseen, so I had to fix it .... and there you go, I released zero Next productions so far :( ... but about 10 versions of sjasmplus :) ).
Also I don't see any chance how it could help, as the architecture is completely different, M80 doesn't even have IFUSED (or lua scripts and other dynamic stuff), so whatever they do with temporary labels, they don't need to solve the issue which is demonstrated by krt17 example. And if you don't use the dynamic stuff like IFUSED, the current implementation of sjasmplus works too.
Or to rephrase it, if you take any source which can be assembled by M80, and you take it "as is", only fix syntax for sjasmplus, it will assemble. But this is not true the other way, if I take some more complex project which is assembled by sjasmplus and try to fix syntax for M80, I will hit issues with some missing features.
But, if *you* think there is some lesson to be learned in M80 and can be applied to current sjasmplus, and I'm wrong, all is not lost. You can just check the M80 source yourself, apply the knowledge to sjasmplus source (which *is* available for you), and create pull request on github so I can check the improvements and add them to the z00m's fork. Any improvements or helper hands are welcome, the sjasmplus will not improve on its own, only when people put effort into it, and create the improvements. :) Easy.
Ped7g, я тебе открою тайну. Ifused это костыль! Его сюда внедрили потому, что sjasm отродясь не умел работать с объектными файлами вроде REL файлов. Вот так можно собрать компактную библиотеку и вот тебе ifused. А может sjasm умеет нормально работать с условиями внутри макросов? Нет. А m80 уже 100 лет как умеет.
А может sjasm умеет нормально работать с условиями внутри макросов?
what do you mean?
https://github.com/z00m128/sjasmplus/releases/tag/v1.18.3
added --color to enable/disable ANSI coloring of errors/warnings
added --syntax=s mode to disable sub-word substitutions of DEFINEs
added at-sign prefix for macro local labels to act as non-macro local label
SAVETRD accepts names containing dot ("z.x.B" is "z.x" with extension "B") - by Dart Alver
SAVETRD has optional argument to save BASIC with variables (length_minus_variables)
minor bugfixes (conditional block parser)
So the `--syntax=s` may help with too aggressive substitutions, like macro arguments with name "x" ... not sure how much this helps for example with AloneCoder's sources, but should be a step forward. Let me know if there are more issues, maybe we will figure it out. :)
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. :)
---
With regard 1.18.4 ... not many plans yet, of course any bug fixes if some bugs are found, and Amstrad CPC snapshots are in the pipeline...
Dart Alver
31.08.2021, 18:04
Что-то странное происходит с функцией DISPLAY в королевстве Датском ;)
SjASMPlus Z80 Cross-Assembler v1.18.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
> [36mCompile BGE v3.12 (2021)[m
> [36mBased of Burial Gfx Editor v.3.o5 and Supreme-GUI[m
> [36m(c) Copyright Delirium Tremens from Freedom[m
> [36m(c) Copyright Sinn from Delirium Tremens[m
> [36m(2ooo-2oo1)[m
> [36m [m
include data: name=52f.bin (2048 bytes) Offset=0 Len=2048
> [36m End PGNJP adr : 0x60EE[m
> [36mEnd GuiVar:0x61B8[m
> [36mThis addres must be < 0x8000: 0x648E, 25742[m
> [36mResident GUI len :0x04F5, 1269[m
> [36mHM0x75F7[m
> [36mRGB: 0x0138, 312[m
> [36mPrimitive len :0x03CA, 970[m
> [36mMiniLoupe len :0x0387, 903[m
> [36mMFree : 0xA390, 41872[m
> [36mLenMFree : 0x0070, 112[m
> [36mSetUp len :0x109B, 4251[m
> [36m $iOV free :0x005E, 94[m
> [36m $iPL free :0x000D, 13[m
> [36m [m
> [36mRAM drivers for modeles[m
> [36m [m
> [36mlScorp1024 :0x001C, 28[m
> [36mlKAY256 :0x0015, 21[m
> [36mlKAY1024 :0x0023, 35[m
> [36mlS128 :0x000A, 10[m
> [36mlPen512 :0x0014, 20[m
> [36mlPen1024 :0x0013, 19[m
> [36mlATM1 :0x0017, 23[m
> [36mlTURBO2 :0x001D, 29[m
> [36mlPROFI :0x0017, 23[m
> [36m [m
> [36mLEN AUTOCONF :0x05A2, 1442[m
> [36mLength Init :0x07CD, 1997[m
> [36m Limit $ :0x0098, 152[m
> [36m(c) Sinn^dtr^fdm^2oo1[m
> [36mLength BGE :0x4390, 17296[m
> [36mFree for BGE :0x0070, 112[m
> [36m [m
> [36mAerosol len :0x0E0C, 3596[m
> [36mBrush len :0x10B9, 4281[m
> [36mBrush Free :0x004B, 75[m
> [36mSprites len :0x1ACB, 6859[m
> [36mSprites free:0x0035, 53[m
> [36mCHR len :0x08AC, 2220[m
> [36mFNT len :0x085F, 2143[m
> [36mFNT + CHR len :0x1116, 4374[m
> [36mSprtExport len :0x02DE, 734[m
> [36mSprtExport free:0x1822, 6178[m
> [36mSprHack len :0x045F, 1119[m
> [36mDiskSRV len :0x09B3, 2483[m
> [36mDiskSRV & SpHack len :0x0E1D, 3613[m
> [36mAbout len :0x05C7, 1479[m
> [36m [m
> [36mGUI [all] : 0x2E6B, [free] :0x0093, 147[m
> [36m [m
> [36mMISC len :0x012C, 300[m
> [36mFill len :0x0304, 772[m
include data: name=bgetxr.t8 (256 bytes) Offset=0 Len=256
include data: name=bgetxr.t16 (1024 bytes) Offset=0 Len=1024
> [36mTexture len :0x0A21, 2593[m
> [36mWinMenu len :0x0DB2, 3506[m
> [36mMGN len :0x12D2, 4818[m
> [36mCoordXY len :0x0161, 353[m
> [36mMScreen len :0x0271, 625[m
> [36mCOLORpgn len :0x08D1, 2257[m
> [36m [m
> [36mLenP6Free : 0x0488, 1160[m
> [36m [m
> [36m [m
include data: name=bge_spr (1696 bytes) Offset=0 Len=1696
> [36mBrs data len :0x0444, 1092[m
> [36mBox len :0x0369, 873[m
> [36mChnk len :0x05DF, 1503[m
> [36mObjects len :0x0F1B, 3867[m
> [36m [m
> [36mLenP7Free : 0x00B9, 185[m
> [36m [m
> [36m [m
> [36m [m
> [36m [m
Pass 3 complete
Errors: 0, warnings: 0, compiled: 51245 lines, work time: 1.206 seconds
you mean the ANSI color codes, or something else? And if you mean the color codes ("[36m" and "[m"), what terminal are you using or how do you process the sjasmplus output?
There is some heuristic trying to decide if the current terminal supports color codes, checking for environment variable "TERM" and if that variable exist, then it looks if it contains substring "color". So you can maybe check what your TERM env. variable value is.
If you are capturing the output to file, you may want to switch off color codes even if your terminal supports them.
so --color=off to disable them then.
Dart Alver
01.09.2021, 21:18
you mean the ANSI color codes, or something else? And if you mean the color codes ("[36m" and "[m"), what terminal are you using or how do you process the sjasmplus output?
so --color=off to disable them then.
Понятно... Новая версия - новые забавы :rolleyes:
Вывод производился в файл.
Ok ! Поправил скрипт, --color=off решает проблему.
Понятно... Новая версия - новые забавы
yeah... this is how it looks on my machine :)
76045
Ped7g, is it possible to save some area of RAM into the file? Looks like SAVEBIN works only at compile time, but I need to do this in runtime, i.e. load some block of code via INCBIN, do some conversions with it and save to the file? Obviously, it is not assembler's job, but who knows...
Something like
ld hl, #E000
xor a
ld (hl), a
inc a
ld (hl), a
SAVEBIN "file",#E000,#1
and I need to get in the file "file" value of 1, not 0.
ofc, I can save .sna, open it then with emulator, and save the block I need with TR-DOS, but it is not the straightforward way.
upd
ok, nevermind.
"-ms address size filename": Saves a memory dump to a file. The file is saved to the temp directory.
It is a command in debug console of DeZog extension for VSCode.
:v2_dizzy_heart:
But thanks in any case. :D
at runtime sjasmplus has no control over anything, it did already produce your machine code and exit, and that's all.
You could produce your own macros for common tasks under your OS, like TR-DOS calls, etc.. but that differs from every target platform (ZX/NextZXOS/TR-DOS/esxdos/MSX/...) and it all could be done in the form of Z80 source defining some macros or subroutines.
If the DeZog debugger command is enough for you, then even better.
Ped7g, One word about ABYTE(C|Z) pseudo-op.
Suddenly, if <bytes> argument enclosed in double quotes, it means in 99,99999% (if not 100%) just text, plain text. So, if I want to include in text some control characters, it works ok (mgs02). But, if I add an <offset> to ABYTE(C|Z), the control character gets same offset as text string (mgs01).
Why is it important (at least, for me)?
Imagine that we define some text string with ABYTEZ (wow) and print it out. As is known, ASCII codes in ZX font starts from 32d (space). So, if I want to calculate an 1st address of symbol's byte in font file, I need to subtract 32 from ASCII code of symbol being printed, then add this value to the start address of the font.
It can be done in two ways:
something like
ld a, (msg01)
sub 32
add a, l
ld l, a
jr nc, .skip
inc h
.skip
and this takes some CPU cycles and memory
or by defining an offset like this:
msg0 abytez -32 "01234567"
But abytez with offset breaks control codes.
So, I suggest to skip processing offset (only for double quoted content) for escape sequences (maybe except \\ one) in ABYTE(C|Z) pseudo-op.
http://i.piccy_.info/i9/c223189d23cccd91529f2ab3aff68656/1631099792/24901/1379577/12598Code_2021_09_08_13_52_51.png
p.s.
Don't tell me about LUA :-)
I think, LUA-script for EACH text string is an overhead, overkill and over-whatever-else in this simple case.
So, I suggest to skip processing offset (only for double quoted content) for escape sequences (maybe except \\ one) in ABYTE(C|Z) pseudo-op.
I'm afraid that would cause too much confusion with other users of previous versions.
I guess you can eventually patch your own sjasmplus to do this, or I could maybe add something like this under some extra option.
But I'm confused by your example reason:
So, if I want to calculate an 1st address of symbol's byte in font file, I need to subtract 32 from ASCII code of symbol being printed, then add this value to the start address of the font.
That's usually not done this way, but you instead have the font address already pointing to virtual char zero, ie. like ZX ROM has font address $3C00 (the sysvar CHARS at $5C36), and the actual data starts at $3D00 with space char, because 32 * 8 = 256 and $3C00 + 256 is $3D00
Similarly if you are fetching something from byte array for indices 4..7, you don't start with `ld hl,array` and do the full `array+index-4` math, but you start with `ld hl,array-4` already, adding only the index to it.
Maybe check first if you can simplify your code?
If you want to try your idea by patching sjasmplus, then in reader.cpp in `template <class strT> int GetCharConstAsString(char* & p, strT e[], int & ei, int max_ei, int add) {` (line 623 in v1.18.3 source) modify this part:
while (ei < max_ei && (quotes ? GetCharConstInDoubleQuotes(p, val) : GetCharConstInApostrophes(p, val))) {
e[ei++] = (val + add) & 255;
}
to something like this I guess:
while (ei < max_ei && (quotes ? GetCharConstInDoubleQuotes(p, val) : GetCharConstInApostrophes(p, val))) {
const int ascii_add = (' ' <= val && val < 0x80) ? add : 0; // use "add" value only for ASCII chars
e[ei++] = (val + ascii_add) & 255;
}
(but using patched version of sjasmplus will probably complicate things later, so I would first check if you can avoid it by some simple way)
(edit: no lua suggested, as you requested, instead we landed in the land of C++ :) )
- - - Updated - - -
actually, my confusion just adds up... imagine this:
ABYTEZ -32 "*\n"
The current sjasmplus will produce bytes: 0A EA 00
If I would add your idea to the sjasmplus, the produced bytes would be: 0A 0A 00
How do you plan in your code to know which 0A is the newline and which is the asterisk character? (and similar collisions for other control codes).
I'm afraid your proposal is too complicated and fragile for general-purpose directive like ABYTE, not planning to add it, sorry.
That's usually not done this way, but you instead have the font address already pointing to virtual char zero, ie. like ZX ROM has font address $3C00 (the sysvar CHARS at $5C36), and the actual data starts at $3D00 with space char, because 32 * 8 = 256 and $3C00 + 256 is $3D00
I know about this. But imagine a KOI-8 font, containing english and russian characters, where, for example, char "D" has code 65 and corresponding to it russian char "Д" has code 132?
Russian-speaking progammers often use transliteration from english in their code, because KOI8, CP866 and such not supported by software or/and hardware e.g., if you actually need to print string "Привет, как дела", you would define string "Privet, kak dela", and print it, using font, where code "P" corresponds to image of char "П", and so on - for readability.
lat_string abyte -32 "Hello\n how are you?"
rus_string abyte 32 "<what should I write here to keep \n value and get readable string?>"
The current sjasmplus will produce bytes: 0A EA 00
If I would add your idea to the sjasmplus, the produced bytes would be: 0A 0A 00
How do you plan in your code to know which 0A is the newline and which is the asterisk character? (and similar collisions for other control codes).
The initial idea was to reach string behavior like in Java/C++/C# (https://docs.microsoft.com/en-us/archive/blogs/csharpfaq/what-character-escape-sequences-are-available). But Spectrum is not PC, and assembler is not Java, everyone has their own print, draw, plot, beep... routines.
The sjasmplus does process source files as 8bit extended ASCII (except when you use `--dos866` option), so you can put in quotes anything except 0, 10 and 13. (those need to be replaced by \0,\n,\r.
So you can put the 132 for Д directly into string. The question is, how to edit such file conveniently, if you are using some common encoding like KOI-8 and your text editor understands different encodings, you can use it directly and write `DB "новые\nзабавы"`
Example from listing file (I did edit source in Kate switching to KOI8-R encoding):
22 8284 CE CF D7 D9 DZ "новые\nзабавы"
22 8288 C5 0A DA C1
22 828C C2 C1 D7 D9
22 8290 00
23 8291
If you insist on using ABYTE with some +- offset, you also do it in a bit more-typing way: ABYTEZ -32 "Ahoy*",10+32,"world" adjusting control codes by +32
This still of course doesn't solve the collisions:
23 8291 21 48 4F 59 ABYTEZ -32 "Ahoy*",10+32,"world"
23 8295 0A 0A 57 4F ; notice 2x 0A here, one is asterisk, other is "control code" 10+32
23 8299 52 4C 44 00
Or you can abuse it the other way, just checking in char table what is the control code with offset, and using '*' instead of \n in text to get value 10 after -32.
If your print routine is aware of the offset used to process the text, like -32, it could also check for modified control codes, ie. looking for $EA instead of $0A, which is probably the more correct way, as it does resolve the control-codes value collisions with offset characters.
If you have custom encoding, then it may be difficult to edit the file in text editor (I guess if I would define my own Locale in linux, the Kate editor would be maybe able to use it for editing, but I'm not sure, and I have no idea how much work it is). Then you can hypothetically have full 0..255 encoding exactly as you want it, including both English and Cyrillic characters in the font, or special symbols, etc... while being able to edit it conveniently in text form in some regular text editor.
But with some standard like KOI-8 and similar, you can mostly avoid these extra features by editing the text directly in target encoding.
Ped7g, hello
i have little problem
i make program and it will work from #0000 to #ffff
and labellist not created correctly
what can i do?
i make program and it will work from #0000 to #ffff
and labellist not created correctly
what can i do?
Sorry, but I don't understand what is the issue. Can you post some example?
Do you have issue with code starting at #0000? You can use ORG to change current address of assembling.
Sorry, but I don't understand what is the issue. Can you post some example?
Do you have issue with code starting at #0000? You can use ORG to change current address of assembling.
ok.
i compile this code.76141
labelslist "D:\_work\dropbox\_sources\___stoneage\user.l"
05:00AF T0XOffsL
05:01AF T0XOffsH
05:02AF T0YOffsL
05:03AF T0YOffsH
05:04AF T1XOffsL
05:05AF T1XOffsH
05:06AF T1YOffsL
05:07AF T1YOffsH
02:0000 stek
05:3FF1 starter
there is more labels but i see only this
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot