2017-01-31 13 views
2

Я не уверен, что это подходящее сообщество для этого, но подумал, что я попробую.Как получить память PPU от FCEUX в Lua?

FCEUX является удивительным эмулятором для NES, который отличается функциями отладки. Он также предлагает пользователям возможность запускать сценарии Lua, которые имеют доступ к various emulator functions. Тем не менее, я не могу понять, как получить доступ к PPU memory РЭШ. Он предлагает прямой доступ к CPU memory и данным ПЗУ, но, похоже, не имеет прямого доступа к памяти PPU. Так как NES использует memory-mapped I/O, теоретически возможно получить данные из специальных адресов памяти ЦП, но это кажется громоздким, а также может помешать эмуляции.

Кто-нибудь знает, как программно извлечь память PPU через API Lua FCEUX? Если нет, знает ли кто-нибудь об эмуляторе, который имеет API для программной реализации PPU-памяти?

ответ

2

После осознания того, что «О, подождите, я программист, и FCEUX - это с открытым исходным кодом! Так что, может быть, я должен потратить время, чтобы посмотреть на их источник/репозиторий, чтобы узнать, могу ли я ответить на вопрос сам!» , я нашел ответ, который я искал:

Commit [r3327] on 22-Dec-2016: add ppu lua library, only has readbyte and readbyterange so far

так что, казалось бы, что на момент написания этой статьи, доступ к памяти ППУ с помощью Lua не возможно в текущей версии (2.2.3 выпущен 28- Июль-2016), но, скорее всего, будет доступна в следующем выпуске.

Кроме того, после проверки Nestopia и Jnes (двух других, по-видимому, наиболее популярных эмуляторов NES), похоже, что эти эмуляторы не предлагают такую ​​функциональность. Что касается наличия или отсутствия каких-либо других эмуляторов, которые предлагают эту функциональность, остается открытым вопросом, так как в настоящее время существует множество других эмуляторов для проверки.

2

Вот что я использую:

function memory.readbyteppu(a) 
    memory.writebyte(0x2001,0x00) -- Turn off rendering 
    memory.readbyte(0x2002) -- PPUSTATUS (reset address latch) 
    memory.writebyte(0x2006,math.floor(a/0x100)) -- PPUADDR high byte 
    memory.writebyte(0x2006,a % 0x100) -- PPUADDR low byte 
    if a < 0x3f00 then 
     dummy=memory.readbyte(0x2007) -- PPUDATA (discard contents of internal buffer if not reading palette area) 
    end 
    ret=memory.readbyte(0x2007) -- PPUDATA 
    memory.writebyte(0x2001,0x1e) -- Turn on rendering 
    return ret 
end 

function memory.readbytesppu(a,l) 
    memory.writebyte(0x2001,0x00) -- Turn off rendering 
    local ret 
    local i 
    ret="" 
    for i=0,l-1 do 
     memory.readbyte(0x2002) -- PPUSTATUS (reset address latch) 
     memory.writebyte(0x2006,math.floor((a+i)/0x100)) -- PPUADDR high byte 
     memory.writebyte(0x2006,(a+i) % 0x100) -- PPUADDR low byte 
     if (a+i) < 0x3f00 then 
      dummy=memory.readbyte(0x2007) -- PPUDATA (discard contents of internal buffer if not reading palette area) 
     end 
     ret=ret..string.char(memory.readbyte(0x2007)) -- PPUDATA 
    end 
    memory.writebyte(0x2001,0x1e) -- Turn on rendering 
    return ret 
end 


function memory.writebyteppu(a,v) 
    memory.writebyte(0x2001,0x00) -- Turn off rendering 
    memory.readbyte(0x2002) -- PPUSTATUS (reset address latch) 
    memory.writebyte(0x2006,math.floor(a/0x100)) -- PPUADDR high byte 
    memory.writebyte(0x2006,a % 0x100) -- PPUADDR low byte 
    memory.writebyte(0x2007,v) -- PPUDATA 
    memory.writebyte(0x2001,0x1e) -- Turn on rendering 
end 

function memory.writebytesppu(a,str) 
    memory.writebyte(0x2001,0x00) -- Turn off rendering 

    local i 
    for i = 0, #str-1 do 
     memory.readbyte(0x2002) -- PPUSTATUS (reset address latch) 
     memory.writebyte(0x2006,math.floor((a+i)/0x100)) -- PPUADDR high byte 
     memory.writebyte(0x2006,(a+i) % 0x100) -- PPUADDR low byte 
     memory.writebyte(0x2007,string.byte(str,i+1)) -- PPUDATA 
    end 

    memory.writebyte(0x2001,0x1e) -- Turn on rendering 
end 

В 2.2.3 это не похоже на работу на старом ядре ППУ, но на 2.2.2 это делает. Работает с новым ядром ppu на обеих версиях.