mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-09-27 01:00:24 +03:00
270 lines
4.8 KiB
ArmAsm
270 lines
4.8 KiB
ArmAsm
|
|
; for new GOGO-no-coda (1999/09)
|
|
; Copyright (C) 1999 shigeo
|
|
; modified by Keiichi SAKAI, URURI, Hash
|
|
|
|
; 99/07/29
|
|
; 99/09/06 フラグ追加
|
|
; 99/09/07 SSEの処理を別にする
|
|
; 99/09/29 Cx586対策
|
|
; 99/11/10 Cxrix対策
|
|
|
|
; int haveUNIT(void);
|
|
|
|
; 486未満のCPUまたはFPUを搭載していなければ0
|
|
; それ以外は次の値の論理和
|
|
; PIIIでは丸め誤差を四捨五入モードにする(らしい)
|
|
|
|
; haveunit.hとの整合性注意
|
|
|
|
%include "nasm.h"
|
|
|
|
tFPU equ (1<<0)
|
|
tMMX equ (1<<1)
|
|
t3DN equ (1<<2)
|
|
tSSE equ (1<<3)
|
|
tCMOV equ (1<<4)
|
|
tE3DN equ (1<<5) ;/* Athlon用 (extend 3D Now!)*/
|
|
tEMMX equ (1<<6) ;/* EMMX=E3DNow!_INT=SSE_INT */
|
|
|
|
tSPC1 equ (1<<16) ;/* 特別なスイッチ */
|
|
tSPC2 equ (1<<17) ;/* 用途は決まってない */
|
|
|
|
tINTEL equ (1<<8)
|
|
tAMD equ (1<<9)
|
|
tCYRIX equ (1<<10)
|
|
tIDT equ (1<<11)
|
|
tUNKNOWN equ (1<<15) ;ベンダーが分からない
|
|
|
|
tFAMILY4 equ (1<<20) ;/* 486 この時ベンダー判定は当てにならない */
|
|
tFAMILY5 equ (1<<21) ;/* 586 (P5, P5-MMX, K6, K6-2, K6-III) */
|
|
tFAMILY6 equ (1<<22) ;/* 686以降 P-Pro, P-II, P-III, Athlon */
|
|
|
|
globaldef haveUNIT
|
|
globaldef setPIII_round
|
|
globaldef maskFPU_exception
|
|
|
|
segment_data
|
|
segment_code
|
|
|
|
ACflag equ (1<<18)
|
|
IDflag equ (1<<21)
|
|
|
|
align 16
|
|
haveUNIT:
|
|
push ebx
|
|
push esi
|
|
xor esi,esi
|
|
call near haveFPU
|
|
jnz near .Lexit
|
|
or esi,tFPU
|
|
pushfd ;flag保存
|
|
pushfd
|
|
pop eax ;eax=flag
|
|
or eax,ACflag ;eax=flag|ACflag
|
|
push eax
|
|
popfd ;flag=eax
|
|
pushfd
|
|
pop eax ;eax=flag
|
|
popfd ;flag復元
|
|
test eax,ACflag ;ACflagは変化したか?
|
|
jz near .Lexit
|
|
;486以降
|
|
pushfd ;flag保存
|
|
pushfd
|
|
pop eax ;eax=flag
|
|
or eax,IDflag ;eax=flag|IDflag
|
|
push eax
|
|
popfd ;flag=eax
|
|
pushfd
|
|
pop eax ;eax=flag
|
|
popfd ;flag復元
|
|
test eax,IDflag
|
|
; jz short .Lexit
|
|
jnz .L586
|
|
|
|
%if 1
|
|
;Cyrix 486CPU check Cyrix の HP にあったやつ by Hash
|
|
|
|
xor ax, ax ; clear ax
|
|
sahf ; clear flags, bit 1 is always 1 in flags
|
|
mov ax, 5
|
|
mov bx, 2
|
|
div bl ; do an operation that does not change flags
|
|
lahf ; get flags
|
|
cmp ah, 2 ; check for change in flags
|
|
jne .L486intel ; flags changed not Cyrix
|
|
or esi,tCYRIX ; TRUE Cyrix CPU
|
|
jmp .L486
|
|
|
|
.L486intel:
|
|
or esi,tINTEL
|
|
.L486:
|
|
or esi,tFAMILY4
|
|
jmp .Lexit
|
|
|
|
%else
|
|
; check for Cyrix 486DLC -- based on check routine
|
|
; documented in "Cx486SLC/e SMM Programmer's Guide"
|
|
xor dx,dx
|
|
cmp dx,dx
|
|
pushf
|
|
pop cx
|
|
mov ax,0FFFFh
|
|
mov bx,4
|
|
div bx
|
|
pushf
|
|
pop ax
|
|
and ax,8D5h
|
|
and cx,8D5h
|
|
cmp ax,cx
|
|
jnz .L486intel
|
|
or esi,tCYRIX
|
|
jmp .L486
|
|
.L486intel:
|
|
or esi,tINTEL
|
|
.L486:
|
|
or esi,tFAMILY4
|
|
jmp .Lexit
|
|
%endif
|
|
|
|
|
|
.L586:
|
|
|
|
;cpuid は eax,ebx,ecx,edxを破壊するので注意!!!
|
|
|
|
xor eax,eax
|
|
cpuid
|
|
; cmp ecx,"letn"
|
|
cmp ecx,"ntel" ;うわ〜NASMと反対に配置するんだ
|
|
jne .F00
|
|
or esi,tINTEL
|
|
jmp .F09
|
|
.F00:
|
|
; cmp ecx,"DMAc"
|
|
cmp ecx,"cAMD"
|
|
jne .F01
|
|
or esi,tAMD
|
|
jmp .F09
|
|
.F01:
|
|
; cmp ecx,"daet"
|
|
cmp ecx,"tead"
|
|
jne .F02
|
|
or esi,tCYRIX
|
|
jmp .F09
|
|
.F02:
|
|
; cmp ecx,"slua"
|
|
cmp ecx,"auls"
|
|
jne .F03
|
|
or esi,tIDT
|
|
jmp .F09
|
|
.F03:
|
|
or esi,tUNKNOWN
|
|
jmp .F09
|
|
.F09:
|
|
mov eax,1
|
|
cpuid
|
|
cmp ah,4
|
|
jne .F10
|
|
or esi,tFAMILY4
|
|
jmp .Lexit
|
|
.F10:
|
|
cmp ah,5
|
|
jne .F11
|
|
or esi,tFAMILY5
|
|
jmp .F19
|
|
.F11:
|
|
cmp ah,6
|
|
jne .F12
|
|
or esi,tFAMILY6
|
|
jmp .F19
|
|
.F12:
|
|
or esi,tFAMILY6 ; 7以上は6と見なす
|
|
.F19:
|
|
|
|
;for AMD, IDT
|
|
mov eax,80000001h
|
|
cpuid
|
|
test edx,(1 << 31)
|
|
jz .F20
|
|
or esi,t3DN
|
|
.F20:
|
|
test edx,(1 << 15) ;CMOVcc
|
|
jz .F21
|
|
; test edx,(1 << 16) ;FCMOVcc ;K7から変更 by URURI
|
|
; jz .F21
|
|
or esi,tCMOV
|
|
.F21:
|
|
test edx,(1 << 30) ;拡張 3D Now!
|
|
jz .F22
|
|
%ifdef USE_E3DN
|
|
or esi,tE3DN
|
|
%endif
|
|
.F22:
|
|
test edx,(1 << 22) ;AMD MMX Ext
|
|
jz .F23
|
|
or esi,tEMMX
|
|
.F23:
|
|
;Intel系
|
|
mov eax,1
|
|
cpuid
|
|
test edx,(1 << 23)
|
|
jz .F30
|
|
or esi,tMMX
|
|
.F30:
|
|
test edx,(1 << 15) ;CMOVcc and FCMOV if FPU=1
|
|
jz .F31
|
|
or esi,tCMOV
|
|
.F31:
|
|
test edx,(1 << 25)
|
|
jz short .Lexit
|
|
or esi,tEMMX
|
|
%ifndef UNAVAILABLE_SSE
|
|
or esi,tSSE
|
|
%endif
|
|
.Lexit:
|
|
mov eax,esi
|
|
pop esi
|
|
pop ebx
|
|
ret
|
|
|
|
; in:none
|
|
; out:ZF FPUあり=1, なし=0
|
|
; dest:eax
|
|
|
|
align 16
|
|
haveFPU:
|
|
mov al,1
|
|
fninit
|
|
fnstsw ax
|
|
cmp al,0
|
|
jne short .LhF_exit
|
|
sub esp,4
|
|
fnstcw word [esp]
|
|
mov ax,[esp]
|
|
add esp,4
|
|
and ax,103Fh
|
|
cmp ax,3Fh
|
|
.LhF_exit:
|
|
ret
|
|
|
|
setPIII_round:
|
|
;P-IIIのSSEを確実に四捨五入モードに
|
|
; mov eax,0x1f80 ; default mode
|
|
mov eax,0x9f80 ; flush to ZERO mode
|
|
push eax
|
|
ldmxcsr [esp] ; setup MXCSR
|
|
pop eax
|
|
ret
|
|
|
|
; for Win32 Delphi
|
|
maskFPU_exception:
|
|
push eax
|
|
fnstcw word [esp]
|
|
and word [esp],0xFFF2
|
|
fldcw word [esp]
|
|
pop eax
|
|
ret
|
|
|
|
end
|