public gh-pages site
This commit is contained in:
commit
2046fbcb32
66
CMOS.js
Normal file
66
CMOS.js
Normal 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
27
KBD.js
Normal 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
4
LICENSE
Normal 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
207
PCEmulator.js
Normal 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
315
PIC.js
Normal 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
225
PIT.js
Normal 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
146
Serial.js
Normal 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
72
clipboard.js
Normal 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
9719
cpux86-ta.js
Normal file
File diff suppressed because it is too large
Load Diff
10498
cpux86-ta.original.js
Normal file
10498
cpux86-ta.original.js
Normal file
File diff suppressed because it is too large
Load Diff
94
index.html
94
index.html
@ -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 you’re using GitHub Desktop, simply sync your repository and you’ll 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>We’ve 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><a></code> element will link to the contributor’s 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 we’ll 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">© 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
164
jslinux.js
Normal 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
BIN
linuxstart-20110820.tar.gz
Normal file
Binary file not shown.
BIN
linuxstart.bin
Normal file
BIN
linuxstart.bin
Normal file
Binary file not shown.
99
readme.md
Normal file
99
readme.md
Normal 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/
|
706
refactoring_hacks/Opcodes.txt
Normal file
706
refactoring_hacks/Opcodes.txt
Normal 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);
|
||||
}
|
||||
}
|
122
refactoring_hacks/autocomments.py
Normal file
122
refactoring_hacks/autocomments.py
Normal 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()
|
15
refactoring_hacks/js-change-symbol.el
Normal file
15
refactoring_hacks/js-change-symbol.el
Normal 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)
|
||||
)
|
||||
)
|
1
refactoring_hacks/onebyte_dict.json
Normal file
1
refactoring_hacks/onebyte_dict.json
Normal file
File diff suppressed because one or more lines are too long
51
refactoring_hacks/reify.js
Normal file
51
refactoring_hacks/reify.js
Normal 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);
|
1
refactoring_hacks/twobyte_dict.json
Normal file
1
refactoring_hacks/twobyte_dict.json
Normal file
File diff suppressed because one or more lines are too long
15197
refactoring_hacks/x86reference.xml
Normal file
15197
refactoring_hacks/x86reference.xml
Normal file
File diff suppressed because it is too large
Load Diff
528
term.js
Normal file
528
term.js
Normal 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 += " ";
|
||||
break;
|
||||
case 38:
|
||||
na += "&";
|
||||
break;
|
||||
case 60:
|
||||
na += "<";
|
||||
break;
|
||||
case 62:
|
||||
na += ">";
|
||||
break;
|
||||
default:
|
||||
if (c < 32) {
|
||||
na += " ";
|
||||
} 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
BIN
vmlinux-2.6.20.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user