├── README.md ├── css └── main.css ├── .eslintrc.yml ├── index.html ├── js ├── main.js └── vm.js └── obj ├── rogue.js ├── 2048.js └── lc3os.js /README.md: -------------------------------------------------------------------------------- 1 | # lc3sim-js 2 | 3 | A JavaScript implementation of the LC-3 virtual machine, an educational computer architecture. 4 | 5 | [View live version here](https://rpendleton.github.io/lc3sim-js/) 6 | 7 | [Read tutorial here](https://www.jmeiners.com/lc3-vm/) 8 | -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: sans-serif; 3 | background-color: #eee; 4 | color: #333; 5 | } 6 | 7 | #container { 8 | max-width: 680px; 9 | margin: 0 auto; 10 | } 11 | 12 | #container > * { 13 | margin: 1rem; 14 | } 15 | 16 | #terminal { 17 | height: 360px; 18 | padding: 0.5rem; 19 | background-color: #1f1f1f; 20 | border-radius: 10px; 21 | border: 3px solid black; 22 | } 23 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | globals: 2 | Terminal: true 3 | VirtualMachine: true 4 | 5 | env: 6 | browser: true 7 | es6: true 8 | extends: 'eslint:recommended' 9 | rules: 10 | linebreak-style: 11 | - error 12 | - unix 13 | indent: 14 | - error 15 | - 4 16 | - SwitchCase: 1 17 | brace-style: 18 | - error 19 | - stroustrup 20 | quotes: 21 | - error 22 | - single 23 | semi: 24 | - error 25 | - always 26 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | LC-3 Virtual Machine 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |

lc3sim-js

16 |

lc3sim-js is a JavaScript implementation of the LC-3 virtual machine, an educational computer architecture.

17 |
18 | 19 |
20 |

Programs

21 |

Although lc3sim-js is capable of running any valid LC-3 program, this demo includes just two sample games:

22 |

23 | 24 | 25 |

26 |
27 | 28 |
29 | 30 |
31 |

Controls:

32 |

Any keys that are pressed while the terminal is focused will be forwarded to the VM.

33 |

34 | On mobile (or devices with a touch screen), swiping on the terminal will simulate WASD key presses. 35 | To send keys other than this, you can tap anywhere in the terminal to manually focus the terminal and open a keyboard. 36 |

37 |
38 | 39 |
40 |

More Information

41 |

Source code is available on GitHub at rpendleton/lc3sim-js.

42 |

43 | This project is based on a tutorial written by my friend and me. 44 | If you're interested in writing your own VM (or just want to learn more about the project), you can 45 | find the tutorial here. 46 |

47 |
48 |
49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var vm = new VirtualMachine(); 3 | 4 | Terminal.applyAddon(fit); 5 | 6 | var term = new Terminal({ 7 | theme: { 8 | background: '#1f1f1f' 9 | } 10 | }); 11 | 12 | var termContainer = document.getElementById('terminal'); 13 | term.open(termContainer); 14 | term.write('Choose a game to begin.\r\n'); 15 | term.fit(); 16 | 17 | // MARK: - display 18 | 19 | var pendingWrites = ''; 20 | 21 | vm.putChar = function(val) { 22 | var char = String.fromCharCode(val); 23 | if (char === '\n') char = '\r\n'; 24 | 25 | if (pendingWrites.length == 0) { 26 | window.requestAnimationFrame(() => { 27 | term.write(pendingWrites); 28 | pendingWrites = []; 29 | }); 30 | } 31 | 32 | pendingWrites += char; 33 | }; 34 | 35 | // MARK: - input 36 | 37 | var supportsTouch = 'ontouchstart' in document; 38 | var availableKeys = []; 39 | 40 | term.on('key', function(char, e) { // eslint-disable-line no-unused-vars 41 | if (char === '\r') char = '\n'; 42 | 43 | availableKeys.push(char.charCodeAt(0)); 44 | vm.interrupt(); 45 | }); 46 | 47 | vm.hasChar = function() { 48 | return availableKeys.length > 0; 49 | }; 50 | 51 | vm.getChar = function() { 52 | if (availableKeys.length > 0) { 53 | return availableKeys.splice(0, 1)[0]; 54 | } 55 | else { 56 | return 0; 57 | } 58 | }; 59 | 60 | // MARK: - loading 61 | 62 | function restartAndLoad(program) { 63 | term.clear(); 64 | 65 | if (!supportsTouch) { 66 | term.focus(); 67 | } 68 | 69 | vm.reset(); 70 | availableKeys = []; 71 | 72 | vm.loadOS(); 73 | vm.loadData(program); 74 | vm.schedule(); 75 | } 76 | 77 | window.restartAndLoad = restartAndLoad; 78 | 79 | // MARK: - gestures 80 | 81 | function recognizeGesture(touchStart, touchEnd) { 82 | // If both deltas are >= this threshold, we'll consider the swipe to be 83 | // diagonal and cancel it. 84 | var swipeDiagonalThreshold = 50; 85 | 86 | // If one of the detals is >= this threshold and the other is < the 87 | // diagonal threshold, we'll consider the swipe to be valid. 88 | var swipeMinimumThreshold = 75; 89 | var swipeThreshold = 75; 90 | 91 | var deltaX = touchEnd.x - touchStart.x; 92 | var deltaY = touchEnd.y - touchStart.y; 93 | 94 | if (Math.abs(deltaX) >= swipeMinimumThreshold && Math.abs(deltaY) < swipeDiagonalThreshold) { 95 | return deltaX > 0 ? 'd' : 'a'; 96 | } 97 | else if (Math.abs(deltaY) >= swipeMinimumThreshold && Math.abs(deltaX) < swipeDiagonalThreshold) { 98 | return deltaY > 0 ? 's' : 'w'; 99 | } 100 | else { 101 | return null; 102 | } 103 | } 104 | 105 | if (supportsTouch) { 106 | var touchStart; 107 | 108 | termContainer.addEventListener('touchstart', function(e) { 109 | touchStart = { 110 | x: e.changedTouches[0].screenX, 111 | y: e.changedTouches[0].screenY 112 | }; 113 | }); 114 | 115 | termContainer.addEventListener('touchend', function(e) { 116 | var touchEnd = { 117 | x: e.changedTouches[0].screenX, 118 | y: e.changedTouches[0].screenY 119 | }; 120 | 121 | var recognizedGestureKey = recognizeGesture(touchStart, touchEnd); 122 | touchStart = null; 123 | 124 | if (recognizedGestureKey !== null) { 125 | availableKeys.push(recognizedGestureKey.charCodeAt(0)); 126 | vm.interrupt(); 127 | } 128 | }); 129 | } 130 | })(); 131 | -------------------------------------------------------------------------------- /obj/rogue.js: -------------------------------------------------------------------------------- 1 | window.lc3_rogue = new Uint8Array([ 2 | 0x30, 0x00, 0xe0, 0x03, 0xf0, 0x22, 0xf0, 0x20, 0x0e, 0x39, 0x00, 0x57, 3 | 0x00, 0x65, 0x00, 0x6c, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x65, 4 | 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x43, 5 | 0x00, 0x33, 0x00, 0x20, 0x00, 0x52, 0x00, 0x6f, 0x00, 0x67, 0x00, 0x75, 6 | 0x00, 0x65, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 7 | 0x00, 0x20, 0x00, 0x57, 0x00, 0x53, 0x00, 0x41, 0x00, 0x44, 0x00, 0x20, 8 | 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x76, 9 | 0x00, 0x65, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x50, 0x00, 0x72, 0x00, 0x65, 10 | 0x00, 0x73, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x79, 11 | 0x00, 0x20, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x2e, 0x00, 0x2e, 12 | 0x00, 0x0a, 0x00, 0x00, 0x2c, 0x53, 0x48, 0xd5, 0x20, 0x57, 0x02, 0x03, 13 | 0x48, 0x93, 0x48, 0x56, 0xf0, 0x25, 0x50, 0x20, 0x30, 0x51, 0xe0, 0x06, 14 | 0xf0, 0x22, 0xf0, 0x20, 0x22, 0x46, 0x12, 0x01, 0x0b, 0xf1, 0xf0, 0x25, 15 | 0x00, 0x59, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x20, 0x00, 0x73, 0x00, 0x75, 16 | 0x00, 0x72, 0x00, 0x76, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x64, 17 | 0x00, 0x21, 0x00, 0x0a, 0x00, 0x4f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 18 | 0x00, 0x6f, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x74, 19 | 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x64, 0x00, 0x75, 20 | 0x00, 0x6e, 0x00, 0x67, 0x00, 0x65, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x3f, 21 | 0x00, 0x20, 0x00, 0x28, 0x00, 0x6e, 0x00, 0x29, 0x00, 0x6f, 0x00, 0x20, 22 | 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x79, 23 | 0x00, 0x20, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x20, 0x00, 0x74, 24 | 0x00, 0x6f, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 25 | 0x00, 0x69, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x0a, 26 | 0x00, 0x00, 0xff, 0x92, 0x40, 0x00, 0x00, 0x41, 0x00, 0x20, 0x00, 0x10, 27 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x23, 0xfb, 0x25, 0xfb, 28 | 0xf0, 0x20, 0x26, 0x33, 0x16, 0x03, 0x04, 0x0a, 0x26, 0x32, 0x16, 0x03, 29 | 0x04, 0x09, 0x26, 0x2e, 0x16, 0x03, 0x04, 0x08, 0x26, 0x2d, 0x16, 0x03, 30 | 0x04, 0x07, 0x0f, 0xf0, 0x14, 0xbf, 0x0e, 0x06, 0x14, 0xa1, 0x0e, 0x04, 31 | 0x12, 0x7f, 0x0e, 0x02, 0x12, 0x61, 0x0e, 0x00, 0x52, 0x7f, 0x54, 0xaf, 32 | 0x73, 0xbf, 0x75, 0xbe, 0x1d, 0xbe, 0x48, 0x4a, 0x66, 0xc0, 0x04, 0x04, 33 | 0x28, 0x1a, 0x16, 0xc4, 0x04, 0x10, 0x4f, 0x82, 0x23, 0xd7, 0x25, 0xd7, 34 | 0x48, 0x41, 0x59, 0x20, 0x78, 0xc0, 0x65, 0x80, 0x63, 0x81, 0x1d, 0xa2, 35 | 0x48, 0x3b, 0x59, 0x20, 0x19, 0x22, 0x78, 0xc0, 0x33, 0xcb, 0x35, 0xcb, 36 | 0x4f, 0x73, 0x59, 0x20, 0x19, 0x21, 0x39, 0xc8, 0x4f, 0x6f, 0xff, 0x89, 37 | 0xff, 0x9f, 0xff, 0x8d, 0xff, 0x9c, 0xff, 0xfc, 0x7f, 0xbf, 0x1d, 0xbf, 38 | 0x27, 0xbb, 0x29, 0xbb, 0x2b, 0xbe, 0xe0, 0x1a, 0xf0, 0x22, 0x63, 0x40, 39 | 0xe4, 0x11, 0x14, 0x81, 0x60, 0x80, 0xf0, 0x21, 0x1b, 0x61, 0x16, 0xff, 40 | 0x03, 0xf8, 0x20, 0x09, 0xf0, 0x21, 0x27, 0xac, 0x19, 0x3f, 0x03, 0xf3, 41 | 0x20, 0x04, 0xf0, 0x21, 0x6f, 0x80, 0x1d, 0xa1, 0xc1, 0xc0, 0x00, 0x0a, 42 | 0x00, 0x20, 0x00, 0x23, 0x00, 0x40, 0x00, 0x4b, 0x00, 0x44, 0x00, 0x00, 43 | 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x32, 0x00, 0x4a, 0x00, 0x1b, 0x00, 0x5b, 44 | 0x00, 0x48, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x33, 0x00, 0x4a, 0x00, 0x00, 45 | 0x71, 0xbf, 0x79, 0xbe, 0x7b, 0xbd, 0x7f, 0xbc, 0x1d, 0xbc, 0x27, 0x91, 46 | 0x16, 0xc1, 0x18, 0xa0, 0x04, 0x04, 0x2b, 0x88, 0x16, 0xc5, 0x19, 0x3f, 47 | 0x03, 0xfd, 0x6f, 0x80, 0x6b, 0x81, 0x69, 0x82, 0x61, 0x83, 0x1d, 0xa4, 48 | 0xc1, 0xc0, 0x7f, 0xbf, 0x1d, 0xbf, 0x23, 0x7c, 0x25, 0x7c, 0x56, 0xe0, 49 | 0x16, 0xe1, 0x2b, 0x7d, 0x77, 0x40, 0x1b, 0x61, 0x12, 0x7f, 0x03, 0xfc, 50 | 0x23, 0x73, 0x14, 0xbf, 0x03, 0xf9, 0x48, 0x26, 0x23, 0x70, 0x48, 0x42, 51 | 0x14, 0x20, 0x52, 0x60, 0x4f, 0xd9, 0x59, 0x20, 0x19, 0x22, 0x78, 0xc0, 52 | 0x33, 0x69, 0x35, 0x69, 0x29, 0x65, 0x19, 0x3f, 0x99, 0x3f, 0x19, 0x21, 53 | 0x12, 0x61, 0x4f, 0xce, 0x5b, 0x60, 0x7a, 0xc0, 0x73, 0xbf, 0x1d, 0xbf, 54 | 0x48, 0x11, 0x52, 0x60, 0x12, 0x63, 0x48, 0x2c, 0x10, 0x3f, 0x14, 0x80, 55 | 0x54, 0xaf, 0x63, 0x80, 0x1d, 0xa1, 0x4f, 0xc0, 0x7a, 0xc0, 0x1a, 0x44, 56 | 0x09, 0xed, 0x1b, 0x64, 0x7a, 0xc0, 0x6f, 0x80, 0x1d, 0xa1, 0xc1, 0xc0, 57 | 0x73, 0xbf, 0x75, 0xbe, 0x77, 0xbd, 0x79, 0xbc, 0x7b, 0xbb, 0x7f, 0xba, 58 | 0x1d, 0xba, 0x22, 0x13, 0x24, 0x11, 0x50, 0x20, 0x10, 0x02, 0x12, 0x7f, 59 | 0x03, 0xfd, 0x22, 0x0e, 0x10, 0x01, 0x22, 0x0d, 0x50, 0x01, 0x30, 0x08, 60 | 0x6f, 0x80, 0x6b, 0x81, 0x69, 0x82, 0x67, 0x83, 0x65, 0x84, 0x63, 0x85, 61 | 0x1d, 0xa6, 0xc1, 0xc0, 0xac, 0x34, 0x3b, 0x8d, 0x00, 0x83, 0x7f, 0xff, 62 | 0x75, 0xbf, 0x77, 0xbe, 0x79, 0xbd, 0x7b, 0xbc, 0x7f, 0xbb, 0x1d, 0xbb, 63 | 0x92, 0x7f, 0x12, 0x61, 0x04, 0x05, 0x14, 0x01, 0x08, 0x03, 0x10, 0x01, 64 | 0x14, 0x01, 0x07, 0xfd, 0x6f, 0x80, 0x6b, 0x81, 0x69, 0x82, 0x67, 0x83, 65 | 0x65, 0x84, 0x1d, 0xa5, 0xc1, 0xc0 66 | ]); 67 | -------------------------------------------------------------------------------- /js/vm.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | function assert(condition) { 3 | if (!condition) { 4 | debugger; // eslint-disable-line no-debugger 5 | } 6 | } 7 | 8 | // MARK: - Constants 9 | 10 | var STEPS_PER_FRAME = 100000; 11 | var EXIT_SUCCESS = true; 12 | var EXIT_INPUT_TOO_LARGE = -1; 13 | var EXIT_OPCODE_NOT_IMPLEMENTED = -2; 14 | var EXIT_RETRY_AFTER_INTERRUPT = -3; 15 | 16 | var ADDR_INITIAL = 0x3000; 17 | var ADDR_KBSR = 0xfe00; 18 | var ADDR_KBDR = 0xfe02; 19 | var ADDR_DSR = 0xfe04; 20 | var ADDR_DDR = 0xfe06; 21 | var ADDR_MCR = 0xfffe; 22 | var ADDR_MAX = 0xffff; 23 | 24 | var OPCODE_ADD = 0b0001; 25 | var OPCODE_AND = 0b0101; 26 | var OPCODE_BR = 0b0000; 27 | var OPCODE_JMP = 0b1100; 28 | var OPCODE_JSR = 0b0100; 29 | var OPCODE_LD = 0b0010; 30 | var OPCODE_LDI = 0b1010; 31 | var OPCODE_LDR = 0b0110; 32 | var OPCODE_LEA = 0b1110; 33 | var OPCODE_NOT = 0b1001; 34 | var OPCODE_RTI = 0b1000; 35 | var OPCODE_ST = 0b0011; 36 | var OPCODE_STI = 0b1011; 37 | var OPCODE_STR = 0b0111; 38 | var OPCODE_TRAP = 0b1111; 39 | var OPCODE_RESERVED = 0b1101; 40 | 41 | var REG_PC = 8; 42 | var REG_PSR = 9; 43 | var REG_COUNT = 10; 44 | 45 | var FLAG_NEGATIVE = 0b100; 46 | var FLAG_ZERO = 0b010; 47 | var FLAG_POSITIVE = 0b001; 48 | 49 | var SIGN_BIT = 1 << 15; 50 | var STATUS_BIT = 1 << 15; 51 | 52 | // MARK: - Utilities 53 | 54 | function swap16(val) { 55 | return (val << 8) | (val >> 8); 56 | } 57 | 58 | function signExtend(val, n) { 59 | var m = 1 << (n - 1); 60 | val &= (1 << n) - 1; 61 | return (val ^ m) - m; 62 | } 63 | 64 | function signFlag(val) { 65 | if (val == 0) { 66 | return FLAG_ZERO; 67 | } 68 | else if (val & SIGN_BIT) { 69 | return FLAG_NEGATIVE; 70 | } 71 | else { 72 | return FLAG_POSITIVE; 73 | } 74 | } 75 | 76 | // MARK: - Creation 77 | 78 | function VirtualMachine() { 79 | this.reset(); 80 | } 81 | 82 | VirtualMachine.prototype.reset = function() { 83 | this.mem = new Uint16Array(ADDR_MAX + 1); 84 | this.reg = new Uint16Array(REG_COUNT); 85 | 86 | this.reg[REG_PC] = ADDR_INITIAL; 87 | this.reg[REG_PSR] = FLAG_ZERO; 88 | this.mem[ADDR_MCR] = STATUS_BIT; 89 | 90 | this.retryAfterInterrupt = false; 91 | 92 | if (this.animationFrameHandle !== undefined) { 93 | window.cancelAnimationFrame(this.animationFrameHandle); 94 | this.animationFrameHandle = undefined; 95 | } 96 | }; 97 | 98 | // MARK: - Memory 99 | 100 | VirtualMachine.prototype.read = function(addr) { 101 | if (addr == ADDR_KBSR) { 102 | return this.hasChar() ? STATUS_BIT : 0; 103 | } 104 | else if (addr == ADDR_KBDR) { 105 | if (this.hasChar()) { 106 | return this.getChar(); 107 | } 108 | else { 109 | return 0; 110 | } 111 | } 112 | else if (addr == ADDR_DSR) { 113 | return STATUS_BIT; 114 | } 115 | else if (addr == ADDR_DDR) { 116 | return 0; 117 | } 118 | else { 119 | return this.mem[addr]; 120 | } 121 | }; 122 | 123 | VirtualMachine.prototype.write = function(addr, val) { 124 | if (addr == ADDR_KBSR || addr == ADDR_KBDR || addr == ADDR_DSR) { 125 | assert(0); 126 | } 127 | else if (addr == ADDR_DDR) { 128 | this.putChar(val); 129 | } 130 | else { 131 | this.mem[addr] = val; 132 | } 133 | }; 134 | 135 | VirtualMachine.prototype.loadOS = function() { 136 | var res = this.loadData(window.lc3os); 137 | assert(res == EXIT_SUCCESS); 138 | }; 139 | 140 | VirtualMachine.prototype.loadData = function(arr8) { 141 | var arr16 = new Uint16Array(arr8.buffer); 142 | 143 | var loadAddr = swap16(arr16[0]); 144 | var loadLength = arr16.length - 1; 145 | 146 | if (loadAddr + loadLength > ADDR_MAX) { 147 | assert(0); 148 | return EXIT_INPUT_TOO_LARGE; 149 | } 150 | 151 | for (var i = 1; i < arr16.length; ++i) { 152 | this.mem[loadAddr + i - 1] = swap16(arr16[i]); 153 | } 154 | 155 | return EXIT_SUCCESS; 156 | }; 157 | 158 | // MARK: - Execution 159 | 160 | VirtualMachine.prototype.setCC = function(reg) { 161 | this.reg[REG_PSR] = signFlag(this.reg[reg]); 162 | }; 163 | 164 | VirtualMachine.prototype.perform = function(instr) { 165 | switch (instr >> 12) { 166 | case OPCODE_ADD: { 167 | let dr = (instr >> 9) & 0b111; 168 | let sr1 = (instr >> 6) & 0b111; 169 | 170 | if (instr & (1 << 5)) { 171 | let imm5 = signExtend(instr, 5); 172 | this.reg[dr] = this.reg[sr1] + imm5; 173 | } 174 | else { 175 | let sr2 = instr & 0b111; 176 | this.reg[dr] = this.reg[sr1] + this.reg[sr2]; 177 | } 178 | 179 | this.setCC(dr); 180 | break; 181 | } 182 | 183 | case OPCODE_AND: { 184 | let dr = (instr >> 9) & 0b111; 185 | let sr1 = (instr >> 6) & 0b111; 186 | 187 | if (instr & (1 << 5)) { 188 | let imm5 = signExtend(instr, 5); 189 | this.reg[dr] = this.reg[sr1] & imm5; 190 | } 191 | else { 192 | let sr2 = instr & 0b111; 193 | this.reg[dr] = this.reg[sr1] & this.reg[sr2]; 194 | } 195 | 196 | this.setCC(dr); 197 | break; 198 | } 199 | 200 | case OPCODE_BR: { 201 | let current_nzp = this.reg[REG_PSR] & 0b111; 202 | let desired_nzp = (instr >> 9) & 0b111; 203 | 204 | if (current_nzp & desired_nzp) { 205 | let pc_offset9 = signExtend(instr, 9); 206 | this.reg[REG_PC] += pc_offset9; 207 | } 208 | 209 | break; 210 | } 211 | 212 | case OPCODE_JMP: { 213 | let baser = (instr >> 6) & 0b111; 214 | this.reg[REG_PC] = this.reg[baser]; 215 | break; 216 | } 217 | 218 | case OPCODE_JSR: { 219 | this.reg[7] = this.reg[REG_PC]; 220 | 221 | if (instr & (1 << 11)) { 222 | let pc_offset11 = signExtend(instr, 11); 223 | this.reg[REG_PC] += pc_offset11; 224 | } 225 | else { 226 | let baser = (instr >> 6) & 0b111; 227 | this.reg[REG_PC] = this.reg[baser]; 228 | } 229 | 230 | break; 231 | } 232 | 233 | case OPCODE_LD: { 234 | let dr = (instr >> 9) & 0b111; 235 | let pc_offset9 = signExtend(instr, 9); 236 | 237 | this.reg[dr] = this.read(this.reg[REG_PC] + pc_offset9); 238 | 239 | this.setCC(dr); 240 | break; 241 | } 242 | 243 | case OPCODE_LDI: { 244 | let dr = (instr >> 9) & 0b111; 245 | let pc_offset9 = signExtend(instr, 9); 246 | 247 | this.reg[dr] = this.read(this.read(this.reg[REG_PC] + pc_offset9)); 248 | 249 | this.setCC(dr); 250 | break; 251 | } 252 | 253 | case OPCODE_LDR: { 254 | let dr = (instr >> 9) & 0b111; 255 | let baser = (instr >> 6) & 0b111; 256 | let offset6 = signExtend(instr, 6); 257 | 258 | this.reg[dr] = this.read(this.reg[baser] + offset6); 259 | 260 | this.setCC(dr); 261 | break; 262 | } 263 | 264 | case OPCODE_LEA: { 265 | let dr = (instr >> 9) & 0b111; 266 | let pc_offset9 = signExtend(instr, 9); 267 | 268 | this.reg[dr] = this.reg[REG_PC] + pc_offset9; 269 | 270 | this.setCC(dr); 271 | break; 272 | } 273 | 274 | case OPCODE_NOT: { 275 | let dr = (instr >> 9) & 0b111; 276 | let sr = (instr >> 6) & 0b111; 277 | 278 | this.reg[dr] = ~this.reg[sr]; 279 | 280 | this.setCC(dr); 281 | break; 282 | } 283 | 284 | case OPCODE_RTI: { 285 | return EXIT_OPCODE_NOT_IMPLEMENTED; 286 | } 287 | 288 | case OPCODE_ST: { 289 | let sr = (instr >> 9) & 0b111; 290 | let pc_offset9 = signExtend(instr, 9); 291 | 292 | this.write(this.reg[REG_PC] + pc_offset9, this.reg[sr]); 293 | 294 | break; 295 | } 296 | 297 | case OPCODE_STI: { 298 | let sr = (instr >> 9) & 0b111; 299 | let pc_offset9 = signExtend(instr, 9); 300 | 301 | this.write(this.read(this.reg[REG_PC] + pc_offset9), this.reg[sr]); 302 | 303 | break; 304 | } 305 | 306 | case OPCODE_STR: { 307 | let sr = (instr >> 9) & 0b111; 308 | let baser = (instr >> 6) & 0b111; 309 | let offset6 = signExtend(instr, 6); 310 | 311 | this.write(this.reg[baser] + offset6, this.reg[sr]); 312 | 313 | break; 314 | } 315 | 316 | case OPCODE_TRAP: { 317 | let trapvect8 = instr & 0xff; 318 | 319 | if (trapvect8 == 0x20) { 320 | // handle GETC efficiently to prevent high CPU usage when idle 321 | if (this.hasChar()) { 322 | this.reg[0] = this.getChar(); 323 | } 324 | else { 325 | return EXIT_RETRY_AFTER_INTERRUPT; 326 | } 327 | } 328 | else { 329 | // fallback to OS implementation of remaining traps 330 | this.reg[7] = this.reg[REG_PC]; 331 | this.reg[REG_PC] = this.read(trapvect8); 332 | } 333 | 334 | break; 335 | } 336 | 337 | case OPCODE_RESERVED: 338 | return EXIT_OPCODE_NOT_IMPLEMENTED; 339 | } 340 | 341 | return EXIT_SUCCESS; 342 | }; 343 | 344 | VirtualMachine.prototype.step = function() { 345 | for (var i = 0; i < STEPS_PER_FRAME; ++i) { 346 | if (!(this.read(ADDR_MCR) & STATUS_BIT)) { 347 | // halted 348 | return; 349 | } 350 | 351 | var instr = this.read(this.reg[REG_PC]++); 352 | var res = this.perform(instr); 353 | 354 | if (res == EXIT_RETRY_AFTER_INTERRUPT) { 355 | this.reg[REG_PC]--; 356 | this.retryAfterInterrupt = true; 357 | return; 358 | } 359 | else if (res != EXIT_SUCCESS) { 360 | return; 361 | } 362 | } 363 | 364 | this.schedule(); 365 | }; 366 | 367 | VirtualMachine.prototype.schedule = function() { 368 | this.animationFrameHandle = window.requestAnimationFrame(() => this.step()); 369 | }; 370 | 371 | VirtualMachine.prototype.interrupt = function() { 372 | if (this.retryAfterInterrupt) { 373 | this.retryAfterInterrupt = false; 374 | this.schedule(); 375 | } 376 | }; 377 | 378 | // MARK: - I/O Placeholders 379 | 380 | VirtualMachine.prototype.putChar = function(val) { 381 | console.log(val); // eslint-disable-line no-console 382 | }; 383 | 384 | VirtualMachine.prototype.hasChar = function() { 385 | return false; 386 | }; 387 | 388 | VirtualMachine.prototype.getChar = function() { 389 | return 0; 390 | }; 391 | 392 | // MARK: - Exports 393 | 394 | window.VirtualMachine = VirtualMachine; 395 | })(); 396 | -------------------------------------------------------------------------------- /obj/2048.js: -------------------------------------------------------------------------------- 1 | window.lc3_2048 = new Uint8Array([ 2 | 0x30, 0x00, 0x2c, 0x13, 0xea, 0x14, 0xe0, 0x79, 0xf0, 0x22, 0xe0, 0x21, 3 | 0xf0, 0x22, 0x4a, 0xc0, 0x48, 0xa9, 0x49, 0xea, 0x48, 0xb6, 0x20, 0x0a, 4 | 0x02, 0x01, 0x0f, 0xfb, 0x49, 0xe5, 0xe0, 0x5e, 0xf0, 0x22, 0xe0, 0x37, 5 | 0x4a, 0x7a, 0x03, 0xf4, 0xf0, 0x25, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 6 | 0x00, 0x07, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x06, 0x00, 0x09, 7 | 0x00, 0x0e, 0x00, 0x02, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x03, 8 | 0x00, 0x04, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x50, 0x00, 0x72, 0x00, 0x65, 9 | 0x00, 0x73, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x79, 10 | 0x00, 0x20, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x79, 0x00, 0x20, 0x00, 0x74, 11 | 0x00, 0x6f, 0x00, 0x20, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x72, 12 | 0x00, 0x74, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 13 | 0x00, 0x67, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x0a, 14 | 0x00, 0x00, 0x00, 0x57, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x64, 15 | 0x00, 0x20, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x20, 0x00, 0x6c, 16 | 0x00, 0x69, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 17 | 0x00, 0x20, 0x00, 0x70, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, 0x20, 18 | 0x00, 0x61, 0x00, 0x67, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 19 | 0x00, 0x28, 0x00, 0x79, 0x00, 0x2f, 0x00, 0x6e, 0x00, 0x29, 0x00, 0x3f, 20 | 0x00, 0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x59, 0x00, 0x6f, 0x00, 0x75, 21 | 0x00, 0x20, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x74, 0x00, 0x20, 22 | 0x00, 0x3a, 0x00, 0x28, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 23 | 0x00, 0x65, 0x00, 0x6c, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x65, 24 | 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 25 | 0x00, 0x34, 0x00, 0x38, 0x00, 0x21, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x43, 26 | 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6c, 27 | 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x67, 28 | 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 29 | 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x57, 0x00, 0x41, 30 | 0x00, 0x53, 0x00, 0x44, 0x00, 0x20, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x79, 31 | 0x00, 0x73, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x00, 0x7f, 0xbf, 0x1d, 0xbf, 32 | 0x50, 0x20, 0x52, 0x60, 0x31, 0x5f, 0x14, 0x45, 0x70, 0x80, 0x12, 0x61, 33 | 0x14, 0x70, 0x09, 0xfb, 0x48, 0xe8, 0x48, 0xe7, 0x6f, 0x80, 0x1d, 0xa1, 34 | 0xc1, 0xc0, 0x7f, 0xbf, 0x1d, 0xbf, 0xf0, 0x20, 0x22, 0x29, 0x12, 0x01, 35 | 0x04, 0x12, 0x22, 0x27, 0x12, 0x01, 0x04, 0x07, 0x22, 0x25, 0x12, 0x01, 36 | 0x04, 0x12, 0x22, 0x23, 0x12, 0x01, 0x04, 0x03, 0x0f, 0xf2, 0x48, 0x51, 37 | 0x0e, 0x11, 0x48, 0x1e, 0x48, 0x1d, 0x48, 0x4d, 0x48, 0x1b, 0x48, 0x1a, 38 | 0x0e, 0x0b, 0x48, 0x18, 0x48, 0x17, 0x48, 0x16, 0x48, 0x46, 0x48, 0x14, 39 | 0x0e, 0x05, 0x48, 0x12, 0x48, 0x42, 0x48, 0x10, 0x48, 0x0f, 0x48, 0x0e, 40 | 0x10, 0x20, 0x0d, 0xdd, 0x48, 0xbe, 0x10, 0x20, 0x02, 0x02, 0x48, 0xdc, 41 | 0x31, 0x2b, 0x6f, 0x80, 0x1d, 0xa1, 0xc1, 0xc0, 0xff, 0x89, 0xff, 0x9f, 42 | 0xff, 0x8d, 0xff, 0x9c, 0x71, 0xbf, 0x1d, 0xbf, 0x61, 0x41, 0x71, 0xbf, 43 | 0x61, 0x42, 0x71, 0xbe, 0x61, 0x43, 0x71, 0xbd, 0x1d, 0xbd, 0x61, 0x40, 44 | 0x71, 0x43, 0x61, 0x44, 0x71, 0x42, 0x61, 0x48, 0x71, 0x41, 0x61, 0x4c, 45 | 0x71, 0x40, 0x61, 0x4d, 0x71, 0x44, 0x61, 0x4e, 0x71, 0x48, 0x61, 0x4f, 46 | 0x71, 0x4c, 0x61, 0x4b, 0x71, 0x4d, 0x61, 0x47, 0x71, 0x4e, 0x61, 0x80, 47 | 0x71, 0x4f, 0x61, 0x81, 0x71, 0x4b, 0x61, 0x82, 0x71, 0x47, 0x1d, 0xa3, 48 | 0x61, 0x46, 0x71, 0xbf, 0x1d, 0xbf, 0x61, 0x45, 0x71, 0x46, 0x61, 0x49, 49 | 0x71, 0x45, 0x61, 0x4a, 0x71, 0x49, 0x61, 0x80, 0x71, 0x4a, 0x1d, 0xa1, 50 | 0x61, 0x80, 0x1d, 0xa1, 0xc1, 0xc0, 0x7f, 0xbf, 0x73, 0xbe, 0x1d, 0xbe, 51 | 0x52, 0x60, 0x11, 0x60, 0x48, 0x0e, 0x12, 0x01, 0x11, 0x64, 0x48, 0x0b, 52 | 0x12, 0x01, 0x11, 0x68, 0x48, 0x08, 0x12, 0x01, 0x11, 0x6c, 0x48, 0x05, 53 | 0x10, 0x01, 0x63, 0x80, 0x6f, 0x81, 0x1d, 0xa2, 0xc1, 0xc0, 0x73, 0xbf, 54 | 0x1d, 0xbf, 0x52, 0x60, 0x54, 0xa0, 0x68, 0x00, 0x17, 0x04, 0x16, 0xc3, 55 | 0x16, 0xc3, 0x16, 0xc3, 0x68, 0x01, 0x16, 0xc4, 0x16, 0xc3, 0x16, 0xc3, 56 | 0x16, 0xc3, 0x16, 0xc3, 0x68, 0x02, 0x16, 0xc4, 0x16, 0xc3, 0x16, 0xc3, 57 | 0x16, 0xc3, 0x16, 0xc3, 0x68, 0x03, 0x16, 0xc4, 0x77, 0xbf, 0x1d, 0xbf, 58 | 0x18, 0x01, 0x69, 0x00, 0x0c, 0x03, 0x16, 0x02, 0x14, 0xa1, 0x78, 0xc0, 59 | 0x12, 0x61, 0x18, 0x7c, 0x09, 0xf7, 0x52, 0x60, 0x18, 0xbc, 0x04, 0x04, 60 | 0x16, 0x02, 0x14, 0xa1, 0x72, 0xc0, 0x0f, 0xfa, 0x62, 0x00, 0x66, 0x01, 61 | 0x04, 0x25, 0x96, 0xff, 0x16, 0xe1, 0x16, 0x43, 0x0a, 0x08, 0x12, 0x61, 62 | 0x72, 0x00, 0x62, 0x02, 0x72, 0x01, 0x62, 0x03, 0x72, 0x02, 0x52, 0x60, 63 | 0x72, 0x03, 0x62, 0x01, 0x66, 0x02, 0x04, 0x16, 0x96, 0xff, 0x16, 0xe1, 64 | 0x16, 0x43, 0x0a, 0x07, 0x12, 0x61, 0x72, 0x01, 0x62, 0x03, 0x72, 0x02, 65 | 0x52, 0x60, 0x72, 0x03, 0x0e, 0x0b, 0x62, 0x02, 0x66, 0x03, 0x04, 0x08, 66 | 0x96, 0xff, 0x16, 0xe1, 0x16, 0x43, 0x0a, 0x04, 0x12, 0x61, 0x72, 0x02, 67 | 0x52, 0x60, 0x72, 0x03, 0x68, 0x00, 0x17, 0x04, 0x16, 0xc3, 0x16, 0xc3, 68 | 0x16, 0xc3, 0x68, 0x01, 0x16, 0xc4, 0x16, 0xc3, 0x16, 0xc3, 0x16, 0xc3, 69 | 0x16, 0xc3, 0x68, 0x02, 0x16, 0xc4, 0x16, 0xc3, 0x16, 0xc3, 0x16, 0xc3, 70 | 0x16, 0xc3, 0x68, 0x03, 0x16, 0xc4, 0x96, 0xff, 0x16, 0xe1, 0x69, 0x80, 71 | 0x50, 0x20, 0x16, 0xc4, 0x04, 0x01, 0x10, 0x21, 0x63, 0x81, 0x1d, 0xa2, 72 | 0xc1, 0xc0, 0x7f, 0xbf, 0x1d, 0xbf, 0x52, 0x60, 0x54, 0xa0, 0x10, 0x85, 73 | 0x14, 0xa1, 0x71, 0xbf, 0x60, 0x00, 0x02, 0x02, 0x12, 0x61, 0x1d, 0xbf, 74 | 0x10, 0xb0, 0x09, 0xf7, 0x10, 0x60, 0x04, 0x0d, 0x48, 0xc1, 0x14, 0x06, 75 | 0x20, 0x0e, 0x48, 0xbe, 0x10, 0x20, 0x04, 0x03, 0x50, 0x20, 0x10, 0x21, 76 | 0x0e, 0x01, 0x10, 0x22, 0x64, 0x80, 0x70, 0x80, 0x10, 0x7f, 0x1d, 0x81, 77 | 0x6f, 0x80, 0x1d, 0xa1, 0xc1, 0xc0, 0x00, 0x0b, 0x7f, 0xbf, 0x1d, 0xbf, 78 | 0x59, 0x20, 0x19, 0x21, 0x11, 0x60, 0x48, 0x17, 0x04, 0x0d, 0x11, 0x64, 79 | 0x48, 0x14, 0x04, 0x0a, 0x11, 0x68, 0x48, 0x11, 0x04, 0x07, 0x11, 0x6c, 80 | 0x48, 0x0e, 0x04, 0x04, 0x19, 0x3f, 0x08, 0x02, 0x4f, 0x19, 0x0f, 0xf0, 81 | 0x19, 0x20, 0x02, 0x03, 0x4f, 0x15, 0x4f, 0x14, 0x4f, 0x13, 0x6f, 0x80, 82 | 0x1d, 0xa1, 0x10, 0x60, 0xc1, 0xc0, 0x64, 0x00, 0x66, 0x01, 0x96, 0xff, 83 | 0x16, 0xe1, 0x12, 0x83, 0x04, 0x0a, 0x64, 0x02, 0x12, 0x83, 0x04, 0x07, 84 | 0x66, 0x03, 0x96, 0xff, 0x16, 0xe1, 0x12, 0x83, 0x04, 0x02, 0x52, 0x60, 85 | 0x12, 0x61, 0xc1, 0xc0, 0x7f, 0xbf, 0x1d, 0xbf, 0xe0, 0x2f, 0xf0, 0x22, 86 | 0x22, 0x7c, 0x54, 0xa0, 0xe0, 0x37, 0xf0, 0x22, 0x20, 0x77, 0xf0, 0x21, 87 | 0xe0, 0x50, 0xf0, 0x22, 0x20, 0x73, 0xf0, 0x21, 0xe0, 0x69, 0xf0, 0x22, 88 | 0x20, 0x6e, 0xf0, 0x21, 0x17, 0x42, 0x66, 0xc0, 0x14, 0xa1, 0x10, 0x43, 89 | 0x60, 0x00, 0xf0, 0x22, 0x20, 0x66, 0xf0, 0x21, 0x10, 0xbc, 0x04, 0x07, 90 | 0x10, 0xb8, 0x04, 0x05, 0x10, 0xb4, 0x04, 0x03, 0x10, 0xb0, 0x04, 0x01, 91 | 0x0b, 0xed, 0xe0, 0x57, 0xf0, 0x22, 0x10, 0xb0, 0x0b, 0xe3, 0xe0, 0x33, 92 | 0xf0, 0x22, 0x20, 0x56, 0xf0, 0x21, 0xe0, 0x12, 0xf0, 0x22, 0x20, 0x52, 93 | 0xf0, 0x21, 0x6f, 0x80, 0x1d, 0xa1, 0xc1, 0xc0, 0x00, 0x1b, 0x00, 0x5b, 94 | 0x00, 0x32, 0x00, 0x4a, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x48, 0x00, 0x1b, 95 | 0x00, 0x5b, 0x00, 0x33, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x2d, 96 | 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 97 | 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 98 | 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 99 | 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 100 | 0x00, 0x2d, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x20, 0x00, 0x20, 101 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 102 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 103 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 104 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 105 | 0x00, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 106 | 0x00, 0x7c, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x0a, 0x33, 0x17, 107 | 0x71, 0xbf, 0x73, 0xbe, 0x75, 0xbd, 0x7f, 0xbc, 0x1d, 0xbc, 0x20, 0x0d, 108 | 0x22, 0x0f, 0x48, 0x5b, 0x22, 0x0b, 0x48, 0x6d, 0x30, 0x08, 0x63, 0x83, 109 | 0x48, 0x56, 0x6f, 0x80, 0x65, 0x81, 0x63, 0x82, 0x1d, 0xa4, 0xc1, 0xc0, 110 | 0x00, 0x00, 0xc2, 0x0d, 0x00, 0x07, 0x7f, 0xff, 0x12, 0x49, 0x71, 0xbf, 111 | 0x73, 0xbe, 0x7f, 0xbd, 0x1d, 0xbd, 0x61, 0x82, 0xf0, 0x22, 0x48, 0x34, 112 | 0xf0, 0x21, 0x12, 0x20, 0x20, 0x30, 0xf0, 0x21, 0x20, 0x2c, 0x10, 0x01, 113 | 0x04, 0x0a, 0x20, 0x2a, 0x10, 0x01, 0x04, 0x05, 0x10, 0x60, 0xf0, 0x21, 114 | 0xe0, 0x0b, 0xf0, 0x22, 0x0f, 0xee, 0x50, 0x20, 0x0e, 0x02, 0x50, 0x20, 115 | 0x10, 0x21, 0x6f, 0x80, 0x63, 0x81, 0x1d, 0xa3, 0x10, 0x20, 0xc1, 0xc0, 116 | 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x6f, 117 | 0x00, 0x74, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x76, 0x00, 0x61, 118 | 0x00, 0x6c, 0x00, 0x69, 0x00, 0x64, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 119 | 0x00, 0x70, 0x00, 0x75, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 120 | 0x00, 0x00, 0xff, 0x87, 0xff, 0x92, 0x00, 0x0a, 0x73, 0xbf, 0x1d, 0xbf, 121 | 0x52, 0x60, 0x12, 0x61, 0xa0, 0x09, 0x07, 0xfd, 0x20, 0x09, 0x52, 0x40, 122 | 0xa0, 0x06, 0x33, 0xb7, 0x33, 0xb5, 0x63, 0x80, 0x1d, 0xa1, 0xc1, 0xc0, 123 | 0xfe, 0x00, 0xfe, 0x02, 0x7f, 0xff, 0x73, 0xbf, 0x75, 0xbe, 0x77, 0xbd, 124 | 0x1d, 0xbd, 0x94, 0x7f, 0x14, 0xa1, 0x04, 0x0c, 0x52, 0x60, 0x12, 0x61, 125 | 0x10, 0x02, 0x03, 0xfd, 0x04, 0x03, 0x65, 0x82, 0x12, 0x7f, 0x10, 0x02, 126 | 0x67, 0x80, 0x65, 0x81, 0x1d, 0xa3, 0xc1, 0xc0, 0xf0, 0x25, 0x10, 0x20, 127 | 0x04, 0x16, 0x12, 0x60, 0x04, 0x14, 0x73, 0xbf, 0x75, 0xbe, 0x77, 0xbd, 128 | 0x79, 0xbc, 0x1d, 0xbc, 0x54, 0xa0, 0x16, 0xa1, 0x58, 0x03, 0x0c, 0x01, 129 | 0x14, 0x81, 0x12, 0x41, 0x16, 0xc3, 0x03, 0xfa, 0x10, 0xa0, 0x69, 0x80, 130 | 0x67, 0x81, 0x65, 0x82, 0x63, 0x83, 0x1d, 0xa4, 0xc1, 0xc0, 0x50, 0x20, 131 | 0xc1, 0xc0, 0x33, 0x28, 0x33, 0x2d, 0x33, 0x32, 0x33, 0x37, 0x33, 0x3c, 132 | 0x33, 0x41, 0x33, 0x46, 0x33, 0x4b, 0x33, 0x50, 0x33, 0x55, 0x33, 0x5a, 133 | 0x33, 0x5f, 0x33, 0x64, 0x33, 0x69, 0x33, 0x6e, 0x33, 0x73, 0x33, 0x78, 134 | 0x33, 0x7d, 0x33, 0x82, 0x33, 0x90, 0x33, 0xa0, 0x33, 0xae, 0x33, 0xbc, 135 | 0x33, 0xcc, 0x33, 0xdc, 0x33, 0xea, 0x33, 0xf8, 0x34, 0x06, 0x34, 0x16, 136 | 0x34, 0x26, 0x34, 0x36, 0x34, 0x47, 0x34, 0x58, 0x34, 0x69, 0x00, 0x20, 137 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x32, 138 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x34, 0x00, 0x20, 139 | 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x38, 0x00, 0x20, 0x00, 0x20, 140 | 0x00, 0x00, 0x00, 0x20, 0x00, 0x31, 0x00, 0x36, 0x00, 0x20, 0x00, 0x00, 141 | 0x00, 0x20, 0x00, 0x33, 0x00, 0x32, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 142 | 0x00, 0x36, 0x00, 0x34, 0x00, 0x20, 0x00, 0x00, 0x00, 0x31, 0x00, 0x32, 143 | 0x00, 0x38, 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x00, 0x35, 0x00, 0x36, 144 | 0x00, 0x20, 0x00, 0x00, 0x00, 0x35, 0x00, 0x31, 0x00, 0x32, 0x00, 0x20, 145 | 0x00, 0x00, 0x00, 0x31, 0x00, 0x30, 0x00, 0x32, 0x00, 0x34, 0x00, 0x00, 146 | 0x00, 0x32, 0x00, 0x30, 0x00, 0x34, 0x00, 0x38, 0x00, 0x00, 0x00, 0x34, 147 | 0x00, 0x30, 0x00, 0x39, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x31, 148 | 0x00, 0x39, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x00, 0x5e, 0x00, 0x31, 149 | 0x00, 0x34, 0x00, 0x00, 0x00, 0x32, 0x00, 0x5e, 0x00, 0x31, 0x00, 0x35, 150 | 0x00, 0x00, 0x00, 0x32, 0x00, 0x5e, 0x00, 0x31, 0x00, 0x36, 0x00, 0x00, 151 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1b, 152 | 0x00, 0x5b, 0x00, 0x33, 0x00, 0x37, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x32, 153 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 154 | 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x31, 0x00, 0x3b, 0x00, 0x33, 155 | 0x00, 0x37, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x34, 0x00, 0x20, 0x00, 0x20, 156 | 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 157 | 0x00, 0x5b, 0x00, 0x33, 0x00, 0x31, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x38, 158 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 159 | 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x33, 0x00, 0x31, 0x00, 0x6d, 160 | 0x00, 0x20, 0x00, 0x31, 0x00, 0x36, 0x00, 0x20, 0x00, 0x1b, 0x00, 0x5b, 161 | 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x31, 162 | 0x00, 0x3b, 0x00, 0x33, 0x00, 0x31, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x33, 163 | 0x00, 0x32, 0x00, 0x20, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 164 | 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x31, 0x00, 0x3b, 0x00, 0x33, 165 | 0x00, 0x31, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x36, 0x00, 0x34, 0x00, 0x20, 166 | 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 167 | 0x00, 0x5b, 0x00, 0x33, 0x00, 0x33, 0x00, 0x6d, 0x00, 0x31, 0x00, 0x32, 168 | 0x00, 0x38, 0x00, 0x20, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 169 | 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x33, 0x00, 0x33, 0x00, 0x6d, 170 | 0x00, 0x32, 0x00, 0x35, 0x00, 0x36, 0x00, 0x20, 0x00, 0x1b, 0x00, 0x5b, 171 | 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x33, 172 | 0x00, 0x33, 0x00, 0x6d, 0x00, 0x35, 0x00, 0x31, 0x00, 0x32, 0x00, 0x20, 173 | 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 174 | 0x00, 0x5b, 0x00, 0x31, 0x00, 0x3b, 0x00, 0x33, 0x00, 0x33, 0x00, 0x6d, 175 | 0x00, 0x31, 0x00, 0x30, 0x00, 0x32, 0x00, 0x34, 0x00, 0x1b, 0x00, 0x5b, 176 | 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x31, 177 | 0x00, 0x3b, 0x00, 0x33, 0x00, 0x33, 0x00, 0x6d, 0x00, 0x32, 0x00, 0x30, 178 | 0x00, 0x34, 0x00, 0x38, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 179 | 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x31, 0x00, 0x3b, 0x00, 0x33, 180 | 0x00, 0x33, 0x00, 0x6d, 0x00, 0x34, 0x00, 0x30, 0x00, 0x39, 0x00, 0x36, 181 | 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 182 | 0x00, 0x5b, 0x00, 0x33, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x34, 0x00, 0x30, 183 | 0x00, 0x6d, 0x00, 0x38, 0x00, 0x31, 0x00, 0x39, 0x00, 0x32, 0x00, 0x1b, 184 | 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 185 | 0x00, 0x33, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x34, 0x00, 0x30, 0x00, 0x6d, 186 | 0x00, 0x32, 0x00, 0x5e, 0x00, 0x31, 0x00, 0x34, 0x00, 0x1b, 0x00, 0x5b, 187 | 0x00, 0x30, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x33, 188 | 0x00, 0x37, 0x00, 0x3b, 0x00, 0x34, 0x00, 0x30, 0x00, 0x6d, 0x00, 0x32, 189 | 0x00, 0x5e, 0x00, 0x31, 0x00, 0x35, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 190 | 0x00, 0x6d, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x33, 0x00, 0x37, 191 | 0x00, 0x3b, 0x00, 0x34, 0x00, 0x30, 0x00, 0x6d, 0x00, 0x32, 0x00, 0x5e, 192 | 0x00, 0x31, 0x00, 0x36, 0x00, 0x1b, 0x00, 0x5b, 0x00, 0x30, 0x00, 0x6d, 193 | 0x00, 0x00 194 | ]); 195 | -------------------------------------------------------------------------------- /obj/lc3os.js: -------------------------------------------------------------------------------- 1 | window.lc3os = new Uint8Array([ 2 | 0x00, 0x00, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 3 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 4 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 5 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 6 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 7 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x4c, 0x04, 0x50, 0x04, 0x56, 8 | 0x04, 0x63, 0x04, 0x6f, 0x04, 0x8e, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 9 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 10 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 11 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 12 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 13 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 14 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 15 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 16 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 17 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 18 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 19 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 20 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 21 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 22 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 23 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 24 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 25 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 26 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 27 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 28 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 29 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 30 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 31 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 32 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 33 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 34 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 35 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 36 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 37 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 38 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 39 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 40 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 41 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 42 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 43 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 44 | 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x95, 0x04, 0x98, 45 | 0x04, 0x99, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 46 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 47 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 48 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 49 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 50 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 51 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 52 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 53 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 54 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 55 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 56 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 57 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 58 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 59 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 60 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 61 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 62 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 63 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 64 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 65 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 66 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 67 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 68 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 69 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 70 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 71 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 72 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 73 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 74 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 75 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 76 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 77 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 78 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 79 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 80 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 81 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 82 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 83 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 84 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 85 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 86 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 87 | 0x04, 0x9a, 0x04, 0x9a, 0x04, 0x9a, 0xe0, 0x02, 0xf0, 0x22, 0xf0, 0x25, 88 | 0x00, 0x0a, 0x00, 0x57, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x63, 0x00, 0x6f, 89 | 0x00, 0x6d, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 90 | 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x43, 91 | 0x00, 0x2d, 0x00, 0x33, 0x00, 0x20, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6d, 92 | 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 93 | 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 94 | 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 95 | 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 96 | 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x4c, 97 | 0x00, 0x43, 0x00, 0x2d, 0x00, 0x33, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 98 | 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 99 | 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, 0x00, 0x75, 100 | 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 101 | 0x00, 0x69, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x64, 102 | 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x73, 0x00, 0x6f, 103 | 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2c, 104 | 0x00, 0x20, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x67, 105 | 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x0a, 106 | 0x00, 0x74, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x2c, 107 | 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x64, 108 | 0x00, 0x61, 0x00, 0x74, 0x00, 0x61, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 109 | 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 110 | 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 111 | 0x00, 0x20, 0x00, 0x28, 0x00, 0x63, 0x00, 0x29, 0x00, 0x20, 0x00, 0x32, 112 | 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, 113 | 0x00, 0x65, 0x00, 0x76, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x53, 114 | 0x00, 0x2e, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 115 | 0x00, 0x74, 0x00, 0x74, 0x00, 0x61, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 116 | 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x43, 117 | 0x00, 0x2d, 0x00, 0x33, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x6f, 118 | 0x00, 0x6c, 0x00, 0x73, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 119 | 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, 0x00, 0x75, 0x00, 0x74, 120 | 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 121 | 0x00, 0x20, 0x00, 0x66, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x20, 122 | 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, 0x00, 0x61, 123 | 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x76, 124 | 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x62, 125 | 0x00, 0x79, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 126 | 0x00, 0x47, 0x00, 0x4e, 0x00, 0x55, 0x00, 0x20, 0x00, 0x47, 0x00, 0x65, 127 | 0x00, 0x6e, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x0a, 128 | 0x00, 0x50, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 129 | 0x00, 0x20, 0x00, 0x4c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 130 | 0x00, 0x73, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 131 | 0x00, 0x64, 0x00, 0x20, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x20, 132 | 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x77, 0x00, 0x65, 133 | 0x00, 0x6c, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x20, 134 | 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 135 | 0x00, 0x69, 0x00, 0x66, 0x00, 0x79, 0x00, 0x20, 0x00, 0x69, 0x00, 0x74, 136 | 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x2f, 0x00, 0x6f, 137 | 0x00, 0x72, 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 138 | 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 139 | 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x69, 0x00, 0x65, 140 | 0x00, 0x73, 0x00, 0x0a, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x69, 141 | 0x00, 0x74, 0x00, 0x20, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x65, 142 | 0x00, 0x72, 0x00, 0x20, 0x00, 0x63, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 143 | 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 144 | 0x00, 0x6e, 0x00, 0x64, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 145 | 0x00, 0x6e, 0x00, 0x73, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x20, 0x00, 0x54, 146 | 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 147 | 0x00, 0x65, 0x00, 0x20, 0x00, 0x43, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x59, 148 | 0x00, 0x49, 0x00, 0x4e, 0x00, 0x47, 0x00, 0x20, 0x00, 0x28, 0x00, 0x64, 149 | 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, 150 | 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x77, 151 | 0x00, 0x69, 0x00, 0x74, 0x00, 0x68, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 152 | 0x00, 0x65, 0x00, 0x0a, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6c, 153 | 0x00, 0x73, 0x00, 0x29, 0x00, 0x20, 0x00, 0x73, 0x00, 0x70, 0x00, 0x65, 154 | 0x00, 0x63, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x65, 0x00, 0x73, 155 | 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x65, 156 | 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x69, 157 | 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x2e, 158 | 0x00, 0x20, 0x00, 0x20, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 159 | 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 160 | 0x00, 0x62, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x74, 161 | 0x00, 0x65, 0x00, 0x6c, 0x00, 0x79, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x6f, 162 | 0x00, 0x20, 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 163 | 0x00, 0x6e, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 164 | 0x00, 0x72, 0x00, 0x0a, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 165 | 0x00, 0x4c, 0x00, 0x43, 0x00, 0x2d, 0x00, 0x33, 0x00, 0x20, 0x00, 0x74, 166 | 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x20, 0x00, 0x64, 167 | 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, 168 | 0x00, 0x75, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x2c, 169 | 0x00, 0x20, 0x00, 0x61, 0x00, 0x73, 0x00, 0x20, 0x00, 0x64, 0x00, 0x65, 170 | 0x00, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, 0x00, 0x65, 171 | 0x00, 0x64, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 172 | 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, 173 | 0x00, 0x65, 0x00, 0x20, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x5f, 0x00, 0x57, 174 | 0x00, 0x41, 0x00, 0x52, 0x00, 0x52, 0x00, 0x41, 0x00, 0x4e, 0x00, 0x54, 175 | 0x00, 0x59, 0x00, 0x20, 0x00, 0x28, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x73, 176 | 0x00, 0x6f, 0x00, 0x0a, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 177 | 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 178 | 0x00, 0x64, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x74, 0x00, 0x68, 179 | 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 180 | 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x29, 0x00, 0x2e, 181 | 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x48, 0x00, 0x61, 0x00, 0x76, 0x00, 0x65, 182 | 0x00, 0x20, 0x00, 0x66, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x0a, 183 | 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x02, 0xfe, 0x04, 0xfe, 0x06, 0xff, 0xfe, 184 | 0x7f, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 185 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xf1, 0x07, 0xfe, 0xa1, 0xf0, 186 | 0xc1, 0xc0, 0x33, 0xf4, 0xa3, 0xee, 0x07, 0xfe, 0xb1, 0xed, 0x23, 0xf0, 187 | 0xc1, 0xc0, 0x31, 0xf0, 0x33, 0xf0, 0x3f, 0xf2, 0x12, 0x20, 0x60, 0x40, 188 | 0x04, 0x03, 0xf0, 0x21, 0x12, 0x61, 0x0f, 0xfb, 0x21, 0xe7, 0x23, 0xe7, 189 | 0x2f, 0xe9, 0xc1, 0xc0, 0x3f, 0xe2, 0xe0, 0x36, 0xf0, 0x22, 0xf0, 0x20, 190 | 0xf0, 0x21, 0x31, 0xde, 0x50, 0x20, 0x10, 0x2a, 0xf0, 0x21, 0x21, 0xda, 191 | 0x2f, 0xd8, 0xc1, 0xc0, 0x31, 0xd7, 0x33, 0xd7, 0x35, 0xd7, 0x37, 0xd7, 192 | 0x3f, 0xd7, 0x12, 0x20, 0x64, 0x40, 0x21, 0xcd, 0x50, 0x02, 0x04, 0x0f, 193 | 0xf0, 0x21, 0x50, 0x20, 0x16, 0x28, 0x10, 0x00, 0x14, 0xa0, 0x06, 0x01, 194 | 0x10, 0x21, 0x14, 0x82, 0x16, 0xff, 0x03, 0xf9, 0x10, 0x20, 0x04, 0x03, 195 | 0xf0, 0x21, 0x12, 0x61, 0x0f, 0xed, 0x21, 0xbe, 0x23, 0xbe, 0x25, 0xbe, 196 | 0x27, 0xbe, 0x2f, 0xbe, 0xc1, 0xc0, 0xe0, 0x21, 0xf0, 0x22, 0xa1, 0xb1, 197 | 0x23, 0xb1, 0x50, 0x01, 0xb1, 0xae, 0x0f, 0xf9, 0xe0, 0x37, 0xf0, 0x22, 198 | 0x0f, 0xf6, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x0a, 0x00, 0x49, 199 | 0x00, 0x6e, 0x00, 0x70, 0x00, 0x75, 0x00, 0x74, 0x00, 0x20, 0x00, 0x61, 200 | 0x00, 0x20, 0x00, 0x63, 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00, 0x61, 201 | 0x00, 0x63, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x3e, 0x00, 0x20, 202 | 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 203 | 0x00, 0x20, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x74, 0x00, 0x69, 204 | 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 205 | 0x00, 0x20, 0x00, 0x4c, 0x00, 0x43, 0x00, 0x2d, 0x00, 0x33, 0x00, 0x20, 206 | 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 207 | 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x20, 208 | 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 209 | 0x00, 0x6e, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x72, 210 | 0x00, 0x61, 0x00, 0x70, 0x00, 0x20, 0x00, 0x65, 0x00, 0x78, 0x00, 0x65, 211 | 0x00, 0x63, 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 212 | 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00 213 | ]); 214 | --------------------------------------------------------------------------------