├── CMOS.js ├── KBD.js ├── LICENSE ├── PCEmulator.js ├── PIC.js ├── PIT.js ├── Serial.js ├── clipboard.js ├── cpux86-ta.js ├── cpux86-ta.original.js ├── index.html ├── jslinux.js ├── linuxstart-20110820.tar.gz ├── linuxstart.bin ├── readme.md ├── refactoring_hacks ├── Opcodes.txt ├── autocomments.py ├── js-change-symbol.el ├── onebyte_dict.json ├── reify.js ├── twobyte_dict.json └── x86reference.xml ├── root.bin ├── term.js └── vmlinux-2.6.20.bin /CMOS.js: -------------------------------------------------------------------------------- 1 | /* 2 | JSLinux-deobfuscated - An annotated version of the original JSLinux. 3 | 4 | Original is Copyright (c) 2011-2012 Fabrice Bellard 5 | Redistribution or commercial use is prohibited without the author's permission. 6 | 7 | CMOS Ram Memory, actually just the RTC Clock Emulator 8 | 9 | Useful references: 10 | ------------------ 11 | http://www.bioscentral.com/misc/cmosmap.htm 12 | http://wiki.osdev.org/CMOS 13 | */ 14 | 15 | /* 16 | In this implementation, bytes are stored in the RTC in BCD format 17 | binary -> bcd: bcd = ((bin / 10) << 4) | (bin % 10) 18 | bcd -> binary: bin = ((bcd / 16) * 10) + (bcd & 0xf) 19 | */ 20 | function bin_to_bcd(a) { return ((a / 10) << 4) | (a % 10);} 21 | 22 | function CMOS(PC) { 23 | var time_array, d; 24 | time_array = new Uint8Array(128); 25 | this.cmos_data = time_array; 26 | this.cmos_index = 0; 27 | d = new Date(); 28 | time_array[0] = bin_to_bcd(d.getUTCSeconds()); 29 | time_array[2] = bin_to_bcd(d.getUTCMinutes()); 30 | time_array[4] = bin_to_bcd(d.getUTCHours()); 31 | time_array[6] = bin_to_bcd(d.getUTCDay()); 32 | time_array[7] = bin_to_bcd(d.getUTCDate()); 33 | time_array[8] = bin_to_bcd(d.getUTCMonth() + 1); 34 | time_array[9] = bin_to_bcd(d.getUTCFullYear() % 100); 35 | time_array[10] = 0x26; 36 | time_array[11] = 0x02; 37 | time_array[12] = 0x00; 38 | time_array[13] = 0x80; 39 | time_array[0x14] = 0x02; 40 | PC.register_ioport_write(0x70, 2, 1, this.ioport_write.bind(this)); 41 | PC.register_ioport_read(0x70, 2, 1, this.ioport_read.bind(this)); 42 | } 43 | CMOS.prototype.ioport_write = function(mem8_loc, data) { 44 | if (mem8_loc == 0x70) { 45 | // the high order bit is used to indicate NMI masking 46 | // low order bits are used to address CMOS 47 | // the index written here is used on an ioread 0x71 48 | this.cmos_index = data & 0x7f; 49 | } 50 | }; 51 | CMOS.prototype.ioport_read = function(mem8_loc) { 52 | var data; 53 | if (mem8_loc == 0x70) { 54 | return 0xff; 55 | } else { 56 | // else here => 0x71, i.e., CMOS read 57 | data = this.cmos_data[this.cmos_index]; 58 | if (this.cmos_index == 10) 59 | // flip the UIP (update in progress) bit on a read 60 | this.cmos_data[10] ^= 0x80; 61 | else if (this.cmos_index == 12) 62 | // Always return interrupt status == 0 63 | this.cmos_data[12] = 0x00; 64 | return data; 65 | } 66 | }; 67 | -------------------------------------------------------------------------------- /KBD.js: -------------------------------------------------------------------------------- 1 | /* 2 | JSLinux-deobfuscated - An annotated version of the original JSLinux. 3 | 4 | Original is Copyright (c) 2011-2012 Fabrice Bellard 5 | Redistribution or commercial use is prohibited without the author's permission. 6 | 7 | Keyboard Device Emulator 8 | */ 9 | function KBD(PC, reset_callback) { 10 | PC.register_ioport_read(0x64, 1, 1, this.read_status.bind(this)); 11 | PC.register_ioport_write(0x64, 1, 1, this.write_command.bind(this)); 12 | this.reset_request = reset_callback; 13 | } 14 | KBD.prototype.read_status = function(mem8_loc) { 15 | return 0; 16 | }; 17 | KBD.prototype.write_command = function(mem8_loc, x) { 18 | switch (x) { 19 | case 0xfe: // Resend command. Other commands are, apparently, ignored. 20 | this.reset_request(); 21 | break; 22 | default: 23 | break; 24 | } 25 | }; 26 | 27 | 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is a derivative work of JSLinux and is posted here with permission of the author. 2 | 3 | JSLinux is Copyright (c) 2011-2013 Fabrice Bellard 4 | Redistribution or commercial use is prohibited without the author's permission. 5 | -------------------------------------------------------------------------------- /PCEmulator.js: -------------------------------------------------------------------------------- 1 | /* 2 | JSLinux-deobfuscated - An annotated version of the original JSLinux. 3 | 4 | Original is Copyright (c) 2011-2012 Fabrice Bellard 5 | Redistribution or commercial use is prohibited without the author's permission. 6 | 7 | Main PC Emulator Routine 8 | */ 9 | 10 | // used as callback wrappers for emulated PIT and PIC chips 11 | function set_hard_irq_wrapper(irq) { this.hard_irq = irq;} 12 | function return_cycle_count() { return this.cycle_count; } 13 | 14 | function PCEmulator(params) { 15 | var cpu; 16 | cpu = new CPU_X86(); 17 | this.cpu = cpu; 18 | cpu.phys_mem_resize(params.mem_size); 19 | this.init_ioports(); 20 | this.register_ioport_write(0x80, 1, 1, this.ioport80_write); 21 | this.pic = new PIC_Controller(this, 0x20, 0xa0, set_hard_irq_wrapper.bind(cpu)); 22 | this.pit = new PIT(this, this.pic.set_irq.bind(this.pic, 0), return_cycle_count.bind(cpu)); 23 | this.cmos = new CMOS(this); 24 | this.serial = new Serial(this, 0x3f8, this.pic.set_irq.bind(this.pic, 4), params.serial_write); 25 | this.kbd = new KBD(this, this.reset.bind(this)); 26 | this.reset_request = 0; 27 | if (params.clipboard_get && params.clipboard_set) { 28 | this.jsclipboard = new clipboard_device(this, 0x3c0, params.clipboard_get, params.clipboard_set, params.get_boot_time); 29 | } 30 | cpu.ld8_port = this.ld8_port.bind(this); 31 | cpu.ld16_port = this.ld16_port.bind(this); 32 | cpu.ld32_port = this.ld32_port.bind(this); 33 | cpu.st8_port = this.st8_port.bind(this); 34 | cpu.st16_port = this.st16_port.bind(this); 35 | cpu.st32_port = this.st32_port.bind(this); 36 | cpu.get_hard_intno = this.pic.get_hard_intno.bind(this.pic); 37 | } 38 | 39 | PCEmulator.prototype.load_binary = function(binary_array, mem8_loc) { return this.cpu.load_binary(binary_array, mem8_loc); }; 40 | 41 | PCEmulator.prototype.start = function() { setTimeout(this.timer_func.bind(this), 10); }; 42 | 43 | PCEmulator.prototype.timer_func = function() { 44 | var exit_status, Ncycles, do_reset, err_on_exit, PC, cpu; 45 | PC = this; 46 | cpu = PC.cpu; 47 | Ncycles = cpu.cycle_count + 100000; 48 | 49 | do_reset = false; 50 | err_on_exit = false; 51 | 52 | exec_loop: while (cpu.cycle_count < Ncycles) { 53 | PC.pit.update_irq(); 54 | exit_status = cpu.exec(Ncycles - cpu.cycle_count); 55 | if (exit_status == 256) { 56 | if (PC.reset_request) { 57 | do_reset = true; 58 | break; 59 | } 60 | } else if (exit_status == 257) { 61 | err_on_exit = true; 62 | break; 63 | } else { 64 | do_reset = true; 65 | break; 66 | } 67 | } 68 | if (!do_reset) { 69 | if (err_on_exit) { 70 | setTimeout(this.timer_func.bind(this), 10); 71 | } else { 72 | setTimeout(this.timer_func.bind(this), 0); 73 | } 74 | } 75 | }; 76 | 77 | PCEmulator.prototype.init_ioports = function() { 78 | var i, readw, writew; 79 | this.ioport_readb_table = new Array(); 80 | this.ioport_writeb_table = new Array(); 81 | this.ioport_readw_table = new Array(); 82 | this.ioport_writew_table = new Array(); 83 | this.ioport_readl_table = new Array(); 84 | this.ioport_writel_table = new Array(); 85 | readw = this.default_ioport_readw.bind(this); 86 | writew = this.default_ioport_writew.bind(this); 87 | for (i = 0; i < 1024; i++) { 88 | this.ioport_readb_table[i] = this.default_ioport_readb; 89 | this.ioport_writeb_table[i] = this.default_ioport_writeb; 90 | this.ioport_readw_table[i] = readw; 91 | this.ioport_writew_table[i] = writew; 92 | this.ioport_readl_table[i] = this.default_ioport_readl; 93 | this.ioport_writel_table[i] = this.default_ioport_writel; 94 | } 95 | }; 96 | 97 | PCEmulator.prototype.default_ioport_readb = function(port_num) { 98 | var x; 99 | x = 0xff; 100 | return x; 101 | }; 102 | 103 | PCEmulator.prototype.default_ioport_readw = function(port_num) { 104 | var x; 105 | x = this.ioport_readb_table[port_num](port_num); 106 | port_num = (port_num + 1) & (1024 - 1); 107 | x |= this.ioport_readb_table[port_num](port_num) << 8; 108 | return x; 109 | }; 110 | 111 | PCEmulator.prototype.default_ioport_readl = function(port_num) { 112 | var x; 113 | x = -1; 114 | return x; 115 | }; 116 | 117 | PCEmulator.prototype.default_ioport_writeb = function(port_num, x) {}; 118 | 119 | PCEmulator.prototype.default_ioport_writew = function(port_num, x) { 120 | this.ioport_writeb_table[port_num](port_num, x & 0xff); 121 | port_num = (port_num + 1) & (1024 - 1); 122 | this.ioport_writeb_table[port_num](port_num, (x >> 8) & 0xff); 123 | }; 124 | 125 | PCEmulator.prototype.default_ioport_writel = function(port_num, x) {}; 126 | 127 | PCEmulator.prototype.ld8_port = function(port_num) { 128 | var x; 129 | x = this.ioport_readb_table[port_num & (1024 - 1)](port_num); 130 | return x; 131 | }; 132 | 133 | PCEmulator.prototype.ld16_port = function(port_num) { 134 | var x; 135 | x = this.ioport_readw_table[port_num & (1024 - 1)](port_num); 136 | return x; 137 | }; 138 | 139 | PCEmulator.prototype.ld32_port = function(port_num) { 140 | var x; 141 | x = this.ioport_readl_table[port_num & (1024 - 1)](port_num); 142 | return x; 143 | }; 144 | 145 | PCEmulator.prototype.st8_port = function(port_num, x) { this.ioport_writeb_table[port_num & (1024 - 1)](port_num, x); }; 146 | PCEmulator.prototype.st16_port = function(port_num, x) { this.ioport_writew_table[port_num & (1024 - 1)](port_num, x); }; 147 | PCEmulator.prototype.st32_port = function(port_num, x) { this.ioport_writel_table[port_num & (1024 - 1)](port_num, x); }; 148 | 149 | PCEmulator.prototype.register_ioport_read = function(start, len, iotype, io_callback) { 150 | var i; 151 | switch (iotype) { 152 | case 1: 153 | for (i = start; i < start + len; i++) { 154 | this.ioport_readb_table[i] = io_callback; 155 | } 156 | break; 157 | case 2: 158 | for (i = start; i < start + len; i += 2) { 159 | this.ioport_readw_table[i] = io_callback; 160 | } 161 | break; 162 | case 4: 163 | for (i = start; i < start + len; i += 4) { 164 | this.ioport_readl_table[i] = io_callback; 165 | } 166 | break; 167 | } 168 | }; 169 | 170 | PCEmulator.prototype.register_ioport_write = function(start, len, iotype, io_callback) { 171 | var i; 172 | switch (iotype) { 173 | case 1: 174 | for (i = start; i < start + len; i++) { 175 | this.ioport_writeb_table[i] = io_callback; 176 | } 177 | break; 178 | case 2: 179 | for (i = start; i < start + len; i += 2) { 180 | this.ioport_writew_table[i] = io_callback; 181 | } 182 | break; 183 | case 4: 184 | for (i = start; i < start + len; i += 4) { 185 | this.ioport_writel_table[i] = io_callback; 186 | } 187 | break; 188 | } 189 | }; 190 | 191 | PCEmulator.prototype.ioport80_write = function(mem8_loc, data) {}; //POST codes! Seem to be ignored? 192 | PCEmulator.prototype.reset = function() { this.request_request = 1; }; 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /PIC.js: -------------------------------------------------------------------------------- 1 | /* 2 | JSLinux-deobfuscated - An annotated version of the original JSLinux. 3 | 4 | Original is Copyright (c) 2011-2012 Fabrice Bellard 5 | Redistribution or commercial use is prohibited without the author's permission. 6 | 7 | 8259A PIC (Programmable Interrupt Controller) Emulation Code 8 | 9 | The 8259 combines multiple interrupt input sources into a single 10 | interrupt output to the host microprocessor, extending the interrupt 11 | levels available in a system beyond the one or two levels found on the 12 | processor chip. 13 | 14 | There are three registers, an Interrupt Mask Register (IMR), an 15 | Interrupt Request Register (IRR), and an In-Service Register 16 | (ISR): 17 | IRR - a mask of the current interrupts that are pending acknowledgement 18 | ISR - a mask of the interrupts that are pending an EOI 19 | IMR - a mask of interrupts that should not be sent an acknowledgement 20 | 21 | End Of Interrupt (EOI) operations support specific EOI, non-specific 22 | EOI, and auto-EOI. A specific EOI specifies the IRQ level it is 23 | acknowledging in the ISR. A non-specific EOI resets the IRQ level in 24 | the ISR. Auto-EOI resets the IRQ level in the ISR immediately after 25 | the interrupt is acknowledged. 26 | 27 | After the IBM XT, it was decided that 8 IRQs was not enough. 28 | The backwards-compatible solution was simply to chain two 8259As together, 29 | the master and slave PIC. 30 | 31 | Useful References 32 | ----------------- 33 | https://en.wikipedia.org/wiki/Programmable_Interrupt_Controller 34 | https://en.wikipedia.org/wiki/Intel_8259 35 | http://www.thesatya.com/8259.html 36 | */ 37 | 38 | /* 39 | Common PC arrangements of IRQ lines: 40 | ------------------------------------ 41 | 42 | PC/AT and later systems had two 8259 controllers, master and 43 | slave. IRQ0 through IRQ7 are the master 8259's interrupt lines, while 44 | IRQ8 through IRQ15 are the slave 8259's interrupt lines. The labels on 45 | the pins on an 8259 are IR0 through IR7. IRQ0 through IRQ15 are the 46 | names of the ISA bus's lines to which the 8259s are attached. 47 | 48 | Master 8259 49 | IRQ0 – Intel 8253 or Intel 8254 Programmable Interval Timer, aka the system timer 50 | IRQ1 – Intel 8042 keyboard controller 51 | IRQ2 – not assigned in PC/XT; cascaded to slave 8259 INT line in PC/AT 52 | IRQ3 – 8250 UART serial ports 2 and 4 53 | IRQ4 – 8250 UART serial ports 1 and 3 54 | IRQ5 – hard disk controller in PC/XT; Intel 8255 parallel ports 2 and 3 in PC/AT 55 | IRQ6 – Intel 82072A floppy disk controller 56 | IRQ7 – Intel 8255 parallel port 1 / spurious interrupt 57 | 58 | Slave 8259 (PC/AT and later only) 59 | IRQ8 – real-time clock (RTC) 60 | IRQ9 – no common assignment, but 8-bit cards' IRQ2 line is routed to this interrupt. 61 | IRQ10 – no common assignment 62 | IRQ11 – no common assignment 63 | IRQ12 – Intel 8042 PS/2 mouse controller 64 | IRQ13 – math coprocessor 65 | IRQ14 – hard disk controller 1 66 | IRQ15 – hard disk controller 2 67 | */ 68 | 69 | function PIC(PC, port_num) { 70 | PC.register_ioport_write(port_num, 2, 1, this.ioport_write.bind(this)); 71 | PC.register_ioport_read(port_num, 2, 1, this.ioport_read.bind(this)); 72 | this.reset(); 73 | } 74 | PIC.prototype.reset = function() { 75 | this.last_irr = 0; 76 | this.irr = 0; //Interrupt Request Register 77 | this.imr = 0; //Interrupt Mask Register 78 | this.isr = 0; //In-Service Register 79 | this.priority_add = 0; 80 | this.irq_base = 0; 81 | this.read_reg_select = 0; 82 | this.special_mask = 0; 83 | this.init_state = 0; 84 | this.auto_eoi = 0; 85 | this.rotate_on_autoeoi = 0; 86 | this.init4 = 0; 87 | this.elcr = 0; // Edge/Level Control Register 88 | this.elcr_mask = 0; 89 | }; 90 | PIC.prototype.set_irq1 = function(irq, Qf) { 91 | var ir_register; 92 | ir_register = 1 << irq; 93 | if (Qf) { 94 | if ((this.last_irr & ir_register) == 0) 95 | this.irr |= ir_register; 96 | this.last_irr |= ir_register; 97 | } else { 98 | this.last_irr &= ~ir_register; 99 | } 100 | }; 101 | /* 102 | The priority assignments for IRQ0-7 seem to be maintained in a 103 | cyclic order modulo 8 by the 8259A. On bootup, it default to: 104 | 105 | Priority: 0 1 2 3 4 5 6 7 106 | IRQ: 7 6 5 4 3 2 1 0 107 | 108 | but can be rotated automatically or programmatically to a state e.g.: 109 | 110 | Priority: 5 6 7 0 1 2 3 4 111 | IRQ: 7 6 5 4 3 2 1 0 112 | */ 113 | PIC.prototype.get_priority = function(ir_register) { 114 | var priority; 115 | if (ir_register == 0) 116 | return -1; 117 | priority = 7; 118 | while ((ir_register & (1 << ((priority + this.priority_add) & 7))) == 0) 119 | priority--; 120 | return priority; 121 | }; 122 | PIC.prototype.get_irq = function() { 123 | var ir_register, in_service_priority, priority; 124 | ir_register = this.irr & ~this.imr; 125 | priority = this.get_priority(ir_register); 126 | if (priority < 0) 127 | return -1; 128 | in_service_priority = this.get_priority(this.isr); 129 | if (priority > in_service_priority) { 130 | return priority; 131 | } else { 132 | return -1; 133 | } 134 | }; 135 | PIC.prototype.intack = function(irq) { 136 | if (this.auto_eoi) { 137 | if (this.rotate_on_auto_eoi) 138 | this.priority_add = (irq + 1) & 7; 139 | } else { 140 | this.isr |= (1 << irq); 141 | } 142 | if (!(this.elcr & (1 << irq))) 143 | this.irr &= ~(1 << irq); 144 | }; 145 | PIC.prototype.ioport_write = function(mem8_loc, x) { 146 | var priority; 147 | mem8_loc &= 1; 148 | if (mem8_loc == 0) { 149 | if (x & 0x10) { 150 | /* 151 | ICW1 152 | // 7:5 = address (if MCS-80/85 mode) 153 | // 4 == 1 154 | // 3: 1 == level triggered, 0 == edge triggered 155 | // 2: 1 == call interval 4, 0 == call interval 8 156 | // 1: 1 == single PIC, 0 == cascaded PICs 157 | // 0: 1 == send ICW4 158 | 159 | */ 160 | this.reset(); 161 | this.init_state = 1; 162 | this.init4 = x & 1; 163 | if (x & 0x02) 164 | throw "single mode not supported"; 165 | if (x & 0x08) 166 | throw "level sensitive irq not supported"; 167 | } else if (x & 0x08) { 168 | if (x & 0x02) 169 | this.read_reg_select = x & 1; 170 | if (x & 0x40) 171 | this.special_mask = (x >> 5) & 1; 172 | } else { 173 | switch (x) { 174 | case 0x00: 175 | case 0x80: 176 | this.rotate_on_autoeoi = x >> 7; 177 | break; 178 | case 0x20: 179 | case 0xa0: 180 | priority = this.get_priority(this.isr); 181 | if (priority >= 0) { 182 | this.isr &= ~(1 << ((priority + this.priority_add) & 7)); 183 | } 184 | if (x == 0xa0) 185 | this.priority_add = (this.priority_add + 1) & 7; 186 | break; 187 | case 0x60: 188 | case 0x61: 189 | case 0x62: 190 | case 0x63: 191 | case 0x64: 192 | case 0x65: 193 | case 0x66: 194 | case 0x67: 195 | priority = x & 7; 196 | this.isr &= ~(1 << priority); 197 | break; 198 | case 0xc0: 199 | case 0xc1: 200 | case 0xc2: 201 | case 0xc3: 202 | case 0xc4: 203 | case 0xc5: 204 | case 0xc6: 205 | case 0xc7: 206 | this.priority_add = (x + 1) & 7; 207 | break; 208 | case 0xe0: 209 | case 0xe1: 210 | case 0xe2: 211 | case 0xe3: 212 | case 0xe4: 213 | case 0xe5: 214 | case 0xe6: 215 | case 0xe7: 216 | priority = x & 7; 217 | this.isr &= ~(1 << priority); 218 | this.priority_add = (priority + 1) & 7; 219 | break; 220 | } 221 | } 222 | } else { 223 | switch (this.init_state) { 224 | case 0: 225 | this.imr = x; 226 | this.update_irq(); 227 | break; 228 | case 1: 229 | this.irq_base = x & 0xf8; 230 | this.init_state = 2; 231 | break; 232 | case 2: 233 | if (this.init4) { 234 | this.init_state = 3; 235 | } else { 236 | this.init_state = 0; 237 | } 238 | break; 239 | case 3: 240 | this.auto_eoi = (x >> 1) & 1; 241 | this.init_state = 0; 242 | break; 243 | } 244 | } 245 | }; 246 | PIC.prototype.ioport_read = function(Ug) { 247 | var mem8_loc, return_register; 248 | mem8_loc = Ug & 1; 249 | if (mem8_loc == 0) { 250 | if (this.read_reg_select) 251 | return_register = this.isr; 252 | else 253 | return_register = this.irr; 254 | } else { 255 | return_register = this.imr; 256 | } 257 | return return_register; 258 | }; 259 | 260 | 261 | function PIC_Controller(PC, master_PIC_port, slave_PIC_port, cpu_set_irq_callback) { 262 | this.pics = new Array(); 263 | this.pics[0] = new PIC(PC, master_PIC_port); 264 | this.pics[1] = new PIC(PC, slave_PIC_port); 265 | this.pics[0].elcr_mask = 0xf8; 266 | this.pics[1].elcr_mask = 0xde; 267 | this.irq_requested = 0; 268 | this.cpu_set_irq = cpu_set_irq_callback; 269 | this.pics[0].update_irq = this.update_irq.bind(this); 270 | this.pics[1].update_irq = this.update_irq.bind(this); 271 | } 272 | PIC_Controller.prototype.update_irq = function() { 273 | var slave_irq, irq; 274 | slave_irq = this.pics[1].get_irq(); 275 | if (slave_irq >= 0) { 276 | this.pics[0].set_irq1(2, 1); 277 | this.pics[0].set_irq1(2, 0); 278 | } 279 | irq = this.pics[0].get_irq(); 280 | if (irq >= 0) { 281 | this.cpu_set_irq(1); 282 | } else { 283 | this.cpu_set_irq(0); 284 | } 285 | }; 286 | PIC_Controller.prototype.set_irq = function(irq, Qf) { 287 | this.pics[irq >> 3].set_irq1(irq & 7, Qf); 288 | this.update_irq(); 289 | }; 290 | PIC_Controller.prototype.get_hard_intno = function() { 291 | var irq, slave_irq, intno; 292 | irq = this.pics[0].get_irq(); 293 | if (irq >= 0) { 294 | this.pics[0].intack(irq); 295 | if (irq == 2) { //IRQ 2 cascaded to slave 8259 INT line in PC/AT 296 | slave_irq = this.pics[1].get_irq(); 297 | if (slave_irq >= 0) { 298 | this.pics[1].intack(slave_irq); 299 | } else { 300 | slave_irq = 7; 301 | } 302 | intno = this.pics[1].irq_base + slave_irq; 303 | irq = slave_irq + 8; 304 | } else { 305 | intno = this.pics[0].irq_base + irq; 306 | } 307 | } else { 308 | irq = 7; 309 | intno = this.pics[0].irq_base + irq; 310 | } 311 | this.update_irq(); 312 | return intno; 313 | }; 314 | 315 | 316 | -------------------------------------------------------------------------------- /PIT.js: -------------------------------------------------------------------------------- 1 | /* 2 | JSLinux-deobfuscated - An annotated version of the original JSLinux. 3 | 4 | Original is Copyright (c) 2011-2012 Fabrice Bellard 5 | Redistribution or commercial use is prohibited without the author's permission. 6 | 7 | 8254 Programmble Interrupt Timer Emulator 8 | 9 | Useful References 10 | ----------------- 11 | https://en.wikipedia.org/wiki/Intel_8253 12 | */ 13 | function PIT(PC, set_irq_callback, cycle_count_callback) { 14 | var s, i; 15 | this.pit_channels = new Array(); 16 | for (i = 0; i < 3; i++) { 17 | s = new IRQCH(cycle_count_callback); 18 | this.pit_channels[i] = s; 19 | s.mode = 3; 20 | s.gate = (i != 2) >> 0; 21 | s.pit_load_count(0); 22 | } 23 | this.speaker_data_on = 0; 24 | this.set_irq = set_irq_callback; 25 | // Ports: 26 | // 0x40: Channel 0 data port 27 | // 0x61: Control 28 | PC.register_ioport_write(0x40, 4, 1, this.ioport_write.bind(this)); 29 | PC.register_ioport_read(0x40, 3, 1, this.ioport_read.bind(this)); 30 | PC.register_ioport_read(0x61, 1, 1, this.speaker_ioport_read.bind(this)); 31 | PC.register_ioport_write(0x61, 1, 1, this.speaker_ioport_write.bind(this)); 32 | } 33 | 34 | function IRQCH(cycle_count_callback) { 35 | this.count = 0; 36 | this.latched_count = 0; 37 | this.rw_state = 0; 38 | this.mode = 0; 39 | this.bcd = 0; 40 | this.gate = 0; 41 | this.count_load_time = 0; 42 | this.get_ticks = cycle_count_callback; 43 | this.pit_time_unit = 1193182 / 2000000; 44 | } 45 | IRQCH.prototype.get_time = function() { 46 | return Math.floor(this.get_ticks() * this.pit_time_unit); 47 | }; 48 | IRQCH.prototype.pit_get_count = function() { 49 | var d, dh; 50 | d = this.get_time() - this.count_load_time; 51 | switch (this.mode) { 52 | case 0: 53 | case 1: 54 | case 4: 55 | case 5: 56 | dh = (this.count - d) & 0xffff; 57 | break; 58 | default: 59 | dh = this.count - (d % this.count); 60 | break; 61 | } 62 | return dh; 63 | }; 64 | IRQCH.prototype.pit_get_out = function() { 65 | var d, eh; 66 | d = this.get_time() - this.count_load_time; 67 | switch (this.mode) { 68 | default: 69 | case 0: // Interrupt on terminal count 70 | eh = (d >= this.count) >> 0; 71 | break; 72 | case 1: // One shot 73 | eh = (d < this.count) >> 0; 74 | break; 75 | case 2: // Frequency divider 76 | if ((d % this.count) == 0 && d != 0) 77 | eh = 1; 78 | else 79 | eh = 0; 80 | break; 81 | case 3: // Square wave 82 | eh = ((d % this.count) < (this.count >> 1)) >> 0; 83 | break; 84 | case 4: // SW strobe 85 | case 5: // HW strobe 86 | eh = (d == this.count) >> 0; 87 | break; 88 | } 89 | return eh; 90 | }; 91 | IRQCH.prototype.get_next_transition_time = function() { 92 | var d, fh, base, gh; 93 | d = this.get_time() - this.count_load_time; 94 | switch (this.mode) { 95 | default: 96 | case 0: // Interrupt on terminal count 97 | case 1: // One shot 98 | if (d < this.count) 99 | fh = this.count; 100 | else 101 | return -1; 102 | break; 103 | case 2: // Frequency divider 104 | base = (d / this.count) * this.count; 105 | if ((d - base) == 0 && d != 0) 106 | fh = base + this.count; 107 | else 108 | fh = base + this.count + 1; 109 | break; 110 | case 3: // Square wave 111 | base = (d / this.count) * this.count; 112 | gh = ((this.count + 1) >> 1); 113 | if ((d - base) < gh) 114 | fh = base + gh; 115 | else 116 | fh = base + this.count; 117 | break; 118 | case 4: // SW strobe 119 | case 5: // HW strobe 120 | if (d < this.count) 121 | fh = this.count; 122 | else if (d == this.count) 123 | fh = this.count + 1; 124 | else 125 | return -1; 126 | break; 127 | } 128 | fh = this.count_load_time + fh; 129 | return fh; 130 | }; 131 | IRQCH.prototype.pit_load_count = function(x) { 132 | if (x == 0) 133 | x = 0x10000; 134 | this.count_load_time = this.get_time(); 135 | this.count = x; 136 | }; 137 | 138 | 139 | 140 | PIT.prototype.ioport_write = function(mem8_loc, x) { 141 | var hh, ih, s; 142 | mem8_loc &= 3; 143 | if (mem8_loc == 3) { 144 | hh = x >> 6; 145 | if (hh == 3) 146 | return; 147 | s = this.pit_channels[hh]; 148 | ih = (x >> 4) & 3; 149 | switch (ih) { 150 | case 0: 151 | s.latched_count = s.pit_get_count(); 152 | s.rw_state = 4; 153 | break; 154 | default: 155 | s.mode = (x >> 1) & 7; 156 | s.bcd = x & 1; 157 | s.rw_state = ih - 1 + 0; 158 | break; 159 | } 160 | } else { 161 | s = this.pit_channels[mem8_loc]; 162 | switch (s.rw_state) { 163 | case 0: 164 | s.pit_load_count(x); 165 | break; 166 | case 1: 167 | s.pit_load_count(x << 8); 168 | break; 169 | case 2: 170 | case 3: 171 | if (s.rw_state & 1) { 172 | s.pit_load_count((s.latched_count & 0xff) | (x << 8)); 173 | } else { 174 | s.latched_count = x; 175 | } 176 | s.rw_state ^= 1; 177 | break; 178 | } 179 | } 180 | }; 181 | PIT.prototype.ioport_read = function(mem8_loc) { 182 | var Pg, ma, s; 183 | mem8_loc &= 3; 184 | s = this.pit_channels[mem8_loc]; 185 | switch (s.rw_state) { 186 | case 0: 187 | case 1: 188 | case 2: 189 | case 3: 190 | ma = s.pit_get_count(); 191 | if (s.rw_state & 1) 192 | Pg = (ma >> 8) & 0xff; 193 | else 194 | Pg = ma & 0xff; 195 | if (s.rw_state & 2) 196 | s.rw_state ^= 1; 197 | break; 198 | default: 199 | case 4: 200 | case 5: 201 | if (s.rw_state & 1) 202 | Pg = s.latched_count >> 8; 203 | else 204 | Pg = s.latched_count & 0xff; 205 | s.rw_state ^= 1; 206 | break; 207 | } 208 | return Pg; 209 | }; 210 | PIT.prototype.speaker_ioport_write = function(mem8_loc, x) { 211 | this.speaker_data_on = (x >> 1) & 1; 212 | this.pit_channels[2].gate = x & 1; 213 | }; 214 | PIT.prototype.speaker_ioport_read = function(mem8_loc) { 215 | var eh, s, x; 216 | s = this.pit_channels[2]; 217 | eh = s.pit_get_out(); 218 | x = (this.speaker_data_on << 1) | s.gate | (eh << 5); 219 | return x; 220 | }; 221 | PIT.prototype.update_irq = function() { 222 | this.set_irq(1); 223 | this.set_irq(0); 224 | }; 225 | 226 | -------------------------------------------------------------------------------- /Serial.js: -------------------------------------------------------------------------------- 1 | /* 2 | JSLinux-deobfuscated - An annotated version of the original JSLinux. 3 | 4 | Original is Copyright (c) 2011-2012 Fabrice Bellard 5 | Redistribution or commercial use is prohibited without the author's permission. 6 | 7 | Serial Controller Emulator 8 | */ 9 | 10 | function Serial(Ng, mem8_loc, kh, lh) { 11 | this.divider = 0; 12 | this.rbr = 0; 13 | this.ier = 0; 14 | this.iir = 0x01; 15 | this.lcr = 0; 16 | this.mcr; 17 | this.lsr = 0x40 | 0x20; 18 | this.msr = 0; 19 | this.scr = 0; 20 | this.set_irq_func = kh; 21 | this.write_func = lh; 22 | this.receive_fifo = ""; 23 | Ng.register_ioport_write(0x3f8, 8, 1, this.ioport_write.bind(this)); 24 | Ng.register_ioport_read(0x3f8, 8, 1, this.ioport_read.bind(this)); 25 | } 26 | Serial.prototype.update_irq = function() { 27 | if ((this.lsr & 0x01) && (this.ier & 0x01)) { 28 | this.iir = 0x04; 29 | } else if ((this.lsr & 0x20) && (this.ier & 0x02)) { 30 | this.iir = 0x02; 31 | } else { 32 | this.iir = 0x01; 33 | } 34 | if (this.iir != 0x01) { 35 | this.set_irq_func(1); 36 | } else { 37 | this.set_irq_func(0); 38 | } 39 | }; 40 | Serial.prototype.ioport_write = function(mem8_loc, x) { 41 | mem8_loc &= 7; 42 | switch (mem8_loc) { 43 | default: 44 | case 0: 45 | if (this.lcr & 0x80) { 46 | this.divider = (this.divider & 0xff00) | x; 47 | } else { 48 | this.lsr &= ~0x20; 49 | this.update_irq(); 50 | this.write_func(String.fromCharCode(x)); 51 | this.lsr |= 0x20; 52 | this.lsr |= 0x40; 53 | this.update_irq(); 54 | } 55 | break; 56 | case 1: 57 | if (this.lcr & 0x80) { 58 | this.divider = (this.divider & 0x00ff) | (x << 8); 59 | } else { 60 | this.ier = x; 61 | this.update_irq(); 62 | } 63 | break; 64 | case 2: 65 | break; 66 | case 3: 67 | this.lcr = x; 68 | break; 69 | case 4: 70 | this.mcr = x; 71 | break; 72 | case 5: 73 | break; 74 | case 6: 75 | this.msr = x; 76 | break; 77 | case 7: 78 | this.scr = x; 79 | break; 80 | } 81 | }; 82 | Serial.prototype.ioport_read = function(mem8_loc) { 83 | var Pg; 84 | mem8_loc &= 7; 85 | switch (mem8_loc) { 86 | default: 87 | case 0: 88 | if (this.lcr & 0x80) { 89 | Pg = this.divider & 0xff; 90 | } else { 91 | Pg = this.rbr; 92 | this.lsr &= ~(0x01 | 0x10); 93 | this.update_irq(); 94 | this.send_char_from_fifo(); 95 | } 96 | break; 97 | case 1: 98 | if (this.lcr & 0x80) { 99 | Pg = (this.divider >> 8) & 0xff; 100 | } else { 101 | Pg = this.ier; 102 | } 103 | break; 104 | case 2: 105 | Pg = this.iir; 106 | break; 107 | case 3: 108 | Pg = this.lcr; 109 | break; 110 | case 4: 111 | Pg = this.mcr; 112 | break; 113 | case 5: 114 | Pg = this.lsr; 115 | break; 116 | case 6: 117 | Pg = this.msr; 118 | break; 119 | case 7: 120 | Pg = this.scr; 121 | break; 122 | } 123 | return Pg; 124 | }; 125 | Serial.prototype.send_break = function() { 126 | this.rbr = 0; 127 | this.lsr |= 0x10 | 0x01; 128 | this.update_irq(); 129 | }; 130 | Serial.prototype.send_char = function(mh) { 131 | this.rbr = mh; 132 | this.lsr |= 0x01; 133 | this.update_irq(); 134 | }; 135 | Serial.prototype.send_char_from_fifo = function() { 136 | var nh; 137 | nh = this.receive_fifo; 138 | if (nh != "" && !(this.lsr & 0x01)) { 139 | this.send_char(nh.charCodeAt(0)); 140 | this.receive_fifo = nh.substr(1, nh.length - 1); 141 | } 142 | }; 143 | Serial.prototype.send_chars = function(na) { 144 | this.receive_fifo += na; 145 | this.send_char_from_fifo(); 146 | }; 147 | -------------------------------------------------------------------------------- /clipboard.js: -------------------------------------------------------------------------------- 1 | /* 2 | JSLinux-deobfuscated - An annotated version of the original JSLinux. 3 | 4 | Original is Copyright (c) 2011-2012 Fabrice Bellard 5 | Redistribution or commercial use is prohibited without the author's permission. 6 | 7 | Clipboard Device 8 | */ 9 | function clipboard_device(Ng, Zf, rh, lh, sh) { 10 | Ng.register_ioport_read(Zf, 16, 4, this.ioport_readl.bind(this)); 11 | Ng.register_ioport_write(Zf, 16, 4, this.ioport_writel.bind(this)); 12 | Ng.register_ioport_read(Zf + 8, 1, 1, this.ioport_readb.bind(this)); 13 | Ng.register_ioport_write(Zf + 8, 1, 1, this.ioport_writeb.bind(this)); 14 | this.cur_pos = 0; 15 | this.doc_str = ""; 16 | this.read_func = rh; 17 | this.write_func = lh; 18 | this.get_boot_time = sh; 19 | } 20 | clipboard_device.prototype.ioport_writeb = function(mem8_loc, x) { 21 | this.doc_str += String.fromCharCode(x); 22 | }; 23 | clipboard_device.prototype.ioport_readb = function(mem8_loc) { 24 | var c, na, x; 25 | na = this.doc_str; 26 | if (this.cur_pos < na.length) { 27 | x = na.charCodeAt(this.cur_pos) & 0xff; 28 | } else { 29 | x = 0; 30 | } 31 | this.cur_pos++; 32 | return x; 33 | }; 34 | clipboard_device.prototype.ioport_writel = function(mem8_loc, x) { 35 | var na; 36 | mem8_loc = (mem8_loc >> 2) & 3; 37 | switch (mem8_loc) { 38 | case 0: 39 | this.doc_str = this.doc_str.substr(0, x >>> 0); 40 | break; 41 | case 1: 42 | return this.cur_pos = x >>> 0; 43 | case 2: 44 | na = String.fromCharCode(x & 0xff) + String.fromCharCode((x >> 8) & 0xff) + String.fromCharCode((x >> 16) & 0xff) + String.fromCharCode((x >> 24) & 0xff); 45 | this.doc_str += na; 46 | break; 47 | case 3: 48 | this.write_func(this.doc_str); 49 | } 50 | }; 51 | clipboard_device.prototype.ioport_readl = function(mem8_loc) { 52 | var x; 53 | mem8_loc = (mem8_loc >> 2) & 3; 54 | switch (mem8_loc) { 55 | case 0: 56 | this.doc_str = this.read_func(); 57 | return this.doc_str.length >> 0; 58 | case 1: 59 | return this.cur_pos >> 0; 60 | case 2: 61 | x = this.ioport_readb(0); 62 | x |= this.ioport_readb(0) << 8; 63 | x |= this.ioport_readb(0) << 16; 64 | x |= this.ioport_readb(0) << 24; 65 | return x; 66 | case 3: 67 | if (this.get_boot_time) 68 | return this.get_boot_time() >> 0; 69 | else 70 | return 0; 71 | } 72 | }; 73 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Javascript PC Emulator 5 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /jslinux.js: -------------------------------------------------------------------------------- 1 | /* 2 | Linux launcher 3 | 4 | Copyright (c) 2011 Fabrice Bellard 5 | 6 | Redistribution or commercial use is prohibited without the author's 7 | permission. 8 | */ 9 | "use strict"; 10 | 11 | var term, pc, boot_start_time; 12 | 13 | function term_start() 14 | { 15 | term = new Term(80, 30, term_handler); 16 | 17 | term.open(); 18 | } 19 | 20 | /* send chars to the serial port */ 21 | function term_handler(str) 22 | { 23 | pc.serial.send_chars(str); 24 | } 25 | 26 | function clipboard_set(val) 27 | { 28 | var el; 29 | el = document.getElementById("text_clipboard"); 30 | el.value = val; 31 | } 32 | 33 | function clipboard_get() 34 | { 35 | var el; 36 | el = document.getElementById("text_clipboard"); 37 | return el.value; 38 | } 39 | 40 | function clear_clipboard() 41 | { 42 | var el; 43 | el = document.getElementById("text_clipboard"); 44 | el.value = ""; 45 | } 46 | 47 | /* just used to display the boot time in the VM */ 48 | function get_boot_time() 49 | { 50 | return (+new Date()) - boot_start_time; 51 | } 52 | 53 | /* global to hold binary data from async XHR requests */ 54 | var binaries = [false,false,false]; 55 | 56 | function loadbinary(url,slot) { 57 | var req, binary_array, len, typed_arrays_exist; 58 | 59 | req = new XMLHttpRequest(); 60 | 61 | req.open('GET', url, true); 62 | 63 | typed_arrays_exist = ('ArrayBuffer' in window && 'Uint8Array' in window); 64 | if (typed_arrays_exist && 'mozResponseType' in req) { 65 | req.mozResponseType = 'arraybuffer'; 66 | } else if (typed_arrays_exist && 'responseType' in req) { 67 | req.responseType = 'arraybuffer'; 68 | } else { 69 | req.overrideMimeType('text/plain; charset=x-user-defined'); 70 | typed_arrays_exist = false; 71 | } 72 | 73 | req.onerror = function(e) { 74 | throw "Error while loading " + req.statusText; 75 | }; 76 | 77 | req.onload = function (e) { 78 | console.log('onload triggered'); 79 | if (req.readyState === 4) { 80 | if (req.status === 200) { 81 | if (typed_arrays_exist && 'mozResponse' in req) { 82 | binaries[slot] = req.mozResponse; 83 | } else if (typed_arrays_exist && req.mozResponseArrayBuffer) { 84 | binaries[slot] = req.mozResponseArrayBuffer; 85 | } else if ('responseType' in req) { 86 | binaries[slot] = req.response; 87 | } else { 88 | binaries[slot] = req.responseText; 89 | } 90 | //cb_f() 91 | } else { 92 | throw "Error while loading " + url; 93 | } 94 | } 95 | } 96 | 97 | req.send(null); 98 | }; 99 | 100 | function checkbinaries() { 101 | //console.log("checkbinaries: ",(binaries[0]!=false),(binaries[1]!=false),(binaries[2]!=false)); 102 | if((binaries[0] != false) && (binaries[1] != false) && (binaries[2] != false)){ 103 | console.log("...binaries done loading, calling start()") 104 | start(); 105 | } else { 106 | setTimeout(checkbinaries, 500); 107 | } 108 | }; 109 | 110 | function load_binaries() { 111 | console.log("requesting binaries"); 112 | loadbinary("vmlinux-2.6.20.bin", 0); 113 | loadbinary("root.bin", 1); 114 | loadbinary("linuxstart.bin", 2); 115 | 116 | console.log("waiting for binaries to finish loading..."); 117 | checkbinaries(); 118 | } 119 | 120 | function start() 121 | { 122 | var start_addr, initrd_size, params, cmdline_addr; 123 | 124 | params = new Object(); 125 | 126 | /* serial output chars */ 127 | params.serial_write = term.write.bind(term); 128 | 129 | /* memory size (in bytes) */ 130 | params.mem_size = 16 * 1024 * 1024; 131 | 132 | /* clipboard I/O */ 133 | params.clipboard_get = clipboard_get; 134 | params.clipboard_set = clipboard_set; 135 | 136 | params.get_boot_time = get_boot_time; 137 | 138 | pc = new PCEmulator(params); 139 | 140 | pc.load_binary(binaries[0], 0x00100000); 141 | 142 | initrd_size = pc.load_binary(binaries[1], 0x00400000); 143 | 144 | start_addr = 0x10000; 145 | pc.load_binary(binaries[2], start_addr); 146 | 147 | /* set the Linux kernel command line */ 148 | /* Note: we don't use initramfs because it is not possible to 149 | disable gzip decompression in this case, which would be too 150 | slow. */ 151 | cmdline_addr = 0xf800; 152 | pc.cpu.write_string(cmdline_addr, "console=ttyS0 root=/dev/ram0 rw init=/sbin/init notsc=1"); 153 | 154 | pc.cpu.eip = start_addr; 155 | pc.cpu.regs[0] = params.mem_size; /* eax */ 156 | pc.cpu.regs[3] = initrd_size; /* ebx */ 157 | pc.cpu.regs[1] = cmdline_addr; /* ecx */ 158 | 159 | boot_start_time = (+new Date()); 160 | 161 | pc.start(); 162 | } 163 | 164 | term_start(); 165 | -------------------------------------------------------------------------------- /linuxstart-20110820.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levskaya/jslinux-deobfuscated/d3ff9f170d79b8ca2847d554ceffda2bca150e55/linuxstart-20110820.tar.gz -------------------------------------------------------------------------------- /linuxstart.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levskaya/jslinux-deobfuscated/d3ff9f170d79b8ca2847d554ceffda2bca150e55/linuxstart.bin -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | De-obfuscated JSLinux 2 | ========================================================= 3 | 4 | This repo corresponds to a very old version of jslinux, Mr. Bellard 5 | currently uses an emscripten converted emulator for the current jslinux. 6 | 7 | There are better emulator codebases out there for pedagogical use! 8 | 9 | I highly recommend checking out another open-source x86 emulation 10 | project that includes vga support, "v86" ([demo][6] / [source][7]). 11 | There's yet another open-source 386-style emulator in javascript 12 | called [jslm32][3]. 13 | 14 | For a simpler RISC architecture, take a look at the linux on 15 | [jor1k][5] emulator project. 16 | 17 | Finally, the [Angel][8] emulator ([source][9]) shows off the elegant 18 | open-ISA 64bit [RISC-V][10] architecture that is being brought to 19 | silicon by the [lowrisc][11] team. This is by far the cleanest 20 | architecture for studying general low-level hardware and operating 21 | system implementation details. 22 | 23 | ### History 24 | I wanted to understand how the amazing [JsLinux][1] worked, so in a 25 | fit of mania I hand de-obfuscated the codebase while studying it over 26 | a few days' time. In the off-chance someone else might be interested 27 | in this code as a basis for further weird in-browser x86 hacking I 28 | posted this redacted version of the code here, with permission of 29 | Mr. Bellard. 30 | 31 | ### Status 32 | 33 | The current codebase should run on most modern versions of Chrome, 34 | Safari, and Firefox. If you're running it locally, you will need to 35 | load it via a local server to allow the XHR requests to load the 36 | binaries. 37 | 38 | jslinux-deobfuscated is still a dense, messy code base from any 39 | pedagogic point of view. However for those interested in 40 | Mr. Bellard's code, this version is nowhere near so incomprehensible 41 | as the original. Nearly all of the global variables and function 42 | names have been named somewhat sensibly. Many pointers to references 43 | have been added to the source. 44 | 45 | The core opcode execution loop has been commented to indicate what 46 | instruction the opcode refers to. 47 | 48 | ### Unresolved 49 | 50 | One mystery is, why does CPUID(1) return 8 << 8 in EBX? EBX[15:8] is 51 | now used to indicate CLFLUSH line size, but that field must have been 52 | used for something else in the past. 53 | 54 | The CALL/RET/INT/IRET routines are still quite confused and haven't 55 | yet been rewritten. The code dealing with segmentation, and some of 56 | the code for real-mode remains relatively messy. 57 | 58 | Any recommendations / clarifications are welcome! 59 | 60 | ### ETC 61 | 62 | I highly recommend, by the way, the excellent [JSShaper][2] library 63 | for transforming large javascript code bases. The hacks I made from 64 | it are in this repo: a little symbol-name-transformer node.js script 65 | and an emacs function for doing this in live buffers. 66 | 67 | ### License 68 | 69 | This is a pedagogical/aesthetic derivative of the original JSLinux 70 | code Copyright (c) 2011-2014 Fabrice Bellard. It is posted here with 71 | permission of the original author subject to his original 72 | constraints : Redistribution or commercial use is prohibited without 73 | the (original) author's permission. 74 | 75 | ### References 76 | Some other helpful references for understanding what's going on: 77 | 78 | #### x86 79 | - http://pdos.csail.mit.edu/6.828/2010/readings/i386/toc.htm 80 | - http://pdos.csail.mit.edu/6.828/2010/readings/i386.pdf (PDF of above) 81 | - http://ref.x86asm.net/coder32.html 82 | - http://www.sandpile.org/ 83 | - http://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture 84 | - http://en.wikipedia.org/wiki/X86 85 | - http://en.wikipedia.org/wiki/Control_register 86 | - http://en.wikipedia.org/wiki/X86_assembly_language 87 | - http://en.wikipedia.org/wiki/Translation_lookaside_buffer 88 | 89 | #### Bit Hacking 90 | - http://graphics.stanford.edu/~seander/bithacks.html 91 | 92 | #### Other devices 93 | - http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming 94 | 95 | [1]: http://bellard.org/jslinux/tech.html 96 | [2]: http://jsshaper.org 97 | [3]: https://github.com/ubercomp/jslm32 98 | [4]: https://bugs.webkit.org/show_bug.cgi?id=72154 99 | [5]: https://github.com/s-macke/jor1k 100 | [6]: http://copy.sh/v86/ 101 | [7]: https://github.com/copy/v86 102 | [8]: http://riscv.org/angel/ 103 | [9]: https://github.com/ucb-bar/riscv-angel 104 | [10]: http://riscv.org/ 105 | [11]: http://www.lowrisc.org/ 106 | -------------------------------------------------------------------------------- /refactoring_hacks/Opcodes.txt: -------------------------------------------------------------------------------- 1 | package scale.backend.x86; 2 | 3 | /** 4 | * The Intel X86 opcodes. 5 | *

6 | * $Id$ 7 | *

8 | * Copyright 2008 by James H. Burrill
9 | * All Rights Reserved.
10 | */ 11 | 12 | public final class Opcodes 13 | { 14 | // The opcode value has several fields: 15 | // +------------------+----+----+----------+ 16 | // | F | M | S | O | 17 | // +------------------+----+----+----------+ 18 | // 19 | // F: form flags indicating legal forms 20 | // M: Scaling factor used in some addressing forms 21 | // S: Operand size 22 | // O: instruction opcode 23 | 24 | /** 25 | * Mask for the instruction opcode. 26 | */ 27 | public static final int O_MASK = 0x000003ff; 28 | /** 29 | * Mask for the instruction opcode. 30 | */ 31 | public static final int O_SHIFT = 0; 32 | /** 33 | * Mask for the operand size. 34 | */ 35 | public static final int S_MASK = 0x00000c00; 36 | /** 37 | * Shift for the operand size. 38 | */ 39 | public static final int S_SHIFT = 10; 40 | /** 41 | * Operand size - byte. 42 | */ 43 | public static final int S_BYTE = 0x00000000; 44 | /** 45 | * Operand size - short. 46 | */ 47 | public static final int S_SHORT = 0x00000400; 48 | /** 49 | * Operand size - int. 50 | */ 51 | public static final int S_INT = 0x00000800; 52 | /** 53 | * Operand size - LONG. 54 | */ 55 | public static final int S_LONG = 0x00000c00; 56 | /** 57 | * Mask for the scaling factor used in some addressing modes.. 58 | */ 59 | public static final int M_MASK = 0x00003000; 60 | /** 61 | * Shift for the scaling factor used in some addressing modes.. 62 | */ 63 | public static final int M_SHIFT = 12; 64 | /** 65 | * Scaling factor - 1. 66 | */ 67 | public static final int M_ONE = 0x00000000; 68 | /** 69 | * Scaling factor - 2. 70 | */ 71 | public static final int M_TWO = 0x00001000; 72 | /** 73 | * Scaling factor - 4. 74 | */ 75 | public static final int M_FOUR = 0x00002000; 76 | /** 77 | * Scaling factor - 8. 78 | */ 79 | public static final int M_EIGHT = 0x00003000; 80 | /** 81 | * Valid form has no operands. 82 | */ 83 | public static final int F_NONE = 0x00004000; 84 | /** 85 | * Valid form has one register operand. 86 | */ 87 | public static final int F_R = 0x00008000; 88 | /** 89 | * Valid form has two register operands. 90 | */ 91 | public static final int F_RR = 0x00010000; 92 | /** 93 | * Valid form has three register operands. 94 | */ 95 | public static final int F_RRR = 0x00020000; 96 | /** 97 | * Valid form has a descriptor operand. 98 | */ 99 | public static final int F_D = 0x00040000; 100 | /** 101 | * Valid form has a register operand and a descriptor operand. 102 | */ 103 | public static final int F_RD = 0x00080000; 104 | /** 105 | * Valid form has two register operands and a descriptor operand. 106 | */ 107 | public static final int F_RRD = 0x00100000; 108 | /** 109 | * Valid form has three register operands and a descriptor operand. 110 | */ 111 | public static final int F_RRRD = 0x00200000; 112 | /** 113 | * Branch instruction flag. 114 | */ 115 | public static final int F_BRANCH = 0x00400000; 116 | /** 117 | * Operands are reversed flag. 118 | */ 119 | public static final int F_REV = 0x00800000; 120 | 121 | public static final int F_SHFT = F_RD + F_RR; 122 | public static final int F_ARTH = F_RR + F_RD + F_RRR + F_RRD + F_RRRD; // ADD, ADC, AND, XOR, OR, SBB, SUB, CMP 123 | public static final int F_CALL = F_D + F_R + F_RD + F_RR + F_RRD; 124 | 125 | // Integer Instructions 126 | // DATA TRANSFER INSTRUCTIONS 127 | public static final int MOV = 0X000 + F_NONE; // Move 128 | public static final int CMOVE = 0X001 + F_NONE; // Conditional move if equal 129 | public static final int CMOVZ = 0X002 + F_NONE; // Conditional move if zero 130 | public static final int CMOVNE = 0X003 + F_NONE; // Conditional move if not equal 131 | public static final int CMOVNZ = 0X004 + F_NONE; // Conditional move if not zero 132 | public static final int CMOVA = 0X005 + F_NONE; // Conditional move if above 133 | public static final int CMOVNBE = 0X006 + F_NONE; // Conditional move if not below or equal 134 | public static final int CMOVAE = 0X007 + F_NONE; // Conditional move if above or equal 135 | public static final int CMOVNB = 0X008 + F_NONE; // Conditional move if not below 136 | public static final int CMOVB = 0X009 + F_NONE; // Conditional move if below 137 | public static final int CMOVNAE = 0X00A + F_NONE; // Conditional move if not above or equal 138 | public static final int CMOVBE = 0X00B + F_NONE; // Conditional move if below or equal 139 | public static final int CMOVNA = 0X00C + F_NONE; // Conditional move if not above 140 | public static final int CMOVG = 0X00D + F_NONE; // Conditional move if greater 141 | public static final int CMOVNLE = 0X00E + F_NONE; // Conditional move if not less or equal 142 | public static final int CMOVGE = 0X00F + F_NONE; // Conditional move if greater or equal 143 | public static final int CMOVNL = 0X010 + F_NONE; // Conditional move if not less 144 | public static final int CMOVL = 0X011 + F_NONE; // Conditional move if less 145 | public static final int CMOVNGE = 0X012 + F_NONE; // Conditional move if not greater or equal 146 | public static final int CMOVLE = 0X013 + F_NONE; // Conditional move if less or equal 147 | public static final int CMOVNG = 0X014 + F_NONE; // Conditional move if not greater 148 | public static final int CMOVC = 0X015 + F_NONE; // Conditional move if carry 149 | public static final int CMOVNC = 0X016 + F_NONE; // Conditional move if not carry 150 | public static final int CMOVO = 0X017 + F_NONE; // Conditional move if overflow 151 | public static final int CMOVNO = 0X018 + F_NONE; // Conditional move if not overflow 152 | public static final int CMOVS = 0X019 + F_NONE; // Conditional move if sign (negative) 153 | public static final int CMOVNS = 0X01A + F_NONE; // Conditional move if not sign (non-negative) 154 | public static final int CMOVP = 0X01B + F_NONE; // Conditional move if parity 155 | public static final int CMOVPE = 0X01C + F_NONE; // Conditional move if parity even 156 | public static final int CMOVNP = 0X01D + F_NONE; // Conditional move if not parity 157 | public static final int CMOVPO = 0X01E + F_NONE; // Conditional move if parity odd 158 | public static final int XCHG = 0X01F + F_NONE; // Exchange 159 | public static final int BSWAP = 0X020 + F_NONE; // Byte swap 160 | public static final int XADD = 0X021 + F_NONE; // Exchange and add 161 | public static final int CMPXCHG = 0X022 + F_NONE; // Compare and exchange 162 | public static final int CMPXCHG8B = 0X023 + F_NONE; // Compare and exchange 8 bytes 163 | public static final int PUSH = 0X024 + F_NONE; // Push onto stack 164 | public static final int POP = 0X025 + F_NONE; // Pop off of stack 165 | public static final int PUSHA = 0X026 + F_NONE; // Push general-purpose registers onto stack 166 | public static final int PUSHAD = 0X027 + F_NONE; // Push general-purpose registers onto stack 167 | public static final int POPA = 0X028 + F_NONE; // Pop general-purpose registers from stack 168 | public static final int POPAD = 0X029 + F_NONE; // Pop general-purpose registers from stack 169 | public static final int IN = 0X02A + F_NONE; // Read from a port 170 | public static final int OUT = 0X02B + F_NONE; // Write to a port 171 | public static final int CWD = 0X02C + F_NONE; // Convert word to doubleword 172 | public static final int CDQ = 0X02D + F_NONE; // Convert doubleword to quadword 173 | public static final int CBW = 0X02E + F_NONE; // Convert byte to word 174 | public static final int CWDE = 0X02F + F_NONE; // Convert word to doubleword in EAX register 175 | public static final int MOVSX = 0X030 + F_NONE; // Move and sign extend 176 | public static final int MOVZX = 0X031 + F_NONE; // Move and zero extend 177 | // BINARY ARTHMETIC INSTRUCTIONS 178 | public static final int ADD = 0X032 + F_ARTH; // Integer add 179 | public static final int ADC = 0X033 + F_ARTH; // Add with carry 180 | public static final int SUB = 0X034 + F_ARTH; // Subtract 181 | public static final int SBB = 0X035 + F_ARTH; // Subtract with borrow 182 | public static final int IMUL = 0X036 + F_NONE; // Signed multiply 183 | public static final int MUL = 0X037 + F_NONE; // Unsigned multiply 184 | public static final int IDIV = 0X038 + F_NONE; // Signed divide 185 | public static final int DIV = 0X039 + F_NONE; // Unsigned divide 186 | public static final int INC = 0X03A + F_NONE; // Increment 187 | public static final int DEC = 0X03B + F_NONE; // Decrement 188 | public static final int NEG = 0X03C + F_NONE; // Negate 189 | public static final int CMP = 0X03D + F_ARTH; // Compare 190 | // DECIMAL ARTHMETIC 191 | public static final int DAA = 0X03E + F_NONE; // Decimal adjust after addition 192 | public static final int DAS = 0X03F + F_NONE; // Decimal adjust after subtraction 193 | public static final int AAA = 0X040 + F_NONE; // ASCII adjust after addition 194 | public static final int AAS = 0X041 + F_NONE; // ASCII adjust after subtraction 195 | public static final int AAM = 0X042 + F_NONE; // ASCII adjust after multiplication 196 | public static final int AAD = 0X043 + F_NONE; // ASCII adjust before division 197 | // LOGIC INSTRUCTIONS 198 | public static final int AND = 0X044 + F_ARTH; // And 199 | public static final int OR = 0X045 + F_ARTH; // Or 200 | public static final int XOR = 0X046 + F_ARTH; // Exclusive or 201 | public static final int NOT = 0X047 + F_NONE; // Not 202 | // SHIFT AND ROTATE INSTRUCTIONS 203 | public static final int SAR = 0X048 + F_SHFT; // Shift arithmetic right 204 | public static final int SHR = 0X049 + F_SHFT; // Shift logical right 205 | public static final int SAL = 0X04A + F_SHFT; // Shift arithmetic left 206 | public static final int SHL = 0X04B + F_SHFT; // Shift arithmetic left 207 | public static final int SHRD = 0X04C + F_SHFT; // Shift right double 208 | public static final int SHLD = 0X04D + F_SHFT; // Shift left double 209 | public static final int ROR = 0X04E + F_SHFT; // Rotate right 210 | public static final int ROL = 0X04F + F_SHFT; // Rotate left 211 | public static final int RCR = 0X050 + F_SHFT; // Rotate through carry right 212 | public static final int RCL = 0X051 + F_SHFT; // Rotate through carry left 213 | // BIT AND BYTE INSTRUCTIONS 214 | public static final int BT = 0X052 + F_ARTH; // Bit test 215 | public static final int BTS = 0X053 + F_NONE; // Bit test and set 216 | public static final int BTR = 0X054 + F_NONE; // Bit test and reset 217 | public static final int BTC = 0X055 + F_ARTH; // Bit test and complement 218 | public static final int BSF = 0X056 + F_NONE; // Bit scan forward 219 | public static final int BSR = 0X057 + F_NONE; // Bit scan reverse 220 | public static final int SETE = 0X058 + F_NONE; // Set byte if equal 221 | public static final int SETZ = 0X059 + F_NONE; // Set byte if zero 222 | public static final int SETNE = 0X05A + F_NONE; // Set byte if not equal 223 | public static final int SETNZ = 0X05B + F_NONE; // Set byte if not zero 224 | public static final int SETA = 0X05C + F_NONE; // Set byte if above 225 | public static final int SETNBE = 0X05D + F_NONE; // Set byte if not below or equal 226 | public static final int SETAE = 0X05E + F_NONE; // Set byte if above or equal 227 | public static final int SETNB = 0X05F + F_NONE; // Set byte if not below 228 | public static final int SETNC = 0X060 + F_NONE; // Set byte if not carry 229 | public static final int SETB = 0X061 + F_NONE; // Set byte if below 230 | public static final int SETNAE = 0X062 + F_NONE; // Set byte if not above or equal 231 | public static final int SETC = 0X063 + F_NONE; // Set byte if carry 232 | public static final int SETBE = 0X064 + F_NONE; // Set byte if below or equal 233 | public static final int SETNA = 0X065 + F_NONE; // Set byte if not above 234 | public static final int SETG = 0X066 + F_NONE; // Set byte if greater 235 | public static final int SETNLE = 0X067 + F_NONE; // Set byte if not less or equal 236 | public static final int SETGE = 0X068 + F_NONE; // Set byte if greater or equal 237 | public static final int SETNL = 0X069 + F_NONE; // Set byte if not less 238 | public static final int SETL = 0X06A + F_NONE; // Set byte if less 239 | public static final int SETNGE = 0X06B + F_NONE; // Set byte if not greater or equal 240 | public static final int SETLE = 0X06C + F_NONE; // Set byte if less or equal 241 | public static final int SETNG = 0X06D + F_NONE; // Set byte if not greater 242 | public static final int SETS = 0X06E + F_NONE; // Set byte if sign (negative) 243 | public static final int SETNS = 0X06F + F_NONE; // Set byte if not sign (non-negative) 244 | public static final int SETO = 0X070 + F_NONE; // Set byte if overflow 245 | public static final int SETNO = 0X071 + F_NONE; // Set byte if not overflow 246 | public static final int SETPE = 0X072 + F_NONE; // Set byte if parity even 247 | public static final int SETP = 0X073 + F_NONE; // Set byte if parity 248 | public static final int SETPO = 0X074 + F_NONE; // Set byte if parity odd 249 | public static final int SETNP = 0X075 + F_NONE; // Set byte if not parity 250 | public static final int TEST = 0X076 + F_NONE; // Logical compare 251 | // CONTROL TRANSFER INSTRUCTIONS 252 | public static final int JMP = 0X077 + F_NONE; // Jump 253 | public static final int JE = 0X078 + F_NONE; // Jump if equal 254 | public static final int JZ = 0X079 + F_NONE; // Jump if zero 255 | public static final int JNE = 0X07A + F_NONE; // Jump if not equal 256 | public static final int JNZ = 0X07B + F_NONE; // Jump if not zero 257 | public static final int JA = 0X07C + F_NONE; // Jump if above 258 | public static final int JNBE = 0X07D + F_NONE; // Jump if not below or equal 259 | public static final int JAE = 0X07E + F_NONE; // Jump if above or equal 260 | public static final int JNB = 0X07F + F_NONE; // Jump if not below 261 | public static final int JB = 0X080 + F_NONE; // Jump if below 262 | public static final int JNAE = 0X081 + F_NONE; // Jump if not above or equal 263 | public static final int JBE = 0X082 + F_NONE; // Jump if below or equal 264 | public static final int JNA = 0X083 + F_NONE; // Jump if not above 265 | public static final int JG = 0X084 + F_NONE; // Jump if greater 266 | public static final int JNLE = 0X085 + F_NONE; // Jump if not less or equal 267 | public static final int JGE = 0X086 + F_NONE; // Jump if greater or equal 268 | public static final int JNL = 0X087 + F_NONE; // Jump if not less 269 | public static final int JL = 0X088 + F_NONE; // Jump if less 270 | public static final int JNGE = 0X089 + F_NONE; // Jump if not greater or equal 271 | public static final int JLE = 0X08A + F_NONE; // Jump if less or equal 272 | public static final int JNG = 0X08B + F_NONE; // Jump if not greater 273 | public static final int JC = 0X08C + F_NONE; // Jump if carry 274 | public static final int JNC = 0X08D + F_NONE; // Jump if not carry 275 | public static final int JO = 0X08E + F_NONE; // Jump if overflow 276 | public static final int JNO = 0X08F + F_NONE; // Jump if not overflow 277 | public static final int JS = 0X090 + F_NONE; // Jump if sign (negative) 278 | public static final int JNS = 0X091 + F_NONE; // Jump if not sign (non-negative) 279 | public static final int JPO = 0X092 + F_NONE; // Jump if parity odd 280 | public static final int JNP = 0X093 + F_NONE; // Jump if not parity 281 | public static final int JPE = 0X094 + F_NONE; // Jump if parity even 282 | public static final int JP = 0X095 + F_NONE; // Jump if parity 283 | public static final int JCXZ = 0X096 + F_NONE; // Jump register CX zero 284 | public static final int JECXZ = 0X097 + F_NONE; // Jump register ECX zero 285 | public static final int LOOP = 0X098 + F_NONE; // Loop with ECX counter 286 | public static final int LOOPZ = 0X099 + F_NONE; // Loop with ECX and zero 287 | public static final int LOOPE = 0X09A + F_NONE; // Loop with ECX and equal 288 | public static final int LOOPNZ = 0X09B + F_NONE; // Loop with ECX and not zero 289 | public static final int LOOPNE = 0X09C + F_NONE; // Loop with ECX and not equal 290 | public static final int CALL = 0X09D + F_NONE; // Call procedure 291 | public static final int RET = 0X09E + F_NONE; // Return 292 | public static final int IRET = 0X09F + F_NONE; // Return from interrupt 293 | public static final int INT = 0X0A0 + F_NONE; // Software interrupt 294 | public static final int INTO = 0X0A1 + F_NONE; // Interrupt on overflow 295 | public static final int BOUND = 0X0A2 + F_NONE; // Detect value out of range 296 | public static final int ENTER = 0X0A3 + F_NONE; // High-level procedure entry 297 | public static final int LEAVE = 0X0A4 + F_NONE; // High-level procedure exit 298 | // STRING INSTRUCTIONS 299 | public static final int UN00 = 0X0A5 + F_NONE; // Unused 300 | public static final int MOVSB = 0X0A6 + F_NONE; // Move byte string 301 | public static final int UN01 = 0X0A7 + F_NONE; // Unused 302 | public static final int MOVSW = 0X0A8 + F_NONE; // Move word string 303 | public static final int UN02 = 0X0A9 + F_NONE; // Unused 304 | public static final int MOVSD = 0X0AA + F_NONE; // Move doubleword string 305 | public static final int UN03 = 0X0AB + F_NONE; // Unused 306 | public static final int CMPSB = 0X0AC + F_NONE; // Compare byte string 307 | public static final int UN04 = 0X0AD + F_NONE; // Unused 308 | public static final int CMPSW = 0X0AE + F_NONE; // Compare word string 309 | public static final int UN05 = 0X0AF + F_NONE; // Unused 310 | public static final int CMPSD = 0X0B0 + F_NONE; // Compare doubleword string 311 | public static final int UN06 = 0X0B1 + F_NONE; // Unused 312 | public static final int SCASB = 0X0B2 + F_NONE; // Scan byte string 313 | public static final int UN07 = 0X0B3 + F_NONE; // Unused 314 | public static final int SCASW = 0X0B4 + F_NONE; // Scan word string 315 | public static final int UN08 = 0X0B5 + F_NONE; // Unused 316 | public static final int SCASD = 0X0B6 + F_NONE; // Scan doubleword string 317 | public static final int UN09 = 0X0B7 + F_NONE; // Unused 318 | public static final int LODSB = 0X0B8 + F_NONE; // Load byte string 319 | public static final int UN10 = 0X0B9 + F_NONE; // Unused 320 | public static final int LODSW = 0X0BA + F_NONE; // Load word string 321 | public static final int UN11 = 0X0BB + F_NONE; // Unused 322 | public static final int LODSD = 0X0BC + F_NONE; // Load doubleword string 323 | public static final int UN12 = 0X0BD + F_NONE; // Unused 324 | public static final int STOSB = 0X0BE + F_NONE; // Store byte string 325 | public static final int UN13 = 0X0BF + F_NONE; // Unused 326 | public static final int STOSW = 0X0C0 + F_NONE; // Store word string 327 | public static final int UN14 = 0X0C1 + F_NONE; // KUnusedStore string 328 | public static final int STOSD = 0X0C2 + F_NONE; // Store doubleword string 329 | public static final int REP = 0X0C3 + F_NONE; // Repeat while ECX not zero 330 | public static final int REPE = 0X0C4 + F_NONE; // Repeat while equal 331 | public static final int REPZ = 0X0C5 + F_NONE; // Repeat while zero 332 | public static final int REPNE = 0X0C6 + F_NONE; // Repeat while not equal 333 | public static final int REPNZ = 0X0C7 + F_NONE; // Repeat while not zero 334 | public static final int UN15 = 0X0C8 + F_NONE; // Unused 335 | public static final int INSB = 0X0C9 + F_NONE; // Input byte string from port 336 | public static final int UN16 = 0X0CA + F_NONE; // Unused 337 | public static final int INSW = 0X0CB + F_NONE; // Input word string from port 338 | public static final int UN17 = 0X0CC + F_NONE; // Unused 339 | public static final int INSD = 0X0CD + F_NONE; // Input doubleword string from port 340 | public static final int UN18 = 0X0CE + F_NONE; // Unused 341 | public static final int OUTSB = 0X0CF + F_NONE; // Output byte string to port 342 | public static final int UN19 = 0X0D0 + F_NONE; // Unused 343 | public static final int OUTSW = 0X0D1 + F_NONE; // Output word string to port 344 | public static final int UN20 = 0X0D2 + F_NONE; // Unused 345 | public static final int OUTSD = 0X0D3 + F_NONE; // Output doubleword string to port 346 | // FLAG CONTROL INSTRUCTIONS 347 | public static final int STC = 0X0D4 + F_NONE; // Set carry flag 348 | public static final int CLC = 0X0D5 + F_NONE; // Clear the carry flag 349 | public static final int CMC = 0X0D6 + F_NONE; // Complement the carry flag 350 | public static final int CLD = 0X0D7 + F_NONE; // Clear the direction flag 351 | public static final int STD = 0X0D8 + F_NONE; // Set direction flag 352 | public static final int LAHF = 0X0D9 + F_NONE; // Load flags into AH register 353 | public static final int SAHF = 0X0DA + F_NONE; // Store AH register into flags 354 | public static final int PUSHF = 0X0DB + F_NONE; // Push EFLAGS onto stack 355 | public static final int PUSHFD = 0X0DC + F_NONE; // Push EFLAGS onto stack 356 | public static final int POPF = 0X0DD + F_NONE; // Pop EFLAGS from stack 357 | public static final int POPFD = 0X0DE + F_NONE; // Pop EFLAGS from stack 358 | public static final int STI = 0X0DF + F_NONE; // Set interrupt flag 359 | public static final int CLI = 0X0E0 + F_NONE; // Clear the interrupt flag 360 | // SEGMENT REGISTER INSTRUCTIONS 361 | public static final int LDS = 0X0E1 + F_NONE; // Load far pointer using DS 362 | public static final int LES = 0X0E2 + F_NONE; // Load far pointer using ES 363 | public static final int LFS = 0X0E3 + F_NONE; // Load far pointer using FS 364 | public static final int LGS = 0X0E4 + F_NONE; // Load far pointer using GS 365 | public static final int LSS = 0X0E5 + F_NONE; // Load far pointer using SS 366 | // MISCELLANEOUS INSTRUCTIONS 367 | public static final int LEA = 0X0E6 + F_NONE; // Load effective address 368 | public static final int NOP = 0X0E7 + F_NONE; // No operation 369 | public static final int UB2 = 0X0E8 + F_NONE; // Undefined instruction 370 | public static final int XLAT = 0X0E9 + F_NONE; // Table lookup translation 371 | public static final int XLATB = 0X0EA + F_NONE; // Table lookup translation 372 | public static final int CPUID = 0X0EB + F_NONE; // Processor Identification 373 | // MMXTM Technology Instructions 374 | // MMXTM DATA TRANSFER INSTRUCTIONS 375 | public static final int MOVD = 0X0EC + F_NONE; // Move doubleword 376 | public static final int MOVQ = 0X0ED + F_NONE; // Move quadword 377 | // MMXTM CONVERSION INSTRUCTIONS 378 | public static final int PACKSSWB = 0X0EE + F_NONE; // Pack words into bytes with signed saturation 379 | public static final int PACKSSDW = 0X0EF + F_NONE; // Pack doublewords into words with signed saturation 380 | public static final int PACKUSWB = 0X0F0 + F_NONE; // Pack words into bytes with unsigned saturation 381 | public static final int PUNPCKHBW = 0X0F1 + F_NONE; // Unpack high-order bytes from words 382 | public static final int PUNPCKHWD = 0X0F2 + F_NONE; // Unpack high-order words from doublewords 383 | public static final int PUNPCKHDQ = 0X0F3 + F_NONE; // Unpack high-order doublewords from quadword 384 | public static final int PUNPCKLBW = 0X0F4 + F_NONE; // Unpack low-order bytes from words 385 | public static final int PUNPCKLWD = 0X0F5 + F_NONE; // Unpack low-order words from doublewords 386 | public static final int PUNPCKLDQ = 0X0F6 + F_NONE; // Unpack low-order doublewords from quadword 387 | // MMXTM PACKED ARTHMETIC INSTRUCTIONS 388 | public static final int PADDB = 0X0F7 + F_NONE; // Add packed bytes 389 | public static final int PADDW = 0X0F8 + F_NONE; // Add packed words 390 | public static final int PADDD = 0X0F9 + F_NONE; // Add packed doublewords 391 | public static final int PADDSB = 0X0FA + F_NONE; // Add packed bytes with saturation 392 | public static final int PADDSW = 0X0FB + F_NONE; // Add packed words with saturation 393 | public static final int PADDUSB = 0X0FC + F_NONE; // Add packed unsigned bytes with saturation 394 | public static final int PADDUSW = 0X0FD + F_NONE; // Add packed unsigned words with saturation 395 | public static final int PSUBB = 0X0FE + F_NONE; // Subtract packed bytes 396 | public static final int PSUBW = 0X0FF + F_NONE; // Subtract packed words 397 | public static final int PSUBD = 0X100 + F_NONE; // Subtract packed doublewords 398 | public static final int PSUBSB = 0X101 + F_NONE; // Subtract packed bytes with saturation 399 | public static final int PSUBSW = 0X102 + F_NONE; // Subtract packed words with saturation 400 | public static final int PSUBUSB = 0X103 + F_NONE; // Subtract packed unsigned bytes with saturation 401 | public static final int PSUBUSW = 0X104 + F_NONE; // Subtract packed unsigned words with saturation 402 | public static final int PMULHW = 0X105 + F_NONE; // Multiply packed words and store high result 403 | public static final int PMULLW = 0X106 + F_NONE; // Multiply packed words and store low result 404 | public static final int PMADDWD = 0X107 + F_NONE; // Multiply and add packed words 405 | // MMXTM COMPARISON INSTRUCTIONS 406 | public static final int PCMPEQB = 0X108 + F_NONE; // Compare packed bytes for equal 407 | public static final int PCMPEQW = 0X109 + F_NONE; // Compare packed words for equal 408 | public static final int PCMPEQD = 0X10A + F_NONE; // Compare packed doublewords for equal 409 | public static final int PCMPGTB = 0X10B + F_NONE; // Compare packed bytes for greater than 410 | public static final int PCMPGTW = 0X10C + F_NONE; // Compare packed words for greater than 411 | public static final int PCMPGTD = 0X10D + F_NONE; // Compare packed doublewords for greater than 412 | // MMXTM LOGIC INSTRUCTIONS 413 | public static final int PAND = 0X10E + F_NONE; // Bitwise logical and 414 | public static final int PANDN = 0X10F + F_NONE; // Bitwise logical and not 415 | public static final int POR = 0X110 + F_NONE; // Bitwise logical or 416 | public static final int PXOR = 0X111 + F_NONE; // Bitwise logical exclusive or 417 | // MMXTM SHIFT AND ROTATE INSTRUCTIONS 418 | public static final int PSLLW = 0X112 + F_NONE; // Shift packed words left logical 419 | public static final int PSLLD = 0X113 + F_NONE; // Shift packed doublewords left logical 420 | public static final int PSLLQ = 0X114 + F_NONE; // Shift packed quadword left logical 421 | public static final int PSRLW = 0X115 + F_NONE; // Shift packed words right logical 422 | public static final int PSRLD = 0X116 + F_NONE; // Shift packed doublewords right logical 423 | public static final int PSRLQ = 0X117 + F_NONE; // Shift packed quadword right logical 424 | public static final int PSRAW = 0X118 + F_NONE; // Shift packed words right arithmetic 425 | public static final int PSRAD = 0X119 + F_NONE; // Shift packed doublewords right arithmetic 426 | // MMXTM STATE MANAGEMENT 427 | public static final int EMMS = 0X11A + F_NONE; // Empty MMX state 428 | // Floating-Point Instructions 429 | // DATA TRANSFER 430 | public static final int FLD = 0X11B + F_NONE; // Load real 431 | public static final int FST = 0X11C + F_NONE; // Store real 432 | public static final int FSTP = 0X11D + F_NONE; // Store real and pop 433 | public static final int FILD = 0X11E + F_NONE; // Load integer 434 | public static final int FIST = 0X11F + F_NONE; // Store integer 435 | public static final int FISTP = 0X120 + F_NONE; // Store integer and pop 436 | public static final int FBLD = 0X121 + F_NONE; // Load BCD 437 | public static final int FBSTP = 0X122 + F_NONE; // Store BCD and pop 438 | public static final int FXCH = 0X123 + F_NONE; // Exchange registers 439 | public static final int FCMOVE = 0X124 + F_NONE; // Floating-point conditional move if equal 440 | public static final int FCMOVNE = 0X125 + F_NONE; // Floating-point conditional move if not equal 441 | public static final int FCMOVB = 0X126 + F_NONE; // Floating-point conditional move if below 442 | public static final int FCMOVBE = 0X127 + F_NONE; // Floating-point conditional move if below or equal 443 | public static final int FCMOVNB = 0X128 + F_NONE; // Floating-point conditional move if not below 444 | public static final int FCMOVNBE = 0X129 + F_NONE; // Floating-point conditional move if not below or equal 445 | public static final int FCMOVU = 0X12A + F_NONE; // Floating-point conditional move if unordered 446 | public static final int FCMOVNU = 0X12B + F_NONE; // Floating-point conditional move if not unordered 447 | // BASIC ARTHMETIC 448 | public static final int FADD = 0X12C + F_NONE; // Add real 449 | public static final int FADDP = 0X12D + F_NONE; // Add real and pop 450 | public static final int FIADD = 0X12E + F_NONE; // Add integer 451 | public static final int FSUB = 0X12F + F_NONE; // Subtract real 452 | public static final int FSUBP = 0X130 + F_NONE; // Subtract real and pop 453 | public static final int FISUB = 0X131 + F_NONE; // Subtract integer 454 | public static final int FSUBR = 0X132 + F_NONE; // Subtract real reverse 455 | public static final int FSUBRP = 0X133 + F_NONE; // Subtract real reverse and pop 456 | public static final int FISUBR = 0X134 + F_NONE; // Subtract integer reverse 457 | public static final int FMUL = 0X135 + F_NONE; // Multiply real 458 | public static final int FMULP = 0X136 + F_NONE; // Multiply real and pop 459 | public static final int FIMUL = 0X137 + F_NONE; // Multiply integer 460 | public static final int FDIV = 0X138 + F_NONE; // Divide real 461 | public static final int FDIVP = 0X139 + F_NONE; // Divide real and pop 462 | public static final int FIDIV = 0X13A + F_NONE; // Divide integer 463 | public static final int FDIVR = 0X13B + F_NONE; // Divide real reverse 464 | public static final int FDIVRP = 0X13C + F_NONE; // Divide real reverse and pop 465 | public static final int FIDIVR = 0X13D + F_NONE; // Divide integer reverse 466 | public static final int FPREM = 0X13E + F_NONE; // Partial remainder 467 | public static final int FPREMI = 0X13F + F_NONE; // IEEE Partial remainder 468 | public static final int FABS = 0X140 + F_NONE; // Absolute value 469 | public static final int FCHS = 0X141 + F_NONE; // Change sign 470 | public static final int FRNDINT = 0X142 + F_NONE; // Round to integer 471 | public static final int FSCALE = 0X143 + F_NONE; // Scale by power of two 472 | public static final int FSQRT = 0X144 + F_NONE; // Square root 473 | public static final int FXTRACT = 0X145 + F_NONE; // Extract exponent and significand 474 | // COMPARISON 475 | public static final int FCOM = 0X146 + F_NONE; // Compare real 476 | public static final int FCOMP = 0X147 + F_NONE; // Compare real and pop 477 | public static final int FCOMPP = 0X148 + F_NONE; // Compare real and pop twice 478 | public static final int FUCOM = 0X149 + F_NONE; // Unordered compare real 479 | public static final int FUCOMP = 0X14A + F_NONE; // Unordered compare real and pop 480 | public static final int FUCOMPP = 0X14B + F_NONE; // Unordered compare real and pop twice 481 | public static final int FICOM = 0X14C + F_NONE; // Compare integer 482 | public static final int FICOMP = 0X14D + F_NONE; // Compare integer and pop 483 | public static final int FCOMI = 0X14E + F_NONE; // Compare real and set EFLAGS 484 | public static final int FUCOMI = 0X14F + F_NONE; // Unordered compare real and set EFLAGS 485 | public static final int FCOMIP = 0X150 + F_NONE; // Compare real, set EFLAGS, and pop 486 | public static final int FUCOMIP = 0X151 + F_NONE; // Unordered compare real, set EFLAGS, and pop 487 | public static final int FTST = 0X152 + F_NONE; // Test real 488 | public static final int FXAM = 0X153 + F_NONE; // Examine real 489 | // TRANSCENDENTAL 490 | public static final int FSIN = 0X154 + F_NONE; // Sine 491 | public static final int FCOS = 0X155 + F_NONE; // Cosine 492 | public static final int FSINCOS = 0X156 + F_NONE; // Sine and cosine 493 | public static final int FPTAN = 0X157 + F_NONE; // Partial tangent 494 | public static final int FPATAN = 0X158 + F_NONE; // Partial arctangent 495 | public static final int F2XM1 = 0X159 + F_NONE; // 2x - 1 496 | public static final int FYL2X = 0X15A + F_NONE; // y*log2x 497 | public static final int FYL2XP1 = 0X15B + F_NONE; // y*log 2(x+1) 498 | // LOAD CONSTANTS 499 | public static final int FLD1 = 0X15C + F_NONE; // Load +1.0 500 | public static final int FLDZ = 0X15D + F_NONE; // Load +0.0 501 | public static final int FLDPI = 0X15E + F_NONE; // Load Pi 502 | public static final int FLDL2E = 0X15F + F_NONE; // Load log2e 503 | public static final int FLDLN2 = 0X160 + F_NONE; // Load loge2 504 | public static final int FLDL2T = 0X161 + F_NONE; // Load log210 505 | public static final int FLDLG2 = 0X162 + F_NONE; // Load log102 506 | // FPU CONTROL 507 | public static final int FINCSTP = 0X163 + F_NONE; // Increment FPU register stack pointer 508 | public static final int FDECSTP = 0X164 + F_NONE; // Decrement FPU register stack pointer 509 | public static final int FFREE = 0X165 + F_NONE; // Free floating-point register 510 | public static final int FINIT = 0X166 + F_NONE; // Initialize FPU after checking error conditions 511 | public static final int FNINIT = 0X167 + F_NONE; // Initialize FPU without checking error conditions 512 | public static final int FCLEX = 0X168 + F_NONE; // Clear floating-point exception flags after checking for error conditions 513 | public static final int FNCLEX = 0X169 + F_NONE; // Clear floating-point exception flags without checking for error conditions 514 | public static final int FSTCW = 0X16A + F_NONE; // Store FPU control word after checking error conditions 515 | public static final int FNSTCW = 0X16B + F_NONE; // Store FPU control word without checking error conditions 516 | public static final int FLDCW = 0X16C + F_NONE; // Load FPU control word 517 | public static final int FSTENV = 0X16D + F_NONE; // Store FPU environment after checking error conditions 518 | public static final int FNSTENV = 0X16E + F_NONE; // Store FPU environment without checking error conditions 519 | public static final int FLDENV = 0X16F + F_NONE; // Load FPU environment 520 | public static final int FSAVE = 0X170 + F_NONE; // Save FPU state after checking error conditions 521 | public static final int FNSAVE = 0X171 + F_NONE; // Save FPU state without checking error conditions 522 | public static final int FRSTOR = 0X172 + F_NONE; // Restore FPU state 523 | public static final int FSTSW = 0X173 + F_NONE; // Store FPU status word after checking error conditions 524 | public static final int FNSTSW = 0X174 + F_NONE; // Store FPU status word without checking error conditions 525 | public static final int WAIT = 0X175 + F_NONE; // Wait for FPU 526 | public static final int FWAIT = 0X176 + F_NONE; // Wait for FPU 527 | public static final int FNOP = 0X177 + F_NONE; // FPU no operation 528 | // System Instructions 529 | public static final int LGDT = 0X178 + F_NONE; // Load global descriptor table (GDT) register 530 | public static final int SGDT = 0X179 + F_NONE; // Store global descriptor table (GDT) register 531 | public static final int LLDT = 0X17A + F_NONE; // Load local descriptor table (LDT) register 532 | public static final int SLDT = 0X17B + F_NONE; // Store local descriptor table (LDT) register 533 | public static final int LTR = 0X17C + F_NONE; // Load task register 534 | public static final int STR = 0X17D + F_NONE; // Store task register 535 | public static final int LIDT = 0X17E + F_NONE; // Load interrupt descriptor table (IDT) register 536 | public static final int SIDT = 0X17F + F_NONE; // Store interrupt descriptor table (IDT) register 537 | public static final int LMSW = 0X180 + F_NONE; // Load machine status word 538 | public static final int SMSW = 0X181 + F_NONE; // Store machine status word 539 | public static final int CLTS = 0X182 + F_NONE; // Clear the task-switched flag 540 | public static final int ARPL = 0X183 + F_NONE; // Adjust requested privilege level 541 | public static final int LAR = 0X184 + F_NONE; // Load access rights 542 | public static final int LSL = 0X185 + F_NONE; // Load segment limit 543 | public static final int VERR = 0X186 + F_NONE; // Verify segment for reading 544 | public static final int VERW = 0X187 + F_NONE; // Verify segment for writing 545 | public static final int INVD = 0X188 + F_NONE; // Invalidate cache, no writeback 546 | public static final int WBINVD = 0X189 + F_NONE; // Invalidate cache, with writeback 547 | public static final int INVLPG = 0X18A + F_NONE; // Invalidate TLB Entry 548 | public static final int LOCK = 0X18B + F_NONE; // (prefix) Lock Bus 549 | public static final int HLT = 0X18C + F_NONE; // Halt processor 550 | public static final int RSM = 0X18D + F_NONE; // Return from system management mode (SSM) 551 | public static final int RDMSR = 0X18E + F_NONE; // Read model-specific register 552 | public static final int WRMSR = 0X18F + F_NONE; // Write model-specific register 553 | public static final int RDPMC = 0X190 + F_NONE; // Read performance monitoring counters 554 | public static final int RDTSC = 0X191 + F_NONE; // Read time stamp counter 555 | public static final int LDDR = 0X192 + F_NONE; // Load debug register 556 | public static final int STDR = 0X193 + F_NONE; // Store debug register 557 | public static final int LDCR = 0X194 + F_NONE; // Load Control Register 558 | public static final int STCR = 0X195 + F_NONE; // Store Control Register 559 | 560 | public static final String[] opnames = { 561 | /* 000 */ "MOV", "CMOVE", "CMOVZ", "CMOVNE", "CMOVNZ", "CMOVA", "CMOVNBE", "CMOVAE", 562 | /* 008 */ "CMOVNB", "CMOVB", "CMOVNAE", "CMOVBE", "CMOVNA", "CMOVG", "CMOVNLE", "CMOVGE", 563 | /* 010 */ "CMOVNL", "CMOVL", "CMOVNGE", "CMOVLE", "CMOVNG", "CMOVC", "CMOVNC", "CMOVO", 564 | /* 018 */ "CMOVNO", "CMOVS", "CMOVNS", "CMOVP", "CMOVPE", "CMOVNP", "CMOVPO", "XCHG", 565 | /* 020 */ "BSWAP", "XADD", "CMPXCHG", "CMPXCHG8B", "PUSH", "POP", "PUSHA", "PUSHAD", 566 | /* 028 */ "POPA", "POPAD", "IN", "OUT", "CWD", "CDQ", "CBW", "CWDE", 567 | /* 030 */ "MOVSX", "MOVZX", "ADD", "ADC", "SUB", "SBB", "IMUL", "MUL", 568 | /* 038 */ "IDIV", "DIV", "INC", "DEC", "NEG", "CMP", "DAA", "DAS", 569 | /* 040 */ "AAA", "AAS", "AAM", "AAD", "AND", "OR", "XOR", "NOT", 570 | /* 048 */ "SAR", "SHR", "SAL", "SHL", "SHRD", "SHLD", "ROR", "ROL", 571 | /* 050 */ "RCR", "RCL", "BT", "BTS", "BTR", "BTC", "BSF", "BSR", 572 | /* 058 */ "SETE", "SETZ", "SETNE", "SETNZ", "SETA", "SETNBE", "SETAE", "SETNB", 573 | /* 060 */ "SETNC", "SETB", "SETNAE", "SETC", "SETBE", "SETNA", "SETG", "SETNLE", 574 | /* 068 */ "SETGE", "SETNL", "SETL", "SETNGE", "SETLE", "SETNG", "SETS", "SETNS", 575 | /* 070 */ "SETO", "SETNO", "SETPE", "SETP", "SETPO", "SETNP", "TEST", "JMP", 576 | /* 078 */ "JE", "JZ", "JNE", "JNZ", "JA", "JNBE", "JAE", "JNB", 577 | /* 080 */ "JB", "JNAE", "JBE", "JNA", "JG", "JNLE", "JGE", "JNL", 578 | /* 088 */ "JL", "JNGE", "JLE", "JNG", "JC", "JNC", "JO", "JNO", 579 | /* 090 */ "JS", "JNS", "JPO", "JNP", "JPE", "JP", "JCXZ", "JECXZ", 580 | /* 098 */ "LOOP", "LOOPZ", "LOOPE", "LOOPNZ", "LOOPNE", "CALL", "RET", "IRET", 581 | /* 0A0 */ "INT", "INTO", "BOUND", "ENTER", "LEAVE", "UN00", "MOVSB", "UN01", 582 | /* 0A8 */ "MOVSW", "UN02", "MOVSD", "UN03", "CMPSB", "UN04", "CMPSW", "UN05", 583 | /* 0B0 */ "CMPSD", "UN06", "SCASB", "UN07", "SCASW", "UN08", "SCASD", "UN09", 584 | /* 0B8 */ "LODSB", "UN10", "LODSW", "UN11", "LODSD", "UN12", "STOSB", "UN13", 585 | /* 0C0 */ "STOSW", "UN14", "STOSD", "REP", "REPE", "REPZ", "REPNE", "REPNZ", 586 | /* 0C8 */ "UN15", "INSB", "UN16", "INSW", "UN17", "INSD", "UN18", "OUTSB", 587 | /* 0D0 */ "UN19", "OUTSW", "UN20", "OUTSD", "STC", "CLC", "CMC", "CLD", 588 | /* 0D8 */ "STD", "LAHF", "SAHF", "PUSHF", "PUSHFD", "POPF", "POPFD", "STI", 589 | /* 0E0 */ "CLI", "LDS", "LES", "LFS", "LGS", "LSS", "LEA", "NOP", 590 | /* 0E8 */ "UB2", "XLAT", "XLATB", "CPUID", "MOVD", "MOVQ", "PACKSSWB", "PACKSSDW", 591 | /* 0F0 */ "PACKUSWB", "PUNPCKHBW", "PUNPCKHWD", "PUNPCKHDQ", "PUNPCKLBW", "PUNPCKLWD", "PUNPCKLDQ", "PADDB", 592 | /* 0F8 */ "PADDW", "PADDD", "PADDSB", "PADDSW", "PADDUSB", "PADDUSW", "PSUBB", "PSUBW", 593 | /* 100 */ "PSUBD", "PSUBSB", "PSUBSW", "PSUBUSB", "PSUBUSW", "PMULHW", "PMULLW", "PMADDWD", 594 | /* 108 */ "PCMPEQB", "PCMPEQW", "PCMPEQD", "PCMPGTB", "PCMPGTW", "PCMPGTD", "PAND", "PANDN", 595 | /* 110 */ "POR", "PXOR", "PSLLW", "PSLLD", "PSLLQ", "PSRLW", "PSRLD", "PSRLQ", 596 | /* 118 */ "PSRAW", "PSRAD", "EMMS", "FLD", "FST", "FSTP", "FILD", "FIST", 597 | /* 120 */ "FISTP", "FBLD", "FBSTP", "FXCH", "FCMOVE", "FCMOVNE", "FCMOVB", "FCMOVBE", 598 | /* 128 */ "FCMOVNB", "FCMOVNBE", "FCMOVU", "FCMOVNU", "FADD", "FADDP", "FIADD", "FSUB", 599 | /* 130 */ "FSUBP", "FISUB", "FSUBR", "FSUBRP", "FISUBR", "FMUL", "FMULP", "FIMUL", 600 | /* 138 */ "FDIV", "FDIVP", "FIDIV", "FDIVR", "FDIVRP", "FIDIVR", "FPREM", "FPREMI", 601 | /* 140 */ "FABS", "FCHS", "FRNDINT", "FSCALE", "FSQRT", "FXTRACT", "FCOM", "FCOMP", 602 | /* 148 */ "FCOMPP", "FUCOM", "FUCOMP", "FUCOMPP", "FICOM", "FICOMP", "FCOMI", "FUCOMI", 603 | /* 150 */ "FCOMIP", "FUCOMIP", "FTST", "FXAM", "FSIN", "FCOS", "FSINCOS", "FPTAN", 604 | /* 158 */ "FPATAN", "F2XM1", "FYL2X", "FYL2XP1", "FLD1", "FLDZ", "FLDPI", "FLDL2E", 605 | /* 160 */ "FLDLN2", "FLDL2T", "FLDLG2", "FINCSTP", "FDECSTP", "FFREE", "FINIT", "FNINIT", 606 | /* 168 */ "FCLEX", "FNCLEX", "FSTCW", "FNSTCW", "FLDCW", "FSTENV", "FNSTENV", "FLDENV", 607 | /* 170 */ "FSAVE", "FNSAVE", "FRSTOR", "FSTSW", "FNSTSW", "WAIT", "FWAIT", "FNOP", 608 | /* 178 */ "LGDT", "SGDT", "LLDT", "SLDT", "LTR", "STR", "LIDT", "SIDT", 609 | /* 180 */ "LMSW", "SMSW", "CLTS", "ARPL", "LAR", "LSL", "VERR", "VERW", 610 | /* 188 */ "INVD", "WBINVD", "INVLPG", "LOCK", "HLT", "RSM", "RDMSR", "WRMSR", 611 | /* 190 */ "RDPMC", "RDTSC", "LDDR", "STDR", "LDCR", "STCR", 612 | }; 613 | 614 | private static final char[] sizeLabels = {'b', 'w', 'l', 'x'}; 615 | 616 | static 617 | { 618 | assert opnames.length == 0x193; 619 | } 620 | 621 | /** 622 | * Return the symbolic string for the instruction. 623 | */ 624 | public static String getOp(X86Instruction inst) 625 | { 626 | return opnames[inst.getOpcode() & O_MASK]; 627 | } 628 | 629 | /** 630 | * Return the symbolic string for the instruction. 631 | */ 632 | public static String getOp(X86Branch inst) 633 | { 634 | assert ((inst.getOpcode() & F_BRANCH) != 0); 635 | return opnames[inst.getOpcode() & O_MASK]; 636 | } 637 | 638 | /** 639 | * Return the symbolic string for the instruction. 640 | */ 641 | public static String getOp(int opcode) 642 | { 643 | return opnames[opcode & O_MASK]; 644 | } 645 | 646 | /** 647 | * Return 1, 2, 4, or 8 depending on the scale factor specified for 648 | * the instruction. 649 | */ 650 | public static int getScale(int opcode) 651 | { 652 | return 1 << ((opcode & M_MASK) >> M_SHIFT); 653 | } 654 | 655 | /** 656 | * Set the scale factor specified for the instruction. The value 657 | * must be 1, 2, 4, or 8. 658 | * @return the new opcode 659 | */ 660 | public static int setScale(int opcode, int scale) 661 | { 662 | int sf = 0; 663 | switch (scale) { 664 | case 1: sf = M_ONE; break; 665 | case 2: sf = M_TWO; break; 666 | case 4: sf = M_FOUR; break; 667 | case 8: sf = M_EIGHT; break; 668 | } 669 | return ((opcode & M_MASK) | sf); 670 | } 671 | 672 | /** 673 | * Return 1, 2, 4, or 8 depending on the size of the operand, in 674 | * bytes, specified for the instruction. 675 | */ 676 | public static int getOperandSize(int opcode) 677 | { 678 | return 1 << ((opcode & S_MASK) >> S_SHIFT); 679 | } 680 | 681 | /** 682 | * Return 'b', 'w', 'l', or 'x' depending on the size of the 683 | * operand specified for the instruction. 684 | */ 685 | public static char getOperandSizeLabel(int opcode) 686 | { 687 | return sizeLabels[(opcode & S_MASK) >> S_SHIFT]; 688 | } 689 | 690 | /** 691 | * Set the operand size specified for the instruction. The value 692 | * must be 1, 2, 4, or 8. 693 | * @return the new opcode 694 | */ 695 | public static int setOperandSize(int opcode, int size) 696 | { 697 | int sf = 0; 698 | switch (size) { 699 | case 1: sf = S_BYTE; break; 700 | case 2: sf = S_SHORT; break; 701 | case 4: sf = S_INT; break; 702 | case 8: sf = S_LONG; break; 703 | } 704 | return ((opcode & S_MASK) | sf); 705 | } 706 | } 707 | -------------------------------------------------------------------------------- /refactoring_hacks/autocomments.py: -------------------------------------------------------------------------------- 1 | # quick hack: 2 | # grabs data from XML file describing opcodes from http://ref.x86asm.net 3 | # then autocomments the cpux86 emulator code 4 | # 5 | # (super brittle hack) 6 | # 7 | 8 | from BeautifulSoup import BeautifulStoneSoup #thank you soup, fuck XML parsers 9 | import json, re 10 | 11 | # 12 | # Let me reiterate how much I despise scraping data from XML 13 | # 14 | infile = open("x86reference.xml","r").read() 15 | soup=BeautifulStoneSoup(infile) 16 | onesies=soup.find('one-byte').findAll('pri_opcd') 17 | twosies=soup.find('two-byte').findAll('pri_opcd') 18 | 19 | def hexRepOfOp(op): 20 | i=int(op['value'],16) 21 | if i < 16: 22 | return ("0x0"+hex(i)[2:]).lower() 23 | else: 24 | return ("0x" +hex(i)[2:]).lower() 25 | def mnem(op): 26 | res = op.find('mnem') 27 | if res: 28 | return res.string 29 | else: 30 | return "" 31 | def src(op): 32 | res = op.find('syntax').find('src') 33 | if res: 34 | return res.getText() 35 | else: 36 | return "" 37 | def dst(op): 38 | res = op.find('syntax').find('dst') 39 | if res: 40 | return res.getText() 41 | else: 42 | return "" 43 | def note(op): 44 | res = op.find('note').find('brief') 45 | if res: 46 | return res.getText() 47 | else: 48 | return "" 49 | def opstr(op): 50 | return mnem(op)+" "+src(op)+" "+dst(op)+" "+note(op) 51 | 52 | onedict = {} 53 | for op in onesies: 54 | onedict[hexRepOfOp(op)] = opstr(op) 55 | twodict = {} 56 | for op in twosies: 57 | twodict[hexRepOfOp(op)] = opstr(op) 58 | 59 | # barf some temporaries just for reference later 60 | outfile=open("onebyte_dict.json",'w') 61 | json.dump(onedict,outfile) 62 | outfile.close() 63 | 64 | outfile=open("twobyte_dict.json",'w') 65 | json.dump(twodict,outfile) 66 | outfile.close() 67 | 68 | # now transform source file -------------------------------------------------------------------------------- 69 | 70 | # - for weird exec counting function 71 | caseline = re.compile("( case )(0x[0-9a-f]+):.*") 72 | def strip_1(str): 73 | return str 74 | onebyte_start = 3176 75 | twobyte_start = 3177 76 | twobyte_end = 3546 77 | 78 | # - for normal instruction format: 0xXX 79 | #caseline = re.compile("(\s+case )(0x[0-9a-f]+):.*") 80 | #def strip_1(str): 81 | # return str 82 | #onebyte_start = 5662 83 | #twobyte_start = 7551 84 | #twobyte_end = 8291 85 | 86 | # - for 16bit compat instruction format: 0x1XX 87 | #caseline = re.compile("(\s+case )(0x1[0-9a-f]+):.*") 88 | #def strip_1(str): 89 | # return "0x"+str[-2:] 90 | #onebyte_start = 8472 91 | #twobyte_start = 9245 92 | #twobyte_end = 9647 93 | 94 | emulatorlines = open("cpux86-ta.js","r").readlines() 95 | newlines=[] 96 | for i,line in enumerate(emulatorlines): 97 | if i < onebyte_start: 98 | newlines.append(line) 99 | if onebyte_start <= i < twobyte_start: #one-byte instructions 100 | linematch=caseline.match(line) 101 | if linematch: 102 | try: 103 | newlines.append(linematch.group(1)+linematch.group(2)+"://"+onedict[strip_1(linematch.group(2))]+"\n") 104 | except KeyError: 105 | newlines.append(line) 106 | else: 107 | newlines.append(line) 108 | if twobyte_start <= i < twobyte_end: #two-byte instructions 109 | linematch=caseline.match(line) 110 | if linematch: 111 | try: 112 | newlines.append(linematch.group(1)+linematch.group(2)+"://"+twodict[strip_1(linematch.group(2))]+"\n") 113 | except KeyError: 114 | newlines.append(line) 115 | else: 116 | newlines.append(line) 117 | if twobyte_end <= i: 118 | newlines.append(line) 119 | 120 | outfile=open("cpux86-ta-auto-annotated.js",'w') 121 | outfile.writelines(newlines) 122 | outfile.close() 123 | -------------------------------------------------------------------------------- /refactoring_hacks/js-change-symbol.el: -------------------------------------------------------------------------------- 1 | ;; 2 | ;; Simple hack to use JSShaper script reify.js to change symbolnames on the fly in an emacs buffer. 3 | ;; assumes existence of /var/tmp and unix tools 4 | ;; 5 | (defun js-change-symbol (name1 name2) 6 | (interactive "sOld Symbol Name: 7 | sNew Symbol Name: ") 8 | (let (commandstr (curline (current-line)) (reifypath "/path/to/reify.js")) 9 | (setq commandstr (concat "cat >/var/tmp/refactoring_tmp; node " reifypath " /var/tmp/refactoring_tmp " name1 " " name2)) 10 | (message "Command: %s" commandstr) 11 | ;;this does most of the work: 12 | (shell-command-on-region 1 (point-max) commandstr t t ) 13 | (goto-line curline) 14 | ) 15 | ) 16 | -------------------------------------------------------------------------------- /refactoring_hacks/onebyte_dict.json: -------------------------------------------------------------------------------- 1 | {"0x3e": "DS DS DS segment override prefix", "0x3d": "CMP rAX Compare Two Operands", "0xe4": "IN Ib AL Input from Port", "0x3f": "AAS AL ASCII Adjust AL After Subtraction", "0x3a": "CMP Gb Compare Two Operands", "0x3c": "CMP AL Compare Two Operands", "0x3b": "CMP Gvqp Compare Two Operands", "0xfa": "CLI Clear Interrupt Flag", "0xda": "FIADD Mdi ST Add", "0xec": "IN DX AL Input from Port", "0x28": "SUB Gb Eb Subtract", "0x29": "SUB Gvqp Evqp Subtract", "0xf8": "CLC Clear Carry Flag", "0xeb": "JMP Jbs Jump", "0x22": "AND Eb Gb Logical AND", "0x23": "AND Evqp Gvqp Logical AND", "0x20": "AND Gb Eb Logical AND", "0x21": "AND Gvqp Evqp Logical AND", "0x26": "ES ES ES segment override prefix", "0x27": "DAA AL Decimal Adjust AL after Addition", "0x24": "AND Ib AL Logical AND", "0x25": "AND Ivds rAX Logical AND", "0xef": "OUT eAX DX Output to Port", "0xe2": "LOOP Jbs eCX Decrement count; Jump short if count!=0", "0xee": "OUT AL DX Output to Port", "0xed": "IN DX eAX Input from Port", "0x35": "XOR Ivds rAX Logical Exclusive OR", "0x34": "XOR Ib AL Logical Exclusive OR", "0x37": "AAA AL ASCII Adjust After Addition", "0x36": "SS SS SS segment override prefix", "0x31": "XOR Gvqp Evqp Logical Exclusive OR", "0x30": "XOR Gb Eb Logical Exclusive OR", "0x33": "XOR Evqp Gvqp Logical Exclusive OR", "0x32": "XOR Eb Gb Logical Exclusive OR", "0xd4": "AAM AL ASCII Adjust AX After Multiply", "0x39": "CMP Evqp Compare Two Operands", "0x38": "CMP Eb Compare Two Operands", "0xc0": "ROL Ib Eb Rotate", "0xe1": "LOOPZ Jbs eCX Decrement count; Jump short if count!=0 and ZF=1", "0xfe": "INC Eb Increment by 1", "0x88": "MOV Gb Eb Move", "0x89": "MOV Gvqp Evqp Move", "0x2b": "SUB Evqp Gvqp Subtract", "0x2c": "SUB Ib AL Subtract", "0xfd": "STD Set Direction Flag", "0x2a": "SUB Eb Gb Subtract", "0x2f": "DAS AL Decimal Adjust AL after Subtraction", "0xfc": "CLD Clear Direction Flag", "0x2d": "SUB Ivds rAX Subtract", "0x2e": "CS CS CS segment override prefix", "0x40": "INC Zv Increment by 1", "0x41": "REX.B Extension of r/m field, base field, or opcode reg field", "0x42": "REX.X Extension of SIB index field", "0x43": "REX.XB REX.X and REX.B combination", "0x44": "REX.R Extension of ModR/M reg field", "0x45": "REX.RB REX.R and REX.B combination", "0x46": "REX.RX REX.R and REX.X combination", "0x47": "REX.RXB REX.R, REX.X and REX.B combination", "0x48": "DEC Zv Decrement by 1", "0x49": "REX.WB REX.W and REX.B combination", "0xaf": "SCAS ES:[DI] Scan String", "0xae": "SCAS (ES:)[rDI] Scan String", "0xad": "LODS DS:[SI] AX Load String", "0xac": "LODS (DS:)[rSI] AL Load String", "0xab": "STOS AX ES:[DI] Store String", "0xaa": "STOS AL (ES:)[rDI] Store String", "0xe6": "OUT AL Ib Output to Port", "0xea": "JMPF Ap Jump", "0x4a": "REX.WX REX.W and REX.X combination", "0x4b": "REX.WXB REX.W, REX.X and REX.B combination", "0x4c": "REX.WR REX.W and REX.R combination", "0x4d": "REX.WRB REX.W, REX.R and REX.B combination", "0x4e": "REX.WRX REX.W, REX.R and REX.X combination", "0x4f": "REX.WRXB REX.W, REX.R, REX.X and REX.B combination", "0xff": "INC Evqp Increment by 1", "0x50": "PUSH Zv SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0xe5": "IN Ib eAX Input from Port", "0x58": "POP SS:[rSP] Zv Pop a Value from the Stack", "0xf4": "HLT Halt", "0xfb": "STI Set Interrupt Flag", "0xf9": "STC Set Carry Flag", "0xf6": "TEST Eb Logical Compare", "0xa9": "TEST rAX Logical Compare", "0xa8": "TEST AL Logical Compare", "0xa7": "CMPS ES:[DI] Compare String Operands", "0xa6": "CMPS (ES:)[rDI] Compare String Operands", "0xa5": "MOVS DS:[SI] ES:[DI] Move Data from String to String", "0xa4": "MOVS (DS:)[rSI] (ES:)[rDI] Move Data from String to String", "0xa3": "MOV rAX Ovqp Move", "0xa2": "MOV AL Ob Move", "0xa1": "MOV Ovqp rAX Move", "0xa0": "MOV Ob AL Move", "0xf5": "CMC Complement Carry Flag", "0x7a": "JP Jbs Jump short if parity/parity even (PF=1)", "0xf2": "REPNZ eCX Repeat String Operation Prefix", "0x7c": "JL Jbs Jump short if less/not greater (SF!=OF)", "0x7b": "JNP Jbs Jump short if not parity/parity odd", "0x7e": "JLE Jbs Jump short if less or equal/not greater ((ZF=1) OR (SF!=OF))", "0x7d": "JNL Jbs Jump short if not less/greater or equal (SF=OF)", "0x7f": "JNLE Jbs Jump short if not less nor equal/greater ((ZF=0) AND (SF=OF))", "0xf0": "LOCK Assert LOCK# Signal Prefix", "0x68": "PUSH Ivs SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0x69": "IMUL Evqp Gvqp Signed Multiply", "0x66": " Operand-size override prefix", "0x67": " Address-size override prefix", "0x64": "FS FS FS segment override prefix", "0x65": "GS GS GS segment override prefix", "0x62": "BOUND Gv SS:[rSP] Check Array Index Against Bounds", "0x63": "ARPL Ew Adjust RPL Field of Segment Selector", "0x60": "PUSHA AX SS:[rSP] Push All General-Purpose Registers", "0x61": "POPA SS:[rSP] DI Pop All General-Purpose Registers", "0xd5": "AAD AL ASCII Adjust AX Before Division", "0xce": "INTO eFlags SS:[rSP] Call to Interrupt Procedure", "0xcd": "INT Ib SS:[rSP] Call to Interrupt Procedure", "0xb8": "MOV Ivqp Zvqp Move", "0xcf": "IRET SS:[rSP] Flags Interrupt Return", "0xca": "RETF Iw Return from procedure", "0xcc": "INT 3 SS:[rSP] Call to Interrupt Procedure", "0xcb": "RETF SS:[rSP] Return from procedure", "0xb0": "MOV Ib Zb Move", "0xf3": "REPZ eCX Repeat String Operation Prefix", "0xe3": "JCXZ Jbs Jump short if eCX register is 0", "0xd6": "SALC Undefined and Reserved; Does not Generate #UD", "0x6f": "OUTS DS:[SI] DX Output String to Port", "0x6d": "INS DX ES:[DI] Input from Port to String", "0x6e": "OUTS (DS):[rSI] DX Output String to Port", "0x6b": "IMUL Evqp Gvqp Signed Multiply", "0x6c": "INS DX (ES:)[rDI] Input from Port to String", "0x6a": "PUSH Ibss SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0x79": "JNS Jbs Jump short if not sign (SF=0)", "0x78": "JS Jbs Jump short if sign (SF=1)", "0x71": "JNO Jbs Jump short if not overflow (OF=0)", "0x70": "JO Jbs Jump short if overflow (OF=1)", "0x73": "JNB Jbs Jump short if not below/above or equal/not carry (CF=0)", "0x72": "JB Jbs Jump short if below/not above or equal/carry (CF=1)", "0x75": "JNZ Jbs Jump short if not zero/not equal (ZF=1)", "0x74": "JZ Jbs Jump short if zero/equal (ZF=0)", "0x77": "JNBE Jbs Jump short if not below or equal/above (CF=0 AND ZF=0)", "0x76": "JBE Jbs Jump short if below or equal/not above (CF=1 AND ZF=1)", "0xc5": "LDS Mp DS Load Far Pointer", "0xc4": "LES Mp ES Load Far Pointer", "0xc7": "MOV Ivds Evqp Move", "0xc6": "MOV Ib Eb Move", "0xc1": "ROL Ib Evqp Rotate", "0x8b": "MOV Evqp Gvqp Move", "0xc3": "RETN SS:[rSP] Return from procedure", "0xc2": "RETN SS:[rSP] Return from procedure", "0x8c": "MOV Sw Mw Move", "0xc9": "LEAVE SS:[rSP] eBP High Level Procedure Exit", "0xc8": "ENTER Iw SS:[rSP] Make Stack Frame for Procedure Parameters", "0xf1": "INT1 Undefined and Reserved; Does not Generate #UD", "0xe9": "JMP Jvds Jump", "0xe8": "CALL Jvds SS:[rSP] Call Procedure", "0xd9": "FLD ESsr ST Load Floating Point Value", "0xf7": "TEST Evqp Logical Compare", "0xd0": "ROL 1 Eb Rotate", "0x9f": "LAHF AH Load Status Flags into AH Register", "0x9e": "SAHF AH Store AH into Flags", "0x9d": "POPF SS:[rSP] Flags Pop Stack into FLAGS Register", "0x08": "OR Gb Eb Logical Inclusive OR", "0x09": "OR Gvqp Evqp Logical Inclusive OR", "0x9a": "CALLF Ap SS:[rSP] Call Procedure", "0xd7": "XLAT (DS:)[rBX+AL] AL Table Look-up Translation", "0x04": "ADD Ib AL Add", "0x05": "ADD Ivds rAX Add", "0x06": "PUSH ES SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0x07": "POP SS:[rSP] ES Pop a Value from the Stack", "0x00": "ADD Gb Eb Add", "0x01": "ADD Gvqp Evqp Add", "0x02": "ADD Eb Gb Add", "0x03": "ADD Evqp Gvqp Add", "0x84": "TEST Eb Logical Compare", "0x85": "TEST Evqp Logical Compare", "0x86": "XCHG Gb Exchange Register/Memory with Register", "0x87": "XCHG Gvqp Exchange Register/Memory with Register", "0x80": "ADD Ib Eb Add", "0x81": "ADD Ivds Evqp Add", "0x82": "ADD Ib Eb Add", "0x83": "ADD Ibs Evqp Add", "0x1f": "POP SS:[rSP] DS Pop a Value from the Stack", "0x1e": "PUSH DS SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0x1d": "SBB Ivds rAX Integer Subtraction with Borrow", "0x1c": "SBB Ib AL Integer Subtraction with Borrow", "0x1b": "SBB Evqp Gvqp Integer Subtraction with Borrow", "0x1a": "SBB Eb Gb Integer Subtraction with Borrow", "0xde": "FIADD Mwi ST Add", "0xd1": "ROL 1 Evqp Rotate", "0xd2": "ROL CL Eb Rotate", "0xd3": "ROL CL Evqp Rotate", "0x9c": "PUSHF Flags SS:[rSP] Push FLAGS Register onto the Stack", "0x9b": "FWAIT Check pending unmasked floating-point exceptions", "0x8d": "LEA M Gvqp Load Effective Address", "0x8e": "MOV Ew Sw Move", "0x8f": "POP SS:[rSP] Ev Pop a Value from the Stack", "0xe0": "LOOPNZ Jbs eCX Decrement count; Jump short if count!=0 and ZF=0", "0xe7": "OUT eAX Ib Output to Port", "0x8a": "MOV Eb Gb Move", "0x19": "SBB Gvqp Evqp Integer Subtraction with Borrow", "0x18": "SBB Gb Eb Integer Subtraction with Borrow", "0x17": "POP SS:[rSP] SS Pop a Value from the Stack", "0x16": "PUSH SS SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0x15": "ADC Ivds rAX Add with Carry", "0x14": "ADC Ib AL Add with Carry", "0x13": "ADC Evqp Gvqp Add with Carry", "0x12": "ADC Eb Gb Add with Carry", "0x11": "ADC Gvqp Evqp Add with Carry", "0x10": "ADC Gb Eb Add with Carry", "0xd8": "FADD Msr ST Add", "0xdb": "FILD Mdi ST Load Integer", "0xdc": "FADD Mdr ST Add", "0xdd": "FLD Mdr ST Load Floating Point Value", "0x99": "CWD AX DX Convert Word to Doubleword", "0xdf": "FILD Mwi ST Load Integer", "0x90": "XCHG Zvqp Exchange Register/Memory with Register", "0x0d": "OR Ivds rAX Logical Inclusive OR", "0x0e": "PUSH CS SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0x0f": "POP SS:[rSP] CS Pop a Value from the Stack", "0x98": "CBW AL AX Convert Byte to Word", "0x0a": "OR Eb Gb Logical Inclusive OR", "0x0b": "OR Evqp Gvqp Logical Inclusive OR", "0x0c": "OR Ib AL Logical Inclusive OR"} -------------------------------------------------------------------------------- /refactoring_hacks/reify.js: -------------------------------------------------------------------------------- 1 | /* 2 | JS Reify 3 | 4 | Uses JSShaper to parse javascript files and replace symbol names 5 | 6 | >node reify.js [filename] old_symbolname new_symbolname 7 | 8 | - it barfs output to stdout 9 | - doesn't work w. stdin, node.js can't do sync stdin, 10 | so write to tmpfile for external feeding of this animal) 11 | */ 12 | "use strict"; "use restrict"; 13 | var require = require || function(f) { load(f); }; 14 | require.paths && typeof __dirname !== "undefined" && require.paths.unshift(__dirname); 15 | var args = (typeof process !== "undefined" && process.argv !== undefined) ? 16 | process.argv.slice(2) : arguments; 17 | var log = (typeof console !== "undefined") && console.log || print; 18 | 19 | //if (args.length > 0 && args[0] === "--") { 20 | // args.shift(); 21 | //} 22 | 23 | if (args.length <= 0) { 24 | log("run-shaper: filename OLDNAME NEWNAME"); 25 | (typeof quit === "undefined" ? process.exit : quit)(0); 26 | } 27 | var Shaper = Shaper || require("shaper.js") || Shaper; 28 | 29 | var filename = args.shift(); 30 | var ORIGNAME = args.shift(); 31 | var NEWNAME = args.shift(); 32 | 33 | //define reify transformer 34 | Shaper("reify", function(root) { 35 | return Shaper.traverse(root, {pre: function(node, ref) { 36 | if (node.type === tkn.IDENTIFIER) { // or: if (Shaper.match("$", node)) { 37 | if(node.value === ORIGNAME ){ 38 | Shaper.renameIdentifier(node, NEWNAME); 39 | } 40 | } 41 | }}); 42 | }); 43 | 44 | //specify the transform pipeline 45 | var pipeline = ["reify","source"]; 46 | 47 | // read: js/d8/v8 || rhino || node 48 | var read = read || typeof readFile !== "undefined" && readFile || require("fs").readFileSync; 49 | var src = read(filename); 50 | var root = Shaper.parseScript(src, filename); 51 | root = Shaper.run(root, pipeline); 52 | -------------------------------------------------------------------------------- /refactoring_hacks/twobyte_dict.json: -------------------------------------------------------------------------------- 1 | {"0xe4": "PMULHUW Qq Pq Multiply Packed Unsigned Integers and Store High Result", "0x3a": "ROUNDPS Wps Vps Round Packed Single-FP Values", "0xfa": "PSUBD Qq Pq Subtract Packed Integers", "0xda": "PMINUB Qq Pq Minimum of Packed Unsigned Byte Integers", "0xec": "PADDSB Qq Pq Add Packed Signed Integers with Signed Saturation", "0x28": "MOVAPS Wps Vps Move Aligned Packed Single-FP Values", "0x29": "MOVAPS Vps Wps Move Aligned Packed Single-FP Values", "0xf8": "PSUBB Qq Pq Subtract Packed Integers", "0xeb": "POR Qq Pq Bitwise Logical OR", "0x22": "MOV Rd Cd Move to/from Control Registers", "0x23": "MOV Rd Dd Move to/from Debug Registers", "0x20": "MOV Cd Rd Move to/from Control Registers", "0x21": "MOV Dd Rd Move to/from Debug Registers", "0x26": "MOV Rd Td Move to/from Test Registers", "0xea": "PMINSW Qq Pq Minimum of Packed Signed Word Integers", "0x24": "MOV Td Rd Move to/from Test Registers", "0xf1": "PSLLW Qq Pq Shift Packed Data Left Logical", "0xdb": "PAND Qd Pq Logical AND", "0xef": "PXOR Qq Pq Logical Exclusive OR", "0xe2": "PSRAD Qq Pq Shift Packed Data Right Arithmetic", "0xee": "PMAXSW Qq Pq Maximum of Packed Signed Word Integers", "0xed": "PADDSW Qq Pq Add Packed Signed Integers with Signed Saturation", "0xdc": "PADDUSB Qq Pq Add Packed Unsigned Integers with Unsigned Saturation", "0x35": "SYSEXIT IA32_SYSENTER_CS SS Fast Return from Fast System Call", "0x34": "SYSENTER IA32_SYSENTER_CS SS Fast System Call", "0x37": "GETSEC EAX GETSEC Leaf Functions", "0x31": "RDTSC IA32_TIME_STAMP_COUNTER EAX Read Time-Stamp Counter", "0x30": "WRMSR rCX MSR Write to Model Specific Register", "0x33": "RDPMC PMC EAX Read Performance-Monitoring Counters", "0x32": "RDMSR rCX rAX Read from Model Specific Register", "0x38": "PSHUFB Qq Pq Packed Shuffle Bytes", "0xc0": "XADD Eb Exchange and Add", "0xe1": "PSRAW Qq Pq Shift Packed Data Right Arithmetic", "0xfe": "PADDD Qq Pq Add Packed Integers", "0x88": "JS Jvds Jump short if sign (SF=1)", "0xdd": "PADDUSW Qq Pq Add Packed Unsigned Integers with Unsigned Saturation", "0x89": "JNS Jvds Jump short if not sign (SF=0)", "0x2b": "MOVNTPS Vps Mps Store Packed Single-FP Values Using Non-Temporal Hint", "0x2c": "CVTTPS2PI Wpsq Ppi Convert with Trunc. Packed Single-FP Values to1.11 PackedDW Integers", "0xfd": "PADDW Qq Pq Add Packed Integers", "0x2a": "CVTPI2PS Qpi Vps Convert Packed DW Integers to1.11 PackedSingle-FP Values", "0x2f": "COMISS Vss Compare Scalar Ordered Single-FP Values and Set EFLAGS", "0xfc": "PADDB Qq Pq Add Packed Integers", "0x2d": "CVTPS2PI Wpsq Ppi Convert Packed Single-FP Values to1.11 PackedDW Integers", "0x2e": "UCOMISS Vss Unordered Compare Scalar Single-FP Values and Set EFLAGS", "0x5c": "SUBPS Wps Vps Subtract Packed Single-FP Values", "0x5b": "CVTDQ2PS Wdq Vps Convert Packed DW Integers to1.11 PackedSingle-FP Values", "0x5a": "CVTPS2PD Wps Vpd Convert Packed Single-FP Values to1.11 PackedDouble-FP Values", "0xba": "BT Evqp Bit Test", "0x5f": "MAXPS Wps Vps Return Maximum Packed Single-FP Values", "0x5e": "DIVPS Wps Vps Divide Packed Single-FP Values", "0x5d": "MINPS Wps Vps Return Minimum Packed Single-FP Values", "0x40": "CMOVO Evqp Gvqp Conditional Move - overflow (OF=1)", "0x41": "CMOVNO Evqp Gvqp Conditional Move - not overflow (OF=0)", "0x42": "CMOVB Evqp Gvqp Conditional Move - below/not above or equal/carry (CF=1)", "0x43": "CMOVNB Evqp Gvqp Conditional Move - not below/above or equal/not carry (CF=0)", "0x44": "CMOVZ Evqp Gvqp Conditional Move - zero/equal (ZF=0)", "0x45": "CMOVNZ Evqp Gvqp Conditional Move - not zero/not equal (ZF=1)", "0x46": "CMOVBE Evqp Gvqp Conditional Move - below or equal/not above (CF=1 AND ZF=1)", "0x47": "CMOVNBE Evqp Gvqp Conditional Move - not below or equal/above (CF=0 AND ZF=0)", "0x48": "CMOVS Evqp Gvqp Conditional Move - sign (SF=1)", "0x49": "CMOVNS Evqp Gvqp Conditional Move - not sign (SF=0)", "0xaf": "IMUL Evqp Gvqp Signed Multiply", "0xae": "FXSAVE ST Mstx Save x87 FPU, MMX, XMM, and MXCSR State", "0xad": "SHRD Gvqp Evqp Double Precision Shift Right", "0xac": "SHRD Gvqp Evqp Double Precision Shift Right", "0xab": "BTS Gvqp Evqp Bit Test and Set", "0xaa": "RSM Flags Resume from System Management Mode", "0xe6": "CVTPD2DQ Wpd Vdq Convert Packed Double-FP Values to1.11 PackedDW Integers", "0x4a": "CMOVP Evqp Gvqp Conditional Move - parity/parity even (PF=1)", "0x4b": "CMOVNP Evqp Gvqp Conditional Move - not parity/parity odd", "0x4c": "CMOVL Evqp Gvqp Conditional Move - less/not greater (SF!=OF)", "0x4d": "CMOVNL Evqp Gvqp Conditional Move - not less/greater or equal (SF=OF)", "0x4e": "CMOVLE Evqp Gvqp Conditional Move - less or equal/not greater ((ZF=1) OR (SF!=OF))", "0x4f": "CMOVNLE Evqp Gvqp Conditional Move - not less nor equal/greater ((ZF=0) AND (SF=OF))", "0x53": "RCPPS Wps Vps Compute Reciprocals of Packed Single-FP Values", "0x52": "RSQRTPS Wps Vps Compute Recipr. of Square Roots of Packed Single-FP Values", "0x51": "SQRTPS Wps Vps Compute Square Roots of Packed Single-FP Values", "0x50": "MOVMSKPS Ups Gdqp Extract Packed Single-FP Sign Mask", "0x57": "XORPS Wps Vps Bitwise Logical XOR for Single-FP Values", "0x56": "ORPS Wps Vps Bitwise Logical OR of Single-FP Values", "0x55": "ANDNPS Wps Vps Bitwise Logical AND NOT of Packed Single-FP Values", "0x54": "ANDPS Wps Vps Bitwise Logical AND of Packed Single-FP Values", "0xe5": "PMULHW Qq Pq Multiply Packed Signed Integers and Store High Result", "0x59": "MULPS Wps Vps Multiply Packed Single-FP Values", "0x58": "ADDPS Wps Vps Add Packed Single-FP Values", "0xf4": "PMULUDQ Qq Pq Multiply Packed Unsigned DW Integers", "0xfb": "PSUBQ Qq Pq Subtract Packed Quadword Integers", "0xf9": "PSUBW Qq Pq Subtract Packed Integers", "0xf6": "PSADBW Qq Pq Compute Sum of Absolute Differences", "0xa9": "POP SS:[rSP] GS Pop a Value from the Stack", "0xa8": "PUSH GS SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0xa5": "SHLD Gvqp Evqp Double Precision Shift Left", "0xa4": "SHLD Gvqp Evqp Double Precision Shift Left", "0xa3": "BT Evqp Bit Test", "0xa2": "CPUID IA32_BIOS_SIGN_ID CPU Identification", "0xa1": "POP SS:[rSP] FS Pop a Value from the Stack", "0xa0": "PUSH FS SS:[rSP] Push Word, Doubleword or Quadword Onto the Stack", "0xf5": "PMADDWD Qd Pq Multiply and Add Packed Integers", "0xf2": "PSLLD Qq Pq Shift Packed Data Left Logical", "0x7c": "HADDPD Wpd Vpd Packed Double-FP Horizontal Add", "0xd4": "PADDQ Qq Pq Add Packed Quadword Integers", "0x7e": "MOVD Pq Ed Move Doubleword", "0x7d": "HSUBPD Wpd Vpd Packed Double-FP Horizontal Subtract", "0x7f": "MOVQ Pq Qq Move Quadword", "0xf0": "LDDQU Mdq Vdq Load Unaligned Integer 128 Bits", "0x68": "PUNPCKHBW Qq Pq Unpack High Data", "0x69": "PUNPCKHWD Qq Pq Unpack High Data", "0x66": "PCMPGTD Qd Pq Compare Packed Signed Integers for Greater Than", "0x67": "PACKUSWB Qq Pq Pack with Unsigned Saturation", "0x64": "PCMPGTB Qd Pq Compare Packed Signed Integers for Greater Than", "0x65": "PCMPGTW Qd Pq Compare Packed Signed Integers for Greater Than", "0x62": "PUNPCKLDQ Qd Pq Unpack Low Data", "0x63": "PACKSSWB Qd Pq Pack with Signed Saturation", "0x60": "PUNPCKLBW Qd Pq Unpack Low Data", "0x61": "PUNPCKLWD Qd Pq Unpack Low Data", "0x99": "SETNS Eb Set Byte on Condition - not sign (SF=0)", "0xd5": "PMULLW Qq Pq Multiply Packed Signed Integers and Store Low Result", "0xf3": "PSLLQ Qq Pq Shift Packed Data Left Logical", "0xb8": "JMPE Jump to IA-64 Instruction Set", "0xb9": "UD G Undefined Instruction", "0xb2": "LSS Mptp SS Load Far Pointer", "0xb3": "BTR Gvqp Evqp Bit Test and Reset", "0xb0": "CMPXCHG Gb Eb Compare and Exchange", "0xb1": "CMPXCHG Gvqp Evqp Compare and Exchange", "0xb6": "MOVZX Eb Gvqp Move with Zero-Extend", "0xb7": "MOVZX Ew Gvqp Move with Zero-Extend", "0xb4": "LFS Mptp FS Load Far Pointer", "0xb5": "LGS Mptp GS Load Far Pointer", "0xe3": "PAVGW Qq Pq Average Packed Integers", "0xd6": "MOVQ Vq Wq Move Quadword", "0x6f": "MOVQ Qq Pq Move Quadword", "0x6d": "PUNPCKHQDQ Wdq Vdq Unpack High Data", "0x6e": "MOVD Ed Pq Move Doubleword", "0x6b": "PACKSSDW Qq Pq Pack with Signed Saturation", "0x6c": "PUNPCKLQDQ Wdq Vdq Unpack Low Data", "0x6a": "PUNPCKHDQ Qq Pq Unpack High Data", "0x79": "VMWRITE Gd Write Field to Virtual-Machine Control Structure", "0x78": "VMREAD Gd Ed Read Field from Virtual-Machine Control Structure", "0x71": "PSRLW Ib Nq Shift Packed Data Right Logical", "0x70": "PSHUFW Qq Pq Shuffle Packed Words", "0x73": "PSRLQ Ib Nq Shift Packed Data Right Logical", "0x72": "PSRLD Ib Nq Shift Double Quadword Right Logical", "0x75": "PCMPEQW Qq Pq Compare Packed Data for Equal", "0x74": "PCMPEQB Qq Pq Compare Packed Data for Equal", "0x77": "EMMS Empty MMX Technology State", "0x76": "PCMPEQD Qq Pq Compare Packed Data for Equal", "0xc5": "PEXTRW Nq Gdqp Extract Word", "0xc4": "PINSRW Rdqp Pq Insert Word", "0xc7": "CMPXCHG8B EBX Mq Compare and Exchange Bytes", "0xc6": "SHUFPS Wps Vps Shuffle Packed Single-FP Values", "0xc1": "XADD Evqp Exchange and Add", "0x8b": "JNP Jvds Jump short if not parity/parity odd", "0xc3": "MOVNTI Gdqp Mdqp Store Doubleword Using Non-Temporal Hint", "0xc2": "CMPPS Wps Vps Compare Packed Single-FP Values", "0xbb": "BTC Gvqp Evqp Bit Test and Complement", "0xbc": "BSF Evqp Gvqp Bit Scan Forward", "0x8c": "JL Jvds Jump short if less/not greater (SF!=OF)", "0xbf": "MOVSX Ew Gvqp Move with Sign-Extension", "0xc8": "BSWAP Zvqp Byte Swap", "0xbd": "BSR Evqp Gvqp Bit Scan Reverse", "0xbe": "MOVSX Eb Gvqp Move with Sign-Extension", "0xe9": "PSUBSW Qq Pq Subtract Packed Signed Integers with Signed Saturation", "0xe8": "PSUBSB Qq Pq Subtract Packed Signed Integers with Signed Saturation", "0xd9": "PSUBUSW Qq Pq Subtract Packed Unsigned Integers with Unsigned Saturation", "0xf7": "MASKMOVQ Nq (DS:)[rDI] Store Selected Bytes of Quadword", "0xd0": "ADDSUBPD Wpd Vpd Packed Double-FP Add/Subtract", "0x9f": "SETNLE Eb Set Byte on Condition - not less nor equal/greater ((ZF=0) AND (SF=OF))", "0x9e": "SETLE Eb Set Byte on Condition - less or equal/not greater ((ZF=1) OR (SF!=OF))", "0x9d": "SETNL Eb Set Byte on Condition - not less/greater or equal (SF=OF)", "0x08": "INVD Invalidate Internal Caches", "0x09": "WBINVD Write Back and Invalidate Cache", "0x9a": "SETP Eb Set Byte on Condition - parity/parity even (PF=1)", "0xd7": "PMOVMSKB Nq Gdqp Move Byte Mask", "0xd8": "PSUBUSB Qq Pq Subtract Packed Unsigned Integers with Unsigned Saturation", "0x05": "LOADALL AX Load All of the CPU Registers", "0x06": "CLTS CR0 Clear Task-Switched Flag in CR0", "0x07": "LOADALL EAX Load All of the CPU Registers", "0x00": "SLDT LDTR Mw Store Local Descriptor Table Register", "0x01": "SGDT GDTR Ms Store Global Descriptor Table Register", "0x02": "LAR Mw Gvqp Load Access Rights Byte", "0x03": "LSL Mw Gvqp Load Segment Limit", "0x84": "JZ Jvds Jump short if zero/equal (ZF=0)", "0x85": "JNZ Jvds Jump short if not zero/not equal (ZF=1)", "0x86": "JBE Jvds Jump short if below or equal/not above (CF=1 AND ZF=1)", "0x87": "JNBE Jvds Jump short if not below or equal/above (CF=0 AND ZF=0)", "0x80": "JO Jvds Jump short if overflow (OF=1)", "0x81": "JNO Jvds Jump short if not overflow (OF=0)", "0x82": "JB Jvds Jump short if below/not above or equal/carry (CF=1)", "0x83": "JNB Jvds Jump short if not below/above or equal/not carry (CF=0)", "0x1f": "HINT_NOP Ev Hintable NOP", "0x1e": "HINT_NOP Ev Hintable NOP", "0x1d": "HINT_NOP Ev Hintable NOP", "0x1c": "HINT_NOP Ev Hintable NOP", "0x1b": "HINT_NOP Ev Hintable NOP", "0x1a": "HINT_NOP Ev Hintable NOP", "0xde": "PMAXUB Qq Pq Maximum of Packed Unsigned Byte Integers", "0xdf": "PANDN Qq Pq Logical AND NOT", "0xd1": "PSRLW Qq Pq Shift Packed Data Right Logical", "0xd2": "PSRLD Qq Pq Shift Packed Data Right Logical", "0xd3": "PSRLQ Qq Pq Shift Packed Data Right Logical", "0x9c": "SETL Eb Set Byte on Condition - less/not greater (SF!=OF)", "0x9b": "SETNP Eb Set Byte on Condition - not parity/parity odd", "0x8d": "JNL Jvds Jump short if not less/greater or equal (SF=OF)", "0x8e": "JLE Jvds Jump short if less or equal/not greater ((ZF=1) OR (SF!=OF))", "0x8f": "JNLE Jvds Jump short if not less nor equal/greater ((ZF=0) AND (SF=OF))", "0xe0": "PAVGB Qq Pq Average Packed Integers", "0xe7": "MOVNTQ Pq Mq Store of Quadword Using Non-Temporal Hint", "0x8a": "JP Jvds Jump short if parity/parity even (PF=1)", "0x19": "HINT_NOP Ev Hintable NOP", "0x18": "HINT_NOP Ev Hintable NOP", "0x17": "MOVHPS Vq Mq Move High Packed Single-FP Values", "0x16": "MOVLHPS Uq Vq Move Packed Single-FP Values Low to High", "0x15": "UNPCKHPS Wq Vps Unpack and Interleave High Packed Single-FP Values", "0x14": "UNPCKLPS Wq Vps Unpack and Interleave Low Packed Single-FP Values", "0x13": "MOVLPS Vq Mq Move Low Packed Single-FP Values", "0x12": "MOVHLPS Uq Vq Move Packed Single-FP Values High to Low", "0x11": "MOVUPS Vps Wps Move Unaligned Packed Single-FP Values", "0x10": "MOVUPS Wps Vps Move Unaligned Packed Single-FP Values", "0x97": "SETNBE Eb Set Byte on Condition - not below or equal/above (CF=0 AND ZF=0)", "0x96": "SETBE Eb Set Byte on Condition - below or equal/not above (CF=1 AND ZF=1)", "0x95": "SETNZ Eb Set Byte on Condition - not zero/not equal (ZF=1)", "0x94": "SETZ Eb Set Byte on Condition - zero/equal (ZF=0)", "0x93": "SETNB Eb Set Byte on Condition - not below/above or equal/not carry (CF=0)", "0x92": "SETB Eb Set Byte on Condition - below/not above or equal/carry (CF=1)", "0x91": "SETNO Eb Set Byte on Condition - not overflow (OF=0)", "0x90": "SETO Eb Set Byte on Condition - overflow (OF=1)", "0x0d": "NOP Ev No Operation", "0x0b": "UD2 Undefined Instruction", "0x98": "SETS Eb Set Byte on Condition - sign (SF=1)"} -------------------------------------------------------------------------------- /root.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levskaya/jslinux-deobfuscated/d3ff9f170d79b8ca2847d554ceffda2bca150e55/root.bin -------------------------------------------------------------------------------- /term.js: -------------------------------------------------------------------------------- 1 | /* 2 | Javascript Terminal 3 | 4 | Copyright (c) 2011 Fabrice Bellard 5 | 6 | Redistribution or commercial use is prohibited without the author's 7 | permission. 8 | */ 9 | "use strict"; 10 | if (!Function.prototype.bind) { 11 | Function.prototype.bind = function(aa) { 12 | var ba = [].slice, ca = ba.call(arguments, 1), self = this, da = function() { 13 | }, ea = function() { 14 | return self.apply(this instanceof da ? this : (aa || {}), ca.concat(ba.call(arguments))); 15 | }; 16 | da.prototype = self.prototype; 17 | ea.prototype = new da(); 18 | return ea; 19 | }; 20 | } 21 | function Term(fa, ga, ha) { 22 | this.w = fa; 23 | this.h = ga; 24 | this.cur_h = ga; 25 | this.tot_h = 1000; 26 | this.y_base = 0; 27 | this.y_disp = 0; 28 | this.x = 0; 29 | this.y = 0; 30 | this.cursorstate = 0; 31 | this.handler = ha; 32 | this.convert_lf_to_crlf = false; 33 | this.state = 0; 34 | this.output_queue = ""; 35 | this.bg_colors = ["#000000", "#ff0000", "#00ff00", "#ffff00", "#0000ff", "#ff00ff", "#00ffff", "#ffffff"]; 36 | this.fg_colors = ["#000000", "#ff0000", "#00ff00", "#ffff00", "#0000ff", "#ff00ff", "#00ffff", "#ffffff"]; 37 | this.def_attr = (7 << 3) | 0; 38 | this.cur_attr = this.def_attr; 39 | this.is_mac = (navigator.userAgent.indexOf("Mac") >= 0) ? true : false; 40 | this.key_rep_state = 0; 41 | this.key_rep_str = ""; 42 | } 43 | Term.prototype.open = function() { 44 | var y, ia, i, ja, c; 45 | this.lines = new Array(); 46 | c = 32 | (this.def_attr << 16); 47 | for (y = 0; y < this.cur_h; y++) { 48 | ia = new Array(); 49 | for (i = 0; i < this.w; i++) 50 | ia[i] = c; 51 | this.lines[y] = ia; 52 | } 53 | document.writeln(''); 54 | for (y = 0; y < this.h; y++) { 55 | document.writeln(''); 56 | } 57 | document.writeln('
'); 58 | this.refresh(0, this.h - 1); 59 | document.addEventListener("keydown", this.keyDownHandler.bind(this), true); 60 | document.addEventListener("keypress", this.keyPressHandler.bind(this), true); 61 | ja = this; 62 | setInterval(function() { 63 | ja.cursor_timer_cb(); 64 | }, 1000); 65 | }; 66 | Term.prototype.refresh = function(ka, la) { 67 | var ma, y, ia, na, c, w, i, oa, pa, qa, ra, sa, ta; 68 | for (y = ka; y <= la; y++) { 69 | ta = y + this.y_disp; 70 | if (ta >= this.cur_h) 71 | ta -= this.cur_h; 72 | ia = this.lines[ta]; 73 | na = ""; 74 | w = this.w; 75 | if (y == this.y && this.cursor_state && this.y_disp == this.y_base) { 76 | oa = this.x; 77 | } else { 78 | oa = -1; 79 | } 80 | qa = this.def_attr; 81 | for (i = 0; i < w; i++) { 82 | c = ia[i]; 83 | pa = c >> 16; 84 | c &= 0xffff; 85 | if (i == oa) { 86 | pa = -1; 87 | } 88 | if (pa != qa) { 89 | if (qa != this.def_attr) 90 | na += ''; 91 | if (pa != this.def_attr) { 92 | if (pa == -1) { 93 | na += ''; 94 | } else { 95 | na += ''; 105 | } 106 | } 107 | } 108 | switch (c) { 109 | case 32: 110 | na += " "; 111 | break; 112 | case 38: 113 | na += "&"; 114 | break; 115 | case 60: 116 | na += "<"; 117 | break; 118 | case 62: 119 | na += ">"; 120 | break; 121 | default: 122 | if (c < 32) { 123 | na += " "; 124 | } else { 125 | na += String.fromCharCode(c); 126 | } 127 | break; 128 | } 129 | qa = pa; 130 | } 131 | if (qa != this.def_attr) { 132 | na += ''; 133 | } 134 | ma = document.getElementById("tline" + y); 135 | ma.innerHTML = na; 136 | } 137 | }; 138 | Term.prototype.cursor_timer_cb = function() { 139 | this.cursor_state ^= 1; 140 | this.refresh(this.y, this.y); 141 | }; 142 | Term.prototype.show_cursor = function() { 143 | if (!this.cursor_state) { 144 | this.cursor_state = 1; 145 | this.refresh(this.y, this.y); 146 | } 147 | }; 148 | Term.prototype.scroll = function() { 149 | var y, ia, x, c, ta; 150 | if (this.cur_h < this.tot_h) { 151 | this.cur_h++; 152 | } 153 | if (++this.y_base == this.cur_h) 154 | this.y_base = 0; 155 | this.y_disp = this.y_base; 156 | c = 32 | (this.def_attr << 16); 157 | ia = new Array(); 158 | for (x = 0; x < this.w; x++) 159 | ia[x] = c; 160 | ta = this.y_base + this.h - 1; 161 | if (ta >= this.cur_h) 162 | ta -= this.cur_h; 163 | this.lines[ta] = ia; 164 | }; 165 | Term.prototype.scroll_disp = function(n) { 166 | var i, ta; 167 | if (n >= 0) { 168 | for (i = 0; i < n; i++) { 169 | if (this.y_disp == this.y_base) 170 | break; 171 | if (++this.y_disp == this.cur_h) 172 | this.y_disp = 0; 173 | } 174 | } else { 175 | n = -n; 176 | ta = this.y_base + this.h; 177 | if (ta >= this.cur_h) 178 | ta -= this.cur_h; 179 | for (i = 0; i < n; i++) { 180 | if (this.y_disp == ta) 181 | break; 182 | if (--this.y_disp < 0) 183 | this.y_disp = this.cur_h - 1; 184 | } 185 | } 186 | this.refresh(0, this.h - 1); 187 | }; 188 | Term.prototype.write = function(char) { 189 | function va(y) { 190 | ka = Math.min(ka, y); 191 | la = Math.max(la, y); 192 | } 193 | function wa(s, x, y) { 194 | var l, i, c, ta; 195 | ta = s.y_base + y; 196 | if (ta >= s.cur_h) 197 | ta -= s.cur_h; 198 | l = s.lines[ta]; 199 | c = 32 | (s.def_attr << 16); 200 | for (i = x; i < s.w; i++) 201 | l[i] = c; 202 | va(y); 203 | } 204 | function xa(s, ya) { 205 | var j, n; 206 | if (ya.length == 0) { 207 | s.cur_attr = s.def_attr; 208 | } else { 209 | for (j = 0; j < ya.length; j++) { 210 | n = ya[j]; 211 | if (n >= 30 && n <= 37) { 212 | s.cur_attr = (s.cur_attr & ~(7 << 3)) | ((n - 30) << 3); 213 | } else if (n >= 40 && n <= 47) { 214 | s.cur_attr = (s.cur_attr & ~7) | (n - 40); 215 | } else if (n == 0) { 216 | s.cur_attr = s.def_attr; 217 | } 218 | } 219 | } 220 | } 221 | var za = 0; 222 | var Aa = 1; 223 | var Ba = 2; 224 | var i, c, ka, la, l, n, j, ta; 225 | ka = this.h; 226 | la = -1; 227 | va(this.y); 228 | if (this.y_base != this.y_disp) { 229 | this.y_disp = this.y_base; 230 | ka = 0; 231 | la = this.h - 1; 232 | } 233 | for (i = 0; i < char.length; i++) { 234 | c = char.charCodeAt(i); 235 | switch (this.state) { 236 | case za: 237 | switch (c) { 238 | case 10: 239 | if (this.convert_lf_to_crlf) { 240 | this.x = 0; 241 | } 242 | this.y++; 243 | if (this.y >= this.h) { 244 | this.y--; 245 | this.scroll(); 246 | ka = 0; 247 | la = this.h - 1; 248 | } 249 | break; 250 | case 13: 251 | this.x = 0; 252 | break; 253 | case 8: 254 | if (this.x > 0) { 255 | this.x--; 256 | } 257 | break; 258 | case 9: 259 | n = (this.x + 8) & ~7; 260 | if (n <= this.w) { 261 | this.x = n; 262 | } 263 | break; 264 | case 27: 265 | this.state = Aa; 266 | break; 267 | default: 268 | if (c >= 32) { 269 | if (this.x >= this.w) { 270 | this.x = 0; 271 | this.y++; 272 | if (this.y >= this.h) { 273 | this.y--; 274 | this.scroll(); 275 | ka = 0; 276 | la = this.h - 1; 277 | } 278 | } 279 | ta = this.y + this.y_base; 280 | if (ta >= this.cur_h) 281 | ta -= this.cur_h; 282 | this.lines[ta][this.x] = (c & 0xffff) | (this.cur_attr << 16); 283 | this.x++; 284 | va(this.y); 285 | } 286 | break; 287 | } 288 | break; 289 | case Aa: 290 | if (c == 91) { 291 | this.esc_params = new Array(); 292 | this.cur_param = 0; 293 | this.state = Ba; 294 | } else { 295 | this.state = za; 296 | } 297 | break; 298 | case Ba: 299 | if (c >= 48 && c <= 57) { 300 | this.cur_param = this.cur_param * 10 + c - 48; 301 | } else { 302 | this.esc_params[this.esc_params.length] = this.cur_param; 303 | this.cur_param = 0; 304 | if (c == 59) 305 | break; 306 | this.state = za; 307 | switch (c) { 308 | case 65: 309 | n = this.esc_params[0]; 310 | if (n < 1) 311 | n = 1; 312 | this.y -= n; 313 | if (this.y < 0) 314 | this.y = 0; 315 | break; 316 | case 66: 317 | n = this.esc_params[0]; 318 | if (n < 1) 319 | n = 1; 320 | this.y += n; 321 | if (this.y >= this.h) 322 | this.y = this.h - 1; 323 | break; 324 | case 67: 325 | n = this.esc_params[0]; 326 | if (n < 1) 327 | n = 1; 328 | this.x += n; 329 | if (this.x >= this.w - 1) 330 | this.x = this.w - 1; 331 | break; 332 | case 68: 333 | n = this.esc_params[0]; 334 | if (n < 1) 335 | n = 1; 336 | this.x -= n; 337 | if (this.x < 0) 338 | this.x = 0; 339 | break; 340 | case 72: 341 | { 342 | var Ca, ta; 343 | ta = this.esc_params[0] - 1; 344 | if (this.esc_params.length >= 2) 345 | Ca = this.esc_params[1] - 1; 346 | else 347 | Ca = 0; 348 | if (ta < 0) 349 | ta = 0; 350 | else if (ta >= this.h) 351 | ta = this.h - 1; 352 | if (Ca < 0) 353 | Ca = 0; 354 | else if (Ca >= this.w) 355 | Ca = this.w - 1; 356 | this.x = Ca; 357 | this.y = ta; 358 | } 359 | break; 360 | case 74: 361 | wa(this, this.x, this.y); 362 | for (j = this.y + 1; j < this.h; j++) 363 | wa(this, 0, j); 364 | break; 365 | case 75: 366 | wa(this, this.x, this.y); 367 | break; 368 | case 109: 369 | xa(this, this.esc_params); 370 | break; 371 | case 110: 372 | this.queue_chars("\x1b[" + (this.y + 1) + ";" + (this.x + 1) + "R"); 373 | break; 374 | default: 375 | break; 376 | } 377 | } 378 | break; 379 | } 380 | } 381 | va(this.y); 382 | if (la >= ka) 383 | this.refresh(ka, la); 384 | }; 385 | Term.prototype.writeln = function(char) { 386 | this.write(char + '\r\n'); 387 | }; 388 | Term.prototype.keyDownHandler = function(event) { 389 | var char; 390 | char = ""; 391 | switch (event.keyCode) { 392 | case 8: 393 | char = ""; 394 | break; 395 | case 9: 396 | char = "\t"; 397 | break; 398 | case 13: 399 | char = "\r"; 400 | break; 401 | case 27: 402 | char = "\x1b"; 403 | break; 404 | case 37: 405 | char = "\x1b[D"; 406 | break; 407 | case 39: 408 | char = "\x1b[C"; 409 | break; 410 | case 38: 411 | if (event.ctrlKey) { 412 | this.scroll_disp(-1); 413 | } else { 414 | char = "\x1b[A"; 415 | } 416 | break; 417 | case 40: 418 | if (event.ctrlKey) { 419 | this.scroll_disp(1); 420 | } else { 421 | char = "\x1b[B"; 422 | } 423 | break; 424 | case 46: 425 | char = "\x1b[3~"; 426 | break; 427 | case 45: 428 | char = "\x1b[2~"; 429 | break; 430 | case 36: 431 | char = "\x1bOH"; 432 | break; 433 | case 35: 434 | char = "\x1bOF"; 435 | break; 436 | case 33: 437 | if (event.ctrlKey) { 438 | this.scroll_disp(-(this.h - 1)); 439 | } else { 440 | char = "\x1b[5~"; 441 | } 442 | break; 443 | case 34: 444 | if (event.ctrlKey) { 445 | this.scroll_disp(this.h - 1); 446 | } else { 447 | char = "\x1b[6~"; 448 | } 449 | break; 450 | default: 451 | if (event.ctrlKey) { 452 | if (event.keyCode >= 65 && event.keyCode <= 90) { 453 | char = String.fromCharCode(event.keyCode - 64); 454 | } else if (event.keyCode == 32) { 455 | char = String.fromCharCode(0); 456 | } 457 | } else if ((!this.is_mac && event.altKey) || (this.is_mac && event.metaKey)) { 458 | if (event.keyCode >= 65 && event.keyCode <= 90) { 459 | char = "\x1b" + String.fromCharCode(event.keyCode + 32); 460 | } 461 | } 462 | break; 463 | } 464 | if (char) { 465 | if (event.stopPropagation) 466 | event.stopPropagation(); 467 | if (event.preventDefault) 468 | event.preventDefault(); 469 | this.show_cursor(); 470 | this.key_rep_state = 1; 471 | this.key_rep_str = char; 472 | this.handler(char); 473 | return false; 474 | } else { 475 | this.key_rep_state = 0; 476 | return true; 477 | } 478 | }; 479 | Term.prototype.keyPressHandler = function(event) { 480 | var char, charcode; 481 | if (event.stopPropagation) 482 | event.stopPropagation(); 483 | if (event.preventDefault) 484 | event.preventDefault(); 485 | char = ""; 486 | if (!("charCode" in event)) { 487 | charcode = event.keyCode; 488 | if (this.key_rep_state == 1) { 489 | this.key_rep_state = 2; 490 | return false; 491 | } else if (this.key_rep_state == 2) { 492 | this.show_cursor(); 493 | this.handler(this.key_rep_str); 494 | return false; 495 | } 496 | } else { 497 | charcode = event.charCode; 498 | } 499 | if (charcode != 0) { 500 | if (!event.ctrlKey && ((!this.is_mac && !event.altKey) || (this.is_mac && !event.metaKey))) { 501 | char = String.fromCharCode(charcode); 502 | } 503 | } 504 | if (char) { 505 | this.show_cursor(); 506 | this.handler(char); 507 | return false; 508 | } else { 509 | return true; 510 | } 511 | }; 512 | Term.prototype.queue_chars = function(char) { 513 | this.output_queue += char; 514 | if (this.output_queue) 515 | setTimeout(this.outputHandler.bind(this), 0); 516 | }; 517 | Term.prototype.outputHandler = function() { 518 | if (this.output_queue) { 519 | this.handler(this.output_queue); 520 | this.output_queue = ""; 521 | } 522 | }; 523 | 524 | 525 | 526 | 527 | 528 | 529 | -------------------------------------------------------------------------------- /vmlinux-2.6.20.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levskaya/jslinux-deobfuscated/d3ff9f170d79b8ca2847d554ceffda2bca150e55/vmlinux-2.6.20.bin --------------------------------------------------------------------------------