Fixed the Debugger opcode history buffer (was broken by DbgAddr changes)

This commit is contained in:
Jeff Parsons 2015-05-09 07:52:03 -07:00 committed by jeffpar
commit ac862f3b1d
3 changed files with 78 additions and 70 deletions

View file

@ -51,29 +51,23 @@ if (DEBUGGER) {
} }
/** /**
* DbgAddr object definition * Debugger Address Object
* *
* off: offset, if any * NOTE: I originally tried to define DbgAddr as a record typedef, which allowed me to reference the
* sel: selector, if any * type as {DbgAddr} instead of {{DbgAddr}}, but my IDE (WebStorm) did not recognize all instances of {DbgAddr}.
* addr: linear address, if any * Using this @class definition is a bit cleaner, and it makes both WebStorm and the Closure Compiler happier,
* fData32: true if 32-bit operand size in effect * at the expense of making all references {{DbgAddr}}. Defining a typedef based on this class doesn't help.
* fAddr32: true if 32-bit address size in effect
* fOverride: true if any overrides were processed with this address
* fComplete: true if a complete instruction was processed with this address
* fTempBreak: true if temporary breakpoint address
* *
* @typedef {{ * @class DbgAddr
* off: (number|null|undefined), * @property {number|null|undefined} off (offset, if any)
* sel: (number|null|undefined), * @property {number|null|undefined} sel (selector, if any)
* addr: (number|null|undefined), * @property {number|null|undefined} addr (linear address, if any)
* fData32: (boolean|undefined), * @property {boolean|undefined} fData32 (true if 32-bit operand size in effect)
* fAddr32: (boolean|undefined), * @property {boolean|undefined} fAddr32 (true if 32-bit address size in effect)
* fOverride: (boolean|undefined), * @property {boolean|undefined} fOverride (true if any overrides were processed with this address)
* fComplete: (boolean|undefined), * @property {boolean|undefined} fComplete (true if a complete instruction was processed with this address)
* fTempBreak: (boolean|undefined) * @property {boolean|undefined} fTempBreak (true if this is a temporary breakpoint address)
* }}
*/ */
var DbgAddr;
/** /**
* Debugger(parmsDbg) * Debugger(parmsDbg)
@ -1418,7 +1412,7 @@ if (DEBUGGER) {
* getAddr(dbgAddr, fWrite, cb) * getAddr(dbgAddr, fWrite, cb)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {boolean} [fWrite] * @param {boolean} [fWrite]
* @param {number} [cb] is number of bytes to check (1, 2 or 4); default is 1 * @param {number} [cb] is number of bytes to check (1, 2 or 4); default is 1
* @return {number} is the corresponding linear address, or X86.ADDR_INVALID * @return {number} is the corresponding linear address, or X86.ADDR_INVALID
@ -1450,7 +1444,7 @@ if (DEBUGGER) {
* We must route all our memory requests through the CPU now, in case paging is enabled. * We must route all our memory requests through the CPU now, in case paging is enabled.
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {number} [inc] * @param {number} [inc]
* @return {number} * @return {number}
*/ */
@ -1471,7 +1465,7 @@ if (DEBUGGER) {
* getWord(dbgAddr, fAdvance) * getWord(dbgAddr, fAdvance)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {boolean} [fAdvance] * @param {boolean} [fAdvance]
* @return {number} * @return {number}
*/ */
@ -1487,7 +1481,7 @@ if (DEBUGGER) {
* getShort(dbgAddr, inc) * getShort(dbgAddr, inc)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {number} [inc] * @param {number} [inc]
* @return {number} * @return {number}
*/ */
@ -1508,7 +1502,7 @@ if (DEBUGGER) {
* getLong(dbgAddr, inc) * getLong(dbgAddr, inc)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {number} [inc] * @param {number} [inc]
* @return {number} * @return {number}
*/ */
@ -1529,7 +1523,7 @@ if (DEBUGGER) {
* setByte(dbgAddr, b, inc) * setByte(dbgAddr, b, inc)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {number} b * @param {number} b
* @param {number} [inc] * @param {number} [inc]
*/ */
@ -1549,7 +1543,7 @@ if (DEBUGGER) {
* setShort(dbgAddr, w, inc) * setShort(dbgAddr, w, inc)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {number} w * @param {number} w
* @param {number} [inc] * @param {number} [inc]
*/ */
@ -1569,25 +1563,25 @@ if (DEBUGGER) {
* newAddr(off, sel, addr, fData32, fAddr32) * newAddr(off, sel, addr, fData32, fAddr32)
* *
* @this {Debugger} * @this {Debugger}
* @param {number|null|undefined} [off] * @param {number|null|undefined} [off] (default is zero)
* @param {number|null|undefined} [sel] * @param {number|null|undefined} [sel] (default is null)
* @param {number|null|undefined} [addr] * @param {number|null|undefined} [addr] (default is zero)
* @param {boolean} [fData32] * @param {boolean} [fData32] (default is false)
* @param {boolean} [fAddr32] * @param {boolean} [fAddr32] (default is false)
* @return {DbgAddr} * @return {{DbgAddr}}
*/ */
Debugger.prototype.newAddr = function(off, sel, addr, fData32, fAddr32) Debugger.prototype.newAddr = function(off, sel, addr, fData32, fAddr32)
{ {
if (fData32 === undefined) fData32 = (this.cpu && this.cpu.segCS.dataSize == 4); if (fData32 === undefined) fData32 = (this.cpu && this.cpu.segCS.dataSize == 4);
if (fAddr32 === undefined) fAddr32 = (this.cpu && this.cpu.segCS.addrSize == 4); if (fAddr32 === undefined) fAddr32 = (this.cpu && this.cpu.segCS.addrSize == 4);
return {off: off, sel: sel, addr: addr, fTempBreak: false, fData32: fData32 || false, fAddr32: fAddr32 || false}; return {off: off || 0, sel: sel || null, addr: addr || 0, fTempBreak: false, fData32: fData32 || false, fAddr32: fAddr32 || false};
}; };
/** /**
* packAddr(dbgAddr) * packAddr(dbgAddr)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @return {Array} * @return {Array}
*/ */
Debugger.prototype.packAddr = function(dbgAddr) Debugger.prototype.packAddr = function(dbgAddr)
@ -1600,7 +1594,7 @@ if (DEBUGGER) {
* *
* @this {Debugger} * @this {Debugger}
* @param {Array} aAddr * @param {Array} aAddr
* @return {DbgAddr} * @return {{DbgAddr}}
*/ */
Debugger.prototype.unpackAddr = function(aAddr) Debugger.prototype.unpackAddr = function(aAddr)
{ {
@ -1611,7 +1605,7 @@ if (DEBUGGER) {
* checkLimit(dbgAddr) * checkLimit(dbgAddr)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
*/ */
Debugger.prototype.checkLimit = function(dbgAddr) Debugger.prototype.checkLimit = function(dbgAddr)
{ {
@ -1628,7 +1622,7 @@ if (DEBUGGER) {
* incAddr(dbgAddr, inc) * incAddr(dbgAddr, inc)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {number|undefined} inc contains value to increment dbgAddr by (default is 1) * @param {number|undefined} inc contains value to increment dbgAddr by (default is 1)
*/ */
Debugger.prototype.incAddr = function(dbgAddr, inc) Debugger.prototype.incAddr = function(dbgAddr, inc)
@ -1664,7 +1658,7 @@ if (DEBUGGER) {
* hexAddr(dbgAddr) * hexAddr(dbgAddr)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @return {string} the hex representation of the address * @return {string} the hex representation of the address
*/ */
Debugger.prototype.hexAddr = function(dbgAddr) Debugger.prototype.hexAddr = function(dbgAddr)
@ -1678,7 +1672,7 @@ if (DEBUGGER) {
* Dump helper for zero-terminated strings. * Dump helper for zero-terminated strings.
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {number} [cchMax] * @param {number} [cchMax]
* @return {string} (and dbgAddr advanced past the terminating zero) * @return {string} (and dbgAddr advanced past the terminating zero)
*/ */
@ -2311,7 +2305,7 @@ if (DEBUGGER) {
* Preallocate dummy Addr (Array) objects in every history slot, so that * Preallocate dummy Addr (Array) objects in every history slot, so that
* checkInstruction() doesn't need to call newAddr() on every slot update. * checkInstruction() doesn't need to call newAddr() on every slot update.
*/ */
this.aOpcodeHistory[i] = [0, null, 0]; this.aOpcodeHistory[i] = this.newAddr();
} }
this.iOpcodeHistory = 0; this.iOpcodeHistory = 0;
} }
@ -2690,10 +2684,10 @@ if (DEBUGGER) {
var bOpcode = this.cpu.probeAddr(addr); var bOpcode = this.cpu.probeAddr(addr);
if (bOpcode != null) { if (bOpcode != null) {
this.aaOpcodeCounts[bOpcode][1]++; this.aaOpcodeCounts[bOpcode][1]++;
var a = this.aOpcodeHistory[this.iOpcodeHistory]; var dbgAddr = this.aOpcodeHistory[this.iOpcodeHistory];
a[0] = this.cpu.getIP(); dbgAddr.off = this.cpu.getIP();
a[1] = this.cpu.getCS(); dbgAddr.sel = this.cpu.getCS();
a[2] = addr; dbgAddr.addr = addr;
if (++this.iOpcodeHistory == this.aOpcodeHistory.length) this.iOpcodeHistory = 0; if (++this.iOpcodeHistory == this.aOpcodeHistory.length) this.iOpcodeHistory = 0;
} }
} }
@ -2807,7 +2801,7 @@ if (DEBUGGER) {
* *
* @this {Debugger} * @this {Debugger}
* @param {Array} aBreak * @param {Array} aBreak
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {boolean} [fTempBreak] * @param {boolean} [fTempBreak]
* @return {boolean} true if breakpoint added, false if already exists * @return {boolean} true if breakpoint added, false if already exists
*/ */
@ -2841,7 +2835,7 @@ if (DEBUGGER) {
* *
* @this {Debugger} * @this {Debugger}
* @param {Array} aBreak * @param {Array} aBreak
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {boolean} [fRemove] * @param {boolean} [fRemove]
* @return {boolean} true if found, false if not * @return {boolean} true if found, false if not
*/ */
@ -2921,7 +2915,7 @@ if (DEBUGGER) {
* setTempBreakpoint(dbgAddr) * setTempBreakpoint(dbgAddr)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr of new temp breakpoint * @param {{DbgAddr}} dbgAddr of new temp breakpoint
*/ */
Debugger.prototype.setTempBreakpoint = function(dbgAddr) Debugger.prototype.setTempBreakpoint = function(dbgAddr)
{ {
@ -3030,7 +3024,7 @@ if (DEBUGGER) {
* getInstruction(dbgAddr, sComment, nSequence) * getInstruction(dbgAddr, sComment, nSequence)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {string} [sComment] is an associated comment * @param {string} [sComment] is an associated comment
* @param {number} [nSequence] is an associated sequence number, undefined if none * @param {number} [nSequence] is an associated sequence number, undefined if none
* @return {string} (and dbgAddr is updated to the next instruction) * @return {string} (and dbgAddr is updated to the next instruction)
@ -3191,7 +3185,7 @@ if (DEBUGGER) {
* *
* @this {Debugger} * @this {Debugger}
* @param {number} type * @param {number} type
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @return {string} operand * @return {string} operand
*/ */
Debugger.prototype.getImmOperand = function(type, dbgAddr) Debugger.prototype.getImmOperand = function(type, dbgAddr)
@ -3238,7 +3232,7 @@ if (DEBUGGER) {
* @this {Debugger} * @this {Debugger}
* @param {number} bReg * @param {number} bReg
* @param {number} type * @param {number} type
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @return {string} operand * @return {string} operand
*/ */
Debugger.prototype.getRegOperand = function(bReg, type, dbgAddr) Debugger.prototype.getRegOperand = function(bReg, type, dbgAddr)
@ -3271,7 +3265,7 @@ if (DEBUGGER) {
* *
* @this {Debugger} * @this {Debugger}
* @param {number} bMod * @param {number} bMod
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @return {string} operand * @return {string} operand
*/ */
Debugger.prototype.getSIBOperand = function(bMod, dbgAddr) Debugger.prototype.getSIBOperand = function(bMod, dbgAddr)
@ -3298,7 +3292,7 @@ if (DEBUGGER) {
* @this {Debugger} * @this {Debugger}
* @param {number} bModRM * @param {number} bModRM
* @param {number} type * @param {number} type
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @return {string} operand * @return {string} operand
*/ */
Debugger.prototype.getModRMOperand = function(bModRM, type, dbgAddr) Debugger.prototype.getModRMOperand = function(bModRM, type, dbgAddr)
@ -3391,7 +3385,7 @@ if (DEBUGGER) {
* @this {Debugger} * @this {Debugger}
* @param {string} sOp * @param {string} sOp
* @param {string|undefined} sOperand * @param {string|undefined} sOperand
* @param {DbgAddr} dbgAddr of memory where this instruction is being assembled * @param {{DbgAddr}} dbgAddr of memory where this instruction is being assembled
* @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty * @return {Array.<number>} of opcode bytes; if the instruction can't be parsed, the array will be empty
*/ */
Debugger.prototype.parseInstruction = function(sOp, sOperand, dbgAddr) Debugger.prototype.parseInstruction = function(sOp, sOperand, dbgAddr)
@ -3606,7 +3600,7 @@ if (DEBUGGER) {
* @this {Debugger} * @this {Debugger}
* @param {string|undefined} sAddr * @param {string|undefined} sAddr
* @param {number|undefined} type is the address segment type, in case sAddr doesn't specify a segment * @param {number|undefined} type is the address segment type, in case sAddr doesn't specify a segment
* @return {DbgAddr} * @return {{DbgAddr}}
*/ */
Debugger.prototype.parseAddr = function(sAddr, type) Debugger.prototype.parseAddr = function(sAddr, type)
{ {
@ -3821,7 +3815,7 @@ if (DEBUGGER) {
* *
* @this {Debugger} * @this {Debugger}
* @param {string} sSymbol * @param {string} sSymbol
* @return {DbgAddr|null} a valid dbgAddr if a valid symbol, an empty dbgAddr if an unknown symbol, or null if not a symbol * @return {{DbgAddr}|null} a valid dbgAddr if a valid symbol, an empty dbgAddr if an unknown symbol, or null if not a symbol
*/ */
Debugger.prototype.findSymbolAddr = function(sSymbol) Debugger.prototype.findSymbolAddr = function(sSymbol)
{ {
@ -3869,7 +3863,7 @@ if (DEBUGGER) {
* entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol. * entries: [0]-[3] will refer to closest preceding symbol, and [4]-[7] will refer to the closest subsequent symbol.
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {boolean} [fNearest] * @param {boolean} [fNearest]
* @return {Array|null} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment * @return {Array|null} where [0] == symbol name, [1] == symbol value, [2] == any annotation, and [3] == any associated comment
*/ */
@ -5137,7 +5131,7 @@ if (DEBUGGER) {
* initAddrSize(dbgAddr, fNonPrefix) * initAddrSize(dbgAddr, fNonPrefix)
* *
* @this {Debugger} * @this {Debugger}
* @param {DbgAddr} dbgAddr * @param {{DbgAddr}} dbgAddr
* @param {boolean} fNonPrefix * @param {boolean} fNonPrefix
*/ */
Debugger.prototype.initAddrSize = function(dbgAddr, fNonPrefix) Debugger.prototype.initAddrSize = function(dbgAddr, fNonPrefix)

View file

@ -38,6 +38,19 @@ if (typeof module !== 'undefined') {
var X86 = require("./x86"); var X86 = require("./x86");
} }
/**
* @class X86Seg
* @property {number} sel
* @property {number} limit (in protected-mode, this comes from descriptor word 0x0)
* @property {number} base (in protected-mode, this comes from descriptor word 0x2)
* @property {number} acc (in protected-mode, this comes from descriptor word 0x4, masked with 0xff00; bits 0-7 supplement base bits 16-23)
* @property {number} ext (in protected-mode, this is descriptor word 0x6, 80386 only; supplements limit bits 16-19 and base bits 24-31)
*
* TODO: Determine what good, if any, these class annotations are for either an IDE like WebStorm or a tool like
* the Closure Compiler. More importantly, what good do they do at runtime? Is it better to simply ensure that all
* object properties are explicitly initialized in the constructor, and document them there instead?
*/
/** /**
* X86Seg(cpu, sName) * X86Seg(cpu, sName)
* *
@ -54,10 +67,10 @@ function X86Seg(cpu, id, sName, fProt)
this.id = id; this.id = id;
this.sName = sName || ""; this.sName = sName || "";
this.sel = 0; this.sel = 0;
this.limit = 0xffff; // in protected-mode, this is descriptor word 0x0 this.limit = 0xffff;
this.base = 0; // in protected-mode, this is descriptor word 0x2 this.base = 0;
this.acc = this.type = 0; // in protected-mode, this is descriptor word 0x4, masked with 0xff00 (bits 0-7 supplement base bits 16-23) this.acc = this.type = 0;
this.ext = 0; // in protected-mode, this is descriptor word 0x6 (80386 only; supplements limit bits 16-19 and base bits 24-31) this.ext = 0;
this.cpl = this.dpl = 0; this.cpl = this.dpl = 0;
this.addrDesc = X86.ADDR_INVALID; this.addrDesc = X86.ADDR_INVALID;
this.dataSize = this.addrSize = 2; this.dataSize = this.addrSize = 2;
@ -108,7 +121,7 @@ X86Seg.ID = {
* @this {X86Seg} * @this {X86Seg}
* @param {number} sel * @param {number} sel
* @param {boolean} [fSuppress] is true to suppress any errors * @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} base address of selected segment, or ADDR_INVALID if error (TODO: No error conditions exist yet) * @return {number} base address of selected segment, or ADDR_INVALID if error (TODO: No error conditions yet)
*/ */
X86Seg.prototype.loadReal = function loadReal(sel, fSuppress) X86Seg.prototype.loadReal = function loadReal(sel, fSuppress)
{ {
@ -122,7 +135,7 @@ X86Seg.prototype.loadReal = function loadReal(sel, fSuppress)
* this.dataSize = this.addrSize = 2; * this.dataSize = this.addrSize = 2;
* this.dataMask = this.addrMask = 0xffff; * this.dataMask = this.addrMask = 0xffff;
* *
* Only the selector and base portions of a segment register can be changed in real-mode. * In short, only the selector and base portions of a segment register can be changed in real-mode.
*/ */
return this.base = this.sel << 4; return this.base = this.sel << 4;
}; };
@ -209,7 +222,7 @@ X86Seg.prototype.loadProt = function loadProt(sel, fSuppress)
* *
* @this {X86Seg} * @this {X86Seg}
* @param {number} nIDT * @param {number} nIDT
* @return {number} address from selected vector, or ADDR_INVALID if error (TODO: No error conditions exist yet) * @return {number} address from selected vector, or ADDR_INVALID if error (TODO: No error conditions yet)
*/ */
X86Seg.prototype.loadIDTReal = function loadIDTReal(nIDT) X86Seg.prototype.loadIDTReal = function loadIDTReal(nIDT)
{ {
@ -238,7 +251,7 @@ X86Seg.prototype.loadIDTReal = function loadIDTReal(nIDT)
* *
* @this {X86Seg} * @this {X86Seg}
* @param {number} nIDT * @param {number} nIDT
* @return {number} address from selected vector, or ADDR_INVALID if error (TODO: No error conditions exist yet) * @return {number} address from selected vector, or ADDR_INVALID if error (TODO: No error conditions yet)
*/ */
X86Seg.prototype.loadIDTProt = function loadIDTProt(nIDT) X86Seg.prototype.loadIDTProt = function loadIDTProt(nIDT)
{ {
@ -264,7 +277,7 @@ X86Seg.prototype.loadIDTProt = function loadIDTProt(nIDT)
* @param {number} off is a segment-relative offset * @param {number} off is a segment-relative offset
* @param {number} cb is number of bytes to check (1, 2 or 4) * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors * @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, or ADDR_INVALID if error (TODO: No error conditions exist yet) * @return {number} corresponding physical address if valid, or ADDR_INVALID if error (TODO: No error conditions yet)
*/ */
X86Seg.prototype.checkReadReal = function checkReadReal(off, cb, fSuppress) X86Seg.prototype.checkReadReal = function checkReadReal(off, cb, fSuppress)
{ {
@ -281,7 +294,7 @@ X86Seg.prototype.checkReadReal = function checkReadReal(off, cb, fSuppress)
* @param {number} off is a segment-relative offset * @param {number} off is a segment-relative offset
* @param {number} cb is number of bytes to check (1, 2 or 4) * @param {number} cb is number of bytes to check (1, 2 or 4)
* @param {boolean} [fSuppress] is true to suppress any errors * @param {boolean} [fSuppress] is true to suppress any errors
* @return {number} corresponding physical address if valid, or ADDR_INVALID if error (TODO: No error conditions exist yet) * @return {number} corresponding physical address if valid, or ADDR_INVALID if error (TODO: No error conditions yet)
*/ */
X86Seg.prototype.checkWriteReal = function checkWriteReal(off, cb, fSuppress) X86Seg.prototype.checkWriteReal = function checkWriteReal(off, cb, fSuppress)
{ {

View file

@ -52,8 +52,8 @@ PAGING equ 0
; 0x0d10-0x0d13 RAM_RETF (Real-mode return address) ; 0x0d10-0x0d13 RAM_RETF (Real-mode return address)
; 0x0d14-0x0fff reserved ; 0x0d14-0x0fff reserved
; ;
; And in the second page (0x1000-0x1fff), we might build a page directory, followed by a single page table that ; And in the second page (0x1000-0x1fff), we might build a page directory, followed by a single page table
; allows us to map up to 4Mb (although we'd likely only create PTEs for the first 1Mb). ; that allows us to map up to 4Mb (although we'd likely only create PTEs for the first 1Mb).
; ;
;RAM_GDT equ 0x0c00 ;RAM_GDT equ 0x0c00
;RAM_IDTR equ 0x0d00 ;RAM_IDTR equ 0x0d00
@ -243,6 +243,7 @@ initPages:
; Build a page directory at EDI with only 1 valid PDE (the first one) ; Build a page directory at EDI with only 1 valid PDE (the first one)
; ;
cld cld
cli ; make sure interrupts are still off (in case any DOS calls turned them back on)
mov eax,edi mov eax,edi
add eax,0x1000 ; EAX == page frame address (of the next page) add eax,0x1000 ; EAX == page frame address (of the next page)
or eax,PTE_USER | PTE_READWRITE | PTE_PRESENT or eax,PTE_USER | PTE_READWRITE | PTE_PRESENT