1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
; Results:
; 0 - 8088
; 1 - 8086
; 2 - V20
; 3 - V30
; 4 - 80188
; 5 - 80186
; 6 - 80286
; 7 - 80386+
push bp
mov bp, sp ; needs to be &H8B, &HEC
pushf
; push zero onto the stack and pop it into flags.
; some bits won't change
xor ax,ax
push ax
popf
pushf
pop ax
and ax, 0xf000 ;0f000h
cmp ax, 0xf000 ;0f000h
je lessthantwoeightsix
; marked as 286 (6)
mov dl, 6
mov ax, 0x7000 ;7000h
push ax
popf
pushf
pop ax
and ax, 0x7000 ;7000h
jz alldone
; mark as 386 (7)
inc dl
jmp alldone
lessthantwoeightsix:
; Mark as 80188 (4)
mov dl, 4
mov al, 0xff ;0ffh
mov cl, 0x21 ;21h
shr al, cl
; if the shift leaves zero, it's a 8088 class cpu, else 80186/88
jnz buswidth
; Lets see if we have a V20/V30 (2)
mov dl, 2
sti
push si
mov si, 0
mov cx, 0xffff ;0ffffh
;rep lods [BYTE PTR es:si]
; INLINE assembler doesn't understand above - must be replaced after...
; because we need a lods with ES as a parameter
; so drop a 3-byte nonsense call to be replaced
mov cx, 0x0f99 ; replace with 0xF3, 0x26, 0xAC or &HF3, &H26, &HAC
pop si
or cx, cx
jz buswidth
; mark as a 8088/8086 (1)
mov dl, 0
buswidth:
; we are destroying es now, must be restored later
push cs
pop es
std
; The 99 _must_ be replaced with the true offset of qqend
mov di, 99 ; OFFSET qqend ;99
;set up al and cx: 0xfb is the 'sti' instruction
mov al, 0xfb
mov cx, 3
; disable interrupts
cli
rep stosb
cld
nop
nop
nop
inc dx
nop
qqend:
sti
; ES must be restored
push ds
pop es
alldone:
; store in ax
xor dh, dh
mov di, [bp]+6
mov [di], dx
popf
pop bp
retf 2
|