first public release

This commit is contained in:
copy 2013-11-06 01:12:55 +01:00
commit 8180d49f24
79 changed files with 28876 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
images/*

26
LICENSE Normal file
View file

@ -0,0 +1,26 @@
Copyright (c) 2012, Fabian Hemmer
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.

72
Makefile Normal file
View file

@ -0,0 +1,72 @@
CLOSURE=~/closure/closure-compiler/build/compiler.jar
CPP=cpp
all: v86_all.js
browser: v86_all.js
node: v86_node.js
src/cpu.js: src/*.macro.js
# build cpu.macro.js using cpp
$(CPP) -P -undef -Wundef -std=c99 -nostdinc -Wtrigraphs -fdollars-in-identifiers -C src/cpu.macro.js src/cpu.js
# Used for nodejs builds and in order to profile code.
# `debug` gives identifiers a readable name, make sure it doesn't have any side effects.
CLOSURE_READABLE=--formatting PRETTY_PRINT --debug
CLOSURE_SOURCE_MAP=\
--source_map_format V3\
--create_source_map
CLOSURE_FLAGS=\
--compilation_level ADVANCED_OPTIMIZATIONS\
--externs externs.js\
--warning_level VERBOSE\
--jscomp_off uselessCode\
--use_types_for_optimization\
--summary_detail_level 3\
--language_in ECMASCRIPT5_STRICT
CORE_FILES=const.js io.js cpu.js main.js disk.js pci.js floppy.js memory.js dma.js pit.js vga.js ps2.js pic.js rtc.js uart.js
BROWSER_FILES=browser/main.js browser/screen.js browser/keyboard.js browser/mouse.js
NODE_FILES=node/main.js node/keyboard.js node/screen.js
v86_all.js: src/*.js src/browser/*.js src/cpu.js
-ls -lh v86_all.js
cd src &&\
java -jar $(CLOSURE) \
--js_output_file "../v86_all.js"\
--define=DEBUG=false\
$(CLOSURE_SOURCE_MAP) v86_all.js.map\
$(CLOSURE_FLAGS)\
--js $(CORE_FILES)\
--js $(BROWSER_FILES)
echo "//# sourceMappingURL=src/v86_all.js.map" >> v86_all.js
ls -lh v86_all.js
v86_node.js: src/*.js src/node/*.js
cd src &&\
java -jar $(CLOSURE) \
--js_output_file "../v86_node.js"\
--define=DEBUG=false\
$(CLOSURE_FLAGS)\
--js $(CORE_FILES) $(NODE_FILES)
pack:
rm -f v86-latest.tar.gz
# Not sure if legally necessary
#--exclude "qemu"
tar -zcvf ../v86-latest.tar.gz ../v86/ \
--exclude "images" \
--exclude ".git"
clean:
rm -f v86-latest.tar.gz v86_all.js src/v86_all.js.map src/cpu.js

87
Readme.md Normal file
View file

@ -0,0 +1,87 @@
How does it work?
-
v86 emulates an x86-compatible CPU and hardware. Here's a list of emulated hardware:
- An x86 compatible CPU. The instruction set is around Pentium 1 level. Some
features are missing, more specifically:
- Task gates, far calls in protected mode
- 16 bit protected mode features and Virtual 8086 mode
- Single stepping
- MMX, SSE
- A bunch of FPU instructions, FPU exceptions
- Some other exceptions
- A floating point unit (FPU). Calculations are done with JavaScript's double
precision numbers (64 bit), so they are not as precise as calculations on a
real FPU (80 bit).
- An ISA bus.
- A floppy disk controller (8272A).
- A DMA (direct memory access) controller, currently only used by the FDC.
- An 8042 Keyboard Controller, PS2. With mouse support.
- An 8254 Programmable Interval Timer (PIT).
- An 8259 Programmable Interrupt Controller (PIC).
- A CMOS Real Time Clock (RTC).
- A VGA controller with SVGA support and Bochs VBE Extensions. This includes
support for large resolutions.
- A PCI bus. This one is mostly incomplete and not used by every device.
- An AT disk controller with some ATAPI and some SCSI commands. This is quite
incomplete and possibly buggy, too.
How to build, run and embed?
-
- In order to build the `cpu.js` file, you need `make` and `cpp` (the C preprocessor).
Run: `make src/cpu.js`.
- If you want a compressed and fast (ie, with debug code removed) version, you
need Closure Compiler.
Set the path to `compiler.jar` in the Makefile and run `make v86_all.js`.
- For more details on how to customize the behaviour and interface, see [docs/adapters.md](docs/adapters.md).
Why?
-
Similiar projects have been done before, but I decided to work on this as a fun
project and learn something about the x86 architecture. It has grown pretty
advanced and I just got Linux and KolibriOS working recently and
there might be some actual uses.
If you build something interesting, let me know. However, keep in mind that the project
is not very stable at the moment.
How can I contribute?
-
- Someone who could work on hardware devices, such as a modem or the AT
controller. I'll write an overview for that at a later point, if people are
interested.
- Donate. Since Bitcoin is the new cool thing, here's my address:
`14KBXSoewGzbQY8VoznJ5MZXGxoia8RxC9`
License
-
Simplified BSD License, see [LICENSE](LICENSE), unless otherwise noted.
Credits
-
- Test cases via QEMU, http://wiki.qemu.org/Main_Page
- https://github.com/creationix/node-sdl
- ascii.ttf (used in node) from http://www.apollosoft.de/ASCII/indexen.htm
More questions?
-
Shoot me an email to `copy@copy.sh`. Please don't tell about bugs via mail,
create a bug report on github instead.
Author
-
Fabian Hemmer (http://copy.sh/, `copy@copy.sh`)

165
bios/COPYING.LESSER Normal file
View file

@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

94
bios/seabios-config Normal file
View file

@ -0,0 +1,94 @@
#
# Automatically generated make config: don't edit
# SeaBIOS Configuration
# Sun Nov 18 21:22:50 2012
#
#
# General Features
#
# CONFIG_COREBOOT is not set
CONFIG_XEN=y
CONFIG_THREADS=y
# CONFIG_THREAD_OPTIONROMS is not set
CONFIG_RELOCATE_INIT=y
# CONFIG_BOOTMENU is not set
# CONFIG_BOOTORDER is not set
#
# Hardware support
#
CONFIG_ATA=y
# CONFIG_ATA_DMA is not set
# CONFIG_ATA_PIO32 is not set
CONFIG_AHCI=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_SCSI=y
CONFIG_ESP_SCSI=y
CONFIG_LSI_SCSI=y
CONFIG_FLOPPY=y
CONFIG_PS2PORT=y
CONFIG_USB=y
CONFIG_USB_UHCI=y
CONFIG_USB_OHCI=y
CONFIG_USB_EHCI=y
CONFIG_USB_MSC=y
CONFIG_USB_UAS=y
CONFIG_USB_HUB=y
CONFIG_USB_KEYBOARD=y
CONFIG_USB_MOUSE=y
CONFIG_SERIAL=y
CONFIG_LPT=y
CONFIG_USE_SMM=y
CONFIG_MTRR_INIT=y
#
# BIOS interfaces
#
CONFIG_DRIVES=y
CONFIG_CDROM_BOOT=y
CONFIG_CDROM_EMU=y
CONFIG_PCIBIOS=n
CONFIG_APMBIOS=n
CONFIG_PNPBIOS=n
CONFIG_OPTIONROMS=y
CONFIG_OPTIONROMS_DEPLOYED=y
CONFIG_PMM=y
CONFIG_BOOT=y
CONFIG_KEYBOARD=y
CONFIG_KBD_CALL_INT15_4F=y
CONFIG_MOUSE=y
CONFIG_S3_RESUME=y
CONFIG_VGAHOOKS=y
# CONFIG_DISABLE_A20 is not set
#
# BIOS Tables
#
CONFIG_PIRTABLE=n
CONFIG_MPTABLE=n
CONFIG_SMBIOS=n
CONFIG_ACPI=n
#
# VGA ROM
#
# CONFIG_NO_VGABIOS is not set
CONFIG_VGA_STANDARD_VGA=y
# CONFIG_VGA_CIRRUS is not set
# CONFIG_VGA_BOCHS is not set
# CONFIG_VGA_GEODEGX2 is not set
# CONFIG_VGA_GEODELX is not set
CONFIG_BUILD_VGABIOS=y
CONFIG_VGA_VBE=y
CONFIG_VGA_PCI=y
# CONFIG_OVERRIDE_PCI_ID is not set
CONFIG_VGA_VID=0x0000
CONFIG_VGA_DID=0x0000
#
# Debugging
#
CONFIG_DEBUG_LEVEL=2
# CONFIG_DEBUG_SERIAL is not set
CONFIG_DEBUG_IO=y

BIN
bios/seabios.bin Normal file

Binary file not shown.

BIN
bios/vgabios.bin Normal file

Binary file not shown.

71
debug.html Normal file
View file

@ -0,0 +1,71 @@
<!doctype html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Virtual x86</title>
<script src="loader.js"></script>
<link rel="stylesheet" href="v86.css">
<textarea readonly id="log"></textarea>
<div>
<a href="/v86/">To fast version</a>
<div id="boot_options">
CD image: <input type="file" id="cd_image"><br>
<small>(Bootable El Torito)</small><br><br>
Floppy disk image: <input type="file" id="floppy_image"><br>
<small>(1.44 or 2.88)</small><br><br>
Hard drive disk image: <input type="file" id="hd_image"><br>
<small></small><br><br>
<hr>
or <input type="button" value="Start FreeDOS" id="start_freedos">
<br>
<br>
<input type="button" value="Start Linux" id="start_linux">
<input type="button" value="Start KolibriOS" id="start_koli">
<input type="button" value="Start Windows" id="start_win101">
<input type="button" value="Start OpenBSD" id="start_bsd">
<input type="button" value="Start Test" id="start_test">
</div>
<div id="runtime_options" style="display: none">
<input type="button" value="Step" id="step">
<input type="button" value="Run until" id="run_until">
<input type="button" value="Debugger" id="debugger">
<br>
<div id="log_levels"></div>
<input type="button" value="Pause" id="run">
<input type="button" value="Reset" id="reset">
<input type="button" value="Send Ctrl-Alt-Del" id="ctrlaltdel">
<input type="button" value="Get floppy image" id="get_floppy">
<input type="button" value="Lock mouse" id="lock_mouse">
<input type="button" value="Go fullscreen" id="fullscreen">
Scale:
<input type="number" min="0.25" step="0.25" value="1.0" id="scale" style="width: 50px">
<div id="info">
<div>running <span id="running_time"></span>s</div>
<div>speed <span id="speed"></span>kIPS</div>
</div>
</div>
<pre style="display: none" id="loading"></pre>
<a href="readme.html">readme</a>
<br>
<br>
</div>
<div id="screen_container">
<div id="screen"></div>
<canvas id="vga"></canvas>
</div>
<br style="clear:both">
<input class="phone_keyboard">

15
docs/Makefile Normal file
View file

@ -0,0 +1,15 @@
DOCS=adapters embedding
HTML=$(addsuffix .html, $(DOCS))
MD=$(addsuffix .md, $(DOCS))
all: $(HTML)
%.html: %.md
markdown $< > $@
clean:
rm -f *.html

49
docs/adapters.md Normal file
View file

@ -0,0 +1,49 @@
Adapters are used to communicate between virtual hardware and the browser (or
nodejs, or anything else). Currently, there are 3 adapters: Keyboard, Mouse and
Screen. Adapters are passed through `settings.keyboard_adapter`,
`settings.mouse_adapter` and `settings.screen_adapter` respectively, but they
can also be undefined.
Here is a list of functions that must be implemented by adapters:
**ScreenAdapter:**
- `put_pixel(x, y, color)`
- `put_pixel_linear(offset, color_part)`
- `put_char(row, col, chr, bg_color, fg_color)`
- `update_cursor(row, col)`
- `update_cursor_scanline(start, end)`
- `clear_screen()`
- `timer_graphical()`
- `timer_text()`
- `set_mode(is_graphical)`
- `set_size_graphical(width, height)`
- `set_size_text(rows, cols)`
- `destroy()`
**KeyboardAdapter:**
- `init(send_code_fn)`
- `destroy()`
- `enabled`
**MouseAdapter:**
- `init(click_fn, move_fn, wheel_fn)`
- `destroy()`
- `enabled`
**More**
In addition to adapters, the following functions must be provided in global
scope (TODO: Improve that).
- `next_tick()`
- `set_tick(fn)`
- `log(str)` - only in debug modes
<br>
Everything on this page may be subject to change.

62
index.html Normal file
View file

@ -0,0 +1,62 @@
<!doctype html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Virtual x86</title>
<script src="v86_all.js"></script>
<link rel="stylesheet" href="v86.css">
<textarea readonly id="log"></textarea>
<div>
<div id="boot_options">
CD image: <input type="file" id="cd_image"><br>
<br>
Floppy disk image: <input type="file" id="floppy_image"><br>
<br>
Hard drive disk image: <input type="file" id="hd_image"><br>
<br>
- OR -
<br>
<br>
<input type="button" value="KolibriOS (1.4 MB)" id="start_koli"> - Graphical OS, takes about 60 seconds to boot<br>
<input type="button" value="Linux 2.6 (4.9 MB)" id="start_linux"> - With busybox and lua interpreter, takes about 20 seconds to boot<br>
<input type="button" value="Windows 1.01 (1.4 MB)" id="start_win101"> - Takes 1 second to boot<br>
<input type="button" value="FreeDOS (0.7 MB)" id="start_freedos"> - With nasm, vim, debug.com, some games and demos, takes 1 second to boot<br>
<input type="button" value="OpenBSD (1.4 MB)" id="start_bsd"> - Random boot floppy, takes very long to boot<br>
</div>
<div id="runtime_options" style="display: none">
<input type="button" value="Pause" id="run">
<input type="button" value="Reset" id="reset">
<input type="button" value="Send Ctrl-Alt-Del" id="ctrlaltdel">
<input type="button" value="Get modified floppy image" id="get_floppy">
<input type="button" value="Lock mouse" id="lock_mouse">
<input type="button" value="Go fullscreen" id="fullscreen">
Scale:
<input type="number" min="0.25" step="0.25" value="1.0" id="scale" style="width: 50px">
<div id="info">
<div>running <span id="running_time"></span>s</div>
<div>speed <span id="speed"></span>kIPS</div>
</div>
</div>
<pre style="display: none" id="loading"></pre>
<br>
<br>
</div>
<div id="screen_container">
<div id="screen"></div>
<canvas id="vga"></canvas>
</div>
<br style="clear: both">
<input type="text" class="phone_keyboard" style="display: none">
<br>
<b>News:</b> Source Code now available: <a href="https://github.com/copy/iwbtc">Github</a>, <a href="v86-latest.tar.gz">tarball</a>.</li>

28
loader.js Normal file
View file

@ -0,0 +1,28 @@
// load all files to run v86 in browser, uncompiled
(function()
{
var PATH = "src/",
CORE_FILES="const.js io.js cpu.js main.js disk.js pci.js floppy.js memory.js dma.js pit.js vga.js ps2.js pic.js rtc.js uart.js"
BROWSER_FILES="browser/main.js browser/screen.js browser/keyboard.js browser/mouse.js"
window.onload = function()
{
load_scripts(CORE_FILES);
load_scripts(BROWSER_FILES);
function load_scripts(resp)
{
var files = resp.split(" "),
script;
for(var i = 0; i < files.length; i++)
{
script = document.createElement("script");
script.src = PATH + files[i] + "?" + Math.random();
document.body.appendChild(script);
}
}
};
})();

1646
src/arith.macro.js Normal file

File diff suppressed because it is too large Load diff

236
src/browser/keyboard.js Normal file
View file

@ -0,0 +1,236 @@
"use strict";
/**
* @constructor
*/
function KeyboardAdapter()
{
var
/**
* @type {!Object.<boolean>}
*/
keys_pressed = {},
keyboard = this,
// callback to call on a keypress
send_code;
this.enabled = true;
/**
* Format:
* Javascript event.keyCode -> make code
* @const
*/
var charmap = new Uint16Array([
0, 0, 0, 0, 0, 0, 0, 0,
// 0x08: backspace, tab, enter
0x0E, 0x0F, 0, 0, 0, 0x1C, 0, 0,
// 0x10: shift, ctrl, alt, pause, caps lock
0x2A, 0x1D, 0x38, 0, 0x3A, 0, 0, 0,
// 0x18: escape
0, 0, 0, 0x01, 0, 0, 0, 0,
// 0x20: spacebar, page down/up, end, home, arrow keys, ins, del
0x39, 0xE049, 0xE051, 0x4F, 0x47, 0x4B, 0x48, 0x4D,
0x50, 0, 0, 0, 0, 0x52, 0x53, 0,
// 0x30: numbers
0x0B, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0A,
// 0x3B: ;= (firefox only)
0, 0x27, 0, 0x0D, 0, 0, 0,
// 0x65: letters
0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 0x32,
0x31, 0x18, 0x19, 0x10, 0x13, 0x1F, 0x14, 0x16, 0x2F, 0x11, 0x2D, 0x15, 0x2C,
0, 0, 0, 0, 0,
// 0x60: keypad
0x52, 0x4F, 0x50, 0x51, 0x4B, 0x4C, 0x4D, 0x47,
0x48, 0x49, 0, 0, 0, 0, 0, 0,
// 0x70: F1 to F12
0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x57, 0x58,
0, 0, 0, 0,
// 0x80
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// 0x90
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// 0xA0: - (firefox only)
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0x0C, 0, 0,
// 0xB0
// ,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0x27, 0x0D, 0x33, 0x0C, 0x34, 0x35,
// 0xC0
// `
0x29, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
// 0xD0
// [']\
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0x1A, 0x2B, 0x1B, 0x28, 0
]);
this.init = function(code_fn)
{
this.destroy();
send_code = code_fn;
window.addEventListener("keyup", keyup_handler, false);
window.addEventListener("keydown", keydown_handler, false);
window.addEventListener("blur", blur_handler, false);
};
this.destroy = function()
{
window.removeEventListener("keyup", keyup_handler, false);
window.removeEventListener("keydown", keydown_handler, false);
window.removeEventListener("blur", blur_handler, false);
};
function may_handle(e)
{
if(
(e.shiftKey && e.ctrlKey && e.keyCode === 74) ||
e.keyCode === 116
) {
// don't prevent opening chromium dev tools or F5
// maybe add other important combinations here, too
return false;
}
if(!keyboard.enabled)
{
return false;
}
if(e.target)
{
return e.target.className === "phone_keyboard" ||
(e.target.nodeName !== "INPUT" && e.target.nodeName !== "TEXTAREA");
}
else
{
return true;
}
}
function keyup_handler(e)
{
if(!may_handle(e))
{
return;
}
var code = e.keyCode;
if(!keys_pressed[code])
{
// stray keyup
return false;
}
keys_pressed[code] = false;
if(!handler(code, false))
{
e.preventDefault();
}
}
function keydown_handler(e)
{
if(!may_handle(e))
{
return;
}
var code = e.keyCode;
if(keys_pressed[code])
{
handler(code, false);
}
keys_pressed[code] = true;
if(!handler(code, true))
{
e.preventDefault();
}
}
function blur_handler(e)
{
// trigger keyup for all pressed keys
var keys = Object.keys(keys_pressed),
key;
for(var i = 0; i < keys.length; i++)
{
key = +keys[i];
if(keys_pressed[key])
{
handler(key, false);
}
}
keys_pressed = {};
}
/**
* @param {number} chr
* @param {boolean} keydown
*/
function handler(chr, keydown)
{
if(chr >= charmap.length || charmap[chr] === 0)
{
dbg_log("missing char: " + h(chr), LOG_PS2);
return true;
}
var code = charmap[chr];
if(!keydown)
{
code |= 0x80;
}
dbg_log("Key: " + h(code) + " from " + h(chr) + " down=" + keydown, LOG_PS2);
if(code > 0xFF)
{
// prefix
send_code(code >> 8);
send_code(code & 0xFF);
}
else
{
send_code(code);
}
return false;
}
}

589
src/browser/main.js Normal file
View file

@ -0,0 +1,589 @@
"use strict";
// setImmediate for the browser
var next_tick, set_tick;
(function()
{
var fn,
host = location.protocol + "//" + location.hostname;
set_tick = function(f)
{
fn = f;
window.removeEventListener("message", tick_handler, false);
window.addEventListener("message", tick_handler, false);
};
next_tick = function()
{
window.postMessage(null, host);
};
function tick_handler(e)
{
if(e.origin === host)
{
fn();
}
}
})();
function log(data)
{
var log_element = document.getElementById("log");
log_element.textContent += data + "\n";
log_element.scrollTop = 1e9;
}
function dump_text(text)
{
var box = document.createElement("textarea");
box.appendChild(document.createTextNode(text));
document.body.appendChild(box);
}
function dump_file(ab, name)
{
var blob = new Blob([ab]),
a;
a = document.createElement("a");
a["download"] = name;
a.href = window.URL.createObjectURL(blob),
a.textContent = "Download " + name;
a.onclick = function() { a.parentNode.removeChild(a); };
a.dataset["downloadurl"] = ["application/octet-stream", a["download"], a.href].join(":");
document.body.appendChild(a);
}
(function()
{
/** @param {?=} progress */
function load_file(filename, done, progress)
{
var http = new XMLHttpRequest();
http.open("get", filename, true);
http.responseType = "arraybuffer";
http.onload = function(e)
{
//if(http.readyState === 4 && http.status === 200)
if(http.response)
{
done(http.response);
}
};
if(progress)
{
http.onprogress = function(e)
{
progress(e);
};
}
http.send(null);
}
/**
* Asynchronous access to ArrayBuffer, loading blocks lazily as needed.
* This is just a prototype and partly incomplete.
*
* @constructor
* @param {string} filename Name of the file to download parts
* from. Replaces %d with the block number (padded)
*/
function AsyncXHRBuffer(filename, block_size, size)
{
var block_count = size / block_size,
loaded_blocks,
padding_width;
dbg_assert(block_count === (block_count | 0));
loaded_blocks = Array(block_count);
padding_width = ("" + (block_count - 1)).length;
this.byteLength = size;
// warning: fn may be called synchronously or asynchronously
this.get = function(start, len, fn)
{
// TODO: Unaligned read
dbg_assert(start % block_size === 0);
dbg_assert(len % block_size === 0);
dbg_assert(len);
var blocks_to_load = len / block_size,
data,
loaded_count = 0,
start_block = start / block_size;
if(blocks_to_load > 1)
{
// copy blocks in this buffer if there is more than one
data = new Uint8Array(len);
}
for(var i = start_block; i < start_block + blocks_to_load; i++)
{
this.load_block(i, block_loaded);
}
function block_loaded(buffer, i)
{
var block = new Uint8Array(buffer);
loaded_count++;
if(blocks_to_load === 1)
{
data = block;
}
else
{
data.set(block, (i - start_block) * block_size);
}
if(loaded_count === blocks_to_load)
{
fn(data);
}
}
};
this.load_block = function(i, fn)
{
var cached_block = loaded_blocks[i];
if(cached_block === undefined)
{
var file = filename.replace("%d", String.pad0(i, padding_width));
load_file(file, function(buffer)
{
loaded_blocks[i] = buffer;
fn(buffer, i);
});
}
else
{
fn(cached_block, i);
}
};
this.get_buffer = function(fn)
{
// We must download all parts, unlikely a good idea for big files
if(size > 32 * 1024 * 1024)
{
dbg_log("Warning: Downloading all parts of a huge file. Will probably " +
"crash or never finish");
}
this.get(0, size, function(data)
{
return data.buffer;
});
};
this.set = function(start, slice, fn)
{
// Discard (we can't write to the server)
// TODO: Put data into cache
};
}
function lock_mouse(elem)
{
var fn = elem["requestPointerLock"] ||
elem["mozRequestPointerLock"] ||
elem["webkitRequestPointerLock"];
if(fn)
{
fn.call(elem);
}
}
function show_progress(e)
{
var el = $("loading");
el.style.display = "block";
if(e.lengthComputable)
{
var per50 = e.loaded / e.total * 50 | 0;
el.textContent = "Loading: " + 2 * per50 + "% [" +
String.chr_repeat("#", per50) +
String.chr_repeat(" ", 50 - per50) + "]";
}
else
{
el.textContent = "Loading ...";
}
}
function $(id)
{
return document.getElementById(id);
}
window.onload = function()
{
if(!("responseType" in new XMLHttpRequest))
{
log("Your browser is not supported because it doesn't have XMLHttpRequest.responseType");
return;
}
var settings = {
load_devices: true
};
$("lock_mouse").onclick = function()
{
lock_mouse(document.body);
$("lock_mouse").blur();
};
load_file("bios/seabios.bin", function(img)
{
settings.bios = img;
});
load_file("bios/vgabios.bin", function(img)
{
settings.vga_bios = img;
});
function load_local(me, type)
{
if(me.files.length)
{
var reader = new FileReader();
reader.onload = function(e)
{
var buffer = new SyncBuffer(e.target.result);
switch(type)
{
case "floppy":
settings.floppy_disk = buffer;
break;
case "hd":
settings.hda_disk = buffer;
break;
case "cdrom":
settings.cdrom_disk = buffer;
break;
}
init(settings);
};
//reader.readAsBinaryString($("file").files[0]);
reader.readAsArrayBuffer(me.files[0]);
}
};
$("floppy_image").onchange = function()
{
load_local(this, "floppy");
};
$("cd_image").onchange = function()
{
load_local(this, "cdrom");
};
$("hd_image").onchange = function()
{
load_local(this, "hd");
};
$("start_freedos").onclick = function()
{
load_file("images/freedos722.img", function(buffer)
{
settings.floppy_disk = new SyncBuffer(buffer);
init(settings);
}, show_progress);
$("start_freedos").blur();
};
$("start_win101").onclick = function()
{
load_file("images/windows101.img", function(buffer)
{
settings.floppy_disk = new SyncBuffer(buffer);
init(settings);
}, show_progress);
$("start_win101").blur();
};
$("start_linux").onclick = function()
{
load_file("images/linux.iso", function(buffer)
{
settings.cdrom_disk = new SyncBuffer(buffer);
init(settings);
}, show_progress);
$("start_linux").blur();
};
$("start_koli").onclick = function()
{
load_file("images/kolibri.img", function(buffer)
{
settings.floppy_disk = new SyncBuffer(buffer);
init(settings);
}, show_progress);
$("start_koli").blur();
};
$("start_bsd").onclick = function()
{
load_file("images/openbsd.img", function(buffer)
{
settings.floppy_disk = new SyncBuffer(buffer);
init(settings);
}, show_progress);
$("start_bsd").blur();
};
if(DEBUG)
{
$("start_test").onclick = function()
{
settings.floppy_disk = new AsyncXHRBuffer("images/fd/freedos.part%d.img", 512, 720 * 1024);
init(settings);
//settings.bios = settings.vga_bios = undefined;
//settings.linux = {};
////settings.linux.cmdline = "console=ttyS0 root=/dev/hda ro init=/sbin/init notsc=1 hdb=none"
//settings.linux.cmdline = "root=/dev/ram0 rw init=/sbin/init notsc=1";
//load_file("images/linux/vmlinux.bin", function(buffer)
//{
// settings.linux.vmlinux = buffer;
// load_file("images/linux/linuxstart.bin", function(buffer)
// {
// settings.linux.linuxstart = buffer;
// load_file("images/linux/root.bin", function(buffer)
// {
// settings.linux.root = buffer;
// init(settings);
// });
// });
//});
}
}
};
// works in firefox and chromium
if(document.readyState === "complete")
{
window.onload();
}
// load_external("https://dl.dropbox.com/example/freedos.img.js");
function load_external(url)
{
window["loaded"] = function(bin_image)
{
var buffer = new ArrayBuffer(bin_image.length),
buffer_array = new Uint8Array(buffer);
for(var i = 0; i < bin_image.length; i++)
{
buffer_array[i] = bin_image.charCodeAt(i);
}
window["loaded"] = function() {
dbg_log("load_external: result loaded twice ?");
};
};
var script = document.createElement("script");
script.src = url;
document.body.appendChild(script);
}
function init(settings)
{
var cpu = new v86(),
screen_adapter = new ScreenAdapter();
$("boot_options").parentNode.removeChild($("boot_options"));
$("loading").style.display = "none";
$("runtime_options").style.display = "block";
document.getElementsByClassName("phone_keyboard")[0].style.display = "block";
if(DEBUG)
{
$("step").onclick = function()
{
debug.step();
}
$("run_until").onclick = function()
{
debug.run_until();
};
$("debugger").onclick = function()
{
debug.debugger();
};
}
var running = true;
$("run").onclick = function()
{
if(running)
{
running_time += Date.now() - last_tick;
$("run").value = "Run";
cpu.stop();
}
else
{
$("run").value = "Pause";
cpu.run();
last_tick = Date.now();
}
running = !running;
$("run").blur();
};
var time = document.getElementById("running_time"),
ips = document.getElementById("speed"),
last_tick = Date.now(),
running_time = 0,
last_instr_counter = 0;
function update_info()
{
if(running)
{
var now = Date.now();
running_time += now - last_tick;
last_tick = now;
ips.textContent = (cpu.instr_counter - last_instr_counter) / 1000 | 0;
time.textContent = (running_time / 1000 | 0);
last_instr_counter = cpu.instr_counter;
}
}
setInterval(update_info, 1000);
$("reset").onclick = function()
{
cpu.restart();
$("reset").blur();
};
$("get_floppy").onclick = function()
{
var buffer = cpu.dev.fdc.buffer;
if(!buffer)
{
return;
}
buffer.get_buffer(function(b)
{
dump_file(b, "floppy.img");
});
$("get_floppy").blur();
};
$("ctrlaltdel").onclick = function()
{
var ps2 = cpu.dev.ps2;
ps2.kbd_send_code(0x1D); // ctrl
ps2.kbd_send_code(0x38); // alt
ps2.kbd_send_code(0x53); // delete
// break codes
ps2.kbd_send_code(0x1D | 0x80);
ps2.kbd_send_code(0x38 | 0x80);
ps2.kbd_send_code(0x53 | 0x80);
$("ctrlaltdel").blur();
};
$("scale").onchange = function()
{
var n = parseFloat(this.value);
if(n || n > 0)
{
screen_adapter.set_scale(n, n);
}
else
{
this.value = "1";
}
};
$("fullscreen").onclick = function()
{
var elem = document.getElementById("screen_container"),
// bracket notation because otherwise they get renamed by closure compiler
fn = elem["requestFullScreen"] ||
elem["webkitRequestFullscreen"] ||
elem["mozRequestFullScreen"] ||
elem["msRequestFullScreen"];
if(fn)
{
fn.call(elem);
// This is necessary, because otherwise chromium keyboard doesn't work anymore.
// Might (but doesn't seem to) break something else
document.getElementsByClassName("phone_keyboard")[0].focus();
}
lock_mouse(elem);
};
settings.screen_adapter = screen_adapter;
settings.keyboard_adapter = new KeyboardAdapter();
settings.mouse_adapter = new MouseAdapter();
cpu.init(settings);
cpu.run();
}
})();

132
src/browser/mouse.js Normal file
View file

@ -0,0 +1,132 @@
/** @constructor */
function MouseAdapter()
{
/** @const */
var SPEED_FACTOR = .5;
var left_down = false,
right_down = false,
middle_down = false,
last_x = 0,
last_y = 0,
// callback to call on a mouse click
send_click,
// callback to call on a mouse move
send_delta,
mouse = this;
this.enabled = false;
function may_handle(e)
{
return mouse.enabled &&
(!e.target || e.type === "mousemove" || (e.target.nodeName !== "INPUT" && e.target.nodeName !== "TEXTAREA"));
}
this.destroy = function()
{
window.removeEventListener("mousemove", mousemove_handler, false);
document.removeEventListener("contextmenu", contextmenu_handler, false);
window.removeEventListener("mousedown", mousedown_handler, false);
window.removeEventListener("mouseup", mouseup_handler, false);
};
this.init = function(click_fn, delta_fn, wheel_fn)
{
this.destroy();
send_click = click_fn;
send_delta = delta_fn;
// TODO: wheel_fn
window.addEventListener("mousemove", mousemove_handler, false);
document.addEventListener("contextmenu", contextmenu_handler, false);
window.addEventListener("mousedown", mousedown_handler, false);
window.addEventListener("mouseup", mouseup_handler, false);
};
function mousemove_handler(e)
{
if(!may_handle(e))
{
return;
}
var delta_x, delta_y;
if(true)
{
delta_x = e["webkitMovementX"] || e["mozMovementX"] || 0;
delta_y = e["webkitMovementY"] || e["mozMovementY"] || 0;
}
else
{
// Fallback for other browsers?
delta_x = e.clientX - last_x;
delta_y = e.clientY - last_y;
last_x = e.clientX;
last_y = e.clientY;
}
delta_x = Math.roundInfinity(delta_x * SPEED_FACTOR);
delta_y = Math.roundInfinity(delta_y * SPEED_FACTOR);
send_delta(delta_x, -delta_y);
}
function contextmenu_handler(e)
{
if(may_handle(e))
{
e.preventDefault();
}
}
function mousedown_handler(e)
{
if(may_handle(e))
{
click_event(e, true);
}
}
function mouseup_handler(e)
{
if(may_handle(e))
{
click_event(e, false);
}
}
function click_event(e, down)
{
if(e.which === 1)
{
left_down = down;
}
else if(e.which === 2)
{
middle_down = down;
}
else if(e.which === 3)
{
right_down = down;
}
else
{
dbg_log("Unknown event.which: " + e.which, LOG_MOUSE);
}
send_click(left_down, middle_down, right_down);
e.preventDefault();
}
}

354
src/browser/screen.js Normal file
View file

@ -0,0 +1,354 @@
"use strict";
if(!window.requestAnimationFrame)
{
window.requestAnimationFrame =
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame;
}
/**
* Adapter to use visual screen in browsers (in constrast to node)
* @constructor
*/
function ScreenAdapter()
{
var
dom_target = document.body,
text_screen = document.getElementById("screen"),
graphic_screen = document.getElementById("vga"),
graphic_context = graphic_screen.getContext("2d"),
cursor_element = document.createElement("div"),
graphic_image_data,
graphic_buffer,
/** @type {number} */
cursor_row,
/** @type {number} */
cursor_col,
/** @type {number} */
scale_x = 1,
/** @type {number} */
scale_y = 1,
graphical_mode_width,
screen = this,
changed_rows,
did_redraw = true,
// Index 0: ASCII code
// Index 1: Background color
// Index 2: Foreground color
text_mode_data,
// number of columns
text_mode_width,
// number of rows
text_mode_height;
/**
* Charmaps that containt unicode sequences for the default dospage
* @const
*/
var charmap_high = new Uint16Array([
0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7,
0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5,
0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9,
0xFF, 0xD6, 0xDC, 0xA2, 0xA3, 0xA5, 0x20A7, 0x192,
0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA,
0xBF, 0x2310, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
0x3B1, 0xDF, 0x393, 0x3C0, 0x3A3, 0x3C3, 0xB5, 0x3C4,
0x3A6, 0x398, 0x3A9, 0x3B4, 0x221E, 0x3C6, 0x3B5, 0x2229,
0x2261, 0xB1, 0x2265, 0x2264, 0x2320, 0x2321, 0xF7,
0x2248, 0xB0, 0x2219, 0xB7, 0x221A, 0x207F, 0xB2, 0x25A0, 0xA0
]);
/** @const */
var charmap_low = new Uint16Array([
0x20, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
0x25BA, 0x25C4, 0x2195, 0x203C, 0xB6, 0xA7, 0x25AC, 0x21A8,
0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC
]);
graphic_context["imageSmoothingEnabled"] = false;
graphic_context["mozImageSmoothingEnabled"] = false;
graphic_context["webkitImageSmoothingEnabled"] = false;
cursor_element.id = "cursor";
text_screen.style.display = "block";
graphic_screen.style.display = "none";
this.put_char = function(row, col, chr, bg_color, fg_color)
{
changed_rows[row] = 1;
var p = 3 * (row * text_mode_width + col);
text_mode_data[p] = chr;
text_mode_data[p + 1] = bg_color;
text_mode_data[p + 2] = fg_color;
};
this.timer_text = function()
{
if(!did_redraw)
{
return;
}
did_redraw = false;
requestAnimationFrame(update_text);
};
function update_text()
{
did_redraw = true;
for(var i = 0; i < text_mode_height; i++)
{
if(changed_rows[i])
{
screen.text_update_row(i);
changed_rows[i] = 0;
}
}
}
this.put_pixel = function(x, y, color)
{
var offset = y * graphical_mode_width + x << 2;
graphic_buffer[offset] = color >> 16 & 0xFF;
graphic_buffer[offset + 1] = color >> 8 & 0xFF;
graphic_buffer[offset + 2] = color & 0xFF;
};
this.put_pixel_linear = function(index, color)
{
// (addr ^ 3) - 1: Change BGR (svga) order to RGB (canvas)
graphic_buffer[(index ^ 3) - 1] = color;
};
this.timer_graphical = function()
{
if(!did_redraw)
{
return;
}
did_redraw = false;
requestAnimationFrame(function()
{
did_redraw = true;
graphic_context.putImageData(graphic_image_data, 0, 0);
});
};
this.destroy = function()
{
//dom_target.removeChild(text_screen);
//dom_target.removeChild(graphic_screen);
};
this.set_mode = function(graphical)
{
if(graphical)
{
text_screen.style.display = "none";
graphic_screen.style.display = "block";
}
else
{
text_screen.style.display = "block";
graphic_screen.style.display = "none";
}
};
this.clear_screen = function()
{
graphic_context.fillStyle = "#000";
graphic_context.fillRect(0, 0, graphic_screen.width, graphic_screen.height);
};
/**
* @param {number} cols
* @param {number} rows
*/
this.set_size_text = function(cols, rows)
{
changed_rows = new Int8Array(rows);
text_mode_data = new Int32Array(cols * rows * 3);
text_mode_width = cols;
text_mode_height = rows;
while(text_screen.firstChild)
{
text_screen.removeChild(text_screen.firstChild);
}
for(var i = 0; i < rows; i++)
{
text_screen.appendChild(document.createElement("div"));
}
};
this.set_size_graphical = function(width, height)
{
graphic_screen.style.display = "block";
graphic_screen.width = width;
graphic_screen.height = height;
//graphic_screen.style.width = width * scale_x + "px";
//graphic_screen.style.height = height * scale_y + "px";
// Make sure to call this here, because pixels are transparent otherwise
screen.clear_screen();
graphic_image_data = graphic_context.getImageData(0, 0, width, height);
graphic_buffer = graphic_image_data.data;
graphical_mode_width = width;
};
this.set_scale = function(s_x, s_y)
{
scale_x = s_x;
scale_y = s_y;
elem_set_scale(graphic_screen, scale_x, scale_y);
elem_set_scale(text_screen, scale_x, scale_y);
};
this.set_scale(scale_x, scale_y);
function elem_set_scale(elem, scale_x, scale_y)
{
var scale_str = "";
scale_str += scale_x === 1 ? "" : " scaleX(" + scale_x + ")";
scale_str += scale_y === 1 ? "" : " scaleY(" + scale_y + ")";
elem.style.webkitTransform = elem.style.MozTransform = scale_str;
}
this.update_cursor_scanline = function(start, end)
{
if(start & 0x20)
{
cursor_element.style.display = "none";
}
else
{
cursor_element.style.display = "inline";
cursor_element.style.height = (end - start) + "px";
cursor_element.style.marginTop = start + "px";
}
};
this.update_cursor = function(row, col)
{
if(row !== cursor_row || col !== cursor_col)
{
changed_rows[row] = 1;
changed_rows[cursor_row] = 1;
cursor_row = row;
cursor_col = col;
}
};
this.text_update_row = function(row)
{
var offset = 3 * row * text_mode_width,
row_element,
color_element,
bg_color,
fg_color,
text;
row_element = document.createElement("div");
for(var i = 0; i < text_mode_width; )
{
color_element = document.createElement("span");
bg_color = text_mode_data[offset + 1];
fg_color = text_mode_data[offset + 2];
color_element.style.backgroundColor = "#" + h(bg_color, 6);
color_element.style.color = "#" + h(fg_color, 6);
text = "";
// put characters of the same color in one element
while(i < text_mode_width
&& text_mode_data[offset + 1] === bg_color
&& text_mode_data[offset + 2] === fg_color)
{
var ascii = text_mode_data[offset],
chr;
// use of utf-8
if(ascii > 127)
{
chr = String.fromCharCode(charmap_high[ascii - 0x80]);
}
else if(ascii < 32)
{
chr = String.fromCharCode(charmap_low[ascii]);
}
else
{
chr = String.fromCharCode(ascii);
}
text += chr;
i++;
offset += 3;
if(row === cursor_row)
{
if(i === cursor_col)
{
// next row will be cursor
// create new element
break;
}
else if(i === cursor_col + 1)
{
// found the cursor
row_element.appendChild(cursor_element);
break;
}
}
}
color_element.textContent = text;
row_element.appendChild(color_element);
}
text_screen.replaceChild(row_element, text_screen.childNodes[row]);
};
}

155
src/const.js Normal file
View file

@ -0,0 +1,155 @@
/** @define {boolean} */
var DEBUG = true;
var
/**
* @const
* @type {number}
*/
memory_size = 1024 * 1024 * 64;
var
/** @const */ LOG_ALL = -1,
/** @const */ LOG_NONE = 0,
/** @const */ LOG_OTHER = 0x00001,
/** @const */ LOG_CPU = 0x00002,
/** @const */ LOG_FPU = 0x00004,
/** @const */ LOG_MEM = 0x00008,
/** @const */ LOG_DMA = 0x00010,
/** @const */ LOG_IO = 0x00020,
/** @const */ LOG_PS2 = 0x00040,
/** @const */ LOG_PIC = 0x00080,
/** @const */ LOG_VGA = 0x00100,
/** @const */ LOG_PIT = 0x00200,
/** @const */ LOG_MOUSE = 0x00400,
/** @const */ LOG_PCI = 0x00800,
/** @const */ LOG_BIOS = 0x01000,
/** @const */ LOG_CD = 0x02000,
/** @const */ LOG_SERIAL = 0x04000,
/** @const */ LOG_DISK = 0x08000,
/** @const */ LOG_RTC = 0x10000,
///** @const */ LOG_LEVEL = LOG_OTHER | LOG_PS2 | LOG_BIOS;
///** @const */ LOG_LEVEL = LOG_PS2 | LOG_OTHER | LOG_IO;
///** @const */ LOG_LEVEL = LOG_PS2;
///** @const */ LOG_LEVEL = LOG_OTHER | LOG_CPU | LOG_BIOS;
///** @const */ LOG_LEVEL = LOG_VGA | LOG_IO | LOG_BIOS | LOG_OTHER;
///** @const */ LOG_LEVEL = LOG_FPU | LOG_OTHER;
///** @const */ LOG_LEVEL = LOG_DMA | LOG_DISK | LOG_IO | LOG_PCI;
///** @const */ LOG_LEVEL = LOG_DMA | LOG_DISK | LOG_PCI | LOG_CD | LOG_BIOS;
/** @const */ LOG_LEVEL = LOG_ALL & ~LOG_DISK & ~LOG_DMA & ~LOG_VGA & ~LOG_PS2 & ~LOG_FPU;
///** @const */ LOG_LEVEL = LOG_SERIAL | LOG_IO;
///** @const */ LOG_LEVEL = LOG_PIT | LOG_RTC;
///** @const */ LOG_LEVEL = 0;
var
/** @const */ TLB_SYSTEM_READ = 1,
/** @const */ TLB_SYSTEM_WRITE = 2,
/** @const */ TLB_USER_READ = 4,
/** @const */ TLB_USER_WRITE = 8;
var
// flags register bitflags
/** @const */ flag_carry = 1,
/** @const */ flag_parity = 4,
/** @const */ flag_adjust = 16,
/** @const */ flag_zero = 64,
/** @const */ flag_sign = 128,
/** @const */ flag_trap = 256,
/** @const */ flag_interrupt = 512,
/** @const */ flag_direction = 1024,
/** @const */ flag_overflow = 2048,
/** @const */ flag_iopl = 1 << 12 | 1 << 13,
/** @const */ flag_nt = 1 << 14,
/** @const */ flag_vm = 1 << 17,
/**
* default values of unused flags bits
* @const
*/
flags_default = 1 << 1,
/**
* bitmask to select used flags bits
* @const
*/
flags_mask = 1 << 0 | 1 << 2 | 1 << 4 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9
| 1 << 10 | 1 << 11 | 1 << 12 | 1 << 13 | 1 << 14 |
1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 | 1 << 21,
/**
* all arithmetic flags
* @const
*/
flags_all = flag_carry | flag_parity | flag_adjust | flag_zero | flag_sign | flag_overflow,
/**
* opsizes used by get flag functions
*
* @const
*/
OPSIZE_8 = 8,
/** @const */
OPSIZE_16 = 16,
/** @const */
OPSIZE_32 = 32,
/** @const */
PSE_ENABLED = 128,
/** @const */ reg_eax = 0,
/** @const */ reg_ecx = 1,
/** @const */ reg_edx = 2,
/** @const */ reg_ebx = 3,
/** @const */ reg_esp = 4,
/** @const */ reg_ebp = 5,
/** @const */ reg_esi = 6,
/** @const */ reg_edi = 7,
/** @const */ reg_ax = 0,
/** @const */ reg_cx = 2,
/** @const */ reg_dx = 4,
/** @const */ reg_bx = 6,
/** @const */ reg_sp = 8,
/** @const */ reg_bp = 10,
/** @const */ reg_si = 12,
/** @const */ reg_di = 14,
/** @const */ reg_al = 0,
/** @const */ reg_cl = 4,
/** @const */ reg_dl = 8,
/** @const */ reg_bl = 12,
/** @const */ reg_ah = 1,
/** @const */ reg_ch = 5,
/** @const */ reg_dh = 9,
/** @const */ reg_bh = 13,
/** @const */ reg_es = 0,
/** @const */ reg_cs = 1,
/** @const */ reg_ss = 2,
/** @const */ reg_ds = 3,
/** @const */ reg_fs = 4,
/** @const */ reg_gs = 5,
/** @const */ reg_noseg = 6,
/** @const */ LOOP_COUNTER = 20001,
/** @const */ TIME_PER_FRAME = 33;

6029
src/cpu.js Normal file

File diff suppressed because one or more lines are too long

2384
src/cpu.macro.js Normal file

File diff suppressed because it is too large Load diff

445
src/debug.macro.js Normal file
View file

@ -0,0 +1,445 @@
"use strict";
debug.dump_regs = dump_regs;
debug.dump_regs_short = dump_regs_short;
debug.dump_stack = dump_stack;
debug.dump_page_directory = dump_page_directory;
debug.dump_gdt_ldt = dump_gdt_ldt;
debug.dump_idt = dump_idt;
debug.step = step;
debug.run_until = run_until;
debug.debugger = function()
{
debugger;
}
function step()
{
step_mode = true;
if(!running)
{
cycle();
}
dump_regs();
var now = Date.now();
vga.timer(now);
timer.timer(now);
rtc.timer(now);
running = false;
}
function run_until()
{
running = false;
var a = parseInt(prompt("input hex", ""), 16);
if(a) while(instruction_pointer != a) cycle()
dump_regs();
}
// http://ref.x86asm.net/x86reference.xml
// for debuggin' purposes
var opcode_map = [
"ADD", "ADD", "ADD", "ADD", "ADD", "ADD", "PUSH", "POP",
"OR", "OR", "OR", "OR", "OR", "OR", "PUSH", "0F:",
"ADC", "ADC", "ADC", "ADC", "ADC", "ADC", "PUSH", "POP",
"SBB", "SBB", "SBB", "SBB", "SBB", "SBB", "PUSH", "POP",
"AND", "AND", "AND", "AND", "AND", "AND", "ES", "DAA",
"SUB", "SUB", "SUB", "SUB", "SUB", "SUB", "CS", "DAS",
"XOR", "XOR", "XOR", "XOR", "XOR", "XOR", "SS", "AAA",
"CMP", "CMP", "CMP", "CMP", "CMP", "CMP", "DS", "AAS",
"INC", "INC", "INC", "INC", "INC", "INC", "INC", "INC",
"DEC", "DEC", "DEC", "DEC", "DEC", "DEC", "DEC", "DEC",
"PUSH", "PUSH", "PUSH", "PUSH", "PUSH", "PUSH", "PUSH", "PUSH",
"POP", "POP", "POP", "POP", "POP", "POP", "POP", "POP",
"PUSHA", "POPA", "BOUND", "ARPL", "FS", "GS", "none", "none",
"PUSH", "IMUL", "PUSH", "IMUL", "INS", "INS", "OUTS", "OUTS",
"JO", "JNO", "JB", "JNB", "JZ", "JNZ", "JBE", "JNBE",
"JS", "JNS", "JP", "JNP", "JL", "JNL", "JLE", "JNLE",
"ADD", "ADD", "ADD", "ADD", "TEST", "TEST", "XCHG", "XCHG",
"MOV", "MOV", "MOV", "MOV", "MOV", "LEA", "MOV", "POP",
"NOP", "XCHG", "XCHG", "XCHG", "XCHG", "XCHG", "XCHG", "XCHG",
"CBW", "CWD", "CALLF", "FWAIT", "PUSHF", "POPF", "SAHF", "LAHF",
"MOV", "MOV", "MOV", "MOV", "MOVS", "MOVS", "CMPS", "CMPS",
"TEST", "TEST", "STOS", "STOS", "LODS", "LODS", "SCAS", "SCAS",
"MOV", "MOV", "MOV", "MOV", "MOV", "MOV", "MOV", "MOV",
"MOV", "MOV", "MOV", "MOV", "MOV", "MOV", "MOV", "MOV",
"ROL", "ROL", "RETN", "RETN", "LES", "LDS", "MOV", "MOV",
"ENTER", "LEAVE", "RETF", "RETF", "INT", "INT", "INTO", "IRET",
"ROL", "ROL", "ROL", "ROL", "AAM", "AAD", "none", "XLAT",
"FADD", "FLD", "FIADD", "FILD", "FADD", "FLD", "FIADD", "FILD",
"LOOPNZ", "LOOPZ", "LOOP", "JCXZ", "IN", "IN", "OUT", "OUT",
"CALL", "JMP", "JMPF", "JMP", "IN", "IN", "OUT", "OUT",
"LOCK", "none", "REPNZ", "REPZ", "HLT", "CMC", "TEST", "TEST",
"CLC", "STC", "CLI", "STI", "CLD", "STD", "INC", "INC"
];
function logop(_ip, op)
{
if(!DEBUG || !ops)
{
return;
}
if(!step_mode)
{
//return;
}
ops.add(_ip);
ops.add(opcode_map[op] || "unkown");
ops.add(op);
}
function dump_stack(start, end)
{
var esp = reg32[reg_esp];
dbg_log("========= STACK ==========");
if(end >= start || end === undefined)
{
start = 5;
end = -5;
}
for(var i = start; i > end; i--)
{
var line = " ";
if(!i) line = "=> ";
line += h(i, 2) + " | ";
dbg_log(line + h(esp + 4 * i, 8) + " | " + h(memory.read32s(esp + 4 * i) >>> 0));
}
}
function dump_regs_short()
{
var
r32 = { "eax": reg_eax, "ecx": reg_ecx, "edx": reg_edx, "ebx": reg_ebx,
"esp": reg_esp, "ebp": reg_ebp, "esi": reg_esi, "edi": reg_edi },
r32_names = ["eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"],
s = { "cs": reg_cs, "ds": reg_ds, "es": reg_es, "fs": reg_fs, "gs": reg_gs, "ss": reg_ss },
line1 = "",
line2 = "";
for(var i = 0; i < 4; i++)
{
line1 += r32_names[i] + "=" + h(reg32[r32[r32_names[i]]], 8) + " ";
line2 += r32_names[i+4] + "=" + h(reg32[r32[r32_names[i+4]]], 8) + " ";
}
line1 += " eip=" + h(get_real_ip(), 8);
line2 += " flg=" + h(get_flags());
line1 += " ds=" + h(sreg[reg_ds], 4) + " es=" + h(sreg[reg_es], 4) + " fs=" + h(sreg[reg_fs], 4);
line2 += " gs=" + h(sreg[reg_gs], 4) + " cs=" + h(sreg[reg_cs], 4) + " ss=" + h(sreg[reg_ss], 4);
dbg_log(line1);
dbg_log(line2);
}
function dump_regs()
{
var
r32 = { "eax": reg_eax, "ecx": reg_ecx, "edx": reg_edx, "ebx": reg_ebx,
"esp": reg_esp, "ebp": reg_ebp, "esi": reg_esi, "edi": reg_edi },
s = { "cs": reg_cs, "ds": reg_ds, "es": reg_es,
"fs": reg_fs, "gs": reg_gs, "ss": reg_ss },
out = "";
var opcodes = ops.toArray();
for(var i = 0; i < opcodes.length; i += 3)
{
if(opcodes[i])
{
out += h(opcodes[i], 6) + ": " +
String.pads(opcodes[i + 1], 20) + h(opcodes[i + 2], 2) + "\n";
}
}
log(out.substr(0, out.length - 1));
ops.clear();
dbg_log("----- DUMP (ip = 0x" + h(instruction_pointer >>> 0) + ") ----------")
dbg_log("protected mode: " + protected_mode);
for(i in r32)
{
dbg_log(i + " = 0x" + h(reg32[r32[i]], 8));
}
dbg_log("eip = 0x" + h(get_real_ip(), 8));
for(i in s)
{
dbg_log(i + " = 0x" + h(sreg[s[i]], 4));
}
out = "";
var flg = { "cf": getcf, "pf": getpf, "zf": getzf, "sf": getsf,
"of": getof, "df": flag_direction, "if": flag_interrupt };
for(var i in flg)
{
if(+flg[i])
{
out += i + "=" + Number(!!(flags & flg[i])) + " | ";
}
else
{
out += i + "=" + Number(!!flg[i]()) + " | ";
}
}
out += "iopl=" + getiopl();
dbg_log(out);
//dbg_log("last operation: " + h(last_op1 | 0) + ", " + h(last_op2 | 0) + " = " +
//h(last_result | 0) + " (" + last_op_size + " bit)")
}
function dump_gdt_ldt()
{
dbg_log("gdt: (len = " + h(gdtr_size) + ")");
dump_table(translate_address_read(gdtr_offset), gdtr_size);
dbg_log("\nldt: (len = " + h(ldtr_size) + ")");
dump_table(translate_address_read(ldtr_offset), ldtr_size);
function dump_table(addr, size)
{
for(var i = 0; i < size; i += 8, addr += 8)
{
var base = memory.read16(addr + 2) |
memory.read8(addr + 4) << 16 |
memory.read8(addr + 7) << 24,
limit = (memory.read16(addr) | memory.read8(addr + 6) & 0xF) + 1,
access = memory.read8(addr + 5),
flags = memory.read8(addr + 6) >> 4,
flags_str = '',
dpl = access >> 5 & 3;
if(!(access & 128))
{
// present bit not set
//continue;
flags_str += 'NP ';
}
else
{
flags_str += ' P ';
}
if(access & 16)
{
if(flags & 4)
{
flags_str += '32b ';
}
else
{
flags_str += '16b ';
}
if(access & 8)
{
// executable
flags_str += 'X ';
if(access & 4)
{
flags_str += 'C ';
}
}
else
{
// data
flags_str += 'R ';
}
}
else
{
// system
flags_str += 'sys: ' + h(access & 15);
}
if(flags & 8)
{
limit <<= 12;
}
dbg_log(h(i & ~7, 4) + " " + h(base >>> 0, 8) + " (" + h(limit, 8) + " bytes) " +
flags_str + "; dpl = " + dpl + ", a = " + access.toString(2) +
", f = " + flags.toString(2));
}
}
}
function dump_idt()
{
for(var i = 0; i < idtr_size; i += 8)
{
var addr = do_page_translation(idtr_offset + i, 0, 0),
base = memory.read16(addr) | memory.read16(addr + 6) << 16,
selector = memory.read16(addr + 2),
type = memory.read8(addr + 5),
line,
dpl = type >> 5 & 3;
if((type & 31) === 5)
{
line = 'task gate ';
}
else if((type & 31) === 14)
{
line = 'intr gate ';
}
else if((type & 31) === 15)
{
line = 'trap gate ';
}
else
{
line = 'invalid ';
}
if(type & 128)
{
line += ' P';
}
else
{
// present bit not set
//continue;
line += 'NP';
}
dbg_log(h(i >> 3, 4) + " " + h(base >>> 0, 8) + ", " +
h(selector, 4) + "; " + line + "; dpl = " + dpl + ", t = " + type.toString(2));
}
}
function load_page_entry(dword_entry, is_directory)
{
if(!(dword_entry & 1))
{
// present bit not set
return false;
}
var size = (dword_entry & 128) === 128,
address;
if(size && !is_directory)
{
address = dword_entry & 0xFFC00000;
}
else
{
address = dword_entry & 0xFFFFF000;
}
return {
size: size,
global: (dword_entry & 256) === 256,
accessed: (dword_entry & 0x20) === 0x20,
dirty: (dword_entry & 0x40) === 0x40,
cache : (dword_entry & 16) === 16,
user : (dword_entry & 4) === 4,
read_write : (dword_entry & 2) === 2,
address : address >>> 0
};
}
function dump_page_directory()
{
for(var i = 0; i < 1024; i++)
{
var dword = memory.read32s(cr3 + 4 * i),
entry = load_page_entry(dword, true);
if(!entry)
{
continue;
}
var flags = '';
if(entry.size)
flags += 'S ';
if(entry.cache)
flags += 'D ';
if(entry.user)
flags += 'U ';
if(entry.read_write)
flags += 'R ';
if(entry.accessed)
flags += 'A ';
dbg_log("=== " + h(entry.address >>> 0, 8) + " | " + flags);
if(entry.size)
{
continue;
}
for(var j = 0; j < 1024; j++)
{
dword = memory.read32s(entry.address + 4 * j);
var subentry = load_page_entry(dword, false);
if(subentry)
{
flags = '';
if(subentry.size)
flags += 'S ';
if(subentry.cache)
flags += 'D ';
if(subentry.user)
flags += 'U ';
if(subentry.read_write)
flags += 'R ';
if(subentry.global)
flags += 'G ';
if(subentry.accessed)
flags += 'A ';
if(subentry.dirty)
flags += 'Di ';
dbg_log("# " + h((i << 22 | j << 12) >>> 0, 8) + " -> " +
h(subentry.address, 8) + " | " + flags);
}
}
}
}

545
src/disk.js Normal file
View file

@ -0,0 +1,545 @@
"use strict";
var
/** @const */
CDROM_SECTOR_SIZE = 2048,
/** @const */
HD_SECTOR_SIZE = 512;
/** @constructor */
function CDRom(dev, cd_buffer)
{
this.io = dev.io;
this.memory = dev.memory;
this.pic = dev.pic;
this.pci = dev.pci;
this.vendor_id = 0x1002;
this.class_revision = 0x106 << 16 | 0x01 << 8;
this.irq = 14;
this.iobase = 0xFFF10000;
this.sector_size = CDROM_SECTOR_SIZE;
this.buffer = cd_buffer;
this.atapi = true;
this.pci_id = 8;
this.init();
}
CDRom.prototype = new AHCIDevice();
/** @constructor */
function HDD(dev, disk_buffer, nr)
{
var port = nr === 0 ? 0x1F0 : 0x170,
irq = nr === 0 ? 14 : 15;
var pic = dev.pic;
this.io = dev.io;
this.memory = dev.memory;
this.pic = dev.pic;
this.pci = dev.pci;
this.vendor_id = 0x1002;
this.class_revision = 0x106 << 16 | 0x01 << 8;
this.irq = irq;
this.iobase = 0xFFF00000;
this.sector_size = HD_SECTOR_SIZE;
this.sector_count = disk_buffer.byteLength / this.sector_size;
this.buffer = disk_buffer;
this.atapi = false;
this.pci_id = 0x10;
this.head_count = 16;
this.sectors_per_track = 63;
this.cylinder_count = disk_buffer.byteLength /
this.head_count / (this.sectors_per_track + 1) / this.sector_size;
dbg_assert(this.cylinder_count === (this.cylinder_count | 0));
dbg_assert(this.cylinder_count <= 16383);
var me = this;
// status
this.io.register_read(port | 7, read_status);
// alternate status, starting at 3f6/376
this.io.register_read(port | 0x206, read_status);
function read_status()
{
dbg_log("ATA read status", LOG_DISK);
var status = 0x50;
if(data_pointer < pio_data.length)
status |= 8;
return status;
}
var last_drive = 0xFF,
data_pointer = 0,
pio_data = [],
drq = false,
is_lba = 0,
slave = 0,
bytecount = 0,
sector = 0,
cylinder = 0,
head = 0;
function push_irq()
{
pic.push_irq(me.irq);
}
this.io.register_write(port | 6, function(data)
{
dbg_log("1F6 write " + h(data), LOG_DISK);
var slave = data & 0x10,
mode = data & 0xE0,
low = data & 0xF;
if(slave)
{
//drq = false;
return;
}
is_lba = data >> 6 & 1;
head = data & 0xF;
last_drive = data;
});
this.io.register_write(port | 2, function(data)
{
dbg_log("1F2 write: " + data, LOG_DISK);
if(data)
{
bytecount = data << 9;
}
else
{
bytecount = 256 << 9;
}
//bytecount = 1 << 9;
});
this.io.register_write(port | 3, function(data)
{
sector = data;
});
this.io.register_write(port | 4, function(data)
{
cylinder = cylinder & 0xFF00 | data;
});
this.io.register_write(port | 5, function(data)
{
cylinder = cylinder & 0xFF | data << 8;
});
this.io.register_write(port | 7, function(cmd)
{
if(cmd === 0xEC)
{
dbg_log("ATA identify device", LOG_DISK);
// identify device
// http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/harddrv.cc#L2821
data_pointer = 0;
pio_data = new Uint8Array([
0x40, 0,
// 1 cylinders
me.cylinder_count, me.cylinder_count >> 8,
0, 0,
// 3 heads
me.head_count, me.head_count >> 8,
0, 0,
// 5
0, 0,
// sectors per track
me.sectors_per_track, 0,
0, 0, 0, 0, 0, 0,
// 10-19 serial number
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 15
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 20
3, 0, 0, 2, 4, 0,
// 23-26 firmware revision
0, 0, 0, 0, 0, 0, 0, 0,
// 27 model number
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
// 47
0, 0,
1, 0,
0, 3, // capabilities
// 50
0, 0,
0, 2,
0, 2,
7, 0,
// 54 cylinders
me.cylinder_count, me.cylinder_count >> 8,
// 55 heads
me.head_count, me.head_count >> 8,
// 56 sectors per track
me.sectors_per_track, 0,
// capacity in sectors
this.sector_count & 0xFF, this.sector_count >> 8 & 0xFF,
this.sector_count >> 16 & 0xFF, this.sector_count >> 24 & 0xFF,
0, 0,
// 60
this.sector_count & 0xFF, this.sector_count >> 8 & 0xFF,
this.sector_count >> 16 & 0xFF, this.sector_count >> 24 & 0xFF,
0, 0, 0, 0, 0, 0,
// 65
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 70
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 75
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 80
0x7E, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 85
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 90
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 95
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 100
this.sector_count & 0xFF, this.sector_count >> 8 & 0xFF,
this.sector_count >> 16 & 0xFF, this.sector_count >> 24 & 0xFF,
]);
push_irq();
}
else if(cmd === 0x91)
{
dbg_log("ATA cmd 91", LOG_DISK);
push_irq();
}
else if(cmd === 0x10)
{
// obsolete
dbg_log("ATA cmd 10", LOG_DISK);
push_irq();
}
else if(cmd = 0x27)
{
// READ NATIVE MAX ADDRESS EXT - read the actual size of the HD
// https://en.wikipedia.org/wiki/Host_protected_area
dbg_log("ATA cmd 27", LOG_DISK);
push_irq();
pio_data = [
0, 0, // error
0, 0, // count
// result
disk_buffer.byteLength & 0xff,
disk_buffer.byteLength >> 8 & 0xff,
disk_buffer.byteLength >> 16 & 0xff,
disk_buffer.byteLength >> 24 & 0xff,
0, 0,
0, 0, //
];
}
else if(cmd === 0x20)
{
if(DEBUG && is_lba)
throw "unimplemented";
var lba = (cylinder * me.head_count + head) * me.sectors_per_track + sector - 1;
dbg_log("ATA read: from=" + h(lba * me.sector_size) + " chs=" + cylinder + "/" + head + "/" + sector + " length=" + h(bytecount), LOG_DISK);
me.buffer.get(lba * me.sector_size, bytecount, function(data)
{
data_pointer = 0;
pio_data = data;
push_irq();
});
}
else
{
dbg_log("New ATA cmd on 1F7: " + h(cmd), LOG_DISK);
}
});
this.io.register_read(port | 0, function()
{
if(data_pointer < pio_data.length)
{
dbg_log("Read 1F0: " + h(pio_data[data_pointer], 2), LOG_DISK);
if((data_pointer & 511) === 0)
push_irq();
return pio_data[data_pointer++] & 0xFF;
}
else
{
dbg_log("Read 1F0: empty", LOG_DISK);
return 0;
}
});
this.io.register_read(port | 1, function()
{
dbg_log("Read 1F1", LOG_DISK);
return 0xFF;
});
this.io.register_read(port | 2, function()
{
dbg_log("Read 1F2", LOG_DISK);
return 0xFF;
});
this.io.register_read(port | 3, function()
{
dbg_log("Read 1F3", LOG_DISK);
return 0xFF;
});
this.io.register_read(port | 6, function()
{
dbg_log("Read 1F6", LOG_DISK);
return last_drive;
});
this.init();
}
HDD.prototype = new AHCIDevice();
/** @constructor */
function AHCIDevice()
{
var me,
memory;
this.init = function()
{
me = this;
memory = this.memory;
this.pci.register_device(this, this.pci_id);
this.memory.mmap_register(this.iobase, 0x4000, true, mmio_read, mmio_write);
};
var host_ctl = 0,
host_caps = 1,
host_ports_impl = 1,
host_intbits = 1,
port_lst_addr,
port_fis_addr;
function atapi_command_read(atapi, dest, byte_len)
{
var lba = Math.to_be32(memory.read32s(atapi + 2)),
count = Math.to_be16(memory.read16(atapi + 7)),
flags = memory.read8(atapi + 1),
//bytecount = Math.min(count * me.sector_size, byte_len + 1);
bytecount = count * me.sector_size;
dbg_log("CD read lba=" + h(lba) +
" lbacount=" + h(count) +
" bytelen=" + h(byte_len) +
" copycount=" + h(bytecount) +
" flags=" + h(flags) +
" buf=" + h(dest, 8), LOG_CD);
me.buffer.get(lba * me.sector_size, bytecount, function(data)
{
memory.write_blob(data, dest);
});
//pic.push_irq(me.irq);
}
function ata_command_rw(cmd_fis, dest, is_read)
{
var lba = memory.read32s(cmd_fis + 4) & 0xFFFFFF,
count = memory.read16(cmd_fis + 12),
bytecount = count * me.sector_size;
dbg_log("ahci " + (is_read ? "read" : "write") + ": lba=" + h(lba, 8) +
" count=" + h(count, 4) +
" dest=" + h(dest, 8));
if(is_read)
{
this.buffer.get(lba * me.sector_size, bytecount, function(data)
{
memory.write_blob(data, dest);
});
}
else
{
this.buffer.set(lba * me.sector_size,
new Uint8Array(memory.buffer, dest, bytecount),
function()
{
});
}
}
function mmio_read(addr)
{
switch(addr)
{
case 0:
return host_caps;
case 4:
return host_ctl;
case 0xC:
return host_ports_impl;
case 0x128:
return 0x03;
case 0x110:
return host_intbits;
default:
dbg_log("New PCI mmio read from " + h(addr, 8), LOG_CD);
}
}
function mmio_write(addr, value)
{
switch(addr)
{
case 0x100:
port_lst_addr = value;
dbg_log("lst at " + h(value, 8), LOG_CD);
break;
case 0x108:
port_fis_addr = value;
dbg_log("fis at " + h(value, 8), LOG_CD);
break;
case 0x118:
dbg_log("port cmd: " + h(value, 8), LOG_CD);
break;
case 0x138:
var
ctba_addr = memory.read32s(port_lst_addr + 8),
first_prdt_start = ctba_addr + 0x80,
flags = memory.read16(port_lst_addr),
prdt_addr = memory.read32s(first_prdt_start) + 0x100000000 * memory.read32s(first_prdt_start + 4),
prdt_len = memory.read32s(ctba_addr + 0x80 + 0xC) & 0xFFF,
atapi_command = memory.read8(ctba_addr + 0x40),
fis_command = memory.read8(ctba_addr + 2),
dma_fis_start = port_fis_addr + 0,
pio_fis_start = port_fis_addr + 0x20,
d2h_fis_start = port_fis_addr + 0x40,
ufis_start = port_fis_addr + 0x60,
command_fis_start = ctba_addr + 0,
atapi_command_start = ctba_addr + 0x40;
if((fis_command === 0xA0 || fis_command === 0xA1) &&
!me.atapi)
{
return;
}
// status success
memory.write8(d2h_fis_start + 2, 0x40);
dbg_log("ctba at " + h(ctba_addr), LOG_CD);
dbg_log("prdt at " + h(prdt_addr), LOG_CD);
dbg_log("flags: " + h(flags, 2), LOG_CD);
dbg_log("cmd fis command: " + h(fis_command, 2), LOG_CD);
dbg_log("fis LBA=" + h(memory.read32s(command_fis_start + 4) & 0xffffff), LOG_CD);
dbg_log("Prdts count: " + h(memory.read16(port_lst_addr + 2)), LOG_CD);
dbg_log("PRD byte count: " + h(memory.read32s(port_lst_addr + 4)), LOG_CD);
dbg_log("First prdt byte count: " + h(memory.read32s(ctba_addr + 0x80 + 0xC)), LOG_CD);
if(fis_command === 0xC8 || fis_command === 0xCA)
{
ata_command_rw(command_fis_start, prdt_addr, fis_command === 0xC8);
}
else if(fis_command === 0xEC)
{
// ATA_CMD_IDENTIFY_DEVICE
// number of sectors
memory.write32(prdt_addr + 120, me.buffer.byteLength / me.sector_size);
}
else if(fis_command === 0xA1)
{
// ATA_CMD_IDENTIFY_PACKET_DEVICE
// is CD
memory.write32(prdt_addr, 0x0500);
}
else if(fis_command === 0xA0)
{
// ATA_CMD_PACKET
if(atapi_command === 0x28)
{
atapi_command_read(ctba_addr + 0x40, prdt_addr, prdt_len);
}
else if(atapi_command === 0x2a)
{
// write
dbg_log("atapi - unimplemented write", LOG_CD);
}
else if(atapi_command === 0x25)
{
// read capacity
dbg_log("atapi - unimplemented read cap", LOG_CD);
}
else
{
dbg_log("atapi - unimplemented " + h(atapi_command, 2), LOG_CD);
}
}
else
{
dbg_log("unimplemented fis command: " + h(fis_command, 2));
}
break;
default:
dbg_log("PCI mmio write addr=" + h(addr, 8) + " value=" + h(value, 8), LOG_CD);
}
}
}

149
src/dma.js Normal file
View file

@ -0,0 +1,149 @@
"use strict";
/**
* @constructor
*/
function DMA(dev)
{
var io = dev.io,
memory = dev.memory,
channels = [
{ address: 0, count: 0 },
{ address: 0, count: 0 },
{ address: 0, count: 0 },
{ address: 0, count: 0 }
],
lsb_msb_flipflop = 0;
io.register_write(0x04, port_write.bind(0, 0x04));
io.register_write(0x05, port_write.bind(0, 0x05));
io.register_write(0x0A, portA_write);
io.register_write(0x0B, portB_write);
io.register_write(0x0C, portC_write);
io.register_write(0x81, port81_write);
function port_write(port, data_byte)
{
dbg_log("port " + port + " write " + data_byte, LOG_DMA);
if(port < 8)
{
var channel = port >> 1;
if(port & 1)
{
channels[channel].count = flipflop_get(channels[channel].count, data_byte);
}
else
{
channels[channel].address = flipflop_get(channels[channel].address, data_byte);
}
}
};
function port_read(port)
{
if(port < 8)
{
var channel = port >> 1;
if(port & 1)
{
return channels[channel].count;
}
else
{
// Bug?
return channels[channel].address;
}
}
else
{
dbg_log("port " + h(port) + " read", LOG_DMA);
}
};
function portA_write(data_byte)
{
dbg_log("port A write: " + h(data_byte), LOG_DMA);
};
function portB_write(data_byte)
{
dbg_log("port B write: " + h(data_byte), LOG_DMA);
};
function portC_write(data_byte)
{
lsb_msb_flipflop = 0;
}
function port81_write(data_byte)
{
channels[2].address = channels[2].address & 0xFFFF | data_byte << 16;
}
// read data, write to memory
this.do_read = function(buffer, start, len, channel, fn)
{
var read_count = channels[channel].count,
addr = channels[channel].address;
dbg_log("DMA write channel " + channel, LOG_DMA);
dbg_log("to " + h(addr) + " len " + h(read_count), LOG_DMA);
if(len < read_count)
{
dbg_log("DMA should read more than provided: " + h(len) + " " + h(read_count), LOG_DMA);
}
channels[channel].address += len;
buffer.get(start, len, function(data)
{
memory.write_blob(data, addr);
fn();
});
};
// write data, read memory
this.do_write = function(buffer, start, len, channel, fn)
{
var read_count = channels[channel].count,
addr = channels[channel].address;
dbg_log("DMA write channel " + channel, LOG_DMA);
dbg_log("to " + h(addr) + " len " + h(read_count), LOG_DMA);
dbg_log(channels[channel], LOG_DMA);
if(len < read_count)
{
dbg_log("DMA should read more than provided", LOG_DMA);
}
buffer.set(start,
new Uint8Array(memory.buffer, addr, read_count + 1),
function() {
fn();
}
);
}
function flipflop_get(old_dword, new_byte)
{
lsb_msb_flipflop ^= 1;
if(lsb_msb_flipflop)
{
// low byte
return old_dword & ~0xFF | new_byte;
}
else
{
// high byte
return old_dword & ~0xFF00 | new_byte << 8;
}
}
}

1
src/externs.js Normal file
View file

@ -0,0 +1 @@
var console = {};

396
src/floppy.js Normal file
View file

@ -0,0 +1,396 @@
"use strict";
/** @constructor */
function FloppyController(dev, floppy_image)
{
var
io = dev.io,
pic = dev.pic,
dma = dev.dma,
bytes_expecting = 0,
receiving_command = new Uint8Array(10),
receiving_index = 0,
next_command,
response_data = new Uint8Array(10),
response_index = 0,
response_length = 0,
/** @const */
byte_per_sector = 512,
/** @const */
number_of_heads = 2;
this.buffer = floppy_image;
if(!floppy_image)
{
this.type = 0;
return;
}
var number_of_cylinders,
number_of_sectors,
sectors_per_track;
if(floppy_image.byteLength === 1024 * 360)
{
this.type = 1;
number_of_cylinders = 40;
number_of_sectors = 2880;
sectors_per_track = 9;
}
if(floppy_image.byteLength === 1024 * 1200)
{
this.type = 2;
number_of_cylinders = 80;
number_of_sectors = 2400;
sectors_per_track = 15;
}
else if(floppy_image.byteLength === 1024 * 720)
{
this.type = 3;
number_of_cylinders = 80;
number_of_sectors = 2880;
sectors_per_track = 9;
}
else if(floppy_image.byteLength === 1024 * 1440)
{
this.type = 4;
number_of_cylinders = 80;
number_of_sectors = 2880;
sectors_per_track = 18;
}
else if(floppy_image.byteLength === 1024 * 2880)
{
this.type = 5;
number_of_cylinders = 80;
number_of_sectors = 5760;
sectors_per_track = 36;
}
else if(floppy_image.byteLength === 1024 * 1722)
{
// type is wrong, but only this works for seabios
this.type = 5;
number_of_cylinders = 82;
number_of_sectors = 3444;
sectors_per_track = 21;
}
else
{
throw unimpl("Unknown floppy size: " + h(floppy_image.byteLength));
}
var status_reg0 = 0,
status_reg1 = 0,
status_reg2 = 0,
drive = 0;
var last_cylinder = 0,
last_head = 0,
last_sector = 1;
io.register_read(0x3F0, port3F0_read);
io.register_read(0x3F4, port3F4_read);
io.register_read(0x3F5, port3F5_read);
io.register_read(0x3F7, port3F7_read);
io.register_write(0x3F5, port3F5_write);
function port3F0_read()
{
dbg_log("3F0 read", LOG_DISK);
return 0;
};
function port3F4_read()
{
dbg_log("3F4 read", LOG_DISK);
var return_byte = 0x80;
if(response_index < response_length)
{
return_byte |= 0x40 | 0x10;
}
if((dor & 8) === 0)
{
return_byte |= 0x20;
}
return return_byte;
};
function port3F7_read()
{
dbg_log("3F7 read", LOG_DISK);
return 0x00;
}
function port3F5_read()
{
if(response_index < response_length)
{
dbg_log("3F5 read: " + response_data[response_index], LOG_DISK);
return response_data[response_index++];
}
else
{
dbg_log("3F5 read, empty", LOG_DISK);
return 0xFF;
}
};
function port3F5_write(reg_byte)
{
dbg_log("3F5 write " + h(reg_byte), LOG_DISK);
if(bytes_expecting > 0)
{
receiving_command[receiving_index++] = reg_byte;
bytes_expecting--;
if(bytes_expecting === 0)
{
if(DEBUG)
{
var log = "3F5 command received: ";
for(var i = 0; i < receiving_index; i++)
log += h(receiving_command[i]) + " ";
dbg_log(log, LOG_DISK);
}
next_command(receiving_command);
}
}
else
{
switch(reg_byte)
{
// TODO
//case 2:
//next_command = read_complete_track;
//bytes_expecting = 8;
//break;
case 0x03:
next_command = fix_drive_data;
bytes_expecting = 2;
break;
case 0x04:
next_command = check_drive_status;
bytes_expecting = 1;
break;
case 0x05:
case 0xC5:
next_command = function(args) { do_sector(true, args); };
bytes_expecting = 8;
break;
case 0xE6:
next_command = function(args) { do_sector(false, args); };
bytes_expecting = 8;
break;
case 0x07:
next_command = calibrate;
bytes_expecting = 1;
break;
case 0x08:
check_interrupt_status();
break;
case 0x4A:
next_command = read_sector_id;
bytes_expecting = 1;
break;
case 0x0F:
bytes_expecting = 2;
next_command = seek;
break;
case 0x0E:
// dump regs
dbg_log("dump registers", LOG_DISK);
response_data[0] = 0x80;
response_index = 0;
response_length = 1;
bytes_expecting = 0;
break;
default:
if(DEBUG) throw "unimpl floppy command call " + h(reg_byte);
}
receiving_index = 0;
}
};
// this should actually be write-only ... but people read it anyway
var dor = 0;
function port3F2_read()
{
dbg_log("read 3F2: DOR", LOG_DISK);
return dor;
}
io.register_read(0x3F2, port3F2_read);
function port3F2_write(value)
{
if((value & 4) === 4 && (dor & 4) === 0)
{
// reset
pic.push_irq(6);
}
dbg_log("start motors: " + h(value >> 4), LOG_DISK);
dbg_log("enable dma: " + !!(value & 8), LOG_DISK);
dbg_log("reset fdc: " + !!(value & 4), LOG_DISK);
dbg_log("drive select: " + (value & 3), LOG_DISK);
dbg_log("DOR = " + h(value), LOG_DISK);
dor = value;
}
io.register_write(0x3F2, port3F2_write);
function check_drive_status(args)
{
dbg_log("check drive status", LOG_DISK);
response_index = 0;
response_length = 1;
response_data[0] = 1 << 5;
}
function seek(args)
{
dbg_log("seek", LOG_DISK);
last_cylinder = args[1];
last_head = args[0] >> 2 & 1;
if(dor & 8)
{
pic.push_irq(6);
}
}
function calibrate(args)
{
dbg_log("floppy calibrate", LOG_DISK);
if(dor & 8)
{
pic.push_irq(6);
}
}
function check_interrupt_status()
{
// do not trigger an interrupt here
dbg_log("floppy check interrupt status", LOG_DISK);
response_index = 0;
response_length = 2;
response_data[0] = 1 << 5;
response_data[1] = last_cylinder;
}
function do_sector(is_write, args)
{
var head = args[2],
cylinder = args[1],
sector = args[3],
sector_size = 128 * (1 << args[4]),
read_count = args[5] - args[3] + 1,
read_offset = ((head + number_of_heads * cylinder) * sectors_per_track + sector - 1) * sector_size;
dbg_log("Floppy Read", LOG_DISK);
dbg_log("from " + h(read_offset) + " length " + h(read_count * sector_size), LOG_DISK);
dbg_log(cylinder + " / " + head + " / " + sector, LOG_DISK);
if(!args[4])
{
dbg_log("FDC: sector count is zero, use data length instead", LOG_DISK);
}
if(is_write)
{
dma.do_write(floppy_image, read_offset, read_count * sector_size, 2, done);
}
else
{
dma.do_read(floppy_image, read_offset, read_count * sector_size, 2, done);
}
function done()
{
sector++;
if(sector > sectors_per_track)
{
sector = 1;
head++;
if(head > 1)
{
head = 0;
cylinder++;
}
}
last_cylinder = cylinder;
last_head = head;
last_sector = sector;
response_index = 0;
response_length = 7;
response_data[0] = head << 2 | 0x20;
response_data[1] = 0;
response_data[2] = 0;
response_data[3] = cylinder;
response_data[4] = head;
response_data[5] = sector;
response_data[6] = args[4];
if(dor & 8)
{
pic.push_irq(6);
}
}
}
function fix_drive_data(args)
{
dbg_log("floppy fix drive data " + args, LOG_DISK);
}
function read_sector_id(args)
{
dbg_log("floppy read sector id " + args, LOG_DISK);
response_index = 0;
response_length = 7;
response_data[0] = 0;
response_data[1] = 0;
response_data[2] = 0;
response_data[3] = 0;
response_data[4] = 0;
response_data[5] = 0;
response_data[6] = 0;
if(dor & 8)
{
pic.push_irq(6);
}
}
}

1656
src/fpu.macro.js Normal file

File diff suppressed because it is too large Load diff

2263
src/instructions.macro.js Normal file

File diff suppressed because it is too large Load diff

175
src/io.js Normal file
View file

@ -0,0 +1,175 @@
"use strict";
/**
* The ISA IO bus
* Devices register their ports here
*
* @constructor
*/
function IO()
{
var a20_byte = 0,
me = this;
function get_port_description(addr)
{
// via seabios ioport.h
var ports = {
0x0004: "PORT_DMA_ADDR_2",
0x0005: "PORT_DMA_CNT_2",
0x000a: "PORT_DMA1_MASK_REG",
0x000b: "PORT_DMA1_MODE_REG",
0x000c: "PORT_DMA1_CLEAR_FF_REG",
0x000d: "PORT_DMA1_MASTER_CLEAR",
0x0020: "PORT_PIC1_CMD",
0x0021: "PORT_PIC1_DATA",
0x0040: "PORT_PIT_COUNTER0",
0x0041: "PORT_PIT_COUNTER1",
0x0042: "PORT_PIT_COUNTER2",
0x0043: "PORT_PIT_MODE",
0x0060: "PORT_PS2_DATA",
0x0061: "PORT_PS2_CTRLB",
0x0064: "PORT_PS2_STATUS",
0x0070: "PORT_CMOS_INDEX",
0x0071: "PORT_CMOS_DATA",
0x0080: "PORT_DIAG",
0x0081: "PORT_DMA_PAGE_2",
0x0092: "PORT_A20",
0x00a0: "PORT_PIC2_CMD",
0x00a1: "PORT_PIC2_DATA",
0x00b2: "PORT_SMI_CMD",
0x00b3: "PORT_SMI_STATUS",
0x00d4: "PORT_DMA2_MASK_REG",
0x00d6: "PORT_DMA2_MODE_REG",
0x00da: "PORT_DMA2_MASTER_CLEAR",
0x00f0: "PORT_MATH_CLEAR",
0x0170: "PORT_ATA2_CMD_BASE",
0x01f0: "PORT_ATA1_CMD_BASE",
0x0278: "PORT_LPT2",
0x02e8: "PORT_SERIAL4",
0x02f8: "PORT_SERIAL2",
0x0374: "PORT_ATA2_CTRL_BASE",
0x0378: "PORT_LPT1",
0x03e8: "PORT_SERIAL3",
//0x03f4: "PORT_ATA1_CTRL_BASE",
0x03f0: "PORT_FD_BASE",
0x03f2: "PORT_FD_DOR",
0x03f4: "PORT_FD_STATUS",
0x03f5: "PORT_FD_DATA",
0x03f6: "PORT_HD_DATA",
0x03f7: "PORT_FD_DIR",
0x03f8: "PORT_SERIAL1",
0x0cf8: "PORT_PCI_CMD",
0x0cf9: "PORT_PCI_REBOOT",
0x0cfc: "PORT_PCI_DATA",
0x0402: "PORT_BIOS_DEBUG",
0x0510: "PORT_QEMU_CFG_CTL",
0x0511: "PORT_QEMU_CFG_DATA",
0xb000: "PORT_ACPI_PM_BASE",
0xb100: "PORT_SMB_BASE",
0x8900: "PORT_BIOS_APM"
};
if(ports[addr])
{
return " (" + ports[addr] + ")";
}
else
{
return "";
}
}
function empty_port_read_debug(port_addr)
{
dbg_log(
"read port #" + h(port_addr, 3) + get_port_description(port_addr),
LOG_IO
);
return 0xFF;
}
function empty_port_write_debug(port_addr, out_byte)
{
dbg_log(
"write port #" + h(port_addr, 3) + " <- " + h(out_byte, 2) + get_port_description(port_addr),
LOG_IO
);
}
function empty_port_read()
{
return 0xFF;
}
function empty_port_write(x)
{
}
var read_callbacks = [],
write_callbacks = [];
for(var i = 0; i < 0x10000; i++)
{
// avoid sparse arrays
if(DEBUG)
{
read_callbacks[i] = empty_port_read_debug.bind(0, i);
write_callbacks[i] = empty_port_write_debug.bind(0, i);
}
else
{
read_callbacks[i] = empty_port_read;
write_callbacks[i] = empty_port_write;
}
}
/**
* @param {number} port_addr
* @param {function():number} callback
*/
this.register_read = function(port_addr, callback)
{
read_callbacks[port_addr] = callback;
};
/**
* @param {number} port_addr
* @param {function(number)} callback
*/
this.register_write = function(port_addr, callback)
{
write_callbacks[port_addr] = callback;
};
// should maybe be somewhere else?
this.register_read(0x92, function()
{
return a20_byte;
});
this.register_write(0x92, function(out_byte)
{
a20_byte = out_byte;
});
// use by linux for timing
this.register_write(0x80, function(out_byte)
{
});
this.port_write = function(port_addr, out_byte)
{
write_callbacks[port_addr](out_byte);
};
// read byte from port
this.port_read = function(port_addr)
{
return read_callbacks[port_addr]();
};
}

339
src/main.js Normal file
View file

@ -0,0 +1,339 @@
"use strict";
Object.fromList = function(xs)
{
var result = {};
for(var i = 0; i < xs.length; i++)
{
result[xs[i][0]] = xs[i][1];
}
return result;
};
var dbg_names = Object.fromList([
[1, ""],
[LOG_CPU, "CPU"],
[LOG_DISK, "DISK"],
[LOG_FPU, "FPU"],
[LOG_MEM, "MEM"],
[LOG_DMA, "DMA"],
[LOG_IO, "IO"],
[LOG_PS2, "PS2"],
[LOG_PIC, "PIC"],
[LOG_VGA, "VGA"],
[LOG_PIT, "PIT"],
[LOG_MOUSE, "MOUS"],
[LOG_PCI, "PCI"],
[LOG_BIOS, "BIOS"],
[LOG_CD, "CD"],
[LOG_SERIAL, "SERI"],
[LOG_RTC, "RTC"],
]);
/**
* @param {number=} level
*/
function dbg_log(stuff, level)
{
if(!DEBUG) return;
level = level || 1;
if(level & LOG_LEVEL)
{
var level_name = dbg_names[level] || "";
console.log("[" + String.pads(level_name, 4) + "] " + stuff);
}
};
function dbg_trace()
{
if(!DEBUG) return;
dbg_log(Error().stack);
}
/**
* console.assert is fucking slow
* @param {string=} msg
*/
function dbg_assert(cond, msg)
{
if(!DEBUG) return;
if(!cond)
{
//dump_regs();
console.log(Error().stack);
console.trace();
if(msg)
{
throw "Assert failed: " + msg;
}
else
{
throw "Assert failed";
}
}
};
Object.extend = function(target, src)
{
var keys = Object.keys(src);
for(var i = 0; i < keys.length; i++)
{
target[keys[i]] = src[keys[i]];
}
}
// pad string with spaces on the right
String.pads = function(str, len)
{
str = str ? str + "" : "";
while(str.length < len)
{
str = str + " ";
}
return str;
}
// pad string with zeros on the left
String.pad0 = function(str, len)
{
str = str ? str + "" : "";
while(str.length < len)
{
str = "0" + str;
}
return str;
}
Array.range = function(n)
{
var a = [];
for(var i = 0; i < n; i++)
{
a[i] = i;
}
return a;
}
/**
* number to hex
* @param {number=} len
*/
function h(n, len)
{
//dbg_assert(typeof n === "number");
if(!n) return String.pad0("", len || 1);
if(len)
{
return String.pad0(n.toString(16).toUpperCase(), len);
}
else
{
return n.toString(16).toUpperCase();
}
}
Number.bits = function(n)
{
var result = [];
for(var bit = 31; bit > -1; bit--)
{
if(n & 1 << bit)
{
result.push(bit);
}
}
return result.join(', ');
}
String.chr_repeat = function(chr, count)
{
var result = "";
while(count--)
{
result += chr;
}
return result;
}
Math.bcd_pack = function(n)
{
var i = 0,
result = 0,
digit;
while(n)
{
digit = n % 10;
result |= digit << (4 * i);
i++;
n = (n - digit) / 10;
}
return result;
}
/**
* @param {string=} msg
* */
function unimpl(msg)
{
var s = "Unimplemented" + (msg ? ": " + msg : "");
log(s);
if(DEBUG)
{
console.trace();
return s;
}
else
{
log("Execution stopped");
return s;
}
//this.name = "Unimplemented";
}
/**
* Synchronous access to ArrayBuffer
* @constructor
*/
function SyncBuffer(buffer)
{
this.byteLength = buffer.byteLength;
// warning: fn may be called synchronously or asynchronously
this.get = function(start, len, fn)
{
fn(new Uint8Array(buffer, start, len));
};
this.set = function(start, slice, fn)
{
new Uint8Array(buffer, start, slice.byteLength).set(slice);
fn();
};
this.get_buffer = function(fn)
{
fn(buffer);
};
}
/**
* Simple circular queue for logs
*
* @param {number} size
* @param {?=} Proto
* @constructor
*/
function CircularQueue(size, Proto)
{
var data,
index;
this.add = function(item)
{
data[index] = item;
index = (index + 1) % size;
};
this.toArray = function()
{
return [].slice.call(data, index).concat([].slice.call(data, 0, index));
};
this.clear = function()
{
if(Proto)
{
data = new Proto(size);
}
else
{
data = [];
}
index = 0;
};
this.set = function(new_data)
{
data = new_data;
index = 0;
};
this.clear();
}
// switch number to big endian
Math.to_be32 = function(dword)
{
return dword >>> 24 |
dword >> 8 & 0xff00 |
dword << 8 & 0xff0000 |
dword << 24;
}
Math.to_be16 = function(word)
{
return word >>> 8 & 0xff | word << 8 & 0xff00;
}
// used in several places
// the first entry is -1
// http://jsperf.com/integer-log2/2
var log2_table = (function()
{
var t = new Int8Array(256);
for(var i = 0, b = -2; i < 256; i++)
{
if(!(i & i - 1))
b++;
t[i] = b;
}
return t;
})();
// round away from zero, opposite of truncation
Math.roundInfinity = function(x)
{
return x > 0 ? Math.ceil(x) : Math.floor(x);
};

486
src/memory.js Normal file
View file

@ -0,0 +1,486 @@
"use strict";
/**
* @constructor
*/
function Memory(buffer, memory_size)
{
var int8array = new Uint8Array(buffer),
int16array = new Uint16Array(buffer),
int8sarray = new Int8Array(buffer),
int32sarray = new Int32Array(buffer);
this.mem8 = int8array;
this.mem8s = int8sarray;
this.mem32s = int32sarray;
this.buffer = buffer;
// debug function called by all memory reads and writes
function debug_write(addr, size, value)
{
if(!DEBUG)
{
return;
}
//dbg_assert(typeof value === "number" && !isNaN(value));
debug_read(addr, size, true);
}
/** @param {boolean=} is_write */
function debug_read(addr, size, is_write)
{
if(!DEBUG)
{
return;
}
dbg_assert(typeof addr === "number");
dbg_assert(!isNaN(addr));
if((addr >= memory_size || addr < 0) && !memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
dbg_log("Read from unmapped memory space, addr=" + h(addr, 8) /*+ " at " + h(instruction_pointer, 8)*/, LOG_IO);
}
//dbg_assert(memory_map_registered[addr >>> MMAP_BLOCK_SIZE]);
};
this.dump_all = function(start, end)
{
start = start || 0;
end = end || 0x100000;
// textarea method: (slow)
//var result_string = "";
//for(var i = start; i < start + end; i++)
//{
// result_string += String.fromCharCode(int8array[i]);
//}
//dump_text(btoa(result_string));
// save as method:
dump_file(buffer.slice(start, end), "memory.bin");
};
this.dump = function(addr, length)
{
length = length || 4 * 0x10;
var line, byt;
for(var i = 0; i < length >> 4; i++)
{
line = h(addr + (i << 4), 5) + " ";
for(var j = 0; j < 0x10; j++)
{
byt = this.read8(addr + (i << 4) + j);
line += h(byt, 2) + " ";
}
line += " ";
for(j = 0; j < 0x10; j++)
{
byt = this.read8(addr + (i << 4) + j);
line += (byt < 33 || byt > 126) ? "." : String.fromCharCode(byt);
}
dbg_log(line);
}
};
this.print_memory_map = function()
{
var width = 0x80,
height = 0x10,
block_size = memory_size / width / height | 0,
row;
for(var i = 0; i < height; i++)
{
row = "0x" + h(i * width * block_size, 8) + " | ";
for(var j = 0; j < width; j++)
{
var used = this.mem32s[(i * width + j) * block_size] > 0;
row += used ? "X" : " ";
}
dbg_log(row);
}
};
var
/**
* Arbritary value, the minimum number of bytes that can be mapped
* by one device. This might be spec'd somewhere ...
*
* Written as a power of 2.
*
* @const
*/
MMAP_BLOCK_SIZE = 14,
/** @const */
MMAP_BYTEWISE = 1,
MMAP_DWORDWISE = 4,
// this only supports a 32 bit address space
memory_map_registered = new Int8Array(1 << 32 - MMAP_BLOCK_SIZE),
memory_map_read = [],
memory_map_write = [];
for(var i = 0; i < (1 << 32 - MMAP_BLOCK_SIZE); i++)
{
// avoid sparse arrays
memory_map_read[i] = memory_map_write[i] = undefined;
}
/**
* @param addr {number}
* @param size {number}
* @param is_dword {boolean} true if the memory is addressed in dwords, otherwise byte
*
*/
this.mmap_register = function(addr, size, is_dword, read_func, write_func)
{
dbg_log("mmap_register32 " + h(addr, 8) + ": " + h(size, 8), LOG_IO);
dbg_assert((addr & (1 << MMAP_BLOCK_SIZE) - 1) === 0);
dbg_assert(size >= (1 << MMAP_BLOCK_SIZE) && (size & (1 << MMAP_BLOCK_SIZE) - 1) === 0);
var aligned_addr = addr >>> MMAP_BLOCK_SIZE,
unit_size = is_dword ? MMAP_DWORDWISE : MMAP_BYTEWISE;
for(; size > 0; aligned_addr++)
{
memory_map_registered[aligned_addr] = unit_size;
memory_map_read[aligned_addr] = function(read_addr)
{
return read_func(read_addr - addr | 0);
};
memory_map_write[aligned_addr] = function(write_addr, value)
{
write_func(write_addr - addr | 0, value);
}
size -= 1 << MMAP_BLOCK_SIZE;
}
};
function mmap_read8(addr)
{
var aligned_addr = addr >>> MMAP_BLOCK_SIZE,
registered = memory_map_read[aligned_addr];
//dbg_log("mmap_read8 " + h(addr, 8), LOG_IO);
if(memory_map_registered[aligned_addr] === MMAP_BYTEWISE)
{
return registered(addr);
}
else
{
return mmap_read32(addr & ~3) >> 8 * (addr & 3) & 0xFF;
}
};
function mmap_write8(addr, value)
{
var aligned_addr = addr >>> MMAP_BLOCK_SIZE,
registered = memory_map_write[addr >>> MMAP_BLOCK_SIZE];
//dbg_log("mmap_write8 " + h(addr, 8) + ": " + h(value, 2), LOG_IO);
if(memory_map_registered[aligned_addr] === MMAP_BYTEWISE)
{
registered(addr, value);
}
else
{
// impossible without reading. Maybe this should do nothing
dbg_assert(false);
}
};
function mmap_read32(addr)
{
var registered = memory_map_read[addr >>> MMAP_BLOCK_SIZE];
//dbg_log("mmap_read32 " + h(addr, 8), LOG_IO);
//dbg_assert((addr & 3) === 0);
dbg_assert(registered);
if((addr & 3) === 0 &&
memory_map_registered[addr >>> MMAP_BLOCK_SIZE] === MMAP_DWORDWISE)
{
return registered(addr);
}
else
{
return mmap_read8(addr) | mmap_read8(addr + 1) << 8 |
mmap_read8(addr + 2) << 16 | mmap_read8(addr + 3) << 24;
}
};
function mmap_write32(addr, value)
{
var registered = memory_map_write[addr >>> MMAP_BLOCK_SIZE];
//dbg_log("mmap_write32 " + h(addr, 8) + ": " + h(value, 8), LOG_IO);
//dbg_assert((addr & 3) === 0);
dbg_assert(registered);
if((addr & 3) === 0 &&
memory_map_registered[addr >>> MMAP_BLOCK_SIZE] === MMAP_DWORDWISE)
{
registered(addr, value);
}
else
{
mmap_write8(addr, value & 0xFF);
mmap_write8(addr + 1, value >> 8 & 0xFF);
mmap_write8(addr + 2, value >> 16 & 0xFF);
mmap_write8(addr + 3, value >> 24 & 0xFF);
}
};
/**
* @param addr {number}
*/
this.read8s = function(addr)
{
debug_read(addr, 1);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
return mmap_read8(addr) << 24 >> 24;
}
else
{
return int8sarray[addr];
}
};
/**
* @param addr {number}
*/
this.read8 = function(addr)
{
debug_read(addr, 1);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
return mmap_read8(addr);
}
else
{
return int8array[addr];
}
};
/**
* @param addr {number}
*/
this.read16 = function(addr)
{
debug_read(addr, 2);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
return mmap_read8(addr) | mmap_read8(addr + 1) << 8;
}
else
{
return int8array[addr] | int8array[addr + 1] << 8;
}
};
/**
* @param addr {number}
*/
this.read_aligned16 = function(addr)
{
debug_read(addr, 2);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
return mmap_read8(addr) | mmap_read8(addr + 1) << 8;
}
else
{
return int16array[addr >> 1];
}
};
/**
* @param addr {number}
*/
this.read32s = function(addr)
{
debug_read(addr, 4);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
return mmap_read32(addr) | 0;
}
else
{
return int8array[addr] | int8array[addr + 1] << 8 |
int8array[addr + 2] << 16 | int8array[addr + 3] << 24;
}
};
/**
* @param addr {number}
*/
this.read_aligned32 = function(addr)
{
debug_read(addr, 4);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
return mmap_read32(addr) | 0;
}
else
{
return int32sarray[addr >> 2];
}
};
/**
* @param addr {number}
* @param value {number}
*/
this.write8 = function(addr, value)
{
debug_write(addr, 1, value);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
mmap_write8(addr, value);
}
else
{
int8array[addr] = value;
}
};
/**
* @param addr {number}
* @param value {number}
*/
this.write16 = function(addr, value)
{
debug_write(addr, 2, value);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
mmap_write8(addr, value & 0xff);
mmap_write8(addr + 1, value >> 8 & 0xff);
}
else
{
int8array[addr] = value;
int8array[addr + 1] = value >> 8;
}
};
/**
* @param addr {number}
* @param value {number}
*/
this.write_aligned16 = function(addr, value)
{
debug_write(addr, 2, value);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
mmap_write8(addr, value & 0xff);
mmap_write8(addr + 1, value >> 8 & 0xff);
}
else
{
int16array[addr >> 1] = value;
}
};
/**
* @param addr {number}
* @param value {number}
*/
this.write32 = function(addr, value)
{
debug_write(addr, 4, value);
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
mmap_write32(addr, value);
}
else
{
int8array[addr] = value;
int8array[addr + 1] = value >> 8;
int8array[addr + 2] = value >> 16;
int8array[addr + 3] = value >> 24;
}
};
this.write_aligned32 = function(addr, value)
{
if(memory_map_registered[addr >>> MMAP_BLOCK_SIZE])
{
mmap_write32(addr, value);
}
else
{
int32sarray[addr >> 2] = value;
}
};
/**
* @param offset {number}
* @param blob {Array.<number>}
*/
this.write_blob = function(blob, offset)
{
dbg_assert(blob && blob.length);
int8array.set(blob, offset);
};
/**
* zero byte terminated string
*/
this.read_string = function(addr)
{
var str = "",
data_byte;
while(data_byte = this.read8(addr))
{
str += String.fromCharCode(data_byte);
addr++;
}
return str;
};
this.write_string = function(str, addr)
{
for(var i = 0; i < str.length; i++)
{
this.write8(addr + i, str.charCodeAt(i));
}
};
}

458
src/misc_instr.macro.js Normal file
View file

@ -0,0 +1,458 @@
/*
* Some miscellaneous instructions:
*
* jmpcc16, jmpcc32, jmp16
* loop, loope, loopne, jcxz
* test_cc
*
* mov, push, pop
* pusha, popa
* xchg, lss
* lea
* enter
* bswap
*
* Gets #included by cpu.macro.js
*/
"use strict";
function jmp_rel16(rel16)
{
var current_cs = get_seg(reg_cs);
// limit ip to 16 bit
// ugly
instruction_pointer -= current_cs;
instruction_pointer = (instruction_pointer + rel16) & 0xFFFF;
instruction_pointer = instruction_pointer + current_cs | 0;
}
function jmpcc16(condition)
{
if(condition)
{
jmp_rel16(read_imm16());
}
else
{
instruction_pointer += 2;
}
}
function jmpcc32(condition)
{
if(condition)
{
// don't write `instruction_pointer += read_imm32s()`
var imm32s = read_imm32s();
instruction_pointer = instruction_pointer + imm32s | 0;
}
else
{
instruction_pointer = instruction_pointer + 4 | 0;
}
}
function loopne()
{
if(--regv[reg_vcx] && !getzf())
{
var imm8s = read_imm8s();
instruction_pointer = instruction_pointer + imm8s | 0;
}
else
{
instruction_pointer++;
}
}
function loope()
{
if(--regv[reg_vcx] && getzf())
{
var imm8s = read_imm8s();
instruction_pointer = instruction_pointer + imm8s | 0;
}
else
{
instruction_pointer++;
}
}
function loop()
{
if(--regv[reg_vcx])
{
var imm8s = read_imm8s();
instruction_pointer = instruction_pointer + imm8s | 0;
}
else
{
instruction_pointer++;
}
}
function jcxz()
{
var imm8s = read_imm8s();
if(regv[reg_vcx] === 0)
{
instruction_pointer = instruction_pointer + imm8s | 0;
}
}
var test_o = getof,
test_b = getcf,
test_z = getzf,
test_s = getsf,
test_p = getpf;
function test_be()
{
return getcf() || getzf();
}
function test_l()
{
return !getsf() !== !getof();
}
function test_le()
{
return getzf() || !getsf() !== !getof();
}
/**
* @return {number}
* @const
*/
function getcf()
{
if(flags_changed & 1)
{
if(last_op_size === OPSIZE_32)
{
// cannot bit test above 2^32-1
return last_result > 0xffffffff | last_result < 0;
//return ((last_op1 ^ last_result) & (last_op2 ^ last_result)) >>> 31;
}
else
{
return last_result >> last_op_size & 1;
}
//return last_result >= (1 << last_op_size) | last_result < 0;
}
else
{
return flags & 1;
}
}
/** @return {number} */
function getpf()
{
if(flags_changed & flag_parity)
{
// inverted lookup table
return 0x9669 << 2 >> ((last_result ^ last_result >> 4) & 0xF) & flag_parity;
}
else
{
return flags & flag_parity;
}
}
/** @return {number} */
function getaf()
{
if(flags_changed & flag_adjust)
{
return (last_op1 ^ last_op2 ^ last_result ^ (last_op2 < 0) << 4) & flag_adjust;
}
else
{
return flags & flag_adjust;
}
}
/** @return {number} */
function getzf()
{
if(flags_changed & flag_zero)
{
return (~last_result & last_result - 1) >> last_op_size - 7 & flag_zero;
}
else
{
return flags & flag_zero;
}
}
/** @return {number} */
function getsf()
{
if(flags_changed & flag_sign)
{
return last_result >> last_op_size - 8 & flag_sign;
}
else
{
return flags & flag_sign;
}
}
/** @return {number} */
function getof()
{
if(flags_changed & flag_overflow)
{
return (((last_op1 ^ last_result) & (last_op2 ^ last_result)) >> last_op_size - 1) << 11 & flag_overflow;
}
else
{
return flags & flag_overflow;
}
}
function push16(imm16)
{
var sp = get_esp_write(-2);
stack_reg[reg_vsp] -= 2;
memory.write16(sp, imm16);
}
function push32(imm32)
{
var sp = get_esp_write(-4);
stack_reg[reg_vsp] -= 4;
memory.write32(sp, imm32);
}
function pop16()
{
var sp = get_esp_read(0);
stack_reg[reg_vsp] += 2;
return memory.read16(sp);
}
function pop32s()
{
var sp = get_esp_read(0);
stack_reg[reg_vsp] += 4;
return memory.read32s(sp);
}
function pusha16()
{
var temp = reg16[reg_sp];
// make sure we don't get a pagefault after having
// pushed several registers already
translate_address_write(temp - 15);
push16(reg16[reg_ax]);
push16(reg16[reg_cx]);
push16(reg16[reg_dx]);
push16(reg16[reg_bx]);
push16(temp);
push16(reg16[reg_bp]);
push16(reg16[reg_si]);
push16(reg16[reg_di]);
}
function pusha32()
{
var temp = reg32s[reg_esp];
translate_address_write(temp - 31);
push32(reg32s[reg_eax]);
push32(reg32s[reg_ecx]);
push32(reg32s[reg_edx]);
push32(reg32s[reg_ebx]);
push32(temp);
push32(reg32s[reg_ebp]);
push32(reg32s[reg_esi]);
push32(reg32s[reg_edi]);
}
function popa16()
{
translate_address_read(stack_reg[reg_vsp] + 15);
reg16[reg_di] = pop16();
reg16[reg_si] = pop16();
reg16[reg_bp] = pop16();
stack_reg[reg_vsp] += 2;
reg16[reg_bx] = pop16();
reg16[reg_dx] = pop16();
reg16[reg_cx] = pop16();
reg16[reg_ax] = pop16();
}
function popa32()
{
translate_address_read(stack_reg[reg_vsp] + 31);
reg32[reg_edi] = pop32s();
reg32[reg_esi] = pop32s();
reg32[reg_ebp] = pop32s();
stack_reg[reg_vsp] += 4;
reg32[reg_ebx] = pop32s();
reg32[reg_edx] = pop32s();
reg32[reg_ecx] = pop32s();
reg32[reg_eax] = pop32s();
}
function xchg8(memory_data, modrm_byte)
{
var mod = modrm_byte >> 1 & 0xC | modrm_byte >> 5 & 1,
tmp = reg8[mod];
reg8[mod] = memory_data;
return tmp;
}
function xchg16(memory_data, modrm_byte)
{
var mod = modrm_byte >> 2 & 14,
tmp = reg16[mod];
reg16[mod] = memory_data;
return tmp;
}
function xchg16r(operand)
{
var temp = reg16[reg_ax];
reg16[reg_ax] = reg16[operand];
reg16[operand] = temp;
}
function xchg32(memory_data, modrm_byte)
{
var mod = modrm_byte >> 3 & 7,
tmp = reg32s[mod];
reg32[mod] = memory_data;
return tmp;
}
function xchg32r(operand)
{
var temp = reg32s[reg_eax];
reg32[reg_eax] = reg32s[operand];
reg32[operand] = temp;
}
function lss16(seg, addr, mod)
{
var new_reg = safe_read16(addr),
new_seg = safe_read16(addr + 2);
switch_seg(seg, new_seg);
reg16[mod] = new_reg;
}
function lss32(seg, addr, mod)
{
var new_reg = safe_read32s(addr),
new_seg = safe_read16(addr + 4);
switch_seg(seg, new_seg);
reg32[mod] = new_reg;
}
function lea16()
{
var modrm_byte = read_imm8(),
mod = modrm_byte >> 3 & 7;
// override prefix, so modrm16 does not return the segment part
segment_prefix = reg_noseg;
reg16[mod << 1] = modrm_resolve(modrm_byte);
segment_prefix = -1;
}
function lea32()
{
var modrm_byte = read_imm8(),
mod = modrm_byte >> 3 & 7;
segment_prefix = reg_noseg;
reg32[mod] = modrm_resolve(modrm_byte);
segment_prefix = -1;
}
function enter16()
{
var size = read_imm16(),
nesting_level = read_imm8(),
frame_temp;
push16(reg16[reg_bp]);
frame_temp = reg16[reg_sp];
if(nesting_level > 0)
{
for(var i = 1; i < nesting_level; i++)
{
reg16[reg_bp] -= 2;
push16(reg16[reg_bp]);
}
push16(frame_temp);
}
reg16[reg_bp] = frame_temp;
reg16[reg_sp] = frame_temp - size;
dbg_assert(!page_fault);
}
function enter32()
{
var size = read_imm16(),
nesting_level = read_imm8() & 31,
frame_temp;
push32(reg32s[reg_ebp]);
frame_temp = reg32s[reg_esp];
if(nesting_level > 0)
{
for(var i = 1; i < nesting_level; i++)
{
reg32[reg_ebp] -= 4;
push32(reg32s[reg_ebp]);
}
push32(frame_temp);
}
reg32[reg_ebp] = frame_temp;
reg32[reg_esp] -= size;
dbg_assert(!page_fault);
}
function bswap(reg)
{
var temp = reg32s[reg];
reg32[reg] = temp >>> 24 | temp << 24 | (temp >> 8 & 0xFF00) | (temp << 8 & 0xFF0000);
}

176
src/modrm.macro.js Normal file
View file

@ -0,0 +1,176 @@
/*
* This file contains functions to decode the modrm and sib bytes
*
* These functions return a virtual address
*
* Gets #included by cpu.macro.js
*/
"use strict";
var modrm_resolve16,
modrm_resolve32;
(function() {
var modrm_table16 = Array(0xC0),
modrm_table32 = Array(0xC0),
sib_table = Array(0x100);
#define ds get_seg_prefix(reg_ds)
#define ss get_seg_prefix(reg_ss)
#define eax reg32s[reg_eax]
#define ecx reg32s[reg_ecx]
#define edx reg32s[reg_edx]
#define ebx reg32s[reg_ebx]
#define esp reg32s[reg_esp]
#define ebp reg32s[reg_ebp]
#define esi reg32s[reg_esi]
#define edi reg32s[reg_edi]
#define imm32 read_imm32s()
#define imm16 read_imm16()
#define imm8 read_imm8()
#define entry16(row, seg, value)\
entry16_(0x00 | row, seg + ((value) & 0xFFFF))\
entry16_(0x40 | row, seg + ((value) + read_imm8s() & 0xFFFF))\
entry16_(0x80 | row, seg + ((value) + read_imm16() & 0xFFFF))\
#define entry16_(n, offset)\
modrm_table16[n] = function() { return offset | 0; };
entry16(0, ds, reg16[reg_bx] + reg16[reg_si])
entry16(1, ds, reg16[reg_bx] + reg16[reg_di])
entry16(2, ss, reg16[reg_bp] + reg16[reg_si])
entry16(3, ss, reg16[reg_bp] + reg16[reg_di])
entry16(4, ds, reg16[reg_si])
entry16(5, ds, reg16[reg_di])
entry16(6, ss, reg16[reg_bp])
entry16(7, ds, reg16[reg_bx])
#define entry32(row, value)\
entry32_(0x00 | row, (value))\
entry32_(0x40 | row, (value) + read_imm8s())\
entry32_(0x80 | row, (value) + read_imm32s())\
#define entry32_(n, offset)\
modrm_table32[n] = function() { return offset | 0; };
entry32(0, ds + eax);
entry32(1, ds + ecx);
entry32(2, ds + edx);
entry32(3, ds + ebx);
entry32(4, getsib(false));
entry32(5, ss + ebp);
entry32(6, ds + esi);
entry32(7, ds + edi);
// special cases
modrm_table16[0x00 | 6] = function() { return ds + read_imm16() | 0; }
modrm_table32[0x00 | 5] = function() { return ds + read_imm32s() | 0; };
modrm_table32[0x00 | 4] = function() { return getsib(false) | 0; };
modrm_table32[0x40 | 4] = function() { return getsib(true) + read_imm8s() | 0; };
modrm_table32[0x80 | 4] = function() { return getsib(true) + read_imm32s() | 0; };
for(var low = 0; low < 8; low++)
{
for(var high = 0; high < 3; high++)
{
for(var i = 1; i < 8; i++)
{
var x = low | high << 6;
modrm_table32[x | i << 3] = modrm_table32[x];
modrm_table16[x | i << 3] = modrm_table16[x];
}
}
}
#define entry_sib(n, reg1)\
entry_sib2(0x00 | n << 3, reg1)\
entry_sib2(0x40 | n << 3, reg1 << 1)\
entry_sib2(0x80 | n << 3, reg1 << 2)\
entry_sib2(0xC0 | n << 3, reg1 << 3)
#define entry_sib2(n, offset)\
entry_sib3(n | 0, (offset) + ds + eax)\
entry_sib3(n | 1, (offset) + ds + ecx)\
entry_sib3(n | 2, (offset) + ds + edx)\
entry_sib3(n | 3, (offset) + ds + ebx)\
entry_sib3(n | 4, (offset) + ss + esp)\
entry_sib3(n | 5, (offset) + (mod ? ss + ebp : ds + imm32))\
entry_sib3(n | 6, (offset) + ds + esi)\
entry_sib3(n | 7, (offset) + ds + edi)
#define entry_sib3(n, offset)\
sib_table[n] = function(mod) { return offset | 0; };
entry_sib(0, eax);
entry_sib(1, ecx);
entry_sib(2, edx);
entry_sib(3, ebx);
entry_sib(4, 0);
entry_sib(5, ebp);
entry_sib(6, esi);
entry_sib(7, edi);
/**
* @param {number} modrm_byte
* @return {number}
*/
modrm_resolve16 = function(modrm_byte)
{
return modrm_table16[modrm_byte]();
}
/**
* @param {number} modrm_byte
* @return {number}
*/
modrm_resolve32 = function(modrm_byte)
{
return modrm_table32[modrm_byte]();
}
/**
* @param {boolean} mod
* @return {number}
*/
function getsib(mod)
{
return sib_table[read_imm8()](mod);
}
#undef ds
#undef ss
#undef eax
#undef ecx
#undef edx
#undef ebx
#undef esp
#undef ebp
#undef esi
#undef edi
#undef imm32
#undef imm16
#undef imm8
#undef entry16
#undef entry16_
#undef entry32_
#undef entry_sib
#undef entry_sib2
#undef entry_sib3
})();

BIN
src/node/ascii.ttf Normal file

Binary file not shown.

35
src/node/keyboard_sdl.js Normal file
View file

@ -0,0 +1,35 @@
"use strict";
function NodeKeyboardSDL(sdl)
{
var send_code;
sdl.events.on("KEYDOWN", onkeydown);
sdl.events.on("KEYUP", onkeyup);
this.enabled = true;
this.destroy = function()
{
};
this.init = function(send_code_fn)
{
send_code = send_code_fn;
};
function onkeydown(e)
{
//console.log("d", e);
send_code(e.scancode - 8);
}
function onkeyup(e)
{
//console.log("u", e);
send_code(e.scancode - 8 | 0x80);
}
}

60
src/node/keyboard_tty.js Normal file
View file

@ -0,0 +1,60 @@
"use strict";
function NodeKeyboardTTY()
{
var stdin = process.stdin;
var send_code;
var charmap = [
// TODO: Fill this in or get it from somewhere
];
//stdin.setRawMode(true);
stdin.resume();
stdin.setEncoding('utf8');
this.enabled = true;
this.destroy = function()
{
};
this.init = function(send_code_fn)
{
send_code = send_code_fn;
};
stdin.on("data", function(c)
{
if(c === '\u0003')
{
process.exit();
}
var str = "";
for(var i = 0; i < c.length; i++)
{
str += c.charCodeAt(i);
}
//dbg_log(str);
dbg_log("2 " + JSON.stringify(arguments));
});
stdin.on("keypress", function(c)
{
if(c === '\u0003')
{
process.exit();
}
dbg_log("keypress: " + JSON.stringify(arguments));
var code = charmap[c.charCodeAt(0)];
send_code(code);
//send_code(code | 0x80);
});
}

141
src/node/main.js Normal file
View file

@ -0,0 +1,141 @@
"use strict";
var path = __dirname + "/../",
bios_path = path + "../bios/",
image_path = path + "../images/";
// otherwise tty ouput is used
var USE_SDL = true,
FONT_FILE = path + "node/ascii.ttf";
(function()
{
var tick_fn;
global.set_tick = function(fn)
{
tick_fn = fn;
};
global.next_tick = function()
{
setImmediate(tick_fn);
};
})();
global.log = function(str)
{
console.log(str);
};
var fs = require('fs'),
vm = require('vm'),
include = function(path)
{
// ugh ...
var code = fs.readFileSync(path);
vm.runInThisContext(code, path);
}.bind(this);
include(path + "const.js");
include(path + "cpu.js");
include(path + "main.js");
include(path + "floppy.js");
include(path + "memory.js");
include(path + "io.js");
include(path + "pci.js");
include(path + "disk.js");
include(path + "dma.js");
include(path + "pit.js");
include(path + "vga.js");
include(path + "ps2.js");
include(path + "pic.js");
include(path + "uart.js");
include(path + "rtc.js");
DEBUG = true;
function read_array_buffer(file)
{
var buffer = fs.readFileSync(file),
ab = new ArrayBuffer(buffer.length),
arr = new Uint8Array(ab);
for (var i = 0; i < buffer.length; i++)
{
arr[i] = buffer[i];
}
return ab;
}
var settings = {
load_devices: true,
},
argv = process.argv;
if(USE_SDL)
{
var sdl = require("node-sdl");
include(path + "node/keyboard_sdl.js");
include(path + "node/screen_sdl.js");
settings.screen_adapter = new NodeScreenSDL(sdl, FONT_FILE);
settings.keyboard_adapter = new NodeKeyboardSDL(sdl);
}
else
{
require('tty').setRawMode(true);
include(path + "node/keyboard_tty.js");
include(path + "node/screen_tty.js");
settings.screen_adapter = new NodeScreenTTY();
settings.keyboard_adapter = new NodeKeyboardTTY();
}
// just a prototype of a loader
if(argv && argv.length === 4 && (argv[2] === "cdrom" || argv[2] === "fda"))
{
var disk = new SyncBuffer(read_array_buffer(argv[3]));
if(argv[2] === "cdrom")
{
settings.cdrom_disk = disk;
}
else if(argv[2] === "fda")
{
settings.floppy_disk = disk;
}
settings.bios = read_array_buffer(bios_path + "seabios.bin");
settings.vga_bios = read_array_buffer(bios_path + "vgabios.bin");
settings.screen_adapter
var cpu = new v86();
cpu.init(settings);
cpu.run();
}
else
{
console.log("Usage: node main.js [cdrom|fda] disk.img");
process.exit();
}

5
src/node/node_modules/node-sdl/.gitignore generated vendored Normal file
View file

@ -0,0 +1,5 @@
.svn
*.o
.lock-wscript
build
node_modules

3
src/node/node_modules/node-sdl/.npmignore generated vendored Normal file
View file

@ -0,0 +1,3 @@
build
examples
examples/*

72
src/node/node_modules/node-sdl/Makefile generated vendored Normal file
View file

@ -0,0 +1,72 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := nodesdl
DEFS_Default :=
# Flags passed to all source files.
CFLAGS_Default := \
-I/usr/include/SDL \
-D_GNU_SOURCE=1 \
-D_REENTRANT
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
INCS_Default :=
OBJS := \
$(obj).target/$(TARGET)/node/node_modules/node-sdl/src/helpers.o \
$(obj).target/$(TARGET)/node/node_modules/node-sdl/src/nodesdl.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default := \
-L/usr/lib \
-lSDL \
-lpthread \
-lSDL_ttf \
-lSDL_image
LIBS :=
$(obj).target/node/node_modules/node-sdl/libnodesdl.a: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(obj).target/node/node_modules/node-sdl/libnodesdl.a: LIBS := $(LIBS)
$(obj).target/node/node_modules/node-sdl/libnodesdl.a: TOOLSET := $(TOOLSET)
$(obj).target/node/node_modules/node-sdl/libnodesdl.a: $(OBJS) FORCE_DO_CMD
$(call do_cmd,alink_thin)
all_deps += $(obj).target/node/node_modules/node-sdl/libnodesdl.a
# Add target alias
.PHONY: nodesdl
nodesdl: $(obj).target/node/node_modules/node-sdl/libnodesdl.a
# Add target alias to "all" target.
.PHONY: all
all: nodesdl

429
src/node/node_modules/node-sdl/README.md.orig generated vendored Normal file
View file

@ -0,0 +1,429 @@
# node-sdl ( Simple DirectMedia Layer bindings for node.js )
## 0. Installation
Installation of the node-sdl package is straight-forward: first clone the
package using git, then build the C++ portion of the package with the
node-waf command.
This package depends on the SDL libraries being present on the target system.
The following command was required to install these libraries on a "stock"
Ubuntu 11.04 install:
<pre> sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-dev</pre>
Now that your library dependencies are satisfied, check out the source from
github:
<pre> git clone https://github.com/creationix/node-sdl.git</pre>
Second, build the package:
<pre> cd node-sdl
node-waf configure build</pre>
You can test if the package was properly built by running one or more of the
example programs:
<pre> cd examples
node img.js</pre>
## 1. Usage
### 1.1. Initialization and Shutdown
Begin by requiring the node-sdl package and calling the init() function:
<pre> var SDL = require( 'sdl' );
SDL.init( SDL.INIT.VIDEO )</pre>
The init() function takes a numeric parameter telling the library what
subsystems to initialize. The node-sdl package defines the following
constants:
<pre> SDL.INIT.TIMER - initializes timers (not currently supported)
SDL.INIT.AUDIO - initialize audio subsystem (not currently supported)
SDL.INIT.VIDEO - initialize video subsystem
SDL.INIT.CDROM - initialize CD playback subsystem (not currently supported)
SDL.INIT.JOYSTICK - initialize joystick support
SDL.INIT.EVERYTHING - all of the above
SDL.INIT.NOPARACHUTE - don't catch fatal signals
</pre>
Two or more of these parameters may be selected by or-ing them together:
<pre> SDL.init( SDL.INIT.VIDEO | SDL.INIT.JOYSTICK );</pre>
The QUIT event signals the closure of a SDL managed window, so adding a
function that exits the application when it is received may be useful:
<pre> SDL.events.on( 'QUIT', function( evt ) { process.exit( 0 ); } );</pre>
Exiting the application when the user presses Control-C or the Escape key
can be achieved by adding a listener to the KEYDOWN event:
<pre> SDL.events.on( 'KEYDOWN', function ( evt ) {
if( ( ( evt.sym === 99 ) && ( evt.mod === 64 ) ) ||
( ( evt.sym === 27 ) && ( evt.mod === 0 ) ) ) {
process.exit( 0 );
}
} );</pre>
### 1.2. Video Functions
To create a window under SDL control, use the setVideoMode() function to
create a "surface".
<pre> var screen = SDL.setVideoMode( 640, 480, 32, SDL.SURFACE.SWSURFACE );</pre>
The setVideoMode() function takes four parameters: surface width, surface
height, bit depth and surface flags. The flags parameter selects options for
the video buffer:
<pre> SDL.SURFACE.SWSURFACE - video buffer created in system memory
SDL.SURFACE.HWSURFACE - video buffer created in video memory
SDL.SURFACE.ASYNCBLIT - enable async updates of display surface
SDL.SURFACE.ANYFORMAT - don't emulate unavailable BPPs with a shadow surface
SDL.SURFACE.HWPALETTE - give SDL exclusive palette access (not supported)
SDL.SURFACE.DOUBLEBUF - enable hardware double buffering. (only works with
SDL.SURFACE.HWSURFACE)
SDL.SURFACE.FULLSCREEN - use fullscreen mode
SDL.SURFACE.OPENGL - create an OpenGL rendering context (not supported)
SDL.SURFACE.RESIZABLE - create a resizable window
SDL.SURFACE.HWACCEL - use hardware accelerated blitter
SDL.SURFACE.SRCCOLORKEY - use color key blitter
SDL.SURFACE.RLEACCEL - color key blitting is accelerated with RLE
SDL.SURFACE.SRCALPHA - surface blit uses alpha blending
SDL.SURFACE.PREALLOC - surface uses preallocated memory
</pre>
Like other numeric constants, they may be combined with the or operator:
<pre> var screen = SDL.setVideoMode( 640, 480, 32, SDL.SURFACE.HWSURFACE | SDL.SURFACE.HWACCEL );</pre>
The surface created with the setVideoMode() call represents the contents of
the displayed window. It's common practice to create a buffer surface to hold
video contents in preparation for drawing on the screen. To create a buffer,
use the createRGBSurface() call.
<pre> var surface = SDL.createRGBSurface( SDL.SURFACE.SWSURFACE, 24, 24 );</pre>
The first parameter describes the type of surface to create, and the remaining
parameters are x and y sizes.
After you're done using a surface, you *should* free it. The freeSurface()
function takes a surface (like one returned from the createRGBSurface()
function above) and frees memory associated with it:
<pre> SDL.freeSurface( surface );</pre>
The displayFormat() function copies a surface into a new surface suitable
for blitting into the frame buffer. It takes a surface as it's first (and only)
parameter and returns a new surface conformable with the system's frame buffer.
This call is extremely useful in conjunction with the SDL.IMG.load() call:
<pre> var tempSheet = SDL.IMG.load( __dirname + "/sprites.png" );
var sheet = SDL.displayFormat( tempSheet );
SDL.freeSurface( tempSheet );</pre>
SDL surfaces may have an Alpha value associated with them. This is a value from
0 to 255 and sets the transparency of the surface's contents when blitted into
another surface (like the frame buffer).
<pre> SDL.setAlpha( sheet, SDL.SURFACE.SRCALPHA | SRC.SURFACE.RLEACCEL, 192 );</pre>
Options to the setAlpha() function include:
<pre> SDL.SURFACE.SRCALPHA - specifies that alpha blending should be used
SLD.SURFACE.RLEACCEL - specifies that RLE acceleration should be used for blitting</pre>
You can set a specific color to be transparent (i.e. - the color key) using the
setColorKey() function. After setting this value, when the surface's contents
are blitted to another surface, pixels with the color key value won't be copied.
<pre> SDL.setColorKey( sheet, SDL.SURFACE.SRCCOLORKEY, 0x01010100 );</pre>
The first parameter is the surface whose color key you're setting. The second
is a set of flags that may be or'd together. The third is a 32 bit integer
representing the value of the color key you want to use. Values for the flags
include:
<pre> SDL.SURFACE.SRCCOLORKEY - means you're setting the surface's color key
SDL.SURFACE.RLEACCEL - you want to enable RLE accleration
0 - means you want to clear the surface's color key
</pre>
It can sometimes be tricky to get the precise color key value if you're using
multiple surface geometries. Fortunately, you can use the mapRGB() function
to return a color value, modified to account for a surface's color geometry.
In other words, do this when you want to set the color key:
<pre> var colorKey = [ 255, 0, 0 ]; // setting the color key to red
SDL.setColorKey( sheet,
SDL.SURFACE.SRCCOLORKEY | SDL.SURFACE.RLEACCEL,
SDL.mapRGB( sheet.format,
colorKey[0],
colorKey[1],
colorKey[2] ) );</pre>
To fill a rectangle with a particular color, use the fillRect() function.
<pre> SDL.fillRect( surface, [0, 0, 24, 24], 0xFF8080AF );</pre>
To blit (copy) a portion of one surface into anotehr, use the blitSurface()
function. It takes as it's parameters: the source surface, a rectangle
describing the origin and extent of the pixels to be copied, the destination
surface, and a point in the destination you're copying pixels to.
So the following example copies an 8x16 rectangle from position (10,25) in the
spriteSource surface into position (128,15) in the screen surface:
<pre> SDL.blitSurface( spriteSource, [10, 25, 8, 16], screen, [128, 15] );</pre>
After making changes to a surface, you use the flip() function to instruct
the system to make the changes apparent. In systems that support hardware
double-buffering, this call "does the right thing" and waits for a vertical
retrace to flip between video screens. On systems with a software surface, it
simply makes sure that the contents of the surface are made visible.
It's very useful to call this command after you make updates to the screen. For
example:
<pre> var screen = SDL.setVideoMode( 640, 480, 32, SDL.SURFACE.SWSURFACE );
SDL.fillRect( surface, [0, 0, 24, 24], 0xFF8080AF );
SDL.flip( screen );
</pre>
### 1.3. Image Related Functions
This package uses a supplimentary image library intended to make it easy for
node-sdl applications to load and use JPG, PNG or TIFF images. Before using
Image functions, you should initalize them with the image init() function:
<pre> SDL.IMG.init( 0 );</pre>
To load an image into memory, use the image load() function. It takes a file
path as a parameter and returns a reference to it. The following line loads
a PNG file called "foo.png" into the variable foo.
<pre> var foo = SDL.IMG.load( __dirname + '/foo.png' );</pre>
The foo variable can now be used as a surface blit calls (see below.)
After you are finished using the image functions, be sure to use the image
quit() function:
<pre> SDL.IMG.quit();</pre>
### 1.4. Joystick Functions
If you are developing an application that uses joysticks, you'll need to pass
the SDL.INIT.JOYSTICK option along to the SDL.init() call:
<pre> SDL.init( SDL.INIT.VIDEO | SDL.INIT.JOYSTICK );</pre>
Now that your app knows you want to use joysticks, you can detect the number of
joysticks present with the numJoysticks() function. The following code checks
to see if there's at least one joystick and complains if there's not:
<pre> var numPlayers = SDL.numJoysticks();
if( numPlayers &lt; 1 ) {
console.log( 'Blargh! At least one joystick is required!' );
process.exit( 2 );
}</pre>
On systems with multiple joysticks, it might be useful to offer a player a
selection of which joystick to use. The system assigns a human readable name
for a joystick which the app can query with the joystickName() function. The
following code prints out the name of each joystick:
<pre> SDL.init( SDL.INIT.VIDEO | SDL.INIT.JOYSTICK );
var stickCount = SDL.numJoysticks();
for( var i = 0; i &lt; stickCount; i ++ ) {
console.log( 'joystick ' + i + ': ' + SDL.joystickName( i ) );
}
// etc</pre>
Now you must explicitly open each joystick you want to receive inputs from. Do
this with the joystickOpen() function. This function takes an integer as a
parameter and represents the index of the joystick you want to open. Here is
some code that opens joystick number zero:
<pre> SDL.joystickOpen( 0 );</pre>
After the joystick is opened, it will start to generate events. You can register
event handlers with the SDL.events.on() function. Joystick related events are
described in the events section below.
### 1.5. Window Manager Functions
node-sdl is capable of setting window manager related info with the SDL.WM.*
functions.
To set the title of a SDL window, use the setCaption() function. This fragment
sets the window's title to "Window Title" and (if supported by your window
manager) sets the name of the minimized icon to "Icon Title"
<pre> SDL.WM.setCaption( 'Window Title', 'Icon Title' );</pre>
To set the application's icon, use the setIcon() function. It expects an image
to be passed as it's parameter, so it's common practice to use the image load()
function. The following example loads an icon from the file 'eight.png' and
uses it as the app's icon:
<pre> SDL.WM.setIcon( SDL.IMG.load( __dirname + '/eight.png' ) );</pre>
## 2. Events
node-sdl uses javascript events to communicate certain conditions. The
events.on() function is used to set handlers for these events. Event handlers
are passed an object describing the event as a parameter.
### 2.1. Quit
As described above, the QUIT event is called when the user closes a SDL window.
The proper response is to free buffers, and exit:
<pre> SDL.events.on( 'QUIT', function ( evt ) {
SDL.IMG.quit();
process.exit( 0 );
} );</pre>
### 2.2. KEYDOWN & KEYUP
The KEYDOWN and KEYUP events signal the app that the user has pressed (or
released) a key. The event passed to the handler includes the following
properties:
<pre> scancode - the scancode of the key pressed
sym - the symbol of the key pressed
mod - key modifier</pre>
Key scancodes are hardware and locale dependent; it's recommended they be
left alone unless you really are targeting a specific piece of hardware. Key
symbols are numbers representing keyboard glyphs. Key modifiers represent
shift, meta, alt and control keys. As you might expect, it's possible for
multiple modifiers to be pressed simultaneously, so the mod value is a bit
field with the following definitions:
<pre>
0x0000 - No modifiers pressed
0x0001 - Left Shift
0x0002 - Right Shift
0x0040 - Left Control Key
0x0080 - Right Control Key
0x0100 - Left Alt Key
0x0200 - Right Alt Key
0x0400 - Left Meta Key (for hardware that has a meta key)
0x0800 - Right Meta Key (for hardware that has a meta key)
0x1000 - Num Lock on
0x2000 - Caps Lock on
0x4000 - Mode Key Pressed (bonus points if you can find hardware with a mode key)
</pre>
It should probably be noted that SDL keysyms are not exactly ASCII. Most
importantly, the system will not return a capital letter ASCII code when the
user hits a letter key and the shift key. Instead, you must manually check
for the shift key being pressed, check the modifier bits and adjust the key
code accordingly.
The following code converts the modifier and symbol to an ascii value:
<pre> SDL.events.on( 'KEYDOWN', function( evt ) {
var ascii = evt.sym;
if( ( ascii &lt; 123 ) && ( ascii &gt; 96 ) ) {
if( 0 != ( evt.mod && 0x2003 ) ) {
ascii -= 32;
}
}
console.log( 'ascii: ' + ascii );
} );</pre>
### 2.3. MOUSEMOTION
When the user moves a mouse over an SDL screen, the system will generate
MOUSEMOTION events. If you create a handler for these events, every time the
mouse moves, you'll receive an event with the following properties:
<pre> state - button state (as described above)
x - x position of the mouse pointer
y - y position of the mouse pointer
xrel - relative motion of the mouse pointer along the x axis
yrel - relative motion of the mouse pointer along the y axis</pre>
The button state is a bit field with the following values:
<pre> 0x0000 - no mouse button pressed
0x0001 - left mouse button pressed
0x0002 - middle mouse button pressed
0x0004 - right mouse button pressed</pre>
Take mouse chords with a grain of salt, some systems may be configured to
emulate a 3 button mouse. In these systems, pressing the left and right button
together will generate a middle button press (code 0x0002) instead of the
mouse chord you might be expecting (code 0x0005).
### 2.4. MOUSEBUTTONDOWN & MOUSEBUTTONUP
The MOUSEBUTTONUP and MOUSEBUTTONDOWN events report more data and have
slightly different semantics than the button state in the MOUSEMOTION event.
Handlers for these events are passed an object with the following properties:
<pre> button - mouse button clicked
x - x position of the mouse
y - y position of the mouse</pre>
The button property IS NOT a bit field, but an integer. Instead of detecting
mouse chords, it reports multiple button clicks. Here is the list of mouse
buttons supported:
<pre> 1 - left button
2 - middle button
3 - right button
4 - scroll wheel up
5 - scroll wheel down</pre>
### 2.5. JOYAXISMOTION (Joystick Axis Motion)
The JOYAXISMOTION event reports movement of the joystick device along one of
its axes. Handlers for this event are passed an object with the following
properties:
<pre> which - which joystick generated the event
axis - which axis (x or y) the event is reporting movement upon
value - a value from -32768 to 32767 describing the logical position of the joystick</pre>
### 2.6. JOYBALLMOTION (Joystick Trackball Motion)
If a user's joystick is equipped with a trackball, it may generate these events
when motion along the trackball is detected. Handlers assigned to listen for
these events will receive an object with the following properties:
<pre> which - which joystick generated the event
ball - which trackball generated the event
xrel - relative trackball motion along the x axis
yrel - relative trackball motion along the y axis</pre>
### 2.7. JOYHATMOTION (Joystick Hat Motion)
If a user's joystick is equipped with a hat, it may generate these events when
hat motion is detected. Handlers for this event will be passed an object with
the following properties:
<pre> which - which joystick generated the event
hat - which hat on the joystick generated the event
value - the position of the hat</pre>
### 2.8. JOYBUTTONDOWN & JOYBUTTONUP
If a user's joystick is equipped with buttons, it may generate these events when
a button press is detected. Handlers for these events will be passed an object
with the following properties:
<pre> which - which joystick generated the event
button - which button was pressed</pre>

4
src/node/node_modules/node-sdl/Readme generated vendored Normal file
View file

@ -0,0 +1,4 @@
This is a fork from node-sdl (https://github.com/creationix/node-sdl) with a
couple of modifications.
The build process is currently broken. Will be fixed at a later point.

21
src/node/node_modules/node-sdl/binding.gyp generated vendored Normal file
View file

@ -0,0 +1,21 @@
{
'targets': [
{
# have to specify 'liblib' here since gyp will remove the first one :\
'target_name': 'nodesdl',
'type': 'shared_library',
'sources': [
'src/helpers.cc',
'src/nodesdl.cc',
],
'ldflags': [
'<!@(sdl-config --libs)',
"-lSDL_ttf",
"-lSDL_image"
],
'cflags': [
'<!@(sdl-config --cflags)'
],
}
]
}

83
src/node/node_modules/node-sdl/nodesdl.target.mk generated vendored Normal file
View file

@ -0,0 +1,83 @@
# This file is generated by gyp; do not edit.
TOOLSET := target
TARGET := nodesdl
DEFS_Default :=
# Flags passed to all source files.
CFLAGS_Default := \
-I/usr/include/SDL \
-D_GNU_SOURCE=1 \
-D_REENTRANT
# Flags passed to only C files.
CFLAGS_C_Default :=
# Flags passed to only C++ files.
CFLAGS_CC_Default :=
INCS_Default :=
OBJS := \
$(obj).target/$(TARGET)/node/node_modules/node-sdl/src/helpers.o \
$(obj).target/$(TARGET)/node/node_modules/node-sdl/src/nodesdl.o
# Add to the list of files we specially track dependencies for.
all_deps += $(OBJS)
# CFLAGS et al overrides must be target-local.
# See "Target-specific Variable Values" in the GNU Make manual.
$(OBJS): TOOLSET := $(TOOLSET)
$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
# Suffix rules, putting all outputs into $(obj).
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
# Try building from generated source, too.
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD
@$(call do_cmd,cxx,1)
# End of this set of suffix rules
### Rules for final target.
LDFLAGS_Default := \
-L/usr/lib \
-lSDL \
-lpthread \
-lSDL_ttf \
-lSDL_image
LIBS :=
$(obj).target/node/node_modules/node-sdl/libnodesdl.so: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
$(obj).target/node/node_modules/node-sdl/libnodesdl.so: LIBS := $(LIBS)
$(obj).target/node/node_modules/node-sdl/libnodesdl.so: LD_INPUTS := $(OBJS)
$(obj).target/node/node_modules/node-sdl/libnodesdl.so: TOOLSET := $(TOOLSET)
$(obj).target/node/node_modules/node-sdl/libnodesdl.so: $(OBJS) FORCE_DO_CMD
$(call do_cmd,solink)
all_deps += $(obj).target/node/node_modules/node-sdl/libnodesdl.so
# Add target alias
.PHONY: nodesdl
nodesdl: $(builddir)/libnodesdl.so
# Copy this to the shared library output path.
$(builddir)/libnodesdl.so: TOOLSET := $(TOOLSET)
$(builddir)/libnodesdl.so: $(obj).target/node/node_modules/node-sdl/libnodesdl.so FORCE_DO_CMD
$(call do_cmd,copy)
all_deps += $(builddir)/libnodesdl.so
# Short alias for building this shared library.
.PHONY: libnodesdl.so
libnodesdl.so: $(obj).target/node/node_modules/node-sdl/libnodesdl.so $(builddir)/libnodesdl.so
# Add shared library to "all" target.
.PHONY: all
all: $(builddir)/libnodesdl.so

16
src/node/node_modules/node-sdl/package.json generated vendored Normal file
View file

@ -0,0 +1,16 @@
{
"author": "Tim Caswell <tim@creationix.com> (http://creationix.com/)",
"name": "sdl",
"description": "SDL bindings for node",
"version": "0.1.8",
"repository": {
"type": "git",
"url": "git://github.com/creationix/node-sdl.git"
},
"main": "sdl.js",
"engines": {
"node": ">=0.4.4"
},
"dependencies": {},
"devDependencies": {}
}

25
src/node/node_modules/node-sdl/sdl.js generated vendored Executable file
View file

@ -0,0 +1,25 @@
var SDL = module.exports = require('./build/Release/nodesdl.node');
// Easy event emitter based event loop. Started automatically when the first
// listener is added.
var events;
Object.defineProperty(SDL, 'events', {
get: function () {
if (events) return events;
events = new (require('events').EventEmitter);
var now = Date.now();
setInterval(function () {
var after = Date.now();
var delta = after - now;
now = after;
var data;
while (data = SDL.pollEvent()) {
events.emit('event', data);
events.emit(data.type, data);
}
events.emit('tick', delta);
}, 16);
return events;
}
});

437
src/node/node_modules/node-sdl/src/helpers.cc generated vendored Normal file
View file

@ -0,0 +1,437 @@
#include <v8.h>
#include <node.h>
#include <node_buffer.h>
#include <SDL.h>
#include <SDL_ttf.h>
#include "helpers.h"
namespace sdl {
// Helper for formatting error exceptions
Handle<Value> ThrowSDLException(const char* name) {
return ThrowException(MakeSDLException(name));
}
Local<Value> MakeSDLException(const char* name) {
return Exception::Error(String::Concat(
String::Concat(String::New(name), String::New(": ")),
String::New(SDL_GetError())
));
}
// Wrap/Unwrap Surface
static Persistent<ObjectTemplate> surface_template_;
Handle<Value> GetSurfaceFlags(Local<String> name, const AccessorInfo& info) {
SDL_Surface* surface = UnwrapSurface(info.Holder());
return Number::New(surface->flags);
}
Handle<Value> GetSurfaceFormat(Local<String> name, const AccessorInfo& info) {
HandleScope scope;
SDL_Surface* surface = UnwrapSurface(info.Holder());
return scope.Close(WrapPixelFormat(surface->format));
}
Handle<Value> GetSurfaceWidth(Local<String> name, const AccessorInfo& info) {
SDL_Surface* surface = UnwrapSurface(info.Holder());
return Number::New(surface->w);
}
Handle<Value> GetSurfaceHeight(Local<String> name, const AccessorInfo& info) {
SDL_Surface* surface = UnwrapSurface(info.Holder());
return Number::New(surface->h);
}
Handle<Value> GetSurfacePitch(Local<String> name, const AccessorInfo& info) {
SDL_Surface* surface = UnwrapSurface(info.Holder());
return Number::New(surface->pitch);
}
Handle<Value> GetSurfaceRect(Local<String> name, const AccessorInfo& info) {
HandleScope scope;
SDL_Surface* surface = UnwrapSurface(info.Holder());
return scope.Close(WrapRect(&surface->clip_rect));
}
Handle<ObjectTemplate> MakeSurfaceTemplate() {
HandleScope handle_scope;
Handle<ObjectTemplate> result = ObjectTemplate::New();
result->SetInternalFieldCount(1);
// Add accessors for some of the fields of the surface.
result->SetAccessor(String::NewSymbol("flags"), GetSurfaceFlags);
result->SetAccessor(String::NewSymbol("format"), GetSurfaceFormat);
result->SetAccessor(String::NewSymbol("w"), GetSurfaceWidth);
result->SetAccessor(String::NewSymbol("h"), GetSurfaceHeight);
result->SetAccessor(String::NewSymbol("pitch"), GetSurfacePitch);
result->SetAccessor(String::NewSymbol("clip_rect"), GetSurfaceRect);
// Again, return the result through the current handle scope.
return handle_scope.Close(result);
}
Handle<Object> WrapSurface(SDL_Surface* surface) {
// Handle scope for temporary handles.
HandleScope handle_scope;
// Fetch the template for creating JavaScript http request wrappers.
// It only has to be created once, which we do on demand.
if (surface_template_.IsEmpty()) {
Handle<ObjectTemplate> raw_template = MakeSurfaceTemplate();
surface_template_ = Persistent<ObjectTemplate>::New(raw_template);
}
Handle<ObjectTemplate> templ = surface_template_;
// Create an empty http request wrapper.
Handle<Object> result = templ->NewInstance();
// Wrap the raw C++ pointer in an External so it can be referenced
// from within JavaScript.
Handle<External> request_ptr = External::New(surface);
// Store the request pointer in the JavaScript wrapper.
result->SetInternalField(0, request_ptr);
// Return the result through the current handle scope. Since each
// of these handles will go away when the handle scope is deleted
// we need to call Close to let one, the result, escape into the
// outer handle scope.
return handle_scope.Close(result);
}
SDL_Surface* UnwrapSurface(Handle<Object> obj) {
Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0));
void* ptr = field->Value();
return static_cast<SDL_Surface*>(ptr);
}
// Wrap/Unwrap Rect
static Persistent<ObjectTemplate> rect_template_;
Handle<Value> GetRectX(Local<String> name, const AccessorInfo& info) {
SDL_Rect* rect = UnwrapRect(info.Holder());
return Number::New(rect->x);
}
Handle<Value> GetRectY(Local<String> name, const AccessorInfo& info) {
SDL_Rect* rect = UnwrapRect(info.Holder());
return Number::New(rect->y);
}
Handle<Value> GetRectW(Local<String> name, const AccessorInfo& info) {
SDL_Rect* rect = UnwrapRect(info.Holder());
return Number::New(rect->w);
}
Handle<Value> GetRectH(Local<String> name, const AccessorInfo& info) {
SDL_Rect* rect = UnwrapRect(info.Holder());
return Number::New(rect->h);
}
Handle<ObjectTemplate> MakeRectTemplate() {
HandleScope handle_scope;
Handle<ObjectTemplate> result = ObjectTemplate::New();
result->SetInternalFieldCount(1);
// Add accessors for some of the fields of the rect.
result->SetAccessor(String::NewSymbol("x"), GetRectX);
result->SetAccessor(String::NewSymbol("y"), GetRectY);
result->SetAccessor(String::NewSymbol("w"), GetRectW);
result->SetAccessor(String::NewSymbol("h"), GetRectH);
// Again, return the result through the current handle scope.
return handle_scope.Close(result);
}
Handle<Object> WrapRect(SDL_Rect* rect) {
// Handle scope for temporary handles.
HandleScope handle_scope;
// Fetch the template for creating JavaScript http request wrappers.
// It only has to be created once, which we do on demand.
if (rect_template_.IsEmpty()) {
Handle<ObjectTemplate> raw_template = MakeRectTemplate();
rect_template_ = Persistent<ObjectTemplate>::New(raw_template);
}
Handle<ObjectTemplate> templ = rect_template_;
// Create an empty http request wrapper.
Handle<Object> result = templ->NewInstance();
// Wrap the raw C++ pointer in an External so it can be referenced
// from within JavaScript.
Handle<External> request_ptr = External::New(rect);
// Store the request pointer in the JavaScript wrapper.
result->SetInternalField(0, request_ptr);
// Return the result through the current handle scope. Since each
// of these handles will go away when the handle scope is deleted
// we need to call Close to let one, the result, escape into the
// outer handle scope.
return handle_scope.Close(result);
}
SDL_Rect* UnwrapRect(Handle<Object> obj) {
Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0));
void* ptr = field->Value();
return static_cast<SDL_Rect*>(ptr);
}
// Wrap/Unwrap PixelFormat
static Persistent<ObjectTemplate> pixelformat_template_;
Handle<Value> GetFormatBits(Local<String> name, const AccessorInfo& info) {
SDL_PixelFormat* format = UnwrapPixelFormat(info.Holder());
return Number::New(format->BitsPerPixel);
}
Handle<Value> GetFormatBytes(Local<String> name, const AccessorInfo& info) {
SDL_PixelFormat* format = UnwrapPixelFormat(info.Holder());
return Number::New(format->BytesPerPixel);
}
Handle<Value> GetFormatColorkey(Local<String> name, const AccessorInfo& info) {
SDL_PixelFormat* format = UnwrapPixelFormat(info.Holder());
return Number::New(format->colorkey);
}
Handle<Value> GetFormatAlpha(Local<String> name, const AccessorInfo& info) {
SDL_PixelFormat* format = UnwrapPixelFormat(info.Holder());
return Number::New(format->alpha);
}
Handle<ObjectTemplate> MakePixelFormatTemplate() {
HandleScope handle_scope;
Handle<ObjectTemplate> result = ObjectTemplate::New();
result->SetInternalFieldCount(1);
// Add accessors for some of the fields of the pixelformat.
result->SetAccessor(String::NewSymbol("bitsPerPixel"), GetFormatBits);
result->SetAccessor(String::NewSymbol("bytesPerPixel"), GetFormatBytes);
result->SetAccessor(String::NewSymbol("colorkey"), GetFormatColorkey);
result->SetAccessor(String::NewSymbol("alpha"), GetFormatAlpha);
// Again, return the result through the current handle scope.
return handle_scope.Close(result);
}
Handle<Object> WrapPixelFormat(SDL_PixelFormat* pixelformat) {
// Handle scope for temporary handles.
HandleScope handle_scope;
// Fetch the template for creating JavaScript http request wrappers.
// It only has to be created once, which we do on demand.
if (pixelformat_template_.IsEmpty()) {
Handle<ObjectTemplate> raw_template = MakePixelFormatTemplate();
pixelformat_template_ = Persistent<ObjectTemplate>::New(raw_template);
}
Handle<ObjectTemplate> templ = pixelformat_template_;
// Create an empty http request wrapper.
Handle<Object> result = templ->NewInstance();
// Wrap the raw C++ pointer in an External so it can be referenced
// from within JavaScript.
Handle<External> request_ptr = External::New(pixelformat);
// Store the request pointer in the JavaScript wrapper.
result->SetInternalField(0, request_ptr);
// Return the result through the current handle scope. Since each
// of these handles will go away when the handle scope is deleted
// we need to call Close to let one, the result, escape into the
// outer handle scope.
return handle_scope.Close(result);
}
SDL_PixelFormat* UnwrapPixelFormat(Handle<Object> obj) {
Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0));
void* ptr = field->Value();
return static_cast<SDL_PixelFormat*>(ptr);
}
// Wrap/Unwrap Joystick
static Persistent<ObjectTemplate> joystick_template_;
//Handle<Value> GetJoystickFlags(Local<String> name, const AccessorInfo& info) {
// SDL_Joystick* joystick = UnwrapJoystick(info.Holder());
// return Number::New(joystick->flags);
//}
//Handle<Value> GetJoystickFormat(Local<String> name, const AccessorInfo& info) {
// HandleScope scope;
// SDL_Joystick* joystick = UnwrapJoystick(info.Holder());
// return scope.Close(WrapPixelFormat(joystick->format));
//}
//Handle<Value> GetJoystickWidth(Local<String> name, const AccessorInfo& info) {
// SDL_Joystick* joystick = UnwrapJoystick(info.Holder());
// return Number::New(joystick->w);
//}
//Handle<Value> GetJoystickHeight(Local<String> name, const AccessorInfo& info) {
// SDL_Joystick* joystick = UnwrapJoystick(info.Holder());
// return Number::New(joystick->h);
//}
//Handle<Value> GetJoystickPitch(Local<String> name, const AccessorInfo& info) {
// SDL_Joystick* joystick = UnwrapJoystick(info.Holder());
// return Number::New(joystick->pitch);
//}
//Handle<Value> GetJoystickRect(Local<String> name, const AccessorInfo& info) {
// HandleScope scope;
// SDL_Joystick* joystick = UnwrapJoystick(info.Holder());
// return scope.Close(WrapRect(&joystick->clip_rect));
//}
Handle<ObjectTemplate> MakeJoystickTemplate() {
HandleScope handle_scope;
Handle<ObjectTemplate> result = ObjectTemplate::New();
result->SetInternalFieldCount(1);
// Add accessors for some of the fields of the joystick.
// result->SetAccessor(String::NewSymbol("flags"), GetJoystickFlags);
// result->SetAccessor(String::NewSymbol("format"), GetJoystickFormat);
// result->SetAccessor(String::NewSymbol("w"), GetJoystickWidth);
// result->SetAccessor(String::NewSymbol("h"), GetJoystickHeight);
// result->SetAccessor(String::NewSymbol("pitch"), GetJoystickPitch);
// result->SetAccessor(String::NewSymbol("clip_rect"), GetJoystickRect);
// Again, return the result through the current handle scope.
return handle_scope.Close(result);
}
Handle<Object> WrapJoystick(SDL_Joystick* joystick) {
// Handle scope for temporary handles.
HandleScope handle_scope;
// Fetch the template for creating JavaScript http request wrappers.
// It only has to be created once, which we do on demand.
if (joystick_template_.IsEmpty()) {
Handle<ObjectTemplate> raw_template = MakeJoystickTemplate();
joystick_template_ = Persistent<ObjectTemplate>::New(raw_template);
}
Handle<ObjectTemplate> templ = joystick_template_;
// Create an empty http request wrapper.
Handle<Object> result = templ->NewInstance();
// Wrap the raw C++ pointer in an External so it can be referenced
// from within JavaScript.
Handle<External> request_ptr = External::New(joystick);
// Store the request pointer in the JavaScript wrapper.
result->SetInternalField(0, request_ptr);
// Return the result through the current handle scope. Since each
// of these handles will go away when the handle scope is deleted
// we need to call Close to let one, the result, escape into the
// outer handle scope.
return handle_scope.Close(result);
}
SDL_Joystick* UnwrapJoystick(Handle<Object> obj) {
Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0));
void* ptr = field->Value();
return static_cast<SDL_Joystick*>(ptr);
}
// Wrap/Unwrap Font
static Persistent<ObjectTemplate> font_template_;
//Handle<Value> GetFontFlags(Local<String> name, const AccessorInfo& info) {
// TTF_Font* font = UnwrapFont(info.Holder());
// return Number::New(font->flags);
//}
//Handle<Value> GetFontFormat(Local<String> name, const AccessorInfo& info) {
// HandleScope scope;
// TTF_Font* font = UnwrapFont(info.Holder());
// return scope.Close(WrapPixelFormat(font->format));
//}
//Handle<Value> GetFontWidth(Local<String> name, const AccessorInfo& info) {
// TTF_Font* font = UnwrapFont(info.Holder());
// return Number::New(font->w);
//}
//Handle<Value> GetFontHeight(Local<String> name, const AccessorInfo& info) {
// TTF_Font* font = UnwrapFont(info.Holder());
// return Number::New(font->h);
//}
//Handle<Value> GetFontPitch(Local<String> name, const AccessorInfo& info) {
// TTF_Font* font = UnwrapFont(info.Holder());
// return Number::New(font->pitch);
//}
//Handle<Value> GetFontRect(Local<String> name, const AccessorInfo& info) {
// HandleScope scope;
// TTF_Font* font = UnwrapFont(info.Holder());
// return scope.Close(WrapRect(&font->clip_rect));
//}
Handle<ObjectTemplate> MakeFontTemplate() {
HandleScope handle_scope;
Handle<ObjectTemplate> result = ObjectTemplate::New();
result->SetInternalFieldCount(1);
// Add accessors for some of the fields of the font.
// result->SetAccessor(String::NewSymbol("flags"), GetFontFlags);
// result->SetAccessor(String::NewSymbol("format"), GetFontFormat);
// result->SetAccessor(String::NewSymbol("w"), GetFontWidth);
// result->SetAccessor(String::NewSymbol("h"), GetFontHeight);
// result->SetAccessor(String::NewSymbol("pitch"), GetFontPitch);
// result->SetAccessor(String::NewSymbol("clip_rect"), GetFontRect);
// Again, return the result through the current handle scope.
return handle_scope.Close(result);
}
Handle<Object> WrapFont(TTF_Font* font) {
// Handle scope for temporary handles.
HandleScope handle_scope;
// Fetch the template for creating JavaScript http request wrappers.
// It only has to be created once, which we do on demand.
if (font_template_.IsEmpty()) {
Handle<ObjectTemplate> raw_template = MakeFontTemplate();
font_template_ = Persistent<ObjectTemplate>::New(raw_template);
}
Handle<ObjectTemplate> templ = font_template_;
// Create an empty http request wrapper.
Handle<Object> result = templ->NewInstance();
// Wrap the raw C++ pointer in an External so it can be referenced
// from within JavaScript.
Handle<External> request_ptr = External::New(font);
// Store the request pointer in the JavaScript wrapper.
result->SetInternalField(0, request_ptr);
// Return the result through the current handle scope. Since each
// of these handles will go away when the handle scope is deleted
// we need to call Close to let one, the result, escape into the
// outer handle scope.
return handle_scope.Close(result);
}
TTF_Font* UnwrapFont(Handle<Object> obj) {
Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0));
void* ptr = field->Value();
return static_cast<TTF_Font*>(ptr);
}
//char* BufferData(Buffer *b) {
// return Buffer::Data(b->handle_);
//}
//size_t BufferLength(Buffer *b) {
// return Buffer::Length(b->handle_);
//}
char* BufferData(Local<Object> buf_obj) {
return Buffer::Data(buf_obj);
}
size_t BufferLength(Local<Object> buf_obj) {
return Buffer::Length(buf_obj);
}
} // node_sdl

42
src/node/node_modules/node-sdl/src/helpers.h generated vendored Normal file
View file

@ -0,0 +1,42 @@
#ifndef HELPERS_H_
#define HELPERS_H_
#include <v8.h>
#include <node.h>
#include <node_buffer.h>
using namespace node;
using namespace v8;
namespace sdl {
// Error reporting helpers
Handle<Value> ThrowSDLException(const char* name);
Local<Value> MakeSDLException(const char* name);
// Wrapper and Unwrappers
Handle<Object> WrapSurface(SDL_Surface* surface);
SDL_Surface* UnwrapSurface(Handle<Object> obj);
Handle<Object> WrapRect(SDL_Rect* rect);
SDL_Rect* UnwrapRect(Handle<Object> obj);
Handle<Object> WrapPixelFormat(SDL_PixelFormat* pixelformat);
SDL_PixelFormat* UnwrapPixelFormat(Handle<Object> obj);
Handle<Object> WrapJoystick(SDL_Joystick* joystick);
SDL_Joystick* UnwrapJoystick(Handle<Object> obj);
Handle<Object> WrapFont(TTF_Font* font);
TTF_Font* UnwrapFont(Handle<Object> obj);
// Helpers to work with buffers
//char* BufferData(Buffer *b);
//size_t BufferLength(Buffer *b);
char* BufferData(Local<Object> buf_obj);
size_t BufferLength(Local<Object> buf_obj);
} // sdl
#endif // HELPERS_H_

1078
src/node/node_modules/node-sdl/src/nodesdl.cc generated vendored Normal file

File diff suppressed because it is too large Load diff

93
src/node/node_modules/node-sdl/src/nodesdl.h generated vendored Normal file
View file

@ -0,0 +1,93 @@
#ifndef NODE_SDL_H_
#define NODE_SDL_H_
#include <node.h>
#include <v8.h>
#include <SDL.h>
#include <SDL_ttf.h>
#include <SDL_image.h>
#include "helpers.h"
using namespace v8;
namespace sdl {
static Handle<Value> Init(const Arguments& args);
static Handle<Value> InitSubSystem(const Arguments& args);
static Handle<Value> Quit(const Arguments& args);
static Handle<Value> QuitSubSystem(const Arguments& args);
static Handle<Value> WasInit(const Arguments& args);
static Handle<Value> ClearError(const Arguments& args);
static Handle<Value> GetError(const Arguments& args);
static Handle<Value> SetError(const Arguments& args);
static Handle<Value> WaitEvent(const Arguments& args);
static Handle<Value> PollEvent(const Arguments& args);
static Handle<Value> SetVideoMode(const Arguments& args);
static Handle<Value> VideoModeOK(const Arguments& args);
static Handle<Value> NumJoysticks(const Arguments& args);
static Handle<Value> JoystickOpen(const Arguments& args);
static Handle<Value> JoystickOpened(const Arguments& args);
static Handle<Value> JoystickName(const Arguments& args);
static Handle<Value> JoystickNumAxes(const Arguments& args);
static Handle<Value> JoystickNumButtons(const Arguments& args);
static Handle<Value> JoystickNumBalls(const Arguments& args);
static Handle<Value> JoystickNumHats(const Arguments& args);
static Handle<Value> JoystickClose(const Arguments& args);
static Handle<Value> JoystickUpdate(const Arguments& args);
static Handle<Value> JoystickEventState(const Arguments& args);
static Handle<Value> Flip(const Arguments& args);
static Handle<Value> PutImageData(const Arguments& args);
static Handle<Value> FillRect(const Arguments& args);
static Handle<Value> UpdateRect(const Arguments& args);
static Handle<Value> CreateRGBSurface(const Arguments& args);
static Handle<Value> BlitSurface(const Arguments& args);
static Handle<Value> FreeSurface(const Arguments& args);
static Handle<Value> SetColorKey(const Arguments& args);
static Handle<Value> DisplayFormat(const Arguments& args);
static Handle<Value> DisplayFormatAlpha(const Arguments& args);
static Handle<Value> SetAlpha(const Arguments& args);
static Handle<Value> MapRGB(const Arguments& args);
static Handle<Value> MapRGBA(const Arguments& args);
static Handle<Value> GetRGB(const Arguments& args);
static Handle<Value> GetRGBA(const Arguments& args);
static Handle<Value> SetClipRect(const Arguments& args);
namespace TTF {
static Handle<Value> Init(const Arguments& args);
static Handle<Value> OpenFont(const Arguments& args);
static Handle<Value> RenderTextBlended(const Arguments& args);
static Handle<Value> RenderTextShaded(const Arguments& args);
}
namespace IMG {
static Handle<Value> Load(const Arguments& args);
}
namespace WM {
static Handle<Value> SetCaption(const Arguments& args);
static Handle<Value> SetIcon(const Arguments& args);
}
namespace GL {
static Handle<Value> SetAttribute (const Arguments& args);
static Handle<Value> GetAttribute (const Arguments& args);
static Handle<Value> SwapBuffers (const Arguments& args);
}
typedef struct {
Persistent<Function> fn;
int status;
} closure_t;
//static void EIO_WaitEvent(eio_req *req);
//static int EIO_OnEvent(eio_req *req);
}
#endif

124
src/node/screen_sdl.js Normal file
View file

@ -0,0 +1,124 @@
"use strict";
function NodeScreenSDL(sdl, font_file)
{
var ROW_HEIGHT = 16,
// about right for ascii.ttf
CHAR_WIDTH = 10,
/** @type {number} */
cursor_scanline_start,
/** @type {number} */
cursor_scanline_end,
current_cursor_address,
graphic_buffer,
graphic_buffer8,
graphic_buffer32;
sdl.init(sdl.INIT.VIDEO);
var ttf = sdl.TTF,
screen;
ttf.init();
var font = ttf.openFont(font_file, 16);
sdl.events.on("QUIT", function()
{
process.exit();
});
this.put_char = function(row, col, chr, bg_color, fg_color)
{
if((chr & 0xff) === 0)
{
// required, otherwise sdl throws up
return;
}
var str = String.fromCharCode(chr & 0xff),
s = ttf.renderTextShaded(font, str, fg_color, bg_color);
sdl.blitSurface(s, null, screen, [col * CHAR_WIDTH, row * ROW_HEIGHT]);
sdl.freeSurface(s);
};
this.put_pixel_linear = function(offset, color_part)
{
graphic_buffer8[offset] = color_part;
};
this.put_pixel = function(x, y, color)
{
throw "TODO";
};
this.timer_text = function()
{
sdl.flip(screen);
};
this.timer_graphical = function()
{
sdl.putImageData(screen, graphic_buffer32);
sdl.flip(screen);
};
this.destroy = function()
{
};
this.set_mode = function(graphical)
{
// switch between graphical and text mode
};
this.clear_screen = function()
{
};
this.set_size_text = function(cols, rows)
{
screen = sdl.setVideoMode(CHAR_WIDTH * cols, ROW_HEIGHT * rows, 32, 0);
//dbg_log(screen, LOG_VGA);
//dbg_log(screen.pixels, LOG_VGA);
};
this.set_size_graphical = function(width, height)
{
screen = sdl.setVideoMode(width, height, 32, 0);
graphic_buffer = new ArrayBuffer(width * height * 4);
graphic_buffer8 = new Uint8Array(graphic_buffer);
graphic_buffer32 = new Int32Array(graphic_buffer);
};
this.update_cursor = function(cursor_row, cursor_col)
{
refresh_cursor();
};
this.update_cursor_scanline = function(start, end)
{
cursor_scanline_start = start;
cursor_scanline_end = end;
refresh_cursor();
};
function refresh_cursor()
{
// TODO
}
}

90
src/node/screen_tty.js Normal file
View file

@ -0,0 +1,90 @@
"use strict";
/*
* Very simple prototype, mostly incomplete
*/
function NodeScreenTTY()
{
var stdout = process.stdout,
cursor_row = 0,
cursor_col = 0;
clear();
function clear()
{
stdout.write("\x1b[2J");
}
function set_cursor_pos(row, col)
{
stdout.write("\x1b[" + row + ";" + col + "H");
}
function hide_cursor()
{
stdout.write("\x1b[?25l");
}
function show_cursor()
{
stdout.write("\x1b[?25h");
}
this.timer_text = function()
{
};
this.destroy = function()
{
};
this.set_mode = function(is_graphical)
{
if(is_graphical)
{
console.log("Graphical Mode is not supported for NodeScreenTTY");
}
};
this.clear_screen = function()
{
};
this.set_size_text = function(cols, rows)
{
};
this.set_size_graphical = function(width, height)
{
};
this.update_cursor = function(row, col)
{
cursor_row = row;
cursor_col = col;
};
this.update_cursor_scanline = function(start, end)
{
};
this.put_char = function(row, col, chr, bg_color, fg_color)
{
var str = String.fromCharCode(chr);
hide_cursor();
set_cursor_pos(row, col + 1);
stdout.write(str);
set_cursor_pos(cursor_row, cursor_col + 2);
show_cursor();
};
}

173
src/pci.js Normal file
View file

@ -0,0 +1,173 @@
"use strict";
var
/** @const */ PCI_VENDOR_ID = 0x00 /* 16 bits */
/** @const */ ,PCI_DEVICE_ID = 0x02 /* 16 bits */
/** @const */ ,PCI_COMMAND = 0x04 /* 16 bits */
/** @const */ ,PCI_BASE_ADDRESS_0 = 0x10 /* 32 bits */
/** @const */ ,PCI_BASE_ADDRESS_1 = 0x14 /* 32 bits [htype 0,1 only] */
/** @const */ ,PCI_BASE_ADDRESS_2 = 0x18 /* 32 bits [htype 0 only] */
/** @const */ ,PCI_BASE_ADDRESS_3 = 0x1c /* 32 bits */
/** @const */ ,PCI_BASE_ADDRESS_4 = 0x20 /* 32 bits */
/** @const */ ,PCI_BASE_ADDRESS_5 = 0x24 /* 32 bits */
/** @const */ ,PCI_INTERRUPT_LINE = 0x3c /* 8 bits */
/** @const */ ,PCI_CLASS_REVISION = 0x08; /* High 24 bits are class, low 8 revision */
/** @constructor */
function PCI(dev)
{
var
io = dev.io,
pci_data = 0,
pci_counter = 0,
pci_response = -1,
pci_status = -1,
self = this;
// TODO: Change the format of this
this.devices = {};
/*
io.register_write(0xCF9, function(value)
{
dbg_log("PCI reboot: " + h(value, 2), LOG_PCI);
// PCI reboot
if(value & 6)
{
cpu_restart();
}
});*/
io.register_read(0xCFC, function()
{
return pci_response & 0xFF;
});
io.register_read(0xCFD, function()
{
return pci_response >> 8 & 0xFF;
});
io.register_read(0xCFE, function()
{
return pci_response >> 16 & 0xFF;
});
io.register_read(0xCFF, function()
{
return pci_response >> 24 & 0xFF;
});
io.register_read(0xCF8, function()
{
return pci_status & 0xFF;
});
io.register_read(0xCF9, function()
{
return pci_status >> 8 & 0xFF;
});
io.register_read(0xCFA, function()
{
return pci_status >> 16 & 0xFF;
});
io.register_read(0xCFB, function()
{
return pci_status >> 24 & 0xFF;
});
io.register_write(0xCF8, function(out_byte)
{
pci_data = pci_data & ~0xFF | out_byte;
});
io.register_write(0xCF9, function(out_byte)
{
pci_data = pci_data & ~0xFF00 | out_byte << 8;
});
io.register_write(0xCFA, function(out_byte)
{
pci_data = pci_data & ~0xFF0000 | out_byte << 16;
});
io.register_write(0xCFB, function(out_byte)
{
pci_data = pci_data & 0xFFFFFF | out_byte << 24;
pci_query(pci_data);
});
function pci_query(dword)
{
var dbg_line = "PCI: ";
// Bit | .31 .0
// Fmt | EBBBBBBBBDDDDDFFFRRRRRR00
var bdf = (dword & 0x7FFFFFFF) >> 8,
addr = dword & 0xFC,
devfn = bdf & 0xFF,
bus = bdf >> 8,
dev = bdf >> 3 & 0x1F,
fn = bdf & 7,
enabled = dword >> 31 & 1;
dbg_line += " enabled=" + (enabled);
dbg_line += " bdf=" + h(bdf);
dbg_line += " addr=" + h(addr);
dbg_log(dbg_line + " " + h(dword >>> 0, 8), LOG_PCI);
if(dword === (0x80000000 | 0))
{
pci_status = 0x80000000;
}
else if(self.devices[bdf])
{
var device = self.devices[bdf];
pci_status = 0x80000000;
if(addr === PCI_VENDOR_ID)
{
pci_response = device.vendor_id;
}
else if(addr === PCI_CLASS_REVISION)
{
pci_response = device.class_revision;
}
else if(addr === PCI_BASE_ADDRESS_5)
{
pci_response = device.iobase;
}
else if(addr === PCI_INTERRUPT_LINE)
{
pci_response = device.irq;
}
else
{
dbg_log("unimplemented addr " + h(addr) + " for device " + h(bdf), LOG_PCI);
pci_response = 0;
}
}
else
{
pci_response = 0;
pci_status = 0;
}
}
this.register_device = function(device, device_id)
{
dbg_assert(!this.devices[device_id]);
this.devices[device_id] = device;
};
// ~% lspci -x
// 00:00.0 Host bridge: Intel Corporation 4 Series Chipset DRAM Controller (rev 02)
// 00: 86 80 20 2e 06 00 90 20 02 00 00 06 00 00 00 00
// 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
// 20: 00 00 00 00 00 00 00 00 00 00 00 00 43 10 d3 82
// 30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00
this.register_device({
irq: 0,
iobase: 0,
vendor_id: 0x8680202e,
class_revision: 0x06009020,
}, 0);
}

280
src/pic.js Normal file
View file

@ -0,0 +1,280 @@
"use strict";
/**
* Programmable Interrupt Controller
* http://stanislavs.org/helppc/8259.html
*
* @constructor
* @param {PIC=} master
*/
function PIC(dev, call_interrupt_vector, handle_irqs, master)
{
var
io = dev.io,
/**
* all irqs off
* @type {number}
*/
irq_mask = 0,
/**
* @type {number}
*
* Bogus default value (both master and slave mapped to 0).
* Will be initialized by the BIOS
*/
irq_map = 0,
/**
* in-service register
* Holds interrupts that are currently being serviced
* @type {number}
*/
isr = 0,
/**
* interrupt request register
* Holds interrupts that have been requested
* @type {number}
*/
irr = 0,
is_master = master === undefined,
slave,
me = this;
if(is_master)
{
slave = new PIC(dev, call_interrupt_vector, handle_irqs, this);
this.handle_irqs = function()
{
var enabled_irr = irr & irq_mask;
if(!enabled_irr)
{
return false
}
var irq = enabled_irr & -enabled_irr;
if(isr && (isr & -isr) <= irq)
{
// wait for eoi of higher or same priority interrupt
return false;
}
irr &= ~irq;
isr |= irq;
if(irq === 4)
{
// this should always return true
return slave.handle_irqs();
}
call_interrupt_vector(irq_map + log2_table[irq], false, false);
return true;
};
}
else
{
// is slave
this.handle_irqs = function()
{
var enabled_irr = irr & irq_mask;
if(!enabled_irr)
{
return false;
}
var irq = enabled_irr & -enabled_irr;
if(isr && (isr & -isr) <= irq)
{
// wait for eoi of higher or same priority interrupt
return false;
}
irr &= ~irq;
isr |= irq;
call_interrupt_vector(irq_map + log2_table[irq], false, false);
if(irr)
{
// tell the master we have one more
master.push_irq(2);
}
return true;
};
}
this.dump = function()
{
dbg_log("mask: " + h(irq_mask & 0xFF), LOG_PIC);
dbg_log("base: " + h(irq_map), LOG_PIC);
dbg_log("requested: " + h(irr), LOG_PIC);
dbg_log("serviced: " + h(isr), LOG_PIC);
if(is_master)
{
slave.dump();
}
};
var expect_icw4,
state = 0,
read_irr = 1,
io_base,
auto_eoi;
if(is_master)
{
io_base = 0x20;
}
else
{
io_base = 0xA0;
}
io.register_write(io_base, port20_write);
io.register_read(io_base, port20_read);
io.register_write(io_base | 1, port21_write);
io.register_read(io_base | 1, port21_read);
function port20_write(data_byte)
{
//dbg_log("20 write: " + h(data_byte), LOG_PIC);
if(data_byte & 0x10) // xxxx1xxx
{
// icw1
dbg_log("icw1 = " + h(data_byte), LOG_PIC);
expect_icw4 = data_byte & 1;
state = 1;
}
else if(data_byte & 8) // xxx01xxx
{
// ocw3
dbg_log("ocw3: " + h(data_byte), LOG_PIC);
read_irr = data_byte & 1;
}
else // xxx00xxx
{
// ocw2
// end of interrupt
//dbg_log("ocw2: " + h(data_byte), LOG_PIC);
var eoi_type = data_byte >> 5;
if(eoi_type === 1)
{
// non-specific eoi
isr = 0;
}
else if(eoi_type === 3)
{
// specific eoi
isr &= ~(1 << (data_byte & 7));
}
else
{
dbg_log("Unknown eoi: " + h(data_byte), LOG_PIC);
}
}
};
function port20_read()
{
if(read_irr)
{
return irr;
}
else
{
return isr;
}
}
function port21_write(data_byte)
{
//dbg_log("21 write: " + h(data_byte), LOG_PIC);
if(state === 0)
{
if(expect_icw4)
{
// icw4
expect_icw4 = false;
auto_eoi = data_byte & 2;
dbg_log("icw4: " + h(data_byte), LOG_PIC);
}
else
{
// ocw1
irq_mask = ~data_byte;
//dbg_log("interrupt mask: " + (irq_mask & 0xFFFF).toString(2) + " / map " + h(irq_map), LOG_PIC);
}
}
else if(state === 1)
{
// icw2
irq_map = data_byte;
dbg_log("interrupts are mapped to " + h(irq_map) +
" (" + (is_master ? "master" : "slave") + ")", LOG_PIC);
state++;
}
else if(state === 2)
{
// icw3
state = 0;
dbg_log("icw3: " + h(data_byte), LOG_PIC);
}
};
function port21_read()
{
//dbg_log("21h read (" + h(irq_map) + ")", LOG_PIC);
return ~irq_mask;
};
if(is_master)
{
this.push_irq = function(irq_number)
{
dbg_assert(irq_number >= 0 && irq_number < 16);
if(irq_number >= 8)
{
slave.push_irq(irq_number - 8);
irq_number = 2;
}
irr |= 1 << irq_number;
handle_irqs();
};
}
else
{
this.push_irq = function(irq_number)
{
dbg_assert(irq_number >= 0 && irq_number < 8);
irr |= 1 << irq_number;
};
}
this.get_isr = function()
{
return isr;
};
}

303
src/pit.js Normal file
View file

@ -0,0 +1,303 @@
"use strict";
/**
* @constructor
*
* Programmable Interval Timer
*/
function PIT(dev)
{
var
io = dev.io,
pic = dev.pic,
next_tick = Date.now(),
me = this,
/**
* @const
* In kHz
*/
OSCILLATOR_FREQ = 1193.1816666, // 1.193182 MHz
counter_next_low = new Uint8Array(3),
counter_enabled = new Uint8Array(3),
counter_mode = new Uint8Array(3),
counter_read_mode = new Uint8Array(3),
// 2 = latch low, 1 = latch high, 0 = no latch
counter_latch = new Uint8Array(3),
counter_latch_value = new Uint16Array(3),
counter_reload = new Uint16Array(3),
counter_current = new Uint16Array(3),
// only counter2 output can be read
counter2_out = 0;
// TODO:
// - counter2 can be controlled by an input
this.get_timer2 = function()
{
//dbg_log("timer2 read", LOG_PIT);
return counter2_out;
};
var parity = 0;
io.register_read(0x61, function()
{
// > xxx1 xxxx 0=RAM parity error enable
// > PS/2: Read: This bit tiggles for each refresh request.
//
// tiggles??
parity ^= 0x10;
return parity | counter2_out << 5;
});
this.timer = function(time)
{
var current,
mode,
steps = (time - next_tick) * OSCILLATOR_FREQ >>> 0;
if(!steps)
{
return;
}
dbg_assert(steps >= 0);
next_tick += steps / OSCILLATOR_FREQ;
// counter 0 produces interrupts
if(counter_enabled[0])
{
current = counter_current[0] -= steps;
if(current <= 0)
{
pic.push_irq(0);
mode = counter_mode[0];
if(mode === 0)
{
counter_enabled[0] = 0;
counter_current[0] = 0;
}
else if(mode === 3 || mode === 2)
{
counter_current[0] = counter_reload[0] + current % counter_reload[0];
}
}
}
// counter 2 has an output bit
if(counter_enabled[2])
{
current = counter_current[2] -= steps;
if(current <= 0)
{
mode = counter_mode[2];
if(mode === 0)
{
counter2_out = 1;
counter_enabled[2] = 0;
counter_current[2] = 0;
}
else if(mode === 2)
{
counter2_out = 1;
counter_current[2] = counter_reload[2] + current % counter_reload[2];
}
else if(mode === 3)
{
counter2_out ^= 1;
counter_current[2] = counter_reload[2] + current % counter_reload[2];
}
}
// cannot really happen, because the counter gets changed by big numbers
//else if(current === 1)
//{
// if(counter_mode[2] === 2)
// {
// counter2_out = 0;
// }
//}
}
}
io.register_read(0x40, function() { return counter_read(0); });
io.register_read(0x41, function() { return counter_read(1); });
io.register_read(0x42, function() { return counter_read(2); });
function counter_read(i)
{
var latch = counter_latch[i];
if(latch)
{
counter_latch[i]--;
if(latch === 2)
{
return counter_latch_value[i] & 0xFF;
}
else
{
return counter_latch_value[i] >> 8;
}
}
else
{
var next_low = counter_next_low[i];
if(counter_mode[i] === 3)
{
counter_next_low[i] ^= 1;
}
if(next_low)
{
return counter_current[i] & 0xFF;
}
else
{
return counter_current[i] >> 8;
}
}
}
io.register_write(0x40, function(value) { counter_write(0, value); });
io.register_write(0x41, function(value) { counter_write(1, value); });
io.register_write(0x42, function(value) { counter_write(2, value); });
function counter_write(i, value)
{
if(counter_next_low[i])
{
counter_reload[i] = counter_reload[i] & ~0xFF | value;
}
else
{
counter_reload[i] = counter_reload[i] & 0xFF | value << 8;
}
if(counter_read_mode[i] !== 3 || !counter_next_low[i])
{
if(!counter_reload[i])
{
counter_reload[i] = 0xFFFF;
}
// depends on the mode, should actually
// happen on the first tick
counter_current[i] = counter_reload[i];
counter_enabled[i] = true;
dbg_log("counter" + i + " reload=" + h(counter_reload[i]) +
" tick=" + (counter_reload[i] || 0x10000) / OSCILLATOR_FREQ + "ms", LOG_PIT);
}
if(counter_read_mode[i] === 3)
{
counter_next_low[i] ^= 1;
}
}
io.register_write(0x43, port43_write);
function port43_write(reg_byte)
{
var mode = reg_byte >> 1 & 7,
binary_mode = reg_byte & 1,
i = reg_byte >> 6 & 3,
read_mode = reg_byte >> 4 & 3,
next_low;
if(i === 1)
{
dbg_log("Unimplemented timer1", LOG_PIT);
}
if(i === 3)
{
dbg_log("Unimplemented read back", LOG_PIT);
return;
}
if(read_mode === 0)
{
// latch
counter_latch[i] = 2;
counter_latch_value[i] = counter_current[i];
return;
}
if(mode >= 6)
{
// 6 and 7 are aliased to 2 and 3
mode &= ~4;
}
dbg_log("Control: mode=" + mode + " ctr=" + i +
" read_mode=" + read_mode + " bcd=" + binary_mode, LOG_PIT);
if(read_mode === 1)
{
// lsb
counter_next_low[i] = 1;
}
else if(read_mode === 2)
{
// msb
counter_next_low[i] = 0;
}
else
{
// first lsb then msb
counter_next_low[i] = 1;
}
if(mode === 0)
{
}
else if(mode === 3 || mode === 2)
{
// what is the difference
}
else
{
dbg_log("Unimplemented counter mode: " + h(mode), LOG_PIT);
}
counter_mode[i] = mode;
counter_read_mode[i] = read_mode;
if(i === 2)
{
if(mode === 0)
{
counter2_out = 0;
}
else
{
// correct for mode 2 and 3
counter2_out = 1;
}
}
};
}

432
src/ps2.js Normal file
View file

@ -0,0 +1,432 @@
"use strict";
/**
* @constructor
*/
function PS2(dev, keyboard, mouse)
{
var
io = dev.io,
pic = dev.pic,
me = this,
/** @type {boolean} */
enable_mouse_stream = false,
/** @type {boolean} */
enable_mouse = false,
/** @type {boolean} */
have_mouse = false,
/** @type {number} */
mouse_delta_x = 0,
/** @type {number} */
mouse_delta_y = 0,
/** @type {number} */
mouse_clicks = 0,
/** @type {boolean} */
have_keyboard = false,
/** @type {boolean} */
next_is_mouse_command = false,
/** @type {boolean} */
next_read_sample = false,
/** @type {boolean} */
next_read_led = false,
/**
* @type {Array.<number>}
*/
kbd_buffer = [],
/** @type {number} */
sample_rate = 100,
/** @type {number} */
last_mouse_packet = -1,
/**
* @type {Array.<number>}
*/
mouse_buffer = [];
if(keyboard)
{
have_keyboard = true;
keyboard.init(kbd_send_code);
}
if(mouse)
{
have_mouse = true;
mouse.init(mouse_send_click, mouse_send_delta);
// TODO: Mouse Wheel
// http://www.computer-engineering.org/ps2mouse/
}
function mouse_irq()
{
pic.push_irq(12);
}
function kbd_irq()
{
pic.push_irq(1);
}
function kbd_send_code(code)
{
//console.log(h(code));
kbd_buffer.push(code);
kbd_irq();
}
this.kbd_send_code = kbd_send_code;
function mouse_send_delta(delta_x, delta_y)
{
if(have_mouse && enable_mouse)
{
mouse_delta_x += delta_x;
mouse_delta_y += delta_y;
if(enable_mouse_stream)
{
var now = Date.now();
if(now - last_mouse_packet < 1000 / sample_rate)
{
// TODO: set timeout
return;
}
last_mouse_packet = now;
send_mouse_packet();
}
}
}
function mouse_send_click(left, middle, right)
{
if(have_mouse && enable_mouse)
{
mouse_clicks = left | right << 1 | middle << 2;
if(enable_mouse_stream)
{
send_mouse_packet();
}
}
}
function send_mouse_packet()
{
var info_byte =
(mouse_delta_y < 0) << 5 |
(mouse_delta_x < 0) << 4 |
1 << 3 |
mouse_clicks;
mouse_buffer.push(
info_byte,
mouse_delta_x & 0xFF,
mouse_delta_y & 0xFF
);
if(mouse_buffer.length > 15)
{
var off = mouse_buffer.length % 3;
mouse_buffer = mouse_buffer.slice(0, off).concat(mouse_buffer.slice(off + 3));
}
mouse_delta_x = 0;
mouse_delta_y = 0;
mouse_irq();
}
this.destroy = function()
{
if(have_keyboard)
{
keyboard.destroy();
}
if(have_mouse)
{
mouse.destroy();
}
};
var command_register = 0,
read_output_register = false,
read_command_register = false;
io.register_read(0x60, port60_read);
io.register_read(0x64, port64_read);
io.register_write(0x60, port60_write);
io.register_write(0x64, port64_write);
function port60_read()
{
//log("port 60 read: " + (buffer[0] || "(none)"));
if(!kbd_buffer.length && !mouse_buffer.length)
{
// should not happen
dbg_log("Port 60 read: Empty", LOG_PS2);
return 0xFF;
}
var do_mouse_buffer;
if(kbd_buffer.length && mouse_buffer.length)
{
// tough decision, let's ask the PIC
do_mouse_buffer = (pic.get_isr() & 2) === 0;
}
else if(kbd_buffer.length)
{
do_mouse_buffer = false;
}
else
{
do_mouse_buffer = true;
}
if(do_mouse_buffer)
{
dbg_log("Port 60 read (mouse): " + h(mouse_buffer[0]), LOG_PS2);
if(mouse_buffer.length > 1)
{
mouse_irq();
}
return mouse_buffer.shift();
}
else
{
dbg_log("Port 60 read (kbd) : " + h(kbd_buffer[0]), LOG_PS2);
if(kbd_buffer.length > 1)
{
kbd_irq();
}
return kbd_buffer.shift();
}
};
function port64_read()
{
// status port
//dbg_log("port 64 read", LOG_PS2);
var status_byte = 0x10;
if(mouse_buffer.length || kbd_buffer.length)
{
status_byte |= 1;
}
if(mouse_buffer.length)
{
status_byte |= 0x20;
}
return status_byte;
};
function port60_write(write_byte)
{
if(read_command_register)
{
command_register = write_byte;
read_command_register = false;
dbg_log("Keyboard command register = " + h(command_register), LOG_PS2);
}
else if(read_output_register)
{
read_output_register = false;
mouse_buffer = [write_byte];
mouse_irq();
}
else if(next_read_sample)
{
next_read_sample = false;
mouse_buffer = [0xFA];
sample_rate = write_byte;
mouse_irq();
}
else if(next_read_led)
{
// nope
next_read_led = false;
}
else if(next_is_mouse_command)
{
dbg_log("Port 60 data register write: " + h(write_byte), LOG_PS2);
if(!have_mouse)
{
return;
}
// send ack
mouse_buffer = [0xFA];
if(write_byte === 0xFF)
{
// reset, send completion code
mouse_buffer.push(0xAA, 0x00);
enable_mouse = true;
mouse.enabled = true;
}
else if(write_byte === 0xF2)
{
// MouseID Byte
mouse_buffer.push(0, 0);
}
else if(write_byte === 0xF3)
{
// sample rate
next_read_sample = true;
}
else if(write_byte === 0xF4)
{
// enable streaming
enable_mouse_stream = true;
enable_mouse = true;
mouse.enabled = true;
}
else if(write_byte === 0xF5)
{
// disable streaming
enable_mouse_stream = true;
}
else if(write_byte === 0xF6)
{
// reset defaults
enable_mouse_stream = false;
sample_rate = 100;
// ... resolution, scaling
}
else if(write_byte === 0xEB)
{
// request single packet
dbg_log("unimplemented request single packet");
}
else
{
dbg_log("new mouse command: " + h(write_byte), LOG_PS2);
}
mouse_irq();
}
else
{
dbg_log("Port 60 data register write: " + h(write_byte), LOG_PS2);
// send ack
kbd_buffer.push(0xFA);
if(write_byte === 0xFF)
{
kbd_buffer.push(0xAA, 0x00);
}
else if(write_byte === 0xF2)
{
// identify
kbd_buffer.push(0xAB, 83);
}
else if(write_byte === 0xF4)
{
// enable scanning
}
else if(write_byte === 0xF5)
{
// disable scanning
}
else if(write_byte === 0xED)
{
next_read_led = true;
}
kbd_irq();
}
};
function port64_write(write_byte)
{
dbg_log("port 64 write: " + h(write_byte), LOG_PS2);
if(write_byte === 0xFE)
{
dbg_log("CPU reboot via PS2");
dev.reboot();
}
else if(write_byte === 0x20)
{
kbd_buffer.push(command_register);
kbd_irq();
}
else if(write_byte === 0x60)
{
read_command_register = true;
}
else if(write_byte === 0xD3)
{
read_output_register = true;
}
else if(write_byte === 0xD4)
{
next_is_mouse_command = true;
}
else if(write_byte === 0xA9)
{
// test second ps/2 port
kbd_buffer = [0];
kbd_irq();
}
else if(write_byte === 0xAA)
{
kbd_buffer = [0x55];
kbd_irq();
}
else if(write_byte === 0xAB)
{
kbd_buffer = [0];
kbd_irq();
}
/*else if(write_byte === 0xAE)
{
// not sure if right ...
kbd_buffer =[];
}*/
else
{
dbg_log("port 64: New command byte: " + h(write_byte), LOG_PS2);
}
};
}

188
src/rtc.js Normal file
View file

@ -0,0 +1,188 @@
/**
* RTC (real time clock) and CMOS
* @constructor
*/
function RTC(dev, diskette_type)
{
var
io = dev.io,
pic = dev.pic,
cmos_index = 0,
me = this,
// used for cmos entries
rtc_time = Date.now(),
last_update = rtc_time,
// used for periodic interrupt
next_interrupt,
periodic_interrupt = false,
// corresponds to default value for cmos_a
periodic_interrupt_time = 1000 / 1024;
var cmos_a = 0x26,
cmos_b = 2;
this.nmi_disabled = 0;
this.timer = function(time)
{
if(periodic_interrupt)
{
while(next_interrupt < time)
{
next_interrupt += periodic_interrupt_time;
pic.push_irq(8);
}
}
rtc_time += time - last_update;
last_update = time;
};
io.register_write(0x70, function(out_byte)
{
cmos_index = out_byte & 0x7F;
me.nmi_disabled = out_byte >> 7;
});
io.register_write(0x71, cmos_write);
io.register_read(0x71, cmos_read);
function encode_time(t)
{
if(cmos_b & 4)
{
// binary mode
return t;
}
else
{
return Math.bcd_pack(t);
}
}
// TODO
// - interrupt on update
// - countdown
// - letting bios/os set values
// (none of these are used by seabios or the OSes we're
// currently testing)
function cmos_read()
{
var index = cmos_index;
cmos_index = 0xD;
switch(index)
{
case 0:
return encode_time(new Date(rtc_time).getUTCSeconds());
case 2:
return encode_time(new Date(rtc_time).getUTCMinutes());
case 4:
// TODO: 12 hour mode
return encode_time(new Date(rtc_time).getUTCHours());
case 7:
return encode_time(new Date(rtc_time).getUTCDate());
case 8:
return encode_time(new Date(rtc_time).getUTCMonth() + 1);
case 9:
return encode_time(new Date(rtc_time).getUTCFullYear() % 100);
case 0xA:
return cmos_a;
case 0xB:
//dbg_log("cmos read from index " + h(index));
return cmos_b;
case 0xE:
// post info
return 0;
case 0xC:
//dbg_log("cmos read from index " + h(index));
// TODO:
// It is important to know that upon a IRQ 8, Status Register C
// will contain a bitmask telling which interrupt happened.
// What is important is that if register C is not read after an
// IRQ 8, then the interrupt will not happen again.
//dbg_log("cmos Ch read");
return 0;
// Missing IRQF flag
//return cmos_b & 0x70;
case 0xF:
return 0;
case 0x10:
// floppy type
return diskette_type;
case 0x14:
// equipment
return 0x2D;
case 0x32:
return encode_time(new Date(rtc_time).getUTCFullYear() / 100 | 0);
case 0x34:
return (memory_size - 16 * 1024 * 1024) >> 16 & 0xff;
case 0x35:
return (memory_size - 16 * 1024 * 1024) >> 24 & 0xff;
case 0x38:
// used by seabios to determine the boot order
// bootflag 1, high nibble, lowest priority
return 0x30; // hd
case 0x3D:
// bootflag 2, both nibbles, high and middle priority
return 0x21; // floppy first, cd second
case 0x5B:
case 0x5C:
case 0x5D:
// memory above 4GB
return 0;
}
dbg_log("cmos read from index " + h(index), LOG_RTC);
return 0xFF;
}
function cmos_write(data_byte)
{
switch(cmos_index)
{
case 0xA:
cmos_a = data_byte & 0x7F;
periodic_interrupt_time = 1000 / (32768 >> (cmos_a & 0xF) - 1);
dbg_log("Periodic interrupt, a=" + h(cmos_a, 2) + " t=" + periodic_interrupt_time , LOG_RTC);
break;
case 0xB:
cmos_b = data_byte;
if(cmos_b & 0x40)
{
next_interrupt = Date.now();
}
if(cmos_b & 0x20) dbg_log("Unimplemented: alarm interrupt");
if(cmos_b & 0x10) dbg_log("Unimplemented: updated interrupt");
dbg_log("cmos b=" + h(cmos_b, 2), LOG_RTC);
break;
default:
dbg_log("cmos write index " + h(cmos_index) + ": " + h(data_byte), LOG_RTC);
}
periodic_interrupt = (cmos_b & 0x40) === 0x40 && (cmos_a & 0xF) > 0;
}
}

281
src/string.macro.js Normal file
View file

@ -0,0 +1,281 @@
"use strict";
/*
* string operations
*
* cmp si di
* movs 0 1 1 A4
* cmps 1 1 1 A6
* stos 0 0 1 AA
* lods 0 1 0 AC
* scas 1 0 1 AE
* ins 0 0 1
* outs 0 1 0
*/
#define string_instruction(s, use_cmp, use_di, use_si, fn, aligned_fn)\
var src, dest, data_src, data_dest;\
var size = flags & flag_direction ? -(s >> 3) : s >> 3;\
var ds, es;\
if(use_cmp && !use_si) data_src = reg ## s[reg_eax];\
if(use_di) es = get_seg(reg_es), dest = es + regv[reg_vdi];\
if(use_si) ds = get_seg_prefix(reg_ds), src = ds + regv[reg_vsi];\
if(repeat_string_prefix) {\
if(regv[reg_vcx] === 0) return;\
var aligned = s > 8 && (!use_di || (dest & (s >> 3) - 1) === 0) && (!use_si || (src & (s >> 3) - 1) === 0);\
do {\
if(aligned) {\
aligned_fn;\
} else {\
fn;\
}\
if(use_di) dest += size, regv[reg_vdi] += size;\
if(use_si) src += size, regv[reg_vsi] += size;\
} while(--regv[reg_vcx] && (!use_cmp || (data_src === data_dest) === repeat_string_type));\
} else {\
fn;\
if(use_di) regv[reg_vdi] += size;\
if(use_si) regv[reg_vsi] += size;\
}\
if(use_cmp) cmp ## s(data_src, data_dest);\
function movsb()
{
string_instruction(8, false, true, true,
{
safe_write8(dest, safe_read8(src));
}, {});
}
function movsw()
{
string_instruction(16, false, true, true,
{
safe_write16(dest, safe_read16(src));
}, {
var phys_src = translate_address_read(src);
var phys_dest = translate_address_write(dest);
memory.write_aligned16(phys_dest, memory.read_aligned16(phys_src));
});
}
function movsd()
{
string_instruction(32, false, true, true,
{
safe_write32(dest, safe_read32s(src));
}, {
var phys_src = translate_address_read(src);
var phys_dest = translate_address_write(dest);
memory.write_aligned32(phys_dest, memory.read_aligned32(phys_src));
});
}
function cmpsb()
{
string_instruction(8, true, true, true,
{
data_dest = safe_read8(dest);
data_src = safe_read8(src);
}, {});
}
function cmpsw()
{
string_instruction(16, true, true, true,
{
data_dest = safe_read16(dest);
data_src = safe_read16(src);
}, {
data_dest = memory.read_aligned16(translate_address_read(dest));
data_src = memory.read_aligned16(translate_address_read(src));
});
}
function cmpsd()
{
string_instruction(32, true, true, true,
{
data_dest = safe_read32(dest);
data_src = safe_read32(src);
}, {
data_dest = memory.read_aligned32(translate_address_read(dest)) >>> 0;
data_src = memory.read_aligned32(translate_address_read(src)) >>> 0;
});
}
function stosb()
{
var data = reg8[reg_al];
string_instruction(8, false, true, false,
{
safe_write8(dest, data);
}, {});
}
function stosw()
{
var data = reg16[reg_ax];
string_instruction(16, false, true, false,
{
safe_write16(dest, data);
}, {
memory.write_aligned16(translate_address_write(dest), data);
});
}
function stosd()
{
//dbg_log("stosd " + ((reg32[reg_edi] & 3) ? "mis" : "") + "aligned", LOG_CPU);
var data = reg32[reg_eax];
string_instruction(32, false, true, false,
{
safe_write32(dest, data);
}, {
memory.write_aligned32(translate_address_write(dest), data);
});
}
function lodsb()
{
string_instruction(8, false, false, true,
{
reg8[reg_al] = safe_read8(src);
}, {});
}
function lodsw()
{
string_instruction(16, false, false, true,
{
reg16[reg_ax] = safe_read16(src);
}, {
reg16[reg_ax] = safe_read16(src);
});
}
function lodsd()
{
string_instruction(32, false, false, true,
{
reg32[reg_eax] = safe_read32s(src);
}, {
reg32[reg_eax] = safe_read32s(src);
});
}
function scasb()
{
string_instruction(8, true, true, false,
{
data_dest = safe_read8(dest);
}, {});
}
function scasw()
{
string_instruction(16, true, true, false,
{
data_dest = safe_read16(dest);
}, {
data_dest = memory.read_aligned16(translate_address_read(dest));
});
}
function scasd()
{
string_instruction(32, true, true, false,
{
data_dest = safe_read32(dest);
}, {
data_dest = memory.read_aligned32(translate_address_read(dest)) >>> 0;
});
}
function insb()
{
var port = reg16[reg_dx];
string_instruction(8, false, true, false,
{
safe_write8(dest, in8(port));
}, {
});
}
function insw()
{
var port = reg16[reg_dx];
string_instruction(8, false, true, false,
{
safe_write16(dest, in16(port));
}, {
var phys_dest = translate_address_write(dest);
memory.write_aligned16(phys_dest, in16(port));
});
}
function insd()
{
var port = reg16[reg_dx];
string_instruction(32, false, true, false,
{
safe_write32(dest, in32(port));
}, {
var phys_dest = translate_address_write(dest);
memory.write_aligned32(phys_dest, in32(port));
});
}
function outsb()
{
var port = reg16[reg_dx];
string_instruction(8, false, false, true,
{
out8(port, safe_read8(src));
}, {
out8(port, safe_read8(src));
});
}
function outsw()
{
var port = reg16[reg_dx];
string_instruction(16, false, false, true,
{
out16(port, safe_read16(src));
}, {
out16(port, safe_read16(src));
});
}
function outsd()
{
var port = reg16[reg_dx];
string_instruction(32, false, false, true,
{
out32(port, safe_read32s(src));
}, {
out32(port, safe_read32s(src));
});
}

26
src/uart.js Normal file
View file

@ -0,0 +1,26 @@
/**
* No full implementation, just dumping serial output
* to console
*
* @constructor
*/
function UART(dev)
{
var
io = dev.io,
line = "";
io.register_write(0x3F8, function(out_byte)
{
if(out_byte === 0x0A)
{
log(line);
dbg_log(line, LOG_SERIAL);
line = "";
}
else
{
line += String.fromCharCode(out_byte);
}
});
}

8
src/v86_all.js.map Normal file

File diff suppressed because one or more lines are too long

1023
src/vga.js Normal file

File diff suppressed because it is too large Load diff

8
tests/perf/build.sh Executable file
View file

@ -0,0 +1,8 @@
nasm test.asm -o test.bin
echo "var file = [" > test-asm.js
cat test.bin|xxd -i >> test-asm.js
echo "]" >> test-asm.js
echo "done."

59
tests/perf/runtest.js Normal file
View file

@ -0,0 +1,59 @@
// Run with d8, not node
var path = "../../src/";
load(path + "const.js");
load(path + "io.js");
load(path + "cpu.js");
load(path + "main.js");
load(path + "disk.js");
load(path + "pci.js");
load(path + "test_helpers.js");
load(path + "memory.js");
load(path + "dma.js");
load(path + "pit.js");
load(path + "pic.js");
if(typeof console === "undefined")
{
var console = {
log: print,
}
}
var log = print;
DEBUG = false;
var cpu = new v86();
cpu.init({});
// defines file
load("test-asm.js");
for(var i = 0; i < file.length; i++)
{
cpu.memory.mem8[i] = file[i];
}
function run()
{
for(var i = 0; i < count; i++)
{
cpu.cycle();
}
}
var count = 1e7;
var start = Date.now();
run();
var end = Date.now(),
duration = (end - start) / 1e3;
console.log("Finished in " + duration + " seconds, " + (count / duration / 1e6).toFixed(2) + " mips");

12
tests/perf/test-asm.js Normal file
View file

@ -0,0 +1,12 @@
var file = [
0x66, 0xbb, 0x00, 0x00, 0x10, 0x00, 0x66, 0xb8, 0xff, 0xff, 0xff, 0xff,
0xb8, 0xff, 0xff, 0xb0, 0xff, 0x67, 0x8a, 0x03, 0x66, 0x0f, 0xbf, 0xc0,
0x0f, 0xbe, 0xc0, 0x66, 0x0f, 0xb6, 0xc0, 0x66, 0x91, 0x67, 0x86, 0x03,
0x67, 0x87, 0x03, 0x67, 0xfe, 0x03, 0x66, 0x67, 0xff, 0x03, 0x40, 0xfe,
0xc0, 0x67, 0xfe, 0x0b, 0x66, 0x67, 0xff, 0x0b, 0x48, 0xfe, 0xc8, 0x66,
0xf7, 0xe1, 0xf7, 0xe1, 0xf6, 0xe1, 0x66, 0xf7, 0xe9, 0xf7, 0xe9, 0xf6,
0xe9, 0x66, 0x6b, 0xc0, 0x10, 0x66, 0x69, 0xc0, 0x00, 0x00, 0x00, 0x01,
0x6b, 0xc0, 0x10, 0x66, 0x0f, 0xaf, 0xc1, 0x0f, 0xaf, 0xc1, 0x66, 0x50,
0x50, 0x5f, 0x66, 0x5f, 0xfb, 0xfa, 0xfd, 0xfc, 0x60, 0x61, 0x66, 0x60,
0x66, 0x61, 0x9c, 0x9d, 0x66, 0x9c, 0x66, 0x9d, 0xeb, 0x8a
]

199
tests/perf/test.asm Normal file
View file

@ -0,0 +1,199 @@
;[BITS 32]
start:
mov ebx, 100000h
%if 0
add al, [4*ebx+100h]
add eax, ecx
add [4*ebx+1000h], cl
add al, 10h
add eax, 1000h
add cl, 10h
add ecx, 1000h
or al, [4*ebx+100h]
or eax, ecx
or [4*ebx+1000h], cl
or al, 10h
or eax, 1000h
or cl, 10h
or ecx, 1000h
adc al, [4*ebx+100h]
adc eax, ecx
adc [4*ebx+1000h], cl
adc al, 10h
adc eax, 1000h
adc cl, 10h
adc ecx, 1000h
sbb al, [4*ebx+100h]
sbb eax, ecx
sbb [4*ebx+1000h], cl
sbb al, 10h
sbb eax, 1000h
sbb cl, 10h
sbb ecx, 1000h
and al, [4*ebx+100h]
and eax, ecx
and [4*ebx+1000h], cl
and al, 10h
and eax, 1000h
and cl, 10h
and ecx, 1000h
sub al, [4*ebx+100h]
sub eax, ecx
sub [4*ebx+1000h], cl
sub al, 10h
sub eax, 1000h
sub cl, 10h
sub ecx, 1000h
xor al, [4*ebx+100h]
xor eax, ecx
xor [4*ebx+1000h], cl
xor al, 10h
xor eax, 1000h
xor cl, 10h
xor ecx, 1000h
cmp al, [4*ebx+100h]
cmp eax, ecx
cmp [4*ebx+1000h], cl
cmp al, 10h
cmp eax, 1000h
cmp cl, 10h
cmp ecx, 1000h
test al, [4*ebx+100h]
test eax, ecx
test [4*ebx+1000h], cl
test al, 10h
test eax, 1000h
%endif
%if 0
add eax, 12345671h
jo $+2
jno $+2
jp $+2
jnp $+2
jc $+2
jnc $+2
js $+2
jns $+2
jz $+2
jnz $+2
jl $+2
jnl $+2
jbe $+2
jnbe $+2
jle $+2
jnle $+2
%endif
%if 0
sal eax, 12
sal cx, 7
sal dl, 1
sal dh, 0
shl eax, 12
shl cx, 7
shl dl, 1
shl dh, 0
shr eax, 12
shr cx, 7
shr dl, 1
shr dh, 0
ror eax, 12
ror cx, 7
ror dl, 1
ror dh, 0
rol eax, 12
rol cx, 7
rol dl, 1
rol dh, 0
rcr eax, 12
rcr cx, 7
rcr dl, 1
rcr dh, 0
rcl eax, 12
rcl cx, 7
rcl dl, 1
rcl dh, 0
%endif
mov eax, -1
mov ax, -1
mov al, -1
mov al, [ebx]
movsx eax, ax
movsx ax, al
movzx eax, al
xchg eax, ecx
xchg [ebx], al
xchg [ebx], ax
inc byte [ebx]
inc dword [ebx]
inc ax
inc al
dec byte [ebx]
dec dword [ebx]
dec ax
dec al
mul ecx
mul cx
mul cl
imul ecx
imul cx
imul cl
imul eax, 10h
imul eax, 1000000h
imul ax, 10h
imul eax, ecx
imul ax, cx
push eax
push ax
pop di
pop edi
sti
cli
std
cld
pusha
popa
pushad
popad
pushf
popf
pushfd
popfd
jmp start

BIN
tests/perf/test.bin Normal file

Binary file not shown.

16
tests/qemu/LICENSE Normal file
View file

@ -0,0 +1,16 @@
x86 CPU test
Copyright (c) 2003 Fabrice Bellard
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.

17
tests/qemu/Makefile Normal file
View file

@ -0,0 +1,17 @@
CC=gcc
CC_I386=$(CC) -m32
QEMU_INCLUDES += -I../..
CFLAGS=-Wall -O2 -g -fno-strict-aliasing -static
LDFLAGS=
# i386/x86_64 emulation test (test various opcodes) */
test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
test-i386.h test-i386-shift.h test-i386-muldiv.h
$(CC_I386) $(QEMU_INCLUDES) $(CFLAGS) $(LDFLAGS) -o $@ \
$(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm
clean:
rm -f test-i386

8
tests/qemu/Reame Normal file
View file

@ -0,0 +1,8 @@
How to run:
- Build test-i386
- Run test-i386 locally (requires Linux and an x86 machine)
- Put the both on a disk (for instance, a cd image built with buildroot)
- Run test-i386 in the emulator
- Compare the result

58
tests/qemu/compiler.h Normal file
View file

@ -0,0 +1,58 @@
/* public domain */
#ifndef COMPILER_H
#define COMPILER_H
#include "config-host.h"
/*----------------------------------------------------------------------------
| The macro QEMU_GNUC_PREREQ tests for minimum version of the GNU C compiler.
| The code is a copy of SOFTFLOAT_GNUC_PREREQ, see softfloat-macros.h.
*----------------------------------------------------------------------------*/
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
# define QEMU_GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
#else
# define QEMU_GNUC_PREREQ(maj, min) 0
#endif
#define QEMU_NORETURN __attribute__ ((__noreturn__))
#if QEMU_GNUC_PREREQ(3, 4)
#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
#define QEMU_WARN_UNUSED_RESULT
#endif
#if defined(_WIN32)
# define QEMU_PACKED __attribute__((gcc_struct, packed))
#else
# define QEMU_PACKED __attribute__((packed))
#endif
#define cat(x,y) x ## y
#define cat2(x,y) cat(x,y)
#define QEMU_BUILD_BUG_ON(x) \
typedef char cat2(qemu_build_bug_on__,__LINE__)[(x)?-1:1];
#if defined __GNUC__
# if !QEMU_GNUC_PREREQ(4, 4)
/* gcc versions before 4.4.x don't support gnu_printf, so use printf. */
# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2)))
# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m)))
# else
/* Use gnu_printf when supported (qemu uses standard format strings). */
# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2)))
# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
# if defined(_WIN32)
/* Map __printf__ to __gnu_printf__ because we want standard format strings
* even when MinGW or GLib include files use __printf__. */
# define __printf__ __gnu_printf__
# endif
# endif
#else
#define GCC_ATTR /**/
#define GCC_FMT_ATTR(n, m)
#endif
#endif /* COMPILER_H */

66
tests/qemu/config-host.h Normal file
View file

@ -0,0 +1,66 @@
/* Automatically generated by create_config - do not modify */
#define CONFIG_QEMU_CONFDIR "/usr/local/etc/qemu"
#define CONFIG_QEMU_DATADIR "/usr/local/share/qemu"
#define CONFIG_QEMU_DOCDIR "/usr/local/share/doc/qemu"
#define CONFIG_QEMU_LOCALSTATEDIR "/usr/local/var"
#define CONFIG_QEMU_HELPERDIR "/usr/local/libexec"
#define HOST_I386 1
#define CONFIG_POSIX 1
#define CONFIG_LINUX 1
#define CONFIG_SLIRP 1
#define CONFIG_SMBD_COMMAND "/usr/sbin/smbd"
#define CONFIG_AC97 1
#define CONFIG_ES1370 1
#define CONFIG_SB16 1
#define CONFIG_HDA 1
#define CONFIG_AUDIO_DRIVERS \
&oss_audio_driver,\
#define CONFIG_OSS 1
#define CONFIG_BDRV_WHITELIST \
NULL
#define CONFIG_VNC 1
#define CONFIG_VNC_TLS 1
#define CONFIG_VNC_PNG 1
#define CONFIG_FNMATCH 1
#define QEMU_VERSION "1.3.1"
#define QEMU_PKGVERSION ""
#define CONFIG_SDL 1
#define CONFIG_CURSES 1
#define CONFIG_ATFILE 1
#define CONFIG_UTIMENSAT 1
#define CONFIG_PIPE2 1
#define CONFIG_ACCEPT4 1
#define CONFIG_SPLICE 1
#define CONFIG_EVENTFD 1
#define CONFIG_FALLOCATE 1
#define CONFIG_SYNC_FILE_RANGE 1
#define CONFIG_FIEMAP 1
#define CONFIG_DUP3 1
#define CONFIG_EPOLL 1
#define CONFIG_EPOLL_CREATE1 1
#define CONFIG_EPOLL_PWAIT 1
#define CONFIG_INOTIFY 1
#define CONFIG_INOTIFY1 1
#define CONFIG_BYTESWAP_H 1
#define CONFIG_CURL 1
#define CONFIG_ATTR 1
#define CONFIG_IOVEC 1
#define CONFIG_PREADV 1
#define CONFIG_SIGNALFD 1
#define CONFIG_FDATASYNC 1
#define CONFIG_MADVISE 1
#define CONFIG_POSIX_MADVISE 1
#define CONFIG_SIGEV_THREAD_ID 1
#define CONFIG_SMARTCARD 1
#define CONFIG_OPENGL 1
#define CONFIG_UNAME_RELEASE ""
#define CONFIG_ZERO_MALLOC 1
#define CONFIG_UCONTEXT_COROUTINE 1
#define CONFIG_OPEN_BY_HANDLE 1
#define CONFIG_LINUX_MAGIC_H 1
#define CONFIG_PRAGMA_DISABLE_UNUSED_BUT_SET 1
#define CONFIG_HAS_ENVIRON 1
#define CONFIG_TRACE_NOP 1
#define CONFIG_TRACE_FILE trace
#define CONFIG_TRACE_DEFAULT 1

View file

@ -0,0 +1,79 @@
.code16
.globl code16_start
.globl code16_end
CS_SEG = 0xf
code16_start:
.globl code16_func1
/* basic test */
code16_func1 = . - code16_start
mov $1, %eax
data32 lret
/* test push/pop in 16 bit mode */
.globl code16_func2
code16_func2 = . - code16_start
xor %eax, %eax
mov $0x12345678, %ebx
movl %esp, %ecx
push %bx
subl %esp, %ecx
pop %ax
data32 lret
/* test various jmp opcodes */
.globl code16_func3
code16_func3 = . - code16_start
jmp 1f
nop
1:
mov $4, %eax
mov $0x12345678, %ebx
xor %bx, %bx
jz 2f
add $2, %ax
2:
call myfunc
lcall $CS_SEG, $(myfunc2 - code16_start)
ljmp $CS_SEG, $(myjmp1 - code16_start)
myjmp1_next:
cs lcall *myfunc2_addr - code16_start
cs ljmp *myjmp2_addr - code16_start
myjmp2_next:
data32 lret
myfunc2_addr:
.short myfunc2 - code16_start
.short CS_SEG
myjmp2_addr:
.short myjmp2 - code16_start
.short CS_SEG
myjmp1:
add $8, %ax
jmp myjmp1_next
myjmp2:
add $16, %ax
jmp myjmp2_next
myfunc:
add $1, %ax
ret
myfunc2:
add $4, %ax
lret
code16_end:

View file

@ -0,0 +1,76 @@
void glue(glue(test_, OP), b)(long op0, long op1)
{
long res, s1, s0, flags;
s0 = op0;
s1 = op1;
res = s0;
flags = 0;
asm ("push %4\n\t"
"popf\n\t"
stringify(OP)"b %b2\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=a" (res), "=g" (flags)
: "q" (s1), "0" (res), "1" (flags));
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CC=%04lx\n",
stringify(OP) "b", s0, s1, res, flags & CC_MASK);
}
void glue(glue(test_, OP), w)(long op0h, long op0, long op1)
{
long res, s1, flags, resh;
s1 = op1;
resh = op0h;
res = op0;
flags = 0;
asm ("push %5\n\t"
"popf\n\t"
stringify(OP) "w %w3\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=a" (res), "=g" (flags), "=d" (resh)
: "q" (s1), "0" (res), "1" (flags), "2" (resh));
printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK);
}
void glue(glue(test_, OP), l)(long op0h, long op0, long op1)
{
long res, s1, flags, resh;
s1 = op1;
resh = op0h;
res = op0;
flags = 0;
asm ("push %5\n\t"
"popf\n\t"
stringify(OP) "l %k3\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=a" (res), "=g" (flags), "=d" (resh)
: "q" (s1), "0" (res), "1" (flags), "2" (resh));
printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK);
}
#if defined(__x86_64__)
void glue(glue(test_, OP), q)(long op0h, long op0, long op1)
{
long res, s1, flags, resh;
s1 = op1;
resh = op0h;
res = op0;
flags = 0;
asm ("push %5\n\t"
"popf\n\t"
stringify(OP) "q %3\n\t"
"pushf\n\t"
"pop %1\n\t"
: "=a" (res), "=g" (flags), "=d" (resh)
: "q" (s1), "0" (res), "1" (flags), "2" (resh));
printf("%-10s AH=" FMTLX " AL=" FMTLX " B=" FMTLX " RH=" FMTLX " RL=" FMTLX " CC=%04lx\n",
stringify(OP) "q", op0h, op0, s1, resh, res, flags & CC_MASK);
}
#endif
#undef OP

View file

@ -0,0 +1,185 @@
#define exec_op glue(exec_, OP)
#define exec_opq glue(glue(exec_, OP), q)
#define exec_opl glue(glue(exec_, OP), l)
#define exec_opw glue(glue(exec_, OP), w)
#define exec_opb glue(glue(exec_, OP), b)
#ifndef OP_SHIFTD
#ifdef OP_NOBYTE
#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
asm ("push %4\n\t"\
"popf\n\t"\
stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \
"pushf\n\t"\
"pop %1\n\t"\
: "=g" (res), "=g" (flags)\
: "r" (s1), "0" (res), "1" (flags));
#else
#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
asm ("push %4\n\t"\
"popf\n\t"\
stringify(OP) size " %%cl, %" rsize "0\n\t" \
"pushf\n\t"\
"pop %1\n\t"\
: "=q" (res), "=g" (flags)\
: "c" (s1), "0" (res), "1" (flags));
#endif
#if defined(__x86_64__)
void exec_opq(long s2, long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECSHIFT("q", "", res, s1, s2, flags);
/* overflow is undefined if count != 1 */
if (s1 != 1)
flags &= ~CC_O;
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK);
}
#endif
void exec_opl(long s2, long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECSHIFT("l", "k", res, s1, s2, flags);
/* overflow is undefined if count != 1 */
if (s1 != 1)
flags &= ~CC_O;
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
}
void exec_opw(long s2, long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECSHIFT("w", "w", res, s1, s2, flags);
/* overflow is undefined if count != 1 */
if (s1 != 1)
flags &= ~CC_O;
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
}
#else
#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
asm ("push %4\n\t"\
"popf\n\t"\
stringify(OP) size " %%cl, %" rsize "5, %" rsize "0\n\t" \
"pushf\n\t"\
"pop %1\n\t"\
: "=g" (res), "=g" (flags)\
: "c" (s1), "0" (res), "1" (flags), "r" (s2));
#if defined(__x86_64__)
void exec_opq(long s2, long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECSHIFT("q", "", res, s1, s2, flags);
/* overflow is undefined if count != 1 */
if (s1 != 1)
flags &= ~CC_O;
printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
stringify(OP) "q", s0, s2, s1, res, iflags, flags & CC_MASK);
}
#endif
void exec_opl(long s2, long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECSHIFT("l", "k", res, s1, s2, flags);
/* overflow is undefined if count != 1 */
if (s1 != 1)
flags &= ~CC_O;
printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
}
void exec_opw(long s2, long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECSHIFT("w", "w", res, s1, s2, flags);
/* overflow is undefined if count != 1 */
if (s1 != 1)
flags &= ~CC_O;
printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
}
#endif
#ifndef OP_NOBYTE
void exec_opb(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECSHIFT("b", "b", res, s1, 0, flags);
/* overflow is undefined if count != 1 */
if (s1 != 1)
flags &= ~CC_O;
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
}
#endif
void exec_op(long s2, long s0, long s1)
{
s2 = i2l(s2);
s0 = i2l(s0);
#if defined(__x86_64__)
exec_opq(s2, s0, s1, 0);
#endif
exec_opl(s2, s0, s1, 0);
#ifdef OP_SHIFTD
exec_opw(s2, s0, s1, 0);
#else
exec_opw(s2, s0, s1, 0);
#endif
#ifndef OP_NOBYTE
exec_opb(s0, s1, 0);
#endif
#ifdef OP_CC
#if defined(__x86_64__)
exec_opq(s2, s0, s1, CC_C);
#endif
exec_opl(s2, s0, s1, CC_C);
exec_opw(s2, s0, s1, CC_C);
exec_opb(s0, s1, CC_C);
#endif
}
void glue(test_, OP)(void)
{
int i, n;
#if defined(__x86_64__)
n = 64;
#else
n = 32;
#endif
for(i = 0; i < n; i++)
exec_op(0x21ad3d34, 0x12345678, i);
for(i = 0; i < n; i++)
exec_op(0x813f3421, 0x82345679, i);
}
void *glue(_test_, OP) __init_call = glue(test_, OP);
#undef OP
#undef OP_CC
#undef OP_SHIFTD
#undef OP_NOBYTE
#undef EXECSHIFT

103
tests/qemu/test-i386-vm86.S Normal file
View file

@ -0,0 +1,103 @@
.code16
.globl vm86_code_start
.globl vm86_code_end
#define GET_OFFSET(x) ((x) - vm86_code_start + 0x100)
vm86_code_start:
movw $GET_OFFSET(hello_world), %dx
movb $0x09, %ah
int $0x21
/* prepare int 0x90 vector */
xorw %ax, %ax
movw %ax, %es
es movw $GET_OFFSET(int90_test), 0x90 * 4
es movw %cs, 0x90 * 4 + 2
/* launch int 0x90 */
int $0x90
/* test IF support */
movw $GET_OFFSET(IF_msg), %dx
movb $0x09, %ah
int $0x21
pushf
popw %dx
movb $0xff, %ah
int $0x21
cli
pushf
popw %dx
movb $0xff, %ah
int $0x21
sti
pushfl
popl %edx
movb $0xff, %ah
int $0x21
#if 0
movw $GET_OFFSET(IF_msg1), %dx
movb $0x09, %ah
int $0x21
pushf
movw %sp, %bx
andw $~0x200, (%bx)
popf
#else
cli
#endif
pushf
popw %dx
movb $0xff, %ah
int $0x21
pushfl
movw %sp, %bx
orw $0x200, (%bx)
popfl
pushfl
popl %edx
movb $0xff, %ah
int $0x21
movb $0x00, %ah
int $0x21
int90_test:
pushf
pop %dx
movb $0xff, %ah
int $0x21
movw %sp, %bx
movw 4(%bx), %dx
movb $0xff, %ah
int $0x21
movw $GET_OFFSET(int90_msg), %dx
movb $0x09, %ah
int $0x21
iret
int90_msg:
.string "INT90 started\n$"
hello_world:
.string "Hello VM86 world\n$"
IF_msg:
.string "VM86 IF test\n$"
IF_msg1:
.string "If you see a diff here, your Linux kernel is buggy, please update to 2.4.20 kernel\n$"
vm86_code_end:

2774
tests/qemu/test-i386.c Normal file

File diff suppressed because it is too large Load diff

152
tests/qemu/test-i386.h Normal file
View file

@ -0,0 +1,152 @@
#define exec_op glue(exec_, OP)
#define exec_opq glue(glue(exec_, OP), q)
#define exec_opl glue(glue(exec_, OP), l)
#define exec_opw glue(glue(exec_, OP), w)
#define exec_opb glue(glue(exec_, OP), b)
#define EXECOP2(size, rsize, res, s1, flags) \
asm ("push %4\n\t"\
"popf\n\t"\
stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \
"pushf\n\t"\
"pop %1\n\t"\
: "=q" (res), "=g" (flags)\
: "q" (s1), "0" (res), "1" (flags)); \
printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", \
stringify(OP) size, s0, s1, res, iflags, flags & CC_MASK);
#define EXECOP1(size, rsize, res, flags) \
asm ("push %3\n\t"\
"popf\n\t"\
stringify(OP) size " %" rsize "0\n\t" \
"pushf\n\t"\
"pop %1\n\t"\
: "=q" (res), "=g" (flags)\
: "0" (res), "1" (flags)); \
printf("%-10s A=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", \
stringify(OP) size, s0, res, iflags, flags & CC_MASK);
#ifdef OP1
#if defined(__x86_64__)
void exec_opq(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECOP1("q", "", res, flags);
}
#endif
void exec_opl(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECOP1("l", "k", res, flags);
}
void exec_opw(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECOP1("w", "w", res, flags);
}
void exec_opb(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECOP1("b", "b", res, flags);
}
#else
#if defined(__x86_64__)
void exec_opq(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECOP2("q", "", res, s1, flags);
}
#endif
void exec_opl(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECOP2("l", "k", res, s1, flags);
}
void exec_opw(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECOP2("w", "w", res, s1, flags);
}
void exec_opb(long s0, long s1, long iflags)
{
long res, flags;
res = s0;
flags = iflags;
EXECOP2("b", "b", res, s1, flags);
}
#endif
void exec_op(long s0, long s1)
{
s0 = i2l(s0);
s1 = i2l(s1);
#if defined(__x86_64__)
exec_opq(s0, s1, 0);
#endif
exec_opl(s0, s1, 0);
exec_opw(s0, s1, 0);
exec_opb(s0, s1, 0);
#ifdef OP_CC
#if defined(__x86_64__)
exec_opq(s0, s1, CC_C);
#endif
exec_opl(s0, s1, CC_C);
exec_opw(s0, s1, CC_C);
exec_opb(s0, s1, CC_C);
#endif
}
void glue(test_, OP)(void)
{
exec_op(0x12345678, 0x812FADA);
exec_op(0x12341, 0x12341);
exec_op(0x12341, -0x12341);
exec_op(0xffffffff, 0);
exec_op(0xffffffff, -1);
exec_op(0xffffffff, 1);
exec_op(0xffffffff, 2);
exec_op(0x7fffffff, 0);
exec_op(0x7fffffff, 1);
exec_op(0x7fffffff, -1);
exec_op(0x80000000, -1);
exec_op(0x80000000, 1);
exec_op(0x80000000, -2);
exec_op(0x12347fff, 0);
exec_op(0x12347fff, 1);
exec_op(0x12347fff, -1);
exec_op(0x12348000, -1);
exec_op(0x12348000, 1);
exec_op(0x12348000, -2);
exec_op(0x12347f7f, 0);
exec_op(0x12347f7f, 1);
exec_op(0x12347f7f, -1);
exec_op(0x12348080, -1);
exec_op(0x12348080, 1);
exec_op(0x12348080, -2);
}
void *glue(_test_, OP) __init_call = glue(test_, OP);
#undef OP
#undef OP_CC

60
v86.css Normal file
View file

@ -0,0 +1,60 @@
#log {
font-family: DejaVu Sans Mono;
font-size: 13px;
height: 350px;
float: right;
width: 400px;
border: 0 none;
background-color: #111;
color: #fff;
}
#screen {
white-space: pre;
position: relative;
font-family: Liberation Mono, DejaVu Sans Mono, Courier New, monospace;
font-weight: bold;
font-size: 15px;
line-height: 1;
float: left;
}
#screen, #vga {
border: 1px solid #555;
border-width: 2px 1px;
display: none;
-webkit-transform-origin: top left;
-moz-transform-origin: top left;
}
#vga {
image-rendering: -moz-crisp-edges; // FF 6.0+
image-rendering: -webkit-optimize-contrast; // Webkit
// (Safari now, Chrome soon)
image-rendering: -o-crisp-edges; // OS X & Windows Opera (12.02+)
image-rendering: optimize-contrast; // Possible future browsers.
-ms-interpolation-mode: nearest-neighbor; // IE
}
#screen > div > span {
height: 15px;
}
#cursor {
position: absolute;
background-color: #ccc;
width: 7px;
display: inline-block;
}
body {
background-color: #111;
color: #fff;
line-height: 1.5;
}
#info {
font-size: 80%;
}
a {
color: wheat;
}
.phone_keyboard {
background-color: #111;
border: 1px solid #555;
width: 100px;
height: 100px;
}

247
v86_all.js Normal file
View file

@ -0,0 +1,247 @@
'use strict';var ea,oa;function Tb(f){f.origin===dc&&mc()}var mc,dc=location.protocol+"//"+location.hostname;oa=function(f){mc=f;window.removeEventListener("message",Tb,!1);window.addEventListener("message",Tb,!1)};ea=function(){window.postMessage(null,dc)};function nc(f){var t=document.getElementById("log");t.textContent+=f+"\n";t.scrollTop=1E9}
function Lc(f,t,D){var C=new XMLHttpRequest;C.open("get",f,!0);C.responseType="arraybuffer";C.onload=function(){C.response&&t(C.response)};D&&(C.onprogress=function(f){D(f)});C.send(null)}function Mc(f){var t=f.requestPointerLock||f.mozRequestPointerLock||f.webkitRequestPointerLock;t&&t.call(f)}
function Wc(f){var t=vd("loading");t.style.display="block";f.lengthComputable?(f=f.loaded/f.total*50|0,t.textContent="Loading: "+2*f+"% ["+String.a("#",f)+String.a(" ",50-f)+"]"):t.textContent="Loading ..."}function vd(f){return document.getElementById(f)}
function Hd(f){var t=new Vd,D=new Wd;vd("boot_options").parentNode.removeChild(vd("boot_options"));vd("loading").style.display="none";vd("runtime_options").style.display="block";document.getElementsByClassName("phone_keyboard")[0].style.display="block";var C=!0;vd("run").onclick=function(){C?(B+=Date.now()-X,vd("run").value="Run",t.v()):(vd("run").value="Pause",t.m(),X=Date.now());C=!C;vd("run").blur()};var O=document.getElementById("running_time"),L=document.getElementById("speed"),X=Date.now(),
B=0,G=0;setInterval(function(){if(C){var f=Date.now();B+=f-X;X=f;L.textContent=(t.i-G)/1E3|0;O.textContent=B/1E3|0;G=t.i}},1E3);vd("reset").onclick=function(){t.q();vd("reset").blur()};vd("get_floppy").onclick=function(){var f=t.a.Aa.buffer;f&&(f.Ba(function(f){f=new Blob([f]);var t;t=document.createElement("a");t.download="floppy.img";t.href=window.URL.createObjectURL(f);t.textContent="Download floppy.img";t.onclick=function(){t.parentNode.removeChild(t)};t.dataset.downloadurl=["application/octet-stream",
t.download,t.href].join(":");document.body.appendChild(t)}),vd("get_floppy").blur())};vd("ctrlaltdel").onclick=function(){var f=t.a.Pa;f.G(29);f.G(56);f.G(83);f.G(157);f.G(184);f.G(211);vd("ctrlaltdel").blur()};vd("scale").onchange=function(){var f=parseFloat(this.value);f||0<f?D.a(f,f):this.value="1"};vd("fullscreen").onclick=function(){var f=document.getElementById("screen_container"),t=f.requestFullScreen||f.webkitRequestFullscreen||f.mozRequestFullScreen||f.msRequestFullScreen;t&&(t.call(f),document.getElementsByClassName("phone_keyboard")[0].focus());
Mc(f)};f.Ua=D;f.Ha=new Xd;f.La=new Yd;t.w(f);t.m()}
window.onload=function(){function f(f,C){if(f.files.length){var O=new FileReader;O.onload=function(f){f=new Zd(f.target.result);switch(C){case "floppy":t.K=f;break;case "hd":t.ja=f;break;case "cdrom":t.X=f}Hd(t)};O.readAsArrayBuffer(f.files[0])}}if("responseType"in new XMLHttpRequest){var t={Ja:!0};vd("lock_mouse").onclick=function(){Mc(document.body);vd("lock_mouse").blur()};Lc("bios/seabios.bin",function(f){t.P=f});Lc("bios/vgabios.bin",function(f){t.ea=f});vd("floppy_image").onchange=function(){f(this,
"floppy")};vd("cd_image").onchange=function(){f(this,"cdrom")};vd("hd_image").onchange=function(){f(this,"hd")};vd("start_freedos").onclick=function(){Lc("images/freedos722.img",function(f){t.K=new Zd(f);Hd(t)},Wc);vd("start_freedos").blur()};vd("start_win101").onclick=function(){Lc("images/windows101.img",function(f){t.K=new Zd(f);Hd(t)},Wc);vd("start_win101").blur()};vd("start_linux").onclick=function(){Lc("images/linux.iso",function(f){t.X=new Zd(f);Hd(t)},Wc);vd("start_linux").blur()};vd("start_koli").onclick=
function(){Lc("images/kolibri.img",function(f){t.K=new Zd(f);Hd(t)},Wc);vd("start_koli").blur()};vd("start_bsd").onclick=function(){Lc("images/openbsd.img",function(f){t.K=new Zd(f);Hd(t)},Wc);vd("start_bsd").blur()}}else nc("Your browser is not supported because it doesn't have XMLHttpRequest.responseType")};if("complete"===document.readyState)window.onload();function $d(){function f(){return 255}function t(){}for(var D=0,C=[],O=[],L=0;65536>L;L++)C[L]=f,O[L]=t;this.h=function(f,t){C[f]=t};this.g=function(f,t){O[f]=t};this.h(146,function(){return D});this.g(146,function(f){D=f});this.g(128,function(){});this.i=function(f,t){O[f](t)};this.a=function(f){return C[f]()}};function Vd(){function f(){if(oc)oc=ec=!1;else{ec=!0;try{C()}catch(b){if(233495534===b)wa=Nc=!1,ab=-1,Cb=Db,zb(),xa=Db,La(),f();else throw b;}}}function t(){wd.n();Xc.n();D(xd);throw 233495534;}function D(b){"undefined"!==typeof oa&&oa(f);xd=b;bb.memory=k=new be;Yc=new Uint8Array(8);yd=new Uint32Array(8);ae=new Uint32Array(8);da=new Int32Array(8);zd=new Int32Array(1048576);Ad=new Int32Array(1048576);Bd=new Int32Array(1048576);Cd=new Int32Array(1048576);Eb=new Uint8Array(1048576);pc=new Uint8Array(1048576);
y=new Uint32Array(8);e=new Int32Array(y.buffer);g=new Uint16Array(y.buffer);Ga=new Int16Array(y.buffer);v=new Uint8Array(y.buffer);fc=new Int8Array(y.buffer);ra=new Uint16Array(8);Ma=!1;Dd=Ed=Zc=$c=qc=ad=rc=bd=0;Nc=!1;ya=Oc=cd=Ub=Na=0;J=!1;Fd=0;Cb=dd=xa=Db=!1;L();La();zb();$=g;aa=8;sc=10;Vb=ed=0;oc=ec=fd=!1;Pc=20;q=Ea=Qc;ab=-1;wa=!1;I=0;u=2;Y=ma=ba=K=0;if(b.P){for(var c=new Uint8Array(b.P),d=1048576-b.P.byteLength,h=0;h<b.P.byteLength;h++)k.m[d+h]=c[h];if(b.ea)for(c=new Uint8Array(b.ea),h=0;h<b.ea.byteLength;h++)k.m[786432+
h]=c[h];E=1048560;ca(2,48);g[8]=256}else b.H?(E=65536,k.J(new Uint8Array(b.H.kb),1048576),k.J(new Uint8Array(b.H.ib),E),b.H.root&&(k.J(new Uint8Array(b.H.root),4194304),y[3]=b.H.root.byteLength),k.aa(b.H.ab),y[0]=67108864,y[1]=63488,ca(1,0),ca(2,0),ca(3,0),ca(0,0),ca(5,0),ca(4,0),Ma=dd=xa=Cb=Db=!0,La(),zb(),A=y,aa=4,sc=5,Na=1):(ca(2,48),g[8]=256,E=0);bb.a={};b.Ja&&(c={memory:k,Ta:t},c.j=bb.a.j=Ua=new $d,c.s=Gd=new de(c,ha,Da),c.M=new pe(c),c.xa=new qe(c),bb.a.jb=Xc=new re(c,b.Ua),bb.a.Pa=wd=new se(c,
b.Ha,b.La),Ha=new Ce,new te(c),bb.a.Aa=ce=new ue(c,b.K),b.X&&(bb.a.$a=new ve(c,b.X)),b.ja&&(bb.a.gb=new we(c,b.ja,0)),b.Da&&(bb.a.hb=new we(c,b.Da,1)),ee=new xe(c),fe=new ye(c,ce.type))}function C(){var b,c=Date.now();Xc.i();for(var d=Pc;d--;){for(b=20001;b--;){Vb=E;var e=m();Ab[e]();ed++}b=Date.now();ee.a(b);fe.a(b)}bb.i+=20001*Pc;33<b-c?Pc--:Pc++;ea()}function O(){var b=0!==(Na&2147483648);Na=Ha.a?Na&-5:Na|4;b!==J&&(J=b,L())}function L(){var b=J?He:Ie;m=b.na;P=b.oa;U=b.la;M=b.ma;ka=b.ta;Rc=b.ua;
Q=b.ra;S=b.sa;Va=b.ha;Id=b.ia;X()}function X(){Fb=-1;J?ya?(q=Wb,Ea=gd):(q=Ia,Ea=hb):Ea=q=Qc}function B(b,c){return k.d(b)|k.d(c)<<8}function G(b,c){var d=k.d(b)|k.d(c)<<24;return d=b&1?b&2?d|k.d(c-2)<<8|k.d(c-1)<<16:d|k.d(b+1)<<8|k.d(b+2)<<16:d|k.d(b+1)<<8|k.d(c-1)<<16}function n(b,c,d){k.e(b,d);k.e(c,d>>8)}function H(b,c,d){k.e(b,d);k.e(c,d>>24);b&1?b&2?(k.e(c-2,d>>8),k.e(c-1,d>>16)):(k.e(b+1,d>>8),k.e(b+2,d>>16)):(k.e(b+1,d>>8),k.e(c-1,d>>16))}function V(b,c){k.e(q(b),c)}function R(b,c){var d=q(b);
4095===(b&4095)?n(d,q(b+1),c):k.a(d,c)}function N(b,c){var d=q(b);4093<=(b&4095)?H(d,q(b+3),c):k.f(d,c)}function F(){return Cb?h(3)+M():h(3)+U()}function na(){u=u&-2262|Ba()|ge()|Sc()|Gb()|hd()|Tc();K=0}function sa(b){return dd?da[2]+$[aa]+b:da[2]+($[aa]+b&65535)}function pa(){return E-da[1]}function ha(b,c,d){fd&&(E++,fd=!1);if(Ma){if((b<<3|7)>bd)throw ze("#GP handler");var g=rc+(b<<3)|0;J&&(g=hb(g));var h=k.b(g)|k.b(g+6)<<16,l=k.b(g+2),g=k.d(g+5),m=g>>5&3;if(0===(g&128))throw ze("#NP handler");
c&&m<ya&&fa(b<<3|2);g&=31;if(14===g)b=!1;else if(15===g)b=!0;else{if(5===g)throw ze("call int to task gate");if(6===g)throw ze("16 bit interrupt gate");if(7===g)throw ze("16 bit trap gate");throw ze("#GP handler");}c=Bb(l);if(c.A)throw ze("#GP handler");if(-1===c)throw ze("#GP handler");if(!c.F||c.l>ya)throw ze("#GP handler");if(!c.B)throw ze("#NP handler");if(u&131072)throw ze("VM flag");if(!c.C&&c.l<ya){m=(c.l<<3)+4;if(m+5>Ed)throw ze("#TS handler");m+=Dd;J&&(m=hb(m));var g=k.c(m),m=k.b(m+4),q=
Bb(m);if(q.A)throw ze("#TS handler");if(q.t!==c.l)throw ze("#TS handler");if(q.l!==c.l||!q.ca)throw ze("#TS handler");if(!q.B)throw ze("#TS handler");var q=e[4],p=ra[2];y[4]=g;ra[2]=m;ya=c.l;X();ia(p);ia(q)}na();ia(u);ia(ra[1]);ia(pa());!1!==d&&ia(d);ra[1]=l;E=da[1]+h|0;b?Da():u&=-513}else na(),la(u),la(ra[1]),la(pa()),u&=-513,ca(1,k.b((b<<2)+2)),E=da[1]+k.b(b<<2)|0}function za(b){ha(b,!1,!1);throw 233495534;}function qa(){E=Vb;za(0)}function z(){E=Vb;za(6)}function fa(b){E=Vb;ha(13,!1,b);throw 233495534;
}function ja(b){ab=b;Ab[m()]();ab=-1}function h(b){return-1===ab?da[b]:da[ab]}function Ca(b,c){K&=-65;if((b&3)<(g[c]&3))return u|=64,b&-4|g[c]&3;u&=-65;return b}function Da(){Gd&&u&512&&!Nc&&Gd.a()}function Fa(b,c){$a()?Ua.i(b,c):fa(0)}function Xb(b,c){$a()?(Ua.i(b,c&255),Ua.i(b+1,c>>8&255)):fa(0)}function gc(b,c){$a()?(Ua.i(b,c&255),Ua.i(b+1,c>>8&255),Ua.i(b+2,c>>16&255),Ua.i(b+3,c>>24&255)):fa(0)}function hc(b){if($a())return Ua.a(b);fa(0)}function ic(b){if($a())return Ua.a(b)|Ua.a(b+1)<<8;fa(0)}
function cb(b){if($a())return Ua.a(b)|Ua.a(b+1)<<8|Ua.a(b+2)<<16|Ua.a(b+3)<<24;fa(0)}function $a(){return!Ma||ya<=(u>>12&3)}function jc(b){u=0!==ya&&Ma?ya<=(u>>12&3)?b&-12289|u&12288:b&-12801|u&12800:b;K=0}function La(){xa?(Ab=s,Jd=w):(Ab=r,Jd=x)}function zb(){Cb?(l=he,A=y,ga=1,W=6,T=7):(l=ie,A=g,ga=2,W=12,T=14)}function Bb(b){var c=0===(b&4),d=b&-8,e;b={t:b&3,ga:c,A:!1,$:!0};c?(c=qc,e=ad):(c=Zc,e=$c);if(0===d)return b.A=!0,b;if(d>>3>e)return b.$=!1,b;c+=d;J&&(c=hb(c));b.W=k.b(c+2)|k.d(c+4)<<16|k.d(c+
7)<<24;b.u=k.d(c+5);b.fa=k.d(c+6)>>4;b.V=k.b(c)|(k.d(c+6)&15)<<16;b.type=b.u&15;b.l=b.u>>5&3;b.L=0===(b.u&16);b.B=128===(b.u&128);b.F=8===(b.u&8);b.ca=2===(b.u&2);b.C=4===(b.u&4);b.size=4===(b.fa&4);b.fb=8===(b.fa&8);b.Sa=b.eb?(b.V<<12|4095)>>>0:b.V;b.Fa=b.ca&&!b.F;b.Ea=b.ca||!b.F;return b}function ca(b,c){1===b&&(Ma=1===(Na&1));if(Ma){var d=Bb(c);if(2===b){if(d.A){fa(0);return}if(!d.$||d.L||d.t!==ya||!d.Fa||d.l!==ya){fa(c&-4);return}if(!d.B)throw E=Vb,ha(12,!1,c&-4),233495534;(dd=d.size)?($=e,aa=
4,sc=5):($=g,aa=8,sc=10)}else if(1===b){if(!d.F)throw ze("#GP handler");if(d.L)throw ze("load system segment descriptor, type = "+(d.u&15));if(d.C&&d.l!==d.t)throw ze("#GP handler");if(d.t!==ya)throw ze("privilege change");if(!d.C&&d.l<ya)throw ze("inter privilege interrupt");if(!d.C&&d.l!==ya)throw ze("#GP handler");xa=Cb=Db=d.size;La();zb()}else{if(d.A){ra[b]=c;Yc[b]=1;return}if(!d.$||d.L||!d.Ea||(!d.F||!d.C)&&d.t>d.l&&ya>d.l){fa(c&-4);return}if(!d.B)throw E=Vb,ha(11,!1,c&-4),233495534;}Yc[b]=0;
yd[b]=d.Sa;ae[b]=0;da[b]=d.W;ra[b]=c}else ra[b]=c,Yc[b]=0,yd[b]=1048575,da[b]=c<<4}function tc(){Fb=-1;Eb.set(pc)}function Qc(b){return b}function Wb(b){var c=b>>>12;return Eb[c]&8?Ad[c]^b:db(b,1,1)|b&4095}function gd(b){var c=b>>>12;return Eb[c]&4?zd[c]^b:db(b,0,1)|b&4095}function Ia(b){var c=b>>>12;return Eb[c]&2?Cd[c]^b:db(b,1,0)|b&4095}function hb(b){var c=b>>>12;return Eb[c]&1?Bd[c]^b:db(b,0,0)|b&4095}function db(b,c,d){var e=b>>>12,g=(cd>>>2)+(e>>10),h=k.i[g],l=!0,m=!0,q=!0;h&1||(Ub=b,ib(c,
d,0));0===(h&2)&&(l=!1,c&&(Ub=b,ib(c,d,1)));0===(h&4)&&(q=!1,d&&(Ub=b,ib(c,d,1)));0===(h&16)&&(m=!1);if(h&Fd)k.i[g]=h|32|c<<6,b=h&4290772992|e<<12&4190208,h=h&256;else{var u=((h&4294963200)>>>2)+(e&1023),p=k.i[u];p&1||(Ub=b,ib(c,d,0));0===(p&2)&&(l=!1,c&&(Ub=b,ib(c,d,1)));0===(p&4)&&(q=!1,d&&(Ub=b,ib(c,d,1)));0===(p&16)&&(m=!1);k.i[g]=h|32;k.i[u]=p|32|c<<6;b=p&4294963200;h=p&256}m&&(m=b^e<<12,p=0,q&&(zd[e]=m,p|=4,l&&(Ad[e]=m,p|=8)),Bd[e]=m,p|=1,l&&(Cd[e]=m,p|=2),Eb[e]|=p,h&&(pc[e]=p));return b}function ib(b,
c,d){if(Nc)throw ze("Double fault");E=Vb;Nc=!0;ha(14,!1,c<<2|b<<1|d);throw 233495534;}function Z(b,c){var d=b&65535,e=c&65535;return d*e+d*(c&-65536)+(b&-65536)*e}function kc(b,c){ba=b;ma=c;I=ba+c|0;Y=8;K=2261;return I}function eb(b,c){ba=b;ma=c;I=ba+c|0;Y=16;K=2261;return I}function fb(b,c){ba=b;ma=c;I=ba+c;Y=32;K=2261;return I}function uc(b,c){ba=b;ma=c;I=ba+ma+Ba()|0;Y=8;K=2261;return I}function jb(b,c){ba=b;ma=c;I=ba+ma+Ba()|0;Y=16;K=2261;return I}function kb(b,c){ba=b;ma=c;I=ba+ma+Ba();Y=32;
K=2261;return I}function lc(b,c){ba=b;ma=~c;I=ba-c;Y=8;K=2261}function Yb(b,c){ba=b;ma=~c;I=ba-c;Y=16;K=2261}function Zb(b,c){ba=b;ma=-c-1;I=ba-c;Y=32;K=2261}function vc(b,c){ba=b;ma=~c;I=ba-c|0;Y=8;K=2261;return I}function lb(b,c){ba=b;ma=~c;I=ba-c|0;Y=16;K=2261;return I}function mb(b,c){ba=b;ma=-c-1;I=ba-c;Y=32;K=2261;return I}function wc(b,c){ba=b;ma=~c;I=ba-c-Ba()|0;Y=8;K=2261;return I}function nb(b,c){ba=b;ma=~c;I=ba-c-Ba()|0;Y=16;K=2261;return I}function ob(b,c){ba=b;ma=-c-1;I=ba-c-Ba();Y=32;
K=2261;return I}function je(b){u=u&-2|Ba();ba=b;ma=1;I=ba+1|0;Y=8;K=2260;return I}function pb(b){u=u&-2|Ba();ba=b;ma=1;I=ba+1|0;Y=16;K=2260;return I}function qb(b){u=u&-2|Ba();ba=b;ma=1;I=ba+1;Y=32;K=2260;return I}function ke(b){u=u&-2|Ba();ba=b;ma=-1;I=ba-1|0;Y=8;K=2260;return I}function rb(b){u=u&-2|Ba();ba=b;ma=-1;I=ba-1|0;Y=16;K=2260;return I}function sb(b){u=u&-2|Ba();ba=b;ma=-1;I=ba-1;Y=32;K=2260;return I}function le(b){I=-b;K=2261;Y=8;ba=0;ma=I-1;return I}function Kd(b){I=-b;K=2261;Y=16;ba=
0;ma=I-1;return I}function Ld(b){I=-b;K=2261;Y=32;ba=0;ma=I-1;return I}function Md(b,c){var d=b*c;u=32767<d||-32768>d?u|2049:u&-2050;K=0;return d}function Nd(b,c){var d=Z(b,c);u=0===(b*c/4294967296|0)?u&-2050:u|2049;K=0;return d}function me(b,c){var d=v[c];v[c]=b;return kc(b,d)}function Od(b,c){var d=g[c];g[c]=b;return eb(b,d)}function Pd(b,c){var d=y[c];y[c]=b;return fb(b,d)}function xc(b,c){I=b&c;Y=8;u&=-2066;K=196;return I}function tb(b,c){I=b&c;Y=16;u&=-2066;K=196;return I}function ub(b,c){I=
b&c;Y=32;u&=-2066;K=196;return I}function id(b,c){I=b&c;Y=8;u&=-2066;K=196}function jd(b,c){I=b&c;Y=16;u&=-2050;K=196}function kd(b,c){I=b&c;Y=32;u&=-2066;K=196}function yc(b,c){I=b|c;Y=8;u&=-2066;K=196;return I}function vb(b,c){I=b|c;Y=16;u&=-2066;K=196;return I}function wb(b,c){I=b|c;Y=32;u&=-2066;K=196;return I}function zc(b,c){I=b^c;Y=8;u&=-2066;K=196;return I}function xb(b,c){I=b^c;Y=16;u&=-2066;K=196;return I}function yb(b,c){I=b^c;Y=32;u&=-2066;K=196;return I}function Ac(b,c){if(!c)return b;
c&=7;var d=b<<c|b>>8-c;K&=-2050;u=u&-2050|d&1|(d<<11^d<<4)&2048;return d}function Hb(b,c){if(!c)return b;c&=15;var d=b<<c|b>>16-c;K&=-2050;u=u&-2050|d&1|(d<<11^d>>4)&2048;return d}function Ib(b,c){if(!c)return b;var d=b<<c|b>>>32-c;K&=-2050;u=u&-2050|d&1|(d<<11^d>>20)&2048;return d}function Bc(b,c){c%=9;if(!c)return b;var d=b<<c|Ba()<<c-1|b>>9-c;K&=-2050;u=u&-2050|d>>8&1|(d<<3^d<<4)&2048;return d}function Jb(b,c){c%=17;if(!c)return b;var d=b<<c|Ba()<<c-1|b>>17-c;K&=-2050;u=u&-2050|d>>16&1|(d>>5^d>>
4)&2048;return d}function Kb(b,c){if(!c)return b;var d=b<<c|Ba()<<c-1;1<c&&(d|=b>>>33-c);K&=-2050;u=u&-2050|b>>>32-c&1;u|=(u<<11^d>>20)&2048;return d}function Cc(b,c){c&=7;if(!c)return b;var d=b>>c|b<<8-c;K&=-2050;u=u&-2050|d>>7&1|(d<<4^d<<5)&2048;return d}function Lb(b,c){c&=15;if(!c)return b;var d=b>>c|b<<16-c;K&=-2050;u=u&-2050|d>>15&1|(d>>4^d>>3)&2048;return d}function Mb(b,c){if(!c)return b;var d=b>>>c|b<<32-c;K&=-2050;u=u&-2050|d>>31&1|(d>>20^d>>19)&2048;return d}function Dc(b,c){c%=9;if(!c)return b;
var d=b>>c|Ba()<<8-c|b<<9-c;K&=-2050;u=u&-2050|d>>8&1|(d<<4^d<<5)&2048;return d}function Nb(b,c){c%=17;if(!c)return b;var d=b>>c|Ba()<<16-c|b<<17-c;K&=-2050;u=u&-2050|d>>16&1|(d>>4^d>>3)&2048;return d}function Ob(b,c){if(!c)return b;var d=b>>>c|Ba()<<32-c;1<c&&(d|=b<<33-c);K&=-2050;u=u&-2050|b>>c-1&1|(d>>20^d>>19)&2048;return d}function gb(b,c){if(0===c)return b;I=b<<c;Y=8;K=212;u=u&-2050|I>>8&1|(I<<3^I<<4)&2048;return I}function Ja(b,c){if(0===c)return b;I=b<<c;Y=16;K=212;u=u&-2050|I>>16&1|(I>>5^
I>>4)&2048;return I}function Ka(b,c){if(0===c)return b;I=b<<c;Y=32;K=212;u=u&-2050|b>>>32-c&1;u|=(u&1^I>>31&1)<<11&2048;return I}function Ec(b,c){if(0===c)return b;I=b>>c;Y=8;K=212;u=u&-2050|b>>c-1&1|(b>>7&1)<<11&2048;return I}function Pb(b,c){if(0===c)return b;I=b>>c;Y=16;K=212;u=u&-2050|b>>c-1&1|b>>4&2048;return I}function Qb(b,c){if(0===c)return b;I=b>>>c;Y=32;K=212;u=u&-2050|b>>>c-1&1|b>>20&2048;return I}function Fc(b,c){if(0===c)return b;I=b>>c;Y=8;K=212;u=u&-2050|b>>c-1&1;return I}function Rb(b,
c){if(0===c)return b;I=b>>c;Y=16;K=212;u=u&-2050|b>>c-1&1;return I}function Sb(b,c){if(0===c)return b;I=b>>c;Y=32;K=212;u=u&-2050|b>>>c-1&1;return I}function Gc(b,c,d){if(0===d)return b;16>=d?(I=b>>d|c<<16-d,u=u&-2|b>>d-1&1):(I=b<<32-d|c>>d-16,u=u&-2|c>>d-17&1);Y=16;K=212;u=u&-2049|(I^b)>>4&2048;return I}function Hc(b,c,d){if(0===d)return b;I=b>>>d|c<<32-d;Y=32;K=212;u=u&-2|b>>>d-1&1;u=u&-2049|(I^b)>>20&2048;return I}function Ic(b,c,d){if(0===d)return b;16>=d?(I=b<<d|c>>>16-d,u=u&-2|b>>>16-d&1):(I=
b>>32-d|c<<d-16,u=u&-2|c>>>32-d&1);Y=16;K=212;u=u&-2049|(u&1^I>>15&1)<<11;return I}function Jc(b,c,d){if(0===d)return b;I=b<<d|c>>>32-d;Y=32;K=212;u=u&-2|b>>>32-d&1;u=u&-2049|(u&1^I>>31&1)<<11;return I}function ld(b,c){u=u&-2|b>>c&1;K=0}function md(b,c){u=u&-2|b>>c&1;K=0;return b^1<<c}function nd(b,c){u=u&-2|b>>c&1;K=0;return b|1<<c}function od(b,c){u=u&-2|b>>c&1;K=0;return b&~(1<<c)}function pd(b,c){var d=ka(b+(c>>3));u=u&-2|d>>(c&7)&1;K=0}function qd(b,c){var d=q(b+(c>>3)),e=k.d(d);c&=7;u=u&-2|
e>>c&1;K=0;k.e(d,e^1<<c)}function rd(b,c){var d=q(b+(c>>3)),e=k.d(d);c&=7;u=u&-2|e>>c&1;K=0;k.e(d,e&~(1<<c))}function sd(b,c){var d=q(b+(c>>3)),e=k.d(d);c&=7;u=u&-2|e>>c&1;K=0;k.e(d,e|1<<c)}function Qd(b){var c=da[1];E-=c;E=E+b&65535;E=E+c|0}function Oa(b){b?Qd(U()):E+=2}function Pa(b){b?(b=M(),E=E+b|0):E=E+4|0}function Qa(){return Ba()||Gb()}function Wa(){return!hd()!==!Tc()}function Xa(){return Gb()||!hd()!==!Tc()}function Ba(){return K&1?32===Y?4294967295<I|0>I:I>>Y&1:u&1}function ge(){return K&
4?154020>>((I^I>>4)&15)&4:u&4}function Sc(){return K&16?(ba^ma^I^(0>ma)<<4)&16:u&16}function Gb(){return K&64?(~I&I-1)>>Y-7&64:u&64}function hd(){return K&128?I>>Y-8&128:u&128}function Tc(){return K&2048?((ba^I)&(ma^I))>>Y-1<<11&2048:u&2048}function la(b){var c=Id(-2);$[aa]-=2;k.a(c,b)}function ia(b){var c=Id(-4);$[aa]-=4;k.f(c,b)}function Aa(){var b=Va(0);$[aa]+=2;return k.b(b)}function ua(){var b=Va(0);$[aa]+=4;return k.c(b)}function ne(b,c){var d=c>>1&12|c>>5&1,e=v[d];v[d]=b;return e}function Rd(b,
c){var d=c>>2&14,e=g[d];g[d]=b;return e}function $b(b){var c=g[0];g[0]=g[b];g[b]=c}function Sd(b,c){var d=c>>3&7,g=e[d];y[d]=b;return g}function ac(b){var c=e[0];y[0]=e[b];y[b]=c}function Uc(b,c,d){var e=Q(c);c=Q(c+2);ca(b,c);g[d]=e}function Vc(b,c,d){var e=S(c);c=Q(c+4);ca(b,c);y[d]=e}function bc(b){var c=e[b];y[b]=c>>>24|c<<24|c>>8&65280|c<<8&16711680}function Ce(){function b(b){var c=r();Z&=-18177;c>b||(Z=b>c?Z|256:c===b?Z|16384:Z|17664)}function c(b){var c=n[F];K&=-70;u&=-70;c>b||(u=b>c?u|1:c===
b?u|64:u|69)}function d(){J=895;M=sa=L=Z=0;E=255;F=0}function e(b){if(xa){R(b,J);R(b+4,Z&-14337|F<<11);for(var c=0,d,g=0;8>g;g++)if(d=n[g],E>>g&1)c|=3<<(g<<1);else if(0===d)c|=1<<(g<<1);else if(isNaN(d)||Infinity===d||-Infinity===d)c|=2<<(g<<1);R(b+8,c);N(b+12,L);R(b+16,V);R(b+18,M);N(b+20,sa);R(b+24,P)}else z()}function k(b){if(xa){J=Q(b);var c=Q(b+4);Z=c&-14337;F=c>>11&7;for(var c=Q(b+8),d=E=0;8>d;d++)E|=c>>d&c>>d+1&1<<d;L=S(b+12)>>>0;V=Q(b+16);M=Q(b+18);sa=S(b+20)>>>0;P=Q(b+24)}else z()}function h(b){var c=
J>>10&3;return 0===c?(c=Math.round(b),0.5===c-b&&c&1&&c--,c):1===c||3===c&&0<b?Math.floor(b):Math.ceil(b)}function l(b){return 0<b?Math.floor(b):Math.ceil(b)}function m(b){F=F-1&7;E>>F&1?(Z&=-513,E&=~(1<<F),n[F]=b):(Z|=512,Z=Z|t|A,n[F]=NaN)}function p(){E|=1<<F;F=F+1&7}function s(b){b=b+F&7;return E>>b&1?(Z&=-513,Z=Z|t|A,NaN):n[b]}function r(){return E>>F&1?(Z&=-513,Z=Z|t|A,NaN):n[F]}function v(b){var c=Q(b+8),d=S(b)>>>0,e=S(b+4)>>>0;b=c>>15;c&=-32769;if(0===c)return 0;if(!(32767>c))return I[7]=127|
b<<7,I[6]=240|e>>30<<3&8,I[5]=0,I[4]=0,D[0]=0,G[0];d+=4294967296*e;b&&(d=-d);return d*Math.pow(2,c-16383-63)}function w(b,c){G[0]=n[F+c&7];var d=I[7]&128,e=(I[7]&127)<<4|I[6]>>4,g,k;2047===e?(e=32767,g=0,k=2147483648|(D[1]&524288)<<11):0===e?k=g=0:(e+=15360,g=D[0]<<11,k=2147483648|(D[1]&1048575)<<11|D[0]>>>21);N(b,g);N(b+4,k);R(b+8,d<<8|e)}function x(b){D[0]=S(b);D[1]=S(b+4);return G[0]}function y(b){q(b+7);G[0]=s(0);N(b,D[0]);N(b+4,D[1])}function f(b){H[0]=S(b);return C[0]}this.a=1;var t=64,A=1,
n=new Float64Array(8),B=new Uint8Array(n.buffer);new Uint32Array(n.buffer);var E=255,F=0,C=new Float32Array(1);new Uint8Array(C.buffer);var H=new Uint32Array(C.buffer),G=new Float64Array(1),I=new Uint8Array(G.buffer),D=new Uint32Array(G.buffer);new Uint8Array(10);var J=895,Z=0,L=0,V=0,M=0,sa=0,P=0,O=new Float64Array([1,Math.log(10)/Math.LN2,Math.LOG2E,Math.PI,Math.log(2)/Math.LN10,Math.LN2,0]);this.m=function(c){var d=c>>3&7;c=s(c&7);var e=r();switch(d){case 0:n[F]=e+c;break;case 1:n[F]=e*c;break;
case 2:b(c);break;case 3:b(c);p();break;case 4:n[F]=e-c;break;case 5:n[F]=c-e;break;case 6:n[F]=e/c;break;case 7:n[F]=c/e;break;default:z()}};this.i=function(c,d){var e=c>>3&7,g=f(d),k=r();switch(e){case 0:n[F]=k+g;break;case 1:n[F]=k*g;break;case 2:b(g);break;case 3:b(g);p();break;case 4:n[F]=k-g;break;case 5:n[F]=g-k;break;case 6:n[F]=k/g;break;case 7:n[F]=g/k;break;default:z()}};this.v=function(b){var c=b&7;switch(b>>3&7){case 0:b=s(c);m(b);break;case 1:b=s(c);n[F+c&7]=r();n[F]=b;break;case 4:switch(c){case 0:n[F]=
-r();break;case 1:n[F]=Math.abs(r());break;case 4:c=r();Z&=-18177;isNaN(c)?Z|=17664:0===c?Z|=16384:0>c&&(Z|=256);break;case 5:c=r();Z&=-18177;Z|=B[(F+0&7)<<3|7]>>7<<9;Z=E>>F&1?Z|16640:isNaN(c)?Z|256:0===c?Z|16384:Infinity===c||-Infinity===c?Z|1280:Z|1024;break;default:z()}break;case 5:m(O[c]);break;case 6:switch(c){case 0:n[F]=Math.pow(2,r())-1;break;case 1:n[F+1&7]=s(1)*Math.log(r())/Math.LN2;p();break;case 2:n[F]=Math.tan(r());m(1);break;case 3:n[F+1&7]=Math.atan2(s(1),r());p();break;case 5:n[F]=
r()%s(1);break;default:z()}break;case 7:switch(c){case 0:n[F]=r()%s(1);break;case 2:n[F]=Math.sqrt(r());break;case 3:c=r();n[F]=Math.sin(c);m(Math.cos(c));break;case 4:n[F]=h(r());break;case 5:n[F]=r()*Math.pow(2,l(s(1)));break;case 6:n[F]=Math.sin(r());break;case 7:n[F]=Math.cos(r());break;default:z()}break;default:z()}};this.q=function(b,c){switch(b>>3&7){case 0:var d=f(c);m(d);break;case 2:C[0]=s(0);N(c,H[0]);break;case 3:C[0]=s(0);N(c,H[0]);p();break;case 4:k(c);break;case 5:J=Q(c);break;case 6:e(c);
break;case 7:R(c,J);break;default:z()}};this.Q=function(c){var d=c&7;switch(c>>3&7){case 0:Ra()&&(n[F]=s(d),E&=~(1<<F));break;case 1:Sa()&&(n[F]=s(d),E&=~(1<<F));break;case 2:Qa()&&(n[F]=s(d),E&=~(1<<F));break;case 3:Ta()&&(n[F]=s(d),E&=~(1<<F));break;case 5:1===d?(c=s(1),b(c),p(),p()):z();break;default:z()}};this.D=function(c,d){var e=c>>3&7,g=S(d),k=r();switch(e){case 0:n[F]=k+g;break;case 1:n[F]=k*g;break;case 2:b(g);break;case 3:b(g);p();break;case 4:n[F]=k-g;break;case 5:n[F]=g-k;break;case 6:n[F]=
k/g;break;case 7:n[F]=g/k;break;default:z()}};this.S=function(b){var e=b&7;switch(b>>3&7){case 0:Ra()||(n[F]=s(e),E&=~(1<<F));break;case 1:Sa()||(n[F]=s(e),E&=~(1<<F));break;case 2:Qa()||(n[F]=s(e),E&=~(1<<F));break;case 3:Ta()||(n[F]=s(e),E&=~(1<<F));break;case 4:227===b?d():228!==b&&z();break;case 5:b=s(e);c(b);break;case 6:c(s(e));break;default:z()}};this.R=function(b,c){switch(b>>3&7){case 0:var d=S(c);m(d);break;case 2:d=r();isNaN(d)||2147483647<d||-2147483648>d?(Z|=A,N(c,2147483648)):N(c,h(d));
break;case 3:d=r();isNaN(d)||2147483647<d||-2147483648>d?(Z|=A,N(c,2147483648)):N(c,h(d));p();break;case 5:m(v(c));break;case 7:w(c,0);p();break;default:z()}};this.Ga=function(c){var d=c>>3&7,e=c&7;c=F+e&7;var e=s(e),g=r();switch(d){case 0:n[c]=e+g;break;case 1:n[c]=e*g;break;case 2:b(e);break;case 3:b(e);p();break;case 4:n[c]=g-e;break;case 5:n[c]=e-g;break;case 6:n[c]=g/e;break;case 7:n[c]=e/g;break;default:z()}};this.aa=function(c,d){var e=c>>3&7,g=x(d),k=r();switch(e){case 0:n[F]=k+g;break;case 1:n[F]=
k*g;break;case 2:b(g);break;case 3:b(g);p();break;case 4:n[F]=k-g;break;case 5:n[F]=g-k;break;case 6:n[F]=k/g;break;case 7:n[F]=g/k;break;default:z()}};this.Ka=function(c){var d=c&7;switch(c>>3&7){case 0:E|=1<<(F+d&7);break;case 2:n[F+d&7]=r();break;case 3:0!==d&&(n[F+d&7]=r());p();break;case 4:c=s(d);b(c);break;case 5:c=s(d);b(c);p();break;default:z()}};this.Ia=function(b,c){switch(b>>3&7){case 0:var g=x(c);m(g);break;case 2:y(c);break;case 3:y(c);p();break;case 4:g=c;k(g);for(var g=g+28,h=0;8>h;h++)n[h]=
v(g),g+=10;break;case 6:g=c;e(g);g+=28;for(h=0;8>h;h++)w(g,h-F&7),g+=10;d();break;case 7:R(c,Z&-14337|F<<11);break;default:z()}};this.Na=function(c){var d=c>>3&7;c=c&7;var e=F+c&7,g=s(c),k=r();switch(d){case 0:n[e]=g+k;break;case 1:n[e]=g*k;break;case 2:b(g);break;case 3:1===c?(b(n[e]),p()):z();break;case 4:n[e]=k-g;break;case 5:n[e]=g-k;break;case 6:n[e]=k/g;break;case 7:n[e]=g/k;break;default:z()}p()};this.Ma=function(c,d){var e=c>>3&7,g=Q(d)<<16>>16,k=r();switch(e){case 0:n[F]=k+g;break;case 1:n[F]=
k*g;break;case 2:b(g);break;case 3:b(g);p();break;case 4:n[F]=k-g;break;case 5:n[F]=g-k;break;case 6:n[F]=k/g;break;case 7:n[F]=g/k;break;default:z()}};this.Ra=function(b){var d=b&7;switch(b>>3&7){case 4:224===b?g[0]=Z&-14337|F<<11:z();break;case 5:b=s(d);c(b);p();break;default:z()}};this.Oa=function(b,c){switch(b>>3&7){case 0:var d=Q(c)<<16>>16;m(d);break;case 2:d=r();isNaN(d)||32767<d||-32768>d?(Z|=A,R(c,32768)):R(c,h(d));break;case 3:d=r();isNaN(d)||32767<d||-32768>d?(Z|=A,R(c,32768)):R(c,h(d));
p();break;case 5:var e=S(c)>>>0,d=S(c+4)>>>0,e=e+4294967296*d;d>>31&&(e-=1.8446744073709552E19);m(e);break;case 7:d=h(r());if(isNaN(d)||9223372036854775E3<d||-9223372036854775E3>d)d=9223372036854775E3,Z|=A;p();N(c,d);d/=4294967296;0>d&&-1<d&&(d=-1);N(c+4,d);break;default:z()}}}var bb=this;this.m=function(){ec||f()};this.v=function(){ec&&(oc=!0)};this.w=D;this.q=function(){var b=ec;oc=!0;ec=!1;setTimeout(function(){wd.n();Xc.n();D(xd);b&&f()},10)};this.a={};this.i=0;var Yc,da,yd,ae,zd,Ad,Bd,Cd,Eb,
pc,Ma,bd,rc,ad,qc,$c,Zc,Ed,Dd,Nc,Na,Ub,cd,Oc,ya,J,Fd,Db,xa,dd,ed,Vb,fd,Xc,wd,ee,fe,ce,ec,oc,Pc,k,Ha,Gd,Ua,Ea,q,Cb,E,Fb,Kc,ab,wa,cc,I,u,K,ba,ma,Y,y,e,g,Ga,v,fc,ra,$,aa,sc,A,ga,W,T,m,P,U,M,ka,Rc,Q,S,Va,Id,Ab,Jd,l,xd;"undefined"!==typeof window&&(window.a=C);bb.D=function(){Ab[m()]()};var Ie={ha:sa,ia:sa,na:function(){return k.m[E++]},oa:function(){return k.Q[E++]},la:function(){var b=k.b(E);E=E+2|0;return b},ma:function(){var b=k.c(E);E=E+4|0;return b},ta:function(b){return k.d(b)},ua:function(b){return k.R(b)},
ra:function(b){return k.b(b)},sa:function(b){return k.c(b)}},He={ha:function(b){return Ea(da[2]+$[aa]+b)},ia:function(b){return q(da[2]+$[aa]+b)},na:function(){E&-4096^Fb&&(Kc=Ea(E)^E,Fb=E&-4096);return k.m[Kc^E++]},oa:function(){E&-4096^Fb&&(Kc=Ea(E)^E,Fb=E&-4096);return k.Q[Kc^E++]},la:function(){if(4094<(E^Fb))return m()|m()<<8;var b=k.b(Kc^E);E=E+2|0;return b},ma:function(){if(4092<(E^Fb))return U()|U()<<16;var b=k.c(Kc^E);E=E+4|0;return b},ta:function(b){return k.d(Ea(b))},ua:function(b){return k.R(Ea(b))},
ra:function(b){return 4095===(b&4095)?ka(b)|ka(b+1)<<8:k.b(Ea(b))},sa:function(b){return 4093<=(b&4095)?Q(b)|Q(b+2)<<16:k.c(Ea(b))}};"use strict";"use strict";var ie,he,va=Array(192),ta=Array(192),p=Array(256);va[0]=function(){return h(3)+(g[6]+g[12]&65535)|0};va[64]=function(){return h(3)+(g[6]+g[12]+P()&65535)|0};va[128]=function(){return h(3)+(g[6]+g[12]+U()&65535)|0};va[1]=function(){return h(3)+(g[6]+g[14]&65535)|0};va[65]=function(){return h(3)+(g[6]+g[14]+P()&65535)|0};va[129]=function(){return h(3)+
(g[6]+g[14]+U()&65535)|0};va[2]=function(){return h(2)+(g[10]+g[12]&65535)|0};va[66]=function(){return h(2)+(g[10]+g[12]+P()&65535)|0};va[130]=function(){return h(2)+(g[10]+g[12]+U()&65535)|0};va[3]=function(){return h(2)+(g[10]+g[14]&65535)|0};va[67]=function(){return h(2)+(g[10]+g[14]+P()&65535)|0};va[131]=function(){return h(2)+(g[10]+g[14]+U()&65535)|0};va[4]=function(){return h(3)+(g[12]&65535)|0};va[68]=function(){return h(3)+(g[12]+P()&65535)|0};va[132]=function(){return h(3)+(g[12]+U()&65535)|
0};va[5]=function(){return h(3)+(g[14]&65535)|0};va[69]=function(){return h(3)+(g[14]+P()&65535)|0};va[133]=function(){return h(3)+(g[14]+U()&65535)|0};va[6]=function(){return h(2)+(g[10]&65535)|0};va[70]=function(){return h(2)+(g[10]+P()&65535)|0};va[134]=function(){return h(2)+(g[10]+U()&65535)|0};va[7]=function(){return h(3)+(g[6]&65535)|0};va[71]=function(){return h(3)+(g[6]+P()&65535)|0};va[135]=function(){return h(3)+(g[6]+U()&65535)|0};ta[0]=function(){return h(3)+e[0]|0};ta[64]=function(){return h(3)+
e[0]+P()|0};ta[128]=function(){return h(3)+e[0]+M()|0};ta[1]=function(){return h(3)+e[1]|0};ta[65]=function(){return h(3)+e[1]+P()|0};ta[129]=function(){return h(3)+e[1]+M()|0};ta[2]=function(){return h(3)+e[2]|0};ta[66]=function(){return h(3)+e[2]+P()|0};ta[130]=function(){return h(3)+e[2]+M()|0};ta[3]=function(){return h(3)+e[3]|0};ta[67]=function(){return h(3)+e[3]+P()|0};ta[131]=function(){return h(3)+e[3]+M()|0};ta[4]=function(){return p[m()](!1)|0};ta[68]=function(){return p[m()](!1)+P()|0};
ta[132]=function(){return p[m()](!1)+M()|0};ta[5]=function(){return h(2)+e[5]|0};ta[69]=function(){return h(2)+e[5]+P()|0};ta[133]=function(){return h(2)+e[5]+M()|0};ta[6]=function(){return h(3)+e[6]|0};ta[70]=function(){return h(3)+e[6]+P()|0};ta[134]=function(){return h(3)+e[6]+M()|0};ta[7]=function(){return h(3)+e[7]|0};ta[71]=function(){return h(3)+e[7]+P()|0};ta[135]=function(){return h(3)+e[7]+M()|0};va[6]=function(){return h(3)+U()|0};ta[5]=function(){return h(3)+M()|0};ta[4]=function(){return p[m()](!1)|
0};ta[68]=function(){return p[m()](!0)+P()|0};ta[132]=function(){return p[m()](!0)+M()|0};for(var Td=0;8>Td;Td++)for(var Ud=0;3>Ud;Ud++)for(var td=1;8>td;td++){var ud=Td|Ud<<6;ta[ud|td<<3]=ta[ud];va[ud|td<<3]=va[ud]}p[0]=function(){return e[0]+h(3)+e[0]|0};p[1]=function(){return e[0]+h(3)+e[1]|0};p[2]=function(){return e[0]+h(3)+e[2]|0};p[3]=function(){return e[0]+h(3)+e[3]|0};p[4]=function(){return e[0]+h(2)+e[4]|0};p[5]=function(b){return e[0]+(b?h(2)+e[5]:h(3)+M())|0};p[6]=function(){return e[0]+
h(3)+e[6]|0};p[7]=function(){return e[0]+h(3)+e[7]|0};p[64]=function(){return(e[0]<<1)+h(3)+e[0]|0};p[65]=function(){return(e[0]<<1)+h(3)+e[1]|0};p[66]=function(){return(e[0]<<1)+h(3)+e[2]|0};p[67]=function(){return(e[0]<<1)+h(3)+e[3]|0};p[68]=function(){return(e[0]<<1)+h(2)+e[4]|0};p[69]=function(b){return(e[0]<<1)+(b?h(2)+e[5]:h(3)+M())|0};p[70]=function(){return(e[0]<<1)+h(3)+e[6]|0};p[71]=function(){return(e[0]<<1)+h(3)+e[7]|0};p[128]=function(){return(e[0]<<2)+h(3)+e[0]|0};p[129]=function(){return(e[0]<<
2)+h(3)+e[1]|0};p[130]=function(){return(e[0]<<2)+h(3)+e[2]|0};p[131]=function(){return(e[0]<<2)+h(3)+e[3]|0};p[132]=function(){return(e[0]<<2)+h(2)+e[4]|0};p[133]=function(b){return(e[0]<<2)+(b?h(2)+e[5]:h(3)+M())|0};p[134]=function(){return(e[0]<<2)+h(3)+e[6]|0};p[135]=function(){return(e[0]<<2)+h(3)+e[7]|0};p[192]=function(){return(e[0]<<3)+h(3)+e[0]|0};p[193]=function(){return(e[0]<<3)+h(3)+e[1]|0};p[194]=function(){return(e[0]<<3)+h(3)+e[2]|0};p[195]=function(){return(e[0]<<3)+h(3)+e[3]|0};p[196]=
function(){return(e[0]<<3)+h(2)+e[4]|0};p[197]=function(b){return(e[0]<<3)+(b?h(2)+e[5]:h(3)+M())|0};p[198]=function(){return(e[0]<<3)+h(3)+e[6]|0};p[199]=function(){return(e[0]<<3)+h(3)+e[7]|0};p[8]=function(){return e[1]+h(3)+e[0]|0};p[9]=function(){return e[1]+h(3)+e[1]|0};p[10]=function(){return e[1]+h(3)+e[2]|0};p[11]=function(){return e[1]+h(3)+e[3]|0};p[12]=function(){return e[1]+h(2)+e[4]|0};p[13]=function(b){return e[1]+(b?h(2)+e[5]:h(3)+M())|0};p[14]=function(){return e[1]+h(3)+e[6]|0};
p[15]=function(){return e[1]+h(3)+e[7]|0};p[72]=function(){return(e[1]<<1)+h(3)+e[0]|0};p[73]=function(){return(e[1]<<1)+h(3)+e[1]|0};p[74]=function(){return(e[1]<<1)+h(3)+e[2]|0};p[75]=function(){return(e[1]<<1)+h(3)+e[3]|0};p[76]=function(){return(e[1]<<1)+h(2)+e[4]|0};p[77]=function(b){return(e[1]<<1)+(b?h(2)+e[5]:h(3)+M())|0};p[78]=function(){return(e[1]<<1)+h(3)+e[6]|0};p[79]=function(){return(e[1]<<1)+h(3)+e[7]|0};p[136]=function(){return(e[1]<<2)+h(3)+e[0]|0};p[137]=function(){return(e[1]<<
2)+h(3)+e[1]|0};p[138]=function(){return(e[1]<<2)+h(3)+e[2]|0};p[139]=function(){return(e[1]<<2)+h(3)+e[3]|0};p[140]=function(){return(e[1]<<2)+h(2)+e[4]|0};p[141]=function(b){return(e[1]<<2)+(b?h(2)+e[5]:h(3)+M())|0};p[142]=function(){return(e[1]<<2)+h(3)+e[6]|0};p[143]=function(){return(e[1]<<2)+h(3)+e[7]|0};p[200]=function(){return(e[1]<<3)+h(3)+e[0]|0};p[201]=function(){return(e[1]<<3)+h(3)+e[1]|0};p[202]=function(){return(e[1]<<3)+h(3)+e[2]|0};p[203]=function(){return(e[1]<<3)+h(3)+e[3]|0};p[204]=
function(){return(e[1]<<3)+h(2)+e[4]|0};p[205]=function(b){return(e[1]<<3)+(b?h(2)+e[5]:h(3)+M())|0};p[206]=function(){return(e[1]<<3)+h(3)+e[6]|0};p[207]=function(){return(e[1]<<3)+h(3)+e[7]|0};p[16]=function(){return e[2]+h(3)+e[0]|0};p[17]=function(){return e[2]+h(3)+e[1]|0};p[18]=function(){return e[2]+h(3)+e[2]|0};p[19]=function(){return e[2]+h(3)+e[3]|0};p[20]=function(){return e[2]+h(2)+e[4]|0};p[21]=function(b){return e[2]+(b?h(2)+e[5]:h(3)+M())|0};p[22]=function(){return e[2]+h(3)+e[6]|0};
p[23]=function(){return e[2]+h(3)+e[7]|0};p[80]=function(){return(e[2]<<1)+h(3)+e[0]|0};p[81]=function(){return(e[2]<<1)+h(3)+e[1]|0};p[82]=function(){return(e[2]<<1)+h(3)+e[2]|0};p[83]=function(){return(e[2]<<1)+h(3)+e[3]|0};p[84]=function(){return(e[2]<<1)+h(2)+e[4]|0};p[85]=function(b){return(e[2]<<1)+(b?h(2)+e[5]:h(3)+M())|0};p[86]=function(){return(e[2]<<1)+h(3)+e[6]|0};p[87]=function(){return(e[2]<<1)+h(3)+e[7]|0};p[144]=function(){return(e[2]<<2)+h(3)+e[0]|0};p[145]=function(){return(e[2]<<
2)+h(3)+e[1]|0};p[146]=function(){return(e[2]<<2)+h(3)+e[2]|0};p[147]=function(){return(e[2]<<2)+h(3)+e[3]|0};p[148]=function(){return(e[2]<<2)+h(2)+e[4]|0};p[149]=function(b){return(e[2]<<2)+(b?h(2)+e[5]:h(3)+M())|0};p[150]=function(){return(e[2]<<2)+h(3)+e[6]|0};p[151]=function(){return(e[2]<<2)+h(3)+e[7]|0};p[208]=function(){return(e[2]<<3)+h(3)+e[0]|0};p[209]=function(){return(e[2]<<3)+h(3)+e[1]|0};p[210]=function(){return(e[2]<<3)+h(3)+e[2]|0};p[211]=function(){return(e[2]<<3)+h(3)+e[3]|0};p[212]=
function(){return(e[2]<<3)+h(2)+e[4]|0};p[213]=function(b){return(e[2]<<3)+(b?h(2)+e[5]:h(3)+M())|0};p[214]=function(){return(e[2]<<3)+h(3)+e[6]|0};p[215]=function(){return(e[2]<<3)+h(3)+e[7]|0};p[24]=function(){return e[3]+h(3)+e[0]|0};p[25]=function(){return e[3]+h(3)+e[1]|0};p[26]=function(){return e[3]+h(3)+e[2]|0};p[27]=function(){return e[3]+h(3)+e[3]|0};p[28]=function(){return e[3]+h(2)+e[4]|0};p[29]=function(b){return e[3]+(b?h(2)+e[5]:h(3)+M())|0};p[30]=function(){return e[3]+h(3)+e[6]|0};
p[31]=function(){return e[3]+h(3)+e[7]|0};p[88]=function(){return(e[3]<<1)+h(3)+e[0]|0};p[89]=function(){return(e[3]<<1)+h(3)+e[1]|0};p[90]=function(){return(e[3]<<1)+h(3)+e[2]|0};p[91]=function(){return(e[3]<<1)+h(3)+e[3]|0};p[92]=function(){return(e[3]<<1)+h(2)+e[4]|0};p[93]=function(b){return(e[3]<<1)+(b?h(2)+e[5]:h(3)+M())|0};p[94]=function(){return(e[3]<<1)+h(3)+e[6]|0};p[95]=function(){return(e[3]<<1)+h(3)+e[7]|0};p[152]=function(){return(e[3]<<2)+h(3)+e[0]|0};p[153]=function(){return(e[3]<<
2)+h(3)+e[1]|0};p[154]=function(){return(e[3]<<2)+h(3)+e[2]|0};p[155]=function(){return(e[3]<<2)+h(3)+e[3]|0};p[156]=function(){return(e[3]<<2)+h(2)+e[4]|0};p[157]=function(b){return(e[3]<<2)+(b?h(2)+e[5]:h(3)+M())|0};p[158]=function(){return(e[3]<<2)+h(3)+e[6]|0};p[159]=function(){return(e[3]<<2)+h(3)+e[7]|0};p[216]=function(){return(e[3]<<3)+h(3)+e[0]|0};p[217]=function(){return(e[3]<<3)+h(3)+e[1]|0};p[218]=function(){return(e[3]<<3)+h(3)+e[2]|0};p[219]=function(){return(e[3]<<3)+h(3)+e[3]|0};p[220]=
function(){return(e[3]<<3)+h(2)+e[4]|0};p[221]=function(b){return(e[3]<<3)+(b?h(2)+e[5]:h(3)+M())|0};p[222]=function(){return(e[3]<<3)+h(3)+e[6]|0};p[223]=function(){return(e[3]<<3)+h(3)+e[7]|0};p[32]=function(){return 0+h(3)+e[0]|0};p[33]=function(){return 0+h(3)+e[1]|0};p[34]=function(){return 0+h(3)+e[2]|0};p[35]=function(){return 0+h(3)+e[3]|0};p[36]=function(){return 0+h(2)+e[4]|0};p[37]=function(b){return 0+(b?h(2)+e[5]:h(3)+M())|0};p[38]=function(){return 0+h(3)+e[6]|0};p[39]=function(){return 0+
h(3)+e[7]|0};p[96]=function(){return 0+h(3)+e[0]|0};p[97]=function(){return 0+h(3)+e[1]|0};p[98]=function(){return 0+h(3)+e[2]|0};p[99]=function(){return 0+h(3)+e[3]|0};p[100]=function(){return 0+h(2)+e[4]|0};p[101]=function(b){return 0+(b?h(2)+e[5]:h(3)+M())|0};p[102]=function(){return 0+h(3)+e[6]|0};p[103]=function(){return 0+h(3)+e[7]|0};p[160]=function(){return 0+h(3)+e[0]|0};p[161]=function(){return 0+h(3)+e[1]|0};p[162]=function(){return 0+h(3)+e[2]|0};p[163]=function(){return 0+h(3)+e[3]|0};
p[164]=function(){return 0+h(2)+e[4]|0};p[165]=function(b){return 0+(b?h(2)+e[5]:h(3)+M())|0};p[166]=function(){return 0+h(3)+e[6]|0};p[167]=function(){return 0+h(3)+e[7]|0};p[224]=function(){return 0+h(3)+e[0]|0};p[225]=function(){return 0+h(3)+e[1]|0};p[226]=function(){return 0+h(3)+e[2]|0};p[227]=function(){return 0+h(3)+e[3]|0};p[228]=function(){return 0+h(2)+e[4]|0};p[229]=function(b){return 0+(b?h(2)+e[5]:h(3)+M())|0};p[230]=function(){return 0+h(3)+e[6]|0};p[231]=function(){return 0+h(3)+e[7]|
0};p[40]=function(){return e[5]+h(3)+e[0]|0};p[41]=function(){return e[5]+h(3)+e[1]|0};p[42]=function(){return e[5]+h(3)+e[2]|0};p[43]=function(){return e[5]+h(3)+e[3]|0};p[44]=function(){return e[5]+h(2)+e[4]|0};p[45]=function(b){return e[5]+(b?h(2)+e[5]:h(3)+M())|0};p[46]=function(){return e[5]+h(3)+e[6]|0};p[47]=function(){return e[5]+h(3)+e[7]|0};p[104]=function(){return(e[5]<<1)+h(3)+e[0]|0};p[105]=function(){return(e[5]<<1)+h(3)+e[1]|0};p[106]=function(){return(e[5]<<1)+h(3)+e[2]|0};p[107]=
function(){return(e[5]<<1)+h(3)+e[3]|0};p[108]=function(){return(e[5]<<1)+h(2)+e[4]|0};p[109]=function(b){return(e[5]<<1)+(b?h(2)+e[5]:h(3)+M())|0};p[110]=function(){return(e[5]<<1)+h(3)+e[6]|0};p[111]=function(){return(e[5]<<1)+h(3)+e[7]|0};p[168]=function(){return(e[5]<<2)+h(3)+e[0]|0};p[169]=function(){return(e[5]<<2)+h(3)+e[1]|0};p[170]=function(){return(e[5]<<2)+h(3)+e[2]|0};p[171]=function(){return(e[5]<<2)+h(3)+e[3]|0};p[172]=function(){return(e[5]<<2)+h(2)+e[4]|0};p[173]=function(b){return(e[5]<<
2)+(b?h(2)+e[5]:h(3)+M())|0};p[174]=function(){return(e[5]<<2)+h(3)+e[6]|0};p[175]=function(){return(e[5]<<2)+h(3)+e[7]|0};p[232]=function(){return(e[5]<<3)+h(3)+e[0]|0};p[233]=function(){return(e[5]<<3)+h(3)+e[1]|0};p[234]=function(){return(e[5]<<3)+h(3)+e[2]|0};p[235]=function(){return(e[5]<<3)+h(3)+e[3]|0};p[236]=function(){return(e[5]<<3)+h(2)+e[4]|0};p[237]=function(b){return(e[5]<<3)+(b?h(2)+e[5]:h(3)+M())|0};p[238]=function(){return(e[5]<<3)+h(3)+e[6]|0};p[239]=function(){return(e[5]<<3)+h(3)+
e[7]|0};p[48]=function(){return e[6]+h(3)+e[0]|0};p[49]=function(){return e[6]+h(3)+e[1]|0};p[50]=function(){return e[6]+h(3)+e[2]|0};p[51]=function(){return e[6]+h(3)+e[3]|0};p[52]=function(){return e[6]+h(2)+e[4]|0};p[53]=function(b){return e[6]+(b?h(2)+e[5]:h(3)+M())|0};p[54]=function(){return e[6]+h(3)+e[6]|0};p[55]=function(){return e[6]+h(3)+e[7]|0};p[112]=function(){return(e[6]<<1)+h(3)+e[0]|0};p[113]=function(){return(e[6]<<1)+h(3)+e[1]|0};p[114]=function(){return(e[6]<<1)+h(3)+e[2]|0};p[115]=
function(){return(e[6]<<1)+h(3)+e[3]|0};p[116]=function(){return(e[6]<<1)+h(2)+e[4]|0};p[117]=function(b){return(e[6]<<1)+(b?h(2)+e[5]:h(3)+M())|0};p[118]=function(){return(e[6]<<1)+h(3)+e[6]|0};p[119]=function(){return(e[6]<<1)+h(3)+e[7]|0};p[176]=function(){return(e[6]<<2)+h(3)+e[0]|0};p[177]=function(){return(e[6]<<2)+h(3)+e[1]|0};p[178]=function(){return(e[6]<<2)+h(3)+e[2]|0};p[179]=function(){return(e[6]<<2)+h(3)+e[3]|0};p[180]=function(){return(e[6]<<2)+h(2)+e[4]|0};p[181]=function(b){return(e[6]<<
2)+(b?h(2)+e[5]:h(3)+M())|0};p[182]=function(){return(e[6]<<2)+h(3)+e[6]|0};p[183]=function(){return(e[6]<<2)+h(3)+e[7]|0};p[240]=function(){return(e[6]<<3)+h(3)+e[0]|0};p[241]=function(){return(e[6]<<3)+h(3)+e[1]|0};p[242]=function(){return(e[6]<<3)+h(3)+e[2]|0};p[243]=function(){return(e[6]<<3)+h(3)+e[3]|0};p[244]=function(){return(e[6]<<3)+h(2)+e[4]|0};p[245]=function(b){return(e[6]<<3)+(b?h(2)+e[5]:h(3)+M())|0};p[246]=function(){return(e[6]<<3)+h(3)+e[6]|0};p[247]=function(){return(e[6]<<3)+h(3)+
e[7]|0};p[56]=function(){return e[7]+h(3)+e[0]|0};p[57]=function(){return e[7]+h(3)+e[1]|0};p[58]=function(){return e[7]+h(3)+e[2]|0};p[59]=function(){return e[7]+h(3)+e[3]|0};p[60]=function(){return e[7]+h(2)+e[4]|0};p[61]=function(b){return e[7]+(b?h(2)+e[5]:h(3)+M())|0};p[62]=function(){return e[7]+h(3)+e[6]|0};p[63]=function(){return e[7]+h(3)+e[7]|0};p[120]=function(){return(e[7]<<1)+h(3)+e[0]|0};p[121]=function(){return(e[7]<<1)+h(3)+e[1]|0};p[122]=function(){return(e[7]<<1)+h(3)+e[2]|0};p[123]=
function(){return(e[7]<<1)+h(3)+e[3]|0};p[124]=function(){return(e[7]<<1)+h(2)+e[4]|0};p[125]=function(b){return(e[7]<<1)+(b?h(2)+e[5]:h(3)+M())|0};p[126]=function(){return(e[7]<<1)+h(3)+e[6]|0};p[127]=function(){return(e[7]<<1)+h(3)+e[7]|0};p[184]=function(){return(e[7]<<2)+h(3)+e[0]|0};p[185]=function(){return(e[7]<<2)+h(3)+e[1]|0};p[186]=function(){return(e[7]<<2)+h(3)+e[2]|0};p[187]=function(){return(e[7]<<2)+h(3)+e[3]|0};p[188]=function(){return(e[7]<<2)+h(2)+e[4]|0};p[189]=function(b){return(e[7]<<
2)+(b?h(2)+e[5]:h(3)+M())|0};p[190]=function(){return(e[7]<<2)+h(3)+e[6]|0};p[191]=function(){return(e[7]<<2)+h(3)+e[7]|0};p[248]=function(){return(e[7]<<3)+h(3)+e[0]|0};p[249]=function(){return(e[7]<<3)+h(3)+e[1]|0};p[250]=function(){return(e[7]<<3)+h(3)+e[2]|0};p[251]=function(){return(e[7]<<3)+h(3)+e[3]|0};p[252]=function(){return(e[7]<<3)+h(2)+e[4]|0};p[253]=function(b){return(e[7]<<3)+(b?h(2)+e[5]:h(3)+M())|0};p[254]=function(){return(e[7]<<3)+h(3)+e[6]|0};p[255]=function(){return(e[7]<<3)+h(3)+
e[7]|0};ie=function(b){return va[b]()};he=function(b){return ta[b]()};"use strict";var oe=new Uint8Array([32,0,1,26,2,23,27,0,3,16,24,30,28,11,0,13,4,7,17,0,25,22,31,15,29,10,12,6,0,21,14,9,5,20,8,19,18]);"use strict";var Ya=Tc,Ra=Ba,Sa=Gb,Za=hd,Ta=ge;"use strict";"use strict";"use strict";var r=[],s=[],x=[],w=[];r[0]=s[0]=function(){var b=m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,kc(c,v[b>>1&12|b>>5&1]))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=kc(c,v[b>>1&12|b>>5&1]))};r[1]=function(){var b=m(),c,
d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,eb(c,g[b>>2&14]))):(c=k.b(d),k.a(d,eb(c,g[b>>2&14])))):(c=g[b<<1&14],g[b<<1&14]=eb(c,g[b>>2&14]))};s[1]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,fb(c,y[b>>3&7]))):(c=k.c(d)>>>0,k.f(d,fb(c,y[b>>3&7])))):(c=y[b&7],e[b&7]=fb(c,y[b>>3&7]))};r[2]=s[2]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];v[b>>1&12|b>>5&1]=kc(v[b>>1&12|b>>5&1],c)};r[3]=function(){var b=m(),c=192>
b?Q(l(b)):g[b<<1&14];g[b>>2&14]=eb(g[b>>2&14],c)};s[3]=function(){var b=m(),c=192>b?S(l(b))>>>0:y[b&7];e[b>>3&7]=fb(y[b>>3&7],c)};r[4]=s[4]=function(){v[0]=kc(v[0],m())};r[5]=function(){g[0]=eb(g[0],U())};s[5]=function(){y[0]=fb(y[0],M()>>>0)};r[6]=function(){la(ra[0])};s[6]=function(){ia(ra[0])};r[7]=function(){ca(0,k.b(Va(0)));$[aa]+=2};s[7]=function(){ca(0,k.b(Va(0)));$[aa]+=4};r[8]=s[8]=function(){var b=m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,yc(c,v[b>>1&12|b>>5&1]))):(c=v[b<<2&12|b>>2&1],v[b<<
2&12|b>>2&1]=yc(c,v[b>>1&12|b>>5&1]))};r[9]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,vb(c,g[b>>2&14]))):(c=k.b(d),k.a(d,vb(c,g[b>>2&14])))):(c=g[b<<1&14],g[b<<1&14]=vb(c,g[b>>2&14]))};s[9]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g),H(d,g,wb(c,e[b>>3&7]))):(c=k.c(d),k.f(d,wb(c,e[b>>3&7])))):(c=e[b&7],e[b&7]=wb(c,e[b>>3&7]))};r[10]=s[10]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];v[b>>1&12|b>>5&
1]=yc(v[b>>1&12|b>>5&1],c)};r[11]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=vb(g[b>>2&14],c)};s[11]=function(){var b=m(),c=192>b?S(l(b)):e[b&7];e[b>>3&7]=wb(e[b>>3&7],c)};r[12]=s[12]=function(){v[0]=yc(v[0],m())};r[13]=function(){g[0]=vb(g[0],U())};s[13]=function(){y[0]=wb(e[0],M())};r[14]=function(){la(ra[1])};s[14]=function(){ia(ra[1])};r[15]=s[15]=function(){Jd[m()]()};r[16]=s[16]=function(){var b=m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,uc(c,v[b>>1&12|b>>5&1]))):(c=v[b<<2&12|b>>
2&1],v[b<<2&12|b>>2&1]=uc(c,v[b>>1&12|b>>5&1]))};r[17]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,jb(c,g[b>>2&14]))):(c=k.b(d),k.a(d,jb(c,g[b>>2&14])))):(c=g[b<<1&14],g[b<<1&14]=jb(c,g[b>>2&14]))};s[17]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,kb(c,y[b>>3&7]))):(c=k.c(d)>>>0,k.f(d,kb(c,y[b>>3&7])))):(c=y[b&7],e[b&7]=kb(c,y[b>>3&7]))};r[18]=s[18]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>
2&1];v[b>>1&12|b>>5&1]=uc(v[b>>1&12|b>>5&1],c)};r[19]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=jb(g[b>>2&14],c)};s[19]=function(){var b=m(),c=192>b?S(l(b))>>>0:y[b&7];e[b>>3&7]=kb(y[b>>3&7],c)};r[20]=s[20]=function(){v[0]=uc(v[0],m())};r[21]=function(){g[0]=jb(g[0],U())};s[21]=function(){y[0]=kb(y[0],M()>>>0)};r[22]=function(){la(ra[2])};s[22]=function(){ia(ra[2])};r[23]=function(){ca(2,k.b(Va(0)));$[aa]+=2};s[23]=function(){ca(2,k.b(Va(0)));$[aa]+=4};r[24]=s[24]=function(){var b=
m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,wc(c,v[b>>1&12|b>>5&1]))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=wc(c,v[b>>1&12|b>>5&1]))};r[25]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,nb(c,g[b>>2&14]))):(c=k.b(d),k.a(d,nb(c,g[b>>2&14])))):(c=g[b<<1&14],g[b<<1&14]=nb(c,g[b>>2&14]))};s[25]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,ob(c,y[b>>3&7]))):(c=k.c(d)>>>0,k.f(d,ob(c,y[b>>3&7])))):(c=y[b&7],e[b&7]=
ob(c,y[b>>3&7]))};r[26]=s[26]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];v[b>>1&12|b>>5&1]=wc(v[b>>1&12|b>>5&1],c)};r[27]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=nb(g[b>>2&14],c)};s[27]=function(){var b=m(),c=192>b?S(l(b))>>>0:y[b&7];e[b>>3&7]=ob(y[b>>3&7],c)};r[28]=s[28]=function(){v[0]=wc(v[0],m())};r[29]=function(){g[0]=nb(g[0],U())};s[29]=function(){y[0]=ob(y[0],M()>>>0)};r[30]=function(){la(ra[3])};s[30]=function(){ia(ra[3])};r[31]=function(){ca(3,k.b(Va(0)));
$[aa]+=2};s[31]=function(){ca(3,k.b(Va(0)));$[aa]+=4};r[32]=s[32]=function(){var b=m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,xc(c,v[b>>1&12|b>>5&1]))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=xc(c,v[b>>1&12|b>>5&1]))};r[33]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,tb(c,g[b>>2&14]))):(c=k.b(d),k.a(d,tb(c,g[b>>2&14])))):(c=g[b<<1&14],g[b<<1&14]=tb(c,g[b>>2&14]))};s[33]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g),
H(d,g,ub(c,e[b>>3&7]))):(c=k.c(d),k.f(d,ub(c,e[b>>3&7])))):(c=e[b&7],e[b&7]=ub(c,e[b>>3&7]))};r[34]=s[34]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];v[b>>1&12|b>>5&1]=xc(v[b>>1&12|b>>5&1],c)};r[35]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=tb(g[b>>2&14],c)};s[35]=function(){var b=m(),c=192>b?S(l(b)):e[b&7];e[b>>3&7]=ub(e[b>>3&7],c)};r[36]=s[36]=function(){v[0]=xc(v[0],m())};r[37]=function(){g[0]=tb(g[0],U())};s[37]=function(){y[0]=ub(e[0],M())};r[38]=s[38]=function(){ja(0)};
r[39]=s[39]=function(){var b=v[0],c=Ba(),d=Sc();u&=-18;if(9<(b&15)||d)v[0]+=6,u|=16;if(153<b||c)v[0]+=96,u|=1;I=v[0];Y=8;ba=ma=0;K=196};r[40]=s[40]=function(){var b=m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,vc(c,v[b>>1&12|b>>5&1]))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=vc(c,v[b>>1&12|b>>5&1]))};r[41]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,lb(c,g[b>>2&14]))):(c=k.b(d),k.a(d,lb(c,g[b>>2&14])))):(c=g[b<<1&14],g[b<<1&14]=lb(c,g[b>>2&14]))};s[41]=function(){var b=
m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,mb(c,y[b>>3&7]))):(c=k.c(d)>>>0,k.f(d,mb(c,y[b>>3&7])))):(c=y[b&7],e[b&7]=mb(c,y[b>>3&7]))};r[42]=s[42]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];v[b>>1&12|b>>5&1]=vc(v[b>>1&12|b>>5&1],c)};r[43]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=lb(g[b>>2&14],c)};s[43]=function(){var b=m(),c=192>b?S(l(b))>>>0:y[b&7];e[b>>3&7]=mb(y[b>>3&7],c)};r[44]=s[44]=function(){v[0]=vc(v[0],m())};r[45]=function(){g[0]=
lb(g[0],U())};s[45]=function(){y[0]=mb(y[0],M()>>>0)};r[46]=s[46]=function(){ja(1)};r[47]=s[47]=function(){var b=v[0],c=Ba();u&=-2;9<(b&15)||Sc()?(v[0]-=6,u|=16,u=u&-2|c|v[0]>>7):u&=-17;if(153<b||c)v[0]-=96,u|=1;I=v[0];Y=8;ba=ma=0;K=196};r[48]=s[48]=function(){var b=m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,zc(c,v[b>>1&12|b>>5&1]))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=zc(c,v[b>>1&12|b>>5&1]))};r[49]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,xb(c,
g[b>>2&14]))):(c=k.b(d),k.a(d,xb(c,g[b>>2&14])))):(c=g[b<<1&14],g[b<<1&14]=xb(c,g[b>>2&14]))};s[49]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g),H(d,g,yb(c,e[b>>3&7]))):(c=k.c(d),k.f(d,yb(c,e[b>>3&7])))):(c=e[b&7],e[b&7]=yb(c,e[b>>3&7]))};r[50]=s[50]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];v[b>>1&12|b>>5&1]=zc(v[b>>1&12|b>>5&1],c)};r[51]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=xb(g[b>>2&14],c)};s[51]=function(){var b=m(),c=
192>b?S(l(b)):e[b&7];e[b>>3&7]=yb(e[b>>3&7],c)};r[52]=s[52]=function(){v[0]=zc(v[0],m())};r[53]=function(){g[0]=xb(g[0],U())};s[53]=function(){y[0]=yb(e[0],M())};r[54]=s[54]=function(){ja(2)};r[55]=s[55]=function(){9<(v[0]&15)||Sc()?(g[0]+=6,v[1]+=1,u|=17):u&=-18;v[0]&=15;K&=-18};r[56]=s[56]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];lc(c,v[b>>1&12|b>>5&1])};r[57]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];Yb(c,g[b>>2&14])};s[57]=function(){var b=m(),c=192>b?S(l(b))>>>0:y[b&7];Zb(c,
y[b>>3&7])};r[58]=s[58]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];lc(v[b>>1&12|b>>5&1],c)};r[59]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];Yb(g[b>>2&14],c)};s[59]=function(){var b=m(),c=192>b?S(l(b))>>>0:y[b&7];Zb(y[b>>3&7],c)};r[60]=s[60]=function(){lc(v[0],m())};r[61]=function(){Yb(g[0],U())};s[61]=function(){Zb(y[0],M()>>>0)};r[62]=s[62]=function(){ja(3)};r[63]=s[63]=function(){9<(v[0]&15)||Sc()?(g[0]-=6,v[1]-=1,u|=17):u&=-18;v[0]&=15;K&=-18};r[64]=function(){g[0]=pb(g[0])};
s[64]=function(){y[0]=qb(y[0])};r[65]=function(){g[2]=pb(g[2])};s[65]=function(){y[1]=qb(y[1])};r[66]=function(){g[4]=pb(g[4])};s[66]=function(){y[2]=qb(y[2])};r[67]=function(){g[6]=pb(g[6])};s[67]=function(){y[3]=qb(y[3])};r[68]=function(){g[8]=pb(g[8])};s[68]=function(){y[4]=qb(y[4])};r[69]=function(){g[10]=pb(g[10])};s[69]=function(){y[5]=qb(y[5])};r[70]=function(){g[12]=pb(g[12])};s[70]=function(){y[6]=qb(y[6])};r[71]=function(){g[14]=pb(g[14])};s[71]=function(){y[7]=qb(y[7])};r[72]=function(){g[0]=
rb(g[0])};s[72]=function(){y[0]=sb(y[0])};r[73]=function(){g[2]=rb(g[2])};s[73]=function(){y[1]=sb(y[1])};r[74]=function(){g[4]=rb(g[4])};s[74]=function(){y[2]=sb(y[2])};r[75]=function(){g[6]=rb(g[6])};s[75]=function(){y[3]=sb(y[3])};r[76]=function(){g[8]=rb(g[8])};s[76]=function(){y[4]=sb(y[4])};r[77]=function(){g[10]=rb(g[10])};s[77]=function(){y[5]=sb(y[5])};r[78]=function(){g[12]=rb(g[12])};s[78]=function(){y[6]=sb(y[6])};r[79]=function(){g[14]=rb(g[14])};s[79]=function(){y[7]=sb(y[7])};r[80]=
function(){la(g[0])};s[80]=function(){ia(e[0])};r[81]=function(){la(g[2])};s[81]=function(){ia(e[1])};r[82]=function(){la(g[4])};s[82]=function(){ia(e[2])};r[83]=function(){la(g[6])};s[83]=function(){ia(e[3])};r[84]=function(){la(g[8])};s[84]=function(){ia(e[4])};r[85]=function(){la(g[10])};s[85]=function(){ia(e[5])};r[86]=function(){la(g[12])};s[86]=function(){ia(e[6])};r[87]=function(){la(g[14])};s[87]=function(){ia(e[7])};r[88]=function(){g[0]=Aa()};s[88]=function(){y[0]=ua()};r[89]=function(){g[2]=
Aa()};s[89]=function(){y[1]=ua()};r[90]=function(){g[4]=Aa()};s[90]=function(){y[2]=ua()};r[91]=function(){g[6]=Aa()};s[91]=function(){y[3]=ua()};r[92]=function(){g[8]=Aa()};s[92]=function(){y[4]=ua()};r[93]=function(){g[10]=Aa()};s[93]=function(){y[5]=ua()};r[94]=function(){g[12]=Aa()};s[94]=function(){y[6]=ua()};r[95]=function(){g[14]=Aa()};s[95]=function(){y[7]=ua()};r[96]=function(){var b=g[8];q(b-15);la(g[0]);la(g[2]);la(g[4]);la(g[6]);la(b);la(g[10]);la(g[12]);la(g[14])};s[96]=function(){var b=
e[4];q(b-31);ia(e[0]);ia(e[1]);ia(e[2]);ia(e[3]);ia(b);ia(e[5]);ia(e[6]);ia(e[7])};r[97]=function(){Ea($[aa]+15);g[14]=Aa();g[12]=Aa();g[10]=Aa();$[aa]+=2;g[6]=Aa();g[4]=Aa();g[2]=Aa();g[0]=Aa()};s[97]=function(){Ea($[aa]+31);y[7]=ua();y[6]=ua();y[5]=ua();$[aa]+=4;y[3]=ua();y[2]=ua();y[1]=ua();y[0]=ua()};r[98]=s[98]=function(){throw ze("bound instruction");};r[99]=s[99]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,Ca(c,b>>2&14))):(c=k.b(d),k.a(d,Ca(c,
b>>2&14)))):(c=g[b<<1&14],g[b<<1&14]=Ca(c,b>>2&14))};r[100]=s[100]=function(){ja(4)};r[101]=s[101]=function(){ja(5)};r[102]=s[102]=function(){xa=!Db;La();Ab[m()]();xa=Db;La()};r[103]=s[103]=function(){Cb=!Db;zb();Ab[m()]();Cb=Db;zb()};r[104]=function(){la(U())};s[104]=function(){ia(M())};r[105]=function(){var b=m(),c=192>b?Q(l(b))<<16>>16:Ga[b<<1&14];g[b>>2&14]=Md(U()<<16>>16,c)};s[105]=function(){var b=m(),c=192>b?S(l(b)):e[b&7];y[b>>3&7]=Nd(M(),c)};r[106]=function(){la(P())};s[106]=function(){ia(P())};
r[107]=function(){var b=m(),c=192>b?Q(l(b))<<16>>16:Ga[b<<1&14];g[b>>2&14]=Md(P(),c)};s[107]=function(){var b=m(),c=192>b?S(l(b)):e[b&7];y[b>>3&7]=Nd(P(),c)};r[108]=s[108]=function(){var b=g[4],c,d=u&1024?-1:1;c=da[0]+A[T];if(wa){if(0!==A[ga]){do V(c,hc(b)),c+=d,A[T]+=d;while(--A[ga])}}else V(c,hc(b)),A[T]+=d};r[109]=function(){var b=g[4],c,d=u&1024?-1:1;c=da[0]+A[T];if(wa){if(0!==A[ga]){do R(c,ic(b)),c+=d,A[T]+=d;while(--A[ga])}}else R(c,ic(b)),A[T]+=d};s[109]=function(){var b=g[4],c,d=u&1024?-4:
4;c=da[0]+A[T];if(wa){if(0!==A[ga]){var e=0===(c&3)&&!0;do{if(e){var h=q(c);k.D(h,cb(b))}else N(c,cb(b));c+=d;A[T]+=d}while(--A[ga])}}else N(c,cb(b)),A[T]+=d};r[110]=s[110]=function(){var b=g[4],c,d=u&1024?-1:1;c=h(3)+A[W];if(wa){if(0!==A[ga]){do Fa(b,ka(c)),c+=d,A[W]+=d;while(--A[ga])}}else Fa(b,ka(c)),A[W]+=d};r[111]=function(){var b=g[4],c,d=u&1024?-2:2;c=h(3)+A[W];if(wa){if(0!==A[ga]){do Xb(b,Q(c)),c+=d,A[W]+=d;while(--A[ga])}}else Xb(b,Q(c)),A[W]+=d};s[111]=function(){var b=g[4],c,d=u&1024?-4:
4;c=h(3)+A[W];if(wa){if(0!==A[ga]){do gc(b,S(c)),c+=d,A[W]+=d;while(--A[ga])}}else gc(b,S(c)),A[W]+=d};r[112]=s[112]=function(){Ya()&&(E=E+P()|0);E++};r[113]=s[113]=function(){Ya()||(E=E+P()|0);E++};r[114]=s[114]=function(){Ra()&&(E=E+P()|0);E++};r[115]=s[115]=function(){Ra()||(E=E+P()|0);E++};r[116]=s[116]=function(){Sa()&&(E=E+P()|0);E++};r[117]=s[117]=function(){Sa()||(E=E+P()|0);E++};r[118]=s[118]=function(){Qa()&&(E=E+P()|0);E++};r[119]=s[119]=function(){Qa()||(E=E+P()|0);E++};r[120]=s[120]=
function(){Za()&&(E=E+P()|0);E++};r[121]=s[121]=function(){Za()||(E=E+P()|0);E++};r[122]=s[122]=function(){Ta()&&(E=E+P()|0);E++};r[123]=s[123]=function(){Ta()||(E=E+P()|0);E++};r[124]=s[124]=function(){Wa()&&(E=E+P()|0);E++};r[125]=s[125]=function(){Wa()||(E=E+P()|0);E++};r[126]=s[126]=function(){Xa()&&(E=E+P()|0);E++};r[127]=s[127]=function(){Xa()||(E=E+P()|0);E++};r[128]=s[128]=function(){var b=m();switch(b>>3&7){case 0:var c;192>b?(b=q(l(b)),c=k.d(b),k.e(b,kc(c,m()))):(c=v[b<<2&12|b>>2&1],v[b<<
2&12|b>>2&1]=kc(c,m()));break;case 1:192>b?(b=q(l(b)),c=k.d(b),k.e(b,yc(c,m()))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=yc(c,m()));break;case 2:192>b?(b=q(l(b)),c=k.d(b),k.e(b,uc(c,m()))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=uc(c,m()));break;case 3:192>b?(b=q(l(b)),c=k.d(b),k.e(b,wc(c,m()))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=wc(c,m()));break;case 4:192>b?(b=q(l(b)),c=k.d(b),k.e(b,xc(c,m()))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=xc(c,m()));break;case 5:192>b?(b=q(l(b)),c=k.d(b),k.e(b,vc(c,
m()))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=vc(c,m()));break;case 6:192>b?(b=q(l(b)),c=k.d(b),k.e(b,zc(c,m()))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=zc(c,m()));break;case 7:c=192>b?ka(l(b)):v[b<<2&12|b>>2&1],lc(c,m())}};r[129]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,eb(c,U()))):(c=k.b(b),k.a(b,eb(c,U())))):(c=g[b<<1&14],g[b<<1&14]=eb(c,U()));break;case 1:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,
vb(c,U()))):(c=k.b(b),k.a(b,vb(c,U())))):(c=g[b<<1&14],g[b<<1&14]=vb(c,U()));break;case 2:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,jb(c,U()))):(c=k.b(b),k.a(b,jb(c,U())))):(c=g[b<<1&14],g[b<<1&14]=jb(c,U()));break;case 3:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,nb(c,U()))):(c=k.b(b),k.a(b,nb(c,U())))):(c=g[b<<1&14],g[b<<1&14]=nb(c,U()));break;case 4:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,tb(c,U()))):(c=k.b(b),k.a(b,tb(c,U())))):
(c=g[b<<1&14],g[b<<1&14]=tb(c,U()));break;case 5:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,lb(c,U()))):(c=k.b(b),k.a(b,lb(c,U())))):(c=g[b<<1&14],g[b<<1&14]=lb(c,U()));break;case 6:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,xb(c,U()))):(c=k.b(b),k.a(b,xb(c,U())))):(c=g[b<<1&14],g[b<<1&14]=xb(c,U()));break;case 7:c=192>b?Q(l(b)):g[b<<1&14],Yb(c,U())}};s[129]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+
3),c=G(b,d)>>>0,H(b,d,fb(c,M()>>>0))):(c=k.c(b)>>>0,k.f(b,fb(c,M()>>>0)))):(c=y[b&7],e[b&7]=fb(c,M()>>>0));break;case 1:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d),H(b,d,wb(c,M()))):(c=k.c(b),k.f(b,wb(c,M())))):(c=e[b&7],e[b&7]=wb(c,M()));break;case 2:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,kb(c,M()>>>0))):(c=k.c(b)>>>0,k.f(b,kb(c,M()>>>0)))):(c=y[b&7],e[b&7]=kb(c,M()>>>0));break;case 3:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,ob(c,
M()>>>0))):(c=k.c(b)>>>0,k.f(b,ob(c,M()>>>0)))):(c=y[b&7],e[b&7]=ob(c,M()>>>0));break;case 4:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d),H(b,d,ub(c,M()))):(c=k.c(b),k.f(b,ub(c,M())))):(c=e[b&7],e[b&7]=ub(c,M()));break;case 5:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,mb(c,M()>>>0))):(c=k.c(b)>>>0,k.f(b,mb(c,M()>>>0)))):(c=y[b&7],e[b&7]=mb(c,M()>>>0));break;case 6:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d),H(b,d,yb(c,M()))):(c=k.c(b),k.f(b,yb(c,
M())))):(c=e[b&7],e[b&7]=yb(c,M()));break;case 7:192>b?c=S(l(b))>>>0:c=y[b&7],Zb(c,M()>>>0)}};r[130]=s[130]=function(){Ab[128]()};r[131]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,eb(c,P()&65535))):(c=k.b(b),k.a(b,eb(c,P()&65535)))):(c=g[b<<1&14],g[b<<1&14]=eb(c,P()&65535));break;case 1:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,vb(c,P()))):(c=k.b(b),k.a(b,vb(c,P())))):(c=g[b<<1&14],g[b<<1&14]=vb(c,P()));
break;case 2:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,jb(c,P()&65535))):(c=k.b(b),k.a(b,jb(c,P()&65535)))):(c=g[b<<1&14],g[b<<1&14]=jb(c,P()&65535));break;case 3:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,nb(c,P()&65535))):(c=k.b(b),k.a(b,nb(c,P()&65535)))):(c=g[b<<1&14],g[b<<1&14]=nb(c,P()&65535));break;case 4:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,tb(c,P()))):(c=k.b(b),k.a(b,tb(c,P())))):(c=g[b<<1&14],g[b<<1&14]=tb(c,P()));
break;case 5:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,lb(c,P()&65535))):(c=k.b(b),k.a(b,lb(c,P()&65535)))):(c=g[b<<1&14],g[b<<1&14]=lb(c,P()&65535));break;case 6:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,xb(c,P()))):(c=k.b(b),k.a(b,xb(c,P())))):(c=g[b<<1&14],g[b<<1&14]=xb(c,P()));break;case 7:c=192>b?Q(l(b)):g[b<<1&14],Yb(c,P()&65535)}};s[131]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>
0,H(b,d,fb(c,P()>>>0))):(c=k.c(b)>>>0,k.f(b,fb(c,P()>>>0)))):(c=y[b&7],e[b&7]=fb(c,P()>>>0));break;case 1:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d),H(b,d,wb(c,P()))):(c=k.c(b),k.f(b,wb(c,P())))):(c=e[b&7],e[b&7]=wb(c,P()));break;case 2:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,kb(c,P()>>>0))):(c=k.c(b)>>>0,k.f(b,kb(c,P()>>>0)))):(c=y[b&7],e[b&7]=kb(c,P()>>>0));break;case 3:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,ob(c,P()>>>0))):
(c=k.c(b)>>>0,k.f(b,ob(c,P()>>>0)))):(c=y[b&7],e[b&7]=ob(c,P()>>>0));break;case 4:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d),H(b,d,ub(c,P()))):(c=k.c(b),k.f(b,ub(c,P())))):(c=e[b&7],e[b&7]=ub(c,P()));break;case 5:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,mb(c,P()>>>0))):(c=k.c(b)>>>0,k.f(b,mb(c,P()>>>0)))):(c=y[b&7],e[b&7]=mb(c,P()>>>0));break;case 6:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d),H(b,d,yb(c,P()))):(c=k.c(b),k.f(b,yb(c,P())))):(c=
e[b&7],e[b&7]=yb(c,P()));break;case 7:192>b?c=S(l(b))>>>0:c=y[b&7],Zb(c,P()>>>0)}};r[132]=s[132]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];id(c,v[b>>1&12|b>>5&1])};r[133]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];jd(c,g[b>>2&14])};s[133]=function(){var b=m(),c=192>b?S(l(b)):e[b&7];kd(c,e[b>>3&7])};r[134]=s[134]=function(){var b=m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,ne(c,b))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=ne(c,b))};r[135]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),
J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,Rd(c,b))):(c=k.b(d),k.a(d,Rd(c,b)))):(c=g[b<<1&14],g[b<<1&14]=Rd(c,b))};s[135]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,Sd(c,b))):(c=k.c(d)>>>0,k.f(d,Sd(c,b)))):(c=y[b&7],e[b&7]=Sd(c,b))};r[136]=s[136]=function(){var b=m();192>b?V(l(b),v[b>>1&12|b>>5&1]):v[b<<2&12|b>>2&1]=v[b>>1&12|b>>5&1]};r[137]=function(){var b=m();192>b?R(l(b),g[b>>2&14]):g[b<<1&14]=g[b>>2&14]};s[137]=function(){var b=m();192>b?N(l(b),
e[b>>3&7]):y[b&7]=e[b>>3&7]};r[138]=s[138]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];v[b>>1&12|b>>5&1]=c};r[139]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c};s[139]=function(){var b=m(),c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c};r[140]=function(){var b=m();192>b?R(l(b),ra[b>>3&7]):g[b<<1&14]=ra[b>>3&7]};s[140]=function(){var b=m();192>b?N(l(b),ra[b>>3&7]):y[b&7]=ra[b>>3&7]};r[141]=function(){var b=m();ab=6;g[(b>>3&7)<<1]=l(b);ab=-1};s[141]=function(){var b=m();ab=6;y[b>>3&
7]=l(b);ab=-1};r[142]=s[142]=function(){var b=m(),c=b>>3&7,b=192>b?Q(l(b)):g[b<<1&14];ca(c,b)};r[143]=s[143]=function(){var b=m();if(xa){var c=Va(0);$[aa]+=4;192>b?N(l(b),k.c(c)):y[b&7]=k.c(c)}else c=Va(0),$[aa]+=2,192>b?R(l(b),k.b(c)):g[b<<1&14]=k.b(c)};r[144]=function(){$b(0)};s[144]=function(){ac(0)};r[145]=function(){$b(2)};s[145]=function(){ac(1)};r[146]=function(){$b(4)};s[146]=function(){ac(2)};r[147]=function(){$b(6)};s[147]=function(){ac(3)};r[148]=function(){$b(8)};s[148]=function(){ac(4)};
r[149]=function(){$b(10)};s[149]=function(){ac(5)};r[150]=function(){$b(12)};s[150]=function(){ac(6)};r[151]=function(){$b(14)};s[151]=function(){ac(7)};r[144]=s[144]=function(){};r[152]=function(){g[0]=fc[0]};s[152]=function(){y[0]=Ga[0]};r[153]=function(){g[4]=Ga[0]>>15};s[153]=function(){y[2]=e[0]>>31};r[154]=function(){if(Ma)throw ze("16 bit callf in protected mode");var b=U(),c=U();la(ra[1]);la(pa());ca(1,c);E=da[1]+b|0};s[154]=function(){if(Ma)throw ze("callf");var b=M(),c=U();ia(ra[1]);ia(pa());
ca(1,c);E=da[1]+b|0};r[155]=s[155]=function(){};r[156]=function(){na();la(u)};s[156]=function(){na();ia(u)};r[157]=function(){var b;b=Aa();jc(b);Da()};s[157]=function(){jc(ua());Da()};r[158]=s[158]=function(){u=u&-256|v[1];u=u&4161493|2;K=0};r[159]=s[159]=function(){na();v[1]=u};r[160]=s[160]=function(){var b=ka(F());v[0]=b};r[161]=function(){var b=Q(F());g[0]=b};s[161]=function(){var b=S(F());y[0]=b};r[162]=s[162]=function(){V(F(),v[0])};r[163]=function(){R(F(),g[0])};s[163]=function(){N(F(),e[0])};
r[164]=s[164]=function(){var b,c,d=u&1024?-1:1;c=da[0]+A[T];b=h(3)+A[W];if(wa){if(0!==A[ga]){do V(c,ka(b)),c+=d,A[T]+=d,b+=d,A[W]+=d;while(--A[ga])}}else V(c,ka(b)),A[T]+=d,A[W]+=d};r[165]=function(){var b,c,d=u&1024?-2:2;c=da[0]+A[T];b=h(3)+A[W];if(wa){if(0!==A[ga]){var e=0===(c&1)&&0===(b&1);do{if(e){var g=Ea(b),l=q(c);k.S(l,k.q(g))}else R(c,Q(b));c+=d;A[T]+=d;b+=d;A[W]+=d}while(--A[ga])}}else R(c,Q(b)),A[T]+=d,A[W]+=d};s[165]=function(){var b,c,d=u&1024?-4:4;c=da[0]+A[T];b=h(3)+A[W];if(wa){if(0!==
A[ga]){var e=0===(c&3)&&0===(b&3);do{if(e){var g=Ea(b),l=q(c);k.D(l,k.v(g))}else N(c,S(b));c+=d;A[T]+=d;b+=d;A[W]+=d}while(--A[ga])}}else N(c,S(b)),A[T]+=d,A[W]+=d};r[166]=s[166]=function(){a:{var b,c,d,e,g=u&1024?-1:1;c=da[0]+A[T];b=h(3)+A[W];if(wa){if(0===A[ga])break a;do e=ka(c),d=ka(b),c+=g,A[T]+=g,b+=g,A[W]+=g;while(--A[ga]&&d===e===cc)}else e=ka(c),d=ka(b),A[T]+=g,A[W]+=g;lc(d,e)}};r[167]=function(){a:{var b,c,d,e,g=u&1024?-2:2;c=da[0]+A[T];b=h(3)+A[W];if(wa){if(0===A[ga])break a;var l=0===
(c&1)&&0===(b&1);do l?(e=k.q(Ea(c)),d=k.q(Ea(b))):(e=Q(c),d=Q(b)),c+=g,A[T]+=g,b+=g,A[W]+=g;while(--A[ga]&&d===e===cc)}else e=Q(c),d=Q(b),A[T]+=g,A[W]+=g;Yb(d,e)}};s[167]=function(){a:{var b,c,d,e,g=u&1024?-4:4;c=da[0]+A[T];b=h(3)+A[W];if(wa){if(0===A[ga])break a;var l=0===(c&3)&&0===(b&3);do l?(e=k.v(Ea(c))>>>0,d=k.v(Ea(b))>>>0):(e=S(c)>>>0,d=S(b)>>>0),c+=g,A[T]+=g,b+=g,A[W]+=g;while(--A[ga]&&d===e===cc)}else e=S(c)>>>0,d=S(b)>>>0,A[T]+=g,A[W]+=g;Zb(d,e)}};r[168]=s[168]=function(){id(v[0],m())};
r[169]=function(){jd(g[0],U())};s[169]=function(){kd(e[0],M())};r[170]=s[170]=function(){var b=v[0],c,d=u&1024?-1:1;c=da[0]+A[T];if(wa){if(0!==A[ga]){do V(c,b),c+=d,A[T]+=d;while(--A[ga])}}else V(c,b),A[T]+=d};r[171]=function(){var b=g[0],c,d=u&1024?-2:2;c=da[0]+A[T];if(wa){if(0!==A[ga]){var e=0===(c&1)&&!0;do e?k.S(q(c),b):R(c,b),c+=d,A[T]+=d;while(--A[ga])}}else R(c,b),A[T]+=d};s[171]=function(){var b=y[0],c,d=u&1024?-4:4;c=da[0]+A[T];if(wa){if(0!==A[ga]){var e=0===(c&3)&&!0;do e?k.D(q(c),b):N(c,
b),c+=d,A[T]+=d;while(--A[ga])}}else N(c,b),A[T]+=d};r[172]=s[172]=function(){var b,c=u&1024?-1:1;b=h(3)+A[W];if(wa){if(0!==A[ga]){do v[0]=ka(b),b+=c,A[W]+=c;while(--A[ga])}}else v[0]=ka(b),A[W]+=c};r[173]=function(){var b,c=u&1024?-2:2;b=h(3)+A[W];if(wa){if(0!==A[ga]){do g[0]=Q(b),b+=c,A[W]+=c;while(--A[ga])}}else g[0]=Q(b),A[W]+=c};s[173]=function(){var b,c=u&1024?-4:4;b=h(3)+A[W];if(wa){if(0!==A[ga]){do y[0]=S(b),b+=c,A[W]+=c;while(--A[ga])}}else y[0]=S(b),A[W]+=c};r[174]=s[174]=function(){a:{var b,
c,d,e=u&1024?-1:1;c=v[0];b=da[0]+A[T];if(wa){if(0===A[ga])break a;do d=ka(b),b+=e,A[T]+=e;while(--A[ga]&&c===d===cc)}else d=ka(b),A[T]+=e;lc(c,d)}};r[175]=function(){a:{var b,c,d,e=u&1024?-2:2;c=g[0];b=da[0]+A[T];if(wa){if(0===A[ga])break a;var h=0===(b&1)&&!0;do d=h?k.q(Ea(b)):Q(b),b+=e,A[T]+=e;while(--A[ga]&&c===d===cc)}else d=Q(b),A[T]+=e;Yb(c,d)}};s[175]=function(){a:{var b,c,d,e=u&1024?-4:4;c=y[0];b=da[0]+A[T];if(wa){if(0===A[ga])break a;var g=0===(b&3)&&!0;do d=g?k.v(Ea(b))>>>0:S(b)>>>0,b+=
e,A[T]+=e;while(--A[ga]&&c===d===cc)}else d=S(b)>>>0,A[T]+=e;Zb(c,d)}};r[176]=s[176]=function(){v[0]=m()};r[177]=s[177]=function(){v[4]=m()};r[178]=s[178]=function(){v[8]=m()};r[179]=s[179]=function(){v[12]=m()};r[180]=s[180]=function(){v[1]=m()};r[181]=s[181]=function(){v[5]=m()};r[182]=s[182]=function(){v[9]=m()};r[183]=s[183]=function(){v[13]=m()};r[184]=function(){g[0]=U()};s[184]=function(){e[0]=M()};r[185]=function(){g[2]=U()};s[185]=function(){e[1]=M()};r[186]=function(){g[4]=U()};s[186]=function(){e[2]=
M()};r[187]=function(){g[6]=U()};s[187]=function(){e[3]=M()};r[188]=function(){g[8]=U()};s[188]=function(){e[4]=M()};r[189]=function(){g[10]=U()};s[189]=function(){e[5]=M()};r[190]=function(){g[12]=U()};s[190]=function(){e[6]=M()};r[191]=function(){g[14]=U()};s[191]=function(){e[7]=M()};r[192]=s[192]=function(){var b=m();switch(b>>3&7){case 0:var c;192>b?(b=q(l(b)),c=k.d(b),k.e(b,Ac(c,m()&31))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Ac(c,m()&31));break;case 1:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Cc(c,
m()&31))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Cc(c,m()&31));break;case 2:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Bc(c,m()&31))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Bc(c,m()&31));break;case 3:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Dc(c,m()&31))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Dc(c,m()&31));break;case 4:192>b?(b=q(l(b)),c=k.d(b),k.e(b,gb(c,m()&31))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=gb(c,m()&31));break;case 5:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Ec(c,m()&31))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=
Ec(c,m()&31));break;case 6:192>b?(b=q(l(b)),c=k.d(b),k.e(b,gb(c,m()&31))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=gb(c,m()&31));break;case 7:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Fc(c,m()&31))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Fc(c,m()&31))}};r[193]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Hb(c,m()&31))):(c=k.b(b),k.a(b,Hb(c,m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Hb(c,m()&31));break;case 1:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?
(d=q(c+1),c=B(b,d),n(b,d,Lb(c,m()&31))):(c=k.b(b),k.a(b,Lb(c,m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Lb(c,m()&31));break;case 2:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Jb(c,m()&31))):(c=k.b(b),k.a(b,Jb(c,m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Jb(c,m()&31));break;case 3:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Nb(c,m()&31))):(c=k.b(b),k.a(b,Nb(c,m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Nb(c,m()&31));break;case 4:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),
c=B(b,d),n(b,d,Ja(c,m()&31))):(c=k.b(b),k.a(b,Ja(c,m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Ja(c,m()&31));break;case 5:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Pb(c,m()&31))):(c=k.b(b),k.a(b,Pb(c,m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Pb(c,m()&31));break;case 6:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Ja(c,m()&31))):(c=k.b(b),k.a(b,Ja(c,m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Ja(c,m()&31));break;case 7:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),
n(b,d,Rb(c,m()&31))):(c=k.b(b),k.a(b,Rb(c,m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Rb(c,m()&31))}};s[193]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Ib(c,m()&31))):(c=k.c(b)>>>0,k.f(b,Ib(c,m()&31)))):(c=y[b&7],e[b&7]=Ib(c,m()&31));break;case 1:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Mb(c,m()&31))):(c=k.c(b)>>>0,k.f(b,Mb(c,m()&31)))):(c=y[b&7],e[b&7]=Mb(c,m()&31));break;case 2:192>b?(c=l(b),b=q(c),J&&
4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Kb(c,m()&31))):(c=k.c(b)>>>0,k.f(b,Kb(c,m()&31)))):(c=y[b&7],e[b&7]=Kb(c,m()&31));break;case 3:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Ob(c,m()&31))):(c=k.c(b)>>>0,k.f(b,Ob(c,m()&31)))):(c=y[b&7],e[b&7]=Ob(c,m()&31));break;case 4:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Ka(c,m()&31))):(c=k.c(b)>>>0,k.f(b,Ka(c,m()&31)))):(c=y[b&7],e[b&7]=Ka(c,m()&31));break;case 5:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?
(d=q(c+3),c=G(b,d)>>>0,H(b,d,Qb(c,m()&31))):(c=k.c(b)>>>0,k.f(b,Qb(c,m()&31)))):(c=y[b&7],e[b&7]=Qb(c,m()&31));break;case 6:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Ka(c,m()&31))):(c=k.c(b)>>>0,k.f(b,Ka(c,m()&31)))):(c=y[b&7],e[b&7]=Ka(c,m()&31));break;case 7:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Sb(c,m()&31))):(c=k.c(b)>>>0,k.f(b,Sb(c,m()&31)))):(c=y[b&7],e[b&7]=Sb(c,m()&31))}};r[194]=function(){var b=U();E=da[1]+Aa()|0;y[4]+=b};s[194]=function(){var b=
U();E=da[1]+ua()|0;y[4]+=b};r[195]=function(){E=da[1]+Aa()|0};s[195]=function(){E=da[1]+ua()|0};r[196]=s[196]=function(){var b=m();192<=b?za(6):xa?Vc(0,l(b),b>>3&7):Uc(0,l(b),b>>2&14)};r[197]=s[197]=function(){var b=m();192<=b?za(6):xa?Vc(3,l(b),b>>3&7):Uc(3,l(b),b>>2&14)};r[198]=s[198]=function(){var b=m();192>b?V(l(b),m()):v[b<<2&12|b>>2&1]=m()};r[199]=function(){var b=m();192>b?R(l(b),U()):g[b<<1&14]=U()};s[199]=function(){var b=m();192>b?N(l(b),M()):y[b&7]=M()};r[200]=function(){var b=U(),c=m(),
d;la(g[10]);d=g[8];if(0<c){for(var e=1;e<c;e++)g[10]-=2,la(g[10]);la(d)}g[10]=d;g[8]=d-b};s[200]=function(){var b=U(),c=m()&31,d;ia(e[5]);d=e[4];if(0<c){for(var g=1;g<c;g++)y[5]-=4,ia(e[5]);ia(d)}y[5]=d;y[4]-=b};r[201]=function(){$[aa]=$[sc];g[10]=Aa()};s[201]=function(){$[aa]=$[sc];y[5]=ua()};r[202]=function(){if(Ma)throw ze("16 bit retf in protected mode");var b=U(),c=Aa();ca(1,Aa());E=da[1]+c|0;g[8]+=b};s[202]=function(){var b=U();if(Ma){var c=ua();ca(1,ua()&65535);E=da[1]+c|0;$[aa]+=b}else throw ze("32 bit retf in real mode");
};r[203]=function(){if(Ma)throw ze("16 bit retf in protected mode");var b=Aa();ca(1,Aa());E=da[1]+b|0};s[203]=function(){var b=ua();ca(1,ua()&65535);E=da[1]+b|0};r[204]=s[204]=function(){ha(3,!0,!1)};r[205]=s[205]=function(){var b=m();ha(b,!0,!1)};r[206]=s[206]=function(){Tc()&&ha(4,!0,!1)};r[207]=function(){if(Ma)throw ze("16 bit iret in protected mode");var b=Aa();ca(1,Aa());var c=Aa();E=b+da[1]|0;u=c;K=0;Da()};s[207]=function(){if(!Ma)throw ze("32 bit iret in real mode");E=ua();ra[1]=ua();var b=
ua(),c=Bb(ra[1]);if(c.A)throw ze("is null");if(!c.B)throw ze("not present");if(!c.F)throw ze("not exec");if(c.t<ya)throw ze("rpl < cpl");if(c.C&&c.l>c.t)throw ze("conforming and dpl > rpl");if(c.t>ya){var d=ua(),e=ua();y[4]=d;jc(b);ya=c.t;ca(2,e&65535);X()}else jc(b);Da()};r[208]=s[208]=function(){var b=m();switch(b>>3&7){case 0:var c;192>b?(b=q(l(b)),c=k.d(b),k.e(b,Ac(c,1))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Ac(c,1));break;case 1:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Cc(c,1))):(c=v[b<<2&12|b>>2&1],
v[b<<2&12|b>>2&1]=Cc(c,1));break;case 2:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Bc(c,1))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Bc(c,1));break;case 3:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Dc(c,1))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Dc(c,1));break;case 4:192>b?(b=q(l(b)),c=k.d(b),k.e(b,gb(c,1))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=gb(c,1));break;case 5:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Ec(c,1))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Ec(c,1));break;case 6:192>b?(b=q(l(b)),c=k.d(b),k.e(b,gb(c,1))):(c=v[b<<
2&12|b>>2&1],v[b<<2&12|b>>2&1]=gb(c,1));break;case 7:192>b?(b=q(l(b)),c=k.d(b),k.e(b,Fc(c,1))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Fc(c,1))}};r[209]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Hb(c,1))):(c=k.b(b),k.a(b,Hb(c,1)))):(c=g[b<<1&14],g[b<<1&14]=Hb(c,1));break;case 1:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Lb(c,1))):(c=k.b(b),k.a(b,Lb(c,1)))):(c=g[b<<1&14],g[b<<1&14]=Lb(c,1));break;case 2:192>
b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Jb(c,1))):(c=k.b(b),k.a(b,Jb(c,1)))):(c=g[b<<1&14],g[b<<1&14]=Jb(c,1));break;case 3:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Nb(c,1))):(c=k.b(b),k.a(b,Nb(c,1)))):(c=g[b<<1&14],g[b<<1&14]=Nb(c,1));break;case 4:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Ja(c,1))):(c=k.b(b),k.a(b,Ja(c,1)))):(c=g[b<<1&14],g[b<<1&14]=Ja(c,1));break;case 5:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),
n(b,d,Pb(c,1))):(c=k.b(b),k.a(b,Pb(c,1)))):(c=g[b<<1&14],g[b<<1&14]=Pb(c,1));break;case 6:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Ja(c,1))):(c=k.b(b),k.a(b,Ja(c,1)))):(c=g[b<<1&14],g[b<<1&14]=Ja(c,1));break;case 7:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Rb(c,1))):(c=k.b(b),k.a(b,Rb(c,1)))):(c=g[b<<1&14],g[b<<1&14]=Rb(c,1))}};s[209]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,
d,Ib(c,1))):(c=k.c(b)>>>0,k.f(b,Ib(c,1)))):(c=y[b&7],e[b&7]=Ib(c,1));break;case 1:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Mb(c,1))):(c=k.c(b)>>>0,k.f(b,Mb(c,1)))):(c=y[b&7],e[b&7]=Mb(c,1));break;case 2:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Kb(c,1))):(c=k.c(b)>>>0,k.f(b,Kb(c,1)))):(c=y[b&7],e[b&7]=Kb(c,1));break;case 3:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Ob(c,1))):(c=k.c(b)>>>0,k.f(b,Ob(c,1)))):(c=y[b&7],e[b&
7]=Ob(c,1));break;case 4:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Ka(c,1))):(c=k.c(b)>>>0,k.f(b,Ka(c,1)))):(c=y[b&7],e[b&7]=Ka(c,1));break;case 5:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Qb(c,1))):(c=k.c(b)>>>0,k.f(b,Qb(c,1)))):(c=y[b&7],e[b&7]=Qb(c,1));break;case 6:192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Ka(c,1))):(c=k.c(b)>>>0,k.f(b,Ka(c,1)))):(c=y[b&7],e[b&7]=Ka(c,1));break;case 7:192>b?(c=l(b),b=q(c),J&&4093<=(c&
4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Sb(c,1))):(c=k.c(b)>>>0,k.f(b,Sb(c,1)))):(c=y[b&7],e[b&7]=Sb(c,1))}};r[210]=s[210]=function(){var b=m(),c=v[4]&31;switch(b>>3&7){case 0:var d;192>b?(b=q(l(b)),d=k.d(b),k.e(b,Ac(d,c))):(d=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Ac(d,c));break;case 1:192>b?(b=q(l(b)),d=k.d(b),k.e(b,Cc(d,c))):(d=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Cc(d,c));break;case 2:192>b?(b=q(l(b)),d=k.d(b),k.e(b,Bc(d,c))):(d=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Bc(d,c));break;case 3:192>b?(b=q(l(b)),
d=k.d(b),k.e(b,Dc(d,c))):(d=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Dc(d,c));break;case 4:192>b?(b=q(l(b)),d=k.d(b),k.e(b,gb(d,c))):(d=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=gb(d,c));break;case 5:192>b?(b=q(l(b)),d=k.d(b),k.e(b,Ec(d,c))):(d=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Ec(d,c));break;case 6:192>b?(b=q(l(b)),d=k.d(b),k.e(b,gb(d,c))):(d=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=gb(d,c));break;case 7:192>b?(b=q(l(b)),d=k.d(b),k.e(b,Fc(d,c))):(d=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=Fc(d,c))}};r[211]=function(){var b=
m(),c=v[4]&31;switch(b>>3&7){case 0:var d,e;192>b?(d=l(b),b=q(d),J&&4095===(d&4095)?(e=q(d+1),d=B(b,e),n(b,e,Hb(d,c))):(d=k.b(b),k.a(b,Hb(d,c)))):(d=g[b<<1&14],g[b<<1&14]=Hb(d,c));break;case 1:192>b?(d=l(b),b=q(d),J&&4095===(d&4095)?(e=q(d+1),d=B(b,e),n(b,e,Lb(d,c))):(d=k.b(b),k.a(b,Lb(d,c)))):(d=g[b<<1&14],g[b<<1&14]=Lb(d,c));break;case 2:192>b?(d=l(b),b=q(d),J&&4095===(d&4095)?(e=q(d+1),d=B(b,e),n(b,e,Jb(d,c))):(d=k.b(b),k.a(b,Jb(d,c)))):(d=g[b<<1&14],g[b<<1&14]=Jb(d,c));break;case 3:192>b?(d=l(b),
b=q(d),J&&4095===(d&4095)?(e=q(d+1),d=B(b,e),n(b,e,Nb(d,c))):(d=k.b(b),k.a(b,Nb(d,c)))):(d=g[b<<1&14],g[b<<1&14]=Nb(d,c));break;case 4:192>b?(d=l(b),b=q(d),J&&4095===(d&4095)?(e=q(d+1),d=B(b,e),n(b,e,Ja(d,c))):(d=k.b(b),k.a(b,Ja(d,c)))):(d=g[b<<1&14],g[b<<1&14]=Ja(d,c));break;case 5:192>b?(d=l(b),b=q(d),J&&4095===(d&4095)?(e=q(d+1),d=B(b,e),n(b,e,Pb(d,c))):(d=k.b(b),k.a(b,Pb(d,c)))):(d=g[b<<1&14],g[b<<1&14]=Pb(d,c));break;case 6:192>b?(d=l(b),b=q(d),J&&4095===(d&4095)?(e=q(d+1),d=B(b,e),n(b,e,Ja(d,
c))):(d=k.b(b),k.a(b,Ja(d,c)))):(d=g[b<<1&14],g[b<<1&14]=Ja(d,c));break;case 7:192>b?(d=l(b),b=q(d),J&&4095===(d&4095)?(e=q(d+1),d=B(b,e),n(b,e,Rb(d,c))):(d=k.b(b),k.a(b,Rb(d,c)))):(d=g[b<<1&14],g[b<<1&14]=Rb(d,c))}};s[211]=function(){var b=m(),c=v[4]&31;switch(b>>3&7){case 0:var d,g;192>b?(d=l(b),b=q(d),J&&4093<=(d&4095)?(g=q(d+3),d=G(b,g)>>>0,H(b,g,Ib(d,c))):(d=k.c(b)>>>0,k.f(b,Ib(d,c)))):(d=y[b&7],e[b&7]=Ib(d,c));break;case 1:192>b?(d=l(b),b=q(d),J&&4093<=(d&4095)?(g=q(d+3),d=G(b,g)>>>0,H(b,g,
Mb(d,c))):(d=k.c(b)>>>0,k.f(b,Mb(d,c)))):(d=y[b&7],e[b&7]=Mb(d,c));break;case 2:192>b?(d=l(b),b=q(d),J&&4093<=(d&4095)?(g=q(d+3),d=G(b,g)>>>0,H(b,g,Kb(d,c))):(d=k.c(b)>>>0,k.f(b,Kb(d,c)))):(d=y[b&7],e[b&7]=Kb(d,c));break;case 3:192>b?(d=l(b),b=q(d),J&&4093<=(d&4095)?(g=q(d+3),d=G(b,g)>>>0,H(b,g,Ob(d,c))):(d=k.c(b)>>>0,k.f(b,Ob(d,c)))):(d=y[b&7],e[b&7]=Ob(d,c));break;case 4:192>b?(d=l(b),b=q(d),J&&4093<=(d&4095)?(g=q(d+3),d=G(b,g)>>>0,H(b,g,Ka(d,c))):(d=k.c(b)>>>0,k.f(b,Ka(d,c)))):(d=y[b&7],e[b&7]=
Ka(d,c));break;case 5:192>b?(d=l(b),b=q(d),J&&4093<=(d&4095)?(g=q(d+3),d=G(b,g)>>>0,H(b,g,Qb(d,c))):(d=k.c(b)>>>0,k.f(b,Qb(d,c)))):(d=y[b&7],e[b&7]=Qb(d,c));break;case 6:192>b?(d=l(b),b=q(d),J&&4093<=(d&4095)?(g=q(d+3),d=G(b,g)>>>0,H(b,g,Ka(d,c))):(d=k.c(b)>>>0,k.f(b,Ka(d,c)))):(d=y[b&7],e[b&7]=Ka(d,c));break;case 7:192>b?(d=l(b),b=q(d),J&&4093<=(d&4095)?(g=q(d+3),d=G(b,g)>>>0,H(b,g,Sb(d,c))):(d=k.c(b)>>>0,k.f(b,Sb(d,c)))):(d=y[b&7],e[b&7]=Sb(d,c))}};r[212]=s[212]=function(){var b=m();if(0===b)qa();
else{var c=v[0];v[1]=c/b;v[0]=c%b;I=v[0];K=2261}};r[213]=s[213]=function(){var b=m();I=v[0]+v[1]*b;g[0]=I&255;Y=8;K=2261};r[214]=s[214]=function(){throw ze("salc instruction");};r[215]=s[215]=function(){v[0]=Cb?ka(h(3)+e[3]+v[0]):ka(h(3)+g[6]+v[0])};r[216]=s[216]=function(){var b=m();192>b?Ha.i(b,l(b)):Ha.m(b)};r[217]=s[217]=function(){var b=m();192>b?Ha.q(b,l(b)):Ha.v(b)};r[218]=s[218]=function(){var b=m();192>b?Ha.D(b,l(b)):Ha.Q(b)};r[219]=s[219]=function(){var b=m();192>b?Ha.R(b,l(b)):Ha.S(b)};
r[220]=s[220]=function(){var b=m();192>b?Ha.aa(b,l(b)):Ha.Ga(b)};r[221]=s[221]=function(){var b=m();192>b?Ha.Ia(b,l(b)):Ha.Ka(b)};r[222]=s[222]=function(){var b=m();192>b?Ha.Ma(b,l(b)):Ha.Na(b)};r[223]=s[223]=function(){var b=m();192>b?Ha.Oa(b,l(b)):Ha.Ra(b)};r[224]=s[224]=function(){if(--A[ga]&&!Gb()){var b=P();E=E+b|0}else E++};r[225]=s[225]=function(){if(--A[ga]&&Gb()){var b=P();E=E+b|0}else E++};r[226]=s[226]=function(){if(--A[ga]){var b=P();E=E+b|0}else E++};r[227]=s[227]=function(){var b=P();
0===A[ga]&&(E=E+b|0)};r[228]=s[228]=function(){v[0]=hc(m())};r[229]=function(){g[0]=ic(m())};s[229]=function(){y[0]=cb(m())};r[230]=s[230]=function(){Fa(m(),v[0])};r[231]=function(){Xb(m(),g[0])};s[231]=function(){gc(m(),e[0])};r[232]=function(){var b=U()<<16>>16;la(pa());Qd(b)};s[232]=function(){var b=M();ia(pa());E=E+b|0};r[233]=function(){var b=U()<<16>>16;Qd(b)};s[233]=function(){var b=M();E=E+b|0};r[234]=function(){var b=U();ca(1,U());E=b+da[1]|0};s[234]=function(){var b=M();ca(1,U());E=b+da[1]|
0};r[235]=s[235]=function(){var b=P();E=E+b|0};r[236]=s[236]=function(){v[0]=hc(g[4])};r[237]=function(){g[0]=ic(g[4])};s[237]=function(){y[0]=cb(g[4])};r[238]=s[238]=function(){Fa(g[4],v[0])};r[239]=function(){Xb(g[4],g[0])};s[239]=function(){gc(g[4],e[0])};r[240]=s[240]=function(){};r[241]=s[241]=function(){throw ze("int1 instruction");};r[242]=s[242]=function(){wa=!0;cc=!1;Ab[m()]();wa=!1};r[243]=s[243]=function(){cc=wa=!0;Ab[m()]();wa=!1};r[244]=s[244]=function(){ya&&fa(0);if(0===(u&512))throw nc("cpu halted"),
oc=!0,"HALT";E--;fd=!0};r[245]=s[245]=function(){u=(u|1)^Ba();K&=-2};r[246]=s[246]=function(){var b=m();switch(b>>3&7){case 0:var c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];id(c,m());break;case 1:c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];id(c,m());break;case 2:192>b?(b=q(l(b)),c=k.d(b),k.e(b,~c)):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=~c);break;case 3:192>b?(b=q(l(b)),c=k.d(b),k.e(b,le(c))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=le(c));break;case 4:c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];c=c*v[0];g[0]=c;u=256>c?u&-2050:
u|2049;K=0;break;case 5:c=192>b?Rc(l(b)):fc[b<<2&12|b>>2&1];c=c*fc[0];g[0]=c;u=127<c||-128>c?u|2049:u&-2050;K=0;break;case 6:var c=192>b?ka(l(b)):v[b<<2&12|b>>2&1],b=g[0],d=b/c|0;255<d||0===c?qa():(v[0]=d,v[1]=b%c);break;case 7:c=192>b?Rc(l(b)):fc[b<<2&12|b>>2&1],b=Ga[0],d=b/c|0,127<d||-128>d||0===c?qa():(v[0]=d,v[1]=b%c)}};r[247]=function(){var b=m();switch(b>>3&7){case 0:var c=192>b?Q(l(b)):g[b<<1&14];jd(c,U());break;case 1:c=192>b?Q(l(b)):g[b<<1&14];jd(c,U());break;case 2:var d;192>b?(c=l(b),b=
q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,~c)):(c=k.b(b),k.a(b,~c))):(c=g[b<<1&14],g[b<<1&14]=~c);break;case 3:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,Kd(c))):(c=k.b(b),k.a(b,Kd(c)))):(c=g[b<<1&14],g[b<<1&14]=Kd(c));break;case 4:c=192>b?Q(l(b)):g[b<<1&14];c=c*g[0];b=c>>>16;g[0]=c;g[4]=b;u=0===b?u&-2050:u|2049;K=0;break;case 5:192>b?c=Q(l(b))<<16>>16:c=Ga[b<<1&14];c=c*Ga[0];g[0]=c;g[4]=c>>16;u=32767<c||-32768>c?u|2049:u&-2050;K=0;break;case 6:c=192>b?Q(l(b)):g[b<<1&
14];b=(g[0]|g[4]<<16)>>>0;d=b/c|0;65535<d||0===c?qa():(g[0]=d,g[4]=b%c);break;case 7:192>b?c=Q(l(b))<<16>>16:c=Ga[b<<1&14],b=g[0]|g[4]<<16,d=b/c|0,32767<d||-32768>d||0===c?qa():(g[0]=d,g[4]=b%c)}};s[247]=function(){var b=m();switch(b>>3&7){case 0:var c=192>b?S(l(b)):e[b&7];kd(c,M());break;case 1:c=192>b?S(l(b)):e[b&7];kd(c,M());break;case 2:var d;192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,~c)):(c=k.c(b)>>>0,k.f(b,~c))):(c=y[b&7],e[b&7]=~c);break;case 3:192>b?(c=l(b),b=q(c),
J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,Ld(c))):(c=k.c(b)>>>0,k.f(b,Ld(c)))):(c=y[b&7],e[b&7]=Ld(c));break;case 4:192>b?c=S(l(b))>>>0:c=y[b&7];b=y[0];d=c*b/4294967296|0;y[0]=Z(c,b);y[2]=d;u=0===d?u&-2050:u|2049;K=0;break;case 5:b=c=192>b?S(l(b)):e[b&7];d=e[0];c=b*d/4294967296|0;b=Z(b,d);0===c&&0>b&&(c=-1);y[0]=b;y[2]=c;u=c===(2147483648>y[0]?0:-1)?u&-2050:u|2049;K=0;break;case 6:192>b?c=S(l(b))>>>0:c=y[b&7];d=y[0];var g=y[2],b=(4294967296*g%c+d%c)%c;d=d/c+4294967296*g/c;4294967295<d||0===c?
qa():(y[0]=d,y[2]=b);break;case 7:c=192>b?S(l(b)):e[b&7],d=y[0],g=e[2],b=(4294967296*g%c+d%c)%c,d=d/c+4294967296*g/c,2147483647<d||-2147483648>d||0===c?qa():(y[0]=d,y[2]=b)}};r[248]=s[248]=function(){u&=-2;K&=-2};r[249]=s[249]=function(){u|=1;K&=-2};r[250]=s[250]=function(){$a()?u&=-513:fa(0)};r[251]=s[251]=function(){$a()?(u|=512,Da()):fa(0)};r[252]=s[252]=function(){u&=-1025};r[253]=s[253]=function(){u|=1024};r[254]=s[254]=function(){var b=m(),c=b&56;0===c?192>b?(b=q(l(b)),c=k.d(b),k.e(b,je(c))):
(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=je(c)):8===c?192>b?(b=q(l(b)),c=k.d(b),k.e(b,ke(c))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=ke(c)):z()};r[255]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,pb(c))):(c=k.b(b),k.a(b,pb(c)))):(c=g[b<<1&14],g[b<<1&14]=pb(c));break;case 1:192>b?(c=l(b),b=q(c),J&&4095===(c&4095)?(d=q(c+1),c=B(b,d),n(b,d,rb(c))):(c=k.b(b),k.a(b,rb(c)))):(c=g[b<<1&14],g[b<<1&14]=rb(c));break;case 2:c=192>b?Q(l(b)):
g[b<<1&14];la(pa());E=da[1]+c|0;break;case 3:192<=b&&za(6);c=l(b);la(ra[1]);la(pa());ca(1,Q(c+2));E=da[1]+Q(c)|0;break;case 4:c=192>b?Q(l(b)):g[b<<1&14];E=da[1]+c|0;break;case 5:192<=b&&za(6);c=l(b);ca(1,Q(c+2));E=da[1]+Q(c)|0;break;case 6:c=192>b?Q(l(b)):g[b<<1&14];la(c);break;case 7:z()}};s[255]=function(){var b=m();switch(b>>3&7){case 0:var c,d;192>b?(c=l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,qb(c))):(c=k.c(b)>>>0,k.f(b,qb(c)))):(c=y[b&7],e[b&7]=qb(c));break;case 1:192>b?(c=
l(b),b=q(c),J&&4093<=(c&4095)?(d=q(c+3),c=G(b,d)>>>0,H(b,d,sb(c))):(c=k.c(b)>>>0,k.f(b,sb(c)))):(c=y[b&7],e[b&7]=sb(c));break;case 2:c=192>b?S(l(b)):e[b&7];ia(pa());E=da[1]+c|0;break;case 3:192<=b&&za(6);c=l(b);b=Q(c+4);c=S(c);ia(ra[1]);ia(pa());ca(1,b);E=da[1]+c|0;break;case 4:c=192>b?S(l(b)):e[b&7];E=da[1]+c|0;break;case 5:192<=b&&za(6);c=l(b);b=Q(c+4);c=S(c);ca(1,b);E=da[1]+c|0;break;case 6:c=192>b?S(l(b)):e[b&7];ia(c);break;case 7:z()}};x[0]=w[0]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];
Ma||z();ya&&fa(0);switch(b>>3&7){case 2:b=Bb(c);if(b.A)Zc=$c=0;else{if(!b.ga)throw ze("LDTR can only be loaded from GDT");if(!b.B)throw ze("#GP handler");if(!b.L)throw ze("#GP handler");if(2!==b.type)throw ze("#GP handler");$c=b.V;Zc=b.W}break;case 3:b=Bb(c);if(!b.ga)throw ze("TR can only be loaded from GDT");if(b.A)throw ze("#GP handler");if(!b.B)throw ze("#GP handler");if(!b.L)throw ze("#GP handler");if(9!==b.type)throw ze("#GP handler");Ed=b.V;Dd=b.W;break;default:z()}};x[1]=w[1]=function(){var b=
m();ya&&fa(0);var c=b>>3&7;if(4===c)192>b?R(l(b),Na):g[b<<1&14]=Na;else if(6===c)c=192>b?Q(l(b)):g[b<<1&14],Na=Na&-16|c&15,O();else switch(192<=b&&za(6),2!==c&&3!==c||!Ma||(ab=6),b=l(b),ab=-1,c){case 0:R(b,ad);N(b+2,qc);break;case 1:R(b,bd);N(b+2,rc);break;case 2:c=Q(b);b=S(b+2);ad=c;qc=b;xa||(qc&=16777215);break;case 3:c=Q(b);b=S(b+2);bd=c;rc=b;xa||(rc&=16777215);break;case 7:c=b>>>12;Eb[c]=0;pc[c]=0;Fb=-1;break;default:z()}};x[2]=w[2]=function(){m();z()};x[3]=w[3]=function(){m();z()};x[4]=w[4]=
function(){z()};x[5]=w[5]=function(){z()};x[6]=w[6]=function(){ya?fa(0):Na&=-9};x[7]=w[7]=function(){z()};x[8]=w[8]=function(){z()};x[9]=w[9]=function(){ya&&fa(0)};x[10]=w[10]=function(){z()};x[11]=w[11]=function(){z()};x[12]=w[12]=function(){z()};x[13]=w[13]=function(){z()};x[14]=w[14]=function(){z()};x[15]=w[15]=function(){z()};x[16]=w[16]=function(){z()};x[17]=w[17]=function(){z()};x[18]=w[18]=function(){z()};x[19]=w[19]=function(){z()};x[20]=w[20]=function(){z()};x[21]=w[21]=function(){z()};x[22]=
w[22]=function(){z()};x[23]=w[23]=function(){z()};x[24]=w[24]=function(){var b=m();xa?192>b&&S(l(b)):192>b&&Q(l(b))};x[25]=w[25]=function(){z()};x[26]=w[26]=function(){z()};x[27]=w[27]=function(){z()};x[28]=w[28]=function(){z()};x[29]=w[29]=function(){z()};x[30]=w[30]=function(){z()};x[31]=w[31]=function(){z()};x[32]=w[32]=function(){var b=m();ya&&fa(0);switch(b>>3&7){case 0:y[b&7]=Na;break;case 2:y[b&7]=Ub;break;case 3:y[b&7]=cd;break;case 4:y[b&7]=Oc;break;default:z()}};x[33]=w[33]=function(){m();
ya&&fa(0)};x[34]=w[34]=function(){var b=m();ya&&fa(0);var c=y[b&7];switch(b>>3&7){case 0:if(-2147483648===(c&2147483649))throw ze("#GP handler");Na&2147483648&&!(c&2147483648)&&(pc=new Uint8Array(1048576),tc());Na=c;O();break;case 3:cd=c;tc();break;case 4:(Oc^c)&128&&(pc=new Uint8Array(1048576),tc());Oc=c;Fd=Oc&16?128:0;break;default:z()}};x[35]=w[35]=function(){m();ya&&fa(0)};x[36]=w[36]=function(){z()};x[37]=w[37]=function(){z()};x[38]=w[38]=function(){z()};x[39]=w[39]=function(){z()};x[40]=w[40]=
function(){z()};x[41]=w[41]=function(){z()};x[42]=w[42]=function(){z()};x[43]=w[43]=function(){z()};x[44]=w[44]=function(){z()};x[45]=w[45]=function(){z()};x[46]=w[46]=function(){z()};x[47]=w[47]=function(){z()};x[48]=w[48]=function(){z()};x[49]=w[49]=function(){y[0]=ed;y[2]=ed/4294967296};x[50]=w[50]=function(){z()};x[51]=w[51]=function(){z()};x[52]=w[52]=function(){z()};x[53]=w[53]=function(){z()};x[54]=w[54]=function(){z()};x[55]=w[55]=function(){z()};x[56]=w[56]=function(){z()};x[57]=w[57]=function(){z()};
x[58]=w[58]=function(){z()};x[59]=w[59]=function(){z()};x[60]=w[60]=function(){z()};x[61]=w[61]=function(){z()};x[62]=w[62]=function(){z()};x[63]=w[63]=function(){z()};x[64]=function(){var b=m();if(Ya()){var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}else 192>b&&l(b)};w[64]=function(){var b=m();if(Ya()){var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}else 192>b&&l(b)};x[65]=function(){var b=m();if(Ya())192>b&&l(b);else{var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}};w[65]=function(){var b=m();if(Ya())192>b&&l(b);
else{var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}};x[66]=function(){var b=m();if(Ra()){var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}else 192>b&&l(b)};w[66]=function(){var b=m();if(Ra()){var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}else 192>b&&l(b)};x[67]=function(){var b=m();if(Ra())192>b&&l(b);else{var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}};w[67]=function(){var b=m();if(Ra())192>b&&l(b);else{var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}};x[68]=function(){var b=m();if(Sa()){var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&
14]=c}else 192>b&&l(b)};w[68]=function(){var b=m();if(Sa()){var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}else 192>b&&l(b)};x[69]=function(){var b=m();if(Sa())192>b&&l(b);else{var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}};w[69]=function(){var b=m();if(Sa())192>b&&l(b);else{var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}};x[70]=function(){var b=m();if(Qa()){var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}else 192>b&&l(b)};w[70]=function(){var b=m();if(Qa()){var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}else 192>b&&l(b)};x[71]=
function(){var b=m();if(Qa())192>b&&l(b);else{var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}};w[71]=function(){var b=m();if(Qa())192>b&&l(b);else{var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}};x[72]=function(){var b=m();if(Za()){var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}else 192>b&&l(b)};w[72]=function(){var b=m();if(Za()){var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}else 192>b&&l(b)};x[73]=function(){var b=m();if(Za())192>b&&l(b);else{var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}};w[73]=function(){var b=m();
if(Za())192>b&&l(b);else{var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}};x[74]=function(){var b=m();if(Ta()){var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}else 192>b&&l(b)};w[74]=function(){var b=m();if(Ta()){var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}else 192>b&&l(b)};x[75]=function(){var b=m();if(Ta())192>b&&l(b);else{var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}};w[75]=function(){var b=m();if(Ta())192>b&&l(b);else{var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}};x[76]=function(){var b=m();if(Wa()){var c=192>b?Q(l(b)):
g[b<<1&14];g[b>>2&14]=c}else 192>b&&l(b)};w[76]=function(){var b=m();if(Wa()){var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}else 192>b&&l(b)};x[77]=function(){var b=m();if(Wa())192>b&&l(b);else{var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}};w[77]=function(){var b=m();if(Wa())192>b&&l(b);else{var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}};x[78]=function(){var b=m();if(Xa()){var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}else 192>b&&l(b)};w[78]=function(){var b=m();if(Xa()){var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}else 192>
b&&l(b)};x[79]=function(){var b=m();if(Xa())192>b&&l(b);else{var c=192>b?Q(l(b)):g[b<<1&14];g[b>>2&14]=c}};w[79]=function(){var b=m();if(Xa())192>b&&l(b);else{var c=192>b?S(l(b)):e[b&7];e[b>>3&7]=c}};x[80]=w[80]=function(){z()};x[81]=w[81]=function(){z()};x[82]=w[82]=function(){z()};x[83]=w[83]=function(){z()};x[84]=w[84]=function(){z()};x[85]=w[85]=function(){z()};x[86]=w[86]=function(){z()};x[87]=w[87]=function(){z()};x[88]=w[88]=function(){z()};x[89]=w[89]=function(){z()};x[90]=w[90]=function(){z()};
x[91]=w[91]=function(){z()};x[92]=w[92]=function(){z()};x[93]=w[93]=function(){z()};x[94]=w[94]=function(){z()};x[95]=w[95]=function(){z()};x[96]=w[96]=function(){z()};x[97]=w[97]=function(){z()};x[98]=w[98]=function(){z()};x[99]=w[99]=function(){z()};x[100]=w[100]=function(){z()};x[101]=w[101]=function(){z()};x[102]=w[102]=function(){z()};x[103]=w[103]=function(){z()};x[104]=w[104]=function(){z()};x[105]=w[105]=function(){z()};x[106]=w[106]=function(){z()};x[107]=w[107]=function(){z()};x[108]=w[108]=
function(){z()};x[109]=w[109]=function(){z()};x[110]=w[110]=function(){z()};x[111]=w[111]=function(){z()};x[112]=w[112]=function(){z()};x[113]=w[113]=function(){z()};x[114]=w[114]=function(){z()};x[115]=w[115]=function(){z()};x[116]=w[116]=function(){z()};x[117]=w[117]=function(){z()};x[118]=w[118]=function(){z()};x[119]=w[119]=function(){z()};x[120]=w[120]=function(){z()};x[121]=w[121]=function(){z()};x[122]=w[122]=function(){z()};x[123]=w[123]=function(){z()};x[124]=w[124]=function(){z()};x[125]=
w[125]=function(){z()};x[126]=w[126]=function(){z()};x[127]=w[127]=function(){z()};x[128]=function(){Oa(Ya())};w[128]=function(){Pa(Ya())};x[129]=function(){Oa(!Ya())};w[129]=function(){Pa(!Ya())};x[130]=function(){Oa(Ra())};w[130]=function(){Pa(Ra())};x[131]=function(){Oa(!Ra())};w[131]=function(){Pa(!Ra())};x[132]=function(){Oa(Sa())};w[132]=function(){Pa(Sa())};x[133]=function(){Oa(!Sa())};w[133]=function(){Pa(!Sa())};x[134]=function(){Oa(Qa())};w[134]=function(){Pa(Qa())};x[135]=function(){Oa(!Qa())};
w[135]=function(){Pa(!Qa())};x[136]=function(){Oa(Za())};w[136]=function(){Pa(Za())};x[137]=function(){Oa(!Za())};w[137]=function(){Pa(!Za())};x[138]=function(){Oa(Ta())};w[138]=function(){Pa(Ta())};x[139]=function(){Oa(!Ta())};w[139]=function(){Pa(!Ta())};x[140]=function(){Oa(Wa())};w[140]=function(){Pa(Wa())};x[141]=function(){Oa(!Wa())};w[141]=function(){Pa(!Wa())};x[142]=function(){Oa(Xa())};w[142]=function(){Pa(Xa())};x[143]=function(){Oa(!Xa())};w[143]=function(){Pa(!Xa())};x[144]=w[144]=function(){var b=
m();192>b?V(l(b),!Ya()^1):v[b<<2&12|b>>2&1]=!Ya()^1};x[145]=w[145]=function(){var b=m();192>b?V(l(b),!!Ya()^1):v[b<<2&12|b>>2&1]=!!Ya()^1};x[146]=w[146]=function(){var b=m();192>b?V(l(b),!Ra()^1):v[b<<2&12|b>>2&1]=!Ra()^1};x[147]=w[147]=function(){var b=m();192>b?V(l(b),!!Ra()^1):v[b<<2&12|b>>2&1]=!!Ra()^1};x[148]=w[148]=function(){var b=m();192>b?V(l(b),!Sa()^1):v[b<<2&12|b>>2&1]=!Sa()^1};x[149]=w[149]=function(){var b=m();192>b?V(l(b),!!Sa()^1):v[b<<2&12|b>>2&1]=!!Sa()^1};x[150]=w[150]=function(){var b=
m();192>b?V(l(b),!Qa()^1):v[b<<2&12|b>>2&1]=!Qa()^1};x[151]=w[151]=function(){var b=m();192>b?V(l(b),!!Qa()^1):v[b<<2&12|b>>2&1]=!!Qa()^1};x[152]=w[152]=function(){var b=m();192>b?V(l(b),!Za()^1):v[b<<2&12|b>>2&1]=!Za()^1};x[153]=w[153]=function(){var b=m();192>b?V(l(b),!!Za()^1):v[b<<2&12|b>>2&1]=!!Za()^1};x[154]=w[154]=function(){var b=m();192>b?V(l(b),!Ta()^1):v[b<<2&12|b>>2&1]=!Ta()^1};x[155]=w[155]=function(){var b=m();192>b?V(l(b),!!Ta()^1):v[b<<2&12|b>>2&1]=!!Ta()^1};x[156]=w[156]=function(){var b=
m();192>b?V(l(b),!Wa()^1):v[b<<2&12|b>>2&1]=!Wa()^1};x[157]=w[157]=function(){var b=m();192>b?V(l(b),!!Wa()^1):v[b<<2&12|b>>2&1]=!!Wa()^1};x[158]=w[158]=function(){var b=m();192>b?V(l(b),!Xa()^1):v[b<<2&12|b>>2&1]=!Xa()^1};x[159]=w[159]=function(){var b=m();192>b?V(l(b),!!Xa()^1):v[b<<2&12|b>>2&1]=!!Xa()^1};x[160]=function(){la(ra[4])};w[160]=function(){ia(ra[4])};x[161]=function(){ca(4,k.b(Va(0)));$[aa]+=2};w[161]=function(){ca(4,k.b(Va(0)));$[aa]+=4};x[162]=w[162]=function(){var b=e[0];0===(b&2147483647)?
(y[0]=2,0===b&&(y[3]=1970169159,y[2]=1231384169,y[1]=1818588270)):1===b?(y[0]=1299,y[3]=0,y[1]=0,y[2]=Ha.a|41240):2===b?(y[0]=1717260289,y[3]=0,y[1]=0,y[2]=8024064):-2138701824===b&&(y[0]=0,y[3]=0,y[1]=0,y[2]=0)};x[163]=w[163]=function(){var b=m();xa?192>b?pd(l(b),e[b>>3&7]):ld(y[b&7],y[b>>3&7]&31):192>b?pd(l(b),Ga[b>>2&14]):ld(g[b<<1&14],g[b>>2&14]&15)};x[164]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,Ic(c,g[b>>2&14],m()&31))):(c=k.b(d),k.a(d,Ic(c,
g[b>>2&14],m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Ic(c,g[b>>2&14],m()&31))};w[164]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,Jc(c,y[b>>3&7],m()&31))):(c=k.c(d)>>>0,k.f(d,Jc(c,y[b>>3&7],m()&31)))):(c=y[b&7],e[b&7]=Jc(c,y[b>>3&7],m()&31))};x[165]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,Ic(c,g[b>>2&14],v[4]&31))):(c=k.b(d),k.a(d,Ic(c,g[b>>2&14],v[4]&31)))):(c=g[b<<1&14],g[b<<1&14]=Ic(c,g[b>>2&14],v[4]&
31))};w[165]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,Jc(c,y[b>>3&7],v[4]&31))):(c=k.c(d)>>>0,k.f(d,Jc(c,y[b>>3&7],v[4]&31)))):(c=y[b&7],e[b&7]=Jc(c,y[b>>3&7],v[4]&31))};x[166]=w[166]=function(){z()};x[167]=w[167]=function(){z()};x[168]=function(){la(ra[5])};w[168]=function(){ia(ra[5])};x[169]=function(){ca(5,k.b(Va(0)));$[aa]+=2};w[169]=function(){ca(5,k.b(Va(0)));$[aa]+=4};x[170]=w[170]=function(){z()};x[171]=w[171]=function(){var b=m();xa?192>
b?sd(l(b),e[b>>3&7]):y[b&7]=nd(e[b&7],e[b>>3&7]&31):192>b?sd(l(b),Ga[b>>2&14]):g[b<<1&14]=nd(g[b<<1&14],Ga[b>>2&14]&15)};x[172]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,Gc(c,g[b>>2&14],m()&31))):(c=k.b(d),k.a(d,Gc(c,g[b>>2&14],m()&31)))):(c=g[b<<1&14],g[b<<1&14]=Gc(c,g[b>>2&14],m()&31))};w[172]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,Hc(c,y[b>>3&7],m()&31))):(c=k.c(d)>>>0,k.f(d,Hc(c,y[b>>3&7],
m()&31)))):(c=y[b&7],e[b&7]=Hc(c,y[b>>3&7],m()&31))};x[173]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,Gc(c,g[b>>2&14],v[4]&31))):(c=k.b(d),k.a(d,Gc(c,g[b>>2&14],v[4]&31)))):(c=g[b<<1&14],g[b<<1&14]=Gc(c,g[b>>2&14],v[4]&31))};w[173]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,Hc(c,y[b>>3&7],v[4]&31))):(c=k.c(d)>>>0,k.f(d,Hc(c,y[b>>3&7],v[4]&31)))):(c=y[b&7],e[b&7]=Hc(c,y[b>>3&7],v[4]&31))};x[174]=w[174]=
function(){z()};x[175]=function(){var b=m(),c=192>b?Q(l(b))<<16>>16:Ga[b<<1&14];g[b>>2&14]=Md(Ga[b>>2&14],c)};w[175]=function(){var b=m(),c=192>b?S(l(b)):e[b&7];y[b>>3&7]=Nd(e[b>>3&7],c)};x[176]=w[176]=function(){var b=m();if(192>b)var c=l(b),d=ka(c);else d=v[b<<2&12|b>>2&1];lc(d,v[0]);Gb()?192>b?V(c,v[b>>1&12|b>>5&1]):v[b<<2&12|b>>2&1]=v[b>>1&12|b>>5&1]:v[0]=d};x[177]=w[177]=function(){var b=m();if(xa){if(192>b)var c=l(b),d=S(c)>>>0;else d=y[b&7];Zb(d,y[0]);Gb()?192>b?N(c,y[b>>3&7]):y[b&7]=y[b>>
3&7]:y[0]=d}else 192>b?(c=l(b),d=Q(c)):d=g[b<<1&14],Yb(d,g[0]),Gb()?192>b?R(c,g[b>>2&14]):g[b<<1&14]=g[b>>2&14]:g[0]=d};x[178]=w[178]=function(){var b=m();192<=b?za(6):xa?Vc(2,l(b),b>>3&7):Uc(2,l(b),b>>2&14)};x[179]=w[179]=function(){var b=m();xa?192>b?rd(l(b),e[b>>3&7]):y[b&7]=od(e[b&7],e[b>>3&7]&31):192>b?rd(l(b),Ga[b>>2&14]):g[b<<1&14]=od(g[b<<1&14],Ga[b>>2&14]&15)};x[180]=w[180]=function(){var b=m();192<=b?za(6):xa?Vc(4,l(b),b>>3&7):Uc(4,l(b),b>>2&14)};x[181]=w[181]=function(){var b=m();192<=
b?za(6):xa?Vc(5,l(b),b>>3&7):Uc(5,l(b),b>>2&14)};x[182]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];g[b>>2&14]=c};w[182]=function(){var b=m(),c=192>b?ka(l(b)):v[b<<2&12|b>>2&1];y[b>>3&7]=c};x[183]=w[183]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14];y[b>>3&7]=c};x[184]=w[184]=function(){z()};x[185]=w[185]=function(){z()};x[186]=w[186]=function(){var b=m();switch(b>>3&7){case 4:xa?192>b?pd(l(b),m()&31):ld(y[b&7],m()&31):192>b?pd(l(b),m()&31):ld(g[b<<1&14],m()&15);break;case 5:xa?192>
b?sd(l(b),m()&31):y[b&7]=nd(e[b&7],m()&31):192>b?sd(l(b),m()&31):g[b<<1&14]=nd(g[b<<1&14],m()&15);break;case 6:xa?192>b?rd(l(b),m()&31):y[b&7]=od(e[b&7],m()&31):192>b?rd(l(b),m()&31):g[b<<1&14]=od(g[b<<1&14],m()&15);break;case 7:xa?192>b?qd(l(b),m()&31):y[b&7]=md(e[b&7],m()&31):192>b?qd(l(b),m()&31):g[b<<1&14]=md(g[b<<1&14],m()&15);break;default:z()}};x[187]=w[187]=function(){var b=m();xa?192>b?qd(l(b),e[b>>3&7]):y[b&7]=md(e[b&7],e[b>>3&7]&31):192>b?qd(l(b),Ga[b>>2&14]):g[b<<1&14]=md(g[b<<1&14],Ga[b>>
2&14]&15)};x[188]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14],d=g;var e=g[b>>2&14];K=0;0===c?(u|=64,c=e):(u&=-65,c=oe[((-c&c)>>>0)%37]);d[b>>2&14]=c};w[188]=function(){var b=m(),c=192>b?S(l(b)):e[b&7],d=y;var g=y[b>>3&7];K=0;0===c?(u|=64,c=g):(u&=-65,c=oe[((-c&c)>>>0)%37]);d[b>>3&7]=c};x[189]=function(){var b=m(),c=192>b?Q(l(b)):g[b<<1&14],d=g;var e=g[b>>2&14];K=0;0===c?(u|=64,c=e):(u&=-65,c=(e=c>>>8)?8+Ae[e]:Ae[c]);d[b>>2&14]=c};w[189]=function(){var b=m(),c=192>b?S(l(b)):e[b&7],d=y;var g=y[b>>
3&7];K=0;if(0===c)u|=64,c=g;else{u&=-65;var g=c>>>16,k;c=g?(k=g>>>8)?24+Ae[k]:16+Ae[g]:(k=c>>>8)?8+Ae[k]:Ae[c]}d[b>>3&7]=c};x[190]=function(){var b=m(),c=192>b?Rc(l(b)):fc[b<<2&12|b>>2&1];g[b>>2&14]=c};w[190]=function(){var b=m(),c=192>b?Rc(l(b)):fc[b<<2&12|b>>2&1];e[b>>3&7]=c};x[191]=w[191]=function(){var b=m(),c=192>b?Q(l(b))<<16>>16:Ga[b<<1&14];e[b>>3&7]=c};x[192]=w[192]=function(){var b=m(),c,d;192>b?(d=q(l(b)),c=k.d(d),k.e(d,me(c,b>>1&12|b>>5&1))):(c=v[b<<2&12|b>>2&1],v[b<<2&12|b>>2&1]=me(c,
b>>1&12|b>>5&1))};x[193]=function(){var b=m(),c,d,e;192>b?(c=l(b),d=q(c),J&&4095===(c&4095)?(e=q(c+1),c=B(d,e),n(d,e,Od(c,b>>2&14))):(c=k.b(d),k.a(d,Od(c,b>>2&14)))):(c=g[b<<1&14],g[b<<1&14]=Od(c,b>>2&14))};w[193]=function(){var b=m(),c,d,g;192>b?(c=l(b),d=q(c),J&&4093<=(c&4095)?(g=q(c+3),c=G(d,g)>>>0,H(d,g,Pd(c,b>>3&7))):(c=k.c(d)>>>0,k.f(d,Pd(c,b>>3&7)))):(c=y[b&7],e[b&7]=Pd(c,b>>3&7))};x[194]=w[194]=function(){z()};x[195]=w[195]=function(){z()};x[196]=w[196]=function(){z()};x[197]=w[197]=function(){z()};
x[198]=w[198]=function(){z()};x[199]=w[199]=function(){var b=m(),b=l(b),c=S(b)>>>0,d=S(b+4)>>>0;y[0]===c&&y[2]===d?(u|=64,N(b,y[3]),N(b+4,y[1])):(u&=-65,y[0]=c,y[2]=d);K&=-65};x[200]=w[200]=function(){bc(0)};x[201]=w[201]=function(){bc(1)};x[202]=w[202]=function(){bc(2)};x[203]=w[203]=function(){bc(3)};x[204]=w[204]=function(){bc(4)};x[205]=w[205]=function(){bc(5)};x[206]=w[206]=function(){bc(6)};x[207]=w[207]=function(){bc(7)};x[208]=w[208]=function(){z()};x[209]=w[209]=function(){z()};x[210]=w[210]=
function(){z()};x[211]=w[211]=function(){z()};x[212]=w[212]=function(){z()};x[213]=w[213]=function(){z()};x[214]=w[214]=function(){z()};x[215]=w[215]=function(){z()};x[216]=w[216]=function(){z()};x[217]=w[217]=function(){z()};x[218]=w[218]=function(){z()};x[219]=w[219]=function(){z()};x[220]=w[220]=function(){z()};x[221]=w[221]=function(){z()};x[222]=w[222]=function(){z()};x[223]=w[223]=function(){z()};x[224]=w[224]=function(){z()};x[225]=w[225]=function(){z()};x[226]=w[226]=function(){z()};x[227]=
w[227]=function(){z()};x[228]=w[228]=function(){z()};x[229]=w[229]=function(){z()};x[230]=w[230]=function(){z()};x[231]=w[231]=function(){z()};x[232]=w[232]=function(){z()};x[233]=w[233]=function(){z()};x[234]=w[234]=function(){z()};x[235]=w[235]=function(){z()};x[236]=w[236]=function(){z()};x[237]=w[237]=function(){z()};x[238]=w[238]=function(){z()};x[239]=w[239]=function(){z()};x[240]=w[240]=function(){z()};x[241]=w[241]=function(){z()};x[242]=w[242]=function(){z()};x[243]=w[243]=function(){z()};
x[244]=w[244]=function(){z()};x[245]=w[245]=function(){z()};x[246]=w[246]=function(){z()};x[247]=w[247]=function(){z()};x[248]=w[248]=function(){z()};x[249]=w[249]=function(){z()};x[250]=w[250]=function(){z()};x[251]=w[251]=function(){z()};x[252]=w[252]=function(){z()};x[253]=w[253]=function(){z()};x[254]=w[254]=function(){z()};x[255]=w[255]=function(){z()}};Object.bb=function(f){for(var t={},D=0;D<f.length;D++)t[f[D][0]]=f[D][1];return t};Object.cb=function(f,t){for(var D=Object.keys(t),C=0;C<D.length;C++)f[D[C]]=t[D[C]]};String.m=function(f){for(f=f?f+"":"";20>f.length;)f=f+" ";return f};String.i=function(f,t){for(f=f?f+"":"";f.length<t;)f="0"+f;return f};Array.a=function(f){for(var t=[],D=0;D<f;D++)t[D]=D;return t};function Be(f,t){return f?t?String.i(f.toString(16).toUpperCase(),t):f.toString(16).toUpperCase():String.i("",t||1)}
Number.a=function(f){for(var t=[],D=31;-1<D;D--)f&1<<D&&t.push(D);return t.join(", ")};String.a=function(f,t){for(var D="";t--;)D+=f;return D};Math.wa=function(f){for(var t=0,D=0,C;f;)C=f%10,D|=C<<4*t,t++,f=(f-C)/10;return D};function ze(f){f="Unimplemented"+(f?": "+f:"");nc(f);nc("Execution stopped");return f}
function Zd(f){this.byteLength=f.byteLength;this.get=function(t,D,C){C(new Uint8Array(f,t,D))};this.set=function(t,D,C){(new Uint8Array(f,t,D.byteLength)).set(D);C()};this.Ba=function(t){t(f)}}Math.Ya=function(f){return f>>>24|f>>8&65280|f<<8&16711680|f<<24};Math.Xa=function(f){return f>>>8&255|f<<8&65280};for(var Ae,De=new Int8Array(256),Ee=0,Fe=-2;256>Ee;Ee++)Ee&Ee-1||Fe++,De[Ee]=Fe;Ae=De;Math.qa=function(f){return 0<f?Math.ceil(f):Math.floor(f)};function ve(f,t){this.j=f.j;this.memory=f.memory;this.s=f.s;this.M=f.M;this.da=4098;this.Y=17170688;this.U=14;this.T=4293984256;this.a=2048;this.buffer=t;this.m=!0;this.q=8;this.w()}ve.prototype=new Ge;
function we(f,t,D){function C(){var f=80;n<H.length&&(f|=8);return f}function O(){X.k(B.U)}var L=0===D?496:368,X=f.s;this.j=f.j;this.memory=f.memory;this.s=f.s;this.M=f.M;this.da=4098;this.Y=17170688;this.U=0===D?14:15;this.T=4293918720;this.a=512;this.o=t.byteLength/this.a;this.buffer=t;this.m=!1;this.q=16;this.i=t.byteLength/16/64/this.a;var B=this;this.j.h(L|7,C);this.j.h(L|518,C);var G=255,n=0,H=[];this.j.g(L|6,function(f){f&16||(G=f)});this.j.g(L|2,function(){});this.j.g(L|3,function(){});this.j.g(L|
4,function(){});this.j.g(L|5,function(){});this.j.g(L|7,function(f){236===f?(n=0,H=new Uint8Array([64,0,B.i,B.i>>8,0,0,16,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,4,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,1,0,0,3,0,0,0,2,0,2,7,0,B.i,B.i>>8,16,0,63,0,this.o&255,this.o>>8&255,this.o>>16&255,this.o>>24&255,0,0,this.o&255,this.o>>8&255,this.o>>16&255,this.o>>24&255,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,126,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,this.o&255,this.o>>8&255,this.o>>16&255,this.o>>24&255]),O()):145===f?O():16===f?O():(O(),H=[0,0,0,0,t.byteLength&255,t.byteLength>>8&255,t.byteLength>>16&255,t.byteLength>>24&255,0,0,0,0])});this.j.h(L|0,function(){return n<H.length?(0===(n&511)&&O(),H[n++]&255):0});this.j.h(L|1,function(){return 255});this.j.h(L|2,function(){return 255});this.j.h(L|
3,function(){return 255});this.j.h(L|6,function(){return G});this.w()}we.prototype=new Ge;
function Ge(){function f(f,n,t){var F=O.c(f+4)&16777215;f=O.b(f+12)*C.a;t?this.buffer.get(F*C.a,f,function(f){O.J(f,n)}):this.buffer.set(F*C.a,new Uint8Array(O.buffer,n,f),function(){})}function t(f){switch(f){case 0:return X;case 4:return L;case 12:return B;case 296:return 3;case 272:return G}}function D(t,B){switch(t){case 256:n=B;break;case 264:H=B;break;case 312:var N=O.c(n+8),F=N+128;O.b(n);var G=O.c(F)+4294967296*O.c(F+4);O.c(N+128+12);var F=O.d(N+64),D=O.d(N+2),L=N+0;if((160===D||161===D)&&
!C.m)break;O.e(H+64+2,64);O.c(L+4);O.b(n+2);O.c(n+4);O.c(N+128+12);200===D||202===D?f(L,G,200===D):236===D?O.f(G+120,C.buffer.byteLength/C.a):161===D?O.f(G,1280):160===D&&40===F&&(N=N+64,F=Math.Ya(O.c(N+2)),D=Math.Xa(O.b(N+7)),O.d(N+1),C.buffer.get(F*C.a,D*C.a,function(f){O.J(f,G)}))}}var C,O;this.w=function(){C=this;O=this.memory;this.M.pa(this,this.q);this.memory.ba(this.T,16384,!0,t,D)};var L=0,X=1,B=1,G=1,n,H};function pe(f){f=f.j;var t=0,D=-1,C=-1,O=this;this.a={};f.h(3324,function(){return D&255});f.h(3325,function(){return D>>8&255});f.h(3326,function(){return D>>16&255});f.h(3327,function(){return D>>24&255});f.h(3320,function(){return C&255});f.h(3321,function(){return C>>8&255});f.h(3322,function(){return C>>16&255});f.h(3323,function(){return C>>24&255});f.g(3320,function(f){t=t&-256|f});f.g(3321,function(f){t=t&-65281|f<<8});f.g(3322,function(f){t=t&-16711681|f<<16});f.g(3323,function(f){var X=
t=t&16777215|f<<24,B=(X&2147483647)>>8;f=X&252;-2147483648===X?C=2147483648:O.a[B]?(X=O.a[B],C=2147483648,0===f?D=X.da:8===f?D=X.Y:36===f?D=X.T:60===f?D=X.U:D=0):C=D=0});this.pa=function(f,t){this.a[t]=f};this.pa({U:0,T:0,da:2256543790,Y:100700192},0)};function ue(f,t){function D(){return 0}function C(){var f=128;ja<h&&(f|=80);0===(Fa&8)&&(f|=32);return f}function O(){return 0}function L(){return ja<h?fa[ja++]:255}function X(f){if(0<ha)za[qa++]=f,ha--,0===ha&&z(za);else{switch(f){case 3:z=N;ha=2;break;case 4:z=n;ha=1;break;case 5:case 197:z=function(h){R(!0,h)};ha=8;break;case 230:z=function(h){R(!1,h)};ha=8;break;case 7:z=V;ha=1;break;case 8:ja=0;h=2;fa[0]=32;fa[1]=Da;break;case 74:z=F;ha=1;break;case 15:ha=2;z=H;break;case 14:fa[0]=128,ja=0,h=
1,ha=0}qa=0}}function B(){return Fa}function G(h){4===(h&4)&&0===(Fa&4)&&sa.k(6);Fa=h}function n(){ja=0;h=1;fa[0]=32}function H(h){Da=h[1];Fa&8&&sa.k(6)}function V(){Fa&8&&sa.k(6)}function R(f,z){function n(){B++;B>Ca&&(B=1,F++,1<F&&(F=0,N++));Da=N;ja=0;h=7;fa[0]=F<<2|32;fa[1]=0;fa[2]=0;fa[3]=N;fa[4]=F;fa[5]=B;fa[6]=z[4];Fa&8&&sa.k(6)}var F=z[2],N=z[1],B=z[3],G=128*(1<<z[4]),D=z[5]-z[3]+1,C=((F+2*N)*Ca+B-1)*G;f?pa.za(t,C,n):pa.ya(t,C,D*G,n)}function N(){}function F(){ja=0;h=7;fa[0]=0;fa[1]=0;fa[2]=
0;fa[3]=0;fa[4]=0;fa[5]=0;fa[6]=0;Fa&8&&sa.k(6)}var na=f.j,sa=f.s,pa=f.xa,ha=0,za=new Uint8Array(10),qa=0,z,fa=new Uint8Array(10),ja=0,h=0;if(this.buffer=t){var Ca;368640===t.byteLength&&(this.type=1,Ca=9);if(1228800===t.byteLength)this.type=2,Ca=15;else if(737280===t.byteLength)this.type=3,Ca=9;else if(1474560===t.byteLength)this.type=4,Ca=18;else if(2949120===t.byteLength)this.type=5,Ca=36;else if(1763328===t.byteLength)this.type=5,Ca=21;else throw ze("Unknown floppy size: "+Be(t.byteLength));var Da=
0;na.h(1008,D);na.h(1012,C);na.h(1013,L);na.h(1015,O);na.g(1013,X);var Fa=0;na.h(1010,B);na.g(1010,G)}else this.type=0};function be(){var f=new ArrayBuffer(67108864);function t(f){var F=f>>>14,n=V[F];return 1===H[F]?n(f):C(f&-4)>>8*(f&3)&255}function D(f,F){var n=R[f>>>14];1===H[f>>>14]&&n(f,F)}function C(f){var F=V[f>>>14];return 0===(f&3)&&H[f>>>14]===n?F(f):t(f)|t(f+1)<<8|t(f+2)<<16|t(f+3)<<24}function O(f,F){var t=R[f>>>14];0===(f&3)&&H[f>>>14]===n?t(f,F):(D(f,F&255),D(f+1,F>>8&255),D(f+2,F>>16&255),D(f+3,F>>24&255))}var L=new Uint8Array(f),X=new Uint16Array(f),B=new Int8Array(f),G=new Int32Array(f);this.m=L;this.Q=
B;this.i=G;this.buffer=f;for(var n=4,H=new Int8Array(262144),V=[],R=[],f=0;262144>f;f++)V[f]=R[f]=void 0;this.ba=function(f,F,t,B,G){var D=f>>>14;for(t=t?n:1;0<F;D++)H[D]=t,V[D]=function(n){return B(n-f|0)},R[D]=function(n,F){G(n-f|0,F)},F-=16384};this.R=function(f){return H[f>>>14]?t(f)<<24>>24:B[f]};this.d=function(f){return H[f>>>14]?t(f):L[f]};this.b=function(f){return H[f>>>14]?t(f)|t(f+1)<<8:L[f]|L[f+1]<<8};this.q=function(f){return H[f>>>14]?t(f)|t(f+1)<<8:X[f>>1]};this.c=function(f){return H[f>>>
14]?C(f)|0:L[f]|L[f+1]<<8|L[f+2]<<16|L[f+3]<<24};this.v=function(f){return H[f>>>14]?C(f)|0:G[f>>2]};this.e=function(f,n){H[f>>>14]?D(f,n):L[f]=n};this.a=function(f,n){H[f>>>14]?(D(f,n&255),D(f+1,n>>8&255)):(L[f]=n,L[f+1]=n>>8)};this.S=function(f,n){H[f>>>14]?(D(f,n&255),D(f+1,n>>8&255)):X[f>>1]=n};this.f=function(f,n){H[f>>>14]?O(f,n):(L[f]=n,L[f+1]=n>>8,L[f+2]=n>>16,L[f+3]=n>>24)};this.D=function(f,n){H[f>>>14]?O(f,n):G[f>>2]=n};this.J=function(f,n){L.set(f,n)};this.aa=function(f){for(var n=0;n<
f.length;n++)this.e(63488+n,f.charCodeAt(n))}};function qe(f){function t(f,t){if(8>f){var n=f>>1;f&1?L[n].count=D(L[n].count,t):L[n].p=D(L[n].p,t)}}function D(f,t){return(X^=1)?f&-256|t:f&-65281|t<<8}var C=f.j,O=f.memory,L=[{p:0,count:0},{p:0,count:0},{p:0,count:0},{p:0,count:0}],X=0;C.g(4,t.bind(0,4));C.g(5,t.bind(0,5));C.g(10,function(){});C.g(11,function(){});C.g(12,function(){X=0});C.g(129,function(f){L[2].p=L[2].p&65535|f<<16});this.ya=function(f,t,n,D){var C=L[2].p;L[2].p+=n;f.get(t,n,function(f){O.J(f,C);D()})};this.za=function(f,t,n){f.set(t,
new Uint8Array(O.buffer,L[2].p,L[2].count+1),function(){n()})}};function xe(f){function t(f){var n=H[f];if(n)return H[f]--,2===n?V[f]&255:V[f]>>8;n=X[f];3===G[f]&&(X[f]^=1);return n?N[f]&255:N[f]>>8}function D(f,t){R[f]=X[f]?R[f]&-256|t:R[f]&255|t<<8;3===n[f]&&X[f]||(R[f]||(R[f]=65535),N[f]=R[f],B[f]=!0);3===n[f]&&(X[f]^=1)}var C=f.j,O=f.s,L=Date.now(),X=new Uint8Array(3),B=new Uint8Array(3),G=new Uint8Array(3),n=new Uint8Array(3),H=new Uint8Array(3),V=new Uint16Array(3),R=new Uint16Array(3),N=new Uint16Array(3),F=0,na=0;C.h(97,function(){na^=16;return na|F<<
5});this.a=function(f){var n,t=1193.1816666*(f-L)>>>0;if(t){L+=t/1193.1816666;if(B[0]&&(f=N[0]-=t,0>=f))if(O.k(0),n=G[0],0===n)B[0]=0,N[0]=0;else if(3===n||2===n)N[0]=R[0]+f%R[0];B[2]&&(f=N[2]-=t,0>=f&&(n=G[2],0===n?(F=1,B[2]=0,N[2]=0):2===n?(F=1,N[2]=R[2]+f%R[2]):3===n&&(F^=1,N[2]=R[2]+f%R[2])))}};C.h(64,function(){return t(0)});C.h(65,function(){return t(1)});C.h(66,function(){return t(2)});C.g(64,function(f){D(0,f)});C.g(65,function(f){D(1,f)});C.g(66,function(f){D(2,f)});C.g(67,function(f){var t=
f>>1&7,D=f>>6&3;f=f>>4&3;3!==D&&(0===f?(H[D]=2,V[D]=N[D]):(6<=t&&(t&=-5),X[D]=1===f?1:2===f?0:1,G[D]=t,n[D]=f,2===D&&(F=0===t?0:1)))})};function re(f,t){function D(){var f=(L-N)/n|0,h=(L-N)%n,f=Math.min(H-1,f);t.Za(f,h)}var C=f.j,O=f.memory,L=0,X=14,B=15,G=this,n,H,V,R,N=0,F=!0,na=!1,sa=!1,pa=new Int32Array(256),ha=new Uint8Array(262144),za=new Uint8Array(ha.buffer,0,65536),qa=new Uint8Array(ha.buffer,65536,65536),z=new Uint8Array(ha.buffer,131072,65536),fa=new Uint8Array(ha.buffer,196608,65536),ja=0,h=0,Ca=0,Da=0,Fa=new Uint8Array(8388608),Xb=!1,gc=0,hc=0,ic=0;this.i=function(){if(sa)if(sa=!1,na){if(!F)for(var f=0,h,D=0;D<R;D++)for(var B=
0;B<V;B+=8){for(var C=0;8>C;C++)h=za[f]>>C&1|qa[f]>>C<<1&2|z[f]>>C<<2&4|fa[f]>>C<<3&8,t.Qa(B+7-C,D,pa[zb[h]]);f++}}else for(f=98304|N<<1,B=0;B<H;B++)for(C=0;C<n;C++)h=ha[f],D=ha[f|1],t.ka(B,C,h,pa[D>>4&15],pa[D&15]),f+=2;na||Xb?t.Va():t.Wa()};this.N=function(f,h){n=f;H=h;t.N(f,h)};this.I=function(f,h){t.I(f,h)};this.O=function(){t.O(X,B)};this.Z=function(){t.Z()};this.a=function(f){var h=!1;switch(f){case 3:this.N(80,25);break;case 16:this.I(640,350);V=640;R=350;h=!0;F=!1;break;case 18:this.I(640,
480);V=640;R=480;h=!0;F=!1;break;case 19:this.I(320,200),V=320,R=200,F=h=!0}t.va(h);na=h};this.n=function(){};var cb=0,$a=0;C.g(967,function(){});C.g(968,function(f){$a=3*f});C.g(969,function(f){var h=$a/3|0,n=$a%3,z=pa[h];f=f<<2&255|3;pa[h]=0===n?z&-16711681|f<<16:1===n?z&-65281|f<<8:z&-256|f;$a++;sa=!0});C.g(980,function(f){cb=f});C.g(981,function(f){switch(cb){case 2:G.N(f,25);break;case 10:X=f;G.O();break;case 11:B=f;G.O();break;case 12:N=N&255|f<<8;sa=!0;break;case 13:N=N&65280|f;sa=!0;break;
case 14:L=L&255|f<<8;D();break;case 15:L=L&65280|f,D()}});C.h(981,function(){return 10===cb?X:11===cb?B:14===cb?L>>8:15===cb?L&255:0});var jc=255;C.h(972,function(){return jc});C.g(962,function(f){jc=f;103===f?G.a(3):227===f?G.a(18):99===f?G.a(19):163===f?G.a(16):G.a(3)});C.h(986,function(){La=-1;return 255});var La=-1;C.h(961,function(){return La=-1});var zb=new Uint8Array(16);C.g(960,function(f){-1===La?La=f:(16>La&&(zb[La]=f),La=-1)});C.h(960,function(){var f=La;La=-1;return f});var Bb=-1;C.g(964,
function(f){Bb=f});var ca=15;C.g(965,function(f){switch(Bb){case 2:ca=f}});C.h(965,function(){switch(Bb){case 6:return 18}});var tc=-1;C.g(974,function(f){tc=f});var Qc=0,Wb=0,gd=0,Ia=255;C.g(975,function(f){switch(tc){case 3:gd=f;break;case 4:Qc=f;break;case 5:Wb=f;break;case 8:Ia=f}});var hb=-1,db=-1,ib=!0;C.g(462,function(f){hb=f;ib=!0});C.g(463,function(f){ib?(hb|=f<<8,ib=!1):(ib=!0,db=f)});C.g(464,function(f){db|=f<<8;switch(hb){case 1:gc=db;break;case 2:hc=db;break;case 3:ic=db;break;case 4:Xb=
1===(db&1)}Xb&&(G.I(gc,hc),t.va(!0))});C.h(463,function(){switch(hb){case 0:return 192;case 1:return 1280;case 2:return 1024;case 3:return 32;case 10:return 128}});C.h(464,function(){switch(hb){case 0:return 176;case 1:return 5;case 2:return 4;case 3:return 0;case 10:return 0}});G.N(80,25);G.O();O.ba(655360,131072,!1,function(f){if(!na||F)return ha[f];f&=65535;ja=za[f];h=qa[f];Ca=z[f];Da=fa[f];return ha[Qc<<16|f]},function(f,D){if(na)if(F){var C=f<<2,B=pa[D];t.r(C|2,B>>16&255);t.r(C|1,B>>8&255);t.r(C,
B&255);ha[f]=D}else{if(!(65535<f)){var G,H;0===Wb?C=B=G=H=D:2===Wb&&(ca&1&&(C=ja&~Ia|(D&1?255:0)&Ia),ca&2&&(B=h&~Ia|(D&2?255:0)&Ia),ca&4&&(G=Ca&~Ia|(D&4?255:0)&Ia),ca&8&&(H=Da&~Ia|(D&8?255:0)&Ia));if(0===Wb||2===Wb){switch(gd&24){case 8:C&=ja;B&=h;G&=Ca;H&=Da;break;case 16:C|=ja;B|=h;G|=Ca;H|=Da;break;case 24:C^=ja,B^=h,G^=Ca,H^=Da}ca&1&&(C=ja&~Ia|C&Ia);ca&2&&(B=h&~Ia|B&Ia);ca&4&&(G=Ca&~Ia|G&Ia);ca&8&&(H=Da&~Ia|H&Ia)}else 1===Wb&&(C=ja,B=h,G=Ca,H=Da);ca&1?za[f]=C:C=za[f];ca&2?qa[f]=B:B=qa[f];ca&4?
z[f]=G:G=z[f];ca&8?fa[f]=H:H=fa[f];if(!(f>=V*R<<3)){B<<=1;G<<=2;H<<=3;for(var L=(f<<3|7)<<2,O=0;8>O;O++){var Fa=pa[zb[C>>O&1|B>>O&2|G>>O&4|H>>O&8]];t.r(L|2,Fa>>16);t.r(L|1,Fa>>8&255);t.r(L,Fa&255);L-=4}}}}else 98304>f||(B=(f-98304>>1)-N,C=B/n|0,B%=n,f&1?(H=D,G=ha[f&-2]):(G=D,H=ha[f|1]),t.ka(C,B,G,pa[H>>4&15],pa[H&15]),ha[f]=D)});O.ba(3758096384,8388608,!1,function(f){return Fa[f]},function(f,h){Fa[f]=h;switch(ic){case 32:if(3===(f&3))break;t.r(f,h);break;case 24:t.r(4/3*f|0,h);break;case 16:if(f&
1){var n=Fa[f^1]>>5&7|h<<3&56,z;z=255*(h>>3&31)/31|0;f<<=1;t.r(f-1,255*n/63|0);t.r(f-2,z)}else n=255*(h&31)/31|0,t.r((f<<1)+2,n)}})};function se(f,t,D){function C(){n.k(1)}function O(f){qa.push(f);C()}function L(f,h){if(R&&V&&(N+=f,F+=h,H)){var n=Date.now();n-fa<1E3/z||(fa=n,B())}}function X(f,h,n){R&&V&&(na=f|n<<1|h<<2,H&&B())}function B(){ja.push((0>F)<<5|(0>N)<<4|8|na,N&255,F&255);if(15<ja.length){var f=ja.length%3;ja=ja.slice(0,f).concat(ja.slice(f+3))}F=N=0;n.k(12)}var G=f.j,n=f.s,H=!1,V=!1,R=!1,N=0,F=0,na=0,sa=!1,pa=!1,ha=!1,za=!1,qa=[],z=100,fa=-1,ja=[];t&&(sa=!0,t.w(O));D&&(R=!0,D.w(X,L));this.G=O;this.n=function(){sa&&
t.n();R&&D.n()};var h=0,Ca=!1,Da=!1;G.h(96,function(){if(!qa.length&&!ja.length)return 255;if(qa.length&&ja.length?0===(n.Ca()&2):!qa.length)return 1<ja.length&&n.k(12),ja.shift();1<qa.length&&C();return qa.shift()});G.h(100,function(){var f=16;if(ja.length||qa.length)f|=1;ja.length&&(f|=32);return f});G.g(96,function(f){Da?(h=f,Da=!1):Ca?(Ca=!1,ja=[f],n.k(12)):ha?(ha=!1,ja=[250],z=f,n.k(12)):za?za=!1:pa?R&&(ja=[250],255===f?(ja.push(170,0),V=!0,D.enabled=!0):242===f?ja.push(0,0):243===f?ha=!0:244===
f?(V=H=!0,D.enabled=!0):245===f?H=!0:246===f&&(H=!1,z=100),n.k(12)):(qa.push(250),255===f?qa.push(170,0):242===f?qa.push(171,83):244!==f&&245!==f&&237===f&&(za=!0),C())});G.g(100,function(n){254===n?f.Ta():32===n?(qa.push(h),C()):96===n?Da=!0:211===n?Ca=!0:212===n?pa=!0:169===n?(qa=[0],C()):170===n?(qa=[85],C()):171===n&&(qa=[0],C())})};function de(f,t,D,C){var O=f.j,L=0,X=0,B=0,G=0,n=void 0===C,H;n?(H=new de(f,t,D,this),this.a=function(){var f=G&L;if(!f)return!1;f&=-f;if(B&&(B&-B)<=f)return!1;G&=~f;B|=f;if(4===f)return H.a();t(X+Ae[f],!1,!1);return!0}):this.a=function(){var f=G&L;if(!f)return!1;f&=-f;if(B&&(B&-B)<=f)return!1;G&=~f;B|=f;t(X+Ae[f],!1,!1);G&&C.k(2);return!0};this.i=function(){n&&H.i()};var V,R=0,N=1;f=n?32:160;O.g(f,function(f){if(f&16)V=f&1,R=1;else if(f&8)N=f&1;else{var n=f>>5;1===n?B=0:3===n&&(B&=~(1<<(f&7)))}});
O.h(f,function(){return N?G:B});O.g(f|1,function(f){0===R?V?V=!1:L=~f:1===R?(X=f,R++):2===R&&(R=0)});O.h(f|1,function(){return~L});this.k=n?function(f){8<=f&&(H.k(f-8),f=2);G|=1<<f;D()}:function(f){G|=1<<f};this.Ca=function(){return B}};function ye(f,t){function D(f){return N&4?f:Math.wa(f)}var C=f.j,O=f.s,L=0,X=this,B=Date.now(),G=B,n,H=!1,V=0.9765625,R=38,N=2;this.i=0;this.a=function(f){if(H)for(;n<f;)n+=V,O.k(8);B+=f-G;G=f};C.g(112,function(f){L=f&127;X.i=f>>7});C.g(113,function(f){switch(L){case 10:R=f&127;V=1E3/(32768>>(R&15)-1);break;case 11:N=f,N&64&&(n=Date.now())}H=64===(N&64)&&0<(R&15)});C.h(113,function(){var f=L;L=13;switch(f){case 0:return D((new Date(B)).getUTCSeconds());case 2:return D((new Date(B)).getUTCMinutes());
case 4:return D((new Date(B)).getUTCHours());case 7:return D((new Date(B)).getUTCDate());case 8:return D((new Date(B)).getUTCMonth()+1);case 9:return D((new Date(B)).getUTCFullYear()%100);case 10:return R;case 11:return N;case 14:return 0;case 12:return 0;case 15:return 0;case 16:return t;case 20:return 45;case 50:return D((new Date(B)).getUTCFullYear()/100|0);case 52:return 0;case 53:return 3;case 56:return 48;case 61:return 33;case 91:case 92:case 93:return 0}return 255})};function te(f){var t="";f.j.g(1016,function(f){10===f?(nc(t),t=""):t+=String.fromCharCode(f)})};window.requestAnimationFrame||(window.requestAnimationFrame=window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame);
function Wd(){function f(){na=!0;for(var f=0;f<ha;f++)F[f]&&(N.i(f),F[f]=0)}function t(f,n,t){n=""+(1===n?"":" scaleX("+n+")")+(1===t?"":" scaleY("+t+")");f.style.webkitTransform=f.style.MozTransform=n}var D=document.getElementById("screen"),C=document.getElementById("vga"),O=C.getContext("2d"),L=document.createElement("div"),X,B,G,n,H=1,V=1,R,N=this,F,na=!0,sa,pa,ha,za=new Uint16Array([199,252,233,226,228,224,229,231,234,235,232,239,238,236,196,197,201,230,198,244,246,242,251,249,255,214,220,162,
163,165,8359,402,225,237,243,250,241,209,170,186,191,8976,172,189,188,161,171,187,9617,9618,9619,9474,9508,9569,9570,9558,9557,9571,9553,9559,9565,9564,9563,9488,9492,9524,9516,9500,9472,9532,9566,9567,9562,9556,9577,9574,9568,9552,9580,9575,9576,9572,9573,9561,9560,9554,9555,9579,9578,9496,9484,9608,9604,9612,9616,9600,945,223,915,960,931,963,181,964,934,920,937,948,8734,966,949,8745,8801,177,8805,8804,8992,8993,247,8776,176,8729,183,8730,8319,178,9632,160]),qa=new Uint16Array([32,9786,9787,9829,
9830,9827,9824,8226,9688,9675,9689,9794,9792,9834,9835,9788,9658,9668,8597,8252,182,167,9644,8616,8593,8595,8594,8592,8735,8596,9650,9660]);O.imageSmoothingEnabled=!1;O.mozImageSmoothingEnabled=!1;O.webkitImageSmoothingEnabled=!1;L.id="cursor";D.style.display="block";C.style.display="none";this.ka=function(f,n,t,h,B){F[f]=1;f=3*(f*pa+n);sa[f]=t;sa[f+1]=h;sa[f+2]=B};this.Wa=function(){na&&(na=!1,requestAnimationFrame(f))};this.Qa=function(f,n,t){f=n*R+f<<2;B[f]=t>>16&255;B[f+1]=t>>8&255;B[f+2]=t&255};
this.r=function(f,n){B[(f^3)-1]=n};this.Va=function(){na&&(na=!1,requestAnimationFrame(function(){na=!0;O.putImageData(X,0,0)}))};this.n=function(){};this.va=function(f){f?(D.style.display="none",C.style.display="block"):(D.style.display="block",C.style.display="none")};this.Z=function(){O.fillStyle="#000";O.fillRect(0,0,C.width,C.height)};this.N=function(f,n){F=new Int8Array(n);sa=new Int32Array(f*n*3);pa=f;for(ha=n;D.firstChild;)D.removeChild(D.firstChild);for(var t=0;t<n;t++)D.appendChild(document.createElement("div"))};
this.I=function(f,n){C.style.display="block";C.width=f;C.height=n;N.Z();X=O.getImageData(0,0,f,n);B=X.data;R=f};this.a=function(f,n){H=f;V=n;t(C,H,V);t(D,H,V)};this.a(H,V);this.O=function(f,n){f&32?L.style.display="none":(L.style.display="inline",L.style.height=n-f+"px",L.style.marginTop=f+"px")};this.Za=function(f,t){if(f!==G||t!==n)F[f]=1,F[G]=1,G=f,n=t};this.i=function(f){var t=3*f*pa,B,h,C,F,H;B=document.createElement("div");for(var R=0;R<pa;){h=document.createElement("span");C=sa[t+1];F=sa[t+
2];h.style.backgroundColor="#"+Be(C,6);h.style.color="#"+Be(F,6);for(H="";R<pa&&sa[t+1]===C&&sa[t+2]===F;){var N=sa[t];H+=127<N?String.fromCharCode(za[N-128]):32>N?String.fromCharCode(qa[N]):String.fromCharCode(N);R++;t+=3;if(f===G)if(R===n)break;else if(R===n+1){B.appendChild(L);break}}h.textContent=H;B.appendChild(h)}D.replaceChild(B,D.childNodes[f])}};function Xd(){function f(f){return f.shiftKey&&f.ctrlKey&&74===f.keyCode||116===f.keyCode||!X.enabled?!1:f.target?"phone_keyboard"===f.target.className||"INPUT"!==f.target.nodeName&&"TEXTAREA"!==f.target.nodeName:!0}function t(n){if(f(n)){var t=n.keyCode;if(!L[t])return!1;L[t]=!1;O(t,!1)||n.preventDefault()}}function D(n){if(f(n)){var t=n.keyCode;L[t]&&O(t,!1);L[t]=!0;O(t,!0)||n.preventDefault()}}function C(){for(var f=Object.keys(L),t,B=0;B<f.length;B++)t=+f[B],L[t]&&O(t,!1);L={}}function O(f,t){if(f>=
G.length||0===G[f])return!0;var C=G[f];t||(C|=128);255<C?(B(C>>8),B(C&255)):B(C);return!1}var L={},X=this,B;this.enabled=!0;var G=new Uint16Array([0,0,0,0,0,0,0,0,14,15,0,0,0,28,0,0,42,29,56,0,58,0,0,0,0,0,0,1,0,0,0,0,57,57417,57425,79,71,75,72,77,80,0,0,0,0,82,83,0,11,2,3,4,5,6,7,8,9,10,0,39,0,13,0,0,0,30,48,46,32,18,33,34,35,23,36,37,38,50,49,24,25,16,19,31,20,22,47,17,45,21,44,0,0,0,0,0,82,79,80,81,75,76,77,71,72,73,0,0,0,0,0,0,59,60,61,62,63,64,65,66,67,68,87,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,39,13,51,12,52,53,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,43,27,40,0]);this.w=function(f){this.n();B=f;window.addEventListener("keyup",t,!1);window.addEventListener("keydown",D,!1);window.addEventListener("blur",C,!1)};this.n=function(){window.removeEventListener("keyup",t,!1);window.removeEventListener("keydown",D,!1);window.removeEventListener("blur",C,!1)}};function Yd(){function f(f){return V.enabled&&(!f.target||"mousemove"===f.type||"INPUT"!==f.target.nodeName&&"TEXTAREA"!==f.target.nodeName)}function t(n){if(f(n)){var t;t=n.webkitMovementX||n.mozMovementX||0;n=n.webkitMovementY||n.mozMovementY||0;t=Math.qa(0.5*t);n=Math.qa(0.5*n);H(t,-n)}}function D(n){f(n)&&n.preventDefault()}function C(n){f(n)&&L(n,!0)}function O(n){f(n)&&L(n,!1)}function L(f,t){1===f.which?X=t:2===f.which?G=t:3===f.which&&(B=t);n(X,G,B);f.preventDefault()}var X=!1,B=!1,G=!1,n,
H,V=this;this.enabled=!1;this.n=function(){window.removeEventListener("mousemove",t,!1);document.removeEventListener("contextmenu",D,!1);window.removeEventListener("mousedown",C,!1);window.removeEventListener("mouseup",O,!1)};this.w=function(f,B){this.n();n=f;H=B;window.addEventListener("mousemove",t,!1);document.addEventListener("contextmenu",D,!1);window.addEventListener("mousedown",C,!1);window.addEventListener("mouseup",O,!1)}};
//# sourceMappingURL=src/v86_all.js.map