honeylisp/link/mame.fnl

65 lines
2.1 KiB
Plaintext
Raw Normal View History

2020-11-08 20:36:38 +00:00
(local util (require :lib.util))
(local {: spawn : kill} (util.require :lib.spawn))
(local nrepl (require :link.nrepl))
(local Session (require :link.nrepl-session))
(local bencode (require :lib.bencode))
(local lume (require :lib.lume))
(fn start-mame [platform]
(spawn [:mame :-debug :-plugins :-pluginspath "/home/jeremy/src;/usr/share/mame/plugins" :-plugin :jeejah platform]))
(local Machine (Session:extend))
(fn Machine.new [self]
(Machine.super.new self {:out (fn []) :value (fn [])}))
(fn Machine.boot [self]
(when (not self.pid)
(set self.pid (start-mame :apple2p))))
(fn Machine.run [self]
(self:boot)
(self:connect))
(fn Machine.die [self]
(self:disconnect)
(when self.pid
(kill (- self.pid) 1)
(set self.pid nil)))
(fn Machine.running? [self] self.pid)
(fn Machine.connected? [self] self.session)
(fn Machine.connect [self]
(util.in-coro (fn []
(when (not (nrepl:connected?))
(util.waitfor
#(if (nrepl:connected?) true
(do (pcall #(nrepl:connect)) false))))
(self:init-session))))
(fn Machine.disconnect [self]
(when (nrepl:connected?) (nrepl:disconnect))
(set self.session nil))
(fn Machine.write [self addr bytes]
(self:send
{:op :eval
:code
"(let [bencode (require :bencode)
{: addr : bytes} (bencode.decode (io.read))
mem (-> (manager:machine) (. :devices ::maincpu :spaces :program))]
(print :writing (bytes:len) :to addr)
(for [i 1 (bytes:len)]
(mem:write_u8 (+ addr i -1) (string.byte (bytes:sub i i)))))"}
{:status/need-input #(self:send-oob {:op :stdin :stdin (bencode.encode {: addr : bytes})})}))
(fn Machine.reboot [self] (self:eval "(: (manager:machine) :hard_reset)"))
(fn Machine.coro-eval [self code]
(var result nil)
(self:eval code
(self:coro-handlers (coroutine.running) {:out #(set result $2)}))
(coroutine.yield)
(or result "<no result?>"))
(fn Machine.dbgcmd [self cmd]
(self:eval (.. "(-> (manager:machine) (: :debugger) (: :command \"" cmd "\"))")))
(fn Machine.continue [self] (self:dbgcmd :go))
(fn Machine.step [self] (self:dbgcmd :s))
(fn Machine.stop-at [self addr])
(Machine:new)
Machine