Rev 539 | Blame | Compare with Previous | Last modification | View Log | Download
# file opened: lua_build_jp_table.asm1 0000 ;-----------------------------------------------------------------2 0000 ; idea is from NEO SPECTRUMAN, who was trying to speed up "opcode" jumptable.3 0000 ; implementation of Lua scripts and macros for sjasmplus is from Ped7g4 0000 device zxspectrum485 00006 0000 ;-----------------------------------------------------------------7 0000 ; example of usage of the produced table (code provided by NEO SPECTRUMAN)8 0000 org $C0009 C000 ; A = operation (alias "opcode") number 0..25510 C000 6F ld l,a ;411 C001 26 7F ld h,high opJpTab ;712 C003 66 ld h,(hl) ;713 C004 E9 jp (hl) ;414 C005 ;=22t15 C00516 C005 ;-----------------------------------------------------------------17 C005 ; define LUA functions for memory allocations for opcodes functions18 C005 ;19 C005 ; (the ";" ahead of "end" and some "--" is not needed for Lua, but for my text20 C005 ; editor sjasmplus syntax highlight, as it gets confused by lua source)21 C005 ;22 C005 ; Opcodes *must* be allocated in sequence (0,1,2 ...) to avoid large empty23 C005 ; areas in memory, or even running out of memory completely. Also opcode24 C005 ; implementation subroutines must be reasonably short (few bytes, not hundreds)25 C00526 C005 lua pass127 C005 ~ function allocateOpMemory(opcode)28 C005 ~ -- search for free "page" (512B pages starting at opRoutines address)29 C005 ~ freePage = _c("high opRoutines")30 C005 ~ while allocatedPages[freePage] and opcode < allocatedPages[freePage] do31 C005 ~ freePage = freePage + 232 C005 ~ -- +2 to operate over 512 bytes, with 256B pages high opcodes like FE33 C005 ~ -- may overwrite following page where early opcodes like 01 resides34 C005 ~ ;end35 C005 ~ ; -- remember it for "finishOpAllocate" function36 C005 ~ _G.lastFreePage = freePage37 C005 ~ ; -- free page found, emit it into jump table38 C005 ~ _pc(string.format("org $%04x", _c("opJpTab") + opcode))39 C005 ~ _pc(string.format("db $%02x", freePage))40 C005 ~ ; -- and reset ORG to target memory for opcode function body41 C005 ~ _pc(string.format("org $%04x", freePage*256 + opcode))42 C005 ~ _pl(string.format("opcode_%02x_impl:", opcode))43 C005 ~ ;end -- ";" to make my Kate editor syntax highlight survive "end" in lua44 C005 ~45 C005 ~ function finishOpAllocate()46 C005 ~ assert(_G.lastFreePage, "allocateOpMemory not called yet")47 C005 ~ allocatedPages[_G.lastFreePage] = _c("$ & $1FF")48 C005 ~ ;end49 C005 ~50 C005 ~ function setOrgAfterLastAllocated()51 C005 ~ checkPage = _c("high opRoutines")52 C005 ~ while allocatedPages[checkPage] do53 C005 ~ lastAdr = checkPage*256 + allocatedPages[checkPage]54 C005 ~ checkPage = checkPage + 255 C005 ~ ;end56 C005 ~ assert(lastAdr, "no memory was allocated yet")57 C005 ~ _pc(string.format("org $%04x", lastAdr))58 C005 ~ ;end59 C005 endlua60 C00561 C005 ;-----------------------------------------------------------------62 C005 ; helper macros to make the lua calls one-liners in asm63 C005 macro allocateOpMemory _opcode?64 C005 ~ @__allocateOpMemory_opcode = _opcode?65 C005 ~ lua allpass66 C005 ~ allocateOpMemory(_c("__allocateOpMemory_opcode"))67 C005 ~ endlua68 C005 endm69 C005 macro finishOpAllocate70 C005 ~ lua allpass71 C005 ~ finishOpAllocate()72 C005 ~ endlua73 C005 endm74 C00575 C005 ;-----------------------------------------------------------------76 C005 ; global definitions and variables used to generate jump table77 C00578 C005 ; jump table with "high" bytes of opcode function addresses79 C005 opJpTab equ $7F00 ; must be 256B aligned, size 256B80 C005 ; opcode functions will go into memory starting from $800081 C005 opRoutines equ $8000 ; must be 256B aligned, size dynamic (N * 512)82 C005 ; reset all Lua global variables ahead of each assembling pass83 C005 lua allpass84 C005 ~ allocatedPages = {} -- reset allocated pages for every pass85 C005 ~ lastFreePage = nil86 C005 endlua87 C00588 C005 ;-----------------------------------------------------------------89 C005 ; define opcode functions (builds also jump table and labels like "opcode_a1_impl")90 C00591 C005 allocateOpMemory 091 C005 >@__allocateOpMemory_opcode = 091 C005 > lua allpass91 C005 ~ > allocateOpMemory(_c("__allocateOpMemory_opcode"))91 C005 >org $7f0091 7F00 80 >db $8091 7F01 >org $800091 8000 >opcode_00_impl:91 8000 > endlua92 8000 01 02 db 1, 2 ; fake "implementation" (just 1,2,3,4,... byte values)93 8002 finishOpAllocate93 8002 > lua allpass93 8002 ~ > finishOpAllocate()93 8002 > endlua94 800295 8002 allocateOpMemory 195 8002 >@__allocateOpMemory_opcode = 195 8002 > lua allpass95 8002 ~ > allocateOpMemory(_c("__allocateOpMemory_opcode"))95 8002 >org $7f0195 7F01 82 >db $8295 7F02 >org $820195 8201 >opcode_01_impl:95 8201 > endlua96 8201 03 04 05 db 3, 4, 597 8204 finishOpAllocate97 8204 > lua allpass97 8204 ~ > finishOpAllocate()97 8204 > endlua98 820499 8204 allocateOpMemory 299 8204 >@__allocateOpMemory_opcode = 299 8204 > lua allpass99 8204 ~ > allocateOpMemory(_c("__allocateOpMemory_opcode"))99 8204 >org $7f0299 7F02 80 >db $8099 7F03 >org $800299 8002 >opcode_02_impl:99 8002 > endlua100 8002 06 07 08 db 6, 7, 8101 8005 finishOpAllocate101 8005 > lua allpass101 8005 ~ > finishOpAllocate()101 8005 > endlua102 8005103 8005 allocateOpMemory 3103 8005 >@__allocateOpMemory_opcode = 3103 8005 > lua allpass103 8005 ~ > allocateOpMemory(_c("__allocateOpMemory_opcode"))103 8005 >org $7f03103 7F03 84 >db $84103 7F04 >org $8403103 8403 >opcode_03_impl:103 8403 > endlua104 8403 09 0A db 9, 10105 8405 finishOpAllocate105 8405 > lua allpass105 8405 ~ > finishOpAllocate()105 8405 > endlua106 8405107 8405 allocateOpMemory 4107 8405 >@__allocateOpMemory_opcode = 4107 8405 > lua allpass107 8405 ~ > allocateOpMemory(_c("__allocateOpMemory_opcode"))107 8405 >org $7f04107 7F04 82 >db $82107 7F05 >org $8204107 8204 >opcode_04_impl:107 8204 > endlua108 8204 0B db 11109 8205 finishOpAllocate109 8205 > lua allpass109 8205 ~ > finishOpAllocate()109 8205 > endlua110 8205111 8205 allocateOpMemory 253111 8205 >@__allocateOpMemory_opcode = 253111 8205 > lua allpass111 8205 ~ > allocateOpMemory(_c("__allocateOpMemory_opcode"))111 8205 >org $7ffd111 7FFD 80 >db $80111 7FFE >org $80fd111 80FD >opcode_fd_impl:111 80FD > endlua112 80FD 0C 0D 0E 0F db 12, 13, 14, 15, "this goes over into page $8100..81FF"112 8101 74 68 69 73112 8105 20 67 6F 65112 8109 73 20 6F 76112 810D 65 72 20 69112 8111 6E 74 6F 20112 8115 70 61 67 65112 8119 20 24 38 31112 811D 30 30 2E 2E112 8121 38 31 46 46113 8125 finishOpAllocate113 8125 > lua allpass113 8125 ~ > finishOpAllocate()113 8125 > endlua114 8125115 8125 allocateOpMemory 255115 8125 >@__allocateOpMemory_opcode = 255115 8125 > lua allpass115 8125 ~ > allocateOpMemory(_c("__allocateOpMemory_opcode"))115 8125 >org $7fff115 7FFF 82 >db $82115 8000 >org $82ff115 82FF >opcode_ff_impl:115 82FF > endlua116 82FF FF FF FF FF db 255, 255, 255, 255, 255 ; another going into second half116 8303 FF117 8304 finishOpAllocate117 8304 > lua allpass117 8304 ~ > finishOpAllocate()117 8304 > endlua118 8304119 8304 lua allpass120 8304 ~ setOrgAfterLastAllocated()121 8304 org $8405121 8405 endlua122 8405123 8405 ;-----------------------------------------------------------------124 8405 ; store result as binary blob for simple verification in hexa editor125 8405 00 00 00... align 512, 0 ; fill also last page to full 512B first126 8600 savebin "lua_build_jp_table.bin", opJpTab, $ - opJpTab127 8600# file closed: lua_build_jp_table.asmValue Label------ - -----------------------------------------------------------0x00FF __allocateOpMemory_opcode0x8000 X opcode_00_impl0x8201 X opcode_01_impl0x8002 X opcode_02_impl0x8403 X opcode_03_impl0x8204 X opcode_04_impl0x80FD X opcode_fd_impl0x82FF X opcode_ff_impl0x7F00 opJpTab0x8000 opRoutines