diff --git a/.gitignore b/.gitignore index 4b04142..eed0c78 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ .DS_Store +.firebase +.firebaserc /target **/*.rs.bk Cargo.lock pkg/ wasm-pack.log -www/node_modules www/dist +**/node_modules diff --git a/README.md b/README.md index a435994..6381fa7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ [![Build Status](https://travis-ci.com/d0iasm/rvemu.svg?branch=master)](https://travis-ci.com/d0iasm/rvemu) RISC-V online emulator with WebAssembly generated by Rust. The instruction sets in this emulator complies "The RISC-V Instruction Set Manual Volume I: Unprivileged ISA Document Version 20190608-Base-Ratified". +https://riscvemu.web.app/ + Supports the following RISC-V ISA features: - RV32I (v2.1): supports 37/40 instructions (except FENCE, ECALL, and EBREAK) - RV64I (v2.1): supports 12/12 instructions (SLLI, SRLI, and SRAI are included in RV32I) @@ -17,18 +19,17 @@ Supports the following RISC-V ISA features: The `wasm-pack build` command generates a pkg directory and makes Rust source code into `.wasm` binary. It also generates the JavaScript API for using our Rust-generated WebAssembly. The toolchain's supported target is `wasm32-unknown-unknown`. You need to execute this command whenever you change your Rust code. ``` -$ wasm-pack build --out-dir www/pkg +$ wasm-pack build --out-dir www/pkg --target web ``` -Use `npm init wasm-app www` just once to generate a www directory for a web page. Also, need `npm install` in a www directory at the first time and whenever you change a dependency in package.json. +This command installs dependencies in the `node_modules` directory. Need `npm install --save` in the `public` directory at the first time and whenever you change dependencies in package.json. ``` -$ npm init wasm-app www // at a root directory -$ npm install // at ./www directory +$ npm install --save // at the public directory ``` -You can see a web page via http://localhost:8080/ that reflects changes when we rus the wasm-pack build command. +You can see the website via http://localhost:8000. `npm start` is the alias of `python3 -m http.server` so you need Python3 in your environment. ``` -$ npm start +$ npm start // at the public directory ``` ## Test diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..6dd839b --- /dev/null +++ b/firebase.json @@ -0,0 +1,9 @@ +{ + "hosting": { + "public": "public", + "ignore": [ + "firebase.json", + "**/.*" + ] + } +} diff --git a/public/404.html b/public/404.html new file mode 100644 index 0000000..829eda8 --- /dev/null +++ b/public/404.html @@ -0,0 +1,33 @@ + + + + + + Page Not Found + + + + +
+

404

+

Page Not Found

+

The specified file was not found on this website. Please check the URL for mistakes and try again.

+

Why am I seeing this?

+

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

+
+ + diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..81bd50b --- /dev/null +++ b/public/index.html @@ -0,0 +1,31 @@ + + + + + RISC-V Emulator + + + + + + + +
+
+ + + diff --git a/public/index.js b/public/index.js new file mode 100644 index 0000000..e0e0397 --- /dev/null +++ b/public/index.js @@ -0,0 +1,181 @@ +import init, { Emulator } from "./pkg/rvemu.js"; + +const fileIn = document.getElementById("file"); +const buffer = document.getElementById("buffer"); + +const termContainer = document.getElementById("terminal"); +const term = new Terminal({cursorBlink: true}); + +console.log(Terminal); +console.log(FitAddon.FitAddon); + +const fitAddon = new FitAddon.FitAddon(); +const newLine = "\r\n$ "; +const deleteLine = "\x1b[2K\r"; + +const fileReader = new FileReader(); +let files = []; +let execute_once = false; + +async function initialize() { + // Load the wasm file. + await init(); + + term.loadAddon(fitAddon); + term.open(termContainer); + fitAddon.fit(); + + runTerminal(); + + buffer.addEventListener('DOMSubtreeModified', (e) => { + if (e.target.childNodes.length <= 0) { + term.write("$ "); + return; + } + const firstChild = e.target.childNodes[0]; + term.write(deleteLine); + term.writeln(firstChild.innerText); + e.target.removeChild(firstChild); + }); + + fileReader.onloadend = e => { + const emu = Emulator.new(); + const bin = new Uint8Array(fileReader.result); + emu.set_binary(bin); + emu.execute(); + }; + + fileIn.onchange = e => { + let names = ""; + for (let i=0; i { + term.write('\r\n$ '); + }; + + term.writeln("Welcome to RISC-V emulator"); + help(); + term.writeln(""); + prompt(); + + let input = ""; + let cursor = 0; + term.onKey(e => { + const printable = !e.domEvent.altKey && !e.domEvent.altGraphKey && !e.domEvent.ctrlKey && !e.domEvent.metaKey; + + if (e.domEvent.keyCode === 13) { // Enter key + command(input); + input = ""; + cursor = 0; + prompt(); + } else if (e.domEvent.keyCode === 8) { // Backspace key + // Do not delete the prompt + if (term._core.buffer.x > 2) { + input = input.substr(0, cursor-1) + input.substr(cursor); + if (cursor > input.length) { + cursor--; + } + term.write(deleteLine); + term.write("$ "); + term.write(input); + } + } else if (e.domEvent.keyCode === 37) { // Arrow left + if (cursor > 0) { + cursor--; + } + term.write(e.key); + } else if (e.domEvent.keyCode === 39) { // Arrow right + if (cursor < input.length) { + cursor++; + } + term.write(e.key); + } else if (printable) { + cursor++; + input = input.substr(0, cursor) + e.key + input.substr(cursor); + term.write(e.key); + } + }); +} + +initialize(); diff --git a/public/package-lock.json b/public/package-lock.json new file mode 100644 index 0000000..2d68fa0 --- /dev/null +++ b/public/package-lock.json @@ -0,0 +1,21 @@ +{ + "name": "rvemu", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "rvemu": { + "version": "file:pkg" + }, + "xterm": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.3.0.tgz", + "integrity": "sha512-6dnrC4nxgnRKQzIWwC5HA0mnT9/rpDPZflUIr24gdcdSMTKM1QQcor4qQ/xz4Zerz6AIL/CuuBPypFfzsB63dQ==" + }, + "xterm-addon-fit": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.3.0.tgz", + "integrity": "sha512-kvkiqHVrnMXgyCH9Xn0BOBJ7XaWC/4BgpSWQy3SueqximgW630t/QOankgqkvk11iTOCwWdAY9DTyQBXUMN3lw==" + } + } +} diff --git a/public/package.json b/public/package.json new file mode 100644 index 0000000..4991503 --- /dev/null +++ b/public/package.json @@ -0,0 +1,31 @@ +{ + "name": "rvemu", + "version": "0.1.0", + "description": "RISC-V emulator on a browser with WebAssembly generated by Rust", + "main": "index.js", + "scripts": { + "deploy": "firebase deploy", + "start": "python3 -m http.server" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/d0iasm/rvemu.git" + }, + "keywords": [ + "webassembly", + "wasm", + "rust", + "webpack" + ], + "author": "Asami Doi ", + "license": "MIT", + "bugs": { + "url": "https://github.com/d0iasm/rvemu/issues" + }, + "homepage": "https://github.com/d0iasm/rvemu", + "dependencies": { + "rvemu": "file:./pkg", + "xterm": "^4.3.0", + "xterm-addon-fit": "^0.3.0" + } +}