Preserve state across hot code reload!!
This commit is contained in:
parent
a5dbc5fcfc
commit
1db882c150
BIN
8Bitsy.dsk
BIN
8Bitsy.dsk
Binary file not shown.
25
asm/asm.fnl
25
asm/asm.fnl
|
@ -115,7 +115,7 @@
|
||||||
; takes the form [:op args]
|
; takes the form [:op args]
|
||||||
; pdat - a parsed dat; takes the form {:type type :addr addr ...}
|
; pdat - a parsed dat; takes the form {:type type :addr addr ...}
|
||||||
(local dat-parser {})
|
(local dat-parser {})
|
||||||
(fn new-block [last-symbol] {:type :block :pdats [] :symbols {} :globals {} : last-symbol})
|
(fn new-block [last-symbol] {:type :block :pdats [] :preserved {} :symbols {} :globals {} : last-symbol})
|
||||||
|
|
||||||
(fn parse-dats [block dats]
|
(fn parse-dats [block dats]
|
||||||
(each [_ dat (ipairs dats)]
|
(each [_ dat (ipairs dats)]
|
||||||
|
@ -139,7 +139,10 @@
|
||||||
(table.insert block.pdats pdat)
|
(table.insert block.pdats pdat)
|
||||||
(when pdat.globals
|
(when pdat.globals
|
||||||
(each [name _ (pairs pdat.globals)]
|
(each [name _ (pairs pdat.globals)]
|
||||||
(tset block.globals name (length block.pdats))))))))
|
(tset block.globals name (length block.pdats))))
|
||||||
|
(when pdat.preserved
|
||||||
|
(each [name pdat-preserved (pairs pdat.preserved)]
|
||||||
|
(tset block.preserved name pdat-preserved)))))))
|
||||||
block)
|
block)
|
||||||
|
|
||||||
(fn dat-parser.op [op]
|
(fn dat-parser.op [op]
|
||||||
|
@ -166,6 +169,13 @@
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(fn dat-parser.align [pad] {:type :pad :align (. pad 2)})
|
(fn dat-parser.align [pad] {:type :pad :align (. pad 2)})
|
||||||
|
(fn dat-parser.hot-preserve [[_ label & dats] block]
|
||||||
|
(let [preserve-block (new-block)]
|
||||||
|
(tset block.preserved label preserve-block)
|
||||||
|
(tset preserve-block.globals label true)
|
||||||
|
(parse-dats preserve-block [label])
|
||||||
|
(parse-dats preserve-block dats)
|
||||||
|
preserve-block))
|
||||||
|
|
||||||
(local pdat-processor {
|
(local pdat-processor {
|
||||||
:op {}
|
:op {}
|
||||||
|
@ -338,6 +348,17 @@
|
||||||
(self.dbgfile:close)
|
(self.dbgfile:close)
|
||||||
(set self.dbgfile nil))
|
(set self.dbgfile nil))
|
||||||
self)
|
self)
|
||||||
|
:read-hotswap
|
||||||
|
(fn [self machine]
|
||||||
|
(let [hotswap {}]
|
||||||
|
(each [_ block (pairs self.org-to-block)]
|
||||||
|
(each [label pdat (pairs block.preserved)]
|
||||||
|
(tset hotswap label (machine:read pdat.addr pdat.size))))
|
||||||
|
hotswap))
|
||||||
|
:write-hotswap
|
||||||
|
(fn [self machine hotswap]
|
||||||
|
(each [label bytes (pairs hotswap)]
|
||||||
|
(machine:write (self:lookup-addr label) bytes)))
|
||||||
:upload
|
:upload
|
||||||
(fn [self machine]
|
(fn [self machine]
|
||||||
(if machine.upload (machine:upload self)
|
(if machine.upload (machine:upload self)
|
||||||
|
|
|
@ -385,8 +385,9 @@
|
||||||
|
|
||||||
(fn vm.var [self name init]
|
(fn vm.var [self name init]
|
||||||
(self.code:append name [:jsr :$dovar]
|
(self.code:append name [:jsr :$dovar]
|
||||||
(if (= (type init) :table) init
|
[:hot-preserve (.. :G-HOT-PRESERVE- name)
|
||||||
[:dw init])))
|
(if (= (type init) :table) init
|
||||||
|
[:dw init])]))
|
||||||
|
|
||||||
(vm:def :$doconst ; usage: [jsr :$doconst] followed by two bytes
|
(vm:def :$doconst ; usage: [jsr :$doconst] followed by two bytes
|
||||||
(vm:reserve)
|
(vm:reserve)
|
||||||
|
|
|
@ -132,7 +132,7 @@
|
||||||
[:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)]
|
[:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)]
|
||||||
[:jmp (if (= (or map.loadword "") "") :next map.loadword)]))
|
[:jmp (if (= (or map.loadword "") "") :next map.loadword)]))
|
||||||
|
|
||||||
(vm.code:append :map-ptr [:db 0] :map-page [:db 0])
|
(vm.code:append :map-ptr [:db 0] [:hot-preserve :map-page [:db 0]])
|
||||||
(vm:word :map :lit :map-ptr :get)
|
(vm:word :map :lit :map-ptr :get)
|
||||||
(vm:word :entity-count :map 240 :+ :bget)
|
(vm:word :entity-count :map 240 :+ :bget)
|
||||||
(vm:word :map-player-yx-ptr 241 :+)
|
(vm:word :map-player-yx-ptr 241 :+)
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -45,7 +45,7 @@
|
||||||
[:vm :hires
|
[:vm :hires
|
||||||
:lit :map1 :load-level
|
:lit :map1 :load-level
|
||||||
(vm:forever
|
(vm:forever
|
||||||
(vm:hotswap-sync :lit :map1 :load-level)
|
(vm:hotswap-sync :full-redraw)
|
||||||
:interactive-eval-checkpoint
|
:interactive-eval-checkpoint
|
||||||
:handle-key
|
:handle-key
|
||||||
)
|
)
|
||||||
|
|
|
@ -87,6 +87,20 @@
|
||||||
(when self.monitor (self.monitor:shutdown-session))
|
(when self.monitor (self.monitor:shutdown-session))
|
||||||
(when (nrepl:connected?) (nrepl:disconnect))
|
(when (nrepl:connected?) (nrepl:disconnect))
|
||||||
(set self.breakpoints {}))
|
(set self.breakpoints {}))
|
||||||
|
(fn Machine.read [self addr len]
|
||||||
|
(-> (self:coro-eval
|
||||||
|
(.. "(let [bencode (require :bencode)
|
||||||
|
addr " addr "
|
||||||
|
len " len "
|
||||||
|
mem (. manager.machine.devices ::maincpu :spaces :program)]
|
||||||
|
(var bytes \"\")
|
||||||
|
(print :reading len :from addr)
|
||||||
|
(for [i 1 len]
|
||||||
|
(set bytes (.. bytes (string.char (mem:read_u8 (+ addr i -1))))))
|
||||||
|
bytes)"))
|
||||||
|
; result is piped through fennelview; have to eval it to turn it back into bytes
|
||||||
|
; would be nice if io.write worked
|
||||||
|
(fennel.eval)))
|
||||||
(fn Machine.write [self addr bytes]
|
(fn Machine.write [self addr bytes]
|
||||||
(if (> (bytes:len) 0x1000)
|
(if (> (bytes:len) 0x1000)
|
||||||
(do (self:write addr (bytes:sub 1 0x1000))
|
(do (self:write addr (bytes:sub 1 0x1000))
|
||||||
|
@ -103,11 +117,11 @@
|
||||||
(self:eval "(manager.machine:soft_reset)")
|
(self:eval "(manager.machine:soft_reset)")
|
||||||
(self:eval (string.format "(emu.keypost \"CALL-151\\n %xG\\n\")" (prg:lookup-addr prg.start-symbol))))
|
(self:eval (string.format "(emu.keypost \"CALL-151\\n %xG\\n\")" (prg:lookup-addr prg.start-symbol))))
|
||||||
(fn Machine.reboot [self] (self:eval "(manager.machine:hard_reset)"))
|
(fn Machine.reboot [self] (self:eval "(manager.machine:hard_reset)"))
|
||||||
(fn Machine.coro-eval [self code]
|
(fn Machine.coro-eval [self code ?handlers]
|
||||||
(var result nil)
|
(var result nil)
|
||||||
(local append-to-result #(set result (.. (or result "") $2)))
|
(local append-to-result #(set result (.. (or result "") $2)))
|
||||||
(self:eval code
|
(self:eval code
|
||||||
(self:coro-handlers (coroutine.running) {:value append-to-result :out append-to-result}))
|
(self:coro-handlers (coroutine.running) {:value append-to-result :out append-to-result} ?handlers))
|
||||||
(coroutine.yield)
|
(coroutine.yield)
|
||||||
(or result "<no result>"))
|
(or result "<no result>"))
|
||||||
(fn Machine.dbgcmd [self cmd ?handlers]
|
(fn Machine.dbgcmd [self cmd ?handlers]
|
||||||
|
@ -130,10 +144,14 @@
|
||||||
(fn Machine.hotswap [self prg-old prg-new]
|
(fn Machine.hotswap [self prg-old prg-new]
|
||||||
(local addr (prg-old:lookup-addr :debug-stub))
|
(local addr (prg-old:lookup-addr :debug-stub))
|
||||||
(self:set-bp addr
|
(self:set-bp addr
|
||||||
(fn [] (self:clear-bp addr)
|
#(util.in-coro (fn []
|
||||||
(prg-new:upload self)
|
(self:clear-bp addr)
|
||||||
(self:jump (prg-new:lookup-addr :on-hotswap))
|
(local hotswap (prg-old:read-hotswap self))
|
||||||
(self:continue))))
|
(prg-new:upload self)
|
||||||
|
(prg-new:write-hotswap self hotswap)
|
||||||
|
(self:jump (prg-new:lookup-addr :on-hotswap))
|
||||||
|
(self:continue)))))
|
||||||
|
|
||||||
(fn Machine.overlay [self prg-overlay]
|
(fn Machine.overlay [self prg-overlay]
|
||||||
(self:step)
|
(self:step)
|
||||||
(prg-overlay:upload self)
|
(prg-overlay:upload self)
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
(fn Session.shutdown-session [self]
|
(fn Session.shutdown-session [self]
|
||||||
(set self.queue [])
|
(set self.queue [])
|
||||||
(set self.in-progress false)
|
(set self.in-progress false)
|
||||||
(set self.sesion nil))
|
(set self.session nil))
|
||||||
|
|
||||||
(fn Session.cleanup-handlers [self]
|
(fn Session.cleanup-handlers [self]
|
||||||
{:status/done #(self:done-msg)
|
{:status/done #(self:done-msg)
|
||||||
|
@ -63,9 +63,11 @@
|
||||||
(fn Session.eval [self code ?handlers]
|
(fn Session.eval [self code ?handlers]
|
||||||
(self:send {:op :eval : code} ?handlers))
|
(self:send {:op :eval : code} ?handlers))
|
||||||
|
|
||||||
|
(fn Session.input-handler [self input]
|
||||||
|
{:status/need-input #(self:send-oob {:op :stdin :stdin input})})
|
||||||
|
|
||||||
(fn Session.eval-input [self code input ?handlers]
|
(fn Session.eval-input [self code input ?handlers]
|
||||||
(self:send {:op :eval : code}
|
(self:send {:op :eval : code}
|
||||||
(lume.merge (or ?handlers {})
|
(lume.merge (or ?handlers {}) (self:input-handler input))))
|
||||||
{:status/need-input #(self:send-oob {:op :stdin :stdin input})})))
|
|
||||||
|
|
||||||
Session
|
Session
|
||||||
|
|
Loading…
Reference in a new issue