; ( function ( ) { 'use strict' ; var $jscomp = $jscomp || { } ; $jscomp . scope = { } ; $jscomp . ASSUME_ES5 = ! 1 ; $jscomp . ASSUME_NO_NATIVE_MAP = ! 1 ; $jscomp . ASSUME_NO_NATIVE_SET = ! 1 ; $jscomp . defineProperty = $jscomp . ASSUME_ES5 || "function" == typeof Object . defineProperties ? Object . defineProperty : function ( a , b , c ) { a != Array . prototype && a != Object . prototype && ( a [ b ] = c . value ) ; } ; $jscomp . getGlobal = function ( a ) { return "undefined" != typeof window && window === a ? a : "undefined" != typeof global && null != global ? global : a ; } ; $jscomp . global = $jscomp . getGlobal ( this ) ; $jscomp . SYMBOL_PREFIX = "jscomp_symbol_" ; $jscomp . initSymbol = function ( ) { $jscomp . initSymbol = function ( ) { } ; $jscomp . global . Symbol || ( $jscomp . global . Symbol = $jscomp . Symbol ) ; } ; $jscomp . Symbol = function ( ) { var a = 0 ; return function ( b ) { return $jscomp . SYMBOL_PREFIX + ( b || "" ) + a ++ ; } ; } ( ) ; $jscomp . initSymbolIterator = function ( ) { $jscomp . initSymbol ( ) ; var a = $jscomp . global . Symbol . iterator ; a || ( a = $jscomp . global . Symbol . iterator = $jscomp . global . Symbol ( "iterator" ) ) ; "function" != typeof Array . prototype [ a ] && $jscomp . defineProperty ( Array . prototype , a , { configurable : ! 0 , writable : ! 0 , value : function ( ) { return $jscomp . arrayIterator ( this ) ; } } ) ; $jscomp . initSymbolIterator = function ( ) { } ; } ; $jscomp . initSymbolAsyncIterator = function ( ) { $jscomp . initSymbol ( ) ; var a = $jscomp . global . Symbol . asyncIterator ; a || ( a = $jscomp . global . Symbol . asyncIterator = $jscomp . global . Symbol ( "asyncIterator" ) ) ; $jscomp . initSymbolAsyncIterator = function ( ) { } ; } ; $jscomp . arrayIterator = function ( a ) { var b = 0 ; return $jscomp . iteratorPrototype ( function ( ) { return b < a . length ? { done : ! 1 , value : a [ b ++ ] } : { done : ! 0 } ; } ) ; } ; $jscomp . iteratorPrototype = function ( a ) { $jscomp . initSymbolIterator ( ) ; a = { next : a } ; a [ $jscomp . global . Symbol . iterator ] = function ( ) { return this ; } ; return a ; } ; $jscomp . makeIterator = function ( a ) { $jscomp . initSymbolIterator ( ) ; var b = a [ Symbol . iterator ] ; return b ? b . call ( a ) : $jscomp . arrayIterator ( a ) ; } ; $jscomp . polyfill = function ( a , b , c , d ) { if ( b ) { c = $jscomp . global ; a = a . split ( "." ) ; for ( d = 0 ; d < a . length - 1 ; d ++ ) { var e = a [ d ] ; e in c || ( c [ e ] = { } ) ; c = c [ e ] ; } a = a [ a . length - 1 ] ; d = c [ a ] ; b = b ( d ) ; b != d && null != b && $jscomp . defineProperty ( c , a , { configurable : ! 0 , writable : ! 0 , value : b } ) ; } } ; $jscomp . polyfill ( "Math.trunc" , function ( a ) { return a ? a : function ( a ) { a = Number ( a ) ; if ( isNaN ( a ) || Infinity === a || - Infinity === a || 0 === a ) return a ; var b = Math . floor ( Math . abs ( a ) ) ; return 0 > a ? - b : b ; } ; } , "es6" , "es3" ) ; $jscomp . iteratorFromArray = function ( a , b ) { $jscomp . initSymbolIterator ( ) ; a instanceof String && ( a += "" ) ; var c = 0 , d = { next : function ( ) { if ( c < a . length ) { var e = c ++ ; return { value : b ( e , a [ e ] ) , done : ! 1 } ; } d . next = function ( ) { return { done : ! 0 , value : void 0 } ; } ; return d . next ( ) ; } } ; d [ Symbol . iterator ] = function ( ) { return d ; } ; return d ; } ; $jscomp . polyfill ( "Array.prototype.entries" , function ( a ) { return a ? a : function ( ) { return $jscomp . iteratorFromArray ( this , function ( a , c ) { return [ a , c ] ; } ) ; } ; } , "es6" , "es3" ) ; $jscomp . checkEs6ConformanceViaProxy = function ( ) { try { var a = { } , b = Object . create ( new $jscomp . global . Proxy ( a , { get : function ( c , d , e ) { return c == a && "q" == d && e == b ; } } ) ) ; return ! 0 === b . q ; } catch ( c ) { return ! 1 ; } } ; $jscomp . USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS = ! 1 ; $jscomp . ES6_CONFORMANCE = $jscomp . USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS && $jscomp . checkEs6ConformanceViaProxy ( ) ; $jscomp . owns = function ( a , b ) { return Object . prototype . hasOwnProperty . call ( a , b ) ; } ; $jscomp . polyfill ( "WeakMap" , function ( a ) { function b ( ) { if ( ! a || ! Object . seal ) return ! 1 ; try { var b = Object . seal ( { } ) , c = Object . seal ( { } ) , e = new a ( [ [ b , 2 ] , [ c , 3 ] ] ) ; if ( 2 != e . get ( b ) || 3 != e . get ( c ) ) return ! 1 ; e . delete ( b ) ; e . set ( c , 4 ) ; return ! e . has ( b ) && 4 == e . get ( c ) ; } catch ( n ) { return ! 1 ; } } function c ( a ) { $jscomp . owns ( a , e ) || $jscomp . defineProperty ( a , e , { value : { } } ) ; } function d ( a ) { var b = Object [ a ] ; b && ( Object [ a ] = function ( a ) { c ( a ) ; return b ( a ) ; } ) ; } if ( $jscomp . USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS ) { if ( a && $jscomp . ES6_CONFORMANCE ) return a ; } else if ( b ( ) ) return a ; var e = "$jscomp_hidden_" + Math . random ( ) ; d ( "freeze" ) ; d ( "preventExtensions" ) ; d ( "seal" ) ; var g = 0 , f = function ( a ) { this . id_ = ( g += Math . random ( ) + 1 ) . toString ( ) ; if ( a ) { $jscomp . initSymbol ( ) ; $jscomp . initSymbolIterator ( ) ; a = $jscomp . makeIterator ( a ) ; for ( var b ; ! ( b = a . next ( ) ) . done ; ) b = b . value , this . set ( b [ 0 ] , b [ 1 ] ) ; } } ; f . prototype . set = function ( a , b ) { c ( a ) ; if ( ! $jscomp . owns ( a , e ) ) throw Error ( "WeakMap key fail: " + a ) ; a [ e ] [ this . id_ ] = b ; return this ; } ; f . prototype . get = function ( a ) { return $jscomp . owns ( a , e ) ? a [ e ] [ this . id_ ] : void 0 ; } ; f . prototype . has = function ( a ) { return $jscomp . owns ( a , e ) && $jscomp . owns ( a [ e ] , this . id_ ) ; } ; f . prototype . delete = function ( a ) { return $jscomp . owns ( a , e ) && $jscomp . owns ( a [ e ] , this . id_ ) ? delete a [ e ] [ this . id_ ] : ! 1 ; } ; return f ; } , "es6" , "es3" ) ; $jscomp . MapEntry = function ( ) { } ; $jscomp . polyfill ( "Map" , function ( a ) { function b ( ) { if ( $jscomp . ASSUME_NO_NATIVE_MAP || ! a || "function" != typeof a || ! a . prototype . entries || "function" != typeof Object . seal ) return ! 1 ; try { var b = Object . seal ( { x : 4 } ) , c = new a ( $jscomp . makeIterator ( [ [ b , "s" ] ] ) ) ; if ( "s" != c . get ( b ) || 1 != c . size || c . get ( { x : 4 } ) || c . set ( { x : 4 } , "t" ) != c || 2 != c . size ) return ! 1 ; var e = c . entries ( ) , d = e . next ( ) ; if ( d . done || d . value [ 0 ] != b || "s" != d . value [ 1 ] ) return ! 1 ; d = e . next ( ) ; return d . done || 4 != d . value [ 0 ] . x || "t" != d . value [ 1 ] || ! e . next ( ) . done ? ! 1 : ! 0 ; } catch ( q ) { return ! 1 ; } } if ( $jscomp . USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS ) { if ( a && $jscomp . ES6_CONFORMANCE ) return a ; } else if ( b ( ) ) return a ; $jscomp . initSymbol ( ) ; $jscomp . initSymbolIterator ( ) ; var c = new WeakMap , d = function ( a ) { this . data_ = { } ; this . head_ = f ( ) ; this . size = 0 ; if ( a ) { a = $jscomp . makeIterator ( a ) ; for ( var b ; ! ( b = a . next ( ) ) . done ; ) b = b . value , this . set ( b [ 0 ] , b [ 1 ] ) ; } } ; d . prototype . set = function ( a , b ) { a = 0 === a ? 0 : a ; var c = e ( this , a ) ; c . list || ( c . list = this . data_ [ c . id ] = [ ] ) ; c . entry ? c . entry . value = b : ( c . entry = { next : this . head_ , previous : this . head_ . previous , head : this . head_ , key : a , value : b } , c . list . push ( c . entry ) , this . head_ . previous . next = c . entry , this . head_ . previous = c . entry , this . size ++ ) ; return this ; } ; d . prototype . delete = function ( a ) { a = e ( this , a ) ; return a . entry && a . list ? ( a . list . splice ( a . index , 1 ) , a . list . length || delete this . data_ [ a . id ] , a . entry . previous . next = a . entry . next , a . entry . next . previous = a . entry . previous , a . entry . head = null , this . size -- , ! 0 ) : ! 1 ; } ; d . prototype . clear = function ( ) { this . data_ = { } ; this . head_ = this . head_ . previous = f ( ) ; this . size = 0 ; } ; d . prototype . has = function ( a ) { return ! ! e ( this , a ) . entry ; } ; d . prototype . get = function ( a ) { return ( a = e ( this , a ) . entry ) && a . value ; } ; d . prototype . entries = function ( ) { return g ( this , function ( a ) { return [ a . key , a . value ] ; } ) ; } ; d . prototype . keys = function ( ) { return g ( this , function ( a ) { return a . key ; } ) ; } ; d . prototype . values = function ( ) { return g ( this , function ( a ) { return a . value ; } ) ; } ; d . prototype . forEach = function ( a , b ) { for ( var c = this . entries ( ) , e ; ! ( e = c . next ( ) ) . done ; ) e = e . value , a . call ( b , e [ 1 ] , e [ 0 ] , this ) ; } ; d . prototype [ Symbol . iterator ] = d . prototype . entries ; var e = function ( a , b ) { var e = b && typeof b ; "object" == e || "function" == e ? c . has ( b ) ? e = c . get ( b ) : ( e = "" + ++ k , c . set ( b , e ) ) : e = "p_" + b ; var d = a . data_ [ e ] ; if ( d && $jscomp . owns ( a . data_ , e ) ) for ( a = 0 ; a < d . length ; a ++ ) { var g = d [ a ] ; if ( b !== b && g . key !== g . key || b === g . key ) return { id : e , list : d , index : a , entry : g } ; } return { id : e , list : d , index : - 1 , entry : void 0 } ; } , g = function ( a , b ) { var c = a . head_ ; return $jscomp . iteratorPrototype ( function ( ) { if ( c ) { for ( ; c . head != a . head_ ; ) c = c . previous ; for ( ; c . next != c . head ; ) return c = c . next , { done : ! 1 , value : b ( c ) } ; c = null ; } return { done : ! 0 , value : void 0 } ; } ) ; } , f = function ( ) { var a = { } ; return a . previous = a . next = a . head = a ; } , k = 0 ; return d ; } , "es6" , "es3" ) ; $jscomp . objectCreate = $jscomp . ASSUME_ES5 || "function" == typeof Object . create ? Object . create : function ( a ) { var b = function ( ) { } ; b . prototype = a ; return new b ; } ; $jscomp . construct = function ( ) { function a ( ) { function a ( ) { } new a ; Reflect . construct ( a , [ ] , function ( ) { } ) ; return new a instanceof a ; } if ( "undefined" != typeof Reflect && Reflect . construct ) { if ( a ( ) ) return Reflect . construct ; var b = Reflect . construct ; return function ( a , d , e ) { a = b ( a , d ) ; e && Reflect . setPrototypeOf ( a , e . prototype ) ; return a ; } ; } return function ( a , b , e ) { void 0 === e && ( e = a ) ; e = $jscomp . objectCreate ( e . prototype || Object . prototype ) ; return Function . prototype . apply . call ( a , e , b ) || e ; } ; } ( ) ; $jscomp . polyfill ( "Reflect.construct" , function ( a ) { return $jscomp . construct ; } , "es6" , "es3" ) ; $jscomp . underscoreProtoCanBeSet = function ( ) { var a = { a : ! 0 } , b = { } ; try { return b . __proto__ = a , b . a ; } catch ( c ) { } return ! 1 ; } ; $jscomp . setPrototypeOf = "function" == typeof Object . setPrototypeOf ? Object . setPrototypeOf : $jscomp . underscoreProtoCanBeSet ( ) ? function ( a , b ) { a . __proto__ = b ; if ( a . __proto__ !== b ) throw new TypeError ( a + " is not extensible" ) ; return a ; } : null ; $jscomp . polyfill ( "Reflect.setPrototypeOf" , function ( a ) { if ( a ) return a ; if ( $jscomp . setPrototypeOf ) { var b = $jscomp . setPrototypeOf ; return function ( a , d ) { try { return b ( a , d ) , ! 0 ; } catch ( e ) { return ! 1 ; } } ; } return null ; } , "es6" , "es5" ) ; var COMPILED = ! 0 , goog = goog || { } ; goog . global = this ; goog . isDef = function ( a ) { return void 0 !== a ; } ; goog . exportPath_ = function ( a , b , c ) { a = a . split ( "." ) ; c = c || goog . global ; a [ 0 ] in c || ! c . execScript || c . execScript ( "var " + a [ 0 ] ) ; for ( var d ; a . length && ( d = a . shift ( ) ) ; ) ! a . length && goog . isDef ( b ) ? c [ d ] = b : c = c [ d ] ? c [ d ] : c [ d ] = { } ; } ; goog . define = function ( a , b ) { COMPILED || ( goog . global . CLOSURE_UNCOMPILED_DEFINES && Object . prototype . hasOwnProperty . call ( goog . global . CLOSURE_UNCOMPILED_DEFINES , a ) ? b = goog . global . CLOSURE_UNCOMPILED_DEFINES [ a ] : goog . global . CLOSURE_DEFINES && Object . prototype . hasOwnProperty . call ( goog . global . CLOSURE_DEFINES , a ) && ( b = goog . global . CLOSURE_DEFINES [ a ] ) ) ; goog . exportPath_ ( a , b ) ; } ; goog . DEBUG = ! 0 ; goog . LOCALE = "en" ; goog . TRUSTED_SITE = ! 0 ; goog . STRICT_MODE_COMPATIBLE = ! 1 ; goog . DISALLOW_TEST_ONLY_CODE = COMPILED && ! goog . DEBUG ; goog . ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING = ! 1 ; goog . provide = function ( a ) { if ( ! COMPILED && goog . isProvided_ ( a ) ) throw Error ( 'Namespace "' + a + '" already declared.' ) ; goog . constructNamespace_ ( a ) ; } ; goog . constructNamespace_ = function ( a , b ) { if ( ! COMPILED ) { delete goog . implicitNamespaces_ [ a ] ; for ( var c = a ; ( c = c . substring ( 0 , c . lastIndexOf ( "." ) ) ) && ! goog . getObjectByName ( c ) ; ) goog . implicitNamespaces_ [ c ] = ! 0 ; } goog . exportPath_ ( a , b ) ; } ; goog . VALID_MODULE_RE_ = /^[a-zA-Z_$][a-zA-Z0-9._$]*$/ ; goog . module = function ( a ) { if ( ! goog . isString ( a ) || ! a || - 1 == a . search ( goog . VALID_MODULE_RE_ ) ) throw Error ( "Invalid module identifier" ) ; if ( ! goog . isInModuleLoader_ ( ) ) throw Error ( "Module " + a + " has been loaded incorrectly." ) ; if ( goog . moduleLoaderState_ . moduleName ) throw Error ( "goog.module may only be called once per module." ) ; goog . moduleLoaderState_ . moduleName = a ; if ( ! COMPILED ) { if ( goog . isProvided_ ( a ) ) throw Error ( 'Namespace "' + a + '" already declared.' ) ; delete goog . implicitNamespaces_ [ a ] ; } } ; goog . module . get = function ( a ) { return goog . module . getInternal_ ( a ) ; } ; goog . module . getInternal_ = function ( a ) { if ( ! COMPILED ) return goog . isProvided_ ( a ) ? a in goog . loadedModules_ ? goog . loadedModules_ [ a ] : goog . getObjectByName ( a ) : null ; } ; goog . moduleLoaderState_ = null ; goog . isInModuleLoader_ = function ( ) { return null != goog . moduleLoaderState_ ; } ; goog . module . declareTestMethods = function ( ) { if ( ! goog . isInModuleLoader_ ( ) ) throw Error ( "goog.module.declareTestMethods must be called from within a goog.module" ) ; goog . moduleLoaderState_ . declareTestMethods = ! 0 ; } ; goog . module . declareLegacyNamespace = function ( ) { if ( ! COMPILED && ! goog . isInModuleLoader_ ( ) ) throw Error ( "goog.module.declareLegacyNamespace must be called from within a goog.module" ) ; if ( ! COMPILED && ! goog . moduleLoaderState_ . moduleName ) throw Error ( "goog.module must be called prior to goog.module.declareLegacyNamespace." ) ; goog . moduleLoaderState_ . declareLegacyNamespace = ! 0 ; } ; goog . setTestOnly = function ( a ) { if ( goog . DISALLOW_TEST_ONLY_CODE ) throw a = a || "" , Error ( "Importing test-only code into non-debug environment" + ( a ? ": " + a : "." ) ) ; } ; goog . forwardDeclare = function ( a ) { } ; COMPILED || ( goog . isProvided_ = function ( a ) { return a in goog . loadedModules_ || ! goog . implicitNamespaces_ [ a ] && goog . isDefAndNotNull ( goog . getObjectByName ( a ) ) ; } , goog . implicitNamespaces_ = { "goog.module" : ! 0 } ) ; goog . getObjectByName = function ( a , b ) { a = a . split ( "." ) ; b = b || goog . global ; for ( var c ; c = a . shift ( ) ; ) if ( goog . isDefAndNotNull ( b [ c ] ) ) b = b [ c ] ; else return null ; return b ; } ; goog . globalize = function ( a , b ) { b = b || goog . global ; for ( var c in a ) b [ c ] = a [ c ] ; } ; goog . addDependency = function ( a , b , c , d ) { if ( goog . DEPENDENCIES_ENABLED ) { var e ; a = a . replace ( /\\/g , "/" ) ; for ( var g = goog . dependencies_ , f = 0 ; e = b [ f ] ; f ++ ) g . nameToPath [ e ] = a , g . pathIsModule [ a ] = ! ! d ; for ( d = 0 ; b = c [ d ] ; d ++ ) a in g . requires || ( g . requires [ a ] = { } ) , g . requires [ a ] [ b ] = ! 0 ; } } ; goog . ENABLE_DEBUG_LOADER = ! 0 ; goog . logToConsole_ = function ( a ) { goog . global . console && goog . global . console . error ( a ) ; } ; goog . require = function ( a ) { if ( ! COMPILED ) { goog . ENABLE_DEBUG_LOADER && goog . IS_OLD_IE_ && goog . maybeProcessDeferredDep_ ( a ) ; if ( goog . isProvided_ ( a ) ) return goog . isInModuleLoader_ ( ) ? goog . module . getInternal_ ( a ) : null ; if ( goog . ENABLE_DEBUG_LOADER ) { var b = goog . getPathFromDeps_ ( a ) ; if ( b ) return goog . included_ [ b ] = ! 0 , goog . writeScripts_ ( ) , null ; } a = "goog.require could not find: " + a ; goog . logToConsole_ ( a ) ; throw Error ( a ) ; } } ; goog . basePath = "" ; goog . nullFunction = function ( ) { } ; goog . abstractMethod = function ( ) { throw Error ( "unimplemented abstract method" ) ; } ; goog . addSingletonGetter = function ( a ) { a . getInstance = function ( ) { if ( a . instance_ ) return a . instance_ ; goog . DEBUG && ( goog . instantiatedSingletons_ [ goog . instantiatedSingletons_ . length ] = a ) ; return a . instance_ = new a ; } ; } ; goog . instantiatedSingletons_ = [ ] ; goog . LOAD_MODULE_USING_EVAL = ! 0 ; goog . SEAL_MODULE_EXPORTS = goog . DEBUG ; goog . loadedModules_ = { } ; goog . DEPENDENCIES_ENABLED = ! COMPILED && goog . ENABLE_DEBUG_LOADER ; goog . DEPENDENCIES_ENABLED && ( goog . included_ = { } , goog . dependencies_ = { pathIsModule : { } , nameToPath : { } , requires : { } , visited : { } , written : { } , deferred : { } } , goog . inHtmlDocument_ = function ( ) { var a = goog . global . document ; return "undefined" != typeof a && "write" in a ; } , goog . findBasePath_ = function ( ) { if ( goog . global . CLOSURE_BASE_PATH ) goog . basePath = goog . global . CLOSURE_BASE_PATH ; else if ( goog . inHtmlDocument_ ( ) ) for ( var a = goog . global . document . getElementsByTagName ( "SCRIPT" ) , b = a . length - 1 ; 0 <= b ; -- b ) { var c = a [ b ] . src , d = c . lastIndexOf ( "?" ) ; d = - 1 == d ? c . length : d ; if ( "base.js" == c . substr ( d - 7 , 7 ) ) { goog . basePath = c . substr ( 0 , d - 7 ) ; break ; } } } , goog . importScript_ = function ( a , b ) { ( goog . global . CLOSURE_IMPORT_SCRIPT || goog . writeScriptTag_ ) ( a , b ) && ( goog . dependencies_ . written [ a ] = ! 0 ) ; } , goog . IS_OLD_IE_ = ! goog . global . atob && goog . global . document && goog . global . document . all , goog . importModule_ = function ( a ) { goog . importScript_ ( "" , 'goog.retrieveAndExecModule_("' + a + '");' ) && ( goog . dependencies_ . written [ a ] = ! 0 ) ; } , goog . queuedModules_ = [ ] , goog . wrapModule_ = function ( a , b ) { return goog . LOAD_MODULE_USING_EVAL && goog . isDef ( goog . global . JSON ) ? "goog.loadModule(" + goog . global . JSON . stringify ( b + "\n//# sourceURL=" + a + "\n" ) + ");" : 'goog.loadModule(function(exports) {"use strict";' + b + "\n;return exports});\n//# sourceURL=" + a + "\n" ; } , goog . loadQueuedModules_ = function ( ) { var a = goog . queuedModules_ . length ; if ( 0 < a ) { var b = goog . queuedModules_ ; goog . queuedModules_ = [ ] ; for ( var c = 0 ; c < a ; c ++ ) goog . maybeProcessDeferredPath_ ( b [ c ] ) ; } } , goog . maybeProcessDeferredDep_ = function ( a ) { goog . isDeferredModule_ ( a ) && goog . allDepsAreAvailable_ ( a ) && ( a = goog . getPathFromDeps_ ( a ) , goog . maybeProcessDeferredPath_ ( goog . basePath + a ) ) ; } , goog . isDeferredModule_ = function ( a ) { return ( a = goog . getPathFromDeps_ ( a ) ) && goog . dependencies_ . pathIsModule [ a ] ? goog . basePath + a in goog . dependencies_ . deferred : ! 1 ; } , goog . allDepsAreAvailable_ = function ( a ) { if ( ( a = goog . getPathFromDeps_ ( a ) ) && a in goog . dependencies_ . requires ) for ( var b in goog . dependencies_ . requires [ a ] ) if ( ! goog . isProvided_ ( b ) && ! goog . isDeferredModule_ ( b ) ) return ! 1 ; return ! 0 ; } , goog . maybeProcessDeferredPath_ = function ( a ) { if ( a in goog . dependencies_ . deferred ) { var b = goog . dependencies_ . deferred [ a ] ; delete goog . dependencies_ . deferred [ a ] ; goog . globalEval ( b ) ; } } , goog . loadModule = function ( a ) { var b = goog . moduleLoaderState_ ; try { goog . moduleLoaderState_ = { moduleName : void 0 , declareTestMethods : ! 1 } ; if ( goog . isFunction ( a ) ) var c = a . call ( goog . global , { } ) ; else if ( goog . isString ( a ) ) c = goog . loadModuleFromSource_ . call ( goog . global , a ) ; else throw Error ( "Invalid module definition" ) ; var d = goog . moduleLoaderState_ . moduleName ; if ( ! goog . isString ( d ) || ! d ) throw Error ( 'Invalid module name "' + d + '"' ) ; goog . moduleLoaderState_ . declareLegacyNamespace ? goog . constructNamespace_ ( d , c ) : goog . SEAL_MODULE_EXPORTS && Object . seal && Object . seal ( c ) ; goog . loadedModules_ [ d ] = c ; if ( goog . moduleLoaderState_ . declareTestMethods ) for ( var e in c ) if ( 0 === e . indexOf ( "test" , 0 ) || "tearDown" == e || "setUp" == e || "setUpPage" == e || "tearDownPage" == e ) goog . global [ e ] = c [ e ] ; } finally { goog . moduleLoaderState_ = b ; } } , goog . loadModuleFromSource_ = function ( a ) { eval ( a ) ; return { } ; } , goog . writeScriptSrcNode_ = function ( a ) { goog . global . document . write ( '<script type="text/javascript" src="' + a + '">\x3c/script>' ) ; } , goog . appendScriptSrcNode_ = function ( a ) { var b = goog . global . document , c = b . createElement ( "script" ) ; c . type = "text/javascript" ; c . src = a ; c . defer = ! 1 ; c . async = ! 1 ; b . head . appendChild ( c ) ; } , goog . writeScriptTag_ = function ( a , b ) { if ( goog . inHtmlDocument_ ( ) ) { var c = goog . global . document ; if ( ! goog . ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING && "complete" == c . readyState ) { if ( /\bdeps.js$/ . test ( a ) ) return ! 1 ; throw Error ( 'Cannot write "' + a + '" after document load' ) ; } var d = goog . IS_OLD_IE_ ; void 0 === b ? d ? ( b = " onreadystatechange='goog.onScriptLoad_(this, " + ++ goog . lastNonModuleScriptIndex_ + ")' " , c . write ( '<script type="text/javascript" src="' + a + '"' + b + ">\x3c/script>" ) ) : goog . ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING ? goog . appendScriptSrcNode_ ( a ) : goog . writeScriptSrcNode_ ( a ) : c . write ( '<script type="text/javascript">' + b + "\x3c/script>" ) ; return ! 0 ; } return ! 1 ; } , goog . lastNonModuleScriptIndex_ = 0 , goog . onScriptLoad_ = function ( a , b ) { "complete" == a . readyState && goog . lastNonModuleScriptIndex_ == b && goog . loadQueuedModules_ ( ) ; return ! 0 ; } , goog . writeScripts_ = function ( ) { function a ( e ) { if ( ! ( e in d . written ) ) { if ( ! ( e in d . visited ) && ( d . visited [ e ] = ! 0 , e in d . requires ) ) for ( var g in d . requires [ e ] ) if ( ! goog . isProvided_ ( g ) ) if ( g in d . nameToPath ) a ( d . nameToPath [ g ] ) ; else throw Error ( "Undefined nameToPath for " + g ) ; e in c || ( c [ e ] = ! 0 , b . push ( e ) ) ; } } var b = [ ] , c = { } , d = goog . dependencies_ ; for ( g in goog . included_ ) d . written [ g ] || a ( g ) ; for ( var e = 0 ; e < b . length ; e ++ ) { var g = b [ e ] ; goog . dependencies_ . written [ g ] = ! 0 ; } var f = goog . moduleLoaderState_ ; goog . moduleLoaderState_ = null ; for ( e = 0 ; e < b . length ; e ++ ) if ( g = b [ e ] ) d . pathIsModule [ g ] ? goog . importModule_ ( goog . basePath + g ) : goog . importScript_ ( goog . basePath + g ) ; else throw goog . moduleLoaderState_ = f , Error ( "Undefined script input" ) ; goog . moduleLoaderState_ = f ; } , goog . getPathFromDeps_ = function ( a ) { return a in goog . dependencies_ . nameToPath ? goog . dependencies_ . nameToPath [ a ] : null ; } , goog . findBasePath_ ( ) , goog . global . CLOSURE_NO_DEPS || goog . importScript_ ( goog . basePath + "deps.js" ) ) ; goog . normalizePath_ = function ( a ) { a = a . split ( "/" ) ; for ( var b = 0 ; b < a . length ; ) "." == a [ b ] ? a . splice ( b , 1 ) : b && ".." == a [ b ] && a [ b - 1 ] && ".." != a [ b - 1 ] ? a . splice ( -- b , 2 ) : b ++ ; return a . join ( "/" ) ; } ; goog . loadFileSync_ = function ( a ) { if ( goog . global . CLOSURE_LOAD_FILE_SYNC ) return goog . global . CLOSURE_LOAD_FILE_SYNC ( a ) ; var b = new goog . global . XMLHttpRequest ; b . open ( "get" , a , ! 1 ) ; b . send ( ) ; return b . responseText ; } ; goog . retrieveAndExecModule_ = function ( a ) { if ( ! COMPILED ) { var b = a ; a = goog . normalizePath_ ( a ) ; var c = goog . global . CLOSURE_IMPORT_SCRIPT || goog . writeScriptTag_ , d = goog . loadFileSync_ ( a ) ; if ( null != d ) d = goog . wrapModule_ ( a , d ) , goog . IS_OLD_IE_ ? ( goog . dependencies_ . deferred [ b ] = d , goog . queuedModules_ . push ( b ) ) : c ( a , d ) ; else throw Error ( "load of " + a + "failed" ) ; } } ; goog . typeOf = function ( a ) { var b = typeof a ; if ( "object" == b ) if ( a ) { if ( a instanceof Array ) return "array" ; if ( a instanceof Object ) return b ; var c = Object . prototype . toString . call ( a ) ; if ( "[object Window]" == c ) return "object" ; if ( "[object Array]" == c || "number" == typeof a . length && "undefined" != typeof a . splice && "undefined" != typeof a . propertyIsEnumerable && ! a . propertyIsEnumerable ( "splice" ) ) return "array" ; if ( "[object Function]" == c || "undefined" != typeof a . call && "undefined" != typeof a . propertyIsEnumerable && ! a . propertyIsEnumerable ( "call" ) ) return "function" ; } else return "null" ; else if ( "function" == b && "undefined" == typeof a . call ) return "object" ; return b ; } ; goog . isNull = function ( a ) { return null === a ; } ; goog . isDefAndNotNull = function ( a ) { return null != a ; } ; goog . isArray = function ( a ) { return "array" == goog . typeOf ( a ) ; } ; goog . isArrayLike = function ( a ) { var b = goog . typeOf ( a ) ; return "array" == b || "object" == b && "number" == typeof a . length ; } ; goog . isDateLike = function ( a ) { return goog . isObject ( a ) && "function" == typeof a . getFullYear ; } ; goog . isString = function ( a ) { return "string" == typeof a ; } ; goog . isBoolean = function ( a ) { return "boolean" == typeof a ; } ; goog . isNumber = function ( a ) { return "number" == typeof a ; } ; goog . isFunction = function ( a ) { return "function" == goog . typeOf ( a ) ; } ; goog . isObject = function ( a ) { var b = typeof a ; return "object" == b && null != a || "function" == b ; } ; goog . getUid = function ( a ) { return a [ goog . UID_PROPERTY_ ] || ( a [ goog . UID_PROPERTY_ ] = ++ goog . uidCounter_ ) ; } ; goog . hasUid = function ( a ) { return ! ! a [ goog . UID_PROPERTY_ ] ; } ; goog . removeUid = function ( a ) { "removeAttribute" in a && a . removeAttribute ( goog . UID_PROPERTY_ ) ; try { delete a [ goog . UID_PROPERTY_ ] ; } catch ( b ) { } } ; goog . UID_PROPERTY_ = "closure_uid_" + ( 1E9 * Math . random ( ) >>> 0 ) ; goog . uidCounter_ = 0 ; goog . getHashCode = goog . getUid ; goog . removeHashCode = goog . removeUid ; goog . cloneObject = function ( a ) { var b = goog . typeOf ( a ) ; if ( "object" == b || "array" == b ) { if ( a . clone ) return a . clone ( ) ; b = "array" == b ? [ ] : { } ; for ( var c in a ) b [ c ] = goog . cloneObject ( a [ c ] ) ; return b ; } return a ; } ; goog . bindNative_ = function ( a , b , c ) { return a . call . apply ( a . bind , arguments ) ; } ; goog . bindJs_ = function ( a , b , c ) { if ( ! a ) throw Error ( ) ; if ( 2 < arguments . length ) { var d = Array . prototype . slice . call ( arguments , 2 ) ; return function ( ) { var e = Array . prototype . slice . call ( arguments ) ; Array . prototype . unshift . apply ( e , d ) ; return a . apply ( b , e ) ; } ; } return function ( ) { return a . apply ( b , arguments ) ; } ; } ; goog . bind = function ( a , b , c ) { Function . prototype . bind && - 1 != Function . prototype . bind . toString ( ) . indexOf ( "native code" ) ? goog . bind = goog . bindNative_ : goog . bind = goog . bindJs_ ; return goog . bind . apply ( null , arguments ) ; } ; goog . partial = function ( a , b ) { var c = Array . prototype . slice . call ( arguments , 1 ) ; return function ( ) { var b = c . slice ( ) ; b . push . apply ( b , arguments ) ; return a . apply ( this , b ) ; } ; } ; goog . mixin = function ( a , b ) { for ( var c in b ) a [ c ] = b [ c ] ; } ; goog . now = goog . TRUSTED_SITE && Date . now || function ( ) { return + new Date ; } ; goog . globalEval = function ( a ) { if ( goog . global . execScript ) goog . global . execScript ( a , "JavaScript" ) ; else if ( goog . global . eval ) if ( null == goog . evalWorksForGlobals_ && ( goog . global . eval ( "var _et_ = 1;" ) , "undefined" != typeof goog . global . _et_ ? ( delete goog . global . _et_ , goog . evalWorksForGlobals_ = ! 0 ) : goog . evalWorksForGlobals_ = ! 1 ) , goog . evalWorksForGlobals_ ) goog . global . eval ( a ) ; else { var b = goog . global . document , c = b . createElement ( "SCRIPT" ) ; c . type = "text/javascript" ; c . defer = ! 1 ; c . appendChild ( b . createTextNode ( a ) ) ; b . body . appendChild ( c ) ; b . body . removeChild ( c ) ; } else throw Error ( "goog.globalEval not available" ) ; } ; goog . evalWorksForGlobals_ = null ; goog . getCssName = function ( a , b ) { var c = function ( a ) { return goog . cssNameMapping_ [ a ] || a ; } , d = function ( a ) { a = a . split ( "-" ) ; for ( var b = [ ] , e = 0 ; e < a . length ; e ++ ) b . push ( c ( a [ e ] ) ) ; return b . join ( "-" ) ; } ; d = goog . cssNameMapping_ ? "BY_WHOLE" == goog . cssNameMappingStyle_ ? c : d : function ( a ) { return a ; } ; return b ? a + "-" + d ( b ) : d ( a ) ; } ; goog . setCssNameMapping = function ( a , b ) { goog . cssNameMapping_ = a ; goog . cssNameMappingStyle_ = b ; } ; ! COMPILED && goog . global . CLOSURE_CSS_NAME_MAPPING && ( goog . cssNameMapping_ = goog . global . CLOSURE_CSS_NAME_MAPPING ) ; goog . getMsg = function ( a , b ) { b && ( a = a . replace ( /\{\$([^}]+)}/g , function ( a , d ) { return d in b ? b [ d ] : a ; } ) ) ; return a ; } ; goog . getMsgWithFallback = function ( a , b ) { return a ; } ; goog . exportSymbol = function ( a , b , c ) { goog . exportPath_ ( a , b , c ) ; } ; goog . exportProperty = function ( a , b , c ) { a [ b ] = c ; } ; goog . inherits = function ( a , b ) { function c ( ) { } c . prototype = b . prototype ; a . superClass_ = b . prototype ; a . prototype = new c ; a . prototype . constructor = a ; a . base = function ( a , e , c ) { for ( var d = Array ( arguments . length - 2 ) , g = 2 ; g < arguments . length ; g ++ ) d [ g - 2 ] = arguments [ g ] ; return b . prototype [ e ] . apply ( a , d ) ; } ; } ; goog . base = function ( a , b , c ) { var d = arguments . callee . caller ; if ( goog . STRICT_MODE_COMPATIBLE || goog . DEBUG && ! d ) throw Error ( "arguments.caller not defined.  goog.base() cannot be used with strict mode code. See http://www.ecma-international.org/ecma-262/5.1/#sec-C" ) ; if ( d . superClass_ ) { for ( var e = Array ( arguments . length - 1 ) , g = 1 ; g < arguments . length ; g ++ ) e [ g - 1 ] = arguments [ g ] ; return d . superClass_ . constructor . apply ( a , e ) ; } e = Array ( arguments . length - 2 ) ; for ( g = 2 ; g < arguments . length ; g ++ ) e [ g - 2 ] = arguments [ g ] ; g = ! 1 ; for ( var f = a . constructor ; f ; f = f . superClass_ && f . superClass_ . constructor ) if ( f . prototype [ b ] === d ) g = ! 0 ; else if ( g ) return f . prototype [ b ] . apply ( a , e ) ; if ( a [ b ] === d ) return a . constructor . prototype [ b ] . apply ( a , e ) ; throw Error ( "goog.base called from a method of one name to a method of a different name" ) ; } ; goog . scope = function ( a ) { a . call ( goog . global ) ; } ; COMPILED || ( goog . global . COMPILED = COMPILED ) ; goog . defineClass = function ( a , b ) { var c = b . constructor , d = b . statics ; c && c != Object . prototype . constructor || ( c = function ( ) { throw Error ( "cannot instantiate an interface (no constructor defined)." ) ; } ) ; c = goog . defineClass . createSealingConstructor_ ( c , a ) ; a && goog . inherits ( c , a ) ; delete b . constructor ; delete b . statics ; goog . defineClass . applyProperties_ ( c . prototype , b ) ; null != d && ( d instanceof Function ? d ( c ) : goog . defineClass . applyProperties_ ( c , d ) ) ; return c ; } ; goog . defineClass . SEAL_CLASS_INSTANCES = goog . DEBUG ; goog . defineClass . createSealingConstructor_ = function ( a , b ) { if ( goog . defineClass . SEAL_CLASS_INSTANCES && Object . seal instanceof Function ) { if ( b && b . prototype && b . prototype [ goog . UNSEALABLE_CONSTRUCTOR_PROPERTY_ ] ) return a ; var c = function ( ) { var b = a . apply ( this , arguments ) || this ; b [ goog . UID_PROPERTY_ ] = b [ goog . UID_PROPERTY_ ] ; this . constructor === c && Object . seal ( b ) ; return b ; } ; return c ; } return a ; } ; goog . defineClass . OBJECT_PROTOTYPE_FIELDS_ = "constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf" . split ( " " ) ; goog . defineClass . applyProperties_ = function ( a , b ) { for ( var c in b ) Object . prototype . hasOwnProperty . call ( b , c ) && ( a [ c ] = b [ c ] ) ; for ( var d = 0 ; d < goog . defineClass . OBJECT_PROTOTYPE_FIELDS_ . length ; d ++ ) c = goog . defineClass . OBJECT_PROTOTYPE_FIELDS_ [ d ] , Object . prototype . hasOwnProperty . call ( b , c ) && ( a [ c ] = b [ c ] ) ; } ; goog . tagUnsealableClass = function ( a ) { ! COMPILED && goog . defineClass . SEAL_CLASS_INSTANCES && ( a . prototype [ goog . UNSEALABLE_CONSTRUCTOR_PROPERTY_ ] = ! 0 ) ; } ; goog . UNSEALABLE_CONSTRUCTOR_PROPERTY_ = "goog_defineClass_legacy_unsealable" ; var LOG_ALL = - 1 , LOG_NONE = 0 , LOG_OTHER = 1 , LOG_CPU = 2 , LOG_FPU = 4 , LOG_MEM = 8 , LOG_DMA = 16 , LOG_IO = 32 , LOG_PS2 = 64 , LOG_PIC = 128 , LOG_VGA = 256 , LOG_PIT = 512 , LOG_MOUSE = 1024 , LOG_PCI = 2048 , LOG_BIOS = 4096 , LOG_FLOPPY = 8192 , LOG_SERIAL = 16384 , LOG_DISK = 32768 , LOG_RTC = 65536 , LOG_HPET = 131072 , LOG_ACPI = 262144 , LOG_APIC = 524288 , LOG_NET = 1048576 , LOG_VIRTIO = 2097152 , LOG_9P = 4194304 , LOG_SB16 = 8388608 , LOG_NAMES = [ [ 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_FLOPPY , "FLOP" ] , [ LOG_SERIAL , "SERI" ] , [ LOG_RTC , "RTC" ] , [ LOG_HPET , "HPET" ] , [ LOG_ACPI , "ACPI" ] , [ LOG_APIC , "APIC" ] , [ LOG_NET , "NET" ] , [ LOG_VIRTIO , "VIO" ] , [ LOG_9P , "9P" ] , [ LOG_SB16 , "SB16" ] ] , TLB_SYSTEM_READ = 1 , TLB_SYSTEM_WRITE = 2 , TLB_USER_READ = 4 , TLB_USER_WRITE = 8 , flag_carry = 1 , flag_parity = 4 , flag_adjust = 16 , flag_zero = 64 , flag_sign = 128 , flag_trap = 256 , flag_interrupt = 512 , flag_direction = 1024 , flag_overflow = 2048 , flag_iopl = 12288 , flag_nt = 16384 , flag_rf = 65536 , flag_vm = 131072 , flag_ac = 262144 , flag_vif = 524288 , flag_vip = 1048576 , flag_id = 2097152 , flags_default = 2 , flags_mask = flag_carry | flag_parity | flag_adjust | flag_zero | flag_sign | flag_trap | flag_interrupt | flag_direction | flag_overflow | flag_iopl | flag_nt | flag_rf | flag_vm | flag_ac | flag_vif | flag_vip | flag_id , flags_all = flag_carry | flag_parity | flag_adjust | flag_zero | flag_sign | flag_overflow , OPSIZE_8 = 7 , OPSIZE_16 = 15 , OPSIZE_32 = 31 , PSE_ENABLED = 128 , reg_eax = 0 , reg_ecx = 1 , reg_edx = 2 , reg_ebx = 3 , reg_esp = 4 , reg_ebp = 5 , reg_esi = 6 , reg_edi = 7 , reg_ax = 0 , reg_cx = 2 , reg_dx = 4 , reg_bx = 6 , reg_sp = 8 , reg_bp = 10 , reg_si = 12 , reg_di = 14 , reg_al = 0 , reg_cl = 4 , reg_dl = 8 , reg_bl = 12 , reg_ah = 1 , reg_ch = 5 , reg_dh = 9 , reg_bh = 13 , reg_es = 0 , reg_cs = 1 , reg_ss = 2 , reg_ds = 3 , reg_fs = 4 , reg_gs = 5 , reg_tr = 6 , reg_ldtr = 7 , MMAP_BLOCK_BITS = 17 , MMAP_BLOCK_SIZE = 1 << MMAP_BLOCK_BITS , MEM_PAGE_WRITTEN = 1 , MAGIC_CPU_EXCEPTION = 233495534 , REPEAT_STRING_PREFIX_NONE = 0 , REPEAT_STRING_PREFIX_NZ = 1 , REPEAT_STRING_PREFIX_Z = 2 , CR0_PE = 1 , CR0_MP = 2 , CR0_EM = 4 , CR0_TS = 8 , CR0_ET = 16 , CR0_WP = 65536 , CR0_NW = 536870912 , CR0_CD = 1073741824 , CR0_PG = - 2147483648 , CR4_VME = 1 , CR4_PVI = 2 , CR4_TSD = 4 , CR4_PSE = 16 , CR4_DE = 8 , CR4_PAE = 32 , CR4_PGE = 128 , CR4_OSFXSR = 512 , CR4_OSXMMEXCPT = 1024 , SEG_PREFIX_NONE = - 1 , SEG_PREFIX_ZERO = 7 , IA32_SYSENTER_CS = 372 , IA32_SYSENTER_ESP = 373 , IA32_SYSENTER_EIP = 374 , IA32_TIME_STAMP_COUNTER = 16 , IA32_PLATFORM_ID = 23 , MSR_EBC_FREQUENCY_ID = 44 , IA32_APIC_BASE_MSR = 27 , IA32_BIOS_SIGN_ID = 139 , IA32_MISC_ENABLE = 416 , IA32_RTIT_CTL = 1392 , MSR_SMI_COUNT = 52 , IA32_MCG_CAP = 377 , IA32_KERNEL_GS_BASE = - 1073741567 , MSR_PKG_C2_RESIDENCY = 1549 , IA32_APIC_BASE_BSP = 256 , IA32_APIC_BASE_EXTD = 1024 , IA32_APIC_BASE_EN = 2048 , TSR_BACKLINK = 0 , TSR_CR3 = 28 , TSR_EIP = 32 , TSR_EFLAGS = 36 , TSR_EAX = 40 , TSR_ECX = 44 , TSR_EDX = 48 , TSR_EBX = 52 , TSR_ESP = 56 , TSR_EBP = 60 , TSR_ESI = 64 , TSR_EDI = 68 , TSR_ES = 72 , TSR_CS = 76 , TSR_SS = 80 , TSR_DS = 84 , TSR_FS = 88 , TSR_GS = 92 , TSR_LDT = 96 , FW_CFG_SIGNATURE = 0 , FW_CFG_RAM_SIZE = 3 , FW_CFG_NB_CPUS = 5 , PREFIX_MASK_REP = 24 , PREFIX_REPZ = 8 , PREFIX_REPNZ = 16 , PREFIX_MASK_SEGMENT = 7 , PREFIX_MASK_OPSIZE = 32 , PREFIX_MASK_ADDRSIZE = 64 , PREFIX_F2 = PREFIX_REPNZ , PREFIX_F3 = PREFIX_REPZ , PREFIX_66 = PREFIX_MASK_OPSIZE , MXCSR_MASK = 65471 , MIXER_CHANNEL_LEFT = 0 , MIXER_CHANNEL_RIGHT = 1 , MIXER_CHANNEL_BOTH = 2 , MIXER_SRC_MASTER = 0 , MIXER_SRC_PCSPEAKER = 1 , MIXER_SRC_DAC = 2 ; "undefined" === typeof window || window . requestAnimationFrame || ( window . requestAnimationFrame = window . mozRequestAnimationFrame || window . webkitRequestAnimationFrame ) ; function ScreenAdapter ( a , b ) { function c ( a ) { a = a . toString ( 16 ) ; return "#" + Array ( 7 - a . length ) . join ( "0" ) + a ; } function d ( a , b , c , d ) { a . style . width = "" ; a . style . height = "" ; d && ( a . style . transform = a . style . webkitTransform = a . style . MozTransform = "" ) ; var g = a . getBoundingClientRect ( ) ; d ? a . style . transform = a . style . webkitTransform = a . style . MozTransform = ( 1 === b ? "" : " scaleX(" + b + ")" ) + ( 1 === c ? "" : " scaleY(" + c + ")" ) : ( 0 === b % 1 && 0 === c % 1 ? ( e . style . imageRendering = "pixelated" , e . style [ "-ms-interpolation-mode" ] = "nearest-neighbor" ) : ( e . style . imageRendering = "" , e . style [ "-ms-interpolation-mode" ] = "" ) , d = window . devicePixelRatio || 1 , 0 !== d % 1 && ( b /= d , c /= d ) ) ; 1 !== b && ( a . style . width = g . width * b + "px" ) ; 1 !== c && ( a . style . height = g . height * c + "px" ) ; } console . assert ( a , "1st argument must be a DOM container" ) ; var e = a . getElementsByTagName ( "canvas" ) [ 0 ] , g = e . getContext ( "2d" ) , f = a . getElementsByTagName ( "div" ) [ 0 ] , k = document . createElement ( "div" ) , l , m , n , p , q = 1 , r = 1 , v , u = ! 1 , w , z , B , D = this ; a = 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 ] ) ; for ( var A = 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 ] ) , x = [ ] , C , y = 0 ; 256 > y ; y ++ ) C = 127 < y ? a [ y - 128 ] : 32 > y ? A [ y ] : y , x [ y ] = String . fromCharCode ( C ) ; g . imageSmoothingEnabled = ! 1 ; k . style . position = "absolute" ; k . style . backgroundColor = "#ccc" ; k . style . width = "7px" ; k . style . display = "inline-block" ; f . style . display = "block" ; e . style . display = "none" ; this . bus = b ; b . register ( "screen-set-mode" , function ( a ) { this . set_mode ( a ) ; } , this ) ; b . register ( "screen-fill-buffer-end" , function ( a ) { this . update_buffer ( a ) ; } , this ) ; b . register ( "screen-put-char" , function ( a ) { this . put_char ( a [ 0 ] , a [ 1 ] , a [ 2 ] , a [ 3 ] , a [ 4 ] ) ; } , this ) ; b . register ( "screen-update-cursor" , function ( a ) { this . update_cursor ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; b . register ( "screen-update-cursor-scanline" , function ( a ) { this . update_cursor_scanline ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; b . register ( "screen-clear" , function ( ) { this . clear_screen ( ) ; } , this ) ; b . register ( "screen-set-size-text" , function ( a ) { this . set_size_text ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; b . register ( "screen-set-size-graphical" , function ( a ) { this . set_size_graphical ( a [ 0 ] , a [ 1 ] , a [ 2 ] , a [ 3 ] ) ; } , this ) ; this . init = function ( ) { this . set_size_text ( 80 , 25 ) ; this . timer ( ) ; } ; this . make_screenshot = function ( ) { try { window . open ( e . toDataURL ( ) ) ; } catch ( G ) { } } ; this . put_char = function ( a , b , c , e , d ) { a < B && b < z && ( b = 3 * ( a * z + b ) , w [ b ] = c , w [ b + 1 ] = e , w [ b + 2 ] = d , v [ a ] = 1 ) ; } ; this . timer = function ( ) { requestAnimationFrame ( u ? E : F ) ; } ; var F = function ( ) { for ( var a = 0 ; a < B ; a ++ ) v [ a ] && ( D . text_update_row ( a ) , v [ a ] = 0 ) ; this . timer ( ) ; } . bind ( this ) , E = function ( ) { this . bus . send ( "screen-fill-buffer" ) ; this . timer ( ) ; } . bind ( this ) ; this . destroy = function ( ) { } ; this . set_mode = function ( a ) { ( u = a ) ? ( f . style . display = "none" , e . style . display = "block" ) : ( f . style . display = "block" , e . style . display = "none" ) ; } ; this . clear_screen = function ( ) { g . fillStyle = "#000" ; g . fillRect ( 0 , 0 , e . width , e . height ) ; } ; this . set_size_text = function ( a , b ) { if ( a !== z || b !== B ) { v = new Int8Array ( b ) ; w = new Int32Array ( a * b * 3 ) ; z = a ; for ( B = b ; f . childNodes . length > b ; ) f . removeChild ( f . firstChild ) ; for ( ; f . childNodes . length < b ; ) f . appendChild ( document . createElement ( "div" ) ) ; for ( a = 0 ; a < b ; a ++ ) this . text_update_row ( a ) ; d ( f , q , r , ! 0 ) ; } } ; this . set_size_graphical = function ( a , b , c , f ) { DEBUG_SCREEN_LAYERS && ( a = c , b = f ) ; e . style . display = "block" ; e . width = a ; e . height = b ; l = g . createImageData ( c , f ) ; new Uint8Array ( l . data . buffer ) ; m = new Int32Array ( l . data . buffer ) ; this . bus . send ( "screen-tell-buffer" , [ m ] , [ m . buffer ] ) ; d ( e , q , r , ! 1 ) ; } ; this . set_scale = function ( a , b ) { q = a ; r = b ; d ( f , q , r , ! 0 ) ; d ( e , q , r , ! 1 ) ; } ; this . set_scale ( q , r ) ; this . update_cursor_scanline = function ( a , b ) { a & 32 ? k . style . display = "none" : ( k . style . display = "inline" , k . style . height = Math . min ( 15 , b - a ) + "px" , k . style . marginTop = Math . min ( 15 , a ) + "px" ) ; } ; this . update_cursor = function ( a , b ) { if ( a !== n || b !== p ) v [ a ] = 1 , v [ n ] = 1 , n = a , p = b ; } ; this . text_update_row = function ( a ) { var b = 3 * a * z , e ; var d = f . childNodes [ a ] ; var g = document . createElement ( "div" ) ; for ( var l = 0 ; l < z ; ) { var m = document . createElement ( "span" ) ; var v = w [ b + 1 ] ; var r = w [ b + 2 ] ; m . style . backgroundColor = c ( v ) ; m . style . color = c ( r ) ; for ( e = "" ; l < z && w [ b + 1 ] === v && w [ b + 2 ] === r ; ) if ( e += x [ w [ b ] ] , l ++ , b += 3 , a === n ) if ( l === p ) break ; else if ( l === p + 1 ) { g . appendChild ( k ) ; break ; } m . textContent = e ; g . appendChild ( m ) ; } d . parentNode . replaceChild ( g , d ) ; } ; this . update_buffer = function ( a ) { DEBUG_SCREEN_LAYERS ? ( g . putImageData ( l , 0 , 0 ) , g . strokeStyle = "#0F0" , g . lineWidth = 4 , a . forEach ( function ( a ) { g . strokeRect ( a . buffer_x , a . buffer_y , a . buffer_width , a . buffer_height ) ; } ) , g . lineWidth = 1 ) : a . forEach ( function ( a ) { g . putImageData ( l , a . screen_x - a . buffer_x , a . screen_y - a . buffer_y , a . buffer_x , a . buffer_y , a . buffer_width , a . buffer_height ) ; } ) ; } ; this . init ( ) ; } ; var EPERM = 1 , ENOENT = 2 , EINVAL = 22 , ENOTSUPP = 524 , ENOTEMPTY = 39 , EPROTO = 71 , P9_SETATTR_MODE = 1 , P9_SETATTR_UID = 2 , P9_SETATTR_GID = 4 , P9_SETATTR_SIZE = 8 , P9_SETATTR_ATIME = 16 , P9_SETATTR_MTIME = 32 , P9_SETATTR_CTIME = 64 , P9_SETATTR_ATIME_SET = 128 , P9_SETATTR_MTIME_SET = 256 , P9_STAT_MODE_DIR = 2147483648 , P9_STAT_MODE_APPEND = 1073741824 , P9_STAT_MODE_EXCL = 536870912 , P9_STAT_MODE_MOUNT = 268435456 , P9_STAT_MODE_AUTH = 134217728 , P9_STAT_MODE_TMP = 67108864 , P9_STAT_MODE_SYMLINK = 33554432 , P9_STAT_MODE_LINK = 16777216 , P9_STAT_MODE_DEVICE = 8388608 , P9_STAT_MODE_NAMED_PIPE = 2097152 , P9_STAT_MODE_SOCKET = 1048576 , P9_STAT_MODE_SETUID = 524288 , P9_STAT_MODE_SETGID = 262144 , P9_STAT_MODE_SETVTX = 65536 , FID_NONE = - 1 , FID_INODE = 1 , FID_XATTR = 2 ; function Virtio9p ( a , b ) { this . fs = a ; this . bus = b ; this . SendReply = function ( a , b ) { } ; this . deviceid = 9 ; this . hostfeature = 1 ; this . configspace = new Uint8Array ( [ 6 , 0 , 104 , 111 , 115 , 116 , 57 , 112 ] ) ; this . VERSION = "9P2000.L" ; this . msize = this . BLOCKSIZE = 8192 ; this . replybuffer = new Uint8Array ( 2 * this . msize ) ; this . replybuffersize = 0 ; this . fids = [ ] ; } Virtio9p . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . deviceid ; a [ 1 ] = this . hostfeature ; a [ 2 ] = this . configspace ; a [ 3 ] = this . VERSION ; a [ 4 ] = this . BLOCKSIZE ; a [ 5 ] = this . msize ; a [ 6 ] = this . replybuffer ; a [ 7 ] = this . replybuffersize ; a [ 8 ] = this . fids . map ( function ( a ) { return [ a . inodeid , a . type , a . uid ] ; } ) ; return a ; } ; Virtio9p . prototype . set_state = function ( a ) { this . deviceid = a [ 0 ] ; this . hostfeature = a [ 1 ] ; this . configspace = a [ 2 ] ; this . VERSION = a [ 3 ] ; this . BLOCKSIZE = a [ 4 ] ; this . msize = a [ 5 ] ; this . replybuffer = a [ 6 ] ; this . replybuffersize = a [ 7 ] ; this . fids = a [ 8 ] . map ( function ( a ) { return { inodeid : a [ 0 ] , type : a [ 1 ] , uid : a [ 2 ] } ; } ) ; } ; Virtio9p . prototype . Createfid = function ( a , b , c ) { return { inodeid : a , type : b , uid : c } ; } ; Virtio9p . prototype . Reset = function ( ) { this . fids = [ ] ; } ; Virtio9p . prototype . BuildReply = function ( a , b , c ) { marshall . Marshall ( [ "w" , "b" , "h" ] , [ c + 7 , a + 1 , b ] , this . replybuffer , 0 ) ; c + 7 >= this . replybuffer . length && message . Debug ( "Error in 9p: payloadsize exceeds maximum length" ) ; this . replybuffersize = c + 7 ; } ; Virtio9p . prototype . SendError = function ( a , b , c ) { b = marshall . Marshall ( [ "w" ] , [ c ] , this . replybuffer , 7 ) ; this . BuildReply ( 6 , a , b ) ; } ; Virtio9p . prototype . ReceiveRequest = function ( a , b ) { var c = marshall . Unmarshall2 ( [ "w" , "b" , "h" ] , b ) , d = c [ 0 ] , e = c [ 1 ] , g = c [ 2 ] ; switch ( e ) { case 8 : d = this . fs . GetTotalSize ( ) ; b = this . fs . GetSpace ( ) ; var f = [ 16914839 ] ; f [ 1 ] = this . BLOCKSIZE ; f [ 2 ] = Math . floor ( b / f [ 1 ] ) ; f [ 3 ] = f [ 2 ] - Math . floor ( d / f [ 1 ] ) ; f [ 4 ] = f [ 2 ] - Math . floor ( d / f [ 1 ] ) ; f [ 5 ] = this . fs . inodes . length ; f [ 6 ] = 1048576 ; f [ 7 ] = 0 ; f [ 8 ] = 256 ; d = marshall . Marshall ( "wwddddddw" . split ( "" ) , f , this . replybuffer , 7 ) ; this . BuildReply ( e , g , d ) ; this . SendReply ( 0 , a ) ; break ; case 112 : case 12 : f = marshall . Unmarshall2 ( [ "w" , "w" ] , b ) ; var k = f [ 0 ] ; c = f [ 1 ] ; message . Debug ( "[open] fid=" + k + ", mode=" + c ) ; b = this . fids [ k ] . inodeid ; var l = this . fs . GetInode ( b ) ; message . Debug ( "file open " + l . name ) ; b = this . fs . OpenInode ( b , c ) ; this . fs . AddEvent ( this . fids [ k ] . inodeid , function ( ) { message . Debug ( "file opened " + l . name + " tag:" + g ) ; f [ 0 ] = l . qid ; f [ 1 ] = this . msize - 24 ; marshall . Marshall ( [ "Q" , "w" ] , f , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 17 ) ; this . SendReply ( 0 , a ) ; } . bind ( this ) ) ; break ; case 70 : f = marshall . Unmarshall2 ( [ "w" , "w" , "s" ] , b ) ; c = f [ 0 ] ; k = f [ 1 ] ; b = f [ 2 ] ; message . Debug ( "[link] dfid=" + c + ", name=" + b ) ; l = this . fs . CreateInode ( ) ; d = this . fs . GetInode ( this . fids [ k ] . inodeid ) ; var m = this . fs . inodedata [ this . fids [ k ] . inodeid ] ; l . mode = d . mode ; l . size = d . size ; l . symlink = d . symlink ; var n = this . fs . inodedata [ this . fs . inodes . length ] = new Uint8Array ( l . size ) ; for ( d = 0 ; d < l . size ; d ++ ) n [ d ] = m [ d ] ; l . name = b ; l . parentid = this . fids [ c ] . inodeid ; this . fs . PushInode ( l ) ; this . BuildReply ( e , g , 0 ) ; this . SendReply ( 0 , a ) ; break ; case 16 : f = marshall . Unmarshall2 ( [ "w" , "s" , "s" , "w" ] , b ) ; k = f [ 0 ] ; b = f [ 1 ] ; c = f [ 2 ] ; d = f [ 3 ] ; message . Debug ( "[symlink] fid=" + k + ", name=" + b + ", symgt=" + c + ", gid=" + d ) ; b = this . fs . CreateSymlink ( b , this . fids [ k ] . inodeid , c ) ; l = this . fs . GetInode ( b ) ; l . uid = this . fids [ k ] . uid ; l . gid = d ; marshall . Marshall ( [ "Q" ] , [ l . qid ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 13 ) ; this . SendReply ( 0 , a ) ; break ; case 18 : f = marshall . Unmarshall2 ( "wswwww" . split ( "" ) , b ) ; k = f [ 0 ] ; b = f [ 1 ] ; c = f [ 2 ] ; m = f [ 3 ] ; n = f [ 4 ] ; d = f [ 5 ] ; message . Debug ( "[mknod] fid=" + k + ", name=" + b + ", major=" + m + ", minor=" + n ) ; b = this . fs . CreateNode ( b , this . fids [ k ] . inodeid , m , n ) ; l = this . fs . GetInode ( b ) ; l . mode = c ; l . uid = this . fids [ k ] . uid ; l . gid = d ; marshall . Marshall ( [ "Q" ] , [ l . qid ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 13 ) ; this . SendReply ( 0 , a ) ; break ; case 22 : f = marshall . Unmarshall2 ( [ "w" ] , b ) ; k = f [ 0 ] ; message . Debug ( "[readlink] fid=" + k ) ; l = this . fs . GetInode ( this . fids [ k ] . inodeid ) ; d = marshall . Marshall ( [ "s" ] , [ l . symlink ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , d ) ; this . SendReply ( 0 , a ) ; break ; case 72 : f = marshall . Unmarshall2 ( [ "w" , "s" , "w" , "w" ] , b ) ; k = f [ 0 ] ; b = f [ 1 ] ; c = f [ 2 ] ; d = f [ 3 ] ; message . Debug ( "[mkdir] fid=" + k + ", name=" + b + ", mode=" + c + ", gid=" + d ) ; b = this . fs . CreateDirectory ( b , this . fids [ k ] . inodeid ) ; l = this . fs . GetInode ( b ) ; l . mode = c | S_IFDIR ; l . uid = this . fids [ k ] . uid ; l . gid = d ; marshall . Marshall ( [ "Q" ] , [ l . qid ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 13 ) ; this . SendReply ( 0 , a ) ; break ; case 14 : f = marshall . Unmarshall2 ( [ "w" , "s" , "w" , "w" , "w" ] , b ) ; k = f [ 0 ] ; b = f [ 1 ] ; m = f [ 2 ] ; c = f [ 3 ] ; d = f [ 4 ] ; message . Debug ( "[create] fid=" + k + ", name=" + b + ", flags=" + m + ", mode=" + c + ", gid=" + d ) ; b = this . fs . CreateFile ( b , this . fids [ k ] . inodeid ) ; this . fids [ k ] . inodeid = b ; this . fids [ k ] . type = FID_INODE ; l = this . fs . GetInode ( b ) ; l . uid = this . fids [ k ] . uid ; l . gid = d ; l . mode = c ; marshall . Marshall ( [ "Q" , "w" ] , [ l . qid , this . msize - 24 ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 17 ) ; this . SendReply ( 0 , a ) ; break ; case 52 : message . Debug ( "lock file\n" ) ; marshall . Marshall ( [ "w" ] , [ 0 ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 1 ) ; this . SendReply ( 0 , a ) ; break ; case 24 : f = marshall . Unmarshall2 ( [ "w" , "d" ] , b ) ; k = f [ 0 ] ; l = this . fs . GetInode ( this . fids [ k ] . inodeid ) ; message . Debug ( "[getattr]: fid=" + k + " name=" + l . name + " request mask=" + f [ 1 ] ) ; if ( ! l || l . status === STATUS_UNLINKED ) { message . Debug ( "getattr: unlinked" ) ; this . SendError ( g , "No such file or directory" , ENOENT ) ; this . SendReply ( 0 , a ) ; break ; } f [ 0 ] |= 4096 ; f [ 0 ] = f [ 1 ] ; f [ 1 ] = l . qid ; f [ 2 ] = l . mode ; f [ 3 ] = l . uid ; f [ 4 ] = l . gid ; f [ 5 ] = l . nlinks ; f [ 6 ] = l . major << 8 | l . minor ; f [ 7 ] = l . size ; f [ 8 ] = this . BLOCKSIZE ; f [ 9 ] = Math . floor ( l . size / 512 + 1 ) ; f [ 10 ] = l . atime ; f [ 11 ] = 0 ; f [ 12 ] = l . mtime ; f [ 13 ] = 0 ; f [ 14 ] = l . ctime ; f [ 15 ] = 0 ; f [ 16 ] = 0 ; f [ 17 ] = 0 ; f [ 18 ] = 0 ; f [ 19 ] = 0 ; marshall . Marshall ( "dQwwwddddddddddddddd" . split ( "" ) , f , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 153 ) ; this . SendReply ( 0 , a ) ; break ; case 26 : f = marshall . Unmarshall2 ( "wwwwwddddd" . split ( "" ) , b ) ; k = f [ 0 ] ; l = this . fs . GetInode ( this . fids [ k ] . inodeid ) ; message . Debug ( "[setattr]: fid=" + k + " request mask=" + f [ 1 ] + " name=" + l . name ) ; f [ 1 ] & P9_SETATTR_MODE && ( l . mode = f [ 2 ] ) ; f [ 1 ] & P9_SETATTR_UID && ( l . uid = f [ 3 ] ) ; f [ 1 ] & P9_SETATTR_GID && ( l . gid = f [ 4 ] ) ; f [ 1 ] & P9_SETATTR_ATIME && ( l . atime = Math . floor ( ( new Date ) . getTime ( ) / 1E3 ) ) ; f [ 1 ] & P9_SETATTR_MTIME && ( l . mtime = Math . floor ( ( new Date ) . getTime ( ) / 1E3 ) ) ; f [ 1 ] & P9_SETATTR_CTIME && ( l . ctime = Math . floor ( ( new Date ) . getTime ( ) / 1E3 ) ) ; f [ 1 ] & P9_SETATTR_ATIME_SET && ( l . atime = f [ 6 ] ) ; f [ 1 ] & P9_SETATTR_MTIME_SET && ( l . mtime = f [ 8 ] ) ; f [ 1 ] & P9_SETATTR_SIZE && this . fs . ChangeSize ( this . fids [ k ] . inodeid , f [ 5 ] ) ; this . BuildReply ( e , g , 0 ) ; this . SendReply ( 0 , a ) ; break ; case 50 : f = marshall . Unmarshall2 ( [ "w" , "d" ] , b ) ; k = f [ 0 ] ; this . BuildReply ( e , g , 0 ) ; this . SendReply ( 0 , a ) ; break ; case 40 : case 116 : f = marshall . Unmarshall2 ( [ "w" , "d" , "w" ] , b ) ; k = f [ 0 ] ; var p = f [ 1 ] , q = f [ 2 ] ; l = this . fs . GetInode ( this . fids [ k ] . inodeid ) ; 40 == e && message . Debug ( "[treaddir]: fid=" + k + " offset=" + p + " count=" + q ) ; 116 == e && message . Debug ( "[read]: fid=" + k + " (" + l . name + ") offset=" + p + " count=" + q + " fidtype=" + this . fids [ k ] . type ) ; if ( ! l || l . status === STATUS_UNLINKED ) { message . Debug ( "read/treaddir: unlinked" ) ; this . SendError ( g , "No such file or directory" , ENOENT ) ; this . SendReply ( 0 , a ) ; break ; } if ( this . fids [ k ] . type == FID_XATTR ) { l . caps . length < p + q && ( q = l . caps . length - p ) ; for ( d = 0 ; d < q ; d ++ ) this . replybuffer [ 11 + d ] = l . caps [ p + d ] ; marshall . Marshall ( [ "w" ] , [ q ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 4 + q ) ; this . SendReply ( 0 , a ) ; } else { var r = this . fs . inodes [ this . fids [ k ] . inodeid ] ; this . bus . send ( "9p-read-start" ) ; this . fs . OpenInode ( this . fids [ k ] . inodeid , void 0 ) ; this . fs . AddEvent ( this . fids [ k ] . inodeid , function ( ) { this . bus . send ( "9p-read-end" , [ r . name , q ] ) ; l . size < p + q && ( q = l . size - p ) ; var b = this . fs . inodedata [ this . fids [ k ] . inodeid ] ; if ( b ) for ( var c = 0 ; c < q ; c ++ ) this . replybuffer [ 11 + c ] = b [ p + c ] ; marshall . Marshall ( [ "w" ] , [ q ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 4 + q ) ; this . SendReply ( 0 , a ) ; } . bind ( this ) ) ; } break ; case 118 : f = marshall . Unmarshall2 ( [ "w" , "d" , "w" ] , b ) ; k = f [ 0 ] ; p = f [ 1 ] ; q = f [ 2 ] ; message . Debug ( "[write]: fid=" + k + " (" + this . fs . inodes [ this . fids [ k ] . inodeid ] . name + ") offset=" + p + " count=" + q ) ; this . fs . Write ( this . fids [ k ] . inodeid , p , q , b ) ; r = this . fs . inodes [ this . fids [ k ] . inodeid ] ; this . bus . send ( "9p-write-end" , [ r . name , q ] ) ; marshall . Marshall ( [ "w" ] , [ q ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 4 ) ; this . SendReply ( 0 , a ) ; break ; case 74 : f = marshall . Unmarshall2 ( [ "w" , "s" , "w" , "s" ] , b ) ; b = f [ 0 ] ; d = f [ 1 ] ; c = f [ 2 ] ; m = f [ 3 ] ; message . Debug ( "[renameat]: oldname=" + d + " newname=" + m ) ; b = this . fs . Rename ( this . fids [ b ] . inodeid , d , this . fids [ c ] . inodeid , m ) ; if ( 0 == b ) { this . SendError ( g , "No such file or directory" , ENOENT ) ; this . SendReply ( 0 , a ) ; break ; } this . BuildReply ( e , g , 0 ) ; this . SendReply ( 0 , a ) ; break ; case 76 : f = marshall . Unmarshall2 ( [ "w" , "s" , "w" ] , b ) ; d = f [ 0 ] ; b = f [ 1 ] ; m = f [ 2 ] ; message . Debug ( "[unlink]: dirfd=" + d + " name=" + b + " flags=" + m ) ; k = this . fs . Search ( this . fids [ d ] . inodeid , b ) ; if ( - 1 == k ) { this . SendError ( g , "No such file or directory" , ENOENT ) ; this . SendReply ( 0 , a ) ; break ; } b = this . fs . Unlink ( k ) ; if ( ! b ) { this . SendError ( g , "Directory not empty" , ENOTEMPTY ) ; this . SendReply ( 0 , a ) ; break ; } this . BuildReply ( e , g , 0 ) ; this . SendReply ( 0 , a ) ; break ; case 100 : b = marshall . Unmarshall2 ( [ "w" , "s" ] , b ) ; message . Debug ( "[version]: msize=" + b [ 0 ] + " version=" + b [ 1 ] ) ; this . msize = b [ 0 ] ; d = marshall . Marshall ( [ "w" , "s" ] , [ this . msize , this . VERSION ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , d ) ; this . SendReply ( 0 , a ) ; break ; case 104 : f = marshall . Unmarshall2 ( [ "w" , "w" , "s" , "s" , "w" ] , b ) ; k = f [ 0 ] ; b = f [ 4 ] ; message . Debug ( "[attach]: fid=" + k + " afid=" + hex8 ( f [ 1 ] ) + " uname=" + f [ 2 ] + " aname=" + f [ 3 ] ) ; this . fids [ k ] = this . Createfid ( 0 , FID_INODE , b ) ; l = this . fs . GetInode ( this . fids [ k ] . inodeid ) ; marshall . Marshall ( [ "Q" ] , [ l . qid ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 13 ) ; this . SendReply ( 0 , a ) ; break ; case 108 : f = marshall . Unmarshall2 ( [ "h" ] , b ) ; message . Debug ( "[flush] " + g ) ; this . BuildReply ( e , g , 0 ) ; this . SendReply ( 0 , a ) ; break ; case 110 : f = marshall . Unmarshall2 ( [ "w" , "w" , "h" ] , b ) ; k = f [ 0 ] ; c = f [ 1 ] ; m = f [ 2 ] ; message . Debug ( "[walk]: fid=" + f [ 0 ] + " nwfid=" + f [ 1 ] + " nwname=" + m ) ; if ( 0 == m ) { this . fids [ c ] = this . Createfid ( this . fids [ k ] . inodeid , FID_INODE , this . fids [ k ] . uid ) ; marshall . Marshall ( [ "h" ] , [ 0 ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 2 ) ; this . SendReply ( 0 , a ) ; break ; } n = [ ] ; for ( d = 0 ; d < m ; d ++ ) n . push ( "s" ) ; n = marshall . Unmarshall2 ( n , b ) ; b = this . fids [ k ] . inodeid ; p = 9 ; var v = 0 ; message . Debug ( "walk in dir " + this . fs . inodes [ b ] . name + " to: " + n . toString ( ) ) ; for ( d = 0 ; d < m ; d ++ ) { b = this . fs . Search ( b , n [ d ] ) ; if ( - 1 == b ) { message . Debug ( "Could not find: " + n [ d ] ) ; break ; } p += marshall . Marshall ( [ "Q" ] , [ this . fs . inodes [ b ] . qid ] , this . replybuffer , p ) ; v ++ ; this . fids [ c ] = this . Createfid ( b , FID_INODE , this . fids [ k ] . uid ) ; } marshall . Marshall ( [ "h" ] , [ v ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , p - 7 ) ; this . SendReply ( 0 , a ) ; break ; case 120 : f = marshall . Unmarshall2 ( [ "w" ] , b ) ; message . Debug ( "[clunk]: fid=" + f [ 0 ] ) ; this . fids [ f [ 0 ] ] && 0 <= this . fids [ f [ 0 ] ] . inodeid && ( this . fs . CloseInode ( this . fids [ f [ 0 ] ] . inodeid ) , this . fids [ f [ 0 ] ] . inodeid = - 1 , this . fids [ f [ 0 ] ] . type = FID_NONE ) ; this . BuildReply ( e , g , 0 ) ; this . SendReply ( 0 , a ) ; break ; case 32 : f = marshall . Unmarshall2 ( [ "w" , "s" , "d" , "w" ] , b ) ; k = f [ 0 ] ; b = f [ 1 ] ; d = f [ 2 ] ; m = f [ 3 ] ; message . Debug ( "[txattrcreate]: fid=" + k + " name=" + b + " attr_size=" + d + " flags=" + m ) ; this . BuildReply ( e , g , 0 ) ; this . SendReply ( 0 , a ) ; break ; case 30 : f = marshall . Unmarshall2 ( [ "w" , "w" , "s" ] , b ) ; k = f [ 0 ] ; d = f [ 1 ] ; b = f [ 2 ] ; message . Debug ( "[xattrwalk]: fid=" + f [ 0 ] + " newfid=" + f [ 1 ] + " name=" + f [ 2 ] ) ; this . fids [ d ] = this . Createfid ( this . fids [ k ] . inodeid , FID_NONE , this . fids [ k ] . uid ) ; c = 0 ; "security.capability" == b && ( c = this . fs . PrepareCAPs ( this . fids [ k ] . inodeid ) , this . fids [ d ] . type = FID_XATTR ) ; marshall . Marshall ( [ "d" ] , [ c ] , this . replybuffer , 7 ) ; this . BuildReply ( e , g , 8 ) ; this . SendReply ( 0 , a ) ; break ; default : message . Debug ( "Error in Virtio9p: Unknown id " + e + " received" ) , message . Abort ( ) ; } } ; var DEBUG = ! 1 , LOG_TO_FILE = ! 1 , LOG_ALL_IO = ! 1 , LOG_PAGE_FAULTS = ! 1 , LOG_LEVEL = LOG_ALL & ~ LOG_PS2 & ~ LOG_PIT & ~ LOG_VIRTIO & ~ LOG_9P & ~ LOG_PIC & ~ LOG_DMA & ~ LOG_SERIAL & ~ LOG_NET & ~ LOG_FLOPPY & ~ LOG_DISK , DEBUG_SCREEN_LAYERS = DEBUG && ! 1 , ENABLE_HPET = DEBUG && ! 1 , ENABLE_ACPI = ! 1 , LOOP_COUNTER = 11001 , TIME_PER_FRAME = 1 , TSC_RATE = 8192 , APIC_TIMER_FREQ = TSC_RATE , VMWARE_HYPERVISOR_PORT = ! 0 ; function IO ( a ) { this . ports = [ ] ; this . cpu = a ; for ( var b = 0 ; 65536 > b ; b ++ ) this . ports [ b ] = this . create_empty_entry ( ) ; var c = a . memory_size ; for ( b = 0 ; b << MMAP_BLOCK_BITS < c ; b ++ ) a . memory_map_read8 [ b ] = a . memory_map_write8 [ b ] = void 0 , a . memory_map_read32 [ b ] = a . memory_map_write32 [ b ] = void 0 ; this . mmap_register ( c , 4294967296 - c , function ( a ) { dbg_log ( "Read from unmapped memory space, addr=" + h ( a >>> 0 , 8 ) , LOG_IO ) ; return 255 ; } , function ( a , b ) { dbg_log ( "Write to unmapped memory space, addr=" + h ( a >>> 0 , 8 ) + " value=" + h ( b , 2 ) , LOG_IO ) ; } , function ( a ) { dbg_log ( "Read from unmapped memory space, addr=" + h ( a >>> 0 , 8 ) , LOG_IO ) ; return - 1 ; } , function ( a , b ) { dbg_log ( "Write to unmapped memory space, addr=" + h ( a >>> 0 , 8 ) + " value=" + h ( b >>> 0 , 8 ) , LOG_IO ) ; } ) ; } IO . prototype . create_empty_entry = function ( ) { return { read8 : this . empty_port_read8 , read16 : this . empty_port_read16 , read32 : this . empty_port_read32 , write8 : this . empty_port_write , write16 : this . empty_port_write , write32 : this . empty_port_write , device : void 0 } ; } ; IO . prototype . empty_port_read8 = function ( ) { return 255 ; } ; IO . prototype . empty_port_read16 = function ( ) { return 65535 ; } ; IO . prototype . empty_port_read32 = function ( ) { return - 1 ; } ; IO . prototype . empty_port_write = function ( a ) { } ; IO . prototype . register_read = function ( a , b , c , d , e ) { dbg_assert ( "number" === typeof a ) ; dbg_assert ( "object" === typeof b ) ; dbg_assert ( ! c || "function" === typeof c ) ; dbg_assert ( ! d || "function" === typeof d ) ; dbg_assert ( ! e || "function" === typeof e ) ; dbg_assert ( c || d || e ) ; if ( DEBUG ) { var g = function ( c ) { dbg_assert ( ! 1 , "Overlapped read" + c + " " + h ( a , 4 ) + " (" + b . name + ")" ) ; return - 1 >>> 32 - c | 0 ; } ; c || ( c = g . bind ( this , 8 ) ) ; d || ( d = g . bind ( this , 16 ) ) ; e || ( e = g . bind ( this , 32 ) ) ; } c && ( this . ports [ a ] . read8 = c ) ; d && ( this . ports [ a ] . read16 = d ) ; e && ( this . ports [ a ] . read32 = e ) ; this . ports [ a ] . device = b ; } ; IO . prototype . register_write = function ( a , b , c , d , e ) { dbg_assert ( "number" === typeof a ) ; dbg_assert ( "object" === typeof b ) ; dbg_assert ( ! c || "function" === typeof c ) ; dbg_assert ( ! d || "function" === typeof d ) ; dbg_assert ( ! e || "function" === typeof e ) ; dbg_assert ( c || d || e ) ; if ( DEBUG ) { var g = function ( c ) { dbg_assert ( ! 1 , "Overlapped write" + c + " " + h ( a ) + " (" + b . name + ")" ) ; } ; c || ( c = g . bind ( this , 8 ) ) ; d || ( d = g . bind ( this , 16 ) ) ; e || ( e = g . bind ( this , 32 ) ) ; } c && ( this . ports [ a ] . write8 = c ) ; d && ( this . ports [ a ] . write16 = d ) ; e && ( this . ports [ a ] . write32 = e ) ; this . ports [ a ] . device = b ; } ; IO . prototype . register_read_consecutive = function ( a , b , c , d , e , g ) { function f ( ) { return c . call ( this ) | d . call ( this ) << 8 ; } function k ( ) { return e . call ( this ) | g . call ( this ) << 8 ; } function l ( ) { return c . call ( this ) | d . call ( this ) << 8 | e . call ( this ) << 16 | g . call ( this ) << 24 ; } dbg_assert ( 4 === arguments . length || 6 === arguments . length ) ; e && g ? ( this . register_read ( a , b , c , f , l ) , this . register_read ( a + 1 , b , d ) , this . register_read ( a + 2 , b , e , k ) , this . register_read ( a + 3 , b , g ) ) : ( this . register_read ( a , b , c , f ) , this . register_read ( a + 1 , b , d ) ) ; } ; IO . prototype . register_write_consecutive = function ( a , b , c , d , e , g ) { function f ( a ) { c . call ( this , a & 255 ) ; d . call ( this , a >> 8 & 255 ) ; } function k ( a ) { e . call ( this , a & 255 ) ; g . call ( this , a >> 8 & 255 ) ; } function l ( a ) { c . call ( this , a & 255 ) ; d . call ( this , a >> 8 & 255 ) ; e . call ( this , a >> 16 & 255 ) ; g . call ( this , a >>> 24 ) ; } dbg_assert ( 4 === arguments . length || 6 === arguments . length ) ; e && g ? ( this . register_write ( a , b , c , f , l ) , this . register_write ( a + 1 , b , d ) , this . register_write ( a + 2 , b , e , k ) , this . register_write ( a + 3 , b , g ) ) : ( this . register_write ( a , b , c , f ) , this . register_write ( a + 1 , b , d ) ) ; } ; IO . prototype . in_mmap_range = function ( a , b ) { a >>>= 0 ; b = a + ( b >>> 0 ) ; if ( b >= this . cpu . memory_size ) return ! 0 ; for ( a &= ~ ( MMAP_BLOCK_SIZE - 1 ) ; a < b ; ) { if ( this . cpu . in_mapped_range ( a ) ) return ! 0 ; a += MMAP_BLOCK_SIZE ; } return ! 1 ; } ; IO . prototype . mmap_read32_shim = function ( a ) { var b = this . cpu . memory_map_read8 [ a >>> MMAP_BLOCK_BITS ] ; return b ( a ) | b ( a + 1 ) << 8 | b ( a + 2 ) << 16 | b ( a + 3 ) << 24 ; } ; IO . prototype . mmap_write32_shim = function ( a , b ) { var c = this . cpu . memory_map_write8 [ a >>> MMAP_BLOCK_BITS ] ; c ( a , b & 255 ) ; c ( a + 1 , b >> 8 & 255 ) ; c ( a + 2 , b >> 16 & 255 ) ; c ( a + 3 , b >>> 24 ) ; } ; IO . prototype . mmap_register = function ( a , b , c , d , e , g ) { dbg_log ( "mmap_register addr=" + h ( a >>> 0 , 8 ) + " size=" + h ( b , 8 ) , LOG_IO ) ; dbg_assert ( 0 === ( a & MMAP_BLOCK_SIZE - 1 ) ) ; dbg_assert ( b && 0 === ( b & MMAP_BLOCK_SIZE - 1 ) ) ; e || ( e = this . mmap_read32_shim . bind ( this ) ) ; g || ( g = this . mmap_write32_shim . bind ( this ) ) ; for ( a >>>= MMAP_BLOCK_BITS ; 0 < b ; a ++ ) this . cpu . memory_map_read8 [ a ] = c , this . cpu . memory_map_write8 [ a ] = d , this . cpu . memory_map_read32 [ a ] = e , this . cpu . memory_map_write32 [ a ] = g , b -= MMAP_BLOCK_SIZE ; } ; IO . prototype . port_write8 = function ( a , b ) { var c = this . ports [ a ] ; ( c . write8 === this . empty_port_write || LOG_ALL_IO ) && dbg_log ( "write8 port #" + h ( a , 4 ) + " <- " + h ( b , 2 ) + this . get_port_description ( a ) , LOG_IO ) ; return c . write8 . call ( c . device , b ) ; } ; IO . prototype . port_write16 = function ( a , b ) { var c = this . ports [ a ] ; ( c . write16 === this . empty_port_write || LOG_ALL_IO ) && dbg_log ( "write16 port #" + h ( a , 4 ) + " <- " + h ( b , 4 ) + this . get_port_description ( a ) , LOG_IO ) ; return c . write16 . call ( c . device , b ) ; } ; IO . prototype . port_write32 = function ( a , b ) { var c = this . ports [ a ] ; ( c . write32 === this . empty_port_write || LOG_ALL_IO ) && dbg_log ( "write32 port #" + h ( a , 4 ) + " <- " + h ( b >>> 0 , 8 ) + this . get_port_description ( a ) , LOG_IO ) ; return c . write32 . call ( c . device , b ) ; } ; IO . prototype . port_read8 = function ( a ) { var b = this . ports [ a ] ; ( b . read8 === this . empty_port_read8 || LOG_ALL_IO ) && dbg_log ( "read8 port  #" + h ( a , 4 ) + this . get_port_description ( a ) , LOG_IO ) ; b = b . read8 . call ( b . device ) ; dbg_assert ( 256 > b , "8 bit port returned large value: " + h ( a ) ) ; return b ; } ; IO . prototype . port_read16 = function ( a ) { var b = this . ports [ a ] ; ( b . read16 === this . empty_port_read16 || LOG_ALL_IO ) && dbg_log ( "read16 port  #" + h ( a , 4 ) + this . get_port_description ( a ) , LOG_IO ) ; b = b . read16 . call ( b . device ) ; dbg_assert ( 65536 > b && 0 <= b , "16 bit port returned large value: " + h ( a ) ) ; return b ; } ; IO . prototype . port_read32 = function ( a ) { var b = this . ports [ a ] ; ( b . read32 === this . empty_port_read32 || LOG_ALL_IO ) && dbg_log ( "read32 port  #" + h ( a , 4 ) + this . get_port_description ( a ) , LOG_IO ) ; a = b . read32 . call ( b . device ) ; dbg_assert ( ( a | 0 ) === a ) ; return a ; } ; var debug_port_list = { 4 : "PORT_DMA_ADDR_2" , 5 : "PORT_DMA_CNT_2" , 10 : "PORT_DMA1_MASK_REG" , 11 : "PORT_DMA1_MODE_REG" , 12 : "PORT_DMA1_CLEAR_FF_REG" , 13 : "PORT_DMA1_MASTER_CLEAR" , 32 : "PORT_PIC1_CMD" , 33 : "PORT_PIC1_DATA" , 64 : "PORT_PIT_COUNTER0" , 65 : "PORT_PIT_COUNTER1" , 66 : "PORT_PIT_COUNTER2" , 67 : "PORT_PIT_MODE" , 96 : "PORT_PS2_DATA" , 97 : "PORT_PS2_CTRLB" , 100 : "PORT_PS2_STATUS" , 112 : "PORT_CMOS_INDEX" , 113 : "PORT_CMOS_DATA" , 128 : "PORT_DIAG" , 129 : "PORT_DMA_PAGE_2" , 146 : "PORT_A20" , 160 : "PORT_PIC2_CMD" , 161 : "PORT_PIC2_DATA" , 178 : "PORT_SMI_CMD" , 179 : "PORT_SMI_STATUS" , 212 : "PORT_DMA2_MASK_REG" , 214 : "PORT_DMA2_MODE_REG" , 218 : "PORT_DMA2_MASTER_CLEAR" , 240 : "PORT_MATH_CLEAR" , 368 : "PORT_ATA2_CMD_BASE" , 496 : "PORT_ATA1_CMD_BASE" , 632 : "PORT_LPT2" , 744 : "PORT_SERIAL4" , 760 : "PORT_SERIAL2" , 884 : "PORT_ATA2_CTRL_BASE" , 888 : "PORT_LPT1" , 1E3 : "PORT_SERIAL3" , 1008 : "PORT_FD_BASE" , 1010 : "PORT_FD_DOR" , 1012 : "PORT_FD_STATUS" , 1013 : "PORT_FD_DATA" , 1014 : "PORT_HD_DATA" , 1015 : "PORT_FD_DIR" , 1016 : "PORT_SERIAL1" , 3320 : "PORT_PCI_CMD" , 3321 : "PORT_PCI_REBOOT" , 3324 : "PORT_PCI_DATA" , 1026 : "PORT_BIOS_DEBUG" , 1296 : "PORT_QEMU_CFG_CTL" , 1297 : "PORT_QEMU_CFG_DATA" , 45056 : "PORT_ACPI_PM_BASE" , 45312 : "PORT_SMB_BASE" , 35072 : "PORT_BIOS_APM" } ; IO . prototype . get_port_description = function ( a ) { return debug_port_list [ a ] ? "  (" + debug_port_list [ a ] + ")" : "" ; } ; function v86 ( a ) { this . stopped = this . running = ! 1 ; this . cpu = new CPU ( a ) ; this . bus = a ; a . register ( "cpu-init" , this . init , this ) ; a . register ( "cpu-run" , this . run , this ) ; a . register ( "cpu-stop" , this . stop , this ) ; a . register ( "cpu-restart" , this . restart , this ) ; this . register_tick ( ) ; } v86 . prototype . run = function ( ) { this . running || ( this . bus . send ( "emulator-started" ) , this . fast_next_tick ( ) ) ; } ; v86 . prototype . do_tick = function ( ) { if ( this . stopped ) this . stopped = this . running = ! 1 , this . bus . send ( "emulator-stopped" ) ; else { this . running = ! 0 ; var a = this . cpu . main_run ( ) ; 0 >= a ? this . fast_next_tick ( ) : this . next_tick ( a ) ; } } ; v86 . prototype . stop = function ( ) { this . running && ( this . stopped = ! 0 ) ; } ; v86 . prototype . restart = function ( ) { this . cpu . reset ( ) ; this . cpu . load_bios ( ) ; } ; v86 . prototype . init = function ( a ) { this . cpu . init ( a , this . bus ) ; this . bus . send ( "emulator-ready" ) ; } ; if ( "undefined" !== typeof setImmediate ) var fast_next_tick = function ( ) { var a = this ; setImmediate ( function ( ) { a . do_tick ( ) ; } ) ; } , register_tick = function ( ) { } ; else if ( "undefined" !== typeof window && "undefined" !== typeof postMessage ) { var MAGIC_POST_MESSAGE = 43605 ; fast_next_tick = function ( ) { window . postMessage ( MAGIC_POST_MESSAGE , "*" ) ; } ; register_tick = function ( ) { var a = this ; window . addEventListener ( "message" , function ( b ) { b . source === window && b . data === MAGIC_POST_MESSAGE && a . do_tick ( ) ; } , ! 1 ) ; } ; } else fast_next_tick = function ( ) { var a = this ; setTimeout ( function ( ) { a . do_tick ( ) ; } , 0 ) ; } , register_tick = function ( ) { } ; v86 . prototype . fast_next_tick = fast_next_tick ; v86 . prototype . register_tick = register_tick ; var next_tick = "undefined" !== typeof document && "boolean" === typeof document . hidden ? function ( a ) { var b = this ; 4 > a || document . hidden ? this . fast_next_tick ( ) : setTimeout ( function ( ) { b . do_tick ( ) ; } , a ) ; } : function ( a ) { var b = this ; setTimeout ( function ( ) { b . do_tick ( ) ; } , a ) ; } ; v86 . prototype . next_tick = next_tick ; v86 . prototype . save_state = function ( ) { return this . cpu . save_state ( ) ; } ; v86 . prototype . restore_state = function ( a ) { return this . cpu . restore_state ( a ) ; } ; v86 . microtick = "object" === typeof performance && performance . now ? function ( ) { return performance . now ( ) ; } : Date . now ; var v86util = v86util || { } ; v86util . pads = function ( a , b ) { for ( a = a ? a + "" : "" ; a . length < b ; ) a += " " ; return a ; } ; v86util . pad0 = function ( a , b ) { for ( a = a ? a + "" : "" ; a . length < b ; ) a = "0" + a ; return a ; } ; function h ( a , b ) { a = a ? a . toString ( 16 ) : "" ; return "0x" + v86util . pad0 ( a . toUpperCase ( ) , b || 1 ) ; } if ( "undefined" !== typeof window && window . crypto && window . crypto . getRandomValues ) { var rand_data = new Int32Array ( 1 ) ; v86util . has_rand_int = function ( ) { return ! 0 ; } ; v86util . get_rand_int = function ( ) { window . crypto . getRandomValues ( rand_data ) ; return rand_data [ 0 ] ; } ; } else v86util . has_rand_int = function ( ) { return ! 1 ; } , v86util . get_rand_int = function ( ) { console . assert ( ! 1 ) ; } ; function SyncBuffer ( a ) { this . buffer = a ; this . byteLength = a . byteLength ; this . onprogress = this . onload = void 0 ; } SyncBuffer . prototype . load = function ( ) { this . onload && this . onload ( { buffer : this . buffer } ) ; } ; SyncBuffer . prototype . get = function ( a , b , c ) { dbg_assert ( a + b <= this . byteLength ) ; c ( new Uint8Array ( this . buffer , a , b ) ) ; } ; SyncBuffer . prototype . set = function ( a , b , c ) { dbg_assert ( a + b . byteLength <= this . byteLength ) ; ( new Uint8Array ( this . buffer , a , b . byteLength ) ) . set ( b ) ; c ( ) ; } ; SyncBuffer . prototype . get_buffer = function ( a ) { a ( this . buffer ) ; } ; ( function ( ) { for ( var a = new Int8Array ( 256 ) , b = 0 , c = - 2 ; 256 > b ; b ++ ) b & b - 1 || c ++ , a [ b ] = c ; v86util . int_log2_byte = function ( b ) { dbg_assert ( 0 < b ) ; dbg_assert ( 256 > b ) ; return a [ b ] ; } ; v86util . int_log2 = function ( b ) { dbg_assert ( 0 < b ) ; var c = b >>> 16 ; if ( c ) { var d = c >>> 8 ; return d ? 24 + a [ d ] : 16 + a [ c ] ; } return ( d = b >>> 8 ) ? 8 + a [ d ] : a [ b ] ; } ; } ) ( ) ; function ByteQueue ( a ) { var b = new Uint8Array ( a ) , c , d ; dbg_assert ( 0 === ( a & a - 1 ) ) ; this . length = 0 ; this . push = function ( c ) { this . length !== a && this . length ++ ; b [ d ] = c ; d = d + 1 & a - 1 ; } ; this . shift = function ( ) { if ( this . length ) { var e = b [ c ] ; c = c + 1 & a - 1 ; this . length -- ; return e ; } return - 1 ; } ; this . peek = function ( ) { return this . length ? b [ c ] : - 1 ; } ; this . clear = function ( ) { this . length = d = c = 0 ; } ; this . clear ( ) ; } function FloatQueue ( a ) { this . size = a ; this . data = new Float32Array ( a ) ; this . length = this . end = this . start = 0 ; dbg_assert ( 0 === ( a & a - 1 ) ) ; } FloatQueue . prototype . push = function ( a ) { this . length === this . size ? this . start = this . start + 1 & this . size - 1 : this . length ++ ; this . data [ this . end ] = a ; this . end = this . end + 1 & this . size - 1 ; } ; FloatQueue . prototype . shift = function ( ) { if ( this . length ) { var a = this . data [ this . start ] ; this . start = this . start + 1 & this . size - 1 ; this . length -- ; return a ; } } ; FloatQueue . prototype . shift_block = function ( a ) { var b = new Float32Array ( a ) ; a > this . length && ( a = this . length ) ; var c = this . start + a , d = this . data . subarray ( this . start , c ) ; b . set ( d ) ; c >= this . size && ( c -= this . size , b . set ( this . data . subarray ( 0 , c ) , d . length ) ) ; this . start = c ; this . length -= a ; return b ; } ; FloatQueue . prototype . peek = function ( ) { if ( this . length ) return this . data [ this . start ] ; } ; FloatQueue . prototype . clear = function ( ) { this . length = this . end = this . start = 0 ; } ; function CircularQueue ( a ) { this . data = [ ] ; this . index = 0 ; this . size = a ; } CircularQueue . prototype . add = function ( a ) { this . data [ this . index ] = a ; this . index = ( this . index + 1 ) % this . size ; } ; CircularQueue . prototype . toArray = function ( ) { return [ ] . slice . call ( this . data , this . index ) . concat ( [ ] . slice . call ( this . data , 0 , this . index ) ) ; } ; CircularQueue . prototype . clear = function ( ) { this . data = [ ] ; this . index = 0 ; } ; CircularQueue . prototype . set = function ( a ) { this . data = a ; this . index = 0 ; } ; function dump_file ( a , b ) { a instanceof Array || ( a = [ a ] ) ; a = new Blob ( a ) ; download ( a , b ) ; } function download ( a , b ) { var c = document . createElement ( "a" ) ; c . download = b ; c . href = window . URL . createObjectURL ( a ) ; c . dataset . downloadurl = [ "application/octet-stream" , c . download , c . href ] . join ( ":" ) ; document . createEvent ? ( a = document . createEvent ( "MouseEvent" ) , a . initMouseEvent ( "click" , ! 0 , ! 0 , window , 0 , 0 , 0 , 0 , 0 , ! 1 , ! 1 , ! 1 , ! 1 , 0 , null ) , c . dispatchEvent ( a ) ) : c . click ( ) ; window . URL . revokeObjectURL ( c . href ) ; } ; var FPU_LOG_OP = ! 1 , FPU_C0 = 256 , FPU_C1 = 512 , FPU_C2 = 1024 , FPU_C3 = 16384 , FPU_RESULT_FLAGS = FPU_C0 | FPU_C1 | FPU_C2 | FPU_C3 , FPU_STACK_TOP = 14336 , FPU_PC = 768 , FPU_RC = 3072 , FPU_IF = 4096 , FPU_EX_SF = 64 , FPU_EX_P = 32 , FPU_EX_U = 16 , FPU_EX_O = 8 , FPU_EX_Z = 4 , FPU_EX_D = 2 , FPU_EX_I = 1 , TWO_POW_63 = 0x7fffffffffffffff ; function FPU ( a ) { this . cpu = a ; this . st = new Float64Array ( 8 ) ; this . float32 = new Float32Array ( 1 ) ; this . float32_byte = new Uint8Array ( this . float32 . buffer ) ; this . float32_int = new Int32Array ( this . float32 . buffer ) ; this . float64 = new Float64Array ( 1 ) ; this . float64_byte = new Uint8Array ( this . float64 . buffer ) ; this . float64_int = new Int32Array ( this . float64 . buffer ) ; this . st8 = new Uint8Array ( this . st . buffer ) ; this . st32 = new Int32Array ( this . st . buffer ) ; this . stack_empty = 255 ; this . stack_ptr = 0 ; this . control_word = 895 ; this . fpu_dp_selector = this . fpu_dp = this . fpu_opcode = this . fpu_ip_selector = this . fpu_ip = this . status_word = 0 ; this . indefinite_nan = NaN ; this . constants = new Float64Array ( [ 1 , Math . log ( 10 ) / Math . LN2 , Math . LOG2E , Math . PI , Math . log ( 2 ) / Math . LN10 , Math . LN2 , 0 ] ) ; } FPU . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . st ; a [ 1 ] = this . stack_empty ; a [ 2 ] = this . stack_ptr ; a [ 3 ] = this . control_word ; a [ 4 ] = this . fpu_dp_selector ; a [ 5 ] = this . fpu_ip ; a [ 6 ] = this . fpu_ip_selector ; a [ 7 ] = this . fpu_dp ; a [ 8 ] = this . fpu_dp_selector ; a [ 9 ] = this . fpu_opcode ; return a ; } ; FPU . prototype . set_state = function ( a ) { this . st . set ( a [ 0 ] ) ; this . stack_empty = a [ 1 ] ; this . stack_ptr = a [ 2 ] ; this . control_word = a [ 3 ] ; this . fpu_ip = a [ 5 ] ; this . fpu_ip_selector = a [ 6 ] ; this . fpu_dp = a [ 7 ] ; this . fpu_dp_selector = a [ 8 ] ; this . fpu_opcode = a [ 9 ] ; } ; FPU . prototype . fpu_unimpl = function ( ) { dbg_trace ( ) ; if ( DEBUG ) throw "fpu: unimplemented" ; this . cpu . trigger_ud ( ) ; } ; FPU . prototype . stack_fault = function ( ) { this . status_word = this . status_word | FPU_EX_SF | FPU_EX_I ; } ; FPU . prototype . invalid_arithmatic = function ( ) { this . status_word |= FPU_EX_I ; } ; FPU . prototype . fcom = function ( a ) { var b = this . get_st0 ( ) ; this . status_word &= ~ FPU_RESULT_FLAGS ; b > a || ( this . status_word = a > b ? this . status_word | FPU_C0 : b === a ? this . status_word | FPU_C3 : this . status_word | FPU_C0 | FPU_C2 | FPU_C3 ) ; } ; FPU . prototype . fucom = function ( a ) { this . fcom ( a ) ; } ; FPU . prototype . fcomi = function ( a ) { var b = this . st [ this . stack_ptr ] ; this . cpu . flags_changed &= ~ ( 1 | flag_parity | flag_zero ) ; this . cpu . flags &= ~ ( 1 | flag_parity | flag_zero ) ; b > a || ( this . cpu . flags = a > b ? this . cpu . flags | 1 : b === a ? this . cpu . flags | flag_zero : this . cpu . flags | 1 | flag_parity | flag_zero ) ; } ; FPU . prototype . fucomi = function ( a ) { this . fcomi ( a ) ; } ; FPU . prototype . ftst = function ( a ) { this . status_word &= ~ FPU_RESULT_FLAGS ; isNaN ( a ) ? this . status_word = this . status_word | FPU_C3 | FPU_C2 | FPU_C0 : 0 === a ? this . status_word |= FPU_C3 : 0 > a && ( this . status_word |= FPU_C0 ) ; } ; FPU . prototype . fxam = function ( a ) { this . status_word &= ~ FPU_RESULT_FLAGS ; this . status_word |= this . sign ( 0 ) << 9 ; this . stack_empty >> this . stack_ptr & 1 ? this . status_word = this . status_word | FPU_C3 | FPU_C0 : isNaN ( a ) ? this . status_word |= FPU_C0 : this . status_word = 0 === a ? this . status_word | FPU_C3 : Infinity === a || - Infinity === a ? this . status_word | FPU_C2 | FPU_C0 : this . status_word | FPU_C2 ; } ; FPU . prototype . finit = function ( ) { this . control_word = 895 ; this . fpu_opcode = this . fpu_dp = this . fpu_ip = this . status_word = 0 ; this . stack_empty = 255 ; this . stack_ptr = 0 ; } ; FPU . prototype . load_status_word = function ( ) { return this . status_word & - 14337 | this . stack_ptr << 11 ; } ; FPU . prototype . set_status_word = function ( a ) { this . status_word = a & - 14337 ; this . stack_ptr = a >> 11 & 7 ; } ; FPU . prototype . load_tag_word = function ( ) { for ( var a = 0 , b , c = 0 ; 8 > c ; c ++ ) b = this . st [ c ] , this . stack_empty >> c & 1 ? a |= 3 << ( c << 1 ) : 0 === b ? a |= 1 << ( c << 1 ) : isFinite ( b ) || ( a |= 2 << ( c << 1 ) ) ; return a ; } ; FPU . prototype . set_tag_word = function ( a ) { for ( var b = this . stack_empty = 0 ; 8 > b ; b ++ ) this . stack_empty |= a >> b & a >> b + 1 & 1 << b ; } ; FPU . prototype . fstenv = function ( a ) { this . cpu . is_osize_32 ( ) ? ( this . cpu . writable_or_pagefault ( a , 26 ) , this . cpu . safe_write16 ( a , this . control_word ) , this . cpu . safe_write16 ( a + 4 , this . load_status_word ( ) ) , this . cpu . safe_write16 ( a + 8 , this . load_tag_word ( ) ) , this . cpu . safe_write32 ( a + 12 , this . fpu_ip ) , this . cpu . safe_write16 ( a + 16 , this . fpu_ip_selector ) , this . cpu . safe_write16 ( a + 18 , this . fpu_opcode ) , this . cpu . safe_write32 ( a + 20 , this . fpu_dp ) , this . cpu . safe_write16 ( a + 24 , this . fpu_dp_selector ) ) : this . fpu_unimpl ( ) ; } ; FPU . prototype . fldenv = function ( a ) { this . cpu . is_osize_32 ( ) ? ( this . control_word = this . cpu . safe_read16 ( a ) , this . set_status_word ( this . cpu . safe_read16 ( a + 4 ) ) , this . set_tag_word ( this . cpu . safe_read16 ( a + 8 ) ) , this . fpu_ip = this . cpu . safe_read32s ( a + 12 ) , this . fpu_ip_selector = this . cpu . safe_read16 ( a + 16 ) , this . fpu_opcode = this . cpu . safe_read16 ( a + 18 ) , this . fpu_dp = this . cpu . safe_read32s ( a + 20 ) , this . fpu_dp_selector = this . cpu . safe_read16 ( a + 24 ) ) : this . fpu_unimpl ( ) ; } ; FPU . prototype . fsave = function ( a ) { this . cpu . writable_or_pagefault ( a , 108 ) ; this . fstenv ( a ) ; a += 28 ; for ( var b = 0 ; 8 > b ; b ++ ) this . store_m80 ( a , this . st [ this . stack_ptr + b & 7 ] ) , a += 10 ; this . finit ( ) ; } ; FPU . prototype . frstor = function ( a ) { this . fldenv ( a ) ; a += 28 ; for ( var b = 0 ; 8 > b ; b ++ ) this . st [ b + this . stack_ptr & 7 ] = this . load_m80 ( a ) , a += 10 ; } ; FPU . prototype . fxtract = function ( ) { this . float64 [ 0 ] = this . get_st0 ( ) ; var a = ( ( this . float64_byte [ 7 ] & 127 ) << 4 | this . float64_byte [ 6 ] >> 4 ) - 1023 ; this . float64_byte [ 7 ] = 63 | this . float64_byte [ 7 ] & 128 ; this . float64_byte [ 6 ] |= 240 ; this . st [ this . stack_ptr ] = a ; this . push ( this . float64 [ 0 ] ) ; } ; FPU . prototype . integer_round = function ( a ) { var b = this . control_word >> 10 & 3 ; return 0 === b ? ( b = Math . round ( a ) , .5 === b - a && b % 2 && b -- , b ) : 1 === b || 3 === b && 0 < a ? Math . floor ( a ) : Math . ceil ( a ) ; } ; FPU . prototype . truncate = function ( a ) { return 0 < a ? Math . floor ( a ) : Math . ceil ( a ) ; } ; FPU . prototype . push = function ( a ) { this . stack_ptr = this . stack_ptr - 1 & 7 ; this . stack_empty >> this . stack_ptr & 1 ? ( this . status_word &= ~ FPU_C1 , this . stack_empty &= ~ ( 1 << this . stack_ptr ) , this . st [ this . stack_ptr ] = a ) : ( this . status_word |= FPU_C1 , this . stack_fault ( ) , this . st [ this . stack_ptr ] = this . indefinite_nan ) ; } ; FPU . prototype . pop = function ( ) { this . stack_empty |= 1 << this . stack_ptr ; this . stack_ptr = this . stack_ptr + 1 & 7 ; } ; FPU . prototype . get_sti = function ( a ) { dbg_assert ( "number" === typeof a && 0 <= a && 8 > a ) ; a = a + this . stack_ptr & 7 ; return this . stack_empty >> a & 1 ? ( this . status_word &= ~ FPU_C1 , this . stack_fault ( ) , this . indefinite_nan ) : this . st [ a ] ; } ; FPU . prototype . get_st0 = function ( ) { return this . stack_empty >> this . stack_ptr & 1 ? ( this . status_word &= ~ FPU_C1 , this . stack_fault ( ) , this . indefinite_nan ) : this . st [ this . stack_ptr ] ; } ; FPU . prototype . load_m80 = function ( a ) { var b = this . cpu . safe_read16 ( a + 8 ) , c = this . cpu . safe_read32s ( a ) >>> 0 , d = this . cpu . safe_read32s ( a + 4 ) >>> 0 ; a = b >> 15 ; b &= - 32769 ; if ( 0 === b ) return 0 ; if ( ! ( 32767 > b ) ) return this . float64_byte [ 7 ] = 127 | a << 7 , this . float64_byte [ 6 ] = 240 | d >> 30 << 3 & 8 , this . float64_byte [ 5 ] = 0 , this . float64_byte [ 4 ] = 0 , this . float64_int [ 0 ] = 0 , this . float64 [ 0 ] ; c += 4294967296 * d ; a && ( c = - c ) ; return c * Math . pow ( 2 , b - 16383 - 63 ) ; } ; FPU . prototype . store_m80 = function ( a , b ) { this . float64 [ 0 ] = b ; b = this . float64_byte [ 7 ] & 128 ; var c = ( this . float64_byte [ 7 ] & 127 ) << 4 | this . float64_byte [ 6 ] >> 4 ; if ( 2047 === c ) { c = 32767 ; var d = 0 ; var e = 2147483648 | ( this . float64_int [ 1 ] & 524288 ) << 11 ; } else 0 === c ? e = d = 0 : ( c += 15360 , d = this . float64_int [ 0 ] << 11 , e = 2147483648 | ( this . float64_int [ 1 ] & 1048575 ) << 11 | this . float64_int [ 0 ] >>> 21 ) ; dbg_assert ( 0 <= c && 32768 > c ) ; this . cpu . safe_write32 ( a , d ) ; this . cpu . safe_write32 ( a + 4 , e ) ; this . cpu . safe_write16 ( a + 8 , b << 8 | c ) ; } ; FPU . prototype . load_m64 = function ( a ) { var b = this . cpu . safe_read32s ( a ) ; a = this . cpu . safe_read32s ( a + 4 ) ; this . float64_int [ 0 ] = b ; this . float64_int [ 1 ] = a ; return this . float64 [ 0 ] ; } ; FPU . prototype . store_m64 = function ( a , b ) { this . cpu . writable_or_pagefault ( a , 8 ) ; this . float64 [ 0 ] = this . get_sti ( b ) ; this . cpu . safe_write32 ( a , this . float64_int [ 0 ] ) ; this . cpu . safe_write32 ( a + 4 , this . float64_int [ 1 ] ) ; } ; FPU . prototype . load_m32 = function ( a ) { this . float32_int [ 0 ] = this . cpu . safe_read32s ( a ) ; return this . float32 [ 0 ] ; } ; FPU . prototype . store_m32 = function ( a , b ) { this . float32 [ 0 ] = b ; this . cpu . safe_write32 ( a , this . float32_int [ 0 ] ) ; } ; FPU . prototype . sign = function ( a ) { return this . st8 [ ( this . stack_ptr + a & 7 ) << 3 | 7 ] >> 7 ; } ; FPU . prototype . dbg_log_fpu_op = function ( a , b ) { FPU_LOG_OP && ( 192 <= b ? dbg_log ( h ( a , 2 ) + " " + h ( b , 2 ) + "/" + ( b >> 3 & 7 ) + "/" + ( b & 7 ) + " @" + h ( this . cpu . instruction_pointer >>> 0 , 8 ) + " sp=" + this . stack_ptr + " st=" + h ( this . stack_empty , 2 ) , LOG_FPU ) : dbg_log ( h ( a , 2 ) + " /" + ( b >> 3 & 7 ) + "     @" + h ( this . cpu . instruction_pointer >>> 0 , 8 ) + " sp=" + this . stack_ptr + " st=" + h ( this . stack_empty , 2 ) , LOG_FPU ) ) ; } ; FPU . prototype . fwait = function ( ) { } ; FPU . prototype . op_D8_reg = function ( a ) { this . dbg_log_fpu_op ( 216 , a ) ; var b = a >> 3 & 7 ; a = this . get_sti ( a & 7 ) ; var c = this . get_st0 ( ) ; switch ( b ) { case 0 : this . st [ this . stack_ptr ] = c + a ; break ; case 1 : this . st [ this . stack_ptr ] = c * a ; break ; case 2 : this . fcom ( a ) ; break ; case 3 : this . fcom ( a ) ; this . pop ( ) ; break ; case 4 : this . st [ this . stack_ptr ] = c - a ; break ; case 5 : this . st [ this . stack_ptr ] = a - c ; break ; case 6 : this . st [ this . stack_ptr ] = c / a ; break ; case 7 : this . st [ this . stack_ptr ] = a / c ; break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_D8_mem = function ( a , b ) { this . dbg_log_fpu_op ( 216 , a ) ; a = a >> 3 & 7 ; b = this . load_m32 ( b ) ; var c = this . get_st0 ( ) ; switch ( a ) { case 0 : this . st [ this . stack_ptr ] = c + b ; break ; case 1 : this . st [ this . stack_ptr ] = c * b ; break ; case 2 : this . fcom ( b ) ; break ; case 3 : this . fcom ( b ) ; this . pop ( ) ; break ; case 4 : this . st [ this . stack_ptr ] = c - b ; break ; case 5 : this . st [ this . stack_ptr ] = b - c ; break ; case 6 : this . st [ this . stack_ptr ] = c / b ; break ; case 7 : this . st [ this . stack_ptr ] = b / c ; break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_D9_reg = function ( a ) { this . dbg_log_fpu_op ( 217 , a ) ; var b = a & 7 ; switch ( a >> 3 & 7 ) { case 0 : a = this . get_sti ( b ) ; this . push ( a ) ; break ; case 1 : a = this . get_sti ( b ) ; this . st [ this . stack_ptr + b & 7 ] = this . get_st0 ( ) ; this . st [ this . stack_ptr ] = a ; break ; case 2 : switch ( b ) { case 0 : break ; default : dbg_log ( b ) , this . fpu_unimpl ( ) ; } break ; case 3 : this . fpu_unimpl ( ) ; break ; case 4 : a = this . get_st0 ( ) ; switch ( b ) { case 0 : this . st [ this . stack_ptr ] = - a ; break ; case 1 : this . st [ this . stack_ptr ] = Math . abs ( a ) ; break ; case 4 : this . ftst ( a ) ; break ; case 5 : this . fxam ( a ) ; break ; default : dbg_log ( b ) , this . fpu_unimpl ( ) ; } break ; case 5 : this . push ( this . constants [ b ] ) ; break ; case 6 : a = this . get_st0 ( ) ; switch ( b ) { case 0 : this . st [ this . stack_ptr ] = Math . pow ( 2 , a ) - 1 ; break ; case 1 : this . st [ this . stack_ptr + 1 & 7 ] = this . get_sti ( 1 ) * Math . log ( a ) / Math . LN2 ; this . pop ( ) ; break ; case 2 : this . st [ this . stack_ptr ] = Math . tan ( a ) ; this . push ( 1 ) ; break ; case 3 : this . st [ this . stack_ptr + 1 & 7 ] = Math . atan2 ( this . get_sti ( 1 ) , a ) ; this . pop ( ) ; break ; case 4 : this . fxtract ( ) ; break ; case 5 : this . st [ this . stack_ptr ] = a % this . get_sti ( 1 ) ; break ; case 6 : this . stack_ptr = this . stack_ptr - 1 & 7 ; this . status_word &= ~ FPU_C1 ; break ; case 7 : this . stack_ptr = this . stack_ptr + 1 & 7 ; this . status_word &= ~ FPU_C1 ; break ; default : dbg_assert ( ! 1 ) ; } break ; case 7 : a = this . get_st0 ( ) ; switch ( b ) { case 0 : b = this . get_sti ( 1 ) ; var c = Math . trunc ( a / b ) ; this . st [ this . stack_ptr ] = a % b ; this . status_word &= ~ ( FPU_C0 | FPU_C1 | FPU_C3 ) ; c & 1 && ( this . status_word |= FPU_C1 ) ; c & 2 && ( this . status_word |= FPU_C3 ) ; c & 4 && ( this . status_word |= FPU_C0 ) ; this . status_word &= ~ FPU_C2 ; break ; case 1 : this . st [ this . stack_ptr + 1 & 7 ] = this . get_sti ( 1 ) * Math . log ( a + 1 ) / Math . LN2 ; this . pop ( ) ; break ; case 2 : this . st [ this . stack_ptr ] = Math . sqrt ( a ) ; break ; case 3 : this . st [ this . stack_ptr ] = Math . sin ( a ) ; this . push ( Math . cos ( a ) ) ; break ; case 4 : this . st [ this . stack_ptr ] = this . integer_round ( a ) ; break ; case 5 : this . st [ this . stack_ptr ] = a * Math . pow ( 2 , this . truncate ( this . get_sti ( 1 ) ) ) ; break ; case 6 : this . st [ this . stack_ptr ] = Math . sin ( a ) ; break ; case 7 : this . st [ this . stack_ptr ] = Math . cos ( a ) ; break ; default : dbg_assert ( ! 1 ) ; } break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_D9_mem = function ( a , b ) { this . dbg_log_fpu_op ( 217 , a ) ; switch ( a >> 3 & 7 ) { case 0 : a = this . load_m32 ( b ) ; this . push ( a ) ; break ; case 1 : this . fpu_unimpl ( ) ; break ; case 2 : this . store_m32 ( b , this . get_st0 ( ) ) ; break ; case 3 : this . store_m32 ( b , this . get_st0 ( ) ) ; this . pop ( ) ; break ; case 4 : this . fldenv ( b ) ; break ; case 5 : this . control_word = this . cpu . safe_read16 ( b ) ; break ; case 6 : this . fstenv ( b ) ; break ; case 7 : this . cpu . safe_write16 ( b , this . control_word ) ; break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_DA_reg = function ( a ) { this . dbg_log_fpu_op ( 218 , a ) ; var b = a >> 3 & 7 ; a &= 7 ; switch ( b ) { case 0 : this . cpu . test_b ( ) && ( this . st [ this . stack_ptr ] = this . get_sti ( a ) , this . stack_empty &= ~ ( 1 << this . stack_ptr ) ) ; break ; case 1 : this . cpu . test_z ( ) && ( this . st [ this . stack_ptr ] = this . get_sti ( a ) , this . stack_empty &= ~ ( 1 << this . stack_ptr ) ) ; break ; case 2 : this . cpu . test_be ( ) && ( this . st [ this . stack_ptr ] = this . get_sti ( a ) , this . stack_empty &= ~ ( 1 << this . stack_ptr ) ) ; break ; case 3 : this . cpu . test_p ( ) && ( this . st [ this . stack_ptr ] = this . get_sti ( a ) , this . stack_empty &= ~ ( 1 << this . stack_ptr ) ) ; break ; case 5 : 1 === a ? ( this . fucom ( this . get_sti ( 1 ) ) , this . pop ( ) , this . pop ( ) ) : ( dbg_log ( b ) , this . fpu_unimpl ( ) ) ; break ; default : dbg_log ( b ) , this . fpu_unimpl ( ) ; } } ; FPU . prototype . op_DA_mem = function ( a , b ) { this . dbg_log_fpu_op ( 218 , a ) ; a = a >> 3 & 7 ; b = this . cpu . safe_read32s ( b ) ; var c = this . get_st0 ( ) ; switch ( a ) { case 0 : this . st [ this . stack_ptr ] = c + b ; break ; case 1 : this . st [ this . stack_ptr ] = c * b ; break ; case 2 : this . fcom ( b ) ; break ; case 3 : this . fcom ( b ) ; this . pop ( ) ; break ; case 4 : this . st [ this . stack_ptr ] = c - b ; break ; case 5 : this . st [ this . stack_ptr ] = b - c ; break ; case 6 : this . st [ this . stack_ptr ] = c / b ; break ; case 7 : this . st [ this . stack_ptr ] = b / c ; break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_DB_reg = function ( a ) { this . dbg_log_fpu_op ( 219 , a ) ; var b = a >> 3 & 7 , c = a & 7 ; switch ( b ) { case 0 : this . cpu . test_b ( ) || ( this . st [ this . stack_ptr ] = this . get_sti ( c ) , this . stack_empty &= ~ ( 1 << this . stack_ptr ) ) ; break ; case 1 : this . cpu . test_z ( ) || ( this . st [ this . stack_ptr ] = this . get_sti ( c ) , this . stack_empty &= ~ ( 1 << this . stack_ptr ) ) ; break ; case 2 : this . cpu . test_be ( ) || ( this . st [ this . stack_ptr ] = this . get_sti ( c ) , this . stack_empty &= ~ ( 1 << this . stack_ptr ) ) ; break ; case 3 : this . cpu . test_p ( ) || ( this . st [ this . stack_ptr ] = this . get_sti ( c ) , this . stack_empty &= ~ ( 1 << this . stack_ptr ) ) ; break ; case 4 : 227 === a ? this . finit ( ) : 228 !== a && 225 !== a && ( 226 === a ? this . status_word = 0 : ( dbg_log ( h ( a ) ) , this . fpu_unimpl ( ) ) ) ; break ; case 5 : this . fucomi ( this . get_sti ( c ) ) ; break ; case 6 : this . fcomi ( this . get_sti ( c ) ) ; break ; default : dbg_log ( b ) , this . fpu_unimpl ( ) ; } } ; FPU . prototype . op_DB_mem = function ( a , b ) { this . dbg_log_fpu_op ( 219 , a ) ; a = a >> 3 & 7 ; switch ( a ) { case 0 : b = this . cpu . safe_read32s ( b ) ; this . push ( b ) ; break ; case 2 : a = this . integer_round ( this . get_st0 ( ) ) ; 2147483647 >= a && - 2147483648 <= a ? this . cpu . safe_write32 ( b , a ) : ( this . invalid_arithmatic ( ) , this . cpu . safe_write32 ( b , - 2147483648 ) ) ; break ; case 3 : a = this . integer_round ( this . get_st0 ( ) ) ; 2147483647 >= a && - 2147483648 <= a ? this . cpu . safe_write32 ( b , a ) : ( this . invalid_arithmatic ( ) , this . cpu . safe_write32 ( b , - 2147483648 ) ) ; this . pop ( ) ; break ; case 5 : this . push ( this . load_m80 ( b ) ) ; break ; case 7 : this . cpu . writable_or_pagefault ( b , 10 ) ; this . store_m80 ( b , this . get_st0 ( ) ) ; this . pop ( ) ; break ; default : dbg_log ( a ) , this . fpu_unimpl ( ) ; } } ; FPU . prototype . op_DC_reg = function ( a ) { this . dbg_log_fpu_op ( 220 , a ) ; var b = a >> 3 & 7 , c = a & 7 ; a = this . stack_ptr + c & 7 ; c = this . get_sti ( c ) ; var d = this . get_st0 ( ) ; switch ( b ) { case 0 : this . st [ a ] = c + d ; break ; case 1 : this . st [ a ] = c * d ; break ; case 2 : this . fcom ( c ) ; break ; case 3 : this . fcom ( c ) ; this . pop ( ) ; break ; case 4 : this . st [ a ] = d - c ; break ; case 5 : this . st [ a ] = c - d ; break ; case 6 : this . st [ a ] = d / c ; break ; case 7 : this . st [ a ] = c / d ; break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_DC_mem = function ( a , b ) { this . dbg_log_fpu_op ( 220 , a ) ; a = a >> 3 & 7 ; b = this . load_m64 ( b ) ; var c = this . get_st0 ( ) ; switch ( a ) { case 0 : this . st [ this . stack_ptr ] = c + b ; break ; case 1 : this . st [ this . stack_ptr ] = c * b ; break ; case 2 : this . fcom ( b ) ; break ; case 3 : this . fcom ( b ) ; this . pop ( ) ; break ; case 4 : this . st [ this . stack_ptr ] = c - b ; break ; case 5 : this . st [ this . stack_ptr ] = b - c ; break ; case 6 : this . st [ this . stack_ptr ] = c / b ; break ; case 7 : this . st [ this . stack_ptr ] = b / c ; break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_DD_reg = function ( a ) { this . dbg_log_fpu_op ( 221 , a ) ; var b = a >> 3 & 7 ; a &= 7 ; switch ( b ) { case 0 : this . stack_empty |= 1 << ( this . stack_ptr + a & 7 ) ; break ; case 2 : this . st [ this . stack_ptr + a & 7 ] = this . get_st0 ( ) ; break ; case 3 : 0 !== a && ( this . st [ this . stack_ptr + a & 7 ] = this . get_st0 ( ) ) ; this . pop ( ) ; break ; case 4 : this . fucom ( this . get_sti ( a ) ) ; break ; case 5 : this . fucom ( this . get_sti ( a ) ) ; this . pop ( ) ; break ; default : dbg_log ( b ) , this . fpu_unimpl ( ) ; } } ; FPU . prototype . op_DD_mem = function ( a , b ) { this . dbg_log_fpu_op ( 221 , a ) ; switch ( a >> 3 & 7 ) { case 0 : a = this . load_m64 ( b ) ; this . push ( a ) ; break ; case 1 : this . fpu_unimpl ( ) ; break ; case 2 : this . store_m64 ( b , 0 ) ; break ; case 3 : this . store_m64 ( b , 0 ) ; this . pop ( ) ; break ; case 4 : this . frstor ( b ) ; break ; case 5 : this . fpu_unimpl ( ) ; break ; case 6 : this . fsave ( b ) ; break ; case 7 : this . cpu . safe_write16 ( b , this . load_status_word ( ) ) ; break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_DE_reg = function ( a ) { this . dbg_log_fpu_op ( 222 , a ) ; var b = a >> 3 & 7 ; a &= 7 ; var c = this . stack_ptr + a & 7 , d = this . get_sti ( a ) , e = this . get_st0 ( ) ; switch ( b ) { case 0 : this . st [ c ] = d + e ; break ; case 1 : this . st [ c ] = d * e ; break ; case 2 : this . fcom ( d ) ; break ; case 3 : 1 === a ? ( this . fcom ( this . st [ c ] ) , this . pop ( ) ) : ( dbg_log ( b ) , this . fpu_unimpl ( ) ) ; break ; case 4 : this . st [ c ] = e - d ; break ; case 5 : this . st [ c ] = d - e ; break ; case 6 : this . st [ c ] = e / d ; break ; case 7 : this . st [ c ] = d / e ; break ; default : dbg_assert ( ! 1 ) ; } this . pop ( ) ; } ; FPU . prototype . op_DE_mem = function ( a , b ) { this . dbg_log_fpu_op ( 222 , a ) ; a = a >> 3 & 7 ; b = this . cpu . safe_read16 ( b ) << 16 >> 16 ; var c = this . get_st0 ( ) ; switch ( a ) { case 0 : this . st [ this . stack_ptr ] = c + b ; break ; case 1 : this . st [ this . stack_ptr ] = c * b ; break ; case 2 : this . fcom ( b ) ; break ; case 3 : this . fcom ( b ) ; this . pop ( ) ; break ; case 4 : this . st [ this . stack_ptr ] = c - b ; break ; case 5 : this . st [ this . stack_ptr ] = b - c ; break ; case 6 : this . st [ this . stack_ptr ] = c / b ; break ; case 7 : this . st [ this . stack_ptr ] = b / c ; break ; default : dbg_assert ( ! 1 ) ; } } ; FPU . prototype . op_DF_reg = function ( a ) { this . dbg_log_fpu_op ( 223 , a ) ; var b = a >> 3 & 7 , c = a & 7 ; switch ( b ) { case 4 : 224 === a ? this . cpu . reg16 [ reg_ax ] = this . load_status_word ( ) : ( dbg_log ( a ) , this . fpu_unimpl ( ) ) ; break ; case 5 : this . fucomi ( this . get_sti ( c ) ) ; this . pop ( ) ; break ; case 6 : this . fcomi ( this . get_sti ( c ) ) ; this . pop ( ) ; break ; default : dbg_log ( b ) , this . fpu_unimpl ( ) ; } } ; FPU . prototype . op_DF_mem = function ( a , b ) { this . dbg_log_fpu_op ( 223 , a ) ; switch ( a >> 3 & 7 ) { case 0 : b = this . cpu . safe_read16 ( b ) << 16 >> 16 ; this . push ( b ) ; break ; case 1 : this . fpu_unimpl ( ) ; break ; case 2 : a = this . integer_round ( this . get_st0 ( ) ) ; 32767 >= a && - 32768 <= a ? this . cpu . safe_write16 ( b , a ) : ( this . invalid_arithmatic ( ) , this . cpu . safe_write16 ( b , 32768 ) ) ; break ; case 3 : a = this . integer_round ( this . get_st0 ( ) ) ; 32767 >= a && - 32768 <= a ? this . cpu . safe_write16 ( b , a ) : ( this . invalid_arithmatic ( ) , this . cpu . safe_write16 ( b , 32768 ) ) ; this . pop ( ) ; break ; case 4 : this . fpu_unimpl ( ) ; break ; case 5 : a = this . cpu . safe_read32s ( b ) >>> 0 ; b = this . cpu . safe_read32s ( b + 4 ) ; this . push ( a + 4294967296 * b ) ; break ; case 6 : this . fpu_unimpl ( ) ; break ; case 7 : this . cpu . writable_or_pagefault ( b , 8 ) ; a = this . integer_round ( this . get_st0 ( ) ) ; if ( a < TWO_POW_63 && a >= - TWO_POW_63 ) { var c = a | 0 ; var d = a / 4294967296 | 0 ; 0 === d && 0 > a && ( d = - 1 ) ; } else c = 0 , d = - 2147483648 , this . invalid_arithmatic ( ) ; this . cpu . safe_write32 ( b , c ) ; this . cpu . safe_write32 ( b + 4 , d ) ; this . pop ( ) ; break ; default : dbg_assert ( ! 1 ) ; } } ; function hex_dump ( a , b ) { var c = [ ] ; b = b || a . byteLength ; for ( var d , e , g = 0 ; g < b >> 4 ; g ++ ) { d = h ( g << 4 , 5 ) + "   " ; for ( var f = 0 ; 16 > f ; f ++ ) e = a [ ( g << 4 ) + f ] , d += h ( e , 2 ) + " " ; d += "  " ; for ( f = 0 ; 16 > f ; f ++ ) e = a [ ( g << 4 ) + f ] , d += 33 > e || 126 < e ? "." : String . fromCharCode ( e ) ; c . push ( d ) ; } return "\n" + c . join ( "\n" ) ; } var CDROM_SECTOR_SIZE = 2048 , HD_SECTOR_SIZE = 512 ; function IDEDevice ( a , b , c , d , e ) { this . master = new IDEInterface ( this , a , b , c , d , 0 , e ) ; this . slave = new IDEInterface ( this , a , void 0 , ! 1 , d , 1 , e ) ; this . current_interface = this . master ; this . cpu = a ; 0 === d ? ( this . ata_port = 496 , this . irq = 14 , this . pci_id = 240 ) : 1 === d ? ( this . ata_port = 368 , this . irq = 15 , this . pci_id = 248 ) : dbg_assert ( ! 1 , "IDE device with nr " + d + " ignored" , LOG_DISK ) ; this . ata_port_high = this . ata_port | 516 ; this . master_port = 46080 ; this . pci_space = [ 134 , 128 , 16 , 112 , 5 , 0 , 160 , 2 , 0 , 128 , 1 , 1 , 0 , 0 , 0 , 0 , this . ata_port & 255 | 1 , this . ata_port >> 8 , 0 , 0 , this . ata_port_high & 255 | 1 , this . ata_port_high >> 8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , this . master_port & 255 | 1 , this . master_port >> 8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 67 , 16 , 212 , 130 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , this . irq , 1 , 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 , 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 ] ; this . pci_bars = [ { size : 8 } , { size : 4 } , void 0 , void 0 , { size : 16 } ] ; this . name = "ide" + d ; this . device_control = 2 ; a . io . register_read ( this . ata_port | 7 , this , function ( ) { dbg_log ( "lower irq" , LOG_DISK ) ; this . cpu . device_lower_irq ( this . irq ) ; return this . read_status ( ) ; } ) ; a . io . register_read ( this . ata_port_high | 2 , this , this . read_status ) ; a . io . register_write ( this . ata_port_high | 2 , this , this . write_control ) ; a . io . register_read ( this . ata_port | 0 , this , function ( ) { return this . current_interface . read_data ( 1 ) ; } , function ( ) { return this . current_interface . read_data ( 2 ) ; } , function ( ) { return this . current_interface . read_data ( 4 ) ; } ) ; a . io . register_read ( this . ata_port | 1 , this , function ( ) { dbg_log ( "Read error: " + h ( this . current_interface . error & 255 ) + " slave=" + ( this . current_interface === this . slave ) , LOG_DISK ) ; return this . current_interface . error ; } ) ; a . io . register_read ( this . ata_port | 2 , this , function ( ) { dbg_log ( "Read bytecount: " + h ( this . current_interface . bytecount & 255 ) , LOG_DISK ) ; return this . current_interface . bytecount & 255 ; } ) ; a . io . register_read ( this . ata_port | 3 , this , function ( ) { dbg_log ( "Read sector: " + h ( this . current_interface . sector & 255 ) , LOG_DISK ) ; return this . current_interface . sector & 255 ; } ) ; a . io . register_read ( this . ata_port | 4 , this , function ( ) { dbg_log ( "Read 1F4: " + h ( this . current_interface . cylinder_low & 255 ) , LOG_DISK ) ; return this . current_interface . cylinder_low & 255 ; } ) ; a . io . register_read ( this . ata_port | 5 , this , function ( ) { dbg_log ( "Read 1F5: " + h ( this . current_interface . cylinder_high & 255 ) , LOG_DISK ) ; return this . current_interface . cylinder_high & 255 ; } ) ; a . io . register_read ( this . ata_port | 6 , this , function ( ) { dbg_log ( "Read 1F6" , LOG_DISK ) ; return this . current_interface . drive_head ; } ) ; a . io . register_write ( this . ata_port | 0 , this , function ( a ) { this . current_interface . write_data_port8 ( a ) ; } , function ( a ) { this . current_interface . write_data_port16 ( a ) ; } , function ( a ) { this . current_interface . write_data_port32 ( a ) ; } ) ; a . io . register_write ( this . ata_port | 1 , this , function ( a ) { dbg_log ( "1F1/lba_count: " + h ( a ) , LOG_DISK ) ; this . master . lba_count = ( this . master . lba_count << 8 | a ) & 65535 ; this . slave . lba_count = ( this . slave . lba_count << 8 | a ) & 65535 ; } ) ; a . io . register_write ( this . ata_port | 2 , this , function ( a ) { dbg_log ( "1F2/bytecount: " + h ( a ) , LOG_DISK ) ; this . master . bytecount = ( this . master . bytecount << 8 | a ) & 65535 ; this . slave . bytecount = ( this . slave . bytecount << 8 | a ) & 65535 ; } ) ; a . io . register_write ( this . ata_port | 3 , this , function ( a ) { dbg_log ( "1F3/sector: " + h ( a ) , LOG_DISK ) ; this . master . sector = ( this . master . sector << 8 | a ) & 65535 ; this . slave . sector = ( this . slave . sector << 8 | a ) & 65535 ; } ) ; a . io . register_write ( this . ata_port | 4 , this , function ( a ) { dbg_log ( "1F4/sector low: " + h ( a ) , LOG_DISK ) ; this . master . cylinder_low = ( this . master . cylinder_low << 8 | a ) & 65535 ; this . slave . cylinder_low = ( this . slave . cylinder_low << 8 | a ) & 65535 ; } ) ; a . io . register_write ( this . ata_port | 5 , this , function ( a ) { dbg_log ( "1F5/sector high: " + h ( a ) , LOG_DISK ) ; this . master . cylinder_high = ( this . master . cylinder_high << 8 | a ) & 65535 ; this . slave . cylinder_high = ( this . slave . cylinder_high << 8 | a ) & 65535 ; } ) ; a . io . register_write ( this . ata_port | 6 , this , function ( a ) { var b = a & 16 ; dbg_log ( "1F6/drive: " + h ( a , 2 ) , LOG_DISK ) ; b ? ( dbg_log ( "Slave" , LOG_DISK ) , this . current_interface = this . slave ) : this . current_interface = this . master ; this . master . drive_head = a ; this . slave . drive_head = a ; this . master . is_lba = this . slave . is_lba = a >> 6 & 1 ; this . master . head = this . slave . head = a & 15 ; } ) ; this . dma_command = this . dma_status = this . prdt_addr = 0 ; a . io . register_write ( this . ata_port | 7 , this , function ( a ) { dbg_log ( "lower irq" , LOG_DISK ) ; this . cpu . device_lower_irq ( this . irq ) ; this . current_interface . ata_command ( a ) ; } ) ; a . io . register_read ( this . master_port | 4 , this , void 0 , void 0 , this . dma_read_addr ) ; a . io . register_write ( this . master_port | 4 , this , void 0 , void 0 , this . dma_set_addr ) ; a . io . register_read ( this . master_port , this , this . dma_read_command8 , void 0 , this . dma_read_command ) ; a . io . register_write ( this . master_port , this , this . dma_write_command8 , void 0 , this . dma_write_command ) ; a . io . register_read ( this . master_port | 2 , this , this . dma_read_status ) ; a . io . register_write ( this . master_port | 2 , this , this . dma_write_status ) ; a . io . register_read ( this . master_port | 8 , this , function ( ) { dbg_log ( "DMA read 0x8" , LOG_DISK ) ; return 0 ; } ) ; a . io . register_read ( this . master_port | 10 , this , function ( ) { dbg_log ( "DMA read 0xA" , LOG_DISK ) ; return 0 ; } ) ; a . devices . pci . register_device ( this ) ; DEBUG && Object . seal ( this ) ; } IDEDevice . prototype . read_status = function ( ) { if ( this . current_interface . buffer ) { var a = this . current_interface . status ; dbg_log ( "ATA read status: " + h ( a , 2 ) , LOG_DISK ) ; return a ; } return 0 ; } ; IDEDevice . prototype . write_control = function ( a ) { dbg_log ( "set device control: " + h ( a , 2 ) + " interrupts " + ( a & 2 ? "disabled" : "enabled" ) , LOG_DISK ) ; a & 4 && ( dbg_log ( "Reset via control port" , LOG_DISK ) , this . cpu . device_lower_irq ( this . irq ) , this . master . device_reset ( ) , this . slave . device_reset ( ) ) ; this . device_control = a ; } ; IDEDevice . prototype . dma_read_addr = function ( ) { dbg_log ( "dma get address: " + h ( this . prdt_addr , 8 ) , LOG_DISK ) ; return this . prdt_addr ; } ; IDEDevice . prototype . dma_set_addr = function ( a ) { dbg_log ( "dma set address: " + h ( a , 8 ) , LOG_DISK ) ; this . prdt_addr = a ; } ; IDEDevice . prototype . dma_read_status = function ( ) { dbg_log ( "DMA read status: " + h ( this . dma_status ) , LOG_DISK ) ; return this . dma_status ; } ; IDEDevice . prototype . dma_write_status = function ( a ) { dbg_log ( "DMA set status: " + h ( a ) , LOG_DISK ) ; this . dma_status &= ~ ( a & 6 ) ; } ; IDEDevice . prototype . dma_read_command = function ( ) { return this . dma_read_command8 ( ) | this . dma_read_status ( ) << 16 ; } ; IDEDevice . prototype . dma_read_command8 = function ( ) { dbg_log ( "DMA read command: " + h ( this . dma_command ) , LOG_DISK ) ; return this . dma_command ; } ; IDEDevice . prototype . dma_write_command = function ( a ) { dbg_log ( "DMA write command: " + h ( a ) , LOG_DISK ) ; this . dma_write_command8 ( a & 255 ) ; this . dma_write_status ( a >> 16 & 255 ) ; } ; IDEDevice . prototype . dma_write_command8 = function ( a ) { dbg_log ( "DMA write command8: " + h ( a ) , LOG_DISK ) ; var b = this . dma_command ; this . dma_command = a & 9 ; if ( ( b & 1 ) !== ( a & 1 ) ) if ( 0 === ( a & 1 ) ) this . dma_status &= - 2 ; else switch ( this . dma_status |= 1 , this . current_interface . current_command ) { case 37 : case 200 : this . current_interface . do_ata_read_sectors_dma ( ) ; break ; case 202 : case 53 : this . current_interface . do_ata_write_sectors_dma ( ) ; break ; case 160 : this . current_interface . do_atapi_dma ( ) ; break ; default : dbg_log ( "Spurious dma command write, current command: " + h ( this . current_interface . current_command ) , LOG_DISK ) , dbg_assert ( ! 1 ) ; } } ; IDEDevice . prototype . push_irq = function ( ) { 0 === ( this . device_control & 2 ) && ( dbg_log ( "push irq" , LOG_DISK ) , this . dma_status |= 4 , this . cpu . device_raise_irq ( this . irq ) ) ; } ; IDEDevice . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . master ; a [ 1 ] = this . slave ; a [ 2 ] = this . ata_port ; a [ 3 ] = this . irq ; a [ 4 ] = this . pci_id ; a [ 5 ] = this . ata_port_high ; a [ 6 ] = this . master_port ; a [ 7 ] = this . name ; a [ 8 ] = this . device_control ; a [ 9 ] = this . prdt_addr ; a [ 10 ] = this . dma_status ; a [ 11 ] = this . current_interface === this . master ; a [ 12 ] = this . dma_command ; return a ; } ; IDEDevice . prototype . set_state = function ( a ) { this . master = a [ 0 ] ; this . slave = a [ 1 ] ; this . ata_port = a [ 2 ] ; this . irq = a [ 3 ] ; this . pci_id = a [ 4 ] ; this . ata_port_high = a [ 5 ] ; this . master_port = a [ 6 ] ; this . name = a [ 7 ] ; this . device_control = a [ 8 ] ; this . prdt_addr = a [ 9 ] ; this . dma_status = a [ 10 ] ; this . current_interface = a [ 11 ] ? this . master : this . slave ; this . dma_command = a [ 12 ] ; } ; function IDEInterface ( a , b , c , d , e , g , f ) { this . device = a ; this . bus = f ; this . nr = e ; this . cpu = b ; this . buffer = c ; this . sector_size = d ? CDROM_SECTOR_SIZE : HD_SECTOR_SIZE ; this . is_atapi = d ; this . cylinder_count = this . sectors_per_track = this . head_count = this . sector_count = 0 ; this . buffer && ( this . sector_count = this . buffer . byteLength / this . sector_size , this . sector_count !== ( this . sector_count | 0 ) && ( dbg_log ( "Warning: Disk size not aligned with sector size" , LOG_DISK ) , this . sector_count = Math . ceil ( this . sector_count ) ) , d ? ( this . head_count = 1 , this . sectors_per_track = 0 ) : ( this . head_count = 16 , this . sectors_per_track = 63 ) , this . cylinder_count = this . sector_count / this . head_count / this . sectors_per_track , this . cylinder_count !== ( this . cylinder_count | 0 ) && ( dbg_log ( "Warning: Rounding up cylinder count. Choose different head number" , LOG_DISK ) , this . cylinder_count = Math . floor ( this . cylinder_count ) ) , a = b . devices . rtc , a . cmos_write ( CMOS_BIOS_DISKTRANSFLAG , a . cmos_read ( CMOS_BIOS_DISKTRANSFLAG ) | 1 << 4 * this . nr ) , a . cmos_write ( CMOS_DISK_DATA , a . cmos_read ( CMOS_DISK_DATA ) & 15 | 240 ) , b = CMOS_DISK_DRIVE1_CYL , a . cmos_write ( b + 0 , this . cylinder_count & 255 ) , a . cmos_write ( b + 1 , this . cylinder_count >> 8 & 255 ) , a . cmos_write ( b + 2 , this . head_count & 255 ) , a . cmos_write ( b + 3 , 255 ) , a . cmos_write ( b + 4 , 255 ) , a . cmos_write ( b + 5 , 200 ) , a . cmos_write ( b + 6 , this . cylinder_count & 255 ) , a . cmos_write ( b + 7 , this . cylinder_count >> 8 & 255 ) , a . cmos_write ( b + 8 , this . sectors_per_track & 255 ) ) ; this . stats = { sectors_read : 0 , sectors_written : 0 , bytes_read : 0 , bytes_written : 0 , loading : ! 1 } ; this . buffer = c ; this . drive_head = this . head = this . cylinder_high = this . cylinder_low = this . lba_count = this . sector = this . bytecount = this . is_lba = 0 ; this . status = 80 ; this . sectors_per_drq = 128 ; this . data_pointer = this . error = 0 ; this . data = new Uint8Array ( 65536 ) ; this . data16 = new Uint16Array ( this . data . buffer ) ; this . data32 = new Int32Array ( this . data . buffer ) ; this . data_end = this . data_length = 0 ; this . current_atapi_command = this . current_command = - 1 ; this . write_dest = 0 ; Object . seal ( this ) ; } IDEInterface . prototype . device_reset = function ( ) { this . is_atapi ? ( this . status = 0 , this . sector = this . error = this . bytecount = 1 , this . cylinder_low = 20 , this . cylinder_high = 235 ) : ( this . status = 81 , this . sector = this . error = this . bytecount = 1 , this . cylinder_high = this . cylinder_low = 0 ) ; } ; IDEInterface . prototype . push_irq = function ( ) { this . device . push_irq ( ) ; } ; IDEInterface . prototype . ata_command = function ( a ) { dbg_log ( "ATA Command: " + h ( a ) + " slave=" + ( this . drive_head >> 4 & 1 ) , LOG_DISK ) ; if ( this . buffer ) switch ( this . current_command = a , this . error = 0 , a ) { case 8 : dbg_log ( "ATA device reset" , LOG_DISK ) ; this . data_length = this . data_end = this . data_pointer = 0 ; this . device_reset ( ) ; this . push_irq ( ) ; break ; case 16 : this . status = 80 ; this . cylinder_low = 0 ; this . push_irq ( ) ; break ; case 248 : this . status = 80 ; a = this . sector_count - 1 ; this . sector = a & 255 ; this . cylinder_low = a >> 8 & 255 ; this . cylinder_high = a >> 16 & 255 ; this . drive_head = this . drive_head & 240 | a >> 24 & 15 ; this . push_irq ( ) ; break ; case 39 : this . status = 80 ; a = this . sector_count - 1 ; this . sector = a & 255 ; this . cylinder_low = a >> 8 & 255 ; this . cylinder_high = a >> 16 & 255 ; this . sector |= a >> 24 << 8 & 65280 ; this . push_irq ( ) ; break ; case 32 : case 36 : case 41 : case 196 : this . ata_read_sectors ( a ) ; break ; case 48 : case 52 : case 57 : case 197 : this . ata_write_sectors ( a ) ; break ; case 144 : this . push_irq ( ) ; this . error = 257 ; this . status = 80 ; break ; case 145 : this . status = 80 ; this . push_irq ( ) ; break ; case 160 : this . is_atapi && ( this . status = 88 , this . data_allocate ( 12 ) , this . data_end = 12 , this . bytecount = 1 , this . push_irq ( ) ) ; break ; case 161 : dbg_log ( "ATA identify packet device" , LOG_DISK ) ; this . is_atapi ? ( this . create_identify_packet ( ) , this . status = 88 , this . cylinder_low = 20 , this . cylinder_high = 235 ) : this . status = 65 ; this . push_irq ( ) ; break ; case 198 : dbg_log ( "Logical sectors per DRQ Block: " + h ( this . bytecount & 255 ) , LOG_DISK ) ; this . sectors_per_drq = this . bytecount & 255 ; this . status = 80 ; this . push_irq ( ) ; break ; case 37 : case 200 : this . ata_read_sectors_dma ( a ) ; break ; case 53 : case 202 : this . ata_write_sectors_dma ( a ) ; break ; case 64 : dbg_log ( "read verify sectors" , LOG_DISK ) ; this . status = 80 ; this . push_irq ( ) ; break ; case 218 : dbg_log ( "Unimplemented: get media status" , LOG_DISK ) ; this . status = 65 ; this . error = 4 ; this . push_irq ( ) ; break ; case 224 : dbg_log ( "ATA standby immediate" , LOG_DISK ) ; this . status = 80 ; this . push_irq ( ) ; break ; case 225 : dbg_log ( "ATA idle immediate" , LOG_DISK ) ; this . status = 80 ; this . push_irq ( ) ; break ; case 231 : dbg_log ( "ATA flush cache" , LOG_DISK ) ; this . status = 80 ; this . push_irq ( ) ; break ; case 236 : dbg_log ( "ATA identify device" , LOG_DISK ) ; if ( this . is_atapi ) { this . status = 65 ; this . error = 4 ; this . push_irq ( ) ; break ; } this . create_identify_packet ( ) ; this . status = 88 ; this . push_irq ( ) ; break ; case 234 : dbg_log ( "flush cache ext" , LOG_DISK ) ; this . status = 80 ; this . push_irq ( ) ; break ; case 239 : dbg_log ( "set features: " + h ( this . bytecount & 255 ) , LOG_DISK ) ; this . status = 80 ; this . push_irq ( ) ; break ; case 245 : dbg_log ( "security freeze lock" , LOG_DISK ) ; this . status = 80 ; this . push_irq ( ) ; break ; case 249 : dbg_log ( "Unimplemented: set max address" , LOG_DISK ) ; this . status = 65 ; this . error = 4 ; break ; default : dbg_assert ( ! 1 , "New ATA cmd on 1F7: " + h ( a ) , LOG_DISK ) , this . status = 65 , this . error = 4 ; } else dbg_log ( "abort: No buffer" , LOG_DISK ) , this . error = 4 , this . status = 65 , this . push_irq ( ) ; } ; IDEInterface . prototype . atapi_handle = function ( ) { dbg_log ( "ATAPI Command: " + h ( this . data [ 0 ] ) + " slave=" + ( this . drive_head >> 4 & 1 ) , LOG_DISK ) ; this . data_pointer = 0 ; this . current_atapi_command = this . data [ 0 ] ; switch ( this . current_atapi_command ) { case 0 : dbg_log ( "test unit ready" , LOG_DISK ) ; this . data_allocate ( 0 ) ; this . data_end = this . data_length ; this . status = 80 ; break ; case 3 : this . data_allocate ( this . data [ 4 ] ) ; this . data_end = this . data_length ; this . status = 88 ; this . data [ 0 ] = 240 ; this . data [ 2 ] = 5 ; this . data [ 7 ] = 8 ; break ; case 18 : var a = this . data [ 4 ] ; this . status = 88 ; dbg_log ( "inquiry: " + h ( this . data [ 1 ] , 2 ) + " length=" + a , LOG_DISK ) ; this . data . set ( [ 5 , 128 , 1 , 49 , 31 , 0 , 0 , 0 , 83 , 79 , 78 , 89 , 32 , 32 , 32 , 32 , 67 , 68 , 45 , 82 , 79 , 77 , 32 , 67 , 68 , 85 , 45 , 49 , 48 , 48 , 48 , 32 , 49 , 46 , 49 , 97 ] ) ; this . data_end = this . data_length = Math . min ( 36 , a ) ; break ; case 26 : this . data_allocate ( this . data [ 4 ] ) ; this . data_end = this . data_length ; this . status = 88 ; break ; case 30 : this . data_allocate ( 0 ) ; this . data_end = this . data_length ; this . status = 80 ; break ; case 37 : a = this . sector_count - 1 ; this . data_set ( new Uint8Array ( [ a >> 24 & 255 , a >> 16 & 255 , a >> 8 & 255 , a & 255 , 0 , 0 , this . sector_size >> 8 & 255 , this . sector_size & 255 ] ) ) ; this . data_end = this . data_length ; this . status = 88 ; break ; case 40 : this . lba_count & 1 ? this . atapi_read_dma ( this . data ) : this . atapi_read ( this . data ) ; break ; case 66 : a = this . data [ 8 ] ; this . data_allocate ( Math . min ( 8 , a ) ) ; this . data_end = this . data_length ; dbg_log ( "read q subcode: length=" + a , LOG_DISK ) ; this . status = 88 ; break ; case 67 : a = this . data [ 8 ] | this . data [ 7 ] << 8 ; var b = this . data [ 9 ] >> 6 ; this . data_allocate ( a ) ; this . data_end = this . data_length ; dbg_log ( "read toc: " + h ( b , 2 ) + " length=" + a + " " + ( this . data [ 1 ] & 2 ) + " " + h ( this . data [ 6 ] ) , LOG_DISK ) ; 0 === b ? ( a = this . sector_count , this . data . set ( new Uint8Array ( [ 0 , 18 , 1 , 1 , 0 , 20 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 22 , 170 , 0 , a >> 24 , a >> 16 & 255 , a >> 8 & 255 , a & 255 ] ) ) ) : 1 === b ? this . data . set ( new Uint8Array ( [ 0 , 10 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ) ) : dbg_assert ( ! 1 , "Unimplemented format: " + b ) ; this . status = 88 ; break ; case 70 : a = this . data [ 8 ] | this . data [ 7 ] << 8 ; a = Math . min ( a , 32 ) ; this . data_allocate ( a ) ; this . data_end = this . data_length ; this . data [ 0 ] = a - 4 >> 24 & 255 ; this . data [ 1 ] = a - 4 >> 16 & 255 ; this . data [ 2 ] = a - 4 >> 8 & 255 ; this . data [ 3 ] = a - 4 & 255 ; this . data [ 6 ] = 8 ; this . data [ 10 ] = 3 ; this . status = 88 ; break ; case 81 : this . data_allocate ( 0 ) ; this . data_end = this . data_length ; this . status = 80 ; break ; case 82 : dbg_log ( "Unimplemented ATAPI command: " + h ( this . data [ 0 ] ) , LOG_DISK ) ; this . status = 81 ; this . data_length = 0 ; this . error = 80 ; break ; case 90 : a = this . data [ 8 ] | this . data [ 7 ] << 8 ; b = this . data [ 2 ] ; dbg_log ( "mode sense: " + h ( b ) + " length=" + a , LOG_DISK ) ; 42 === b && this . data_allocate ( Math . min ( 30 , a ) ) ; this . data_end = this . data_length ; this . status = 88 ; break ; case 189 : this . data_allocate ( this . data [ 9 ] | this . data [ 8 ] << 8 ) ; this . data_end = this . data_length ; this . data [ 5 ] = 1 ; this . status = 88 ; break ; case 74 : this . status = 81 ; this . data_length = 0 ; this . error = 80 ; dbg_log ( "Unimplemented ATAPI command: " + h ( this . data [ 0 ] ) , LOG_DISK ) ; break ; default : this . status = 81 , this . data_length = 0 , this . error = 80 , dbg_log ( "Unimplemented ATAPI command: " + h ( this . data [ 0 ] ) , LOG_DISK ) , dbg_assert ( ! 1 ) ; } this . bytecount = this . bytecount & - 8 | 2 ; 0 === ( this . status & 128 ) && this . push_irq ( ) ; 0 === ( this . status & 128 ) && 0 === this . data_length && ( this . bytecount |= 1 , this . status &= - 9 ) ; } ; IDEInterface . prototype . do_write = function ( ) { this . status = 80 ; dbg_assert ( this . data_length <= this . data . length ) ; var a = this . data . subarray ( 0 , this . data_length ) ; dbg_assert ( 0 === this . data_length % 512 ) ; this . ata_advance ( this . current_command , this . data_length / 512 ) ; this . push_irq ( ) ; this . buffer . set ( this . write_dest , a , function ( ) { } ) ; this . report_write ( this . data_length ) ; } ; IDEInterface . prototype . atapi_read = function ( a ) { var b = this , c = a [ 2 ] << 24 | a [ 3 ] << 16 | a [ 4 ] << 8 | a [ 5 ] , d = a [ 7 ] << 8 | a [ 8 ] ; a = a [ 1 ] ; var e = d * this . sector_size , g = c * this . sector_size ; dbg_log ( "CD read lba=" + h ( c ) + " lbacount=" + h ( d ) + " bytecount=" + h ( e ) + " flags=" + h ( a ) , LOG_DISK ) ; this . data_length = 0 ; var f = this . cylinder_high << 8 & 65280 | this . cylinder_low & 255 ; dbg_log ( h ( this . cylinder_high , 2 ) + " " + h ( this . cylinder_low , 2 ) , LOG_DISK ) ; this . cylinder_low = this . cylinder_high = 0 ; 65535 === f && f -- ; f > e && ( f = e ) ; g >= this . buffer . byteLength ? ( dbg_assert ( ! 1 , "CD read: Outside of disk  end=" + h ( g + e ) + " size=" + h ( this . buffer . byteLength ) , LOG_DISK ) , this . status = 255 , this . push_irq ( ) ) : 0 === e ? ( this . status = 80 , this . data_pointer = 0 ) : ( e = Math . min ( e , this . buffer . byteLength - g ) , this . status = 208 , this . report_read_start ( ) , this . buffer . get ( g , e , function ( a ) { dbg_log ( "cd read: data arrived" , LOG_DISK ) ; b . data_set ( a ) ; b . status = 88 ; b . bytecount = b . bytecount & - 8 | 2 ; b . push_irq ( ) ; f &= - 4 ; b . data_end = f ; b . data_end > b . data_length && ( b . data_end = b . data_length ) ; b . cylinder_low = b . data_end & 255 ; b . cylinder_high = b . data_end >> 8 & 255 ; b . report_read_end ( e ) ; } ) ) ; } ; IDEInterface . prototype . atapi_read_dma = function ( a ) { var b = this , c = a [ 2 ] << 24 | a [ 3 ] << 16 | a [ 4 ] << 8 | a [ 5 ] , d = a [ 7 ] << 8 | a [ 8 ] ; a = a [ 1 ] ; var e = d * this . sector_size , g = c * this . sector_size ; dbg_log ( "CD read DMA lba=" + h ( c ) + " lbacount=" + h ( d ) + " bytecount=" + h ( e ) + " flags=" + h ( a ) , LOG_DISK ) ; g >= this . buffer . byteLength ? ( dbg_assert ( ! 1 , "CD read: Outside of disk  end=" + h ( g + e ) + " size=" + h ( this . buffer . byteLength ) , LOG_DISK ) , this . status = 255 , this . push_irq ( ) ) : ( this . status = 208 , this . report_read_start ( ) , this . buffer . get ( g , e , function ( a ) { dbg_log ( "atapi_read_dma: Data arrived" ) ; b . report_read_end ( e ) ; b . status = 88 ; b . bytecount = b . bytecount & - 8 | 2 ; b . data_set ( a ) ; b . do_atapi_dma ( ) ; } ) ) ; } ; IDEInterface . prototype . do_atapi_dma = function ( ) { if ( 0 === ( this . device . dma_status & 1 ) ) dbg_log ( "do_atapi_dma: Status not set" , LOG_DISK ) ; else if ( 0 === ( this . status & 8 ) ) dbg_log ( "do_atapi_dma: DRQ not set" , LOG_DISK ) ; else { dbg_log ( "atapi dma transfer len=" + this . data_length , LOG_DISK ) ; var a = this . device . prdt_addr , b = 0 , c = this . data ; do { var d = this . cpu . read32s ( a ) , e = this . cpu . read16 ( a + 4 ) , g = this . cpu . read8 ( a + 7 ) & 128 ; e || ( e = 65536 ) ; dbg_log ( "dma read dest=" + h ( d ) + " count=" + h ( e ) + " datalen=" + h ( this . data_length ) , LOG_DISK ) ; this . cpu . write_blob ( c . subarray ( b , Math . min ( b + e , this . data_length ) ) , d ) ; b += e ; a += 8 ; if ( b >= this . data_length && ! g ) { dbg_log ( "leave early end=" + + g + " offset=" + h ( b ) + " data_length=" + h ( this . data_length ) + " cmd=" + h ( this . current_command ) , LOG_DISK ) ; break ; } } while ( ! g ) ; dbg_log ( "end offset=" + b , LOG_DISK ) ; this . status = 80 ; this . device . dma_status &= - 2 ; this . bytecount = this . bytecount & - 8 | 3 ; this . push_irq ( ) ; } } ; IDEInterface . prototype . read_data = function ( a ) { if ( this . data_pointer < this . data_end ) { dbg_assert ( this . data_pointer + a - 1 < this . data_end ) ; dbg_assert ( 0 === this . data_pointer % a , h ( this . data_pointer ) + " " + a ) ; var b = 1 === a ? this . data [ this . data_pointer ] : 2 === a ? this . data16 [ this . data_pointer >>> 1 ] : this . data32 [ this . data_pointer >>> 2 ] ; this . data_pointer += a ; 0 === ( this . data_pointer & ( 0 === ( this . data_end & 4095 ) ? 4095 : 255 ) ) && dbg_log ( "Read 1F0: " + h ( this . data [ this . data_pointer ] , 2 ) + " cur=" + h ( this . data_pointer ) + " cnt=" + h ( this . data_length ) , LOG_DISK ) ; this . data_pointer >= this . data_end && this . read_end ( ) ; return b ; } dbg_log ( "Read 1F0: empty" , LOG_DISK ) ; this . data_pointer += a ; return 0 ; } ; IDEInterface . prototype . read_end = function ( ) { dbg_log ( "read_end cmd=" + h ( this . current_command ) + " data_pointer=" + h ( this . data_pointer ) + " end=" + h ( this . data_end ) + " length=" + h ( this . data_length ) , LOG_DISK ) ; if ( 160 === this . current_command ) if ( this . data_end === this . data_length ) this . status = 80 , this . bytecount = this . bytecount & - 8 | 3 , this . push_irq ( ) ; else { this . status = 88 ; this . bytecount = this . bytecount & - 8 | 2 ; this . push_irq ( ) ; var a = this . cylinder_high << 8 & 65280 | this . cylinder_low & 255 ; this . data_end + a > this . data_length ? ( this . cylinder_low = this . data_length - this . data_end & 255 , this . cylinder_high = this . data_length - this . data_end >> 8 & 255 , this . data_end = this . data_length ) : this . data_end += a ; dbg_log ( "data_end=" + h ( this . data_end ) , LOG_DISK ) ; } else this . error = 0 , this . data_pointer >= this . data_length ? this . status = 80 : ( 196 === this . current_command || 41 === this . current_command ? ( a = Math . min ( this . sectors_per_drq , ( this . data_length - this . data_end ) / 512 ) , dbg_assert ( 0 === a % 1 ) ) : ( dbg_assert ( 32 === this . current_command || 36 === this . current_command ) , a = 1 ) , this . ata_advance ( this . current_command , a ) , this . data_end += 512 * a , this . status = 88 ) , this . push_irq ( ) ; } ; IDEInterface . prototype . write_data_port = function ( a , b ) { dbg_assert ( 0 === this . data_pointer % b ) ; this . data_pointer >= this . data_end ? dbg_log ( "Redundant write to data port: " + h ( a ) + " count=" + h ( this . data_end ) + " cur=" + h ( this . data_pointer ) , LOG_DISK ) : ( ( 0 === ( this . data_pointer + b & ( 0 === ( this . data_end & 4095 ) ? 4095 : 255 ) ) || 20 > this . data_end ) && dbg_log ( "Data port: " + h ( a >>> 0 ) + " count=" + h ( this . data_end ) + " cur=" + h ( this . data_pointer ) , LOG_DISK ) , 1 === b ? this . data [ this . data_pointer ++ ] = a : 2 === b ? ( this . data16 [ this . data_pointer >>> 1 ] = a , this . data_pointer += 2 ) : ( this . data32 [ this . data_pointer >>> 2 ] = a , this . data_pointer += 4 ) , dbg_assert ( this . data_pointer <= this . data_end ) , this . data_pointer === this . data_end && this . write_end ( ) ) ; } ; IDEInterface . prototype . write_data_port8 = function ( a ) { this . write_data_port ( a , 1 ) ; } ; IDEInterface . prototype . write_data_port16 = function ( a ) { this . write_data_port ( a , 2 ) ; } ; IDEInterface . prototype . write_data_port32 = function ( a ) { this . write_data_port ( a , 4 ) ; } ; IDEInterface . prototype . write_end = function ( ) { 160 === this . current_command ? this . atapi_handle ( ) : ( dbg_log ( "write_end data_pointer=" + h ( this . data_pointer ) + " data_length=" + h ( this . data_length ) , LOG_DISK ) , this . data_pointer >= this . data_length ? this . do_write ( ) : ( dbg_assert ( 48 === this . current_command || 52 === this . current_command ) , this . status = 88 , this . data_end += 512 , this . push_irq ( ) ) ) ; } ; IDEInterface . prototype . ata_advance = function ( a , b ) { dbg_log ( "Advance sectors=" + b + " old_bytecount=" + this . bytecount , LOG_DISK ) ; this . bytecount -= b ; 36 === a || 41 === a || 52 === a || 57 === a || 37 === a || 53 === a ? ( a = b + this . get_lba48 ( ) , this . sector = a & 255 | a >> 16 & 65280 , this . cylinder_low = a >> 8 & 255 , this . cylinder_high = a >> 16 & 255 ) : this . is_lba ? ( a = b + this . get_lba28 ( ) , this . sector = a & 255 , this . cylinder_low = a >> 8 & 255 , this . cylinder_high = a >> 16 & 255 , this . head = this . head & - 16 | a & 15 ) : ( a = b + this . get_chs ( ) , b = a / ( this . head_count * this . sectors_per_track ) | 0 , this . cylinder_low = b & 255 , this . cylinder_high = b >> 8 & 255 , this . head = ( a / this . sectors_per_track | 0 ) % this . head_count & 15 , this . sector = a % this . sectors_per_track + 1 & 255 , dbg_assert ( a === this . get_chs ( ) ) ) ; } ; IDEInterface . prototype . ata_read_sectors = function ( a ) { var b = this , c = 36 === a || 41 === a , d = this . get_count ( c ) ; c = this . get_lba ( c ) ; var e = 32 === a || 36 === a , g = d * this . sector_size , f = c * this . sector_size ; dbg_log ( "ATA read cmd=" + h ( a ) + " mode=" + ( this . is_lba ? "lba" : "chs" ) + " lba=" + h ( c ) + " lbacount=" + h ( d ) + " bytecount=" + h ( g ) , LOG_DISK ) ; f + g > this . buffer . byteLength ? ( dbg_assert ( ! 1 , "ATA read: Outside of disk" , LOG_DISK ) , this . status = 255 , this . push_irq ( ) ) : ( this . status = 192 , this . report_read_start ( ) , this . buffer . get ( f , g , function ( c ) { dbg_log ( "ata_read: Data arrived" , LOG_DISK ) ; b . data_set ( c ) ; b . status = 88 ; b . data_end = e ? 512 : Math . min ( g , 512 * b . sectors_per_drq ) ; b . ata_advance ( a , e ? 1 : Math . min ( d , b . sectors_per_track ) ) ; b . push_irq ( ) ; b . report_read_end ( g ) ; } ) ) ; } ; IDEInterface . prototype . ata_read_sectors_dma = function ( a ) { var b = 37 === a ; a = this . get_count ( b ) ; b = this . get_lba ( b ) ; var c = a * this . sector_size , d = b * this . sector_size ; dbg_log ( "ATA DMA read lba=" + h ( b ) + " lbacount=" + h ( a ) + " bytecount=" + h ( c ) , LOG_DISK ) ; d + c > this . buffer . byteLength ? ( dbg_assert ( ! 1 , "ATA read: Outside of disk" , LOG_DISK ) , this . status = 255 , this . push_irq ( ) ) : ( this . status = 88 , this . device . dma_status |= 1 ) ; } ; IDEInterface . prototype . do_ata_read_sectors_dma = function ( ) { var a = this , b = 37 === this . current_command , c = this . get_count ( b ) ; b = this . get_lba ( b ) ; var d = c * this . sector_size , e = b * this . sector_size ; dbg_assert ( b < this . buffer . byteLength ) ; this . report_read_start ( ) ; var g = this . device . prdt_addr ; this . buffer . get ( e , d , function ( b ) { dbg_log ( "do_ata_read_sectors_dma: Data arrived" , LOG_DISK ) ; var e = a . device . prdt_addr , f = 0 ; dbg_assert ( g === e ) ; do { var m = a . cpu . read32s ( e ) , n = a . cpu . read16 ( e + 4 ) , p = a . cpu . read8 ( e + 7 ) & 128 ; n || ( n = 65536 , dbg_log ( "dma: prd count was 0" , LOG_DISK ) ) ; dbg_log ( "dma read transfer dest=" + h ( m ) + " prd_count=" + h ( n ) , LOG_DISK ) ; a . cpu . write_blob ( b . subarray ( f , f + n ) , m ) ; f += n ; e += 8 ; } while ( ! p ) ; dbg_assert ( f === d ) ; a . ata_advance ( a . current_command , c ) ; a . status = 80 ; a . device . dma_status &= - 2 ; a . current_command = - 1 ; a . push_irq ( ) ; a . report_read_end ( d ) ; } ) ; } ; IDEInterface . prototype . ata_write_sectors = function ( a ) { var b = 52 === a || 57 === a , c = this . get_count ( b ) ; b = this . get_lba ( b ) ; a = 48 === a || 52 === a ; var d = c * this . sector_size , e = b * this . sector_size ; dbg_log ( "ATA write lba=" + h ( b ) + " mode=" + ( this . is_lba ? "lba" : "chs" ) + " lbacount=" + h ( c ) + " bytecount=" + h ( d ) , LOG_DISK ) ; e + d > this . buffer . byteLength ? ( dbg_assert ( ! 1 , "ATA write: Outside of disk" , LOG_DISK ) , this . status = 255 , this . push_irq ( ) ) : ( this . status = 88 , this . data_allocate_noclear ( d ) , this . data_end = a ? 512 : Math . min ( d , 512 * this . sectors_per_drq ) , this . write_dest = e ) ; } ; IDEInterface . prototype . ata_write_sectors_dma = function ( a ) { var b = 53 === a ; a = this . get_count ( b ) ; b = this . get_lba ( b ) ; var c = a * this . sector_size , d = b * this . sector_size ; dbg_log ( "ATA DMA write lba=" + h ( b ) + " lbacount=" + h ( a ) + " bytecount=" + h ( c ) , LOG_DISK ) ; d + c > this . buffer . byteLength ? ( dbg_assert ( ! 1 , "ATA DMA write: Outside of disk" , LOG_DISK ) , this . status = 255 , this . push_irq ( ) ) : ( this . status = 88 , this . device . dma_status |= 1 ) ; } ; IDEInterface . prototype . do_ata_write_sectors_dma = function ( ) { var a = 53 === this . current_command , b = this . get_count ( a ) , c = this . get_lba ( a ) ; a = b * this . sector_size ; c *= this . sector_size ; var d = this . device . prdt_addr , e = 0 , g = 0 , f = 0 ; dbg_log ( "prdt addr: " + h ( d , 8 ) , LOG_DISK ) ; do { var k = this . cpu . read32s ( d ) , l = this . cpu . read16 ( d + 4 ) , m = this . cpu . read8 ( d + 7 ) & 128 ; l || ( l = 65536 , dbg_log ( "dma: prd count was 0" , LOG_DISK ) ) ; dbg_log ( "dma write transfer dest=" + h ( k ) + " prd_count=" + h ( l ) , LOG_DISK ) ; k = this . cpu . mem8 . subarray ( k , k + l ) ; dbg_assert ( k . length === l ) ; this . buffer . set ( c + f , k , function ( ) { g ++ ; } ) ; f += l ; d += 8 ; e ++ ; } while ( ! m ) ; g === e ? ( dbg_log ( "dma write completed" , LOG_DISK ) , this . ata_advance ( this . current_command , b ) , this . status = 80 , this . push_irq ( ) , this . device . dma_status &= - 2 , this . current_command = - 1 ) : dbg_assert ( ! 1 , "dma write not completed" , LOG_DISK ) ; this . report_write ( a ) ; } ; IDEInterface . prototype . get_chs = function ( ) { var a = this . cylinder_low & 255 | this . cylinder_high << 8 & 65280 , b = this . head , c = this . sector & 255 ; dbg_log ( "get_chs: c=" + a + " h=" + b + " s=" + c , LOG_DISK ) ; return ( a * this . head_count + b ) * this . sectors_per_track + c - 1 ; } ; IDEInterface . prototype . get_lba28 = function ( ) { return this . sector & 255 | this . cylinder_low << 8 & 65280 | this . cylinder_high << 16 & 16711680 | ( this . head & 15 ) << 24 ; } ; IDEInterface . prototype . get_lba48 = function ( ) { return ( this . sector & 255 | this . cylinder_low << 8 & 65280 | this . cylinder_high << 16 & 16711680 | this . sector >> 8 << 24 & 4278190080 ) >>> 0 ; } ; IDEInterface . prototype . get_lba = function ( a ) { return a ? this . get_lba48 ( ) : this . is_lba ? this . get_lba28 ( ) : this . get_chs ( ) ; } ; IDEInterface . prototype . get_count = function ( a ) { a ? ( a = this . bytecount , 0 === a && ( a = 65536 ) ) : ( a = this . bytecount & 255 , 0 === a && ( a = 256 ) ) ; return a ; } ; IDEInterface . prototype . create_identify_packet = function ( ) { if ( this . drive_head & 16 ) this . data_allocate ( 0 ) ; else { for ( var a = 0 ; 512 > a ; a ++ ) this . data [ a ] = 0 ; a = Math . min ( 16383 , this . cylinder_count ) ; this . data_set ( [ 64 , this . is_atapi ? 133 : 0 , a , a >> 8 , 0 , 0 , this . head_count , this . head_count >> 8 , this . sectors_per_track / 512 , this . sectors_per_track / 512 >> 8 , 0 , 2 , this . sectors_per_track , this . sectors_per_track >> 8 , 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 , 56 , 118 , 32 , 54 , 68 , 72 , 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 , 128 , 0 , 1 , 0 , 0 , 2 , 0 , 0 , 0 , 2 , 0 , 2 , 7 , 0 , a , a >> 8 , this . head_count , this . head_count >> 8 , this . sectors_per_track , 0 , this . sector_count & 255 , this . sector_count >> 8 & 255 , this . sector_count >> 16 & 255 , this . sector_count >> 24 & 255 , 0 , 0 , this . sector_count & 255 , this . sector_count >> 8 & 255 , this . sector_count >> 16 & 255 , this . sector_count >> 24 & 255 , 0 , 0 , 160 === this . current_command ? 0 : 7 , 160 === this . current_command ? 0 : 4 , 0 , 0 , 30 , 0 , 30 , 0 , 30 , 0 , 30 , 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 , 116 , 0 , 64 , 0 , 64 , 0 , 116 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 96 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , this . sector_count & 255 , this . sector_count >> 8 & 255 , this . sector_count >> 16 & 255 , this . sector_count >> 24 & 255 ] ) ; this . data_end = this . data_length = 512 ; } } ; IDEInterface . prototype . data_allocate = function ( a ) { this . data_allocate_noclear ( a ) ; for ( var b = 0 ; b < a + 3 >> 2 ; b ++ ) this . data32 [ b ] = 0 ; } ; IDEInterface . prototype . data_allocate_noclear = function ( a ) { this . data . length < a && ( this . data = new Uint8Array ( a + 3 & - 4 ) , this . data16 = new Uint16Array ( this . data . buffer ) , this . data32 = new Int32Array ( this . data . buffer ) ) ; this . data_length = a ; this . data_pointer = 0 ; } ; IDEInterface . prototype . data_set = function ( a ) { this . data_allocate_noclear ( a . length ) ; this . data . set ( a ) ; } ; IDEInterface . prototype . report_read_start = function ( ) { this . stats . loading = ! 0 ; this . bus . send ( "ide-read-start" ) ; } ; IDEInterface . prototype . report_read_end = function ( a ) { this . stats . loading = ! 1 ; var b = a / this . sector_size | 0 ; this . stats . sectors_read += b ; this . stats . bytes_read += a ; this . bus . send ( "ide-read-end" , [ this . nr , a , b ] ) ; } ; IDEInterface . prototype . report_write = function ( a ) { var b = a / this . sector_size | 0 ; this . stats . sectors_written += b ; this . stats . bytes_written += a ; this . bus . send ( "ide-write-end" , [ this . nr , a , b ] ) ; } ; IDEInterface . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . bytecount ; a [ 1 ] = this . cylinder_count ; a [ 2 ] = this . cylinder_high ; a [ 3 ] = this . cylinder_low ; a [ 4 ] = this . data_pointer ; a [ 5 ] = 0 ; a [ 6 ] = 0 ; a [ 7 ] = 0 ; a [ 8 ] = 0 ; a [ 9 ] = this . drive_head ; a [ 10 ] = this . error ; a [ 11 ] = this . head ; a [ 12 ] = this . head_count ; a [ 13 ] = this . is_atapi ; a [ 14 ] = this . is_lba ; a [ 15 ] = this . lba_count ; a [ 16 ] = this . data ; a [ 17 ] = this . data_length ; a [ 18 ] = this . sector ; a [ 19 ] = this . sector_count ; a [ 20 ] = this . sector_size ; a [ 21 ] = this . sectors_per_drq ; a [ 22 ] = this . sectors_per_track ; a [ 23 ] = this . status ; a [ 24 ] = this . write_dest ; a [ 25 ] = this . current_command ; a [ 26 ] = this . data_end ; a [ 27 ] = this . current_atapi_command ; return a ; } ; IDEInterface . prototype . set_state = function ( a ) { this . bytecount = a [ 0 ] ; this . cylinder_count = a [ 1 ] ; this . cylinder_high = a [ 2 ] ; this . cylinder_low = a [ 3 ] ; this . data_pointer = a [ 4 ] ; this . drive_head = a [ 9 ] ; this . error = a [ 10 ] ; this . head = a [ 11 ] ; this . head_count = a [ 12 ] ; this . is_atapi = a [ 13 ] ; this . is_lba = a [ 14 ] ; this . lba_count = a [ 15 ] ; this . data = a [ 16 ] ; this . data_length = a [ 17 ] ; this . sector = a [ 18 ] ; this . sector_count = a [ 19 ] ; this . sector_size = a [ 20 ] ; this . sectors_per_drq = a [ 21 ] ; this . sectors_per_track = a [ 22 ] ; this . status = a [ 23 ] ; this . write_dest = a [ 24 ] ; this . current_command = a [ 25 ] ; this . data_end = a [ 26 ] ; this . current_atapi_command = a [ 27 ] ; this . data16 = new Uint16Array ( this . data . buffer ) ; this . data32 = new Int32Array ( this . data . buffer ) ; } ; var PCI_CONFIG_ADDRESS = 3320 , PCI_CONFIG_DATA = 3324 ; function PCI ( a ) { this . pci_addr = new Uint8Array ( 4 ) ; this . pci_value = new Uint8Array ( 4 ) ; this . pci_response = new Uint8Array ( 4 ) ; this . pci_status = new Uint8Array ( 4 ) ; this . pci_addr32 = new Int32Array ( this . pci_addr . buffer ) ; this . pci_value32 = new Int32Array ( this . pci_value . buffer ) ; this . pci_response32 = new Int32Array ( this . pci_response . buffer ) ; this . pci_status32 = new Int32Array ( this . pci_status . buffer ) ; this . device_spaces = [ ] ; this . devices = [ ] ; this . cpu = a ; for ( var b = 0 ; 256 > b ; b ++ ) this . device_spaces [ b ] = void 0 , this . devices [ b ] = void 0 ; this . io = a . io ; a . io . register_write ( PCI_CONFIG_DATA , this , function ( a ) { this . pci_write8 ( this . pci_addr32 [ 0 ] , a ) ; } , function ( a ) { this . pci_write16 ( this . pci_addr32 [ 0 ] , a ) ; } , function ( a ) { this . pci_write32 ( this . pci_addr32 [ 0 ] , a ) ; } ) ; a . io . register_write ( PCI_CONFIG_DATA + 1 , this , function ( a ) { this . pci_write8 ( this . pci_addr32 [ 0 ] + 1 | 0 , a ) ; } ) ; a . io . register_write ( PCI_CONFIG_DATA + 2 , this , function ( a ) { this . pci_write8 ( this . pci_addr32 [ 0 ] + 2 | 0 , a ) ; } , function ( a ) { this . pci_write16 ( this . pci_addr32 [ 0 ] + 2 | 0 , a ) ; } ) ; a . io . register_write ( PCI_CONFIG_DATA + 3 , this , function ( a ) { this . pci_write8 ( this . pci_addr32 [ 0 ] + 3 | 0 , a ) ; } ) ; a . io . register_read_consecutive ( PCI_CONFIG_DATA , this , function ( ) { return this . pci_response [ 0 ] ; } , function ( ) { return this . pci_response [ 1 ] ; } , function ( ) { return this . pci_response [ 2 ] ; } , function ( ) { return this . pci_response [ 3 ] ; } ) ; a . io . register_read_consecutive ( PCI_CONFIG_ADDRESS , this , function ( ) { return this . pci_status [ 0 ] ; } , function ( ) { return this . pci_status [ 1 ] ; } , function ( ) { return this . pci_status [ 2 ] ; } , function ( ) { return this . pci_status [ 3 ] ; } ) ; a . io . register_write_consecutive ( PCI_CONFIG_ADDRESS , this , function ( a ) { this . pci_addr [ 0 ] = a & 252 ; } , function ( a ) { this . pci_addr [ 1 ] = a ; } , function ( a ) { this . pci_addr [ 2 ] = a ; } , function ( a ) { this . pci_addr [ 3 ] = a ; this . pci_query ( ) ; } ) ; this . register_device ( { pci_id : 0 , pci_space : [ 134 , 128 , 55 , 18 , 0 , 0 , 0 , 0 , 2 , 0 , 0 , 6 , 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 , 0 , 0 , 0 ] , pci_bars : [ ] , name : "82441FX PMC" } ) ; this . isa_bridge = { pci_id : 8 , pci_space : [ 134 , 128 , 0 , 112 , 7 , 0 , 0 , 2 , 0 , 0 , 1 , 6 , 0 , 0 , 128 , 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 ] , pci_bars : [ ] , name : "82371SB PIIX3 ISA" } ; this . isa_bridge_space = this . register_device ( this . isa_bridge ) ; this . isa_bridge_space8 = new Uint8Array ( this . isa_bridge_space . buffer ) ; } PCI . prototype . get_state = function ( ) { for ( var a = [ ] , b = 0 ; 256 > b ; b ++ ) a [ b ] = this . device_spaces [ b ] ; a [ 256 ] = this . pci_addr ; a [ 257 ] = this . pci_value ; a [ 258 ] = this . pci_response ; a [ 259 ] = this . pci_status ; return a ; } ; PCI . prototype . set_state = function ( a ) { for ( var b = 0 ; 256 > b ; b ++ ) { var c = this . devices [ b ] , d = a [ b ] ; if ( c && d ) { for ( var e = 0 ; e < c . pci_bars . length ; e ++ ) { var g = d [ 4 + e ] ; if ( g & 1 ) { var f = c . pci_bars [ e ] ; this . set_io_bars ( f , f . original_bar & 65534 , g & 65534 ) ; } } this . device_spaces [ b ] . set ( d ) ; } else c && dbg_log ( "Warning: While restoring PCI device: Device exists in current configuration but not in snapshot (" + c . name + ")" ) , d && dbg_log ( "Warning: While restoring PCI device: Device doesn't exist in current configuration but does in snapshot (device " + h ( b , 2 ) + ")" ) ; } this . pci_addr . set ( a [ 256 ] ) ; this . pci_value . set ( a [ 257 ] ) ; this . pci_response . set ( a [ 258 ] ) ; this . pci_status . set ( a [ 259 ] ) ; } ; PCI . prototype . pci_query = function ( ) { var a = this . pci_addr [ 2 ] << 8 | this . pci_addr [ 1 ] , b = this . pci_addr [ 0 ] & 252 , c = a >> 3 & 31 ; var d = "query enabled=" + ( this . pci_addr [ 3 ] >> 7 ) + ( " bdf=" + h ( a , 4 ) ) ; d += " dev=" + h ( c , 2 ) ; d += " addr=" + h ( b , 2 ) ; c = this . device_spaces [ a ] ; void 0 !== c ? ( this . pci_status32 [ 0 ] = - 2147483648 , this . pci_response32 [ 0 ] = b < c . byteLength ? c [ b >> 2 ] : 0 , d += " " + h ( this . pci_addr32 [ 0 ] >>> 0 , 8 ) + " -> " + h ( this . pci_response32 [ 0 ] >>> 0 , 8 ) , b >= c . byteLength && ( d += " (undef)" ) , d += " (" + this . devices [ a ] . name + ")" , dbg_log ( d , LOG_PCI ) ) : ( this . pci_response32 [ 0 ] = - 1 , this . pci_status32 [ 0 ] = 0 ) ; } ; PCI . prototype . pci_write8 = function ( a , b ) { var c = a >> 8 & 65535 ; a &= 255 ; var d = new Uint8Array ( this . device_spaces [ c ] . buffer ) , e = this . devices [ c ] ; d && ( dbg_assert ( ! ( 16 <= a && 44 > a || 48 <= a && 52 > a ) , "PCI: Expected 32-bit write" ) , dbg_log ( "PCI write8 dev=" + h ( c >> 3 , 2 ) + " (" + e . name + ") addr=" + h ( a , 4 ) + " value=" + h ( b , 2 ) , LOG_PCI ) , d [ a ] = b ) ; } ; PCI . prototype . pci_write16 = function ( a , b ) { dbg_assert ( 0 === ( a & 1 ) ) ; var c = a >> 8 & 65535 ; a &= 255 ; var d = new Uint16Array ( this . device_spaces [ c ] . buffer ) , e = this . devices [ c ] ; d && ( dbg_assert ( ! ( 16 <= a && 44 > a || 48 <= a && 52 > a ) , "PCI: Expected 32-bit write" ) , dbg_log ( "PCI writ16 dev=" + h ( c >> 3 , 2 ) + " (" + e . name + ") addr=" + h ( a , 4 ) + " value=" + h ( b , 4 ) , LOG_PCI ) , d [ a >>> 1 ] = b ) ; } ; PCI . prototype . pci_write32 = function ( a , b ) { dbg_assert ( 0 === ( a & 3 ) ) ; var c = a >> 8 & 65535 ; a &= 255 ; var d = this . device_spaces [ c ] , e = this . devices [ c ] ; if ( d ) if ( 16 <= a && 40 > a ) { var g = a - 16 >> 2 , f = e . pci_bars [ g ] ; dbg_log ( "BAR" + g + " exists=" + ( f ? "y" : "n" ) + " changed to " + h ( b >>> 0 ) + " dev=" + h ( c >> 3 , 2 ) + " (" + e . name + ") " , LOG_PCI ) ; f ? ( dbg_assert ( ! ( f . size & f . size - 1 ) , "bar size should be power of 2" ) , c = a >> 2 , e = d [ c ] & 1 , - 1 === ( b | 3 | f . size - 1 ) ? ( b = ~ ( f . size - 1 ) | e , 0 === e && ( d [ c ] = b ) ) : 0 === e && ( g = f . original_bar , ( b & - 16 ) !== ( g & - 16 ) && dbg_log ( "Warning: Changing memory bar not supported, ignored" , LOG_PCI ) , d [ c ] = g ) , 1 === e && ( dbg_assert ( 1 === e ) , e = d [ c ] & 65534 , g = b & 65534 , dbg_log ( "io bar changed from " + h ( e >>> 0 , 8 ) + " to " + h ( g >>> 0 , 8 ) + " size=" + f . size , LOG_PCI ) , this . set_io_bars ( f , e , g ) , d [ c ] = b | 1 ) ) : d [ a >> 2 ] = 0 ; dbg_log ( "BAR effective value: " + h ( d [ a >> 2 ] >>> 0 ) , LOG_PCI ) ; } else 48 === a ? ( dbg_log ( "PCI write rom address dev=" + h ( c >> 3 , 2 ) + " (" + e . name + ") value=" + h ( b >>> 0 , 8 ) , LOG_PCI ) , d [ a >> 2 ] = e . pci_rom_size ? - 1 === ( b | 2047 ) ? - e . pci_rom_size | 0 : e . pci_rom_address | 0 : 0 ) : ( dbg_log ( "PCI write dev=" + h ( c >> 3 , 2 ) + " (" + e . name + ") addr=" + h ( a , 4 ) + " value=" + h ( b >>> 0 , 8 ) , LOG_PCI ) , d [ a >>> 2 ] = b ) ; } ; PCI . prototype . register_device = function ( a ) { dbg_assert ( void 0 !== a . pci_id ) ; dbg_assert ( void 0 !== a . pci_space ) ; dbg_assert ( void 0 !== a . pci_bars ) ; var b = a . pci_id ; dbg_log ( "PCI register bdf=" + h ( b ) + " (" + a . name + ")" , LOG_PCI ) ; dbg_assert ( ! this . devices [ b ] ) ; dbg_assert ( 64 <= a . pci_space . length ) ; dbg_assert ( b < this . devices . length ) ; var c = new Int32Array ( 64 ) ; c . set ( new Int32Array ( ( new Uint8Array ( a . pci_space ) ) . buffer ) ) ; this . device_spaces [ b ] = c ; this . devices [ b ] = a ; b = c . slice ( 4 , 10 ) ; for ( var d = 0 ; d < a . pci_bars . length ; d ++ ) { var e = a . pci_bars [ d ] ; if ( e ) { var g = b [ d ] , f = g & 1 ; e . original_bar = g ; e . entries = [ ] ; if ( 0 !== f ) for ( dbg_assert ( 1 === f ) , g &= - 2 , f = 0 ; f < e . size ; f ++ ) e . entries [ f ] = this . io . ports [ g + f ] ; } } return c ; } ; PCI . prototype . set_io_bars = function ( a , b , c ) { var d = a . size ; dbg_log ( "Move io bars: from=" + h ( b ) + " to=" + h ( c ) + " count=" + d , LOG_PCI ) ; for ( var e = this . io . ports , g = 0 ; g < d ; g ++ ) { var f = e [ b + g ] ; e [ b + g ] = this . io . create_empty_entry ( ) ; f . read8 === this . io . empty_port_read8 && f . read16 === this . io . empty_port_read16 && f . read32 === this . io . empty_port_read32 && f . write8 === this . io . empty_port_write && f . write16 === this . io . empty_port_write && f . write32 === this . io . empty_port_write && dbg_log ( "Move IO bar: Source not mapped, port=" + h ( b + g , 4 ) , LOG_PCI ) ; f = a . entries [ g ] ; var k = e [ c + g ] ; dbg_assert ( f && k ) ; e [ c + g ] = f ; dbg_assert ( k . read8 === this . io . empty_port_read8 , "Bad IO bar: Target already mapped" ) ; dbg_assert ( k . read16 === this . io . empty_port_read16 , "Bad IO bar: Target already mapped" ) ; dbg_assert ( k . read32 === this . io . empty_port_read32 , "Bad IO bar: Target already mapped" ) ; dbg_assert ( k . write8 === this . io . empty_port_write , "Bad IO bar: Target already mapped" ) ; dbg_assert ( k . write16 === this . io . empty_port_write , "Bad IO bar: Target already mapped" ) ; dbg_assert ( k . write32 === this . io . empty_port_write , "Bad IO bar: Target already mapped" ) ; } } ; PCI . prototype . raise_irq = function ( a ) { var b = this . device_spaces [ a ] ; dbg_assert ( b ) ; this . cpu . device_raise_irq ( this . isa_bridge_space8 [ 96 + ( ( b [ 15 ] >> 8 & 255 ) - 1 + ( ( a >> 3 ) - 1 & 255 ) & 3 ) ] ) ; } ; PCI . prototype . lower_irq = function ( a ) { var b = this . device_spaces [ a ] ; dbg_assert ( b ) ; this . cpu . device_lower_irq ( this . isa_bridge_space8 [ 96 + ( ( b [ 15 ] >> 8 & 255 ) + ( a >> 3 & 255 ) - 2 & 3 ) ] ) ; } ; function FloppyController ( a , b , c ) { this . io = a . io ; this . cpu = a ; this . dma = a . devices . dma ; this . bytes_expecting = 0 ; this . receiving_command = new Uint8Array ( 10 ) ; this . receiving_index = 0 ; this . next_command = null ; this . response_data = new Uint8Array ( 10 ) ; this . floppy_size = this . response_length = this . response_index = 0 ; this . fda_image = b ; this . fdb_image = c ; this . last_head = this . last_cylinder = this . drive = this . status_reg2 = this . status_reg1 = this . status_reg0 = 0 ; this . last_sector = 1 ; this . dor = 0 ; if ( b ) { this . floppy_size = b . byteLength ; if ( ( c = { 160 : { type : 1 , tracks : 40 , sectors : 8 , heads : 1 } , 180 : { type : 1 , tracks : 40 , sectors : 9 , heads : 1 } , 200 : { type : 1 , tracks : 40 , sectors : 10 , heads : 1 } , 320 : { type : 1 , tracks : 40 , sectors : 8 , heads : 2 } , 360 : { type : 1 , tracks : 40 , sectors : 9 , heads : 2 } , 400 : { type : 1 , tracks : 40 , sectors : 10 , heads : 2 } , 720 : { type : 3 , tracks : 80 , sectors : 9 , heads : 2 } , 1200 : { type : 2 , tracks : 80 , sectors : 15 , heads : 2 } , 1440 : { type : 4 , tracks : 80 , sectors : 18 , heads : 2 } , 1722 : { type : 5 , tracks : 82 , sectors : 21 , heads : 2 } , 2880 : { type : 5 , tracks : 80 , sectors : 36 , heads : 2 } } [ this . floppy_size >> 10 ] ) && 0 === ( this . floppy_size & 1023 ) ) a . devices . rtc . cmos_write ( CMOS_FLOPPY_DRIVE_TYPE , c . type << 4 ) , a = c . sectors , b = c . heads , c = c . tracks ; else throw "Unknown floppy size: " + h ( b . byteLength ) ; this . sectors_per_track = a ; this . number_of_heads = b ; this . number_of_cylinders = c ; } else a . devices . rtc . cmos_write ( CMOS_FLOPPY_DRIVE_TYPE , 64 ) , this . floppy_size = this . number_of_cylinders = this . number_of_heads = this . sectors_per_track = 0 ; this . io . register_read ( 1008 , this , this . port3F0_read ) ; this . io . register_read ( 1010 , this , this . port3F2_read ) ; this . io . register_read ( 1012 , this , this . port3F4_read ) ; this . io . register_read ( 1013 , this , this . port3F5_read ) ; this . io . register_read ( 1015 , this , this . port3F7_read ) ; this . io . register_write ( 1010 , this , this . port3F2_write ) ; this . io . register_write ( 1013 , this , this . port3F5_write ) ; } FloppyController . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . bytes_expecting ; a [ 1 ] = this . receiving_command ; a [ 2 ] = this . receiving_index ; a [ 4 ] = this . response_data ; a [ 5 ] = this . response_index ; a [ 6 ] = this . response_length ; a [ 7 ] = this . floppy_size ; a [ 8 ] = this . status_reg0 ; a [ 9 ] = this . status_reg1 ; a [ 10 ] = this . status_reg2 ; a [ 11 ] = this . drive ; a [ 12 ] = this . last_cylinder ; a [ 13 ] = this . last_head ; a [ 14 ] = this . last_sector ; a [ 15 ] = this . dor ; a [ 16 ] = this . sectors_per_track ; a [ 17 ] = this . number_of_heads ; a [ 18 ] = this . number_of_cylinders ; return a ; } ; FloppyController . prototype . set_state = function ( a ) { this . bytes_expecting = a [ 0 ] ; this . receiving_command = a [ 1 ] ; this . receiving_index = a [ 2 ] ; this . next_command = a [ 3 ] ; this . response_data = a [ 4 ] ; this . response_index = a [ 5 ] ; this . response_length = a [ 6 ] ; this . floppy_size = a [ 7 ] ; this . status_reg0 = a [ 8 ] ; this . status_reg1 = a [ 9 ] ; this . status_reg2 = a [ 10 ] ; this . drive = a [ 11 ] ; this . last_cylinder = a [ 12 ] ; this . last_head = a [ 13 ] ; this . last_sector = a [ 14 ] ; this . dor = a [ 15 ] ; this . sectors_per_track = a [ 16 ] ; this . number_of_heads = a [ 17 ] ; this . number_of_cylinders = a [ 18 ] ; } ; FloppyController . prototype . port3F0_read = function ( ) { dbg_log ( "3F0 read" , LOG_FLOPPY ) ; return 0 ; } ; FloppyController . prototype . port3F4_read = function ( ) { dbg_log ( "3F4 read" , LOG_FLOPPY ) ; var a = 128 ; this . response_index < this . response_length && ( a |= 80 ) ; 0 === ( this . dor & 8 ) && ( a |= 32 ) ; return a ; } ; FloppyController . prototype . port3F7_read = function ( ) { dbg_log ( "3F7 read" , LOG_FLOPPY ) ; return 0 ; } ; FloppyController . prototype . port3F5_read = function ( ) { if ( this . response_index < this . response_length ) return dbg_log ( "3F5 read: " + this . response_data [ this . response_index ] , LOG_FLOPPY ) , this . cpu . device_lower_irq ( 6 ) , this . response_data [ this . response_index ++ ] ; dbg_log ( "3F5 read, empty" , LOG_FLOPPY ) ; return 255 ; } ; FloppyController . prototype . port3F5_write = function ( a ) { if ( this . fda_image ) if ( dbg_log ( "3F5 write " + h ( a ) , LOG_FLOPPY ) , 0 < this . bytes_expecting ) { if ( this . receiving_command [ this . receiving_index ++ ] = a , this . bytes_expecting -- , 0 === this . bytes_expecting ) { if ( DEBUG ) { a = "3F5 command received: " ; for ( var b = 0 ; b < this . receiving_index ; b ++ ) a += h ( this . receiving_command [ b ] ) + " " ; dbg_log ( a , LOG_FLOPPY ) ; } this . next_command . call ( this , this . receiving_command ) ; } } else { switch ( a ) { case 3 : this . next_command = this . fix_drive_data ; this . bytes_expecting = 2 ; break ; case 4 : this . next_command = this . check_drive_status ; this . bytes_expecting = 1 ; break ; case 5 : case 197 : this . next_command = function ( a ) { this . do_sector ( ! 0 , a ) ; } ; this . bytes_expecting = 8 ; break ; case 230 : this . next_command = function ( a ) { this . do_sector ( ! 1 , a ) ; } ; this . bytes_expecting = 8 ; break ; case 7 : this . next_command = this . calibrate ; this . bytes_expecting = 1 ; break ; case 8 : this . check_interrupt_status ( ) ; break ; case 74 : this . next_command = this . read_sector_id ; this . bytes_expecting = 1 ; break ; case 15 : this . bytes_expecting = 2 ; this . next_command = this . seek ; break ; case 14 : dbg_log ( "dump registers" , LOG_FLOPPY ) ; this . response_data [ 0 ] = 128 ; this . response_index = 0 ; this . response_length = 1 ; this . bytes_expecting = 0 ; break ; default : dbg_assert ( ! 1 , "Unimplemented floppy command call " + h ( a ) ) ; } this . receiving_index = 0 ; } } ; FloppyController . prototype . port3F2_read = function ( ) { dbg_log ( "read 3F2: DOR" , LOG_FLOPPY ) ; return this . dor ; } ; FloppyController . prototype . port3F2_write = function ( a ) { 4 === ( a & 4 ) && 0 === ( this . dor & 4 ) && this . cpu . device_raise_irq ( 6 ) ; dbg_log ( "start motors: " + h ( a >> 4 ) , LOG_FLOPPY ) ; dbg_log ( "enable dma: " + ! ! ( a & 8 ) , LOG_FLOPPY ) ; dbg_log ( "reset fdc: " + ! ! ( a & 4 ) , LOG_FLOPPY ) ; dbg_log ( "drive select: " + ( a & 3 ) , LOG_FLOPPY ) ; dbg_log ( "DOR = " + h ( a ) , LOG_FLOPPY ) ; this . dor = a ; } ; FloppyController . prototype . check_drive_status = function ( a ) { dbg_log ( "check drive status" , LOG_FLOPPY ) ; this . response_index = 0 ; this . response_length = 1 ; this . response_data [ 0 ] = 32 ; } ; FloppyController . prototype . seek = function ( a ) { dbg_log ( "seek" , LOG_FLOPPY ) ; dbg_assert ( 0 === ( a [ 0 ] & 3 ) , "Unhandled seek drive" ) ; this . last_cylinder = a [ 1 ] ; this . last_head = a [ 0 ] >> 2 & 1 ; this . raise_irq ( ) ; } ; FloppyController . prototype . calibrate = function ( a ) { dbg_log ( "floppy calibrate" , LOG_FLOPPY ) ; this . raise_irq ( ) ; } ; FloppyController . prototype . check_interrupt_status = function ( ) { dbg_log ( "floppy check interrupt status" , LOG_FLOPPY ) ; this . response_index = 0 ; this . response_length = 2 ; this . response_data [ 0 ] = 32 ; this . response_data [ 1 ] = this . last_cylinder ; } ; FloppyController . prototype . do_sector = function ( a , b ) { var c = b [ 2 ] , d = b [ 1 ] , e = b [ 3 ] , g = 128 << b [ 4 ] , f = b [ 5 ] - b [ 3 ] + 1 , k = ( ( c + this . number_of_heads * d ) * this . sectors_per_track + e - 1 ) * g ; dbg_log ( "Floppy " + ( a ? "Write" : "Read" ) , LOG_FLOPPY ) ; dbg_log ( "from " + h ( k ) + " length " + h ( f * g ) , LOG_FLOPPY ) ; dbg_log ( d + " / " + c + " / " + e , LOG_FLOPPY ) ; b [ 4 ] || dbg_log ( "FDC: sector count is zero, use data length instead" , LOG_FLOPPY ) ; this . fda_image && ( a ? this . dma . do_write ( this . fda_image , k , f * g , 2 , this . done . bind ( this , b , d , c , e ) ) : this . dma . do_read ( this . fda_image , k , f * g , 2 , this . done . bind ( this , b , d , c , e ) ) ) ; } ; FloppyController . prototype . done = function ( a , b , c , d , e ) { e || ( d ++ , d > this . sectors_per_track && ( d = 1 , c ++ , c >= this . number_of_heads && ( c = 0 , b ++ ) ) , this . last_cylinder = b , this . last_head = c , this . last_sector = d , this . response_index = 0 , this . response_length = 7 , this . response_data [ 0 ] = c << 2 | 32 , this . response_data [ 1 ] = 0 , this . response_data [ 2 ] = 0 , this . response_data [ 3 ] = b , this . response_data [ 4 ] = c , this . response_data [ 5 ] = d , this . response_data [ 6 ] = a [ 4 ] , this . raise_irq ( ) ) ; } ; FloppyController . prototype . fix_drive_data = function ( a ) { dbg_log ( "floppy fix drive data " + a , LOG_FLOPPY ) ; } ; FloppyController . prototype . read_sector_id = function ( a ) { dbg_log ( "floppy read sector id " + a , LOG_FLOPPY ) ; this . response_index = 0 ; this . response_length = 7 ; this . response_data [ 0 ] = 0 ; this . response_data [ 1 ] = 0 ; this . response_data [ 2 ] = 0 ; this . response_data [ 3 ] = 0 ; this . response_data [ 4 ] = 0 ; this . response_data [ 5 ] = 0 ; this . response_data [ 6 ] = 0 ; this . raise_irq ( ) ; } ; FloppyController . prototype . raise_irq = function ( ) { this . dor & 8 && this . cpu . device_raise_irq ( 6 ) ; } ; var A20_MASK = - 1048577 , A20_MASK16 = - 524289 , A20_MASK32 = - 262145 , USE_A20 = ! 1 ; CPU . prototype . debug_write = function ( a , b , c ) { DEBUG && ( dbg_assert ( "number" === typeof c && ! isNaN ( c ) ) , dbg_assert ( - 2147483648 <= c && 2147483648 > a ) , this . debug_read ( a , b , ! 0 ) ) ; } ; CPU . prototype . debug_read = function ( a , b , c ) { DEBUG && ( dbg_assert ( "number" === typeof a ) , dbg_assert ( ! isNaN ( a ) ) ) ; } ; CPU . prototype . mmap_read8 = function ( a ) { return this . memory_map_read8 [ a >>> MMAP_BLOCK_BITS ] ( a ) ; } ; CPU . prototype . mmap_write8 = function ( a , b ) { this . memory_map_write8 [ a >>> MMAP_BLOCK_BITS ] ( a , b ) ; } ; CPU . prototype . mmap_read16 = function ( a ) { var b = this . memory_map_read8 [ a >>> MMAP_BLOCK_BITS ] ; return b ( a ) | b ( a + 1 | 0 ) << 8 ; } ; CPU . prototype . mmap_write16 = function ( a , b ) { var c = this . memory_map_write8 [ a >>> MMAP_BLOCK_BITS ] ; c ( a , b & 255 ) ; c ( a + 1 | 0 , b >> 8 & 255 ) ; } ; CPU . prototype . mmap_read32 = function ( a ) { return this . memory_map_read32 [ a >>> MMAP_BLOCK_BITS ] ( a ) ; } ; CPU . prototype . mmap_write32 = function ( a , b ) { this . memory_map_write32 [ a >>> MMAP_BLOCK_BITS ] ( a , b ) ; } ; CPU . prototype . in_mapped_range = function ( a ) { return 655360 <= ( a | 0 ) && 786432 > ( a | 0 ) || a >>> 0 >= this . memory_size >>> 0 ; } ; CPU . prototype . read8 = function ( a ) { this . debug_read ( a , 1 ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK ) ; return this . in_mapped_range ( a ) ? this . mmap_read8 ( a ) : this . mem8 [ a ] ; } ; CPU . prototype . read16 = function ( a ) { this . debug_read ( a , 2 ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK ) ; return this . in_mapped_range ( a ) ? this . mmap_read16 ( a ) : this . mem8 [ a ] | this . mem8 [ a + 1 | 0 ] << 8 ; } ; CPU . prototype . read_aligned16 = function ( a ) { dbg_assert ( 0 <= a && 2147483648 > a ) ; this . debug_read ( a << 1 , 2 ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK16 ) ; return this . in_mapped_range ( a << 1 ) ? this . mmap_read16 ( a << 1 ) : this . mem16 [ a ] ; } ; CPU . prototype . read32s = function ( a ) { this . debug_read ( a , 4 ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK ) ; return this . in_mapped_range ( a ) ? this . mmap_read32 ( a ) : this . mem8 [ a ] | this . mem8 [ a + 1 | 0 ] << 8 | this . mem8 [ a + 2 | 0 ] << 16 | this . mem8 [ a + 3 | 0 ] << 24 ; } ; CPU . prototype . read_aligned32 = function ( a ) { dbg_assert ( 0 <= a && 1073741824 > a ) ; this . debug_read ( a << 2 , 4 ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK32 ) ; return this . in_mapped_range ( a << 2 ) ? this . mmap_read32 ( a << 2 ) : this . mem32s [ a ] ; } ; CPU . prototype . write8 = function ( a , b ) { this . debug_write ( a , 1 , b ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK ) ; this . in_mapped_range ( a ) ? this . mmap_write8 ( a , b ) : this . mem8 [ a ] = b ; } ; CPU . prototype . write16 = function ( a , b ) { this . debug_write ( a , 2 , b ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK ) ; this . in_mapped_range ( a ) ? this . mmap_write16 ( a , b ) : ( this . mem8 [ a ] = b , this . mem8 [ a + 1 | 0 ] = b >> 8 ) ; } ; CPU . prototype . write_aligned16 = function ( a , b ) { dbg_assert ( 0 <= a && 2147483648 > a ) ; this . debug_write ( a << 1 , 2 , b ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK16 ) ; this . in_mapped_range ( a << 1 ) ? this . mmap_write16 ( a << 1 , b ) : this . mem16 [ a ] = b ; } ; CPU . prototype . write32 = function ( a , b ) { this . debug_write ( a , 4 , b ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK ) ; this . in_mapped_range ( a ) ? this . mmap_write32 ( a , b ) : ( this . mem8 [ a ] = b , this . mem8 [ a + 1 | 0 ] = b >> 8 , this . mem8 [ a + 2 | 0 ] = b >> 16 , this . mem8 [ a + 3 | 0 ] = b >> 24 ) ; } ; CPU . prototype . write_aligned32 = function ( a , b ) { dbg_assert ( 0 <= a && 1073741824 > a ) ; this . debug_write ( a << 2 , 4 , b ) ; USE_A20 && ! this . a20_enabled && ( a &= A20_MASK32 ) ; this . in_mapped_range ( a << 2 ) ? this . mmap_write32 ( a << 2 , b ) : this . mem32s [ a ] = b ; } ; CPU . prototype . write_blob = function ( a , b ) { this . debug_write ( b , a . length , 0 ) ; dbg_assert ( a && 0 <= a . length ) ; this . mem8 . set ( a , b ) ; } ; CPU . prototype . write_blob32 = function ( a , b ) { dbg_assert ( a && a . length ) ; this . debug_write ( b , a . length << 2 , 0 ) ; this . mem32s . set ( a , b ) ; } ; function DMA ( a ) { this . cpu = a ; this . channel_page = new Uint8Array ( 8 ) ; this . channel_pagehi = new Uint8Array ( 8 ) ; this . channel_addr = new Uint16Array ( 8 ) ; this . channel_addr_init = new Uint16Array ( 8 ) ; this . channel_count = new Uint16Array ( 8 ) ; this . channel_count_init = new Uint16Array ( 8 ) ; this . channel_mask = new Uint8Array ( 8 ) ; this . channel_mode = new Uint8Array ( 8 ) ; this . unmask_listeners = [ ] ; this . lsb_msb_flipflop = 0 ; a = a . io ; a . register_write ( 0 , this , this . port_addr_write . bind ( this , 0 ) ) ; a . register_write ( 2 , this , this . port_addr_write . bind ( this , 1 ) ) ; a . register_write ( 4 , this , this . port_addr_write . bind ( this , 2 ) ) ; a . register_write ( 6 , this , this . port_addr_write . bind ( this , 3 ) ) ; a . register_write ( 1 , this , this . port_count_write . bind ( this , 0 ) ) ; a . register_write ( 3 , this , this . port_count_write . bind ( this , 1 ) ) ; a . register_write ( 5 , this , this . port_count_write . bind ( this , 2 ) ) ; a . register_write ( 7 , this , this . port_count_write . bind ( this , 3 ) ) ; a . register_read ( 0 , this , this . port_addr_read . bind ( this , 0 ) ) ; a . register_read ( 2 , this , this . port_addr_read . bind ( this , 1 ) ) ; a . register_read ( 4 , this , this . port_addr_read . bind ( this , 2 ) ) ; a . register_read ( 6 , this , this . port_addr_read . bind ( this , 3 ) ) ; a . register_read ( 1 , this , this . port_count_read . bind ( this , 0 ) ) ; a . register_read ( 3 , this , this . port_count_read . bind ( this , 1 ) ) ; a . register_read ( 5 , this , this . port_count_read . bind ( this , 2 ) ) ; a . register_read ( 7 , this , this . port_count_read . bind ( this , 3 ) ) ; a . register_write ( 192 , this , this . port_addr_write . bind ( this , 4 ) ) ; a . register_write ( 196 , this , this . port_addr_write . bind ( this , 5 ) ) ; a . register_write ( 200 , this , this . port_addr_write . bind ( this , 6 ) ) ; a . register_write ( 204 , this , this . port_addr_write . bind ( this , 7 ) ) ; a . register_write ( 194 , this , this . port_count_write . bind ( this , 4 ) ) ; a . register_write ( 198 , this , this . port_count_write . bind ( this , 5 ) ) ; a . register_write ( 202 , this , this . port_count_write . bind ( this , 6 ) ) ; a . register_write ( 206 , this , this . port_count_write . bind ( this , 7 ) ) ; a . register_read ( 192 , this , this . port_addr_read . bind ( this , 4 ) ) ; a . register_read ( 196 , this , this . port_addr_read . bind ( this , 5 ) ) ; a . register_read ( 200 , this , this . port_addr_read . bind ( this , 6 ) ) ; a . register_read ( 204 , this , this . port_addr_read . bind ( this , 7 ) ) ; a . register_read ( 194 , this , this . port_count_read . bind ( this , 4 ) ) ; a . register_read ( 198 , this , this . port_count_read . bind ( this , 5 ) ) ; a . register_read ( 202 , this , this . port_count_read . bind ( this , 6 ) ) ; a . register_read ( 206 , this , this . port_count_read . bind ( this , 7 ) ) ; a . register_write ( 135 , this , this . port_page_write . bind ( this , 0 ) ) ; a . register_write ( 131 , this , this . port_page_write . bind ( this , 1 ) ) ; a . register_write ( 129 , this , this . port_page_write . bind ( this , 2 ) ) ; a . register_write ( 130 , this , this . port_page_write . bind ( this , 3 ) ) ; a . register_write ( 143 , this , this . port_page_write . bind ( this , 4 ) ) ; a . register_write ( 139 , this , this . port_page_write . bind ( this , 5 ) ) ; a . register_write ( 137 , this , this . port_page_write . bind ( this , 6 ) ) ; a . register_write ( 138 , this , this . port_page_write . bind ( this , 7 ) ) ; a . register_read ( 135 , this , this . port_page_read . bind ( this , 0 ) ) ; a . register_read ( 131 , this , this . port_page_read . bind ( this , 1 ) ) ; a . register_read ( 129 , this , this . port_page_read . bind ( this , 2 ) ) ; a . register_read ( 130 , this , this . port_page_read . bind ( this , 3 ) ) ; a . register_read ( 143 , this , this . port_page_read . bind ( this , 4 ) ) ; a . register_read ( 139 , this , this . port_page_read . bind ( this , 5 ) ) ; a . register_read ( 137 , this , this . port_page_read . bind ( this , 6 ) ) ; a . register_read ( 138 , this , this . port_page_read . bind ( this , 7 ) ) ; a . register_write ( 1159 , this , this . port_pagehi_write . bind ( this , 0 ) ) ; a . register_write ( 1155 , this , this . port_pagehi_write . bind ( this , 1 ) ) ; a . register_write ( 1153 , this , this . port_pagehi_write . bind ( this , 2 ) ) ; a . register_write ( 1154 , this , this . port_pagehi_write . bind ( this , 3 ) ) ; a . register_write ( 1163 , this , this . port_pagehi_write . bind ( this , 5 ) ) ; a . register_write ( 1161 , this , this . port_pagehi_write . bind ( this , 6 ) ) ; a . register_write ( 1162 , this , this . port_pagehi_write . bind ( this , 7 ) ) ; a . register_read ( 1159 , this , this . port_pagehi_read . bind ( this , 0 ) ) ; a . register_read ( 1155 , this , this . port_pagehi_read . bind ( this , 1 ) ) ; a . register_read ( 1153 , this , this . port_pagehi_read . bind ( this , 2 ) ) ; a . register_read ( 1154 , this , this . port_pagehi_read . bind ( this , 3 ) ) ; a . register_read ( 1163 , this , this . port_pagehi_read . bind ( this , 5 ) ) ; a . register_read ( 1161 , this , this . port_pagehi_read . bind ( this , 6 ) ) ; a . register_read ( 1162 , this , this . port_pagehi_read . bind ( this , 7 ) ) ; a . register_write ( 10 , this , this . port_singlemask_write . bind ( this , 0 ) ) ; a . register_write ( 212 , this , this . port_singlemask_write . bind ( this , 4 ) ) ; a . register_write ( 15 , this , this . port_multimask_write . bind ( this , 0 ) ) ; a . register_write ( 222 , this , this . port_multimask_write . bind ( this , 4 ) ) ; a . register_read ( 15 , this , this . port_multimask_read . bind ( this , 0 ) ) ; a . register_read ( 222 , this , this . port_multimask_read . bind ( this , 4 ) ) ; a . register_write ( 11 , this , this . port_mode_write . bind ( this , 0 ) ) ; a . register_write ( 214 , this , this . port_mode_write . bind ( this , 4 ) ) ; a . register_write ( 12 , this , this . portC_write ) ; a . register_write ( 216 , this , this . portC_write ) ; } DMA . prototype . get_state = function ( ) { return [ this . channel_page , this . channel_pagehi , this . channel_addr , this . channel_addr_init , this . channel_count , this . channel_count_init , this . channel_mask , this . channel_mode , this . lsb_msb_flipflop ] ; } ; DMA . prototype . set_state = function ( a ) { this . channel_page = a [ 0 ] ; this . channel_pagehi = a [ 1 ] ; this . channel_addr = a [ 2 ] ; this . channel_addr_init = a [ 3 ] ; this . channel_count = a [ 4 ] ; this . channel_count_init = a [ 5 ] ; this . channel_mask = a [ 6 ] ; this . channel_mode = a [ 7 ] ; this . lsb_msb_flipflop = a [ 8 ] ; } ; DMA . prototype . port_count_write = function ( a , b ) { dbg_log ( "count write [" + a + "] = " + h ( b ) , LOG_DMA ) ; this . channel_count [ a ] = this . flipflop_get ( this . channel_count [ a ] , b , ! 1 ) ; this . channel_count_init [ a ] = this . flipflop_get ( this . channel_count_init [ a ] , b , ! 0 ) ; } ; DMA . prototype . port_count_read = function ( a ) { dbg_log ( "count read [" + a + "] -> " + h ( this . channel_count [ a ] ) , LOG_DMA ) ; return this . flipflop_read ( this . channel_count [ a ] ) ; } ; DMA . prototype . port_addr_write = function ( a , b ) { dbg_log ( "addr write [" + a + "] = " + h ( b ) , LOG_DMA ) ; this . channel_addr [ a ] = this . flipflop_get ( this . channel_addr [ a ] , b , ! 1 ) ; this . channel_addr_init [ a ] = this . flipflop_get ( this . channel_addr_init [ a ] , b , ! 0 ) ; } ; DMA . prototype . port_addr_read = function ( a ) { dbg_log ( "addr read [" + a + "] -> " + h ( this . channel_addr [ a ] ) , LOG_DMA ) ; return this . flipflop_read ( this . channel_addr [ a ] ) ; } ; DMA . prototype . port_pagehi_write = function ( a , b ) { dbg_log ( "pagehi write [" + a + "] = " + h ( b ) , LOG_DMA ) ; this . channel_pagehi [ a ] = b ; } ; DMA . prototype . port_pagehi_read = function ( a ) { dbg_log ( "pagehi read [" + a + "]" , LOG_DMA ) ; return this . channel_pagehi [ a ] ; } ; DMA . prototype . port_page_write = function ( a , b ) { dbg_log ( "page write [" + a + "] = " + h ( b ) , LOG_DMA ) ; this . channel_page [ a ] = b ; } ; DMA . prototype . port_page_read = function ( a ) { dbg_log ( "page read [" + a + "]" , LOG_DMA ) ; return this . channel_page [ a ] ; } ; DMA . prototype . port_singlemask_write = function ( a , b ) { a = ( b & 3 ) + a ; b = b & 4 ? 1 : 0 ; dbg_log ( "singlechannel mask write [" + a + "] = " + b , LOG_DMA ) ; this . update_mask ( a , b ) ; } ; DMA . prototype . port_multimask_write = function ( a , b ) { dbg_log ( "multichannel mask write: " + h ( b ) , LOG_DMA ) ; for ( var c = 0 ; 4 > c ; c ++ ) this . update_mask ( a + c , b & 1 << c ) ; } ; DMA . prototype . port_multimask_read = function ( a ) { var b = 0 | this . channel_mask [ a + 0 ] ; b |= this . channel_mask [ a + 1 ] << 1 ; b |= this . channel_mask [ a + 2 ] << 2 ; b |= this . channel_mask [ a + 3 ] << 3 ; dbg_log ( "multichannel mask read: " + h ( b ) , LOG_DMA ) ; return b ; } ; DMA . prototype . port_mode_write = function ( a , b ) { a = ( b & 3 ) + a ; dbg_log ( "mode write [" + a + "] = " + h ( b ) , LOG_DMA ) ; this . channel_mode [ a ] = b ; } ; DMA . prototype . portC_write = function ( a ) { dbg_log ( "flipflop reset" , LOG_DMA ) ; this . lsb_msb_flipflop = 0 ; } ; DMA . prototype . on_unmask = function ( a , b ) { this . unmask_listeners . push ( { fn : a , this_value : b } ) ; } ; DMA . prototype . update_mask = function ( a , b ) { if ( this . channel_mask [ a ] !== b && ( this . channel_mask [ a ] = b , ! b ) ) for ( dbg_log ( "firing on_unmask(" + a + ")" , LOG_DMA ) , b = 0 ; b < this . unmask_listeners . length ; b ++ ) this . unmask_listeners [ b ] . fn . call ( this . unmask_listeners [ b ] . this_value , a ) ; } ; DMA . prototype . do_read = function ( a , b , c , d , e ) { var g = this . count_get_8bit ( d ) , f = this . address_get_8bit ( d ) ; dbg_log ( "DMA write channel " + d , LOG_DMA ) ; dbg_log ( "to " + h ( f ) + " len " + h ( g ) , LOG_DMA ) ; c < g && dbg_log ( "DMA should read more than provided: " + h ( c ) + " " + h ( g ) , LOG_DMA ) ; if ( b + g > a . byteLength ) dbg_log ( "DMA read outside of buffer" , LOG_DMA ) , e ( ! 0 ) ; else { var k = this . cpu ; this . channel_addr [ d ] += g ; a . get ( b , g , function ( a ) { k . write_blob ( a , f ) ; e ( ! 1 ) ; } ) ; } } ; DMA . prototype . do_write = function ( a , b , c , d , e ) { var g = this , f = this . channel_count [ d ] + 1 & 65535 , k = 5 <= d ? 2 : 1 , l = f * k , m = this . address_get_8bit ( d ) , n = ! 1 , p = ! 1 , q = this . channel_mode [ d ] & 16 ; dbg_log ( "DMA write channel " + d , LOG_DMA ) ; dbg_log ( "to " + h ( m ) + " len " + h ( l ) , LOG_DMA ) ; c < l ? ( dbg_log ( "DMA should read more than provided" , LOG_DMA ) , f = Math . floor ( c / k ) , l = f * k , n = ! 0 ) : c > l && ( dbg_log ( "DMA attempted to read more than provided" , LOG_DMA ) , p = ! 0 ) ; b + l > a . byteLength ? ( dbg_log ( "DMA write outside of buffer" , LOG_DMA ) , e ( ! 0 ) ) : ( this . channel_addr [ d ] += f , this . channel_count [ d ] -= f , ! n && q && ( dbg_log ( "DMA autoinit" , LOG_DMA ) , this . channel_addr [ d ] = this . channel_addr_init [ d ] , this . channel_count [ d ] = this . channel_count_init [ d ] ) , a . set ( b , this . cpu . mem8 . subarray ( m , m + l ) , function ( ) { p && q ? ( dbg_log ( "DMA continuing from start" , LOG_DMA ) , g . do_write ( a , b + l , c - l , d , e ) ) : e ( ! 1 ) ; } ) ) ; } ; DMA . prototype . address_get_8bit = function ( a ) { var b = this . channel_addr [ a ] ; 5 <= a && ( b <<= 1 ) ; b = b & 65535 | this . channel_page [ a ] << 16 ; return b |= this . channel_pagehi [ a ] << 24 ; } ; DMA . prototype . count_get_8bit = function ( a ) { var b = this . channel_count [ a ] + 1 ; 5 <= a && ( b *= 2 ) ; return b ; } ; DMA . prototype . flipflop_get = function ( a , b , c ) { c || ( this . lsb_msb_flipflop ^= 1 ) ; return this . lsb_msb_flipflop ? a & - 256 | b : a & - 65281 | b << 8 ; } ; DMA . prototype . flipflop_read = function ( a ) { return ( this . lsb_msb_flipflop ^= 1 ) ? a & 255 : a >> 8 & 255 ; } ; var OSCILLATOR_FREQ = 1193.1816666 ; function PIT ( a , b ) { this . cpu = a ; this . bus = b ; this . counter_start_time = new Float64Array ( 3 ) ; this . counter_start_value = new Uint16Array ( 3 ) ; this . counter_next_low = new Uint8Array ( 4 ) ; this . counter_enabled = new Uint8Array ( 4 ) ; this . counter_mode = new Uint8Array ( 4 ) ; this . counter_read_mode = new Uint8Array ( 4 ) ; this . counter_latch = new Uint8Array ( 4 ) ; this . counter_latch_value = new Uint16Array ( 3 ) ; this . counter_reload = new Uint16Array ( 3 ) ; a . io . register_read ( 97 , this , function ( ) { var a = v86 . microtick ( ) , b = 66.66666666666667 * a & 1 ; a = this . did_rollover ( 2 , a ) ; return b << 4 | a << 5 ; } ) ; a . io . register_write ( 97 , this , function ( a ) { a & 1 ? this . bus . send ( "pcspeaker-enable" ) : this . bus . send ( "pcspeaker-disable" ) ; } ) ; a . io . register_read ( 64 , this , function ( ) { return this . counter_read ( 0 ) ; } ) ; a . io . register_read ( 65 , this , function ( ) { return this . counter_read ( 1 ) ; } ) ; a . io . register_read ( 66 , this , function ( ) { return this . counter_read ( 2 ) ; } ) ; a . io . register_write ( 64 , this , function ( a ) { this . counter_write ( 0 , a ) ; } ) ; a . io . register_write ( 65 , this , function ( a ) { this . counter_write ( 1 , a ) ; } ) ; a . io . register_write ( 66 , this , function ( a ) { this . counter_write ( 2 , a ) ; } ) ; a . io . register_write ( 67 , this , this . port43_write ) ; } PIT . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . counter_next_low ; a [ 1 ] = this . counter_enabled ; a [ 2 ] = this . counter_mode ; a [ 3 ] = this . counter_read_mode ; a [ 4 ] = this . counter_latch ; a [ 5 ] = this . counter_latch_value ; a [ 6 ] = this . counter_reload ; a [ 7 ] = this . counter_start_time ; a [ 8 ] = this . counter_start_value ; return a ; } ; PIT . prototype . set_state = function ( a ) { this . counter_next_low = a [ 0 ] ; this . counter_enabled = a [ 1 ] ; this . counter_mode = a [ 2 ] ; this . counter_read_mode = a [ 3 ] ; this . counter_latch = a [ 4 ] ; this . counter_latch_value = a [ 5 ] ; this . counter_reload = a [ 6 ] ; this . counter_start_time = a [ 7 ] ; this . counter_start_value = a [ 8 ] ; } ; PIT . prototype . timer = function ( a , b ) { b || ( this . counter_enabled [ 0 ] && this . did_rollover ( 0 , a ) ? ( this . counter_start_value [ 0 ] = this . get_counter_value ( 0 , a ) , this . counter_start_time [ 0 ] = a , dbg_log ( "pit interrupt. new value: " + this . counter_start_value [ 0 ] , LOG_PIT ) , this . cpu . device_raise_irq ( 0 ) , 0 === this . counter_mode [ 0 ] && ( this . counter_enabled [ 0 ] = 0 ) ) : this . cpu . device_lower_irq ( 0 ) ) ; return 0 ; } ; PIT . prototype . get_counter_value = function ( a , b ) { if ( ! this . counter_enabled [ a ] ) return 0 ; var c = b - this . counter_start_time [ a ] , d = Math . floor ( c * OSCILLATOR_FREQ ) ; b = this . counter_start_value [ a ] - d ; dbg_log ( "diff=" + c + " dticks=" + d + " value=" + b + " reload=" + this . counter_reload [ a ] , LOG_PIT ) ; c = this . counter_reload [ a ] ; b >= c ? ( dbg_log ( "Warning: Counter" + a + " value " + b + " is larger than reload " + c , LOG_PIT ) , b %= c ) : 0 > b && ( b = b % c + c ) ; return b ; } ; PIT . prototype . did_rollover = function ( a , b ) { b -= this . counter_start_time [ a ] ; return 0 > b ? ( dbg_log ( "Warning: PIT timer difference is negative, resetting" ) , ! 0 ) : this . counter_start_value [ a ] < Math . floor ( b * OSCILLATOR_FREQ ) ; } ; PIT . prototype . counter_read = function ( a ) { var b = this . counter_latch [ a ] ; if ( b ) return this . counter_latch [ a ] -- , 2 === b ? this . counter_latch_value [ a ] & 255 : this . counter_latch_value [ a ] >> 8 ; b = this . counter_next_low [ a ] ; 3 === this . counter_mode [ a ] && ( this . counter_next_low [ a ] ^= 1 ) ; a = this . get_counter_value ( a , v86 . microtick ( ) ) ; return b ? a & 255 : a >> 8 ; } ; PIT . prototype . counter_write = function ( a , b ) { this . counter_reload [ a ] = this . counter_next_low [ a ] ? this . counter_reload [ a ] & - 256 | b : this . counter_reload [ a ] & 255 | b << 8 ; 3 === this . counter_read_mode [ a ] && this . counter_next_low [ a ] || ( this . counter_reload [ a ] || ( this . counter_reload [ a ] = 65535 ) , this . counter_start_value [ a ] = this . counter_reload [ a ] , this . counter_enabled [ a ] = ! 0 , this . counter_start_time [ a ] = v86 . microtick ( ) , dbg_log ( "counter" + a + " reload=" + h ( this . counter_reload [ a ] ) + " tick=" + ( this . counter_reload [ a ] || 65536 ) / OSCILLATOR_FREQ + "ms" , LOG_PIT ) ) ; 3 === this . counter_read_mode [ a ] && ( this . counter_next_low [ a ] ^= 1 ) ; this . bus . send ( "pcspeaker-update" , [ this . counter_mode [ 2 ] , this . counter_reload [ 2 ] ] ) ; } ; PIT . prototype . port43_write = function ( a ) { var b = a >> 1 & 7 , c = a & 1 , d = a >> 6 & 3 ; a = a >> 4 & 3 ; 1 === d && dbg_log ( "Unimplemented timer1" , LOG_PIT ) ; 3 === d ? dbg_log ( "Unimplemented read back" , LOG_PIT ) : 0 === a ? ( this . counter_latch [ d ] = 2 , b = this . get_counter_value ( d , v86 . microtick ( ) ) , dbg_log ( "latch: " + b , LOG_PIT ) , this . counter_latch_value [ d ] = b ? b - 1 : 0 ) : ( 6 <= b && ( b &= - 5 ) , dbg_log ( "Control: mode=" + b + " ctr=" + d + " read_mode=" + a + " bcd=" + c , LOG_PIT ) , this . counter_next_low [ d ] = 1 === a ? 0 : 1 , 0 === d && this . cpu . device_lower_irq ( 0 ) , 0 !== b && 3 !== b && 2 !== b && dbg_log ( "Unimplemented counter mode: " + h ( b ) , LOG_PIT ) , this . counter_mode [ d ] = b , this . counter_read_mode [ d ] = a , this . bus . send ( "pcspeaker-update" , [ this . counter_mode [ 2 ] , this . counter_reload [ 2 ] ] ) ) ; } ; var VGA_BANK_SIZE = 65536 , MAX_XRES = 2560 , MAX_YRES = 1600 , MAX_BPP = 32 , VGA_LFB_ADDRESS = 3758096384 , VGA_PIXEL_BUFFER_START = 4 * VGA_BANK_SIZE , VGA_PIXEL_BUFFER_SIZE = 8 * VGA_BANK_SIZE , VGA_MIN_MEMORY_SIZE = VGA_PIXEL_BUFFER_START + VGA_PIXEL_BUFFER_SIZE , VGA_HOST_MEMORY_SPACE_START = Uint32Array . from ( [ 655360 , 655360 , 720896 , 753664 ] ) , VGA_HOST_MEMORY_SPACE_SIZE = Uint32Array . from ( [ 131072 , 65536 , 32768 , 32768 ] ) ; function VGAScreen ( a , b , c ) { var d = this ; this . bus = b ; this . vga_memory_size = c ; this . cursor_address = 0 ; this . cursor_scanline_start = 14 ; this . cursor_scanline_end = 15 ; this . max_cols = 80 ; this . max_rows = 25 ; this . virtual_height = this . virtual_width = this . screen_height = this . screen_width = 0 ; this . layers = [ ] ; this . start_address_latched = this . start_address = 0 ; this . crtc = new Uint8Array ( 25 ) ; this . line_compare = this . offset_register = this . preset_row_scan = this . underline_location_register = this . vertical_blank_start = this . vertical_display_enable_end = this . horizontal_blank_start = this . horizontal_display_enable_end = this . crtc_mode = 0 ; this . graphical_mode_is_linear = ! 0 ; this . graphical_mode = ! 1 ; setTimeout ( function ( ) { b . send ( "screen-set-mode" , d . graphical_mode ) ; } , 0 ) ; this . vga256_palette = new Int32Array ( 256 ) ; this . svga_height = this . svga_width = this . latch_dword = 0 ; this . svga_enabled = ! 1 ; this . svga_bpp = 32 ; this . svga_offset = this . svga_bank_offset = 0 ; this . pci_space = [ 222 , 16 , 32 , 10 , 7 , 0 , 0 , 0 , 162 , 0 , 0 , 3 , 0 , 0 , 128 , 0 , 8 , VGA_LFB_ADDRESS >>> 8 , VGA_LFB_ADDRESS >>> 16 , VGA_LFB_ADDRESS >>> 24 , 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 , 10 , 1 , 0 , 0 ] ; this . pci_id = 144 ; this . pci_bars = [ { size : c } ] ; this . pci_rom_size = 65536 ; this . pci_rom_address = 4272947200 ; this . name = "vga" ; this . stats = { is_graphical : ! 1 , res_x : 0 , res_y : 0 , bpp : 0 } ; this . dac_state = this . dac_color_index_read = this . dac_color_index_write = this . index_crtc = 0 ; this . dac_map = new Uint8Array ( 16 ) ; this . attribute_controller_index = - 1 ; this . palette_source = 32 ; this . color_select = this . horizontal_panning = this . color_plane_enable = this . attribute_mode = 0 ; this . sequencer_index = - 1 ; this . plane_write_bm = 15 ; this . clocking_mode = this . sequencer_memory_mode = 0 ; this . graphics_index = - 1 ; this . planar_rotate_reg = this . planar_mode = this . plane_read = 0 ; this . planar_bitmap = 255 ; this . max_scan_line = this . color_dont_care = this . color_compare = this . miscellaneous_graphics_register = this . planar_setreset_enable = this . planar_setreset = 0 ; this . port_3DA_value = this . miscellaneous_output_register = 255 ; c = a . io ; c . register_write ( 960 , this , this . port3C0_write ) ; c . register_read ( 960 , this , this . port3C0_read , this . port3C0_read16 ) ; c . register_read ( 961 , this , this . port3C1_read ) ; c . register_write ( 962 , this , this . port3C2_write ) ; c . register_write_consecutive ( 964 , this , this . port3C4_write , this . port3C5_write ) ; c . register_read ( 964 , this , this . port3C4_read ) ; c . register_read ( 965 , this , this . port3C5_read ) ; c . register_write_consecutive ( 974 , this , this . port3CE_write , this . port3CF_write ) ; c . register_read ( 974 , this , this . port3CE_read ) ; c . register_read ( 975 , this , this . port3CF_read ) ; c . register_write ( 967 , this , this . port3C7_write ) ; c . register_read ( 967 , this , this . port3C7_read ) ; c . register_write ( 968 , this , this . port3C8_write ) ; c . register_read ( 968 , this , this . port3C8_read ) ; c . register_write ( 969 , this , this . port3C9_write ) ; c . register_read ( 969 , this , this . port3C9_read ) ; c . register_read ( 972 , this , this . port3CC_read ) ; c . register_write_consecutive ( 980 , this , this . port3D4_write , this . port3D5_write ) ; c . register_read ( 980 , this , this . port3D4_read ) ; c . register_read ( 981 , this , this . port3D5_read ) ; c . register_read ( 970 , this , function ( ) { dbg_log ( "3CA read" , LOG_VGA ) ; return 0 ; } ) ; c . register_read ( 986 , this , this . port3DA_read ) ; c . register_read ( 954 , this , this . port3DA_read ) ; this . dispi_index = - 1 ; this . dispi_enable_value = 0 ; c . register_write ( 462 , this , void 0 , this . port1CE_write ) ; c . register_write ( 463 , this , void 0 , this . port1CF_write ) ; c . register_read ( 463 , this , void 0 , this . port1CF_read ) ; void 0 === this . vga_memory_size || this . vga_memory_size < VGA_MIN_MEMORY_SIZE ? ( this . vga_memory_size = VGA_MIN_MEMORY_SIZE , dbg_log ( "vga memory size rounded up to " + this . vga_memory_size , LOG_VGA ) ) : this . vga_memory_size & VGA_BANK_SIZE - 1 && ( this . vga_memory_size |= VGA_BANK_SIZE - 1 , this . vga_memory_size ++ ) ; this . svga_memory = new Uint8Array ( this . vga_memory_size ) ; this . diff_addr_min = this . vga_memory_size ; this . diff_addr_max = 0 ; this . diff_plot_min = this . vga_memory_size ; this . diff_plot_max = 0 ; this . dest_buffer = void 0 ; b . register ( "screen-tell-buffer" , function ( a ) { this . dest_buffer && a [ 0 ] && a [ 0 ] . set ( this . dest_buffer . subarray ( 0 , a [ 0 ] . length ) ) ; this . dest_buffer = a [ 0 ] ; } , this ) ; b . register ( "screen-fill-buffer" , function ( ) { this . screen_fill_buffer ( ) ; } , this ) ; this . svga_memory16 = new Uint16Array ( this . svga_memory . buffer ) ; this . svga_memory32 = new Int32Array ( this . svga_memory . buffer ) ; this . vga_memory = new Uint8Array ( this . svga_memory . buffer , 0 , 4 * VGA_BANK_SIZE ) ; this . plane0 = new Uint8Array ( this . svga_memory . buffer , 0 * VGA_BANK_SIZE , VGA_BANK_SIZE ) ; this . plane1 = new Uint8Array ( this . svga_memory . buffer , 1 * VGA_BANK_SIZE , VGA_BANK_SIZE ) ; this . plane2 = new Uint8Array ( this . svga_memory . buffer , 2 * VGA_BANK_SIZE , VGA_BANK_SIZE ) ; this . plane3 = new Uint8Array ( this . svga_memory . buffer , 3 * VGA_BANK_SIZE , VGA_BANK_SIZE ) ; this . pixel_buffer = new Uint8Array ( this . svga_memory . buffer , VGA_PIXEL_BUFFER_START , VGA_PIXEL_BUFFER_SIZE ) ; var e = this ; c . mmap_register ( 655360 , 131072 , function ( a ) { return e . vga_memory_read ( a ) ; } , function ( a , b ) { e . vga_memory_write ( a , b ) ; } ) ; c . mmap_register ( VGA_LFB_ADDRESS , this . vga_memory_size , function ( a ) { return e . svga_memory_read8 ( a ) ; } , function ( a , b ) { e . svga_memory_write8 ( a , b ) ; } , function ( a ) { return e . svga_memory_read32 ( a ) ; } , function ( a , b ) { e . svga_memory_write32 ( a , b ) ; } ) ; a . devices . pci . register_device ( this ) ; } VGAScreen . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . vga_memory_size ; a [ 1 ] = this . cursor_address ; a [ 2 ] = this . cursor_scanline_start ; a [ 3 ] = this . cursor_scanline_end ; a [ 4 ] = this . max_cols ; a [ 5 ] = this . max_rows ; a [ 6 ] = this . layers ; a [ 7 ] = this . dac_state ; a [ 8 ] = this . start_address ; a [ 9 ] = this . graphical_mode ; a [ 10 ] = this . vga256_palette ; a [ 11 ] = this . latch_dword ; a [ 12 ] = this . color_compare ; a [ 13 ] = this . color_dont_care ; a [ 14 ] = this . miscellaneous_graphics_register ; a [ 15 ] = this . svga_width ; a [ 16 ] = this . svga_height ; a [ 17 ] = this . crtc_mode ; a [ 18 ] = this . svga_enabled ; a [ 19 ] = this . svga_bpp ; a [ 20 ] = this . svga_bank_offset ; a [ 21 ] = this . svga_offset ; a [ 22 ] = this . index_crtc ; a [ 23 ] = this . dac_color_index_write ; a [ 24 ] = this . dac_color_index_read ; a [ 25 ] = this . dac_map ; a [ 26 ] = this . sequencer_index ; a [ 27 ] = this . plane_write_bm ; a [ 28 ] = this . sequencer_memory_mode ; a [ 29 ] = this . graphics_index ; a [ 30 ] = this . plane_read ; a [ 31 ] = this . planar_mode ; a [ 32 ] = this . planar_rotate_reg ; a [ 33 ] = this . planar_bitmap ; a [ 34 ] = this . max_scan_line ; a [ 35 ] = this . miscellaneous_output_register ; a [ 36 ] = this . port_3DA_value ; a [ 37 ] = this . dispi_index ; a [ 38 ] = this . dispi_enable_value ; a [ 39 ] = this . svga_memory ; a [ 40 ] = this . graphical_mode_is_linear ; a [ 41 ] = this . attribute_controller_index ; a [ 42 ] = this . offset_register ; a [ 43 ] = this . planar_setreset ; a [ 44 ] = this . planar_setreset_enable ; a [ 45 ] = this . start_address_latched ; a [ 46 ] = this . crtc ; a [ 47 ] = this . horizontal_display_enable_end ; a [ 48 ] = this . horizontal_blank_start ; a [ 49 ] = this . vertical_display_enable_end ; a [ 50 ] = this . vertical_blank_start ; a [ 51 ] = this . underline_location_register ; a [ 52 ] = this . preset_row_scan ; a [ 53 ] = this . offset_register ; a [ 54 ] = this . palette_source ; a [ 55 ] = this . attribute_mode ; a [ 56 ] = this . color_plane_enable ; a [ 57 ] = this . horizontal_panning ; a [ 58 ] = this . color_select ; a [ 59 ] = this . clocking_mode ; a [ 60 ] = this . line_compare ; return a ; } ; VGAScreen . prototype . set_state = function ( a ) { this . vga_memory_size = a [ 0 ] ; this . cursor_address = a [ 1 ] ; this . cursor_scanline_start = a [ 2 ] ; this . cursor_scanline_end = a [ 3 ] ; this . max_cols = a [ 4 ] ; this . max_rows = a [ 5 ] ; this . layers = a [ 6 ] ; this . dac_state = a [ 7 ] ; this . start_address = a [ 8 ] ; this . graphical_mode = a [ 9 ] ; this . vga256_palette = a [ 10 ] ; this . latch_dword = a [ 11 ] ; this . color_compare = a [ 12 ] ; this . color_dont_care = a [ 13 ] ; this . miscellaneous_graphics_register = a [ 14 ] ; this . svga_width = a [ 15 ] ; this . svga_height = a [ 16 ] ; this . crtc_mode = a [ 17 ] ; this . svga_enabled = a [ 18 ] ; this . svga_bpp = a [ 19 ] ; this . svga_bank_offset = a [ 20 ] ; this . svga_offset = a [ 21 ] ; this . index_crtc = a [ 22 ] ; this . dac_color_index_write = a [ 23 ] ; this . dac_color_index_read = a [ 24 ] ; this . dac_map = a [ 25 ] ; this . sequencer_index = a [ 26 ] ; this . plane_write_bm = a [ 27 ] ; this . sequencer_memory_mode = a [ 28 ] ; this . graphics_index = a [ 29 ] ; this . plane_read = a [ 30 ] ; this . planar_mode = a [ 31 ] ; this . planar_rotate_reg = a [ 32 ] ; this . planar_bitmap = a [ 33 ] ; this . max_scan_line = a [ 34 ] ; this . miscellaneous_output_register = a [ 35 ] ; this . port_3DA_value = a [ 36 ] ; this . dispi_index = a [ 37 ] ; this . dispi_enable_value = a [ 38 ] ; this . svga_memory . set ( a [ 39 ] ) ; this . graphical_mode_is_linear = a [ 40 ] ; this . attribute_controller_index = a [ 41 ] ; this . offset_register = a [ 42 ] ; this . planar_setreset = a [ 43 ] ; this . planar_setreset_enable = a [ 44 ] ; this . start_address_latched = a [ 45 ] ; this . crtc . set ( a [ 46 ] ) ; this . horizontal_display_enable_end = a [ 47 ] ; this . horizontal_blank_start = a [ 48 ] ; this . vertical_display_enable_end = a [ 49 ] ; this . vertical_blank_start = a [ 50 ] ; this . underline_location_register = a [ 51 ] ; this . preset_row_scan = a [ 52 ] ; this . offset_register = a [ 53 ] ; this . palette_source = a [ 54 ] ; this . attribute_mode = a [ 55 ] ; this . color_plane_enable = a [ 56 ] ; this . horizontal_panning = a [ 57 ] ; this . color_select = a [ 58 ] ; this . clocking_mode = a [ 59 ] ; this . line_compare = a [ 60 ] ; this . bus . send ( "screen-set-mode" , this . graphical_mode ) ; this . graphical_mode ? ( this . screen_height = this . screen_width = 0 , this . svga_enabled ? ( this . set_size_graphical ( this . svga_width , this . svga_height , this . svga_bpp , this . svga_width , this . svga_height ) , this . update_layers ( ) ) : ( this . update_vga_size ( ) , this . complete_replot ( ) ) ) : ( this . set_size_text ( this . max_cols , this . max_rows ) , this . update_cursor_scanline ( ) , this . update_cursor ( ) ) ; this . complete_redraw ( ) ; } ; VGAScreen . prototype . vga_memory_read = function ( a ) { if ( this . svga_enabled && this . graphical_mode_is_linear ) return a = a - 655360 | this . svga_bank_offset , this . svga_memory [ a ] ; var b = this . miscellaneous_graphics_register >> 2 & 3 ; a -= VGA_HOST_MEMORY_SPACE_START [ b ] ; if ( 0 > a || a >= VGA_HOST_MEMORY_SPACE_SIZE [ b ] ) return dbg_log ( "vga read outside memory space: addr:" + h ( a ) , LOG_VGA ) , 0 ; this . latch_dword = this . plane0 [ a ] ; this . latch_dword |= this . plane1 [ a ] << 8 ; this . latch_dword |= this . plane2 [ a ] << 16 ; this . latch_dword |= this . plane3 [ a ] << 24 ; if ( this . planar_mode & 8 ) return b = 255 , this . color_dont_care & 1 && ( b &= this . plane0 [ a ] ^ ~ ( this . color_compare & 1 ? 255 : 0 ) ) , this . color_dont_care & 2 && ( b &= this . plane1 [ a ] ^ ~ ( this . color_compare & 2 ? 255 : 0 ) ) , this . color_dont_care & 4 && ( b &= this . plane2 [ a ] ^ ~ ( this . color_compare & 4 ? 255 : 0 ) ) , this . color_dont_care & 8 && ( b &= this . plane3 [ a ] ^ ~ ( this . color_compare & 8 ? 255 : 0 ) ) , b ; b = this . plane_read ; this . graphical_mode ? this . sequencer_memory_mode & 8 ? ( b = a & 3 , a &= - 4 ) : this . planar_mode & 16 && ( b = a & 1 , a &= - 2 ) : b = 0 ; return this . vga_memory [ b << 16 | a ] ; } ; VGAScreen . prototype . vga_memory_write = function ( a , b ) { if ( this . svga_enabled && this . graphical_mode && this . graphical_mode_is_linear ) this . vga_memory_write_graphical_linear ( a - 655360 , b ) ; else { var c = this . miscellaneous_graphics_register >> 2 & 3 ; a -= VGA_HOST_MEMORY_SPACE_START [ c ] ; 0 > a || a >= VGA_HOST_MEMORY_SPACE_SIZE [ c ] ? dbg_log ( "vga write outside memory space: addr:" + h ( a ) + ", value:" + h ( b ) , LOG_VGA ) : this . graphical_mode ? this . vga_memory_write_graphical ( a , b ) : this . plane_write_bm & 3 && this . vga_memory_write_text_mode ( a , b ) ; } } ; VGAScreen . prototype . vga_memory_write_graphical_linear = function ( a , b ) { a |= this . svga_bank_offset ; this . diff_addr_min = a < this . diff_addr_min ? a : this . diff_addr_min ; this . diff_addr_max = a > this . diff_addr_max ? a : this . diff_addr_max ; this . svga_memory [ a ] = b ; } ; VGAScreen . prototype . vga_memory_write_graphical = function ( a , b ) { var c = this . planar_mode & 3 , d = this . apply_feed ( this . planar_bitmap ) , e = this . apply_expand ( this . planar_setreset ) , g = this . apply_expand ( this . planar_setreset_enable ) ; switch ( c ) { case 0 : b = this . apply_rotate ( b ) ; var f = this . apply_feed ( b ) ; f = this . apply_setreset ( f , g ) ; f = this . apply_logical ( f , this . latch_dword ) ; f = this . apply_bitmask ( f , d ) ; break ; case 1 : f = this . latch_dword ; break ; case 2 : f = this . apply_expand ( b ) ; f = this . apply_logical ( f , this . latch_dword ) ; f = this . apply_bitmask ( f , d ) ; break ; case 3 : b = this . apply_rotate ( b ) , d &= this . apply_feed ( b ) , f = this . apply_bitmask ( e , d ) ; } b = 15 ; switch ( this . sequencer_memory_mode & 12 ) { case 0 : b = 5 << ( a & 1 ) ; a &= - 2 ; break ; case 8 : case 12 : b = 1 << ( a & 3 ) , a &= - 4 ; } b &= this . plane_write_bm ; b & 1 && ( this . plane0 [ a ] = f >> 0 & 255 ) ; b & 2 && ( this . plane1 [ a ] = f >> 8 & 255 ) ; b & 4 && ( this . plane2 [ a ] = f >> 16 & 255 ) ; b & 8 && ( this . plane3 [ a ] = f >> 24 & 255 ) ; a = this . vga_addr_to_pixel ( a ) ; this . partial_replot ( a , a + 7 ) ; } ; VGAScreen . prototype . apply_feed = function ( a ) { return a | a << 8 | a << 16 | a << 24 ; } ; VGAScreen . prototype . apply_expand = function ( a ) { return ( a & 1 ? 255 : 0 ) | ( a & 2 ? 255 : 0 ) << 8 | ( a & 4 ? 255 : 0 ) << 16 | ( a & 8 ? 255 : 0 ) << 24 ; } ; VGAScreen . prototype . apply_rotate = function ( a ) { return ( a | a << 8 ) >>> ( this . planar_rotate_reg & 7 ) & 255 ; } ; VGAScreen . prototype . apply_setreset = function ( a , b ) { var c = this . apply_expand ( this . planar_setreset ) ; return ( a | b & c ) & ( ~ b | c ) ; } ; VGAScreen . prototype . apply_logical = function ( a , b ) { switch ( this . planar_rotate_reg & 24 ) { case 8 : return a & b ; case 16 : return a | b ; case 24 : return a ^ b ; } return a ; } ; VGAScreen . prototype . apply_bitmask = function ( a , b ) { return b & a | ~ b & this . latch_dword ; } ; VGAScreen . prototype . text_mode_redraw = function ( ) { for ( var a = this . start_address << 1 , b , c , d = 0 ; d < this . max_rows ; d ++ ) for ( var e = 0 ; e < this . max_cols ; e ++ ) b = this . vga_memory [ a ] , c = this . vga_memory [ a | 1 ] , this . bus . send ( "screen-put-char" , [ d , e , b , this . vga256_palette [ c >> 4 & 15 ] , this . vga256_palette [ c & 15 ] ] ) , a += 2 ; } ; VGAScreen . prototype . vga_memory_write_text_mode = function ( a , b ) { var c = ( a >> 1 ) - this . start_address , d = c / this . max_cols | 0 ; c %= this . max_cols ; if ( a & 1 ) { var e = b ; var g = this . vga_memory [ a & - 2 ] ; } else g = b , e = this . vga_memory [ a | 1 ] ; this . bus . send ( "screen-put-char" , [ d , c , g , this . vga256_palette [ e >> 4 & 15 ] , this . vga256_palette [ e & 15 ] ] ) ; this . vga_memory [ a ] = b ; } ; VGAScreen . prototype . update_cursor = function ( ) { var a = ( this . cursor_address - this . start_address ) / this . max_cols | 0 , b = ( this . cursor_address - this . start_address ) % this . max_cols ; a = Math . min ( this . max_rows - 1 , a ) ; this . bus . send ( "screen-update-cursor" , [ a , b ] ) ; } ; VGAScreen . prototype . svga_memory_read8 = function ( a ) { return this . svga_memory [ a & 268435455 ] ; } ; VGAScreen . prototype . svga_memory_read32 = function ( a ) { a &= 268435455 ; return a & 3 ? this . svga_memory [ a ] | this . svga_memory [ a + 1 ] << 8 | this . svga_memory [ a + 2 ] << 16 | this . svga_memory [ a + 3 ] << 24 : this . svga_memory32 [ a >> 2 ] ; } ; VGAScreen . prototype . svga_memory_write8 = function ( a , b ) { a &= 268435455 ; this . svga_memory [ a ] = b ; this . diff_addr_min = a < this . diff_addr_min ? a : this . diff_addr_min ; this . diff_addr_max = a > this . diff_addr_max ? a : this . diff_addr_max ; } ; VGAScreen . prototype . svga_memory_write32 = function ( a , b ) { a &= 268435455 ; this . diff_addr_min = a < this . diff_addr_min ? a : this . diff_addr_min ; this . diff_addr_max = a + 3 > this . diff_addr_max ? a + 3 : this . diff_addr_max ; this . svga_memory [ a ] = b ; this . svga_memory [ a + 1 ] = b >> 8 ; this . svga_memory [ a + 2 ] = b >> 16 ; this . svga_memory [ a + 3 ] = b >> 24 ; } ; VGAScreen . prototype . complete_redraw = function ( ) { dbg_log ( "complete redraw" , LOG_VGA ) ; this . graphical_mode ? ( this . diff_addr_min = 0 , this . diff_addr_max = this . svga_enabled ? this . vga_memory_size : VGA_PIXEL_BUFFER_SIZE ) : this . text_mode_redraw ( ) ; } ; VGAScreen . prototype . complete_replot = function ( ) { dbg_log ( "complete replot" , LOG_VGA ) ; this . graphical_mode && ! this . svga_enabled && ( this . diff_plot_min = 0 , this . diff_plot_max = VGA_PIXEL_BUFFER_SIZE , this . complete_redraw ( ) ) ; } ; VGAScreen . prototype . partial_redraw = function ( a , b ) { a < this . diff_addr_min && ( this . diff_addr_min = a ) ; b > this . diff_addr_max && ( this . diff_addr_max = b ) ; } ; VGAScreen . prototype . partial_replot = function ( a , b ) { a < this . diff_plot_min && ( this . diff_plot_min = a ) ; b > this . diff_plot_max && ( this . diff_plot_max = b ) ; this . partial_redraw ( a , b ) ; } ; VGAScreen . prototype . reset_diffs = function ( ) { this . diff_addr_min = this . vga_memory_size ; this . diff_addr_max = 0 ; this . diff_plot_min = this . vga_memory_size ; this . diff_plot_max = 0 ; } ; VGAScreen . prototype . destroy = function ( ) { } ; VGAScreen . prototype . vga_bytes_per_line = function ( ) { var a = this . offset_register << 2 ; this . underline_location_register & 64 ? a <<= 1 : this . crtc_mode & 64 && ( a >>>= 1 ) ; return a ; } ; VGAScreen . prototype . vga_addr_shift_count = function ( ) { var a = 128 + ( ~ this . underline_location_register & this . crtc_mode & 64 ) ; a -= this . underline_location_register & 64 ; a -= this . attribute_mode & 64 ; return a >>> 6 ; } ; VGAScreen . prototype . vga_addr_to_pixel = function ( a ) { var b = this . vga_addr_shift_count ( ) ; if ( ~ this . crtc_mode & 3 ) { var c = a - this . start_address ; c &= this . crtc_mode << 13 | - 24577 ; c <<= b ; var d = c / this . virtual_width | 0 ; c %= this . virtual_width ; switch ( this . crtc_mode & 3 ) { case 2 : d = d << 1 | a >> 13 & 1 ; break ; case 1 : d = d << 1 | a >> 14 & 1 ; break ; case 0 : d = d << 2 | a >> 13 & 3 ; } return d * this . virtual_width + c + ( this . start_address << b ) ; } return a << b ; } ; VGAScreen . prototype . scan_line_to_screen_row = function ( a ) { this . max_scan_line & 128 && ( a >>>= 1 ) ; a = Math . ceil ( a / ( 1 + ( this . max_scan_line & 31 ) ) ) ; this . crtc_mode & 1 || ( a <<= 1 ) ; this . crtc_mode & 2 || ( a <<= 1 ) ; return a ; } ; VGAScreen . prototype . set_size_text = function ( a , b ) { this . max_cols = a ; this . max_rows = b ; this . bus . send ( "screen-set-size-text" , [ a , b ] ) ; } ; VGAScreen . prototype . set_size_graphical = function ( a , b , c , d , e ) { this . stats . is_graphical && this . stats . bpp === c && this . screen_width === a && this . screen_height === b && this . virtual_width === d && this . virtual_height === e || ( this . screen_width = a , this . screen_height = b , this . virtual_width = d , this . virtual_height = e , this . stats . bpp = c , this . stats . is_graphical = ! 0 , this . stats . res_x = a , this . stats . res_y = b , this . bus . send ( "screen-set-size-graphical" , [ a , b , d , e , c ] ) ) ; } ; VGAScreen . prototype . update_vga_size = function ( ) { if ( ! this . svga_enabled ) { var a = Math . min ( 1 + this . horizontal_display_enable_end , this . horizontal_blank_start ) , b = Math . min ( 1 + this . vertical_display_enable_end , this . vertical_blank_start ) ; if ( a && b ) if ( this . graphical_mode ) { a <<= 3 ; var c = this . offset_register << 4 ; this . attribute_mode & 64 && ( a >>>= 1 , c >>>= 1 ) ; b = this . scan_line_to_screen_row ( b ) ; var d = Math . ceil ( VGA_HOST_MEMORY_SPACE_SIZE [ 0 ] / this . vga_bytes_per_line ( ) ) ; this . set_size_graphical ( a , b , 8 , c , d ) ; this . update_vertical_retrace ( ) ; this . update_layers ( ) ; } else this . max_scan_line & 128 && ( b >>>= 1 ) , c = b / ( 1 + ( this . max_scan_line & 31 ) ) | 0 , a && c && this . set_size_text ( a , c ) ; } } ; VGAScreen . prototype . update_layers = function ( ) { this . graphical_mode || this . text_mode_redraw ( ) ; if ( this . svga_enabled ) this . layers = [ ] ; else if ( this . virtual_width && this . screen_width ) if ( ! this . palette_source || this . clocking_mode & 32 ) this . layers = [ ] , this . bus . send ( "screen-clear" ) ; else { var a = this . start_address_latched , b = this . horizontal_panning ; this . attribute_mode & 64 && ( b >>>= 1 ) ; var c = this . preset_row_scan >> 5 & 3 , d = this . vga_addr_to_pixel ( a + c ) ; a = d / this . virtual_width | 0 ; var e = d % this . virtual_width + b ; d = this . scan_line_to_screen_row ( 1 + this . line_compare ) ; d = Math . min ( d , this . screen_height ) ; var g = this . screen_height - d ; this . layers = [ ] ; e = - e ; for ( var f = 0 ; e < this . screen_width ; e += this . virtual_width , f ++ ) this . layers . push ( { screen_x : e , screen_y : 0 , buffer_x : 0 , buffer_y : a + f , buffer_width : this . virtual_width , buffer_height : d } ) ; a = 0 ; this . attribute_mode & 32 || ( a = this . vga_addr_to_pixel ( c ) + b ) ; e = - a ; for ( f = 0 ; e < this . screen_width ; e += this . virtual_width , f ++ ) this . layers . push ( { screen_x : e , screen_y : d , buffer_x : 0 , buffer_y : f , buffer_width : this . virtual_width , buffer_height : g } ) ; } } ; VGAScreen . prototype . update_vertical_retrace = function ( ) { this . port_3DA_value |= 8 ; this . start_address_latched !== this . start_address && ( this . start_address_latched = this . start_address , this . update_layers ( ) ) ; } ; VGAScreen . prototype . update_cursor_scanline = function ( ) { this . bus . send ( "screen-update-cursor-scanline" , [ this . cursor_scanline_start , this . cursor_scanline_end ] ) ; } ; VGAScreen . prototype . port3C0_write = function ( a ) { if ( - 1 === this . attribute_controller_index ) dbg_log ( "attribute controller index register: " + h ( a ) , LOG_VGA ) , this . attribute_controller_index = a & 31 , dbg_log ( "attribute actual index: " + h ( this . attribute_controller_index ) , LOG_VGA ) , this . palette_source !== ( a & 32 ) && ( this . palette_source = a & 32 , this . update_layers ( ) ) ; else { if ( 16 > this . attribute_controller_index ) dbg_log ( "internal palette: " + h ( this . attribute_controller_index ) + " -> " + h ( a ) , LOG_VGA ) , this . dac_map [ this . attribute_controller_index ] = a , this . attribute_mode & 64 || this . complete_redraw ( ) ; else switch ( this . attribute_controller_index ) { case 16 : dbg_log ( "3C0 / attribute mode control: " + h ( a ) , LOG_VGA ) ; if ( this . attribute_mode !== a ) { var b = this . attribute_mode ; this . attribute_mode = a ; var c = 0 < ( a & 1 ) ; this . svga_enabled || this . graphical_mode === c || ( this . graphical_mode = c , this . bus . send ( "screen-set-mode" , this . graphical_mode ) ) ; ( b ^ a ) & 64 && this . complete_replot ( ) ; this . update_vga_size ( ) ; this . complete_redraw ( ) ; } break ; case 18 : dbg_log ( "3C0 / color plane enable: " + h ( a ) , LOG_VGA ) ; this . color_plane_enable !== a && ( this . color_plane_enable = a , this . complete_redraw ( ) ) ; break ; case 19 : dbg_log ( "3C0 / horizontal panning: " + h ( a ) , LOG_VGA ) ; this . horizontal_panning !== a && ( this . horizontal_panning = a & 15 , this . update_layers ( ) ) ; break ; case 20 : dbg_log ( "3C0 / color select: " + h ( a ) , LOG_VGA ) ; this . color_select !== a && ( this . color_select = a , this . complete_redraw ( ) ) ; break ; default : dbg_log ( "3C0 / attribute controller write " + h ( this . attribute_controller_index ) + ": " + h ( a ) , LOG_VGA ) ; } this . attribute_controller_index = - 1 ; } } ; VGAScreen . prototype . port3C0_read = function ( ) { dbg_log ( "3C0 read" , LOG_VGA ) ; return this . attribute_controller_index | this . palette_source ; } ; VGAScreen . prototype . port3C0_read16 = function ( ) { dbg_log ( "3C0 read16" , LOG_VGA ) ; return this . port3C0_read ( ) & 255 | this . port3C1_read ( ) << 8 & 65280 ; } ; VGAScreen . prototype . port3C1_read = function ( ) { if ( 16 > this . attribute_controller_index ) return dbg_log ( "3C1 / internal palette read: " + h ( this . attribute_controller_index ) + " -> " + h ( this . dac_map [ this . attribute_controller_index ] ) , LOG_VGA ) , this . dac_map [ this . attribute_controller_index ] ; switch ( this . attribute_controller_index ) { case 16 : return dbg_log ( "3C1 / attribute mode read: " + h ( this . attribute_mode ) , LOG_VGA ) , this . attribute_mode ; case 18 : return dbg_log ( "3C1 / color plane enable read: " + h ( this . color_plane_enable ) , LOG_VGA ) , this . color_plane_enable ; case 19 : return dbg_log ( "3C1 / horizontal panning read: " + h ( this . horizontal_panning ) , LOG_VGA ) , this . horizontal_panning ; case 20 : return dbg_log ( "3C1 / color select read: " + h ( this . color_select ) , LOG_VGA ) , this . color_select ; default : dbg_log ( "3C1 / attribute controller read " + h ( this . attribute_controller_index ) , LOG_VGA ) ; } return - 1 ; } ; VGAScreen . prototype . port3C2_write = function ( a ) { dbg_log ( "3C2 / miscellaneous output register = " + h ( a ) , LOG_VGA ) ; this . miscellaneous_output_register = a ; } ; VGAScreen . prototype . port3C4_write = function ( a ) { this . sequencer_index = a ; } ; VGAScreen . prototype . port3C4_read = function ( ) { return this . sequencer_index ; } ; VGAScreen . prototype . port3C5_write = function ( a ) { switch ( this . sequencer_index ) { case 1 : dbg_log ( "clocking mode: " + h ( a ) , LOG_VGA ) ; var b = this . clocking_mode ; this . clocking_mode = a ; ( b ^ a ) & 32 && this . update_layers ( ) ; break ; case 2 : dbg_log ( "plane write mask: " + h ( a ) , LOG_VGA ) ; this . plane_write_bm = a ; break ; case 4 : dbg_log ( "sequencer memory mode: " + h ( a ) , LOG_VGA ) ; this . sequencer_memory_mode = a ; break ; default : dbg_log ( "3C5 / sequencer write " + h ( this . sequencer_index ) + ": " + h ( a ) , LOG_VGA ) ; } } ; VGAScreen . prototype . port3C5_read = function ( ) { dbg_log ( "3C5 / sequencer read " + h ( this . sequencer_index ) , LOG_VGA ) ; switch ( this . sequencer_index ) { case 1 : return this . clocking_mode ; case 2 : return this . plane_write_bm ; case 4 : return this . sequencer_memory_mode ; case 6 : return 18 ; } return 0 ; } ; VGAScreen . prototype . port3C7_write = function ( a ) { dbg_log ( "3C7 write: " + h ( a ) , LOG_VGA ) ; this . dac_color_index_read = 3 * a ; this . dac_state &= 0 ; } ; VGAScreen . prototype . port3C7_read = function ( ) { return this . dac_state ; } ; VGAScreen . prototype . port3C8_write = function ( a ) { this . dac_color_index_write = 3 * a ; this . dac_state |= 3 ; } ; VGAScreen . prototype . port3C8_read = function ( ) { return this . dac_color_index_write / 3 | 0 ; } ; VGAScreen . prototype . port3C9_write = function ( a ) { var b = this . dac_color_index_write / 3 | 0 , c = this . dac_color_index_write % 3 , d = this . vga256_palette [ b ] ; a = 255 * ( a & 63 ) / 63 | 0 ; 0 === c ? d = d & - 16711681 | a << 16 : 1 === c ? d = d & - 65281 | a << 8 : ( d = d & - 256 | a , dbg_log ( "dac set color, index=" + h ( b ) + " value=" + h ( d ) , LOG_VGA ) ) ; this . vga256_palette [ b ] !== d && ( this . vga256_palette [ b ] = d , this . complete_redraw ( ) ) ; this . dac_color_index_write ++ ; } ; VGAScreen . prototype . port3C9_read = function ( ) { dbg_log ( "3C9 read" , LOG_VGA ) ; var a = this . dac_color_index_read % 3 , b = this . vga256_palette [ this . dac_color_index_read / 3 | 0 ] ; this . dac_color_index_read ++ ; return ( b >> 8 * ( 2 - a ) & 255 ) / 255 * 63 | 0 ; } ; VGAScreen . prototype . port3CC_read = function ( ) { dbg_log ( "3CC read" , LOG_VGA ) ; return this . miscellaneous_output_register ; } ; VGAScreen . prototype . port3CE_write = function ( a ) { this . graphics_index = a ; } ; VGAScreen . prototype . port3CE_read = function ( ) { return this . graphics_index ; } ; VGAScreen . prototype . port3CF_write = function ( a ) { switch ( this . graphics_index ) { case 0 : this . planar_setreset = a ; dbg_log ( "plane set/reset: " + h ( a ) , LOG_VGA ) ; break ; case 1 : this . planar_setreset_enable = a ; dbg_log ( "plane set/reset enable: " + h ( a ) , LOG_VGA ) ; break ; case 2 : this . color_compare = a ; dbg_log ( "color compare: " + h ( a ) , LOG_VGA ) ; break ; case 3 : this . planar_rotate_reg = a ; dbg_log ( "plane rotate: " + h ( a ) , LOG_VGA ) ; break ; case 4 : this . plane_read = a ; dbg_log ( "plane read: " + h ( a ) , LOG_VGA ) ; break ; case 5 : var b = this . planar_mode ; this . planar_mode = a ; dbg_log ( "planar mode: " + h ( a ) , LOG_VGA ) ; ( b ^ a ) & 96 && this . complete_replot ( ) ; break ; case 6 : dbg_log ( "miscellaneous graphics register: " + h ( a ) , LOG_VGA ) ; this . miscellaneous_graphics_register !== a && ( this . miscellaneous_graphics_register = a , this . update_vga_size ( ) ) ; break ; case 7 : this . color_dont_care = a ; dbg_log ( "color don't care: " + h ( a ) , LOG_VGA ) ; break ; case 8 : this . planar_bitmap = a ; dbg_log ( "planar bitmap: " + h ( a ) , LOG_VGA ) ; break ; default : dbg_log ( "3CF / graphics write " + h ( this . graphics_index ) + ": " + h ( a ) , LOG_VGA ) ; } } ; VGAScreen . prototype . port3CF_read = function ( ) { dbg_log ( "3CF / graphics read " + h ( this . graphics_index ) , LOG_VGA ) ; switch ( this . graphics_index ) { case 0 : return this . planar_setreset ; case 1 : return this . planar_setreset_enable ; case 2 : return this . color_compare ; case 3 : return this . planar_rotate_reg ; case 4 : return this . plane_read ; case 5 : return this . planar_mode ; case 6 : return this . miscellaneous_graphics_register ; case 7 : return this . color_dont_care ; case 8 : return this . planar_bitmap ; } return 0 ; } ; VGAScreen . prototype . port3D4_write = function ( a ) { dbg_log ( "3D4 / crtc index: " + a , LOG_VGA ) ; this . index_crtc = a ; } ; VGAScreen . prototype . port3D4_read = function ( ) { dbg_log ( "3D4 read / crtc index: " + this . index_crtc , LOG_VGA ) ; return this . index_crtc ; } ; VGAScreen . prototype . port3D5_write = function ( a ) { switch ( this . index_crtc ) { case 1 : dbg_log ( "3D5 / hdisp enable end write: " + h ( a ) , LOG_VGA ) ; this . horizontal_display_enable_end !== a && ( this . horizontal_display_enable_end = a , this . update_vga_size ( ) ) ; break ; case 2 : this . horizontal_blank_start !== a && ( this . horizontal_blank_start = a , this . update_vga_size ( ) ) ; break ; case 7 : dbg_log ( "3D5 / overflow register write: " + h ( a ) , LOG_VGA ) ; var b = this . vertical_display_enable_end ; this . vertical_display_enable_end &= 255 ; this . vertical_display_enable_end = this . vertical_display_enable_end | a << 3 & 512 | a << 7 & 256 ; b != this . vertical_display_enable_end && this . update_vga_size ( ) ; this . line_compare = this . line_compare & 767 | a << 4 & 256 ; b = this . vertical_blank_start ; this . vertical_blank_start = this . vertical_blank_start & 767 | a << 5 & 256 ; b !== this . vertical_blank_start && this . update_vga_size ( ) ; this . update_layers ( ) ; break ; case 8 : dbg_log ( "3D5 / preset row scan write: " + h ( a ) , LOG_VGA ) ; this . preset_row_scan = a ; this . update_layers ( ) ; break ; case 9 : dbg_log ( "3D5 / max scan line write: " + h ( a ) , LOG_VGA ) ; this . max_scan_line = a ; this . line_compare = this . line_compare & 511 | a << 3 & 512 ; b = this . vertical_blank_start ; this . vertical_blank_start = this . vertical_blank_start & 511 | a << 4 & 512 ; b !== this . vertical_blank_start && this . update_vga_size ( ) ; this . update_layers ( ) ; break ; case 10 : dbg_log ( "3D5 / cursor scanline start write: " + h ( a ) , LOG_VGA ) ; this . cursor_scanline_start = a ; this . update_cursor_scanline ( ) ; break ; case 11 : dbg_log ( "3D5 / cursor scanline end write: " + h ( a ) , LOG_VGA ) ; this . cursor_scanline_end = a ; this . update_cursor_scanline ( ) ; break ; case 12 : ( this . start_address >> 8 & 255 ) !== a && ( this . start_address = this . start_address & 255 | a << 8 , this . update_layers ( ) , ~ this . crtc_mode & 3 && this . complete_replot ( ) ) ; dbg_log ( "3D5 / start addr hi write: " + h ( a ) + " -> " + h ( this . start_address , 4 ) , LOG_VGA ) ; break ; case 13 : ( this . start_address & 255 ) !== a && ( this . start_address = this . start_address & 65280 | a , this . update_layers ( ) , ~ this . crtc_mode & 3 && this . complete_replot ( ) ) ; dbg_log ( "3D5 / start addr lo write: " + h ( a ) + " -> " + h ( this . start_address , 4 ) , LOG_VGA ) ; break ; case 14 : dbg_log ( "3D5 / cursor address hi write: " + h ( a ) , LOG_VGA ) ; this . cursor_address = this . cursor_address & 255 | a << 8 ; this . update_cursor ( ) ; break ; case 15 : dbg_log ( "3D5 / cursor address lo write: " + h ( a ) , LOG_VGA ) ; this . cursor_address = this . cursor_address & 65280 | a ; this . update_cursor ( ) ; break ; case 18 : dbg_log ( "3D5 / vdisp enable end write: " + h ( a ) , LOG_VGA ) ; ( this . vertical_display_enable_end & 255 ) !== a && ( this . vertical_display_enable_end = this . vertical_display_enable_end & 768 | a , this . update_vga_size ( ) ) ; break ; case 19 : dbg_log ( "3D5 / offset register write: " + h ( a ) , LOG_VGA ) ; this . offset_register !== a && ( this . offset_register = a , this . update_vga_size ( ) , ~ this . crtc_mode & 3 && this . complete_replot ( ) ) ; break ; case 20 : dbg_log ( "3D5 / underline location write: " + h ( a ) , LOG_VGA ) ; this . underline_location_register !== a && ( b = this . underline_location_register , this . underline_location_register = a , this . update_vga_size ( ) , ( b ^ a ) & 64 && this . complete_replot ( ) ) ; break ; case 21 : dbg_log ( "3D5 / vertical blank start write: " + h ( a ) , LOG_VGA ) ; ( this . vertical_blank_start & 255 ) !== a && ( this . vertical_blank_start = this . vertical_blank_start & 768 | a , this . update_vga_size ( ) ) ; break ; case 23 : dbg_log ( "3D5 / crtc mode write: " + h ( a ) , LOG_VGA ) ; this . crtc_mode !== a && ( b = this . crtc_mode , this . crtc_mode = a , this . update_vga_size ( ) , ( b ^ a ) & 67 && this . complete_replot ( ) ) ; break ; case 24 : dbg_log ( "3D5 / line compare write: " + h ( a ) , LOG_VGA ) ; this . line_compare = this . line_compare & 768 | a ; this . update_layers ( ) ; break ; default : this . index_crtc < this . crtc . length && ( this . crtc [ this . index_crtc ] = a ) , dbg_log ( "3D5 / CRTC write " + h ( this . index_crtc ) + ": " + h ( a ) , LOG_VGA ) ; } } ; VGAScreen . prototype . port3D5_read = function ( ) { dbg_log ( "3D5 read " + h ( this . index_crtc ) , LOG_VGA ) ; switch ( this . index_crtc ) { case 1 : return this . horizontal_display_enable_end ; case 2 : return this . horizontal_blank_start ; case 7 : return this . vertical_display_enable_end >> 7 & 2 | this . vertical_blank_start >> 5 & 8 | this . line_compare >> 4 & 16 | this . vertical_display_enable_end >> 3 & 64 ; case 8 : return this . preset_row_scan ; case 9 : return this . max_scan_line ; case 10 : return this . cursor_scanline_start ; case 11 : return this . cursor_scanline_end ; case 12 : return this . start_address & 255 ; case 13 : return this . start_address >> 8 ; case 14 : return this . cursor_address >> 8 ; case 15 : return this . cursor_address & 255 ; case 18 : return this . vertical_display_enable_end & 255 ; case 19 : return this . offset_register ; case 20 : return this . underline_location_register ; case 21 : return this . vertical_blank_start & 255 ; case 23 : return this . crtc_mode ; case 24 : return this . line_compare & 255 ; } return this . index_crtc < this . crtc . length ? this . crtc [ this . index_crtc ] : 0 ; } ; VGAScreen . prototype . port3DA_read = function ( ) { dbg_log ( "3DA read - status 1 and clear attr index" , LOG_VGA ) ; var a = this . port_3DA_value ; this . graphical_mode ? ( this . port_3DA_value ^= 1 , this . port_3DA_value &= 1 ) : ( this . port_3DA_value & 1 && ( this . port_3DA_value ^= 8 ) , this . port_3DA_value ^= 1 ) ; this . attribute_controller_index = - 1 ; return a ; } ; VGAScreen . prototype . svga_bytes_per_line = function ( ) { return this . svga_width * ( 15 === this . svga_bpp ? 16 : this . svga_bpp ) / 8 ; } ; VGAScreen . prototype . port1CE_write = function ( a ) { this . dispi_index = a ; } ; VGAScreen . prototype . port1CF_write = function ( a ) { dbg_log ( "1CF / dispi write " + h ( this . dispi_index ) + ": " + h ( a ) , LOG_VGA ) ; switch ( this . dispi_index ) { case 1 : this . svga_width = a ; this . svga_width > MAX_XRES && ( dbg_log ( "svga_width reduced from " + this . svga_width + " to " + MAX_XRES , LOG_VGA ) , this . svga_width = MAX_XRES ) ; break ; case 2 : this . svga_height = a ; this . svga_height > MAX_YRES && ( dbg_log ( "svga_height reduced from " + this . svga_height + " to " + MAX_YRES , LOG_VGA ) , this . svga_height = MAX_YRES ) ; break ; case 3 : this . svga_bpp = a ; break ; case 4 : this . svga_enabled = 1 === ( a & 1 ) ; this . dispi_enable_value = a ; break ; case 5 : this . svga_bank_offset = a << 16 ; break ; case 9 : this . svga_offset = a * this . svga_bytes_per_line ( ) , dbg_log ( "SVGA offset: " + h ( this . svga_offset ) + " y=" + h ( a ) , LOG_VGA ) , this . complete_redraw ( ) ; } ! this . svga_enabled || this . svga_width && this . svga_height || ( dbg_log ( "SVGA: disabled because of invalid width/height: " + this . svga_width + "x" + this . svga_height , LOG_VGA ) , this . svga_enabled = ! 1 ) ; dbg_assert ( 4 !== this . svga_bpp , "unimplemented svga bpp: 4" ) ; dbg_assert ( 15 !== this . svga_bpp , "unimplemented svga bpp: 15" ) ; dbg_assert ( 4 === this . svga_bpp || 8 === this . svga_bpp || 15 === this . svga_bpp || 16 === this . svga_bpp || 24 === this . svga_bpp || 32 === this . svga_bpp , "unexpected svga bpp: " + this . svga_bpp ) ; dbg_log ( "SVGA: enabled=" + this . svga_enabled + ", " + this . svga_width + "x" + this . svga_height + "x" + this . svga_bpp , LOG_VGA ) ; this . svga_enabled && 4 === this . dispi_index && ( this . set_size_graphical ( this . svga_width , this . svga_height , this . svga_bpp , this . svga_width , this . svga_height ) , this . bus . send ( "screen-set-mode" , ! 0 ) , this . graphical_mode_is_linear = this . graphical_mode = ! 0 ) ; this . svga_enabled || ( this . svga_bank_offset = 0 ) ; this . update_layers ( ) ; } ; VGAScreen . prototype . port1CF_read = function ( ) { dbg_log ( "1CF / dispi read " + h ( this . dispi_index ) , LOG_VGA ) ; return this . svga_register_read ( this . dispi_index ) ; } ; VGAScreen . prototype . svga_register_read = function ( a ) { switch ( a ) { case 0 : return 45248 ; case 1 : return this . dispi_enable_value & 2 ? MAX_XRES : this . svga_width ; case 2 : return this . dispi_enable_value & 2 ? MAX_YRES : this . svga_height ; case 3 : return this . dispi_enable_value & 2 ? MAX_BPP : this . svga_bpp ; case 4 : return this . dispi_enable_value ; case 5 : return this . svga_bank_offset >>> 16 ; case 6 : return this . screen_width ? this . screen_width : 1 ; case 8 : return 0 ; case 10 : return this . vga_memory_size / VGA_BANK_SIZE | 0 ; } return 255 ; } ; VGAScreen . prototype . vga_replot = function ( ) { for ( var a = this . diff_plot_min & - 16 , b = Math . min ( this . diff_plot_max | 15 , VGA_PIXEL_BUFFER_SIZE - 1 ) , c = this . vga_addr_shift_count ( ) , d = ~ this . crtc_mode & 3 , e = this . planar_mode & 96 , g = this . attribute_mode & 64 ; a <= b ; ) { var f = a >>> c ; if ( d ) { var k = a / this . virtual_width | 0 , l = a - this . virtual_width * k ; switch ( d ) { case 1 : f = ( k & 1 ) << 13 ; k >>>= 1 ; break ; case 2 : f = ( k & 1 ) << 14 ; k >>>= 1 ; break ; case 3 : f = ( k & 3 ) << 13 , k >>>= 2 ; } f |= ( k * this . virtual_width + l >>> c ) + this . start_address ; } k = this . plane0 [ f ] ; l = this . plane1 [ f ] ; var m = this . plane2 [ f ] , n = this . plane3 [ f ] ; f = new Uint8Array ( 8 ) ; switch ( e ) { case 0 : k <<= 0 ; l <<= 1 ; m <<= 2 ; n <<= 3 ; for ( var p = 7 ; 0 <= p ; p -- ) f [ 7 - p ] = k >> p & 1 | l >> p & 2 | m >> p & 4 | n >> p & 8 ; break ; case 32 : f [ 0 ] = k >> 6 & 3 | m >> 4 & 12 ; f [ 1 ] = k >> 4 & 3 | m >> 2 & 12 ; f [ 2 ] = k >> 2 & 3 | m >> 0 & 12 ; f [ 3 ] = k >> 0 & 3 | m << 2 & 12 ; f [ 4 ] = l >> 6 & 3 | n >> 4 & 12 ; f [ 5 ] = l >> 4 & 3 | n >> 2 & 12 ; f [ 6 ] = l >> 2 & 3 | n >> 0 & 12 ; f [ 7 ] = l >> 0 & 3 | n << 2 & 12 ; break ; case 64 : case 96 : f [ 0 ] = k >> 4 & 15 , f [ 1 ] = k >> 0 & 15 , f [ 2 ] = l >> 4 & 15 , f [ 3 ] = l >> 0 & 15 , f [ 4 ] = m >> 4 & 15 , f [ 5 ] = m >> 0 & 15 , f [ 6 ] = n >> 4 & 15 , f [ 7 ] = n >> 0 & 15 ; } if ( g ) for ( k = p = 0 ; 4 > p ; p ++ , a ++ , k += 2 ) this . pixel_buffer [ a ] = f [ k ] << 4 | f [ k + 1 ] ; else for ( p = 0 ; 8 > p ; p ++ , a ++ ) this . pixel_buffer [ a ] = f [ p ] ; } } ; VGAScreen . prototype . vga_redraw = function ( ) { var a = this . diff_addr_min , b = Math . min ( this . diff_addr_max , VGA_PIXEL_BUFFER_SIZE - 1 ) , c = this . dest_buffer ; if ( c ) { var d = 255 , e = 0 ; this . attribute_mode & 128 && ( d &= 207 , e |= this . color_select << 4 & 48 ) ; if ( this . attribute_mode & 64 ) for ( ; a <= b ; a ++ ) { var g = this . pixel_buffer [ a ] & d | e ; g = this . vga256_palette [ g ] ; c [ a ] = g & 65280 | g << 16 | g >> 16 | 4278190080 ; } else for ( d &= 63 , e |= this . color_select << 4 & 192 ; a <= b ; a ++ ) g = this . dac_map [ this . pixel_buffer [ a ] & this . color_plane_enable ] & d | e , g = this . vga256_palette [ g ] , c [ a ] = g & 65280 | g << 16 | g >> 16 | 4278190080 ; } } ; VGAScreen . prototype . screen_fill_buffer = function ( ) { if ( this . graphical_mode ) if ( this . dest_buffer ) if ( this . diff_addr_max < this . diff_addr_min && this . diff_plot_max < this . diff_plot_min ) this . bus . send ( "screen-fill-buffer-end" , this . layers ) ; else { if ( this . svga_enabled ) { var a = this . svga_bpp , b = this . dest_buffer , c = this . diff_addr_min , d = this . diff_addr_max ; switch ( a ) { case 32 : var e = c >> 2 , g = ( d >> 2 ) + 1 ; for ( a = e ; a < g ; a ++ ) d = this . svga_memory32 [ a ] , b [ a ] = d << 16 | d >> 16 & 255 | d & 65280 | 4278190080 ; break ; case 24 : e = c / 3 | 0 ; g = ( d / 3 | 0 ) + 1 ; var f = 3 * e ; for ( a = e ; f < d ; a ++ ) { var k = this . svga_memory [ f ++ ] ; c = this . svga_memory [ f ++ ] ; var l = this . svga_memory [ f ++ ] ; b [ a ] = k << 16 | c << 8 | l | 4278190080 ; } break ; case 16 : e = c >> 1 ; g = ( d >> 1 ) + 1 ; for ( a = e ; a < g ; a ++ ) d = this . svga_memory16 [ a ] , l = 255 * ( d >> 11 ) / 31 | 0 , c = 255 * ( d >> 5 & 63 ) / 63 | 0 , k = 255 * ( d & 31 ) / 31 | 0 , b [ a ] = k << 16 | c << 8 | l | 4278190080 ; break ; case 8 : e = c ; g = d + 1 ; for ( a = c ; a <= d ; a ++ ) c = this . vga256_palette [ this . svga_memory [ a ] ] , b [ a ] = c & 65280 | c << 16 | c >> 16 | 4278190080 ; break ; default : dbg_assert ( ! 1 , "Unsupported BPP: " + a ) ; } b = e / this . svga_width | 0 ; this . bus . send ( "screen-fill-buffer-end" , [ { screen_x : 0 , screen_y : b , buffer_x : 0 , buffer_y : b , buffer_width : this . svga_width , buffer_height : ( g / this . svga_width | 0 ) - b + 1 } ] ) ; } else this . vga_replot ( ) , this . vga_redraw ( ) , this . bus . send ( "screen-fill-buffer-end" , this . layers ) ; this . reset_diffs ( ) ; } else dbg_log ( "Cannot fill buffer: No destination buffer" , LOG_VGA ) ; this . update_vertical_retrace ( ) ; } ; function PS2 ( a , b ) { this . cpu = a ; this . bus = b ; this . use_mouse = this . enable_mouse_stream = ! 1 ; this . have_mouse = ! 0 ; this . mouse_clicks = this . mouse_delta_y = this . mouse_delta_x = 0 ; this . have_keyboard = ! 0 ; this . next_read_resolution = this . next_read_rate = this . next_handle_scan_code_set = this . next_read_led = this . next_read_sample = this . next_is_mouse_command = this . enable_keyboard_stream = ! 1 ; this . kbd_buffer = new ByteQueue ( 1024 ) ; this . last_port60_byte = 0 ; this . sample_rate = 100 ; this . resolution = 4 ; this . scaling2 = ! 1 ; this . last_mouse_packet = - 1 ; this . mouse_buffer = new ByteQueue ( 1024 ) ; this . next_byte_is_aux = this . next_byte_is_ready = ! 1 ; this . bus . register ( "keyboard-code" , function ( a ) { this . kbd_send_code ( a ) ; } , this ) ; this . bus . register ( "mouse-click" , function ( a ) { this . mouse_send_click ( a [ 0 ] , a [ 1 ] , a [ 2 ] ) ; } , this ) ; this . bus . register ( "mouse-delta" , function ( a ) { this . mouse_send_delta ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; this . bus . register ( "mouse-wheel" , function ( a ) { } , this ) ; this . command_register = 5 ; this . read_command_register = this . read_output_register = ! 1 ; a . io . register_read ( 96 , this , this . port60_read ) ; a . io . register_read ( 100 , this , this . port64_read ) ; a . io . register_write ( 96 , this , this . port60_write ) ; a . io . register_write ( 100 , this , this . port64_write ) ; } PS2 . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . enable_mouse_stream ; a [ 1 ] = this . use_mouse ; a [ 2 ] = this . have_mouse ; a [ 3 ] = this . mouse_delta_x ; a [ 4 ] = this . mouse_delta_y ; a [ 5 ] = this . mouse_clicks ; a [ 6 ] = this . have_keyboard ; a [ 7 ] = this . enable_keyboard_stream ; a [ 8 ] = this . next_is_mouse_command ; a [ 9 ] = this . next_read_sample ; a [ 10 ] = this . next_read_led ; a [ 11 ] = this . next_handle_scan_code_set ; a [ 12 ] = this . next_read_rate ; a [ 13 ] = this . next_read_resolution ; a [ 15 ] = this . last_port60_byte ; a [ 16 ] = this . sample_rate ; a [ 17 ] = this . resolution ; a [ 18 ] = this . scaling2 ; a [ 20 ] = this . command_register ; a [ 21 ] = this . read_output_register ; a [ 22 ] = this . read_command_register ; return a ; } ; PS2 . prototype . set_state = function ( a ) { this . enable_mouse_stream = a [ 0 ] ; this . use_mouse = a [ 1 ] ; this . have_mouse = a [ 2 ] ; this . mouse_delta_x = a [ 3 ] ; this . mouse_delta_y = a [ 4 ] ; this . mouse_clicks = a [ 5 ] ; this . have_keyboard = a [ 6 ] ; this . enable_keyboard_stream = a [ 7 ] ; this . next_is_mouse_command = a [ 8 ] ; this . next_read_sample = a [ 9 ] ; this . next_read_led = a [ 10 ] ; this . next_handle_scan_code_set = a [ 11 ] ; this . next_read_rate = a [ 12 ] ; this . next_read_resolution = a [ 13 ] ; this . last_port60_byte = a [ 15 ] ; this . sample_rate = a [ 16 ] ; this . resolution = a [ 17 ] ; this . scaling2 = a [ 18 ] ; this . command_register = a [ 20 ] ; this . read_output_register = a [ 21 ] ; this . read_command_register = a [ 22 ] ; this . next_byte_is_aux = this . next_byte_is_ready = ! 1 ; this . kbd_buffer . clear ( ) ; this . mouse_buffer . clear ( ) ; this . bus . send ( "mouse-enable" , this . use_mouse ) ; } ; PS2 . prototype . raise_irq = function ( ) { this . next_byte_is_ready || ( this . kbd_buffer . length ? this . kbd_irq ( ) : this . mouse_buffer . length && this . mouse_irq ( ) ) ; } ; PS2 . prototype . mouse_irq = function ( ) { this . next_byte_is_aux = this . next_byte_is_ready = ! 0 ; this . command_register & 2 && ( dbg_log ( "Mouse irq" , LOG_PS2 ) , this . cpu . device_lower_irq ( 12 ) , this . cpu . device_raise_irq ( 12 ) ) ; } ; PS2 . prototype . kbd_irq = function ( ) { this . next_byte_is_ready = ! 0 ; this . next_byte_is_aux = ! 1 ; this . command_register & 1 && ( dbg_log ( "Keyboard irq" , LOG_PS2 ) , this . cpu . device_lower_irq ( 1 ) , this . cpu . device_raise_irq ( 1 ) ) ; } ; PS2 . prototype . kbd_send_code = function ( a ) { this . enable_keyboard_stream && ( dbg_log ( "adding kbd code: " + h ( a ) , LOG_PS2 ) , this . kbd_buffer . push ( a ) , this . raise_irq ( ) ) ; } ; PS2 . prototype . mouse_send_delta = function ( a , b ) { if ( this . have_mouse && this . use_mouse ) { var c = this . resolution * this . sample_rate / 80 ; this . mouse_delta_x += a * c ; this . mouse_delta_y += b * c ; this . enable_mouse_stream && ( a = this . mouse_delta_x | 0 , b = this . mouse_delta_y | 0 , a || b ) && ( Date . now ( ) , this . mouse_delta_x -= a , this . mouse_delta_y -= b , this . send_mouse_packet ( a , b ) ) ; } } ; PS2 . prototype . mouse_send_click = function ( a , b , c ) { this . have_mouse && this . use_mouse && ( this . mouse_clicks = a | c << 1 | b << 2 , this . enable_mouse_stream && this . send_mouse_packet ( 0 , 0 ) ) ; } ; PS2 . prototype . send_mouse_packet = function ( a , b ) { var c = ( 0 > b ) << 5 | ( 0 > a ) << 4 | 8 | this . mouse_clicks ; this . last_mouse_packet = Date . now ( ) ; this . mouse_buffer . push ( c ) ; this . mouse_buffer . push ( a ) ; this . mouse_buffer . push ( b ) ; dbg_log ( "adding mouse packets: " + [ c , a , b ] , LOG_PS2 ) ; this . raise_irq ( ) ; } ; PS2 . prototype . apply_scaling2 = function ( a ) { var b = a >> 31 ; switch ( Math . abs ( a ) ) { case 0 : case 1 : case 3 : return a ; case 2 : return b ; case 4 : return 6 * b ; case 5 : return 9 * b ; default : return a << 1 ; } } ; PS2 . prototype . port60_read = function ( ) { this . next_byte_is_ready = ! 1 ; if ( ! this . kbd_buffer . length && ! this . mouse_buffer . length ) return dbg_log ( "Port 60 read: Empty" , LOG_PS2 ) , this . last_port60_byte ; this . next_byte_is_aux ? ( this . cpu . device_lower_irq ( 12 ) , this . last_port60_byte = this . mouse_buffer . shift ( ) , dbg_log ( "Port 60 read (mouse): " + h ( this . last_port60_byte ) , LOG_PS2 ) ) : ( this . cpu . device_lower_irq ( 1 ) , this . last_port60_byte = this . kbd_buffer . shift ( ) , dbg_log ( "Port 60 read (kbd)  : " + h ( this . last_port60_byte ) , LOG_PS2 ) ) ; ( this . kbd_buffer . length || this . mouse_buffer . length ) && this . raise_irq ( ) ; return this . last_port60_byte ; } ; PS2 . prototype . port64_read = function ( ) { var a = 16 ; this . next_byte_is_ready && ( a |= 1 ) ; this . next_byte_is_aux && ( a |= 32 ) ; dbg_log ( "port 64 read: " + h ( a ) , LOG_PS2 ) ; return a ; } ; PS2 . prototype . port60_write = function ( a ) { dbg_log ( "port 60 write: " + h ( a ) , LOG_PS2 ) ; if ( this . read_command_register ) this . command_register = a , this . read_command_register = ! 1 , dbg_log ( "Keyboard command register = " + h ( this . command_register ) , LOG_PS2 ) ; else if ( this . read_output_register ) this . read_output_register = ! 1 , this . mouse_buffer . clear ( ) , this . mouse_buffer . push ( a ) , this . mouse_irq ( ) ; else if ( this . next_read_sample ) this . next_read_sample = ! 1 , this . mouse_buffer . clear ( ) , this . mouse_buffer . push ( 250 ) , this . sample_rate = a , dbg_log ( "mouse sample rate: " + h ( a ) , LOG_PS2 ) , this . sample_rate || ( dbg_log ( "invalid sample rate, reset to 100" , LOG_PS2 ) , this . sample_rate = 100 ) , this . mouse_irq ( ) ; else if ( this . next_read_resolution ) this . next_read_resolution = ! 1 , this . mouse_buffer . clear ( ) , this . mouse_buffer . push ( 250 ) , 3 < a ? ( this . resolution = 4 , dbg_log ( "invalid resolution, resetting to 4" , LOG_PS2 ) ) : ( this . resolution = 1 << a , dbg_log ( "resolution: " + this . resolution , LOG_PS2 ) ) , this . mouse_irq ( ) ; else if ( this . next_read_led ) this . next_read_led = ! 1 , this . kbd_buffer . push ( 250 ) , this . kbd_irq ( ) ; else if ( this . next_handle_scan_code_set ) this . next_handle_scan_code_set = ! 1 , this . kbd_buffer . push ( 250 ) , this . kbd_irq ( ) , a || this . kbd_buffer . push ( 2 ) ; else if ( this . next_read_rate ) this . next_read_rate = ! 1 , this . kbd_buffer . push ( 250 ) , this . kbd_irq ( ) ; else if ( this . next_is_mouse_command ) { if ( this . next_is_mouse_command = ! 1 , dbg_log ( "Port 60 data register write: " + h ( a ) , LOG_PS2 ) , this . have_mouse ) { this . kbd_buffer . clear ( ) ; this . mouse_buffer . clear ( ) ; this . mouse_buffer . push ( 250 ) ; switch ( a ) { case 230 : dbg_log ( "Scaling 1:1" , LOG_PS2 ) ; this . scaling2 = ! 1 ; break ; case 231 : dbg_log ( "Scaling 2:1" , LOG_PS2 ) ; this . scaling2 = ! 0 ; break ; case 232 : this . next_read_resolution = ! 0 ; break ; case 233 : this . send_mouse_packet ( 0 , 0 ) ; break ; case 235 : dbg_log ( "unimplemented request single packet" , LOG_PS2 ) ; this . send_mouse_packet ( 0 , 0 ) ; break ; case 242 : this . mouse_buffer . push ( 0 ) ; this . mouse_buffer . push ( 0 ) ; this . mouse_clicks = this . mouse_delta_x = this . mouse_delta_y = 0 ; break ; case 243 : this . next_read_sample = ! 0 ; break ; case 244 : this . use_mouse = this . enable_mouse_stream = ! 0 ; this . bus . send ( "mouse-enable" , ! 0 ) ; this . mouse_clicks = this . mouse_delta_x = this . mouse_delta_y = 0 ; break ; case 245 : this . enable_mouse_stream = ! 1 ; break ; case 246 : this . enable_mouse_stream = ! 1 ; this . sample_rate = 100 ; this . scaling2 = ! 1 ; this . resolution = 4 ; break ; case 255 : dbg_log ( "Mouse reset" , LOG_PS2 ) ; this . mouse_buffer . push ( 170 ) ; this . mouse_buffer . push ( 0 ) ; this . use_mouse = ! 0 ; this . bus . send ( "mouse-enable" , ! 0 ) ; this . enable_mouse_stream = ! 1 ; this . sample_rate = 100 ; this . scaling2 = ! 1 ; this . resolution = 4 ; this . mouse_clicks = this . mouse_delta_x = this . mouse_delta_y = 0 ; break ; default : dbg_log ( "Unimplemented mouse command: " + h ( a ) , LOG_PS2 ) ; } this . mouse_irq ( ) ; } } else { dbg_log ( "Port 60 data register write: " + h ( a ) , LOG_PS2 ) ; this . mouse_buffer . clear ( ) ; this . kbd_buffer . clear ( ) ; this . kbd_buffer . push ( 250 ) ; switch ( a ) { case 237 : this . next_read_led = ! 0 ; break ; case 240 : this . next_handle_scan_code_set = ! 0 ; break ; case 242 : this . kbd_buffer . push ( 171 ) ; this . kbd_buffer . push ( 83 ) ; break ; case 243 : this . next_read_rate = ! 0 ; break ; case 244 : dbg_log ( "kbd enable scanning" , LOG_PS2 ) ; this . enable_keyboard_stream = ! 0 ; break ; case 245 : dbg_log ( "kbd disable scanning" , LOG_PS2 ) ; this . enable_keyboard_stream = ! 1 ; break ; case 246 : break ; case 255 : this . kbd_buffer . clear ( ) ; this . kbd_buffer . push ( 250 ) ; this . kbd_buffer . push ( 170 ) ; this . kbd_buffer . push ( 0 ) ; break ; default : dbg_log ( "Unimplemented keyboard command: " + h ( a ) , LOG_PS2 ) ; } this . kbd_irq ( ) ; } } ; PS2 . prototype . port64_write = function ( a ) { dbg_log ( "port 64 write: " + h ( a ) , LOG_PS2 ) ; switch ( a ) { case 32 : this . kbd_buffer . clear ( ) ; this . mouse_buffer . clear ( ) ; this . kbd_buffer . push ( this . command_register ) ; this . kbd_irq ( ) ; break ; case 96 : this . read_command_register = ! 0 ; break ; case 211 : this . read_output_register = ! 0 ; break ; case 212 : this . next_is_mouse_command = ! 0 ; break ; case 167 : dbg_log ( "Disable second port" , LOG_PS2 ) ; this . command_register |= 32 ; break ; case 168 : dbg_log ( "Enable second port" , LOG_PS2 ) ; this . command_register &= - 33 ; break ; case 169 : this . kbd_buffer . clear ( ) ; this . mouse_buffer . clear ( ) ; this . kbd_buffer . push ( 0 ) ; this . kbd_irq ( ) ; break ; case 170 : this . kbd_buffer . clear ( ) ; this . mouse_buffer . clear ( ) ; this . kbd_buffer . push ( 85 ) ; this . kbd_irq ( ) ; break ; case 171 : this . kbd_buffer . clear ( ) ; this . mouse_buffer . clear ( ) ; this . kbd_buffer . push ( 0 ) ; this . kbd_irq ( ) ; break ; case 173 : dbg_log ( "Disable Keyboard" , LOG_PS2 ) ; this . command_register |= 16 ; break ; case 174 : dbg_log ( "Enable Keyboard" , LOG_PS2 ) ; this . command_register &= - 17 ; break ; case 254 : dbg_log ( "CPU reboot via PS2" ) ; this . cpu . reboot_internal ( ) ; break ; default : dbg_log ( "port 64: Unimplemented command byte: " + h ( a ) , LOG_PS2 ) ; } } ; var PIC_LOG_VERBOSE = ! 1 ; function PIC ( a , b ) { this . irq_value = this . irr = this . isr = this . irq_map = this . irq_mask = 0 ; this . requested_irq = - 1 ; this . master = b ; this . is_master = void 0 === this . master ; this . slave = void 0 ; this . name = this . is_master ? "master" : "slave " ; this . expect_icw4 = ! 1 ; this . read_isr = this . state = 0 ; this . auto_eoi = 1 ; this . elcr = this . special_mask_mode = 0 ; this . cpu = a ; this . is_master ? ( this . slave = new PIC ( this . cpu , this ) , this . check_irqs = function ( ) { if ( 0 <= this . requested_irq ) PIC_LOG_VERBOSE && dbg_log ( "master> Already requested irq: " + this . requested_irq , LOG_PIC ) , this . cpu . handle_irqs ( ) ; else { var a = this . irr & this . irq_mask ; if ( a ) { a &= - a ; var b = this . special_mask_mode ? this . irq_mask : - 1 ; this . isr && ( this . isr & - this . isr & b ) <= a ? dbg_log ( "master> higher prio: isr=" + h ( this . isr , 2 ) + " mask=" + h ( this . irq_mask & 255 , 2 ) + " irq=" + h ( a , 2 ) , LOG_PIC ) : ( dbg_assert ( 0 !== a ) , b = v86util . int_log2_byte ( a ) , dbg_assert ( a === 1 << b ) , PIC_LOG_VERBOSE && dbg_log ( "master> request irq " + b , LOG_PIC ) , this . requested_irq = b , this . cpu . handle_irqs ( ) ) ; } else PIC_LOG_VERBOSE && dbg_log ( "master> no unmasked irrs. irr=" + h ( this . irr , 2 ) + " mask=" + h ( this . irq_mask & 255 , 2 ) + " isr=" + h ( this . isr , 2 ) , LOG_PIC ) ; } } , this . acknowledge_irq = function ( ) { if ( - 1 !== this . requested_irq ) if ( 0 === this . irr ) PIC_LOG_VERBOSE && dbg_log ( "master> spurious requested=" + this . requested_irq , LOG_PIC ) , this . requested_irq = - 1 , this . cpu . pic_call_irq ( this . irq_map | 7 ) ; else { dbg_assert ( this . irr ) ; dbg_assert ( 0 <= this . requested_irq ) ; var a = 1 << this . requested_irq ; 0 === ( this . elcr & a ) && ( this . irr &= ~ a ) ; this . auto_eoi || ( this . isr |= a ) ; PIC_LOG_VERBOSE && dbg_log ( "master> acknowledge " + this . requested_irq , LOG_PIC ) ; 2 === this . requested_irq ? this . slave . acknowledge_irq ( ) : this . cpu . pic_call_irq ( this . irq_map | this . requested_irq ) ; this . requested_irq = - 1 ; this . check_irqs ( ) ; } } ) : ( this . check_irqs = function ( ) { if ( 0 <= this . requested_irq ) PIC_LOG_VERBOSE && dbg_log ( "slave > Already requested irq: " + this . requested_irq , LOG_PIC ) , this . cpu . handle_irqs ( ) ; else { var a = this . irr & this . irq_mask ; if ( a ) { a &= - a ; var b = this . special_mask_mode ? this . irq_mask : - 1 ; this . isr && ( this . isr & - this . isr & b ) <= a ? PIC_LOG_VERBOSE && dbg_log ( "slave > higher prio: isr=" + h ( this . isr , 2 ) + " irq=" + h ( a , 2 ) , LOG_PIC ) : ( dbg_assert ( 0 !== a ) , b = v86util . int_log2_byte ( a ) , dbg_assert ( a === 1 << b ) , PIC_LOG_VERBOSE && dbg_log ( "slave > request irq " + b , LOG_PIC ) , this . requested_irq = b , this . master . set_irq ( 2 ) ) ; } else PIC_LOG_VERBOSE && dbg_log ( "slave > no unmasked irrs. irr=" + h ( this . irr , 2 ) + " mask=" + h ( this . irq_mask & 255 , 2 ) + " isr=" + h ( this . isr , 2 ) , LOG_PIC ) ; } } , this . acknowledge_irq = function ( ) { if ( - 1 !== this . requested_irq ) if ( 0 === this . irr ) PIC_LOG_VERBOSE && dbg_log ( "slave > spurious requested=" + this . requested_irq , LOG_PIC ) , this . requested_irq = - 1 , this . master . irq_value &= - 5 , this . cpu . pic_call_irq ( this . irq_map | 7 ) ; else { dbg_assert ( this . irr ) ; dbg_assert ( 0 <= this . requested_irq ) ; var a = 1 << this . requested_irq ; 0 === ( this . elcr & a ) && ( this . irr &= ~ a ) ; this . auto_eoi || ( this . isr |= a ) ; this . master . irq_value &= - 5 ; PIC_LOG_VERBOSE && dbg_log ( "slave > acknowledge " + this . requested_irq , LOG_PIC ) ; this . cpu . pic_call_irq ( this . irq_map | this . requested_irq ) ; this . requested_irq = - 1 ; this . check_irqs ( ) ; } } ) ; this . dump = function ( ) { dbg_log ( "mask: " + h ( this . irq_mask & 255 ) , LOG_PIC ) ; dbg_log ( "base: " + h ( this . irq_map ) , LOG_PIC ) ; dbg_log ( "requested: " + h ( this . irr ) , LOG_PIC ) ; dbg_log ( "serviced: " + h ( this . isr ) , LOG_PIC ) ; this . is_master && this . slave . dump ( ) ; } ; this . is_master ? ( a = 32 , b = 1232 ) : ( a = 160 , b = 1233 ) ; this . cpu . io . register_write ( a , this , this . port20_write ) ; this . cpu . io . register_read ( a , this , this . port20_read ) ; this . cpu . io . register_write ( a | 1 , this , this . port21_write ) ; this . cpu . io . register_read ( a | 1 , this , this . port21_read ) ; this . cpu . io . register_write ( b , this , this . port4D0_write ) ; this . cpu . io . register_read ( b , this , this . port4D0_read ) ; this . is_master ? ( this . set_irq = function ( a ) { dbg_assert ( 0 <= a && 16 > a ) ; 8 <= a ? this . slave . set_irq ( a - 8 ) : ( PIC_LOG_VERBOSE && dbg_log ( "master> set irq " + a , LOG_PIC ) , a = 1 << a , 0 === ( this . irq_value & a ) && ( this . irr |= a , this . irq_value |= a , this . check_irqs ( ) ) ) ; } , this . clear_irq = function ( a ) { dbg_assert ( 0 <= a && 16 > a ) ; PIC_LOG_VERBOSE && dbg_log ( "master> clear irq " + a , LOG_PIC ) ; 8 <= a ? this . slave . clear_irq ( a - 8 ) : ( a = 1 << a , this . irq_value & a && ( this . irq_value &= ~ a , this . irr &= ~ a , this . check_irqs ( ) ) ) ; } ) : ( this . set_irq = function ( a ) { dbg_assert ( 0 <= a && 8 > a ) ; PIC_LOG_VERBOSE && dbg_log ( "slave > set irq " + a , LOG_PIC ) ; a = 1 << a ; 0 === ( this . irq_value & a ) && ( this . irr |= a , this . irq_value |= a , this . check_irqs ( ) ) ; } , this . clear_irq = function ( a ) { dbg_assert ( 0 <= a && 8 > a ) ; PIC_LOG_VERBOSE && dbg_log ( "slave > clear irq " + a , LOG_PIC ) ; a = 1 << a ; this . irq_value & a && ( this . irq_value &= ~ a , this . irr &= ~ a , this . check_irqs ( ) ) ; } ) ; this . get_isr = function ( ) { return this . isr ; } ; } PIC . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . irq_mask ; a [ 1 ] = this . irq_map ; a [ 2 ] = this . isr ; a [ 3 ] = this . irr ; a [ 4 ] = this . is_master ; a [ 5 ] = this . slave ; a [ 6 ] = this . expect_icw4 ; a [ 7 ] = this . state ; a [ 8 ] = this . read_isr ; a [ 9 ] = this . auto_eoi ; a [ 10 ] = this . elcr ; return a ; } ; PIC . prototype . set_state = function ( a ) { this . irq_mask = a [ 0 ] ; this . irq_map = a [ 1 ] ; this . isr = a [ 2 ] ; this . irr = a [ 3 ] ; this . is_master = a [ 4 ] ; this . slave = a [ 5 ] ; this . expect_icw4 = a [ 6 ] ; this . state = a [ 7 ] ; this . read_isr = a [ 8 ] ; this . auto_eoi = a [ 9 ] ; this . elcr = a [ 10 ] ; } ; PIC . prototype . port20_write = function ( a ) { if ( a & 16 ) dbg_log ( "icw1 = " + h ( a ) , LOG_PIC ) , this . irq_value = this . irq_mask = this . irr = this . isr = 0 , this . auto_eoi = 1 , this . requested_irq = - 1 , this . expect_icw4 = a & 1 , this . state = 1 ; else if ( a & 8 ) dbg_log ( "ocw3: " + h ( a ) , LOG_PIC ) , a & 2 && ( this . read_isr = a & 1 ) , a & 4 && dbg_assert ( ! 1 , "unimplemented: polling" , LOG_PIC ) , a & 64 && ( this . special_mask_mode = 32 === ( a & 32 ) , dbg_log ( "special mask mode: " + this . special_mask_mode , LOG_PIC ) ) ; else { dbg_log ( "eoi: " + h ( a ) + " (" + this . name + ")" , LOG_PIC ) ; var b = a >> 5 ; 1 === b ? ( this . isr &= this . isr - 1 , dbg_log ( "new isr: " + h ( this . isr , 2 ) , LOG_PIC ) ) : 3 === b ? this . isr &= ~ ( 1 << ( a & 7 ) ) : 192 === ( a & 200 ) ? dbg_log ( "lowest priority: " + h ( a & 7 ) , LOG_PIC ) : ( dbg_log ( "Unknown eoi: " + h ( a ) , LOG_PIC ) , dbg_assert ( ! 1 ) , this . isr &= this . isr - 1 ) ; this . check_irqs ( ) ; } } ; PIC . prototype . port20_read = function ( ) { if ( this . read_isr ) return dbg_log ( "read port 20h (isr): " + h ( this . isr ) , LOG_PIC ) , this . isr ; dbg_log ( "read port 20h (irr): " + h ( this . irr ) , LOG_PIC ) ; return this . irr ; } ; PIC . prototype . port21_write = function ( a ) { 0 === this . state ? this . expect_icw4 ? ( this . expect_icw4 = ! 1 , this . auto_eoi = a & 2 , dbg_log ( "icw4: " + h ( a ) + " autoeoi=" + this . auto_eoi , LOG_PIC ) , 0 === ( a & 1 ) && dbg_assert ( ! 1 , "unimplemented: not 8086 mode" , LOG_PIC ) ) : ( this . irq_mask = ~ a , PIC_LOG_VERBOSE && dbg_log ( "interrupt mask: " + ( this . irq_mask & 255 ) . toString ( 2 ) + " (" + this . name + ")" , LOG_PIC ) , this . check_irqs ( ) ) : 1 === this . state ? ( this . irq_map = a , dbg_log ( "interrupts are mapped to " + h ( this . irq_map ) + " (" + this . name + ")" , LOG_PIC ) , this . state ++ ) : 2 === this . state && ( this . state = 0 , dbg_log ( "icw3: " + h ( a ) , LOG_PIC ) ) ; } ; PIC . prototype . port21_read = function ( ) { dbg_log ( "21h read " + h ( ~ this . irq_mask & 255 ) , LOG_PIC ) ; return ~ this . irq_mask & 255 ; } ; PIC . prototype . port4D0_read = function ( ) { dbg_log ( "elcr read: " + h ( this . elcr , 2 ) , LOG_PIC ) ; return this . elcr ; } ; PIC . prototype . port4D0_write = function ( a ) { dbg_log ( "elcr write: " + h ( a , 2 ) , LOG_PIC ) ; this . elcr = a ; } ; var CMOS_RTC_SECONDS = 0 , CMOS_RTC_SECONDS_ALARM = 1 , CMOS_RTC_MINUTES = 2 , CMOS_RTC_MINUTES_ALARM = 3 , CMOS_RTC_HOURS = 4 , CMOS_RTC_HOURS_ALARM = 5 , CMOS_RTC_DAY_WEEK = 6 , CMOS_RTC_DAY_MONTH = 7 , CMOS_RTC_MONTH = 8 , CMOS_RTC_YEAR = 9 , CMOS_STATUS_A = 10 , CMOS_STATUS_B = 11 , CMOS_STATUS_C = 12 , CMOS_STATUS_D = 13 , CMOS_RESET_CODE = 15 , CMOS_FLOPPY_DRIVE_TYPE = 16 , CMOS_DISK_DATA = 18 , CMOS_EQUIPMENT_INFO = 20 , CMOS_MEM_BASE_LOW = 21 , CMOS_MEM_BASE_HIGH = 22 , CMOS_MEM_OLD_EXT_LOW = 23 , CMOS_MEM_OLD_EXT_HIGH = 24 , CMOS_DISK_DRIVE1_TYPE = 25 , CMOS_DISK_DRIVE2_TYPE = 26 , CMOS_DISK_DRIVE1_CYL = 27 , CMOS_DISK_DRIVE2_CYL = 36 , CMOS_MEM_EXTMEM_LOW = 48 , CMOS_MEM_EXTMEM_HIGH = 49 , CMOS_CENTURY = 50 , CMOS_MEM_EXTMEM2_LOW = 52 , CMOS_MEM_EXTMEM2_HIGH = 53 , CMOS_BIOS_BOOTFLAG1 = 56 , CMOS_BIOS_DISKTRANSFLAG = 57 , CMOS_BIOS_BOOTFLAG2 = 61 , CMOS_MEM_HIGHMEM_LOW = 91 , CMOS_MEM_HIGHMEM_MID = 92 , CMOS_MEM_HIGHMEM_HIGH = 93 , CMOS_BIOS_SMP_COUNT = 95 ; function RTC ( a ) { this . cpu = a ; this . cmos_index = 0 ; this . cmos_data = new Uint8Array ( 128 ) ; this . last_update = this . rtc_time = Date . now ( ) ; this . next_interrupt = 0 ; this . periodic_interrupt = ! 1 ; this . periodic_interrupt_time = .9765625 ; this . cmos_a = 38 ; this . cmos_b = 2 ; this . nmi_disabled = this . cmos_c = 0 ; a . io . register_write ( 112 , this , function ( a ) { this . cmos_index = a & 127 ; this . nmi_disabled = a >> 7 ; } ) ; a . io . register_write ( 113 , this , this . cmos_port_write ) ; a . io . register_read ( 113 , this , this . cmos_port_read ) ; } RTC . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . cmos_index ; a [ 1 ] = this . cmos_data ; a [ 2 ] = this . rtc_time ; a [ 3 ] = this . last_update ; a [ 4 ] = this . next_interrupt ; a [ 6 ] = this . periodic_interrupt ; a [ 7 ] = this . periodic_interrupt_time ; a [ 8 ] = this . cmos_a ; a [ 9 ] = this . cmos_b ; a [ 10 ] = this . cmos_c ; a [ 11 ] = this . nmi_disabled ; return a ; } ; RTC . prototype . set_state = function ( a ) { this . cmos_index = a [ 0 ] ; this . cmos_data = a [ 1 ] ; this . rtc_time = a [ 2 ] ; this . last_update = a [ 3 ] ; this . next_interrupt = a [ 4 ] ; this . periodic_interrupt = a [ 6 ] ; this . periodic_interrupt_time = a [ 7 ] ; this . cmos_a = a [ 8 ] ; this . cmos_b = a [ 9 ] ; this . cmos_c = a [ 10 ] ; this . nmi_disabled = a [ 11 ] ; } ; RTC . prototype . timer = function ( a , b ) { a = Date . now ( ) ; this . rtc_time += a - this . last_update ; this . last_update = a ; return this . periodic_interrupt && this . next_interrupt < a ? ( this . cpu . device_raise_irq ( 8 ) , this . cmos_c |= 192 , this . next_interrupt += this . periodic_interrupt_time * Math . ceil ( ( a - this . next_interrupt ) / this . periodic_interrupt_time ) , Math . max ( 0 , a - this . next_interrupt ) ) : 100 ; } ; RTC . prototype . bcd_pack = function ( a ) { for ( var b = 0 , c = 0 , d ; a ; ) d = a % 10 , c |= d << 4 * b , b ++ , a = ( a - d ) / 10 ; return c ; } ; RTC . prototype . encode_time = function ( a ) { return this . cmos_b & 4 ? a : this . bcd_pack ( a ) ; } ; RTC . prototype . cmos_port_read = function ( ) { var a = this . cmos_index ; switch ( a ) { case CMOS_RTC_SECONDS : return this . encode_time ( ( new Date ( this . rtc_time ) ) . getUTCSeconds ( ) ) ; case CMOS_RTC_MINUTES : return this . encode_time ( ( new Date ( this . rtc_time ) ) . getUTCMinutes ( ) ) ; case CMOS_RTC_HOURS : return this . encode_time ( ( new Date ( this . rtc_time ) ) . getUTCHours ( ) ) ; case CMOS_RTC_DAY_MONTH : return this . encode_time ( ( new Date ( this . rtc_time ) ) . getUTCDate ( ) ) ; case CMOS_RTC_MONTH : return this . encode_time ( ( new Date ( this . rtc_time ) ) . getUTCMonth ( ) + 1 ) ; case CMOS_RTC_YEAR : return this . encode_time ( ( new Date ( this . rtc_time ) ) . getUTCFullYear ( ) % 100 ) ; case CMOS_STATUS_A : return this . cmos_a ; case CMOS_STATUS_B : return this . cmos_b ; case CMOS_STATUS_C : return this . cpu . device_lower_irq ( 8 ) , dbg_log ( "cmos reg C read" , LOG_RTC ) , a = this . cmos_c , this . cmos_c &= - 241 , a ; case CMOS_STATUS_D : return 255 ; case CMOS_CENTURY : return this . encode_time ( ( new Date ( this . rtc_time ) ) . getUTCFullYear ( ) / 100 | 0 ) ; default : return dbg_log ( "cmos read from index " + h ( a ) , LOG_RTC ) , this . cmos_data [ this . cmos_index ] ; } } ; RTC . prototype . cmos_port_write = function ( a ) { switch ( this . cmos_index ) { case 10 : this . cmos_a = a & 127 ; this . periodic_interrupt_time = 1E3 / ( 32768 >> ( this . cmos_a & 15 ) - 1 ) ; dbg_log ( "Periodic interrupt, a=" + h ( this . cmos_a , 2 ) + " t=" + this . periodic_interrupt_time , LOG_RTC ) ; break ; case 11 : this . cmos_b = a ; this . cmos_b & 64 && ( this . next_interrupt = Date . now ( ) ) ; this . cmos_b & 32 && dbg_log ( "Unimplemented: alarm interrupt" , LOG_RTC ) ; this . cmos_b & 16 && dbg_log ( "Unimplemented: updated interrupt" , LOG_RTC ) ; dbg_log ( "cmos b=" + h ( this . cmos_b , 2 ) , LOG_RTC ) ; break ; default : dbg_log ( "cmos write index " + h ( this . cmos_index ) + ": " + h ( a ) , LOG_RTC ) ; } this . periodic_interrupt = 64 === ( this . cmos_b & 64 ) && 0 < ( this . cmos_a & 15 ) ; } ; RTC . prototype . cmos_read = function ( a ) { dbg_assert ( 128 > a ) ; return this . cmos_data [ a ] ; } ; RTC . prototype . cmos_write = function ( a , b ) { dbg_log ( "cmos " + h ( a ) + " <- " + h ( b ) , LOG_RTC ) ; dbg_assert ( 128 > a ) ; this . cmos_data [ a ] = b ; } ; var DLAB = 128 , UART_IER_MSI = 8 , UART_IER_THRI = 2 , UART_IER_RDI = 1 , UART_IIR_MSI = 0 , UART_IIR_NO_INT = 1 , UART_IIR_THRI = 2 , UART_IIR_RDI = 4 , UART_IIR_RLSI = 6 , UART_IIR_CTI = 12 , UART_LSR_DATA_READY = 1 , UART_LSR_TX_EMPTY = 32 , UART_LSR_TRANSMITTER_EMPTY = 64 ; function UART ( a , b , c ) { this . bus = c ; this . cpu = a ; this . ints = 1 << UART_IIR_THRI ; this . line_control = this . baud_rate = 0 ; this . lsr = UART_LSR_TRANSMITTER_EMPTY | UART_LSR_TX_EMPTY ; this . ier = this . fifo_control = 0 ; this . iir = UART_IIR_NO_INT ; this . irq = this . scratch_register = this . modem_status = this . modem_control = 0 ; this . input = new ByteQueue ( 4096 ) ; this . current_line = [ ] ; if ( 1E3 === b || 1016 === b ) this . irq = 4 ; else if ( 1E3 === b || 1E3 === b ) this . irq = 3 ; else { dbg_log ( "Invalid port: " + h ( b ) , LOG_SERIAL ) ; return ; } this . bus . register ( "serial0-input" , function ( a ) { this . data_received ( a ) ; } , this ) ; a = a . io ; a . register_write ( b , this , function ( a ) { this . write_data ( a ) ; } , function ( a ) { this . write_data ( a & 255 ) ; this . write_data ( a >> 8 ) ; } ) ; a . register_write ( b | 1 , this , function ( a ) { this . line_control & DLAB ? ( this . baud_rate = this . baud_rate & 255 | a << 8 , dbg_log ( "baud rate: " + h ( this . baud_rate ) , LOG_SERIAL ) ) : ( this . ier = a & 15 , dbg_log ( "interrupt enable: " + h ( a ) , LOG_SERIAL ) , this . CheckInterrupt ( ) ) ; } ) ; a . register_read ( b , this , function ( ) { if ( this . line_control & DLAB ) return this . baud_rate & 255 ; var a = this . input . shift ( ) ; - 1 === a ? dbg_log ( "Read input empty" , LOG_SERIAL ) : dbg_log ( "Read input: " + h ( a ) , LOG_SERIAL ) ; 0 === this . input . length && ( this . lsr &= ~ UART_LSR_DATA_READY , this . ClearInterrupt ( UART_IIR_CTI ) ) ; return a ; } ) ; a . register_read ( b | 1 , this , function ( ) { return this . line_control & DLAB ? this . baud_rate >> 8 : this . ier & 15 ; } ) ; a . register_read ( b | 2 , this , function ( ) { var a = this . iir & 15 | 192 ; dbg_log ( "read interrupt identification: " + h ( this . iir ) , LOG_SERIAL ) ; this . iir == UART_IIR_THRI && this . ClearInterrupt ( UART_IIR_THRI ) ; return a ; } ) ; a . register_write ( b | 2 , this , function ( a ) { dbg_log ( "fifo control: " + h ( a ) , LOG_SERIAL ) ; this . fifo_control = a ; } ) ; a . register_read ( b | 3 , this , function ( ) { dbg_log ( "read line control: " + h ( this . line_control ) , LOG_SERIAL ) ; return this . line_control ; } ) ; a . register_write ( b | 3 , this , function ( a ) { dbg_log ( "line control: " + h ( a ) , LOG_SERIAL ) ; this . line_control = a ; } ) ; a . register_read ( b | 4 , this , function ( ) { return this . modem_control ; } ) ; a . register_write ( b | 4 , this , function ( a ) { dbg_log ( "modem control: " + h ( a ) , LOG_SERIAL ) ; this . modem_control = a ; } ) ; a . register_read ( b | 5 , this , function ( ) { dbg_log ( "read line status: " + h ( this . lsr ) , LOG_SERIAL ) ; return this . lsr ; } ) ; a . register_write ( b | 5 , this , function ( a ) { dbg_log ( "Factory test write" , LOG_SERIAL ) ; } ) ; a . register_read ( b | 6 , this , function ( ) { dbg_log ( "read modem status: " + h ( this . modem_status ) , LOG_SERIAL ) ; return this . modem_status ; } ) ; a . register_write ( b | 6 , this , function ( a ) { dbg_log ( "Unkown register write (base+6)" , LOG_SERIAL ) ; } ) ; a . register_read ( b | 7 , this , function ( ) { return this . scratch_register ; } ) ; a . register_write ( b | 7 , this , function ( a ) { this . scratch_register = a ; } ) ; } UART . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . ints ; a [ 1 ] = this . baud_rate ; a [ 2 ] = this . line_control ; a [ 3 ] = this . lsr ; a [ 4 ] = this . fifo_control ; a [ 5 ] = this . ier ; a [ 6 ] = this . iir ; a [ 7 ] = this . modem_control ; a [ 8 ] = this . modem_status ; a [ 9 ] = this . scratch_register ; a [ 10 ] = this . irq ; return a ; } ; UART . prototype . set_state = function ( a ) { this . ints = a [ 0 ] ; this . baud_rate = a [ 1 ] ; this . line_control = a [ 2 ] ; this . lsr = a [ 3 ] ; this . fifo_control = a [ 4 ] ; this . ier = a [ 5 ] ; this . iir = a [ 6 ] ; this . modem_control = a [ 7 ] ; this . modem_status = a [ 8 ] ; this . scratch_register = a [ 9 ] ; this . irq = a [ 10 ] ; } ; UART . prototype . CheckInterrupt = function ( ) { this . ints & 1 << UART_IIR_CTI && this . ier & UART_IER_RDI ? ( this . iir = UART_IIR_CTI , this . cpu . device_raise_irq ( this . irq ) ) : this . ints & 1 << UART_IIR_THRI && this . ier & UART_IER_THRI ? ( this . iir = UART_IIR_THRI , this . cpu . device_raise_irq ( this . irq ) ) : this . ints & 1 << UART_IIR_MSI && this . ier & UART_IER_MSI ? ( this . iir = UART_IIR_MSI , this . cpu . device_raise_irq ( this . irq ) ) : ( this . iir = UART_IIR_NO_INT , this . cpu . device_lower_irq ( this . irq ) ) ; } ; UART . prototype . ThrowInterrupt = function ( a ) { this . ints |= 1 << a ; this . CheckInterrupt ( ) ; } ; UART . prototype . ClearInterrupt = function ( a ) { this . ints &= ~ ( 1 << a ) ; this . CheckInterrupt ( ) ; } ; UART . prototype . data_received = function ( a ) { dbg_log ( "input: " + h ( a ) , LOG_SERIAL ) ; this . input . push ( a ) ; this . lsr |= UART_LSR_DATA_READY ; this . ThrowInterrupt ( UART_IIR_CTI ) ; } ; UART . prototype . write_data = function ( a ) { if ( this . line_control & DLAB ) this . baud_rate = this . baud_rate & - 256 | a ; else if ( dbg_log ( "data: " + h ( a ) , LOG_SERIAL ) , this . ThrowInterrupt ( UART_IIR_THRI ) , 255 !== a ) { var b = String . fromCharCode ( a ) ; this . bus . send ( "serial0-output-char" , b ) ; this . current_line . push ( a ) ; "\n" === b && ( dbg_log ( "SERIAL: " + String . fromCharCode . apply ( "" , this . current_line ) . trimRight ( ) ) , this . bus . send ( "serial0-output-line" , String . fromCharCode . apply ( "" , this . current_line ) ) , this . current_line = [ ] ) ; } } ; var HPET_ADDR = 4275044352 , HPET_PERIOD = 1E8 , HPET_FREQ_MS = 1E12 / HPET_PERIOD , HPET_SUPPORT_64 = 0 , HPET_COUNTER_CONFIG = 16 | HPET_SUPPORT_64 << 5 , HPET_COUNTER_CONFIG_MASK = 32816 , HPET_NUM_COUNTERS = 4 ; function HPET ( a ) { function b ( ) { return e ? ( Date . now ( ) - g ) * HPET_FREQ_MS + f | 0 : f ; } function c ( ) { return HPET_SUPPORT_64 ? e ? ( Date . now ( ) - g ) * ( HPET_FREQ_MS / 4294967296 ) + k | 0 : k : 0 ; } var d = this , e = ! 1 , g = Date . now ( ) , f = 0 , k = 0 , l = ! 1 , m = 0 , n = new Int32Array ( HPET_NUM_COUNTERS << 1 ) , p = new Int32Array ( HPET_NUM_COUNTERS << 1 ) , q = new Int32Array ( HPET_NUM_COUNTERS << 1 ) , r = 0 ; this . legacy_mode = ! 1 ; this . timer = function ( c ) { if ( e ) { c = b ( ) >>> 0 ; for ( var d , g , f = 0 ; f < HPET_NUM_COUNTERS ; f ++ ) if ( d = n [ f << 1 ] , g = p [ f << 1 ] >>> 0 , r <= c ? g > r && g <= c : g > r || g <= c ) g = d & 4 , d & 2 ? ( g = g && ! ( m & 1 << f ) , m |= 1 << f ) : m &= ~ ( 1 << f ) , d & 8 && ( p [ f << 1 ] += q [ f << 1 ] ) , g && a . device_raise_irq ( 0 ) ; r = c ; } } ; a . io . mmap_register ( HPET_ADDR , 16384 , function ( a ) { dbg_log ( "Read " + h ( a , 4 ) + " (ctr=" + h ( b ( ) >>> 0 ) + ")" , LOG_HPET ) ; switch ( a ) { case 0 : return HPET_NUM_COUNTERS - 1 << 8 | 98305 | HPET_SUPPORT_64 << 13 ; case 4 : return HPET_PERIOD ; case 16 : return d . legacy_mode << 1 | e ; case 240 : return b ( ) ; case 244 : return c ( ) ; } var g = a >> 2 & 7 , f = a - 256 >> 5 ; if ( 256 > a || f >= HPET_NUM_COUNTERS || 5 < g ) return dbg_log ( "Read reserved address: " + h ( a ) , LOG_HPET ) , 0 ; dbg_log ( "Read counter: addr=" + h ( a ) + " counter=" + h ( f , 2 ) + " reg=" + h ( g ) , LOG_HPET ) ; switch ( g ) { case 0 : return n [ f << 1 ] & ~ HPET_COUNTER_CONFIG_MASK | HPET_COUNTER_CONFIG ; case 1 : return n [ f << 1 | 1 ] ; case 2 : return p [ f << 1 ] ; case 3 : return p [ f << 1 | 1 ] ; case 4 : case 5 : return 0 ; } } , function ( a , r ) { dbg_log ( "Write " + h ( a , 4 ) + ": " + h ( r , 2 ) , LOG_HPET ) ; switch ( a ) { case 16 : dbg_log ( "conf: enabled=" + ( r & 1 ) + " legacy=" + ( r >> 1 & 1 ) , LOG_HPET ) ; ( e ^ r ) & 1 && ( r & 1 ? g = Date . now ( ) : ( f = b ( ) , k = c ( ) ) ) ; e = 1 === ( r & 1 ) ; d . legacy_mode = 2 === ( r & 2 ) ; return ; case 32 : m &= ~ r ; return ; case 240 : f = r ; return ; case 244 : k = r ; return ; } var v = a >> 2 & 7 , u = a - 256 >> 5 ; if ( 256 > a || u >= HPET_NUM_COUNTERS || 2 < v ) dbg_log ( "Write reserved address: " + h ( a ) + " data=" + h ( r ) , LOG_HPET ) ; else switch ( dbg_log ( "Write counter: addr=" + h ( a ) + " counter=" + h ( u , 2 ) + " reg=" + h ( v ) + " data=" + h ( r , 2 ) , LOG_HPET ) , v ) { case 0 : n [ u << 1 ] = r ; break ; case 2 : l ? ( q [ u << 1 ] = r , l = ! 1 , dbg_log ( "Accumulator acc=" + h ( r >>> 0 , 8 ) + " ctr=" + h ( u , 2 ) , LOG_HPET ) ) : ( p [ u << 1 ] = r , n [ u << 1 ] & 64 && ( l = ! 0 , n [ u << 1 ] &= - 65 ) ) ; break ; case 3 : p [ u << 1 | 1 ] = r ; } } ) ; } ; var PMTIMER_FREQ = 3579545 ; function ACPI ( a ) { this . cpu = a ; var b = a . io ; a . devices . pci . register_device ( { pci_id : 56 , pci_space : [ 134 , 128 , 19 , 113 , 7 , 0 , 128 , 2 , 8 , 0 , 128 , 6 , 0 , 0 , 128 , 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 , 9 , 1 , 0 , 0 ] , pci_bars : [ ] , name : "acpi" } ) ; this . status = 1 ; this . pm1_enable = this . pm1_status = 0 ; this . last_timer = this . get_timer ( v86 . microtick ( ) ) ; this . gpe = new Uint8Array ( 4 ) ; b . register_read ( 45056 , this , void 0 , function ( ) { dbg_log ( "ACPI pm1_status read" , LOG_ACPI ) ; return this . pm1_status ; } ) ; b . register_write ( 45056 , this , void 0 , function ( a ) { dbg_log ( "ACPI pm1_status write: " + h ( a , 4 ) , LOG_ACPI ) ; this . pm1_status &= ~ a ; } ) ; b . register_read ( 45058 , this , void 0 , function ( ) { dbg_log ( "ACPI pm1_enable read" , LOG_ACPI ) ; return this . pm1_enable ; } ) ; b . register_write ( 45058 , this , void 0 , function ( a ) { dbg_log ( "ACPI pm1_enable write: " + h ( a ) , LOG_ACPI ) ; this . pm1_enable = a ; } ) ; b . register_read ( 45060 , this , void 0 , function ( ) { dbg_log ( "ACPI status read" , LOG_ACPI ) ; return this . status ; } ) ; b . register_write ( 45060 , this , void 0 , function ( a ) { dbg_log ( "ACPI status write: " + h ( a ) , LOG_ACPI ) ; this . status = a ; } ) ; b . register_read ( 45064 , this , void 0 , void 0 , function ( ) { return this . get_timer ( v86 . microtick ( ) ) & 16777215 ; } ) ; b . register_read ( 45024 , this , function ( ) { dbg_log ( "Read gpe#0" , LOG_ACPI ) ; return this . gpe [ 0 ] ; } ) ; b . register_read ( 45025 , this , function ( ) { dbg_log ( "Read gpe#1" , LOG_ACPI ) ; return this . gpe [ 1 ] ; } ) ; b . register_read ( 45026 , this , function ( ) { dbg_log ( "Read gpe#2" , LOG_ACPI ) ; return this . gpe [ 2 ] ; } ) ; b . register_read ( 45027 , this , function ( ) { dbg_log ( "Read gpe#3" , LOG_ACPI ) ; return this . gpe [ 3 ] ; } ) ; b . register_write ( 45024 , this , function ( a ) { dbg_log ( "Write gpe#0: " + h ( a ) , LOG_ACPI ) ; this . gpe [ 0 ] = a ; } ) ; b . register_write ( 45025 , this , function ( a ) { dbg_log ( "Write gpe#1: " + h ( a ) , LOG_ACPI ) ; this . gpe [ 1 ] = a ; } ) ; b . register_write ( 45026 , this , function ( a ) { dbg_log ( "Write gpe#2: " + h ( a ) , LOG_ACPI ) ; this . gpe [ 2 ] = a ; } ) ; b . register_write ( 45027 , this , function ( a ) { dbg_log ( "Write gpe#3: " + h ( a ) , LOG_ACPI ) ; this . gpe [ 3 ] = a ; } ) ; } ACPI . prototype . timer = function ( a ) { a = this . get_timer ( a ) ; var b = 0 !== ( ( a ^ this . last_timer ) & 8388608 ) ; this . pm1_enable & 1 && b ? ( dbg_log ( "ACPI raise irq" , LOG_ACPI ) , this . pm1_status |= 1 , this . cpu . device_raise_irq ( 9 ) ) : this . cpu . device_lower_irq ( 9 ) ; this . last_timer = a ; } ; ACPI . prototype . get_timer = function ( a ) { return PMTIMER_FREQ / 1E3 * a | 0 ; } ; ACPI . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . status ; a [ 1 ] = this . pm1_status ; a [ 2 ] = this . pm1_enable ; return a ; } ; ACPI . prototype . set_state = function ( a ) { this . status = a [ 0 ] ; this . pm1_status = a [ 1 ] ; this . pm1_enable = a [ 2 ] ; } ; var APIC_LOG_VERBOSE = ! 1 , APIC_ADDRESS = 4276092928 , APIC_TIMER_MODE_MASK = 393216 , APIC_TIMER_MODE_ONE_SHOT = 0 , APIC_TIMER_MODE_PERIODIC = 131072 , APIC_TIMER_MODE_TSC = 262144 , DELIVERY_MODES = "Fixed (0);Lowest Prio (1);SMI (2);Reserved (3);NMI (4);INIT (5);Reserved (6);ExtINT (7)" . split ( ";" ) , DESTINATION_MODES = [ "physical" , "logical" ] ; function APIC ( a ) { var b = this ; this . cpu = a ; this . timer_divider = this . apic_id = 0 ; this . timer_divider_shift = 1 ; this . timer_current_count = this . timer_initial_count = 0 ; this . next_tick = v86 . microtick ( ) ; this . lvt_error = this . lvt_int1 = this . lvt_int0 = this . lvt_perf_counter = this . lvt_timer = IOAPIC_CONFIG_MASKED ; this . icr1 = this . icr0 = this . tpr = 0 ; this . irr = new Int32Array ( 8 ) ; this . isr = new Int32Array ( 8 ) ; this . tmr = new Int32Array ( 8 ) ; this . spurious_vector = 254 ; this . destination_format = - 1 ; this . read_error = this . error = this . local_destination = 0 ; a . io . mmap_register ( APIC_ADDRESS , 1048576 , function ( a ) { dbg_log ( "Unsupported read8 from apic: " + h ( a >>> 0 ) , LOG_APIC ) ; var c = a & 3 ; return b . read32 ( a & - 4 ) >> 8 * c & 255 ; } , function ( a , b ) { dbg_log ( "Unsupported write8 from apic: " + h ( a ) + " <- " + h ( b ) , LOG_APIC ) ; dbg_trace ( ) ; dbg_assert ( ! 1 ) ; } , function ( a ) { return b . read32 ( a ) ; } , function ( a , d ) { return b . write32 ( a , d ) ; } ) ; } APIC . prototype . read32 = function ( a ) { a = a - APIC_ADDRESS | 0 ; switch ( a ) { case 32 : return dbg_log ( "APIC read id" , LOG_APIC ) , this . apic_id ; case 48 : return dbg_log ( "APIC read version" , LOG_APIC ) , 327700 ; case 128 : return APIC_LOG_VERBOSE && dbg_log ( "APIC read tpr" , LOG_APIC ) , this . tpr ; case 208 : return dbg_log ( "Read local destination" , LOG_APIC ) , this . local_destination ; case 224 : return dbg_log ( "Read destination format" , LOG_APIC ) , this . destination_format ; case 240 : return this . spurious_vector ; case 256 : case 272 : case 288 : case 304 : case 320 : case 336 : case 352 : case 368 : return a = a - 256 >> 4 , dbg_log ( "Read isr " + a + ": " + h ( this . isr [ a ] >>> 0 , 8 ) , LOG_APIC ) , this . isr [ a ] ; case 384 : case 400 : case 416 : case 432 : case 448 : case 464 : case 480 : case 496 : return a = a - 384 >> 4 , dbg_log ( "Read tmr " + a + ": " + h ( this . tmr [ a ] >>> 0 , 8 ) , LOG_APIC ) , this . tmr [ a ] ; case 512 : case 528 : case 544 : case 560 : case 576 : case 592 : case 608 : case 624 : return a = a - 512 >> 4 , dbg_log ( "Read irr " + a + ": " + h ( this . irr [ a ] >>> 0 , 8 ) , LOG_APIC ) , this . irr [ a ] ; case 640 : return dbg_log ( "Read error: " + h ( this . read_error >>> 0 , 8 ) , LOG_APIC ) , this . read_error ; case 768 : return APIC_LOG_VERBOSE && dbg_log ( "APIC read icr0" , LOG_APIC ) , this . icr0 ; case 784 : return dbg_log ( "APIC read icr1" , LOG_APIC ) , this . icr1 ; case 800 : return dbg_log ( "read timer lvt" , LOG_APIC ) , this . lvt_timer ; case 832 : return dbg_log ( "read lvt perf counter" , LOG_APIC ) , this . lvt_perf_counter ; case 848 : return dbg_log ( "read lvt int0" , LOG_APIC ) , this . lvt_int0 ; case 864 : return dbg_log ( "read lvt int1" , LOG_APIC ) , this . lvt_int1 ; case 880 : return dbg_log ( "read lvt error" , LOG_APIC ) , this . lvt_error ; case 992 : return dbg_log ( "read timer divider" , LOG_APIC ) , this . timer_divider ; case 896 : return dbg_log ( "read timer initial count" , LOG_APIC ) , this . timer_initial_count ; case 912 : return dbg_log ( "read timer current count: " + h ( this . timer_current_count >>> 0 , 8 ) , LOG_APIC ) , this . timer_current_count ; default : return dbg_log ( "APIC read " + h ( a ) , LOG_APIC ) , dbg_assert ( ! 1 ) , 0 ; } } ; APIC . prototype . write32 = function ( a , b ) { a = a - APIC_ADDRESS | 0 ; switch ( a ) { case 48 : dbg_log ( "APIC write version: " + h ( b >>> 0 , 8 ) + ", ignored" , LOG_APIC ) ; break ; case 128 : APIC_LOG_VERBOSE && dbg_log ( "Set tpr: " + h ( b & 255 , 2 ) , LOG_APIC ) ; this . tpr = b & 255 ; this . check_vector ( ) ; break ; case 176 : a = this . highest_isr ( ) ; - 1 !== a ? ( APIC_LOG_VERBOSE && dbg_log ( "eoi: " + h ( b >>> 0 , 8 ) + " for vector " + h ( a ) , LOG_APIC ) , this . register_clear_bit ( this . isr , a ) , this . register_get_bit ( this . tmr , a ) && this . cpu . devices . ioapic . remote_eoi ( a ) , this . check_vector ( ) ) : dbg_log ( "Bad eoi: No isr set" , LOG_APIC ) ; break ; case 208 : dbg_log ( "Set local destination: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . local_destination = b & 4278190080 ; break ; case 224 : dbg_log ( "Set destination format: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . destination_format = b | 16777215 ; break ; case 240 : dbg_log ( "Set spurious vector: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . spurious_vector = b ; break ; case 640 : dbg_log ( "Write error: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . read_error = this . error ; this . error = 0 ; break ; case 768 : a = b & 255 ; var c = b >> 8 & 7 , d = b >> 11 & 1 , e = b >> 15 & 1 , g = b >> 18 & 3 , f = this . icr1 >>> 24 ; dbg_log ( "APIC write icr0: " + h ( b , 8 ) + " vector=" + h ( a , 2 ) + " destination_mode=" + DESTINATION_MODES [ d ] + " delivery_mode=" + DELIVERY_MODES [ c ] + " destination_shorthand=" + [ "no" , "self" , "all with self" , "all without self" ] [ g ] , LOG_APIC ) ; this . icr0 = b & - 4097 ; 0 === g ? this . route ( a , c , e , f , d ) : 1 === g ? this . deliver ( a , IOAPIC_DELIVERY_FIXED , e ) : 2 === g ? this . deliver ( a , c , e ) : 3 !== g && dbg_assert ( ! 1 ) ; break ; case 784 : dbg_log ( "APIC write icr1: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . icr1 = b ; break ; case 800 : dbg_log ( "timer lvt: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . lvt_timer = b ; break ; case 832 : dbg_log ( "lvt perf counter: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . lvt_perf_counter = b ; break ; case 848 : dbg_log ( "lvt int0: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . lvt_int0 = b ; break ; case 864 : dbg_log ( "lvt int1: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . lvt_int1 = b ; break ; case 880 : dbg_log ( "lvt error: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . lvt_error = b ; break ; case 992 : dbg_log ( "timer divider: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . timer_divider = b ; b = b & 3 | ( b & 8 ) >> 1 ; this . timer_divider_shift = 7 === b ? 0 : b + 1 ; break ; case 896 : dbg_log ( "timer initial: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; this . timer_initial_count = b >>> 0 ; this . timer_current_count = b >>> 0 ; this . next_tick = v86 . microtick ( ) ; this . timer_active = ! 0 ; break ; case 912 : dbg_log ( "timer current: " + h ( b >>> 0 , 8 ) , LOG_APIC ) ; dbg_assert ( ! 1 , "read-only register" ) ; break ; default : dbg_log ( "APIC write32 " + h ( a ) + " <- " + h ( b >>> 0 , 8 ) , LOG_APIC ) , dbg_assert ( ! 1 ) ; } } ; APIC . prototype . timer = function ( a ) { 0 !== this . timer_current_count && ( a = ( a - this . next_tick ) * TSC_RATE / ( 1 << this . timer_divider_shift ) >>> 0 , 0 !== a && ( this . next_tick += a / TSC_RATE * ( 1 << this . timer_divider_shift ) , this . timer_current_count -= a , 0 >= this . timer_current_count && ( a = this . lvt_timer & APIC_TIMER_MODE_MASK , a === APIC_TIMER_MODE_PERIODIC ? ( this . timer_current_count = this . timer_initial_count , 0 === ( this . lvt_timer & IOAPIC_CONFIG_MASKED ) && this . deliver ( this . lvt_timer & 255 , IOAPIC_DELIVERY_FIXED , ! 1 ) ) : a === APIC_TIMER_MODE_ONE_SHOT && ( this . timer_current_count = 0 , dbg_log ( "APIC timer one shot end" , LOG_APIC ) , 0 === ( this . lvt_timer & IOAPIC_CONFIG_MASKED ) && this . deliver ( this . lvt_timer & 255 , IOAPIC_DELIVERY_FIXED , ! 1 ) ) ) ) ) ; } ; APIC . prototype . route = function ( a , b , c , d , e ) { this . deliver ( a , b , c ) ; } ; APIC . prototype . deliver = function ( a , b , c ) { APIC_LOG_VERBOSE && dbg_log ( "Deliver " + h ( a , 2 ) + " mode=" + b + " level=" + c , LOG_APIC ) ; b !== IOAPIC_DELIVERY_INIT && b !== IOAPIC_DELIVERY_NMI && ( ( 16 > a || 255 === a ) && dbg_assert ( ! 1 , "TODO: Invalid vector" ) , this . register_get_bit ( this . irr , a ) ? dbg_log ( "Not delivered: irr already set, vector=" + h ( a , 2 ) , LOG_APIC ) : ( this . register_set_bit ( this . irr , a ) , c ? this . register_set_bit ( this . tmr , a ) : this . register_clear_bit ( this . tmr , a ) , this . check_vector ( ) ) ) ; } ; APIC . prototype . highest_irr = function ( ) { var a = this . register_get_highest_bit ( this . irr ) ; dbg_assert ( 255 !== a ) ; dbg_assert ( 16 <= a || - 1 === a ) ; return a ; } ; APIC . prototype . highest_isr = function ( ) { var a = this . register_get_highest_bit ( this . isr ) ; dbg_assert ( 255 !== a ) ; dbg_assert ( 16 <= a || - 1 === a ) ; return a ; } ; APIC . prototype . check_vector = function ( ) { var a = this . highest_irr ( ) ; if ( - 1 !== a ) { var b = this . highest_isr ( ) ; b >= a ? APIC_LOG_VERBOSE && dbg_log ( "Higher isr, isr=" + h ( b ) + " irr=" + h ( a ) , LOG_APIC ) : ( a & 240 ) <= ( this . tpr & 240 ) ? APIC_LOG_VERBOSE && dbg_log ( "Higher tpr, tpr=" + h ( this . tpr & 240 ) + " irr=" + h ( a ) , LOG_APIC ) : this . cpu . handle_irqs ( ) ; } } ; APIC . prototype . acknowledge_irq = function ( ) { var a = this . highest_irr ( ) ; if ( - 1 !== a ) { var b = this . highest_isr ( ) ; b >= a ? APIC_LOG_VERBOSE && dbg_log ( "Higher isr, isr=" + h ( b ) + " irr=" + h ( a ) , LOG_APIC ) : ( a & 240 ) <= ( this . tpr & 240 ) ? APIC_LOG_VERBOSE && dbg_log ( "Higher tpr, tpr=" + h ( this . tpr & 240 ) + " irr=" + h ( a ) , LOG_APIC ) : ( this . register_clear_bit ( this . irr , a ) , this . register_set_bit ( this . isr , a ) , APIC_LOG_VERBOSE && dbg_log ( "Calling vector " + h ( a ) , LOG_APIC ) , this . cpu . pic_call_irq ( a ) , this . check_vector ( ) ) ; } } ; APIC . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . apic_id ; a [ 1 ] = this . timer_divider ; a [ 2 ] = this . timer_divider_shift ; a [ 3 ] = this . timer_initial_count ; a [ 4 ] = this . timer_current_count ; a [ 5 ] = this . next_tick ; a [ 6 ] = this . lvt_timer ; a [ 7 ] = this . lvt_perf_counter ; a [ 8 ] = this . lvt_int0 ; a [ 9 ] = this . lvt_int1 ; a [ 10 ] = this . lvt_error ; a [ 11 ] = this . tpr ; a [ 12 ] = this . icr0 ; a [ 13 ] = this . icr1 ; a [ 14 ] = this . irr ; a [ 15 ] = this . isr ; a [ 16 ] = this . tmr ; a [ 17 ] = this . spurious_vector ; a [ 18 ] = this . destination_format ; a [ 19 ] = this . local_destination ; a [ 20 ] = this . error ; a [ 21 ] = this . read_error ; return a ; } ; APIC . prototype . set_state = function ( a ) { this . apic_id = a [ 0 ] ; this . timer_divider = a [ 1 ] ; this . timer_divider_shift = a [ 2 ] ; this . timer_initial_count = a [ 3 ] ; this . timer_current_count = a [ 4 ] ; this . next_tick = a [ 5 ] ; this . lvt_timer = a [ 6 ] ; this . lvt_perf_counter = a [ 7 ] ; this . lvt_int0 = a [ 8 ] ; this . lvt_int1 = a [ 9 ] ; this . lvt_error = a [ 10 ] ; this . tpr = a [ 11 ] ; this . icr0 = a [ 12 ] ; this . icr1 = a [ 13 ] ; this . irr = a [ 14 ] ; this . isr = a [ 15 ] ; this . tmr = a [ 16 ] ; this . spurious_vector = a [ 17 ] ; this . destination_format = a [ 18 ] ; this . local_destination = a [ 19 ] ; this . error = a [ 20 ] ; this . read_error = a [ 21 ] ; } ; APIC . prototype . register_get_bit = function ( a , b ) { dbg_assert ( 0 <= b && 256 > b ) ; return a [ b >> 5 ] >> ( b & 31 ) & 1 ; } ; APIC . prototype . register_set_bit = function ( a , b ) { dbg_assert ( 0 <= b && 256 > b ) ; a [ b >> 5 ] |= 1 << ( b & 31 ) ; } ; APIC . prototype . register_clear_bit = function ( a , b ) { dbg_assert ( 0 <= b && 256 > b ) ; a [ b >> 5 ] &= ~ ( 1 << ( b & 31 ) ) ; } ; APIC . prototype . register_get_highest_bit = function ( a ) { for ( var b = 7 ; 0 <= b ; b -- ) { var c = a [ b ] ; if ( c ) return v86util . int_log2 ( c >>> 0 ) | b << 5 ; } return - 1 ; } ; var IOAPIC_ADDRESS = 4273995776 , IOREGSEL = 0 , IOWIN = 16 , IOAPIC_IRQ_COUNT = 24 , IOAPIC_ID = 0 , IOAPIC_CONFIG_TRIGGER_MODE_LEVEL = 32768 , IOAPIC_CONFIG_MASKED = 65536 , IOAPIC_CONFIG_DELIVS = 4096 , IOAPIC_CONFIG_REMOTE_IRR = 16384 , IOAPIC_CONFIG_READONLY_MASK = IOAPIC_CONFIG_REMOTE_IRR | IOAPIC_CONFIG_DELIVS | 4294836224 , IOAPIC_DELIVERY_FIXED = 0 , IOAPIC_DELIVERY_LOWEST_PRIORITY = 1 , IOAPIC_DELIVERY_NMI = 4 , IOAPIC_DELIVERY_INIT = 5 ; function IOAPIC ( a ) { var b = this ; this . cpu = a ; this . ioredtbl_config = new Int32Array ( IOAPIC_IRQ_COUNT ) ; this . ioredtbl_destination = new Int32Array ( IOAPIC_IRQ_COUNT ) ; for ( var c = 0 ; c < this . ioredtbl_config . length ; c ++ ) this . ioredtbl_config [ c ] = IOAPIC_CONFIG_MASKED ; this . ioregsel = 0 ; this . ioapic_id = IOAPIC_ID ; this . irq_value = this . irr = 0 ; dbg_assert ( 32 <= MMAP_BLOCK_SIZE ) ; a . io . mmap_register ( IOAPIC_ADDRESS , MMAP_BLOCK_SIZE , function ( a ) { dbg_assert ( ! 1 , "unsupported read8 from ioapic: " + h ( a ) ) ; return 0 ; } , function ( a , b ) { dbg_assert ( ! 1 , "unsupported write8 from ioapic: " + h ( a ) ) ; } , function ( a ) { a = a - IOAPIC_ADDRESS | 0 ; if ( a === IOREGSEL ) return b . ioregsel ; if ( a === IOWIN ) return b . read ( b . ioregsel ) ; dbg_log ( "Unexpected IOAPIC register read: " + h ( a ) , LOG_APIC ) ; dbg_assert ( ! 1 ) ; return 0 ; } , function ( a , e ) { a = a - IOAPIC_ADDRESS | 0 ; a === IOREGSEL ? b . ioregsel = e : a === IOWIN ? b . write ( b . ioregsel , e ) : ( dbg_log ( "Unexpected IOAPIC register write: " + h ( a ) + " <- " + h ( e >>> 0 , 8 ) , LOG_APIC ) , dbg_assert ( ! 1 ) ) ; } ) ; } IOAPIC . prototype . remote_eoi = function ( a ) { for ( var b = 0 ; b < IOAPIC_IRQ_COUNT ; b ++ ) { var c = this . ioredtbl_config [ b ] ; ( c & 255 ) === a && c & IOAPIC_CONFIG_REMOTE_IRR && ( dbg_log ( "Clear remote IRR for irq=" + h ( b ) , LOG_APIC ) , this . ioredtbl_config [ b ] &= ~ IOAPIC_CONFIG_REMOTE_IRR , this . check_irq ( b ) ) ; } } ; IOAPIC . prototype . check_irq = function ( a ) { var b = 1 << a ; if ( 0 !== ( this . irr & b ) ) { var c = this . ioredtbl_config [ a ] ; if ( 0 === ( c & IOAPIC_CONFIG_MASKED ) ) { var d = c >> 8 & 7 , e = c >> 11 & 1 , g = c & 255 , f = this . ioredtbl_destination [ a ] >>> 24 , k = ( c & IOAPIC_CONFIG_TRIGGER_MODE_LEVEL ) === IOAPIC_CONFIG_TRIGGER_MODE_LEVEL ; if ( 0 === ( c & IOAPIC_CONFIG_TRIGGER_MODE_LEVEL ) ) this . irr &= ~ b ; else if ( this . ioredtbl_config [ a ] |= IOAPIC_CONFIG_REMOTE_IRR , c & IOAPIC_CONFIG_REMOTE_IRR ) { dbg_log ( "No route: level interrupt and remote IRR still set" , LOG_APIC ) ; return ; } d === IOAPIC_DELIVERY_FIXED || d === IOAPIC_DELIVERY_LOWEST_PRIORITY ? this . cpu . devices . apic . route ( g , d , k , f , e ) : dbg_assert ( ! 1 , "TODO" ) ; this . ioredtbl_config [ a ] &= ~ IOAPIC_CONFIG_DELIVS ; } } } ; IOAPIC . prototype . set_irq = function ( a ) { if ( a >= IOAPIC_IRQ_COUNT ) dbg_assert ( ! 1 , "Bad irq: " + a , LOG_APIC ) ; else { var b = 1 << a ; 0 === ( this . irq_value & b ) && ( APIC_LOG_VERBOSE && dbg_log ( "apic set irq " + a , LOG_APIC ) , this . irq_value |= b , ( this . ioredtbl_config [ a ] & ( IOAPIC_CONFIG_TRIGGER_MODE_LEVEL | IOAPIC_CONFIG_MASKED ) ) !== IOAPIC_CONFIG_MASKED && ( this . irr |= b , this . check_irq ( a ) ) ) ; } } ; IOAPIC . prototype . clear_irq = function ( a ) { if ( a >= IOAPIC_IRQ_COUNT ) dbg_assert ( ! 1 , "Bad irq: " + a , LOG_APIC ) ; else { var b = 1 << a ; ( this . irq_value & b ) === b && ( this . irq_value &= ~ b , this . ioredtbl_config [ a ] & IOAPIC_CONFIG_TRIGGER_MODE_LEVEL && ( this . irr &= ~ b ) ) ; } } ; IOAPIC . prototype . read = function ( a ) { if ( 0 === a ) return dbg_log ( "IOAPIC Read id" , LOG_APIC ) , this . ioapic_id << 24 ; if ( 1 === a ) return dbg_log ( "IOAPIC Read version" , LOG_APIC ) , 17 | IOAPIC_IRQ_COUNT - 1 << 16 ; if ( 2 === a ) return dbg_log ( "IOAPIC Read arbitration id" , LOG_APIC ) , this . ioapic_id << 24 ; if ( 16 <= a && a < 16 + 2 * IOAPIC_IRQ_COUNT ) { var b = a - 16 >> 1 ; a & 1 ? ( a = this . ioredtbl_destination [ b ] , dbg_log ( "IOAPIC Read destination irq=" + h ( b ) + " -> " + h ( a , 8 ) , LOG_APIC ) ) : ( a = this . ioredtbl_config [ b ] , dbg_log ( "IOAPIC Read config irq=" + h ( b ) + " -> " + h ( a , 8 ) , LOG_APIC ) ) ; return a ; } dbg_log ( "IOAPIC register read outside of range " + h ( a ) , LOG_APIC ) ; dbg_assert ( ! 1 ) ; return 0 ; } ; IOAPIC . prototype . write = function ( a , b ) { if ( 0 === a ) this . ioapic_id = b >>> 24 & 15 ; else if ( 1 === a || 2 === a ) dbg_log ( "Invalid write: " + a , LOG_APIC ) ; else if ( 16 <= a && a < 16 + 2 * IOAPIC_IRQ_COUNT ) { var c = a - 16 >> 1 ; if ( a & 1 ) this . ioredtbl_destination [ c ] = b & 4278190080 , dbg_log ( "Write destination " + h ( b >>> 0 , 8 ) + " irq=" + h ( c ) + " dest=" + h ( b >>> 24 , 2 ) , LOG_APIC ) ; else { this . ioredtbl_config [ c ] = b & ~ IOAPIC_CONFIG_READONLY_MASK | this . ioredtbl_config [ c ] & IOAPIC_CONFIG_READONLY_MASK ; a = b & 255 ; var d = b >> 8 & 7 , e = b >> 11 & 1 , g = b >> 15 & 1 , f = b >> 16 & 1 ; dbg_log ( "Write config " + h ( b >>> 0 , 8 ) + " irq=" + h ( c ) + " vector=" + h ( a , 2 ) + " deliverymode=" + DELIVERY_MODES [ d ] + " destmode=" + DESTINATION_MODES [ e ] + " is_level=" + g + " disabled=" + f , LOG_APIC ) ; this . check_irq ( c ) ; } } else dbg_log ( "IOAPIC register write outside of range " + h ( a ) + ": " + h ( b >>> 0 , 8 ) , LOG_APIC ) , dbg_assert ( ! 1 ) ; } ; IOAPIC . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . ioredtbl_config ; a [ 1 ] = this . ioredtbl_destination ; a [ 2 ] = this . ioregsel ; a [ 3 ] = this . ioapic_id ; a [ 4 ] = this . irr ; a [ 5 ] = this . irq_value ; return a ; } ; IOAPIC . prototype . set_state = function ( a ) { this . ioredtbl_config = a [ 0 ] ; this . ioredtbl_destination = a [ 1 ] ; this . ioregsel = a [ 2 ] ; this . ioapic_id = a [ 3 ] ; this . irr = a [ 4 ] ; this . irq_value = a [ 5 ] ; } ; var STATE_VERSION = 5 , STATE_MAGIC = - 2039052682 , STATE_INDEX_MAGIC = 0 , STATE_INDEX_VERSION = 1 , STATE_INDEX_TOTAL_LEN = 2 , STATE_INDEX_INFO_LEN = 3 , STATE_INFO_BLOCK_START = 16 ; function StateLoadError ( a ) { this . message = a ; } StateLoadError . prototype = Error ( ) ; function save_object ( a , b ) { if ( "object" !== typeof a || null === a || a instanceof Array ) return a ; dbg_assert ( a . constructor !== Object ) ; if ( a . BYTES_PER_ELEMENT ) { var c = new Uint8Array ( a . buffer , a . byteOffset , a . length * a . BYTES_PER_ELEMENT ) ; return { __state_type__ : a . constructor . name , buffer_id : b . push ( c ) - 1 } ; } DEBUG && ! a . get_state && console . log ( "Object without get_state: " , a ) ; a = a . get_state ( ) ; c = [ ] ; for ( var d = 0 ; d < a . length ; d ++ ) { var e = a [ d ] ; dbg_assert ( "function" !== typeof e ) ; c [ d ] = save_object ( e , b ) ; } return c ; } function restore_object ( a , b , c ) { if ( "object" !== typeof b || null === b ) return b ; if ( a instanceof Array ) return b ; var d = b . __state_type__ ; if ( void 0 === d ) { DEBUG && void 0 === a && ( console . log ( "Cannot restore (base doesn't exist)" , b ) , dbg_assert ( ! 1 ) ) ; DEBUG && ! a . get_state && console . log ( "No get_state:" , a ) ; var e = a . get_state ( ) ; dbg_assert ( e . length === b . length , "Cannot restore: Different number of properties" ) ; for ( d = 0 ; d < b . length ; d ++ ) b [ d ] = restore_object ( e [ d ] , b [ d ] , c ) ; a . set_state ( b ) ; return a ; } e = { Uint8Array : Uint8Array , Int8Array : Int8Array , Uint16Array : Uint16Array , Int16Array : Int16Array , Uint32Array : Uint32Array , Int32Array : Int32Array , Float32Array : Float32Array , Float64Array : Float64Array } [ d ] ; dbg_assert ( e , "Unkown type: " + d ) ; b = c . infos [ b . buffer_id ] ; dbg_assert ( a ) ; dbg_assert ( a . constructor === e ) ; if ( 1048576 <= b . length && e === Uint8Array ) return new Uint8Array ( c . full , b . offset , b . length ) ; a = c . full . slice ( b . offset , b . offset + b . length ) ; return new e ( a ) ; } CPU . prototype . save_state = function ( ) { for ( var a = [ ] , b = save_object ( this , a ) , c = [ ] , d = 0 , e = 0 ; e < a . length ; e ++ ) { var g = a [ e ] . byteLength ; c [ e ] = { offset : d , length : g } ; d += g ; d = d + 3 & - 4 ; } b = JSON . stringify ( { buffer_infos : c , state : b } ) ; e = STATE_INFO_BLOCK_START + 2 * b . length ; e = e + 3 & - 4 ; var f = e + d ; d = new ArrayBuffer ( f ) ; var k = new Int32Array ( d , 0 , STATE_INFO_BLOCK_START / 4 ) ; g = new Uint16Array ( d , STATE_INFO_BLOCK_START , b . length ) ; var l = new Uint8Array ( d , e ) ; k [ STATE_INDEX_MAGIC ] = STATE_MAGIC ; k [ STATE_INDEX_VERSION ] = STATE_VERSION ; k [ STATE_INDEX_TOTAL_LEN ] = f ; k [ STATE_INDEX_INFO_LEN ] = 2 * b . length ; for ( e = 0 ; e < b . length ; e ++ ) g [ e ] = b . charCodeAt ( e ) ; for ( e = 0 ; e < a . length ; e ++ ) b = a [ e ] , dbg_assert ( b . constructor === Uint8Array ) , l . set ( b , c [ e ] . offset ) ; return d ; } ; CPU . prototype . restore_state = function ( a ) { var b = a . byteLength ; if ( b < STATE_INFO_BLOCK_START ) throw new StateLoadError ( "Invalid length: " + b ) ; var c = new Int32Array ( a , 0 , 4 ) ; if ( c [ STATE_INDEX_MAGIC ] !== STATE_MAGIC ) throw new StateLoadError ( "Invalid header: " + h ( c [ STATE_INDEX_MAGIC ] >>> 0 ) ) ; if ( c [ STATE_INDEX_VERSION ] !== STATE_VERSION ) throw new StateLoadError ( "Version mismatch: dump=" + c [ STATE_INDEX_VERSION ] + " we=" + STATE_VERSION ) ; if ( c [ STATE_INDEX_TOTAL_LEN ] !== b ) throw new StateLoadError ( "Length doesn't match header: real=" + b + " header=" + c [ STATE_INDEX_TOTAL_LEN ] ) ; c = c [ STATE_INDEX_INFO_LEN ] ; if ( 0 > c || c + 12 >= b || c % 2 ) throw new StateLoadError ( "Invalid info block length: " + c ) ; var d = c / 2 , e = new Uint16Array ( a , STATE_INFO_BLOCK_START , d ) , g = "" ; for ( b = 0 ; b < d - 8 ; ) g += String . fromCharCode ( e [ b ++ ] , e [ b ++ ] , e [ b ++ ] , e [ b ++ ] , e [ b ++ ] , e [ b ++ ] , e [ b ++ ] , e [ b ++ ] ) ; for ( ; b < d ; ) g += String . fromCharCode ( e [ b ++ ] ) ; b = JSON . parse ( g ) ; d = b . state ; e = b . buffer_infos ; c = STATE_INFO_BLOCK_START + c ; c = c + 3 & - 4 ; for ( b = 0 ; b < e . length ; b ++ ) e [ b ] . offset += c ; restore_object ( this , d , { full : a , infos : e } ) ; } ; var E8390_CMD = 0 , EN0_CLDALO = 1 , EN0_STARTPG = 1 , EN0_CLDAHI = 2 , EN0_STOPPG = 2 , EN0_BOUNDARY = 3 , EN0_TSR = 4 , EN0_TPSR = 4 , EN0_NCR = 5 , EN0_TCNTLO = 5 , EN0_FIFO = 6 , EN0_TCNTHI = 6 , EN0_ISR = 7 , EN0_CRDALO = 8 , EN0_RSARLO = 8 , EN0_CRDAHI = 9 , EN0_RSARHI = 9 , EN0_RCNTLO = 10 , EN0_RCNTHI = 11 , EN0_RSR = 12 , EN0_RXCR = 12 , EN0_TXCR = 13 , EN0_COUNTER0 = 13 , EN0_DCFG = 14 , EN0_COUNTER1 = 14 , EN0_IMR = 15 , EN0_COUNTER2 = 15 , NE_DATAPORT = 16 , NE_RESET = 31 , ENISR_RX = 1 , ENISR_TX = 2 , ENISR_RX_ERR = 4 , ENISR_TX_ERR = 8 , ENISR_OVER = 16 , ENISR_COUNTERS = 32 , ENISR_RDC = 64 , ENISR_RESET = 128 , ENISR_ALL = 63 , ENRSR_RXOK = 1 , START_PAGE = 64 , START_RX_PAGE = 76 , STOP_PAGE = 128 ; function Ne2k ( a , b ) { this . cpu = a ; this . pci = a . devices . pci ; this . bus = b ; this . bus . register ( "net0-receive" , function ( a ) { this . receive ( a ) ; } , this ) ; this . port = 768 ; this . name = "ne2k" ; this . pci_space = [ 236 , 16 , 41 , 128 , 3 , 1 , 0 , 0 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 0 , this . port & 255 | 1 , this . port >> 8 , 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 , 244 , 26 , 0 , 17 , 0 , 0 , 184 , 254 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 ] ; this . pci_id = 40 ; this . pci_bars = [ { size : 32 } ] ; this . imr = this . isr = 0 ; this . cr = 1 ; this . tpsr = this . tcnt = this . rcnt = this . dcfg = 0 ; this . memory = new Uint8Array ( 32768 ) ; this . txcr = this . rxcr = 0 ; this . tsr = 1 ; b = [ 0 , 34 , 21 , 255 * Math . random ( ) | 0 , 255 * Math . random ( ) | 0 , 255 * Math . random ( ) | 0 ] ; for ( var c = 0 ; 6 > c ; c ++ ) this . memory [ c << 1 ] = this . memory [ c << 1 | 1 ] = b [ c ] ; this . memory [ 14 ] = this . memory [ 15 ] = 87 ; dbg_log ( "Mac: " + h ( b [ 0 ] , 2 ) + ":" + h ( b [ 1 ] , 2 ) + ":" + h ( b [ 2 ] , 2 ) + ":" + h ( b [ 3 ] , 2 ) + ":" + h ( b [ 4 ] , 2 ) + ":" + h ( b [ 5 ] , 2 ) , LOG_NET ) ; this . rsar = 0 ; this . pstart = START_PAGE ; this . pstop = STOP_PAGE ; this . boundary = this . curpg = START_RX_PAGE ; b = a . io ; b . register_read ( this . port | E8390_CMD , this , function ( ) { dbg_log ( "Read cmd" , LOG_NET ) ; return this . cr ; } ) ; b . register_write ( this . port | E8390_CMD , this , function ( a ) { this . cr = a & - 5 ; dbg_log ( "Write command: " + h ( a , 2 ) + " newpg=" + ( this . cr >> 6 ) + " txcr=" + h ( this . txcr , 2 ) , LOG_NET ) ; this . cr & 1 || ( a | 24 && 0 === this . rcnt && this . do_interrupt ( ENISR_RDC ) , a & 4 && ( a = this . tpsr << 8 , a = this . memory . subarray ( a , a + this . tcnt ) , this . bus . send ( "net0-send" , a ) , this . bus . send ( "eth-transmit-end" , [ a . length ] ) , this . do_interrupt ( ENISR_TX ) , dbg_log ( "Command: Transfer. length=" + h ( a . byteLength ) , LOG_NET ) ) ) ; } ) ; b . register_read ( this . port | EN0_COUNTER0 , this , function ( ) { dbg_log ( "Read counter0" , LOG_NET ) ; return 0 ; } ) ; b . register_read ( this . port | EN0_COUNTER1 , this , function ( ) { dbg_log ( "Read counter1" , LOG_NET ) ; return 0 ; } ) ; b . register_read ( this . port | EN0_COUNTER2 , this , function ( ) { dbg_log ( "Read counter2" , LOG_NET ) ; return 0 ; } ) ; b . register_read ( this . port | NE_RESET , this , function ( ) { 0 === this . get_page ( ) ? ( dbg_log ( "Read reset" , LOG_NET ) , this . do_interrupt ( ENISR_RESET ) ) : dbg_log ( "Read pg1/1f" , LOG_NET ) ; return 0 ; } ) ; b . register_write ( this . port | NE_RESET , this , function ( a ) { 0 === this . get_page ( ) ? dbg_log ( "Write reset: " + h ( a , 2 ) , LOG_NET ) : dbg_log ( "Write pg1/1f: " + h ( a ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_STARTPG , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "start page: " + h ( a , 2 ) , LOG_NET ) , this . pstart = a ) : dbg_log ( "pg1/1: " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_STOPPG , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "stop page: " + h ( a , 2 ) , LOG_NET ) , this . pstop = a ) : dbg_log ( "pg1/2: " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_read ( this . port | EN0_ISR , this , function ( ) { if ( 0 === this . get_page ( ) ) return dbg_log ( "Read isr: " + h ( this . isr , 2 ) , LOG_NET ) , this . isr ; dbg_log ( "Read curpg: " + h ( this . curpg , 2 ) , LOG_NET ) ; return this . curpg ; } ) ; b . register_write ( this . port | EN0_ISR , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write isr: " + h ( a , 2 ) , LOG_NET ) , this . isr &= ~ a , this . update_irq ( ) ) : ( dbg_log ( "Write curpg: " + h ( a , 2 ) , LOG_NET ) , this . curpg = a ) ; } ) ; b . register_write ( this . port | EN0_TXCR , this , function ( a ) { 0 === this . get_page ( ) ? ( this . txcr = a , dbg_log ( "Write tx config: " + h ( a , 2 ) , LOG_NET ) ) : dbg_log ( "Write pg1/0x0d " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_DCFG , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write data configuration: " + h ( a , 2 ) , LOG_NET ) , this . dcfg = a ) : dbg_log ( "Write pg1/0x0e " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_RCNTLO , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write remote byte count low: " + h ( a , 2 ) , LOG_NET ) , this . rcnt = this . rcnt & 65280 | a & 255 ) : dbg_log ( "Write pg1/0x0a " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_RCNTHI , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write remote byte count high: " + h ( a , 2 ) , LOG_NET ) , this . rcnt = this . rcnt & 255 | a << 8 & 65280 ) : dbg_log ( "Write pg1/0x0b " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_RSARLO , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write remote start address low: " + h ( a , 2 ) , LOG_NET ) , this . rsar = this . rsar & 65280 | a & 255 ) : dbg_log ( "Write pg1/0x08 " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_RSARHI , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write start addresse count high: " + h ( a , 2 ) , LOG_NET ) , this . rsar = this . rsar & 255 | a << 8 & 65280 ) : dbg_log ( "Write pg1/0x09 " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_IMR , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write interrupt mask register: " + h ( a , 2 ) + " isr=" + h ( this . isr , 2 ) , LOG_NET ) , this . imr = a , this . update_irq ( ) ) : dbg_log ( "Write pg1/0x0f " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_read ( this . port | EN0_BOUNDARY , this , function ( ) { if ( 0 === this . get_page ( ) ) return dbg_log ( "Read boundary: " + h ( this . boundary , 2 ) , LOG_NET ) , this . boundary ; dbg_log ( "Read pg1/0x03" , LOG_NET ) ; return 0 ; } ) ; b . register_write ( this . port | EN0_BOUNDARY , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write boundary: " + h ( a , 2 ) , LOG_NET ) , this . boundary = a ) : dbg_log ( "Write pg1/0x03 " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_read ( this . port | EN0_TSR , this , function ( ) { if ( 0 === this . get_page ( ) ) return this . tsr ; dbg_log ( "Read pg1/0x04" , LOG_NET ) ; return 0 ; } ) ; b . register_write ( this . port | EN0_TPSR , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write tpsr: " + h ( a , 2 ) , LOG_NET ) , this . tpsr = a ) : dbg_log ( "Write pg1/0x04 " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_TCNTLO , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write tcnt low: " + h ( a , 2 ) , LOG_NET ) , this . tcnt = this . tcnt & - 256 | a ) : dbg_log ( "Write pg1/0x05 " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_write ( this . port | EN0_TCNTHI , this , function ( a ) { 0 === this . get_page ( ) ? ( dbg_log ( "Write tcnt high: " + h ( a , 2 ) , LOG_NET ) , this . tcnt = this . tcnt & 255 | a << 8 ) : dbg_log ( "Write pg1/0x06 " + h ( a , 2 ) , LOG_NET ) ; } ) ; b . register_read ( this . port | EN0_RSR , this , function ( ) { if ( 0 === this . get_page ( ) ) return 9 ; dbg_log ( "Read pg1/0x0c" , LOG_NET ) ; return 0 ; } ) ; b . register_write ( this . port | EN0_RXCR , this , function ( a ) { dbg_log ( "RX configuration reg write: " + h ( a , 2 ) , LOG_NET ) ; this . rxcr = a ; } ) ; b . register_read ( this . port | NE_DATAPORT | 0 , this , this . data_port_read8 , this . data_port_read16 , this . data_port_read32 ) ; b . register_write ( this . port | NE_DATAPORT | 0 , this , this . data_port_write16 , this . data_port_write16 , this . data_port_write32 ) ; a . devices . pci . register_device ( this ) ; } Ne2k . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . isr ; a [ 1 ] = this . imr ; a [ 2 ] = this . cr ; a [ 3 ] = this . dcfg ; a [ 4 ] = this . rcnt ; a [ 5 ] = this . tcnt ; a [ 6 ] = this . tpsr ; a [ 7 ] = this . rsar ; a [ 8 ] = this . pstart ; a [ 9 ] = this . curpg ; a [ 10 ] = this . boundary ; return a ; } ; Ne2k . prototype . set_state = function ( a ) { this . isr = a [ 0 ] ; this . imr = a [ 1 ] ; this . cr = a [ 2 ] ; this . dcfg = a [ 3 ] ; this . rcnt = a [ 4 ] ; this . tcnt = a [ 5 ] ; this . tpsr = a [ 6 ] ; this . rsar = a [ 7 ] ; this . pstart = a [ 8 ] ; this . curpg = a [ 9 ] ; this . boundary = a [ 10 ] ; } ; Ne2k . prototype . do_interrupt = function ( a ) { dbg_log ( "Do interrupt " + h ( a , 2 ) , LOG_NET ) ; this . isr |= a ; this . update_irq ( ) ; } ; Ne2k . prototype . update_irq = function ( ) { this . imr & this . isr ? this . pci . raise_irq ( this . pci_id ) : this . pci . lower_irq ( this . pci_id ) ; } ; Ne2k . prototype . data_port_write = function ( a ) { dbg_log ( "Write data port: data=" + h ( a & 255 , 2 ) + " rsar=" + h ( this . rsar , 4 ) + " rcnt=" + h ( this . rcnt , 4 ) , LOG_NET ) ; 16 < this . rsar && this . rsar < START_PAGE << 8 || ( this . rcnt -- , this . memory [ this . rsar ++ ] = a , this . rsar >= this . pstop << 8 && ( this . rsar += this . pstart - this . pstop << 8 ) , 0 === this . rcnt && this . do_interrupt ( ENISR_RDC ) ) ; } ; Ne2k . prototype . data_port_write16 = function ( a ) { this . data_port_write ( a ) ; this . dcfg & 1 && this . data_port_write ( a >> 8 ) ; } ; Ne2k . prototype . data_port_write32 = function ( a ) { this . data_port_write ( a ) ; this . data_port_write ( a >> 8 ) ; this . data_port_write ( a >> 16 ) ; this . data_port_write ( a >> 24 ) ; } ; Ne2k . prototype . data_port_read = function ( ) { var a = this . memory [ this . rsar ++ ] ; dbg_log ( "Read data port: data=" + h ( a , 2 ) + " rsar=" + h ( this . rsar - 1 , 4 ) + " rcnt=" + h ( this . rcnt , 4 ) , LOG_NET ) ; this . rcnt -- ; this . rsar >= this . pstop << 8 && ( this . rsar += this . pstart - this . pstop << 8 ) ; 0 === this . rcnt && this . do_interrupt ( ENISR_RDC ) ; return a ; } ; Ne2k . prototype . data_port_read8 = function ( ) { return this . data_port_read16 ( ) & 255 ; } ; Ne2k . prototype . data_port_read16 = function ( ) { return this . dcfg & 1 ? this . data_port_read ( ) | this . data_port_read ( ) << 8 : this . data_port_read ( ) ; } ; Ne2k . prototype . data_port_read32 = function ( ) { return this . data_port_read ( ) | this . data_port_read ( ) << 8 | this . data_port_read ( ) << 16 | this . data_port_read ( ) << 24 ; } ; Ne2k . prototype . receive = function ( a ) { if ( ! ( this . cr & 1 ) && ( this . bus . send ( "eth-receive-end" , [ a . length ] ) , this . rxcr & 16 || this . rxcr & 4 && 255 === a [ 0 ] && 255 === a [ 1 ] && 255 === a [ 2 ] && 255 === a [ 3 ] && 255 === a [ 4 ] && 255 === a [ 5 ] || ! ( this . rxcr & 8 && 1 === ( a [ 0 ] & 1 ) || a [ 0 ] !== this . memory [ 0 ] || a [ 1 ] !== this . memory [ 2 ] || a [ 2 ] !== this . memory [ 4 ] || a [ 3 ] !== this . memory [ 6 ] || a [ 4 ] !== this . memory [ 8 ] || a [ 5 ] !== this . memory [ 10 ] ) ) ) { var b = this . curpg << 8 , c = Math . max ( 60 , a . length ) + 4 , d = b + 4 , e = this . curpg + 1 + ( c >> 8 ) ; if ( b + c > this . memory . length ) { dbg_assert ( 60 <= a . length ) ; var g = this . memory . length - d ; this . memory . set ( a . subarray ( 0 , g ) , d ) ; this . memory . set ( a . subarray ( g ) , START_RX_PAGE ) ; dbg_log ( "rcv cut=" + h ( g ) , LOG_NET ) ; } else if ( this . memory . set ( a , d ) , 60 > a . length ) for ( a = a . length ; 60 > a ; a ++ ) this . memory [ d + a ] = 0 ; e >= this . pstop && ( e += this . pstart - this . pstop ) ; this . memory [ b ] = ENRSR_RXOK ; this . memory [ b + 1 ] = e ; this . memory [ b + 2 ] = c ; this . memory [ b + 3 ] = c >> 8 ; this . curpg = e ; dbg_log ( "rcv offset=" + h ( b ) + " len=" + h ( c ) + " next=" + h ( e ) , LOG_NET ) ; this . do_interrupt ( ENISR_RX ) ; } } ; Ne2k . prototype . get_page = function ( ) { return this . cr & 192 ; } ; var DSP_COPYRIGHT = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992." , DSP_NO_COMMAND = 0 , DSP_BUFSIZE = 64 , DSP_DACSIZE = 65536 , SB_DMA_BUFSIZE = 65536 , SB_DMA_BLOCK_SAMPLES = 1024 , SB_DMA0 = 0 , SB_DMA1 = 1 , SB_DMA3 = 3 , SB_DMA5 = 5 , SB_DMA6 = 6 , SB_DMA7 = 7 , SB_DMA_CHANNEL_8BIT = SB_DMA1 , SB_DMA_CHANNEL_16BIT = SB_DMA5 , SB_IRQ2 = 2 , SB_IRQ5 = 5 , SB_IRQ7 = 7 , SB_IRQ10 = 10 , SB_IRQ = SB_IRQ5 , SB_IRQ_8BIT = 1 , SB_IRQ_16BIT = 2 , SB_IRQ_MIDI = 1 , SB_IRQ_MPU = 4 , DSP_COMMAND_SIZES = new Uint8Array ( 256 ) , DSP_COMMAND_HANDLERS = [ ] , MIXER_READ_HANDLERS = [ ] , MIXER_WRITE_HANDLERS = [ ] , FM_HANDLERS = [ ] ; function SB16 ( a , b ) { this . cpu = a ; this . bus = b ; this . write_buffer = new ByteQueue ( DSP_BUFSIZE ) ; this . read_buffer = new ByteQueue ( DSP_BUFSIZE ) ; this . read_buffer_lastvalue = 0 ; this . command = DSP_NO_COMMAND ; this . mixer_current_address = this . command_size = 0 ; this . mixer_registers = new Uint8Array ( 256 ) ; this . mixer_reset ( ) ; this . dummy_speaker_enabled = ! 1 ; this . test_register = 0 ; this . dsp_signed = this . dsp_16bit = this . dsp_stereo = this . dsp_highspeed = ! 1 ; this . dac_buffers = [ new FloatQueue ( DSP_DACSIZE ) , new FloatQueue ( DSP_DACSIZE ) ] ; this . dma = a . devices . dma ; this . dma_channel = this . dma_irq = this . dma_bytes_block = this . dma_bytes_left = this . dma_bytes_count = this . dma_sample_count = 0 ; this . dma_channel_8bit = SB_DMA_CHANNEL_8BIT ; this . dma_channel_16bit = SB_DMA_CHANNEL_16BIT ; this . dma_autoinit = ! 1 ; this . dma_buffer = new ArrayBuffer ( SB_DMA_BUFSIZE ) ; this . dma_buffer_int8 = new Int8Array ( this . dma_buffer ) ; this . dma_buffer_uint8 = new Uint8Array ( this . dma_buffer ) ; this . dma_buffer_int16 = new Int16Array ( this . dma_buffer ) ; this . dma_buffer_uint16 = new Uint16Array ( this . dma_buffer ) ; this . dma_syncbuffer = new SyncBuffer ( this . dma_buffer ) ; this . dma_paused = this . dma_waiting_transfer = ! 1 ; this . sampling_rate = 22050 ; b . send ( "dac-tell-sampling-rate" , this . sampling_rate ) ; this . bytes_per_sample = 1 ; this . e2_value = 170 ; this . e2_count = 0 ; this . asp_registers = new Uint8Array ( 256 ) ; this . mpu_read_buffer = new ByteQueue ( DSP_BUFSIZE ) ; this . fm_current_address1 = this . fm_current_address0 = this . mpu_read_buffer_lastvalue = 0 ; this . fm_waveform_select_enable = ! 1 ; this . irq = SB_IRQ ; this . irq_triggered = new Uint8Array ( 16 ) ; a . io . register_read_consecutive ( 544 , this , this . port2x0_read , this . port2x1_read , this . port2x2_read , this . port2x3_read ) ; a . io . register_read_consecutive ( 904 , this , this . port2x0_read , this . port2x1_read ) ; a . io . register_read_consecutive ( 548 , this , this . port2x4_read , this . port2x5_read ) ; a . io . register_read ( 550 , this , this . port2x6_read ) ; a . io . register_read ( 551 , this , this . port2x7_read ) ; a . io . register_read ( 552 , this , this . port2x8_read ) ; a . io . register_read ( 553 , this , this . port2x9_read ) ; a . io . register_read ( 554 , this , this . port2xA_read ) ; a . io . register_read ( 555 , this , this . port2xB_read ) ; a . io . register_read ( 556 , this , this . port2xC_read ) ; a . io . register_read ( 557 , this , this . port2xD_read ) ; a . io . register_read_consecutive ( 558 , this , this . port2xE_read , this . port2xF_read ) ; a . io . register_write_consecutive ( 544 , this , this . port2x0_write , this . port2x1_write , this . port2x2_write , this . port2x3_write ) ; a . io . register_write_consecutive ( 904 , this , this . port2x0_write , this . port2x1_write ) ; a . io . register_write_consecutive ( 548 , this , this . port2x4_write , this . port2x5_write ) ; a . io . register_write ( 550 , this , this . port2x6_write ) ; a . io . register_write ( 551 , this , this . port2x7_write ) ; a . io . register_write_consecutive ( 552 , this , this . port2x8_write , this . port2x9_write ) ; a . io . register_write ( 554 , this , this . port2xA_write ) ; a . io . register_write ( 555 , this , this . port2xB_write ) ; a . io . register_write ( 556 , this , this . port2xC_write ) ; a . io . register_write ( 557 , this , this . port2xD_write ) ; a . io . register_write ( 558 , this , this . port2xE_write ) ; a . io . register_write ( 559 , this , this . port2xF_write ) ; a . io . register_read_consecutive ( 816 , this , this . port3x0_read , this . port3x1_read ) ; a . io . register_write_consecutive ( 816 , this , this . port3x0_write , this . port3x1_write ) ; this . dma . on_unmask ( this . dma_on_unmask , this ) ; b . register ( "dac-request-data" , function ( ) { this . dac_handle_request ( ) ; } , this ) ; b . register ( "speaker-has-initialized" , function ( ) { this . mixer_reset ( ) ; } , this ) ; b . send ( "speaker-confirm-initialized" ) ; this . dsp_reset ( ) ; } SB16 . prototype . dsp_reset = function ( ) { this . write_buffer . clear ( ) ; this . read_buffer . clear ( ) ; this . command = DSP_NO_COMMAND ; this . command_size = 0 ; this . dummy_speaker_enabled = ! 1 ; this . test_register = 0 ; this . dsp_signed = this . dsp_16bit = this . dsp_stereo = this . dsp_highspeed = ! 1 ; this . dac_buffers [ 0 ] . clear ( ) ; this . dac_buffers [ 1 ] . clear ( ) ; this . dma_channel = this . dma_irq = this . dma_bytes_block = this . dma_bytes_left = this . dma_bytes_count = this . dma_sample_count = 0 ; this . dma_autoinit = ! 1 ; this . dma_buffer_uint8 . fill ( 0 ) ; this . dma_paused = this . dma_waiting_transfer = ! 1 ; this . e2_value = 170 ; this . e2_count = 0 ; this . sampling_rate = 22050 ; this . bytes_per_sample = 1 ; this . lower_irq ( SB_IRQ_8BIT ) ; this . irq_triggered . fill ( 0 ) ; this . asp_registers . fill ( 0 ) ; this . asp_registers [ 5 ] = 1 ; this . asp_registers [ 9 ] = 248 ; } ; SB16 . prototype . get_state = function ( ) { var a = [ ] ; a [ 2 ] = this . read_buffer_lastvalue ; a [ 3 ] = this . command ; a [ 4 ] = this . command_size ; a [ 5 ] = this . mixer_current_address ; a [ 6 ] = this . mixer_registers ; a [ 7 ] = this . dummy_speaker_enabled ; a [ 8 ] = this . test_register ; a [ 9 ] = this . dsp_highspeed ; a [ 10 ] = this . dsp_stereo ; a [ 11 ] = this . dsp_16bit ; a [ 12 ] = this . dsp_signed ; a [ 15 ] = this . dma_sample_count ; a [ 16 ] = this . dma_bytes_count ; a [ 17 ] = this . dma_bytes_left ; a [ 18 ] = this . dma_bytes_block ; a [ 19 ] = this . dma_irq ; a [ 20 ] = this . dma_channel ; a [ 21 ] = this . dma_channel_8bit ; a [ 22 ] = this . dma_channel_16bit ; a [ 23 ] = this . dma_autoinit ; a [ 24 ] = this . dma_buffer_uint8 ; a [ 25 ] = this . dma_waiting_transfer ; a [ 26 ] = this . dma_paused ; a [ 27 ] = this . sampling_rate ; a [ 28 ] = this . bytes_per_sample ; a [ 29 ] = this . e2_value ; a [ 30 ] = this . e2_count ; a [ 31 ] = this . asp_registers ; a [ 33 ] = this . mpu_read_buffer_last_value ; a [ 34 ] = this . irq ; a [ 35 ] = this . irq_triggered ; return a ; } ; SB16 . prototype . set_state = function ( a ) { this . read_buffer_lastvalue = a [ 2 ] ; this . command = a [ 3 ] ; this . command_size = a [ 4 ] ; this . mixer_current_address = a [ 5 ] ; this . mixer_registers = a [ 6 ] ; this . mixer_full_update ( ) ; this . dummy_speaker_enabled = a [ 7 ] ; this . test_register = a [ 8 ] ; this . dsp_highspeed = a [ 9 ] ; this . dsp_stereo = a [ 10 ] ; this . dsp_16bit = a [ 11 ] ; this . dsp_signed = a [ 12 ] ; this . dma_sample_count = a [ 15 ] ; this . dma_bytes_count = a [ 16 ] ; this . dma_bytes_left = a [ 17 ] ; this . dma_bytes_block = a [ 18 ] ; this . dma_irq = a [ 19 ] ; this . dma_channel = a [ 20 ] ; this . dma_channel_8bit = a [ 21 ] ; this . dma_channel_16bit = a [ 22 ] ; this . dma_autoinit = a [ 23 ] ; this . dma_buffer_uint8 = a [ 24 ] ; this . dma_waiting_transfer = a [ 25 ] ; this . dma_paused = a [ 26 ] ; this . sampling_rate = a [ 27 ] ; this . bytes_per_sample = a [ 28 ] ; this . e2_value = a [ 29 ] ; this . e2_count = a [ 30 ] ; this . asp_registers = a [ 31 ] ; this . mpu_read_buffer_last_value = a [ 33 ] ; this . irq = a [ 34 ] ; this . irq_triggered = a [ 35 ] ; this . dma_buffer = this . dma_buffer_uint8 . buffer ; this . dma_buffer_int8 = new Int8Array ( this . dma_buffer ) ; this . dma_buffer_int16 = new Int16Array ( this . dma_buffer ) ; this . dma_buffer_uint16 = new Uint16Array ( this . dma_buffer ) ; this . dma_syncbuffer = new SyncBuffer ( this . dma_buffer ) ; this . dma_paused ? this . bus . send ( "dac-disable" ) : this . bus . send ( "dac-enable" ) ; } ; SB16 . prototype . port2x0_read = function ( ) { dbg_log ( "220 read: fm music status port (unimplemented)" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2x1_read = function ( ) { dbg_log ( "221 read: fm music data port (write only)" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2x2_read = function ( ) { dbg_log ( "222 read: advanced fm music status port (unimplemented)" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2x3_read = function ( ) { dbg_log ( "223 read: advanced music data port (write only)" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2x4_read = function ( ) { dbg_log ( "224 read: mixer address port" , LOG_SB16 ) ; return this . mixer_current_address ; } ; SB16 . prototype . port2x5_read = function ( ) { dbg_log ( "225 read: mixer data port" , LOG_SB16 ) ; return this . mixer_read ( this . mixer_current_address ) ; } ; SB16 . prototype . port2x6_read = function ( ) { dbg_log ( "226 read: (write only)" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2x7_read = function ( ) { dbg_log ( "227 read: undocumented" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2x8_read = function ( ) { dbg_log ( "228 read: fm music status port (unimplemented)" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2x9_read = function ( ) { dbg_log ( "229 read: fm music data port (write only)" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2xA_read = function ( ) { dbg_log ( "22A read: read data" , LOG_SB16 ) ; this . read_buffer . length && ( this . read_buffer_lastvalue = this . read_buffer . shift ( ) ) ; dbg_log ( " <- " + this . read_buffer_lastvalue + " " + h ( this . read_buffer_lastvalue ) + " '" + String . fromCharCode ( this . read_buffer_lastvalue ) + "'" , LOG_SB16 ) ; return this . read_buffer_lastvalue ; } ; SB16 . prototype . port2xB_read = function ( ) { dbg_log ( "22B read: undocumented" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2xC_read = function ( ) { dbg_log ( "22C read: write-buffer status" , LOG_SB16 ) ; return 127 ; } ; SB16 . prototype . port2xD_read = function ( ) { dbg_log ( "22D read: undocumented" , LOG_SB16 ) ; return 255 ; } ; SB16 . prototype . port2xE_read = function ( ) { dbg_log ( "22E read: read-buffer status / irq 8bit ack." , LOG_SB16 ) ; this . irq_triggered [ SB_IRQ_8BIT ] && this . lower_irq ( SB_IRQ_8BIT ) ; return ( this . read_buffer . length && ! this . dsp_highspeed ) << 7 | 127 ; } ; SB16 . prototype . port2xF_read = function ( ) { dbg_log ( "22F read: irq 16bit ack" , LOG_SB16 ) ; this . lower_irq ( SB_IRQ_16BIT ) ; return 0 ; } ; SB16 . prototype . port2x0_write = function ( a ) { dbg_log ( "220 write: (unimplemented) fm register 0 address = " + h ( a ) , LOG_SB16 ) ; this . fm_current_address0 = 0 ; } ; SB16 . prototype . port2x1_write = function ( a ) { dbg_log ( "221 write: (unimplemented) fm register 0 data = " + h ( a ) , LOG_SB16 ) ; var b = FM_HANDLERS [ this . fm_current_address0 ] ; b || ( b = this . fm_default_write ) ; b . call ( this , a , 0 , this . fm_current_address0 ) ; } ; SB16 . prototype . port2x2_write = function ( a ) { dbg_log ( "222 write: (unimplemented) fm register 1 address = " + h ( a ) , LOG_SB16 ) ; this . fm_current_address1 = 0 ; } ; SB16 . prototype . port2x3_write = function ( a ) { dbg_log ( "223 write: (unimplemented) fm register 1 data =" + h ( a ) , LOG_SB16 ) ; var b = FM_HANDLERS [ this . fm_current_address1 ] ; b || ( b = this . fm_default_write ) ; b . call ( this , a , 1 , this . fm_current_address1 ) ; } ; SB16 . prototype . port2x4_write = function ( a ) { dbg_log ( "224 write: mixer address = " + h ( a ) , LOG_SB16 ) ; this . mixer_current_address = a ; } ; SB16 . prototype . port2x5_write = function ( a ) { dbg_log ( "225 write: mixer data = " + h ( a ) , LOG_SB16 ) ; this . mixer_write ( this . mixer_current_address , a ) ; } ; SB16 . prototype . port2x6_write = function ( a ) { dbg_log ( "226 write: reset = " + h ( a ) , LOG_SB16 ) ; this . dsp_highspeed ? ( dbg_log ( " -> exit highspeed" , LOG_SB16 ) , this . dsp_highspeed = ! 1 ) : a && ( dbg_log ( " -> reset" , LOG_SB16 ) , this . dsp_reset ( ) ) ; this . read_buffer . clear ( ) ; this . read_buffer . push ( 170 ) ; } ; SB16 . prototype . port2x7_write = function ( a ) { dbg_log ( "227 write: undocumented" , LOG_SB16 ) ; } ; SB16 . prototype . port2x8_write = function ( a ) { dbg_log ( "228 write: fm music register port (unimplemented)" , LOG_SB16 ) ; } ; SB16 . prototype . port2x9_write = function ( a ) { dbg_log ( "229 write: fm music data port (unimplemented)" , LOG_SB16 ) ; } ; SB16 . prototype . port2xA_write = function ( a ) { dbg_log ( "22A write: dsp read data port (read only)" , LOG_SB16 ) ; } ; SB16 . prototype . port2xB_write = function ( a ) { dbg_log ( "22B write: undocumented" , LOG_SB16 ) ; } ; SB16 . prototype . port2xC_write = function ( a ) { dbg_log ( "22C write: write command/data" , LOG_SB16 ) ; this . command === DSP_NO_COMMAND ? ( dbg_log ( "22C write: command = " + h ( a ) , LOG_SB16 ) , this . command = a , this . write_buffer . clear ( ) , this . command_size = DSP_COMMAND_SIZES [ a ] ) : ( dbg_log ( "22C write: data: " + h ( a ) , LOG_SB16 ) , this . write_buffer . push ( a ) ) ; this . write_buffer . length >= this . command_size && this . command_do ( ) ; } ; SB16 . prototype . port2xD_write = function ( a ) { dbg_log ( "22D write: undocumented" , LOG_SB16 ) ; } ; SB16 . prototype . port2xE_write = function ( a ) { dbg_log ( "22E write: dsp read buffer status (read only)" , LOG_SB16 ) ; } ; SB16 . prototype . port2xF_write = function ( a ) { dbg_log ( "22F write: undocumented" , LOG_SB16 ) ; } ; SB16 . prototype . port3x0_read = function ( ) { dbg_log ( "330 read: mpu data" , LOG_SB16 ) ; this . mpu_read_buffer . length && ( this . mpu_read_buffer_lastvalue = this . mpu_read_buffer . shift ( ) ) ; dbg_log ( " <- " + h ( this . mpu_read_buffer_lastvalue ) , LOG_SB16 ) ; return this . mpu_read_buffer_lastvalue ; } ; SB16 . prototype . port3x0_write = function ( a ) { dbg_log ( "330 write: mpu data (unimplemented) : " + h ( a ) , LOG_SB16 ) ; } ; SB16 . prototype . port3x1_read = function ( ) { dbg_log ( "331 read: mpu status" , LOG_SB16 ) ; return 0 | 128 * ! this . mpu_read_buffer . length ; } ; SB16 . prototype . port3x1_write = function ( a ) { dbg_log ( "331 write: mpu command: " + h ( a ) , LOG_SB16 ) ; 255 == a && ( this . mpu_read_buffer . clear ( ) , this . mpu_read_buffer . push ( 254 ) ) ; } ; SB16 . prototype . command_do = function ( ) { var a = DSP_COMMAND_HANDLERS [ this . command ] ; a || ( a = this . dsp_default_handler ) ; a . call ( this ) ; this . command = DSP_NO_COMMAND ; this . command_size = 0 ; this . write_buffer . clear ( ) ; } ; SB16 . prototype . dsp_default_handler = function ( ) { dbg_log ( "Unhandled command: " + h ( this . command ) , LOG_SB16 ) ; } ; function register_dsp_command ( a , b , c ) { c || ( c = SB16 . prototype . dsp_default_handler ) ; for ( var d = 0 ; d < a . length ; d ++ ) DSP_COMMAND_SIZES [ a [ d ] ] = b , DSP_COMMAND_HANDLERS [ a [ d ] ] = c ; } function any_first_digit ( a ) { for ( var b = [ ] , c = 0 ; 16 > c ; c ++ ) b . push ( a + c ) ; return b ; } register_dsp_command ( [ 14 ] , 2 , function ( ) { this . asp_registers [ this . write_buffer . shift ( ) ] = this . write_buffer . shift ( ) ; } ) ; register_dsp_command ( [ 15 ] , 1 , function ( ) { this . read_buffer . clear ( ) ; this . read_buffer . push ( this . asp_registers [ this . write_buffer . shift ( ) ] ) ; } ) ; register_dsp_command ( [ 16 ] , 1 , function ( ) { var a = audio_normalize ( this . write_buffer . shift ( ) , 127.5 , - 1 ) ; this . dac_buffers [ 0 ] . push ( a ) ; this . dac_buffers [ 1 ] . push ( a ) ; this . bus . send ( "dac-enable" ) ; } ) ; register_dsp_command ( [ 20 , 21 ] , 2 , function ( ) { this . dma_irq = SB_IRQ_8BIT ; this . dma_channel = this . dma_channel_8bit ; this . dsp_highspeed = this . dsp_16bit = this . dsp_signed = this . dma_autoinit = ! 1 ; this . dma_transfer_size_set ( ) ; this . dma_transfer_start ( ) ; } ) ; register_dsp_command ( [ 22 ] , 2 ) ; register_dsp_command ( [ 23 ] , 2 ) ; register_dsp_command ( [ 28 ] , 0 , function ( ) { this . dma_irq = SB_IRQ_8BIT ; this . dma_channel = this . dma_channel_8bit ; this . dma_autoinit = ! 0 ; this . dsp_highspeed = this . dsp_16bit = this . dsp_signed = ! 1 ; this . dma_transfer_start ( ) ; } ) ; register_dsp_command ( [ 31 ] , 0 ) ; register_dsp_command ( [ 32 ] , 0 , function ( ) { this . read_buffer . clear ( ) ; this . read_buffer . push ( 127 ) ; } ) ; register_dsp_command ( [ 36 ] , 2 ) ; register_dsp_command ( [ 44 ] , 0 ) ; register_dsp_command ( [ 48 ] , 0 ) ; register_dsp_command ( [ 49 ] , 0 ) ; register_dsp_command ( [ 52 ] , 0 ) ; register_dsp_command ( [ 53 ] , 0 ) ; register_dsp_command ( [ 54 ] , 0 ) ; register_dsp_command ( [ 55 ] , 0 ) ; register_dsp_command ( [ 56 ] , 0 ) ; register_dsp_command ( [ 64 ] , 1 , function ( ) { this . sampling_rate_change ( 1E6 / ( 256 - this . write_buffer . shift ( ) ) / this . get_channel_count ( ) ) ; } ) ; register_dsp_command ( [ 65 , 66 ] , 2 , function ( ) { this . sampling_rate_change ( this . write_buffer . shift ( ) << 8 | this . write_buffer . shift ( ) ) ; } ) ; register_dsp_command ( [ 72 ] , 2 , function ( ) { this . dma_transfer_size_set ( ) ; } ) ; register_dsp_command ( [ 116 ] , 2 ) ; register_dsp_command ( [ 117 ] , 2 ) ; register_dsp_command ( [ 118 ] , 2 ) ; register_dsp_command ( [ 119 ] , 2 ) ; register_dsp_command ( [ 125 ] , 0 ) ; register_dsp_command ( [ 127 ] , 0 ) ; register_dsp_command ( [ 128 ] , 2 ) ; register_dsp_command ( [ 144 ] , 0 , function ( ) { this . dma_irq = SB_IRQ_8BIT ; this . dma_channel = this . dma_channel_8bit ; this . dma_autoinit = ! 0 ; this . dsp_signed = ! 1 ; this . dsp_highspeed = ! 0 ; this . dsp_16bit = ! 1 ; this . dma_transfer_start ( ) ; } ) ; register_dsp_command ( [ 145 ] , 0 ) ; register_dsp_command ( [ 152 ] , 0 ) ; register_dsp_command ( [ 153 ] , 0 ) ; register_dsp_command ( [ 160 ] , 0 ) ; register_dsp_command ( [ 168 ] , 0 ) ; register_dsp_command ( any_first_digit ( 176 ) , 3 , function ( ) { if ( this . command & 8 ) this . dsp_default_handler ( ) ; else { var a = this . write_buffer . shift ( ) ; this . dma_irq = SB_IRQ_16BIT ; this . dma_channel = this . dma_channel_16bit ; this . dma_autoinit = ! ! ( this . command & 4 ) ; this . dsp_signed = ! ! ( a & 16 ) ; this . dsp_stereo = ! ! ( a & 32 ) ; this . dsp_16bit = ! 0 ; this . dma_transfer_size_set ( ) ; this . dma_transfer_start ( ) ; } } ) ; register_dsp_command ( any_first_digit ( 192 ) , 3 , function ( ) { if ( this . command & 8 ) this . dsp_default_handler ( ) ; else { var a = this . write_buffer . shift ( ) ; this . dma_irq = SB_IRQ_8BIT ; this . dma_channel = this . dma_channel_8bit ; this . dma_autoinit = ! ! ( this . command & 4 ) ; this . dsp_signed = ! ! ( a & 16 ) ; this . dsp_stereo = ! ! ( a & 32 ) ; this . dsp_16bit = ! 1 ; this . dma_transfer_size_set ( ) ; this . dma_transfer_start ( ) ; } } ) ; register_dsp_command ( [ 208 ] , 0 , function ( ) { this . dma_paused = ! 0 ; this . bus . send ( "dac-disable" ) ; } ) ; register_dsp_command ( [ 209 ] , 0 , function ( ) { this . dummy_speaker_enabled = ! 0 ; } ) ; register_dsp_command ( [ 211 ] , 0 , function ( ) { this . dummy_speaker_enabled = ! 1 ; } ) ; register_dsp_command ( [ 212 ] , 0 , function ( ) { this . dma_paused = ! 1 ; this . bus . send ( "dac-enable" ) ; } ) ; register_dsp_command ( [ 213 ] , 0 , function ( ) { this . dma_paused = ! 0 ; this . bus . send ( "dac-disable" ) ; } ) ; register_dsp_command ( [ 214 ] , 0 , function ( ) { this . dma_paused = ! 1 ; this . bus . send ( "dac-enable" ) ; } ) ; register_dsp_command ( [ 216 ] , 0 , function ( ) { this . read_buffer . clear ( ) ; this . read_buffer . push ( 255 * this . dummy_speaker_enabled ) ; } ) ; register_dsp_command ( [ 217 , 218 ] , 0 , function ( ) { this . dma_autoinit = ! 1 ; } ) ; register_dsp_command ( [ 224 ] , 1 , function ( ) { this . read_buffer . clear ( ) ; this . read_buffer . push ( ~ this . write_buffer . shift ( ) ) ; } ) ; register_dsp_command ( [ 225 ] , 0 , function ( ) { this . read_buffer . clear ( ) ; this . read_buffer . push ( 4 ) ; this . read_buffer . push ( 5 ) ; } ) ; register_dsp_command ( [ 226 ] , 1 ) ; register_dsp_command ( [ 227 ] , 0 , function ( ) { this . read_buffer . clear ( ) ; for ( var a = 0 ; a < DSP_COPYRIGHT . length ; a ++ ) this . read_buffer . push ( DSP_COPYRIGHT . charCodeAt ( a ) ) ; this . read_buffer . push ( 0 ) ; } ) ; register_dsp_command ( [ 228 ] , 1 , function ( ) { this . test_register = this . write_buffer . shift ( ) ; } ) ; register_dsp_command ( [ 232 ] , 0 , function ( ) { this . read_buffer . clear ( ) ; this . read_buffer . push ( this . test_register ) ; } ) ; register_dsp_command ( [ 242 , 243 ] , 0 , function ( ) { this . raise_irq ( ) ; } ) ; var SB_F9 = new Uint8Array ( 256 ) ; SB_F9 [ 14 ] = 255 ; SB_F9 [ 15 ] = 7 ; SB_F9 [ 55 ] = 56 ; register_dsp_command ( [ 249 ] , 1 , function ( ) { var a = this . write_buffer . shift ( ) ; dbg_log ( "dsp 0xf9: unknown function. input: " + a , LOG_SB16 ) ; this . read_buffer . clear ( ) ; this . read_buffer . push ( SB_F9 [ a ] ) ; } ) ; SB16 . prototype . mixer_read = function ( a ) { var b = MIXER_READ_HANDLERS [ a ] ; b ? b = b . call ( this ) : ( b = this . mixer_registers [ a ] , dbg_log ( "unhandled mixer register read. addr:" + h ( a ) + " data:" + h ( b ) , LOG_SB16 ) ) ; return b ; } ; SB16 . prototype . mixer_write = function ( a , b ) { var c = MIXER_WRITE_HANDLERS [ a ] ; c ? c . call ( this , b ) : dbg_log ( "unhandled mixer register write. addr:" + h ( a ) + " data:" + h ( b ) , LOG_SB16 ) ; } ; SB16 . prototype . mixer_default_read = function ( ) { dbg_log ( "mixer register read. addr:" + h ( this . mixer_current_address ) , LOG_SB16 ) ; return this . mixer_registers [ this . mixer_current_address ] ; } ; SB16 . prototype . mixer_default_write = function ( a ) { dbg_log ( "mixer register write. addr:" + h ( this . mixer_current_address ) + " data:" + h ( a ) , LOG_SB16 ) ; this . mixer_registers [ this . mixer_current_address ] = a ; } ; SB16 . prototype . mixer_reset = function ( ) { this . mixer_registers [ 4 ] = 204 ; this . mixer_registers [ 34 ] = 204 ; this . mixer_registers [ 38 ] = 204 ; this . mixer_registers [ 40 ] = 0 ; this . mixer_registers [ 46 ] = 0 ; this . mixer_registers [ 10 ] = 0 ; this . mixer_registers [ 48 ] = 192 ; this . mixer_registers [ 49 ] = 192 ; this . mixer_registers [ 50 ] = 192 ; this . mixer_registers [ 51 ] = 192 ; this . mixer_registers [ 52 ] = 192 ; this . mixer_registers [ 53 ] = 192 ; this . mixer_registers [ 54 ] = 0 ; this . mixer_registers [ 55 ] = 0 ; this . mixer_registers [ 56 ] = 0 ; this . mixer_registers [ 57 ] = 0 ; this . mixer_registers [ 59 ] = 0 ; this . mixer_registers [ 60 ] = 31 ; this . mixer_registers [ 61 ] = 21 ; this . mixer_registers [ 62 ] = 11 ; this . mixer_registers [ 63 ] = 0 ; this . mixer_registers [ 64 ] = 0 ; this . mixer_registers [ 65 ] = 0 ; this . mixer_registers [ 66 ] = 0 ; this . mixer_registers [ 67 ] = 0 ; this . mixer_registers [ 68 ] = 128 ; this . mixer_registers [ 69 ] = 128 ; this . mixer_registers [ 70 ] = 128 ; this . mixer_registers [ 71 ] = 128 ; this . mixer_full_update ( ) ; } ; SB16 . prototype . mixer_full_update = function ( ) { for ( var a = 1 ; a < this . mixer_registers . length ; a ++ ) this . mixer_write ( a , this . mixer_registers [ a ] ) ; } ; function register_mixer_read ( a , b ) { b || ( b = SB16 . prototype . mixer_default_read ) ; MIXER_READ_HANDLERS [ a ] = b ; } function register_mixer_write ( a , b ) { b || ( b = SB16 . prototype . mixer_default_write ) ; MIXER_WRITE_HANDLERS [ a ] = b ; } function register_mixer_legacy ( a , b , c ) { MIXER_READ_HANDLERS [ a ] = function ( ) { return this . mixer_registers [ b ] & 240 | this . mixer_registers [ c ] >>> 4 ; } ; MIXER_WRITE_HANDLERS [ a ] = function ( d ) { this . mixer_registers [ a ] = d ; var e = d << 4 & 240 | this . mixer_registers [ c ] & 15 ; this . mixer_write ( b , d & 240 | this . mixer_registers [ b ] & 15 ) ; this . mixer_write ( c , e ) ; } ; } function register_mixer_volume ( a , b , c ) { MIXER_READ_HANDLERS [ a ] = SB16 . prototype . mixer_default_read ; MIXER_WRITE_HANDLERS [ a ] = function ( d ) { this . mixer_registers [ a ] = d ; this . bus . send ( "mixer-volume" , [ b , c , ( d >>> 2 ) - 62 ] ) ; } ; } register_mixer_read ( 0 , function ( ) { this . mixer_reset ( ) ; return 0 ; } ) ; register_mixer_write ( 0 ) ; register_mixer_legacy ( 4 , 50 , 51 ) ; register_mixer_legacy ( 34 , 48 , 49 ) ; register_mixer_legacy ( 38 , 52 , 53 ) ; register_mixer_legacy ( 40 , 54 , 55 ) ; register_mixer_legacy ( 46 , 56 , 57 ) ; register_mixer_volume ( 48 , MIXER_SRC_MASTER , MIXER_CHANNEL_LEFT ) ; register_mixer_volume ( 49 , MIXER_SRC_MASTER , MIXER_CHANNEL_RIGHT ) ; register_mixer_volume ( 50 , MIXER_SRC_DAC , MIXER_CHANNEL_LEFT ) ; register_mixer_volume ( 51 , MIXER_SRC_DAC , MIXER_CHANNEL_RIGHT ) ; register_mixer_read ( 59 ) ; register_mixer_write ( 59 , function ( a ) { this . mixer_registers [ 59 ] = a ; this . bus . send ( "mixer-volume" , [ MIXER_SRC_PCSPEAKER , MIXER_CHANNEL_BOTH , 6 * ( a >>> 6 ) - 18 ] ) ; } ) ; register_mixer_read ( 65 ) ; register_mixer_write ( 65 , function ( a ) { this . mixer_registers [ 65 ] = a ; this . bus . send ( "mixer-gain-left" , 6 * ( a >>> 6 ) ) ; } ) ; register_mixer_read ( 66 ) ; register_mixer_write ( 66 , function ( a ) { this . mixer_registers [ 66 ] = a ; this . bus . send ( "mixer-gain-right" , 6 * ( a >>> 6 ) ) ; } ) ; register_mixer_read ( 68 ) ; register_mixer_write ( 68 , function ( a ) { this . mixer_registers [ 68 ] = a ; a >>>= 3 ; this . bus . send ( "mixer-treble-left" , a - ( 16 > a ? 14 : 16 ) ) ; } ) ; register_mixer_read ( 69 ) ; register_mixer_write ( 69 , function ( a ) { this . mixer_registers [ 69 ] = a ; a >>>= 3 ; this . bus . send ( "mixer-treble-right" , a - ( 16 > a ? 14 : 16 ) ) ; } ) ; register_mixer_read ( 70 ) ; register_mixer_write ( 70 , function ( a ) { this . mixer_registers [ 70 ] = a ; a >>>= 3 ; this . bus . send ( "mixer-bass-right" , a - ( 16 > a ? 14 : 16 ) ) ; } ) ; register_mixer_read ( 71 ) ; register_mixer_write ( 71 , function ( a ) { this . mixer_registers [ 71 ] = a ; a >>>= 3 ; this . bus . send ( "mixer-bass-right" , a - ( 16 > a ? 14 : 16 ) ) ; } ) ; register_mixer_read ( 128 , function ( ) { switch ( this . irq ) { case SB_IRQ2 : return 1 ; case SB_IRQ5 : return 2 ; case SB_IRQ7 : return 4 ; case SB_IRQ10 : return 8 ; default : return 0 ; } } ) ; register_mixer_write ( 128 , function ( a ) { a & 1 && ( this . irq = SB_IRQ2 ) ; a & 2 && ( this . irq = SB_IRQ5 ) ; a & 4 && ( this . irq = SB_IRQ7 ) ; a & 8 && ( this . irq = SB_IRQ10 ) ; } ) ; register_mixer_read ( 129 , function ( ) { var a = 0 ; switch ( this . dma_channel_8bit ) { case SB_DMA0 : a |= 1 ; break ; case SB_DMA1 : a |= 2 ; break ; case SB_DMA3 : a |= 8 ; } switch ( this . dma_channel_16bit ) { case SB_DMA5 : a |= 32 ; break ; case SB_DMA6 : a |= 64 ; break ; case SB_DMA7 : a |= 128 ; } return a ; } ) ; register_mixer_write ( 129 , function ( a ) { a & 1 && ( this . dma_channel_8bit = SB_DMA0 ) ; a & 2 && ( this . dma_channel_8bit = SB_DMA1 ) ; a & 8 && ( this . dma_channel_8bit = SB_DMA3 ) ; a & 32 && ( this . dma_channel_16bit = SB_DMA5 ) ; a & 64 && ( this . dma_channel_16bit = SB_DMA6 ) ; a & 128 && ( this . dma_channel_16bit = SB_DMA7 ) ; } ) ; register_mixer_read ( 130 , function ( ) { for ( var a = 32 , b = 0 ; 16 > b ; b ++ ) a |= b * this . irq_triggered [ b ] ; return a ; } ) ; SB16 . prototype . fm_default_write = function ( a , b , c ) { dbg_log ( "unhandled fm register write. addr:" + b + "|" + h ( c ) + " data:" + h ( a ) , LOG_SB16 ) ; } ; function register_fm_write ( a , b ) { b || ( b = SB16 . prototype . fm_default_write ) ; for ( var c = 0 ; c < a . length ; c ++ ) FM_HANDLERS [ a [ c ] ] = b ; } function between ( a , b ) { for ( var c = [ ] ; a <= b ; a ++ ) c . push ( a ) ; return c ; } var SB_FM_OPERATORS_BY_OFFSET = new Uint8Array ( 32 ) ; SB_FM_OPERATORS_BY_OFFSET [ 0 ] = 0 ; SB_FM_OPERATORS_BY_OFFSET [ 1 ] = 1 ; SB_FM_OPERATORS_BY_OFFSET [ 2 ] = 2 ; SB_FM_OPERATORS_BY_OFFSET [ 3 ] = 3 ; SB_FM_OPERATORS_BY_OFFSET [ 4 ] = 4 ; SB_FM_OPERATORS_BY_OFFSET [ 5 ] = 5 ; SB_FM_OPERATORS_BY_OFFSET [ 8 ] = 6 ; SB_FM_OPERATORS_BY_OFFSET [ 9 ] = 7 ; SB_FM_OPERATORS_BY_OFFSET [ 10 ] = 8 ; SB_FM_OPERATORS_BY_OFFSET [ 11 ] = 9 ; SB_FM_OPERATORS_BY_OFFSET [ 12 ] = 10 ; SB_FM_OPERATORS_BY_OFFSET [ 13 ] = 11 ; SB_FM_OPERATORS_BY_OFFSET [ 16 ] = 12 ; SB_FM_OPERATORS_BY_OFFSET [ 17 ] = 13 ; SB_FM_OPERATORS_BY_OFFSET [ 18 ] = 14 ; SB_FM_OPERATORS_BY_OFFSET [ 19 ] = 15 ; SB_FM_OPERATORS_BY_OFFSET [ 20 ] = 16 ; SB_FM_OPERATORS_BY_OFFSET [ 21 ] = 17 ; function get_fm_operator ( a , b ) { return 18 * a + SB_FM_OPERATORS_BY_OFFSET [ b ] ; } register_fm_write ( [ 1 ] , function ( a , b , c ) { this . fm_waveform_select_enable [ b ] = a & 1 ; this . fm_update_waveforms ( ) ; } ) ; register_fm_write ( [ 2 ] ) ; register_fm_write ( [ 3 ] ) ; register_fm_write ( [ 4 ] , function ( a , b , c ) { } ) ; register_fm_write ( [ 5 ] , function ( a , b , c ) { 0 === b && this . fm_default_write ( a , b , c ) ; } ) ; register_fm_write ( [ 8 ] , function ( a , b , c ) { } ) ; register_fm_write ( between ( 32 , 53 ) , function ( a , b , c ) { get_fm_operator ( b , c - 32 ) ; } ) ; register_fm_write ( between ( 64 , 85 ) , function ( a , b , c ) { get_fm_operator ( b , c - 64 ) ; } ) ; register_fm_write ( between ( 96 , 117 ) , function ( a , b , c ) { get_fm_operator ( b , c - 96 ) ; } ) ; register_fm_write ( between ( 128 , 149 ) , function ( a , b , c ) { get_fm_operator ( b , c - 128 ) ; } ) ; register_fm_write ( between ( 160 , 168 ) , function ( a , b , c ) { } ) ; register_fm_write ( between ( 176 , 184 ) , function ( a , b , c ) { } ) ; register_fm_write ( [ 189 ] , function ( a , b , c ) { } ) ; register_fm_write ( between ( 192 , 200 ) , function ( a , b , c ) { } ) ; register_fm_write ( between ( 224 , 245 ) , function ( a , b , c ) { get_fm_operator ( b , c - 224 ) ; } ) ; SB16 . prototype . fm_update_waveforms = function ( ) { } ; SB16 . prototype . sampling_rate_change = function ( a ) { this . sampling_rate = a ; this . bus . send ( "dac-tell-sampling-rate" , a ) ; } ; SB16 . prototype . get_channel_count = function ( ) { return this . dsp_stereo ? 2 : 1 ; } ; SB16 . prototype . dma_transfer_size_set = function ( ) { this . dma_sample_count = 1 + ( this . write_buffer . shift ( ) << 0 ) + ( this . write_buffer . shift ( ) << 8 ) ; } ; SB16 . prototype . dma_transfer_start = function ( ) { dbg_log ( "begin dma transfer" , LOG_SB16 ) ; this . bytes_per_sample = 1 ; this . dsp_16bit && ( this . bytes_per_sample *= 2 ) ; this . dma_bytes_count = this . dma_sample_count * this . bytes_per_sample ; this . dma_bytes_block = SB_DMA_BLOCK_SAMPLES * this . bytes_per_sample ; this . dma_bytes_block = Math . min ( Math . max ( this . dma_bytes_count >> 2 & - 4 , 32 ) , this . dma_bytes_block ) ; this . dma_waiting_transfer = ! 0 ; this . dma . channel_mask [ this . dma_channel ] || this . dma_on_unmask ( this . dma_channel ) ; } ; SB16 . prototype . dma_on_unmask = function ( a ) { a === this . dma_channel && this . dma_waiting_transfer && ( this . dma_waiting_transfer = ! 1 , this . dma_bytes_left = this . dma_bytes_count , this . dma_paused = ! 1 , this . bus . send ( "dac-enable" ) ) ; } ; SB16 . prototype . dma_transfer_next = function ( ) { var a = this ; dbg_log ( "dma transfering next block" , LOG_SB16 ) ; var b = Math . min ( this . dma_bytes_left , this . dma_bytes_block ) , c = Math . floor ( b / this . bytes_per_sample ) ; this . dma . do_write ( this . dma_syncbuffer , 0 , b , this . dma_channel , function ( d ) { dbg_log ( "dma block transfer " + ( d ? "unsuccessful" : "successful" ) , LOG_SB16 ) ; d || ( a . dma_to_dac ( c ) , a . dma_bytes_left -= b , a . dma_bytes_left || ( a . raise_irq ( a . dma_irq ) , a . dma_autoinit && ( a . dma_bytes_left = a . dma_bytes_count ) ) ) ; } ) ; } ; SB16 . prototype . dma_to_dac = function ( a ) { var b = this . dsp_16bit ? 32767.5 : 127.5 , c = this . dsp_signed ? 0 : - 1 , d = this . dsp_stereo ? 1 : 2 ; var e = this . dsp_16bit ? this . dsp_signed ? this . dma_buffer_int16 : this . dma_buffer_uint16 : this . dsp_signed ? this . dma_buffer_int8 : this . dma_buffer_uint8 ; for ( var g = 0 , f = 0 ; f < a ; f ++ ) for ( var k = audio_normalize ( e [ f ] , b , c ) , l = 0 ; l < d ; l ++ ) this . dac_buffers [ g ] . push ( k ) , g ^= 1 ; this . dac_send ( ) ; } ; SB16 . prototype . dac_handle_request = function ( ) { ! this . dma_bytes_left || this . dma_paused ? this . dac_send ( ) : this . dma_transfer_next ( ) ; } ; SB16 . prototype . dac_send = function ( ) { if ( this . dac_buffers [ 0 ] . length ) { var a = this . dac_buffers [ 0 ] . shift_block ( this . dac_buffers [ 0 ] . length ) , b = this . dac_buffers [ 1 ] . shift_block ( this . dac_buffers [ 1 ] . length ) ; this . bus . send ( "dac-send-data" , [ a , b ] , [ a . buffer , b . buffer ] ) ; } } ; SB16 . prototype . raise_irq = function ( a ) { dbg_log ( "raise irq" , LOG_SB16 ) ; this . irq_triggered [ a ] = 1 ; this . cpu . device_raise_irq ( this . irq ) ; } ; SB16 . prototype . lower_irq = function ( a ) { dbg_log ( "lower irq" , LOG_SB16 ) ; this . irq_triggered [ a ] = 0 ; this . cpu . device_lower_irq ( this . irq ) ; } ; function audio_normalize ( a , b , c ) { return audio_clip ( a / b + c , - 1 , 1 ) ; } function audio_clip ( a , b , c ) { return ( a < b ) * b + ( a > c ) * c + ( b <= a && a <= c ) * a ; } ; function VirtIO ( a , b , c ) { this . pci_space = [ 244 , 26 , 9 , 16 , 7 , 5 , 16 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 1 , 168 , 0 , 0 , 0 , 16 , 191 , 254 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 244 , 26 , 9 , 0 , 0 , 0 , 0 , 0 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 ] ; this . pci_id = 48 ; this . pci_bars = [ { size : 256 } ] ; this . name = "virtio" ; var d = a . io ; d . register_read ( 43008 , this , function ( ) { dbg_log ( "Read device features" , LOG_VIRTIO ) ; return 1 ; } , void 0 , function ( ) { dbg_log ( "Read device features" , LOG_VIRTIO ) ; return 1 ; } ) ; d . register_write ( 43012 , this , void 0 , void 0 , function ( a ) { dbg_log ( "Guest feature selection: " + h ( a , 8 ) , LOG_VIRTIO ) ; } ) ; d . register_write ( 43022 , this , void 0 , function ( a ) { dbg_log ( "Queue select: " + h ( a , 4 ) , LOG_VIRTIO ) ; this . queue_select = a ; } , void 0 ) ; d . register_read ( 43020 , this , void 0 , function ( ) { dbg_log ( "Read queue size" , LOG_VIRTIO ) ; return this . queue_size ; } , void 0 ) ; d . register_read ( 43016 , this , void 0 , void 0 , function ( ) { dbg_log ( "Read queue address" , LOG_VIRTIO ) ; return 0 === this . queue_select ? this . queue_address : 0 ; } ) ; d . register_write ( 43016 , this , void 0 , void 0 , function ( a ) { dbg_log ( "Write queue address: " + h ( a , 8 ) , LOG_VIRTIO ) ; this . queue_address = a ; } ) ; d . register_write ( 43026 , this , function ( a ) { dbg_log ( "Write device status: " + h ( a , 2 ) , LOG_VIRTIO ) ; 0 === a ? ( dbg_log ( "Reset" , LOG_VIRTIO ) , this . reset ( ) ) : a & 128 ? dbg_log ( "Warning: Device status failed" , LOG_VIRTIO ) : dbg_log ( ( a & 1 ? "ACKNOWLEDGE " : "" ) + ( a & 2 ? "DRIVER " : "" ) + ( a & 4 ? "DRIVER_OK" : "" ) , LOG_VIRTIO ) ; this . device_status = a ; } ) ; d . register_read ( 43026 , this , function ( ) { dbg_log ( "Read device status: " + h ( this . device_status ) , LOG_VIRTIO ) ; return this . device_status ; } ) ; d . register_read ( 43027 , this , function ( ) { dbg_log ( "Read isr" , LOG_VIRTIO ) ; var a = this . isr ; this . isr = 0 ; this . pci . lower_irq ( this . pci_id ) ; return a ; } ) ; d . register_write ( 43024 , this , void 0 , function ( a ) { dbg_log ( "Write queue notify: " + h ( a , 4 ) , LOG_VIRTIO ) ; dbg_assert ( 0 === a ) ; var b = ( this . queue_address << 12 ) + 16 * this . queue_size ; a = b + 4 ; b = this . cpu . read16 ( b + 2 ) ; dbg_log ( "idx=" + h ( b , 4 ) , LOG_VIRTIO ) ; var e = this . queue_size - 1 ; for ( b &= e ; this . last_idx !== b ; ) { var c = this . cpu . read16 ( a + 2 * this . last_idx ) ; this . handle_descriptor ( c ) ; this . last_idx = this . last_idx + 1 & e ; } } ) ; this . cpu = a ; this . pci = a . devices . pci ; this . bus = b ; this . last_idx = this . isr = this . device_status = this . queue_select = 0 ; this . queue_size = 32 ; for ( var e = this . queue_address = 0 ; 128 > e ; e ++ ) d . register_read ( 43028 + e , this , function ( a ) { dbg_log ( "Read device " + h ( a ) , LOG_VIRTIO ) ; return a < this . device . configspace . length ? this . device . configspace [ a ] : 0 ; } . bind ( this , e ) , void 0 , void 0 ) , d . register_write ( 43028 + e , this , function ( a , b ) { dbg_log ( "Write device " + h ( a ) + ": " + h ( b , 2 ) , LOG_VIRTIO ) ; } . bind ( this , e ) , void 0 , void 0 ) ; this . device = new Virtio9p ( c , b ) ; this . device . SendReply = this . device_reply . bind ( this ) ; a . devices . pci . register_device ( this ) ; } VirtIO . prototype . get_state = function ( ) { var a = [ 0 ] ; a [ 1 ] = this . queue_select ; a [ 2 ] = this . device_status ; a [ 3 ] = this . isr ; a [ 4 ] = this . last_idx ; a [ 5 ] = this . queue_size ; a [ 6 ] = this . queue_address ; a [ 7 ] = this . device ; return a ; } ; VirtIO . prototype . set_state = function ( a ) { this . queue_select = a [ 1 ] ; this . device_status = a [ 2 ] ; this . isr = a [ 3 ] ; this . last_idx = a [ 4 ] ; this . queue_size = a [ 5 ] ; this . queue_address = a [ 6 ] ; this . device = a [ 7 ] ; this . device . SendReply = this . device_reply . bind ( this ) ; } ; VirtIO . prototype . reset = function ( ) { this . last_idx = this . isr = this . device_status = this . queue_select = 0 ; this . queue_size = 32 ; this . queue_address = 0 ; } ; VirtIO . prototype . handle_descriptor = function ( a ) { var b = a , c = this . queue_address << 12 , d = 0 , e = [ ] ; do { var g = c + 16 * b , f = this . cpu . read16 ( g + 12 ) ; if ( f & VRING_DESC_F_WRITE ) break ; f & VRING_DESC_F_INDIRECT && dbg_assert ( ! 1 , "unsupported" ) ; var k = this . cpu . read32s ( g ) , l = this . cpu . read32s ( g + 4 ) , m = this . cpu . read32s ( g + 8 ) >>> 0 ; e . push ( { addr_low : k , addr_high : l , len : m } ) ; dbg_log ( "descriptor: addr=" + h ( l , 8 ) + ":" + h ( k , 8 ) + " len=" + h ( m , 8 ) + " flags=" + h ( f , 4 ) + " next=" + h ( b , 4 ) , LOG_VIRTIO ) ; if ( f & VRING_DESC_F_NEXT ) b = this . cpu . read16 ( g + 14 ) , dbg_assert ( b < this . queue_size ) ; else { b = - 1 ; break ; } } while ( 1 ) ; var n = - 1 , p = 0 ; this . device . ReceiveRequest ( { start : a , next : b } , function ( ) { if ( p >= n ) { if ( d === e . length ) return dbg_log ( "Read more data than descriptor has" , LOG_VIRTIO ) , 0 ; var a = e [ d ++ ] ; k = a . addr_low ; n = a . len ; p = 0 ; } return this . cpu . read8 ( k + p ++ ) ; } . bind ( this ) ) ; } ; VirtIO . prototype . device_reply = function ( a , b ) { if ( - 1 === b . next ) dbg_log ( "Reply to invalid index" , LOG_VIRTIO ) ; else { var c = this . queue_size - 1 ; a = this . device . replybuffersize ; var d = b . next , e = this . queue_address << 12 , g = 0 , f = [ ] ; do { var k = e + 16 * d , l = this . cpu . read16 ( k + 12 ) ; if ( 0 === ( l & VRING_DESC_F_WRITE ) ) { dbg_log ( "Bug: Readonly ring after writeonly ring" , LOG_VIRTIO ) ; break ; } var m = this . cpu . read32s ( k ) , n = this . cpu . read32s ( k + 4 ) , p = this . cpu . read32s ( k + 8 ) >>> 0 ; f . push ( { addr_low : m , addr_high : n , len : p } ) ; dbg_log ( "descriptor: addr=" + h ( n , 8 ) + ":" + h ( m , 8 ) + " len=" + h ( p , 8 ) + " flags=" + h ( l , 4 ) + " next=" + h ( d , 4 ) , LOG_VIRTIO ) ; if ( l & VRING_DESC_F_NEXT ) d = this . cpu . read16 ( k + 14 ) , dbg_assert ( d < this . queue_size ) ; else break ; } while ( 1 ) ; e = - 1 ; for ( l = k = 0 ; l < a ; l ++ ) { d = this . device . replybuffer [ l ] ; if ( k >= e ) { if ( g === f . length ) return dbg_log ( "Write more data than descriptor has" , LOG_VIRTIO ) , 0 ; e = f [ g ++ ] ; m = e . addr_low ; e = e . len ; k = 0 ; } this . cpu . write8 ( m + k ++ , d ) ; } m = ( this . queue_address << 12 ) + 16 * this . queue_size + 4 + 2 * this . queue_size ; m = m + 4095 & - 4096 ; l = this . cpu . read16 ( m ) ; g = this . cpu . read16 ( m + 2 ) ; this . cpu . write16 ( m + 2 , g + 1 ) ; dbg_log ( "used descriptor: addr=" + h ( m , 8 ) + " flags=" + h ( l , 4 ) + " idx=" + h ( g , 4 ) , LOG_VIRTIO ) ; c = m + 4 + 8 * ( g & c ) ; this . cpu . write32 ( c , b . start ) ; this . cpu . write32 ( c + 4 , a ) ; this . isr |= 1 ; this . pci . raise_irq ( this . pci_id ) ; } } ; var Bus = { } ; function BusConnector ( ) { this . listeners = { } ; this . pair = void 0 ; } BusConnector . prototype . register = function ( a , b , c ) { var d = this . listeners [ a ] ; void 0 === d && ( d = this . listeners [ a ] = [ ] ) ; d . push ( { fn : b , this_value : c } ) ; } ; BusConnector . prototype . unregister = function ( a , b ) { var c = this . listeners [ a ] ; void 0 !== c && ( this . listeners [ a ] = c . filter ( function ( a ) { return a . fn !== b ; } ) ) ; } ; BusConnector . prototype . send = function ( a , b , c ) { if ( this . pair && ( a = this . pair . listeners [ a ] , void 0 !== a ) ) for ( c = 0 ; c < a . length ; c ++ ) { var d = a [ c ] ; d . fn . call ( d . this_value , b ) ; } } ; BusConnector . prototype . send_async = function ( a , b ) { dbg_assert ( 1 === arguments . length || 2 === arguments . length ) ; setTimeout ( this . send . bind ( this , a , b ) , 0 ) ; } ; Bus . create = function ( ) { var a = new BusConnector , b = new BusConnector ; a . pair = b ; b . pair = a ; return [ a , b ] ; } ; var log_data = [ ] ; function do_the_log ( a ) { LOG_TO_FILE ? log_data . push ( a , "\n" ) : console . log ( a ) ; } var dbg_log = function ( ) { if ( ! DEBUG ) return function ( ) { } ; var a = LOG_NAMES . reduce ( function ( a , b ) { a [ b [ 0 ] ] = b [ 1 ] ; return a ; } , { } ) , b = "" , c = 0 ; return function ( d , e ) { if ( DEBUG && ( e = e || 1 , e & LOG_LEVEL ) ) { d = "[" + v86util . pads ( a [ e ] || "" , 4 ) + "] " + d ; if ( d === b && ( c ++ , 2048 > c ) ) return ; e = new Date ; e = v86util . pad0 ( e . getHours ( ) , 2 ) + ":" + v86util . pad0 ( e . getMinutes ( ) , 2 ) + ":" + v86util . pad0 ( e . getSeconds ( ) , 2 ) + "+" + v86util . pad0 ( e . getMilliseconds ( ) , 3 ) + " " ; c && ( 1 === c ? do_the_log ( e + b ) : do_the_log ( "Previous message repeated " + c + " times" ) , c = 0 ) ; do_the_log ( e + d ) ; b = d ; } } ; } ( ) ; function dbg_trace ( a ) { DEBUG && dbg_log ( Error ( ) . stack . replace ( /(?:(?:t|t16|t32)\.\(anonymous function\)\.)+/g , "t.(anonymous function)." ) , a ) ; } function dbg_assert ( a , b , c ) { DEBUG && ( a || dbg_assert_failed ( b ) ) ; } function dbg_assert_failed ( a ) { debugger ; console . trace ( ) ; if ( a ) throw "Assert failed: " + a ; throw "Assert failed" ; } ; var instruction_count , instruction_total , CPU_LOG_VERBOSE = ! 1 ; function CPU ( a ) { this . memory_size = 0 ; this . a20_enabled = ! 0 ; this . mem_page_infos = void 0 ; this . mem8 = new Uint8Array ( 0 ) ; this . mem16 = new Uint16Array ( this . mem8 . buffer ) ; this . mem32s = new Int32Array ( this . mem8 . buffer ) ; this . segment_is_null = new Uint8Array ( 8 ) ; this . segment_limits = new Uint32Array ( 8 ) ; this . segment_offsets = new Int32Array ( 8 ) ; this . tlb_data = new Int32Array ( 1048576 ) ; this . tlb_info = new Uint8Array ( 1048576 ) ; this . tlb_info_global = new Uint8Array ( 1048576 ) ; this . protected_mode = ! 1 ; this . gdtr_offset = this . gdtr_size = this . idtr_offset = this . idtr_size = 0 ; this . page_fault = this . tss_size_32 = ! 1 ; this . cr = new Int32Array ( 8 ) ; this . cr [ 0 ] = 0 ; this . cr [ 2 ] = 0 ; this . cr [ 3 ] = 0 ; this . page_size_extensions = this . cpl = this . cr [ 4 ] = 0 ; this . in_hlt = this . stack_size_32 = this . is_32 = ! 1 ; this . last_result = this . last_add_result = this . last_op_size = this . last_op2 = this . last_op1 = this . flags_changed = this . flags = this . prefixes = this . sysenter_eip = this . sysenter_esp = this . sysenter_cs = this . esp_phys = this . last_virt_esp = this . eip_phys = this . last_virt_eip = 0 ; this . mul32_result = new Int32Array ( 2 ) ; this . div32_result = new Float64Array ( 2 ) ; this . phys_addr_high = this . phys_addr = this . modrm_byte = this . tsc_offset = 0 ; this . devices = { } ; this . table = [ ] ; this . paging = ! 1 ; this . previous_ip = this . instruction_pointer = 0 ; this . apic_enabled = ! 0 ; this . timestamp_counter = 0 ; this . reg32s = new Int32Array ( 8 ) ; this . reg32 = new Uint32Array ( this . reg32s . buffer ) ; this . reg16s = new Int16Array ( this . reg32s . buffer ) ; this . reg16 = new Uint16Array ( this . reg32s . buffer ) ; this . reg8s = new Int8Array ( this . reg32s . buffer ) ; this . reg8 = new Uint8Array ( this . reg32s . buffer ) ; this . reg_mmxs = new Int32Array ( 16 ) ; this . reg_mmx = new Uint32Array ( this . reg_mmxs . buffer ) ; this . reg_mmx8s = new Int8Array ( this . reg_mmxs . buffer ) ; this . reg_mmx8 = new Uint8Array ( this . reg_mmxs . buffer ) ; this . reg_xmm32s = new Int32Array ( 32 ) ; this . mxcsr = 8064 ; this . sreg = new Uint16Array ( 8 ) ; this . dreg = new Int32Array ( 8 ) ; this . memory_map_read8 = [ ] ; this . memory_map_write8 = [ ] ; this . memory_map_read32 = [ ] ; this . memory_map_write32 = [ ] ; this . bios = { main : null , vga : null } ; this . fw_value = 0 ; this . fpu = this . io = void 0 ; this . bus = a ; dbg_assert ( this . table16 && this . table32 ) ; dbg_assert ( this . table0F_16 && this . table0F_32 ) ; this . update_operand_size ( ) ; this . tsc_offset = v86 . microtick ( ) ; this . debug_init ( ) ; this . init2 ( ) ; } CPU . prototype . get_state = function ( ) { var a = [ ] ; a [ 0 ] = this . memory_size ; a [ 1 ] = this . segment_is_null ; a [ 2 ] = this . segment_offsets ; a [ 3 ] = this . segment_limits ; a [ 4 ] = this . protected_mode ; a [ 5 ] = this . idtr_offset ; a [ 6 ] = this . idtr_size ; a [ 7 ] = this . gdtr_offset ; a [ 8 ] = this . gdtr_size ; a [ 9 ] = this . page_fault ; a [ 10 ] = this . cr ; a [ 11 ] = this . cpl ; a [ 12 ] = this . page_size_extensions ; a [ 13 ] = this . is_32 ; a [ 16 ] = this . stack_size_32 ; a [ 17 ] = this . in_hlt ; a [ 18 ] = this . last_virt_eip ; a [ 19 ] = this . eip_phys ; a [ 20 ] = this . last_virt_esp ; a [ 21 ] = this . esp_phys ; a [ 22 ] = this . sysenter_cs ; a [ 23 ] = this . sysenter_eip ; a [ 24 ] = this . sysenter_esp ; a [ 25 ] = this . prefixes ; a [ 26 ] = this . flags ; a [ 27 ] = this . flags_changed ; a [ 28 ] = this . last_op1 ; a [ 29 ] = this . last_op2 ; a [ 30 ] = this . last_op_size ; a [ 31 ] = this . last_add_result ; a [ 32 ] = this . modrm_byte ; a [ 36 ] = this . paging ; a [ 37 ] = this . instruction_pointer ; a [ 38 ] = this . previous_ip ; a [ 39 ] = this . reg32s ; a [ 40 ] = this . sreg ; a [ 41 ] = this . dreg ; a [ 42 ] = this . mem8 ; a [ 43 ] = this . fpu ; a [ 45 ] = this . devices . virtio ; a [ 46 ] = this . devices . apic ; a [ 47 ] = this . devices . rtc ; a [ 48 ] = this . devices . pci ; a [ 49 ] = this . devices . dma ; a [ 50 ] = this . devices . acpi ; a [ 51 ] = this . devices . hpet ; a [ 52 ] = this . devices . vga ; a [ 53 ] = this . devices . ps2 ; a [ 54 ] = this . devices . uart ; a [ 55 ] = this . devices . fdc ; a [ 56 ] = this . devices . cdrom ; a [ 57 ] = this . devices . hda ; a [ 58 ] = this . devices . pit ; a [ 59 ] = this . devices . net ; a [ 60 ] = this . devices . pic ; a [ 61 ] = this . devices . sb16 ; a [ 62 ] = this . a20_enabled ; a [ 63 ] = this . fw_value ; a [ 64 ] = this . devices . ioapic ; a [ 65 ] = this . tss_size_32 ; a [ 66 ] = this . reg_mmxs ; return a ; } ; CPU . prototype . set_state = function ( a ) { this . memory_size = a [ 0 ] ; this . segment_is_null = a [ 1 ] ; this . segment_offsets = a [ 2 ] ; this . segment_limits = a [ 3 ] ; this . protected_mode = a [ 4 ] ; this . idtr_offset = a [ 5 ] ; this . idtr_size = a [ 6 ] ; this . gdtr_offset = a [ 7 ] ; this . gdtr_size = a [ 8 ] ; this . page_fault = a [ 9 ] ; this . cr = a [ 10 ] ; this . cpl = a [ 11 ] ; this . page_size_extensions = a [ 12 ] ; this . is_32 = a [ 13 ] ; this . stack_size_32 = a [ 16 ] ; this . in_hlt = a [ 17 ] ; this . last_virt_eip = a [ 18 ] ; this . eip_phys = a [ 19 ] ; this . last_virt_esp = a [ 20 ] ; this . esp_phys = a [ 21 ] ; this . sysenter_cs = a [ 22 ] ; this . sysenter_eip = a [ 23 ] ; this . sysenter_esp = a [ 24 ] ; this . prefixes = a [ 25 ] ; this . flags = a [ 26 ] ; this . flags_changed = a [ 27 ] ; this . last_op1 = a [ 28 ] ; this . last_op2 = a [ 29 ] ; this . last_op_size = a [ 30 ] ; this . last_add_result = a [ 31 ] ; this . modrm_byte = a [ 32 ] ; this . paging = a [ 36 ] ; this . instruction_pointer = a [ 37 ] ; this . previous_ip = a [ 38 ] ; this . reg32s = a [ 39 ] ; this . sreg = a [ 40 ] ; this . dreg = a [ 41 ] ; this . mem8 = a [ 42 ] ; this . fpu = a [ 43 ] ; this . devices . virtio = a [ 45 ] ; this . devices . apic = a [ 46 ] ; this . devices . rtc = a [ 47 ] ; this . devices . pci = a [ 48 ] ; this . devices . dma = a [ 49 ] ; this . devices . acpi = a [ 50 ] ; this . devices . hpet = a [ 51 ] ; this . devices . vga = a [ 52 ] ; this . devices . ps2 = a [ 53 ] ; this . devices . uart = a [ 54 ] ; this . devices . fdc = a [ 55 ] ; this . devices . cdrom = a [ 56 ] ; this . devices . hda = a [ 57 ] ; this . devices . pit = a [ 58 ] ; this . devices . net = a [ 59 ] ; this . devices . pic = a [ 60 ] ; this . devices . sb16 = a [ 61 ] ; this . a20_enabled = a [ 62 ] ; this . fw_value = a [ 63 ] ; this . devices . ioapic = a [ 64 ] ; this . tss_size_32 = a [ 65 ] ; this . reg_mmxs = a [ 66 ] ; this . mem16 = new Uint16Array ( this . mem8 . buffer , this . mem8 . byteOffset , this . mem8 . length >> 1 ) ; this . mem32s = new Int32Array ( this . mem8 . buffer , this . mem8 . byteOffset , this . mem8 . length >> 2 ) ; this . full_clear_tlb ( ) ; this . reg32 = new Uint32Array ( this . reg32s . buffer ) ; this . reg16s = new Int16Array ( this . reg32s . buffer ) ; this . reg16 = new Uint16Array ( this . reg32s . buffer ) ; this . reg8s = new Int8Array ( this . reg32s . buffer ) ; this . reg8 = new Uint8Array ( this . reg32s . buffer ) ; this . reg_mmx = new Uint32Array ( this . reg_mmxs . buffer ) ; this . reg_mmx8s = new Int8Array ( this . reg_mmxs . buffer ) ; this . reg_mmx8 = new Uint8Array ( this . reg_mmxs . buffer ) ; this . update_operand_size ( ) ; } ; CPU . prototype . main_run = function ( ) { if ( this . in_hlt ) { var a = this . hlt_loop ( ) ; if ( this . in_hlt ) return a ; } this . do_run ( ) ; return 0 ; } ; CPU . prototype . exception_cleanup = function ( a ) { if ( a === MAGIC_CPU_EXCEPTION ) this . page_fault = ! 1 , this . clear_prefixes ( ) ; else throw console . log ( a ) , console . log ( a . stack ) , a ; } ; CPU . prototype . reboot_internal = function ( ) { this . reset ( ) ; this . load_bios ( ) ; throw MAGIC_CPU_EXCEPTION ; } ; CPU . prototype . reset = function ( ) { this . a20_enabled = ! 0 ; for ( var a = 0 ; 8 > a ; a ++ ) this . segment_is_null [ a ] = 0 , this . segment_limits [ a ] = 0 , this . segment_offsets [ a ] = 0 ; this . full_clear_tlb ( ) ; for ( a = 0 ; 8 > a ; a ++ ) this . reg32s [ a ] = 0 , this . sreg [ a ] = 0 , this . cr [ a ] = 0 , this . dreg [ a ] = 0 ; for ( a = 0 ; a < this . reg_mmxs . length ; a ++ ) this . reg_mmxs [ a ] = 0 ; for ( a = 0 ; a < this . reg_xmm32s . length ; a ++ ) this . reg_xmm32s [ a ] = 0 ; this . mxcsr = 8064 ; this . protected_mode = ! 1 ; this . gdtr_offset = this . gdtr_size = this . idtr_offset = this . idtr_size = 0 ; this . page_fault = ! 1 ; this . cr [ 0 ] = 1610612752 ; this . cr [ 2 ] = 0 ; this . cr [ 3 ] = 0 ; this . cr [ 4 ] = 0 ; this . dreg [ 6 ] = - 61456 ; this . dreg [ 7 ] = 1024 ; this . cpl = 0 ; this . paging = ! 1 ; this . page_size_extensions = 0 ; this . stack_size_32 = this . is_32 = ! 1 ; this . prefixes = 0 ; this . last_virt_esp = this . last_virt_eip = - 1 ; this . update_operand_size ( ) ; this . previous_ip = this . timestamp_counter = 0 ; this . in_hlt = ! 1 ; this . sysenter_eip = this . sysenter_esp = this . sysenter_cs = 0 ; this . flags = flags_default ; this . last_op_size = this . last_op2 = this . last_op1 = this . last_add_result = this . last_result = this . flags_changed = 0 ; this . tsc_offset = v86 . microtick ( ) ; this . instruction_pointer = 1048560 ; this . switch_cs_real_mode ( 61440 ) ; this . switch_seg ( reg_ss , 48 ) ; this . reg16 [ reg_sp ] = 256 ; this . devices . virtio && this . devices . virtio . reset ( ) ; this . fw_value = 0 ; } ; CPU . prototype . create_memory = function ( a ) { 1048576 > a ? a = 1048576 : 0 > ( a | 0 ) && ( a = Math . pow ( 2 , 31 ) - MMAP_BLOCK_SIZE ) ; a = ( a - 1 | MMAP_BLOCK_SIZE - 1 ) + 1 | 0 ; dbg_assert ( 0 < ( a | 0 ) ) ; dbg_assert ( 0 === ( a & MMAP_BLOCK_SIZE - 1 ) ) ; this . memory_size = a ; a = new ArrayBuffer ( a ) ; this . mem8 = new Uint8Array ( a ) ; this . mem16 = new Uint16Array ( a ) ; this . mem32s = new Int32Array ( a ) ; } ; goog . exportProperty ( CPU . prototype , "create_memory" , CPU . prototype . create_memory ) ; CPU . prototype . init = function ( a , b ) { this . create_memory ( "number" === typeof a . memory_size ? a . memory_size : 67108864 ) ; this . reset ( ) ; var c = new IO ( this ) ; this . io = c ; this . bios . main = a . bios ; this . bios . vga = a . vga_bios ; this . load_bios ( ) ; var d = 0 ; c . register_read ( 179 , this , function ( ) { dbg_log ( "port 0xB3 read" ) ; return 0 ; } ) ; c . register_read ( 146 , this , function ( ) { return d ; } ) ; c . register_write ( 146 , this , function ( a ) { d = a ; } ) ; c . register_read ( 1297 , this , function ( ) { var a = this . fw_value & 255 ; this . fw_value >>>= 8 ; return a ; } ) ; c . register_write ( 1296 , this , void 0 , function ( a ) { dbg_log ( "bios config port, index=" + h ( a ) ) ; a === FW_CFG_SIGNATURE ? this . fw_value = - 89064784 : a === FW_CFG_RAM_SIZE ? this . fw_value = this . memory_size : a === FW_CFG_NB_CPUS ? this . fw_value = 1 : ( dbg_assert ( ! 1 , "Unimplemented fw index: " + h ( a ) ) , this . fw_value = 0 ) ; } ) ; DEBUG && c . register_write ( 128 , this , function ( a ) { } ) ; this . devices = { } ; a . load_devices && ( this . devices . pic = new PIC ( this ) , this . devices . pci = new PCI ( this ) , ENABLE_ACPI && ( this . devices . ioapic = new IOAPIC ( this ) , this . devices . apic = new APIC ( this ) , this . devices . acpi = new ACPI ( this ) ) , this . devices . rtc = new RTC ( this ) , this . fill_cmos ( this . devices . rtc , a ) , this . devices . dma = new DMA ( this ) , ENABLE_HPET && ( this . devices . hpet = new HPET ( this ) ) , this . devices . vga = new VGAScreen ( this , b , a . vga_memory_size || 8388608 ) , this . fpu = new FPU ( this ) , this . devices . ps2 = new PS2 ( this , b ) , this . devices . uart = new UART ( this , 1016 , b ) , this . devices . fdc = new FloppyController ( this , a . fda , a . fdb ) , c = 0 , a . hda && ( this . devices . hda = new IDEDevice ( this , a . hda , ! 1 , c ++ , b ) ) , a . cdrom && ( this . devices . cdrom = new IDEDevice ( this , a . cdrom , ! 0 , c ++ , b ) ) , a . hdb && ( this . devices . hdb = new IDEDevice ( this , a . hdb , ! 1 , c ++ , b ) ) , this . devices . pit = new PIT ( this , b ) , a . enable_ne2k && ( this . devices . net = new Ne2k ( this , b ) ) , a . fs9p && ( this . devices . virtio = new VirtIO ( this , b , a . fs9p ) ) , this . devices . sb16 = new SB16 ( this , b ) ) ; a . multiboot && ( dbg_assert ( a . multiboot . buffer ) , this . load_multiboot ( a . multiboot . buffer ) ) ; DEBUG && this . debug . init ( ) ; } ; CPU . prototype . load_multiboot = function ( a ) { dbg_log ( "Trying multiboot from buffer of size " + a . byteLength , LOG_CPU ) ; if ( 8192 > a . byteLength ) { var b = new Int32Array ( 2048 ) ; ( new Uint8Array ( b . buffer ) ) . set ( new Uint8Array ( a ) ) ; } else b = new Int32Array ( a , 0 , 2048 ) ; for ( var c = 0 ; 8192 > c ; c += 4 ) if ( 464367618 === b [ c >> 2 ] ) { var d = b [ c + 4 >> 2 ] ; if ( 464367618 + d + b [ c + 8 >> 2 ] | 0 ) dbg_log ( "Multiboot checksum check failed" , LOG_CPU ) ; else { dbg_log ( "Multiboot magic found, flags: " + h ( d >>> 0 , 8 ) , LOG_CPU ) ; dbg_assert ( 0 === ( d & - 65537 ) , "TODO" ) ; this . reg32s [ reg_eax ] = 732803074 ; this . reg32s [ reg_ebx ] = 31744 ; this . write32 ( 31744 , 0 ) ; this . cr [ 0 ] = 1 ; this . protected_mode = ! 0 ; this . flags = flags_default ; this . update_cs_size ( ! 0 ) ; this . stack_size_32 = ! 0 ; for ( var e = 0 ; 6 > e ; e ++ ) this . segment_is_null [ e ] = 0 , this . segment_offsets [ e ] = 0 , this . segment_limits [ e ] = 4294967295 , this . sreg [ e ] = 45058 ; if ( d & 65536 ) { dbg_log ( "Multiboot specifies its own address table" , LOG_CPU ) ; var g = b [ c + 12 >> 2 ] ; d = b [ c + 16 >> 2 ] ; e = b [ c + 20 >> 2 ] ; var f = b [ c + 24 >> 2 ] ; b = b [ c + 28 >> 2 ] ; dbg_log ( "header=" + h ( g , 8 ) + " load=" + h ( d , 8 ) + " load_end=" + h ( e , 8 ) + " bss_end=" + h ( f , 8 ) + " entry=" + h ( b , 8 ) ) ; dbg_assert ( d <= g ) ; c -= g - d ; 0 === e ? e = void 0 : ( dbg_assert ( e >= d ) , e -= d ) ; a = new Uint8Array ( a , c , e ) ; this . write_blob ( a , d ) ; this . instruction_pointer = this . get_seg ( reg_cs ) + b | 0 ; } else if ( 1179403647 === b [ 0 ] ) for ( dbg_log ( "Multiboot image is in elf format" , LOG_CPU ) , d = read_elf ( a ) , this . instruction_pointer = this . get_seg ( reg_cs ) + d . header . entry | 0 , d = $jscomp . makeIterator ( d . program_headers ) , c = d . next ( ) ; ! c . done ; c = d . next ( ) ) c = c . value , 0 !== c . type && ( 1 === c . type ? ( dbg_assert ( c . paddr === c . vaddr ) , dbg_assert ( c . filesz <= c . memsz ) , b = new Uint8Array ( a , c . offset , c . filesz ) , this . write_blob ( b , c . paddr ) ) : 4 !== c . type && 1685382480 !== c . type && 1685382481 !== c . type && dbg_assert ( ! 1 , "unimplemented elf section type" ) ) ; else dbg_assert ( ! 1 , "Not a bootable multiboot format" ) ; this . io . register_write_consecutive ( 244 , this , function ( a ) { console . log ( "Test exited with code " + h ( a , 2 ) ) ; throw "HALT" ; } , function ( ) { } , function ( ) { } , function ( ) { } ) ; for ( a = { i$10 : 14 } ; 15 >= a . i$10 ; a = { i$10 : a . i$10 } , a . i$10 ++ ) this . io . register_write ( 8192 + a . i$10 , this , function ( a ) { return function ( b ) { dbg_log ( "kvm-unit-test: Set irq " + h ( a . i$10 ) + " to " + h ( b , 2 ) ) ; b ? this . device_raise_irq ( a . i$10 ) : this . device_lower_irq ( a . i$10 ) ; } ; } ( a ) ) ; dbg_log ( "Starting multiboot kernel at:" , LOG_CPU ) ; this . debug . dump_state ( ) ; this . debug . dump_regs ( ) ; break ; } } } ; CPU . prototype . fill_cmos = function ( a , b ) { var c = b . boot_order || 531 ; a . cmos_write ( CMOS_BIOS_BOOTFLAG1 , 1 | c >> 4 & 240 ) ; a . cmos_write ( CMOS_BIOS_BOOTFLAG2 , c & 255 ) ; a . cmos_write ( CMOS_MEM_BASE_LOW , 128 ) ; a . cmos_write ( CMOS_MEM_BASE_HIGH , 2 ) ; c = 0 ; 1048576 <= this . memory_size && ( c = this . memory_size - 1048576 >> 10 , c = Math . min ( c , 65535 ) ) ; a . cmos_write ( CMOS_MEM_OLD_EXT_LOW , c & 255 ) ; a . cmos_write ( CMOS_MEM_OLD_EXT_HIGH , c >> 8 & 255 ) ; a . cmos_write ( CMOS_MEM_EXTMEM_LOW , c & 255 ) ; a . cmos_write ( CMOS_MEM_EXTMEM_HIGH , c >> 8 & 255 ) ; c = 0 ; 16777216 <= this . memory_size && ( c = this . memory_size - 16777216 >> 16 , c = Math . min ( c , 65535 ) ) ; a . cmos_write ( CMOS_MEM_EXTMEM2_LOW , c & 255 ) ; a . cmos_write ( CMOS_MEM_EXTMEM2_HIGH , c >> 8 & 255 ) ; a . cmos_write ( CMOS_MEM_HIGHMEM_LOW , 0 ) ; a . cmos_write ( CMOS_MEM_HIGHMEM_MID , 0 ) ; a . cmos_write ( CMOS_MEM_HIGHMEM_HIGH , 0 ) ; a . cmos_write ( CMOS_EQUIPMENT_INFO , 47 ) ; a . cmos_write ( CMOS_BIOS_SMP_COUNT , 0 ) ; b . fastboot && a . cmos_write ( 63 , 1 ) ; } ; CPU . prototype . load_bios = function ( ) { var a = this . bios . main , b = this . bios . vga ; if ( a ) { var c = new Uint8Array ( a ) ; this . write_blob ( c , 1048576 - a . byteLength ) ; if ( b ) { var d = new Uint8Array ( b ) ; this . write_blob ( d , 786432 ) ; this . io . mmap_register ( 4272947200 , 1048576 , function ( a ) { a = a - 4272947200 | 0 ; return a < d . length ? d [ a ] : 0 ; } , function ( a , b ) { dbg_assert ( ! 1 , "Unexpected write to VGA rom" ) ; } ) ; } else dbg_log ( "Warning: No VGA BIOS" ) ; this . io . mmap_register ( 4293918720 , 1048576 , function ( a ) { return this . mem8 [ a & 1048575 ] ; } . bind ( this ) , function ( a , b ) { this . mem8 [ a & 1048575 ] = b ; } . bind ( this ) ) ; } else dbg_log ( "Warning: No BIOS" ) ; } ; CPU . prototype . do_run = function ( ) { for ( var a = v86 . microtick ( ) , b = a ; b - a < TIME_PER_FRAME ; ) { this . run_hardware_timers ( b ) ; this . handle_irqs ( ) ; this . do_many_cycles ( ) ; if ( this . in_hlt ) break ; b = v86 . microtick ( ) ; } } ; CPU . prototype . do_many_cycles = function ( ) { try { this . do_many_cycles_unsafe ( ) ; } catch ( a ) { this . exception_cleanup ( a ) ; } } ; CPU . prototype . do_many_cycles_unsafe = function ( ) { for ( var a = LOOP_COUNTER ; a -- ; ) this . cycle_internal ( ) ; } ; "undefined" !== typeof window && ( window . __no_inline_for_closure_compiler__ = [ CPU . prototype . exception_cleanup , CPU . prototype . do_many_cycles_unsafe , CPU . prototype . do_many_cycles ] ) ; var PROFILING = ! 1 ; CPU . prototype . cycle_internal = function ( ) { this . previous_ip = this . instruction_pointer ; this . timestamp_counter ++ ; if ( PROFILING ) var a = performance . now ( ) ; var b = this . read_imm8 ( ) ; DEBUG && this . debug . logop ( this . instruction_pointer - 1 >>> 0 , b ) ; this . table [ b ] ( this ) ; if ( PROFILING ) { var c = performance . now ( ) ; instruction_total [ b ] += c - a ; instruction_count [ b ] ++ ; } this . flags & flag_trap && dbg_log ( "Trap flag: Ignored" , LOG_CPU ) ; } ; CPU . prototype . cycle = function ( ) { try { this . cycle_internal ( ) ; } catch ( a ) { this . exception_cleanup ( a ) ; } } ; goog . exportProperty ( CPU . prototype , "cycle" , CPU . prototype . cycle ) ; CPU . prototype . segment_prefix_op = function ( a ) { dbg_assert ( 5 >= a ) ; this . prefixes |= a + 1 ; this . run_prefix_instruction ( ) ; this . prefixes = 0 ; } ; CPU . prototype . run_prefix_instruction = function ( ) { if ( this . is_osize_32 ( ) ) this . table32 [ this . read_imm8 ( ) ] ( this ) ; else this . table16 [ this . read_imm8 ( ) ] ( this ) ; } ; CPU . prototype . hlt_loop = function ( ) { dbg_assert ( this . flags & flag_interrupt ) ; this . run_hardware_timers ( v86 . microtick ( ) ) ; this . handle_irqs ( ) ; return 0 ; } ; CPU . prototype . run_hardware_timers = function ( a ) { ENABLE_HPET ? ( this . devices . pit . timer ( a , this . devices . hpet . legacy_mode ) , this . devices . rtc . timer ( a , this . devices . hpet . legacy_mode ) , this . devices . hpet . timer ( a ) ) : ( this . devices . pit . timer ( a , ! 1 ) , this . devices . rtc . timer ( a , ! 1 ) ) ; ENABLE_ACPI && ( this . devices . acpi . timer ( a ) , this . devices . apic . timer ( a ) ) ; } ; CPU . prototype . clear_prefixes = function ( ) { this . prefixes = 0 ; } ; CPU . prototype . set_cr0 = function ( a ) { if ( ( a & ( CR0_PE | CR0_PG ) ) === CR0_PG ) throw this . debug . unimpl ( "#GP handler" ) ; this . cr [ 0 ] = a ; this . fpu || ( this . cr [ 0 ] |= CR0_EM ) ; this . cr [ 0 ] |= CR0_ET ; a = ( this . cr [ 0 ] & CR0_PG ) === CR0_PG ; dbg_assert ( "boolean" === typeof this . paging ) ; a !== this . paging && ( this . paging = a , this . full_clear_tlb ( ) ) ; this . protected_mode = ( this . cr [ 0 ] & CR0_PE ) === CR0_PE ; } ; CPU . prototype . set_cr4 = function ( a ) { a & - 3565568 && this . trigger_gp ( 0 ) ; ( this . cr [ 4 ] ^ a ) & CR4_PGE && ( a & CR4_PGE ? this . clear_tlb ( ) : this . full_clear_tlb ( ) ) ; this . cr [ 4 ] = a ; this . page_size_extensions = a & CR4_PSE ? PSE_ENABLED : 0 ; if ( a & CR4_PAE ) throw this . debug . unimpl ( "PAE" ) ; a & 4294965504 && ( dbg_assert ( ! 1 , "Unimplemented CR4 bits: " + h ( a ) ) , this . trigger_ud ( ) ) ; dbg_log ( "cr4=" + h ( a >>> 0 ) , LOG_CPU ) ; } ; CPU . prototype . cpl_changed = function ( ) { this . last_virt_esp = this . last_virt_eip = - 1 ; } ; CPU . prototype . read_imm8 = function ( ) { this . instruction_pointer & - 4096 ^ this . last_virt_eip && ( this . eip_phys = this . translate_address_read ( this . instruction_pointer ) ^ this . instruction_pointer , this . last_virt_eip = this . instruction_pointer & - 4096 ) ; var a = this . read8 ( this . eip_phys ^ this . instruction_pointer ) ; this . instruction_pointer = this . instruction_pointer + 1 | 0 ; return a ; } ; CPU . prototype . read_imm8s = function ( ) { return this . read_imm8 ( ) << 24 >> 24 ; } ; CPU . prototype . read_imm16 = function ( ) { if ( 4094 < ( this . instruction_pointer ^ this . last_virt_eip ) >>> 0 ) return this . read_imm8 ( ) | this . read_imm8 ( ) << 8 ; var a = this . read16 ( this . eip_phys ^ this . instruction_pointer ) ; this . instruction_pointer = this . instruction_pointer + 2 | 0 ; return a ; } ; CPU . prototype . read_imm32s = function ( ) { if ( 4092 < ( this . instruction_pointer ^ this . last_virt_eip ) >>> 0 ) return this . read_imm16 ( ) | this . read_imm16 ( ) << 16 ; var a = this . read32s ( this . eip_phys ^ this . instruction_pointer ) ; this . instruction_pointer = this . instruction_pointer + 4 | 0 ; return a ; } ; CPU . prototype . create_atom64s = function ( a , b ) { var c = new Int32Array ( 2 ) ; c [ 0 ] = a ; c [ 1 ] = b ; return c ; } ; CPU . prototype . create_atom128s = function ( a , b , c , d ) { var e = new Int32Array ( 4 ) ; e [ 0 ] = a ; e [ 1 ] = b ; e [ 2 ] = c ; e [ 3 ] = d ; return e ; } ; CPU . prototype . read_modrm_byte = function ( ) { this . modrm_byte = this . read_imm8 ( ) ; } ; CPU . prototype . read_op0F = CPU . prototype . read_imm8 ; CPU . prototype . read_sib = CPU . prototype . read_imm8 ; CPU . prototype . read_op8 = CPU . prototype . read_imm8 ; CPU . prototype . read_op8s = CPU . prototype . read_imm8s ; CPU . prototype . read_op16 = CPU . prototype . read_imm16 ; CPU . prototype . read_op32s = CPU . prototype . read_imm32s ; CPU . prototype . read_disp8 = CPU . prototype . read_imm8 ; CPU . prototype . read_disp8s = CPU . prototype . read_imm8s ; CPU . prototype . read_disp16 = CPU . prototype . read_imm16 ; CPU . prototype . read_disp32s = CPU . prototype . read_imm32s ; CPU . prototype . init2 = function ( ) { } ; CPU . prototype . branch_taken = function ( ) { } ; CPU . prototype . branch_not_taken = function ( ) { } ; CPU . prototype . diverged = function ( ) { } ; CPU . prototype . modrm_resolve = function ( a ) { dbg_assert ( 192 > a ) ; return ( this . is_asize_32 ( ) ? this . modrm_table32 : this . modrm_table16 ) [ a ] ( this ) ; } ; CPU . prototype . sib_resolve = function ( a ) { return this . sib_table [ this . read_sib ( ) ] ( this , a ) ; } ; CPU . prototype . clear_instruction_cache = function ( ) { } ; CPU . prototype . virt_boundary_read16 = function ( a , b ) { dbg_assert ( 4095 === ( a & 4095 ) ) ; dbg_assert ( 0 === ( b & 4095 ) ) ; return this . read8 ( a ) | this . read8 ( b ) << 8 ; } ; CPU . prototype . virt_boundary_read32s = function ( a , b ) { dbg_assert ( 4093 <= ( a & 4095 ) ) ; dbg_assert ( ( b - 3 & 4095 ) === ( a & 4095 ) ) ; var c = a & 1 ? a & 2 ? this . read_aligned16 ( b - 2 >> 1 ) : this . read_aligned16 ( a + 1 >> 1 ) : this . virt_boundary_read16 ( a + 1 | 0 , b - 1 | 0 ) ; return this . read8 ( a ) | c << 8 | this . read8 ( b ) << 24 ; } ; CPU . prototype . virt_boundary_write16 = function ( a , b , c ) { dbg_assert ( 4095 === ( a & 4095 ) ) ; dbg_assert ( 0 === ( b & 4095 ) ) ; this . write8 ( a , c ) ; this . write8 ( b , c >> 8 ) ; } ; CPU . prototype . virt_boundary_write32 = function ( a , b , c ) { dbg_assert ( 4093 <= ( a & 4095 ) ) ; dbg_assert ( ( b - 3 & 4095 ) === ( a & 4095 ) ) ; this . write8 ( a , c ) ; this . write8 ( b , c >> 24 ) ; a & 1 ? a & 2 ? ( this . write8 ( b - 2 , c >> 8 ) , this . write8 ( b - 1 , c >> 16 ) ) : ( this . write8 ( a + 1 | 0 , c >> 8 ) , this . write8 ( a + 2 | 0 , c >> 16 ) ) : ( this . write8 ( a + 1 | 0 , c >> 8 ) , this . write8 ( b - 1 , c >> 16 ) ) ; } ; CPU . prototype . safe_read8 = function ( a ) { dbg_assert ( 2147483648 > a ) ; return this . read8 ( this . translate_address_read ( a ) ) ; } ; CPU . prototype . safe_read16 = function ( a ) { return this . paging && 4095 === ( a & 4095 ) ? this . safe_read8 ( a ) | this . safe_read8 ( a + 1 | 0 ) << 8 : this . read16 ( this . translate_address_read ( a ) ) ; } ; CPU . prototype . safe_read32s = function ( a ) { return this . paging && 4093 <= ( a & 4095 ) ? this . safe_read16 ( a ) | this . safe_read16 ( a + 2 | 0 ) << 16 : this . read32s ( this . translate_address_read ( a ) ) ; } ; CPU . prototype . safe_read64s = function ( a ) { var b = this . create_atom64s ( 0 , 0 ) ; this . paging && 4089 <= ( a & 4095 ) ? ( b [ 0 ] = this . safe_read32s ( a ) , b [ 1 ] = this . safe_read32s ( a + 4 | 0 ) ) : ( b [ 0 ] = this . read32s ( this . translate_address_read ( a ) ) , b [ 1 ] = this . read32s ( this . translate_address_read ( a + 4 | 0 ) ) ) ; return b ; } ; CPU . prototype . safe_read128s_aligned = function ( a ) { dbg_assert ( 0 === ( a & 15 ) ) ; a = this . translate_address_read ( a ) ; return this . create_atom128s ( this . read32s ( a ) , this . read32s ( a + 4 | 0 ) , this . read32s ( a + 8 | 0 ) , this . read32s ( a + 12 | 0 ) ) ; } ; CPU . prototype . safe_read128s_unaligned = function ( a ) { return this . create_atom128s ( this . safe_read32s ( a ) , this . safe_read32s ( a + 4 | 0 ) , this . safe_read32s ( a + 8 | 0 ) , this . safe_read32s ( a + 12 | 0 ) ) ; } ; CPU . prototype . safe_write8 = function ( a , b ) { dbg_assert ( 2147483648 > a ) ; this . write8 ( this . translate_address_write ( a ) , b ) ; } ; CPU . prototype . safe_write16 = function ( a , b ) { var c = this . translate_address_write ( a ) ; 4095 === ( a & 4095 ) ? this . virt_boundary_write16 ( c , this . translate_address_write ( a + 1 | 0 ) , b ) : this . write16 ( c , b ) ; } ; CPU . prototype . safe_write32 = function ( a , b ) { var c = this . translate_address_write ( a ) ; 4093 <= ( a & 4095 ) ? this . virt_boundary_write32 ( c , this . translate_address_write ( a + 3 & - 4 ) | a + 3 & 3 , b ) : this . write32 ( c , b ) ; } ; CPU . prototype . safe_write64 = function ( a , b , c ) { this . writable_or_pagefault ( a , 8 ) ; this . safe_write32 ( a , b ) ; this . safe_write32 ( a + 4 | 0 , c ) ; } ; CPU . prototype . safe_write128 = function ( a , b , c , d , e ) { this . writable_or_pagefault ( a , 16 ) ; this . safe_write32 ( a , b ) ; this . safe_write32 ( a + 4 | 0 , c ) ; this . safe_write32 ( a + 8 | 0 , d ) ; this . safe_write32 ( a + 12 | 0 , e ) ; } ; CPU . prototype . read_moffs = function ( ) { return this . is_asize_32 ( ) ? this . get_seg_prefix ( reg_ds ) + this . read_op32s ( ) | 0 : this . get_seg_prefix ( reg_ds ) + this . read_op16 ( ) | 0 ; } ; CPU . prototype . getiopl = function ( ) { return this . flags >> 12 & 3 ; } ; CPU . prototype . vm86_mode = function ( ) { return ! ! ( this . flags & flag_vm ) ; } ; CPU . prototype . get_eflags = function ( ) { return this . flags & ~ flags_all | ! ! this . getcf ( ) | ! ! this . getpf ( ) << 2 | ! ! this . getaf ( ) << 4 | ! ! this . getzf ( ) << 6 | ! ! this . getsf ( ) << 7 | ! ! this . getof ( ) << 11 ; } ; CPU . prototype . update_eflags = function ( a ) { var b = flag_rf | flag_vm | flag_vip | flag_vif , c = ~ flag_vip & ~ flag_vif & flags_mask ; this . flags & flag_vm ? ( dbg_assert ( 3 === this . getiopl ( ) ) , b |= flag_iopl , c |= flag_vip | flag_vif ) : ( this . protected_mode || dbg_assert ( 0 === this . cpl ) , this . cpl && ( b |= flag_iopl , this . cpl > this . getiopl ( ) && ( b |= flag_interrupt ) ) ) ; this . flags = ( a ^ ( this . flags ^ a ) & b ) & c | flags_default ; this . flags_changed = 0 ; } ; CPU . prototype . get_stack_reg = function ( ) { return this . stack_size_32 ? this . reg32s [ reg_esp ] : this . reg16 [ reg_sp ] ; } ; CPU . prototype . set_stack_reg = function ( a ) { this . stack_size_32 ? this . reg32s [ reg_esp ] = a : this . reg16 [ reg_sp ] = a ; } ; CPU . prototype . adjust_stack_reg = function ( a ) { this . stack_size_32 ? this . reg32s [ reg_esp ] += a : this . reg16 [ reg_sp ] += a ; } ; CPU . prototype . get_stack_pointer = function ( a ) { return this . stack_size_32 ? this . get_seg ( reg_ss ) + this . reg32s [ reg_esp ] + a | 0 : this . get_seg ( reg_ss ) + ( this . reg16 [ reg_sp ] + a & 65535 ) | 0 ; } ; CPU . prototype . get_real_eip = function ( ) { return this . instruction_pointer - this . get_seg ( reg_cs ) | 0 ; } ; CPU . prototype . call_interrupt_vector = function ( a , b , c ) { CPU_LOG_VERBOSE && this . debug . dump_state ( "int " + h ( a ) + " start (" + ( b ? "soft" : "hard" ) + "ware)" ) ; CPU_LOG_VERBOSE && this . debug . dump_regs ( ) ; this . debug . debug_interrupt ( a ) ; dbg_assert ( ! 1 === c || "number" === typeof c ) ; this . in_hlt = ! 1 ; if ( this . protected_mode ) { if ( this . vm86_mode ( ) && this . cr [ 4 ] & CR4_VME ) throw this . debug . unimpl ( "VME" ) ; this . vm86_mode ( ) && b && 3 > this . getiopl ( ) && ( dbg_log ( "call_interrupt_vector #GP. vm86 && software int && iopl < 3" , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_gp ( 0 ) ) ; if ( ( a << 3 | 7 ) > this . idtr_size ) throw dbg_log ( a , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . debug . unimpl ( "#GP handler" ) ; var d = this . idtr_offset + ( a << 3 ) | 0 ; dbg_assert ( 4088 > ( d & 4095 ) ) ; this . paging && ( d = this . translate_address_system_read ( d ) ) ; var e = this . read16 ( d ) | this . read16 ( d + 6 | 0 ) << 16 , g = this . read16 ( d + 2 | 0 ) , f = this . read8 ( d + 5 | 0 ) , k = f >> 5 & 3 , l = f & 31 ; if ( 0 === ( f & 128 ) ) throw this . debug . unimpl ( "#NP handler" ) ; b && k < this . cpl && ( dbg_log ( "#gp software interrupt (" + h ( a , 2 ) + ") and dpl < cpl" , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_gp ( a << 3 | 2 ) ) ; if ( 5 === l ) { dbg_log ( "interrupt to task gate: int=" + h ( a , 2 ) + " sel=" + h ( g , 4 ) + " dpl=" + k , LOG_CPU ) ; dbg_trace ( LOG_CPU ) ; this . do_task_switch ( g , c ) ; CPU_LOG_VERBOSE && this . debug . dump_state ( "int end" ) ; return ; } if ( 6 !== ( l & - 10 ) ) throw dbg_trace ( LOG_CPU ) , dbg_log ( "invalid type: " + h ( l ) ) , dbg_log ( h ( d ) + " " + h ( e >>> 0 ) + " " + h ( g ) ) , this . debug . unimpl ( "#GP handler" ) ; b = 1 === ( l & 1 ) ; l = 0 === ( l & 8 ) ; d = this . lookup_segment_selector ( g ) ; dbg_assert ( e >>> 0 <= d . effective_limit ) ; dbg_assert ( d . is_valid ) ; if ( d . is_null ) throw dbg_log ( "is null" ) , this . debug . unimpl ( "#GP handler" ) ; if ( ! d . is_executable || d . dpl > this . cpl ) throw dbg_log ( "not exec" ) , this . debug . unimpl ( "#GP handler" ) ; d . is_present || ( dbg_log ( "not present" ) , this . trigger_np ( a << 3 | 2 ) ) ; a = this . get_eflags ( ) ; if ( ! d . dc_bit && d . dpl < this . cpl ) { k = this . get_tss_stack_addr ( d . dpl ) ; this . tss_size_32 ? ( f = this . read32s ( k ) , k = this . read16 ( k + 4 | 0 ) ) : ( f = this . read16 ( k ) , k = this . read16 ( k + 2 | 0 ) ) ; var m = this . lookup_segment_selector ( k ) ; dbg_assert ( m . is_valid && ! m . is_system && m . is_writable ) ; if ( m . is_null ) throw this . debug . unimpl ( "#TS handler" ) ; if ( m . rpl !== d . dpl ) throw this . debug . unimpl ( "#TS handler" ) ; if ( m . dpl !== d . dpl || ! m . rw_bit ) throw this . debug . unimpl ( "#TS handler" ) ; if ( ! m . is_present ) throw this . debug . unimpl ( "#TS handler" ) ; var n = this . reg32s [ reg_esp ] , p = this . sreg [ reg_ss ] ; a & flag_vm && dbg_assert ( 0 === d . dpl , "switch to non-0 dpl from vm86 mode" ) ; var q = ( l ? 2 : 4 ) * ( 5 + ( ! 1 !== c ) + 4 * ( ( a & flag_vm ) === flag_vm ) ) ; this . translate_address_system_write ( m . base + ( m . size ? f - q : f - q & 65535 ) ) ; this . translate_address_system_write ( m . base + f - 1 ) ; this . cpl = d . dpl ; this . cpl_changed ( ) ; this . update_cs_size ( d . size ) ; this . flags = this . flags & ~ flag_vm & ~ flag_rf ; this . switch_seg ( reg_ss , k ) ; this . set_stack_reg ( f ) ; a & flag_vm && ( l ? dbg_assert ( ! 1 ) : ( this . push32 ( this . sreg [ reg_gs ] ) , this . push32 ( this . sreg [ reg_fs ] ) , this . push32 ( this . sreg [ reg_ds ] ) , this . push32 ( this . sreg [ reg_es ] ) ) ) ; l ? ( this . push16 ( p ) , this . push16 ( n ) ) : ( this . push32 ( p ) , this . push32 ( n ) ) ; } else if ( d . dc_bit || d . dpl === this . cpl ) this . flags & flag_vm && ( dbg_assert ( ! 1 , "check error code" ) , this . trigger_gp ( g & - 4 ) ) , q = ( l ? 2 : 4 ) * ( 3 + ( ! 1 !== c ) ) , this . writable_or_pagefault ( this . get_stack_pointer ( - q ) , q ) ; else throw this . debug . unimpl ( "#GP handler" ) ; l ? ( this . push16 ( a ) , this . push16 ( this . sreg [ reg_cs ] ) , this . push16 ( this . get_real_eip ( ) ) , ! 1 !== c && this . push16 ( c ) , e &= 65535 ) : ( this . push32 ( a ) , this . push32 ( this . sreg [ reg_cs ] ) , this . push32 ( this . get_real_eip ( ) ) , ! 1 !== c && this . push32 ( c ) ) ; a & flag_vm && ( this . switch_seg ( reg_gs , 0 ) , this . switch_seg ( reg_fs , 0 ) , this . switch_seg ( reg_ds , 0 ) , this . switch_seg ( reg_es , 0 ) ) ; this . sreg [ reg_cs ] = g & - 4 | this . cpl ; dbg_assert ( ( this . sreg [ reg_cs ] & 3 ) === this . cpl ) ; this . update_cs_size ( d . size ) ; this . segment_limits [ reg_cs ] = d . effective_limit ; this . segment_offsets [ reg_cs ] = d . base ; this . instruction_pointer = this . get_seg ( reg_cs ) + e | 0 ; this . flags = this . flags & ~ flag_nt & ~ flag_vm & ~ flag_rf & ~ flag_trap ; b ? this . flags & flag_interrupt && ! ( a & flag_interrupt ) && ( this . page_fault [ 0 ] || this . handle_irqs ( ) ) : this . flags &= ~ flag_interrupt ; } else e = a << 2 , c = this . read16 ( e ) , e = this . read16 ( e + 2 | 0 ) , this . push16 ( this . get_eflags ( ) ) , this . push16 ( this . sreg [ reg_cs ] ) , this . push16 ( this . get_real_eip ( ) ) , this . flags &= ~ flag_interrupt , this . switch_cs_real_mode ( e ) , this . instruction_pointer = this . get_seg ( reg_cs ) + c | 0 ; CPU_LOG_VERBOSE && this . debug . dump_state ( "int end" ) ; } ; CPU . prototype . iret16 = function ( ) { this . iret ( ! 0 ) ; } ; CPU . prototype . iret32 = function ( ) { this . iret ( ! 1 ) ; } ; CPU . prototype . iret = function ( a ) { CPU_LOG_VERBOSE && this . debug . dump_state ( "iret" + ( a ? "16" : "32" ) + " start" ) ; this . vm86_mode ( ) && 3 > this . getiopl ( ) && ( dbg_log ( "#gp iret vm86 mode, iopl != 3" , LOG_CPU ) , this . trigger_gp ( 0 ) ) ; if ( a ) var b = this . safe_read16 ( this . get_stack_pointer ( 0 ) ) , c = this . safe_read16 ( this . get_stack_pointer ( 2 ) ) , d = this . safe_read16 ( this . get_stack_pointer ( 4 ) ) ; else b = this . safe_read32s ( this . get_stack_pointer ( 0 ) ) , c = this . safe_read16 ( this . get_stack_pointer ( 4 ) ) , d = this . safe_read32s ( this . get_stack_pointer ( 8 ) ) ; if ( ! this . protected_mode || this . vm86_mode ( ) && 3 === this . getiopl ( ) ) { if ( b & 4294901760 ) throw this . debug . unimpl ( "#GP handler" ) ; this . switch_cs_real_mode ( c ) ; this . instruction_pointer = b + this . get_seg ( reg_cs ) | 0 ; a ? ( this . update_eflags ( d | this . flags & - 65536 ) , this . adjust_stack_reg ( 6 ) ) : ( this . update_eflags ( d ) , this . adjust_stack_reg ( 12 ) ) ; CPU_LOG_VERBOSE && this . debug . dump_state ( "iret end" ) ; } else { dbg_assert ( ! this . vm86_mode ( ) ) ; if ( this . flags & flag_nt ) { if ( DEBUG ) throw this . debug . unimpl ( "nt" ) ; this . trigger_gp ( 0 ) ; } if ( d & flag_vm ) { if ( 0 === this . cpl ) { dbg_assert ( ! a ) ; dbg_assert ( 0 === ( b & - 65536 ) ) ; var e = this . safe_read32s ( this . get_stack_pointer ( 12 ) ) , g = this . safe_read16 ( this . get_stack_pointer ( 16 ) ) ; a = this . safe_read16 ( this . get_stack_pointer ( 20 ) ) ; var f = this . safe_read16 ( this . get_stack_pointer ( 24 ) ) , k = this . safe_read16 ( this . get_stack_pointer ( 28 ) ) , l = this . safe_read16 ( this . get_stack_pointer ( 32 ) ) ; this . update_eflags ( d ) ; this . flags |= flag_vm ; this . switch_cs_real_mode ( c ) ; this . instruction_pointer = ( b & 65535 ) + this . get_seg ( reg_cs ) | 0 ; this . switch_seg ( reg_es , a ) ; this . switch_seg ( reg_ds , f ) ; this . switch_seg ( reg_fs , k ) ; this . switch_seg ( reg_gs , l ) ; this . adjust_stack_reg ( 36 ) ; this . reg32s [ reg_esp ] = e ; this . switch_seg ( reg_ss , g ) ; this . cpl = 3 ; this . cpl_changed ( ) ; this . update_cs_size ( ! 1 ) ; CPU_LOG_VERBOSE && this . debug . dump_state ( "iret end" ) ; return ; } dbg_log ( "vm86 flag ignored because cpl != 0" , LOG_CPU ) ; d &= ~ flag_vm ; } f = this . lookup_segment_selector ( c ) ; dbg_assert ( f . is_valid ) ; dbg_assert ( b >>> 0 <= f . effective_limit ) ; if ( f . is_null ) throw this . debug . unimpl ( "is null" ) ; if ( ! f . is_present ) throw this . debug . unimpl ( "not present" ) ; if ( ! f . is_executable ) throw this . debug . unimpl ( "not exec" ) ; if ( f . rpl < this . cpl ) throw this . debug . unimpl ( "rpl < cpl" ) ; if ( f . dc_bit && f . dpl > f . rpl ) throw this . debug . unimpl ( "conforming and dpl > rpl" ) ; f . dc_bit || f . rpl === f . dpl || ( dbg_log ( "#gp iret: non-conforming cs and rpl != dpl, dpl=" + f . dpl + " rpl=" + f . rpl , LOG_CPU ) , this . trigger_gp ( c & - 4 ) ) ; f . rpl > this . cpl ? ( a ? ( e = this . safe_read16 ( this . get_stack_pointer ( 6 ) ) , g = this . safe_read16 ( this . get_stack_pointer ( 8 ) ) ) : ( e = this . safe_read32s ( this . get_stack_pointer ( 12 ) ) , g = this . safe_read16 ( this . get_stack_pointer ( 16 ) ) ) , k = this . lookup_segment_selector ( g ) , l = f . rpl , k . is_null && ( dbg_log ( "#GP for loading 0 in SS sel=" + h ( g , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_gp ( 0 ) ) , k . is_valid && ! k . is_system && k . rpl === l && k . is_writable && k . dpl === l || ( dbg_log ( "#GP for loading invalid in SS sel=" + h ( g , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_gp ( g & - 4 ) ) , k . is_present || ( dbg_log ( "#SS for loading non-present in SS sel=" + h ( g , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_ss ( g & - 4 ) ) , a ? this . update_eflags ( d | this . flags & - 65536 ) : this . update_eflags ( d ) , this . cpl = f . rpl , this . cpl_changed ( ) , this . switch_seg ( reg_ss , g ) , this . set_stack_reg ( e ) , 0 === this . cpl && ( this . flags = this . flags & ~ flag_vif & ~ flag_vip | d & ( flag_vif | flag_vip ) ) ) : f . rpl === this . cpl ? ( a ? ( this . adjust_stack_reg ( 6 ) , this . update_eflags ( d | this . flags & - 65536 ) ) : ( this . adjust_stack_reg ( 12 ) , this . update_eflags ( d ) ) , 0 === this . cpl && ( this . flags = this . flags & ~ flag_vif & ~ flag_vip | d & ( flag_vif | flag_vip ) ) ) : dbg_assert ( ! 1 ) ; this . sreg [ reg_cs ] = c ; dbg_assert ( ( c & 3 ) === this . cpl ) ; this . update_cs_size ( f . size ) ; this . segment_limits [ reg_cs ] = f . effective_limit ; this . segment_offsets [ reg_cs ] = f . base ; this . instruction_pointer = b + this . get_seg ( reg_cs ) | 0 ; CPU_LOG_VERBOSE && this . debug . dump_state ( "iret" + ( a ? "16" : "32" ) + " end" ) ; } this . handle_irqs ( ) ; } ; CPU . prototype . switch_cs_real_mode = function ( a ) { dbg_assert ( ! this . protected_mode || this . vm86_mode ( ) ) ; this . sreg [ reg_cs ] = a ; this . segment_is_null [ reg_cs ] = 0 ; this . segment_offsets [ reg_cs ] = a << 4 ; } ; CPU . prototype . far_return = function ( a , b , c ) { dbg_assert ( "number" === typeof b && 65536 > b && 0 <= b ) ; CPU_LOG_VERBOSE && this . debug . dump_state ( "far ret start" ) ; this . protected_mode || dbg_assert ( ! this . is_32 ) ; if ( ! this . protected_mode || this . vm86_mode ( ) ) this . switch_cs_real_mode ( b ) , this . instruction_pointer = this . get_seg ( reg_cs ) + a | 0 , this . adjust_stack_reg ( 2 * ( this . is_osize_32 ( ) ? 4 : 2 ) + c ) ; else { var d = this . lookup_segment_selector ( b ) ; d . is_null && ( dbg_log ( "null cs" , LOG_CPU ) , this . trigger_gp ( 0 ) ) ; d . is_valid || ( dbg_log ( "invalid cs: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; d . is_system && ( dbg_assert ( ! 1 , "is system in far return" ) , this . trigger_gp ( b & - 4 ) ) ; d . is_executable || ( dbg_log ( "non-executable cs: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; d . rpl < this . cpl && ( dbg_log ( "cs rpl < cpl: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; d . dc_bit && d . dpl > d . rpl && ( dbg_log ( "cs conforming and dpl > rpl: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; d . dc_bit || d . dpl === d . rpl || ( dbg_log ( "cs non-conforming and dpl != rpl: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; d . is_present || ( dbg_log ( "#NP for loading not-present in cs sel=" + h ( b , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_np ( b & - 4 ) ) ; if ( d . rpl > this . cpl ) { dbg_log ( "far return privilege change cs: " + h ( b ) + " from=" + this . cpl + " to=" + d . rpl + " is_16=" + this . is_osize_32 ( ) , LOG_CPU ) ; if ( this . is_osize_32 ( ) ) var e = this . safe_read32s ( this . get_stack_pointer ( c + 8 ) ) , g = this . safe_read16 ( this . get_stack_pointer ( c + 12 ) ) ; else e = this . safe_read16 ( this . get_stack_pointer ( c + 4 ) ) , g = this . safe_read16 ( this . get_stack_pointer ( c + 6 ) ) ; this . cpl = d . rpl ; this . cpl_changed ( ) ; this . switch_seg ( reg_ss , g ) ; this . set_stack_reg ( e + c ) ; } else this . is_osize_32 ( ) ? this . adjust_stack_reg ( 8 + c ) : this . adjust_stack_reg ( 4 + c ) ; this . update_cs_size ( d . size ) ; this . segment_is_null [ reg_cs ] = 0 ; this . segment_limits [ reg_cs ] = d . effective_limit ; this . segment_offsets [ reg_cs ] = d . base ; this . sreg [ reg_cs ] = b ; dbg_assert ( ( b & 3 ) === this . cpl ) ; this . instruction_pointer = this . get_seg ( reg_cs ) + a | 0 ; CPU_LOG_VERBOSE && this . debug . dump_state ( "far ret end" ) ; } } ; CPU . prototype . far_jump = function ( a , b , c ) { dbg_assert ( "number" === typeof b && 65536 > b && 0 <= b ) ; CPU_LOG_VERBOSE && this . debug . dump_state ( "far " + [ "jump" , "call" ] [ + c ] ) ; if ( ! this . protected_mode || this . vm86_mode ( ) ) c && ( this . is_osize_32 ( ) ? ( this . writable_or_pagefault ( this . get_stack_pointer ( - 8 ) , 8 ) , this . push32 ( this . sreg [ reg_cs ] ) , this . push32 ( this . get_real_eip ( ) ) ) : ( this . writable_or_pagefault ( this . get_stack_pointer ( - 4 ) , 4 ) , this . push16 ( this . sreg [ reg_cs ] ) , this . push16 ( this . get_real_eip ( ) ) ) ) , this . switch_cs_real_mode ( b ) , this . instruction_pointer = this . get_seg ( reg_cs ) + a | 0 ; else { var d = this . lookup_segment_selector ( b ) ; d . is_null && ( dbg_log ( "#gp null cs" , LOG_CPU ) , this . trigger_gp ( 0 ) ) ; d . is_valid || ( dbg_log ( "#gp invalid cs: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; if ( d . is_system ) if ( dbg_assert ( c , "TODO: Jump" ) , dbg_log ( "system type cs: " + h ( b ) , LOG_CPU ) , 12 === d . type || 4 === d . type ) { a = 4 === d . type ; if ( d . dpl < this . cpl || d . dpl < d . rpl ) dbg_log ( "#gp cs gate dpl < cpl or dpl < rpl: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ; d . is_present || ( dbg_log ( "#NP for loading not-present in gate cs sel=" + h ( b , 4 ) , LOG_CPU ) , this . trigger_np ( b & - 4 ) ) ; b = d . raw0 >>> 16 ; var e = this . lookup_segment_selector ( b ) ; e . is_null && ( dbg_log ( "#gp null cs" , LOG_CPU ) , this . trigger_gp ( 0 ) ) ; e . is_valid || ( dbg_log ( "#gp invalid cs: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; e . is_executable || ( dbg_log ( "#gp non-executable cs: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; e . dpl > this . cpl && ( dbg_log ( "#gp dpl > cpl: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; e . is_present || ( dbg_log ( "#NP for loading not-present in cs sel=" + h ( b , 4 ) , LOG_CPU ) , this . trigger_np ( b & - 4 ) ) ; if ( ! e . dc_bit && e . dpl < this . cpl ) { dbg_log ( "more privilege call gate is_16=" + a + " from=" + this . cpl + " to=" + e . dpl ) ; var g = this . get_tss_stack_addr ( e . dpl ) ; if ( this . tss_size_32 ) { var f = this . read32s ( g ) ; g = this . read16 ( g + 4 | 0 ) ; } else f = this . read16 ( g ) , g = this . read16 ( g + 2 | 0 ) ; var k = this . lookup_segment_selector ( g ) ; dbg_assert ( k . is_valid && ! k . is_system && k . is_writable ) ; if ( k . is_null ) throw this . debug . unimpl ( "#TS handler" ) ; if ( k . rpl !== e . dpl ) throw this . debug . unimpl ( "#TS handler" ) ; if ( k . dpl !== e . dpl || ! k . rw_bit ) throw this . debug . unimpl ( "#TS handler" ) ; if ( ! k . is_present ) throw this . debug . unimpl ( "#SS handler" ) ; var l = d . raw1 & 31 , m = a ? 4 : 8 ; c && ( m += a ? 4 + 2 * l : 8 + 4 * l ) ; k . size ? this . writable_or_pagefault ( k . base + f - m | 0 , m ) : this . writable_or_pagefault ( k . base + ( f - m & 65535 ) | 0 , m ) ; m = this . reg32s [ reg_esp ] ; var n = this . sreg [ reg_ss ] ; k = this . get_stack_pointer ( 0 ) ; this . cpl = e . dpl ; this . cpl_changed ( ) ; this . update_cs_size ( e . size ) ; this . switch_seg ( reg_ss , g ) ; this . set_stack_reg ( f ) ; a ? ( this . push16 ( n ) , this . push16 ( m ) ) : ( this . push32 ( n ) , this . push32 ( m ) ) ; if ( c ) if ( a ) { for ( f = l - 1 ; 0 <= f ; f -- ) g = this . safe_read16 ( k + 2 * f ) , this . push16 ( g ) ; this . push16 ( this . sreg [ reg_cs ] ) ; this . push16 ( this . get_real_eip ( ) ) ; } else { for ( f = l - 1 ; 0 <= f ; f -- ) g = this . safe_read32s ( k + 4 * f ) , this . push32 ( g ) ; this . push32 ( this . sreg [ reg_cs ] ) ; this . push32 ( this . get_real_eip ( ) ) ; } } else dbg_log ( "same privilege call gate is_16=" + a + " from=" + this . cpl + " to=" + e . dpl + " conforming=" + e . dc_bit ) , c && ( a ? ( this . writable_or_pagefault ( this . get_stack_pointer ( - 4 ) , 4 ) , this . push16 ( this . sreg [ reg_cs ] ) , this . push16 ( this . get_real_eip ( ) ) ) : ( this . writable_or_pagefault ( this . get_stack_pointer ( - 8 ) , 8 ) , this . push32 ( this . sreg [ reg_cs ] ) , this . push32 ( this . get_real_eip ( ) ) ) ) ; f = d . raw0 & 65535 ; a || ( f |= d . raw1 & 4294901760 ) ; dbg_log ( "call gate eip=" + h ( f >>> 0 ) + " cs=" + h ( b ) + " conforming=" + e . dc_bit ) ; dbg_assert ( f >>> 0 <= e . effective_limit , "todo: #gp" ) ; this . update_cs_size ( e . size ) ; this . segment_is_null [ reg_cs ] = 0 ; this . segment_limits [ reg_cs ] = e . effective_limit ; this . segment_offsets [ reg_cs ] = e . base ; this . sreg [ reg_cs ] = b & - 4 | this . cpl ; dbg_assert ( ( this . sreg [ reg_cs ] & 3 ) === this . cpl ) ; this . instruction_pointer = this . get_seg ( reg_cs ) + f | 0 ; } else throw this . debug . unimpl ( "load system segment descriptor, type = " + ( d . access & 15 ) + " (" + { 9 : "Available 386 TSS" , 11 : "Busy 386 TSS" , 4 : "286 Call Gate" , 12 : "386 Call Gate" } [ d . access & 15 ] + ")" ) ; else { d . is_executable || ( dbg_log ( "#gp non-executable cs: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; if ( d . dc_bit ) d . dpl > this . cpl && ( dbg_log ( "#gp cs dpl > cpl: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) ; else if ( d . rpl > this . cpl || d . dpl !== this . cpl ) dbg_log ( "#gp cs rpl > cpl or dpl != cpl: " + h ( b ) , LOG_CPU ) , this . trigger_gp ( b & - 4 ) ; d . is_present || ( dbg_log ( "#NP for loading not-present in cs sel=" + h ( b , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_np ( b & - 4 ) ) ; c && ( this . is_osize_32 ( ) ? ( this . writable_or_pagefault ( this . get_stack_pointer ( - 8 ) , 8 ) , this . push32 ( this . sreg [ reg_cs ] ) , this . push32 ( this . get_real_eip ( ) ) ) : ( this . writable_or_pagefault ( this . get_stack_pointer ( - 4 ) , 4 ) , this . push16 ( this . sreg [ reg_cs ] ) , this . push16 ( this . get_real_eip ( ) ) ) ) ; dbg_assert ( a >>> 0 <= d . effective_limit , "todo: #gp" ) ; this . update_cs_size ( d . size ) ; this . segment_is_null [ reg_cs ] = 0 ; this . segment_limits [ reg_cs ] = d . effective_limit ; this . segment_offsets [ reg_cs ] = d . base ; this . sreg [ reg_cs ] = b & - 4 | this . cpl ; this . instruction_pointer = this . get_seg ( reg_cs ) + a | 0 ; } CPU_LOG_VERBOSE && this . debug . dump_state ( "far " + [ "jump" , "call" ] [ + c ] + " end" ) ; } } ; CPU . prototype . get_tss_stack_addr = function ( a ) { if ( this . tss_size_32 ) { a = ( a << 3 ) + 4 | 0 ; if ( ( a + 5 | 0 ) > this . segment_limits [ reg_tr ] ) throw this . debug . unimpl ( "#TS handler" ) ; a = a + this . segment_offsets [ reg_tr ] | 0 ; dbg_assert ( 4090 >= ( a & 4095 ) ) ; } else { a = ( a << 2 ) + 2 | 0 ; if ( ( a + 5 | 0 ) > this . segment_limits [ reg_tr ] ) throw this . debug . unimpl ( "#TS handler" ) ; a = a + this . segment_offsets [ reg_tr ] | 0 ; dbg_assert ( 4092 >= ( a & 4095 ) ) ; } this . paging && ( a = this . translate_address_system_read ( a ) ) ; return a ; } ; CPU . prototype . do_task_switch = function ( a , b ) { dbg_assert ( this . tss_size_32 , "TODO" ) ; dbg_log ( "do_task_switch sel=" + h ( a ) , LOG_CPU ) ; var c = this . lookup_segment_selector ( a ) ; dbg_assert ( 3 === ( c . type | 2 ) || 11 === ( c . type | 2 ) ) ; var d = 3 >= c . type , e = 2 === ( c . type & 2 ) ; if ( ! c . is_valid || c . is_null || ! c . from_gdt ) throw this . debug . unimpl ( "#GP handler" ) ; if ( 11 === ( c . access & 31 ) ) throw this . debug . unimpl ( "#GP handler" ) ; if ( ! c . is_present ) throw this . debug . unimpl ( "#NP handler" ) ; if ( 103 > c . effective_limit ) throw this . debug . unimpl ( "#NP handler" ) ; var g = this . segment_offsets [ reg_tr ] , f = this . get_eflags ( ) ; e && ( f &= ~ flag_nt ) ; this . writable_or_pagefault ( g , 102 ) ; this . safe_write32 ( g + TSR_EIP , this . get_real_eip ( ) ) ; this . safe_write32 ( g + TSR_EFLAGS , f ) ; this . safe_write32 ( g + TSR_EAX , this . reg32s [ reg_eax ] ) ; this . safe_write32 ( g + TSR_ECX , this . reg32s [ reg_ecx ] ) ; this . safe_write32 ( g + TSR_EDX , this . reg32s [ reg_edx ] ) ; this . safe_write32 ( g + TSR_EBX , this . reg32s [ reg_ebx ] ) ; this . safe_write32 ( g + TSR_ESP , this . reg32s [ reg_esp ] ) ; this . safe_write32 ( g + TSR_EBP , this . reg32s [ reg_ebp ] ) ; this . safe_write32 ( g + TSR_ESI , this . reg32s [ reg_esi ] ) ; this . safe_write32 ( g + TSR_EDI , this . reg32s [ reg_edi ] ) ; this . safe_write32 ( g + TSR_ES , this . sreg [ reg_es ] ) ; this . safe_write32 ( g + TSR_CS , this . sreg [ reg_cs ] ) ; this . safe_write32 ( g + TSR_SS , this . sreg [ reg_ss ] ) ; this . safe_write32 ( g + TSR_DS , this . sreg [ reg_ds ] ) ; this . safe_write32 ( g + TSR_FS , this . sreg [ reg_fs ] ) ; this . safe_write32 ( g + TSR_GS , this . sreg [ reg_gs ] ) ; this . write8 ( c . table_offset + 5 | 0 , this . read8 ( c . table_offset + 5 | 0 ) | 2 ) ; e = c . base ; dbg_assert ( ! d , "unimplemented" ) ; this . safe_write16 ( e + TSR_BACKLINK , this . sreg [ reg_tr ] ) ; f = this . safe_read32s ( e + TSR_CR3 ) ; this . flags &= ~ flag_vm ; var k = this . safe_read32s ( e + TSR_EIP ) , l = this . safe_read16 ( e + TSR_CS ) , m = this . lookup_segment_selector ( l ) ; if ( m . is_null ) throw dbg_log ( "null cs" , LOG_CPU ) , this . debug . unimpl ( "#TS handler" ) ; if ( ! m . is_valid ) throw dbg_log ( "invalid cs: " + h ( a ) , LOG_CPU ) , this . debug . unimpl ( "#TS handler" ) ; if ( m . is_system ) throw this . debug . unimpl ( "#TS handler" ) ; if ( ! m . is_executable ) throw this . debug . unimpl ( "#TS handler" ) ; if ( m . dc_bit && m . dpl > m . rpl ) throw dbg_log ( "cs conforming and dpl > rpl: " + h ( a ) , LOG_CPU ) , this . debug . unimpl ( "#TS handler" ) ; if ( ! m . dc_bit && m . dpl !== m . rpl ) throw dbg_log ( "cs non-conforming and dpl != rpl: " + h ( a ) , LOG_CPU ) , this . debug . unimpl ( "#TS handler" ) ; if ( ! m . is_present ) throw dbg_log ( "#NP for loading not-present in cs sel=" + h ( a , 4 ) , LOG_CPU ) , this . debug . unimpl ( "#TS handler" ) ; this . segment_is_null [ reg_cs ] = 0 ; this . segment_limits [ reg_cs ] = m . effective_limit ; this . segment_offsets [ reg_cs ] = m . base ; this . sreg [ reg_cs ] = l ; this . cpl = m . dpl ; this . cpl_changed ( ) ; dbg_assert ( ( this . sreg [ reg_cs ] & 3 ) === this . cpl ) ; dbg_assert ( k >>> 0 <= m . effective_limit , "todo: #gp" ) ; this . update_cs_size ( m . size ) ; l = this . safe_read32s ( e + TSR_EFLAGS ) ; this . safe_write32 ( g + TSR_BACKLINK , a ) ; l |= flag_nt ; if ( l & flag_vm ) throw this . debug . unimpl ( "task switch to VM mode" ) ; this . update_eflags ( l ) ; this . flags |= flag_nt ; g = this . safe_read16 ( e + TSR_LDT ) ; this . load_ldt ( g ) ; this . reg32s [ reg_eax ] = this . safe_read32s ( e + TSR_EAX ) ; this . reg32s [ reg_ecx ] = this . safe_read32s ( e + TSR_ECX ) ; this . reg32s [ reg_edx ] = this . safe_read32s ( e + TSR_EDX ) ; this . reg32s [ reg_ebx ] = this . safe_read32s ( e + TSR_EBX ) ; this . reg32s [ reg_esp ] = this . safe_read32s ( e + TSR_ESP ) ; this . reg32s [ reg_ebp ] = this . safe_read32s ( e + TSR_EBP ) ; this . reg32s [ reg_esi ] = this . safe_read32s ( e + TSR_ESI ) ; this . reg32s [ reg_edi ] = this . safe_read32s ( e + TSR_EDI ) ; this . switch_seg ( reg_es , this . safe_read16 ( e + TSR_ES ) ) ; this . switch_seg ( reg_ss , this . safe_read16 ( e + TSR_SS ) ) ; this . switch_seg ( reg_ds , this . safe_read16 ( e + TSR_DS ) ) ; this . switch_seg ( reg_fs , this . safe_read16 ( e + TSR_FS ) ) ; this . switch_seg ( reg_gs , this . safe_read16 ( e + TSR_GS ) ) ; this . instruction_pointer = this . get_seg ( reg_cs ) + k | 0 ; this . segment_offsets [ reg_tr ] = c . base ; this . segment_limits [ reg_tr ] = c . effective_limit ; this . sreg [ reg_tr ] = a ; this . cr [ 3 ] = f ; dbg_assert ( 0 === ( this . cr [ 3 ] & 4095 ) ) ; this . clear_tlb ( ) ; this . cr [ 0 ] |= CR0_TS ; ! 1 !== b && ( d ? this . push16 ( b & 65535 ) : this . push32 ( b ) ) ; } ; CPU . prototype . hlt_op = function ( ) { this . cpl && this . trigger_gp ( 0 ) ; if ( 0 === ( this . flags & flag_interrupt ) ) throw this . debug . show ( "cpu halted" ) , this . bus . send ( "cpu-event-halt" ) , DEBUG && this . debug . dump_regs ( ) , "HALT" ; this . in_hlt = ! 0 ; throw MAGIC_CPU_EXCEPTION ; } ; CPU . prototype . raise_exception = function ( a ) { this . call_interrupt_vector ( a , ! 1 , ! 1 ) ; throw MAGIC_CPU_EXCEPTION ; } ; CPU . prototype . raise_exception_with_code = function ( a , b ) { dbg_assert ( "number" === typeof b ) ; this . call_interrupt_vector ( a , ! 1 , b ) ; throw MAGIC_CPU_EXCEPTION ; } ; CPU . prototype . trigger_de = function ( ) { this . instruction_pointer = this . previous_ip ; this . raise_exception ( 0 ) ; } ; CPU . prototype . trigger_ud = function ( ) { this . instruction_pointer = this . previous_ip ; this . raise_exception ( 6 ) ; } ; CPU . prototype . trigger_nm = function ( ) { this . instruction_pointer = this . previous_ip ; this . raise_exception ( 7 ) ; } ; CPU . prototype . trigger_ts = function ( a ) { this . instruction_pointer = this . previous_ip ; this . raise_exception_with_code ( 10 , a ) ; } ; CPU . prototype . trigger_gp = function ( a ) { this . instruction_pointer = this . previous_ip ; this . raise_exception_with_code ( 13 , a ) ; } ; CPU . prototype . trigger_np = function ( a ) { this . instruction_pointer = this . previous_ip ; this . raise_exception_with_code ( 11 , a ) ; } ; CPU . prototype . trigger_ss = function ( a ) { this . instruction_pointer = this . previous_ip ; this . raise_exception_with_code ( 12 , a ) ; } ; CPU . prototype . task_switch_test = function ( ) { this . cr [ 0 ] & ( CR0_EM | CR0_TS ) && this . trigger_nm ( ) ; } ; CPU . prototype . task_switch_test_mmx = function ( ) { this . cr [ 0 ] & ( CR0_EM | CR0_TS ) && ( this . cr [ 0 ] & CR0_TS ? this . trigger_nm ( ) : this . trigger_ud ( ) ) ; } ; CPU . prototype . todo = function ( ) { if ( DEBUG ) throw dbg_trace ( ) , "TODO" ; this . trigger_ud ( ) ; } ; CPU . prototype . undefined_instruction = function ( ) { dbg_assert ( ! 1 , "Possible fault: undefined instruction" ) ; this . trigger_ud ( ) ; } ; CPU . prototype . unimplemented_sse = function ( ) { dbg_log ( "No SSE" , LOG_CPU ) ; dbg_assert ( ! 1 ) ; this . trigger_ud ( ) ; } ; CPU . prototype . get_seg_prefix_ds = function ( ) { return this . get_seg_prefix ( reg_ds ) ; } ; CPU . prototype . get_seg_prefix_ss = function ( ) { return this . get_seg_prefix ( reg_ss ) ; } ; CPU . prototype . get_seg_prefix_cs = function ( ) { return this . get_seg_prefix ( reg_cs ) ; } ; CPU . prototype . get_seg_prefix = function ( a ) { var b = this . prefixes & PREFIX_MASK_SEGMENT ; return b ? b === SEG_PREFIX_ZERO ? 0 : this . get_seg ( b - 1 ) : this . get_seg ( a ) ; } ; CPU . prototype . get_seg = function ( a ) { dbg_assert ( 0 <= a && 8 > a ) ; this . protected_mode && this . segment_is_null [ a ] && ( dbg_assert ( a !== reg_cs && a !== reg_ss ) , dbg_trace ( ) , dbg_log ( "#gp Use null segment: " + a + " sel=" + h ( this . sreg [ a ] , 4 ) , LOG_CPU ) , this . trigger_gp ( 0 ) ) ; return this . segment_offsets [ a ] ; } ; CPU . prototype . read_e8 = function ( ) { return 192 > this . modrm_byte ? this . safe_read8 ( this . modrm_resolve ( this . modrm_byte ) ) : this . reg8 [ this . modrm_byte << 2 & 12 | this . modrm_byte >> 2 & 1 ] ; } ; CPU . prototype . read_e8s = function ( ) { return this . read_e8 ( ) << 24 >> 24 ; } ; CPU . prototype . read_e16 = function ( ) { return 192 > this . modrm_byte ? this . safe_read16 ( this . modrm_resolve ( this . modrm_byte ) ) : this . reg16 [ this . modrm_byte << 1 & 14 ] ; } ; CPU . prototype . read_e16s = function ( ) { return this . read_e16 ( ) << 16 >> 16 ; } ; CPU . prototype . read_e32s = function ( ) { return 192 > this . modrm_byte ? this . safe_read32s ( this . modrm_resolve ( this . modrm_byte ) ) : this . reg32s [ this . modrm_byte & 7 ] ; } ; CPU . prototype . read_e32 = function ( ) { return this . read_e32s ( ) >>> 0 ; } ; CPU . prototype . read_mmx_mem32s = function ( ) { return 192 > this . modrm_byte ? this . safe_read32s ( this . modrm_resolve ( this . modrm_byte ) ) : this . reg_mmxs [ 2 * ( this . modrm_byte & 7 ) ] ; } ; CPU . prototype . read_mmx_mem64s = function ( ) { return 192 > this . modrm_byte ? this . safe_read64s ( this . modrm_resolve ( this . modrm_byte ) ) : this . create_atom64s ( this . reg_mmxs [ 2 * ( this . modrm_byte & 7 ) ] , this . reg_mmxs [ 2 * ( this . modrm_byte & 7 ) + 1 ] ) ; } ; CPU . prototype . read_xmm_mem64s = function ( ) { if ( 192 > this . modrm_byte ) return this . safe_read64s ( this . modrm_resolve ( this . modrm_byte ) ) ; var a = ( this . modrm_byte & 7 ) << 2 ; return this . create_atom64s ( this . reg_xmm32s [ a ] , this . reg_xmm32s [ a | 1 ] ) ; } ; CPU . prototype . read_xmm_mem128s = function ( ) { if ( 192 > this . modrm_byte ) return this . safe_read128s_aligned ( this . modrm_resolve ( this . modrm_byte ) ) ; var a = ( this . modrm_byte & 7 ) << 2 ; return this . create_atom128s ( this . reg_xmm32s [ a ] , this . reg_xmm32s [ a | 1 ] , this . reg_xmm32s [ a | 2 ] , this . reg_xmm32s [ a | 3 ] ) ; } ; CPU . prototype . read_xmm_mem128s_unaligned = function ( ) { if ( 192 > this . modrm_byte ) return this . safe_read128s_unaligned ( this . modrm_resolve ( this . modrm_byte ) ) ; var a = ( this . modrm_byte & 7 ) << 2 ; return this . create_atom128s ( this . reg_xmm32s [ a ] , this . reg_xmm32s [ a | 1 ] , this . reg_xmm32s [ a | 2 ] , this . reg_xmm32s [ a | 3 ] ) ; } ; CPU . prototype . set_e8 = function ( a ) { if ( 192 > this . modrm_byte ) { var b = this . modrm_resolve ( this . modrm_byte ) ; this . safe_write8 ( b , a ) ; } else this . reg8 [ this . modrm_byte << 2 & 12 | this . modrm_byte >> 2 & 1 ] = a ; } ; CPU . prototype . set_e16 = function ( a ) { if ( 192 > this . modrm_byte ) { var b = this . modrm_resolve ( this . modrm_byte ) ; this . safe_write16 ( b , a ) ; } else this . reg16 [ this . modrm_byte << 1 & 14 ] = a ; } ; CPU . prototype . set_e32 = function ( a ) { if ( 192 > this . modrm_byte ) { var b = this . modrm_resolve ( this . modrm_byte ) ; this . safe_write32 ( b , a ) ; } else this . reg32s [ this . modrm_byte & 7 ] = a ; } ; CPU . prototype . set_mmx_mem64s = function ( a , b ) { if ( 192 > this . modrm_byte ) { var c = this . modrm_resolve ( this . modrm_byte ) ; this . safe_write64 ( c , a , b ) ; } else this . reg_mmxs [ 2 * ( this . modrm_byte & 7 ) ] = a , this . reg_mmxs [ 2 * ( this . modrm_byte & 7 ) + 1 ] = b ; } ; CPU . prototype . read_write_e8 = function ( ) { if ( 192 > this . modrm_byte ) { var a = this . modrm_resolve ( this . modrm_byte ) ; this . phys_addr = this . translate_address_write ( a ) ; return this . read8 ( this . phys_addr ) ; } return this . reg8 [ this . modrm_byte << 2 & 12 | this . modrm_byte >> 2 & 1 ] ; } ; CPU . prototype . write_e8 = function ( a ) { 192 > this . modrm_byte ? this . write8 ( this . phys_addr , a ) : this . reg8 [ this . modrm_byte << 2 & 12 | this . modrm_byte >> 2 & 1 ] = a ; } ; CPU . prototype . read_write_e16 = function ( ) { if ( 192 > this . modrm_byte ) { var a = this . modrm_resolve ( this . modrm_byte ) ; this . phys_addr = this . translate_address_write ( a ) ; if ( this . paging && 4095 === ( a & 4095 ) ) return this . phys_addr_high = this . translate_address_write ( a + 1 | 0 ) , dbg_assert ( this . phys_addr_high ) , this . virt_boundary_read16 ( this . phys_addr , this . phys_addr_high ) ; this . phys_addr_high = 0 ; return this . read16 ( this . phys_addr ) ; } return this . reg16 [ this . modrm_byte << 1 & 14 ] ; } ; CPU . prototype . write_e16 = function ( a ) { 192 > this . modrm_byte ? this . phys_addr_high ? this . virt_boundary_write16 ( this . phys_addr , this . phys_addr_high , a ) : this . write16 ( this . phys_addr , a ) : this . reg16 [ this . modrm_byte << 1 & 14 ] = a ; } ; CPU . prototype . read_write_e32 = function ( ) { if ( 192 > this . modrm_byte ) { var a = this . modrm_resolve ( this . modrm_byte ) ; this . phys_addr = this . translate_address_write ( a ) ; if ( this . paging && 4093 <= ( a & 4095 ) ) return this . phys_addr_high = this . translate_address_write ( a + 3 & - 4 ) | a + 3 & 3 , dbg_assert ( this . phys_addr_high ) , this . virt_boundary_read32s ( this . phys_addr , this . phys_addr_high ) ; this . phys_addr_high = 0 ; return this . read32s ( this . phys_addr ) ; } return this . reg32s [ this . modrm_byte & 7 ] ; } ; CPU . prototype . write_e32 = function ( a ) { 192 > this . modrm_byte ? this . phys_addr_high ? this . virt_boundary_write32 ( this . phys_addr , this . phys_addr_high , a ) : this . write32 ( this . phys_addr , a ) : this . reg32s [ this . modrm_byte & 7 ] = a ; } ; CPU . prototype . read_reg_e16 = function ( ) { return this . reg16 [ this . modrm_byte << 1 & 14 ] ; } ; CPU . prototype . write_reg_e16 = function ( a ) { this . reg16 [ this . modrm_byte << 1 & 14 ] = a ; } ; CPU . prototype . read_reg_e32s = function ( ) { return this . reg32s [ this . modrm_byte & 7 ] ; } ; CPU . prototype . write_reg_e32 = function ( a ) { this . reg32s [ this . modrm_byte & 7 ] = a ; } ; CPU . prototype . read_g8 = function ( ) { return this . reg8 [ this . modrm_byte >> 1 & 12 | this . modrm_byte >> 5 & 1 ] ; } ; CPU . prototype . write_g8 = function ( a ) { this . reg8 [ this . modrm_byte >> 1 & 12 | this . modrm_byte >> 5 & 1 ] = a ; } ; CPU . prototype . read_g16 = function ( ) { return this . reg16 [ this . modrm_byte >> 2 & 14 ] ; } ; CPU . prototype . read_g16s = function ( ) { return this . reg16s [ this . modrm_byte >> 2 & 14 ] ; } ; CPU . prototype . write_g16 = function ( a ) { this . reg16 [ this . modrm_byte >> 2 & 14 ] = a ; } ; CPU . prototype . read_g32s = function ( ) { return this . reg32s [ this . modrm_byte >> 3 & 7 ] ; } ; CPU . prototype . write_g32 = function ( a ) { this . reg32 [ this . modrm_byte >> 3 & 7 ] = a ; } ; CPU . prototype . read_xmm64s = function ( ) { return this . create_atom64s ( this . reg_xmm32s [ ( this . modrm_byte >> 3 & 7 ) << 2 ] , this . reg_xmm32s [ ( this . modrm_byte >> 3 & 7 ) << 2 | 1 ] ) ; } ; CPU . prototype . read_xmm128s = function ( ) { var a = ( this . modrm_byte >> 3 & 7 ) << 2 ; return this . create_atom128s ( this . reg_xmm32s [ a | 0 ] , this . reg_xmm32s [ a | 1 ] , this . reg_xmm32s [ a | 2 ] , this . reg_xmm32s [ a | 3 ] ) ; } ; CPU . prototype . read_mmx64s = function ( ) { return this . create_atom64s ( this . reg_mmxs [ 2 * ( this . modrm_byte >> 3 & 7 ) ] , this . reg_mmxs [ 2 * ( this . modrm_byte >> 3 & 7 ) + 1 ] ) ; } ; CPU . prototype . write_mmx64s = function ( a , b ) { this . reg_mmxs [ 2 * ( this . modrm_byte >> 3 & 7 ) ] = a ; this . reg_mmxs [ 2 * ( this . modrm_byte >> 3 & 7 ) + 1 ] = b ; } ; CPU . prototype . write_xmm64 = function ( a , b ) { var c = ( this . modrm_byte >> 3 & 7 ) << 2 ; this . reg_xmm32s [ c ] = a ; this . reg_xmm32s [ c + 1 ] = b ; } ; CPU . prototype . write_xmm128s = function ( a , b , c , d ) { var e = ( this . modrm_byte >> 3 & 7 ) << 2 ; this . reg_xmm32s [ e ] = a ; this . reg_xmm32s [ e + 1 ] = b ; this . reg_xmm32s [ e + 2 ] = c ; this . reg_xmm32s [ e + 3 ] = d ; } ; CPU . prototype . pic_call_irq = function ( a ) { try { this . previous_ip = this . instruction_pointer , this . call_interrupt_vector ( a , ! 1 , ! 1 ) ; } catch ( b ) { this . exception_cleanup ( b ) ; } } ; CPU . prototype . handle_irqs = function ( ) { dbg_assert ( ! this . page_fault ) ; this . diverged ( ) ; this . flags & flag_interrupt && ! this . page_fault && ( this . devices . pic && this . devices . pic . acknowledge_irq ( ) , this . devices . apic && this . devices . apic . acknowledge_irq ( ) ) ; } ; CPU . prototype . device_raise_irq = function ( a ) { dbg_assert ( 1 === arguments . length ) ; this . devices . pic && this . devices . pic . set_irq ( a ) ; this . devices . ioapic && this . devices . ioapic . set_irq ( a ) ; } ; CPU . prototype . device_lower_irq = function ( a ) { this . devices . pic && this . devices . pic . clear_irq ( a ) ; this . devices . ioapic && this . devices . ioapic . clear_irq ( a ) ; } ; CPU . prototype . test_privileges_for_io = function ( a , b ) { if ( this . protected_mode && ( this . cpl > this . getiopl ( ) || this . flags & flag_vm ) ) { this . tss_size_32 || ( dbg_log ( "#GP for port io, 16-bit TSS  port=" + h ( a ) + " size=" + b , LOG_CPU ) , CPU_LOG_VERBOSE && this . debug . dump_state ( ) , this . trigger_gp ( 0 ) ) ; var c = this . segment_limits [ reg_tr ] , d = this . segment_offsets [ reg_tr ] ; if ( 103 <= c ) { dbg_assert ( 4095 > ( d + 100 + 2 & 4095 ) ) ; var e = this . read16 ( this . translate_address_system_read ( d + 100 + 2 | 0 ) ) ; if ( c >= ( e + ( ( a + b - 1 | 0 ) >> 3 ) | 0 ) && ( c = ( 1 << b ) - 1 << ( a & 7 ) , d = this . translate_address_system_read ( d + e + ( a >> 3 ) | 0 ) , e = c & 65280 ? this . read16 ( d ) : this . read8 ( d ) , dbg_assert ( 4095 > ( d & 4095 ) ) , ! ( e & c ) ) ) return ; } dbg_log ( "#GP for port io  port=" + h ( a ) + " size=" + b , LOG_CPU ) ; CPU_LOG_VERBOSE && this . debug . dump_state ( ) ; this . trigger_gp ( 0 ) ; } } ; CPU . prototype . cpuid = function ( ) { var a = 0 , b = 0 , c = 0 , d = 0 ; switch ( this . reg32s [ reg_eax ] ) { case 0 : a = 5 ; d = 1970169159 ; c = 1231384169 ; b = 1818588270 ; break ; case 1 : a = 3939 ; d = 67584 ; b = 1082130432 ; VMWARE_HYPERVISOR_PORT && ( b |= - 2147483648 ) ; c = ( this . fpu ? 1 : 0 ) | 43320 ; ENABLE_ACPI && this . apic_enabled && ( c |= 512 ) ; break ; case 2 : a = 1717260289 ; b = d = 0 ; c = 8024064 ; break ; case 4 : switch ( this . reg32s [ reg_ecx ] ) { case 0 : a = 289 ; d = 29360191 ; b = 63 ; c = 1 ; break ; case 1 : a = 290 ; d = 29360191 ; b = 63 ; c = 1 ; break ; case 2 : a = 323 , d = 96469055 , b = 4095 , c = 1 ; } break ; case 5 : d = a = 64 ; b = 3 ; c = 1319200 ; break ; case - 2147483648 : a = 5 ; break ; case 1073741824 : VMWARE_HYPERVISOR_PORT && ( d = 1635208534 , b = 1297507698 , c = 1701994871 ) ; break ; default : dbg_log ( "cpuid: unimplemented eax: " + h ( this . reg32 [ reg_eax ] ) , LOG_CPU ) ; } dbg_log ( "cpuid: eax=" + h ( this . reg32 [ reg_eax ] , 8 ) + " cl=" + h ( this . reg8 [ reg_cl ] , 2 ) , LOG_CPU ) ; this . reg32s [ reg_eax ] = a ; this . reg32s [ reg_ecx ] = b ; this . reg32s [ reg_edx ] = c ; this . reg32s [ reg_ebx ] = d ; } ; CPU . prototype . update_cs_size = function ( a ) { dbg_assert ( "boolean" === typeof a ) ; this . is_32 !== a && ( this . clear_instruction_cache ( ) , this . is_32 = a , this . update_operand_size ( ) ) ; } ; CPU . prototype . update_operand_size = function ( ) { this . table = this . is_32 ? this . table32 : this . table16 ; } ; CPU . prototype . lookup_segment_selector = function ( a ) { dbg_assert ( "number" === typeof a && 0 <= a && 65536 > a ) ; var b = 0 === ( a & 4 ) , c = a & - 8 ; var d = { rpl : a & 3 , from_gdt : b , is_null : ! 1 , is_valid : ! 0 , base : 0 , access : 0 , flags : 0 , type : 0 , dpl : 0 , is_system : ! 1 , is_present : ! 1 , is_executable : ! 1 , rw_bit : ! 1 , dc_bit : ! 1 , size : ! 1 , is_conforming_executable : ! 1 , effective_limit : 0 , is_writable : ! 1 , is_readable : ! 1 , table_offset : 0 , raw0 : 0 , raw1 : 0 } ; if ( b ) { var e = this . gdtr_offset ; var g = this . gdtr_size ; } else e = this . segment_offsets [ reg_ldtr ] , g = this . segment_limits [ reg_ldtr ] ; if ( b && 0 === c ) return d . is_null = ! 0 , d ; if ( ( a | 7 ) > g ) return dbg_log ( "Selector " + h ( a , 4 ) + " is outside of the " + ( b ? "g" : "l" ) + "dt limits" , LOG_CPU ) , d . is_valid = ! 1 , d ; e = e + c | 0 ; this . paging && ( e = this . translate_address_system_read ( e ) ) ; d . table_offset = e ; d . base = this . read16 ( e + 2 | 0 ) | this . read8 ( e + 4 | 0 ) << 16 | this . read8 ( e + 7 | 0 ) << 24 ; d . access = this . read8 ( e + 5 | 0 ) ; d . flags = this . read8 ( e + 6 | 0 ) >> 4 ; d . raw0 = this . read32s ( e | 0 ) ; d . raw1 = this . read32s ( e + 4 | 0 ) ; d . type = d . access & 15 ; d . dpl = d . access >> 5 & 3 ; d . is_system = 0 === ( d . access & 16 ) ; d . is_present = 128 === ( d . access & 128 ) ; d . is_executable = 8 === ( d . access & 8 ) ; d . rw_bit = 2 === ( d . access & 2 ) ; d . dc_bit = 4 === ( d . access & 4 ) ; d . is_conforming_executable = d . dc_bit && d . is_executable ; d . size = 4 === ( d . flags & 4 ) ; a = this . read16 ( e ) | ( this . read8 ( e + 6 | 0 ) & 15 ) << 16 ; d . effective_limit = d . flags & 8 ? ( a << 12 | 4095 ) >>> 0 : a ; d . is_writable = d . rw_bit && ! d . is_executable ; d . is_readable = d . rw_bit || ! d . is_executable ; return d ; } ; CPU . prototype . switch_seg = function ( a , b ) { dbg_assert ( 0 <= a && 5 >= a ) ; dbg_assert ( "number" === typeof b && 65536 > b && 0 <= b ) ; if ( ! this . protected_mode || this . vm86_mode ( ) ) this . sreg [ a ] = b , this . segment_is_null [ a ] = 0 , this . segment_offsets [ a ] = b << 4 , a === reg_ss && ( this . stack_size_32 = ! 1 ) ; else { var c = this . lookup_segment_selector ( b ) ; if ( a === reg_ss ) c . is_null && ( dbg_log ( "#GP for loading 0 in SS sel=" + h ( b , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_gp ( 0 ) ) , c . is_valid && ! c . is_system && c . rpl === this . cpl && c . is_writable && c . dpl === this . cpl || ( dbg_log ( "#GP for loading invalid in SS sel=" + h ( b , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_gp ( b & - 4 ) ) , c . is_present || ( dbg_log ( "#SS for loading non-present in SS sel=" + h ( b , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_ss ( b & - 4 ) ) , this . stack_size_32 = c . size ; else if ( a === reg_cs ) dbg_assert ( ! 1 ) ; else { if ( c . is_null ) { this . sreg [ a ] = b ; this . segment_is_null [ a ] = 1 ; return ; } if ( ! c . is_valid || c . is_system || ! c . is_readable || ! c . is_conforming_executable && ( c . rpl > c . dpl || this . cpl > c . dpl ) ) dbg_log ( "#GP for loading invalid in seg " + a + " sel=" + h ( b , 4 ) , LOG_CPU ) , this . debug . dump_state ( ) , this . debug . dump_regs ( ) , dbg_trace ( LOG_CPU ) , this . trigger_gp ( b & - 4 ) ; c . is_present || ( dbg_log ( "#NP for loading not-present in seg " + a + " sel=" + h ( b , 4 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) , this . trigger_np ( b & - 4 ) ) ; } this . segment_is_null [ a ] = 0 ; this . segment_limits [ a ] = c . effective_limit ; this . segment_offsets [ a ] = c . base ; this . sreg [ a ] = b ; } } ; CPU . prototype . load_tr = function ( a ) { var b = this . lookup_segment_selector ( a ) ; dbg_assert ( b . is_valid ) ; if ( ! b . from_gdt ) throw this . debug . unimpl ( "TR can only be loaded from GDT" ) ; if ( b . is_null ) throw dbg_log ( "#GP(0) | tried to load null selector (ltr)" ) , this . debug . unimpl ( "#GP handler" ) ; if ( ! b . is_system ) throw dbg_log ( "#GP | ltr: not a system entry" ) , this . debug . unimpl ( "#GP handler (happens when running kvm-unit-test without ACPI)" ) ; if ( 9 !== b . type && 1 !== b . type ) throw dbg_log ( "#GP | ltr: invalid type (type = " + h ( b . type ) + ")" ) , this . debug . unimpl ( "#GP handler" ) ; if ( ! b . is_present ) throw dbg_log ( "#NT | present bit not set (ltr)" ) , this . debug . unimpl ( "#NT handler" ) ; this . tss_size_32 = 9 === b . type ; this . segment_offsets [ reg_tr ] = b . base ; this . segment_limits [ reg_tr ] = b . effective_limit ; this . sreg [ reg_tr ] = a ; this . write8 ( b . table_offset + 5 | 0 , this . read8 ( b . table_offset + 5 | 0 ) | 2 ) ; } ; CPU . prototype . load_ldt = function ( a ) { var b = this . lookup_segment_selector ( a ) ; if ( b . is_null ) this . segment_offsets [ reg_ldtr ] = 0 , this . segment_limits [ reg_ldtr ] = 0 ; else { dbg_assert ( b . is_valid ) ; if ( ! b . from_gdt ) throw this . debug . unimpl ( "LDTR can only be loaded from GDT" ) ; if ( ! b . is_present ) throw dbg_log ( "lldt: present bit not set" ) , this . debug . unimpl ( "#GP handler" ) ; if ( ! b . is_system ) throw dbg_log ( "lldt: not a system entry" ) , this . debug . unimpl ( "#GP handler" ) ; if ( 2 !== b . type ) throw dbg_log ( "lldt: invalid type (" + b . type + ")" ) , this . debug . unimpl ( "#GP handler" ) ; this . segment_offsets [ reg_ldtr ] = b . base ; this . segment_limits [ reg_ldtr ] = b . effective_limit ; this . sreg [ reg_ldtr ] = a ; } } ; CPU . prototype . arpl = function ( a , b ) { this . flags_changed &= ~ flag_zero ; if ( ( a & 3 ) < ( this . reg16 [ b ] & 3 ) ) return this . flags |= flag_zero , a & - 4 | this . reg16 [ b ] & 3 ; this . flags &= ~ flag_zero ; return a ; } ; CPU . prototype . lar = function ( a , b ) { dbg_log ( "lar sel=" + h ( a , 4 ) , LOG_CPU ) ; var c = this . lookup_segment_selector ( a ) ; this . flags_changed &= ~ flag_zero ; var d = c . dpl < this . cpl || c . dpl < c . rpl ; if ( c . is_null || ! c . is_valid || ( c . is_system ? 58817 >> c . type & 1 || d : ! c . is_conforming_executable && d ) ) return this . flags &= ~ flag_zero , dbg_log ( "lar: invalid selector=" + h ( a , 4 ) + " is_null=" + c . is_null , LOG_CPU ) , b ; this . flags |= flag_zero ; return c . raw1 & 16776960 ; } ; CPU . prototype . lsl = function ( a , b ) { dbg_log ( "lsl sel=" + h ( a , 4 ) , LOG_CPU ) ; var c = this . lookup_segment_selector ( a ) ; this . flags_changed &= ~ flag_zero ; var d = c . dpl < this . cpl || c . dpl < c . rpl ; if ( c . is_null || ! c . is_valid || ( c . is_system ? 62833 >> c . type & 1 || d : ! c . is_conforming_executable && d ) ) return this . flags &= ~ flag_zero , dbg_log ( "lsl: invalid  selector=" + h ( a , 4 ) + " is_null=" + c . is_null , LOG_CPU ) , b ; this . flags |= flag_zero ; return c . effective_limit | 0 ; } ; CPU . prototype . verr = function ( a ) { var b = this . lookup_segment_selector ( a ) ; this . flags_changed &= ~ flag_zero ; b . is_null || ! b . is_valid || b . is_system || ! b . is_readable || ! b . is_conforming_executable && ( b . dpl < this . cpl || b . dpl < b . rpl ) ? ( dbg_log ( "verr -> invalid. selector=" + h ( a , 4 ) , LOG_CPU ) , this . flags &= ~ flag_zero ) : ( dbg_log ( "verr -> valid. selector=" + h ( a , 4 ) , LOG_CPU ) , this . flags |= flag_zero ) ; } ; CPU . prototype . verw = function ( a ) { var b = this . lookup_segment_selector ( a ) ; this . flags_changed &= ~ flag_zero ; b . is_null || ! b . is_valid || b . is_system || ! b . is_writable || b . dpl < this . cpl || b . dpl < b . rpl ? ( dbg_log ( "verw invalid  " + h ( a ) + " " + b . is_null + " " + ! b . is_valid + " " + b . is_system + " " + ! b . is_writable + " " + ( b . dpl < this . cpl ) + " " + ( b . dpl < b . rpl ) + " " + LOG_CPU ) , this . flags &= ~ flag_zero ) : ( dbg_log ( "verw valid" , LOG_CPU ) , this . flags |= flag_zero ) ; } ; CPU . prototype . clear_tlb = function ( ) { this . last_virt_esp = this . last_virt_eip = - 1 ; this . tlb_info . set ( this . tlb_info_global ) ; } ; CPU . prototype . full_clear_tlb = function ( ) { for ( var a = new Int32Array ( this . tlb_info_global . buffer ) , b = 0 ; 262144 > b ; ) a [ b ++ ] = a [ b ++ ] = a [ b ++ ] = a [ b ++ ] = 0 ; this . clear_tlb ( ) ; } ; CPU . prototype . invlpg = function ( a ) { a >>>= 12 ; this . tlb_info [ a ] = 0 ; this . tlb_info_global [ a ] = 0 ; this . last_virt_esp = this . last_virt_eip = - 1 ; } ; CPU . prototype . translate_address_read = function ( a ) { return this . paging ? 3 === this . cpl ? this . translate_address_user_read ( a ) : this . translate_address_system_read ( a ) : a ; } ; CPU . prototype . translate_address_write = function ( a ) { return this . paging ? 3 === this . cpl ? this . translate_address_user_write ( a ) : this . translate_address_system_write ( a ) : a ; } ; CPU . prototype . translate_address_user_write = function ( a ) { if ( ! this . paging ) return a ; var b = a >>> 12 ; return this . tlb_info [ b ] & TLB_USER_WRITE ? this . tlb_data [ b ] ^ a : this . do_page_translation ( a , 1 , 1 ) | a & 4095 ; } ; CPU . prototype . translate_address_user_read = function ( a ) { if ( ! this . paging ) return a ; var b = a >>> 12 ; return this . tlb_info [ b ] & TLB_USER_READ ? this . tlb_data [ b ] ^ a : this . do_page_translation ( a , 0 , 1 ) | a & 4095 ; } ; CPU . prototype . translate_address_system_write = function ( a ) { if ( ! this . paging ) return a ; var b = a >>> 12 ; return this . tlb_info [ b ] & TLB_SYSTEM_WRITE ? this . tlb_data [ b ] ^ a : this . do_page_translation ( a , 1 , 0 ) | a & 4095 ; } ; CPU . prototype . translate_address_system_read = function ( a ) { if ( ! this . paging ) return a ; var b = a >>> 12 ; return this . tlb_info [ b ] & TLB_SYSTEM_READ ? this . tlb_data [ b ] ^ a : this . do_page_translation ( a , 0 , 0 ) | a & 4095 ; } ; CPU . prototype . do_page_translation = function ( a , b , c ) { var d = a >>> 12 , e = ( this . cr [ 3 ] >>> 2 ) + ( d >> 10 ) | 0 , g = this . mem32s [ e ] , f = ! 0 , k = ! 0 ; dbg_assert ( 2147483648 > a ) ; g & 1 || ( this . cr [ 2 ] = a , this . trigger_pagefault ( b , c , 0 ) , dbg_assert ( ! 1 ) ) ; 0 === ( g & 2 ) && ( f = ! 1 , b && ( c || this . cr [ 0 ] & CR0_WP ) && ( this . cr [ 2 ] = a , this . trigger_pagefault ( b , c , 1 ) , dbg_assert ( ! 1 ) ) ) ; 0 === ( g & 4 ) && ( k = ! 1 , c && ( this . cr [ 2 ] = a , this . trigger_pagefault ( b , c , 1 ) , dbg_assert ( ! 1 ) ) ) ; if ( g & this . page_size_extensions ) this . mem32s [ e ] = g | 32 | b << 6 , a = g & 4290772992 | a & 4190208 , g &= 256 ; else { var l = ( ( g & 4294963200 ) >>> 2 ) + ( d & 1023 ) | 0 , m = this . mem32s [ l ] ; 0 === ( m & 1 ) && ( this . cr [ 2 ] = a , this . trigger_pagefault ( b , c , 0 ) , dbg_assert ( ! 1 ) ) ; 0 === ( m & 2 ) && ( f = ! 1 , b && ( c || this . cr [ 0 ] & CR0_WP ) && ( this . cr [ 2 ] = a , this . trigger_pagefault ( b , c , 1 ) , dbg_assert ( ! 1 ) ) ) ; 0 === ( m & 4 ) && ( k = ! 1 , c && ( this . cr [ 2 ] = a , this . trigger_pagefault ( b , c , 1 ) , dbg_assert ( ! 1 ) ) ) ; this . write_aligned32 ( e , g | 32 ) ; this . write_aligned32 ( l , m | 32 | b << 6 ) ; a = m & 4294963200 ; g = m & 256 ; } this . tlb_data [ d ] = a ^ d << 12 ; f = k ? f ? TLB_SYSTEM_READ | TLB_SYSTEM_WRITE | TLB_USER_READ | TLB_USER_WRITE : TLB_SYSTEM_READ | TLB_USER_READ : f ? TLB_SYSTEM_READ | TLB_SYSTEM_WRITE : TLB_SYSTEM_READ ; this . tlb_info [ d ] = f ; g && this . cr [ 4 ] & CR4_PGE && ( this . tlb_info_global [ d ] = f ) ; return a ; } ; CPU . prototype . writable_or_pagefault = function ( a , b ) { dbg_assert ( 4096 > b , "not supported yet" ) ; dbg_assert ( 0 < b ) ; if ( this . paging ) { var c = 3 === this . cpl ? 1 : 0 , d = c ? TLB_USER_WRITE : TLB_SYSTEM_WRITE , e = a >>> 12 ; 0 === ( this . tlb_info [ e ] & d ) && this . do_page_translation ( a , 1 , c ) ; 4096 <= ( a & 4095 ) + b - 1 && 0 === ( this . tlb_info [ e + 1 | 0 ] & d ) && this . do_page_translation ( a + b - 1 | 0 , 1 , c ) ; } } ; CPU . prototype . trigger_pagefault = function ( a , b , c ) { LOG_PAGE_FAULTS && ( dbg_log ( "page fault w=" + a + " u=" + b + " p=" + c + " eip=" + h ( this . previous_ip >>> 0 , 8 ) + " cr2=" + h ( this . cr [ 2 ] >>> 0 , 8 ) , LOG_CPU ) , dbg_trace ( LOG_CPU ) ) ; if ( this . page_fault ) throw dbg_trace ( LOG_CPU ) , this . debug . unimpl ( "Double fault" ) ; var d = this . cr [ 2 ] >>> 12 ; this . tlb_info [ d ] = 0 ; this . tlb_info_global [ d ] = 0 ; this . instruction_pointer = this . previous_ip ; this . page_fault = ! 0 ; this . call_interrupt_vector ( 14 , ! 1 , b << 2 | a << 1 | c ) ; throw MAGIC_CPU_EXCEPTION ; } ; CPU . prototype . is_osize_32 = function ( ) { return this . is_32 !== ( ( this . prefixes & PREFIX_MASK_OPSIZE ) === PREFIX_MASK_OPSIZE ) ; } ; CPU . prototype . is_asize_32 = function ( ) { return this . is_32 !== ( ( this . prefixes & PREFIX_MASK_ADDRSIZE ) === PREFIX_MASK_ADDRSIZE ) ; } ; CPU . prototype . get_reg_asize = function ( a ) { dbg_assert ( a === reg_ecx || a === reg_esi || a === reg_edi ) ; a = this . reg32s [ a ] ; return this . is_asize_32 ( ) ? a : a & 65535 ; } ; CPU . prototype . set_ecx_asize = function ( a ) { this . is_asize_32 ( ) ? this . reg32s [ reg_ecx ] = a : this . reg16 [ reg_cx ] = a ; } ; CPU . prototype . add_reg_asize = function ( a , b ) { dbg_assert ( a === reg_ecx || a === reg_esi || a === reg_edi ) ; this . is_asize_32 ( ) ? this . reg32s [ a ] += b : this . reg16 [ a << 1 ] += b ; } ; CPU . prototype . decr_ecx_asize = function ( ) { return this . is_asize_32 ( ) ? -- this . reg32s [ reg_ecx ] : -- this . reg16 [ reg_cx ] ; } ; "undefined" !== typeof window ? window . CPU = CPU : "undefined" !== typeof module && "undefined" !== typeof module . exports ? module . exports . CPU = CPU : "function" === typeof importScripts && ( self . CPU = CPU ) ; function DynamicTranslator ( a ) { dbg_assert ( ! 1 ) ; this . clear_cache = function ( ) { } ; this . cycle_translated = function ( ) { } ; } ; ( function ( ) { CPU . prototype . modrm_table16 = Array ( 192 ) ; CPU . prototype . modrm_table32 = Array ( 192 ) ; CPU . prototype . sib_table = Array ( 256 ) ; CPU . prototype . modrm_table16 [ 0 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] + a . reg16 [ reg_si ] & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 64 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] + a . reg16 [ reg_si ] + a . read_disp8s ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 128 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] + a . reg16 [ reg_si ] + a . read_disp16 ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 1 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] + a . reg16 [ reg_di ] & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 65 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] + a . reg16 [ reg_di ] + a . read_disp8s ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 129 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] + a . reg16 [ reg_di ] + a . read_disp16 ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 2 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] + a . reg16 [ reg_si ] & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 66 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] + a . reg16 [ reg_si ] + a . read_disp8s ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 130 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] + a . reg16 [ reg_si ] + a . read_disp16 ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 3 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] + a . reg16 [ reg_di ] & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 67 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] + a . reg16 [ reg_di ] + a . read_disp8s ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 131 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] + a . reg16 [ reg_di ] + a . read_disp16 ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 4 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_si ] & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 68 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_si ] + a . read_disp8s ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 132 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_si ] + a . read_disp16 ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 5 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_di ] & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 69 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_di ] + a . read_disp8s ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 133 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_di ] + a . read_disp16 ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 6 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 70 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] + a . read_disp8s ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 134 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + ( a . reg16 [ reg_bp ] + a . read_disp16 ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 7 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 71 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] + a . read_disp8s ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table16 [ 135 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + ( a . reg16 [ reg_bx ] + a . read_disp16 ( ) & 65535 ) | 0 ; } ; CPU . prototype . modrm_table32 [ 0 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . modrm_table32 [ 64 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] + a . read_disp8s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 128 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] + a . read_disp32s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 1 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . modrm_table32 [ 65 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] + a . read_disp8s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 129 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] + a . read_disp32s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 2 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . modrm_table32 [ 66 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] + a . read_disp8s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 130 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] + a . read_disp32s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 3 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . modrm_table32 [ 67 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] + a . read_disp8s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 131 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] + a . read_disp32s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 5 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] | 0 ; } ; CPU . prototype . modrm_table32 [ 69 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] + a . read_disp8s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 133 ] = function ( a ) { return a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] + a . read_disp32s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 6 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . modrm_table32 [ 70 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] + a . read_disp8s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 134 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] + a . read_disp32s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 7 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . modrm_table32 [ 71 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] + a . read_disp8s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 135 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] + a . read_disp32s ( ) | 0 ; } ; CPU . prototype . modrm_table16 [ 6 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . read_disp16 ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 5 ] = function ( a ) { return a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 4 ] = function ( a ) { return a . sib_resolve ( ! 1 ) | 0 ; } ; CPU . prototype . modrm_table32 [ 68 ] = function ( a ) { return a . sib_resolve ( ! 0 ) + a . read_disp8s ( ) | 0 ; } ; CPU . prototype . modrm_table32 [ 132 ] = function ( a ) { return a . sib_resolve ( ! 0 ) + a . read_disp32s ( ) | 0 ; } ; for ( var a = 0 ; 8 > a ; a ++ ) for ( var b = 0 ; 3 > b ; b ++ ) for ( var c = a | b << 6 , d = 1 ; 8 > d ; d ++ ) CPU . prototype . modrm_table32 [ c | d << 3 ] = CPU . prototype . modrm_table32 [ c ] , CPU . prototype . modrm_table16 [ c | d << 3 ] = CPU . prototype . modrm_table16 [ c ] ; CPU . prototype . sib_table [ 0 ] = function ( a , b ) { return a . reg32s [ reg_eax ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 1 ] = function ( a , b ) { return a . reg32s [ reg_eax ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 2 ] = function ( a , b ) { return a . reg32s [ reg_eax ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 3 ] = function ( a , b ) { return a . reg32s [ reg_eax ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 4 ] = function ( a , b ) { return a . reg32s [ reg_eax ] + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 5 ] = function ( a , b ) { return a . reg32s [ reg_eax ] + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 6 ] = function ( a , b ) { return a . reg32s [ reg_eax ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 7 ] = function ( a , b ) { return a . reg32s [ reg_eax ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 64 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 65 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 66 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 67 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 68 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 1 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 69 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 1 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 70 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 71 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 128 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 129 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 130 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 131 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 132 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 2 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 133 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 2 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 134 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 135 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 192 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 193 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 194 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 195 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 196 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 3 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 197 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 3 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 198 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 199 ] = function ( a , b ) { return ( a . reg32s [ reg_eax ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 8 ] = function ( a , b ) { return a . reg32s [ reg_ecx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 9 ] = function ( a , b ) { return a . reg32s [ reg_ecx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 10 ] = function ( a , b ) { return a . reg32s [ reg_ecx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 11 ] = function ( a , b ) { return a . reg32s [ reg_ecx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 12 ] = function ( a , b ) { return a . reg32s [ reg_ecx ] + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 13 ] = function ( a , b ) { return a . reg32s [ reg_ecx ] + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 14 ] = function ( a , b ) { return a . reg32s [ reg_ecx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 15 ] = function ( a , b ) { return a . reg32s [ reg_ecx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 72 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 73 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 74 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 75 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 76 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 1 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 77 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 1 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 78 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 79 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 136 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 137 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 138 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 139 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 140 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 2 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 141 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 2 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 142 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 143 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 200 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 201 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 202 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 203 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 204 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 3 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 205 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 3 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 206 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 207 ] = function ( a , b ) { return ( a . reg32s [ reg_ecx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 16 ] = function ( a , b ) { return a . reg32s [ reg_edx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 17 ] = function ( a , b ) { return a . reg32s [ reg_edx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 18 ] = function ( a , b ) { return a . reg32s [ reg_edx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 19 ] = function ( a , b ) { return a . reg32s [ reg_edx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 20 ] = function ( a , b ) { return a . reg32s [ reg_edx ] + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 21 ] = function ( a , b ) { return a . reg32s [ reg_edx ] + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 22 ] = function ( a , b ) { return a . reg32s [ reg_edx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 23 ] = function ( a , b ) { return a . reg32s [ reg_edx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 80 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 81 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 82 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 83 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 84 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 1 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 85 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 1 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 86 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 87 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 144 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 145 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 146 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 147 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 148 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 2 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 149 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 2 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 150 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 151 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 208 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 209 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 210 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 211 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 212 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 3 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 213 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 3 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 214 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 215 ] = function ( a , b ) { return ( a . reg32s [ reg_edx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 24 ] = function ( a , b ) { return a . reg32s [ reg_ebx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 25 ] = function ( a , b ) { return a . reg32s [ reg_ebx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 26 ] = function ( a , b ) { return a . reg32s [ reg_ebx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 27 ] = function ( a , b ) { return a . reg32s [ reg_ebx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 28 ] = function ( a , b ) { return a . reg32s [ reg_ebx ] + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 29 ] = function ( a , b ) { return a . reg32s [ reg_ebx ] + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 30 ] = function ( a , b ) { return a . reg32s [ reg_ebx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 31 ] = function ( a , b ) { return a . reg32s [ reg_ebx ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 88 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 89 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 90 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 91 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 92 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 1 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 93 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 1 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 94 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 95 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 152 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 153 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 154 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 155 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 156 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 2 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 157 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 2 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 158 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 159 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 216 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 217 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 218 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 219 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 220 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 3 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 221 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 3 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 222 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 223 ] = function ( a , b ) { return ( a . reg32s [ reg_ebx ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 32 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 33 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 34 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 35 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 36 ] = function ( a , b ) { return a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 37 ] = function ( a , b ) { return ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 38 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 39 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 96 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 97 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 98 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 99 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 100 ] = function ( a , b ) { return a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 101 ] = function ( a , b ) { return ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 102 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 103 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 160 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 161 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 162 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 163 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 164 ] = function ( a , b ) { return a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 165 ] = function ( a , b ) { return ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 166 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 167 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 224 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 225 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 226 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 227 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 228 ] = function ( a , b ) { return a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 229 ] = function ( a , b ) { return ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 230 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 231 ] = function ( a , b ) { return a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 40 ] = function ( a , b ) { return a . reg32s [ reg_ebp ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 41 ] = function ( a , b ) { return a . reg32s [ reg_ebp ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 42 ] = function ( a , b ) { return a . reg32s [ reg_ebp ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 43 ] = function ( a , b ) { return a . reg32s [ reg_ebp ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 44 ] = function ( a , b ) { return a . reg32s [ reg_ebp ] + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 45 ] = function ( a , b ) { return a . reg32s [ reg_ebp ] + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 46 ] = function ( a , b ) { return a . reg32s [ reg_ebp ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 47 ] = function ( a , b ) { return a . reg32s [ reg_ebp ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 104 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 105 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 106 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 107 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 108 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 1 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 109 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 1 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 110 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 111 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 168 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 169 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 170 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 171 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 172 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 2 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 173 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 2 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 174 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 175 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 232 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 233 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 234 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 235 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 236 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 3 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 237 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 3 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 238 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 239 ] = function ( a , b ) { return ( a . reg32s [ reg_ebp ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 48 ] = function ( a , b ) { return a . reg32s [ reg_esi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 49 ] = function ( a , b ) { return a . reg32s [ reg_esi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 50 ] = function ( a , b ) { return a . reg32s [ reg_esi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 51 ] = function ( a , b ) { return a . reg32s [ reg_esi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 52 ] = function ( a , b ) { return a . reg32s [ reg_esi ] + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 53 ] = function ( a , b ) { return a . reg32s [ reg_esi ] + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 54 ] = function ( a , b ) { return a . reg32s [ reg_esi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 55 ] = function ( a , b ) { return a . reg32s [ reg_esi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 112 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 113 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 114 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 115 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 116 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 1 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 117 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 1 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 118 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 119 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 176 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 177 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 178 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 179 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 180 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 2 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 181 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 2 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 182 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 183 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 240 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 241 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 242 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 243 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 244 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 3 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 245 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 3 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 246 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 247 ] = function ( a , b ) { return ( a . reg32s [ reg_esi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 56 ] = function ( a , b ) { return a . reg32s [ reg_edi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 57 ] = function ( a , b ) { return a . reg32s [ reg_edi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 58 ] = function ( a , b ) { return a . reg32s [ reg_edi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 59 ] = function ( a , b ) { return a . reg32s [ reg_edi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 60 ] = function ( a , b ) { return a . reg32s [ reg_edi ] + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 61 ] = function ( a , b ) { return a . reg32s [ reg_edi ] + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 62 ] = function ( a , b ) { return a . reg32s [ reg_edi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 63 ] = function ( a , b ) { return a . reg32s [ reg_edi ] + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 120 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 121 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 122 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 123 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 124 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 1 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 125 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 1 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 126 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 127 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 1 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 184 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 185 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 186 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 187 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 188 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 2 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 189 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 2 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 190 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 191 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 2 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; CPU . prototype . sib_table [ 248 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_eax ] | 0 ; } ; CPU . prototype . sib_table [ 249 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ecx ] | 0 ; } ; CPU . prototype . sib_table [ 250 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edx ] | 0 ; } ; CPU . prototype . sib_table [ 251 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_ebx ] | 0 ; } ; CPU . prototype . sib_table [ 252 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 3 ) + a . get_seg_prefix_ss ( ) + a . reg32s [ reg_esp ] | 0 ; } ; CPU . prototype . sib_table [ 253 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 3 ) + ( b ? a . get_seg_prefix_ss ( ) + a . reg32s [ reg_ebp ] : a . get_seg_prefix_ds ( ) + a . read_disp32s ( ) ) | 0 ; } ; CPU . prototype . sib_table [ 254 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_esi ] | 0 ; } ; CPU . prototype . sib_table [ 255 ] = function ( a , b ) { return ( a . reg32s [ reg_edi ] << 3 ) + a . get_seg_prefix_ds ( ) + a . reg32s [ reg_edi ] | 0 ; } ; } ) ( ) ; var MAX_COUNT_PER_CYCLE = 4096 ; function string_get_cycle_count ( a , b ) { dbg_assert ( a && 4 >= a && - 4 <= a ) ; return 0 > a ? ( b & 4095 ) >> ( - a >> 1 ) : ( ~ b & 4095 ) >> a ; } function string_get_cycle_count2 ( a , b , c ) { dbg_assert ( 3 === arguments . length ) ; return Math . min ( string_get_cycle_count ( a , b ) , string_get_cycle_count ( a , c ) ) ; } CPU . prototype . movsb = function ( ) { var a = this . get_seg_prefix ( reg_ds ) + this . get_reg_asize ( reg_esi ) | 0 , b = this . get_seg ( reg_es ) + this . get_reg_asize ( reg_edi ) | 0 , c = this . flags & flag_direction ? - 1 : 1 ; if ( this . prefixes & PREFIX_MASK_REP ) { var d = this . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === d ) return ; var e = d , g = MAX_COUNT_PER_CYCLE , f = this . translate_address_read ( a ) , k = this . translate_address_write ( b ) ; this . paging && ( g = string_get_cycle_count2 ( c , a , b ) ) ; do this . write8 ( k , this . read8 ( f ) ) , k += c , f += c , a = 0 !== -- d ; while ( a && g -- ) ; c = c * ( e - d ) | 0 ; this . add_reg_asize ( reg_edi , c ) ; this . add_reg_asize ( reg_esi , c ) ; this . set_ecx_asize ( d ) ; this . timestamp_counter += e - d ; a && ( this . instruction_pointer = this . previous_ip ) ; } else this . safe_write8 ( b , this . safe_read8 ( a ) ) , this . add_reg_asize ( reg_edi , c ) , this . add_reg_asize ( reg_esi , c ) ; this . diverged ( ) ; } ; CPU . prototype . movsw = function ( ) { var a = this . get_seg_prefix ( reg_ds ) + this . get_reg_asize ( reg_esi ) | 0 , b = this . get_seg ( reg_es ) + this . get_reg_asize ( reg_edi ) | 0 , c = this . flags & flag_direction ? - 2 : 2 ; if ( this . prefixes & PREFIX_MASK_REP ) { var d = this . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === d ) return ; var e = d , g = MAX_COUNT_PER_CYCLE ; if ( b & 1 || a & 1 ) { do { this . safe_write16 ( b , this . safe_read16 ( a ) ) ; b += c ; this . add_reg_asize ( reg_edi , c ) ; a += c ; this . add_reg_asize ( reg_esi , c ) ; var f = 0 !== this . decr_ecx_asize ( ) ; } while ( f && g -- ) ; } else { var k = 0 > c ? - 1 : 1 , l = this . translate_address_read ( a ) >>> 1 , m = this . translate_address_write ( b ) >>> 1 ; this . paging && ( g = string_get_cycle_count2 ( c , a , b ) ) ; do this . write_aligned16 ( m , this . read_aligned16 ( l ) ) , m += k , l += k , f = 0 !== -- d ; while ( f && g -- ) ; a = c * ( e - d ) | 0 ; this . add_reg_asize ( reg_edi , a ) ; this . add_reg_asize ( reg_esi , a ) ; this . set_ecx_asize ( d ) ; this . timestamp_counter += e - d ; } f && ( this . instruction_pointer = this . previous_ip ) ; } else this . safe_write16 ( b , this . safe_read16 ( a ) ) , this . add_reg_asize ( reg_edi , c ) , this . add_reg_asize ( reg_esi , c ) ; this . diverged ( ) ; } ; CPU . prototype . movsd = function ( ) { if ( this . prefixes & PREFIX_MASK_REP ) { var a = this . get_seg_prefix ( reg_ds ) + this . get_reg_asize ( reg_esi ) | 0 , b = this . get_seg ( reg_es ) + this . get_reg_asize ( reg_edi ) | 0 , c = this . get_reg_asize ( reg_ecx ) >>> 0 ; if ( ! c ) return ; var d = this . paging ? 4095 : 3 ; if ( 0 === ( b & d ) && 0 === ( a & d ) && 0 === ( this . flags & flag_direction ) && ( d = ! 1 , this . paging && ( a = this . translate_address_read ( a ) , b = this . translate_address_write ( b ) , 1024 < c && ( c = 1024 , d = ! 0 ) ) , ! this . io . in_mmap_range ( a , c ) && ! this . io . in_mmap_range ( b , c ) ) ) { var e = c << 2 ; this . add_reg_asize ( reg_ecx , - c ) ; this . add_reg_asize ( reg_edi , e ) ; this . add_reg_asize ( reg_esi , e ) ; b >>>= 2 ; a >>>= 2 ; this . write_blob32 ( this . mem32s . subarray ( a , a + c ) , b ) ; d && ( this . instruction_pointer = this . previous_ip ) ; return ; } } a = this . get_seg_prefix ( reg_ds ) + this . get_reg_asize ( reg_esi ) | 0 ; b = this . get_seg ( reg_es ) + this . get_reg_asize ( reg_edi ) | 0 ; e = this . flags & flag_direction ? - 4 : 4 ; if ( this . prefixes & PREFIX_MASK_REP ) { c = this . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === c ) return ; var g = c , f = MAX_COUNT_PER_CYCLE ; if ( b & 3 || a & 3 ) { do this . safe_write32 ( b , this . safe_read32s ( a ) ) , b += e , this . add_reg_asize ( reg_edi , e ) , a += e , this . add_reg_asize ( reg_esi , e ) , d = 0 !== this . decr_ecx_asize ( ) ; while ( d && f -- ) ; } else { var k = 0 > e ? - 1 : 1 , l = this . translate_address_read ( a ) >>> 2 , m = this . translate_address_write ( b ) >>> 2 ; this . paging && ( f = string_get_cycle_count2 ( e , a , b ) ) ; do this . write_aligned32 ( m , this . read_aligned32 ( l ) ) , m += k , l += k , d = 0 !== -- c ; while ( d && f -- ) ; e = e * ( g - c ) | 0 ; this . add_reg_asize ( reg_edi , e ) ; this . add_reg_asize ( reg_esi , e ) ; this . set_ecx_asize ( c ) ; this . timestamp_counter += g - c ; } d && ( this . instruction_pointer = this . previous_ip ) ; } else this . safe_write32 ( b , this . safe_read32s ( a ) ) , this . add_reg_asize ( reg_edi , e ) , this . add_reg_asize ( reg_esi , e ) ; this . diverged ( ) ; } ; function cmpsb ( a ) { var b = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 1 : 1 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = ( a . prefixes & PREFIX_MASK_REP ) === PREFIX_REPZ , k = MAX_COUNT_PER_CYCLE , l = a . translate_address_read ( b ) , m = a . translate_address_read ( c ) ; a . paging && ( k = string_get_cycle_count2 ( d , b , c ) ) ; do { c = a . read8 ( m ) ; b = a . read8 ( l ) ; m += d ; l += d ; var n = 0 !== -- e && b === c === f ; } while ( n && k -- ) ; d = d * ( g - e ) | 0 ; a . add_reg_asize ( reg_edi , d ) ; a . add_reg_asize ( reg_esi , d ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; n && ( a . instruction_pointer = a . previous_ip ) ; } else b = a . safe_read8 ( b ) , c = a . safe_read8 ( c ) , a . add_reg_asize ( reg_edi , d ) , a . add_reg_asize ( reg_esi , d ) ; a . cmp8 ( b , c ) ; a . diverged ( ) ; } function cmpsw ( a ) { var b = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 2 : 2 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = ( a . prefixes & PREFIX_MASK_REP ) === PREFIX_REPZ , k = MAX_COUNT_PER_CYCLE ; if ( c & 1 || b & 1 ) { do { var l = a . safe_read16 ( c ) ; var m = a . safe_read16 ( b ) ; c += d ; a . add_reg_asize ( reg_edi , d ) ; b += d ; a . add_reg_asize ( reg_esi , d ) ; var n = 0 !== a . decr_ecx_asize ( ) && m === l === f ; } while ( n && k -- ) ; } else { var p = 0 > d ? - 1 : 1 , q = a . translate_address_read ( b ) >>> 1 , r = a . translate_address_read ( c ) >>> 1 ; a . paging && ( k = string_get_cycle_count2 ( d , b , c ) ) ; do l = a . read_aligned16 ( r ) , m = a . read_aligned16 ( q ) , r += p , q += p , n = 0 !== -- e && m === l === f ; while ( n && k -- ) ; b = d * ( g - e ) | 0 ; a . add_reg_asize ( reg_edi , b ) ; a . add_reg_asize ( reg_esi , b ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } n && ( a . instruction_pointer = a . previous_ip ) ; } else l = a . safe_read16 ( c ) , m = a . safe_read16 ( b ) , a . add_reg_asize ( reg_edi , d ) , a . add_reg_asize ( reg_esi , d ) ; a . cmp16 ( m , l ) ; a . diverged ( ) ; } function cmpsd ( a ) { var b = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 4 : 4 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = ( a . prefixes & PREFIX_MASK_REP ) === PREFIX_REPZ , k = MAX_COUNT_PER_CYCLE ; if ( c & 3 || b & 3 ) { do { var l = a . safe_read32s ( c ) ; var m = a . safe_read32s ( b ) ; c += d ; a . add_reg_asize ( reg_edi , d ) ; b += d ; a . add_reg_asize ( reg_esi , d ) ; var n = 0 !== a . decr_ecx_asize ( ) && m === l === f ; } while ( n && k -- ) ; } else { var p = 0 > d ? - 1 : 1 , q = a . translate_address_read ( b ) >>> 2 , r = a . translate_address_read ( c ) >>> 2 ; a . paging && ( k = string_get_cycle_count2 ( d , b , c ) ) ; do l = a . read_aligned32 ( r ) , m = a . read_aligned32 ( q ) , r += p , q += p , n = 0 !== -- e && m === l === f ; while ( n && k -- ) ; b = d * ( g - e ) | 0 ; a . add_reg_asize ( reg_edi , b ) ; a . add_reg_asize ( reg_esi , b ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } n && ( a . instruction_pointer = a . previous_ip ) ; } else l = a . safe_read32s ( c ) , m = a . safe_read32s ( b ) , a . add_reg_asize ( reg_edi , d ) , a . add_reg_asize ( reg_esi , d ) ; a . cmp32 ( m , l ) ; a . diverged ( ) ; } function stosb ( a ) { var b = a . reg8 [ reg_al ] , c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 1 : 1 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE , k = a . translate_address_write ( c ) ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . write8 ( k , b ) , k += d , c = 0 !== -- e ; while ( c && f -- ) ; a . add_reg_asize ( reg_edi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; c && ( a . instruction_pointer = a . previous_ip ) ; } else a . safe_write8 ( c , b ) , a . add_reg_asize ( reg_edi , d ) ; a . diverged ( ) ; } function stosw ( a ) { var b = a . reg16 [ reg_ax ] , c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 2 : 2 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE ; if ( c & 1 ) { do { a . safe_write16 ( c , b ) ; c += d ; a . add_reg_asize ( reg_edi , d ) ; var k = 0 !== a . decr_ecx_asize ( ) ; } while ( k && f -- ) ; } else { var l = 0 > d ? - 1 : 1 , m = a . translate_address_write ( c ) >>> 1 ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . write_aligned16 ( m , b ) , m += l , k = 0 !== -- e ; while ( k && f -- ) ; a . add_reg_asize ( reg_edi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } k && ( a . instruction_pointer = a . previous_ip ) ; } else a . safe_write16 ( c , b ) , a . add_reg_asize ( reg_edi , d ) ; a . diverged ( ) ; } function stosd ( a ) { var b = a . reg32s [ reg_eax ] , c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 4 : 4 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE ; if ( c & 3 ) { do { a . safe_write32 ( c , b ) ; c += d ; a . add_reg_asize ( reg_edi , d ) ; var k = 0 !== a . decr_ecx_asize ( ) ; } while ( k && f -- ) ; } else { var l = 0 > d ? - 1 : 1 , m = a . translate_address_write ( c ) >>> 2 ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . write_aligned32 ( m , b ) , m += l , k = 0 !== -- e ; while ( k && f -- ) ; a . add_reg_asize ( reg_edi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } k && ( a . instruction_pointer = a . previous_ip ) ; } else a . safe_write32 ( c , b ) , a . add_reg_asize ( reg_edi , d ) ; a . diverged ( ) ; } function lodsb ( a ) { var b = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , c = a . flags & flag_direction ? - 1 : 1 ; if ( a . prefixes & PREFIX_MASK_REP ) { var d = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === d ) return ; var e = d , g = MAX_COUNT_PER_CYCLE , f = a . translate_address_read ( b ) ; a . paging && ( g = string_get_cycle_count ( c , b ) ) ; do a . reg8 [ reg_al ] = a . read8 ( f ) , f += c , b = 0 !== -- d ; while ( b && g -- ) ; a . add_reg_asize ( reg_esi , c * ( e - d ) | 0 ) ; a . set_ecx_asize ( d ) ; a . timestamp_counter += e - d ; b && ( a . instruction_pointer = a . previous_ip ) ; } else a . reg8 [ reg_al ] = a . safe_read8 ( b ) , a . add_reg_asize ( reg_esi , c ) ; a . diverged ( ) ; } function lodsw ( a ) { var b = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , c = a . flags & flag_direction ? - 2 : 2 ; if ( a . prefixes & PREFIX_MASK_REP ) { if ( 0 === a . get_reg_asize ( reg_ecx ) >>> 0 ) return ; var d = MAX_COUNT_PER_CYCLE ; do { a . reg16 [ reg_ax ] = a . safe_read16 ( b ) ; b += c ; a . add_reg_asize ( reg_esi , c ) ; var e = 0 !== a . decr_ecx_asize ( ) ; } while ( e && d -- ) ; e && ( a . instruction_pointer = a . previous_ip ) ; } else a . reg16 [ reg_ax ] = a . safe_read16 ( b ) , a . add_reg_asize ( reg_esi , c ) ; a . diverged ( ) ; } function lodsd ( a ) { var b = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , c = a . flags & flag_direction ? - 4 : 4 ; if ( a . prefixes & PREFIX_MASK_REP ) { if ( 0 === a . get_reg_asize ( reg_ecx ) >>> 0 ) return ; var d = MAX_COUNT_PER_CYCLE ; do { a . reg32s [ reg_eax ] = a . safe_read32s ( b ) ; b += c ; a . add_reg_asize ( reg_esi , c ) ; var e = 0 !== a . decr_ecx_asize ( ) ; } while ( e && d -- ) ; e && ( a . instruction_pointer = a . previous_ip ) ; } else a . reg32s [ reg_eax ] = a . safe_read32s ( b ) , a . add_reg_asize ( reg_esi , c ) ; a . diverged ( ) ; } function scasb ( a ) { var b = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , c = a . flags & flag_direction ? - 1 : 1 , d = a . reg8 [ reg_al ] ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = ( a . prefixes & PREFIX_MASK_REP ) === PREFIX_REPZ , k = MAX_COUNT_PER_CYCLE , l = a . translate_address_read ( b ) ; a . paging && ( k = string_get_cycle_count ( c , b ) ) ; do { b = a . read8 ( l ) ; l += c ; var m = 0 !== -- e && d === b === f ; } while ( m && k -- ) ; a . add_reg_asize ( reg_edi , c * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; m && ( a . instruction_pointer = a . previous_ip ) ; } else b = a . safe_read8 ( b ) , a . add_reg_asize ( reg_edi , c ) ; a . cmp8 ( d , b ) ; a . diverged ( ) ; } function scasw ( a ) { var b = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , c = a . flags & flag_direction ? - 2 : 2 , d = a . reg16 [ reg_al ] ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = ( a . prefixes & PREFIX_MASK_REP ) === PREFIX_REPZ , k = MAX_COUNT_PER_CYCLE ; if ( b & 1 ) { do { var l = a . safe_read16 ( b ) ; b += c ; a . add_reg_asize ( reg_edi , c ) ; var m = 0 !== a . decr_ecx_asize ( ) && d === l === f ; } while ( m && k -- ) ; } else { var n = 0 > c ? - 1 : 1 , p = a . translate_address_read ( b ) >>> 1 ; a . paging && ( k = string_get_cycle_count ( c , b ) ) ; do l = a . read_aligned16 ( p ) , p += n , m = 0 !== -- e && d === l === f ; while ( m && k -- ) ; a . add_reg_asize ( reg_edi , c * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } m && ( a . instruction_pointer = a . previous_ip ) ; } else l = a . safe_read16 ( b ) , a . add_reg_asize ( reg_edi , c ) ; a . cmp16 ( d , l ) ; a . diverged ( ) ; } function scasd ( a ) { var b = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , c = a . flags & flag_direction ? - 4 : 4 , d = a . reg32s [ reg_eax ] ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = ( a . prefixes & PREFIX_MASK_REP ) === PREFIX_REPZ , k = MAX_COUNT_PER_CYCLE ; if ( b & 3 ) { do { var l = a . safe_read32s ( b ) ; b += c ; a . add_reg_asize ( reg_edi , c ) ; var m = 0 !== a . decr_ecx_asize ( ) && d === l === f ; } while ( m && k -- ) ; } else { var n = 0 > c ? - 1 : 1 , p = a . translate_address_read ( b ) >>> 2 ; a . paging && ( k = string_get_cycle_count ( c , b ) ) ; do l = a . read_aligned32 ( p ) , p += n , m = 0 !== -- e && d === l === f ; while ( m && k -- ) ; a . add_reg_asize ( reg_edi , c * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } m && ( a . instruction_pointer = a . previous_ip ) ; } else l = a . safe_read32s ( b ) , a . add_reg_asize ( reg_edi , c ) ; a . cmp32 ( d , l ) ; a . diverged ( ) ; } function insb ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 1 ) ; var c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 1 : 1 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE , k = a . translate_address_write ( c ) ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . write8 ( k , a . io . port_read8 ( b ) ) , k += d , c = 0 !== -- e ; while ( c && f -- ) ; a . add_reg_asize ( reg_edi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; c && ( a . instruction_pointer = a . previous_ip ) ; } else a . writable_or_pagefault ( c , 1 ) , a . safe_write8 ( c , a . io . port_read8 ( b ) ) , a . add_reg_asize ( reg_edi , d ) ; a . diverged ( ) ; } function insw ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 2 ) ; var c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 2 : 2 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE ; if ( c & 1 ) { do { a . safe_write16 ( c , a . io . port_read16 ( b ) ) ; c += d ; a . add_reg_asize ( reg_edi , d ) ; var k = 0 !== a . decr_ecx_asize ( ) ; } while ( k && f -- ) ; } else { var l = 0 > d ? - 1 : 1 , m = a . translate_address_write ( c ) >>> 1 ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . write_aligned16 ( m , a . io . port_read16 ( b ) ) , m += l , k = 0 !== -- e ; while ( k && f -- ) ; a . add_reg_asize ( reg_edi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } k && ( a . instruction_pointer = a . previous_ip ) ; } else a . writable_or_pagefault ( c , 2 ) , a . safe_write16 ( c , a . io . port_read16 ( b ) ) , a . add_reg_asize ( reg_edi , d ) ; a . diverged ( ) ; } function insd ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 4 ) ; var c = a . get_seg ( reg_es ) + a . get_reg_asize ( reg_edi ) | 0 , d = a . flags & flag_direction ? - 4 : 4 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE ; if ( c & 3 ) { do { a . safe_write32 ( c , a . io . port_read32 ( b ) ) ; c += d ; a . add_reg_asize ( reg_edi , d ) ; var k = 0 !== a . decr_ecx_asize ( ) ; } while ( k && f -- ) ; } else { var l = 0 > d ? - 1 : 1 , m = a . translate_address_write ( c ) >>> 2 ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . write_aligned32 ( m , a . io . port_read32 ( b ) ) , m += l , k = 0 !== -- e ; while ( k && f -- ) ; a . add_reg_asize ( reg_edi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } k && ( a . instruction_pointer = a . previous_ip ) ; } else a . writable_or_pagefault ( c , 4 ) , a . safe_write32 ( c , a . io . port_read32 ( b ) ) , a . add_reg_asize ( reg_edi , d ) ; a . diverged ( ) ; } function outsb ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 1 ) ; var c = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , d = a . flags & flag_direction ? - 1 : 1 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE , k = a . translate_address_read ( c ) ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . io . port_write8 ( b , a . read8 ( k ) ) , k += d , c = 0 !== -- e ; while ( c && f -- ) ; a . add_reg_asize ( reg_esi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; c && ( a . instruction_pointer = a . previous_ip ) ; } else a . io . port_write8 ( b , a . safe_read8 ( c ) ) , a . add_reg_asize ( reg_esi , d ) ; a . diverged ( ) ; } function outsw ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 2 ) ; var c = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , d = a . flags & flag_direction ? - 2 : 2 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE ; if ( c & 1 ) { do { a . io . port_write16 ( b , a . safe_read16 ( c ) ) ; c += d ; a . add_reg_asize ( reg_esi , d ) ; var k = 0 !== a . decr_ecx_asize ( ) ; } while ( k && f -- ) ; } else { var l = 0 > d ? - 1 : 1 , m = a . translate_address_read ( c ) >>> 1 ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . io . port_write16 ( b , a . read_aligned16 ( m ) ) , m += l , k = 0 !== -- e ; while ( k && f -- ) ; a . add_reg_asize ( reg_esi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } k && ( a . instruction_pointer = a . previous_ip ) ; } else a . io . port_write16 ( b , a . safe_read16 ( c ) ) , a . add_reg_asize ( reg_esi , d ) ; a . diverged ( ) ; } function outsd ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 4 ) ; var c = a . get_seg_prefix ( reg_ds ) + a . get_reg_asize ( reg_esi ) | 0 , d = a . flags & flag_direction ? - 4 : 4 ; if ( a . prefixes & PREFIX_MASK_REP ) { var e = a . get_reg_asize ( reg_ecx ) >>> 0 ; if ( 0 === e ) return ; var g = e , f = MAX_COUNT_PER_CYCLE ; if ( c & 3 ) { do { a . io . port_write32 ( b , a . safe_read32s ( c ) ) ; c += d ; a . add_reg_asize ( reg_esi , d ) ; var k = 0 !== a . decr_ecx_asize ( ) ; } while ( k && f -- ) ; } else { var l = 0 > d ? - 1 : 1 , m = a . translate_address_read ( c ) >>> 2 ; a . paging && ( f = string_get_cycle_count ( d , c ) ) ; do a . io . port_write32 ( b , a . read_aligned32 ( m ) ) , m += l , k = 0 !== -- e ; while ( k && f -- ) ; a . add_reg_asize ( reg_esi , d * ( g - e ) | 0 ) ; a . set_ecx_asize ( e ) ; a . timestamp_counter += g - e ; } k && ( a . instruction_pointer = a . previous_ip ) ; } else a . io . port_write32 ( b , a . safe_read32s ( c ) ) , a . add_reg_asize ( reg_esi , d ) ; a . diverged ( ) ; } ; CPU . prototype . add8 = function ( a , b ) { return this . add ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . add16 = function ( a , b ) { return this . add ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . add32 = function ( a , b ) { return this . add ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . adc8 = function ( a , b ) { return this . adc ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . adc16 = function ( a , b ) { return this . adc ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . adc32 = function ( a , b ) { return this . adc ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . sub8 = function ( a , b ) { return this . sub ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . sub16 = function ( a , b ) { return this . sub ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . sub32 = function ( a , b ) { return this . sub ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . cmp8 = function ( a , b ) { return this . sub ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . cmp16 = function ( a , b ) { return this . sub ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . cmp32 = function ( a , b ) { return this . sub ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . sbb8 = function ( a , b ) { return this . sbb ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . sbb16 = function ( a , b ) { return this . sbb ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . sbb32 = function ( a , b ) { return this . sbb ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . add = function ( a , b , c ) { this . last_op1 = a ; this . last_op2 = b ; this . last_add_result = this . last_result = a + b | 0 ; this . last_op_size = c ; this . flags_changed = flags_all ; return this . last_result ; } ; CPU . prototype . adc = function ( a , b , c ) { var d = this . getcf ( ) ; this . last_op1 = a ; this . last_op2 = b ; this . last_add_result = this . last_result = ( a + b | 0 ) + d | 0 ; this . last_op_size = c ; this . flags_changed = flags_all ; return this . last_result ; } ; CPU . prototype . sub = function ( a , b , c ) { this . last_add_result = a ; this . last_op2 = b ; this . last_op1 = this . last_result = a - b | 0 ; this . last_op_size = c ; this . flags_changed = flags_all ; return this . last_result ; } ; CPU . prototype . sbb = function ( a , b , c ) { var d = this . getcf ( ) ; this . last_add_result = a ; this . last_op2 = b ; this . last_op1 = this . last_result = a - b - d | 0 ; this . last_op_size = c ; this . flags_changed = flags_all ; return this . last_result ; } ; CPU . prototype . inc8 = function ( a ) { return this . inc ( a , OPSIZE_8 ) ; } ; CPU . prototype . inc16 = function ( a ) { return this . inc ( a , OPSIZE_16 ) ; } ; CPU . prototype . inc32 = function ( a ) { return this . inc ( a , OPSIZE_32 ) ; } ; CPU . prototype . dec8 = function ( a ) { return this . dec ( a , OPSIZE_8 ) ; } ; CPU . prototype . dec16 = function ( a ) { return this . dec ( a , OPSIZE_16 ) ; } ; CPU . prototype . dec32 = function ( a ) { return this . dec ( a , OPSIZE_32 ) ; } ; CPU . prototype . inc = function ( a , b ) { this . flags = this . flags & - 2 | this . getcf ( ) ; this . last_op1 = a ; this . last_op2 = 1 ; this . last_add_result = this . last_result = a + 1 | 0 ; this . last_op_size = b ; this . flags_changed = flags_all & - 2 ; return this . last_result ; } ; CPU . prototype . dec = function ( a , b ) { this . flags = this . flags & - 2 | this . getcf ( ) ; this . last_add_result = a ; this . last_op2 = 1 ; this . last_op1 = this . last_result = a - 1 | 0 ; this . last_op_size = b ; this . flags_changed = flags_all & - 2 ; return this . last_result ; } ; CPU . prototype . neg8 = function ( a ) { return this . neg ( a , OPSIZE_8 ) ; } ; CPU . prototype . neg16 = function ( a ) { return this . neg ( a , OPSIZE_16 ) ; } ; CPU . prototype . neg32 = function ( a ) { return this . neg ( a , OPSIZE_32 ) ; } ; CPU . prototype . neg = function ( a , b ) { this . last_op1 = this . last_result = - a | 0 ; this . flags_changed = flags_all ; this . last_add_result = 0 ; this . last_op2 = a ; this . last_op_size = b ; return this . last_result ; } ; CPU . prototype . mul8 = function ( a ) { a *= this . reg8 [ reg_al ] ; this . reg16 [ reg_ax ] = a ; this . last_result = a & 255 ; this . last_op_size = OPSIZE_8 ; this . flags = 256 > a ? this . flags & - 2 & ~ flag_overflow : this . flags | 1 | flag_overflow ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; } ; CPU . prototype . imul8 = function ( a ) { a *= this . reg8s [ reg_al ] ; this . reg16 [ reg_ax ] = a ; this . last_result = a & 255 ; this . last_op_size = OPSIZE_8 ; this . flags = 127 < a || - 128 > a ? this . flags | 1 | flag_overflow : this . flags & - 2 & ~ flag_overflow ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; } ; CPU . prototype . mul16 = function ( a ) { a *= this . reg16 [ reg_ax ] ; var b = a >>> 16 ; this . reg16 [ reg_ax ] = a ; this . reg16 [ reg_dx ] = b ; this . last_result = a & 65535 ; this . last_op_size = OPSIZE_16 ; this . flags = 0 === b ? this . flags & - 2 & ~ flag_overflow : this . flags | 1 | flag_overflow ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; } ; CPU . prototype . imul16 = function ( a ) { a *= this . reg16s [ reg_ax ] ; this . reg16 [ reg_ax ] = a ; this . reg16 [ reg_dx ] = a >> 16 ; this . last_result = a & 65535 ; this . last_op_size = OPSIZE_16 ; this . flags = 32767 < a || - 32768 > a ? this . flags | 1 | flag_overflow : this . flags & - 2 & ~ flag_overflow ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; } ; CPU . prototype . imul_reg16 = function ( a , b ) { dbg_assert ( 32768 > a && - 32768 <= a ) ; dbg_assert ( 32768 > b && - 32768 <= b ) ; a *= b ; this . last_result = a & 65535 ; this . last_op_size = OPSIZE_16 ; this . flags = 32767 < a || - 32768 > a ? this . flags | 1 | flag_overflow : this . flags & - 2 & ~ flag_overflow ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; return a ; } ; CPU . prototype . do_mul32 = function ( a , b ) { var c = a & 65535 ; a >>>= 16 ; var d = b & 65535 ; b >>>= 16 ; var e = c * d ; d = ( e >>> 16 ) + ( a * d | 0 ) | 0 ; var g = d >>> 16 ; d = ( d & 65535 ) + ( c * b | 0 ) | 0 ; this . mul32_result [ 0 ] = d << 16 | e & 65535 ; this . mul32_result [ 1 ] = ( ( d >>> 16 ) + ( a * b | 0 ) | 0 ) + g | 0 ; return this . mul32_result ; } ; CPU . prototype . do_imul32 = function ( a , b ) { var c = ! 1 ; 0 > a && ( c = ! 0 , a = - a | 0 ) ; 0 > b && ( c = ! c , b = - b | 0 ) ; a = this . do_mul32 ( a , b ) ; c && ( a [ 0 ] = - a [ 0 ] | 0 , a [ 1 ] = ~ a [ 1 ] + ! a [ 0 ] | 0 ) ; return a ; } ; CPU . prototype . mul32 = function ( a ) { a = this . do_mul32 ( this . reg32s [ reg_eax ] , a ) ; this . reg32s [ reg_eax ] = a [ 0 ] ; this . reg32s [ reg_edx ] = a [ 1 ] ; this . last_result = a [ 0 ] ; this . last_op_size = OPSIZE_32 ; this . flags = 0 === a [ 1 ] ? this . flags & - 2 & ~ flag_overflow : this . flags | 1 | flag_overflow ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; } ; CPU . prototype . imul32 = function ( a ) { dbg_assert ( 2147483648 > a && - 2147483648 <= a ) ; a = this . do_imul32 ( this . reg32s [ reg_eax ] , a ) ; this . reg32s [ reg_eax ] = a [ 0 ] ; this . reg32s [ reg_edx ] = a [ 1 ] ; this . last_result = a [ 0 ] ; this . last_op_size = OPSIZE_32 ; this . flags = a [ 1 ] === a [ 0 ] >> 31 ? this . flags & - 2 & ~ flag_overflow : this . flags | 1 | flag_overflow ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; } ; CPU . prototype . imul_reg32 = function ( a , b ) { dbg_assert ( 2147483648 > a && - 2147483648 <= a ) ; dbg_assert ( 2147483648 > b && - 2147483648 <= b ) ; a = this . do_imul32 ( a , b ) ; this . last_result = a [ 0 ] ; this . last_op_size = OPSIZE_32 ; this . flags = a [ 1 ] === a [ 0 ] >> 31 ? this . flags & - 2 & ~ flag_overflow : this . flags | 1 | flag_overflow ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; return a [ 0 ] ; } ; CPU . prototype . div8 = function ( a ) { dbg_assert ( 0 <= a && 256 > a ) ; if ( 0 === a ) this . trigger_de ( ) ; else { var b = this . reg16 [ reg_ax ] , c = b / a | 0 ; 256 <= c ? this . trigger_de ( ) : ( this . reg8 [ reg_al ] = c , this . reg8 [ reg_ah ] = b % a ) ; } } ; CPU . prototype . idiv8 = function ( a ) { dbg_assert ( - 128 <= a && 128 > a ) ; if ( 0 === a ) this . trigger_de ( ) ; else { var b = this . reg16s [ reg_ax ] , c = b / a | 0 ; 128 <= c || - 129 >= c ? this . trigger_de ( ) : ( this . reg8 [ reg_al ] = c , this . reg8 [ reg_ah ] = b % a ) ; } } ; CPU . prototype . div16 = function ( a ) { dbg_assert ( 0 <= a && 65536 > a ) ; if ( 0 === a ) this . trigger_de ( ) ; else { var b = ( this . reg16 [ reg_ax ] | this . reg16 [ reg_dx ] << 16 ) >>> 0 , c = b / a | 0 ; 65536 <= c || 0 > c ? this . trigger_de ( ) : ( this . reg16 [ reg_ax ] = c , this . reg16 [ reg_dx ] = b % a ) ; } } ; CPU . prototype . idiv16 = function ( a ) { dbg_assert ( - 32768 <= a && 32768 > a ) ; if ( 0 === a ) this . trigger_de ( ) ; else { var b = this . reg16 [ reg_ax ] | this . reg16 [ reg_dx ] << 16 , c = b / a | 0 ; 32768 <= c || - 32769 >= c ? this . trigger_de ( ) : ( this . reg16 [ reg_ax ] = c , this . reg16 [ reg_dx ] = b % a ) ; } } ; CPU . prototype . do_div32 = function ( a , b , c ) { if ( b >= c || 0 === c ) dbg_log ( "div32 #DE: " + h ( b , 8 ) + ":" + h ( a , 8 ) + " div " + h ( c , 8 ) ) , this . trigger_de ( ) ; var d = 0 ; if ( 1048576 < b ) { for ( var e = 32 , g = c ; g > b ; ) g >>>= 1 , e -- ; for ( ; 1048576 < b ; ) { if ( b >= g ) { b -= g ; var f = c << e >>> 0 ; f > a && b -- ; a = a - f >>> 0 ; d |= 1 << e ; } e -- ; g >>= 1 ; } d >>>= 0 ; } a += 4294967296 * b ; this . div32_result [ 0 ] = d + ( a / c | 0 ) ; this . div32_result [ 1 ] = a % c ; return this . div32_result ; } ; CPU . prototype . div32 = function ( a ) { dbg_assert ( 0 <= a && 4294967295 >= a ) ; var b = this . reg32 [ reg_eax ] , c = this . reg32 [ reg_edx ] , d = this . do_div32 ( b , c , a ) , e = d [ 0 ] ; d = d [ 1 ] ; dbg_assert ( a ) ; 4294967296 <= e ? ( dbg_log ( "div32 #DE: " + h ( c , 8 ) + ":" + h ( b , 8 ) + " div " + h ( a , 8 ) ) , dbg_log ( "-> " + h ( e ) ) , this . trigger_de ( ) ) : ( this . reg32s [ reg_eax ] = e , this . reg32s [ reg_edx ] = d ) ; } ; CPU . prototype . idiv32 = function ( a ) { dbg_assert ( 2147483648 > a && - 2147483648 <= a ) ; var b = this . reg32 [ reg_eax ] , c = this . reg32s [ reg_edx ] , d = ! 1 , e = ! 1 ; 0 > a && ( e = ! 0 , a = - a ) ; 0 > c && ( d = ! 0 , e = ! e , b = - b >>> 0 , c = ~ c + ! b ) ; var g = this . do_div32 ( b , c , a ) , f = g [ 0 ] ; g = g [ 1 ] ; e && ( f = - f | 0 ) ; d && ( g = - g | 0 ) ; dbg_assert ( a ) ; 2147483648 <= f || - 2147483649 >= f ? ( dbg_log ( "div32 #DE: " + h ( c , 8 ) + ":" + h ( b , 8 ) + " div " + h ( a , 8 ) ) , dbg_log ( "-> " + h ( f ) ) , this . trigger_de ( ) ) : ( this . reg32s [ reg_eax ] = f , this . reg32s [ reg_edx ] = g ) ; } ; CPU . prototype . xadd8 = function ( a , b ) { var c = this . reg8 [ b ] ; this . reg8 [ b ] = a ; return this . add ( a , c , OPSIZE_8 ) ; } ; CPU . prototype . xadd16 = function ( a , b ) { var c = this . reg16 [ b ] ; this . reg16 [ b ] = a ; return this . add ( a , c , OPSIZE_16 ) ; } ; CPU . prototype . xadd32 = function ( a , b ) { var c = this . reg32s [ b ] ; this . reg32s [ b ] = a ; return this . add ( a , c , OPSIZE_32 ) ; } ; CPU . prototype . bcd_daa = function ( ) { var a = this . reg8 [ reg_al ] , b = this . getcf ( ) , c = this . getaf ( ) ; this . flags = this . flags & - 2 & ~ flag_adjust ; if ( 9 < ( a & 15 ) || c ) this . reg8 [ reg_al ] += 6 , this . flags |= flag_adjust ; if ( 153 < a || b ) this . reg8 [ reg_al ] += 96 , this . flags |= 1 ; this . last_result = this . reg8 [ reg_al ] ; this . last_op_size = OPSIZE_8 ; this . last_op1 = this . last_op2 = 0 ; this . flags_changed = flags_all & - 2 & ~ flag_adjust & ~ flag_overflow ; } ; CPU . prototype . bcd_das = function ( ) { var a = this . reg8 [ reg_al ] , b = this . getcf ( ) ; this . flags &= - 2 ; 9 < ( a & 15 ) || this . getaf ( ) ? ( this . reg8 [ reg_al ] -= 6 , this . flags |= flag_adjust , this . flags = this . flags & - 2 | b | 6 > a ) : this . flags &= ~ flag_adjust ; if ( 153 < a || b ) this . reg8 [ reg_al ] -= 96 , this . flags |= 1 ; this . last_result = this . reg8 [ reg_al ] ; this . last_op_size = OPSIZE_8 ; this . last_op1 = this . last_op2 = 0 ; this . flags_changed = flags_all & - 2 & ~ flag_adjust & ~ flag_overflow ; } ; CPU . prototype . bcd_aam = function ( a ) { if ( 0 === a ) this . trigger_de ( ) ; else { var b = this . reg8 [ reg_al ] ; this . reg8 [ reg_ah ] = b / a ; this . reg8 [ reg_al ] = b % a ; this . last_result = this . reg8 [ reg_al ] ; this . flags_changed = flags_all & - 2 & ~ flag_adjust & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_adjust & ~ flag_overflow ; } } ; CPU . prototype . bcd_aad = function ( a ) { a = this . reg8 [ reg_al ] + this . reg8 [ reg_ah ] * a ; this . last_result = a & 255 ; this . reg16 [ reg_ax ] = this . last_result ; this . last_op_size = OPSIZE_8 ; this . flags_changed = flags_all & - 2 & ~ flag_adjust & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_adjust & ~ flag_overflow ; 65535 < a && ( this . flags |= 1 ) ; } ; CPU . prototype . bcd_aaa = function ( ) { 9 < ( this . reg8 [ reg_al ] & 15 ) || this . getaf ( ) ? ( this . reg16 [ reg_ax ] += 6 , this . reg8 [ reg_ah ] += 1 , this . flags = this . flags | flag_adjust | 1 ) : this . flags = this . flags & ~ flag_adjust & - 2 ; this . reg8 [ reg_al ] &= 15 ; this . flags_changed = this . flags_changed & ~ flag_adjust & - 2 ; } ; CPU . prototype . bcd_aas = function ( ) { 9 < ( this . reg8 [ reg_al ] & 15 ) || this . getaf ( ) ? ( this . reg16 [ reg_ax ] -= 6 , -- this . reg8 [ reg_ah ] , this . flags = this . flags | flag_adjust | 1 ) : this . flags = this . flags & ~ flag_adjust & - 2 ; this . reg8 [ reg_al ] &= 15 ; this . flags_changed = this . flags_changed & ~ flag_adjust & - 2 ; } ; CPU . prototype . and8 = function ( a , b ) { return this . and ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . and16 = function ( a , b ) { return this . and ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . and32 = function ( a , b ) { return this . and ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . test8 = function ( a , b ) { return this . and ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . test16 = function ( a , b ) { return this . and ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . test32 = function ( a , b ) { return this . and ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . or8 = function ( a , b ) { return this . or ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . or16 = function ( a , b ) { return this . or ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . or32 = function ( a , b ) { return this . or ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . xor8 = function ( a , b ) { return this . xor ( a , b , OPSIZE_8 ) ; } ; CPU . prototype . xor16 = function ( a , b ) { return this . xor ( a , b , OPSIZE_16 ) ; } ; CPU . prototype . xor32 = function ( a , b ) { return this . xor ( a , b , OPSIZE_32 ) ; } ; CPU . prototype . and = function ( a , b , c ) { this . last_result = a & b ; this . last_op_size = c ; this . flags = this . flags & - 2 & ~ flag_overflow & ~ flag_adjust ; this . flags_changed = flags_all & - 2 & ~ flag_overflow & ~ flag_adjust ; return this . last_result ; } ; CPU . prototype . or = function ( a , b , c ) { this . last_result = a | b ; this . last_op_size = c ; this . flags = this . flags & - 2 & ~ flag_overflow & ~ flag_adjust ; this . flags_changed = flags_all & - 2 & ~ flag_overflow & ~ flag_adjust ; return this . last_result ; } ; CPU . prototype . xor = function ( a , b , c ) { this . last_result = a ^ b ; this . last_op_size = c ; this . flags = this . flags & - 2 & ~ flag_overflow & ~ flag_adjust ; this . flags_changed = flags_all & - 2 & ~ flag_overflow & ~ flag_adjust ; return this . last_result ; } ; CPU . prototype . rol8 = function ( a , b ) { if ( ! b ) return a ; b &= 7 ; a = a << b | a >> 8 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a & 1 | ( a << 11 ^ a << 4 ) & flag_overflow ; return a ; } ; CPU . prototype . rol16 = function ( a , b ) { if ( ! b ) return a ; b &= 15 ; a = a << b | a >> 16 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a & 1 | ( a << 11 ^ a >> 4 ) & flag_overflow ; return a ; } ; CPU . prototype . rol32 = function ( a , b ) { if ( ! b ) return a ; a = a << b | a >>> 32 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a & 1 | ( a << 11 ^ a >> 20 ) & flag_overflow ; return a ; } ; CPU . prototype . rcl8 = function ( a , b ) { b %= 9 ; if ( ! b ) return a ; a = a << b | this . getcf ( ) << b - 1 | a >> 9 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> 8 & 1 | ( a << 3 ^ a << 4 ) & flag_overflow ; return a ; } ; CPU . prototype . rcl16 = function ( a , b ) { b %= 17 ; if ( ! b ) return a ; a = a << b | this . getcf ( ) << b - 1 | a >> 17 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> 16 & 1 | ( a >> 5 ^ a >> 4 ) & flag_overflow ; return a ; } ; CPU . prototype . rcl32 = function ( a , b ) { if ( ! b ) return a ; var c = a << b | this . getcf ( ) << b - 1 ; 1 < b && ( c |= a >>> 33 - b ) ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >>> 32 - b & 1 ; this . flags |= ( this . flags << 11 ^ c >> 20 ) & flag_overflow ; return c ; } ; CPU . prototype . ror8 = function ( a , b ) { if ( ! b ) return a ; b &= 7 ; a = a >> b | a << 8 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> 7 & 1 | ( a << 4 ^ a << 5 ) & flag_overflow ; return a ; } ; CPU . prototype . ror16 = function ( a , b ) { if ( ! b ) return a ; b &= 15 ; a = a >> b | a << 16 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> 15 & 1 | ( a >> 4 ^ a >> 3 ) & flag_overflow ; return a ; } ; CPU . prototype . ror32 = function ( a , b ) { if ( ! b ) return a ; a = a >>> b | a << 32 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> 31 & 1 | ( a >> 20 ^ a >> 19 ) & flag_overflow ; return a ; } ; CPU . prototype . rcr8 = function ( a , b ) { b %= 9 ; if ( ! b ) return a ; a = a >> b | this . getcf ( ) << 8 - b | a << 9 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> 8 & 1 | ( a << 4 ^ a << 5 ) & flag_overflow ; return a ; } ; CPU . prototype . rcr16 = function ( a , b ) { b %= 17 ; if ( ! b ) return a ; a = a >> b | this . getcf ( ) << 16 - b | a << 17 - b ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> 16 & 1 | ( a >> 4 ^ a >> 3 ) & flag_overflow ; return a ; } ; CPU . prototype . rcr32 = function ( a , b ) { if ( ! b ) return a ; var c = a >>> b | this . getcf ( ) << 32 - b ; 1 < b && ( c |= a << 33 - b ) ; this . flags_changed = this . flags_changed & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> b - 1 & 1 | ( c >> 20 ^ c >> 19 ) & flag_overflow ; return c ; } ; CPU . prototype . shl8 = function ( a , b ) { if ( 0 === b ) return a ; this . last_result = a << b ; this . last_op_size = OPSIZE_8 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | this . last_result >> 8 & 1 | ( this . last_result << 3 ^ this . last_result << 4 ) & flag_overflow ; return this . last_result ; } ; CPU . prototype . shl16 = function ( a , b ) { if ( 0 === b ) return a ; this . last_result = a << b ; this . last_op_size = OPSIZE_16 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | this . last_result >> 16 & 1 | ( this . last_result >> 5 ^ this . last_result >> 4 ) & flag_overflow ; return this . last_result ; } ; CPU . prototype . shl32 = function ( a , b ) { if ( 0 === b ) return a ; this . last_result = a << b ; this . last_op_size = OPSIZE_32 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >>> 32 - b & 1 ; this . flags |= ( this . flags & 1 ^ this . last_result >> 31 & 1 ) << 11 & flag_overflow ; return this . last_result ; } ; CPU . prototype . shr8 = function ( a , b ) { if ( 0 === b ) return a ; this . last_result = a >> b ; this . last_op_size = OPSIZE_8 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> b - 1 & 1 | ( a >> 7 & 1 ) << 11 & flag_overflow ; return this . last_result ; } ; CPU . prototype . shr16 = function ( a , b ) { if ( 0 === b ) return a ; this . last_result = a >> b ; this . last_op_size = OPSIZE_16 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >> b - 1 & 1 | a >> 4 & flag_overflow ; return this . last_result ; } ; CPU . prototype . shr32 = function ( a , b ) { if ( 0 === b ) return a ; this . last_result = a >>> b ; this . last_op_size = OPSIZE_32 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >>> b - 1 & 1 | a >> 20 & flag_overflow ; return this . last_result ; } ; CPU . prototype . sar8 = function ( a , b ) { if ( 0 === b ) return a ; 8 > b ? ( this . last_result = a << 24 >> b + 24 , this . flags = this . flags & - 2 & ~ flag_overflow | a >> b - 1 & 1 ) : ( this . last_result = a << 24 >> 31 , this . flags = this . flags & - 2 & ~ flag_overflow | this . last_result & 1 ) ; this . last_op_size = OPSIZE_8 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; return this . last_result ; } ; CPU . prototype . sar16 = function ( a , b ) { if ( 0 === b ) return a ; 16 > b ? ( this . last_result = a << 16 >> b + 16 , this . flags = this . flags & - 2 & ~ flag_overflow | a >> b - 1 & 1 ) : ( this . last_result = a << 16 >> 31 , this . flags = this . flags & - 2 & ~ flag_overflow | this . last_result & 1 ) ; this . last_op_size = OPSIZE_16 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; return this . last_result ; } ; CPU . prototype . sar32 = function ( a , b ) { if ( 0 === b ) return a ; this . last_result = a >> b ; this . last_op_size = OPSIZE_32 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 & ~ flag_overflow | a >>> b - 1 & 1 ; return this . last_result ; } ; CPU . prototype . shrd16 = function ( a , b , c ) { if ( 0 === c ) return a ; 16 >= c ? ( this . last_result = a >> c | b << 16 - c , this . flags = this . flags & - 2 | a >> c - 1 & 1 ) : ( this . last_result = a << 32 - c | b >> c - 16 , this . flags = this . flags & - 2 | b >> c - 17 & 1 ) ; this . last_op_size = OPSIZE_16 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & ~ flag_overflow | ( this . last_result ^ a ) >> 4 & flag_overflow ; return this . last_result ; } ; CPU . prototype . shrd32 = function ( a , b , c ) { if ( 0 === c ) return a ; this . last_result = a >>> c | b << 32 - c ; this . last_op_size = OPSIZE_32 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 | a >>> c - 1 & 1 ; this . flags = this . flags & ~ flag_overflow | ( this . last_result ^ a ) >> 20 & flag_overflow ; return this . last_result ; } ; CPU . prototype . shld16 = function ( a , b , c ) { if ( 0 === c ) return a ; 16 >= c ? ( this . last_result = a << c | b >>> 16 - c , this . flags = this . flags & - 2 | a >>> 16 - c & 1 ) : ( this . last_result = a >> 32 - c | b << c - 16 , this . flags = this . flags & - 2 | b >>> 32 - c & 1 ) ; this . last_op_size = OPSIZE_16 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & ~ flag_overflow | ( this . flags & 1 ^ this . last_result >> 15 & 1 ) << 11 ; return this . last_result ; } ; CPU . prototype . shld32 = function ( a , b , c ) { if ( 0 === c ) return a ; this . last_result = a << c | b >>> 32 - c ; this . last_op_size = OPSIZE_32 ; this . flags_changed = flags_all & - 2 & ~ flag_overflow ; this . flags = this . flags & - 2 | a >>> 32 - c & 1 ; this . flags = 1 === c ? this . flags & ~ flag_overflow | ( this . flags & 1 ^ this . last_result >> 31 & 1 ) << 11 : this . flags & ~ flag_overflow ; return this . last_result ; } ; CPU . prototype . bt_reg = function ( a , b ) { this . flags = this . flags & - 2 | a >> b & 1 ; this . flags_changed &= - 2 ; } ; CPU . prototype . btc_reg = function ( a , b ) { this . flags = this . flags & - 2 | a >> b & 1 ; this . flags_changed &= - 2 ; return a ^ 1 << b ; } ; CPU . prototype . bts_reg = function ( a , b ) { this . flags = this . flags & - 2 | a >> b & 1 ; this . flags_changed &= - 2 ; return a | 1 << b ; } ; CPU . prototype . btr_reg = function ( a , b ) { this . flags = this . flags & - 2 | a >> b & 1 ; this . flags_changed &= - 2 ; return a & ~ ( 1 << b ) ; } ; CPU . prototype . bt_mem = function ( a , b ) { a = this . safe_read8 ( a + ( b >> 3 ) | 0 ) ; this . flags = this . flags & - 2 | a >> ( b & 7 ) & 1 ; this . flags_changed &= - 2 ; } ; CPU . prototype . btc_mem = function ( a , b ) { a = this . translate_address_write ( a + ( b >> 3 ) | 0 ) ; var c = this . read8 ( a ) ; b &= 7 ; this . flags = this . flags & - 2 | c >> b & 1 ; this . flags_changed &= - 2 ; this . write8 ( a , c ^ 1 << b ) ; } ; CPU . prototype . btr_mem = function ( a , b ) { a = this . translate_address_write ( a + ( b >> 3 ) | 0 ) ; var c = this . read8 ( a ) ; b &= 7 ; this . flags = this . flags & - 2 | c >> b & 1 ; this . flags_changed &= - 2 ; this . write8 ( a , c & ~ ( 1 << b ) ) ; } ; CPU . prototype . bts_mem = function ( a , b ) { a = this . translate_address_write ( a + ( b >> 3 ) | 0 ) ; var c = this . read8 ( a ) ; b &= 7 ; this . flags = this . flags & - 2 | c >> b & 1 ; this . flags_changed &= - 2 ; this . write8 ( a , c | 1 << b ) ; } ; CPU . prototype . bsf16 = function ( a , b ) { this . flags_changed = flags_all & ~ flag_zero ; this . last_op_size = OPSIZE_16 ; if ( 0 === b ) return this . flags |= flag_zero , this . last_result = b , a ; this . flags &= ~ flag_zero ; return this . last_result = v86util . int_log2 ( - b & b ) ; } ; CPU . prototype . bsf32 = function ( a , b ) { this . flags_changed = flags_all & ~ flag_zero ; this . last_op_size = OPSIZE_32 ; if ( 0 === b ) return this . flags |= flag_zero , this . last_result = b , a ; this . flags &= ~ flag_zero ; return this . last_result = v86util . int_log2 ( ( - b & b ) >>> 0 ) ; } ; CPU . prototype . bsr16 = function ( a , b ) { this . flags_changed = flags_all & ~ flag_zero ; this . last_op_size = OPSIZE_16 ; if ( 0 === b ) return this . flags |= flag_zero , this . last_result = b , a ; this . flags &= ~ flag_zero ; return this . last_result = v86util . int_log2 ( b ) ; } ; CPU . prototype . bsr32 = function ( a , b ) { this . flags_changed = flags_all & ~ flag_zero ; this . last_op_size = OPSIZE_32 ; if ( 0 === b ) return this . flags |= flag_zero , this . last_result = b , a ; this . flags &= ~ flag_zero ; return this . last_result = v86util . int_log2 ( b >>> 0 ) ; } ; CPU . prototype . popcnt = function ( a ) { this . flags_changed = 0 ; this . flags &= ~ flags_all ; if ( a ) return a -= a >> 1 & 1431655765 , a = ( a & 858993459 ) + ( a >> 2 & 858993459 ) , 16843009 * ( a + ( a >> 4 ) & 252645135 ) >> 24 ; this . flags |= flag_zero ; return 0 ; } ; CPU . prototype . saturate_sw_to_ub = function ( a ) { dbg_assert ( 0 === ( a & 4294901760 ) ) ; a >>>= 0 ; 32768 <= a ? a = 0 : 255 < a && ( a = 255 ) ; dbg_assert ( 0 === ( a & 4294967040 ) ) ; return a ; } ; CPU . prototype . saturate_sw_to_sb = function ( a ) { dbg_assert ( 0 === ( a & 4294901760 ) ) ; 65408 < a ? a &= 255 : 32767 < a ? a = 128 : 127 < a && ( a = 127 ) ; dbg_assert ( 0 === ( a & 4294967040 ) ) ; return a ; } ; CPU . prototype . saturate_sd_to_sw = function ( a ) { a >>>= 0 ; 4294934528 < a ? a &= 65535 : 2147483647 < a ? a = 32768 : 32767 < a && ( a = 32767 ) ; dbg_assert ( 0 === ( a & 4294901760 ) ) ; return a ; } ; CPU . prototype . saturate_sd_to_sb = function ( a ) { a >>>= 0 ; 4294967168 < a ? a &= 255 : 2147483647 < a ? a = 128 : 127 < a && ( a = 127 ) ; dbg_assert ( 0 === ( a & 4294967040 ) ) ; return a ; } ; CPU . prototype . saturate_sd_to_ub = function ( a ) { a |= 0 ; 0 > a && ( a = 0 ) ; dbg_assert ( 0 === ( a & 4294967040 ) ) ; return a ; } ; CPU . prototype . saturate_ud_to_ub = function ( a ) { a >>>= 0 ; 255 < a && ( a = 255 ) ; dbg_assert ( 0 === ( a & 4294967040 ) ) ; return a ; } ; CPU . prototype . saturate_uw = function ( a ) { dbg_assert ( 0 <= a ) ; return 65535 < a ? 65535 : a ; } ; CPU . prototype . jmpcc8 = function ( a ) { var b = this . read_op8s ( ) ; a ? ( this . instruction_pointer = this . instruction_pointer + b | 0 , this . branch_taken ( ) ) : this . branch_not_taken ( ) ; } ; CPU . prototype . jmp_rel16 = function ( a ) { var b = this . get_seg ( reg_cs ) ; this . instruction_pointer -= b ; this . instruction_pointer = this . instruction_pointer + a & 65535 ; this . instruction_pointer = this . instruction_pointer + b | 0 ; } ; CPU . prototype . jmpcc16 = function ( a ) { var b = this . read_op16 ( ) ; a ? ( this . jmp_rel16 ( b ) , this . branch_taken ( ) ) : this . branch_not_taken ( ) ; } ; CPU . prototype . jmpcc32 = function ( a ) { var b = this . read_op32s ( ) ; a ? ( this . instruction_pointer = this . instruction_pointer + b | 0 , this . branch_taken ( ) ) : this . branch_not_taken ( ) ; } ; CPU . prototype . cmovcc16 = function ( a ) { var b = this . read_e16 ( ) ; a && this . write_g16 ( b ) ; } ; CPU . prototype . cmovcc32 = function ( a ) { var b = this . read_e32s ( ) ; a && this . write_g32 ( b ) ; } ; CPU . prototype . setcc = function ( a ) { this . set_e8 ( a ? 1 : 0 ) ; } ; CPU . prototype . loopne = function ( a ) { this . decr_ecx_asize ( ) && ! this . getzf ( ) ? ( this . instruction_pointer = this . instruction_pointer + a | 0 , this . branch_taken ( ) ) : this . branch_not_taken ( ) ; } ; CPU . prototype . loope = function ( a ) { this . decr_ecx_asize ( ) && this . getzf ( ) ? ( this . instruction_pointer = this . instruction_pointer + a | 0 , this . branch_taken ( ) ) : this . branch_not_taken ( ) ; } ; CPU . prototype . loop = function ( a ) { this . decr_ecx_asize ( ) ? ( this . instruction_pointer = this . instruction_pointer + a | 0 , this . branch_taken ( ) ) : this . branch_not_taken ( ) ; } ; CPU . prototype . jcxz = function ( a ) { 0 === this . get_reg_asize ( reg_ecx ) ? ( this . instruction_pointer = this . instruction_pointer + a | 0 , this . branch_taken ( ) ) : this . branch_not_taken ( ) ; } ; CPU . prototype . getcf = function ( ) { return this . flags_changed & 1 ? ( this . last_op1 ^ ( this . last_op1 ^ this . last_op2 ) & ( this . last_op2 ^ this . last_add_result ) ) >>> this . last_op_size & 1 : this . flags & 1 ; } ; CPU . prototype . getpf = function ( ) { return this . flags_changed & flag_parity ? 154020 >> ( ( this . last_result ^ this . last_result >> 4 ) & 15 ) & flag_parity : this . flags & flag_parity ; } ; CPU . prototype . getaf = function ( ) { return this . flags_changed & flag_adjust ? ( this . last_op1 ^ this . last_op2 ^ this . last_add_result ) & flag_adjust : this . flags & flag_adjust ; } ; CPU . prototype . getzf = function ( ) { return this . flags_changed & flag_zero ? ( ~ this . last_result & this . last_result - 1 ) >>> this . last_op_size & 1 : this . flags & flag_zero ; } ; CPU . prototype . getsf = function ( ) { return this . flags_changed & flag_sign ? this . last_result >>> this . last_op_size & 1 : this . flags & flag_sign ; } ; CPU . prototype . getof = function ( ) { return this . flags_changed & flag_overflow ? ( ( this . last_op1 ^ this . last_add_result ) & ( this . last_op2 ^ this . last_add_result ) ) >>> this . last_op_size & 1 : this . flags & flag_overflow ; } ; CPU . prototype . test_o = CPU . prototype . getof ; CPU . prototype . test_b = CPU . prototype . getcf ; CPU . prototype . test_z = CPU . prototype . getzf ; CPU . prototype . test_s = CPU . prototype . getsf ; CPU . prototype . test_p = CPU . prototype . getpf ; CPU . prototype . test_be = function ( ) { return this . getcf ( ) || this . getzf ( ) ; } ; CPU . prototype . test_l = function ( ) { return ! this . getsf ( ) !== ! this . getof ( ) ; } ; CPU . prototype . test_le = function ( ) { return this . getzf ( ) || ! this . getsf ( ) !== ! this . getof ( ) ; } ; CPU . prototype . push16 = function ( a ) { var b = this . get_stack_pointer ( - 2 ) ; this . safe_write16 ( b , a ) ; this . adjust_stack_reg ( - 2 ) ; } ; CPU . prototype . push32 = function ( a ) { var b = this . get_stack_pointer ( - 4 ) ; this . safe_write32 ( b , a ) ; this . adjust_stack_reg ( - 4 ) ; } ; CPU . prototype . pop16 = function ( ) { var a = this . get_seg ( reg_ss ) + this . get_stack_reg ( ) | 0 ; a = this . safe_read16 ( a ) ; this . adjust_stack_reg ( 2 ) ; return a ; } ; CPU . prototype . pop32s = function ( ) { var a = this . get_seg ( reg_ss ) + this . get_stack_reg ( ) | 0 ; a = this . safe_read32s ( a ) ; this . adjust_stack_reg ( 4 ) ; return a ; } ; CPU . prototype . pusha16 = function ( ) { var a = this . reg16 [ reg_sp ] ; this . writable_or_pagefault ( this . get_stack_pointer ( - 16 ) , 16 ) ; this . push16 ( this . reg16 [ reg_ax ] ) ; this . push16 ( this . reg16 [ reg_cx ] ) ; this . push16 ( this . reg16 [ reg_dx ] ) ; this . push16 ( this . reg16 [ reg_bx ] ) ; this . push16 ( a ) ; this . push16 ( this . reg16 [ reg_bp ] ) ; this . push16 ( this . reg16 [ reg_si ] ) ; this . push16 ( this . reg16 [ reg_di ] ) ; } ; CPU . prototype . pusha32 = function ( ) { var a = this . reg32s [ reg_esp ] ; this . writable_or_pagefault ( this . get_stack_pointer ( - 32 ) , 32 ) ; this . push32 ( this . reg32s [ reg_eax ] ) ; this . push32 ( this . reg32s [ reg_ecx ] ) ; this . push32 ( this . reg32s [ reg_edx ] ) ; this . push32 ( this . reg32s [ reg_ebx ] ) ; this . push32 ( a ) ; this . push32 ( this . reg32s [ reg_ebp ] ) ; this . push32 ( this . reg32s [ reg_esi ] ) ; this . push32 ( this . reg32s [ reg_edi ] ) ; } ; CPU . prototype . popa16 = function ( ) { this . translate_address_read ( this . get_stack_pointer ( 0 ) ) ; this . translate_address_read ( this . get_stack_pointer ( 15 ) ) ; this . reg16 [ reg_di ] = this . pop16 ( ) ; this . reg16 [ reg_si ] = this . pop16 ( ) ; this . reg16 [ reg_bp ] = this . pop16 ( ) ; this . adjust_stack_reg ( 2 ) ; this . reg16 [ reg_bx ] = this . pop16 ( ) ; this . reg16 [ reg_dx ] = this . pop16 ( ) ; this . reg16 [ reg_cx ] = this . pop16 ( ) ; this . reg16 [ reg_ax ] = this . pop16 ( ) ; } ; CPU . prototype . popa32 = function ( ) { this . translate_address_read ( this . get_stack_pointer ( 0 ) ) ; this . translate_address_read ( this . get_stack_pointer ( 31 ) ) ; this . reg32s [ reg_edi ] = this . pop32s ( ) ; this . reg32s [ reg_esi ] = this . pop32s ( ) ; this . reg32s [ reg_ebp ] = this . pop32s ( ) ; this . adjust_stack_reg ( 4 ) ; this . reg32s [ reg_ebx ] = this . pop32s ( ) ; this . reg32s [ reg_edx ] = this . pop32s ( ) ; this . reg32s [ reg_ecx ] = this . pop32s ( ) ; this . reg32s [ reg_eax ] = this . pop32s ( ) ; } ; CPU . prototype . xchg8 = function ( a , b ) { b = b >> 1 & 12 | b >> 5 & 1 ; var c = this . reg8 [ b ] ; this . reg8 [ b ] = a ; return c ; } ; CPU . prototype . xchg16 = function ( a , b ) { b = b >> 2 & 14 ; var c = this . reg16 [ b ] ; this . reg16 [ b ] = a ; return c ; } ; CPU . prototype . xchg16r = function ( a ) { var b = this . reg16 [ reg_ax ] ; this . reg16 [ reg_ax ] = this . reg16 [ a ] ; this . reg16 [ a ] = b ; } ; CPU . prototype . xchg32 = function ( a , b ) { b = b >> 3 & 7 ; var c = this . reg32s [ b ] ; this . reg32s [ b ] = a ; return c ; } ; CPU . prototype . xchg32r = function ( a ) { var b = this . reg32s [ reg_eax ] ; this . reg32s [ reg_eax ] = this . reg32s [ a ] ; this . reg32s [ a ] = b ; } ; CPU . prototype . lss16 = function ( a ) { 192 <= this . modrm_byte && this . trigger_ud ( ) ; var b = this . modrm_resolve ( this . modrm_byte ) , c = this . safe_read16 ( b ) ; b = this . safe_read16 ( b + 2 | 0 ) ; this . switch_seg ( a , b ) ; this . reg16 [ this . modrm_byte >> 2 & 14 ] = c ; } ; CPU . prototype . lss32 = function ( a ) { 192 <= this . modrm_byte && this . trigger_ud ( ) ; var b = this . modrm_resolve ( this . modrm_byte ) , c = this . safe_read32s ( b ) ; b = this . safe_read16 ( b + 4 | 0 ) ; this . switch_seg ( a , b ) ; this . reg32s [ this . modrm_byte >> 3 & 7 ] = c ; } ; CPU . prototype . enter16 = function ( a , b ) { ( b &= 31 ) && dbg_log ( "enter16 stack=" + ( this . stack_size_32 ? 32 : 16 ) + " size=" + a + " nest=" + b , LOG_CPU ) ; this . push16 ( this . reg16 [ reg_bp ] ) ; var c = this . reg16 [ reg_sp ] ; if ( 0 < b ) { for ( var d = this . reg16 [ reg_ebp ] , e = 1 ; e < b ; e ++ ) d -= 2 , this . push16 ( this . safe_read16 ( this . get_seg ( reg_ss ) + d | 0 ) ) ; this . push16 ( c ) ; } this . reg16 [ reg_bp ] = c ; this . adjust_stack_reg ( - a ) ; } ; CPU . prototype . enter32 = function ( a , b ) { ( b &= 31 ) && dbg_log ( "enter32 stack=" + ( this . stack_size_32 ? 32 : 16 ) + " size=" + a + " nest=" + b , LOG_CPU ) ; this . push32 ( this . reg32s [ reg_ebp ] ) ; var c = this . reg32s [ reg_esp ] ; if ( 0 < b ) { for ( var d = this . reg32s [ reg_ebp ] , e = 1 ; e < b ; e ++ ) d -= 4 , this . push32 ( this . safe_read32s ( this . get_seg ( reg_ss ) + d | 0 ) ) ; this . push32 ( c ) ; } this . reg32s [ reg_ebp ] = c ; this . adjust_stack_reg ( - a ) ; } ; CPU . prototype . bswap = function ( a ) { var b = this . reg32s [ a ] ; this . reg32s [ a ] = b >>> 24 | b << 24 | b >> 8 & 65280 | b << 8 & 16711680 ; } ; CPU . prototype . fxsave = function ( a ) { this . writable_or_pagefault ( a , 512 ) ; this . safe_write16 ( a + 0 | 0 , this . fpu . control_word ) ; this . safe_write16 ( a + 2 | 0 , this . fpu . load_status_word ( ) ) ; this . safe_write8 ( a + 4 | 0 , ~ this . fpu . stack_empty & 255 ) ; this . safe_write16 ( a + 6 | 0 , this . fpu . fpu_opcode ) ; this . safe_write32 ( a + 8 | 0 , this . fpu . fpu_ip ) ; this . safe_write16 ( a + 12 | 0 , this . fpu . fpu_ip_selector ) ; this . safe_write32 ( a + 16 | 0 , this . fpu . fpu_dp ) ; this . safe_write16 ( a + 20 | 0 , this . fpu . fpu_dp_selector ) ; this . safe_write32 ( a + 24 | 0 , this . mxcsr ) ; this . safe_write32 ( a + 28 | 0 , MXCSR_MASK ) ; for ( var b = 0 ; 8 > b ; b ++ ) this . fpu . store_m80 ( a + 32 + ( b << 4 ) | 0 , this . fpu . st [ this . fpu . stack_ptr + b & 7 ] ) ; for ( b = 0 ; 8 > b ; b ++ ) this . safe_write32 ( a + 160 + ( b << 4 ) + 0 | 0 , this . reg_xmm32s [ b << 2 | 0 ] ) , this . safe_write32 ( a + 160 + ( b << 4 ) + 4 | 0 , this . reg_xmm32s [ b << 2 | 1 ] ) , this . safe_write32 ( a + 160 + ( b << 4 ) + 8 | 0 , this . reg_xmm32s [ b << 2 | 2 ] ) , this . safe_write32 ( a + 160 + ( b << 4 ) + 12 | 0 , this . reg_xmm32s [ b << 2 | 3 ] ) ; } ; CPU . prototype . fxrstor = function ( a ) { this . translate_address_read ( a | 0 ) ; this . translate_address_read ( a + 511 | 0 ) ; var b = this . safe_read32s ( a + 24 | 0 ) ; b & ~ MXCSR_MASK && ( dbg_log ( "Invalid mxcsr bits: " + h ( ( b & ~ MXCSR_MASK ) >>> 0 , 8 ) ) , this . trigger_gp ( 0 ) ) ; this . fpu . control_word = this . safe_read16 ( a + 0 | 0 ) ; this . fpu . set_status_word ( this . safe_read16 ( a + 2 | 0 ) ) ; this . fpu . stack_empty = ~ this . safe_read8 ( a + 4 | 0 ) & 255 ; this . fpu . fpu_opcode = this . safe_read16 ( a + 6 | 0 ) ; this . fpu . fpu_ip = this . safe_read32s ( a + 8 | 0 ) ; this . fpu . fpu_ip = this . safe_read16 ( a + 12 | 0 ) ; this . fpu . fpu_dp = this . safe_read32s ( a + 16 | 0 ) ; this . fpu . fpu_dp_selector = this . safe_read16 ( a + 20 | 0 ) ; this . mxcsr = b ; for ( b = 0 ; 8 > b ; b ++ ) this . fpu . st [ this . fpu . stack_ptr + b & 7 ] = this . fpu . load_m80 ( a + 32 + ( b << 4 ) | 0 ) ; for ( b = 0 ; 8 > b ; b ++ ) this . reg_xmm32s [ b << 2 | 0 ] = this . safe_read32s ( a + 160 + ( b << 4 ) + 0 | 0 ) , this . reg_xmm32s [ b << 2 | 1 ] = this . safe_read32s ( a + 160 + ( b << 4 ) + 4 | 0 ) , this . reg_xmm32s [ b << 2 | 2 ] = this . safe_read32s ( a + 160 + ( b << 4 ) + 8 | 0 ) , this . reg_xmm32s [ b << 2 | 3 ] = this . safe_read32s ( a + 160 + ( b << 4 ) + 12 | 0 ) ; } ; var t = [ ] , t16 = [ ] , t32 = [ ] ; t [ 0 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e8 ( a . add8 ( a . read_write_e8 ( ) , a . read_g8 ( ) ) ) ; } ; t16 [ 1 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e16 ( a . add16 ( a . read_write_e16 ( ) , a . read_g16 ( ) ) ) ; } ; t32 [ 1 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e32 ( a . add32 ( a . read_write_e32 ( ) , a . read_g32s ( ) ) ) ; } ; t [ 2 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g8 ( a . add8 ( a . read_g8 ( ) , a . read_e8 ( ) ) ) ; } ; t16 [ 3 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . add16 ( a . read_g16 ( ) , a . read_e16 ( ) ) ) ; } ; t32 [ 3 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . add32 ( a . read_g32s ( ) , a . read_e32s ( ) ) ) ; } ; t [ 4 ] = function ( a ) { a . reg8 [ reg_al ] = a . add8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 5 ] = function ( a ) { a . reg16 [ reg_ax ] = a . add16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 5 ] = function ( a ) { a . reg32s [ reg_eax ] = a . add32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t16 [ 6 ] = function ( a ) { a . push16 ( a . sreg [ reg_es ] ) ; } ; t32 [ 6 ] = function ( a ) { a . push32 ( a . sreg [ reg_es ] ) ; } ; t16 [ 7 ] = function ( a ) { a . switch_seg ( reg_es , a . safe_read16 ( a . get_stack_pointer ( 0 ) ) ) ; a . adjust_stack_reg ( 2 ) ; } ; t32 [ 7 ] = function ( a ) { a . switch_seg ( reg_es , a . safe_read32s ( a . get_stack_pointer ( 0 ) ) & 65535 ) ; a . adjust_stack_reg ( 4 ) ; } ; t [ 8 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e8 ( a . or8 ( a . read_write_e8 ( ) , a . read_g8 ( ) ) ) ; } ; t16 [ 9 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e16 ( a . or16 ( a . read_write_e16 ( ) , a . read_g16 ( ) ) ) ; } ; t32 [ 9 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e32 ( a . or32 ( a . read_write_e32 ( ) , a . read_g32s ( ) ) ) ; } ; t [ 10 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g8 ( a . or8 ( a . read_g8 ( ) , a . read_e8 ( ) ) ) ; } ; t16 [ 11 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . or16 ( a . read_g16 ( ) , a . read_e16 ( ) ) ) ; } ; t32 [ 11 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . or32 ( a . read_g32s ( ) , a . read_e32s ( ) ) ) ; } ; t [ 12 ] = function ( a ) { a . reg8 [ reg_al ] = a . or8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 13 ] = function ( a ) { a . reg16 [ reg_ax ] = a . or16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 13 ] = function ( a ) { a . reg32s [ reg_eax ] = a . or32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t16 [ 14 ] = function ( a ) { a . push16 ( a . sreg [ reg_cs ] ) ; } ; t32 [ 14 ] = function ( a ) { a . push32 ( a . sreg [ reg_cs ] ) ; } ; t16 [ 15 ] = function ( a ) { a . table0F_16 [ a . read_op0F ( ) ] ( a ) ; } ; t32 [ 15 ] = function ( a ) { a . table0F_32 [ a . read_op0F ( ) ] ( a ) ; } ; t [ 16 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e8 ( a . adc8 ( a . read_write_e8 ( ) , a . read_g8 ( ) ) ) ; } ; t16 [ 17 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e16 ( a . adc16 ( a . read_write_e16 ( ) , a . read_g16 ( ) ) ) ; } ; t32 [ 17 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e32 ( a . adc32 ( a . read_write_e32 ( ) , a . read_g32s ( ) ) ) ; } ; t [ 18 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g8 ( a . adc8 ( a . read_g8 ( ) , a . read_e8 ( ) ) ) ; } ; t16 [ 19 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . adc16 ( a . read_g16 ( ) , a . read_e16 ( ) ) ) ; } ; t32 [ 19 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . adc32 ( a . read_g32s ( ) , a . read_e32s ( ) ) ) ; } ; t [ 20 ] = function ( a ) { a . reg8 [ reg_al ] = a . adc8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 21 ] = function ( a ) { a . reg16 [ reg_ax ] = a . adc16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 21 ] = function ( a ) { a . reg32s [ reg_eax ] = a . adc32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t16 [ 22 ] = function ( a ) { a . push16 ( a . sreg [ reg_ss ] ) ; } ; t32 [ 22 ] = function ( a ) { a . push32 ( a . sreg [ reg_ss ] ) ; } ; t16 [ 23 ] = function ( a ) { a . switch_seg ( reg_ss , a . safe_read16 ( a . get_stack_pointer ( 0 ) ) ) ; a . adjust_stack_reg ( 2 ) ; a . clear_prefixes ( ) ; a . cycle_internal ( ) ; } ; t32 [ 23 ] = function ( a ) { a . switch_seg ( reg_ss , a . safe_read32s ( a . get_stack_pointer ( 0 ) ) & 65535 ) ; a . adjust_stack_reg ( 4 ) ; a . clear_prefixes ( ) ; a . cycle_internal ( ) ; } ; t [ 24 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e8 ( a . sbb8 ( a . read_write_e8 ( ) , a . read_g8 ( ) ) ) ; } ; t16 [ 25 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e16 ( a . sbb16 ( a . read_write_e16 ( ) , a . read_g16 ( ) ) ) ; } ; t32 [ 25 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e32 ( a . sbb32 ( a . read_write_e32 ( ) , a . read_g32s ( ) ) ) ; } ; t [ 26 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g8 ( a . sbb8 ( a . read_g8 ( ) , a . read_e8 ( ) ) ) ; } ; t16 [ 27 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . sbb16 ( a . read_g16 ( ) , a . read_e16 ( ) ) ) ; } ; t32 [ 27 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . sbb32 ( a . read_g32s ( ) , a . read_e32s ( ) ) ) ; } ; t [ 28 ] = function ( a ) { a . reg8 [ reg_al ] = a . sbb8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 29 ] = function ( a ) { a . reg16 [ reg_ax ] = a . sbb16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 29 ] = function ( a ) { a . reg32s [ reg_eax ] = a . sbb32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t16 [ 30 ] = function ( a ) { a . push16 ( a . sreg [ reg_ds ] ) ; } ; t32 [ 30 ] = function ( a ) { a . push32 ( a . sreg [ reg_ds ] ) ; } ; t16 [ 31 ] = function ( a ) { a . switch_seg ( reg_ds , a . safe_read16 ( a . get_stack_pointer ( 0 ) ) ) ; a . adjust_stack_reg ( 2 ) ; } ; t32 [ 31 ] = function ( a ) { a . switch_seg ( reg_ds , a . safe_read32s ( a . get_stack_pointer ( 0 ) ) & 65535 ) ; a . adjust_stack_reg ( 4 ) ; } ; t [ 32 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e8 ( a . and8 ( a . read_write_e8 ( ) , a . read_g8 ( ) ) ) ; } ; t16 [ 33 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e16 ( a . and16 ( a . read_write_e16 ( ) , a . read_g16 ( ) ) ) ; } ; t32 [ 33 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e32 ( a . and32 ( a . read_write_e32 ( ) , a . read_g32s ( ) ) ) ; } ; t [ 34 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g8 ( a . and8 ( a . read_g8 ( ) , a . read_e8 ( ) ) ) ; } ; t16 [ 35 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . and16 ( a . read_g16 ( ) , a . read_e16 ( ) ) ) ; } ; t32 [ 35 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . and32 ( a . read_g32s ( ) , a . read_e32s ( ) ) ) ; } ; t [ 36 ] = function ( a ) { a . reg8 [ reg_al ] = a . and8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 37 ] = function ( a ) { a . reg16 [ reg_ax ] = a . and16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 37 ] = function ( a ) { a . reg32s [ reg_eax ] = a . and32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t [ 38 ] = function ( a ) { a . segment_prefix_op ( reg_es ) ; } ; t [ 39 ] = function ( a ) { a . bcd_daa ( ) ; } ; t [ 40 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e8 ( a . sub8 ( a . read_write_e8 ( ) , a . read_g8 ( ) ) ) ; } ; t16 [ 41 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e16 ( a . sub16 ( a . read_write_e16 ( ) , a . read_g16 ( ) ) ) ; } ; t32 [ 41 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e32 ( a . sub32 ( a . read_write_e32 ( ) , a . read_g32s ( ) ) ) ; } ; t [ 42 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g8 ( a . sub8 ( a . read_g8 ( ) , a . read_e8 ( ) ) ) ; } ; t16 [ 43 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . sub16 ( a . read_g16 ( ) , a . read_e16 ( ) ) ) ; } ; t32 [ 43 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . sub32 ( a . read_g32s ( ) , a . read_e32s ( ) ) ) ; } ; t [ 44 ] = function ( a ) { a . reg8 [ reg_al ] = a . sub8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 45 ] = function ( a ) { a . reg16 [ reg_ax ] = a . sub16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 45 ] = function ( a ) { a . reg32s [ reg_eax ] = a . sub32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t [ 46 ] = function ( a ) { a . segment_prefix_op ( reg_cs ) ; } ; t [ 47 ] = function ( a ) { a . bcd_das ( ) ; } ; t [ 48 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e8 ( a . xor8 ( a . read_write_e8 ( ) , a . read_g8 ( ) ) ) ; } ; t16 [ 49 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e16 ( a . xor16 ( a . read_write_e16 ( ) , a . read_g16 ( ) ) ) ; } ; t32 [ 49 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_e32 ( a . xor32 ( a . read_write_e32 ( ) , a . read_g32s ( ) ) ) ; } ; t [ 50 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g8 ( a . xor8 ( a . read_g8 ( ) , a . read_e8 ( ) ) ) ; } ; t16 [ 51 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . xor16 ( a . read_g16 ( ) , a . read_e16 ( ) ) ) ; } ; t32 [ 51 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . xor32 ( a . read_g32s ( ) , a . read_e32s ( ) ) ) ; } ; t [ 52 ] = function ( a ) { a . reg8 [ reg_al ] = a . xor8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 53 ] = function ( a ) { a . reg16 [ reg_ax ] = a . xor16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 53 ] = function ( a ) { a . reg32s [ reg_eax ] = a . xor32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t [ 54 ] = function ( a ) { a . segment_prefix_op ( reg_ss ) ; } ; t [ 55 ] = function ( a ) { a . bcd_aaa ( ) ; } ; t [ 56 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmp8 ( a . read_e8 ( ) , a . read_g8 ( ) ) ; } ; t16 [ 57 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmp16 ( a . read_e16 ( ) , a . read_g16 ( ) ) ; } ; t32 [ 57 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmp32 ( a . read_e32s ( ) , a . read_g32s ( ) ) ; } ; t [ 58 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmp8 ( a . read_g8 ( ) , a . read_e8 ( ) ) ; } ; t16 [ 59 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmp16 ( a . read_g16 ( ) , a . read_e16 ( ) ) ; } ; t32 [ 59 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmp32 ( a . read_g32s ( ) , a . read_e32s ( ) ) ; } ; t [ 60 ] = function ( a ) { a . cmp8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 61 ] = function ( a ) { a . cmp16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 61 ] = function ( a ) { a . cmp32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t [ 62 ] = function ( a ) { a . segment_prefix_op ( reg_ds ) ; } ; t [ 63 ] = function ( a ) { a . bcd_aas ( ) ; } ; t16 [ 64 ] = function ( a ) { a . reg16 [ reg_ax ] = a . inc16 ( a . reg16 [ reg_ax ] ) ; } ; t32 [ 64 ] = function ( a ) { a . reg32s [ reg_eax ] = a . inc32 ( a . reg32s [ reg_eax ] ) ; } ; t16 [ 65 ] = function ( a ) { a . reg16 [ reg_cx ] = a . inc16 ( a . reg16 [ reg_cx ] ) ; } ; t32 [ 65 ] = function ( a ) { a . reg32s [ reg_ecx ] = a . inc32 ( a . reg32s [ reg_ecx ] ) ; } ; t16 [ 66 ] = function ( a ) { a . reg16 [ reg_dx ] = a . inc16 ( a . reg16 [ reg_dx ] ) ; } ; t32 [ 66 ] = function ( a ) { a . reg32s [ reg_edx ] = a . inc32 ( a . reg32s [ reg_edx ] ) ; } ; t16 [ 67 ] = function ( a ) { a . reg16 [ reg_bx ] = a . inc16 ( a . reg16 [ reg_bx ] ) ; } ; t32 [ 67 ] = function ( a ) { a . reg32s [ reg_ebx ] = a . inc32 ( a . reg32s [ reg_ebx ] ) ; } ; t16 [ 68 ] = function ( a ) { a . reg16 [ reg_sp ] = a . inc16 ( a . reg16 [ reg_sp ] ) ; } ; t32 [ 68 ] = function ( a ) { a . reg32s [ reg_esp ] = a . inc32 ( a . reg32s [ reg_esp ] ) ; } ; t16 [ 69 ] = function ( a ) { a . reg16 [ reg_bp ] = a . inc16 ( a . reg16 [ reg_bp ] ) ; } ; t32 [ 69 ] = function ( a ) { a . reg32s [ reg_ebp ] = a . inc32 ( a . reg32s [ reg_ebp ] ) ; } ; t16 [ 70 ] = function ( a ) { a . reg16 [ reg_si ] = a . inc16 ( a . reg16 [ reg_si ] ) ; } ; t32 [ 70 ] = function ( a ) { a . reg32s [ reg_esi ] = a . inc32 ( a . reg32s [ reg_esi ] ) ; } ; t16 [ 71 ] = function ( a ) { a . reg16 [ reg_di ] = a . inc16 ( a . reg16 [ reg_di ] ) ; } ; t32 [ 71 ] = function ( a ) { a . reg32s [ reg_edi ] = a . inc32 ( a . reg32s [ reg_edi ] ) ; } ; t16 [ 72 ] = function ( a ) { a . reg16 [ reg_ax ] = a . dec16 ( a . reg16 [ reg_ax ] ) ; } ; t32 [ 72 ] = function ( a ) { a . reg32s [ reg_eax ] = a . dec32 ( a . reg32s [ reg_eax ] ) ; } ; t16 [ 73 ] = function ( a ) { a . reg16 [ reg_cx ] = a . dec16 ( a . reg16 [ reg_cx ] ) ; } ; t32 [ 73 ] = function ( a ) { a . reg32s [ reg_ecx ] = a . dec32 ( a . reg32s [ reg_ecx ] ) ; } ; t16 [ 74 ] = function ( a ) { a . reg16 [ reg_dx ] = a . dec16 ( a . reg16 [ reg_dx ] ) ; } ; t32 [ 74 ] = function ( a ) { a . reg32s [ reg_edx ] = a . dec32 ( a . reg32s [ reg_edx ] ) ; } ; t16 [ 75 ] = function ( a ) { a . reg16 [ reg_bx ] = a . dec16 ( a . reg16 [ reg_bx ] ) ; } ; t32 [ 75 ] = function ( a ) { a . reg32s [ reg_ebx ] = a . dec32 ( a . reg32s [ reg_ebx ] ) ; } ; t16 [ 76 ] = function ( a ) { a . reg16 [ reg_sp ] = a . dec16 ( a . reg16 [ reg_sp ] ) ; } ; t32 [ 76 ] = function ( a ) { a . reg32s [ reg_esp ] = a . dec32 ( a . reg32s [ reg_esp ] ) ; } ; t16 [ 77 ] = function ( a ) { a . reg16 [ reg_bp ] = a . dec16 ( a . reg16 [ reg_bp ] ) ; } ; t32 [ 77 ] = function ( a ) { a . reg32s [ reg_ebp ] = a . dec32 ( a . reg32s [ reg_ebp ] ) ; } ; t16 [ 78 ] = function ( a ) { a . reg16 [ reg_si ] = a . dec16 ( a . reg16 [ reg_si ] ) ; } ; t32 [ 78 ] = function ( a ) { a . reg32s [ reg_esi ] = a . dec32 ( a . reg32s [ reg_esi ] ) ; } ; t16 [ 79 ] = function ( a ) { a . reg16 [ reg_di ] = a . dec16 ( a . reg16 [ reg_di ] ) ; } ; t32 [ 79 ] = function ( a ) { a . reg32s [ reg_edi ] = a . dec32 ( a . reg32s [ reg_edi ] ) ; } ; t16 [ 80 ] = function ( a ) { a . push16 ( a . reg16 [ reg_ax ] ) ; } ; t32 [ 80 ] = function ( a ) { a . push32 ( a . reg32s [ reg_eax ] ) ; } ; t16 [ 81 ] = function ( a ) { a . push16 ( a . reg16 [ reg_cx ] ) ; } ; t32 [ 81 ] = function ( a ) { a . push32 ( a . reg32s [ reg_ecx ] ) ; } ; t16 [ 82 ] = function ( a ) { a . push16 ( a . reg16 [ reg_dx ] ) ; } ; t32 [ 82 ] = function ( a ) { a . push32 ( a . reg32s [ reg_edx ] ) ; } ; t16 [ 83 ] = function ( a ) { a . push16 ( a . reg16 [ reg_bx ] ) ; } ; t32 [ 83 ] = function ( a ) { a . push32 ( a . reg32s [ reg_ebx ] ) ; } ; t16 [ 84 ] = function ( a ) { a . push16 ( a . reg16 [ reg_sp ] ) ; } ; t32 [ 84 ] = function ( a ) { a . push32 ( a . reg32s [ reg_esp ] ) ; } ; t16 [ 85 ] = function ( a ) { a . push16 ( a . reg16 [ reg_bp ] ) ; } ; t32 [ 85 ] = function ( a ) { a . push32 ( a . reg32s [ reg_ebp ] ) ; } ; t16 [ 86 ] = function ( a ) { a . push16 ( a . reg16 [ reg_si ] ) ; } ; t32 [ 86 ] = function ( a ) { a . push32 ( a . reg32s [ reg_esi ] ) ; } ; t16 [ 87 ] = function ( a ) { a . push16 ( a . reg16 [ reg_di ] ) ; } ; t32 [ 87 ] = function ( a ) { a . push32 ( a . reg32s [ reg_edi ] ) ; } ; t16 [ 88 ] = function ( a ) { a . reg16 [ reg_ax ] = a . pop16 ( ) ; } ; t32 [ 88 ] = function ( a ) { a . reg32s [ reg_eax ] = a . pop32s ( ) ; } ; t16 [ 89 ] = function ( a ) { a . reg16 [ reg_cx ] = a . pop16 ( ) ; } ; t32 [ 89 ] = function ( a ) { a . reg32s [ reg_ecx ] = a . pop32s ( ) ; } ; t16 [ 90 ] = function ( a ) { a . reg16 [ reg_dx ] = a . pop16 ( ) ; } ; t32 [ 90 ] = function ( a ) { a . reg32s [ reg_edx ] = a . pop32s ( ) ; } ; t16 [ 91 ] = function ( a ) { a . reg16 [ reg_bx ] = a . pop16 ( ) ; } ; t32 [ 91 ] = function ( a ) { a . reg32s [ reg_ebx ] = a . pop32s ( ) ; } ; t16 [ 92 ] = function ( a ) { a . reg16 [ reg_sp ] = a . pop16 ( ) ; } ; t32 [ 92 ] = function ( a ) { a . reg32s [ reg_esp ] = a . pop32s ( ) ; } ; t16 [ 93 ] = function ( a ) { a . reg16 [ reg_bp ] = a . pop16 ( ) ; } ; t32 [ 93 ] = function ( a ) { a . reg32s [ reg_ebp ] = a . pop32s ( ) ; } ; t16 [ 94 ] = function ( a ) { a . reg16 [ reg_si ] = a . pop16 ( ) ; } ; t32 [ 94 ] = function ( a ) { a . reg32s [ reg_esi ] = a . pop32s ( ) ; } ; t16 [ 95 ] = function ( a ) { a . reg16 [ reg_di ] = a . pop16 ( ) ; } ; t32 [ 95 ] = function ( a ) { a . reg32s [ reg_edi ] = a . pop32s ( ) ; } ; t16 [ 96 ] = function ( a ) { a . pusha16 ( ) ; } ; t32 [ 96 ] = function ( a ) { a . pusha32 ( ) ; } ; t16 [ 97 ] = function ( a ) { a . popa16 ( ) ; } ; t32 [ 97 ] = function ( a ) { a . popa32 ( ) ; } ; t [ 98 ] = function ( a ) { dbg_log ( "Unimplemented BOUND instruction" , LOG_CPU ) ; dbg_assert ( ! 1 ) ; } ; t [ 99 ] = function ( a ) { a . read_modrm_byte ( ) ; a . protected_mode && ! a . vm86_mode ( ) ? a . write_e16 ( a . arpl ( a . read_write_e16 ( ) , a . modrm_byte >> 2 & 14 ) ) : ( dbg_log ( "arpl #ud" , LOG_CPU ) , a . trigger_ud ( ) ) ; } ; t [ 100 ] = function ( a ) { a . segment_prefix_op ( reg_fs ) ; } ; t [ 101 ] = function ( a ) { a . segment_prefix_op ( reg_gs ) ; } ; t [ 102 ] = function ( a ) { a . prefixes |= PREFIX_MASK_OPSIZE ; a . run_prefix_instruction ( ) ; a . prefixes = 0 ; } ; t [ 103 ] = function ( a ) { dbg_assert ( a . is_asize_32 ( ) === a . is_32 ) ; a . prefixes |= PREFIX_MASK_ADDRSIZE ; a . run_prefix_instruction ( ) ; a . prefixes = 0 ; } ; t16 [ 104 ] = function ( a ) { a . push16 ( a . read_op16 ( ) ) ; } ; t32 [ 104 ] = function ( a ) { a . push32 ( a . read_op32s ( ) ) ; } ; t16 [ 105 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . imul_reg16 ( a . read_e16s ( ) , a . read_op16 ( ) << 16 >> 16 ) ) ; } ; t32 [ 105 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . imul_reg32 ( a . read_e32s ( ) , a . read_op32s ( ) ) ) ; } ; t16 [ 106 ] = function ( a ) { a . push16 ( a . read_op8s ( ) ) ; } ; t32 [ 106 ] = function ( a ) { a . push32 ( a . read_op8s ( ) ) ; } ; t16 [ 107 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g16 ( a . imul_reg16 ( a . read_e16s ( ) , a . read_op8s ( ) ) ) ; } ; t32 [ 107 ] = function ( a ) { a . read_modrm_byte ( ) ; a . write_g32 ( a . imul_reg32 ( a . read_e32s ( ) , a . read_op8s ( ) ) ) ; } ; t [ 108 ] = function ( a ) { insb ( a ) ; } ; t16 [ 109 ] = function ( a ) { insw ( a ) ; } ; t32 [ 109 ] = function ( a ) { insd ( a ) ; } ; t [ 110 ] = function ( a ) { outsb ( a ) ; } ; t16 [ 111 ] = function ( a ) { outsw ( a ) ; } ; t32 [ 111 ] = function ( a ) { outsd ( a ) ; } ; t [ 112 ] = function ( a ) { a . jmpcc8 ( a . test_o ( ) ) ; } ; t [ 113 ] = function ( a ) { a . jmpcc8 ( ! a . test_o ( ) ) ; } ; t [ 114 ] = function ( a ) { a . jmpcc8 ( a . test_b ( ) ) ; } ; t [ 115 ] = function ( a ) { a . jmpcc8 ( ! a . test_b ( ) ) ; } ; t [ 116 ] = function ( a ) { a . jmpcc8 ( a . test_z ( ) ) ; } ; t [ 117 ] = function ( a ) { a . jmpcc8 ( ! a . test_z ( ) ) ; } ; t [ 118 ] = function ( a ) { a . jmpcc8 ( a . test_be ( ) ) ; } ; t [ 119 ] = function ( a ) { a . jmpcc8 ( ! a . test_be ( ) ) ; } ; t [ 120 ] = function ( a ) { a . jmpcc8 ( a . test_s ( ) ) ; } ; t [ 121 ] = function ( a ) { a . jmpcc8 ( ! a . test_s ( ) ) ; } ; t [ 122 ] = function ( a ) { a . jmpcc8 ( a . test_p ( ) ) ; } ; t [ 123 ] = function ( a ) { a . jmpcc8 ( ! a . test_p ( ) ) ; } ; t [ 124 ] = function ( a ) { a . jmpcc8 ( a . test_l ( ) ) ; } ; t [ 125 ] = function ( a ) { a . jmpcc8 ( ! a . test_l ( ) ) ; } ; t [ 126 ] = function ( a ) { a . jmpcc8 ( a . test_le ( ) ) ; } ; t [ 127 ] = function ( a ) { a . jmpcc8 ( ! a . test_le ( ) ) ; } ; t [ 128 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : a . write_e8 ( a . add8 ( a . read_write_e8 ( ) , a . read_op8 ( ) ) ) ; break ; case 1 : a . write_e8 ( a . or8 ( a . read_write_e8 ( ) , a . read_op8 ( ) ) ) ; break ; case 2 : a . write_e8 ( a . adc8 ( a . read_write_e8 ( ) , a . read_op8 ( ) ) ) ; break ; case 3 : a . write_e8 ( a . sbb8 ( a . read_write_e8 ( ) , a . read_op8 ( ) ) ) ; break ; case 4 : a . write_e8 ( a . and8 ( a . read_write_e8 ( ) , a . read_op8 ( ) ) ) ; break ; case 5 : a . write_e8 ( a . sub8 ( a . read_write_e8 ( ) , a . read_op8 ( ) ) ) ; break ; case 6 : a . write_e8 ( a . xor8 ( a . read_write_e8 ( ) , a . read_op8 ( ) ) ) ; break ; case 7 : a . cmp8 ( a . read_e8 ( ) , a . read_op8 ( ) ) ; } } ; t16 [ 129 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : a . write_e16 ( a . add16 ( a . read_write_e16 ( ) , a . read_op16 ( ) ) ) ; break ; case 1 : a . write_e16 ( a . or16 ( a . read_write_e16 ( ) , a . read_op16 ( ) ) ) ; break ; case 2 : a . write_e16 ( a . adc16 ( a . read_write_e16 ( ) , a . read_op16 ( ) ) ) ; break ; case 3 : a . write_e16 ( a . sbb16 ( a . read_write_e16 ( ) , a . read_op16 ( ) ) ) ; break ; case 4 : a . write_e16 ( a . and16 ( a . read_write_e16 ( ) , a . read_op16 ( ) ) ) ; break ; case 5 : a . write_e16 ( a . sub16 ( a . read_write_e16 ( ) , a . read_op16 ( ) ) ) ; break ; case 6 : a . write_e16 ( a . xor16 ( a . read_write_e16 ( ) , a . read_op16 ( ) ) ) ; break ; case 7 : a . cmp16 ( a . read_e16 ( ) , a . read_op16 ( ) ) ; } } ; t32 [ 129 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : a . write_e32 ( a . add32 ( a . read_write_e32 ( ) , a . read_op32s ( ) ) ) ; break ; case 1 : a . write_e32 ( a . or32 ( a . read_write_e32 ( ) , a . read_op32s ( ) ) ) ; break ; case 2 : a . write_e32 ( a . adc32 ( a . read_write_e32 ( ) , a . read_op32s ( ) ) ) ; break ; case 3 : a . write_e32 ( a . sbb32 ( a . read_write_e32 ( ) , a . read_op32s ( ) ) ) ; break ; case 4 : a . write_e32 ( a . and32 ( a . read_write_e32 ( ) , a . read_op32s ( ) ) ) ; break ; case 5 : a . write_e32 ( a . sub32 ( a . read_write_e32 ( ) , a . read_op32s ( ) ) ) ; break ; case 6 : a . write_e32 ( a . xor32 ( a . read_write_e32 ( ) , a . read_op32s ( ) ) ) ; break ; case 7 : a . cmp32 ( a . read_e32s ( ) , a . read_op32s ( ) ) ; } } ; t [ 130 ] = t [ 128 ] ; t16 [ 131 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : a . write_e16 ( a . add16 ( a . read_write_e16 ( ) , a . read_op8s ( ) ) ) ; break ; case 1 : a . write_e16 ( a . or16 ( a . read_write_e16 ( ) , a . read_op8s ( ) ) ) ; break ; case 2 : a . write_e16 ( a . adc16 ( a . read_write_e16 ( ) , a . read_op8s ( ) ) ) ; break ; case 3 : a . write_e16 ( a . sbb16 ( a . read_write_e16 ( ) , a . read_op8s ( ) ) ) ; break ; case 4 : a . write_e16 ( a . and16 ( a . read_write_e16 ( ) , a . read_op8s ( ) ) ) ; break ; case 5 : a . write_e16 ( a . sub16 ( a . read_write_e16 ( ) , a . read_op8s ( ) ) ) ; break ; case 6 : a . write_e16 ( a . xor16 ( a . read_write_e16 ( ) , a . read_op8s ( ) ) ) ; break ; case 7 : a . cmp16 ( a . read_e16 ( ) , a . read_op8s ( ) ) ; } } ; t32 [ 131 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : a . write_e32 ( a . add32 ( a . read_write_e32 ( ) , a . read_op8s ( ) ) ) ; break ; case 1 : a . write_e32 ( a . or32 ( a . read_write_e32 ( ) , a . read_op8s ( ) ) ) ; break ; case 2 : a . write_e32 ( a . adc32 ( a . read_write_e32 ( ) , a . read_op8s ( ) ) ) ; break ; case 3 : a . write_e32 ( a . sbb32 ( a . read_write_e32 ( ) , a . read_op8s ( ) ) ) ; break ; case 4 : a . write_e32 ( a . and32 ( a . read_write_e32 ( ) , a . read_op8s ( ) ) ) ; break ; case 5 : a . write_e32 ( a . sub32 ( a . read_write_e32 ( ) , a . read_op8s ( ) ) ) ; break ; case 6 : a . write_e32 ( a . xor32 ( a . read_write_e32 ( ) , a . read_op8s ( ) ) ) ; break ; case 7 : a . cmp32 ( a . read_e32s ( ) , a . read_op8s ( ) ) ; } } ; t [ 132 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e8 ( ) ; a . test8 ( b , a . read_g8 ( ) ) ; } ; t16 [ 133 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e16 ( ) ; a . test16 ( b , a . read_g16 ( ) ) ; } ; t32 [ 133 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e32s ( ) ; a . test32 ( b , a . read_g32s ( ) ) ; } ; t [ 134 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e8 ( ) ; a . write_e8 ( a . xchg8 ( b , a . modrm_byte ) ) ; } ; t16 [ 135 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) ; a . write_e16 ( a . xchg16 ( b , a . modrm_byte ) ) ; } ; t32 [ 135 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) ; a . write_e32 ( a . xchg32 ( b , a . modrm_byte ) ) ; } ; t [ 136 ] = function ( a ) { a . read_modrm_byte ( ) ; a . set_e8 ( a . read_g8 ( ) ) ; } ; t16 [ 137 ] = function ( a ) { a . read_modrm_byte ( ) ; a . set_e16 ( a . read_g16 ( ) ) ; } ; t32 [ 137 ] = function ( a ) { a . read_modrm_byte ( ) ; a . set_e32 ( a . read_g32s ( ) ) ; } ; t [ 138 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e8 ( ) ; a . write_g8 ( b ) ; } ; t16 [ 139 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e16 ( ) ; a . write_g16 ( b ) ; } ; t32 [ 139 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e32s ( ) ; a . write_g32 ( b ) ; } ; t16 [ 140 ] = function ( a ) { a . read_modrm_byte ( ) ; a . set_e16 ( a . sreg [ a . modrm_byte >> 3 & 7 ] ) ; } ; t32 [ 140 ] = function ( a ) { a . read_modrm_byte ( ) ; a . set_e32 ( a . sreg [ a . modrm_byte >> 3 & 7 ] ) ; } ; t16 [ 141 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 <= a . modrm_byte && ( dbg_log ( "lea #ud" , LOG_CPU ) , a . trigger_ud ( ) ) ; var b = a . modrm_byte >> 3 & 7 ; a . prefixes |= SEG_PREFIX_ZERO ; a . reg16 [ b << 1 ] = a . modrm_resolve ( a . modrm_byte ) ; a . prefixes = 0 ; } ; t32 [ 141 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 <= a . modrm_byte && ( dbg_log ( "lea #ud" , LOG_CPU ) , a . trigger_ud ( ) ) ; var b = a . modrm_byte >> 3 & 7 ; a . prefixes |= SEG_PREFIX_ZERO ; a . reg32s [ b ] = a . modrm_resolve ( a . modrm_byte ) ; a . prefixes = 0 ; } ; t [ 142 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . modrm_byte >> 3 & 7 , c = a . read_e16 ( ) ; a . switch_seg ( b , c ) ; b === reg_ss && ( a . clear_prefixes ( ) , a . cycle_internal ( ) ) ; } ; t16 [ 143 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . safe_read16 ( a . get_stack_pointer ( 0 ) ) ; a . adjust_stack_reg ( 2 ) ; if ( 192 > a . modrm_byte ) { var c = a . modrm_resolve ( a . modrm_byte ) ; a . adjust_stack_reg ( - 2 ) ; a . safe_write16 ( c , b ) ; a . adjust_stack_reg ( 2 ) ; } else a . write_reg_e16 ( b ) ; } ; t32 [ 143 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . safe_read32s ( a . get_stack_pointer ( 0 ) ) ; a . adjust_stack_reg ( 4 ) ; if ( 192 > a . modrm_byte ) { var c = a . modrm_resolve ( a . modrm_byte ) ; a . adjust_stack_reg ( - 4 ) ; a . safe_write32 ( c , b ) ; a . adjust_stack_reg ( 4 ) ; } else a . write_reg_e32 ( b ) ; } ; t [ 144 ] = function ( a ) { } ; t16 [ 145 ] = function ( a ) { a . xchg16r ( reg_cx ) ; } ; t32 [ 145 ] = function ( a ) { a . xchg32r ( reg_ecx ) ; } ; t16 [ 146 ] = function ( a ) { a . xchg16r ( reg_dx ) ; } ; t32 [ 146 ] = function ( a ) { a . xchg32r ( reg_edx ) ; } ; t16 [ 147 ] = function ( a ) { a . xchg16r ( reg_bx ) ; } ; t32 [ 147 ] = function ( a ) { a . xchg32r ( reg_ebx ) ; } ; t16 [ 148 ] = function ( a ) { a . xchg16r ( reg_sp ) ; } ; t32 [ 148 ] = function ( a ) { a . xchg32r ( reg_esp ) ; } ; t16 [ 149 ] = function ( a ) { a . xchg16r ( reg_bp ) ; } ; t32 [ 149 ] = function ( a ) { a . xchg32r ( reg_ebp ) ; } ; t16 [ 150 ] = function ( a ) { a . xchg16r ( reg_si ) ; } ; t32 [ 150 ] = function ( a ) { a . xchg32r ( reg_esi ) ; } ; t16 [ 151 ] = function ( a ) { a . xchg16r ( reg_di ) ; } ; t32 [ 151 ] = function ( a ) { a . xchg32r ( reg_edi ) ; } ; t16 [ 152 ] = function ( a ) { a . reg16 [ reg_ax ] = a . reg8s [ reg_al ] ; } ; t32 [ 152 ] = function ( a ) { a . reg32s [ reg_eax ] = a . reg16s [ reg_ax ] ; } ; t16 [ 153 ] = function ( a ) { a . reg16 [ reg_dx ] = a . reg16s [ reg_ax ] >> 15 ; } ; t32 [ 153 ] = function ( a ) { a . reg32s [ reg_edx ] = a . reg32s [ reg_eax ] >> 31 ; } ; t16 [ 154 ] = function ( a ) { var b = a . read_op16 ( ) , c = a . read_disp16 ( ) ; a . far_jump ( b , c , ! 0 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t32 [ 154 ] = function ( a ) { var b = a . read_op32s ( ) , c = a . read_disp16 ( ) ; if ( ( ! a . protected_mode || a . vm86_mode ( ) ) && b & 4294901760 ) throw a . debug . unimpl ( "#GP handler" ) ; a . far_jump ( b , c , ! 0 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t [ 155 ] = function ( a ) { ( a . cr [ 0 ] & ( CR0_MP | CR0_TS ) ) === ( CR0_MP | CR0_TS ) ? a . trigger_nm ( ) : a . fpu && a . fpu . fwait ( ) ; } ; t16 [ 156 ] = function ( a ) { a . flags & flag_vm && 3 > a . getiopl ( ) ? ( dbg_assert ( a . protected_mode ) , dbg_log ( "pushf #gp" , LOG_CPU ) , a . trigger_gp ( 0 ) ) : a . push16 ( a . get_eflags ( ) ) ; } ; t32 [ 156 ] = function ( a ) { a . flags & flag_vm && 3 > a . getiopl ( ) ? ( dbg_assert ( a . protected_mode ) , dbg_log ( "pushf #gp" , LOG_CPU ) , a . trigger_gp ( 0 ) ) : a . push32 ( a . get_eflags ( ) & 16580607 ) ; } ; t16 [ 157 ] = function ( a ) { a . flags & flag_vm && 3 > a . getiopl ( ) && ( dbg_log ( "popf #gp" , LOG_CPU ) , a . trigger_gp ( 0 ) ) ; a . update_eflags ( a . flags & - 65536 | a . pop16 ( ) ) ; a . flags & flag_trap ? a . flags &= ~ flag_trap : a . handle_irqs ( ) ; } ; t32 [ 157 ] = function ( a ) { a . flags & flag_vm && 3 > a . getiopl ( ) && ( dbg_log ( "popf #gp" , LOG_CPU ) , a . trigger_gp ( 0 ) ) ; a . update_eflags ( a . pop32s ( ) ) ; a . handle_irqs ( ) ; } ; t [ 158 ] = function ( a ) { a . flags = a . flags & - 256 | a . reg8 [ reg_ah ] ; a . flags = a . flags & flags_mask | flags_default ; a . flags_changed = 0 ; } ; t [ 159 ] = function ( a ) { a . reg8 [ reg_ah ] = a . get_eflags ( ) ; } ; t [ 160 ] = function ( a ) { var b = a . safe_read8 ( a . read_moffs ( ) ) ; a . reg8 [ reg_al ] = b ; } ; t16 [ 161 ] = function ( a ) { var b = a . safe_read16 ( a . read_moffs ( ) ) ; a . reg16 [ reg_ax ] = b ; } ; t32 [ 161 ] = function ( a ) { var b = a . safe_read32s ( a . read_moffs ( ) ) ; a . reg32s [ reg_eax ] = b ; } ; t [ 162 ] = function ( a ) { a . safe_write8 ( a . read_moffs ( ) , a . reg8 [ reg_al ] ) ; } ; t16 [ 163 ] = function ( a ) { a . safe_write16 ( a . read_moffs ( ) , a . reg16 [ reg_ax ] ) ; } ; t32 [ 163 ] = function ( a ) { a . safe_write32 ( a . read_moffs ( ) , a . reg32s [ reg_eax ] ) ; } ; t [ 164 ] = function ( a ) { a . movsb ( ) ; } ; t16 [ 165 ] = function ( a ) { a . movsw ( ) ; } ; t32 [ 165 ] = function ( a ) { a . movsd ( ) ; } ; t [ 166 ] = function ( a ) { cmpsb ( a ) ; } ; t16 [ 167 ] = function ( a ) { cmpsw ( a ) ; } ; t32 [ 167 ] = function ( a ) { cmpsd ( a ) ; } ; t [ 168 ] = function ( a ) { a . test8 ( a . reg8 [ reg_al ] , a . read_op8 ( ) ) ; } ; t16 [ 169 ] = function ( a ) { a . test16 ( a . reg16 [ reg_ax ] , a . read_op16 ( ) ) ; } ; t32 [ 169 ] = function ( a ) { a . test32 ( a . reg32s [ reg_eax ] , a . read_op32s ( ) ) ; } ; t [ 170 ] = function ( a ) { stosb ( a ) ; } ; t16 [ 171 ] = function ( a ) { stosw ( a ) ; } ; t32 [ 171 ] = function ( a ) { stosd ( a ) ; } ; t [ 172 ] = function ( a ) { lodsb ( a ) ; } ; t16 [ 173 ] = function ( a ) { lodsw ( a ) ; } ; t32 [ 173 ] = function ( a ) { lodsd ( a ) ; } ; t [ 174 ] = function ( a ) { scasb ( a ) ; } ; t16 [ 175 ] = function ( a ) { scasw ( a ) ; } ; t32 [ 175 ] = function ( a ) { scasd ( a ) ; } ; t [ 176 ] = function ( a ) { a . reg8 [ reg_al ] = a . read_op8 ( ) ; } ; t [ 177 ] = function ( a ) { a . reg8 [ reg_cl ] = a . read_op8 ( ) ; } ; t [ 178 ] = function ( a ) { a . reg8 [ reg_dl ] = a . read_op8 ( ) ; } ; t [ 179 ] = function ( a ) { a . reg8 [ reg_bl ] = a . read_op8 ( ) ; } ; t [ 180 ] = function ( a ) { a . reg8 [ reg_ah ] = a . read_op8 ( ) ; } ; t [ 181 ] = function ( a ) { a . reg8 [ reg_ch ] = a . read_op8 ( ) ; } ; t [ 182 ] = function ( a ) { a . reg8 [ reg_dh ] = a . read_op8 ( ) ; } ; t [ 183 ] = function ( a ) { a . reg8 [ reg_bh ] = a . read_op8 ( ) ; } ; t16 [ 184 ] = function ( a ) { a . reg16 [ reg_ax ] = a . read_op16 ( ) ; } ; t32 [ 184 ] = function ( a ) { a . reg32s [ reg_eax ] = a . read_op32s ( ) ; } ; t16 [ 185 ] = function ( a ) { a . reg16 [ reg_cx ] = a . read_op16 ( ) ; } ; t32 [ 185 ] = function ( a ) { a . reg32s [ reg_ecx ] = a . read_op32s ( ) ; } ; t16 [ 186 ] = function ( a ) { a . reg16 [ reg_dx ] = a . read_op16 ( ) ; } ; t32 [ 186 ] = function ( a ) { a . reg32s [ reg_edx ] = a . read_op32s ( ) ; } ; t16 [ 187 ] = function ( a ) { a . reg16 [ reg_bx ] = a . read_op16 ( ) ; } ; t32 [ 187 ] = function ( a ) { a . reg32s [ reg_ebx ] = a . read_op32s ( ) ; } ; t16 [ 188 ] = function ( a ) { a . reg16 [ reg_sp ] = a . read_op16 ( ) ; } ; t32 [ 188 ] = function ( a ) { a . reg32s [ reg_esp ] = a . read_op32s ( ) ; } ; t16 [ 189 ] = function ( a ) { a . reg16 [ reg_bp ] = a . read_op16 ( ) ; } ; t32 [ 189 ] = function ( a ) { a . reg32s [ reg_ebp ] = a . read_op32s ( ) ; } ; t16 [ 190 ] = function ( a ) { a . reg16 [ reg_si ] = a . read_op16 ( ) ; } ; t32 [ 190 ] = function ( a ) { a . reg32s [ reg_esi ] = a . read_op32s ( ) ; } ; t16 [ 191 ] = function ( a ) { a . reg16 [ reg_di ] = a . read_op16 ( ) ; } ; t32 [ 191 ] = function ( a ) { a . reg32s [ reg_edi ] = a . read_op32s ( ) ; } ; t [ 192 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e8 ( ) , c = a . read_op8 ( ) & 31 , d = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : d = a . rol8 ( b , c ) ; break ; case 1 : d = a . ror8 ( b , c ) ; break ; case 2 : d = a . rcl8 ( b , c ) ; break ; case 3 : d = a . rcr8 ( b , c ) ; break ; case 4 : d = a . shl8 ( b , c ) ; break ; case 5 : d = a . shr8 ( b , c ) ; break ; case 6 : d = a . shl8 ( b , c ) ; break ; case 7 : d = a . sar8 ( b , c ) ; } a . write_e8 ( d ) ; } ; t16 [ 193 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) , c = a . read_op8 ( ) & 31 , d = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : d = a . rol16 ( b , c ) ; break ; case 1 : d = a . ror16 ( b , c ) ; break ; case 2 : d = a . rcl16 ( b , c ) ; break ; case 3 : d = a . rcr16 ( b , c ) ; break ; case 4 : d = a . shl16 ( b , c ) ; break ; case 5 : d = a . shr16 ( b , c ) ; break ; case 6 : d = a . shl16 ( b , c ) ; break ; case 7 : d = a . sar16 ( b , c ) ; } a . write_e16 ( d ) ; } ; t32 [ 193 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) , c = a . read_op8 ( ) & 31 , d = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : d = a . rol32 ( b , c ) ; break ; case 1 : d = a . ror32 ( b , c ) ; break ; case 2 : d = a . rcl32 ( b , c ) ; break ; case 3 : d = a . rcr32 ( b , c ) ; break ; case 4 : d = a . shl32 ( b , c ) ; break ; case 5 : d = a . shr32 ( b , c ) ; break ; case 6 : d = a . shl32 ( b , c ) ; break ; case 7 : d = a . sar32 ( b , c ) ; } a . write_e32 ( d ) ; } ; t16 [ 194 ] = function ( a ) { var b = a . read_op16 ( ) ; a . instruction_pointer = a . get_seg ( reg_cs ) + a . pop16 ( ) | 0 ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . adjust_stack_reg ( b ) ; a . diverged ( ) ; } ; t32 [ 194 ] = function ( a ) { var b = a . read_op16 ( ) , c = a . pop32s ( ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > c ) ; a . instruction_pointer = a . get_seg ( reg_cs ) + c | 0 ; a . adjust_stack_reg ( b ) ; a . diverged ( ) ; } ; t16 [ 195 ] = function ( a ) { a . instruction_pointer = a . get_seg ( reg_cs ) + a . pop16 ( ) | 0 ; a . diverged ( ) ; } ; t32 [ 195 ] = function ( a ) { var b = a . pop32s ( ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > b ) ; a . instruction_pointer = a . get_seg ( reg_cs ) + b | 0 ; a . diverged ( ) ; } ; t16 [ 196 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss16 ( reg_es ) ; } ; t32 [ 196 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss32 ( reg_es ) ; } ; t16 [ 197 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss16 ( reg_ds ) ; } ; t32 [ 197 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss32 ( reg_ds ) ; } ; t [ 198 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . safe_write8 ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) ) : a . reg8 [ a . modrm_byte << 2 & 12 | a . modrm_byte >> 2 & 1 ] = a . read_op8 ( ) ; } ; t16 [ 199 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . safe_write16 ( a . modrm_resolve ( a . modrm_byte ) , a . read_op16 ( ) ) : a . reg16 [ a . modrm_byte << 1 & 14 ] = a . read_op16 ( ) ; } ; t32 [ 199 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . safe_write32 ( a . modrm_resolve ( a . modrm_byte ) , a . read_op32s ( ) ) : a . reg32s [ a . modrm_byte & 7 ] = a . read_op32s ( ) ; } ; t16 [ 200 ] = function ( a ) { a . enter16 ( a . read_op16 ( ) , a . read_disp8 ( ) ) ; } ; t32 [ 200 ] = function ( a ) { a . enter32 ( a . read_op16 ( ) , a . read_disp8 ( ) ) ; } ; t16 [ 201 ] = function ( a ) { var b = a . stack_size_32 ? a . reg32s [ reg_ebp ] : a . reg16 [ reg_bp ] , c = a . safe_read16 ( a . get_seg ( reg_ss ) + b | 0 ) ; a . set_stack_reg ( b + 2 | 0 ) ; a . reg16 [ reg_bp ] = c ; } ; t32 [ 201 ] = function ( a ) { var b = a . stack_size_32 ? a . reg32s [ reg_ebp ] : a . reg16 [ reg_bp ] , c = a . safe_read32s ( a . get_seg ( reg_ss ) + b | 0 ) ; a . set_stack_reg ( b + 4 | 0 ) ; a . reg32s [ reg_ebp ] = c ; } ; t16 [ 202 ] = function ( a ) { var b = a . read_op16 ( ) , c = a . safe_read16 ( a . get_stack_pointer ( 0 ) ) , d = a . safe_read16 ( a . get_stack_pointer ( 2 ) ) ; a . far_return ( c , d , b ) ; a . diverged ( ) ; } ; t32 [ 202 ] = function ( a ) { var b = a . read_op16 ( ) , c = a . safe_read32s ( a . get_stack_pointer ( 0 ) ) , d = a . safe_read32s ( a . get_stack_pointer ( 4 ) ) & 65535 ; a . far_return ( c , d , b ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t16 [ 203 ] = function ( a ) { var b = a . safe_read16 ( a . get_stack_pointer ( 0 ) ) , c = a . safe_read16 ( a . get_stack_pointer ( 2 ) ) ; a . far_return ( b , c , 0 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t32 [ 203 ] = function ( a ) { var b = a . safe_read32s ( a . get_stack_pointer ( 0 ) ) , c = a . safe_read32s ( a . get_stack_pointer ( 4 ) ) & 65535 ; a . far_return ( b , c , 0 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t [ 204 ] = function ( a ) { dbg_log ( "INT3" , LOG_CPU ) ; a . call_interrupt_vector ( 3 , ! 0 , ! 1 ) ; a . diverged ( ) ; } ; t [ 205 ] = function ( a ) { var b = a . read_op8 ( ) ; a . call_interrupt_vector ( b , ! 0 , ! 1 ) ; a . diverged ( ) ; } ; t [ 206 ] = function ( a ) { dbg_log ( "INTO" , LOG_CPU ) ; a . getof ( ) && a . call_interrupt_vector ( 4 , ! 0 , ! 1 ) ; a . diverged ( ) ; } ; t16 [ 207 ] = function ( a ) { a . iret16 ( ) ; a . diverged ( ) ; } ; t32 [ 207 ] = function ( a ) { a . iret32 ( ) ; a . diverged ( ) ; } ; t [ 208 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e8 ( ) , c = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : c = a . rol8 ( b , 1 ) ; break ; case 1 : c = a . ror8 ( b , 1 ) ; break ; case 2 : c = a . rcl8 ( b , 1 ) ; break ; case 3 : c = a . rcr8 ( b , 1 ) ; break ; case 4 : c = a . shl8 ( b , 1 ) ; break ; case 5 : c = a . shr8 ( b , 1 ) ; break ; case 6 : c = a . shl8 ( b , 1 ) ; break ; case 7 : c = a . sar8 ( b , 1 ) ; } a . write_e8 ( c ) ; } ; t16 [ 209 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) , c = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : c = a . rol16 ( b , 1 ) ; break ; case 1 : c = a . ror16 ( b , 1 ) ; break ; case 2 : c = a . rcl16 ( b , 1 ) ; break ; case 3 : c = a . rcr16 ( b , 1 ) ; break ; case 4 : c = a . shl16 ( b , 1 ) ; break ; case 5 : c = a . shr16 ( b , 1 ) ; break ; case 6 : c = a . shl16 ( b , 1 ) ; break ; case 7 : c = a . sar16 ( b , 1 ) ; } a . write_e16 ( c ) ; } ; t32 [ 209 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) , c = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : c = a . rol32 ( b , 1 ) ; break ; case 1 : c = a . ror32 ( b , 1 ) ; break ; case 2 : c = a . rcl32 ( b , 1 ) ; break ; case 3 : c = a . rcr32 ( b , 1 ) ; break ; case 4 : c = a . shl32 ( b , 1 ) ; break ; case 5 : c = a . shr32 ( b , 1 ) ; break ; case 6 : c = a . shl32 ( b , 1 ) ; break ; case 7 : c = a . sar32 ( b , 1 ) ; } a . write_e32 ( c ) ; } ; t [ 210 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e8 ( ) , c = a . reg8 [ reg_cl ] & 31 , d = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : d = a . rol8 ( b , c ) ; break ; case 1 : d = a . ror8 ( b , c ) ; break ; case 2 : d = a . rcl8 ( b , c ) ; break ; case 3 : d = a . rcr8 ( b , c ) ; break ; case 4 : d = a . shl8 ( b , c ) ; break ; case 5 : d = a . shr8 ( b , c ) ; break ; case 6 : d = a . shl8 ( b , c ) ; break ; case 7 : d = a . sar8 ( b , c ) ; } a . write_e8 ( d ) ; } ; t16 [ 211 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) , c = a . reg8 [ reg_cl ] & 31 , d = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : d = a . rol16 ( b , c ) ; break ; case 1 : d = a . ror16 ( b , c ) ; break ; case 2 : d = a . rcl16 ( b , c ) ; break ; case 3 : d = a . rcr16 ( b , c ) ; break ; case 4 : d = a . shl16 ( b , c ) ; break ; case 5 : d = a . shr16 ( b , c ) ; break ; case 6 : d = a . shl16 ( b , c ) ; break ; case 7 : d = a . sar16 ( b , c ) ; } a . write_e16 ( d ) ; } ; t32 [ 211 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) , c = a . reg8 [ reg_cl ] & 31 , d = 0 ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : d = a . rol32 ( b , c ) ; break ; case 1 : d = a . ror32 ( b , c ) ; break ; case 2 : d = a . rcl32 ( b , c ) ; break ; case 3 : d = a . rcr32 ( b , c ) ; break ; case 4 : d = a . shl32 ( b , c ) ; break ; case 5 : d = a . shr32 ( b , c ) ; break ; case 6 : d = a . shl32 ( b , c ) ; break ; case 7 : d = a . sar32 ( b , c ) ; } a . write_e32 ( d ) ; } ; t [ 212 ] = function ( a ) { a . bcd_aam ( a . read_op8 ( ) ) ; } ; t [ 213 ] = function ( a ) { a . bcd_aad ( a . read_op8 ( ) ) ; } ; t [ 214 ] = function ( a ) { a . reg8 [ reg_al ] = - a . getcf ( ) ; } ; t [ 215 ] = function ( a ) { a . is_asize_32 ( ) ? a . reg8 [ reg_al ] = a . safe_read8 ( a . get_seg_prefix ( reg_ds ) + a . reg32s [ reg_ebx ] + a . reg8 [ reg_al ] | 0 ) : a . reg8 [ reg_al ] = a . safe_read8 ( a . get_seg_prefix ( reg_ds ) + ( a . reg16 [ reg_bx ] + a . reg8 [ reg_al ] & 65535 ) | 0 ) ; } ; t [ 216 ] = function ( a ) { a . read_modrm_byte ( ) ; a . task_switch_test ( ) ; 192 > a . modrm_byte ? a . fpu . op_D8_mem ( a . modrm_byte , a . modrm_resolve ( a . modrm_byte ) ) : a . fpu . op_D8_reg ( a . modrm_byte ) ; } ; t [ 217 ] = function ( a ) { a . read_modrm_byte ( ) ; a . task_switch_test ( ) ; 192 > a . modrm_byte ? a . fpu . op_D9_mem ( a . modrm_byte , a . modrm_resolve ( a . modrm_byte ) ) : a . fpu . op_D9_reg ( a . modrm_byte ) ; } ; t [ 218 ] = function ( a ) { a . read_modrm_byte ( ) ; a . task_switch_test ( ) ; 192 > a . modrm_byte ? a . fpu . op_DA_mem ( a . modrm_byte , a . modrm_resolve ( a . modrm_byte ) ) : a . fpu . op_DA_reg ( a . modrm_byte ) ; } ; t [ 219 ] = function ( a ) { a . read_modrm_byte ( ) ; a . task_switch_test ( ) ; 192 > a . modrm_byte ? a . fpu . op_DB_mem ( a . modrm_byte , a . modrm_resolve ( a . modrm_byte ) ) : a . fpu . op_DB_reg ( a . modrm_byte ) ; } ; t [ 220 ] = function ( a ) { a . read_modrm_byte ( ) ; a . task_switch_test ( ) ; 192 > a . modrm_byte ? a . fpu . op_DC_mem ( a . modrm_byte , a . modrm_resolve ( a . modrm_byte ) ) : a . fpu . op_DC_reg ( a . modrm_byte ) ; } ; t [ 221 ] = function ( a ) { a . read_modrm_byte ( ) ; a . task_switch_test ( ) ; 192 > a . modrm_byte ? a . fpu . op_DD_mem ( a . modrm_byte , a . modrm_resolve ( a . modrm_byte ) ) : a . fpu . op_DD_reg ( a . modrm_byte ) ; } ; t [ 222 ] = function ( a ) { a . read_modrm_byte ( ) ; a . task_switch_test ( ) ; 192 > a . modrm_byte ? a . fpu . op_DE_mem ( a . modrm_byte , a . modrm_resolve ( a . modrm_byte ) ) : a . fpu . op_DE_reg ( a . modrm_byte ) ; } ; t [ 223 ] = function ( a ) { a . read_modrm_byte ( ) ; a . task_switch_test ( ) ; 192 > a . modrm_byte ? a . fpu . op_DF_mem ( a . modrm_byte , a . modrm_resolve ( a . modrm_byte ) ) : a . fpu . op_DF_reg ( a . modrm_byte ) ; } ; t [ 224 ] = function ( a ) { a . loopne ( a . read_op8s ( ) ) ; } ; t [ 225 ] = function ( a ) { a . loope ( a . read_op8s ( ) ) ; } ; t [ 226 ] = function ( a ) { a . loop ( a . read_op8s ( ) ) ; } ; t [ 227 ] = function ( a ) { a . jcxz ( a . read_op8s ( ) ) ; } ; t [ 228 ] = function ( a ) { var b = a . read_op8 ( ) ; a . test_privileges_for_io ( b , 1 ) ; a . reg8 [ reg_al ] = a . io . port_read8 ( b ) ; a . diverged ( ) ; } ; t16 [ 229 ] = function ( a ) { var b = a . read_op8 ( ) ; a . test_privileges_for_io ( b , 2 ) ; a . reg16 [ reg_ax ] = a . io . port_read16 ( b ) ; a . diverged ( ) ; } ; t32 [ 229 ] = function ( a ) { var b = a . read_op8 ( ) ; a . test_privileges_for_io ( b , 4 ) ; a . reg32s [ reg_eax ] = a . io . port_read32 ( b ) ; a . diverged ( ) ; } ; t [ 230 ] = function ( a ) { var b = a . read_op8 ( ) ; a . test_privileges_for_io ( b , 1 ) ; a . io . port_write8 ( b , a . reg8 [ reg_al ] ) ; a . diverged ( ) ; } ; t16 [ 231 ] = function ( a ) { var b = a . read_op8 ( ) ; a . test_privileges_for_io ( b , 2 ) ; a . io . port_write16 ( b , a . reg16 [ reg_ax ] ) ; a . diverged ( ) ; } ; t32 [ 231 ] = function ( a ) { var b = a . read_op8 ( ) ; a . test_privileges_for_io ( b , 4 ) ; a . io . port_write32 ( b , a . reg32s [ reg_eax ] ) ; a . diverged ( ) ; } ; t16 [ 232 ] = function ( a ) { var b = a . read_op16 ( ) ; a . push16 ( a . get_real_eip ( ) ) ; a . jmp_rel16 ( b ) ; a . diverged ( ) ; } ; t32 [ 232 ] = function ( a ) { var b = a . read_op32s ( ) ; a . push32 ( a . get_real_eip ( ) ) ; a . instruction_pointer = a . instruction_pointer + b | 0 ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t16 [ 233 ] = function ( a ) { var b = a . read_op16 ( ) ; a . jmp_rel16 ( b ) ; a . diverged ( ) ; } ; t32 [ 233 ] = function ( a ) { var b = a . read_op32s ( ) ; a . instruction_pointer = a . instruction_pointer + b | 0 ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t16 [ 234 ] = function ( a ) { var b = a . read_op16 ( ) , c = a . read_disp16 ( ) ; a . far_jump ( b , c , ! 1 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t32 [ 234 ] = function ( a ) { var b = a . read_op32s ( ) , c = a . read_disp16 ( ) ; a . far_jump ( b , c , ! 1 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t [ 235 ] = function ( a ) { var b = a . read_op8s ( ) ; a . instruction_pointer = a . instruction_pointer + b | 0 ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; } ; t [ 236 ] = function ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 1 ) ; a . reg8 [ reg_al ] = a . io . port_read8 ( b ) ; a . diverged ( ) ; } ; t16 [ 237 ] = function ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 2 ) ; a . reg16 [ reg_ax ] = a . io . port_read16 ( b ) ; a . diverged ( ) ; } ; t32 [ 237 ] = function ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 4 ) ; a . reg32s [ reg_eax ] = a . io . port_read32 ( b ) ; a . diverged ( ) ; } ; t [ 238 ] = function ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 1 ) ; a . io . port_write8 ( b , a . reg8 [ reg_al ] ) ; a . diverged ( ) ; } ; t16 [ 239 ] = function ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 2 ) ; a . io . port_write16 ( b , a . reg16 [ reg_ax ] ) ; a . diverged ( ) ; } ; t32 [ 239 ] = function ( a ) { var b = a . reg16 [ reg_dx ] ; a . test_privileges_for_io ( b , 4 ) ; a . io . port_write32 ( b , a . reg32s [ reg_eax ] ) ; a . diverged ( ) ; } ; t [ 240 ] = function ( a ) { a . run_prefix_instruction ( ) ; } ; t [ 241 ] = function ( a ) { throw a . debug . unimpl ( "int1 instruction" ) ; } ; t [ 242 ] = function ( a ) { dbg_assert ( 0 === ( a . prefixes & PREFIX_MASK_REP ) ) ; a . prefixes |= PREFIX_REPNZ ; a . run_prefix_instruction ( ) ; a . prefixes = 0 ; } ; t [ 243 ] = function ( a ) { dbg_assert ( 0 === ( a . prefixes & PREFIX_MASK_REP ) ) ; a . prefixes |= PREFIX_REPZ ; a . run_prefix_instruction ( ) ; a . prefixes = 0 ; } ; t [ 244 ] = function ( a ) { a . hlt_op ( ) ; } ; t [ 245 ] = function ( a ) { a . flags = ( a . flags | 1 ) ^ a . getcf ( ) ; a . flags_changed &= - 2 ; } ; t [ 246 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : var b = a . read_e8 ( ) ; a . test8 ( b , a . read_op8 ( ) ) ; break ; case 1 : b = a . read_e8 ( ) ; a . test8 ( b , a . read_op8 ( ) ) ; break ; case 2 : b = a . read_write_e8 ( ) ; a . write_e8 ( ~ b ) ; break ; case 3 : b = a . read_write_e8 ( ) ; a . write_e8 ( a . neg8 ( b ) ) ; break ; case 4 : b = a . read_e8 ( ) ; a . mul8 ( b ) ; break ; case 5 : b = a . read_e8s ( ) ; a . imul8 ( b ) ; break ; case 6 : b = a . read_e8 ( ) ; a . div8 ( b ) ; break ; case 7 : b = a . read_e8s ( ) , a . idiv8 ( b ) ; } } ; t16 [ 247 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : var b = a . read_e16 ( ) ; a . test16 ( b , a . read_op16 ( ) ) ; break ; case 1 : b = a . read_e16 ( ) ; a . test16 ( b , a . read_op16 ( ) ) ; break ; case 2 : b = a . read_write_e16 ( ) ; a . write_e16 ( ~ b ) ; break ; case 3 : b = a . read_write_e16 ( ) ; a . write_e16 ( a . neg16 ( b ) ) ; break ; case 4 : b = a . read_e16 ( ) ; a . mul16 ( b ) ; break ; case 5 : b = a . read_e16s ( ) ; a . imul16 ( b ) ; break ; case 6 : b = a . read_e16 ( ) ; a . div16 ( b ) ; break ; case 7 : b = a . read_e16s ( ) , a . idiv16 ( b ) ; } } ; t32 [ 247 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : var b = a . read_e32s ( ) ; a . test32 ( b , a . read_op32s ( ) ) ; break ; case 1 : b = a . read_e32s ( ) ; a . test32 ( b , a . read_op32s ( ) ) ; break ; case 2 : b = a . read_write_e32 ( ) ; a . write_e32 ( ~ b ) ; break ; case 3 : b = a . read_write_e32 ( ) ; a . write_e32 ( a . neg32 ( b ) ) ; break ; case 4 : b = a . read_e32 ( ) ; a . mul32 ( b ) ; break ; case 5 : b = a . read_e32s ( ) ; a . imul32 ( b ) ; break ; case 6 : b = a . read_e32 ( ) ; a . div32 ( b ) ; break ; case 7 : b = a . read_e32s ( ) , a . idiv32 ( b ) ; } } ; t [ 248 ] = function ( a ) { a . flags &= ~ flag_carry ; a . flags_changed &= - 2 ; } ; t [ 249 ] = function ( a ) { a . flags |= flag_carry ; a . flags_changed &= - 2 ; } ; t [ 250 ] = function ( a ) { ! a . protected_mode || ( a . flags & flag_vm ? 3 === a . getiopl ( ) : a . getiopl ( ) >= a . cpl ) ? a . flags &= ~ flag_interrupt : ( dbg_log ( "cli #gp" , LOG_CPU ) , a . trigger_gp ( 0 ) ) ; } ; t [ 251 ] = function ( a ) { ! a . protected_mode || ( a . flags & flag_vm ? 3 === a . getiopl ( ) : a . getiopl ( ) >= a . cpl ) ? ( a . flags |= flag_interrupt , a . clear_prefixes ( ) , a . cycle_internal ( ) , a . handle_irqs ( ) ) : ( dbg_log ( "sti #gp" , LOG_CPU ) , a . trigger_gp ( 0 ) ) ; } ; t [ 252 ] = function ( a ) { a . flags &= ~ flag_direction ; } ; t [ 253 ] = function ( a ) { a . flags |= flag_direction ; } ; t [ 254 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . modrm_byte & 56 ; 0 === b ? ( b = a . read_write_e8 ( ) , a . write_e8 ( a . inc8 ( b ) ) ) : 8 === b ? ( b = a . read_write_e8 ( ) , a . write_e8 ( a . dec8 ( b ) ) ) : a . todo ( ) ; } ; t16 [ 255 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : var b = a . read_write_e16 ( ) ; a . write_e16 ( a . inc16 ( b ) ) ; break ; case 1 : b = a . read_write_e16 ( ) ; a . write_e16 ( a . dec16 ( b ) ) ; break ; case 2 : b = a . read_e16 ( ) ; a . push16 ( a . get_real_eip ( ) ) ; a . instruction_pointer = a . get_seg ( reg_cs ) + b | 0 ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; break ; case 3 : 192 <= a . modrm_byte && ( dbg_log ( "callf #ud" , LOG_CPU ) , a . trigger_ud ( ) , dbg_assert ( ! 1 , "unreachable" ) ) ; var c = a . modrm_resolve ( a . modrm_byte ) ; b = a . safe_read16 ( c ) ; c = a . safe_read16 ( c + 2 | 0 ) ; a . far_jump ( b , c , ! 0 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; break ; case 4 : b = a . read_e16 ( ) ; a . instruction_pointer = a . get_seg ( reg_cs ) + b | 0 ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; break ; case 5 : 192 <= a . modrm_byte && ( dbg_log ( "jmpf #ud" , LOG_CPU ) , a . trigger_ud ( ) , dbg_assert ( ! 1 , "unreachable" ) ) ; c = a . modrm_resolve ( a . modrm_byte ) ; b = a . safe_read16 ( c ) ; c = a . safe_read16 ( c + 2 | 0 ) ; a . far_jump ( b , c , ! 1 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > a . get_real_eip ( ) ) ; a . diverged ( ) ; break ; case 6 : b = a . read_e16 ( ) ; a . push16 ( b ) ; break ; case 7 : a . todo ( ) ; } } ; t32 [ 255 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : var b = a . read_write_e32 ( ) ; a . write_e32 ( a . inc32 ( b ) ) ; break ; case 1 : b = a . read_write_e32 ( ) ; a . write_e32 ( a . dec32 ( b ) ) ; break ; case 2 : b = a . read_e32s ( ) ; a . push32 ( a . get_real_eip ( ) ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > b ) ; a . instruction_pointer = a . get_seg ( reg_cs ) + b | 0 ; a . diverged ( ) ; break ; case 3 : 192 <= a . modrm_byte && ( dbg_log ( "callf #ud" , LOG_CPU ) , a . trigger_ud ( ) , dbg_assert ( ! 1 , "unreachable" ) ) ; var c = a . modrm_resolve ( a . modrm_byte ) ; b = a . safe_read32s ( c ) ; c = a . safe_read16 ( c + 4 | 0 ) ; if ( ( ! a . protected_mode || a . vm86_mode ( ) ) && b & 4294901760 ) throw a . debug . unimpl ( "#GP handler" ) ; a . far_jump ( b , c , ! 0 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > b ) ; a . diverged ( ) ; break ; case 4 : b = a . read_e32s ( ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > b ) ; a . instruction_pointer = a . get_seg ( reg_cs ) + b | 0 ; a . diverged ( ) ; break ; case 5 : 192 <= a . modrm_byte && ( dbg_log ( "jmpf #ud" , LOG_CPU ) , a . trigger_ud ( ) , dbg_assert ( ! 1 , "unreachable" ) ) ; c = a . modrm_resolve ( a . modrm_byte ) ; b = a . safe_read32s ( c ) ; c = a . safe_read16 ( c + 4 | 0 ) ; if ( ( ! a . protected_mode || a . vm86_mode ( ) ) && b & 4294901760 ) throw a . debug . unimpl ( "#GP handler" ) ; a . far_jump ( b , c , ! 1 ) ; dbg_assert ( a . is_asize_32 ( ) || 65536 > b ) ; a . diverged ( ) ; break ; case 6 : b = a . read_e32s ( ) ; a . push32 ( b ) ; break ; case 7 : a . todo ( ) ; } } ; var table16 = [ ] , table32 = [ ] ; CPU . prototype . table16 = table16 ; CPU . prototype . table32 = table32 ; for ( var i = 0 ; 256 > i ; i ++ ) t [ i ] ? table16 [ i ] = table32 [ i ] = t [ i ] : t16 [ i ] && ( table16 [ i ] = t16 [ i ] , table32 [ i ] = t32 [ i ] ) ; t = [ ] ; t16 = [ ] ; t32 = [ ] ; t [ 0 ] = function ( a ) { a . read_modrm_byte ( ) ; if ( ! a . protected_mode || a . vm86_mode ( ) ) dbg_log ( "0f 00 #ud" , LOG_CPU ) , a . trigger_ud ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : a . set_e16 ( a . sreg [ reg_ldtr ] ) ; a . is_osize_32 ( ) && 192 <= a . modrm_byte && ( a . reg32s [ a . modrm_byte & 7 ] &= 65535 ) ; break ; case 1 : a . set_e16 ( a . sreg [ reg_tr ] ) ; a . is_osize_32 ( ) && 192 <= a . modrm_byte && ( a . reg32s [ a . modrm_byte & 7 ] &= 65535 ) ; break ; case 2 : a . cpl && a . trigger_gp ( 0 ) ; var b = a . read_e16 ( ) ; a . load_ldt ( b ) ; break ; case 3 : a . cpl && a . trigger_gp ( 0 ) ; b = a . read_e16 ( ) ; a . load_tr ( b ) ; break ; case 4 : a . verr ( a . read_e16 ( ) ) ; break ; case 5 : a . verw ( a . read_e16 ( ) ) ; break ; default : dbg_log ( a . modrm_byte >> 3 & 7 , LOG_CPU ) , a . todo ( ) ; } } ; t [ 1 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . modrm_byte >> 3 & 7 ; if ( 4 === b ) 192 <= a . modrm_byte && a . is_osize_32 ( ) ? a . set_e32 ( a . cr [ 0 ] ) : a . set_e16 ( a . cr [ 0 ] ) ; else if ( 6 === b ) { a . cpl && a . trigger_gp ( 0 ) ; var c = a . read_e16 ( ) ; c = a . cr [ 0 ] & - 16 | c & 15 ; a . protected_mode && ( c |= CR0_PE ) ; a . set_cr0 ( c ) ; } else switch ( 192 <= a . modrm_byte && ( dbg_log ( "0f 01 #ud" , LOG_CPU ) , a . trigger_ud ( ) ) , c = a . modrm_resolve ( a . modrm_byte ) , b ) { case 0 : a . writable_or_pagefault ( c , 6 ) ; a . safe_write16 ( c , a . gdtr_size ) ; b = a . is_osize_32 ( ) ? - 1 : 16777215 ; a . safe_write32 ( c + 2 , a . gdtr_offset & b ) ; break ; case 1 : a . writable_or_pagefault ( c , 6 ) ; a . safe_write16 ( c , a . idtr_size ) ; b = a . is_osize_32 ( ) ? - 1 : 16777215 ; a . safe_write32 ( c + 2 , a . idtr_offset & b ) ; break ; case 2 : a . cpl && a . trigger_gp ( 0 ) ; b = a . safe_read16 ( c ) ; c = a . safe_read32s ( c + 2 ) ; a . gdtr_size = b ; a . gdtr_offset = c ; a . is_osize_32 ( ) || ( a . gdtr_offset &= 16777215 ) ; break ; case 3 : a . cpl && a . trigger_gp ( 0 ) ; b = a . safe_read16 ( c ) ; c = a . safe_read32s ( c + 2 ) ; a . idtr_size = b ; a . idtr_offset = c ; a . is_osize_32 ( ) || ( a . idtr_offset &= 16777215 ) ; break ; case 7 : a . cpl && a . trigger_gp ( 0 ) ; a . invlpg ( c ) ; break ; default : dbg_log ( b ) , a . todo ( ) ; } } ; t16 [ 2 ] = function ( a ) { a . read_modrm_byte ( ) ; if ( ! a . protected_mode || a . vm86_mode ( ) ) dbg_log ( "lar #ud" , LOG_CPU ) , a . trigger_ud ( ) ; var b = a . read_e16 ( ) ; a . write_g16 ( a . lar ( b , a . read_g16 ( ) ) ) ; } ; t32 [ 2 ] = function ( a ) { a . read_modrm_byte ( ) ; if ( ! a . protected_mode || a . vm86_mode ( ) ) dbg_log ( "lar #ud" , LOG_CPU ) , a . trigger_ud ( ) ; var b = a . read_e16 ( ) ; a . write_g32 ( a . lar ( b , a . read_g32s ( ) ) ) ; } ; t16 [ 3 ] = function ( a ) { a . read_modrm_byte ( ) ; if ( ! a . protected_mode || a . vm86_mode ( ) ) dbg_log ( "lsl #ud" , LOG_CPU ) , a . trigger_ud ( ) ; var b = a . read_e16 ( ) ; a . write_g16 ( a . lsl ( b , a . read_g16 ( ) ) ) ; } ; t32 [ 3 ] = function ( a ) { a . read_modrm_byte ( ) ; if ( ! a . protected_mode || a . vm86_mode ( ) ) dbg_log ( "lsl #ud" , LOG_CPU ) , a . trigger_ud ( ) ; var b = a . read_e16 ( ) ; a . write_g32 ( a . lsl ( b , a . read_g32s ( ) ) ) ; } ; t [ 4 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 5 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 6 ] = function ( a ) { a . cpl ? ( dbg_log ( "clts #gp" , LOG_CPU ) , a . trigger_gp ( 0 ) ) : a . cr [ 0 ] &= ~ CR0_TS ; } ; t [ 7 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 8 ] = function ( a ) { a . todo ( ) ; } ; t [ 9 ] = function ( a ) { a . cpl && ( dbg_log ( "wbinvd #gp" , LOG_CPU ) , a . trigger_gp ( 0 ) ) ; } ; t [ 10 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 11 ] = function ( a ) { a . trigger_ud ( ) ; } ; t [ 12 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 13 ] = function ( a ) { a . todo ( ) ; } ; t [ 14 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 15 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 16 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 17 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 18 ] = function ( a ) { dbg_assert ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_xmm_mem64s ( ) ; a . write_xmm64 ( b [ 0 ] , b [ 1 ] ) ; } ; t [ 19 ] = function ( a ) { dbg_assert ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_xmm64s ( ) ; dbg_assert ( 192 > a . modrm_byte ) ; var c = a . modrm_resolve ( a . modrm_byte ) ; a . safe_write64 ( c , b [ 0 ] , b [ 1 ] ) ; } ; t [ 20 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 21 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 22 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 23 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 24 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte && a . modrm_resolve ( a . modrm_byte ) ; } ; t [ 25 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 26 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 27 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 28 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 29 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 30 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 31 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte && a . modrm_resolve ( a . modrm_byte ) ; } ; t [ 32 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cpl && a . trigger_gp ( 0 ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : a . write_reg_e32 ( a . cr [ 0 ] ) ; break ; case 2 : a . write_reg_e32 ( a . cr [ 2 ] ) ; break ; case 3 : a . write_reg_e32 ( a . cr [ 3 ] ) ; break ; case 4 : a . write_reg_e32 ( a . cr [ 4 ] ) ; break ; default : dbg_log ( a . modrm_byte >> 3 & 7 ) , dbg_assert ( ! 1 ) , a . trigger_ud ( ) ; } } ; t [ 33 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cpl && a . trigger_gp ( 0 ) ; var b = a . modrm_byte >> 3 & 7 ; a . cr [ 4 ] & CR4_DE && ( 4 === b || 5 === b ) && ( dbg_log ( "#ud mov dreg 4/5 with cr4.DE set" , LOG_CPU ) , a . trigger_ud ( ) ) ; a . reg32s [ a . modrm_byte & 7 ] = a . dreg [ b ] ; } ; t [ 34 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cpl && a . trigger_gp ( 0 ) ; var b = a . read_reg_e32s ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : a . set_cr0 ( b ) ; break ; case 2 : a . cr [ 2 ] = b ; break ; case 3 : b &= - 4072 ; dbg_assert ( 0 === ( b & 4095 ) , "TODO" ) ; a . cr [ 3 ] = b ; a . clear_tlb ( ) ; break ; case 4 : a . set_cr4 ( b ) ; break ; default : dbg_log ( a . modrm_byte >> 3 & 7 ) , dbg_assert ( ! 1 ) , a . trigger_ud ( ) ; } } ; t [ 35 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cpl && a . trigger_gp ( 0 ) ; var b = a . modrm_byte >> 3 & 7 ; a . cr [ 4 ] & CR4_DE && ( 4 === b || 5 === b ) && ( dbg_log ( "#ud mov dreg 4/5 with cr4.DE set" , LOG_CPU ) , a . trigger_ud ( ) ) ; a . dreg [ b ] = a . read_reg_e32s ( ) ; } ; t [ 36 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 37 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 38 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 39 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 40 ] = function ( a ) { dbg_assert ( 0 === ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_xmm_mem128s ( ) ; a . write_xmm128s ( b [ 0 ] , b [ 1 ] , b [ 2 ] , b [ 3 ] ) ; } ; t [ 41 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) { var b = a . read_xmm128s ( ) ; dbg_assert ( 192 > a . modrm_byte ) ; var c = a . modrm_resolve ( a . modrm_byte ) ; a . safe_write128 ( c , b [ 0 ] , b [ 1 ] , b [ 2 ] , b [ 3 ] ) ; } else dbg_assert ( 0 === ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_xmm128s ( ) , dbg_assert ( 192 > a . modrm_byte ) , c = a . modrm_resolve ( a . modrm_byte ) , a . safe_write128 ( c , b [ 0 ] , b [ 1 ] , b [ 2 ] , b [ 3 ] ) ; } ; t [ 42 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 43 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 44 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 45 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 46 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 47 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 48 ] = function ( a ) { a . cpl && a . trigger_gp ( 0 ) ; var b = a . reg32s [ reg_ecx ] , c = a . reg32s [ reg_eax ] , d = a . reg32s [ reg_edx ] ; b !== IA32_SYSENTER_ESP && dbg_log ( "wrmsr ecx=" + h ( b >>> 0 , 8 ) + " data=" + h ( d >>> 0 , 8 ) + ":" + h ( c >>> 0 , 8 ) , LOG_CPU ) ; switch ( b ) { case IA32_SYSENTER_CS : a . sysenter_cs = c & 65535 ; break ; case IA32_SYSENTER_EIP : a . sysenter_eip = c ; break ; case IA32_SYSENTER_ESP : a . sysenter_esp = c ; break ; case IA32_APIC_BASE_MSR : dbg_assert ( 0 === d , "Changing APIC address (high 32 bits) not supported" ) ; dbg_assert ( ( c & ~ ( IA32_APIC_BASE_BSP | IA32_APIC_BASE_EXTD | IA32_APIC_BASE_EN ) ) >>> 0 === APIC_ADDRESS , "Changing APIC address not supported" ) ; dbg_assert ( 0 === ( c & IA32_APIC_BASE_EXTD ) , "x2apic not supported" ) ; a . apic_enabled = ( c & IA32_APIC_BASE_EN ) === IA32_APIC_BASE_EN ; break ; case IA32_TIME_STAMP_COUNTER : b = ( c >>> 0 ) + 4294967296 * ( d >>> 0 ) ; a . tsc_offset = v86 . microtick ( ) - b / TSC_RATE ; break ; case IA32_BIOS_SIGN_ID : break ; case IA32_MISC_ENABLE : dbg_log ( "IA32_MISC_ENABLE=" + h ( c >>> 0 , 8 ) , LOG_CPU ) ; break ; case IA32_MCG_CAP : break ; case IA32_KERNEL_GS_BASE : dbg_log ( "GS Base written" , LOG_CPU ) ; break ; default : dbg_assert ( ! 1 , "Unknown msr: " + h ( b >>> 0 , 8 ) ) ; } } ; t [ 49 ] = function ( a ) { if ( a . cpl && a . cr [ 4 ] & CR4_TSD ) a . trigger_gp ( 0 ) ; else { var b = v86 . microtick ( ) - a . tsc_offset ; dbg_assert ( isFinite ( b ) , "non-finite tsc: " + b ) ; a . reg32s [ reg_eax ] = b * TSC_RATE ; a . reg32s [ reg_edx ] = TSC_RATE / 4294967296 * b ; } } ; t [ 50 ] = function ( a ) { a . cpl && a . trigger_gp ( 0 ) ; var b = a . reg32s [ reg_ecx ] ; dbg_log ( "rdmsr ecx=" + h ( b >>> 0 , 8 ) , LOG_CPU ) ; var c = 0 , d = 0 ; switch ( b ) { case IA32_SYSENTER_CS : c = a . sysenter_cs ; break ; case IA32_SYSENTER_EIP : c = a . sysenter_eip ; break ; case IA32_SYSENTER_ESP : c = a . sysenter_esp ; break ; case IA32_TIME_STAMP_COUNTER : b = v86 . microtick ( ) - a . tsc_offset ; c = b * TSC_RATE ; d = TSC_RATE / 4294967296 * b ; break ; case IA32_PLATFORM_ID : break ; case IA32_APIC_BASE_MSR : ENABLE_ACPI && ( c = APIC_ADDRESS , a . apic_enabled && ( c |= IA32_APIC_BASE_EN ) ) ; break ; case IA32_BIOS_SIGN_ID : break ; case IA32_MISC_ENABLE : break ; case IA32_RTIT_CTL : break ; case MSR_SMI_COUNT : break ; case IA32_MCG_CAP : break ; case MSR_PKG_C2_RESIDENCY : break ; case MSR_EBC_FREQUENCY_ID : c = 16777216 ; break ; default : dbg_assert ( ! 1 , "Unknown msr: " + h ( b >>> 0 , 8 ) ) ; } a . reg32s [ reg_eax ] = c ; a . reg32s [ reg_edx ] = d ; } ; t [ 51 ] = function ( a ) { a . todo ( ) ; } ; t [ 52 ] = function ( a ) { var b = a . sysenter_cs & 65532 ; a . protected_mode && 0 !== b || a . trigger_gp ( 0 ) ; a . flags = a . flags & ~ flag_vm & ~ flag_interrupt ; a . instruction_pointer = a . sysenter_eip ; a . reg32s [ reg_esp ] = a . sysenter_esp ; a . sreg [ reg_cs ] = b ; a . segment_is_null [ reg_cs ] = 0 ; a . segment_limits [ reg_cs ] = - 1 ; a . segment_offsets [ reg_cs ] = 0 ; a . update_cs_size ( ! 0 ) ; a . cpl = 0 ; a . cpl_changed ( ) ; a . sreg [ reg_ss ] = b + 8 ; a . segment_is_null [ reg_ss ] = 0 ; a . segment_limits [ reg_ss ] = - 1 ; a . segment_offsets [ reg_ss ] = 0 ; a . stack_size_32 = ! 0 ; a . diverged ( ) ; } ; t [ 53 ] = function ( a ) { var b = a . sysenter_cs & 65532 ; a . protected_mode && ! a . cpl && 0 !== b || a . trigger_gp ( 0 ) ; a . instruction_pointer = a . reg32s [ reg_edx ] ; a . reg32s [ reg_esp ] = a . reg32s [ reg_ecx ] ; a . sreg [ reg_cs ] = b + 16 | 3 ; a . segment_is_null [ reg_cs ] = 0 ; a . segment_limits [ reg_cs ] = - 1 ; a . segment_offsets [ reg_cs ] = 0 ; a . update_cs_size ( ! 0 ) ; a . cpl = 3 ; a . cpl_changed ( ) ; a . sreg [ reg_ss ] = b + 24 | 3 ; a . segment_is_null [ reg_ss ] = 0 ; a . segment_limits [ reg_ss ] = - 1 ; a . segment_offsets [ reg_ss ] = 0 ; a . stack_size_32 = ! 0 ; a . diverged ( ) ; } ; t [ 54 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t [ 55 ] = function ( a ) { a . todo ( ) ; } ; t [ 56 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 57 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 58 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 59 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 60 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 61 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 62 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 63 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t16 [ 64 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( a . test_o ( ) ) ; } ; t32 [ 64 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( a . test_o ( ) ) ; } ; t16 [ 65 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( ! a . test_o ( ) ) ; } ; t32 [ 65 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( ! a . test_o ( ) ) ; } ; t16 [ 66 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( a . test_b ( ) ) ; } ; t32 [ 66 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( a . test_b ( ) ) ; } ; t16 [ 67 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( ! a . test_b ( ) ) ; } ; t32 [ 67 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( ! a . test_b ( ) ) ; } ; t16 [ 68 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( a . test_z ( ) ) ; } ; t32 [ 68 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( a . test_z ( ) ) ; } ; t16 [ 69 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( ! a . test_z ( ) ) ; } ; t32 [ 69 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( ! a . test_z ( ) ) ; } ; t16 [ 70 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( a . test_be ( ) ) ; } ; t32 [ 70 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( a . test_be ( ) ) ; } ; t16 [ 71 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( ! a . test_be ( ) ) ; } ; t32 [ 71 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( ! a . test_be ( ) ) ; } ; t16 [ 72 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( a . test_s ( ) ) ; } ; t32 [ 72 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( a . test_s ( ) ) ; } ; t16 [ 73 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( ! a . test_s ( ) ) ; } ; t32 [ 73 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( ! a . test_s ( ) ) ; } ; t16 [ 74 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( a . test_p ( ) ) ; } ; t32 [ 74 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( a . test_p ( ) ) ; } ; t16 [ 75 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( ! a . test_p ( ) ) ; } ; t32 [ 75 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( ! a . test_p ( ) ) ; } ; t16 [ 76 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( a . test_l ( ) ) ; } ; t32 [ 76 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( a . test_l ( ) ) ; } ; t16 [ 77 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( ! a . test_l ( ) ) ; } ; t32 [ 77 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( ! a . test_l ( ) ) ; } ; t16 [ 78 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( a . test_le ( ) ) ; } ; t32 [ 78 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( a . test_le ( ) ) ; } ; t16 [ 79 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc16 ( ! a . test_le ( ) ) ; } ; t32 [ 79 ] = function ( a ) { a . read_modrm_byte ( ) ; a . cmovcc32 ( ! a . test_le ( ) ) ; } ; t [ 80 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 81 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 82 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 83 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 84 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 85 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 86 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 87 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_xmm_mem128s ( ) , c = a . read_xmm128s ( ) ; a . write_xmm128s ( b [ 0 ] ^ c [ 0 ] , b [ 1 ] ^ c [ 1 ] , b [ 2 ] ^ c [ 2 ] , b [ 3 ] ^ c [ 3 ] ) ; } ; t [ 88 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 89 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 90 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 91 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 92 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 93 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 94 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 95 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 96 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem64s ( ) ; b = new Uint8Array ( b . buffer ) ; var c = a . read_xmm64s ( ) ; c = new Uint8Array ( c . buffer ) ; a . write_xmm128s ( c [ 0 ] | b [ 0 ] << 8 | c [ 1 ] << 16 | b [ 1 ] << 24 , c [ 2 ] | b [ 2 ] << 8 | c [ 3 ] << 16 | b [ 3 ] << 24 , c [ 4 ] | b [ 4 ] << 8 | c [ 5 ] << 16 | b [ 5 ] << 24 , c [ 6 ] | b [ 6 ] << 8 | c [ 7 ] << 16 | b [ 7 ] << 24 ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem32s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , a . write_mmx64s ( c & 255 | ( b & 255 ) << 8 | ( c >> 8 & 255 ) << 16 | ( b >> 8 & 255 ) << 24 , c >> 16 & 255 | ( b >> 16 & 255 ) << 8 | c >>> 24 << 16 | b >>> 24 << 24 ) ; } ; t [ 97 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem64s ( ) ; b = new Uint16Array ( b . buffer ) ; var c = a . read_xmm64s ( ) ; c = new Uint16Array ( c . buffer ) ; a . write_xmm128s ( c [ 0 ] | b [ 0 ] << 16 , c [ 1 ] | b [ 1 ] << 16 , c [ 2 ] | b [ 2 ] << 16 , c [ 3 ] | b [ 3 ] << 16 ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem32s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , a . write_mmx64s ( c & 65535 | ( b & 65535 ) << 16 , c >>> 16 | b >>> 16 << 16 ) ; } ; t [ 98 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem32s ( ) ; a . write_mmx64s ( a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , b ) ; } ; t [ 99 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; var e = 0 | a . saturate_sw_to_sb ( c & 65535 ) ; e |= a . saturate_sw_to_sb ( c >>> 16 ) << 8 ; e |= a . saturate_sw_to_sb ( d & 65535 ) << 16 ; e |= a . saturate_sw_to_sb ( d >>> 16 ) << 24 ; c = 0 | a . saturate_sw_to_sb ( b [ 0 ] & 65535 ) ; c |= a . saturate_sw_to_sb ( b [ 0 ] >>> 16 ) << 8 ; c |= a . saturate_sw_to_sb ( b [ 1 ] & 65535 ) << 16 ; c |= a . saturate_sw_to_sb ( b [ 1 ] >>> 16 ) << 24 ; a . write_mmx64s ( e , c ) ; } ; t [ 100 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; b = new Int8Array ( b . buffer ) ; var c = 8 * ( a . modrm_byte >> 3 & 7 ) , d = a . reg_mmx8s ; a . write_mmx64s ( ( d [ c ] > b [ 0 ] ? 255 : 0 ) | ( d [ c + 1 ] > b [ 1 ] ? 255 : 0 ) << 8 | ( d [ c + 2 ] > b [ 2 ] ? 255 : 0 ) << 16 | ( d [ c + 3 ] > b [ 3 ] ? 255 : 0 ) << 24 , ( d [ c + 4 ] > b [ 4 ] ? 255 : 0 ) | ( d [ c + 5 ] > b [ 5 ] ? 255 : 0 ) << 8 | ( d [ c + 6 ] > b [ 6 ] ? 255 : 0 ) << 16 | ( d [ c + 7 ] > b [ 7 ] ? 255 : 0 ) << 24 ) ; } ; t [ 101 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; a . write_mmx64s ( ( c << 16 >> 16 > b [ 0 ] << 16 >> 16 ? 65535 : 0 ) | ( c >> 16 > b [ 0 ] >> 16 ? 65535 : 0 ) << 16 , ( d << 16 >> 16 > b [ 1 ] << 16 >> 16 ? 65535 : 0 ) | ( d >> 16 > b [ 1 ] >> 16 ? 65535 : 0 ) << 16 ) ; } ; t [ 102 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; a . write_mmx64s ( a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] > b [ 0 ] ? - 1 : 0 , a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] > b [ 1 ] ? - 1 : 0 ) ; } ; t [ 103 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) ; b = new Int16Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Int16Array ( c . buffer ) ; for ( var d = a . create_atom128s ( 0 , 0 , 0 , 0 ) , e = new Uint8Array ( d . buffer ) , g = 0 ; 8 > g ; g ++ ) e [ g ] = a . saturate_sw_to_ub ( c [ g ] ) , e [ g | 8 ] = a . saturate_sw_to_ub ( b [ g ] ) ; a . write_xmm128s ( d [ 0 ] , d [ 1 ] , d [ 2 ] , d [ 3 ] ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem64s ( ) , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , e = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] , c = 0 | a . saturate_sw_to_ub ( d & 65535 ) , c |= a . saturate_sw_to_ub ( d >>> 16 ) << 8 , c |= a . saturate_sw_to_ub ( e & 65535 ) << 16 , c |= a . saturate_sw_to_ub ( e >>> 16 ) << 24 , d = 0 | a . saturate_sw_to_ub ( b [ 0 ] & 65535 ) , d |= a . saturate_sw_to_ub ( b [ 0 ] >>> 16 ) << 8 , d |= a . saturate_sw_to_ub ( b [ 1 ] & 65535 ) << 16 , d |= a . saturate_sw_to_ub ( b [ 1 ] >>> 16 ) << 24 , a . write_mmx64s ( c , d ) ; } ; t [ 104 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) ; b = new Uint8Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Uint8Array ( c . buffer ) ; a . write_xmm128s ( c [ 8 ] | b [ 8 ] << 8 | c [ 9 ] << 16 | b [ 9 ] << 24 , c [ 10 ] | b [ 10 ] << 8 | c [ 11 ] << 16 | b [ 11 ] << 24 , c [ 12 ] | b [ 12 ] << 8 | c [ 13 ] << 16 | b [ 13 ] << 24 , c [ 14 ] | b [ 14 ] << 8 | c [ 15 ] << 16 | b [ 15 ] << 24 ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] , a . write_mmx64s ( c & 255 | ( b [ 1 ] & 255 ) << 8 | ( c >> 8 & 255 ) << 16 | ( b [ 1 ] >> 8 & 255 ) << 24 , c >> 16 & 255 | ( b [ 1 ] >> 16 & 255 ) << 8 | c >>> 24 << 16 | b [ 1 ] >>> 24 << 24 ) ; } ; t [ 105 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; a . write_mmx64s ( c & 65535 | ( b [ 1 ] & 65535 ) << 16 , c >>> 16 | b [ 1 ] >>> 16 << 16 ) ; } ; t [ 106 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; a . write_mmx64s ( a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] , b [ 1 ] ) ; } ; t [ 107 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; var d = 0 | a . saturate_sd_to_sw ( a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] ) ; d |= a . saturate_sd_to_sw ( c ) << 16 ; c = 0 | a . saturate_sd_to_sw ( b [ 0 ] ) ; c |= a . saturate_sd_to_sw ( b [ 1 ] ) << 16 ; a . write_mmx64s ( d , c ) ; } ; t [ 108 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 109 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 110 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) { var b = a . read_e32s ( ) ; a . write_xmm128s ( b , 0 , 0 , 0 ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_e32s ( ) , a . write_mmx64s ( b , 0 ) ; } ; t [ 111 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) ; a . write_xmm128s ( b [ 0 ] , b [ 1 ] , b [ 2 ] , b [ 3 ] ) ; } else ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_REPZ ? ( b = a . read_xmm_mem128s_unaligned ( ) , a . write_xmm128s ( b [ 0 ] , b [ 1 ] , b [ 2 ] , b [ 3 ] ) ) : ( dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem64s ( ) , a . write_mmx64s ( b [ 0 ] , b [ 1 ] ) ) ; } ; t [ 112 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) , c = a . read_op8 ( ) ; a . write_xmm128s ( b [ c & 3 ] , b [ c >> 2 & 3 ] , b [ c >> 4 & 3 ] , b [ c >> 6 & 3 ] ) ; } else if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_REPNZ ) { b = a . read_xmm_mem128s ( ) ; c = new Uint16Array ( b . buffer ) ; var d = a . read_op8 ( ) ; a . write_xmm128s ( c [ d & 3 ] | c [ d >> 2 & 3 ] << 16 , c [ d >> 4 & 3 ] | c [ d >> 6 & 3 ] << 16 , b [ 2 ] , b [ 3 ] ) ; } else if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_REPZ ) b = a . read_xmm_mem128s ( ) , c = new Uint16Array ( b . buffer ) , d = a . read_op8 ( ) , a . write_xmm128s ( b [ 0 ] , b [ 1 ] , c [ d & 3 | 4 ] | c [ d >> 2 & 3 | 4 ] << 16 , c [ d >> 4 & 3 | 4 ] | c [ d >> 6 & 3 | 4 ] << 16 ) ; else { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; b = a . read_mmx_mem64s ( ) ; var e = a . read_op8 ( ) ; c = e & 3 ; d = e >> 2 & 3 ; var g = e >> 4 & 3 ; e >>>= 6 ; a . write_mmx64s ( b [ c >> 1 ] >>> 16 * ( c & 1 ) & 65535 | b [ d >> 1 ] >>> 16 * ( d & 1 ) << 16 , b [ g >> 1 ] >>> 16 * ( g & 1 ) & 65535 | b [ e >> 1 ] >>> 16 * ( e & 1 ) << 16 ) ; } } ; t [ 113 ] = function ( a ) { a . read_modrm_byte ( ) ; dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; 192 > a . modrm_byte && a . trigger_ud ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 2 : var b = a . read_op8 ( ) , c = a . modrm_byte & 7 , d = a . reg_mmxs [ 2 * c ] , e = a . reg_mmxs [ 2 * c + 1 ] , g = 0 , f = 0 ; 15 >= b && ( g = ( d & 65535 ) >>> b | d >>> 16 >>> b << 16 , f = ( e & 65535 ) >>> b | e >>> 16 >>> b << 16 ) ; a . reg_mmxs [ 2 * c ] = g ; a . reg_mmxs [ 2 * c + 1 ] = f ; break ; case 4 : b = a . read_op8 ( ) ; c = a . modrm_byte & 7 ; d = a . reg_mmxs [ 2 * c ] ; e = a . reg_mmxs [ 2 * c + 1 ] ; 15 < b && ( b = 16 ) ; a . reg_mmxs [ 2 * c ] = d << 16 >> 16 >> b & 65535 | ( d >> 16 >> b & 65535 ) << 16 ; a . reg_mmxs [ 2 * c + 1 ] = e << 16 >> 16 >> b & 65535 | ( e >> 16 >> b & 65535 ) << 16 ; break ; case 6 : b = a . read_op8 ( ) ; c = a . modrm_byte & 7 ; d = a . reg_mmxs [ 2 * c ] ; e = a . reg_mmxs [ 2 * c + 1 ] ; f = g = 0 ; 15 >= b && ( g = ( d & 65535 ) << b & 65535 | d >>> 16 << b << 16 , f = ( e & 65535 ) << b & 65535 | e >>> 16 << b << 16 ) ; a . reg_mmxs [ 2 * c ] = g ; a . reg_mmxs [ 2 * c + 1 ] = f ; break ; default : a . unimplemented_sse ( ) ; } } ; t [ 114 ] = function ( a ) { a . read_modrm_byte ( ) ; dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; 192 > a . modrm_byte && a . trigger_ud ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 2 : var b = a . read_op8 ( ) , c = a . modrm_byte & 7 , d = a . reg_mmxs [ 2 * c ] , e = a . reg_mmxs [ 2 * c + 1 ] , g = 0 , f = 0 ; 31 >= b && ( g = d >>> b , f = e >>> b ) ; a . reg_mmxs [ 2 * c ] = g ; a . reg_mmxs [ 2 * c + 1 ] = f ; break ; case 4 : b = a . read_op8 ( ) ; c = a . modrm_byte & 7 ; d = a . reg_mmxs [ 2 * c ] ; e = a . reg_mmxs [ 2 * c + 1 ] ; 31 < b && ( b = 31 ) ; a . reg_mmxs [ 2 * c ] = d >> b ; a . reg_mmxs [ 2 * c + 1 ] = e >> b ; break ; case 6 : b = a . read_op8 ( ) ; c = a . modrm_byte & 7 ; d = a . reg_mmxs [ 2 * c ] ; e = a . reg_mmxs [ 2 * c + 1 ] ; f = g = 0 ; 31 >= b && ( g = d << b , f = e << b ) ; a . reg_mmxs [ 2 * c ] = g ; a . reg_mmxs [ 2 * c + 1 ] = f ; break ; default : a . unimplemented_sse ( ) ; } } ; t [ 115 ] = function ( a ) { a . read_modrm_byte ( ) ; dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; 192 > a . modrm_byte && a . trigger_ud ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 2 : var b = a . read_op8 ( ) , c = a . modrm_byte & 7 , d = a . reg_mmxs [ 2 * c ] , e = a . reg_mmxs [ 2 * c + 1 ] , g = 0 , f = 0 ; 31 >= b ? ( g = d >>> b | e << 32 - b , f = e >>> b ) : 63 >= b && ( g = e >>> ( b & 31 ) , f = 0 ) ; a . reg_mmxs [ 2 * c ] = g ; a . reg_mmxs [ 2 * c + 1 ] = f ; break ; case 6 : b = a . read_op8 ( ) ; c = a . modrm_byte & 7 ; d = a . reg_mmxs [ 2 * c ] ; e = a . reg_mmxs [ 2 * c + 1 ] ; f = g = 0 ; 31 >= b ? ( g = d << b , f = e << b | d >>> 32 - b ) : 63 >= b && ( f = d << ( b & 31 ) , g = 0 ) ; a . reg_mmxs [ 2 * c ] = g ; a . reg_mmxs [ 2 * c + 1 ] = f ; break ; default : a . unimplemented_sse ( ) ; } } ; t [ 116 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) ; b = new Uint8Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Uint8Array ( c . buffer ) ; for ( var d = a . create_atom128s ( 0 , 0 , 0 , 0 ) , e = new Uint8Array ( d . buffer ) , g = 0 ; 16 > g ; g ++ ) e [ g ] = b [ g ] === c [ g ] ? 255 : 0 ; a . write_xmm128s ( d [ 0 ] , d [ 1 ] , d [ 2 ] , d [ 3 ] ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem64s ( ) , b = new Int8Array ( b . buffer ) , c = 8 * ( a . modrm_byte >> 3 & 7 ) , d = a . reg_mmx8s , a . write_mmx64s ( ( d [ c ] === b [ 0 ] ? 255 : 0 ) | ( d [ c + 1 ] === b [ 1 ] ? 255 : 0 ) << 8 | ( d [ c + 2 ] === b [ 2 ] ? 255 : 0 ) << 16 | ( d [ c + 3 ] === b [ 3 ] ? 255 : 0 ) << 24 , ( d [ c + 4 ] === b [ 4 ] ? 255 : 0 ) | ( d [ c + 5 ] === b [ 5 ] ? 255 : 0 ) << 8 | ( d [ c + 6 ] === b [ 6 ] ? 255 : 0 ) << 16 | ( d [ c + 7 ] === b [ 7 ] ? 255 : 0 ) << 24 ) ; } ; t [ 117 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; a . write_mmx64s ( ( ( c & 65535 ) === ( b [ 0 ] & 65535 ) ? 65535 : 0 ) | ( ( c & 4294901760 ) === ( b [ 0 ] & 4294901760 ) ? 65535 : 0 ) << 16 , ( ( d & 65535 ) === ( b [ 1 ] & 65535 ) ? 65535 : 0 ) | ( ( d & 4294901760 ) === ( b [ 1 ] & 4294901760 ) ? 65535 : 0 ) << 16 ) ; } ; t [ 118 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) , c = a . read_xmm128s ( ) ; a . write_xmm128s ( b [ 0 ] === c [ 0 ] ? - 1 : 0 , b [ 1 ] === c [ 1 ] ? - 1 : 0 , b [ 2 ] === c [ 2 ] ? - 1 : 0 , b [ 3 ] === c [ 3 ] ? - 1 : 0 ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem64s ( ) , a . write_mmx64s ( a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] === b [ 0 ] ? - 1 : 0 , a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] === b [ 1 ] ? - 1 : 0 ) ; } ; t [ 119 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . fpu . stack_empty = 255 ; } ; t [ 120 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 121 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 122 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 123 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 124 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 125 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 126 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_REPZ ) { var b = a . read_xmm_mem64s ( ) ; a . write_xmm128s ( b [ 0 ] , b [ 1 ] , 0 , 0 ) ; } else ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ? ( b = a . read_xmm64s ( ) , a . set_e32 ( b [ 0 ] ) ) : ( dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx64s ( ) , a . set_e32 ( b [ 0 ] ) ) ; } ; t [ 127 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_REPZ ) { var b = a . read_xmm128s ( ) ; dbg_assert ( 192 > a . modrm_byte ) ; var c = a . modrm_resolve ( a . modrm_byte ) ; a . safe_write128 ( c , b [ 0 ] , b [ 1 ] , b [ 2 ] , b [ 3 ] ) ; } else ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ? ( b = a . read_xmm128s ( ) , dbg_assert ( 192 > a . modrm_byte ) , c = a . modrm_resolve ( a . modrm_byte ) , a . safe_write128 ( c , b [ 0 ] , b [ 1 ] , b [ 2 ] , b [ 3 ] ) ) : ( dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx64s ( ) , a . set_mmx_mem64s ( b [ 0 ] , b [ 1 ] ) ) ; } ; t16 [ 128 ] = function ( a ) { a . jmpcc16 ( a . test_o ( ) ) ; } ; t32 [ 128 ] = function ( a ) { a . jmpcc32 ( a . test_o ( ) ) ; } ; t16 [ 129 ] = function ( a ) { a . jmpcc16 ( ! a . test_o ( ) ) ; } ; t32 [ 129 ] = function ( a ) { a . jmpcc32 ( ! a . test_o ( ) ) ; } ; t16 [ 130 ] = function ( a ) { a . jmpcc16 ( a . test_b ( ) ) ; } ; t32 [ 130 ] = function ( a ) { a . jmpcc32 ( a . test_b ( ) ) ; } ; t16 [ 131 ] = function ( a ) { a . jmpcc16 ( ! a . test_b ( ) ) ; } ; t32 [ 131 ] = function ( a ) { a . jmpcc32 ( ! a . test_b ( ) ) ; } ; t16 [ 132 ] = function ( a ) { a . jmpcc16 ( a . test_z ( ) ) ; } ; t32 [ 132 ] = function ( a ) { a . jmpcc32 ( a . test_z ( ) ) ; } ; t16 [ 133 ] = function ( a ) { a . jmpcc16 ( ! a . test_z ( ) ) ; } ; t32 [ 133 ] = function ( a ) { a . jmpcc32 ( ! a . test_z ( ) ) ; } ; t16 [ 134 ] = function ( a ) { a . jmpcc16 ( a . test_be ( ) ) ; } ; t32 [ 134 ] = function ( a ) { a . jmpcc32 ( a . test_be ( ) ) ; } ; t16 [ 135 ] = function ( a ) { a . jmpcc16 ( ! a . test_be ( ) ) ; } ; t32 [ 135 ] = function ( a ) { a . jmpcc32 ( ! a . test_be ( ) ) ; } ; t16 [ 136 ] = function ( a ) { a . jmpcc16 ( a . test_s ( ) ) ; } ; t32 [ 136 ] = function ( a ) { a . jmpcc32 ( a . test_s ( ) ) ; } ; t16 [ 137 ] = function ( a ) { a . jmpcc16 ( ! a . test_s ( ) ) ; } ; t32 [ 137 ] = function ( a ) { a . jmpcc32 ( ! a . test_s ( ) ) ; } ; t16 [ 138 ] = function ( a ) { a . jmpcc16 ( a . test_p ( ) ) ; } ; t32 [ 138 ] = function ( a ) { a . jmpcc32 ( a . test_p ( ) ) ; } ; t16 [ 139 ] = function ( a ) { a . jmpcc16 ( ! a . test_p ( ) ) ; } ; t32 [ 139 ] = function ( a ) { a . jmpcc32 ( ! a . test_p ( ) ) ; } ; t16 [ 140 ] = function ( a ) { a . jmpcc16 ( a . test_l ( ) ) ; } ; t32 [ 140 ] = function ( a ) { a . jmpcc32 ( a . test_l ( ) ) ; } ; t16 [ 141 ] = function ( a ) { a . jmpcc16 ( ! a . test_l ( ) ) ; } ; t32 [ 141 ] = function ( a ) { a . jmpcc32 ( ! a . test_l ( ) ) ; } ; t16 [ 142 ] = function ( a ) { a . jmpcc16 ( a . test_le ( ) ) ; } ; t32 [ 142 ] = function ( a ) { a . jmpcc32 ( a . test_le ( ) ) ; } ; t16 [ 143 ] = function ( a ) { a . jmpcc16 ( ! a . test_le ( ) ) ; } ; t32 [ 143 ] = function ( a ) { a . jmpcc32 ( ! a . test_le ( ) ) ; } ; t [ 144 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( a . test_o ( ) ) ; } ; t [ 145 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( ! a . test_o ( ) ) ; } ; t [ 146 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( a . test_b ( ) ) ; } ; t [ 147 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( ! a . test_b ( ) ) ; } ; t [ 148 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( a . test_z ( ) ) ; } ; t [ 149 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( ! a . test_z ( ) ) ; } ; t [ 150 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( a . test_be ( ) ) ; } ; t [ 151 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( ! a . test_be ( ) ) ; } ; t [ 152 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( a . test_s ( ) ) ; } ; t [ 153 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( ! a . test_s ( ) ) ; } ; t [ 154 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( a . test_p ( ) ) ; } ; t [ 155 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( ! a . test_p ( ) ) ; } ; t [ 156 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( a . test_l ( ) ) ; } ; t [ 157 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( ! a . test_l ( ) ) ; } ; t [ 158 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( a . test_le ( ) ) ; } ; t [ 159 ] = function ( a ) { a . read_modrm_byte ( ) ; a . setcc ( ! a . test_le ( ) ) ; } ; t16 [ 160 ] = function ( a ) { a . push16 ( a . sreg [ reg_fs ] ) ; } ; t32 [ 160 ] = function ( a ) { a . push32 ( a . sreg [ reg_fs ] ) ; } ; t16 [ 161 ] = function ( a ) { a . switch_seg ( reg_fs , a . safe_read16 ( a . get_stack_pointer ( 0 ) ) ) ; a . adjust_stack_reg ( 2 ) ; } ; t32 [ 161 ] = function ( a ) { a . switch_seg ( reg_fs , a . safe_read32s ( a . get_stack_pointer ( 0 ) ) & 65535 ) ; a . adjust_stack_reg ( 4 ) ; } ; t [ 162 ] = function ( a ) { a . cpuid ( ) ; } ; t16 [ 163 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . bt_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_g16s ( ) ) : a . bt_reg ( a . read_reg_e16 ( ) , a . read_g16 ( ) & 15 ) ; } ; t32 [ 163 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . bt_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_g32s ( ) ) : a . bt_reg ( a . read_reg_e32s ( ) , a . read_g32s ( ) & 31 ) ; } ; t16 [ 164 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) ; a . write_e16 ( a . shld16 ( b , a . read_g16 ( ) , a . read_op8 ( ) & 31 ) ) ; } ; t32 [ 164 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) ; a . write_e32 ( a . shld32 ( b , a . read_g32s ( ) , a . read_op8 ( ) & 31 ) ) ; } ; t16 [ 165 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) ; a . write_e16 ( a . shld16 ( b , a . read_g16 ( ) , a . reg8 [ reg_cl ] & 31 ) ) ; } ; t32 [ 165 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) ; a . write_e32 ( a . shld32 ( b , a . read_g32s ( ) , a . reg8 [ reg_cl ] & 31 ) ) ; } ; t [ 166 ] = function ( a ) { a . trigger_ud ( ) ; } ; t [ 167 ] = function ( a ) { a . undefined_instruction ( ) ; } ; t16 [ 168 ] = function ( a ) { a . push16 ( a . sreg [ reg_gs ] ) ; } ; t32 [ 168 ] = function ( a ) { a . push32 ( a . sreg [ reg_gs ] ) ; } ; t16 [ 169 ] = function ( a ) { a . switch_seg ( reg_gs , a . safe_read16 ( a . get_stack_pointer ( 0 ) ) ) ; a . adjust_stack_reg ( 2 ) ; } ; t32 [ 169 ] = function ( a ) { a . switch_seg ( reg_gs , a . safe_read32s ( a . get_stack_pointer ( 0 ) ) & 65535 ) ; a . adjust_stack_reg ( 4 ) ; } ; t [ 170 ] = function ( a ) { a . todo ( ) ; } ; t16 [ 171 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . bts_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_g16s ( ) ) : a . write_reg_e16 ( a . bts_reg ( a . read_reg_e16 ( ) , a . read_g16s ( ) & 15 ) ) ; } ; t32 [ 171 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . bts_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_g32s ( ) ) : a . write_reg_e32 ( a . bts_reg ( a . read_reg_e32s ( ) , a . read_g32s ( ) & 31 ) ) ; } ; t16 [ 172 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) ; a . write_e16 ( a . shrd16 ( b , a . read_g16 ( ) , a . read_op8 ( ) & 31 ) ) ; } ; t32 [ 172 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) ; a . write_e32 ( a . shrd32 ( b , a . read_g32s ( ) , a . read_op8 ( ) & 31 ) ) ; } ; t16 [ 173 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) ; a . write_e16 ( a . shrd16 ( b , a . read_g16 ( ) , a . reg8 [ reg_cl ] & 31 ) ) ; } ; t32 [ 173 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) ; a . write_e32 ( a . shrd32 ( b , a . read_g32s ( ) , a . reg8 [ reg_cl ] & 31 ) ) ; } ; t [ 174 ] = function ( a ) { a . read_modrm_byte ( ) ; a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) && a . todo ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 0 : 192 <= a . modrm_byte && a . trigger_ud ( ) ; var b = a . modrm_resolve ( a . modrm_byte ) ; a . fxsave ( b ) ; break ; case 1 : 192 <= a . modrm_byte && a . trigger_ud ( ) ; b = a . modrm_resolve ( a . modrm_byte ) ; a . fxrstor ( b ) ; break ; case 2 : 192 <= a . modrm_byte && a . trigger_ud ( ) ; b = a . modrm_resolve ( a . modrm_byte ) ; b = a . safe_read32s ( b ) ; b & ~ MXCSR_MASK && ( dbg_log ( "Invalid mxcsr bits: " + h ( ( b & ~ MXCSR_MASK ) >>> 0 , 8 ) ) , a . trigger_gp ( 0 ) ) ; a . mxcsr = b ; break ; case 3 : 192 <= a . modrm_byte && a . trigger_ud ( ) ; b = a . modrm_resolve ( a . modrm_byte ) ; a . safe_write32 ( b , a . mxcsr ) ; break ; case 5 : dbg_assert ( 192 <= a . modrm_byte , "Unexpected lfence encoding" ) ; 192 > a . modrm_byte && a . trigger_ud ( ) ; break ; case 6 : dbg_assert ( 192 <= a . modrm_byte , "Unexpected mfence encoding" ) ; 192 > a . modrm_byte && a . trigger_ud ( ) ; break ; case 7 : dbg_assert ( 192 <= a . modrm_byte , "Unexpected sfence encoding" ) ; 192 > a . modrm_byte && a . trigger_ud ( ) ; break ; default : dbg_log ( "missing " + ( a . modrm_byte >> 3 & 7 ) , LOG_CPU ) , a . todo ( ) ; } } ; t16 [ 175 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e16s ( ) ; a . write_g16 ( a . imul_reg16 ( a . read_g16s ( ) , b ) ) ; } ; t32 [ 175 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e32s ( ) ; a . write_g32 ( a . imul_reg32 ( a . read_g32s ( ) , b ) ) ; } ; t [ 176 ] = function ( a ) { a . read_modrm_byte ( ) ; if ( 192 > a . modrm_byte ) { var b = a . modrm_resolve ( a . modrm_byte ) ; a . writable_or_pagefault ( b , 1 ) ; var c = a . safe_read8 ( b ) ; } else c = a . reg8 [ a . modrm_byte << 2 & 12 | a . modrm_byte >> 2 & 1 ] ; a . cmp8 ( a . reg8 [ reg_al ] , c ) ; a . getzf ( ) ? 192 > a . modrm_byte ? a . safe_write8 ( b , a . read_g8 ( ) ) : a . reg8 [ a . modrm_byte << 2 & 12 | a . modrm_byte >> 2 & 1 ] = a . read_g8 ( ) : ( 192 > a . modrm_byte && a . safe_write8 ( b , c ) , a . reg8 [ reg_al ] = c ) ; } ; t16 [ 177 ] = function ( a ) { a . read_modrm_byte ( ) ; if ( 192 > a . modrm_byte ) { var b = a . modrm_resolve ( a . modrm_byte ) ; a . writable_or_pagefault ( b , 2 ) ; var c = a . safe_read16 ( b ) ; } else c = a . read_reg_e16 ( ) ; a . cmp16 ( a . reg16 [ reg_ax ] , c ) ; a . getzf ( ) ? 192 > a . modrm_byte ? a . safe_write16 ( b , a . read_g16 ( ) ) : a . write_reg_e16 ( a . read_g16 ( ) ) : ( 192 > a . modrm_byte && a . safe_write16 ( b , c ) , a . reg16 [ reg_ax ] = c ) ; } ; t32 [ 177 ] = function ( a ) { a . read_modrm_byte ( ) ; if ( 192 > a . modrm_byte ) { var b = a . modrm_resolve ( a . modrm_byte ) ; a . writable_or_pagefault ( b , 4 ) ; var c = a . safe_read32s ( b ) ; } else c = a . read_reg_e32s ( ) ; a . cmp32 ( a . reg32s [ reg_eax ] , c ) ; a . getzf ( ) ? 192 > a . modrm_byte ? a . safe_write32 ( b , a . read_g32s ( ) ) : a . write_reg_e32 ( a . read_g32s ( ) ) : ( 192 > a . modrm_byte && a . safe_write32 ( b , c ) , a . reg32s [ reg_eax ] = c ) ; } ; t16 [ 178 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss16 ( reg_ss ) ; } ; t32 [ 178 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss32 ( reg_ss ) ; } ; t16 [ 179 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . btr_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_g16s ( ) ) : a . write_reg_e16 ( a . btr_reg ( a . read_reg_e16 ( ) , a . read_g16s ( ) & 15 ) ) ; } ; t32 [ 179 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . btr_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_g32s ( ) ) : a . write_reg_e32 ( a . btr_reg ( a . read_reg_e32s ( ) , a . read_g32s ( ) & 31 ) ) ; } ; t16 [ 180 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss16 ( reg_fs ) ; } ; t32 [ 180 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss32 ( reg_fs ) ; } ; t16 [ 181 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss16 ( reg_gs ) ; } ; t32 [ 181 ] = function ( a ) { a . read_modrm_byte ( ) ; a . lss32 ( reg_gs ) ; } ; t16 [ 182 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e8 ( ) ; a . write_g16 ( b ) ; } ; t32 [ 182 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e8 ( ) ; a . write_g32 ( b ) ; } ; t16 [ 183 ] = function ( a ) { a . read_modrm_byte ( ) ; dbg_assert ( ! 1 , "Possibly invalid encoding" ) ; var b = a . read_e16 ( ) ; a . write_g16 ( b ) ; } ; t32 [ 183 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e16 ( ) ; a . write_g32 ( b ) ; } ; t16 [ 184 ] = function ( a ) { a . read_modrm_byte ( ) ; 0 === ( a . prefixes & PREFIX_REPZ ) && a . trigger_ud ( ) ; var b = a . read_e16 ( ) ; a . write_g16 ( a . popcnt ( b ) ) ; } ; t32 [ 184 ] = function ( a ) { a . read_modrm_byte ( ) ; 0 === ( a . prefixes & PREFIX_REPZ ) && a . trigger_ud ( ) ; var b = a . read_e32s ( ) ; a . write_g32 ( a . popcnt ( b ) ) ; } ; t [ 185 ] = function ( a ) { a . todo ( ) ; } ; t16 [ 186 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 4 : 192 > a . modrm_byte ? a . bt_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) & 15 ) : a . bt_reg ( a . read_reg_e16 ( ) , a . read_op8 ( ) & 15 ) ; break ; case 5 : 192 > a . modrm_byte ? a . bts_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) & 15 ) : a . write_reg_e16 ( a . bts_reg ( a . read_reg_e16 ( ) , a . read_op8 ( ) & 15 ) ) ; break ; case 6 : 192 > a . modrm_byte ? a . btr_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) & 15 ) : a . write_reg_e16 ( a . btr_reg ( a . read_reg_e16 ( ) , a . read_op8 ( ) & 15 ) ) ; break ; case 7 : 192 > a . modrm_byte ? a . btc_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) & 15 ) : a . write_reg_e16 ( a . btc_reg ( a . read_reg_e16 ( ) , a . read_op8 ( ) & 15 ) ) ; break ; default : dbg_log ( a . modrm_byte >> 3 & 7 ) , a . todo ( ) ; } } ; t32 [ 186 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 4 : 192 > a . modrm_byte ? a . bt_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) & 31 ) : a . bt_reg ( a . read_reg_e32s ( ) , a . read_op8 ( ) & 31 ) ; break ; case 5 : 192 > a . modrm_byte ? a . bts_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) & 31 ) : a . write_reg_e32 ( a . bts_reg ( a . read_reg_e32s ( ) , a . read_op8 ( ) & 31 ) ) ; break ; case 6 : 192 > a . modrm_byte ? a . btr_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) & 31 ) : a . write_reg_e32 ( a . btr_reg ( a . read_reg_e32s ( ) , a . read_op8 ( ) & 31 ) ) ; break ; case 7 : 192 > a . modrm_byte ? a . btc_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_op8 ( ) & 31 ) : a . write_reg_e32 ( a . btc_reg ( a . read_reg_e32s ( ) , a . read_op8 ( ) & 31 ) ) ; break ; default : dbg_log ( a . modrm_byte >> 3 & 7 ) , a . todo ( ) ; } } ; t16 [ 187 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . btc_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_g16s ( ) ) : a . write_reg_e16 ( a . btc_reg ( a . read_reg_e16 ( ) , a . read_g16s ( ) & 15 ) ) ; } ; t32 [ 187 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 > a . modrm_byte ? a . btc_mem ( a . modrm_resolve ( a . modrm_byte ) , a . read_g32s ( ) ) : a . write_reg_e32 ( a . btc_reg ( a . read_reg_e32s ( ) , a . read_g32s ( ) & 31 ) ) ; } ; t16 [ 188 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e16 ( ) ; a . write_g16 ( a . bsf16 ( a . read_g16 ( ) , b ) ) ; } ; t32 [ 188 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e32s ( ) ; a . write_g32 ( a . bsf32 ( a . read_g32s ( ) , b ) ) ; } ; t16 [ 189 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e16 ( ) ; a . write_g16 ( a . bsr16 ( a . read_g16 ( ) , b ) ) ; } ; t32 [ 189 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e32s ( ) ; a . write_g32 ( a . bsr32 ( a . read_g32s ( ) , b ) ) ; } ; t16 [ 190 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e8s ( ) ; a . write_g16 ( b ) ; } ; t32 [ 190 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e8s ( ) ; a . write_g32 ( b ) ; } ; t16 [ 191 ] = function ( a ) { a . read_modrm_byte ( ) ; dbg_assert ( ! 1 , "Possibly invalid encoding" ) ; var b = a . read_e16 ( ) ; a . write_g16 ( b ) ; } ; t32 [ 191 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_e16s ( ) ; a . write_g32 ( b ) ; } ; t [ 192 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e8 ( ) ; a . write_e8 ( a . xadd8 ( b , a . modrm_byte >> 1 & 12 | a . modrm_byte >> 5 & 1 ) ) ; } ; t16 [ 193 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e16 ( ) ; a . write_e16 ( a . xadd16 ( b , a . modrm_byte >> 2 & 14 ) ) ; } ; t32 [ 193 ] = function ( a ) { a . read_modrm_byte ( ) ; var b = a . read_write_e32 ( ) ; a . write_e32 ( a . xadd32 ( b , a . modrm_byte >> 3 & 7 ) ) ; } ; t [ 194 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 195 ] = function ( a ) { a . read_modrm_byte ( ) ; 192 <= a . modrm_byte && a . trigger_ud ( ) ; a . set_e32 ( a . read_g32s ( ) ) ; } ; t [ 196 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 197 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 198 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 199 ] = function ( a ) { a . read_modrm_byte ( ) ; switch ( a . modrm_byte >> 3 & 7 ) { case 1 : 192 <= a . modrm_byte && a . trigger_ud ( ) ; var b = a . modrm_resolve ( a . modrm_byte ) ; a . writable_or_pagefault ( b , 8 ) ; var c = a . safe_read32s ( b ) , d = a . safe_read32s ( b + 4 | 0 ) ; a . reg32s [ reg_eax ] === c && a . reg32s [ reg_edx ] === d ? ( a . flags |= flag_zero , a . safe_write32 ( b , a . reg32s [ reg_ebx ] ) , a . safe_write32 ( b + 4 | 0 , a . reg32s [ reg_ecx ] ) ) : ( a . flags &= ~ flag_zero , a . reg32s [ reg_eax ] = c , a . reg32s [ reg_edx ] = d , a . safe_write32 ( b , c ) , a . safe_write32 ( b + 4 | 0 , d ) ) ; a . flags_changed &= ~ flag_zero ; break ; case 6 : c = ( b = v86util . has_rand_int ( ) ) ? v86util . get_rand_int ( ) : 0 ; a . is_osize_32 ( ) ? a . set_e32 ( c ) : a . set_e16 ( c ) ; a . flags &= ~ flags_all ; a . flags |= b ; a . flags_changed = 0 ; break ; default : dbg_log ( a . modrm_byte >> 3 & 7 , LOG_CPU ) , a . todo ( ) ; } } ; t [ 200 ] = function ( a ) { a . bswap ( reg_eax ) ; } ; t [ 201 ] = function ( a ) { a . bswap ( reg_ecx ) ; } ; t [ 202 ] = function ( a ) { a . bswap ( reg_edx ) ; } ; t [ 203 ] = function ( a ) { a . bswap ( reg_ebx ) ; } ; t [ 204 ] = function ( a ) { a . bswap ( reg_esp ) ; } ; t [ 205 ] = function ( a ) { a . bswap ( reg_ebp ) ; } ; t [ 206 ] = function ( a ) { a . bswap ( reg_esi ) ; } ; t [ 207 ] = function ( a ) { a . bswap ( reg_edi ) ; } ; t [ 208 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 209 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = b [ 0 ] >>> 0 ; var e = 0 , g = 0 ; 15 >= b && ( e = ( c & 65535 ) >>> b | c >>> 16 >>> b << 16 , g = ( d & 65535 ) >>> b | d >>> 16 >>> b << 16 ) ; a . write_mmx64s ( e , g ) ; } ; t [ 210 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = b [ 0 ] >>> 0 ; var e = 0 , g = 0 ; 31 >= b && ( e = c >>> b , g = d >>> b ) ; a . write_mmx64s ( e , g ) ; } ; t [ 211 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = b [ 0 ] >>> 0 ; if ( 0 !== b ) { var e = 0 , g = 0 ; 31 >= b ? ( e = c >>> b | d << 32 - b , g = d >>> b ) : 63 >= b && ( e = d >>> ( b & 31 ) , g = 0 ) ; a . write_mmx64s ( e , g ) ; } } ; t [ 212 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 213 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) ; b = new Int16Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Int16Array ( c . buffer ) ; a . write_xmm128s ( b [ 0 ] * c [ 0 ] & 65535 | b [ 1 ] * c [ 1 ] << 16 , b [ 2 ] * c [ 2 ] & 65535 | b [ 3 ] * c [ 3 ] << 16 , b [ 4 ] * c [ 4 ] & 65535 | b [ 5 ] * c [ 5 ] << 16 , b [ 6 ] * c [ 6 ] & 65535 | b [ 7 ] * c [ 7 ] << 16 ) ; } else { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; b = a . read_mmx_mem64s ( ) ; c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] ; var d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; a . write_mmx64s ( ( c & 65535 ) * ( b [ 0 ] & 65535 ) & 65535 | ( ( c >>> 16 ) * ( b [ 0 ] >>> 16 ) & 65535 ) << 16 , ( d & 65535 ) * ( b [ 1 ] & 65535 ) & 65535 | ( ( d >>> 16 ) * ( b [ 1 ] >>> 16 ) & 65535 ) << 16 ) ; } } ; t [ 214 ] = function ( a ) { dbg_assert ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_xmm64s ( ) ; dbg_assert ( 192 > a . modrm_byte ) ; var c = a . modrm_resolve ( a . modrm_byte ) ; a . safe_write64 ( c , b [ 0 ] , b [ 1 ] ) ; } ; t [ 215 ] = function ( a ) { dbg_assert ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; 192 > a . modrm_byte && a . trigger_ud ( ) ; var b = a . read_xmm_mem128s ( ) ; b = new Uint8Array ( b . buffer ) ; a . write_g32 ( b [ 0 ] >> 7 << 0 | b [ 1 ] >> 7 << 1 | b [ 2 ] >> 7 << 2 | b [ 3 ] >> 7 << 3 | b [ 4 ] >> 7 << 4 | b [ 5 ] >> 7 << 5 | b [ 6 ] >> 7 << 6 | b [ 7 ] >> 7 << 7 | b [ 8 ] >> 7 << 8 | b [ 9 ] >> 7 << 9 | b [ 10 ] >> 7 << 10 | b [ 11 ] >> 7 << 11 | b [ 12 ] >> 7 << 12 | b [ 13 ] >> 7 << 13 | b [ 14 ] >> 7 << 14 | b [ 15 ] >> 7 << 15 ) ; } ; t [ 216 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = new Uint8Array ( b . buffer ) , d = 8 * ( a . modrm_byte >> 3 & 7 ) , e = a . reg_mmx8 ; b = a . saturate_sd_to_ub ( e [ d ] - c [ 0 ] ) ; var g = a . saturate_sd_to_ub ( e [ d + 1 ] - c [ 1 ] ) , f = a . saturate_sd_to_ub ( e [ d + 2 ] - c [ 2 ] ) , k = a . saturate_sd_to_ub ( e [ d + 3 ] - c [ 3 ] ) , l = a . saturate_sd_to_ub ( e [ d + 4 ] - c [ 4 ] ) , m = a . saturate_sd_to_ub ( e [ d + 5 ] - c [ 5 ] ) , n = a . saturate_sd_to_ub ( e [ d + 6 ] - c [ 6 ] ) ; c = a . saturate_sd_to_ub ( e [ d + 7 ] - c [ 7 ] ) ; a . write_mmx64s ( b | g << 8 | f << 16 | k << 24 , l | m << 8 | n << 16 | c << 24 ) ; } ; t [ 217 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] , e = ( c & 65535 ) - ( b [ 0 ] & 65535 ) ; c = ( c >>> 16 ) - ( b [ 0 ] >>> 16 ) ; 0 > e && ( e = 0 ) ; 0 > c && ( c = 0 ) ; var g = ( d & 65535 ) - ( b [ 1 ] & 65535 ) ; b = ( d >>> 16 ) - ( b [ 1 ] >>> 16 ) ; 0 > g && ( g = 0 ) ; 0 > b && ( b = 0 ) ; a . write_mmx64s ( e | c << 16 , g | b << 16 ) ; } ; t [ 218 ] = function ( a ) { dbg_assert ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_xmm_mem128s ( ) ; b = new Uint8Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Uint8Array ( c . buffer ) ; for ( var d = a . create_atom128s ( 0 , 0 , 0 , 0 ) , e = new Uint8Array ( d . buffer ) , g = 0 ; 16 > g ; g ++ ) e [ g ] = b [ g ] < c [ g ] ? b [ g ] : c [ g ] ; a . write_xmm128s ( d [ 0 ] , d [ 1 ] , d [ 2 ] , d [ 3 ] ) ; } ; t [ 219 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; a . write_mmx64s ( b [ 0 ] & a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , b [ 1 ] & a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ) ; } ; t [ 220 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) ; b = new Uint8Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Uint8Array ( c . buffer ) ; for ( var d = a . create_atom128s ( 0 , 0 , 0 , 0 ) , e = new Uint8Array ( d . buffer ) , g = 0 ; 16 > g ; g ++ ) e [ g ] = a . saturate_ud_to_ub ( b [ g ] + c [ g ] ) ; a . write_xmm128s ( d [ 0 ] , d [ 1 ] , d [ 2 ] , d [ 3 ] ) ; } else { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; b = a . read_mmx_mem64s ( ) ; var f = new Uint8Array ( b . buffer ) , k = 8 * ( a . modrm_byte >> 3 & 7 ) , l = a . reg_mmx8 ; b = a . saturate_ud_to_ub ( l [ k ] + f [ 0 ] ) ; c = a . saturate_ud_to_ub ( l [ k + 1 ] + f [ 1 ] ) ; d = a . saturate_ud_to_ub ( l [ k + 2 ] + f [ 2 ] ) ; e = a . saturate_ud_to_ub ( l [ k + 3 ] + f [ 3 ] ) ; g = a . saturate_ud_to_ub ( l [ k + 4 ] + f [ 4 ] ) ; var m = a . saturate_ud_to_ub ( l [ k + 5 ] + f [ 5 ] ) , n = a . saturate_ud_to_ub ( l [ k + 6 ] + f [ 6 ] ) ; f = a . saturate_ud_to_ub ( l [ k + 7 ] + f [ 7 ] ) ; a . write_mmx64s ( b | c << 8 | d << 16 | e << 24 , g | m << 8 | n << 16 | f << 24 ) ; } } ; t [ 221 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) ; b = new Uint16Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Uint16Array ( c . buffer ) ; a . write_xmm128s ( a . saturate_uw ( b [ 0 ] + c [ 0 ] ) | a . saturate_uw ( b [ 1 ] + c [ 1 ] ) << 16 , a . saturate_uw ( b [ 2 ] + c [ 2 ] ) | a . saturate_uw ( b [ 3 ] + c [ 3 ] ) << 16 , a . saturate_uw ( b [ 4 ] + c [ 4 ] ) | a . saturate_uw ( b [ 5 ] + c [ 5 ] ) << 16 , a . saturate_uw ( b [ 6 ] + c [ 6 ] ) | a . saturate_uw ( b [ 7 ] + c [ 7 ] ) << 16 ) ; } else { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; c = a . read_mmx_mem64s ( ) ; var d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , e = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = a . saturate_uw ( ( d & 65535 ) + ( c [ 0 ] & 65535 ) ) ; d = a . saturate_uw ( ( d >>> 16 ) + ( c [ 0 ] >>> 16 ) ) ; var g = a . saturate_uw ( ( e & 65535 ) + ( c [ 1 ] & 65535 ) ) ; c = a . saturate_uw ( ( e >>> 16 ) + ( c [ 1 ] >>> 16 ) ) ; a . write_mmx64s ( b | d << 16 , g | c << 16 ) ; } } ; t [ 222 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) ; b = new Uint8Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Uint8Array ( c . buffer ) ; for ( var d = a . create_atom128s ( 0 , 0 , 0 , 0 ) , e = new Uint8Array ( d . buffer ) , g = 0 ; 16 > g ; g ++ ) e [ g ] = b [ g ] > c [ g ] ? b [ g ] : c [ g ] ; a . write_xmm128s ( d [ 0 ] , d [ 1 ] , d [ 2 ] , d [ 3 ] ) ; } else dbg_assert ( ! 1 ) ; } ; t [ 223 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; a . write_mmx64s ( b [ 0 ] & ~ a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , b [ 1 ] & ~ a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ) ; } ; t [ 224 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 225 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = b [ 0 ] >>> 0 ; 15 < b && ( b = 16 ) ; a . write_mmx64s ( c << 16 >> 16 >> b & 65535 | ( c >> 16 >> b & 65535 ) << 16 , d << 16 >> 16 >> b & 65535 | ( d >> 16 >> b & 65535 ) << 16 ) ; } ; t [ 226 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = b [ 0 ] >>> 0 ; 31 < b && ( b = 31 ) ; a . write_mmx64s ( c >> b , d >> b ) ; } ; t [ 227 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 228 ] = function ( a ) { dbg_assert ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_xmm_mem128s ( ) ; b = new Uint16Array ( b . buffer ) ; var c = a . read_xmm128s ( ) ; c = new Uint16Array ( c . buffer ) ; a . write_xmm128s ( b [ 0 ] * c [ 0 ] >>> 16 | b [ 1 ] * c [ 1 ] & 4294901760 , b [ 2 ] * c [ 2 ] >>> 16 | b [ 3 ] * c [ 3 ] & 4294901760 , b [ 4 ] * c [ 4 ] >>> 16 | b [ 5 ] * c [ 5 ] & 4294901760 , b [ 6 ] * c [ 6 ] >>> 16 | b [ 7 ] * c [ 7 ] & 4294901760 ) ; } ; t [ 229 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; a . write_mmx64s ( ( c << 16 >> 16 ) * ( b [ 0 ] << 16 >> 16 ) >>> 16 | ( c >> 16 ) * ( b [ 0 ] >> 16 ) >>> 16 << 16 , ( d << 16 >> 16 ) * ( b [ 1 ] << 16 >> 16 ) >>> 16 | ( d >> 16 ) * ( b [ 1 ] >> 16 ) >>> 16 << 16 ) ; } ; t [ 230 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 231 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; 192 <= a . modrm_byte && a . trigger_ud ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm128s ( ) , c = a . modrm_resolve ( a . modrm_byte ) ; a . safe_write128 ( c , b [ 0 ] , b [ 1 ] , b [ 2 ] , b [ 3 ] ) ; } else dbg_assert ( ! 1 ) ; } ; t [ 232 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = new Int8Array ( b . buffer ) , d = 8 * ( a . modrm_byte >> 3 & 7 ) , e = a . reg_mmx8s ; b = a . saturate_sd_to_sb ( e [ d ] - c [ 0 ] ) ; var g = a . saturate_sd_to_sb ( e [ d + 1 ] - c [ 1 ] ) , f = a . saturate_sd_to_sb ( e [ d + 2 ] - c [ 2 ] ) , k = a . saturate_sd_to_sb ( e [ d + 3 ] - c [ 3 ] ) , l = a . saturate_sd_to_sb ( e [ d + 4 ] - c [ 4 ] ) , m = a . saturate_sd_to_sb ( e [ d + 5 ] - c [ 5 ] ) , n = a . saturate_sd_to_sb ( e [ d + 6 ] - c [ 6 ] ) ; c = a . saturate_sd_to_sb ( e [ d + 7 ] - c [ 7 ] ) ; a . write_mmx64s ( b | g << 8 | f << 16 | k << 24 , l | m << 8 | n << 16 | c << 24 ) ; } ; t [ 233 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] , e = a . saturate_sd_to_sw ( ( c << 16 >> 16 ) - ( b [ 0 ] << 16 >> 16 ) ) ; c = a . saturate_sd_to_sw ( ( c >> 16 ) - ( b [ 0 ] >> 16 ) ) ; var g = a . saturate_sd_to_sw ( ( d << 16 >> 16 ) - ( b [ 1 ] << 16 >> 16 ) ) ; b = a . saturate_sd_to_sw ( ( d >> 16 ) - ( b [ 1 ] >> 16 ) ) ; a . write_mmx64s ( e | c << 16 , g | b << 16 ) ; } ; t [ 234 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 235 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) === PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) , c = a . read_xmm128s ( ) ; a . write_xmm128s ( b [ 0 ] | c [ 0 ] , b [ 1 ] | c [ 1 ] , b [ 2 ] | c [ 2 ] , b [ 3 ] | c [ 3 ] ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem64s ( ) , a . write_mmx64s ( b [ 0 ] | a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , b [ 1 ] | a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ) ; } ; t [ 236 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = new Int8Array ( b . buffer ) , d = 8 * ( a . modrm_byte >> 3 & 7 ) , e = a . reg_mmx8s ; b = a . saturate_sd_to_sb ( e [ d ] + c [ 0 ] ) ; var g = a . saturate_sd_to_sb ( e [ d + 1 ] + c [ 1 ] ) , f = a . saturate_sd_to_sb ( e [ d + 2 ] + c [ 2 ] ) , k = a . saturate_sd_to_sb ( e [ d + 3 ] + c [ 3 ] ) , l = a . saturate_sd_to_sb ( e [ d + 4 ] + c [ 4 ] ) , m = a . saturate_sd_to_sb ( e [ d + 5 ] + c [ 5 ] ) , n = a . saturate_sd_to_sb ( e [ d + 6 ] + c [ 6 ] ) ; c = a . saturate_sd_to_sb ( e [ d + 7 ] + c [ 7 ] ) ; a . write_mmx64s ( b | g << 8 | f << 16 | k << 24 , l | m << 8 | n << 16 | c << 24 ) ; } ; t [ 237 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] , e = a . saturate_sd_to_sw ( ( c << 16 >> 16 ) + ( b [ 0 ] << 16 >> 16 ) ) ; c = a . saturate_sd_to_sw ( ( c >> 16 ) + ( b [ 0 ] >> 16 ) ) ; var g = a . saturate_sd_to_sw ( ( d << 16 >> 16 ) + ( b [ 1 ] << 16 >> 16 ) ) ; b = a . saturate_sd_to_sw ( ( d >> 16 ) + ( b [ 1 ] >> 16 ) ) ; a . write_mmx64s ( e | c << 16 , g | b << 16 ) ; } ; t [ 238 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 239 ] = function ( a ) { a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; if ( ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) == PREFIX_MASK_OPSIZE ) { var b = a . read_xmm_mem128s ( ) , c = a . read_xmm128s ( ) ; a . write_xmm128s ( b [ 0 ] ^ c [ 0 ] , b [ 1 ] ^ c [ 1 ] , b [ 2 ] ^ c [ 2 ] , b [ 3 ] ^ c [ 3 ] ) ; } else dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) , b = a . read_mmx_mem64s ( ) , a . write_mmx64s ( b [ 0 ] ^ a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , b [ 1 ] ^ a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ) ; } ; t [ 240 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 241 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = b [ 0 ] >>> 0 ; var e = 0 , g = 0 ; 15 >= b && ( e = ( c & 65535 ) << b & 65535 | c >>> 16 << b << 16 , g = ( d & 65535 ) << b & 65535 | d >>> 16 << b << 16 ) ; a . write_mmx64s ( e , g ) ; } ; t [ 242 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = b [ 0 ] >>> 0 ; var e = 0 , g = 0 ; 31 >= b && ( e = c << b , g = d << b ) ; a . write_mmx64s ( e , g ) ; } ; t [ 243 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; b = b [ 0 ] >>> 0 ; if ( 0 !== b ) { var e = 0 , g = 0 ; 31 >= b ? ( e = c << b , g = d << b | c >>> 32 - b ) : 63 >= b && ( g = c << ( b & 31 ) , e = 0 ) ; a . write_mmx64s ( e , g ) ; } } ; t [ 244 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 245 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; a . write_mmx64s ( ( c << 16 >> 16 ) * ( b [ 0 ] << 16 >> 16 ) + ( c >> 16 ) * ( b [ 0 ] >> 16 ) | 0 , ( d << 16 >> 16 ) * ( b [ 1 ] << 16 >> 16 ) + ( d >> 16 ) * ( b [ 1 ] >> 16 ) | 0 ) ; } ; t [ 246 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 247 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 248 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; b = new Int8Array ( b . buffer ) ; var c = 8 * ( a . modrm_byte >> 3 & 7 ) , d = a . reg_mmx8s ; a . write_mmx64s ( d [ c ] - b [ 0 ] & 255 | ( d [ c + 1 ] - b [ 1 ] & 255 ) << 8 | ( d [ c + 2 ] - b [ 2 ] & 255 ) << 16 | ( d [ c + 3 ] - b [ 3 ] & 255 ) << 24 , d [ c + 4 ] - b [ 4 ] & 255 | ( d [ c + 5 ] - b [ 5 ] & 255 ) << 8 | ( d [ c + 6 ] - b [ 6 ] & 255 ) << 16 | ( d [ c + 7 ] - b [ 7 ] & 255 ) << 24 ) ; } ; t [ 249 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; a . write_mmx64s ( c - b [ 0 ] & 65535 | ( ( c >>> 16 ) - ( b [ 0 ] >>> 16 ) & 65535 ) << 16 , d - b [ 1 ] & 65535 | ( ( d >>> 16 ) - ( b [ 1 ] >>> 16 ) & 65535 ) << 16 ) ; } ; t [ 250 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; a . write_mmx64s ( a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] - b [ 0 ] , a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] - b [ 1 ] ) ; } ; t [ 251 ] = function ( a ) { a . unimplemented_sse ( ) ; } ; t [ 252 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; b = new Int8Array ( b . buffer ) ; var c = 8 * ( a . modrm_byte >> 3 & 7 ) , d = a . reg_mmx8s ; a . write_mmx64s ( d [ c ] + b [ 0 ] & 255 | ( d [ c + 1 ] + b [ 1 ] & 255 ) << 8 | ( d [ c + 2 ] + b [ 2 ] & 255 ) << 16 | ( d [ c + 3 ] + b [ 3 ] & 255 ) << 24 , d [ c + 4 ] + b [ 4 ] & 255 | ( d [ c + 5 ] + b [ 5 ] & 255 ) << 8 | ( d [ c + 6 ] + b [ 6 ] & 255 ) << 16 | ( d [ c + 7 ] + b [ 7 ] & 255 ) << 24 ) ; } ; t [ 253 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) , c = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] , d = a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] ; a . write_mmx64s ( c + b [ 0 ] & 65535 | ( ( c >>> 16 ) + ( b [ 0 ] >>> 16 ) & 65535 ) << 16 , d + b [ 1 ] & 65535 | ( ( d >>> 16 ) + ( b [ 1 ] >>> 16 ) & 65535 ) << 16 ) ; } ; t [ 254 ] = function ( a ) { dbg_assert ( 0 == ( a . prefixes & ( PREFIX_MASK_REP | PREFIX_MASK_OPSIZE ) ) ) ; a . task_switch_test_mmx ( ) ; a . read_modrm_byte ( ) ; var b = a . read_mmx_mem64s ( ) ; a . write_mmx64s ( a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) ] + b [ 0 ] | 0 , a . reg_mmxs [ 2 * ( a . modrm_byte >> 3 & 7 ) + 1 ] + b [ 1 ] | 0 ) ; } ; t [ 255 ] = function ( a ) { dbg_log ( "#ud: 0F FF" ) ; a . trigger_ud ( ) ; } ; var table0F_16 = [ ] , table0F_32 = [ ] ; CPU . prototype . table0F_16 = table0F_16 ; CPU . prototype . table0F_32 = table0F_32 ; for ( i = 0 ; 256 > i ; i ++ ) t [ i ] ? table0F_16 [ i ] = table0F_32 [ i ] = t [ i ] : t16 [ i ] && ( table0F_16 [ i ] = t16 [ i ] , table0F_32 [ i ] = t32 [ i ] ) ; CPU . prototype . debug_init = function ( ) { function a ( ) { DEBUG && ( k . running || k . cycle ( ) , d ( ) , Date . now ( ) , k . running = ! 1 , g ( ) ) ; } function b ( a ) { var b = k . flags & flag_vm ? 1 : 0 ; b = k . protected_mode ? b ? "vm86" : "prot" : "real" ; var c = k . get_eflags ( ) , d = k . getiopl ( ) , e = k . cpl , f = h ( k . sreg [ reg_cs ] , 4 ) + ":" + h ( k . get_real_eip ( ) >>> 0 , 8 ) , g = h ( k . sreg [ reg_ss ] , 4 ) + ":" + h ( k . get_stack_reg ( ) >>> 0 , 8 ) , l = k . is_32 ? "32" : "16" , m = k . flags & flag_interrupt ? 1 : 0 , n = { } ; n = ( n [ flag_carry ] = "c" , n [ flag_parity ] = "p" , n [ flag_adjust ] = "a" , n [ flag_zero ] = "z" , n [ flag_sign ] = "s" , n [ flag_trap ] = "t" , n [ flag_interrupt ] = "i" , n [ flag_direction ] = "d" , n [ flag_overflow ] = "o" , n ) ; for ( var A = "" , x = 0 ; 16 > x ; x ++ ) n [ 1 << x ] && ( A = c & 1 << x ? A + n [ 1 << x ] : A + " " ) ; return "mode=" + b + "/" + l + " paging=" + + k . paging + " iopl=" + d + " cpl=" + e + " if=" + m + " cs:eip=" + f + " cs_off=" + h ( k . get_seg ( reg_cs ) >>> 0 , 8 ) + " flgs=" + h ( k . get_eflags ( ) >>> 0 , 6 ) + " (" + A + ") ss:esp=" + g + " ssize=" + + k . stack_size_32 + ( a ? " in " + a : "" ) ; } function c ( ) { for ( var a = { eax : reg_eax , ecx : reg_ecx , edx : reg_edx , ebx : reg_ebx , esp : reg_esp , ebp : reg_ebp , esi : reg_esi , edi : reg_edi } , b = "eax ecx edx ebx esp ebp esi edi" . split ( " " ) , c = "" , d = "" , e = 0 ; 4 > e ; e ++ ) c += b [ e ] + "=" + h ( k . reg32 [ a [ b [ e ] ] ] , 8 ) + " " , d += b [ e + 4 ] + "=" + h ( k . reg32 [ a [ b [ e + 4 ] ] ] , 8 ) + " " ; c += "  ds=" + h ( k . sreg [ reg_ds ] , 4 ) + " es=" + h ( k . sreg [ reg_es ] , 4 ) + " fs=" + h ( k . sreg [ reg_fs ] , 4 ) ; d += "  gs=" + h ( k . sreg [ reg_gs ] , 4 ) + " cs=" + h ( k . sreg [ reg_cs ] , 4 ) + " ss=" + h ( k . sreg [ reg_ss ] , 4 ) ; return [ c , d ] ; } function d ( ) { if ( DEBUG ) { var a = c ( ) ; dbg_log ( a [ 0 ] , LOG_CPU ) ; dbg_log ( a [ 1 ] , LOG_CPU ) ; } } function e ( ) { if ( DEBUG ) { l . step_mode = ! 0 ; var a , b = "" ; l . trace_all && l . all_ops ? a = l . all_ops : l . ops && ( a = l . ops . toArray ( ) ) ; if ( ! a ) return "" ; for ( var c = 0 ; c < a . length ; c += 2 ) { var d = a [ c + 1 ] ; b += h ( a [ c ] , 8 ) + ":        " + v86util . pads ( m [ d ] || "unkown" , 20 ) + h ( d , 2 ) + "\n" ; } l . ops . clear ( ) ; l . all_ops = [ ] ; return b ; } } function g ( ) { DEBUG && l . show ( e ( ) ) ; } function f ( a , b ) { if ( DEBUG ) { if ( ! ( a & 1 ) ) return ! 1 ; var c = 128 === ( a & 128 ) ; return { size : c , global : 256 === ( a & 256 ) , accessed : 32 === ( a & 32 ) , dirty : 64 === ( a & 64 ) , cache_disable : 16 === ( a & 16 ) , user : 4 === ( a & 4 ) , read_write : 2 === ( a & 2 ) , address : ( c && ! b ? a & 4290772992 : a & 4294963200 ) >>> 0 } ; } } var k = this , l = { } ; this . debug = l ; l . step_mode = ! 1 ; l . ops = void 0 ; l . all_ops = [ ] ; l . trace_all = ! 1 ; l . show = function ( a ) { if ( "undefined" !== typeof document ) { var b = document . getElementById ( "log" ) ; if ( b ) { b . textContent += a + "\n" ; b . style . display = "block" ; b . scrollTop = 1E9 ; return ; } } console . log ( a ) ; } ; l . init = function ( ) { function a ( a ) { 10 === a ? ( dbg_log ( b , LOG_BIOS ) , b = "" ) : b += String . fromCharCode ( a ) ; } if ( DEBUG && ( l . ops = new CircularQueue ( 2E5 ) , k . io ) ) { var b = "" ; k . io . register_write ( 1026 , this , a ) ; k . io . register_write ( 1280 , this , a ) ; } } ; l . get_regs_short = c ; l . dump_regs = d ; l . dump_instructions = g ; l . get_instructions = e ; l . get_state = b ; l . dump_state = function ( a ) { DEBUG && dbg_log ( b ( a ) , LOG_CPU ) ; } ; l . dump_stack = function ( a , b ) { if ( DEBUG ) { var c = k . reg32 [ reg_esp ] ; dbg_log ( "========= STACK ==========" ) ; if ( b >= a || void 0 === b ) a = 5 , b = - 5 ; for ( ; a > b ; a -- ) { var d = "    " ; a || ( d = "=>  " ) ; d += h ( a , 2 ) + " | " ; dbg_log ( d + h ( c + 4 * a , 8 ) + " | " + h ( k . read32s ( c + 4 * a ) >>> 0 ) ) ; } } } ; l . dump_page_directory = function ( ) { if ( DEBUG ) for ( var a = 0 ; 1024 > a ; a ++ ) { var b = k . read32s ( k . cr [ 3 ] + 4 * a ) , c = f ( b , ! 0 ) ; if ( c ) if ( b = "" , b += c . size ? "S " : "  " , b += c . accessed ? "A " : "  " , b += c . cache_disable ? "Cd " : "  " , b += c . user ? "U " : "  " , b += c . read_write ? "Rw " : "   " , c . size ) dbg_log ( "=== " + h ( a << 22 >>> 0 , 8 ) + " -> " + h ( c . address >>> 0 , 8 ) + " | " + b ) ; else { dbg_log ( "=== " + h ( a << 22 >>> 0 , 8 ) + " | " + b ) ; for ( var d = 0 ; 1024 > d ; d ++ ) { var e = c . address + 4 * d ; b = k . read32s ( e ) ; var g = f ( b , ! 1 ) ; g && ( b = "" , b += g . cache_disable ? "Cd " : "   " , b += g . user ? "U " : "  " , b += g . read_write ? "Rw " : "   " , b += g . global ? "G " : "  " , b += g . accessed ? "A " : "  " , b += g . dirty ? "Di " : "   " , dbg_log ( "# " + h ( ( a << 22 | d << 12 ) >>> 0 , 8 ) + " -> " + h ( g . address , 8 ) + " | " + b + "        (at " + h ( e , 8 ) + ")" ) ) ; } } } } ; l . dump_gdt_ldt = function ( ) { function a ( a , b ) { for ( var c = 0 ; c < b ; c += 8 , a += 8 ) { var d = k . read16 ( a + 2 ) | k . read8 ( a + 4 ) << 16 | k . read8 ( a + 7 ) << 24 , e = k . read16 ( a ) | ( k . read8 ( a + 6 ) & 15 ) << 16 , f = k . read8 ( a + 5 ) , g = k . read8 ( a + 6 ) >> 4 , l = "" , m = f >> 5 & 3 ; l = f & 128 ? l + " P " : l + "NP " ; f & 16 ? ( l = g & 4 ? l + "32b " : l + "16b " , f & 8 ? ( l += "X " , f & 4 && ( l += "C " ) ) : l += "R " , l += "RW " ) : l += "sys: " + h ( f & 15 ) ; g & 8 && ( e = e << 12 | 4095 ) ; dbg_log ( h ( c & - 8 , 4 ) + " " + h ( d >>> 0 , 8 ) + " (" + h ( e >>> 0 , 8 ) + " bytes) " + l + ";  dpl = " + m + ", a = " + f . toString ( 2 ) + ", f = " + g . toString ( 2 ) ) ; } } DEBUG && ( dbg_log ( "gdt: (len = " + h ( k . gdtr_size ) + ")" ) , a ( k . translate_address_system_read ( k . gdtr_offset ) , k . gdtr_size ) , dbg_log ( "\nldt: (len = " + h ( k . segment_limits [ reg_ldtr ] ) + ")" ) , a ( k . translate_address_system_read ( k . segment_offsets [ reg_ldtr ] ) , k . segment_limits [ reg_ldtr ] ) ) ; } ; l . dump_idt = function ( ) { if ( DEBUG ) for ( var a = 0 ; a < k . idtr_size ; a += 8 ) { var b = k . translate_address_system_read ( k . idtr_offset + a ) , c = k . read16 ( b ) | k . read16 ( b + 6 ) << 16 , d = k . read16 ( b + 2 ) ; b = k . read8 ( b + 5 ) ; var e = b >> 5 & 3 ; var f = 5 === ( b & 31 ) ? "task gate " : 14 === ( b & 31 ) ? "intr gate " : 15 === ( b & 31 ) ? "trap gate " : "invalid   " ; f = b & 128 ? f + " P" : f + "NP" ; dbg_log ( h ( a >> 3 , 4 ) + " " + h ( c >>> 0 , 8 ) + ", " + h ( d , 4 ) + "; " + f + ";  dpl = " + e + ", t = " + b . toString ( 2 ) ) ; } } ; l . get_memory_dump = function ( a , b ) { if ( DEBUG ) return void 0 === a ? ( a = 0 , b = k . memory_size ) : void 0 === b && ( b = a , a = 0 ) , k . mem8 . slice ( a , a + b ) . buffer ; } ; l . memory_hex_dump = function ( a , b ) { if ( DEBUG ) { b = b || 64 ; for ( var c , d , e = 0 ; e < b >> 4 ; e ++ ) { c = h ( a + ( e << 4 ) , 5 ) + "   " ; for ( var f = 0 ; 16 > f ; f ++ ) d = k . read8 ( a + ( e << 4 ) + f ) , c += h ( d , 2 ) + " " ; c += "  " ; for ( f = 0 ; 16 > f ; f ++ ) d = k . read8 ( a + ( e << 4 ) + f ) , c += 33 > d || 126 < d ? "." : String . fromCharCode ( d ) ; dbg_log ( c ) ; } } } ; l . used_memory_dump = function ( ) { if ( DEBUG ) for ( var a = k . memory_size / 128 / 16 | 0 , b , c = 0 ; 16 > c ; c ++ ) { b = h ( 128 * c * a , 8 ) + " | " ; for ( var d = 0 ; 128 > d ; d ++ ) b += 0 < k . mem32s [ ( 128 * c + d ) * a ] ? "X" : " " ; dbg_log ( b ) ; } } ; l . step = a ; l . run_until = function ( ) { if ( DEBUG ) { k . running = ! 1 ; var b = parseInt ( prompt ( "input hex" , "" ) , 16 ) ; if ( b ) for ( ; k . instruction_pointer != b ; ) a ( ) ; } } ; l . unimpl = function ( a ) { a = "Unimplemented" + ( a ? ": " + a : "" ) ; l . show ( a ) ; DEBUG ? console . trace ( ) : l . show ( "Execution stopped" ) ; return a ; } ; var m = "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" . split ( " " ) ; l . logop = function ( a , b ) { DEBUG && l . step_mode && ( l . trace_all && l . all_ops ? l . all_ops . push ( a , b ) : l . ops && ( l . ops . add ( a ) , l . ops . add ( b ) ) ) ; } ; l . debug_interrupt = function ( a ) { } ; } ; var ELF_MAGIC = 1179403647 , types = DataView . prototype , U8 = { size : 1 , get : types . getUint8 , set : types . setUint8 } , U16 = { size : 2 , get : types . getUint16 , set : types . setUint16 } , U32 = { size : 4 , get : types . getUint32 , set : types . setUint32 } , pad = function ( a ) { return { size : a , get : function ( a ) { return - 1 ; } } ; } , Header = create_struct ( [ { magic : U32 } , { class : U8 } , { data : U8 } , { version0 : U8 } , { osabi : U8 } , { abiversion : U8 } , { pad0 : pad ( 7 ) } , { type : U16 } , { machine : U16 } , { version1 : U32 } , { entry : U32 } , { phoff : U32 } , { shoff : U32 } , { flags : U32 } , { ehsize : U16 } , { phentsize : U16 } , { phnum : U16 } , { shentsize : U16 } , { shnum : U16 } , { shstrndx : U16 } ] ) ; console . assert ( 52 === Header . reduce ( function ( a , b ) { return a + b . size ; } , 0 ) ) ; var ProgramHeader = create_struct ( [ { type : U32 } , { offset : U32 } , { vaddr : U32 } , { paddr : U32 } , { filesz : U32 } , { memsz : U32 } , { flags : U32 } , { align : U32 } ] ) ; console . assert ( 32 === ProgramHeader . reduce ( function ( a , b ) { return a + b . size ; } , 0 ) ) ; var SectionHeader = create_struct ( [ { name : U32 } , { type : U32 } , { flags : U32 } , { addr : U32 } , { offset : U32 } , { size : U32 } , { link : U32 } , { info : U32 } , { addralign : U32 } , { entsize : U32 } ] ) ; console . assert ( 40 === SectionHeader . reduce ( function ( a , b ) { return a + b . size ; } , 0 ) ) ; function create_struct ( a ) { return a . map ( function ( a ) { var b = Object . keys ( a ) ; console . assert ( 1 === b . length ) ; b = b [ 0 ] ; a = a [ b ] ; console . assert ( 0 < a . size ) ; return { name : b , type : a , size : a . size , get : a . get , set : a . set } ; } ) ; } function read_elf ( a ) { var b = new DataView ( a ) , c = $jscomp . makeIterator ( read_struct ( b , Header ) ) ; a = c . next ( ) . value ; c = c . next ( ) . value ; console . assert ( 52 === c ) ; if ( DEBUG ) { for ( var d in a ) console . log ( d + ": 0x" + a [ d ] . toString ( 16 ) ) ; console . log ( a ) ; } console . assert ( a . magic === ELF_MAGIC , "Bad magic" ) ; console . assert ( 1 === a . class , "Unimplemented: 64 bit elf" ) ; console . assert ( 1 === a . data , "Unimplemented: big endian" ) ; console . assert ( 1 === a . version0 , "Bad version0" ) ; console . assert ( 2 === a . type , "Unimplemented type" ) ; console . assert ( 1 === a . version1 , "Bad version1" ) ; console . assert ( 52 === a . ehsize , "Bad header size" ) ; console . assert ( 32 === a . phentsize , "Bad program header size" ) ; console . assert ( 40 === a . shentsize , "Bad section header size" ) ; c = $jscomp . makeIterator ( read_structs ( view_slice ( b , a . phoff , a . phentsize * a . phnum ) , ProgramHeader , a . phnum ) ) ; d = c . next ( ) . value ; c . next ( ) ; c = $jscomp . makeIterator ( read_structs ( view_slice ( b , a . shoff , a . shentsize * a . shnum ) , SectionHeader , a . shnum ) ) ; b = c . next ( ) . value ; c . next ( ) ; if ( DEBUG ) { console . log ( "%d program headers:" , d . length ) ; c = $jscomp . makeIterator ( d ) ; for ( var e = c . next ( ) ; ! e . done ; e = c . next ( ) ) e = e . value , console . log ( "type=%s offset=%s vaddr=%s paddr=%s filesz=%s memsz=%s flags=%s align=%s" , e . type . toString ( 16 ) , e . offset . toString ( 16 ) , e . vaddr . toString ( 16 ) , e . paddr . toString ( 16 ) , e . filesz . toString ( 16 ) , e . memsz . toString ( 16 ) , e . flags . toString ( 16 ) , e . align . toString ( 16 ) ) ; console . log ( "%d program headers:" , b . length ) ; c = $jscomp . makeIterator ( b ) ; for ( e = c . next ( ) ; ! e . done ; e = c . next ( ) ) e = e . value , console . log ( "name=%s type=%s flags=%s addr=%s offset=%s size=%s link=%s info=%s addralign=%s entsize=%s" , e . name . toString ( 16 ) , e . type . toString ( 16 ) , e . flags . toString ( 16 ) , e . addr . toString ( 16 ) , e . offset . toString ( 16 ) , e . size . toString ( 16 ) , e . link . toString ( 16 ) , e . info . toString ( 16 ) , e . addralign . toString ( 16 ) , e . entsize . toString ( 16 ) ) ; } return { header : a , program_headers : d , sections_headers : b } ; } function read_struct ( a , b ) { var c = { } , d = 0 ; b = $jscomp . makeIterator ( b ) ; for ( var e = b . next ( ) ; ! e . done ; e = b . next ( ) ) { e = e . value ; var g = e . get . call ( a , d , ! 0 ) ; console . assert ( void 0 === c [ e . name ] ) ; c [ e . name ] = g ; d += e . size ; } return [ c , d ] ; } function read_structs ( a , b , c ) { for ( var d = [ ] , e = 0 , g = 0 ; g < c ; g ++ ) { var f = $jscomp . makeIterator ( read_struct ( view_slice ( a , e ) , b ) ) , k = f . next ( ) . value ; f = f . next ( ) . value ; d . push ( k ) ; e += f ; } return [ d , e ] ; } function view_slice ( a , b , c ) { return new DataView ( a . buffer , a . byteOffset + b , c ) ; } ; var SHIFT_SCAN_CODE = 42 , SCAN_CODE_RELEASE = 128 ; function KeyboardAdapter ( a ) { function b ( a ) { ! a . altKey && k [ 56 ] && g ( 56 , ! 1 ) ; return e ( a , ! 1 ) ; } function c ( a ) { ! a . altKey && k [ 56 ] && g ( 56 , ! 1 ) ; return e ( a , ! 0 ) ; } function d ( a ) { a = Object . keys ( k ) ; for ( var b , c = 0 ; c < a . length ; c ++ ) b = + a [ c ] , k [ b ] && g ( b , ! 1 ) ; k = { } ; } function e ( a , b ) { if ( l . bus && ( a . shiftKey && a . ctrlKey && ( 74 === a . keyCode || 75 === a . keyCode ) || ! l . emu_enabled ? 0 : a . target ? "phone_keyboard" === a . target . className || "INPUT" !== a . target . nodeName && "TEXTAREA" !== a . target . nodeName : 1 ) ) { a : { if ( void 0 !== a . code ) { var c = q [ a . code ] ; if ( void 0 !== c ) break a ; } c = m [ a . keyCode ] ; } if ( c ) return g ( c , b ) , a . preventDefault && a . preventDefault ( ) , ! 1 ; console . log ( "Missing char in map: " + a . keyCode . toString ( 16 ) ) ; } } function g ( a , b ) { if ( b ) k [ a ] && g ( a , ! 1 ) ; else if ( ! k [ a ] ) return ; ( k [ a ] = b ) || ( a |= 128 ) ; 255 < a ? ( f ( a >> 8 ) , f ( a & 255 ) ) : f ( a ) ; } function f ( a ) { l . bus . send ( "keyboard-code" , a ) ; } var k = { } , l = this ; this . emu_enabled = ! 0 ; var m = 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 , 57423 , 57415 , 57419 , 57416 , 57421 , 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 , 57435 , 57436 , 57437 , 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 , 69 , 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 , 57435 , 57400 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ) , n = { 10 : 13 , 32 : 32 , 39 : 222 , 44 : 188 , 45 : 189 , 46 : 190 , 47 : 191 , 48 : 48 , 49 : 49 , 50 : 50 , 51 : 51 , 52 : 52 , 53 : 53 , 54 : 54 , 55 : 55 , 56 : 56 , 57 : 57 , 59 : 186 , 61 : 187 , 91 : 219 , 92 : 220 , 93 : 221 , 96 : 192 , 97 : 65 , 98 : 66 , 99 : 67 , 100 : 68 , 101 : 69 , 102 : 70 , 103 : 71 , 104 : 72 , 105 : 73 , 106 : 74 , 107 : 75 , 108 : 76 , 109 : 77 , 110 : 78 , 111 : 79 , 112 : 80 , 113 : 81 , 114 : 82 , 115 : 83 , 116 : 84 , 117 : 85 , 118 : 86 , 119 : 87 , 120 : 88 , 121 : 89 , 122 : 90 } , p = { 33 : 49 , 34 : 222 , 35 : 51 , 36 : 52 , 37 : 53 , 38 : 55 , 40 : 57 , 41 : 48 , 42 : 56 , 43 : 187 , 58 : 186 , 60 : 188 , 62 : 190 , 63 : 191 , 64 : 50 , 65 : 65 , 66 : 66 , 67 : 67 , 68 : 68 , 69 : 69 , 70 : 70 , 71 : 71 , 72 : 72 , 73 : 73 , 74 : 74 , 75 : 75 , 76 : 76 , 77 : 77 , 78 : 78 , 79 : 79 , 80 : 80 , 81 : 81 , 82 : 82 , 83 : 83 , 84 : 84 , 85 : 85 , 86 : 86 , 87 : 87 , 88 : 88 , 89 : 89 , 90 : 90 , 94 : 54 , 95 : 189 , 123 : 219 , 124 : 220 , 125 : 221 , 126 : 192 } , q = { Escape : 1 , Digit1 : 2 , Digit2 : 3 , Digit3 : 4 , Digit4 : 5 , Digit5 : 6 , Digit6 : 7 , Digit7 : 8 , Digit8 : 9 , Digit9 : 10 , Digit0 : 11 , Minus : 12 , Equal : 13 , Backspace : 14 , Tab : 15 , KeyQ : 16 , KeyW : 17 , KeyE : 18 , KeyR : 19 , KeyT : 20 , KeyY : 21 , KeyU : 22 , KeyI : 23 , KeyO : 24 , KeyP : 25 , BracketLeft : 26 , BracketRight : 27 , Enter : 28 , ControlLeft : 29 , KeyA : 30 , KeyS : 31 , KeyD : 32 , KeyF : 33 , KeyG : 34 , KeyH : 35 , KeyJ : 36 , KeyK : 37 , KeyL : 38 , Semicolon : 39 , Quote : 40 , Backquote : 41 , ShiftLeft : 42 , Backslash : 43 , KeyZ : 44 , KeyX : 45 , KeyC : 46 , KeyV : 47 , KeyB : 48 , KeyN : 49 , KeyM : 50 , Comma : 51 , Period : 52 , Slash : 53 , ShiftRight : 54 , NumpadMultiply : 55 , AltLeft : 56 , Space : 57 , CapsLock : 58 , F1 : 59 , F2 : 60 , F3 : 61 , F4 : 62 , F5 : 63 , F6 : 64 , F7 : 65 , F8 : 66 , F9 : 67 , F10 : 68 , NumLock : 69 , ScrollLock : 70 , Numpad7 : 71 , Numpad8 : 72 , Numpad9 : 73 , NumpadSubtract : 74 , Numpad4 : 75 , Numpad5 : 76 , Numpad6 : 77 , NumpadAdd : 78 , Numpad1 : 79 , Numpad2 : 80 , Numpad3 : 81 , Numpad0 : 82 , NumpadDecimal : 83 , IntlBackslash : 86 , F11 : 87 , F12 : 88 , NumpadEnter : 57372 , ControlRight : 57373 , NumpadDivide : 57397 , AltRight : 57400 , Home : 57423 , ArrowUp : 57416 , PageUp : 57417 , ArrowLeft : 57419 , ArrowRight : 57421 , End : 57423 , ArrowDown : 57424 , PageDown : 57425 , Insert : 57426 , Delete : 57427 , OSLeft : 57435 , OSRight : 57436 , ContextMenu : 57437 } ; this . bus = a ; this . destroy = function ( ) { "undefined" !== typeof window && ( window . removeEventListener ( "keyup" , b , ! 1 ) , window . removeEventListener ( "keydown" , c , ! 1 ) , window . removeEventListener ( "blur" , d , ! 1 ) ) ; } ; this . init = function ( ) { "undefined" !== typeof window && ( this . destroy ( ) , window . addEventListener ( "keyup" , b , ! 1 ) , window . addEventListener ( "keydown" , c , ! 1 ) , window . addEventListener ( "blur" , d , ! 1 ) ) ; } ; this . init ( ) ; this . simulate_press = function ( a ) { a = { keyCode : a } ; e ( a , ! 0 ) ; e ( a , ! 1 ) ; } ; this . simulate_char = function ( a ) { var b = a . charCodeAt ( 0 ) ; b in n ? this . simulate_press ( n [ b ] ) : b in p ? ( f ( SHIFT_SCAN_CODE ) , this . simulate_press ( p [ b ] ) , f ( SHIFT_SCAN_CODE | SCAN_CODE_RELEASE ) ) : console . log ( "ascii -> keyCode not found: " , b , a ) ; } ; } ; function MouseAdapter ( a , b ) { function c ( a ) { if ( ! u . enabled || ! u . emu_enabled ) return ! 1 ; if ( "mousemove" === a . type || "touchmove" === a . type ) return ! 0 ; if ( "mousewheel" === a . type || "DOMMouseScroll" === a . type ) { var c = b || document . body ; a : { for ( a = a . target ; a . parentNode ; ) { if ( a === c ) { c = ! 0 ; break a ; } a = a . parentNode ; } c = ! 1 ; } return c ; } return ! a . target || "INPUT" !== a . target . nodeName && "TEXTAREA" !== a . target . nodeName ; } function d ( a ) { c ( a ) && ( a = a . changedTouches ) && a . length && ( a = a [ a . length - 1 ] , r = a . clientX , v = a . clientY ) ; } function e ( a ) { if ( n || q || p ) u . bus . send ( "mouse-click" , [ ! 1 , ! 1 , ! 1 ] ) , n = q = p = ! 1 ; } function g ( a ) { if ( u . bus && c ( a ) ) { var d = 0 , e = 0 , f = a . changedTouches ; f ? f . length && ( f = f [ f . length - 1 ] , d = f . clientX - r , e = f . clientY - v , r = f . clientX , v = f . clientY , a . preventDefault ( ) ) : "number" === typeof a . movementX ? ( d = a . movementX , e = a . movementY ) : "number" === typeof a . webkitMovementX ? ( d = a . webkitMovementX , e = a . webkitMovementY ) : "number" === typeof a . mozMovementX ? ( d = a . mozMovementX , e = a . mozMovementY ) : ( d = a . clientX - r , e = a . clientY - v , r = a . clientX , v = a . clientY ) ; u . bus . send ( "mouse-delta" , [ .15 * d , - ( .15 * e ) ] ) ; u . bus . send ( "mouse-absolute" , [ a . pageX - b . offsetLeft , a . pageY - b . offsetTop , b . offsetWidth , b . offsetHeight ] ) ; } } function f ( a ) { c ( a ) && l ( a , ! 0 ) ; } function k ( a ) { c ( a ) && l ( a , ! 1 ) ; } function l ( a , b ) { u . bus && ( 1 === a . which ? n = b : 2 === a . which ? q = b : 3 === a . which ? p = b : console . log ( "Unknown event.which: " + a . which ) , u . bus . send ( "mouse-click" , [ n , q , p ] ) ) ; } function m ( a ) { if ( c ( a ) ) { var b = a . wheelDelta || - a . detail ; 0 > b ? b = - 1 : 0 < b && ( b = 1 ) ; u . bus . send ( "mouse-wheel" , [ b , 0 ] ) ; a . preventDefault ( ) ; } } var n = ! 1 , p = ! 1 , q = ! 1 , r = 0 , v = 0 , u = this ; this . enabled = ! 1 ; this . emu_enabled = ! 0 ; this . bus = a ; this . bus . register ( "mouse-enable" , function ( a ) { this . enabled = a ; } , this ) ; this . destroy = function ( ) { window . removeEventListener ( "touchstart" , d , ! 1 ) ; window . removeEventListener ( "touchend" , e , ! 1 ) ; window . removeEventListener ( "touchmove" , g , ! 1 ) ; window . removeEventListener ( "mousemove" , g , ! 1 ) ; window . removeEventListener ( "mousedown" , f , ! 1 ) ; window . removeEventListener ( "mouseup" , k , ! 1 ) ; window . removeEventListener ( "DOMMouseScroll" , m , ! 1 ) ; window . removeEventListener ( "mousewheel" , m , ! 1 ) ; } ; this . init = function ( ) { "undefined" !== typeof window && ( this . destroy ( ) , window . addEventListener ( "touchstart" , d , ! 1 ) , window . addEventListener ( "touchend" , e , ! 1 ) , window . addEventListener ( "touchmove" , g , ! 1 ) , window . addEventListener ( "mousemove" , g , ! 1 ) , window . addEventListener ( "mousedown" , f , ! 1 ) , window . addEventListener ( "mouseup" , k , ! 1 ) , window . addEventListener ( "DOMMouseScroll" , m , ! 1 ) , window . addEventListener ( "mousewheel" , m , ! 1 ) ) ; } ; this . init ( ) ; } ; var DAC_QUEUE_RESERVE = .2 , AUDIOBUFFER_MINIMUM_SAMPLING_RATE = 8E3 ; function SpeakerAdapter ( a ) { if ( "undefined" !== typeof window ) if ( window . AudioContext || window . webkitAudioContext ) { var b = window . AudioWorklet ? SpeakerWorkletDAC : SpeakerBufferSourceDAC ; this . bus = a ; this . audio_context = new ( window . AudioContext || window . webkitAudioContext ) ; this . mixer = new SpeakerMixer ( a , this . audio_context ) ; this . pcspeaker = new PCSpeaker ( a , this . audio_context , this . mixer ) ; this . dac = new b ( a , this . audio_context , this . mixer ) ; this . pcspeaker . start ( ) ; a . register ( "emulator-stopped" , function ( ) { this . audio_context . suspend ( ) ; } , this ) ; a . register ( "emulator-started" , function ( ) { this . audio_context . resume ( ) ; } , this ) ; a . register ( "speaker-confirm-initialized" , function ( ) { a . send ( "speaker-has-initialized" ) ; } , this ) ; a . send ( "speaker-has-initialized" ) ; } else console . warn ( "Web browser doesn't support Web Audio API" ) ; } function SpeakerMixer ( a , b ) { function c ( a ) { return function ( b ) { a . gain . setValueAtTime ( b , this . audio_context . currentTime ) ; } ; } this . audio_context = b ; this . sources = new Map ; this . gain_right = this . gain_left = this . volume_right = this . volume_left = this . volume_both = 1 ; this . node_treble_left = this . audio_context . createBiquadFilter ( ) ; this . node_treble_right = this . audio_context . createBiquadFilter ( ) ; this . node_treble_left . type = "highshelf" ; this . node_treble_right . type = "highshelf" ; this . node_treble_left . frequency . setValueAtTime ( 2E3 , this . audio_context . currentTime ) ; this . node_treble_right . frequency . setValueAtTime ( 2E3 , this . audio_context . currentTime ) ; this . node_bass_left = this . audio_context . createBiquadFilter ( ) ; this . node_bass_right = this . audio_context . createBiquadFilter ( ) ; this . node_bass_left . type = "lowshelf" ; this . node_bass_right . type = "lowshelf" ; this . node_bass_left . frequency . setValueAtTime ( 200 , this . audio_context . currentTime ) ; this . node_bass_right . frequency . setValueAtTime ( 200 , this . audio_context . currentTime ) ; this . node_gain_left = this . audio_context . createGain ( ) ; this . node_gain_right = this . audio_context . createGain ( ) ; this . node_merger = this . audio_context . createChannelMerger ( 2 ) ; this . input_left = this . node_treble_left ; this . input_right = this . node_treble_right ; this . node_treble_left . connect ( this . node_bass_left ) ; this . node_bass_left . connect ( this . node_gain_left ) ; this . node_gain_left . connect ( this . node_merger , 0 , 0 ) ; this . node_treble_right . connect ( this . node_bass_right ) ; this . node_bass_right . connect ( this . node_gain_right ) ; this . node_gain_right . connect ( this . node_merger , 0 , 1 ) ; this . node_merger . connect ( this . audio_context . destination ) ; a . register ( "mixer-connect" , function ( a ) { this . connect_source ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; a . register ( "mixer-disconnect" , function ( a ) { this . disconnect_source ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; a . register ( "mixer-volume" , function ( a ) { var b = a [ 0 ] , c = a [ 1 ] ; a = Math . pow ( 10 , a [ 2 ] / 20 ) ; var d = b === MIXER_SRC_MASTER ? this : this . sources . get ( b ) ; void 0 === d ? dbg_assert ( ! 1 , "Mixer set volume - cannot set volume for undefined source: " + b ) : d . set_volume ( a , c ) ; } , this ) ; a . register ( "mixer-gain-left" , function ( a ) { this . gain_left = Math . pow ( 10 , a / 20 ) ; this . update ( ) ; } , this ) ; a . register ( "mixer-gain-right" , function ( a ) { this . gain_right = Math . pow ( 10 , a / 20 ) ; this . update ( ) ; } , this ) ; a . register ( "mixer-treble-left" , c ( this . node_treble_left ) , this ) ; a . register ( "mixer-treble-right" , c ( this . node_treble_right ) , this ) ; a . register ( "mixer-bass-left" , c ( this . node_bass_left ) , this ) ; a . register ( "mixer-bass-right" , c ( this . node_bass_right ) , this ) ; } SpeakerMixer . prototype . add_source = function ( a , b ) { a = new SpeakerMixerSource ( this . audio_context , a , this . input_left , this . input_right ) ; dbg_assert ( ! this . sources . has ( b ) , "Mixer add source - overwritting source: " + b ) ; this . sources . set ( b , a ) ; return a ; } ; SpeakerMixer . prototype . connect_source = function ( a , b ) { var c = this . sources . get ( a ) ; void 0 === c ? dbg_assert ( ! 1 , "Mixer connect - cannot connect undefined source: " + a ) : c . connect ( b ) ; } ; SpeakerMixer . prototype . disconnect_source = function ( a , b ) { var c = this . sources . get ( a ) ; void 0 === c ? dbg_assert ( ! 1 , "Mixer disconnect - cannot disconnect undefined source: " + a ) : c . disconnect ( b ) ; } ; SpeakerMixer . prototype . set_volume = function ( a , b ) { void 0 === b && ( b = MIXER_CHANNEL_BOTH ) ; switch ( b ) { case MIXER_CHANNEL_LEFT : this . volume_left = a ; break ; case MIXER_CHANNEL_RIGHT : this . volume_right = a ; break ; case MIXER_CHANNEL_BOTH : this . volume_both = a ; break ; default : dbg_assert ( ! 1 , "Mixer set master volume - unknown channel: " + b ) ; return ; } this . update ( ) ; } ; SpeakerMixer . prototype . update = function ( ) { var a = this . volume_both * this . volume_right * this . gain_right ; this . node_gain_left . gain . setValueAtTime ( this . volume_both * this . volume_left * this . gain_left , this . audio_context . currentTime ) ; this . node_gain_right . gain . setValueAtTime ( a , this . audio_context . currentTime ) ; } ; function SpeakerMixerSource ( a , b , c , d ) { this . audio_context = a ; this . connected_right = this . connected_left = ! 0 ; this . volume_right = this . volume_left = this . volume_both = this . gain_hidden = 1 ; this . node_splitter = a . createChannelSplitter ( 2 ) ; this . node_gain_left = a . createGain ( ) ; this . node_gain_right = a . createGain ( ) ; b . connect ( this . node_splitter ) ; this . node_splitter . connect ( this . node_gain_left , 0 ) ; this . node_gain_left . connect ( c ) ; this . node_splitter . connect ( this . node_gain_right , 1 ) ; this . node_gain_right . connect ( d ) ; } SpeakerMixerSource . prototype . update = function ( ) { var a = this . connected_right * this . gain_hidden * this . volume_both * this . volume_right ; this . node_gain_left . gain . setValueAtTime ( this . connected_left * this . gain_hidden * this . volume_both * this . volume_left , this . audio_context . currentTime ) ; this . node_gain_right . gain . setValueAtTime ( a , this . audio_context . currentTime ) ; } ; SpeakerMixerSource . prototype . connect = function ( a ) { var b = ! a || a === MIXER_CHANNEL_BOTH ; if ( b || a === MIXER_CHANNEL_LEFT ) this . connected_left = ! 0 ; if ( b || a === MIXER_CHANNEL_RIGHT ) this . connected_right = ! 0 ; this . update ( ) ; } ; SpeakerMixerSource . prototype . disconnect = function ( a ) { var b = ! a || a === MIXER_CHANNEL_BOTH ; if ( b || a === MIXER_CHANNEL_LEFT ) this . connected_left = ! 1 ; if ( b || a === MIXER_CHANNEL_RIGHT ) this . connected_right = ! 1 ; this . update ( ) ; } ; SpeakerMixerSource . prototype . set_volume = function ( a , b ) { void 0 === b && ( b = MIXER_CHANNEL_BOTH ) ; switch ( b ) { case MIXER_CHANNEL_LEFT : this . volume_left = a ; break ; case MIXER_CHANNEL_RIGHT : this . volume_right = a ; break ; case MIXER_CHANNEL_BOTH : this . volume_both = a ; break ; default : dbg_assert ( ! 1 , "Mixer set volume - unknown channel: " + b ) ; return ; } this . update ( ) ; } ; SpeakerMixerSource . prototype . set_gain_hidden = function ( a ) { this . gain_hidden = a ; } ; function PCSpeaker ( a , b , c ) { this . node_oscillator = b . createOscillator ( ) ; this . node_oscillator . type = "square" ; this . node_oscillator . frequency . setValueAtTime ( 440 , b . currentTime ) ; this . mixer_connection = c . add_source ( this . node_oscillator , MIXER_SRC_PCSPEAKER ) ; this . mixer_connection . disconnect ( ) ; a . register ( "pcspeaker-enable" , function ( ) { c . connect_source ( MIXER_SRC_PCSPEAKER ) ; } , this ) ; a . register ( "pcspeaker-disable" , function ( ) { c . disconnect_source ( MIXER_SRC_PCSPEAKER ) ; } , this ) ; a . register ( "pcspeaker-update" , function ( a ) { var c = a [ 1 ] , d = 0 ; 3 === a [ 0 ] && ( d = 1E3 * OSCILLATOR_FREQ / c , d = Math . min ( d , this . node_oscillator . frequency . maxValue ) , d = Math . max ( d , 0 ) ) ; this . node_oscillator . frequency . setValueAtTime ( d , b . currentTime ) ; } , this ) ; } PCSpeaker . prototype . start = function ( ) { this . node_oscillator . start ( ) ; } ; function SpeakerWorkletDAC ( a , b , c ) { var d = this ; this . bus = a ; this . audio_context = b ; this . enabled = ! 1 ; this . sampling_rate = 48E3 ; b = function ( ) { function a ( a ) { if ( 0 === a ) return 1 ; a *= Math . PI ; return Math . sin ( a ) / a ; } function b ( ) { var a = Reflect . construct ( AudioWorkletProcessor , [ ] , b ) ; a . kernel_size = 3 ; a . queue_data = Array ( 1024 ) ; a . queue_start = 0 ; a . queue_end = 0 ; a . queue_length = 0 ; a . queue_size = a . queue_data . length ; a . queued_samples = 0 ; a . source_buffer_previous = c ; a . source_buffer_current = c ; a . source_samples_per_destination = 1 ; a . source_block_start = 0 ; a . source_time = 0 ; a . source_offset = 0 ; a . port . onmessage = function ( b ) { switch ( b . data . type ) { case "queue" : a . queue_push ( b . data . value ) ; break ; case "sampling-rate" : a . source_samples_per_destination = b . data . value / sampleRate ; } } ; return a ; } var c = [ new Float32Array ( 256 ) , new Float32Array ( 256 ) ] ; Reflect . setPrototypeOf ( b . prototype , AudioWorkletProcessor . prototype ) ; Reflect . setPrototypeOf ( b , AudioWorkletProcessor ) ; b . prototype . process = b . prototype . process = function ( a , b , c ) { for ( a = 0 ; a < b [ 0 ] [ 0 ] . length ; a ++ ) { for ( var d = c = 0 , e = this . source_offset + this . kernel_size , f = this . source_offset - this . kernel_size + 1 ; f <= e ; f ++ ) { var g = this . source_block_start + f ; c += this . get_sample ( g , 0 ) * this . kernel ( this . source_time - f ) ; d += this . get_sample ( g , 1 ) * this . kernel ( this . source_time - f ) ; } if ( isNaN ( c ) || isNaN ( d ) ) c = d = 0 , this . dbg_log ( "ERROR: NaN values! Ignoring for now." ) ; b [ 0 ] [ 0 ] [ a ] = c ; b [ 0 ] [ 1 ] [ a ] = d ; this . source_time += this . source_samples_per_destination ; this . source_offset = Math . floor ( this . source_time ) ; } b = this . source_offset ; b += this . kernel_size + 2 ; this . source_time -= this . source_offset ; this . source_block_start += this . source_offset ; this . source_offset = 0 ; this . ensure_enough_data ( b ) ; return ! 0 ; } ; b . prototype . kernel = function ( b ) { return a ( b ) * a ( b / this . kernel_size ) ; } ; b . prototype . get_sample = function ( a , b ) { return 0 > a ? ( a += this . source_buffer_previous [ 0 ] . length , this . source_buffer_previous [ b ] [ a ] ) : this . source_buffer_current [ b ] [ a ] ; } ; b . prototype . ensure_enough_data = function ( a ) { var b = this . source_buffer_current [ 0 ] . length ; b - this . source_block_start < a && ( this . prepare_next_buffer ( ) , this . source_block_start -= b ) ; } ; b . prototype . prepare_next_buffer = function ( ) { 256 > this . queued_samples && this . queue_length && this . dbg_log ( "Not enough samples - should not happen during midway of playback" ) ; this . source_buffer_previous = this . source_buffer_current ; this . source_buffer_current = this . queue_shift ( ) ; var a = this . source_buffer_current [ 0 ] . length ; if ( 256 > a ) { for ( var b = this . queue_start , c = 0 ; 256 > a && c < this . queue_length ; ) a += this . queue_data [ b ] [ 0 ] . length , b = b + 1 & this . queue_size - 1 , c ++ ; a = Math . max ( a , 256 ) ; a = [ new Float32Array ( a ) , new Float32Array ( a ) ] ; a [ 0 ] . set ( this . source_buffer_current [ 0 ] ) ; a [ 1 ] . set ( this . source_buffer_current [ 1 ] ) ; b = this . source_buffer_current [ 0 ] . length ; for ( var d = 0 ; d < c ; d ++ ) { var e = this . queue_shift ( ) ; a [ 0 ] . set ( e [ 0 ] , b ) ; a [ 1 ] . set ( e [ 1 ] , b ) ; b += e [ 0 ] . length ; } this . source_buffer_current = a ; } this . pump ( ) ; } ; b . prototype . pump = function ( ) { 1024 > this . queued_samples / this . source_samples_per_destination && this . port . postMessage ( { type : "pump" } ) ; } ; b . prototype . queue_push = function ( a ) { this . queue_length < this . queue_size && ( this . queue_data [ this . queue_end ] = a , this . queue_end = this . queue_end + 1 & this . queue_size - 1 , this . queue_length ++ , this . queued_samples += a [ 0 ] . length , this . pump ( ) ) ; } ; b . prototype . queue_shift = function ( ) { if ( ! this . queue_length ) return c ; var a = this . queue_data [ this . queue_start ] ; this . queue_data [ this . queue_start ] = null ; this . queue_start = this . queue_start + 1 & this . queue_size - 1 ; this . queue_length -- ; this . queued_samples -= a [ 0 ] . length ; return a ; } ; b . prototype . dbg_log = function ( a ) { DEBUG && this . port . postMessage ( { type : "debug-log" , value : a } ) ; } ; registerProcessor ( "dac-processor" , b ) ; } . toString ( ) ; var e = b . indexOf ( "{" ) + 1 , g = b . lastIndexOf ( "}" ) ; b = b . substring ( e , g ) ; DEBUG && ( b = "var DEBUG = true;\n" + b ) ; b = new Blob ( [ b ] , { type : "application/javascript" } ) ; var f = URL . createObjectURL ( b ) ; this . node_processor = null ; this . node_output = this . audio_context . createGain ( ) ; this . audio_context . audioWorklet . addModule ( f ) . then ( function ( ) { URL . revokeObjectURL ( f ) ; d . node_processor = new AudioWorkletNode ( d . audio_context , "dac-processor" , { numberOfInputs : 0 , numberOfOutputs : 1 , outputChannelCount : [ 2 ] } ) ; d . node_processor . port . postMessage ( { type : "sampling-rate" , value : d . sampling_rate } ) ; d . node_processor . port . onmessage = function ( a ) { switch ( a . data . type ) { case "pump" : d . pump ( ) ; break ; case "debug-log" : dbg_log ( "SpeakerWorkletDAC - Worklet: " + a . data . value ) ; } } ; d . node_processor . connect ( d . node_output ) ; } ) ; this . mixer_connection = c . add_source ( this . node_output , MIXER_SRC_DAC ) ; this . mixer_connection . set_gain_hidden ( 3 ) ; a . register ( "dac-send-data" , function ( a ) { this . queue ( a ) ; } , this ) ; a . register ( "dac-enable" , function ( a ) { this . enabled = ! 0 ; } , this ) ; a . register ( "dac-disable" , function ( ) { this . enabled = ! 1 ; } , this ) ; a . register ( "dac-tell-sampling-rate" , function ( a ) { dbg_assert ( 0 < a , "Sampling rate should be nonzero" ) ; this . sampling_rate = a ; this . node_processor && this . node_processor . port . postMessage ( { type : "sampling-rate" , value : a } ) ; } , this ) ; DEBUG && ( this . debugger = new SpeakerDACDebugger ( this . audio_context , this . node_output ) ) ; } SpeakerWorkletDAC . prototype . queue = function ( a ) { this . node_processor && ( DEBUG && this . debugger . push_queued_data ( a ) , this . node_processor . port . postMessage ( { type : "queue" , value : a } , [ a [ 0 ] . buffer , a [ 1 ] . buffer ] ) ) ; } ; SpeakerWorkletDAC . prototype . pump = function ( ) { this . enabled && this . bus . send ( "dac-request-data" ) ; } ; function SpeakerBufferSourceDAC ( a , b , c ) { this . bus = a ; this . audio_context = b ; this . enabled = ! 1 ; this . sampling_rate = 22050 ; this . buffered_time = 0 ; this . rate_ratio = 1 ; this . node_lowpass = this . audio_context . createBiquadFilter ( ) ; this . node_lowpass . type = "lowpass" ; this . node_output = this . node_lowpass ; this . mixer_connection = c . add_source ( this . node_output , MIXER_SRC_DAC ) ; this . mixer_connection . set_gain_hidden ( 3 ) ; a . register ( "dac-send-data" , function ( a ) { this . queue ( a ) ; } , this ) ; a . register ( "dac-enable" , function ( a ) { this . enabled = ! 0 ; this . pump ( ) ; } , this ) ; a . register ( "dac-disable" , function ( ) { this . enabled = ! 1 ; } , this ) ; a . register ( "dac-tell-sampling-rate" , function ( a ) { dbg_assert ( 0 < a , "Sampling rate should be nonzero" ) ; this . sampling_rate = a ; this . rate_ratio = Math . ceil ( AUDIOBUFFER_MINIMUM_SAMPLING_RATE / a ) ; this . node_lowpass . frequency . setValueAtTime ( a / 2 , this . audio_context . currentTime ) ; } , this ) ; DEBUG && ( this . debugger = new SpeakerDACDebugger ( this . audio_context , this . node_output ) ) ; } SpeakerBufferSourceDAC . prototype . queue = function ( a ) { var b = this ; DEBUG && this . debugger . push_queued_data ( a ) ; var c = a [ 0 ] . length , d = c / this . sampling_rate ; if ( 1 < this . rate_ratio ) { var e = this . audio_context . createBuffer ( 2 , c * this . rate_ratio , this . sampling_rate * this . rate_ratio ) ; for ( var g = e . getChannelData ( 0 ) , f = e . getChannelData ( 1 ) , k = 0 , l = 0 ; l < c ; l ++ ) for ( var m = 0 ; m < this . rate_ratio ; m ++ , k ++ ) g [ k ] = a [ 0 ] [ l ] , f [ k ] = a [ 1 ] [ l ] ; } else e = this . audio_context . createBuffer ( 2 , c , this . sampling_rate ) , e . copyToChannel ( a [ 0 ] , 0 ) , e . copyToChannel ( a [ 1 ] , 1 ) ; a = this . audio_context . createBufferSource ( ) ; a . buffer = e ; a . connect ( this . node_lowpass ) ; a . addEventListener ( "ended" , this . pump . bind ( this ) ) ; e = this . audio_context . currentTime ; if ( this . buffered_time < e ) for ( dbg_log ( "Speaker DAC - Creating/Recreating reserve - shouldn't occur frequently during playback" ) , this . buffered_time = e , e = DAC_QUEUE_RESERVE - d , c = 0 ; c <= e ; ) c += d , this . buffered_time += d , setTimeout ( function ( ) { return b . pump ( ) ; } , 1E3 * c ) ; a . start ( this . buffered_time ) ; this . buffered_time += d ; setTimeout ( function ( ) { return b . pump ( ) ; } , 0 ) ; } ; SpeakerBufferSourceDAC . prototype . pump = function ( ) { this . enabled && ( this . buffered_time - this . audio_context . currentTime > DAC_QUEUE_RESERVE || this . bus . send ( "dac-request-data" ) ) ; } ; function SpeakerDACDebugger ( a , b ) { this . audio_context = a ; this . node_source = b ; this . node_processor = null ; this . node_gain = this . audio_context . createGain ( ) ; this . node_gain . gain . setValueAtTime ( 0 , this . audio_context . currentTime ) ; this . node_gain . connect ( this . audio_context . destination ) ; this . is_active = ! 1 ; this . queued_history = [ ] ; this . output_history = [ ] ; this . queued = [ [ ] , [ ] ] ; this . output = [ [ ] , [ ] ] ; } SpeakerDACDebugger . prototype . start = function ( a ) { var b = this ; this . is_active = ! 0 ; this . queued = [ [ ] , [ ] ] ; this . output = [ [ ] , [ ] ] ; this . queued_history . push ( this . queued ) ; this . output_history . push ( this . output ) ; this . node_processor = this . audio_context . createScriptProcessor ( 1024 , 2 , 2 ) ; this . node_processor . onaudioprocess = function ( a ) { b . output [ 0 ] . push ( a . inputBuffer . getChannelData ( 0 ) . slice ( ) ) ; b . output [ 1 ] . push ( a . inputBuffer . getChannelData ( 1 ) . slice ( ) ) ; } ; this . node_source . connect ( this . node_processor ) ; this . node_processor . connect ( this . node_gain ) ; setTimeout ( function ( ) { b . stop ( ) ; } , a ) ; } ; SpeakerDACDebugger . prototype . stop = function ( ) { this . is_active = ! 1 ; this . node_source . disconnect ( this . node_processor ) ; this . node_processor . disconnect ( ) ; this . node_processor = null ; } ; SpeakerDACDebugger . prototype . push_queued_data = function ( a ) { this . is_active && ( this . queued [ 0 ] . push ( a [ 0 ] . slice ( ) ) , this . queued [ 1 ] . push ( a [ 1 ] . slice ( ) ) ) ; } ; SpeakerDACDebugger . prototype . download_txt = function ( a , b ) { a = this . output_history [ a ] [ b ] . map ( function ( a ) { return a . join ( " " ) ; } ) . join ( " " ) ; dump_file ( a , "dacdata.txt" ) ; } ; SpeakerDACDebugger . prototype . download_csv = function ( a ) { a = this . output_history [ a ] ; for ( var b = [ ] , c = 0 ; c < a [ 0 ] . length ; c ++ ) for ( var d = 0 ; d < a [ 0 ] [ c ] . length ; d ++ ) b . push ( a [ 0 ] [ c ] [ d ] + "," + a [ 1 ] [ c ] [ d ] ) ; dump_file ( b . join ( "\n" ) , "dacdata.csv" ) ; } ; function SerialAdapter ( a , b ) { function c ( a ) { f . bus && f . enabled && ( f . send_char ( a . which ) , a . preventDefault ( ) ) ; } function d ( a ) { var b = a . which ; 8 === b ? ( f . send_char ( 127 ) , a . preventDefault ( ) ) : 9 === b && ( f . send_char ( 9 ) , a . preventDefault ( ) ) ; } function e ( a ) { if ( f . enabled ) { for ( var b = a . clipboardData . getData ( "text/plain" ) , c = 0 ; c < b . length ; c ++ ) f . send_char ( b . charCodeAt ( c ) ) ; a . preventDefault ( ) ; } } function g ( b ) { b . target !== a && a . blur ( ) ; } var f = this ; this . enabled = ! 0 ; this . bus = b ; this . text = "" ; this . text_new_line = ! 1 ; this . last_update = 0 ; this . bus . register ( "serial0-output-char" , function ( a ) { this . show_char ( a ) ; } , this ) ; this . destroy = function ( ) { a . removeEventListener ( "keypress" , c , ! 1 ) ; a . removeEventListener ( "keydown" , d , ! 1 ) ; a . removeEventListener ( "paste" , e , ! 1 ) ; window . removeEventListener ( "mousedown" , g , ! 1 ) ; } ; this . init = function ( ) { this . destroy ( ) ; a . addEventListener ( "keypress" , c , ! 1 ) ; a . addEventListener ( "keydown" , d , ! 1 ) ; a . addEventListener ( "paste" , e , ! 1 ) ; window . addEventListener ( "mousedown" , g , ! 1 ) ; } ; this . init ( ) ; this . show_char = function ( a ) { "\b" === a ? ( this . text = this . text . slice ( 0 , - 1 ) , this . update ( ) ) : "\r" !== a && ( this . text += a , "\n" === a && ( this . text_new_line = ! 0 ) , this . update ( ) ) ; } ; this . update = function ( ) { var a = this , b = Date . now ( ) , c = b - this . last_update ; 16 > c ? void 0 === this . update_timer && ( this . update_timer = setTimeout ( function ( ) { a . update_timer = void 0 ; var b = Date . now ( ) ; dbg_assert ( 16 <= b - a . last_update ) ; a . last_update = b ; a . render ( ) ; } , 16 - c ) ) : ( void 0 !== this . update_timer && ( clearTimeout ( this . update_timer ) , this . update_timer = void 0 ) , this . last_update = b , this . render ( ) ) ; } ; this . render = function ( ) { a . value = this . text ; this . text_new_line && ( this . text_new_line = ! 1 , a . scrollTop = 1E9 ) ; } ; this . send_char = function ( a ) { f . bus && f . bus . send ( "serial0-input" , a ) ; } ; } ; function NetworkAdapter ( a , b ) { this . send_data = function ( a ) { } ; this . bus = b ; this . socket = void 0 ; this . send_queue = [ ] ; this . url = a ; this . reconnect_interval = 1E4 ; this . last_connect_attempt = Date . now ( ) - this . reconnect_interval ; this . send_queue_limit = 64 ; this . bus . register ( "net0-send" , function ( a ) { this . send ( a ) ; } , this ) ; } NetworkAdapter . prototype . handle_message = function ( a ) { this . bus && this . bus . send ( "net0-receive" , new Uint8Array ( a . data ) ) ; } ; NetworkAdapter . prototype . handle_close = function ( a ) { this . connect ( ) ; setTimeout ( this . connect . bind ( this ) , this . reconnect_interval ) ; } ; NetworkAdapter . prototype . handle_open = function ( a ) { for ( a = 0 ; a < this . send_queue . length ; a ++ ) this . send ( this . send_queue [ a ] ) ; this . send_queue = [ ] ; } ; NetworkAdapter . prototype . handle_error = function ( a ) { } ; NetworkAdapter . prototype . destroy = function ( ) { this . socket && this . socket . close ( ) ; } ; NetworkAdapter . prototype . connect = function ( ) { if ( this . socket ) { var a = this . socket . readyState ; if ( 0 === a || 1 === a ) return ; } a = Date . now ( ) ; if ( ! ( this . last_connect_attempt + this . reconnect_interval > a ) ) { this . last_connect_attempt = Date . now ( ) ; try { this . socket = new WebSocket ( this . url ) ; } catch ( b ) { this . handle_close ( void 0 ) ; return ; } this . socket . binaryType = "arraybuffer" ; this . socket . onopen = this . handle_open . bind ( this ) ; this . socket . onmessage = this . handle_message . bind ( this ) ; this . socket . onclose = this . handle_close . bind ( this ) ; this . socket . onerror = this . handle_error . bind ( this ) ; } } ; NetworkAdapter . prototype . send = function ( a ) { this . socket && 1 === this . socket . readyState ? this . socket . send ( a ) : ( this . send_queue . push ( a ) , this . send_queue . length > 2 * this . send_queue_limit && ( this . send_queue = this . send_queue . slice ( - this . send_queue_limit ) ) , this . connect ( ) ) ; } ; var ASYNC_SAFE = ! 1 ; ( function ( ) { function a ( a , b ) { var c = new XMLHttpRequest ; c . open ( b . method || "get" , a , ! 0 ) ; b . as_text || ( c . responseType = "arraybuffer" ) ; if ( b . headers ) for ( var d = Object . keys ( b . headers ) , e = 0 ; e < d . length ; e ++ ) { var f = d [ e ] ; c . setRequestHeader ( f , b . headers [ f ] ) ; } b . range && ( d = b . range . start , c . setRequestHeader ( "Range" , "bytes=" + d + "-" + ( d + b . range . length - 1 ) ) ) ; c . onload = function ( d ) { 4 === c . readyState && ( 200 !== c . status && 206 !== c . status ? console . error ( "Loading the image `" + a + "` failed (status %d)" , c . status ) : c . response && b . done && b . done ( c . response , c ) ) ; } ; b . progress && ( c . onprogress = function ( a ) { b . progress ( a ) ; } ) ; c . send ( null ) ; } function b ( a , b ) { var c = require ( "fs" ) ; b . range ? ( dbg_assert ( ! b . as_text ) , c . open ( a , "r" , function ( a , d ) { if ( a ) throw a ; var e = b . range . length , f = new global . Buffer ( e ) ; c . read ( d , f , 0 , e , b . range . start , function ( a , g ) { if ( a ) throw a ; dbg_assert ( g === e ) ; b . done && b . done ( new Uint8Array ( f ) ) ; c . close ( d , function ( a ) { if ( a ) throw a ; } ) ; } ) ; } ) ) : c . readFile ( a , { encoding : b . as_text ? "utf-8" : null } , function ( c , d ) { c ? console . log ( "Could not read file:" , a , c ) : ( c = d , b . as_text || ( c = ( new Uint8Array ( c ) ) . buffer ) , b . done ( c ) ) ; } ) ; } function c ( a , b ) { this . filename = a ; this . block_size = 256 ; this . byteLength = b ; this . loaded_blocks = { } ; this . onprogress = this . onload = void 0 ; } function d ( a ) { this . file = a ; this . byteLength = a . size ; 1073741824 < a . size && console . warn ( "SyncFileBuffer: Allocating buffer of " + ( a . size >> 20 ) + " MB ..." ) ; this . buffer = new ArrayBuffer ( a . size ) ; this . onprogress = this . onload = void 0 ; } function e ( a ) { this . file = a ; this . byteLength = a . size ; this . block_size = 256 ; this . loaded_blocks = { } ; this . onprogress = this . onload = void 0 ; } v86util . load_file = "undefined" === typeof XMLHttpRequest ? b : a ; v86util . AsyncXHRBuffer = c ; v86util . AsyncFileBuffer = e ; v86util . SyncFileBuffer = d ; var g = "undefined" === typeof XMLHttpRequest ? function ( a , b ) { require ( "fs" ) . stat ( a , function ( a , c ) { a ? b ( a ) : b ( null , c . size ) ; } ) ; } : function ( a , b ) { v86util . load_file ( a , { done : function ( a , c ) { a = c . getResponseHeader ( "Content-Range" ) || "" ; ( c = a . match ( /\/(\d+)\s*$/ ) ) ? b ( null , + c [ 1 ] ) : b ( { header : a } ) ; } , headers : { Range : "bytes=0-0" } } ) ; } ; c . prototype . load = function ( ) { var a = this ; void 0 !== this . byteLength ? this . onload && this . onload ( { } ) : g ( this . filename , function ( b , c ) { b ? console . assert ( ! 1 , "Cannot use: " + a . filename + ". `Range: bytes=...` header not supported (Got `" + b . header + "`)" ) : ( dbg_assert ( 0 <= c ) , a . byteLength = c , a . onload && a . onload ( { } ) ) ; } ) ; } ; c . prototype . get_from_cache = function ( a , b , c ) { c = b / this . block_size ; a /= this . block_size ; for ( var d = 0 ; d < c ; d ++ ) if ( ! this . loaded_blocks [ a + d ] ) return ; if ( 1 === c ) return this . loaded_blocks [ a ] ; b = new Uint8Array ( b ) ; for ( d = 0 ; d < c ; d ++ ) b . set ( this . loaded_blocks [ a + d ] , d * this . block_size ) ; return b ; } ; c . prototype . get = function ( a , b , c ) { console . assert ( a + b <= this . byteLength ) ; console . assert ( 0 === a % this . block_size ) ; console . assert ( 0 === b % this . block_size ) ; console . assert ( b ) ; var d = this . get_from_cache ( a , b , c ) ; d ? ASYNC_SAFE ? setTimeout ( c . bind ( this , d ) , 0 ) : c ( d ) : v86util . load_file ( this . filename , { done : function ( d ) { d = new Uint8Array ( d ) ; this . handle_read ( a , b , d ) ; c ( d ) ; } . bind ( this ) , range : { start : a , length : b } } ) ; } ; c . prototype . set = function ( a , b , c ) { console . assert ( a + b . byteLength <= this . byteLength ) ; var d = b . length ; console . assert ( 0 === a % this . block_size ) ; console . assert ( 0 === d % this . block_size ) ; console . assert ( d ) ; a /= this . block_size ; d /= this . block_size ; for ( var e = 0 ; e < d ; e ++ ) { var f = this . loaded_blocks [ a + e ] ; void 0 === f && ( f = this . loaded_blocks [ a + e ] = new Uint8Array ( this . block_size ) ) ; var g = b . subarray ( e * this . block_size , ( e + 1 ) * this . block_size ) ; f . set ( g ) ; console . assert ( f . byteLength === g . length ) ; } c ( ) ; } ; c . prototype . handle_read = function ( a , b , c ) { a /= this . block_size ; b /= this . block_size ; for ( var d = 0 ; d < b ; d ++ ) { var e = this . loaded_blocks [ a + d ] ; e && c . set ( e , d * this . block_size ) ; } } ; c . prototype . get_buffer = function ( a ) { a ( ) ; } ; c . prototype . get_written_blocks = function ( ) { var a = 0 ; for ( b in this . loaded_blocks ) a ++ ; a = new Uint8Array ( a * this . block_size ) ; var b = [ ] ; var c = 0 ; for ( e in this . loaded_blocks ) { var d = this . loaded_blocks [ e ] ; dbg_assert ( d . length === this . block_size ) ; var e = + e ; b . push ( e ) ; a . set ( d , c * this . block_size ) ; c ++ ; } return { buffer : a , indices : b , block_size : this . block_size } ; } ; d . prototype . load = function ( ) { this . load_next ( 0 ) ; } ; d . prototype . load_next = function ( a ) { var b = new FileReader ; b . onload = function ( b ) { b = new Uint8Array ( b . target . result ) ; ( new Uint8Array ( this . buffer , a ) ) . set ( b ) ; this . load_next ( a + 4194304 ) ; } . bind ( this ) ; if ( this . onprogress ) this . onprogress ( { loaded : a , total : this . byteLength , lengthComputable : ! 0 } ) ; if ( a < this . byteLength ) { var c = this . file . slice ( a , Math . min ( a + 4194304 , this . byteLength ) ) ; b . readAsArrayBuffer ( c ) ; } else this . file = void 0 , this . onload && this . onload ( { buffer : this . buffer } ) ; } ; d . prototype . get = function ( a , b , c ) { console . assert ( a + b <= this . byteLength ) ; c ( new Uint8Array ( this . buffer , a , b ) ) ; } ; d . prototype . set = function ( a , b , c ) { console . assert ( a + b . byteLength <= this . byteLength ) ; ( new Uint8Array ( this . buffer , a , b . byteLength ) ) . set ( b ) ; c ( ) ; } ; d . prototype . get_buffer = function ( a ) { a ( this . buffer ) ; } ; e . prototype . load = function ( ) { this . onload && this . onload ( { } ) ; } ; e . prototype . get = function ( a , b , c ) { console . assert ( 0 === a % this . block_size ) ; console . assert ( 0 === b % this . block_size ) ; console . assert ( b ) ; var d = this . get_from_cache ( a , b , c ) ; d ? c ( d ) : ( d = new FileReader , d . onload = function ( d ) { d = new Uint8Array ( d . target . result ) ; this . handle_read ( a , b , d ) ; c ( d ) ; } . bind ( this ) , d . readAsArrayBuffer ( this . file . slice ( a , a + b ) ) ) ; } ; e . prototype . get_from_cache = c . prototype . get_from_cache ; e . prototype . set = c . prototype . set ; e . prototype . handle_read = c . prototype . handle_read ; e . prototype . get_buffer = function ( a ) { a ( ) ; } ; e . prototype . get_as_file = function ( a ) { for ( var b = [ ] , c = Object . keys ( this . loaded_blocks ) . map ( Number ) . sort ( function ( a , b ) { return a - b ; } ) , d = 0 , e = 0 ; e < c . length ; e ++ ) { var f = c [ e ] , g = this . loaded_blocks [ f ] ; f *= this . block_size ; console . assert ( f >= d ) ; f !== d && ( b . push ( this . file . slice ( d , f ) ) , d = f ) ; b . push ( g ) ; d += g . length ; } d !== this . file . size && b . push ( this . file . slice ( d ) ) ; a = new File ( b , a ) ; console . assert ( a . size === this . file . size ) ; return a ; } ; } ) ( ) ; function V86Starter ( a ) { function b ( a , b ) { switch ( a ) { case "hda" : k . hda = this . disk_images . hda = b ; break ; case "hdb" : k . hdb = this . disk_images . hdb = b ; break ; case "cdrom" : k . cdrom = this . disk_images . cdrom = b ; break ; case "fda" : k . fda = this . disk_images . fda = b ; break ; case "fdb" : k . fdb = this . disk_images . fdb = b ; break ; case "multiboot" : k . multiboot = this . disk_images . multiboot = b ; break ; case "bios" : k . bios = b . buffer ; break ; case "vga_bios" : k . vga_bios = b . buffer ; break ; case "initial_state" : k . initial_state = b . buffer ; break ; case "fs9p_json" : k . fs9p_json = b . buffer ; break ; default : dbg_assert ( ! 1 , a ) ; } } function c ( a , b ) { if ( b ) if ( b . get && b . set && b . load ) l . push ( { name : a , loadable : b } ) ; else { b = { buffer : b . buffer , async : b . async , url : b . url , size : b . size } ; if ( "bios" === a || "vga_bios" === a || "initial_state" === a || "multiboot" === a ) b . async = ! 1 ; b . buffer instanceof ArrayBuffer ? ( b = new SyncBuffer ( b . buffer ) , l . push ( { name : a , loadable : b } ) ) : "undefined" !== typeof File && b . buffer instanceof File ? ( void 0 === b . async && ( b . async = 268435456 <= b . buffer . size ) , b = b . async ? new v86util . AsyncFileBuffer ( b . buffer ) : new v86util . SyncFileBuffer ( b . buffer ) , l . push ( { name : a , loadable : b } ) ) : b . url ? b . async ? ( b = new v86util . AsyncXHRBuffer ( b . url , b . size ) , l . push ( { name : a , loadable : b } ) ) : l . push ( { name : a , url : b . url , size : b . size } ) : dbg_log ( "Ignored file: url=" + b . url + " buffer=" + b . buffer ) ; } } function d ( ) { k . initial_state && ( k . memory_size = 0 ) ; this . bus . send ( "cpu-init" , k ) ; setTimeout ( function ( ) { k . initial_state && f . restore_state ( k . initial_state ) ; setTimeout ( function ( ) { k . fs9p && k . fs9p_json && k . fs9p . OnJSONLoaded ( k . fs9p_json ) ; a . autostart && this . bus . send ( "cpu-run" ) ; } . bind ( this ) , 0 ) ; } . bind ( this ) , 0 ) ; } this . cpu_is_running = ! 1 ; var e = Bus . create ( ) , g = this . bus = e [ 0 ] ; this . emulator_bus = e [ 1 ] ; var f = this . v86 = new v86 ( this . emulator_bus ) ; this . bus . register ( "emulator-stopped" , function ( ) { this . cpu_is_running = ! 1 ; } , this ) ; this . bus . register ( "emulator-started" , function ( ) { this . cpu_is_running = ! 0 ; } , this ) ; var k = { } ; this . disk_images = { fda : void 0 , fdb : void 0 , hda : void 0 , hdb : void 0 , cdrom : void 0 } ; k . load_devices = ! 0 ; k . memory_size = a . memory_size || 67108864 ; k . vga_memory_size = a . vga_memory_size || 8388608 ; k . boot_order = a . boot_order || 531 ; k . fastboot = a . fastboot || ! 1 ; k . fda = void 0 ; k . fdb = void 0 ; a . network_relay_url && ( this . network_adapter = new NetworkAdapter ( a . network_relay_url , g ) , k . enable_ne2k = ! 0 ) ; a . disable_keyboard || ( this . keyboard_adapter = new KeyboardAdapter ( g ) ) ; a . disable_mouse || ( this . mouse_adapter = new MouseAdapter ( g , a . screen_container ) ) ; a . screen_container ? this . screen_adapter = new ScreenAdapter ( a . screen_container , g ) : a . screen_dummy && ( this . screen_adapter = new DummyScreenAdapter ( g ) ) ; a . serial_container && ( this . serial_adapter = new SerialAdapter ( a . serial_container , g ) ) ; a . disable_speaker || ( this . speaker_adapter = new SpeakerAdapter ( g ) ) ; var l = [ ] ; e = "bios vga_bios cdrom hda hdb fda fdb initial_state multiboot" . split ( " " ) ; for ( g = 0 ; g < e . length ; g ++ ) c ( e [ g ] , a [ e [ g ] ] ) ; if ( a . filesystem && ( e = a . filesystem . basefs , g = a . filesystem . baseurl , this . fs9p = new FS ( g ) , k . fs9p = this . fs9p , e ) ) { console . assert ( g , "Filesystem: baseurl must be specified" ) ; if ( "object" === typeof e ) { var m = e . size ; e = e . url ; } dbg_assert ( "string" === typeof e ) ; l . push ( { name : "fs9p_json" , url : e , size : m , as_text : ! 0 } ) ; } var n = this , p = l . length , q = function ( a ) { if ( a === p ) setTimeout ( d . bind ( this ) , 0 ) ; else { var c = l [ a ] ; c . loadable ? ( c . loadable . onload = function ( d ) { b . call ( this , c . name , c . loadable ) ; q ( a + 1 ) ; } . bind ( this ) , c . loadable . load ( ) ) : v86util . load_file ( c . url , { done : function ( d ) { b . call ( this , c . name , new SyncBuffer ( d ) ) ; q ( a + 1 ) ; } . bind ( this ) , progress : function ( b ) { 200 === b . target . status ? n . emulator_bus . send ( "download-progress" , { file_index : a , file_count : p , file_name : c . url , lengthComputable : b . lengthComputable , total : b . total || c . size , loaded : b . loaded } ) : n . emulator_bus . send ( "download-error" , { file_index : a , file_count : p , file_name : c . url , request : b . target } ) ; } , as_text : c . as_text } ) ; } } . bind ( this ) ; q ( 0 ) ; } V86Starter . prototype . run = function ( ) { this . bus . send ( "cpu-run" ) ; } ; goog . exportProperty ( V86Starter . prototype , "run" , V86Starter . prototype . run ) ; V86Starter . prototype . stop = function ( ) { this . bus . send ( "cpu-stop" ) ; } ; goog . exportProperty ( V86Starter . prototype , "stop" , V86Starter . prototype . stop ) ; V86Starter . prototype . destroy = function ( ) { this . keyboard_adapter . destroy ( ) ; } ; goog . exportProperty ( V86Starter . prototype , "destroy" , V86Starter . prototype . destroy ) ; V86Starter . prototype . restart = function ( ) { this . bus . send ( "cpu-restart" ) ; } ; goog . exportProperty ( V86Starter . prototype , "restart" , V86Starter . prototype . restart ) ; V86Starter . prototype . add_listener = function ( a , b ) { this . bus . register ( a , b , this ) ; } ; goog . exportProperty ( V86Starter . prototype , "add_listener" , V86Starter . prototype . add_listener ) ; V86Starter . prototype . remove_listener = function ( a , b ) { this . bus . unregister ( a , b ) ; } ; goog . exportProperty ( V86Starter . prototype , "remove_listener" , V86Starter . prototype . remove_listener ) ; V86Starter . prototype . restore_state = function ( a ) { this . v86 . restore_state ( a ) ; } ; goog . exportProperty ( V86Starter . prototype , "restore_state" , V86Starter . prototype . restore_state ) ; V86Starter . prototype . save_state = function ( a ) { setTimeout ( function ( ) { try { a ( null , this . v86 . save_state ( ) ) ; } catch ( b ) { a ( b , null ) ; } } . bind ( this ) , 0 ) ; } ; goog . exportProperty ( V86Starter . prototype , "save_state" , V86Starter . prototype . save_state ) ; V86Starter . prototype . get_statistics = function ( ) { console . warn ( "V86Starter.prototype.get_statistics is deprecated. Use events instead." ) ; var a = { cpu : { instruction_counter : this . get_instruction_counter ( ) } } ; if ( ! this . v86 ) return a ; var b = this . v86 . cpu . devices ; b . hda && ( a . hda = b . hda . stats ) ; b . cdrom && ( a . cdrom = b . cdrom . stats ) ; b . ps2 && ( a . mouse = { enabled : b . ps2 . use_mouse } ) ; b . vga && ( a . vga = { is_graphical : b . vga . stats . is_graphical } ) ; return a ; } ; goog . exportProperty ( V86Starter . prototype , "get_statistics" , V86Starter . prototype . get_statistics ) ; V86Starter . prototype . get_instruction_counter = function ( ) { return this . v86 ? this . v86 . cpu . timestamp_counter : 0 ; } ; goog . exportProperty ( V86Starter . prototype , "get_instruction_counter" , V86Starter . prototype . get_instruction_counter ) ; V86Starter . prototype . is_running = function ( ) { return this . cpu_is_running ; } ; goog . exportProperty ( V86Starter . prototype , "is_running" , V86Starter . prototype . is_running ) ; V86Starter . prototype . keyboard_send_scancodes = function ( a ) { for ( var b = 0 ; b < a . length ; b ++ ) this . bus . send ( "keyboard-code" , a [ b ] ) ; } ; goog . exportProperty ( V86Starter . prototype , "keyboard_send_scancodes" , V86Starter . prototype . keyboard_send_scancodes ) ; V86Starter . prototype . keyboard_send_keys = function ( a ) { for ( var b = 0 ; b < a . length ; b ++ ) this . keyboard_adapter . simulate_press ( a [ b ] ) ; } ; goog . exportProperty ( V86Starter . prototype , "keyboard_send_keys" , V86Starter . prototype . keyboard_send_keys ) ; V86Starter . prototype . keyboard_send_text = function ( a ) { for ( var b = 0 ; b < a . length ; b ++ ) this . keyboard_adapter . simulate_char ( a [ b ] ) ; } ; goog . exportProperty ( V86Starter . prototype , "keyboard_send_text" , V86Starter . prototype . keyboard_send_text ) ; V86Starter . prototype . screen_make_screenshot = function ( ) { this . screen_adapter && this . screen_adapter . make_screenshot ( ) ; } ; goog . exportProperty ( V86Starter . prototype , "screen_make_screenshot" , V86Starter . prototype . screen_make_screenshot ) ; V86Starter . prototype . screen_set_scale = function ( a , b ) { this . screen_adapter && this . screen_adapter . set_scale ( a , b ) ; } ; goog . exportProperty ( V86Starter . prototype , "screen_set_scale" , V86Starter . prototype . screen_set_scale ) ; V86Starter . prototype . screen_go_fullscreen = function ( ) { if ( this . screen_adapter ) { var a = document . getElementById ( "screen_container" ) ; if ( a ) { var b = a . requestFullScreen || a . webkitRequestFullscreen || a . mozRequestFullScreen || a . msRequestFullScreen ; b && ( b . call ( a ) , ( a = document . getElementsByClassName ( "phone_keyboard" ) [ 0 ] ) && a . focus ( ) ) ; this . lock_mouse ( ) ; } } } ; goog . exportProperty ( V86Starter . prototype , "screen_go_fullscreen" , V86Starter . prototype . screen_go_fullscreen ) ; V86Starter . prototype . lock_mouse = function ( ) { var a = document . body , b = a . requestPointerLock || a . mozRequestPointerLock || a . webkitRequestPointerLock ; b && b . call ( a ) ; } ; goog . exportProperty ( V86Starter . prototype , "lock_mouse" , V86Starter . prototype . lock_mouse ) ; V86Starter . prototype . mouse_set_status = function ( a ) { this . mouse_adapter && ( this . mouse_adapter . emu_enabled = a ) ; } ; V86Starter . prototype . keyboard_set_status = function ( a ) { this . keyboard_adapter && ( this . keyboard_adapter . emu_enabled = a ) ; } ; goog . exportProperty ( V86Starter . prototype , "keyboard_set_status" , V86Starter . prototype . keyboard_set_status ) ; V86Starter . prototype . serial0_send = function ( a ) { for ( var b = 0 ; b < a . length ; b ++ ) this . bus . send ( "serial0-input" , a . charCodeAt ( b ) ) ; } ; goog . exportProperty ( V86Starter . prototype , "serial0_send" , V86Starter . prototype . serial0_send ) ; V86Starter . prototype . create_file = function ( a , b , c ) { var d = this . fs9p ; if ( d ) { var e = a . split ( "/" ) ; e = e [ e . length - 1 ] ; a = d . SearchPath ( a ) . parentid ; var g = "" === e || - 1 === a ; g || d . CreateBinaryFile ( e , a , b ) ; c && setTimeout ( function ( ) { g ? c ( new FileNotFoundError ) : c ( null ) ; } , 0 ) ; } } ; goog . exportProperty ( V86Starter . prototype , "create_file" , V86Starter . prototype . create_file ) ; V86Starter . prototype . read_file = function ( a , b ) { var c = this . fs9p ; if ( c ) { var d = c . SearchPath ( a ) . id ; - 1 === d ? b ( new FileNotFoundError , null ) : ( c . OpenInode ( d , void 0 ) , c . AddEvent ( d , function ( ) { var a = c . inodedata [ d ] ; a ? b ( null , a . subarray ( 0 , c . inodes [ d ] . size ) ) : b ( new FileNotFoundError , null ) ; } ) ) ; } } ; goog . exportProperty ( V86Starter . prototype , "read_file" , V86Starter . prototype . read_file ) ; function FileNotFoundError ( a ) { this . message = a || "File not found" ; } FileNotFoundError . prototype = Error . prototype ; "undefined" !== typeof window ? ( window . V86Starter = V86Starter , window . V86 = V86Starter ) : "undefined" !== typeof module && "undefined" !== typeof module . exports ? ( module . exports . V86Starter = V86Starter , module . exports . V86 = V86Starter ) : "function" === typeof importScripts && ( self . V86Starter = V86Starter , self . V86 = V86Starter ) ; var WorkerBus = { Connector : function ( a ) { this . listeners = { } ; this . pair = a ; a . addEventListener ( "message" , function ( a ) { a = a . data ; for ( var b = this . listeners [ a [ 0 ] ] , d = 0 ; d < b . length ; d ++ ) { var e = b [ d ] ; e . fn . call ( e . this_value , a [ 1 ] ) ; } } . bind ( this ) , ! 1 ) ; } } ; WorkerBus . Connector . prototype . register = function ( a , b , c ) { var d = this . listeners [ a ] ; void 0 === d && ( d = this . listeners [ a ] = [ ] ) ; d . push ( { fn : b , this_value : c } ) ; } ; WorkerBus . Connector . prototype . send = function ( a , b , c ) { dbg_assert ( 1 <= arguments . length ) ; this . pair && this . pair . postMessage ( [ a , b ] , c ) ; } ; WorkerBus . init = function ( a ) { return new WorkerBus . Connector ( a ) ; } ; function DummyScreenAdapter ( a ) { var b , c , d , e , g , f , k ; this . bus = a ; a . register ( "screen-set-mode" , function ( a ) { this . set_mode ( a ) ; } , this ) ; a . register ( "screen-fill-buffer-end" , function ( a ) { this . update_buffer ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; a . register ( "screen-put-char" , function ( a ) { this . put_char ( a [ 0 ] , a [ 1 ] , a [ 2 ] , a [ 3 ] , a [ 4 ] ) ; } , this ) ; a . register ( "screen-text-scroll" , function ( a ) { console . log ( "scroll" , a ) ; } , this ) ; a . register ( "screen-update-cursor" , function ( a ) { this . update_cursor ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; a . register ( "screen-update-cursor-scanline" , function ( a ) { this . update_cursor_scanline ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; a . register ( "screen-set-size-text" , function ( a ) { this . set_size_text ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; a . register ( "screen-set-size-graphical" , function ( a ) { this . set_size_graphical ( a [ 0 ] , a [ 1 ] ) ; } , this ) ; this . put_char = function ( a , b , c , d , e ) { a < k && b < f && ( a = 3 * ( a * f + b ) , g [ a ] = c , g [ a + 1 ] = d , g [ a + 2 ] = e ) ; } ; this . destroy = function ( ) { } ; this . set_mode = function ( a ) { } ; this . clear_screen = function ( ) { } ; this . set_size_text = function ( a , b ) { if ( a !== f || b !== k ) g = new Int32Array ( a * b * 3 ) , f = a , k = b ; } ; this . set_size_graphical = function ( a , d ) { b = new Uint8Array ( 4 * a * d ) ; c = new Int32Array ( b . buffer ) ; this . bus . send ( "screen-tell-buffer" , [ c ] , [ c . buffer ] ) ; } ; this . set_scale = function ( a , b ) { } ; this . update_cursor_scanline = function ( a , b ) { } ; this . update_cursor = function ( a , b ) { if ( a !== d || b !== e ) d = a , e = b ; } ; this . update_buffer = function ( a , b ) { } ; this . get_text_screen = function ( ) { for ( var a = [ ] , b = 0 ; b < k ; b ++ ) a . push ( this . get_text_row ( b ) ) ; return a ; } ; this . get_text_row = function ( a ) { var b = "" ; a = 3 * a * f ; for ( var c = 0 ; c < f ; c ++ ) b += String . fromCharCode ( g [ a + 3 * c ] ) ; return b ; } ; } ; var S_IRWXUGO = 511 , S_IFMT = 61440 , S_IFSOCK = 49152 , S_IFLNK = 40960 , S_IFREG = 32768 , S_IFBLK = 24576 , S_IFDIR = 16384 , S_IFCHR = 8192 , O_RDONLY = 0 , O_WRONLY = 1 , O_RDWR = 2 , O_ACCMODE = 3 , STATUS_INVALID = - 1 , STATUS_OK = 0 , STATUS_OPEN = 1 , STATUS_ON_SERVER = 2 , STATUS_LOADING = 3 , STATUS_UNLINKED = 4 , JSONFS_VERSION = 2 , JSONFS_IDX_NAME = 0 , JSONFS_IDX_SIZE = 1 , JSONFS_IDX_MTIME = 2 , JSONFS_IDX_MODE = 3 , JSONFS_IDX_UID = 4 , JSONFS_IDX_GID = 5 , JSONFS_IDX_TARGET = 6 ; function FS ( a ) { this . inodes = [ ] ; this . events = [ ] ; this . baseurl = a ; this . filesinloadingqueue = this . qidnumber = 0 ; this . OnLoaded = function ( ) { } ; this . inodedata = { } ; this . total_size = 274877906944 ; this . used_size = 0 ; this . CreateDirectory ( "" , - 1 ) ; } FS . prototype . AddEvent = function ( a , b ) { this . GetInode ( a ) . status == STATUS_OK ? b ( ) : this . events . push ( { id : a , OnEvent : b } ) ; } ; FS . prototype . HandleEvent = function ( a ) { 0 == this . filesinloadingqueue && ( this . OnLoaded ( ) , this . OnLoaded = function ( ) { } ) ; for ( var b = [ ] , c = 0 ; c < this . events . length ; c ++ ) this . events [ c ] . id == a ? this . events [ c ] . OnEvent ( ) : b . push ( this . events [ c ] ) ; this . events = b ; } ; FS . prototype . OnJSONLoaded = function ( a ) { DEBUG && console . assert ( a , "Invalid fs passed to OnJSONLoaded" ) ; a = JSON . parse ( a ) ; if ( a . version !== JSONFS_VERSION ) throw "The filesystem JSON format has changed. Please update your fs2json (https://github.com/copy/fs2json) and recreate the filesystem JSON." ; var b = a . fsroot ; this . used_size = a . size ; var c = this ; setTimeout ( function ( ) { for ( var a = 0 ; a < b . length ; a ++ ) c . LoadRecursive ( b [ a ] , 0 ) ; c . OnLoaded ( ) ; c . OnLoaded = function ( ) { } ; } , 0 ) ; } ; FS . prototype . LoadRecursive = function ( a , b ) { var c = this . CreateInode ( ) ; c . name = a [ JSONFS_IDX_NAME ] ; c . size = a [ JSONFS_IDX_SIZE ] ; c . mtime = a [ JSONFS_IDX_MTIME ] ; c . ctime = c . mtime ; c . atime = c . mtime ; c . mode = a [ JSONFS_IDX_MODE ] ; c . uid = a [ JSONFS_IDX_UID ] ; c . gid = a [ JSONFS_IDX_GID ] ; c . parentid = b ; this . inodes [ c . parentid ] . nlinks ++ ; b = c . mode & S_IFMT ; b === S_IFDIR ? this . LoadDir ( c , a [ JSONFS_IDX_TARGET ] ) : b === S_IFREG ? ( c . status = STATUS_ON_SERVER , this . PushInode ( c ) ) : b === S_IFLNK ? ( c . symlink = a [ JSONFS_IDX_TARGET ] , this . PushInode ( c ) ) : b !== S_IFSOCK && dbg_log ( "Unexpected ifmt: " + h ( b ) + " (" + c . name + ")" ) ; } ; FS . prototype . LoadDir = function ( a , b ) { a . updatedir = ! 0 ; a . nlinks = 2 ; var c = this . inodes . length ; this . PushInode ( a ) ; for ( a = 0 ; a < b . length ; a ++ ) this . LoadRecursive ( b [ a ] , c ) ; } ; FS . prototype . LoadFile = function ( a ) { var b = this . inodes [ a ] ; b . status == STATUS_ON_SERVER && ( b . status = STATUS_LOADING , this . filesinloadingqueue ++ , this . baseurl && LoadBinaryResource ( this . baseurl + this . GetFullPath ( b . fid ) , function ( c ) { c = this . inodedata [ a ] = new Uint8Array ( c ) ; b . size = c . length ; b . status = STATUS_OK ; this . filesinloadingqueue -- ; this . HandleEvent ( a ) ; } . bind ( this ) , function ( a ) { throw a ; } ) ) ; } ; FS . prototype . PushInode = function ( a ) { if ( - 1 != a . parentid ) { this . inodes . push ( a ) ; a . fid = this . inodes . length - 1 ; var b = this . inodes [ a . parentid ] ; b . updatedir = ! 0 ; a . nextid = b . firstid ; b . firstid = this . inodes . length - 1 ; } else 0 == this . inodes . length ? this . inodes . push ( a ) : ( message . Debug ( "Error in Filesystem: Pushed inode with name = " + a . name + " has no parent" ) , message . Abort ( ) ) ; } ; function Inode ( a ) { this . updatedir = ! 1 ; this . nextid = this . firstid = this . parentid = - 1 ; this . status = 0 ; this . name = "" ; this . minor = this . major = this . mtime = this . atime = this . ctime = this . fid = this . gid = this . uid = this . size = 0 ; this . symlink = "" ; this . nlinks = 1 ; this . mode = 493 ; this . qid = { type : 0 , version : 0 , path : a } ; this . caps = void 0 ; } FS . prototype . CreateInode = function ( ) { return new Inode ( ++ this . qidnumber ) ; } ; FS . prototype . CreateDirectory = function ( a , b ) { var c = this . CreateInode ( ) ; c . name = a ; c . parentid = b ; c . mode = 511 | S_IFDIR ; c . updatedir = ! 0 ; c . nlinks = 2 ; 0 <= b && ( c . uid = this . inodes [ b ] . uid , c . gid = this . inodes [ b ] . gid , c . mode = this . inodes [ b ] . mode & 511 | S_IFDIR , this . inodes [ b ] . nlinks ++ ) ; c . qid . type = S_IFDIR >> 8 ; this . PushInode ( c ) ; this . NotifyListeners ( this . inodes . length - 1 , "newdir" ) ; return this . inodes . length - 1 ; } ; FS . prototype . CreateFile = function ( a , b ) { var c = this . CreateInode ( ) ; c . name = a ; c . parentid = b ; c . uid = this . inodes [ b ] . uid ; c . gid = this . inodes [ b ] . gid ; this . inodes [ b ] . nlinks ++ ; c . qid . type = S_IFREG >> 8 ; c . mode = this . inodes [ b ] . mode & 438 | S_IFREG ; this . PushInode ( c ) ; this . NotifyListeners ( this . inodes . length - 1 , "newfile" ) ; return this . inodes . length - 1 ; } ; FS . prototype . CreateNode = function ( a , b , c , d ) { var e = this . CreateInode ( ) ; e . name = a ; e . parentid = b ; e . major = c ; e . minor = d ; e . uid = this . inodes [ b ] . uid ; e . gid = this . inodes [ b ] . gid ; this . inodes [ b ] . nlinks ++ ; e . qid . type = S_IFSOCK >> 8 ; e . mode = this . inodes [ b ] . mode & 438 ; this . PushInode ( e ) ; return this . inodes . length - 1 ; } ; FS . prototype . CreateSymlink = function ( a , b , c ) { var d = this . CreateInode ( ) ; d . name = a ; d . parentid = b ; d . uid = this . inodes [ b ] . uid ; d . gid = this . inodes [ b ] . gid ; this . inodes [ b ] . nlinks ++ ; d . qid . type = S_IFLNK >> 8 ; d . symlink = c ; d . mode = S_IFLNK ; this . PushInode ( d ) ; return this . inodes . length - 1 ; } ; FS . prototype . CreateTextFile = function ( a , b , c ) { a = this . CreateFile ( a , b ) ; var d = this . inodes [ a ] ; b = this . inodedata [ a ] = new Uint8Array ( c . length ) ; d . size = c . length ; for ( d = 0 ; d < c . length ; d ++ ) b [ d ] = c . charCodeAt ( d ) ; return a ; } ; FS . prototype . CreateBinaryFile = function ( a , b , c ) { a = this . CreateFile ( a , b ) ; b = this . inodes [ a ] ; ( this . inodedata [ a ] = new Uint8Array ( c . length ) ) . set ( c ) ; b . size = c . length ; return a ; } ; FS . prototype . OpenInode = function ( a , b ) { b = this . GetInode ( a ) ; ( b . mode & S_IFMT ) == S_IFDIR && this . FillDirectory ( a ) ; return b . status == STATUS_ON_SERVER ? ( this . LoadFile ( a ) , ! 1 ) : ! 0 ; } ; FS . prototype . CloseInode = function ( a ) { var b = this . GetInode ( a ) ; b . status == STATUS_UNLINKED && ( b . status = STATUS_INVALID , delete this . inodedata [ a ] , b . size = 0 ) ; } ; FS . prototype . Rename = function ( a , b , c , d ) { if ( a == c && b == d ) return ! 0 ; b = this . Search ( a , b ) ; var e = this . GetFullPath ( b ) ; if ( - 1 == b ) return ! 1 ; var g = this . Search ( c , d ) ; - 1 != g && this . Unlink ( g ) ; g = this . inodes [ b ] ; if ( this . inodes [ g . parentid ] . firstid == b ) this . inodes [ g . parentid ] . firstid = g . nextid ; else { var f = this . FindPreviousID ( b ) ; - 1 == f && ( message . Debug ( "Error in Filesystem: Cannot find previous id of inode" ) , message . Abort ( ) ) ; this . inodes [ f ] . nextid = g . nextid ; } g . parentid = c ; g . name = d ; g . qid . version ++ ; g . nextid = this . inodes [ g . parentid ] . firstid ; this . inodes [ g . parentid ] . firstid = b ; this . inodes [ a ] . updatedir = ! 0 ; this . inodes [ c ] . updatedir = ! 0 ; this . inodes [ a ] . nlinks -- ; this . inodes [ c ] . nlinks ++ ; this . NotifyListeners ( b , "rename" , { oldpath : e } ) ; return ! 0 ; } ; FS . prototype . Write = function ( a , b , c , d ) { this . NotifyListeners ( a , "write" ) ; var e = this . inodes [ a ] , g = this . inodedata [ a ] ; ! g || g . length < b + c ? ( this . ChangeSize ( a , Math . floor ( 3 * ( b + c ) / 2 ) ) , e . size = b + c , g = this . inodedata [ a ] ) : e . size < b + c && ( e . size = b + c ) ; for ( a = 0 ; a < c ; a ++ ) g [ b + a ] = d ( ) ; } ; FS . prototype . Search = function ( a , b ) { for ( var c = this . inodes [ a ] . firstid ; - 1 != c ; ) { this . inodes [ c ] . parentid != a && message . Debug ( "Error in Filesystem: Found inode with wrong parent id" ) ; if ( this . inodes [ c ] . name == b ) return c ; c = this . inodes [ c ] . nextid ; } return - 1 ; } ; FS . prototype . GetTotalSize = function ( ) { return this . used_size ; } ; FS . prototype . GetSpace = function ( ) { return this . total_size ; } ; FS . prototype . GetFullPath = function ( a ) { for ( var b = "" ; 0 != a ; ) b = "/" + this . inodes [ a ] . name + b , a = this . inodes [ a ] . parentid ; return b . substring ( 1 ) ; } ; FS . prototype . FindPreviousID = function ( a ) { var b = this . GetInode ( a ) ; for ( b = this . inodes [ b . parentid ] . firstid ; - 1 != b && this . inodes [ b ] . nextid != a ; ) b = this . inodes [ b ] . nextid ; return b ; } ; FS . prototype . Unlink = function ( a ) { this . NotifyListeners ( a , "delete" ) ; if ( 0 == a ) return ! 1 ; var b = this . GetInode ( a ) ; if ( ( b . mode & S_IFMT ) == S_IFDIR && - 1 != b . firstid ) return ! 1 ; this . inodes [ b . parentid ] . firstid == a ? this . inodes [ b . parentid ] . firstid = b . nextid : ( a = this . FindPreviousID ( a ) , - 1 == a && ( message . Debug ( "Error in Filesystem: Cannot find previous id of inode" ) , message . Abort ( ) ) , this . inodes [ a ] . nextid = b . nextid ) ; this . inodes [ b . parentid ] . updatedir = ! 0 ; this . inodes [ b . parentid ] . nlinks -- ; b . status = STATUS_UNLINKED ; b . nextid = - 1 ; b . firstid = - 1 ; b . parentid = - 1 ; b . nlinks -- ; return ! 0 ; } ; FS . prototype . GetInode = function ( a ) { return isNaN ( a ) ? ( message . Debug ( "Error in filesystem: id is not a number " ) , 0 ) : 0 > a || a > this . inodes . length ? ( message . Debug ( "Error in filesystem: Attempt to get inode with id " + a ) , 0 ) : this . inodes [ a ] ; } ; FS . prototype . ChangeSize = function ( a , b ) { var c = this . GetInode ( a ) , d = this . inodedata [ a ] ; if ( b != c . size && ( a = this . inodedata [ a ] = new Uint8Array ( b ) , c . size = b , d ) ) for ( b = Math . min ( d . length , c . size ) , c = 0 ; c < b ; c ++ ) a [ c ] = d [ c ] ; } ; FS . prototype . SearchPath = function ( a ) { a = a . replace ( "//" , "/" ) ; a = a . split ( "/" ) ; var b = a . length ; 0 == a [ b - 1 ] . length && a . pop ( ) ; 0 == a [ 0 ] . length && a . shift ( ) ; b = a . length ; for ( var c = 0 , d = - 1 , e = 0 ; e < b ; e ++ ) { d = this . Search ( c , a [ e ] ) ; if ( - 1 == d ) return e < b - 1 ? { id : - 1 , parentid : - 1 , name : a [ e ] } : { id : - 1 , parentid : c , name : a [ e ] } ; c = d ; } return { id : d , parentid : c , name : a [ e ] } ; } ; FS . prototype . GetRecursiveList = function ( a , b ) { for ( a = this . inodes [ a ] . firstid ; - 1 != a ; ) b . push ( a ) , ( this . inodes [ a ] . mode & S_IFMT ) == S_IFDIR && this . GetRecursiveList ( a , b ) , a = this . inodes [ a ] . nextid ; } ; FS . prototype . MergeFile = function ( a ) { message . Debug ( "Merge path:" + a . name ) ; var b = this . SearchPath ( a . name ) ; - 1 != b . parentid && ( - 1 == b . id && ( b . id = this . CreateFile ( b . name , b . parentid ) ) , this . inodes [ b . id ] . data = a . data , this . inodes [ b . id ] . size = a . data . length , this . inodes [ b . id ] . mtime = Math . floor ( ( new Date ) . getTime ( ) / 1E3 ) , this . inodes [ b . id ] . atime = this . inodes [ b . id ] . mtime , this . inodes [ b . id ] . ctime = this . inodes [ b . id ] . mtime ) ; } ; FS . prototype . RecursiveDelete = function ( a ) { var b = [ ] ; a = this . SearchPath ( a ) ; if ( - 1 != a . parentid && - 1 != a . id ) for ( this . GetRecursiveList ( a . id , b ) , a = b . length - 1 ; 0 <= a ; a -- ) this . Unlink ( b [ a ] ) ; } ; FS . prototype . DeleteNode = function ( a ) { a = this . SearchPath ( a ) ; if ( - 1 != a . parentid && - 1 != a . id ) if ( ( this . inodes [ a . id ] . mode & S_IFMT ) == S_IFREG ) this . Unlink ( a . id ) ; else if ( ( this . inodes [ a . id ] . mode & S_IFMT ) == S_IFDIR ) { var b = [ ] ; this . GetRecursiveList ( a . id , b ) ; for ( var c = b . length - 1 ; 0 <= c ; c -- ) this . Unlink ( b [ c ] ) ; this . Unlink ( a . id ) ; } } ; FS . prototype . NotifyListeners = function ( a , b , c ) { } ; FS . prototype . Check = function ( ) { for ( var a = 1 ; a < this . inodes . length ; a ++ ) if ( this . inodes [ a ] . status != STATUS_INVALID ) { this . inodes [ a ] . nextid == a && ( message . Debug ( "Error in filesystem: file points to itself" ) , message . Abort ( ) ) ; var b = this . GetInode ( a ) ; 0 > b . parentid && message . Debug ( "Error in filesystem: negative parent id " + a ) ; 0 == b . name . length && message . Debug ( "Error in filesystem: inode with no name and id " + a ) ; for ( var c in b . name ) 32 > b . name . charCodeAt ( c ) && message . Debug ( "Error in filesystem: Unallowed char in filename" ) ; } } ; FS . prototype . FillDirectory = function ( a ) { var b = this . GetInode ( a ) ; if ( b . updatedir ) { var c = b . parentid ; - 1 == c && ( c = 0 ) ; for ( var d = 0 , e = this . inodes [ a ] . firstid ; - 1 != e ; ) d += 24 + UTF8 . UTF8Length ( this . inodes [ e ] . name ) , e = this . inodes [ e ] . nextid ; d = d + 25 + 26 ; var g = this . inodedata [ a ] = new Uint8Array ( d ) ; b . size = d ; d = 0 ; d += marshall . Marshall ( [ "Q" , "d" , "b" , "s" ] , [ this . inodes [ a ] . qid , d + 13 + 8 + 1 + 2 + 1 , this . inodes [ a ] . mode >> 12 , "." ] , g , d ) ; d += marshall . Marshall ( [ "Q" , "d" , "b" , "s" ] , [ this . inodes [ c ] . qid , d + 13 + 8 + 1 + 2 + 2 , this . inodes [ c ] . mode >> 12 , ".." ] , g , d ) ; for ( e = this . inodes [ a ] . firstid ; - 1 != e ; ) d += marshall . Marshall ( [ "Q" , "d" , "b" , "s" ] , [ this . inodes [ e ] . qid , d + 13 + 8 + 1 + 2 + UTF8 . UTF8Length ( this . inodes [ e ] . name ) , this . inodes [ e ] . mode >> 12 , this . inodes [ e ] . name ] , g , d ) , e = this . inodes [ e ] . nextid ; b . updatedir = ! 1 ; } } ; FS . prototype . PrepareCAPs = function ( a ) { a = this . GetInode ( a ) ; if ( a . caps ) return a . caps . length ; a . caps = new Uint8Array ( 12 ) ; a . caps [ 0 ] = 0 ; a . caps [ 1 ] = 0 ; a . caps [ 2 ] = 0 ; a . caps [ 3 ] = 1 ; a . caps [ 4 ] = 255 ; a . caps [ 5 ] = 255 ; a . caps [ 6 ] = 255 ; a . caps [ 7 ] = 255 ; a . caps [ 8 ] = 255 ; a . caps [ 9 ] = 255 ; a . caps [ 10 ] = 255 ; a . caps [ 11 ] = 255 ; return a . caps . length ; } ; var VIRTIO_MAGIC_REG = 0 , VIRTIO_VERSION_REG = 4 , VIRTIO_DEVICE_REG = 8 , VIRTIO_VENDOR_REG = 12 , VIRTIO_HOSTFEATURES_REG = 16 , VIRTIO_HOSTFEATURESSEL_REG = 20 , VIRTIO_GUESTFEATURES_REG = 32 , VIRTIO_GUESTFEATURESSEL_REG = 36 , VIRTIO_GUEST_PAGE_SIZE_REG = 40 , VIRTIO_QUEUESEL_REG = 48 , VIRTIO_QUEUENUMMAX_REG = 52 , VIRTIO_QUEUENUM_REG = 56 , VIRTIO_QUEUEALIGN_REG = 60 , VIRTIO_QUEUEPFN_REG = 64 , VIRTIO_QUEUENOTIFY_REG = 80 , VIRTIO_INTERRUPTSTATUS_REG = 96 , VIRTIO_INTERRUPTACK_REG = 100 , VIRTIO_STATUS_REG = 112 , VRING_DESC_F_NEXT = 1 , VRING_DESC_F_WRITE = 2 , VRING_DESC_F_INDIRECT = 4 ; function hex8 ( a ) { return h ( a ) ; } var message = { Debug : function ( a ) { dbg_log ( [ ] . slice . apply ( arguments ) . join ( " " ) , LOG_9P ) ; } , Abort : function ( ) { if ( DEBUG ) throw "abort" ; } } , LoadBinaryResource ; LoadBinaryResource = "undefined" !== typeof XMLHttpRequest ? function ( a , b , c ) { var d = new XMLHttpRequest ; d . open ( "GET" , a , ! 0 ) ; d . responseType = "arraybuffer" ; d . onreadystatechange = function ( ) { if ( 4 == d . readyState ) if ( 200 != d . status && 0 != d . status ) c ( "Error: Could not load file " + a ) ; else { var e = d . response ; e ? b ( e ) : c ( "Error: No data received from: " + a ) ; } } ; d . send ( null ) ; } : function ( a , b , c ) { require ( "fs" ) . readFile ( a , function ( a , e ) { a ? c ( a ) : b ( ( new Uint8Array ( e ) ) . buffer ) ; } ) ; } ; var marshall = { Marshall : function ( a , b , c , d ) { for ( var e , g = 0 , f = 0 ; f < a . length ; f ++ ) switch ( e = b [ f ] , a [ f ] ) { case "w" : c [ d ++ ] = e & 255 ; c [ d ++ ] = e >> 8 & 255 ; c [ d ++ ] = e >> 16 & 255 ; c [ d ++ ] = e >> 24 & 255 ; g += 4 ; break ; case "d" : c [ d ++ ] = e & 255 ; c [ d ++ ] = e >> 8 & 255 ; c [ d ++ ] = e >> 16 & 255 ; c [ d ++ ] = e >> 24 & 255 ; c [ d ++ ] = 0 ; c [ d ++ ] = 0 ; c [ d ++ ] = 0 ; c [ d ++ ] = 0 ; g += 8 ; break ; case "h" : c [ d ++ ] = e & 255 ; c [ d ++ ] = e >> 8 ; g += 2 ; break ; case "b" : c [ d ++ ] = e ; g += 1 ; break ; case "s" : var k = d , l = 0 ; c [ d ++ ] = 0 ; c [ d ++ ] = 0 ; g += 2 ; for ( var m in e ) UnicodeToUTF8Stream ( e . charCodeAt ( m ) ) . forEach ( function ( a ) { c [ d ++ ] = a ; g += 1 ; l ++ ; } ) ; c [ k + 0 ] = l & 255 ; c [ k + 1 ] = l >> 8 & 255 ; break ; case "Q" : marshall . Marshall ( [ "b" , "w" , "d" ] , [ e . type , e . version , e . path ] , c , d ) ; d += 13 ; g += 13 ; break ; default : message . Debug ( "Marshall: Unknown type=" + a [ f ] ) ; } return g ; } , Unmarshall : function ( a , b , c ) { for ( var d = [ ] , e = 0 ; e < a . length ; e ++ ) switch ( a [ e ] ) { case "w" : var g = b [ c ++ ] ; g += b [ c ++ ] << 8 ; g += b [ c ++ ] << 16 ; g += b [ c ++ ] << 24 >>> 0 ; d . push ( g ) ; break ; case "d" : g = b [ c ++ ] ; g += b [ c ++ ] << 8 ; g += b [ c ++ ] << 16 ; g += b [ c ++ ] << 24 >>> 0 ; c += 4 ; d . push ( g ) ; break ; case "h" : g = b [ c ++ ] ; d . push ( g + ( b [ c ++ ] << 8 ) ) ; break ; case "b" : d . push ( b [ c ++ ] ) ; break ; case "s" : g = b [ c ++ ] ; g += b [ c ++ ] << 8 ; for ( var f = "" , k = new UTF8StreamToUnicode , l = 0 ; l < g ; l ++ ) { var m = k . Put ( b [ c ++ ] ) ; - 1 != m && ( f += String . fromCharCode ( m ) ) ; } d . push ( f ) ; break ; default : message . Debug ( "Error in Unmarshall: Unknown type=" + a [ e ] ) ; } return d ; } , Unmarshall2 : function ( a , b ) { for ( var c = [ ] , d = 0 ; d < a . length ; d ++ ) switch ( a [ d ] ) { case "w" : var e = b ( ) ; e += b ( ) << 8 ; e += b ( ) << 16 ; e += b ( ) << 24 >>> 0 ; c . push ( e ) ; break ; case "d" : e = b ( ) ; e += b ( ) << 8 ; e += b ( ) << 16 ; e += b ( ) << 24 >>> 0 ; b ( ) ; b ( ) ; b ( ) ; b ( ) ; c . push ( e ) ; break ; case "h" : e = b ( ) ; c . push ( e + ( b ( ) << 8 ) ) ; break ; case "b" : c . push ( b ( ) ) ; break ; case "s" : e = b ( ) ; e += b ( ) << 8 ; for ( var g = "" , f = new UTF8StreamToUnicode , k = 0 ; k < e ; k ++ ) { var l = f . Put ( b ( ) ) ; - 1 != l && ( g += String . fromCharCode ( l ) ) ; } c . push ( g ) ; break ; default : message . Debug ( "Error in Unmarshall2: Unknown type=" + a [ d ] ) ; } return c ; } } ; var UTF8 = { } ; function UTF8StreamToUnicode ( ) { this . stream = new Uint8Array ( 5 ) ; this . ofs = 0 ; this . Put = function ( a ) { this . stream [ this . ofs ] = a ; this . ofs ++ ; switch ( this . ofs ) { case 1 : if ( 128 > this . stream [ 0 ] ) return this . ofs = 0 , this . stream [ 0 ] ; break ; case 2 : if ( 192 == ( this . stream [ 0 ] & 224 ) && 128 == ( this . stream [ 1 ] & 192 ) ) return this . ofs = 0 , ( this . stream [ 0 ] & 31 ) << 6 | this . stream [ 1 ] & 63 ; } return - 1 ; } ; } function UnicodeToUTF8Stream ( a ) { if ( 128 > a ) return [ a ] ; if ( 2048 > a ) return [ 192 | a >> 6 & 31 , 128 | a & 63 ] ; } UTF8 . UTF8Length = function ( a ) { for ( var b = 0 , c = 0 ; c < a . length ; c ++ ) { var d = a . charCodeAt ( c ) ; b += 128 > d ? 1 : 2 ; } return b ; } ; } ) . call ( this ) ;