From 742afcadbfa487b38f014ef3dbd4856ab1d0924f Mon Sep 17 00:00:00 2001 From: copy Date: Wed, 22 Apr 2015 04:15:32 +0200 Subject: [PATCH] Some minor changes --- src/arith.macro.js | 4 +-- src/cpu.macro.js | 75 +++++++++++++++++++++++---------------- src/floppy.js | 2 ++ src/instructions.macro.js | 5 ++- src/pic.js | 8 +++-- src/state.js | 5 --- 6 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/arith.macro.js b/src/arith.macro.js index 12635904..27022781 100644 --- a/src/arith.macro.js +++ b/src/arith.macro.js @@ -49,7 +49,7 @@ CPU.prototype.add = function(dest_operand, source_operand, op_size) this.last_op1 = dest_operand; this.last_op2 = source_operand; this.last_add_result = this.last_result = dest_operand + source_operand | 0; - + this.last_op_size = op_size; this.flags_changed = flags_all; @@ -532,7 +532,7 @@ CPU.prototype.idiv32 = function(source_operand) { div_is_neg = true; is_neg = !is_neg; - dest_operand_low = -dest_operand_low | 0; + dest_operand_low = -dest_operand_low >>> 0; dest_operand_high = ~dest_operand_high + !dest_operand_low; } diff --git a/src/cpu.macro.js b/src/cpu.macro.js index fbbfff3a..bae62eb8 100644 --- a/src/cpu.macro.js +++ b/src/cpu.macro.js @@ -1094,13 +1094,6 @@ CPU.prototype.call_interrupt_vector = function(interrupt_nr, is_software_int, er //this.debug.ops.add(1); } - //if(interrupt_nr == 0x13) - //{ - // dbg_log("INT 13"); - // dbg_log(this.memory.read8(ch) + "/" + this.memory.read8(dh) + "/" + this.memory.read8(cl) + " |" + this.memory.read8(al)); - // dbg_log("=> ", h(this.memory.read16(es) * 16 + this.memory.read16(bx))); - //} - //if(interrupt_nr == 0x10) //{ // dbg_log("int10 ax=" + h(this.reg16[reg_ax], 4) + " '" + String.fromCharCode(this.reg8[reg_al]) + "'"); @@ -1210,6 +1203,7 @@ CPU.prototype.call_interrupt_vector = function(interrupt_nr, is_software_int, er } else if(type === 5) { + dbg_trace(); throw this.debug.unimpl("call int to task gate"); } else if(type === 6) @@ -1498,21 +1492,26 @@ CPU.prototype.call_interrupt_vector = function(interrupt_nr, is_software_int, er this.switch_seg(reg_cs, new_cs); this.instruction_pointer = this.get_seg(reg_cs) + new_ip | 0; } - - this.last_instr_jump = true; }; CPU.prototype.iret16 = function() { if(!this.protected_mode || (this.vm86_mode() && this.getiopl() === 3)) { - var ip = this.pop16(); + if(this.vm86_mode()) + { + dbg_log("iret16 in vm86 mode iopl=3", LOG_CPU); + this.debug.dump_regs_short(); + } - this.switch_seg(reg_cs, this.pop16()); + var new_ip = this.pop16(); + var new_cs = this.pop16(); var new_flags = this.pop16(); - this.instruction_pointer = ip + this.get_seg(reg_cs) | 0; - this.update_eflags(new_flags); + this.switch_seg(reg_cs, new_cs); + + this.instruction_pointer = new_ip + this.get_seg(reg_cs) | 0; + this.update_eflags((this.flags & ~0xFFFF) | new_flags); this.handle_irqs(); } @@ -1536,6 +1535,11 @@ CPU.prototype.iret32 = function() var ip = this.pop32s(); + if(ip & 0xFFFF0000) + { + throw this.debug.unimpl("#GP handler"); + } + this.switch_seg(reg_cs, this.pop32s() & 0xFFFF); var new_flags = this.pop32s(); @@ -1546,7 +1550,7 @@ CPU.prototype.iret32 = function() return; } - if(this.vm86_mode()) + if(this.vm86_mode()) { // vm86 mode, iopl != 3 this.trigger_gp(0); @@ -1557,12 +1561,7 @@ CPU.prototype.iret32 = function() if(DEBUG) throw this.debug.unimpl("nt"); } - //dbg_log("pop eip from " + h(this.reg32[reg_esp], 8)); this.instruction_pointer = this.pop32s(); - - //dbg_log("IRET | from " + h(this.previous_ip >>> 0) + " to " + h(this.instruction_pointer >>> 0)); - //this.debug.dump_regs_short(); - this.sreg[reg_cs] = this.pop32s(); var new_flags = this.pop32s(); @@ -1576,12 +1575,12 @@ CPU.prototype.iret32 = function() this.update_eflags(new_flags); this.flags |= flag_vm; - dbg_log("in vm86 mode now " + + dbg_log("in vm86 mode now " + " cs:eip=" + h(this.sreg[reg_cs]) + ":" + h(this.instruction_pointer >>> 0) + " iopl=" + this.getiopl(), LOG_CPU); this.switch_seg(reg_cs, this.sreg[reg_cs]); - this.instruction_pointer = this.instruction_pointer + this.get_seg(reg_cs) | 0; + this.instruction_pointer = (this.instruction_pointer & 0xFFFF) + this.get_seg(reg_cs) | 0; var temp_esp = this.pop32s(); var temp_ss = this.pop32s(); @@ -1595,6 +1594,8 @@ CPU.prototype.iret32 = function() this.switch_seg(reg_ss, temp_ss & 0xFFFF); this.cpl = 3; + this.cpl_changed(); + this.update_cs_size(false); this.debug.dump_regs_short(); @@ -1644,19 +1645,32 @@ CPU.prototype.iret32 = function() this.update_eflags(new_flags); + if(!this.cpl) + { + this.flags = this.flags & ~flag_vif & ~flag_vip | (new_flags & (flag_vif | flag_vip)); + } + this.cpl = info.rpl; + this.cpl_changed(); + this.switch_seg(reg_ss, temp_ss & 0xFFFF); - //dbg_log("iret cpu.cpl=" + this.cpl + " to " + h(this.instruction_pointer) + + //dbg_log("iret cpu.cpl=" + this.cpl + " to " + h(this.instruction_pointer) + // " cs:eip=" + h(this.sreg[reg_cs],4) + ":" + h(this.get_real_eip(), 8) + // " ss:esp=" + h(temp_ss & 0xFFFF, 2) + ":" + h(temp_esp, 8), LOG_CPU); - - this.cpl_changed(); } else { - this.update_eflags(new_flags); // same privilege return + dbg_assert(info.rpl === this.cpl); + + this.update_eflags(new_flags); + + // update vip and vif, which are not changed by update_eflags + if(!this.cpl) + { + this.flags = this.flags & ~flag_vif & ~flag_vip | (new_flags & (flag_vif | flag_vip)); + } //dbg_log(h(new_flags) + " " + h(this.flags)); //dbg_log("iret to " + h(this.instruction_pointer)); @@ -1673,8 +1687,9 @@ CPU.prototype.iret32 = function() this.instruction_pointer = this.instruction_pointer + this.get_seg(reg_cs) | 0; - - //dbg_log("iret if=" + (this.flags & flag_interrupt) + " cpl=" + this.cpl + " eip=" + h(this.instruction_pointer >>> 0, 8), LOG_CPU); + //dbg_log("iret if=" + (this.flags & flag_interrupt) + + // " cpl=" + this.cpl + + // " eip=" + h(this.instruction_pointer >>> 0, 8), LOG_CPU); this.handle_irqs(); }; @@ -1708,7 +1723,7 @@ CPU.prototype.raise_exception = function(interrupt_nr) { // show interesting exceptions dbg_log("Exception " + h(interrupt_nr), LOG_CPU); - dbg_trace(LOG_CPU); + if(interrupt_nr !== 0xd) dbg_trace(LOG_CPU); this.debug.dump_regs_short(); } @@ -1721,7 +1736,7 @@ CPU.prototype.raise_exception_with_code = function(interrupt_nr, error_code) if(DEBUG) { dbg_log("Exception " + h(interrupt_nr) + " err=" + h(error_code), LOG_CPU); - dbg_trace(LOG_CPU); + if(interrupt_nr !== 0xd) dbg_trace(LOG_CPU); this.debug.dump_regs_short(); } @@ -1820,7 +1835,6 @@ CPU.prototype.get_seg_prefix = function(default_segment /*, offset*/) CPU.prototype.get_seg = function(segment /*, offset*/) { dbg_assert(segment >= 0 && segment < 8); - dbg_assert(this.protected_mode || (this.sreg[segment] << 4) == this.segment_offsets[segment]); if(this.protected_mode) { @@ -2324,6 +2338,7 @@ CPU.prototype.load_tr = function(selector) { dbg_log("#GP | ltr: invalid type (type = " + info.type + ")"); throw this.debug.unimpl("#GP handler"); + // or 286 TSS } diff --git a/src/floppy.js b/src/floppy.js index f89114de..e1fb8fa6 100644 --- a/src/floppy.js +++ b/src/floppy.js @@ -60,7 +60,9 @@ function FloppyController(cpu, fda_image, fdb_image) if(!fda_image) { + // Needed for CD emulation provided by seabios cpu.devices.rtc.cmos_write(CMOS_FLOPPY_DRIVE_TYPE, 4 << 4); + //this.io.register_read(0x3F4, this, function() //{ // return 0xFF; diff --git a/src/instructions.macro.js b/src/instructions.macro.js index e028d3f6..2d49c2ae 100644 --- a/src/instructions.macro.js +++ b/src/instructions.macro.js @@ -1386,7 +1386,6 @@ op(0xFB, { { cpu.flags |= flag_interrupt; - //cpu.table[cpu.read_imm8()](cpu); cpu.cycle(); cpu.handle_irqs(); @@ -1569,7 +1568,6 @@ opm(0x00, { cpu.trigger_gp(0); } - switch(modrm_byte >> 3 & 7) { case 0: @@ -2008,7 +2006,7 @@ op(0x31, { cpu.reg32s[reg_eax] = n * TSC_RATE; cpu.reg32s[reg_edx] = n * (TSC_RATE / 0x100000000); - //dbg_log("rtdsc edx:eax=" + h(cpu.reg32[reg_edx], 8) + ":" + h(cpu.reg32[reg_eax], 8), LOG_CPU); + //dbg_log("rdtsc edx:eax=" + h(cpu.reg32[reg_edx], 8) + ":" + h(cpu.reg32[reg_eax], 8), LOG_CPU); } else { @@ -2303,6 +2301,7 @@ opm(0xAE, { { case 6: // mfence + dbg_assert(modrm_byte >= 0xC0, "Unexpected mfence encoding"); break; default: dbg_log("missing " + (modrm_byte >> 3 & 7), LOG_CPU); diff --git a/src/pic.js b/src/pic.js index 5a3a952f..624b7226 100644 --- a/src/pic.js +++ b/src/pic.js @@ -56,6 +56,7 @@ function PIC(cpu, master) if(!enabled_irr) { + dbg_log("master> no unmasked irrs. irr=" + h(this.irr, 2) + " mask=" + h(this.irq_mask & 0xff, 2), LOG_PIC); return this.slave.check_irqs(); } @@ -64,6 +65,7 @@ function PIC(cpu, master) if(this.isr && (this.isr & -this.isr) <= irq) { // wait for eoi of higher or same priority interrupt + dbg_log("master> higher prio: isr=" + h(this.isr, 2) + " irq=" + h(irq, 2), LOG_PIC); return false; } @@ -84,7 +86,7 @@ function PIC(cpu, master) this.isr |= irq; } - //dbg_log("master handling irq " + irq_number, LOG_PIC); + dbg_log("master handling irq " + irq_number, LOG_PIC); //dbg_trace(LOG_PIC); // call_interrupt_vector can cause an exception in the CPU, so we @@ -104,6 +106,7 @@ function PIC(cpu, master) if(!enabled_irr) { + dbg_log("slave > no unmasked irrs. irr=" + h(this.irr, 2) + " mask=" + h(this.irq_mask & 0xff, 2), LOG_PIC); return false; } @@ -112,6 +115,7 @@ function PIC(cpu, master) if(this.isr && (this.isr & -this.isr) <= irq) { // wait for eoi of higher or same priority interrupt + dbg_log("slave > higher prio: isr=" + h(this.isr, 2) + " irq=" + h(irq, 2), LOG_PIC); return false; } @@ -122,7 +126,7 @@ function PIC(cpu, master) this.irr &= ~irq; this.isr |= irq; - //dbg_log("slave handling irq " + irq_number, LOG_PIC); + dbg_log("slave > handling irq " + irq_number, LOG_PIC); cpu.previous_ip = cpu.instruction_pointer; cpu.call_interrupt_vector(this.irq_map | irq_number, false, false); diff --git a/src/state.js b/src/state.js index c188a94c..6bb55525 100644 --- a/src/state.js +++ b/src/state.js @@ -330,11 +330,6 @@ CPU.prototype.restore_state = function(state) var buffer_block_start = STATE_INFO_BLOCK_START + info_block_len; var buffer_infos = info_block_obj.buffer_infos; - console.assert( - info_block_obj["state"]["memory"]["size"] === this.memory.size, - "Memory size must match" - ); - for(var i = 0; i < buffer_infos.length; i++) { buffer_infos[i].offset += buffer_block_start;