diff --git a/modules/pcjs/lib/debugger.js b/modules/pcjs/lib/debugger.js index 4953f9bd6..9522674ec 100644 --- a/modules/pcjs/lib/debugger.js +++ b/modules/pcjs/lib/debugger.js @@ -2052,50 +2052,57 @@ if (DEBUGGER) { n = cpu.getDS(); cch = 4; break; } - if (I386 && this.cpu.model >= X86.MODEL_80386 && !cch) { - switch(iReg) { - case Debugger.REG_EAX: - n = cpu.regEAX; cch = 8; - break; - case Debugger.REG_ECX: - n = cpu.regECX; cch = 8; - break; - case Debugger.REG_EDX: - n = cpu.regEDX; cch = 8; - break; - case Debugger.REG_EBX: - n = cpu.regEBX; cch = 8; - break; - case Debugger.REG_ESP: - n = cpu.getSP(); cch = 8; - break; - case Debugger.REG_EBP: - n = cpu.regEBP; cch = 8; - break; - case Debugger.REG_ESI: - n = cpu.regESI; cch = 8; - break; - case Debugger.REG_EDI: - n = cpu.regEDI; cch = 8; - break; - case Debugger.REG_CR0: - n = cpu.regCR0; cch = 8; - break; - case Debugger.REG_CR1: - n = cpu.regCR1; cch = 8; - break; - case Debugger.REG_CR2: - n = cpu.regCR2; cch = 8; - break; - case Debugger.REG_CR3: - n = cpu.regCR3; cch = 8; - break; - case Debugger.REG_SEG + Debugger.REG_FS: - n = cpu.getFS(); cch = 4; - break; - case Debugger.REG_SEG + Debugger.REG_GS: - n = cpu.getGS(); cch = 4; - break; + if (!cch) { + if (this.cpu.model == X86.MODEL_80286) { + if (iReg == Debugger.REG_CR0) { + n = cpu.regCR0; cch = 4; + } + } + else if (I386 && this.cpu.model >= X86.MODEL_80386) { + switch(iReg) { + case Debugger.REG_EAX: + n = cpu.regEAX; cch = 8; + break; + case Debugger.REG_ECX: + n = cpu.regECX; cch = 8; + break; + case Debugger.REG_EDX: + n = cpu.regEDX; cch = 8; + break; + case Debugger.REG_EBX: + n = cpu.regEBX; cch = 8; + break; + case Debugger.REG_ESP: + n = cpu.getSP(); cch = 8; + break; + case Debugger.REG_EBP: + n = cpu.regEBP; cch = 8; + break; + case Debugger.REG_ESI: + n = cpu.regESI; cch = 8; + break; + case Debugger.REG_EDI: + n = cpu.regEDI; cch = 8; + break; + case Debugger.REG_CR0: + n = cpu.regCR0; cch = 8; + break; + case Debugger.REG_CR1: + n = cpu.regCR1; cch = 8; + break; + case Debugger.REG_CR2: + n = cpu.regCR2; cch = 8; + break; + case Debugger.REG_CR3: + n = cpu.regCR3; cch = 8; + break; + case Debugger.REG_SEG + Debugger.REG_FS: + n = cpu.getFS(); cch = 4; + break; + case Debugger.REG_SEG + Debugger.REG_GS: + n = cpu.getGS(); cch = 4; + break; + } } } if (cch) s = str.toHex(n, cch); @@ -3476,7 +3483,9 @@ if (DEBUGGER) { Debugger.prototype.getRegString = function(iReg) { if (iReg >= Debugger.REG_AX && iReg <= Debugger.REG_DI && this.cchReg > 4) iReg += Debugger.REG_EAX - Debugger.REG_AX; - return Debugger.REGS[iReg] + '=' + this.getRegValue(iReg) + ' '; + var sReg = Debugger.REGS[iReg]; + if (iReg == Debugger.REG_CR0 && this.cpu.model == X86.MODEL_80286) sReg = "MS"; + return sReg + '=' + this.getRegValue(iReg) + ' '; }; /** @@ -4801,8 +4810,10 @@ if (DEBUGGER) { this.println("missing value for " + asArgs[1]); return; } + var fValid = false; var w = str.parseInt(sValue, 16); if (!isNaN(w)) { + fValid = true; var sRegMatch = sReg.toUpperCase(); if (sRegMatch.charAt(0) == 'E' && this.cchReg <= 4) { sRegMatch = null; @@ -4916,7 +4927,9 @@ if (DEBUGGER) { this.cpu.setMSW(w); break; case "TR": - this.cpu.segTSS.load(w, true); + if (this.cpu.segTSS.load(w, true) === X86.ADDR_INVALID) { + fValid = false; + } break; /* * TODO: Add support for GDTR (addr and limit), IDTR (addr and limit), and perhaps @@ -4957,8 +4970,17 @@ if (DEBUGGER) { case "GS": this.cpu.setGS(w); break; + case "CR0": + this.cpu.regCR0 = w; + break; + case "CR2": + this.cpu.regCR2 = w; + break; + case "CR3": + this.cpu.regCR3 = w; + break; /* - * TODO: Add support for CR0-CR3, DR0-DR7, and TR6-TR7. + * TODO: Add support for DR0-DR7 and TR6-TR7. */ default: fUnknown = true; @@ -4974,7 +4996,7 @@ if (DEBUGGER) { } } } - else { + if (!fValid) { this.println("invalid value: " + sValue); return; } diff --git a/tests/pc/80386/tests.nasm b/tests/pc/80386/tests.nasm index 89ed59d27..58e749343 100644 --- a/tests/pc/80386/tests.nasm +++ b/tests/pc/80386/tests.nasm @@ -339,7 +339,7 @@ toProt32: ; ; Test moving a segment register to a 32-bit memory location ; -test1: mov edx,[0x0000] ; save the DWORD at 0x0000:0x0000 in EDX + mov edx,[0x0000] ; save the DWORD at 0x0000:0x0000 in EDX or eax,-1 mov [0x0000],eax mov [0x0000],ds @@ -351,29 +351,37 @@ test1: mov edx,[0x0000] ; save the DWORD at 0x0000:0x0000 in EDX cmp eax,[0x0000] jne near error mov [0x0000],edx ; restore the DWORD at 0x0000:0x0000 from EDX - jmp test2 + jmp testROM + + ; + ; The next few tests currently work only when running as a ROM image; they rely not only on + ; the contents of the last two bytes at the top of the first 1Mb, but also on their location, + ; because if the processor improperly reads beyond those bytes, a fault should occur. + ; +testROM: + ; ; Test moving a byte to a 32-bit register with sign-extension ; -test2: movsx eax,byte [0xfffff] + movsx eax,byte [0xfffff] cmp eax,0xffffff80 jne error ; ; Test moving a word to a 32-bit register with sign-extension ; -test3: movsx eax,word [0xffffe] + movsx eax,word [0xffffe] cmp eax,0xffff80fc jne error ; ; Test moving a byte to a 32-bit register with zero-extension ; -test4: movzx eax,byte [0xfffff] + movzx eax,byte [0xfffff] cmp eax,0x00000080 jne error ; ; Test moving a word to a 32-bit register with zero-extension ; -test5: movzx eax,word [0xffffe] + movzx eax,word [0xffffe] cmp eax,0x000080fc jne error jmp doneProt @@ -401,11 +409,11 @@ jmpReal: jmp CSEG_REAL:toReal toReal: - mov ax,cs + mov ax,cs ; revert to the usual .COM register conventions mov ds,ax mov es,ax mov ss,ax - sub sp,sp + mov sp,0xfffe cmp ax,CSEG_REAL ; is CS equal to 0xf000? je near jmpStart ; yes, so loop around, only because we have nowhere else to go