User Tag List

Показано с 1 по 10 из 699

Тема: SjASMPlus от z00m

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    Регистрация
    10.05.2019
    Адрес
    Prague, Czech Republic
    Сообщений
    229
    Спасибо Благодарностей отдано 
    51
    Спасибо Благодарностей получено 
    103
    Поблагодарили
    77 сообщений
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NEO SPECTRUMAN Посмотреть сообщение
    ...
    и как мне сделать на lua такое?


    lua (use code_size)

    code
    defb $01
    defb $01
    code_end
    code_size = code_end - code


    lua (use code_size)

    code
    defb $02
    defb $02
    defb $02
    code_end
    code_size = code_end - code

    lua (use code_size)

    code
    defb $03
    defb $03
    code_end
    code_size = code_end - code
    https://github.com/z00m128/sjasmplus...s/lua_examples

    Код:
            ;-----------------------------------------------------------------
            ; idea is from NEO SPECTRUMAN, who was trying to speed up "opcode" jumptable.
            ; implementation of Lua scripts and macros for sjasmplus is from Ped7g
                device zxspectrum48
    
            ;-----------------------------------------------------------------
            ; example of usage of the produced table (code provided by NEO SPECTRUMAN)
                org     $C000
            ; A = operation (alias "opcode") number 0..255
                ld      l,a                 ;4
                ld      h,high opJpTab      ;7
                ld      h,(hl)              ;7
                jp      (hl)                ;4
                                            ;=22t
    
            ;-----------------------------------------------------------------
            ; define LUA functions for memory allocations for opcodes functions
            ;
            ; (the ";" ahead of "end" and some "--" is not needed for Lua, but for my text
            ; editor sjasmplus syntax highlight, as it gets confused by lua source)
            ;
            ; Opcodes *must* be allocated in sequence (0,1,2 ...) to avoid large empty
            ; areas in memory, or even running out of memory completely. Also opcode
            ; implementation subroutines must be reasonably short (few bytes, not hundreds)
    
            lua pass1
                function allocateOpMemory(opcode)
                    -- search for free "page" (512B pages starting at opRoutines address)
                    freePage = _c("high opRoutines")
                    while allocatedPages[freePage] and opcode < allocatedPages[freePage] do
                        freePage = freePage + 2
                        -- +2 to operate over 512 bytes, with 256B pages high opcodes like FE
                        -- may overwrite following page where early opcodes like 01 resides
                    ;end
                    ; -- remember it for "finishOpAllocate" function
                    _G.lastFreePage = freePage
                    ; -- free page found, emit it into jump table
                    _pc(string.format("org $%04x", _c("opJpTab") + opcode))
                    _pc(string.format("db $%02x", freePage))
                    ; -- and reset ORG to target memory for opcode function body
                    _pc(string.format("org $%04x", freePage*256 + opcode))
                    _pl(string.format("opcode_%02x_impl:", opcode))
                ;end    -- ";" to make my Kate editor syntax highlight survive "end" in lua
    
                function finishOpAllocate()
                    assert(_G.lastFreePage, "allocateOpMemory not called yet")
                    allocatedPages[_G.lastFreePage] = _c("low $")
                ;end
    
                function setOrgAfterLastAllocated()
                    checkPage = _c("high opRoutines")
                    while allocatedPages[checkPage] do
                        lastAdr = checkPage*256 + allocatedPages[checkPage]
                        checkPage = checkPage + 2
                    ;end
                    assert(lastAdr, "no memory was allocated yet")
                    _pc(string.format("org $%04x", lastAdr))
                ;end
            endlua
    
            ;-----------------------------------------------------------------
            ; helper macros to make the lua calls one-liners in asm
            macro allocateOpMemory _opcode?
    @__allocateOpMemory_opcode = _opcode?
                lua allpass
                    allocateOpMemory(_c("__allocateOpMemory_opcode"))
                endlua
            endm
            macro finishOpAllocate
                lua allpass
                    finishOpAllocate()
                endlua
            endm
    
            ;-----------------------------------------------------------------
            ; global definitions and variables used to generate jump table
            
            ; jump table with "high" bytes of opcode function addresses
    opJpTab     equ     $7F00               ; must be 256B aligned, size 256B
            ; opcode functions will go into memory starting from $8000
    opRoutines  equ     $8000               ; must be 256B aligned, size dynamic (N * 512)
            ; reset all Lua global variables ahead of each assembling pass
            lua allpass
                allocatedPages = {}     -- reset allocated pages for every pass
                lastFreePage = nil
            endlua
    
            ;-----------------------------------------------------------------
            ; define opcode functions (builds also jump table and labels like "opcode_a1_impl")
    
                allocateOpMemory 0
                db      1, 2            ; fake "implementation" (just 1,2,3,4,... byte values)
                finishOpAllocate
    
                allocateOpMemory 1
                db      3, 4, 5
                finishOpAllocate
    
                allocateOpMemory 2
                db      6, 7, 8
                finishOpAllocate
    
                allocateOpMemory 3
                db      9, 10
                finishOpAllocate
    
                allocateOpMemory 4
                db      11
                finishOpAllocate
    
                allocateOpMemory 255
                db      12, 13, 14, 15, "this goes over into page $8100..81FF"
                finishOpAllocate
    
                lua allpass
                    setOrgAfterLastAllocated()
                endlua
    
            ;-----------------------------------------------------------------
            ; store result as binary blob for simple verification in hexa editor
                align   512, 0              ; fill also last page to full 512B first
                savebin "lua_build_jp_table.bin", opJpTab, $ - opJpTab
    I think this should work reasonably well... I had to raise "page" size to 512B to avoid memory overwrites from last opcodes like FF (with 256B you have either only 1B in "current page", or you need to know that following "page" was used for bigger opcode and beginning of the area is unused. So the memory efficiency will be not very good, probably having multiple almost-256B free blocks between, but on the other hand you don't need to place them manually... So as long as you can exchange a bit of memory for a convenience, this should be fine.

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2

    Регистрация
    22.05.2011
    Адрес
    г. Дзержинск, Украина
    Сообщений
    6,829
    Спасибо Благодарностей отдано 
    483
    Спасибо Благодарностей получено 
    663
    Поблагодарили
    513 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Ped7g Посмотреть сообщение
    allocatedPages[_G.lastFreePage] = _c("low $")
    С low $ не будет правильно работать!
    нужно так
    Код:
    op_allocated_pages[_G.op_allocator_last_free_page] = (_c("$")-(_G.op_allocator_last_free_page*256))
    (я у себя изменил названия всех переменных под стиль своего исходника)


    Цитата Сообщение от Ped7g Посмотреть сообщение
    while allocatedPages[freePage] and opcode < allocatedPages[freePage] do freePage = freePage + 2
    это сильно не экономично!

    lua_build_jp_table.asm
    лучше переименовать в lua_build_fast_jp_table.asm
    чтоб было очевидно что там не обычный вариант


    и все таки нужно как то измерять количество байт в процедуре
    между allocateOpMemory и finishOpAllocate

    завести массив с минимальным начальным адресом в странице

    чтобы можно было предотвратить перезапись кода
    и переместить процедуру в следующую свободную страницу



    может будет проще
    добавить средства генерации таких таблиц в сам sjasm?

    например мне нужно будет делать несколько таких таблиц одновременно
    при этом остается много места
    куда можно было бы поместить другие процедуры
    lua здесь уже не поможет
    или нужно индексировать каждый байт
    и искать свободное место немного по другому
    Последний раз редактировалось NEO SPECTRUMAN; 08.07.2019 в 20:19.

  4. #3

    Регистрация
    19.01.2017
    Адрес
    г. Арзамас
    Сообщений
    2,456
    Записей в дневнике
    42
    Спасибо Благодарностей отдано 
    8
    Спасибо Благодарностей получено 
    172
    Поблагодарили
    121 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NEO SPECTRUMAN Посмотреть сообщение
    ...там еще некоторое обсуждение велось в личке
    так что вникай сильней
    буду краток: не могу, у меня лапки.

    Цитата Сообщение от NEO SPECTRUMAN Посмотреть сообщение
    за одно скажи видел ли ты где то такие таблицы переходов?
    (именно ld h,(hl) а не кастрированный ld l,(hl) который иногда применяется)
    (я не видел))
    не помню. самое извратское, что я применял - стек для чанок.

    Цитата Сообщение от NEO SPECTRUMAN Посмотреть сообщение
    например мне нужно будет делать несколько таких таблиц одновременно
    при этом остается много места
    куда можно было бы поместить другие процедуры
    lua здесь уже не поможет
    а написать процедуру религия не позволяет?

  5. #4

    Регистрация
    22.05.2011
    Адрес
    г. Дзержинск, Украина
    Сообщений
    6,829
    Спасибо Благодарностей отдано 
    483
    Спасибо Благодарностей получено 
    663
    Поблагодарили
    513 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Shiny Посмотреть сообщение
    а написать процедуру религия не позволяет?
    конечно установщики это хорошо
    НО
    у меня куча условной компиляции и несколько вариантов процедур
    256+ самих процедур
    в данном случае заточено оно под 48к
    и даже нет гуи все через конфигурацию переменных в начале исходника

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

    такой вариант мне не подходит...

  6. #5

    Регистрация
    10.05.2019
    Адрес
    Prague, Czech Republic
    Сообщений
    229
    Спасибо Благодарностей отдано 
    51
    Спасибо Благодарностей получено 
    103
    Поблагодарили
    77 сообщений
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NEO SPECTRUMAN Посмотреть сообщение
    С low $ не будет правильно работать!
    Indeed, good catch. I will probably fix it by using _c("$&0x1F") in the official example, but your fix is correct too. (didn't verify my idea yet, but should be ok)

    это сильно не экономично!
    LUL. "... compiled: 119 lines, work time: 0.002 seconds" ... it's even less economic to comment on this point...

    и все таки нужно как то измерять количество байт в процедуре
    между allocateOpMemory и finishOpAllocate
    I'm not sure if I understand you... while inside the opcode-function code, you can measure byte usage at any particular spot by `code_size = $ - opcode_XX_impl` where "XX" is hexa opcode in lowercase (i.e. "opcode_1a_impl" for opcode 26 == 0x1a)

    I would need code size ahead before allocating memory for more optimal solutions, and that *is* problem. It can be probably worked around by defining each subroutine first as macro, and then assemble all of them twice, first time at $0000 to collect code size, second time at final destination. But such solution requires lot of cooperation, the macros for subroutines must be written in certain way, etc... not a prefect fit for generic example.

    завести массив с минимальным начальным адресом в странице

    чтобы можно было предотвратить перезапись кода
    и переместить процедуру в следующую свободную страницу
    *fresh new idea* Thinking about it... I can actually collect code-sizes during pass1 (unless the subroutine does something stupid with if/ifdef/dup to modify it's size between pass1 and pass3)... and use that info in pass2 and pass3 to create the final placement.

    That should be possible with current sjasmplus, maybe I will try to create it as "version 2" somewhere in the future.

    может будет проще
    добавить средства генерации таких таблиц в сам sjasm?
    I don't see how to fit that into sjasmplus in some nice versatile generic way. Also I already forgot all the "algorithm" stuff from the high school, so I can't even recall what was the optimal solution to "pack the boxes"... (can't even count how many times we had similar task at programming contests, hehe)

    If somebody will show me some good designs, how to do it (I mean designs of everything: syntax, docs, algorithm), and it will be compatible with current implementation, then it may happen, but so far only very few people did any kind of "pull request" with new improvements, and people who want to try must be prepared that I will comment on their code a lot and it may take several iterations before the code will be accepted.

    At this stage of development I don't want to spend my time on this, it's very specialized, while I have major general issues with labels, big memory and define substitutions.

    например мне нужно будет делать несколько таких таблиц одновременно
    при этом остается много места
    куда можно было бы поместить другие процедуры
    lua здесь уже не поможет
    или нужно индексировать каждый байт
    и искать свободное место немного по другому
    Lua is full scripting programming language. If your requirements needs O(N*M*K*J) complex algorithm, then so be it. Who cares. We are talking about hundreds of subroutines. I.e. even some ugly brute force O(N^4) on modern CPU will take maybe 10s to generate final machine code. I don't care. In my paid work right now I have Android Studio and I'm forced to use corporate notebook with windows and antivirus, so only "clean" of the project needs 20+ seconds (on my home notebook with linux the "clean" of large projects takes usually between 0.5s to 3s and most of that is that f*cking gradle starting up), and full rebuild takes 4 to 7 minutes. If I would have project build times at 10s, I would be super happy.

    The point is, that you *can* do it in Lua. You don't even need sjasmplus at all, you can just write machine code into file straight from the Lua script. It will be probably ugly and difficult to debug and maintain (the generator in Lua), and I would probably rather write it in C++, but stop crying in the way "it's not possible to do it in lua". It's just difficult and ugly, but by the Turing computational theory, if you can clearly (in computational way) specify the desired outcome, it surely can be calculated also in Lua. Or in Z80 machine code. Or in PHP. Or in hundreds of other programming languages.

    The question is not if it is possible, but which tool is best fit. For such complex generators the sjasmplus is currently a bit cumbersome. If you can do it better in some other assembler, just use it. Programming languages, compilators and assemblers are just tools. Pick the best one for your current task.

    And if you need more runtime memory, use ZX Spectrum Next ... ... 756kiB in base model, and some people will have them extended to 1.75MiB.... :P (or you can code for x86_64 and have gigabytes of memory available).

  7. #6

    Регистрация
    22.05.2011
    Адрес
    г. Дзержинск, Украина
    Сообщений
    6,829
    Спасибо Благодарностей отдано 
    483
    Спасибо Благодарностей получено 
    663
    Поблагодарили
    513 сообщений
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Ped7g Посмотреть сообщение
    756kiB in base model
    православный zx evo имеет 4MB

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

    Цитата Сообщение от Ped7g Посмотреть сообщение
    while inside the opcode-function code, you can measure byte usage at any particular spot by `code_size = $ - opcode_XX_impl` where "XX" is hexa opcode in lowercase (i.e. "opcode_1a_impl" for opcode 26 == 0x1a)
    если измерять так
    тогда боюсь мне не хватит 3 проходов компилятора...

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. SjASMPlus Z80 кросс ассемблер
    от Aprisobal в разделе Программирование
    Ответов: 1663
    Последнее: 19.06.2021, 01:36
  2. Исходники TR-DOS для SjASMPlus
    от Keeper в разделе Программирование
    Ответов: 20
    Последнее: 11.02.2011, 11:57
  3. Запуск STS из .sna, сгенерированного sjasmplus.
    от siril в разделе Программирование
    Ответов: 7
    Последнее: 11.10.2010, 21:33
  4. Breakpoints в связке Sjasmplus+UnrealSpeccy
    от Kurles в разделе Программирование
    Ответов: 19
    Последнее: 26.01.2009, 12:36
  5. Disturbed COverMAnia ( music disk with z00m music collection)
    от kyv в разделе Музыка
    Ответов: 10
    Последнее: 27.03.2008, 10:01

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •