home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
PASCAL
/
PNL010.ZIP
/
TEST186.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-03-01
|
4KB
|
118 lines
(* Code from m274.
(117) Thu 6 Jun 91 3:30a
By: Robert Mashlan
To: All
Re: TEST286.PAS
St: Reply in 118
-----------------------------------------------------------------------------
@EID:522d 16c61bcf
@MSGID: 1:147/38 63036254
Hello All,
It was brought to my attention by Michelango Jones that Borland's Test286.pas
demo program was provided by Borland such than you can provide a stub function
for a program compiled with {$G+}. The problem with this code is that is
unfairly leaves out lesser CPUs capable of running this code.
If you use {$G+}, please feel free to use this code!
===========================================================
*)
{$G+}
Unit Test186;
(* test186.pas 6-6-91 Robert Mashlan
license: to public domain
This unit provides a stub function for code compiled with TP 6.0's
"286" code generation directive {$G-}. Borland provides a demo
program called TEST286.PAS that checks if the machine is a 286 or
better, but leaves out the 80186/80188/V20/V30 machines perfectly
capable of running code compiled in this mode.
To use this unit, simply place it as the first unit listed in a {$G+}
program's unit clause. If the CPU is not capable of running the
program, it will abort.
*)
Interface
Implementation
Function Is186Able : boolean; assembler;
(* This function returns true if the CPU is not a 8088/8086, which
cannot run code compiled in {$G+} mode. A NEC V20, V30,
Intel 80186, 80188, 286, 386, and 486 can all run TP 6.0's
"286" code and return true.
*)
asm
pushf ;(* save flags */
(* This test differentiates between a 286 and up and an 80186 and below
This is done by checking the value of bits 12-15 in the flag register
when it is pushed onto the stack. If they are set, then the CPU
is not a 286 and up.
*)
xor ax,ax ;(* set ax=0 *)
push ax ;(* push onto stack *)
popf ;(* pop flags *)
pushf ;(* push flags *)
pop ax ;(* pop into ax *)
and ax,0f000h ;(* mask upper 4 bits *)
cmp ax,0f000h ;(* are bits 12-15 set? *)
jne @exit186 ;(* NO: is a 286 and up *)
(* This test differentiates a 80186/80188 between a V20/V30/8088/8086.
The 80186/80188 will clear the upper three bits of the shift count
before executing a shift instruction using the cl register.
*)
mov al,0ffh ;(* set all bits in al *)
mov cl,021h ;(* try shifting 21h times *)
shr al,cl ;(* try shifting *)
jne @exit186 ;(* if al!=0 then it is a 80186/80188 *)
(* This test differentiates the NEC V20/V30 between the 8088/8086
This is done by testing for a bug in the 8088/8086. In the
Intel CPUs, if a repeated string instruction with a segment
override is interrupted by a hardware interrupt, the
instruction is not continued.
*)
sti ;(* enable interrupts *)
push si ;(* save si ( could be a register variable) *)
mov si,0 ;(* Starting with first byte in es *)
mov cx,0ffffh ;(* read a complete segment *)
db 0f3h, 26h, 0ach;
{ rep lodsb es:[si] } ;(* rep with a segment override *)
(* hardware interrupt is sure to occur during the above instruction *)
pop si ;(* restore si *)
or cx,cx ;(* has entire segment been read? *)
je @exit186 ;(* YES: V20 or V30 *)
(* NO: must be 8088 or 8086 *)
@exitnot186:
mov ax, 0; ; (* return false *)
jmp @exit
@exit186:
mov ax,01h ;(* return true *)
@exit: ;
popf ;(* restore flags *)
end;
begin
if not Is186Able then
begin
Writeln('This program will not run on an 8088/8086.');
Halt(1);
end;
end.