public gh-pages site

This commit is contained in:
jack 2016-07-29 09:46:27 +08:00
commit 2046fbcb32
25 changed files with 38205 additions and 52 deletions

66
CMOS.js Normal file
View File

@ -0,0 +1,66 @@
/*
JSLinux-deobfuscated - An annotated version of the original JSLinux.
Original is Copyright (c) 2011-2012 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's permission.
CMOS Ram Memory, actually just the RTC Clock Emulator
Useful references:
------------------
http://www.bioscentral.com/misc/cmosmap.htm
http://wiki.osdev.org/CMOS
*/
/*
In this implementation, bytes are stored in the RTC in BCD format
binary -> bcd: bcd = ((bin / 10) << 4) | (bin % 10)
bcd -> binary: bin = ((bcd / 16) * 10) + (bcd & 0xf)
*/
function bin_to_bcd(a) { return ((a / 10) << 4) | (a % 10);}
function CMOS(PC) {
var time_array, d;
time_array = new Uint8Array(128);
this.cmos_data = time_array;
this.cmos_index = 0;
d = new Date();
time_array[0] = bin_to_bcd(d.getUTCSeconds());
time_array[2] = bin_to_bcd(d.getUTCMinutes());
time_array[4] = bin_to_bcd(d.getUTCHours());
time_array[6] = bin_to_bcd(d.getUTCDay());
time_array[7] = bin_to_bcd(d.getUTCDate());
time_array[8] = bin_to_bcd(d.getUTCMonth() + 1);
time_array[9] = bin_to_bcd(d.getUTCFullYear() % 100);
time_array[10] = 0x26;
time_array[11] = 0x02;
time_array[12] = 0x00;
time_array[13] = 0x80;
time_array[0x14] = 0x02;
PC.register_ioport_write(0x70, 2, 1, this.ioport_write.bind(this));
PC.register_ioport_read(0x70, 2, 1, this.ioport_read.bind(this));
}
CMOS.prototype.ioport_write = function(mem8_loc, data) {
if (mem8_loc == 0x70) {
// the high order bit is used to indicate NMI masking
// low order bits are used to address CMOS
// the index written here is used on an ioread 0x71
this.cmos_index = data & 0x7f;
}
};
CMOS.prototype.ioport_read = function(mem8_loc) {
var data;
if (mem8_loc == 0x70) {
return 0xff;
} else {
// else here => 0x71, i.e., CMOS read
data = this.cmos_data[this.cmos_index];
if (this.cmos_index == 10)
// flip the UIP (update in progress) bit on a read
this.cmos_data[10] ^= 0x80;
else if (this.cmos_index == 12)
// Always return interrupt status == 0
this.cmos_data[12] = 0x00;
return data;
}
};

27
KBD.js Normal file
View File

@ -0,0 +1,27 @@
/*
JSLinux-deobfuscated - An annotated version of the original JSLinux.
Original is Copyright (c) 2011-2012 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's permission.
Keyboard Device Emulator
*/
function KBD(PC, reset_callback) {
PC.register_ioport_read(0x64, 1, 1, this.read_status.bind(this));
PC.register_ioport_write(0x64, 1, 1, this.write_command.bind(this));
this.reset_request = reset_callback;
}
KBD.prototype.read_status = function(mem8_loc) {
return 0;
};
KBD.prototype.write_command = function(mem8_loc, x) {
switch (x) {
case 0xfe: // Resend command. Other commands are, apparently, ignored.
this.reset_request();
break;
default:
break;
}
};

4
LICENSE Normal file
View File

@ -0,0 +1,4 @@
This is a derivative work of JSLinux and is posted here with permission of the author.
JSLinux is Copyright (c) 2011-2013 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's permission.

207
PCEmulator.js Normal file
View File

@ -0,0 +1,207 @@
/*
JSLinux-deobfuscated - An annotated version of the original JSLinux.
Original is Copyright (c) 2011-2012 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's permission.
Main PC Emulator Routine
*/
// used as callback wrappers for emulated PIT and PIC chips
function set_hard_irq_wrapper(irq) { this.hard_irq = irq;}
function return_cycle_count() { return this.cycle_count; }
function PCEmulator(params) {
var cpu;
cpu = new CPU_X86();
this.cpu = cpu;
cpu.phys_mem_resize(params.mem_size);
this.init_ioports();
this.register_ioport_write(0x80, 1, 1, this.ioport80_write);
this.pic = new PIC_Controller(this, 0x20, 0xa0, set_hard_irq_wrapper.bind(cpu));
this.pit = new PIT(this, this.pic.set_irq.bind(this.pic, 0), return_cycle_count.bind(cpu));
this.cmos = new CMOS(this);
this.serial = new Serial(this, 0x3f8, this.pic.set_irq.bind(this.pic, 4), params.serial_write);
this.kbd = new KBD(this, this.reset.bind(this));
this.reset_request = 0;
if (params.clipboard_get && params.clipboard_set) {
this.jsclipboard = new clipboard_device(this, 0x3c0, params.clipboard_get, params.clipboard_set, params.get_boot_time);
}
cpu.ld8_port = this.ld8_port.bind(this);
cpu.ld16_port = this.ld16_port.bind(this);
cpu.ld32_port = this.ld32_port.bind(this);
cpu.st8_port = this.st8_port.bind(this);
cpu.st16_port = this.st16_port.bind(this);
cpu.st32_port = this.st32_port.bind(this);
cpu.get_hard_intno = this.pic.get_hard_intno.bind(this.pic);
}
PCEmulator.prototype.load_binary = function(binary_array, mem8_loc) { return this.cpu.load_binary(binary_array, mem8_loc); };
PCEmulator.prototype.start = function() { setTimeout(this.timer_func.bind(this), 10); };
PCEmulator.prototype.timer_func = function() {
var exit_status, Ncycles, do_reset, err_on_exit, PC, cpu;
PC = this;
cpu = PC.cpu;
Ncycles = cpu.cycle_count + 100000;
do_reset = false;
err_on_exit = false;
exec_loop: while (cpu.cycle_count < Ncycles) {
PC.pit.update_irq();
exit_status = cpu.exec(Ncycles - cpu.cycle_count);
if (exit_status == 256) {
if (PC.reset_request) {
do_reset = true;
break;
}
} else if (exit_status == 257) {
err_on_exit = true;
break;
} else {
do_reset = true;
break;
}
}
if (!do_reset) {
if (err_on_exit) {
setTimeout(this.timer_func.bind(this), 10);
} else {
setTimeout(this.timer_func.bind(this), 0);
}
}
};
PCEmulator.prototype.init_ioports = function() {
var i, readw, writew;
this.ioport_readb_table = new Array();
this.ioport_writeb_table = new Array();
this.ioport_readw_table = new Array();
this.ioport_writew_table = new Array();
this.ioport_readl_table = new Array();
this.ioport_writel_table = new Array();
readw = this.default_ioport_readw.bind(this);
writew = this.default_ioport_writew.bind(this);
for (i = 0; i < 1024; i++) {
this.ioport_readb_table[i] = this.default_ioport_readb;
this.ioport_writeb_table[i] = this.default_ioport_writeb;
this.ioport_readw_table[i] = readw;
this.ioport_writew_table[i] = writew;
this.ioport_readl_table[i] = this.default_ioport_readl;
this.ioport_writel_table[i] = this.default_ioport_writel;
}
};
PCEmulator.prototype.default_ioport_readb = function(port_num) {
var x;
x = 0xff;
return x;
};
PCEmulator.prototype.default_ioport_readw = function(port_num) {
var x;
x = this.ioport_readb_table[port_num](port_num);
port_num = (port_num + 1) & (1024 - 1);
x |= this.ioport_readb_table[port_num](port_num) << 8;
return x;
};
PCEmulator.prototype.default_ioport_readl = function(port_num) {
var x;
x = -1;
return x;
};
PCEmulator.prototype.default_ioport_writeb = function(port_num, x) {};
PCEmulator.prototype.default_ioport_writew = function(port_num, x) {
this.ioport_writeb_table[port_num](port_num, x & 0xff);
port_num = (port_num + 1) & (1024 - 1);
this.ioport_writeb_table[port_num](port_num, (x >> 8) & 0xff);
};
PCEmulator.prototype.default_ioport_writel = function(port_num, x) {};
PCEmulator.prototype.ld8_port = function(port_num) {
var x;
x = this.ioport_readb_table[port_num & (1024 - 1)](port_num);
return x;
};
PCEmulator.prototype.ld16_port = function(port_num) {
var x;
x = this.ioport_readw_table[port_num & (1024 - 1)](port_num);
return x;
};
PCEmulator.prototype.ld32_port = function(port_num) {
var x;
x = this.ioport_readl_table[port_num & (1024 - 1)](port_num);
return x;
};
PCEmulator.prototype.st8_port = function(port_num, x) { this.ioport_writeb_table[port_num & (1024 - 1)](port_num, x); };
PCEmulator.prototype.st16_port = function(port_num, x) { this.ioport_writew_table[port_num & (1024 - 1)](port_num, x); };
PCEmulator.prototype.st32_port = function(port_num, x) { this.ioport_writel_table[port_num & (1024 - 1)](port_num, x); };
PCEmulator.prototype.register_ioport_read = function(start, len, iotype, io_callback) {
var i;
switch (iotype) {
case 1:
for (i = start; i < start + len; i++) {
this.ioport_readb_table[i] = io_callback;
}
break;
case 2:
for (i = start; i < start + len; i += 2) {
this.ioport_readw_table[i] = io_callback;
}
break;
case 4:
for (i = start; i < start + len; i += 4) {
this.ioport_readl_table[i] = io_callback;
}
break;
}
};
PCEmulator.prototype.register_ioport_write = function(start, len, iotype, io_callback) {
var i;
switch (iotype) {
case 1:
for (i = start; i < start + len; i++) {
this.ioport_writeb_table[i] = io_callback;
}
break;
case 2:
for (i = start; i < start + len; i += 2) {
this.ioport_writew_table[i] = io_callback;
}
break;
case 4:
for (i = start; i < start + len; i += 4) {
this.ioport_writel_table[i] = io_callback;
}
break;
}
};
PCEmulator.prototype.ioport80_write = function(mem8_loc, data) {}; //POST codes! Seem to be ignored?
PCEmulator.prototype.reset = function() { this.request_request = 1; };

315
PIC.js Normal file
View File

@ -0,0 +1,315 @@
/*
JSLinux-deobfuscated - An annotated version of the original JSLinux.
Original is Copyright (c) 2011-2012 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's permission.
8259A PIC (Programmable Interrupt Controller) Emulation Code
The 8259 combines multiple interrupt input sources into a single
interrupt output to the host microprocessor, extending the interrupt
levels available in a system beyond the one or two levels found on the
processor chip.
There are three registers, an Interrupt Mask Register (IMR), an
Interrupt Request Register (IRR), and an In-Service Register
(ISR):
IRR - a mask of the current interrupts that are pending acknowledgement
ISR - a mask of the interrupts that are pending an EOI
IMR - a mask of interrupts that should not be sent an acknowledgement
End Of Interrupt (EOI) operations support specific EOI, non-specific
EOI, and auto-EOI. A specific EOI specifies the IRQ level it is
acknowledging in the ISR. A non-specific EOI resets the IRQ level in
the ISR. Auto-EOI resets the IRQ level in the ISR immediately after
the interrupt is acknowledged.
After the IBM XT, it was decided that 8 IRQs was not enough.
The backwards-compatible solution was simply to chain two 8259As together,
the master and slave PIC.
Useful References
-----------------
https://en.wikipedia.org/wiki/Programmable_Interrupt_Controller
https://en.wikipedia.org/wiki/Intel_8259
http://www.thesatya.com/8259.html
*/
/*
Common PC arrangements of IRQ lines:
------------------------------------
PC/AT and later systems had two 8259 controllers, master and
slave. IRQ0 through IRQ7 are the master 8259's interrupt lines, while
IRQ8 through IRQ15 are the slave 8259's interrupt lines. The labels on
the pins on an 8259 are IR0 through IR7. IRQ0 through IRQ15 are the
names of the ISA bus's lines to which the 8259s are attached.
Master 8259
IRQ0 Intel 8253 or Intel 8254 Programmable Interval Timer, aka the system timer
IRQ1 Intel 8042 keyboard controller
IRQ2 not assigned in PC/XT; cascaded to slave 8259 INT line in PC/AT
IRQ3 8250 UART serial ports 2 and 4
IRQ4 8250 UART serial ports 1 and 3
IRQ5 hard disk controller in PC/XT; Intel 8255 parallel ports 2 and 3 in PC/AT
IRQ6 Intel 82072A floppy disk controller
IRQ7 Intel 8255 parallel port 1 / spurious interrupt
Slave 8259 (PC/AT and later only)
IRQ8 real-time clock (RTC)
IRQ9 no common assignment, but 8-bit cards' IRQ2 line is routed to this interrupt.
IRQ10 no common assignment
IRQ11 no common assignment
IRQ12 Intel 8042 PS/2 mouse controller
IRQ13 math coprocessor
IRQ14 hard disk controller 1
IRQ15 hard disk controller 2
*/
function PIC(PC, port_num) {
PC.register_ioport_write(port_num, 2, 1, this.ioport_write.bind(this));
PC.register_ioport_read(port_num, 2, 1, this.ioport_read.bind(this));
this.reset();
}
PIC.prototype.reset = function() {
this.last_irr = 0;
this.irr = 0; //Interrupt Request Register
this.imr = 0; //Interrupt Mask Register
this.isr = 0; //In-Service Register
this.priority_add = 0;
this.irq_base = 0;
this.read_reg_select = 0;
this.special_mask = 0;
this.init_state = 0;
this.auto_eoi = 0;
this.rotate_on_autoeoi = 0;
this.init4 = 0;
this.elcr = 0; // Edge/Level Control Register
this.elcr_mask = 0;
};
PIC.prototype.set_irq1 = function(irq, Qf) {
var ir_register;
ir_register = 1 << irq;
if (Qf) {
if ((this.last_irr & ir_register) == 0)
this.irr |= ir_register;
this.last_irr |= ir_register;
} else {
this.last_irr &= ~ir_register;
}
};
/*
The priority assignments for IRQ0-7 seem to be maintained in a
cyclic order modulo 8 by the 8259A. On bootup, it default to:
Priority: 0 1 2 3 4 5 6 7
IRQ: 7 6 5 4 3 2 1 0
but can be rotated automatically or programmatically to a state e.g.:
Priority: 5 6 7 0 1 2 3 4
IRQ: 7 6 5 4 3 2 1 0
*/
PIC.prototype.get_priority = function(ir_register) {
var priority;
if (ir_register == 0)
return -1;
priority = 7;
while ((ir_register & (1 << ((priority + this.priority_add) & 7))) == 0)
priority--;
return priority;
};
PIC.prototype.get_irq = function() {
var ir_register, in_service_priority, priority;
ir_register = this.irr & ~this.imr;
priority = this.get_priority(ir_register);
if (priority < 0)
return -1;
in_service_priority = this.get_priority(this.isr);
if (priority > in_service_priority) {
return priority;
} else {
return -1;
}
};
PIC.prototype.intack = function(irq) {
if (this.auto_eoi) {
if (this.rotate_on_auto_eoi)
this.priority_add = (irq + 1) & 7;
} else {
this.isr |= (1 << irq);
}
if (!(this.elcr & (1 << irq)))
this.irr &= ~(1 << irq);
};
PIC.prototype.ioport_write = function(mem8_loc, x) {
var priority;
mem8_loc &= 1;
if (mem8_loc == 0) {
if (x & 0x10) {
/*
ICW1
// 7:5 = address (if MCS-80/85 mode)
// 4 == 1
// 3: 1 == level triggered, 0 == edge triggered
// 2: 1 == call interval 4, 0 == call interval 8
// 1: 1 == single PIC, 0 == cascaded PICs
// 0: 1 == send ICW4
*/
this.reset();
this.init_state = 1;
this.init4 = x & 1;
if (x & 0x02)
throw "single mode not supported";
if (x & 0x08)
throw "level sensitive irq not supported";
} else if (x & 0x08) {
if (x & 0x02)
this.read_reg_select = x & 1;
if (x & 0x40)
this.special_mask = (x >> 5) & 1;
} else {
switch (x) {
case 0x00:
case 0x80:
this.rotate_on_autoeoi = x >> 7;
break;
case 0x20:
case 0xa0:
priority = this.get_priority(this.isr);
if (priority >= 0) {
this.isr &= ~(1 << ((priority + this.priority_add) & 7));
}
if (x == 0xa0)
this.priority_add = (this.priority_add + 1) & 7;
break;
case 0x60:
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x65:
case 0x66:
case 0x67:
priority = x & 7;
this.isr &= ~(1 << priority);
break;
case 0xc0:
case 0xc1:
case 0xc2:
case 0xc3:
case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
this.priority_add = (x + 1) & 7;
break;
case 0xe0:
case 0xe1:
case 0xe2:
case 0xe3:
case 0xe4:
case 0xe5:
case 0xe6:
case 0xe7:
priority = x & 7;
this.isr &= ~(1 << priority);
this.priority_add = (priority + 1) & 7;
break;
}
}
} else {
switch (this.init_state) {
case 0:
this.imr = x;
this.update_irq();
break;
case 1:
this.irq_base = x & 0xf8;
this.init_state = 2;
break;
case 2:
if (this.init4) {
this.init_state = 3;
} else {
this.init_state = 0;
}
break;
case 3:
this.auto_eoi = (x >> 1) & 1;
this.init_state = 0;
break;
}
}
};
PIC.prototype.ioport_read = function(Ug) {
var mem8_loc, return_register;
mem8_loc = Ug & 1;
if (mem8_loc == 0) {
if (this.read_reg_select)
return_register = this.isr;
else
return_register = this.irr;
} else {
return_register = this.imr;
}
return return_register;
};
function PIC_Controller(PC, master_PIC_port, slave_PIC_port, cpu_set_irq_callback) {
this.pics = new Array();
this.pics[0] = new PIC(PC, master_PIC_port);
this.pics[1] = new PIC(PC, slave_PIC_port);
this.pics[0].elcr_mask = 0xf8;
this.pics[1].elcr_mask = 0xde;
this.irq_requested = 0;
this.cpu_set_irq = cpu_set_irq_callback;
this.pics[0].update_irq = this.update_irq.bind(this);
this.pics[1].update_irq = this.update_irq.bind(this);
}
PIC_Controller.prototype.update_irq = function() {
var slave_irq, irq;
slave_irq = this.pics[1].get_irq();
if (slave_irq >= 0) {
this.pics[0].set_irq1(2, 1);
this.pics[0].set_irq1(2, 0);
}
irq = this.pics[0].get_irq();
if (irq >= 0) {
this.cpu_set_irq(1);
} else {
this.cpu_set_irq(0);
}
};
PIC_Controller.prototype.set_irq = function(irq, Qf) {
this.pics[irq >> 3].set_irq1(irq & 7, Qf);
this.update_irq();
};
PIC_Controller.prototype.get_hard_intno = function() {
var irq, slave_irq, intno;
irq = this.pics[0].get_irq();
if (irq >= 0) {
this.pics[0].intack(irq);
if (irq == 2) { //IRQ 2 cascaded to slave 8259 INT line in PC/AT
slave_irq = this.pics[1].get_irq();
if (slave_irq >= 0) {
this.pics[1].intack(slave_irq);
} else {
slave_irq = 7;
}
intno = this.pics[1].irq_base + slave_irq;
irq = slave_irq + 8;
} else {
intno = this.pics[0].irq_base + irq;
}
} else {
irq = 7;
intno = this.pics[0].irq_base + irq;
}
this.update_irq();
return intno;
};

225
PIT.js Normal file
View File

@ -0,0 +1,225 @@
/*
JSLinux-deobfuscated - An annotated version of the original JSLinux.
Original is Copyright (c) 2011-2012 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's permission.
8254 Programmble Interrupt Timer Emulator
Useful References
-----------------
https://en.wikipedia.org/wiki/Intel_8253
*/
function PIT(PC, set_irq_callback, cycle_count_callback) {
var s, i;
this.pit_channels = new Array();
for (i = 0; i < 3; i++) {
s = new IRQCH(cycle_count_callback);
this.pit_channels[i] = s;
s.mode = 3;
s.gate = (i != 2) >> 0;
s.pit_load_count(0);
}
this.speaker_data_on = 0;
this.set_irq = set_irq_callback;
// Ports:
// 0x40: Channel 0 data port
// 0x61: Control
PC.register_ioport_write(0x40, 4, 1, this.ioport_write.bind(this));
PC.register_ioport_read(0x40, 3, 1, this.ioport_read.bind(this));
PC.register_ioport_read(0x61, 1, 1, this.speaker_ioport_read.bind(this));
PC.register_ioport_write(0x61, 1, 1, this.speaker_ioport_write.bind(this));
}
function IRQCH(cycle_count_callback) {
this.count = 0;
this.latched_count = 0;
this.rw_state = 0;
this.mode = 0;
this.bcd = 0;
this.gate = 0;
this.count_load_time = 0;
this.get_ticks = cycle_count_callback;
this.pit_time_unit = 1193182 / 2000000;
}
IRQCH.prototype.get_time = function() {
return Math.floor(this.get_ticks() * this.pit_time_unit);
};
IRQCH.prototype.pit_get_count = function() {
var d, dh;
d = this.get_time() - this.count_load_time;
switch (this.mode) {
case 0:
case 1:
case 4:
case 5:
dh = (this.count - d) & 0xffff;
break;
default:
dh = this.count - (d % this.count);
break;
}
return dh;
};
IRQCH.prototype.pit_get_out = function() {
var d, eh;
d = this.get_time() - this.count_load_time;
switch (this.mode) {
default:
case 0: // Interrupt on terminal count
eh = (d >= this.count) >> 0;
break;
case 1: // One shot
eh = (d < this.count) >> 0;
break;
case 2: // Frequency divider
if ((d % this.count) == 0 && d != 0)
eh = 1;
else
eh = 0;
break;
case 3: // Square wave
eh = ((d % this.count) < (this.count >> 1)) >> 0;
break;
case 4: // SW strobe
case 5: // HW strobe
eh = (d == this.count) >> 0;
break;
}
return eh;
};
IRQCH.prototype.get_next_transition_time = function() {
var d, fh, base, gh;
d = this.get_time() - this.count_load_time;
switch (this.mode) {
default:
case 0: // Interrupt on terminal count
case 1: // One shot
if (d < this.count)
fh = this.count;
else
return -1;
break;
case 2: // Frequency divider
base = (d / this.count) * this.count;
if ((d - base) == 0 && d != 0)
fh = base + this.count;
else
fh = base + this.count + 1;
break;
case 3: // Square wave
base = (d / this.count) * this.count;
gh = ((this.count + 1) >> 1);
if ((d - base) < gh)
fh = base + gh;
else
fh = base + this.count;
break;
case 4: // SW strobe
case 5: // HW strobe
if (d < this.count)
fh = this.count;
else if (d == this.count)
fh = this.count + 1;
else
return -1;
break;
}
fh = this.count_load_time + fh;
return fh;
};
IRQCH.prototype.pit_load_count = function(x) {
if (x == 0)
x = 0x10000;
this.count_load_time = this.get_time();
this.count = x;
};
PIT.prototype.ioport_write = function(mem8_loc, x) {
var hh, ih, s;
mem8_loc &= 3;
if (mem8_loc == 3) {
hh = x >> 6;
if (hh == 3)
return;
s = this.pit_channels[hh];
ih = (x >> 4) & 3;
switch (ih) {
case 0:
s.latched_count = s.pit_get_count();
s.rw_state = 4;
break;
default:
s.mode = (x >> 1) & 7;
s.bcd = x & 1;
s.rw_state = ih - 1 + 0;
break;
}
} else {
s = this.pit_channels[mem8_loc];
switch (s.rw_state) {
case 0:
s.pit_load_count(x);
break;
case 1:
s.pit_load_count(x << 8);
break;
case 2:
case 3:
if (s.rw_state & 1) {
s.pit_load_count((s.latched_count & 0xff) | (x << 8));
} else {
s.latched_count = x;
}
s.rw_state ^= 1;
break;
}
}
};
PIT.prototype.ioport_read = function(mem8_loc) {
var Pg, ma, s;
mem8_loc &= 3;
s = this.pit_channels[mem8_loc];
switch (s.rw_state) {
case 0:
case 1:
case 2:
case 3:
ma = s.pit_get_count();
if (s.rw_state & 1)
Pg = (ma >> 8) & 0xff;
else
Pg = ma & 0xff;
if (s.rw_state & 2)
s.rw_state ^= 1;
break;
default:
case 4:
case 5:
if (s.rw_state & 1)
Pg = s.latched_count >> 8;
else
Pg = s.latched_count & 0xff;
s.rw_state ^= 1;
break;
}
return Pg;
};
PIT.prototype.speaker_ioport_write = function(mem8_loc, x) {
this.speaker_data_on = (x >> 1) & 1;
this.pit_channels[2].gate = x & 1;
};
PIT.prototype.speaker_ioport_read = function(mem8_loc) {
var eh, s, x;
s = this.pit_channels[2];
eh = s.pit_get_out();
x = (this.speaker_data_on << 1) | s.gate | (eh << 5);
return x;
};
PIT.prototype.update_irq = function() {
this.set_irq(1);
this.set_irq(0);
};

146
Serial.js Normal file
View File

@ -0,0 +1,146 @@
/*
JSLinux-deobfuscated - An annotated version of the original JSLinux.
Original is Copyright (c) 2011-2012 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's permission.
Serial Controller Emulator
*/
function Serial(Ng, mem8_loc, kh, lh) {
this.divider = 0;
this.rbr = 0;
this.ier = 0;
this.iir = 0x01;
this.lcr = 0;
this.mcr;
this.lsr = 0x40 | 0x20;
this.msr = 0;
this.scr = 0;
this.set_irq_func = kh;
this.write_func = lh;
this.receive_fifo = "";
Ng.register_ioport_write(0x3f8, 8, 1, this.ioport_write.bind(this));
Ng.register_ioport_read(0x3f8, 8, 1, this.ioport_read.bind(this));
}
Serial.prototype.update_irq = function() {
if ((this.lsr & 0x01) && (this.ier & 0x01)) {
this.iir = 0x04;
} else if ((this.lsr & 0x20) && (this.ier & 0x02)) {
this.iir = 0x02;
} else {
this.iir = 0x01;
}
if (this.iir != 0x01) {
this.set_irq_func(1);
} else {
this.set_irq_func(0);
}
};
Serial.prototype.ioport_write = function(mem8_loc, x) {
mem8_loc &= 7;
switch (mem8_loc) {
default:
case 0:
if (this.lcr & 0x80) {
this.divider = (this.divider & 0xff00) | x;
} else {
this.lsr &= ~0x20;
this.update_irq();
this.write_func(String.fromCharCode(x));
this.lsr |= 0x20;
this.lsr |= 0x40;
this.update_irq();
}
break;
case 1:
if (this.lcr & 0x80) {
this.divider = (this.divider & 0x00ff) | (x << 8);
} else {
this.ier = x;
this.update_irq();
}
break;
case 2:
break;
case 3:
this.lcr = x;
break;
case 4:
this.mcr = x;
break;
case 5:
break;
case 6:
this.msr = x;
break;
case 7:
this.scr = x;
break;
}
};
Serial.prototype.ioport_read = function(mem8_loc) {
var Pg;
mem8_loc &= 7;
switch (mem8_loc) {
default:
case 0:
if (this.lcr & 0x80) {
Pg = this.divider & 0xff;
} else {
Pg = this.rbr;
this.lsr &= ~(0x01 | 0x10);
this.update_irq();
this.send_char_from_fifo();
}
break;
case 1:
if (this.lcr & 0x80) {
Pg = (this.divider >> 8) & 0xff;
} else {
Pg = this.ier;
}
break;
case 2:
Pg = this.iir;
break;
case 3:
Pg = this.lcr;
break;
case 4:
Pg = this.mcr;
break;
case 5:
Pg = this.lsr;
break;
case 6:
Pg = this.msr;
break;
case 7:
Pg = this.scr;
break;
}
return Pg;
};
Serial.prototype.send_break = function() {
this.rbr = 0;
this.lsr |= 0x10 | 0x01;
this.update_irq();
};
Serial.prototype.send_char = function(mh) {
this.rbr = mh;
this.lsr |= 0x01;
this.update_irq();
};
Serial.prototype.send_char_from_fifo = function() {
var nh;
nh = this.receive_fifo;
if (nh != "" && !(this.lsr & 0x01)) {
this.send_char(nh.charCodeAt(0));
this.receive_fifo = nh.substr(1, nh.length - 1);
}
};
Serial.prototype.send_chars = function(na) {
this.receive_fifo += na;
this.send_char_from_fifo();
};

72
clipboard.js Normal file
View File

@ -0,0 +1,72 @@
/*
JSLinux-deobfuscated - An annotated version of the original JSLinux.
Original is Copyright (c) 2011-2012 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's permission.
Clipboard Device
*/
function clipboard_device(Ng, Zf, rh, lh, sh) {
Ng.register_ioport_read(Zf, 16, 4, this.ioport_readl.bind(this));
Ng.register_ioport_write(Zf, 16, 4, this.ioport_writel.bind(this));
Ng.register_ioport_read(Zf + 8, 1, 1, this.ioport_readb.bind(this));
Ng.register_ioport_write(Zf + 8, 1, 1, this.ioport_writeb.bind(this));
this.cur_pos = 0;
this.doc_str = "";
this.read_func = rh;
this.write_func = lh;
this.get_boot_time = sh;
}
clipboard_device.prototype.ioport_writeb = function(mem8_loc, x) {
this.doc_str += String.fromCharCode(x);
};
clipboard_device.prototype.ioport_readb = function(mem8_loc) {
var c, na, x;
na = this.doc_str;
if (this.cur_pos < na.length) {
x = na.charCodeAt(this.cur_pos) & 0xff;
} else {
x = 0;
}
this.cur_pos++;
return x;
};
clipboard_device.prototype.ioport_writel = function(mem8_loc, x) {
var na;
mem8_loc = (mem8_loc >> 2) & 3;
switch (mem8_loc) {
case 0:
this.doc_str = this.doc_str.substr(0, x >>> 0);
break;
case 1:
return this.cur_pos = x >>> 0;
case 2:
na = String.fromCharCode(x & 0xff) + String.fromCharCode((x >> 8) & 0xff) + String.fromCharCode((x >> 16) & 0xff) + String.fromCharCode((x >> 24) & 0xff);
this.doc_str += na;
break;
case 3:
this.write_func(this.doc_str);
}
};
clipboard_device.prototype.ioport_readl = function(mem8_loc) {
var x;
mem8_loc = (mem8_loc >> 2) & 3;
switch (mem8_loc) {
case 0:
this.doc_str = this.read_func();
return this.doc_str.length >> 0;
case 1:
return this.cur_pos >> 0;
case 2:
x = this.ioport_readb(0);
x |= this.ioport_readb(0) << 8;
x |= this.ioport_readb(0) << 16;
x |= this.ioport_readb(0) << 24;
return x;
case 3:
if (this.get_boot_time)
return this.get_boot_time() >> 0;
else
return 0;
}
};

9719
cpux86-ta.js Normal file

File diff suppressed because it is too large Load Diff

10498
cpux86-ta.original.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +1,47 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Jslinux by jslinux</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">
</head>
<body>
<section class="page-header">
<h1 class="project-name">Jslinux</h1>
<h2 class="project-tagline">JSLinux rewritten to be human readable, hand deobfuscated and annotated.</h2>
<a href="https://github.com/jslinux/jslinux" class="btn">View on GitHub</a>
<a href="https://github.com/jslinux/jslinux/zipball/master" class="btn">Download .zip</a>
<a href="https://github.com/jslinux/jslinux/tarball/master" class="btn">Download .tar.gz</a>
</section>
<html>
<head>
<title>Javascript PC Emulator</title>
<style>
.term {
font-family: courier,fixed,swiss,monospace,sans-serif;
font-size: 14px;
color: #f0f0f0;
background: #000000;
}
<section class="main-content">
<h3>
<a id="welcome-to-github-pages" class="anchor" href="#welcome-to-github-pages" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Welcome to GitHub Pages.</h3>
.termReverse {
color: #000000;
background: #00ff00;
}
#note {
font-size: 12px;
}
#copyright {
font-size: 10px;
}
#clipboard {
font-size: 12px;
}
</style>
</head>
<body onload="load_binaries()">
<table border="0">
<tr valign="top"><td>
<p>This automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here <a href="https://guides.github.com/features/mastering-markdown/">using GitHub Flavored Markdown</a>, select a template crafted by a designer, and publish. After your page is generated, you can check out the new <code>gh-pages</code> branch locally. If youre using GitHub Desktop, simply sync your repository and youll see the new branch.</p>
<script type="text/javascript" src="term.js"></script>
<script type="text/javascript" src="cpux86-ta.js"></script>
<script type="text/javascript" src="Serial.js"></script>
<script type="text/javascript" src="PIT.js"></script>
<script type="text/javascript" src="PIC.js"></script>
<script type="text/javascript" src="CMOS.js"></script>
<script type="text/javascript" src="KBD.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<script type="text/javascript" src="PCEmulator.js"></script>
<script type="text/javascript" src="jslinux.js"></script>
<h3>
<a id="designer-templates" class="anchor" href="#designer-templates" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Designer Templates</h3>
<p>Weve crafted some handsome templates for you to use. Go ahead and click 'Continue to layouts' to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved.</p>
<h3>
<a id="creating-pages-manually" class="anchor" href="#creating-pages-manually" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Creating pages manually</h3>
<p>If you prefer to not use the automatic generator, push a branch named <code>gh-pages</code> to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.</p>
<h3>
<a id="authors-and-contributors" class="anchor" href="#authors-and-contributors" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Authors and Contributors</h3>
<p>You can <a href="https://help.github.com/articles/basic-writing-and-formatting-syntax/#mentioning-users-and-teams" class="user-mention">@mention</a> a GitHub username to generate a link to their profile. The resulting <code>&lt;a&gt;</code> element will link to the contributors GitHub Profile. For example: In 2007, Chris Wanstrath (<a href="https://github.com/defunkt" class="user-mention">@defunkt</a>), PJ Hyett (<a href="https://github.com/pjhyett" class="user-mention">@pjhyett</a>), and Tom Preston-Werner (<a href="https://github.com/mojombo" class="user-mention">@mojombo</a>) founded GitHub.</p>
<h3>
<a id="support-or-contact" class="anchor" href="#support-or-contact" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Support or Contact</h3>
<p>Having trouble with Pages? Check out our <a href="https://help.github.com/pages">documentation</a> or <a href="https://github.com/contact">contact support</a> and well help you sort it out.</p>
<footer class="site-footer">
<span class="site-footer-owner"><a href="https://github.com/jslinux/jslinux">Jslinux</a> is maintained by <a href="https://github.com/jslinux">jslinux</a>.</span>
<span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span>
</footer>
</section>
</body>
<div id="copyright">&copy; 2011 Fabrice Bellard - <a href="news.html">News</a> - <a href="faq.html">FAQ</a> - <a href="tech.html">Technical notes</a></div>
<td><input type="button" value="Clear clipboard" onclick="clear_clipboard();"><br><textarea row="4" cols="16" id="text_clipboard"></textarea>
</table>
</body>
</html>

164
jslinux.js Normal file
View File

@ -0,0 +1,164 @@
/*
Linux launcher
Copyright (c) 2011 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's
permission.
*/
"use strict";
var term, pc, boot_start_time;
function term_start()
{
term = new Term(80, 30, term_handler);
term.open();
}
/* send chars to the serial port */
function term_handler(str)
{
pc.serial.send_chars(str);
}
function clipboard_set(val)
{
var el;
el = document.getElementById("text_clipboard");
el.value = val;
}
function clipboard_get()
{
var el;
el = document.getElementById("text_clipboard");
return el.value;
}
function clear_clipboard()
{
var el;
el = document.getElementById("text_clipboard");
el.value = "";
}
/* just used to display the boot time in the VM */
function get_boot_time()
{
return (+new Date()) - boot_start_time;
}
/* global to hold binary data from async XHR requests */
var binaries = [false,false,false];
function loadbinary(url,slot) {
var req, binary_array, len, typed_arrays_exist;
req = new XMLHttpRequest();
req.open('GET', url, true);
typed_arrays_exist = ('ArrayBuffer' in window && 'Uint8Array' in window);
if (typed_arrays_exist && 'mozResponseType' in req) {
req.mozResponseType = 'arraybuffer';
} else if (typed_arrays_exist && 'responseType' in req) {
req.responseType = 'arraybuffer';
} else {
req.overrideMimeType('text/plain; charset=x-user-defined');
typed_arrays_exist = false;
}
req.onerror = function(e) {
throw "Error while loading " + req.statusText;
};
req.onload = function (e) {
console.log('onload triggered');
if (req.readyState === 4) {
if (req.status === 200) {
if (typed_arrays_exist && 'mozResponse' in req) {
binaries[slot] = req.mozResponse;
} else if (typed_arrays_exist && req.mozResponseArrayBuffer) {
binaries[slot] = req.mozResponseArrayBuffer;
} else if ('responseType' in req) {
binaries[slot] = req.response;
} else {
binaries[slot] = req.responseText;
}
//cb_f()
} else {
throw "Error while loading " + url;
}
}
}
req.send(null);
};
function checkbinaries() {
//console.log("checkbinaries: ",(binaries[0]!=false),(binaries[1]!=false),(binaries[2]!=false));
if((binaries[0] != false) && (binaries[1] != false) && (binaries[2] != false)){
console.log("...binaries done loading, calling start()")
start();
} else {
setTimeout(checkbinaries, 500);
}
};
function load_binaries() {
console.log("requesting binaries");
loadbinary("vmlinux-2.6.20.bin", 0);
loadbinary("root.bin", 1);
loadbinary("linuxstart.bin", 2);
console.log("waiting for binaries to finish loading...");
checkbinaries();
}
function start()
{
var start_addr, initrd_size, params, cmdline_addr;
params = new Object();
/* serial output chars */
params.serial_write = term.write.bind(term);
/* memory size (in bytes) */
params.mem_size = 16 * 1024 * 1024;
/* clipboard I/O */
params.clipboard_get = clipboard_get;
params.clipboard_set = clipboard_set;
params.get_boot_time = get_boot_time;
pc = new PCEmulator(params);
pc.load_binary(binaries[0], 0x00100000);
initrd_size = pc.load_binary(binaries[1], 0x00400000);
start_addr = 0x10000;
pc.load_binary(binaries[2], start_addr);
/* set the Linux kernel command line */
/* Note: we don't use initramfs because it is not possible to
disable gzip decompression in this case, which would be too
slow. */
cmdline_addr = 0xf800;
pc.cpu.write_string(cmdline_addr, "console=ttyS0 root=/dev/ram0 rw init=/sbin/init notsc=1");
pc.cpu.eip = start_addr;
pc.cpu.regs[0] = params.mem_size; /* eax */
pc.cpu.regs[3] = initrd_size; /* ebx */
pc.cpu.regs[1] = cmdline_addr; /* ecx */
boot_start_time = (+new Date());
pc.start();
}
term_start();

BIN
linuxstart-20110820.tar.gz Normal file

Binary file not shown.

BIN
linuxstart.bin Normal file

Binary file not shown.

99
readme.md Normal file
View File

@ -0,0 +1,99 @@
De-obfuscated JSLinux
=========================================================
I wanted to understand how the amazing [JsLinux][1] worked, so in a
fit of mania I hand de-obfuscated the codebase while studying it over
a few days' time. In the off-chance someone else might be interested
in this code as a basis for further weird in-browser x86 hacking I
posted this redacted version of the code here, with permission of
Mr. Bellard.
I highly recommend checking out another open-source x86 emulation
project that includes vga support, "v86" ([demo][6] / [source][7]).
There's yet another open-source 386-style emulator in javascript
called [jslm32][3].
For a simpler RISC architecture, take a look at the linux on
[jor1k][5] emulator project.
Finally, the [Angel][8] emulator ([source][9]) shows off the elegant
open-ISA 64bit [RISC-V][10] architecture that is being brought to
silicon by the [lowrisc][11] team. This is by far the cleanest
architecture for studying general low-level hardware and operating
system implementation details.
### Status
The current codebase should run on most modern versions of Chrome,
Safari, and Firefox. If you're running it locally, you will need to
load it via a local server to allow the XHR requests to load the
binaries.
jslinux-deobfuscated is still a dense, messy code base from any
pedagogic point of view. However for those interested in
Mr. Bellard's code, this version is nowhere near so incomprehensible
as the original. Nearly all of the global variables and function
names have been named somewhat sensibly. Many pointers to references
have been added to the source.
The core opcode execution loop has been commented to indicate what
instruction the opcode refers to.
### Unresolved
One mystery is, why does CPUID(1) return 8 << 8 in EBX? EBX[15:8] is
now used to indicate CLFLUSH line size, but that field must have been
used for something else in the past.
The CALL/RET/INT/IRET routines are still quite confused and haven't
yet been rewritten. The code dealing with segmentation, and some of
the code for real-mode remains relatively messy.
Any recommendations / clarifications are welcome!
### ETC
I highly recommend, by the way, the excellent [JSShaper][2] library
for transforming large javascript code bases. The hacks I made from
it are in this repo: a little symbol-name-transformer node.js script
and an emacs function for doing this in live buffers.
### License
This is a pedagogical/aesthetic derivative of the original JSLinux
code Copyright (c) 2011-2014 Fabrice Bellard. It is posted here with
permission of the original author subject to his original
constraints : Redistribution or commercial use is prohibited without
the (original) author's permission.
### References
Some other helpful references for understanding what's going on:
#### x86
- http://pdos.csail.mit.edu/6.828/2010/readings/i386/toc.htm
- http://pdos.csail.mit.edu/6.828/2010/readings/i386.pdf (PDF of above)
- http://ref.x86asm.net/coder32.html
- http://www.sandpile.org/
- http://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture
- http://en.wikipedia.org/wiki/X86
- http://en.wikipedia.org/wiki/Control_register
- http://en.wikipedia.org/wiki/X86_assembly_language
- http://en.wikipedia.org/wiki/Translation_lookaside_buffer
#### Bit Hacking
- http://graphics.stanford.edu/~seander/bithacks.html
#### Other devices
- http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming
[1]: http://bellard.org/jslinux/tech.html
[2]: http://jsshaper.org
[3]: https://github.com/ubercomp/jslm32
[4]: https://bugs.webkit.org/show_bug.cgi?id=72154
[5]: https://github.com/s-macke/jor1k
[6]: http://copy.sh/v86/
[7]: https://github.com/copy/v86
[8]: http://riscv.org/angel/
[9]: https://github.com/ucb-bar/riscv-angel
[10]: http://riscv.org/
[11]: http://www.lowrisc.org/

View File

@ -0,0 +1,706 @@
package scale.backend.x86;
/**
* The Intel X86 opcodes.
* <p>
* $Id$
* <p>
* Copyright 2008 by James H. Burrill<br>
* All Rights Reserved.<br>
*/
public final class Opcodes
{
// The opcode value has several fields:
// +------------------+----+----+----------+
// | F | M | S | O |
// +------------------+----+----+----------+
//
// F: form flags indicating legal forms
// M: Scaling factor used in some addressing forms
// S: Operand size
// O: instruction opcode
/**
* Mask for the instruction opcode.
*/
public static final int O_MASK = 0x000003ff;
/**
* Mask for the instruction opcode.
*/
public static final int O_SHIFT = 0;
/**
* Mask for the operand size.
*/
public static final int S_MASK = 0x00000c00;
/**
* Shift for the operand size.
*/
public static final int S_SHIFT = 10;
/**
* Operand size - byte.
*/
public static final int S_BYTE = 0x00000000;
/**
* Operand size - short.
*/
public static final int S_SHORT = 0x00000400;
/**
* Operand size - int.
*/
public static final int S_INT = 0x00000800;
/**
* Operand size - LONG.
*/
public static final int S_LONG = 0x00000c00;
/**
* Mask for the scaling factor used in some addressing modes..
*/
public static final int M_MASK = 0x00003000;
/**
* Shift for the scaling factor used in some addressing modes..
*/
public static final int M_SHIFT = 12;
/**
* Scaling factor - 1.
*/
public static final int M_ONE = 0x00000000;
/**
* Scaling factor - 2.
*/
public static final int M_TWO = 0x00001000;
/**
* Scaling factor - 4.
*/
public static final int M_FOUR = 0x00002000;
/**
* Scaling factor - 8.
*/
public static final int M_EIGHT = 0x00003000;
/**
* Valid form has no operands.
*/
public static final int F_NONE = 0x00004000;
/**
* Valid form has one register operand.
*/
public static final int F_R = 0x00008000;
/**
* Valid form has two register operands.
*/
public static final int F_RR = 0x00010000;
/**
* Valid form has three register operands.
*/
public static final int F_RRR = 0x00020000;
/**
* Valid form has a descriptor operand.
*/
public static final int F_D = 0x00040000;
/**
* Valid form has a register operand and a descriptor operand.
*/
public static final int F_RD = 0x00080000;
/**
* Valid form has two register operands and a descriptor operand.
*/
public static final int F_RRD = 0x00100000;
/**
* Valid form has three register operands and a descriptor operand.
*/
public static final int F_RRRD = 0x00200000;
/**
* Branch instruction flag.
*/
public static final int F_BRANCH = 0x00400000;
/**
* Operands are reversed flag.
*/
public static final int F_REV = 0x00800000;
public static final int F_SHFT = F_RD + F_RR;
public static final int F_ARTH = F_RR + F_RD + F_RRR + F_RRD + F_RRRD; // ADD, ADC, AND, XOR, OR, SBB, SUB, CMP
public static final int F_CALL = F_D + F_R + F_RD + F_RR + F_RRD;
// Integer Instructions
// DATA TRANSFER INSTRUCTIONS
public static final int MOV = 0X000 + F_NONE; // Move
public static final int CMOVE = 0X001 + F_NONE; // Conditional move if equal
public static final int CMOVZ = 0X002 + F_NONE; // Conditional move if zero
public static final int CMOVNE = 0X003 + F_NONE; // Conditional move if not equal
public static final int CMOVNZ = 0X004 + F_NONE; // Conditional move if not zero
public static final int CMOVA = 0X005 + F_NONE; // Conditional move if above
public static final int CMOVNBE = 0X006 + F_NONE; // Conditional move if not below or equal
public static final int CMOVAE = 0X007 + F_NONE; // Conditional move if above or equal
public static final int CMOVNB = 0X008 + F_NONE; // Conditional move if not below
public static final int CMOVB = 0X009 + F_NONE; // Conditional move if below
public static final int CMOVNAE = 0X00A + F_NONE; // Conditional move if not above or equal
public static final int CMOVBE = 0X00B + F_NONE; // Conditional move if below or equal
public static final int CMOVNA = 0X00C + F_NONE; // Conditional move if not above
public static final int CMOVG = 0X00D + F_NONE; // Conditional move if greater
public static final int CMOVNLE = 0X00E + F_NONE; // Conditional move if not less or equal
public static final int CMOVGE = 0X00F + F_NONE; // Conditional move if greater or equal
public static final int CMOVNL = 0X010 + F_NONE; // Conditional move if not less
public static final int CMOVL = 0X011 + F_NONE; // Conditional move if less
public static final int CMOVNGE = 0X012 + F_NONE; // Conditional move if not greater or equal
public static final int CMOVLE = 0X013 + F_NONE; // Conditional move if less or equal
public static final int CMOVNG = 0X014 + F_NONE; // Conditional move if not greater
public static final int CMOVC = 0X015 + F_NONE; // Conditional move if carry
public static final int CMOVNC = 0X016 + F_NONE; // Conditional move if not carry
public static final int CMOVO = 0X017 + F_NONE; // Conditional move if overflow
public static final int CMOVNO = 0X018 + F_NONE; // Conditional move if not overflow
public static final int CMOVS = 0X019 + F_NONE; // Conditional move if sign (negative)
public static final int CMOVNS = 0X01A + F_NONE; // Conditional move if not sign (non-negative)
public static final int CMOVP = 0X01B + F_NONE; // Conditional move if parity
public static final int CMOVPE = 0X01C + F_NONE; // Conditional move if parity even
public static final int CMOVNP = 0X01D + F_NONE; // Conditional move if not parity
public static final int CMOVPO = 0X01E + F_NONE; // Conditional move if parity odd
public static final int XCHG = 0X01F + F_NONE; // Exchange
public static final int BSWAP = 0X020 + F_NONE; // Byte swap
public static final int XADD = 0X021 + F_NONE; // Exchange and add
public static final int CMPXCHG = 0X022 + F_NONE; // Compare and exchange
public static final int CMPXCHG8B = 0X023 + F_NONE; // Compare and exchange 8 bytes
public static final int PUSH = 0X024 + F_NONE; // Push onto stack
public static final int POP = 0X025 + F_NONE; // Pop off of stack
public static final int PUSHA = 0X026 + F_NONE; // Push general-purpose registers onto stack
public static final int PUSHAD = 0X027 + F_NONE; // Push general-purpose registers onto stack
public static final int POPA = 0X028 + F_NONE; // Pop general-purpose registers from stack
public static final int POPAD = 0X029 + F_NONE; // Pop general-purpose registers from stack
public static final int IN = 0X02A + F_NONE; // Read from a port
public static final int OUT = 0X02B + F_NONE; // Write to a port
public static final int CWD = 0X02C + F_NONE; // Convert word to doubleword
public static final int CDQ = 0X02D + F_NONE; // Convert doubleword to quadword
public static final int CBW = 0X02E + F_NONE; // Convert byte to word
public static final int CWDE = 0X02F + F_NONE; // Convert word to doubleword in EAX register
public static final int MOVSX = 0X030 + F_NONE; // Move and sign extend
public static final int MOVZX = 0X031 + F_NONE; // Move and zero extend
// BINARY ARTHMETIC INSTRUCTIONS
public static final int ADD = 0X032 + F_ARTH; // Integer add
public static final int ADC = 0X033 + F_ARTH; // Add with carry
public static final int SUB = 0X034 + F_ARTH; // Subtract
public static final int SBB = 0X035 + F_ARTH; // Subtract with borrow
public static final int IMUL = 0X036 + F_NONE; // Signed multiply
public static final int MUL = 0X037 + F_NONE; // Unsigned multiply
public static final int IDIV = 0X038 + F_NONE; // Signed divide
public static final int DIV = 0X039 + F_NONE; // Unsigned divide
public static final int INC = 0X03A + F_NONE; // Increment
public static final int DEC = 0X03B + F_NONE; // Decrement
public static final int NEG = 0X03C + F_NONE; // Negate
public static final int CMP = 0X03D + F_ARTH; // Compare
// DECIMAL ARTHMETIC
public static final int DAA = 0X03E + F_NONE; // Decimal adjust after addition
public static final int DAS = 0X03F + F_NONE; // Decimal adjust after subtraction
public static final int AAA = 0X040 + F_NONE; // ASCII adjust after addition
public static final int AAS = 0X041 + F_NONE; // ASCII adjust after subtraction
public static final int AAM = 0X042 + F_NONE; // ASCII adjust after multiplication
public static final int AAD = 0X043 + F_NONE; // ASCII adjust before division
// LOGIC INSTRUCTIONS
public static final int AND = 0X044 + F_ARTH; // And
public static final int OR = 0X045 + F_ARTH; // Or
public static final int XOR = 0X046 + F_ARTH; // Exclusive or
public static final int NOT = 0X047 + F_NONE; // Not
// SHIFT AND ROTATE INSTRUCTIONS
public static final int SAR = 0X048 + F_SHFT; // Shift arithmetic right
public static final int SHR = 0X049 + F_SHFT; // Shift logical right
public static final int SAL = 0X04A + F_SHFT; // Shift arithmetic left
public static final int SHL = 0X04B + F_SHFT; // Shift arithmetic left
public static final int SHRD = 0X04C + F_SHFT; // Shift right double
public static final int SHLD = 0X04D + F_SHFT; // Shift left double
public static final int ROR = 0X04E + F_SHFT; // Rotate right
public static final int ROL = 0X04F + F_SHFT; // Rotate left
public static final int RCR = 0X050 + F_SHFT; // Rotate through carry right
public static final int RCL = 0X051 + F_SHFT; // Rotate through carry left
// BIT AND BYTE INSTRUCTIONS
public static final int BT = 0X052 + F_ARTH; // Bit test
public static final int BTS = 0X053 + F_NONE; // Bit test and set
public static final int BTR = 0X054 + F_NONE; // Bit test and reset
public static final int BTC = 0X055 + F_ARTH; // Bit test and complement
public static final int BSF = 0X056 + F_NONE; // Bit scan forward
public static final int BSR = 0X057 + F_NONE; // Bit scan reverse
public static final int SETE = 0X058 + F_NONE; // Set byte if equal
public static final int SETZ = 0X059 + F_NONE; // Set byte if zero
public static final int SETNE = 0X05A + F_NONE; // Set byte if not equal
public static final int SETNZ = 0X05B + F_NONE; // Set byte if not zero
public static final int SETA = 0X05C + F_NONE; // Set byte if above
public static final int SETNBE = 0X05D + F_NONE; // Set byte if not below or equal
public static final int SETAE = 0X05E + F_NONE; // Set byte if above or equal
public static final int SETNB = 0X05F + F_NONE; // Set byte if not below
public static final int SETNC = 0X060 + F_NONE; // Set byte if not carry
public static final int SETB = 0X061 + F_NONE; // Set byte if below
public static final int SETNAE = 0X062 + F_NONE; // Set byte if not above or equal
public static final int SETC = 0X063 + F_NONE; // Set byte if carry
public static final int SETBE = 0X064 + F_NONE; // Set byte if below or equal
public static final int SETNA = 0X065 + F_NONE; // Set byte if not above
public static final int SETG = 0X066 + F_NONE; // Set byte if greater
public static final int SETNLE = 0X067 + F_NONE; // Set byte if not less or equal
public static final int SETGE = 0X068 + F_NONE; // Set byte if greater or equal
public static final int SETNL = 0X069 + F_NONE; // Set byte if not less
public static final int SETL = 0X06A + F_NONE; // Set byte if less
public static final int SETNGE = 0X06B + F_NONE; // Set byte if not greater or equal
public static final int SETLE = 0X06C + F_NONE; // Set byte if less or equal
public static final int SETNG = 0X06D + F_NONE; // Set byte if not greater
public static final int SETS = 0X06E + F_NONE; // Set byte if sign (negative)
public static final int SETNS = 0X06F + F_NONE; // Set byte if not sign (non-negative)
public static final int SETO = 0X070 + F_NONE; // Set byte if overflow
public static final int SETNO = 0X071 + F_NONE; // Set byte if not overflow
public static final int SETPE = 0X072 + F_NONE; // Set byte if parity even
public static final int SETP = 0X073 + F_NONE; // Set byte if parity
public static final int SETPO = 0X074 + F_NONE; // Set byte if parity odd
public static final int SETNP = 0X075 + F_NONE; // Set byte if not parity
public static final int TEST = 0X076 + F_NONE; // Logical compare
// CONTROL TRANSFER INSTRUCTIONS
public static final int JMP = 0X077 + F_NONE; // Jump
public static final int JE = 0X078 + F_NONE; // Jump if equal
public static final int JZ = 0X079 + F_NONE; // Jump if zero
public static final int JNE = 0X07A + F_NONE; // Jump if not equal
public static final int JNZ = 0X07B + F_NONE; // Jump if not zero
public static final int JA = 0X07C + F_NONE; // Jump if above
public static final int JNBE = 0X07D + F_NONE; // Jump if not below or equal
public static final int JAE = 0X07E + F_NONE; // Jump if above or equal
public static final int JNB = 0X07F + F_NONE; // Jump if not below
public static final int JB = 0X080 + F_NONE; // Jump if below
public static final int JNAE = 0X081 + F_NONE; // Jump if not above or equal
public static final int JBE = 0X082 + F_NONE; // Jump if below or equal
public static final int JNA = 0X083 + F_NONE; // Jump if not above
public static final int JG = 0X084 + F_NONE; // Jump if greater
public static final int JNLE = 0X085 + F_NONE; // Jump if not less or equal
public static final int JGE = 0X086 + F_NONE; // Jump if greater or equal
public static final int JNL = 0X087 + F_NONE; // Jump if not less
public static final int JL = 0X088 + F_NONE; // Jump if less
public static final int JNGE = 0X089 + F_NONE; // Jump if not greater or equal
public static final int JLE = 0X08A + F_NONE; // Jump if less or equal
public static final int JNG = 0X08B + F_NONE; // Jump if not greater
public static final int JC = 0X08C + F_NONE; // Jump if carry
public static final int JNC = 0X08D + F_NONE; // Jump if not carry
public static final int JO = 0X08E + F_NONE; // Jump if overflow
public static final int JNO = 0X08F + F_NONE; // Jump if not overflow
public static final int JS = 0X090 + F_NONE; // Jump if sign (negative)
public static final int JNS = 0X091 + F_NONE; // Jump if not sign (non-negative)
public static final int JPO = 0X092 + F_NONE; // Jump if parity odd
public static final int JNP = 0X093 + F_NONE; // Jump if not parity
public static final int JPE = 0X094 + F_NONE; // Jump if parity even
public static final int JP = 0X095 + F_NONE; // Jump if parity
public static final int JCXZ = 0X096 + F_NONE; // Jump register CX zero
public static final int JECXZ = 0X097 + F_NONE; // Jump register ECX zero
public static final int LOOP = 0X098 + F_NONE; // Loop with ECX counter
public static final int LOOPZ = 0X099 + F_NONE; // Loop with ECX and zero
public static final int LOOPE = 0X09A + F_NONE; // Loop with ECX and equal
public static final int LOOPNZ = 0X09B + F_NONE; // Loop with ECX and not zero
public static final int LOOPNE = 0X09C + F_NONE; // Loop with ECX and not equal
public static final int CALL = 0X09D + F_NONE; // Call procedure
public static final int RET = 0X09E + F_NONE; // Return
public static final int IRET = 0X09F + F_NONE; // Return from interrupt
public static final int INT = 0X0A0 + F_NONE; // Software interrupt
public static final int INTO = 0X0A1 + F_NONE; // Interrupt on overflow
public static final int BOUND = 0X0A2 + F_NONE; // Detect value out of range
public static final int ENTER = 0X0A3 + F_NONE; // High-level procedure entry
public static final int LEAVE = 0X0A4 + F_NONE; // High-level procedure exit
// STRING INSTRUCTIONS
public static final int UN00 = 0X0A5 + F_NONE; // Unused
public static final int MOVSB = 0X0A6 + F_NONE; // Move byte string
public static final int UN01 = 0X0A7 + F_NONE; // Unused
public static final int MOVSW = 0X0A8 + F_NONE; // Move word string
public static final int UN02 = 0X0A9 + F_NONE; // Unused
public static final int MOVSD = 0X0AA + F_NONE; // Move doubleword string
public static final int UN03 = 0X0AB + F_NONE; // Unused
public static final int CMPSB = 0X0AC + F_NONE; // Compare byte string
public static final int UN04 = 0X0AD + F_NONE; // Unused
public static final int CMPSW = 0X0AE + F_NONE; // Compare word string
public static final int UN05 = 0X0AF + F_NONE; // Unused
public static final int CMPSD = 0X0B0 + F_NONE; // Compare doubleword string
public static final int UN06 = 0X0B1 + F_NONE; // Unused
public static final int SCASB = 0X0B2 + F_NONE; // Scan byte string
public static final int UN07 = 0X0B3 + F_NONE; // Unused
public static final int SCASW = 0X0B4 + F_NONE; // Scan word string
public static final int UN08 = 0X0B5 + F_NONE; // Unused
public static final int SCASD = 0X0B6 + F_NONE; // Scan doubleword string
public static final int UN09 = 0X0B7 + F_NONE; // Unused
public static final int LODSB = 0X0B8 + F_NONE; // Load byte string
public static final int UN10 = 0X0B9 + F_NONE; // Unused
public static final int LODSW = 0X0BA + F_NONE; // Load word string
public static final int UN11 = 0X0BB + F_NONE; // Unused
public static final int LODSD = 0X0BC + F_NONE; // Load doubleword string
public static final int UN12 = 0X0BD + F_NONE; // Unused
public static final int STOSB = 0X0BE + F_NONE; // Store byte string
public static final int UN13 = 0X0BF + F_NONE; // Unused
public static final int STOSW = 0X0C0 + F_NONE; // Store word string
public static final int UN14 = 0X0C1 + F_NONE; // KUnusedStore string
public static final int STOSD = 0X0C2 + F_NONE; // Store doubleword string
public static final int REP = 0X0C3 + F_NONE; // Repeat while ECX not zero
public static final int REPE = 0X0C4 + F_NONE; // Repeat while equal
public static final int REPZ = 0X0C5 + F_NONE; // Repeat while zero
public static final int REPNE = 0X0C6 + F_NONE; // Repeat while not equal
public static final int REPNZ = 0X0C7 + F_NONE; // Repeat while not zero
public static final int UN15 = 0X0C8 + F_NONE; // Unused
public static final int INSB = 0X0C9 + F_NONE; // Input byte string from port
public static final int UN16 = 0X0CA + F_NONE; // Unused
public static final int INSW = 0X0CB + F_NONE; // Input word string from port
public static final int UN17 = 0X0CC + F_NONE; // Unused
public static final int INSD = 0X0CD + F_NONE; // Input doubleword string from port
public static final int UN18 = 0X0CE + F_NONE; // Unused
public static final int OUTSB = 0X0CF + F_NONE; // Output byte string to port
public static final int UN19 = 0X0D0 + F_NONE; // Unused
public static final int OUTSW = 0X0D1 + F_NONE; // Output word string to port
public static final int UN20 = 0X0D2 + F_NONE; // Unused
public static final int OUTSD = 0X0D3 + F_NONE; // Output doubleword string to port
// FLAG CONTROL INSTRUCTIONS
public static final int STC = 0X0D4 + F_NONE; // Set carry flag
public static final int CLC = 0X0D5 + F_NONE; // Clear the carry flag
public static final int CMC = 0X0D6 + F_NONE; // Complement the carry flag
public static final int CLD = 0X0D7 + F_NONE; // Clear the direction flag
public static final int STD = 0X0D8 + F_NONE; // Set direction flag
public static final int LAHF = 0X0D9 + F_NONE; // Load flags into AH register
public static final int SAHF = 0X0DA + F_NONE; // Store AH register into flags
public static final int PUSHF = 0X0DB + F_NONE; // Push EFLAGS onto stack
public static final int PUSHFD = 0X0DC + F_NONE; // Push EFLAGS onto stack
public static final int POPF = 0X0DD + F_NONE; // Pop EFLAGS from stack
public static final int POPFD = 0X0DE + F_NONE; // Pop EFLAGS from stack
public static final int STI = 0X0DF + F_NONE; // Set interrupt flag
public static final int CLI = 0X0E0 + F_NONE; // Clear the interrupt flag
// SEGMENT REGISTER INSTRUCTIONS
public static final int LDS = 0X0E1 + F_NONE; // Load far pointer using DS
public static final int LES = 0X0E2 + F_NONE; // Load far pointer using ES
public static final int LFS = 0X0E3 + F_NONE; // Load far pointer using FS
public static final int LGS = 0X0E4 + F_NONE; // Load far pointer using GS
public static final int LSS = 0X0E5 + F_NONE; // Load far pointer using SS
// MISCELLANEOUS INSTRUCTIONS
public static final int LEA = 0X0E6 + F_NONE; // Load effective address
public static final int NOP = 0X0E7 + F_NONE; // No operation
public static final int UB2 = 0X0E8 + F_NONE; // Undefined instruction
public static final int XLAT = 0X0E9 + F_NONE; // Table lookup translation
public static final int XLATB = 0X0EA + F_NONE; // Table lookup translation
public static final int CPUID = 0X0EB + F_NONE; // Processor Identification
// MMXTM Technology Instructions
// MMXTM DATA TRANSFER INSTRUCTIONS
public static final int MOVD = 0X0EC + F_NONE; // Move doubleword
public static final int MOVQ = 0X0ED + F_NONE; // Move quadword
// MMXTM CONVERSION INSTRUCTIONS
public static final int PACKSSWB = 0X0EE + F_NONE; // Pack words into bytes with signed saturation
public static final int PACKSSDW = 0X0EF + F_NONE; // Pack doublewords into words with signed saturation
public static final int PACKUSWB = 0X0F0 + F_NONE; // Pack words into bytes with unsigned saturation
public static final int PUNPCKHBW = 0X0F1 + F_NONE; // Unpack high-order bytes from words
public static final int PUNPCKHWD = 0X0F2 + F_NONE; // Unpack high-order words from doublewords
public static final int PUNPCKHDQ = 0X0F3 + F_NONE; // Unpack high-order doublewords from quadword
public static final int PUNPCKLBW = 0X0F4 + F_NONE; // Unpack low-order bytes from words
public static final int PUNPCKLWD = 0X0F5 + F_NONE; // Unpack low-order words from doublewords
public static final int PUNPCKLDQ = 0X0F6 + F_NONE; // Unpack low-order doublewords from quadword
// MMXTM PACKED ARTHMETIC INSTRUCTIONS
public static final int PADDB = 0X0F7 + F_NONE; // Add packed bytes
public static final int PADDW = 0X0F8 + F_NONE; // Add packed words
public static final int PADDD = 0X0F9 + F_NONE; // Add packed doublewords
public static final int PADDSB = 0X0FA + F_NONE; // Add packed bytes with saturation
public static final int PADDSW = 0X0FB + F_NONE; // Add packed words with saturation
public static final int PADDUSB = 0X0FC + F_NONE; // Add packed unsigned bytes with saturation
public static final int PADDUSW = 0X0FD + F_NONE; // Add packed unsigned words with saturation
public static final int PSUBB = 0X0FE + F_NONE; // Subtract packed bytes
public static final int PSUBW = 0X0FF + F_NONE; // Subtract packed words
public static final int PSUBD = 0X100 + F_NONE; // Subtract packed doublewords
public static final int PSUBSB = 0X101 + F_NONE; // Subtract packed bytes with saturation
public static final int PSUBSW = 0X102 + F_NONE; // Subtract packed words with saturation
public static final int PSUBUSB = 0X103 + F_NONE; // Subtract packed unsigned bytes with saturation
public static final int PSUBUSW = 0X104 + F_NONE; // Subtract packed unsigned words with saturation
public static final int PMULHW = 0X105 + F_NONE; // Multiply packed words and store high result
public static final int PMULLW = 0X106 + F_NONE; // Multiply packed words and store low result
public static final int PMADDWD = 0X107 + F_NONE; // Multiply and add packed words
// MMXTM COMPARISON INSTRUCTIONS
public static final int PCMPEQB = 0X108 + F_NONE; // Compare packed bytes for equal
public static final int PCMPEQW = 0X109 + F_NONE; // Compare packed words for equal
public static final int PCMPEQD = 0X10A + F_NONE; // Compare packed doublewords for equal
public static final int PCMPGTB = 0X10B + F_NONE; // Compare packed bytes for greater than
public static final int PCMPGTW = 0X10C + F_NONE; // Compare packed words for greater than
public static final int PCMPGTD = 0X10D + F_NONE; // Compare packed doublewords for greater than
// MMXTM LOGIC INSTRUCTIONS
public static final int PAND = 0X10E + F_NONE; // Bitwise logical and
public static final int PANDN = 0X10F + F_NONE; // Bitwise logical and not
public static final int POR = 0X110 + F_NONE; // Bitwise logical or
public static final int PXOR = 0X111 + F_NONE; // Bitwise logical exclusive or
// MMXTM SHIFT AND ROTATE INSTRUCTIONS
public static final int PSLLW = 0X112 + F_NONE; // Shift packed words left logical
public static final int PSLLD = 0X113 + F_NONE; // Shift packed doublewords left logical
public static final int PSLLQ = 0X114 + F_NONE; // Shift packed quadword left logical
public static final int PSRLW = 0X115 + F_NONE; // Shift packed words right logical
public static final int PSRLD = 0X116 + F_NONE; // Shift packed doublewords right logical
public static final int PSRLQ = 0X117 + F_NONE; // Shift packed quadword right logical
public static final int PSRAW = 0X118 + F_NONE; // Shift packed words right arithmetic
public static final int PSRAD = 0X119 + F_NONE; // Shift packed doublewords right arithmetic
// MMXTM STATE MANAGEMENT
public static final int EMMS = 0X11A + F_NONE; // Empty MMX state
// Floating-Point Instructions
// DATA TRANSFER
public static final int FLD = 0X11B + F_NONE; // Load real
public static final int FST = 0X11C + F_NONE; // Store real
public static final int FSTP = 0X11D + F_NONE; // Store real and pop
public static final int FILD = 0X11E + F_NONE; // Load integer
public static final int FIST = 0X11F + F_NONE; // Store integer
public static final int FISTP = 0X120 + F_NONE; // Store integer and pop
public static final int FBLD = 0X121 + F_NONE; // Load BCD
public static final int FBSTP = 0X122 + F_NONE; // Store BCD and pop
public static final int FXCH = 0X123 + F_NONE; // Exchange registers
public static final int FCMOVE = 0X124 + F_NONE; // Floating-point conditional move if equal
public static final int FCMOVNE = 0X125 + F_NONE; // Floating-point conditional move if not equal
public static final int FCMOVB = 0X126 + F_NONE; // Floating-point conditional move if below
public static final int FCMOVBE = 0X127 + F_NONE; // Floating-point conditional move if below or equal
public static final int FCMOVNB = 0X128 + F_NONE; // Floating-point conditional move if not below
public static final int FCMOVNBE = 0X129 + F_NONE; // Floating-point conditional move if not below or equal
public static final int FCMOVU = 0X12A + F_NONE; // Floating-point conditional move if unordered
public static final int FCMOVNU = 0X12B + F_NONE; // Floating-point conditional move if not unordered
// BASIC ARTHMETIC
public static final int FADD = 0X12C + F_NONE; // Add real
public static final int FADDP = 0X12D + F_NONE; // Add real and pop
public static final int FIADD = 0X12E + F_NONE; // Add integer
public static final int FSUB = 0X12F + F_NONE; // Subtract real
public static final int FSUBP = 0X130 + F_NONE; // Subtract real and pop
public static final int FISUB = 0X131 + F_NONE; // Subtract integer
public static final int FSUBR = 0X132 + F_NONE; // Subtract real reverse
public static final int FSUBRP = 0X133 + F_NONE; // Subtract real reverse and pop
public static final int FISUBR = 0X134 + F_NONE; // Subtract integer reverse
public static final int FMUL = 0X135 + F_NONE; // Multiply real
public static final int FMULP = 0X136 + F_NONE; // Multiply real and pop
public static final int FIMUL = 0X137 + F_NONE; // Multiply integer
public static final int FDIV = 0X138 + F_NONE; // Divide real
public static final int FDIVP = 0X139 + F_NONE; // Divide real and pop
public static final int FIDIV = 0X13A + F_NONE; // Divide integer
public static final int FDIVR = 0X13B + F_NONE; // Divide real reverse
public static final int FDIVRP = 0X13C + F_NONE; // Divide real reverse and pop
public static final int FIDIVR = 0X13D + F_NONE; // Divide integer reverse
public static final int FPREM = 0X13E + F_NONE; // Partial remainder
public static final int FPREMI = 0X13F + F_NONE; // IEEE Partial remainder
public static final int FABS = 0X140 + F_NONE; // Absolute value
public static final int FCHS = 0X141 + F_NONE; // Change sign
public static final int FRNDINT = 0X142 + F_NONE; // Round to integer
public static final int FSCALE = 0X143 + F_NONE; // Scale by power of two
public static final int FSQRT = 0X144 + F_NONE; // Square root
public static final int FXTRACT = 0X145 + F_NONE; // Extract exponent and significand
// COMPARISON
public static final int FCOM = 0X146 + F_NONE; // Compare real
public static final int FCOMP = 0X147 + F_NONE; // Compare real and pop
public static final int FCOMPP = 0X148 + F_NONE; // Compare real and pop twice
public static final int FUCOM = 0X149 + F_NONE; // Unordered compare real
public static final int FUCOMP = 0X14A + F_NONE; // Unordered compare real and pop
public static final int FUCOMPP = 0X14B + F_NONE; // Unordered compare real and pop twice
public static final int FICOM = 0X14C + F_NONE; // Compare integer
public static final int FICOMP = 0X14D + F_NONE; // Compare integer and pop
public static final int FCOMI = 0X14E + F_NONE; // Compare real and set EFLAGS
public static final int FUCOMI = 0X14F + F_NONE; // Unordered compare real and set EFLAGS
public static final int FCOMIP = 0X150 + F_NONE; // Compare real, set EFLAGS, and pop
public static final int FUCOMIP = 0X151 + F_NONE; // Unordered compare real, set EFLAGS, and pop
public static final int FTST = 0X152 + F_NONE; // Test real
public static final int FXAM = 0X153 + F_NONE; // Examine real
// TRANSCENDENTAL
public static final int FSIN = 0X154 + F_NONE; // Sine
public static final int FCOS = 0X155 + F_NONE; // Cosine
public static final int FSINCOS = 0X156 + F_NONE; // Sine and cosine
public static final int FPTAN = 0X157 + F_NONE; // Partial tangent
public static final int FPATAN = 0X158 + F_NONE; // Partial arctangent
public static final int F2XM1 = 0X159 + F_NONE; // 2x - 1
public static final int FYL2X = 0X15A + F_NONE; // y*log2x
public static final int FYL2XP1 = 0X15B + F_NONE; // y*log 2(x+1)
// LOAD CONSTANTS
public static final int FLD1 = 0X15C + F_NONE; // Load +1.0
public static final int FLDZ = 0X15D + F_NONE; // Load +0.0
public static final int FLDPI = 0X15E + F_NONE; // Load Pi
public static final int FLDL2E = 0X15F + F_NONE; // Load log2e
public static final int FLDLN2 = 0X160 + F_NONE; // Load loge2
public static final int FLDL2T = 0X161 + F_NONE; // Load log210
public static final int FLDLG2 = 0X162 + F_NONE; // Load log102
// FPU CONTROL
public static final int FINCSTP = 0X163 + F_NONE; // Increment FPU register stack pointer
public static final int FDECSTP = 0X164 + F_NONE; // Decrement FPU register stack pointer
public static final int FFREE = 0X165 + F_NONE; // Free floating-point register
public static final int FINIT = 0X166 + F_NONE; // Initialize FPU after checking error conditions
public static final int FNINIT = 0X167 + F_NONE; // Initialize FPU without checking error conditions
public static final int FCLEX = 0X168 + F_NONE; // Clear floating-point exception flags after checking for error conditions
public static final int FNCLEX = 0X169 + F_NONE; // Clear floating-point exception flags without checking for error conditions
public static final int FSTCW = 0X16A + F_NONE; // Store FPU control word after checking error conditions
public static final int FNSTCW = 0X16B + F_NONE; // Store FPU control word without checking error conditions
public static final int FLDCW = 0X16C + F_NONE; // Load FPU control word
public static final int FSTENV = 0X16D + F_NONE; // Store FPU environment after checking error conditions
public static final int FNSTENV = 0X16E + F_NONE; // Store FPU environment without checking error conditions
public static final int FLDENV = 0X16F + F_NONE; // Load FPU environment
public static final int FSAVE = 0X170 + F_NONE; // Save FPU state after checking error conditions
public static final int FNSAVE = 0X171 + F_NONE; // Save FPU state without checking error conditions
public static final int FRSTOR = 0X172 + F_NONE; // Restore FPU state
public static final int FSTSW = 0X173 + F_NONE; // Store FPU status word after checking error conditions
public static final int FNSTSW = 0X174 + F_NONE; // Store FPU status word without checking error conditions
public static final int WAIT = 0X175 + F_NONE; // Wait for FPU
public static final int FWAIT = 0X176 + F_NONE; // Wait for FPU
public static final int FNOP = 0X177 + F_NONE; // FPU no operation
// System Instructions
public static final int LGDT = 0X178 + F_NONE; // Load global descriptor table (GDT) register
public static final int SGDT = 0X179 + F_NONE; // Store global descriptor table (GDT) register
public static final int LLDT = 0X17A + F_NONE; // Load local descriptor table (LDT) register
public static final int SLDT = 0X17B + F_NONE; // Store local descriptor table (LDT) register
public static final int LTR = 0X17C + F_NONE; // Load task register
public static final int STR = 0X17D + F_NONE; // Store task register
public static final int LIDT = 0X17E + F_NONE; // Load interrupt descriptor table (IDT) register
public static final int SIDT = 0X17F + F_NONE; // Store interrupt descriptor table (IDT) register
public static final int LMSW = 0X180 + F_NONE; // Load machine status word
public static final int SMSW = 0X181 + F_NONE; // Store machine status word
public static final int CLTS = 0X182 + F_NONE; // Clear the task-switched flag
public static final int ARPL = 0X183 + F_NONE; // Adjust requested privilege level
public static final int LAR = 0X184 + F_NONE; // Load access rights
public static final int LSL = 0X185 + F_NONE; // Load segment limit
public static final int VERR = 0X186 + F_NONE; // Verify segment for reading
public static final int VERW = 0X187 + F_NONE; // Verify segment for writing
public static final int INVD = 0X188 + F_NONE; // Invalidate cache, no writeback
public static final int WBINVD = 0X189 + F_NONE; // Invalidate cache, with writeback
public static final int INVLPG = 0X18A + F_NONE; // Invalidate TLB Entry
public static final int LOCK = 0X18B + F_NONE; // (prefix) Lock Bus
public static final int HLT = 0X18C + F_NONE; // Halt processor
public static final int RSM = 0X18D + F_NONE; // Return from system management mode (SSM)
public static final int RDMSR = 0X18E + F_NONE; // Read model-specific register
public static final int WRMSR = 0X18F + F_NONE; // Write model-specific register
public static final int RDPMC = 0X190 + F_NONE; // Read performance monitoring counters
public static final int RDTSC = 0X191 + F_NONE; // Read time stamp counter
public static final int LDDR = 0X192 + F_NONE; // Load debug register
public static final int STDR = 0X193 + F_NONE; // Store debug register
public static final int LDCR = 0X194 + F_NONE; // Load Control Register
public static final int STCR = 0X195 + F_NONE; // Store Control Register
public static final String[] opnames = {
/* 000 */ "MOV", "CMOVE", "CMOVZ", "CMOVNE", "CMOVNZ", "CMOVA", "CMOVNBE", "CMOVAE",
/* 008 */ "CMOVNB", "CMOVB", "CMOVNAE", "CMOVBE", "CMOVNA", "CMOVG", "CMOVNLE", "CMOVGE",
/* 010 */ "CMOVNL", "CMOVL", "CMOVNGE", "CMOVLE", "CMOVNG", "CMOVC", "CMOVNC", "CMOVO",
/* 018 */ "CMOVNO", "CMOVS", "CMOVNS", "CMOVP", "CMOVPE", "CMOVNP", "CMOVPO", "XCHG",
/* 020 */ "BSWAP", "XADD", "CMPXCHG", "CMPXCHG8B", "PUSH", "POP", "PUSHA", "PUSHAD",
/* 028 */ "POPA", "POPAD", "IN", "OUT", "CWD", "CDQ", "CBW", "CWDE",
/* 030 */ "MOVSX", "MOVZX", "ADD", "ADC", "SUB", "SBB", "IMUL", "MUL",
/* 038 */ "IDIV", "DIV", "INC", "DEC", "NEG", "CMP", "DAA", "DAS",
/* 040 */ "AAA", "AAS", "AAM", "AAD", "AND", "OR", "XOR", "NOT",
/* 048 */ "SAR", "SHR", "SAL", "SHL", "SHRD", "SHLD", "ROR", "ROL",
/* 050 */ "RCR", "RCL", "BT", "BTS", "BTR", "BTC", "BSF", "BSR",
/* 058 */ "SETE", "SETZ", "SETNE", "SETNZ", "SETA", "SETNBE", "SETAE", "SETNB",
/* 060 */ "SETNC", "SETB", "SETNAE", "SETC", "SETBE", "SETNA", "SETG", "SETNLE",
/* 068 */ "SETGE", "SETNL", "SETL", "SETNGE", "SETLE", "SETNG", "SETS", "SETNS",
/* 070 */ "SETO", "SETNO", "SETPE", "SETP", "SETPO", "SETNP", "TEST", "JMP",
/* 078 */ "JE", "JZ", "JNE", "JNZ", "JA", "JNBE", "JAE", "JNB",
/* 080 */ "JB", "JNAE", "JBE", "JNA", "JG", "JNLE", "JGE", "JNL",
/* 088 */ "JL", "JNGE", "JLE", "JNG", "JC", "JNC", "JO", "JNO",
/* 090 */ "JS", "JNS", "JPO", "JNP", "JPE", "JP", "JCXZ", "JECXZ",
/* 098 */ "LOOP", "LOOPZ", "LOOPE", "LOOPNZ", "LOOPNE", "CALL", "RET", "IRET",
/* 0A0 */ "INT", "INTO", "BOUND", "ENTER", "LEAVE", "UN00", "MOVSB", "UN01",
/* 0A8 */ "MOVSW", "UN02", "MOVSD", "UN03", "CMPSB", "UN04", "CMPSW", "UN05",
/* 0B0 */ "CMPSD", "UN06", "SCASB", "UN07", "SCASW", "UN08", "SCASD", "UN09",
/* 0B8 */ "LODSB", "UN10", "LODSW", "UN11", "LODSD", "UN12", "STOSB", "UN13",
/* 0C0 */ "STOSW", "UN14", "STOSD", "REP", "REPE", "REPZ", "REPNE", "REPNZ",
/* 0C8 */ "UN15", "INSB", "UN16", "INSW", "UN17", "INSD", "UN18", "OUTSB",
/* 0D0 */ "UN19", "OUTSW", "UN20", "OUTSD", "STC", "CLC", "CMC", "CLD",
/* 0D8 */ "STD", "LAHF", "SAHF", "PUSHF", "PUSHFD", "POPF", "POPFD", "STI",
/* 0E0 */ "CLI", "LDS", "LES", "LFS", "LGS", "LSS", "LEA", "NOP",
/* 0E8 */ "UB2", "XLAT", "XLATB", "CPUID", "MOVD", "MOVQ", "PACKSSWB", "PACKSSDW",
/* 0F0 */ "PACKUSWB", "PUNPCKHBW", "PUNPCKHWD", "PUNPCKHDQ", "PUNPCKLBW", "PUNPCKLWD", "PUNPCKLDQ", "PADDB",
/* 0F8 */ "PADDW", "PADDD", "PADDSB", "PADDSW", "PADDUSB", "PADDUSW", "PSUBB", "PSUBW",
/* 100 */ "PSUBD", "PSUBSB", "PSUBSW", "PSUBUSB", "PSUBUSW", "PMULHW", "PMULLW", "PMADDWD",
/* 108 */ "PCMPEQB", "PCMPEQW", "PCMPEQD", "PCMPGTB", "PCMPGTW", "PCMPGTD", "PAND", "PANDN",
/* 110 */ "POR", "PXOR", "PSLLW", "PSLLD", "PSLLQ", "PSRLW", "PSRLD", "PSRLQ",
/* 118 */ "PSRAW", "PSRAD", "EMMS", "FLD", "FST", "FSTP", "FILD", "FIST",
/* 120 */ "FISTP", "FBLD", "FBSTP", "FXCH", "FCMOVE", "FCMOVNE", "FCMOVB", "FCMOVBE",
/* 128 */ "FCMOVNB", "FCMOVNBE", "FCMOVU", "FCMOVNU", "FADD", "FADDP", "FIADD", "FSUB",
/* 130 */ "FSUBP", "FISUB", "FSUBR", "FSUBRP", "FISUBR", "FMUL", "FMULP", "FIMUL",
/* 138 */ "FDIV", "FDIVP", "FIDIV", "FDIVR", "FDIVRP", "FIDIVR", "FPREM", "FPREMI",
/* 140 */ "FABS", "FCHS", "FRNDINT", "FSCALE", "FSQRT", "FXTRACT", "FCOM", "FCOMP",
/* 148 */ "FCOMPP", "FUCOM", "FUCOMP", "FUCOMPP", "FICOM", "FICOMP", "FCOMI", "FUCOMI",
/* 150 */ "FCOMIP", "FUCOMIP", "FTST", "FXAM", "FSIN", "FCOS", "FSINCOS", "FPTAN",
/* 158 */ "FPATAN", "F2XM1", "FYL2X", "FYL2XP1", "FLD1", "FLDZ", "FLDPI", "FLDL2E",
/* 160 */ "FLDLN2", "FLDL2T", "FLDLG2", "FINCSTP", "FDECSTP", "FFREE", "FINIT", "FNINIT",
/* 168 */ "FCLEX", "FNCLEX", "FSTCW", "FNSTCW", "FLDCW", "FSTENV", "FNSTENV", "FLDENV",
/* 170 */ "FSAVE", "FNSAVE", "FRSTOR", "FSTSW", "FNSTSW", "WAIT", "FWAIT", "FNOP",
/* 178 */ "LGDT", "SGDT", "LLDT", "SLDT", "LTR", "STR", "LIDT", "SIDT",
/* 180 */ "LMSW", "SMSW", "CLTS", "ARPL", "LAR", "LSL", "VERR", "VERW",
/* 188 */ "INVD", "WBINVD", "INVLPG", "LOCK", "HLT", "RSM", "RDMSR", "WRMSR",
/* 190 */ "RDPMC", "RDTSC", "LDDR", "STDR", "LDCR", "STCR",
};
private static final char[] sizeLabels = {'b', 'w', 'l', 'x'};
static
{
assert opnames.length == 0x193;
}
/**
* Return the symbolic string for the instruction.
*/
public static String getOp(X86Instruction inst)
{
return opnames[inst.getOpcode() & O_MASK];
}
/**
* Return the symbolic string for the instruction.
*/
public static String getOp(X86Branch inst)
{
assert ((inst.getOpcode() & F_BRANCH) != 0);
return opnames[inst.getOpcode() & O_MASK];
}
/**
* Return the symbolic string for the instruction.
*/
public static String getOp(int opcode)
{
return opnames[opcode & O_MASK];
}
/**
* Return 1, 2, 4, or 8 depending on the scale factor specified for
* the instruction.
*/
public static int getScale(int opcode)
{
return 1 << ((opcode & M_MASK) >> M_SHIFT);
}
/**
* Set the scale factor specified for the instruction. The value
* must be 1, 2, 4, or 8.
* @return the new opcode
*/
public static int setScale(int opcode, int scale)
{
int sf = 0;
switch (scale) {
case 1: sf = M_ONE; break;
case 2: sf = M_TWO; break;
case 4: sf = M_FOUR; break;
case 8: sf = M_EIGHT; break;
}
return ((opcode & M_MASK) | sf);
}
/**
* Return 1, 2, 4, or 8 depending on the size of the operand, in
* bytes, specified for the instruction.
*/
public static int getOperandSize(int opcode)
{
return 1 << ((opcode & S_MASK) >> S_SHIFT);
}
/**
* Return 'b', 'w', 'l', or 'x' depending on the size of the
* operand specified for the instruction.
*/
public static char getOperandSizeLabel(int opcode)
{
return sizeLabels[(opcode & S_MASK) >> S_SHIFT];
}
/**
* Set the operand size specified for the instruction. The value
* must be 1, 2, 4, or 8.
* @return the new opcode
*/
public static int setOperandSize(int opcode, int size)
{
int sf = 0;
switch (size) {
case 1: sf = S_BYTE; break;
case 2: sf = S_SHORT; break;
case 4: sf = S_INT; break;
case 8: sf = S_LONG; break;
}
return ((opcode & S_MASK) | sf);
}
}

View File

@ -0,0 +1,122 @@
# quick hack:
# grabs data from XML file describing opcodes from http://ref.x86asm.net
# then autocomments the cpux86 emulator code
#
# (super brittle hack)
#
from BeautifulSoup import BeautifulStoneSoup #thank you soup, fuck XML parsers
import json, re
#
# Let me reiterate how much I despise scraping data from XML
#
infile = open("x86reference.xml","r").read()
soup=BeautifulStoneSoup(infile)
onesies=soup.find('one-byte').findAll('pri_opcd')
twosies=soup.find('two-byte').findAll('pri_opcd')
def hexRepOfOp(op):
i=int(op['value'],16)
if i < 16:
return ("0x0"+hex(i)[2:]).lower()
else:
return ("0x" +hex(i)[2:]).lower()
def mnem(op):
res = op.find('mnem')
if res:
return res.string
else:
return ""
def src(op):
res = op.find('syntax').find('src')
if res:
return res.getText()
else:
return ""
def dst(op):
res = op.find('syntax').find('dst')
if res:
return res.getText()
else:
return ""
def note(op):
res = op.find('note').find('brief')
if res:
return res.getText()
else:
return ""
def opstr(op):
return mnem(op)+" "+src(op)+" "+dst(op)+" "+note(op)
onedict = {}
for op in onesies:
onedict[hexRepOfOp(op)] = opstr(op)
twodict = {}
for op in twosies:
twodict[hexRepOfOp(op)] = opstr(op)
# barf some temporaries just for reference later
outfile=open("onebyte_dict.json",'w')
json.dump(onedict,outfile)
outfile.close()
outfile=open("twobyte_dict.json",'w')
json.dump(twodict,outfile)
outfile.close()
# now transform source file --------------------------------------------------------------------------------
# - for weird exec counting function
caseline = re.compile("( case )(0x[0-9a-f]+):.*")
def strip_1(str):
return str
onebyte_start = 3176
twobyte_start = 3177
twobyte_end = 3546
# - for normal instruction format: 0xXX
#caseline = re.compile("(\s+case )(0x[0-9a-f]+):.*")
#def strip_1(str):
# return str
#onebyte_start = 5662
#twobyte_start = 7551
#twobyte_end = 8291
# - for 16bit compat instruction format: 0x1XX
#caseline = re.compile("(\s+case )(0x1[0-9a-f]+):.*")
#def strip_1(str):
# return "0x"+str[-2:]
#onebyte_start = 8472
#twobyte_start = 9245
#twobyte_end = 9647
emulatorlines = open("cpux86-ta.js","r").readlines()
newlines=[]
for i,line in enumerate(emulatorlines):
if i < onebyte_start:
newlines.append(line)
if onebyte_start <= i < twobyte_start: #one-byte instructions
linematch=caseline.match(line)
if linematch:
try:
newlines.append(linematch.group(1)+linematch.group(2)+"://"+onedict[strip_1(linematch.group(2))]+"\n")
except KeyError:
newlines.append(line)
else:
newlines.append(line)
if twobyte_start <= i < twobyte_end: #two-byte instructions
linematch=caseline.match(line)
if linematch:
try:
newlines.append(linematch.group(1)+linematch.group(2)+"://"+twodict[strip_1(linematch.group(2))]+"\n")
except KeyError:
newlines.append(line)
else:
newlines.append(line)
if twobyte_end <= i:
newlines.append(line)
outfile=open("cpux86-ta-auto-annotated.js",'w')
outfile.writelines(newlines)
outfile.close()

View File

@ -0,0 +1,15 @@
;;
;; Simple hack to use JSShaper script reify.js to change symbolnames on the fly in an emacs buffer.
;; assumes existence of /var/tmp and unix tools
;;
(defun js-change-symbol (name1 name2)
(interactive "sOld Symbol Name:
sNew Symbol Name: ")
(let (commandstr (curline (current-line)) (reifypath "/path/to/reify.js"))
(setq commandstr (concat "cat >/var/tmp/refactoring_tmp; node " reifypath " /var/tmp/refactoring_tmp " name1 " " name2))
(message "Command: %s" commandstr)
;;this does most of the work:
(shell-command-on-region 1 (point-max) commandstr t t )
(goto-line curline)
)
)

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,51 @@
/*
JS Reify
Uses JSShaper to parse javascript files and replace symbol names
>node reify.js [filename] old_symbolname new_symbolname
- it barfs output to stdout
- doesn't work w. stdin, node.js can't do sync stdin,
so write to tmpfile for external feeding of this animal)
*/
"use strict"; "use restrict";
var require = require || function(f) { load(f); };
require.paths && typeof __dirname !== "undefined" && require.paths.unshift(__dirname);
var args = (typeof process !== "undefined" && process.argv !== undefined) ?
process.argv.slice(2) : arguments;
var log = (typeof console !== "undefined") && console.log || print;
//if (args.length > 0 && args[0] === "--") {
// args.shift();
//}
if (args.length <= 0) {
log("run-shaper: filename OLDNAME NEWNAME");
(typeof quit === "undefined" ? process.exit : quit)(0);
}
var Shaper = Shaper || require("shaper.js") || Shaper;
var filename = args.shift();
var ORIGNAME = args.shift();
var NEWNAME = args.shift();
//define reify transformer
Shaper("reify", function(root) {
return Shaper.traverse(root, {pre: function(node, ref) {
if (node.type === tkn.IDENTIFIER) { // or: if (Shaper.match("$", node)) {
if(node.value === ORIGNAME ){
Shaper.renameIdentifier(node, NEWNAME);
}
}
}});
});
//specify the transform pipeline
var pipeline = ["reify","source"];
// read: js/d8/v8 || rhino || node
var read = read || typeof readFile !== "undefined" && readFile || require("fs").readFileSync;
var src = read(filename);
var root = Shaper.parseScript(src, filename);
root = Shaper.run(root, pipeline);

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

BIN
root.bin Normal file

Binary file not shown.

528
term.js Normal file
View File

@ -0,0 +1,528 @@
/*
Javascript Terminal
Copyright (c) 2011 Fabrice Bellard
Redistribution or commercial use is prohibited without the author's
permission.
*/
"use strict";
if (!Function.prototype.bind) {
Function.prototype.bind = function(aa) {
var ba = [].slice, ca = ba.call(arguments, 1), self = this, da = function() {
}, ea = function() {
return self.apply(this instanceof da ? this : (aa || {}), ca.concat(ba.call(arguments)));
};
da.prototype = self.prototype;
ea.prototype = new da();
return ea;
};
}
function Term(fa, ga, ha) {
this.w = fa;
this.h = ga;
this.cur_h = ga;
this.tot_h = 1000;
this.y_base = 0;
this.y_disp = 0;
this.x = 0;
this.y = 0;
this.cursorstate = 0;
this.handler = ha;
this.convert_lf_to_crlf = false;
this.state = 0;
this.output_queue = "";
this.bg_colors = ["#000000", "#ff0000", "#00ff00", "#ffff00", "#0000ff", "#ff00ff", "#00ffff", "#ffffff"];
this.fg_colors = ["#000000", "#ff0000", "#00ff00", "#ffff00", "#0000ff", "#ff00ff", "#00ffff", "#ffffff"];
this.def_attr = (7 << 3) | 0;
this.cur_attr = this.def_attr;
this.is_mac = (navigator.userAgent.indexOf("Mac") >= 0) ? true : false;
this.key_rep_state = 0;
this.key_rep_str = "";
}
Term.prototype.open = function() {
var y, ia, i, ja, c;
this.lines = new Array();
c = 32 | (this.def_attr << 16);
for (y = 0; y < this.cur_h; y++) {
ia = new Array();
for (i = 0; i < this.w; i++)
ia[i] = c;
this.lines[y] = ia;
}
document.writeln('<table border="0" cellspacing="0" cellpadding="0">');
for (y = 0; y < this.h; y++) {
document.writeln('<tr><td class="term" id="tline' + y + '"></td></tr>');
}
document.writeln('</table>');
this.refresh(0, this.h - 1);
document.addEventListener("keydown", this.keyDownHandler.bind(this), true);
document.addEventListener("keypress", this.keyPressHandler.bind(this), true);
ja = this;
setInterval(function() {
ja.cursor_timer_cb();
}, 1000);
};
Term.prototype.refresh = function(ka, la) {
var ma, y, ia, na, c, w, i, oa, pa, qa, ra, sa, ta;
for (y = ka; y <= la; y++) {
ta = y + this.y_disp;
if (ta >= this.cur_h)
ta -= this.cur_h;
ia = this.lines[ta];
na = "";
w = this.w;
if (y == this.y && this.cursor_state && this.y_disp == this.y_base) {
oa = this.x;
} else {
oa = -1;
}
qa = this.def_attr;
for (i = 0; i < w; i++) {
c = ia[i];
pa = c >> 16;
c &= 0xffff;
if (i == oa) {
pa = -1;
}
if (pa != qa) {
if (qa != this.def_attr)
na += '</span>';
if (pa != this.def_attr) {
if (pa == -1) {
na += '<span class="termReverse">';
} else {
na += '<span style="';
ra = (pa >> 3) & 7;
sa = pa & 7;
if (ra != 7) {
na += 'color:' + this.fg_colors[ra] + ';';
}
if (sa != 0) {
na += 'background-color:' + this.bg_colors[sa] + ';';
}
na += '">';
}
}
}
switch (c) {
case 32:
na += "&nbsp;";
break;
case 38:
na += "&amp;";
break;
case 60:
na += "&lt;";
break;
case 62:
na += "&gt;";
break;
default:
if (c < 32) {
na += "&nbsp;";
} else {
na += String.fromCharCode(c);
}
break;
}
qa = pa;
}
if (qa != this.def_attr) {
na += '</span>';
}
ma = document.getElementById("tline" + y);
ma.innerHTML = na;
}
};
Term.prototype.cursor_timer_cb = function() {
this.cursor_state ^= 1;
this.refresh(this.y, this.y);
};
Term.prototype.show_cursor = function() {
if (!this.cursor_state) {
this.cursor_state = 1;
this.refresh(this.y, this.y);
}
};
Term.prototype.scroll = function() {
var y, ia, x, c, ta;
if (this.cur_h < this.tot_h) {
this.cur_h++;
}
if (++this.y_base == this.cur_h)
this.y_base = 0;
this.y_disp = this.y_base;
c = 32 | (this.def_attr << 16);
ia = new Array();
for (x = 0; x < this.w; x++)
ia[x] = c;
ta = this.y_base + this.h - 1;
if (ta >= this.cur_h)
ta -= this.cur_h;
this.lines[ta] = ia;
};
Term.prototype.scroll_disp = function(n) {
var i, ta;
if (n >= 0) {
for (i = 0; i < n; i++) {
if (this.y_disp == this.y_base)
break;
if (++this.y_disp == this.cur_h)
this.y_disp = 0;
}
} else {
n = -n;
ta = this.y_base + this.h;
if (ta >= this.cur_h)
ta -= this.cur_h;
for (i = 0; i < n; i++) {
if (this.y_disp == ta)
break;
if (--this.y_disp < 0)
this.y_disp = this.cur_h - 1;
}
}
this.refresh(0, this.h - 1);
};
Term.prototype.write = function(char) {
function va(y) {
ka = Math.min(ka, y);
la = Math.max(la, y);
}
function wa(s, x, y) {
var l, i, c, ta;
ta = s.y_base + y;
if (ta >= s.cur_h)
ta -= s.cur_h;
l = s.lines[ta];
c = 32 | (s.def_attr << 16);
for (i = x; i < s.w; i++)
l[i] = c;
va(y);
}
function xa(s, ya) {
var j, n;
if (ya.length == 0) {
s.cur_attr = s.def_attr;
} else {
for (j = 0; j < ya.length; j++) {
n = ya[j];
if (n >= 30 && n <= 37) {
s.cur_attr = (s.cur_attr & ~(7 << 3)) | ((n - 30) << 3);
} else if (n >= 40 && n <= 47) {
s.cur_attr = (s.cur_attr & ~7) | (n - 40);
} else if (n == 0) {
s.cur_attr = s.def_attr;
}
}
}
}
var za = 0;
var Aa = 1;
var Ba = 2;
var i, c, ka, la, l, n, j, ta;
ka = this.h;
la = -1;
va(this.y);
if (this.y_base != this.y_disp) {
this.y_disp = this.y_base;
ka = 0;
la = this.h - 1;
}
for (i = 0; i < char.length; i++) {
c = char.charCodeAt(i);
switch (this.state) {
case za:
switch (c) {
case 10:
if (this.convert_lf_to_crlf) {
this.x = 0;
}
this.y++;
if (this.y >= this.h) {
this.y--;
this.scroll();
ka = 0;
la = this.h - 1;
}
break;
case 13:
this.x = 0;
break;
case 8:
if (this.x > 0) {
this.x--;
}
break;
case 9:
n = (this.x + 8) & ~7;
if (n <= this.w) {
this.x = n;
}
break;
case 27:
this.state = Aa;
break;
default:
if (c >= 32) {
if (this.x >= this.w) {
this.x = 0;
this.y++;
if (this.y >= this.h) {
this.y--;
this.scroll();
ka = 0;
la = this.h - 1;
}
}
ta = this.y + this.y_base;
if (ta >= this.cur_h)
ta -= this.cur_h;
this.lines[ta][this.x] = (c & 0xffff) | (this.cur_attr << 16);
this.x++;
va(this.y);
}
break;
}
break;
case Aa:
if (c == 91) {
this.esc_params = new Array();
this.cur_param = 0;
this.state = Ba;
} else {
this.state = za;
}
break;
case Ba:
if (c >= 48 && c <= 57) {
this.cur_param = this.cur_param * 10 + c - 48;
} else {
this.esc_params[this.esc_params.length] = this.cur_param;
this.cur_param = 0;
if (c == 59)
break;
this.state = za;
switch (c) {
case 65:
n = this.esc_params[0];
if (n < 1)
n = 1;
this.y -= n;
if (this.y < 0)
this.y = 0;
break;
case 66:
n = this.esc_params[0];
if (n < 1)
n = 1;
this.y += n;
if (this.y >= this.h)
this.y = this.h - 1;
break;
case 67:
n = this.esc_params[0];
if (n < 1)
n = 1;
this.x += n;
if (this.x >= this.w - 1)
this.x = this.w - 1;
break;
case 68:
n = this.esc_params[0];
if (n < 1)
n = 1;
this.x -= n;
if (this.x < 0)
this.x = 0;
break;
case 72:
{
var Ca, ta;
ta = this.esc_params[0] - 1;
if (this.esc_params.length >= 2)
Ca = this.esc_params[1] - 1;
else
Ca = 0;
if (ta < 0)
ta = 0;
else if (ta >= this.h)
ta = this.h - 1;
if (Ca < 0)
Ca = 0;
else if (Ca >= this.w)
Ca = this.w - 1;
this.x = Ca;
this.y = ta;
}
break;
case 74:
wa(this, this.x, this.y);
for (j = this.y + 1; j < this.h; j++)
wa(this, 0, j);
break;
case 75:
wa(this, this.x, this.y);
break;
case 109:
xa(this, this.esc_params);
break;
case 110:
this.queue_chars("\x1b[" + (this.y + 1) + ";" + (this.x + 1) + "R");
break;
default:
break;
}
}
break;
}
}
va(this.y);
if (la >= ka)
this.refresh(ka, la);
};
Term.prototype.writeln = function(char) {
this.write(char + '\r\n');
};
Term.prototype.keyDownHandler = function(event) {
var char;
char = "";
switch (event.keyCode) {
case 8:
char = "";
break;
case 9:
char = "\t";
break;
case 13:
char = "\r";
break;
case 27:
char = "\x1b";
break;
case 37:
char = "\x1b[D";
break;
case 39:
char = "\x1b[C";
break;
case 38:
if (event.ctrlKey) {
this.scroll_disp(-1);
} else {
char = "\x1b[A";
}
break;
case 40:
if (event.ctrlKey) {
this.scroll_disp(1);
} else {
char = "\x1b[B";
}
break;
case 46:
char = "\x1b[3~";
break;
case 45:
char = "\x1b[2~";
break;
case 36:
char = "\x1bOH";
break;
case 35:
char = "\x1bOF";
break;
case 33:
if (event.ctrlKey) {
this.scroll_disp(-(this.h - 1));
} else {
char = "\x1b[5~";
}
break;
case 34:
if (event.ctrlKey) {
this.scroll_disp(this.h - 1);
} else {
char = "\x1b[6~";
}
break;
default:
if (event.ctrlKey) {
if (event.keyCode >= 65 && event.keyCode <= 90) {
char = String.fromCharCode(event.keyCode - 64);
} else if (event.keyCode == 32) {
char = String.fromCharCode(0);
}
} else if ((!this.is_mac && event.altKey) || (this.is_mac && event.metaKey)) {
if (event.keyCode >= 65 && event.keyCode <= 90) {
char = "\x1b" + String.fromCharCode(event.keyCode + 32);
}
}
break;
}
if (char) {
if (event.stopPropagation)
event.stopPropagation();
if (event.preventDefault)
event.preventDefault();
this.show_cursor();
this.key_rep_state = 1;
this.key_rep_str = char;
this.handler(char);
return false;
} else {
this.key_rep_state = 0;
return true;
}
};
Term.prototype.keyPressHandler = function(event) {
var char, charcode;
if (event.stopPropagation)
event.stopPropagation();
if (event.preventDefault)
event.preventDefault();
char = "";
if (!("charCode" in event)) {
charcode = event.keyCode;
if (this.key_rep_state == 1) {
this.key_rep_state = 2;
return false;
} else if (this.key_rep_state == 2) {
this.show_cursor();
this.handler(this.key_rep_str);
return false;
}
} else {
charcode = event.charCode;
}
if (charcode != 0) {
if (!event.ctrlKey && ((!this.is_mac && !event.altKey) || (this.is_mac && !event.metaKey))) {
char = String.fromCharCode(charcode);
}
}
if (char) {
this.show_cursor();
this.handler(char);
return false;
} else {
return true;
}
};
Term.prototype.queue_chars = function(char) {
this.output_queue += char;
if (this.output_queue)
setTimeout(this.outputHandler.bind(this), 0);
};
Term.prototype.outputHandler = function() {
if (this.output_queue) {
this.handler(this.output_queue);
this.output_queue = "";
}
};

BIN
vmlinux-2.6.20.bin Normal file

Binary file not shown.