📄 cmd_fpu.asm
字号:
%include "util.mac"
%include "icedump.inc"
%include "wiat.inc"
%include "fpu.inc"
global Parse_FPU
extern sdata
extern Parser.errorMsg
extern ParseExpression
bits 32
;-------------------------------------------------------------------------------
; FPU <FPU register number> <floating point value>
;-------------------------------------------------------------------------------
segment _LTEXT
Parse_FPU:
mov edx,cr0 ; save CR0.TS
; for now we don't handle the case where the current thread hasn't used
; the FPU yet (i.e. CR0.TS=1), we'd have to use VMCPD_Set_Thread_State
mov edi,.Error_TS
test dl,0x08 ; TS, our thread doesn't own the FPU
jnz near Parser.errorMsg
mov edi,.Error_EM
test dl,0x04 ; EM, we don't deal with emulation
jnz near Parser.errorMsg
mov edi,+.Error_ET
test dl,0x10 ; ET, oldies are not supported
jz near Parser.errorMsg
mov ecx,esi ; parse <FPU number> later
mov edi,.Error_NoValue
call [pSkipWord] ; skip over <FPU number>
jb near Parser.errorMsg
mov byte [esi-1],',' ; terminate the commandline here
xchg esi,ecx ; save and restore ESI
mov edi,.Error_NoSTx
call ParseExpression ; parse <FPU number>
jb near Parser.errorMsg
mov edi,.Error_BadSTx
cmp eax,7 ; accept ST0...ST7 only
ja near Parser.errorMsg
lea ebx,[8*eax+eax] ; EBX: index of STx in the state map
add ebx,eax
mov esi,ecx ; ESI will point to <value> now
mov edi,.Error_BadValue
call [pStr2LongReal]
jb near Parser.errorMsg
; clts ; avoid triggering an exception
fnsave [FPUState]
mov esi,[tLongReal]
lea edi,[ebx+FPUState.STx]
movsd
movsd
movsw
; because winice is fucked up, it cannot display the FPU registers when
; there're pending exceptions, so we shouldn't make such a big deal out
; of saving even this part of the state, but should simply return with
; an error message much like winice does... but we always do better ;-)
; of course introducing inconsistencies into the FPU state is not our
; problem but that of the user...
; now restore FPU state, first clear possible pending exceptions
xor al,al
xchg al,[FPUState.Status+FPU_Status_PM32.StatusLo]
frstor [FPUState]
; now restore status with possible pending exceptions
xchg al,[FPUState.Status+FPU_Status_PM32.StatusLo]
fldenv [FPUState.Status]
; mov cr0,edx ; restore CR0.TS
call [pUpdateSomeWindows] ; we wanna see it, don't we ;-)
popad
retn
segment _LDATA
.Error_TS db 'CR0.TS=1, FPU was last used by another thread.',0
.Error_EM db 'CR0.EM=1, FPU is emulated.',0
.Error_ET db 'CR0.ET=0, oldies are not supported.',0
.Error_NoSTx db 'specify an STx register.',0
.Error_BadSTx db 'STx is invalid.',0
.Error_NoValue db 'specify a value.',0
.Error_BadValue db 'value is invalid.',0
align 4
FPUState:
.Status:
istruc FPU_Status_PM32
iend
.STx:
istruc FPU_STx
iend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -