;:::::::::::::::::::::::::::::::::::::::::
;:      Sito:  www.byteman.it  OpenWeb  ::
;:  Raccolta:  Particelle PAS+ASM       ::
;:    Autore:  Salvo Rosta aka byteman  ::
;:    Titolo:  XTESTCPU.ASM             ::
;: Revisione:  07-04-1994               ::
;:::::::::::::::::::::::::::::::::::::::::

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;:        XTESTCPU.ASM -  Versione: 04-10-1992, a cura di Salvo Rosta.      ::
;:                                                                          ::
;: Function  XTestCPU                 Restituisce Tipo CPU                  ::
;:                                                                          ::
;:                     0088h   INTEL 8088    0086h   INTEL 8086             ::
;:                     0020h     NEC V20     0030h     NEC V30              ::
;:                     0188h   INTEL 80188   0186h   INTEL 80186            ::
;:                     0286h   INTEL 80286   0386h   INTEL 80386            ::
;:                     0486h   INTEL 80486                                  ::
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
DATA      SEGMENT BYTE PUBLIC
;:::::::: DATI ESTERNI GLOBALI :::::::::::::::::::::::::::::::::::::::::::::::
          EXTRN   TP_CPU: Word
DATA      ENDS

CODE      SEGMENT BYTE PUBLIC
          ASSUME  CS:CODE,DS:DATA
          PUBLIC  XTestCPU

ProcUno   PROC    FAR
XTestCPU: PUSH    DS                  ; Salvataggio Registri

                                      ; Da SPEEDCOM.EXE
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;:  PreTest1, utilizzando istruzioni comuni a tutti i microprocessori,    ::
;:  seleziona la categoria degli AT (286,386,486) dagli "Altri".          ::
;:  Si sfrutta il fatto che negli "Altri" i 4 Flag alti sono inutilizzati ::
;:  e, a quanto pare, tenuti al valore 1.                                 ::
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
PreTest1: PUSHF                       ; Salva i Flags
          XOR     AX,AX
          PUSH    AX
          POPF                        ; Azzera i Flags
          PUSHF
          POP     AX                  ; Legge in AX i Flags
          AND     AX,0F000H           ; Isola i 4 bit alti
          CMP     AX,0F000H
          JNE     PreTest2
          POPF                        ; Pop flags
          JMP     Altri               ; Jump if equal

PreTest2: POPF                        ; Pop flags
          MOV     AX,7000h
          PUSH    AX
          POPF
          PUSHF
          POP     AX
          AND     AX,7000h
          JNZ     Test486
          JMP     PrevTest

Test486:  DB      66h, 8Bh, 0D4h, 66h, 83h, 0E4h, 0FCh, 66h
          DB      9Ch, 66h,  58h, 66h, 8Bh, 0C8h,  66h, 35h
          DB      00h, 00h,  04h, 00h, 66h,  50h,  66h, 9Dh
          DB      66h, 9Ch,  66h, 58h, 66h,  33h, 0C1h, 66h
          DB      0C1h, 0E8h, 12h, 66h, 51h,  66h,  9Dh, 66h
          DB      8Bh, 0E2h, 66h, 83h, 0E0h, 01h

;:::::::::Codice equivalente di Test486:

          MOV     EDX,ESP
          AND     ESP,0FFFFFFFCH
          PUSHF                           ; Push flags
          POP     EAX
          MOV     ECX,EAX
          XOR     EAX,40000H
          PUSH    EAX
          POPF                            ; Pop flags
          PUSHF                           ; Push flags
          POP     EAX
          XOR     EAX,ECX
          SHR     EAX,12H                 ; Shift w/zeros fill
          PUSH    ECX
          POPF                            ; Pop flags
          MOV     ESP,EDX
          AND     EAX,1
 
          JZ      PrevTest
          MOV     BX,486h
          JMP     EndCpuTest

PrevTest: MOV     BX,386h             ; Caso 80386
          NOP

          PUSH    SP                  ; Test se 286/386 o Altri
          POP     AX
          CMP     AX,SP
          JNE     Altri               ; Jump if not equal

          MOV     AX,7000H            ; Test se 286 o 386
          PUSH    AX
          POPF                        ; Pop flags
          PUSHF                       ; Push flags
          POP     AX
          AND     AX,7000H
          JNZ     EndCpuTest          ; Jump if not zero
          MOV     BX,286h             ; Caso 80286
          JMP     EndCpuTest
Altri:    MOV     BX,188h             ; Caso 80188
          NOP
          MOV     CL,21H              ; '!'
          MOV     AX,0FFFFH
          SHL     AX,CL               ; Shift w/zeros fill
          JNZ     TestBus16           ; Jump if not zero
          MOV     BX,20h              ; Caso V20
          NOP
          MOV     CX,0FFFFH
          STI                         ; Enable interrupts
          PUSH    AX
          PUSH    SI
;         DB      0F3h,26h,0ACh          ; Istruzioni NEC V20/30
          REP     LODS BYTE PTR ES:[SI]; equivalente a 0F3h,26h,0ACh
          POP     SI
          POP     AX
          JCXZ    TestBus16
          MOV     BX,88h              ; Caso 8088
          NOP

TestBus16:
          CALL    Bus16
          JCXZ    EndCpuTest
          CMP     BL,88h
          JNE     Skip
          MOV     BL,86h              ; Caso 8086, 80186
          JMP     EndCpuTest
Skip:     MOV     BL,30h              ; Caso V30
EndCpuTest:
          MOV     DS:TP_CPU,BX
          MOV     AX,BX
          POP     DS                  ; Ripristino Registri
          RET
ProcUno   ENDP


ProcDue   PROC    NEAR
Bus16:    STD                         ; Set direction flag
          MOV     DI,Offset Destin
          MOV     AL,Byte Ptr CS:CodeSTI
          MOV     CX,3
          CLI                         ; Disable interrupts
          REP     STOSB               ; Rep while cx>0 Store al to es:[di]
          CLD                         ; Clear direction
          NOP
          NOP
          NOP
          INC     CX
CodeSTI:  STI
Destin:   STI
          RET
ProcDue   ENDP

CODE      ENDS
          END