Started work on instruction testing
This commit is contained in:
parent
df1ab0dca1
commit
0cc582405d
3 changed files with 236 additions and 137 deletions
|
|
@ -297,7 +297,7 @@ function doCommand(sCmd)
|
||||||
default:
|
default:
|
||||||
if (sCmd) {
|
if (sCmd) {
|
||||||
try {
|
try {
|
||||||
if (dbg && !dbg.doCommand(sCmd, true)) {
|
if (dbg && !dbg.doCommands(sCmd, true)) {
|
||||||
sCmd = '(' + sCmd + ')';
|
sCmd = '(' + sCmd + ')';
|
||||||
result = eval(sCmd); // jshint ignore:line
|
result = eval(sCmd); // jshint ignore:line
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -233,18 +233,15 @@ function Debugger(parmsDbg)
|
||||||
* $('dw 0:0')
|
* $('dw 0:0')
|
||||||
* $('h')
|
* $('h')
|
||||||
* ...
|
* ...
|
||||||
*
|
|
||||||
* WARNING: doCommand() expects the same conditions that parseCommand() imposes; ie, a trim and
|
|
||||||
* lower-case command string.
|
|
||||||
*/
|
*/
|
||||||
var dbg = this;
|
var dbg = this;
|
||||||
if (window) {
|
if (window) {
|
||||||
if (window['$'] === undefined) {
|
if (window['$'] === undefined) {
|
||||||
window['$'] = function(s) { return dbg.doCommand(s); };
|
window['$'] = function(s) { return dbg.doCommands(s); };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (global['$'] === undefined) {
|
if (global['$'] === undefined) {
|
||||||
global['$'] = function(s) { return dbg.doCommand(s); };
|
global['$'] = function(s) { return dbg.doCommands(s); };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1866,37 +1863,36 @@ if (DEBUGGER) {
|
||||||
* control.focus();
|
* control.focus();
|
||||||
*/
|
*/
|
||||||
control.onkeydown = function onKeyDownDebugInput(event) {
|
control.onkeydown = function onKeyDownDebugInput(event) {
|
||||||
var sInput;
|
var sCmds;
|
||||||
if (event.keyCode == Keyboard.KEYCODE.CR) {
|
if (event.keyCode == Keyboard.KEYCODE.CR) {
|
||||||
sInput = control.value;
|
sCmds = control.value;
|
||||||
control.value = "";
|
control.value = "";
|
||||||
var a = dbg.parseCommand(sInput, true);
|
dbg.doCommands(sCmds, true);
|
||||||
for (var s in a) dbg.doCommand(a[s]);
|
|
||||||
}
|
}
|
||||||
else if (event.keyCode == Keyboard.KEYCODE.ESC) {
|
else if (event.keyCode == Keyboard.KEYCODE.ESC) {
|
||||||
control.value = sInput = "";
|
control.value = sCmds = "";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (event.keyCode == Keyboard.KEYCODE.UP) {
|
if (event.keyCode == Keyboard.KEYCODE.UP) {
|
||||||
if (dbg.iPrevCmd < dbg.aPrevCmds.length - 1) {
|
if (dbg.iPrevCmd < dbg.aPrevCmds.length - 1) {
|
||||||
sInput = dbg.aPrevCmds[++dbg.iPrevCmd];
|
sCmds = dbg.aPrevCmds[++dbg.iPrevCmd];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event.keyCode == Keyboard.KEYCODE.DOWN) {
|
else if (event.keyCode == Keyboard.KEYCODE.DOWN) {
|
||||||
if (dbg.iPrevCmd > 0) {
|
if (dbg.iPrevCmd > 0) {
|
||||||
sInput = dbg.aPrevCmds[--dbg.iPrevCmd];
|
sCmds = dbg.aPrevCmds[--dbg.iPrevCmd];
|
||||||
} else {
|
} else {
|
||||||
sInput = "";
|
sCmds = "";
|
||||||
dbg.iPrevCmd = -1;
|
dbg.iPrevCmd = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sInput != null) {
|
if (sCmds != null) {
|
||||||
var cch = sInput.length;
|
var cch = sCmds.length;
|
||||||
control.value = sInput;
|
control.value = sCmds;
|
||||||
control.setSelectionRange(cch, cch);
|
control.setSelectionRange(cch, cch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sInput != null && event.preventDefault) event.preventDefault();
|
if (sCmds != null && event.preventDefault) event.preventDefault();
|
||||||
};
|
};
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -1907,10 +1903,9 @@ if (DEBUGGER) {
|
||||||
500, 100,
|
500, 100,
|
||||||
function onClickDebugEnter(fRepeat) {
|
function onClickDebugEnter(fRepeat) {
|
||||||
if (dbg.controlDebug) {
|
if (dbg.controlDebug) {
|
||||||
var sInput = dbg.controlDebug.value;
|
var sCmds = dbg.controlDebug.value;
|
||||||
dbg.controlDebug.value = "";
|
dbg.controlDebug.value = "";
|
||||||
var a = dbg.parseCommand(sInput, true);
|
dbg.doCommands(sCmds, true);
|
||||||
for (var s in a) dbg.doCommand(a[s]);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (DEBUG) dbg.log("no debugger input buffer");
|
if (DEBUG) dbg.log("no debugger input buffer");
|
||||||
|
|
@ -3613,9 +3608,9 @@ if (DEBUGGER) {
|
||||||
this.println("Type ? for help with PCjs Debugger commands");
|
this.println("Type ? for help with PCjs Debugger commands");
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
if (this.sInitCommands) {
|
if (this.sInitCommands) {
|
||||||
var a = this.parseCommand(this.sInitCommands);
|
var sCmds = this.sInitCommands;
|
||||||
this.sInitCommands = null;
|
this.sInitCommands = null;
|
||||||
for (var s in a) this.doCommand(a[s]);
|
this.doCommands(sCmds);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -7727,6 +7722,23 @@ if (DEBUGGER) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* doCommands(sCmds, fSave)
|
||||||
|
*
|
||||||
|
* @this {Debugger}
|
||||||
|
* @param {string} sCmds
|
||||||
|
* @param {boolean} [fSave]
|
||||||
|
* @return {boolean} true if all commands processed, false if not
|
||||||
|
*/
|
||||||
|
Debugger.prototype.doCommands = function(sCmds, fSave)
|
||||||
|
{
|
||||||
|
var a = this.parseCommand(sCmds, fSave);
|
||||||
|
for (var s in a) {
|
||||||
|
if (!this.doCommand(a[s])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debugger.init()
|
* Debugger.init()
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ SSEG_PROT32 equ 0x0028
|
||||||
;
|
;
|
||||||
%assign selDesc 0
|
%assign selDesc 0
|
||||||
|
|
||||||
%macro defDesc 1-5 none,0,0,0,0
|
%macro defDesc 1-5 0,0,0,0
|
||||||
%assign %1 selDesc
|
%assign %1 selDesc
|
||||||
dw (%3 & 0x0000ffff)
|
dw (%3 & 0x0000ffff)
|
||||||
dw (%2 & 0x0000ffff)
|
dw (%2 & 0x0000ffff)
|
||||||
|
|
@ -95,7 +95,7 @@ SSEG_PROT32 equ 0x0028
|
||||||
;
|
;
|
||||||
; The "setDesc" macro creates a descriptor, given a name (%1), base (%2), limit (%3), type (%4), and ext (%5)
|
; The "setDesc" macro creates a descriptor, given a name (%1), base (%2), limit (%3), type (%4), and ext (%5)
|
||||||
;
|
;
|
||||||
%macro setDesc 1-5 none,0,0,0,0
|
%macro setDesc 1-5 0,0,0,0
|
||||||
%assign %1 selDesc
|
%assign %1 selDesc
|
||||||
set ebx,%2
|
set ebx,%2
|
||||||
set ecx,%3
|
set ecx,%3
|
||||||
|
|
@ -115,7 +115,7 @@ start: nop
|
||||||
mul ecx
|
mul ecx
|
||||||
div ecx
|
div ecx
|
||||||
cmp eax,ebx
|
cmp eax,ebx
|
||||||
jne near exitErr ; apparently we have to tell NASM "near" because this is a forward reference
|
jne near error ; apparently we have to tell NASM v0.98.40 "near" for all long forward references
|
||||||
|
|
||||||
xor dx,dx
|
xor dx,dx
|
||||||
mov ds,dx ; DS -> 0x0000
|
mov ds,dx ; DS -> 0x0000
|
||||||
|
|
@ -124,7 +124,7 @@ start: nop
|
||||||
;
|
;
|
||||||
mov eax,ds
|
mov eax,ds
|
||||||
test eax,eax
|
test eax,eax
|
||||||
jnz near exitErr
|
jnz near error
|
||||||
|
|
||||||
jmp initGDT
|
jmp initGDT
|
||||||
times 32768 nop ; lots of NOPs to force a 16-bit conditional jump
|
times 32768 nop ; lots of NOPs to force a 16-bit conditional jump
|
||||||
|
|
@ -155,10 +155,7 @@ storeDesc:
|
||||||
addrGDT:dw myGDTEnd - myGDT - 1 ; 16-bit limit of myGDT
|
addrGDT:dw myGDTEnd - myGDT - 1 ; 16-bit limit of myGDT
|
||||||
dw myGDT, 0x000f ; 32-bit base address of myGDT
|
dw myGDT, 0x000f ; 32-bit base address of myGDT
|
||||||
|
|
||||||
;
|
myGDT: defDesc NULL ; the first descriptor in any descriptor table is always a dud (it corresponds to the null selector)
|
||||||
; TODO: Why do I need to provide a 2nd parameter for "defDesc NULL"? Is this a NASM 0.98.x bug?
|
|
||||||
;
|
|
||||||
myGDT: defDesc NULL,0 ; the first descriptor in any descriptor table is always a dud (it corresponds to the null selector)
|
|
||||||
defDesc CSEG_PROT16,0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE,EXT_NONE
|
defDesc CSEG_PROT16,0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE,EXT_NONE
|
||||||
defDesc CSEG_PROT32,0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE,EXT_BIG
|
defDesc CSEG_PROT32,0x000f0000,0x0000ffff,ACC_TYPE_CODE_READABLE,EXT_BIG
|
||||||
defDesc DSEG_PROT16,0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE,EXT_NONE
|
defDesc DSEG_PROT16,0x00000000,0x000fffff,ACC_TYPE_DATA_WRITABLE,EXT_NONE
|
||||||
|
|
@ -235,10 +232,6 @@ exitErrDOS:
|
||||||
errDOSMem:
|
errDOSMem:
|
||||||
db "Insufficient memory",CR,LF,'$'
|
db "Insufficient memory",CR,LF,'$'
|
||||||
|
|
||||||
exitErr:nop
|
|
||||||
int3
|
|
||||||
jmp exitErr
|
|
||||||
|
|
||||||
allocPages:
|
allocPages:
|
||||||
mov bx,0x2000 ; 8K paragraphs == 128K bytes
|
mov bx,0x2000 ; 8K paragraphs == 128K bytes
|
||||||
mov ah,DOS_ALLOC
|
mov ah,DOS_ALLOC
|
||||||
|
|
@ -354,37 +347,28 @@ toProt32:
|
||||||
cmp eax,[0x0000]
|
cmp eax,[0x0000]
|
||||||
jne near error
|
jne near error
|
||||||
mov [0x0000],edx ; restore the DWORD at 0x0000:0x0000 from EDX
|
mov [0x0000],edx ; restore the DWORD at 0x0000:0x0000 from EDX
|
||||||
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
|
; Test moving a byte to a 32-bit register with sign-extension
|
||||||
;
|
;
|
||||||
movsx eax,byte [0xfffff]
|
movsx eax,byte [cs:0xffff]
|
||||||
cmp eax,0xffffff80
|
cmp eax,0xffffff80
|
||||||
jne near error
|
jne near error
|
||||||
;
|
;
|
||||||
; Test moving a word to a 32-bit register with sign-extension
|
; Test moving a word to a 32-bit register with sign-extension
|
||||||
;
|
;
|
||||||
movsx eax,word [0xffffe]
|
movsx eax,word [cs:0xfffe]
|
||||||
cmp eax,0xffff80fc
|
cmp eax,0xffff80fc
|
||||||
jne near error
|
jne near error
|
||||||
;
|
;
|
||||||
; Test moving a byte to a 32-bit register with zero-extension
|
; Test moving a byte to a 32-bit register with zero-extension
|
||||||
;
|
;
|
||||||
movzx eax,byte [0xfffff]
|
movzx eax,byte [cs:0xffff]
|
||||||
cmp eax,0x00000080
|
cmp eax,0x00000080
|
||||||
jne near error
|
jne near error
|
||||||
;
|
;
|
||||||
; Test moving a word to a 32-bit register with zero-extension
|
; Test moving a word to a 32-bit register with zero-extension
|
||||||
;
|
;
|
||||||
movzx eax,word [0xffffe]
|
movzx eax,word [cs:0xfffe]
|
||||||
cmp eax,0x000080fc
|
cmp eax,0x000080fc
|
||||||
jne near error
|
jne near error
|
||||||
;
|
;
|
||||||
|
|
@ -393,25 +377,53 @@ testROM:
|
||||||
mov esp,0x40000
|
mov esp,0x40000
|
||||||
mov edx,[esp] ; save word at scratch address 0x40000
|
mov edx,[esp] ; save word at scratch address 0x40000
|
||||||
add esp,4
|
add esp,4
|
||||||
push -128 ; NASM refuses to use opcode 0x6A ("PUSH imm8")
|
push byte -128 ; NASM refuses to use opcode 0x6A ("PUSH imm8") unless we specify "byte"
|
||||||
pop ebx ; verify EBX == 0xFFFFFF80
|
pop ebx ; verify EBX == 0xFFFFFF80
|
||||||
|
cmp ebx,0xFFFFFF80
|
||||||
|
jne near error
|
||||||
and ebx,0xff ; verify EBX == 0x00000080
|
and ebx,0xff ; verify EBX == 0x00000080
|
||||||
|
cmp ebx,0x00000080
|
||||||
|
jne near error
|
||||||
movsx bx,bl ; verify EBX == 0x0000FF80
|
movsx bx,bl ; verify EBX == 0x0000FF80
|
||||||
|
cmp ebx,0x0000FF80
|
||||||
|
jne near error
|
||||||
movsx ebx,bx ; verify EBX == 0xFFFFFF80
|
movsx ebx,bx ; verify EBX == 0xFFFFFF80
|
||||||
|
cmp ebx,0xFFFFFF80
|
||||||
|
jne near error
|
||||||
movzx bx,bl ; verify EBX == 0xFFFF0080
|
movzx bx,bl ; verify EBX == 0xFFFF0080
|
||||||
|
cmp ebx,0xFFFF0080
|
||||||
|
jne near error
|
||||||
movzx ebx,bl ; verify EBX == 0x00000080
|
movzx ebx,bl ; verify EBX == 0x00000080
|
||||||
|
cmp ebx,0x00000080
|
||||||
|
jne near error
|
||||||
not ebx ; verify EBX == 0xFFFFFF7F
|
not ebx ; verify EBX == 0xFFFFFF7F
|
||||||
|
cmp ebx,0xFFFFFF7F
|
||||||
|
jne near error
|
||||||
movsx bx,bl ; verify EBX == 0xFFFF007F
|
movsx bx,bl ; verify EBX == 0xFFFF007F
|
||||||
|
cmp ebx,0xFFFF007F
|
||||||
|
jne near error
|
||||||
movsx ebx,bl ; verify EBX == 0x0000007F
|
movsx ebx,bl ; verify EBX == 0x0000007F
|
||||||
|
cmp ebx,0x0000007F
|
||||||
|
jne near error
|
||||||
not ebx ; verify EBX == 0xFFFFFF80
|
not ebx ; verify EBX == 0xFFFFFF80
|
||||||
|
cmp ebx,0xFFFFFF80
|
||||||
|
jne near error
|
||||||
movzx ebx,bx ; verify EBX == 0x0000FF80
|
movzx ebx,bx ; verify EBX == 0x0000FF80
|
||||||
|
cmp ebx,0x0000FF80
|
||||||
|
jne near error
|
||||||
movzx bx,bl ; verify EBX == 0x00000080
|
movzx bx,bl ; verify EBX == 0x00000080
|
||||||
|
cmp ebx,0x00000080
|
||||||
|
jne near error
|
||||||
movsx bx,bl
|
movsx bx,bl
|
||||||
neg bx
|
neg bx
|
||||||
neg bx
|
neg bx
|
||||||
|
cmp ebx,0x0000FF80
|
||||||
|
jne near error
|
||||||
movsx ebx,bx
|
movsx ebx,bx
|
||||||
neg ebx
|
neg ebx
|
||||||
neg ebx
|
neg ebx
|
||||||
|
cmp ebx,0xFFFFFF80
|
||||||
|
jne near error
|
||||||
;
|
;
|
||||||
; Test assorted 32-bit addressing modes
|
; Test assorted 32-bit addressing modes
|
||||||
;
|
;
|
||||||
|
|
@ -423,35 +435,109 @@ testROM:
|
||||||
|
|
||||||
mov ecx,0x40000 ; now access that scratch address using various addressing modes
|
mov ecx,0x40000 ; now access that scratch address using various addressing modes
|
||||||
cmp [ecx],eax
|
cmp [ecx],eax
|
||||||
jne error
|
jne near error
|
||||||
|
|
||||||
add ecx,64
|
add ecx,64
|
||||||
cmp [ecx-64],eax
|
cmp [ecx-64],eax
|
||||||
jne error
|
jne near error
|
||||||
sub ecx,64
|
sub ecx,64
|
||||||
|
|
||||||
shr ecx,1
|
shr ecx,1
|
||||||
cmp [ecx+0x20000],eax
|
cmp [ecx+0x20000],eax
|
||||||
jne error
|
jne near error
|
||||||
|
|
||||||
cmp [ecx+ecx],eax
|
cmp [ecx+ecx],eax
|
||||||
jne error
|
jne near error
|
||||||
|
|
||||||
shr ecx,1
|
shr ecx,1
|
||||||
cmp [ecx+ecx*2+0x10000],eax
|
cmp [ecx+ecx*2+0x10000],eax
|
||||||
jne error
|
jne near error
|
||||||
|
|
||||||
cmp [ecx*4],eax
|
cmp [ecx*4],eax
|
||||||
jne error
|
jne near error
|
||||||
|
|
||||||
mov ebp,ecx
|
mov ebp,ecx
|
||||||
cmp [ebp+ecx*2+0x10000],eax
|
cmp [ebp+ecx*2+0x10000],eax
|
||||||
je error ; since SS != DS, this better be a mismatch
|
je near error ; since SS != DS, this better be a mismatch
|
||||||
|
|
||||||
mov [0x40000],edx ; restore word at scratch address 0x40000
|
mov [0x40000],edx ; restore word at scratch address 0x40000
|
||||||
|
;
|
||||||
|
; Now run a series of unverified opcode tests (verification will happen later, by comparing the output of the tests)
|
||||||
|
;
|
||||||
|
mov esi,tableOps ; ESI -> tableOps entry
|
||||||
|
testOps:
|
||||||
|
movzx ecx,byte [cs:esi] ; ECX == length of instruction sequence
|
||||||
|
jecxz doneOps ; zero means we've reached the end of the table
|
||||||
|
movzx ebx,byte [cs:esi+1] ; EBX == TYPE
|
||||||
|
shl ebx,5 ; EBX == type * 32
|
||||||
|
movzx edx,byte [cs:esi+2] ; EDX == SIZE
|
||||||
|
lea ebx,[cs:typeValues+ebx+edx*8] ; EBX -> values for type
|
||||||
|
add esi,3 ; ESI -> instruction sequence to test
|
||||||
|
|
||||||
|
push ecx
|
||||||
|
mov ecx,[cs:ebx] ; ECX == count of values for dst
|
||||||
|
mov ebx,[cs:ebx+4] ; EBX -> values for dst
|
||||||
|
mov ebp,ecx ; EBP == count of values for src
|
||||||
|
mov edi,ebx ; EDI -> values for src
|
||||||
|
testDst:
|
||||||
|
push ebp
|
||||||
|
push edi
|
||||||
|
testSrc:
|
||||||
|
mov eax,[cs:ebx] ; EAX == dst
|
||||||
|
mov edx,[cs:edi] ; EDX == src
|
||||||
|
call esi
|
||||||
|
add edi,4 ; EDI -> next src
|
||||||
|
dec ebp ; decrement src count
|
||||||
|
jnz testSrc
|
||||||
|
|
||||||
|
pop edi ; ESI -> restored values for src
|
||||||
|
pop ebp ; EBP == restored count of values for src
|
||||||
|
add ebx,4 ; EBX -> next dst
|
||||||
|
loop testDst
|
||||||
|
|
||||||
|
pop ecx
|
||||||
|
add esi,ecx ; ESI -> next tableOps entry
|
||||||
|
jmp testOps
|
||||||
|
|
||||||
|
doneOps:
|
||||||
jmp doneProt
|
jmp doneProt
|
||||||
|
|
||||||
error: nop
|
TYPE_ARITH equ 0
|
||||||
|
|
||||||
|
SIZE_BYTE equ 0
|
||||||
|
SIZE_SHORT equ 1
|
||||||
|
SIZE_LONG equ 2
|
||||||
|
|
||||||
|
%macro defOp 4
|
||||||
|
%ifidn %2,al
|
||||||
|
%assign size SIZE_BYTE
|
||||||
|
%elifidn %2,ax
|
||||||
|
%assign size SIZE_SHORT
|
||||||
|
%else
|
||||||
|
%assign size SIZE_LONG
|
||||||
|
%endif
|
||||||
|
db %%end-%%beg,%4,size
|
||||||
|
%%beg: %1 %2,%3
|
||||||
|
ret
|
||||||
|
%%end:
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
tableOps:
|
||||||
|
defOp add,al,dl,TYPE_ARITH
|
||||||
|
defOp add,ax,dx,TYPE_ARITH
|
||||||
|
defOp add,eax,edx,TYPE_ARITH
|
||||||
|
db 0
|
||||||
|
|
||||||
|
typeValues:
|
||||||
|
dd 9,arithValues,18,arithValues,27,arithValues,0,0
|
||||||
|
|
||||||
|
arithValues:
|
||||||
|
dd 0x00,0x01,0x02,0x7E,0x7F,0x80,0x81,0xFE,0xFF
|
||||||
|
dd 0x0000,0x0001,0x0002,0x7FFE,0x7FFF,0x8000,0x8001,0xFFFE,0xFFFF
|
||||||
|
dd 0x00000000,0x00000001,0x00000002,0x7FFFFFFE,0x7FFFFFFF,0x80000000,0x80000001,0xFFFFFFFE,0xFFFFFFFF
|
||||||
|
|
||||||
|
error: int3
|
||||||
|
jmp error
|
||||||
|
|
||||||
doneProt:
|
doneProt:
|
||||||
mov ax,DSEG_PROT16
|
mov ax,DSEG_PROT16
|
||||||
|
|
@ -468,7 +554,7 @@ toProt16:
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
goReal: mov eax,cr0
|
goReal: mov eax,cr0
|
||||||
and eax,~(CR0_MSW_PE | CR0_PG)
|
and eax,~(CR0_MSW_PE | CR0_PG) & 0xffffffff
|
||||||
mov cr0,eax
|
mov cr0,eax
|
||||||
jmpReal:
|
jmpReal:
|
||||||
jmp CSEG_REAL:toReal
|
jmp CSEG_REAL:toReal
|
||||||
|
|
@ -483,6 +569,7 @@ toReal:
|
||||||
cmp ax,CSEG_REAL ; is CS equal to 0xf000?
|
cmp ax,CSEG_REAL ; is CS equal to 0xf000?
|
||||||
je near jmpStart ; yes, so loop around, only because we have nowhere else to go
|
je near jmpStart ; yes, so loop around, only because we have nowhere else to go
|
||||||
int INT_DOSEXIT ; no, so assume we're running under DOS and exit
|
int INT_DOSEXIT ; no, so assume we're running under DOS and exit
|
||||||
|
|
||||||
;
|
;
|
||||||
; Fill the remaining space with NOPs until we get to target offset 0xFFF0.
|
; Fill the remaining space with NOPs until we get to target offset 0xFFF0.
|
||||||
; Note that we subtract 0x100 from the target offset because we're ORG'ed at 0x100.
|
; Note that we subtract 0x100 from the target offset because we're ORG'ed at 0x100.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue