diff --git a/Numworks.js b/Numworks.js index 77df5a1..260850e 100644 --- a/Numworks.js +++ b/Numworks.js @@ -376,7 +376,7 @@ class Numworks { } if (!magikFound) { data["magik"] = false; - console.warn("No usermand magic") + console.warn("No userland magic") return data } @@ -516,7 +516,7 @@ class Numworks { const magik = 0xBADBEEEF; // Hack to handle corrupted slotInfo magik on old Upsilon Bootloader versions (pre 1.0.13) - data["slot"]["magik"] = (dv.getUint32(0x00, false) == magik) || (data["slot"]["magik"] = dv.getUint24(0x01, false) == 0xDBEEEF08); + data["slot"]["magik"] = (dv.getUint32(0x00, false) == magik) || ((dv.getUint32(0x00, false) & 0x00FFFFFF) == (magik & 0x00FFFFFF)); // Check if the data is valid if (data["slot"]["magik"]) { // Check if the end magic is present @@ -674,12 +674,23 @@ class Numworks { * * @param address Storage address * @param size Storage size. + * @param version Calculator version * * @return The storage, as a Blob. */ - async __retrieveStorage(address, size) { + async __retrieveStorage(address, size, version) { + if (version >= "24.2.0") { + await this.device.device_.selectAlternateInterface(this.device.intfNumber, 1); + } + this.device.startAddress = address; - return await this.device.do_upload(this.transferSize, size + 8); + let data = await this.device.do_upload(this.transferSize, size + 8); + + if (version >= "24.2.0") { + await this.device.device_.selectAlternateInterface(this.device.intfNumber, 0); + } + + return data } /** @@ -687,10 +698,19 @@ class Numworks { * * @param address Storage address * @param data Storage data. + * @param version Calculator version */ - async __flashStorage(address, data) { + async __flashStorage(address, data, version) { + if (version >= "24.2.0") { + await this.device.device_.selectAlternateInterface(this.device.intfNumber, 1); + } + this.device.startAddress = address; await this.device.do_download(this.transferSize, data, false); + + if (version >= "24.2.0") { + await this.device.device_.selectAlternateInterface(this.device.intfNumber, 0); + } } /** @@ -705,7 +725,7 @@ class Numworks { let pinfo = await this.getPlatformInfo(); let storage_blob = await storage.encodeStorage(pinfo["storage"]["size"]); - await this.__flashStorage(pinfo["storage"]["address"], await storage_blob.arrayBuffer()); + await this.__flashStorage(pinfo["storage"]["address"], await storage_blob.arrayBuffer(), pinfo["version"]); callback(); } @@ -718,7 +738,7 @@ class Numworks { async backupStorage() { let pinfo = await this.getPlatformInfo(); - let storage_blob = await this.__retrieveStorage(pinfo["storage"]["address"], pinfo["storage"]["size"]); + let storage_blob = await this.__retrieveStorage(pinfo["storage"]["address"], pinfo["storage"]["size"], pinfo["version"]); let storage = new Numworks.Storage(); diff --git a/Storage.js b/Storage.js index 9712f78..b22423f 100644 --- a/Storage.js +++ b/Storage.js @@ -14,7 +14,7 @@ class Storage { } async __encodePyRecord(record) { - var content = new TextEncoder("utf-8").encode(record.code); + var content = new TextEncoder("utf-8").encode(record.code.normalize('NFKD')); record.data = new Blob([ concatTypedArrays( @@ -48,7 +48,9 @@ class Storage { var name = record.name + "." + record.type; var encoded_name = concatTypedArrays( - encoder.encode(name), + // We remove non-ASCII characters as they often cause calculator crashs + // Upsilon.js don't support reading non-ASCII filenames + encoder.encode(name.replace(/[^\x00-\x7F]/g, "")), new Uint8Array([0]) ); @@ -165,7 +167,9 @@ class Storage { var dv = new DataView(await record.data.arrayBuffer()); record.autoImport = dv.getUint8(0) !== 0; - record.code = this.__readString(dv, 1, record.data.size - 1).content; + + var codeDataview = new DataView(await record.data.slice(1, record.data.size - 1).arrayBuffer()); + record.code = new TextDecoder("utf-8").decode(codeDataview); delete record.data; diff --git a/package.json b/package.json index b6b81a6..c7fd356 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "upsilon.js", - "version": "1.4.2", + "version": "1.5.0", "description": "Utility classes to interact with a Numworks calculator using WebUSB.", "main": "index.js", "scripts": {