From badaaa307e84c5af1a9ba5039f051b5bfec822cc Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Tue, 2 Jun 2015 15:39:13 -0700 Subject: [PATCH] Fix pushing/popping at the limits of the stack segment --- blog/2015/06/01/README.md | 2 +- modules/pcjs/lib/x86cpu.js | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/blog/2015/06/01/README.md b/blog/2015/06/01/README.md index f3b5c5d27..8c9d5dabf 100644 --- a/blog/2015/06/01/README.md +++ b/blog/2015/06/01/README.md @@ -39,7 +39,7 @@ The Video component installs I/O port handlers for all possible I/O ranges; when associated I/O operations are redirected to a dummy Card, so that the active Card isn't affected. Here, however, that was insufficient. If the VGA is the only installed video card, the VGA ROM expects *NO RESPONSE* on inactive CRTC ports. So I've changed the CRTC I/O handlers to check the Card's fActive flag. This seems -like a safe and logical change, but we'll still have to check for backward-compatibility issues with older ROMs. +like a safe and logical change, but I still have to check for backward-compatibility issues with older ROMs. The VGA ROM programs the card for the first time here: diff --git a/modules/pcjs/lib/x86cpu.js b/modules/pcjs/lib/x86cpu.js index aaffccf36..9f2afb69f 100644 --- a/modules/pcjs/lib/x86cpu.js +++ b/modules/pcjs/lib/x86cpu.js @@ -3542,8 +3542,8 @@ X86CPU.prototype.popWord = function() * There's no such thing as an SS fault on the 8086/8088, and I'm assuming that, on newer * processors, when the stack segment limit is set to the maximum, it's OK for the stack to wrap. */ - if (this.model <= X86.MODEL_8088 || this.segSS.limit == this.segSS.addrMask) { - this.setSP(this.regLSP - this.segSS.base); + if (this.model <= X86.MODEL_8088 || !this.segSS.fExpDown && this.segSS.limit == this.segSS.addrMask || this.segSS.fExpDown && !this.segSS.limit) { + this.setSP((this.regLSP - this.segSS.base) & this.segSS.addrMask); } else if (off < -1) { // fudge factor X86.fnFault.call(this, X86.EXCEPTION.SS_FAULT, 0); } @@ -3570,11 +3570,10 @@ X86CPU.prototype.pushWord = function(w) if (((this.regLSP - this.regLSPLimitLow)|0) < 0 && (this.regLSPLimitLow ^ this.regLSP) >= 0) { /* * There's no such thing as an SS fault on the 8086/8088, and I'm assuming that, on newer - * processors, when the stack segment is expand-down and the limit is set to the "maximum" of - * zero, it's OK for the stack to wrap. + * processors, when the stack segment limit is set to the maximum, it's OK for the stack to wrap. */ - if (this.model <= X86.MODEL_8088 || this.segSS.fExpDown && !this.segSS.limit) { - this.setSP(this.regLSP - this.segSS.base); + if (this.model <= X86.MODEL_8088 || !this.segSS.fExpDown && this.segSS.limit == this.segSS.addrMask || this.segSS.fExpDown && !this.segSS.limit) { + this.setSP((this.regLSP - this.segSS.base) & this.segSS.addrMask); } else { X86.fnFault.call(this, X86.EXCEPTION.SS_FAULT, 0); }