Permalink
Browse files

save and load memory images!

  • Loading branch information...
robey committed Feb 24, 2013
1 parent ba0b8ef commit d442c7cc928f7d94d40dc19dc76ceedbda8d5716
Showing with 88 additions and 15 deletions.
  1. +6 −0 index.html
  2. +1 −1 src/carrot16/ui.coffee
  3. +3 −0 src/carrot16/webui/codeview.coffee
  4. +78 −14 src/carrot16/webui/project.coffee
View
@@ -44,6 +44,12 @@
<a id="menu-save">Save (download) &nbsp;&nbsp;<span class="pull-right">&#x25c6;S</span></a>
</li>
<li class="divider"></li>
+ <li>
+ <a id="menu-load-image">Open memory image...</a>
+ </li>
+ <li>
+ <a id="menu-save-image">Save memory image</a>
+ </li>
<li>
<a id="menu-disassemble">Disassemble<span class="pull-right">&#x25c6;D</span></a>
</li>
View
@@ -152,7 +152,7 @@ $(document).ready =>
$(document).bind "keydown", "alt+n", => (webui.Project.openNew(); webui.Project.saveSession(); false)
$(document).bind "keydown", "alt+o", => (webui.Project.load(); false)
$(document).bind "keydown", "alt+r", => (webui.Project.rename(); false)
- $(document).bind "keydown", "alt+s", => (webui.Project.save(); false)
+ $(document).bind "keydown", "alt+s", => (webui.Project.saveCode(); false)
$(document).bind "keydown", "alt+w", => (webui.Project.closeTab(); webui.Project.saveSession(); false)
$(document).bind "keydown", "alt+d", => (webui.Project.disassemble(); false)
@@ -279,6 +279,9 @@ CodeViewSet =
for v in @views then if v.getName() == name then return v
null
+ firstName: ->
+ if @views.length > 0 then @views[0].getName() else "none"
+
exports.CodeView = CodeView
exports.CodeViewSet = CodeViewSet
@@ -4,9 +4,11 @@ Project =
init: ->
$("#menu-new").click => (@openNew(); @saveSession())
$("#menu-load").click => @load()
- $("#menu-save").click => @save()
+ $("#menu-save").click => @saveCode()
$("#menu-close").click => (@closeTab(); @saveSession())
$("#menu-rename").click => @rename()
+ $("#menu-load-image").click => @loadImage()
+ $("#menu-save-image").click => @saveImage()
$("#menu-disassemble").click => @disassemble()
# thread "load" clicks through to the real file loader. (the web sucks.)
$("#load_input").bind("change", Project.finishLoading)
@@ -18,43 +20,105 @@ Project =
webui.Tabs.closeCurrent()
load: ->
+ $("#load_input").data("expect", "code")
+ $("#load_input").click()
+
+ loadImage: ->
+ $("#load_input").data("expect", "image")
$("#load_input").click()
finishLoading: (event) ->
file = event.target.files[0]
# reset the chosen file, so it can be chosen again later.
$("#load_input")[0].value = ""
+ expect = $("#load_input").data("expect")
+ switch expect
+ when "code" then Project.loadCode(file)
+ when "image" then Project.loadImage2(file)
+
+ download: (name, data) ->
+ # javascript voodoo begin!
+ window.URL = window.webkitURL or window.URL
+ a = $("<a/>")
+ a.attr("download", name)
+ url = window.URL.createObjectURL(data)
+ a.attr("href", url)
+ a.css("display", "hidden")
+ $("#body").append(a)
+ a[0].click()
+ a.remove()
+ setTimeout((=> window.URL.revokeObjectURL(url)), 60000)
+
+ logError: (message) ->
+ webui.LogPane.clear()
+ webui.LogPane.log(message)
+
+ loadCode: (file) ->
if not file.type.match("text.*")
- webui.LogPane.clear()
- webui.LogPane.log("Not a text file: " + file.name)
+ Project.logError("Not a text file: #{file.name}")
return
reader = new FileReader()
reader.onerror = (e) =>
- webui.LogPane.clear()
- webui.LogPane.log("Error reading file: " + file.name)
+ Project.logError("Error reading file: #{file.name}")
reader.onload = (e) =>
view = new webui.CodeView()
view.setName(file.name)
view.setCode(e.target.result)
view.activate()
reader.readAsText(file)
- save: ->
- window.URL = window.webkitURL or window.URL
+ saveCode: ->
if not webui.CodeViewSet.visible() then return
codeview = webui.Tabs.activePane.data("codeview")
- a = $("<a/>")
- a.attr("download", codeview.getName())
- a.attr("href", window.URL.createObjectURL(codeview.save()))
- a.css("display", "hidden")
- $("#body").append(a)
- a[0].click()
- a.remove()
+ @download(codeview.getName(), codeview.save())
rename: ->
if not webui.CodeViewSet.visible() then return
webui.Tabs.activePane.data("codeview").editName()
+ loadImage2: (file) ->
+ if not (file.size in [ 0x20000, 0x20002, 0x20004 ])
+ Project.logError("Image file isn't 128KB: #{file.name}")
+ return
+ reader = new FileReader()
+ reader.onerror = (e) =>
+ Project.logError("Error reading file: #{file.name}")
+ reader.onload = (e) =>
+ buffer = new Uint8Array(e.target.result)
+ if buffer.length == 0x20004
+ if buffer[0x20002] != 0x10 or buffer[0x20003] != 0x16
+ Project.logError("Not a memory image file: #{file.name}")
+ console.log buffer[0x20002]
+ return
+ endian = "big"
+ if buffer.byteLength > 0x20000 and buffer[0x20000] == 0xff
+ endian = "little"
+ for i in [0 ... 0x10000]
+ data = if endian == "big"
+ (buffer[i * 2] << 8) | (buffer[i * 2 + 1])
+ else
+ (buffer[i * 2 + 1] << 8) | (buffer[i * 2])
+ emulator.memory.memory[i] = data
+ webui.MemView.update()
+ reader.readAsArrayBuffer(file)
+
+ saveImage: ->
+ name = webui.CodeViewSet.firstName() + ".d16"
+ # make a memory buffer
+ buffer = new Uint8Array(0x20004)
+ for i in [0 ... 0x10000]
+ word = emulator.memory.peek(i)
+ buffer[i * 2] = (word >> 8) & 0xff
+ buffer[i * 2 + 1] = word & 0xff
+ # add byte order indicator
+ buffer[0x20000] = 0xfe
+ buffer[0x20001] = 0xff
+ # header to identify a memory image
+ buffer[0x20002] = 0x10
+ buffer[0x20003] = 0x16
+ blob = new Blob([ buffer ], type: "application/binary")
+ @download(name, blob)
+
loadSession: ->
@projectId = localStorage.getItem("c16:current-project")
if not @projectId?

0 comments on commit d442c7c

Please sign in to comment.