
Сообщение от
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.