mov ax,BASE.ops87 ; указатель команды
and ax,mask opseg ; сегмент
mov cl,opseg
shr ax,cl ; цифра
mov ch,1 ; отобразить 1
call bin2hex
@DisChr ':'
mov ax,BASE.opo87 ; указатель операнда
mov ch,4 ; смещение
call bin2hex
;
@DisStr ocode ; код операции
mov ax,BASE.ips87
and ax,mask opcode
or ax,0800h ; добавить бит кода операции
mov ch,3 ; 3 цифры
call bin2hex ; отобразить
;
; Флаги разрешения прерывания / особой ситуации:
@DisStr LINE3 ; следующая строка
mov al,byte ptr BASE.sw87 ; флаг разрешения ситуации
call exception_flags ; показать состояние
;
; Коды условий:
@DisStr space10
mov ah,byte ptr BASE.sw87+1 ; коды условий
push ax ; (сохранить коды)
mov al,30h ; (ASCII "0")
and ah,mask c3 ; C3
sub ah,mask c3 ; 0 -> CY, 1 -> NC
cmc ; 0 -> NC, 1 -> CY
adc al,0 ; 0 -> "0", 1 -> "1"
@DisChr al ; отобразить
pop ax ; (сохранить коды)
;
mov ch,c2 + 1 ; # отображаемых кодов
next_cc:
- 10-28 -
@DisStr SPACE2
;
mov al,30h ; (ASCII "0")
and ah,mask c2 + mask c1 + mask c0 ; C2
sub ah,mask c2 ; 0 -> CY, 1 -> NC
cmc ; 0 -> NC, 1 -> CY
adc al,0 ; 0 -> "0", 1 -> "1"
@DisChr al ; отобразить
;
shl ah,1 ; следующий код
dec ch ; уменьшать на 1 ...
jnz next_cc ; ... пока все не
; ... будет сделано
;
; Флаги состояния прерывания / особой ситуации:
@DisStr LINE6
mov al,byte ptr BASE.sw87 ; флаг сигнала ситуации
call exception_flags ; показать состояние
;
; Отобразить регистр данных:
@DisStr LINE6
mov dh,8 ; # отображаемого регистра
mov si,0 ; начать с регистра #0
;
register_display:
@DisStr LINE8 ; регистры состояния
push dx ; сохранить счет
mov al,8 ; вычислить регистр #
sub al,dh
add al,30h ; перевести в ASCII
@DisChr al ; и отобразить
pop dx
;
; Знак регистра данных:
@DisStr paren ; следующим идет знак
mov ax,word ptr BASE.reg87[si].exp87
test ax,mask sign ; что это?
jnz sign_minus
@DisStr plus
jmp show_exponent
sign_minus:
@DisStr minus
;
; Экспоненциальная часть регистра данных:
show_exponent:
and ax,mask exp ; получить экспоненту
xor cx,cx ; четыре символа
call bin2hex ; и отобразить
@DisStr space3
;
mov di,si ; основание регистра
add di,offset exp87 ; положение мантиссы
mov dl,4 ; 4 слова на регистр
;
; Отобразить значащую часть регистра данных:
show_significand:
sub di,2 ; указать начало слова
- 10-29 -
mov ax,word ptr Base.reg87[di]
call bin2hex ; и отобразить
@DisStr SPACE1
dec dl
jnz show_significand
;
; Правильный номер регистра:
@DisStr truenum
mov al,byte ptr BASE.sw87+1 ; получит указатель стека
and al,mask stp
mov cl,stp
shr al,cl ; иметь указатель стека
;
mov cl,8 ; преобразовать счетчик в
sub cl,dh ; ... значение от 0 до 7
add al,cl ; # текущего регистра
;
push ax ; сохранить номер регистра
add al,30h ; преобразовать в ASCII
@DisChr al ; и отобразить
;
@DisStr SPACE2 ; переход в поле TAG
;
; Состояние слова признака:
mov ax,BASE.tw87 ; получить слово признака
pop cx ; получить номер регистра
; ... в CL
shl cl,1 ; многократно по 2
shr ax,cl ; получить соответствующее
; ... слово признака
and ax,mask tag
;
push dx
mul tag_siz ; смещение условия
add ax,offset tag_cnd ; адрес условия
mov dx,ax
@Display ; показать состояние признака
pop dx
;
; Для данного регистра все выполнено!
add si,size fltreg ; следующий регистр
dec dh ; меньше на 1
jz finished
jmp register_display ; пока все не выполнено
;
; Все выполнено для всех регистров!
;
finished:
@disStr LINE9 ; все сделано!
;
; Восстановить главный центральный процессор в первоначальное
; состояние. Начать с сохраненных регистров.
pop si ; восстановить регистры...
; ... вызывающего оператора
pop di
pop dx
pop cx
- 10-30 -
pop bx
pop ax
mov sp,bp ; восстановить стек
pop ds ; восстановить сегмент данных
popf ; восстановить флаги...
; ... вызывающего оператора
pop bp ; восстановить весь...
; ... базовый указатель
ret ; вернуться после завершения
;
;-------------------------------------------------------------
; Отобразить подпрограмму для вывода на экран состояния маски
; и сигнала особых ситуаций.
; Проверить байт в AL на наличие битов, соответствующих
; флагам особых ситуаций.
;
exception_flags PROC NEAR
test al,mask master ; главное управление
call mark_it
;
mov cl,pr ; следующим идет флаг PR
ror al,cl ; перейти к первой позиции
inc cl ; считать 1 > бита #
;
test_exception:
test al,1 ; флаг установлен?
call mark_it
rol al,1 ; следующий шаг
dec cl ; следить за счетом
jnz test_exception ; продолжать до завершения
ret
;
;-------------------------------------------------------------
; Отметить результат в соответствии с установленными флагами
; записи.
;
mark_it PROC NEAR
jz mark_space
@DisStr marky
ret
mark_space:
@DisStr markn
ret
mark_it ENDP
;
exception_flags ENDP
;
#.DATA
;-------------------------------------------------------------
; З А П И С Ь Л О К А Л Ь Н Ы Х К О Н С Т А Н Т DUMP87
;
; ------- этот раздел только считывается -------
;
; "_lab" - метка раздела
; "_cnd" - условие для метки
; "_siz" - число байтов в условии
;
- 10-31 -
@CRet MACRO ;; новое макроопределение строки
db 0Dh,0Ah
ENDM
;
LINE1 EQU $
@CRet
db '=====================NPX DUMP ====================
db '==='
@CRet
db 'Infinity: $'
rnd_lab db ' Round:........ $' ; метка
pre_lab db ' Precision: $' ; метка
inf_siz db 7
inf_cnd db 'Proj. $' ; состояние бесконечности
db 'Affine$' ; состояние бесконечности
rnd_siz db 5
rnd_cnd db 'near$' ; состояние округления
db 'down$' ; состояние округления
db 'up $' ; состояние округления
db 'chop$' ; состояние округления
pre_siz db 3
pre_cnd db '24$' ; состояние точности "ret"
db '**$' ; состояние точности "ret"
db '53$' ; состояние точности "ret"
db '64$' ; состояние точности "ret"
;
LINE2 EQU $
@CRet
db 'Inst Addr: $' ; "x:xxxx"
opadr db ' Oper Addr: $' ; "x:xxxx"
ocode db ' Opcode: D$' ; "xxx","ret","ret"
;
LINE3 EQU $
@CRet
@CRet
db ' INT PRE UND OVR ZER DEN IOP'
db ' C3 C2 C1 C0'
db 'Masked:$'
; коды условия "ret"
LINE6 EQU $
@CRet
db 'Signal:$' ; "ret"
marky db ' x $'
markn db ' $'
;
LINE8 EQU $
@CRet
db 'ST($' ; "x"
paren db ') $'
plus db '+ $'
minus db '- $' ; "xxxx"
space10 db ' ' ; 10 пробелов
SPACE2 EQU $ + 1 ; 2 пробела
SPACE1 EQU $ + 2 ; 1 пробел