Author Topic: Condition Code Confusion  (Read 20727 times)

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Condition Code Confusion
« on: November 09, 2016, 11:12:13 PM »
It's been so long since I did much coding that I am a little confused at how to use condition codes. I'm trying to simplify some of the code in my rewritten CPUID code.

Code: [Select]
pushf ; save flags

push byte -1
popf ; set flags [15-0]
pushf
pop ax ; read flags back

popf ; restore original flags

test ah,0F0h ; are bits 12-15 clear?
jz is16bit ; all clear: it's not a 386 (it's 286)

je is16bit

test ah,080h ; is bit 15=0?
jz is32bit ; yes, it's a 32-bit CPU

It's the first TEST instruction and the following conditional jumps that I am confused with. Logically, if the high nibble of AH is all clear, the zero flag will be set. If the high nibble is all set, it makes sense that the Equals flag should be said, but I know JE and JZ are the same.

What would be the correct way to code the tests (or ANDs, just as good) and jumps?

For reference, the code should implement the following:

Code: [Select]
; 808x and 8018x: flags[12-15] are always set. +
; 286: flags[12-15] are always clear in real-address mode. +
; 32-bit processors: real-mode: +
; bit 15 is always clear; +
; bits 12-14 have the last value loaded into them. +
; 32-bit processors: protected mode: +
; bit 15 is always clear; +
; bit 14 has the last value loaded into it; +
; and the IOPL bits depends on the (CPL). +
; The IOPL field can be changed only if the CPL is 0. +

I am currently only looking at running the code in real mode or V86 mode. This section won't be needed when I rewrite it for Windows.
My graphics card database: www.gpuzoo.com

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Condition Code Confusion
« Reply #1 on: November 09, 2016, 11:21:07 PM »
I'm considering the following:

Code: [Select]
test ah,0F0h ; are bits 12-15 clear?
jz is16bit ; all clear: it's not a 386 (it's 286)
js is16bit

test ah,080h ; is bit 15=0?
jz is32bit ; yes, it's a 32-bit CPU

For 8086 the high (sign) bit is set, for 286 in real mode the result will always be zero.
Then the second test is just the high bit, which should always be clear on a 386+. I relise the last two lines of code can be replaced by a simple jump, but want to be sure I understand the condition codes first.

I have forgotten so much during a decade of not coding :)
My graphics card database: www.gpuzoo.com

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Condition Code Confusion
« Reply #2 on: November 10, 2016, 02:29:05 AM »
Hi Debs,

Isn't it a drag when your memory goes out the window? I'm having a lot of trouble with that lately. At the moment, I'm fuzzy about the pushf/popf effect(s). I remember how "test" works, I think. If the entire high nibble is clear, the zero flag will be set. If any of the four high bits are set, the zero flag is cleared. That is, we will jump on "nz" (or "ne" but I think "nz" is clearer - exact same opcode). We do not get any information about which one(s) or if more than one bit is set. I'm not sure if "test" sets the sign flag or not - I'd have to test it, and you can do that (or do you need help?). I think you're better off using "test" with one bit at a time, or "and" and "cmp" with a specific value for multiple bits. "all bits clear" will work, though.

Does that help any? I can try to get back to this if I have to, but I'm feeling pretty fuzzy right now...

Best,
Frank


Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Condition Code Confusion
« Reply #3 on: November 10, 2016, 03:35:53 PM »
I need to set up a DOS machine to test it (or maybe create a small test file that I can load from my boot sector, that shouldn't be too hard if my working system can boot from USB floppy). Win 10 64-bit won't run my DOS 16-bit com files, and I never got as far as coding a Win32 console app (and Linux is way ahead of me at the moment). :)
My graphics card database: www.gpuzoo.com

Offline stressful

  • Full Member
  • **
  • Posts: 105
  • Country: 00
    • CPU2.0
Re: Condition Code Confusion
« Reply #4 on: November 10, 2016, 04:31:54 PM »
I am having trouble understanding your code debs, but what you probably need is a SHR or AND instruction against AX if you are interested in knowing the state of bits 15 to bit 12 regardless of other bits

Code: [Select]
xor ax,ax
pushf
pop ax
shr ax,12
;and ax,1111000000000000b ;(mask) bit15 - bit12 (this equals 0xF000)
test ax,ax ;this actually not needed, but for clarity purpose...
jz is286

I don't know if this helps.

Offline stressful

  • Full Member
  • **
  • Posts: 105
  • Country: 00
    • CPU2.0
Re: Condition Code Confusion
« Reply #5 on: November 10, 2016, 04:46:57 PM »
For testing bit 15, you could use BT (carry) or TEST instruction (sign)

Code: [Select]
bt ax,15
jc is386

or
 
test ah,ah
js is386

I'm trying to sum it up...
Code: [Select]
pushf
pop ax
mov bx,ax
shr ax,12
jz .isbit16

test bh,bh
js .isbit32

Is this the effect you are expecting?
 

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Condition Code Confusion
« Reply #6 on: November 11, 2016, 12:21:34 AM »
For testing bit 15, you could use BT (carry) or TEST instruction (sign)

Code: [Select]
bt ax,15
jc is386

or
 
test ah,ah
js is386

I'm trying to sum it up...
Code: [Select]
pushf
pop ax
mov bx,ax
shr ax,12
jz .isbit16

test bh,bh
js .isbit32

Is this the effect you are expecting?

It's roughly what I'm looking for, but it has shown me what to do. BT is the solution, along with shr. My final code is:

Code: [Select]
pushf ; save flags

push byte -1
popf ; set flags [15-0]
pushf
pop ax ; read flags back

popf ; restore original flags

bt ah,0Fh ; is bit15 set?
jc is16bit ; yes, it's an 8018x or earlier

shr ax,0Ch ; shr AX 12.
jnz is32bit ; if not 0, it's 386+

is16bit
<error code, 16-bit processors to be added later>

is32bit

Thanks for pointing me in the right direction.
« Last Edit: November 11, 2016, 12:28:36 AM by debs3759 »
My graphics card database: www.gpuzoo.com

Offline stressful

  • Full Member
  • **
  • Posts: 105
  • Country: 00
    • CPU2.0
Re: Condition Code Confusion
« Reply #7 on: November 11, 2016, 04:49:10 AM »
good to hear that. But as a pointer, the flag register is an extremely volatile register, so you'd probably want to pop it off much later. It does you no good POPFing it earlier since both SHR and BT modify it anyway.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Condition Code Confusion
« Reply #8 on: November 11, 2016, 02:20:35 PM »
If I understand it (possibly not)...
Code: [Select]
push -1
popf
sets only some bits, depending on CPU.
Code: [Select]
pushf
pop ax
puts the bits we're interested in in ax. From then on, it does no harm to alter flags.

This is not looking like one of my better days, so maybe I should shut up.

Best,
Frank


Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Condition Code Confusion
« Reply #9 on: November 11, 2016, 10:43:23 PM »
If I understand it (possibly not)...
Code: [Select]
push -1
popf
sets only some bits, depending on CPU.
Code: [Select]
pushf
pop ax
puts the bits we're interested in in ax. From then on, it does no harm to alter flags.

This is not looking like one of my better days, so maybe I should shut up.

Best,
Frank

I can't find any documentation that describes PUSH BYTE imm8, so I may stick with pushing a word (just in case it doesn't sign extend the imm8)

I restore the original flags where I do in case I ever place the code snippet inside some code the relies on NT, IF or IOPL having the original values. It's only very minimal code and instruction timing overhead..
My graphics card database: www.gpuzoo.com

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Condition Code Confusion
« Reply #10 on: November 11, 2016, 11:42:26 PM »
Hi Debs,

Quote
I can't find any documentation that describes PUSH BYTE imm8, so I may stick with pushing a word (just in case it doesn't sign extend the imm8)

Just:
Code: [Select]
push -1
will assemble the signed byte form, and of course it will be sign extended. If you really want the word form, use:
Code: [Select]
push strict word -1
There's no point in using the long form, though. I can't find where this is documented at the moment, but I'm quite sure it's true.

FWIW, Linux is "easy". "isbit16" isn't going to be happening, of course. True of Windows as well...

Best,
Frank



Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Condition Code Confusion
« Reply #11 on: November 13, 2016, 12:30:26 AM »
FWIW, Linux is "easy". "isbit16" isn't going to be happening, of course. True of Windows as well...

I ultimately aim to write the DOS code to run on all systems from 808x up. Higher end tests with CPUID will be tested from a floppy (USB where possible), then reused for my Windows code (I have to learn the basics of Windows coding) which will only test CPUs with CPUID. I may even dual boot into Linus on some older test systems and learn to code for that as well. It won't be quick, I'm still researching all the CPUID codes from 2001 on, but it may help me to find some programming work when I know the basic API calls and how to implement them in asm and C/C++.

Naturally the 16 bit tests won't be needed for systems with CPUID, and I doubt I'll write Windows or Linux code for a 486 or earlier.
My graphics card database: www.gpuzoo.com

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Condition Code Confusion
« Reply #12 on: November 15, 2016, 02:23:04 AM »
My final code for this portion of the code is

Code: [Select]
push byte -1
popf ; set flags [15-0]
pushf
pop ax ; read flags back

bt ah,0F0h ; is bit 15 set?
jc is16bit ; yes, it's an 80(1)86

bt ah,0Eh ; is bit 14 set?
jc is32bit ; yes? it's a 386+

80286: ; we get here if it is a 286

is16bit:


is32bit:


This looks like the optimal code, and is easy to modify to add 8-bit and 16-bit chips identification. Not sure yet whether to save/restore original flags.
My graphics card database: www.gpuzoo.com

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Condition Code Confusion
« Reply #13 on: November 16, 2016, 04:44:35 AM »
I finished the 8/16 bit detection code (this is what was missing from my original code, I'll rewrite the 32-bit non CPUID code while I finish my CPUID database. The code I am posting in this thread does not include macro definitions, inc files, etc - you'll see all that packaged together when I finish the ground up rewrite (unless you want to see it, then I'll zip it and post it here).

Code: [Select]
bits 16

%include "boot.inc"
%include "cpuid.inc"
%include "i386.inc"

;-----------------------------------------------------------------------+
; Set order and alignment of sections +
;-----------------------------------------------------------------------+

SECTION .text
SECTION .code follows=.text align=16
SECTION .data align=16
SECTION .bss align=16

;-----------------------------------------------------------------------+
; To build a version that will work properly under DOS, use ORG 100h. +
;-----------------------------------------------------------------------+

org 100h

SECTION .text

;-----------------------------------------------------------------------+
; Clear screen. +
; Set up segments and stack. +
;-----------------------------------------------------------------------+
.start:
mov ax,3 ; clear screen and set text
int 10h ; mode 3.

mov dx,cs
mov ds,dx
mov es,dx

mov dx,stackseg ; initialise the stack, using the same
mov ss,dx ; values used in the boot sector.
mov sp,stacksize ; Don't assume that the boot sector
; had cleaned it up first.
xor dx,dx

;-----------------------------------------------------------------------+
;  Now we've set DS and ES to the same as CS, lets check what we can do +
; with the flags (this will detect a 32-bit processor). +
;-----------------------------------------------------------------------+

mov si,Str_Out_Array16 ; this has to be preserved for pre 386

push byte -1
popf ; clear flags [15-0]
pushf
pop ax ; read flags back
cld

bt ax,0Fh ; is bit 15 set?
jc is16bit ; yes, it's an 80(1)86

bt ax,0Eh ; is bit 14 set?
jc is32bit ; yes, it's a 386+

;-----------------------------------------------------------------------+
; If we got here, we have a 286. +
;-----------------------------------------------------------------------+
i80286:

MkClass16 Str_286
MkFamily16 Str_286
MkModel16 Str_286

mov dx,8
jmp i16.end

[section .data]
align 8

Str_Out_Array16:

SOA_Class16 equ $-Str_Out_Array ; Compatability Class
.Class dw Str_CPU_Class,24
dw Str_Blank,1 ; 3,4

SOA_Family16 equ $-Str_Out_Array ; Processor Family
.Family dw Str_CPU_Family,24
dw Str_Blank,1 ;

SOA_Model16 equ $-Str_Out_Array ; CPU Model
.Model dw Str_CPU_Model,24
dw Str_Blank,1 ; Cx...

Str_Out16_Sz equ ($-Str_Out_Array16)>>3 ; Number of elements in array

__SECT__

;-----------------------------------------------------------------------+
; Is it an 8018x or 808x processor? +
;-----------------------------------------------------------------------+

is16bit:
mov ax,-1 ; Set all bits in ax
shr ax,020h ; attempt to shift right 32

or ax,ax ; did it clear ax?
jz i808x ; yes, it's 808x or Vx0

;-----------------------------------------------------------------------+
; It's an 8018x. +
;-----------------------------------------------------------------------+

i8018x:
MkClass16 Str_18x
MkFamily16 Str_18x

call test8bit ; is it 8-bit?
jz i80188 ; yes? It's 80188

MkModel16 Str_186 ; it's a 186
mov dx,7
jmp i16.end

i80188:
MkModel16 Str_188 ; it's a 188
mov dx,6
jmp i16.end

;-----------------------------------------------------------------------+
; It's an 808x, 80C8x or NEC V20/30. +
;-----------------------------------------------------------------------+

i808x:
MkClass16 Str_808x

mov ax,sp ; copy sp
pusha ; executes as 2-byte nop on 808x
nop
cmp ax,sp ; has SP changed?
jne Vx0 ; yes, it's an NEC Vx0

mov ax,0FFFh
push si
mov di,si
MkFamily16 Str_808x
.1
mov cx,0FFFFh
rep es:movsb ; copy 2^32 bits from ES:DI to DS:SI
; these are set to the same places
or cx,cx ; is CX 0?
jnz .3 ; no, it's an 808x
dec ax ; dec dx
jnz .1 ; outer loop

;-----------------------------------------------------------------------+
; It's an 80C8x. +
;-----------------------------------------------------------------------+


call test8bit ; is it 8-bit?
jz .2 ; yes? It's a V20

MkModel16 Str_80C86 ; it's an 8086
mov dx,3
jmp i16.end

.2
MkModel16 Str_80C88 ; it's an 8088
mov dx,2
jmp i16.end

;-----------------------------------------------------------------------+
; It's an 808x. +
;-----------------------------------------------------------------------+
.3
pop si ; restore SI

call test8bit ; is it 8-bit?
jz i8088 ; yes? It's a V20

MkModel16 Str_8086 ; it's an 8086
mov dx,1
jmp i16.end

i8088:
MkModel16 Str_8088 ; it's an 8088
mov dx,0
jmp i16.end

;-----------------------------------------------------------------------+
; It's an NEC V20 or V30. +
;-----------------------------------------------------------------------+

Vx0:
popa
MkFamily16 Str_Vx0

call test8bit ; is it 8-bit?
jz V20 ; yes? It's a V20

MkModel16 Str_V30 ; it's a V30
mov dx,5
jmp i16.end

V20:
MkModel16 Str_V20 ; it's a V20
mov dx,4
jmp i16.end

;-----------------------------------------------------------------------+
; test8bit routine tests whether we have an 8 or 16-bit data bus. +
;-----------------------------------------------------------------------+

[section .code]

test8bit:

mov ax,-1
mov [.1], byte 040h ; try to change code at .1 to inc
nop
nop
nop
nop
.1 nop ; if executes as inc, it's 8-bit
nop ; and ZF is set.
ret

__SECT__

;-----------------------------------------------------------------------+
; Some strings to define the CPU class/family/model for 8/16 bit CPUs. +
;-----------------------------------------------------------------------+

[section .data]

Str_Vx0 db "NEC Vx0"
Str_Vx0_Sz equ $-Str_Vx0

Str_V20 db "NEC V20"
Str_V20_Sz equ $-Str_V20

Str_V30 db "NEC V30"
Str_V30_Sz equ $-Str_V30

Str_808x db "808x"
Str_808x_Sz equ $-Str_808x

Str_8086 db "8086"
Str_8086_Sz equ $-Str_8086

Str_8088 db "8088"
Str_8088_Sz equ $-Str_8088

Str_80C86 db "80C86"
Str_80C86_Sz equ $-Str_80C86

Str_80C88 db "80C88"
Str_80C88_Sz equ $-Str_80C88

Str_18x db "8018x"
Str_18x_Sz equ $-Str_18x

Str_186 db "80186"
Str_186_Sz equ $-Str_186

Str_188 db "80188"
Str_188_Sz equ $-Str_188

Str_286 db "286"
Str_286_Sz equ $-Str_286

__SECT__

;-----------------------------------------------------------------------+
; Display error message if not a 32-bit processor. +
;-----------------------------------------------------------------------+

i16:

.end:

hlt

jmp $-1 ; make sure we halt again if we are
; resumed by an interrupt.

;-------------------------------------------------------------------------------+
; Now for the 32-bit processor detection code... +
; +
; If we got here, we know we have a 386 or later processor. +
;-------------------------------------------------------------------------------+


is32bit:

IntStart ; setup interrupt vectors
call Int_Setup ; first call installs our new interrupts

mov si,Str_Out_Array ; this has to be preserved throughout...


;-------------------------------------------------------------------------------+
; Int06_New: Invalid opcode handler +
; +
; input: BX = 0 +
; +
; output: BX = 0FFFFh +
; +
; Sets BX to 0ffffh (as an invalid opcode semaphore), and then increments the +
; return IP by 3 before returning control to the original code. +
;-------------------------------------------------------------------------------+

[section .code]

Int06_New:
push bp
mov bp,sp

dec bx

add word [SS:BP],3

pop bp

iret
__SECT__
;-------------------------------------------------------------------------------+
; Int0D_New: General Protection Exception handler +
; +
; input: BX = 0 +
; +
; output: BX = 01h +
; +
; Sets BX to 01h (as a #GP semaphore), and then increments the return IP by 3 +
; before returning control to the original code. +
;-------------------------------------------------------------------------------+

[section .code]

Int0D_New:
push bp
mov bp,sp

inc bx

add word [SS:BP + 2],3

pop bp

iret

__SECT__

;-------------------------------------------------------------------------------+
; Int_Setup: Set up Int handlers +
; +
; input [bp-4] = new int 6 offset +
; [bp-2] = new int 6 segment +
; +
; output: none +
; +
; This routine simply exchanges the old Int6 address and the new one, thus +
; saving the original vector on the first call and restoring it on the +
; second. +
;-------------------------------------------------------------------------------+

[section .text]

Int_Setup:

push dx
push ds

push byte 0
pop ds ; interrupt vector table...

mov edx,[IVT_int06]
xchg edx,[es:new_int06]
mov [IVT_int06],edx

mov edx,[IVT_int07]
xchg edx,[es:new_int07]
mov [IVT_int07],edx

mov edx,[IVT_int0D]
xchg edx,[es:new_int0D]
mov [IVT_int0D],edx

pop ds
pop dx

ret

__SECT__

;-------------------------------------------------------------------------------+
; prints: print string +
; +
; input: ES:BP pointer to string +
; CX string length in bytes +
; +
; output: none +
;-------------------------------------------------------------------------------+

[section .code]

prints:
push dx
push ax
push bx
push cx

mov ah,03h
xor bh,bh

int 10h

pop cx

mov ax,01301h
mov bx,7

int 10h

pop bx
pop ax
pop dx

ret

__SECT__





[section .data]

new_int06 dd 0 ; store int 06 vector
new_int07 dd 0 ; store int 06 vector
new_int0D dd 0 ; store int 0D vector

__SECT__

;-----------------------------------------------------------------------+
; This array is used to hold pointers to the various data elements +
; which describe the processor. +
;-----------------------------------------------------------------------+

[section .data]

align 8

Str_Out_Array:

SOA_Class equ $-Str_Out_Array ; Compatability Class
.Class dw Str_CPU_Class,24
dw Str_Blank,1 ; 3,4

SOA_Type equ $-Str_Out_Array ; Processor Type
.Type dw Str_CPU_Type,24 ; Single, Overdrive, Dual
dw Str_Blank,1 ;

SOA_Family equ $-Str_Out_Array ; Processor Family
.Family dw Str_CPU_Family,24
dw Str_Blank,1 ;

SOA_Model equ $-Str_Out_Array ; CPU Model
.Model dw Str_CPU_Model,24
dw Str_Blank,1 ; Cx...

SOA_Mask equ $-Str_Out_Array ; Stepping, revision...
.Mask dw Str_CPU_Mask,24
dw Str_Blank,1 ;

SOA_FPU equ $-Str_Out_Array ; FPU Type
.FPU dw Str_FPU_Type,24
dw Str_Blank,1 ;

SOA_IDType equ $-Str_Out_Array ; Method used for ID
.IDType dw Str_CPUID_Type,24
dw Str_Feat,Str_Feat_Sz ; All

SOA_VID equ $-Str_Out_Array ; Vendor ID String
.VID dw Str_CPU_V_ID,24
dw Str_VendorID,12 ; Completed (CPUID Only)

SOA_Vendor equ $-Str_Out_Array ; Vendor name (or generic...)
.Vendor dw Str_Vendor,24
dw Str_Blank,1 ; All 386, 486

SOA_ID equ $-Str_Out_Array ; CPU ID
.ID dw Str_CPUID_Val,24
dw Str_IDVal,4 ; All 486+

SOA_Clock equ $-Str_Out_Array ; Clock multiplier
.Clock dw Str_CPU_Clock,24
dw Str_Blank,1 ;

Str_Out_Sz equ ($-Str_Out_Array)>>3 ; Number of elements in array

;-----------------------------------------------------------------------+
; The first few data items are part of the output used to display the +
; information returned by this code. +
;-----------------------------------------------------------------------+

Str_CPU_Class db "Compatibility         : " ; 386, 486, Y
; Pentium
Str_CPU_Type db "Processor type        : " ; Overdrive, Dual, etc
Str_CPU_Family db "Family                : " ; 386/486/Pentium, etc
Str_CPU_Model db "Model                 : " ; 486DX, K6-III, etc
; Cx486.... Y
Str_CPU_Mask db "Stepping/Revision     : " ; If known...
Str_FPU_Type db "FPU type              : " ; 287 - 487, built-in
Str_CPUID_Type db "Identification method : " ;CPUID, BIOS, reset, Y
; feature test,
; Cyrix DIRs,
; IBM MSRs
Str_CPU_V_ID db "Vendor ID             : " ; CPUID Vendor ID
Str_Vendor db "CPU Vendor            : " ; Intel or compatible,
; Cyrix or compatible,
; NexGen, IBM, etc
Str_CPUID_Val db "Processor ID          : " ; From CPUID, DIRs, etc
Str_FSB_Clock db "FSB Clock             : " ; If known...
Str_CPU_Clock db "Core Clock            : " ; If known...
Str_Clk_Ratio db "Core/Bus Clock Ratio  : " ; If known...

Str_Blank db " "
Str_Blank_Sz equ $-Str_Blank

;-----------------------------------------------------------------------+
; Some strings to define the CPU class/family/model. +
;-----------------------------------------------------------------------+

Str_386 db "386"
Str_386_Sz equ $-Str_386

Str_486 db "486"
Str_486_Sz equ $-Str_486

Str_P6 db "P6"
Str_P6_Sz equ $-Str_P6

;-----------------------------------------------------------------------+
; Array of CPUID methods strings +
;-----------------------------------------------------------------------+

ID_Arr:

istruc ID_Array

at ID_Array.Feat, dd Str_Feat + (Str_Feat_Sz<<10h)
at ID_Array.CPUID, dd Str_CPUID + (Str_CPUID_Sz<<10h)
at ID_Array.Reset, dd Str_Reset + (Str_Reset_Sz<<10h)
at ID_Array.IBM, dd Str_IBM_MSR + (Str_IBM_MSR_Sz<<10h)
at ID_Array.BIOS, dd Str_BIOS + (Str_BIOS_Sz<<10h)
at ID_Array.CxDIRs, dd Str_Cx_DIR + (Str_Cx_DIR_Sz<<10h)
at ID_Array.CxFeat, dd Str_Cx_Feat + (Str_Cx_Feat_Sz<<10h)
at ID_Array.Unknown, dd Str_Unknown + (7 << 10h)

iend

Str_Feat db "CPU Features"
Str_Feat_Sz equ $-Str_Feat

Str_CPUID db "CPUID"
Str_CPUID_Sz equ $-Str_CPUID

Str_Reset db "Reset"
Str_Reset_Sz equ $-Str_Reset

Str_IBM_MSR db "IBM MSRs"
Str_IBM_MSR_Sz equ $-Str_IBM_MSR

Str_BIOS db "BIOS"
Str_BIOS_Sz equ $-Str_BIOS

Str_Cx_DIR db "Cyrix DIRs"
Str_Cx_DIR_Sz equ $-Str_Cx_DIR

Str_Cx_Feat db "Cyrix features"
Str_Cx_Feat_Sz equ $-Str_Cx_Feat

Str_VendorID db "            "

;-----------------------------------------------------------------------+
; Other strings... +
;-----------------------------------------------------------------------+

Str_IDVal db "        "
CPUID_Val dd 0

CPUID_Arr:
.Type db 0
.Family db 0,0
.Model db 0
.Mask db 0
CPUID_Arr_Sz equ $-CPUID_Arr


__SECT__
My graphics card database: www.gpuzoo.com

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Condition Code Confusion
« Reply #14 on: November 16, 2016, 04:47:27 AM »
All macros like MkClass16, MkFamily16, etc are filling the arrays I will use for setting up the output.
My graphics card database: www.gpuzoo.com