Add bounded logical Z80 disassembly to shared MCP
This commit is contained in:
@@ -100,7 +100,7 @@ function exports.startplugin()
|
||||
instruction_step=true,step_over=true,step_out=true,
|
||||
bank_guard=true,deferred_breakpoints=true,console_print=true,
|
||||
shares=true,screen_pixels=true,screen_snapshot=snapdir~=nil,
|
||||
program_memory=true,list_ports=true},state=state}
|
||||
program_memory=true,list_ports=true,disassemble_logical=true},state=state}
|
||||
elseif command=="snapshot" then
|
||||
local result={state=state,time=now(),paused=machine().paused}
|
||||
local screen=first_screen()
|
||||
@@ -200,6 +200,23 @@ function exports.startplugin()
|
||||
end
|
||||
return {space="program",address=address,length=length,
|
||||
hex=table.concat(bytes),generation=generation}
|
||||
elseif command=="disassemble_logical" then
|
||||
stopped(request)
|
||||
local address=number(args.address,0xffff)
|
||||
local length=number(args.length,256)
|
||||
assert(length>=1 and address+length<=0x10000,
|
||||
"Дизассемблирование за пределами logical Z80")
|
||||
local path=directory.."/_disasm.txt"
|
||||
os.remove(path) -- Не возвращать файл от прежней команды при ошибке MAME.
|
||||
machine().debugger:command(string.format("dasm %s,0x%X,%d",path,address,length))
|
||||
local size=lfs.attributes(path,"size")
|
||||
assert(size and size>0 and size<=65536,"MAME не создал ограниченный disasm-файл")
|
||||
local file=assert(io.open(path,"rb"))
|
||||
local output=file:read("*a")
|
||||
file:close()
|
||||
os.remove(path)
|
||||
return {space="logical_z80",address=address,length=length,
|
||||
text=output,generation=generation}
|
||||
elseif command=="list_ports" then
|
||||
local result={ports={},truncated=false}
|
||||
local fields_seen=0
|
||||
|
||||
@@ -62,6 +62,10 @@ class McpSession:
|
||||
return self.call('read_program_memory', {'address': self._address(address),
|
||||
'length': length})
|
||||
|
||||
def disassemble_logical(self, address: str, length: int = 32):
|
||||
return self.call('disassemble_logical', {'address': self._address(address),
|
||||
'length': length})
|
||||
|
||||
def read_share(self, tag: str, address: str, length: int = 16):
|
||||
return self.call('read_share', {'tag': tag, 'address': self._address(address),
|
||||
'length': length})
|
||||
|
||||
@@ -224,7 +224,8 @@ class SessionController:
|
||||
self._emit('control', {'owner': None})
|
||||
return {'released': owner}
|
||||
if self.running and method in ('where', 'registers', 'read_memory',
|
||||
'read_program_memory', 'read_variable',
|
||||
'read_program_memory', 'disassemble_logical',
|
||||
'read_variable',
|
||||
'break_line', 'break_function'):
|
||||
raise SessionError('Операция требует остановленного CPU; сначала Pause')
|
||||
if method == 'status':
|
||||
@@ -328,6 +329,16 @@ class SessionController:
|
||||
result = self.session.bridge.request('program_memory',
|
||||
address=address, length=length)
|
||||
return {**result, 'bank_pages': mapping.bank_pages}
|
||||
if method == 'disassemble_logical':
|
||||
address = int(arguments['address'])
|
||||
length = int(arguments['length'])
|
||||
if address < 0 or address > 0xffff or length < 1 or length > 256 or \
|
||||
address + length > 0x10000:
|
||||
raise SessionError('Дизассемблирование: адрес 0..0xffff, длина 1..256')
|
||||
mapping = self.session.refresh()
|
||||
result = self.session.bridge.request('disassemble_logical',
|
||||
address=address, length=length)
|
||||
return {**result, 'bank_pages': mapping.bank_pages}
|
||||
if method == 'variables':
|
||||
return self.session.model.variables
|
||||
if method == 'read_variable':
|
||||
|
||||
@@ -77,6 +77,11 @@ def make_server(client: McpSession | ManagedMcpSession,
|
||||
"""Читать 1..4096 байт raw program space 0..0x3ffff; Z80 окна находятся в 0x10000+."""
|
||||
return client.read_program_memory(address, length)
|
||||
|
||||
@tool(annotations=reading)
|
||||
def disassemble_logical(address: str, length: int = 32) -> dict[str, Any]:
|
||||
"""Дизассемблировать 1..256 байт текущей logical Z80 памяти при stop; ответ содержит bank_pages."""
|
||||
return client.disassemble_logical(address, length)
|
||||
|
||||
@tool(annotations=reading)
|
||||
def list_ports() -> dict[str, Any]:
|
||||
"""Перечислить порты ввода MAME и поля с масками; результат ограничен по размеру."""
|
||||
|
||||
Reference in New Issue
Block a user