home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / asm / wasm / show87.asm < prev    next >
Assembly Source File  |  1988-02-29  |  33KB  |  1,254 lines

  1.  
  2.  Title 'Wolfware Assembler Sample Program', '8087 State Display'
  3.  
  4. ;=============================================================================
  5. ; Show87
  6. ; Copyright (c) 1987-1988 Eric Tauck
  7. ; All Rights Reserved
  8. ;
  9. ; This a memory resident program to display the present state of an
  10. ; installed 8087 coprocessor.  Once assembled, to execute, type:
  11. ;
  12. ;   SHOW87 [/R]
  13. ;
  14. ; If run without any options, the program executes a DOS shell and can be
  15. ; removed from memory by typing EXIT at any DOS prompt.  If run with the
  16. ; /R option, the progam is made resident and cannot be removed (but uses
  17. ; less memory).  Uses about 5600 bytes of memory with /R, over 8000 without.
  18. ; Requires CONVERT1.INC, CONVERT2.INC, VIDEO1.INC, and VIDEO2.INC on the
  19. ; default drive/path for assembly.
  20. ;
  21. ; The hot key is ALT-7.  Traps interrupt 16H and uses only BIOS routines for
  22. ; display, thus should work on most computers with most software.
  23. ;
  24. ; Show87 assumes that an 8087 is installed.  If one isn't installed, this
  25. ; program will probably hang the computer.
  26. ;
  27. ;----------------------------------------------------------------------------
  28. ;8 Ins Ptr  XXXXX | Prec      XX | ST(0) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX S
  29. ;0 Opr Ptr  XXXXX | Round  XXXXX | ST(1) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX H
  30. ;8 Op Code   XXXX | Infin  XXXXX | ST(2) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX O
  31. ;7 Control   XXXX |------------- | ST(3) +X.XXXXXXXXXXXXXXXXX +XXXXX XXXXXX W
  32. ;| Status    XXXX | Cond    XXXX | ST(4)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX 8
  33. ;S Tag       XXXX | Comp       X | ST(5)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX 7
  34. ;T ---------------| Test       X | ST(6)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX |
  35. ;A Stack Top    X | Exam  XXXXXX | ST(7)    =XXXXXXXXXXXXXXXX  =XXXX XXXXXX X
  36. ;T ------------------------------------------------------------------------ X
  37. ;E Except PX UX OX ZX DX IX    Intr Mask PX UX OX ZX DX IX    Ints XXXXXXXX X
  38. ;----------------------------------------------------------------------------
  39. ;
  40. ; Compare: > < = ?
  41. ; Test: + - 0 ?
  42. ; Examine: +Unorm +NAN -Unorm -NAN +Norm +Infin -Norm -Infin +0 -0 +Dnorm
  43. ;   -Dnorm Empty
  44. ; Precision: 24 53 64 ??
  45. ; Rounding: Near Up Down Trunc
  46. ; Infinity: Proj Affin
  47. ; Interrupts: Enabled Disabled
  48.  
  49. Ver_Hi Equ 1            ;ones version number
  50. Ver_Lo Equ 10           ;tens version number
  51.  
  52. Hotkey Equ 7e00h        ;hot key, Alt-7
  53.  
  54. StartRow Equ 0          ;screen row offset
  55. StartCol Equ 0          ;screen column offset
  56. Rows Equ 12             ;rows in display
  57. Cols Equ 76             ;columns in display
  58.  
  59. Atr_Bor Equ 07h         ;border attribute
  60. Atr_Mes Equ 70h         ;edge text attribute
  61. Atr_Lin Equ 07h         ;line attribute
  62. Atr_Tex Equ 07h         ;center text attribute
  63. Atr_Set Equ 07h         ;number and settings attribute
  64.  
  65. Sig_Bits Equ 57         ;number of significant bits in real number display
  66.  
  67. ;================================================
  68. ; Main program, execute shell after resetting
  69. ; interrupt 16H.
  70.  
  71.  Jmp Init       ;go to initialization
  72.  
  73. ;--- switch stack and set memory allocation
  74.  
  75. Start
  76.  Mov Bx, Offset Program_Stack   ;new stack top
  77.  Mov Sp, Bx                     ;switch to stack
  78.  Mov Cl, 4
  79.  Shr Bx, Cl             ;make paragraph
  80.  Inc Bx                 ;account for extra
  81.  
  82.  Test Status, Status1   ;check if resident mode
  83.  Jnz Main1
  84.  
  85.  Mov Ah, 4ah            ;function
  86.  Int 21h                ;execute
  87.  
  88. ;--- save the interrupt data
  89.  
  90. Main1
  91.  Push Bx
  92.  Push Es
  93.  Mov Ax, 3516h          ;function and interrupt number
  94.  Int 21h
  95.  Mov Word Original16, Bx        ;save offset
  96.  Mov Word Original16+2, Es      ;save segment
  97.  Pop Es
  98.  Pop Bx
  99.  
  100. ;--- load the new interrupt
  101.  
  102.  Mov Ax, 2516h                  ;function
  103.  Mov Dx, Offset Interrupt16     ;entry point offset
  104.  Int 21h                        ;execute
  105.  
  106.  Test Status, Status1   ;check if resident mode
  107.  Jnz Main3
  108.  
  109. ;--- initialize the EXEC parameter block and enter shell
  110.  
  111.  Push Es
  112.  Push Ds
  113.  Mov Prog_Off, Sp       ;save stack offset
  114.  Mov Prog_Seg, Ss       ;save stack segment
  115.  
  116.  Mov Ax, 4b00h
  117.  Mov Bx, Offset Parameter_Blk   ;pararmeter block location
  118.  Mov [Bx+4], Cs                 ;save the present segment
  119.  Mov Dx, CmdLoc                 ;program name offset
  120.  Mov Ds, [2ch]                  ;             segment
  121.  Int 21h
  122.  
  123.  Cli
  124.  Cs:
  125.  Mov Sp, Prog_Off       ;restore stack offset
  126.  Cs:
  127.  Mov Ss, Prog_Seg       ;restore stack segment
  128.  Sti
  129.  Pop Ds
  130.  Pop Es
  131.  
  132. ;--- show exit message
  133.  
  134.  Sub Al, Al
  135.  Mov Dx, Offset Closemes        ;normal termination message
  136.  Jnc Main2
  137.  Mov Al, 0ffh
  138.  Mov Dx, Offset Errormes        ;error message
  139. Main2
  140.  Mov Ah, 9                      ;function
  141.  Int 21h                        ;show message
  142.  
  143. ;--- finished
  144.  
  145.  Push Ax                ;save return code
  146.  Mov Ax, 2516h          ;function
  147.  Lds Dx, Original16     ;load original interrupt location
  148.  Int 21h                ;execute
  149.  Pop Ax
  150.  
  151.  Mov Ah, 4ch            ;exit function
  152.  Int 21h                ;execute
  153.  
  154. ;--- resident mode, terminate and stay resident
  155.  
  156. Main3
  157.  Mov Ax, 3100h  ;function and return code
  158.  Mov Dx, Bx     ;paragraphs to save
  159.  Int 21h        ;execute
  160.  
  161. ;================================================
  162. ; Control recieved through interrupt 16H.
  163.  
  164. Interrupt16 Proc Far
  165.  
  166. ;--- check if activation key
  167.  
  168.  Sti            ;interrrupts on
  169.  Cmp Ah, 0      ;check if key request
  170.  Je Inter1
  171.  Cmp Ah, 1      ;check if status request
  172.  Je Inter2
  173.  Cs:
  174.  Jmp Original16         ;non-key request, transfer directly to INT 16
  175.  
  176. ;--- key request, function 0
  177.  
  178. Inter1
  179.  Pushf                  ;flags on stack
  180.  Cs:
  181.  Call Original16        ;get key
  182.  Cmp Ax, HotKey         ;check if activation key
  183.  Je Inter5              ;jump if so
  184.  Iret
  185.  
  186. ;--- key status request
  187.  
  188. Inter2
  189.  Pushf                  ;flags on stack
  190.  Cs:
  191.  Call Original16        ;get key status
  192.  Jz Inter3              ;jump if no key
  193.  Pushf                  ;must save return flags
  194.  Cmp Ax, HotKey         ;check if activation key
  195.  Je Inter4              ;jump if so
  196.  Popf                   ;not key, restore flags
  197. Inter3
  198.  Ret 2
  199.  
  200. ;=== activation key detected, proceed with display
  201.  
  202. ;--- status only, must toss out key
  203.  
  204. Inter4
  205.  Add Sp, 2              ;throw out flags save by status
  206.  Sub Ah, Ah             ;get key function
  207.  Pushf                  ;flags on stack
  208.  Cs:
  209.  Call Original16        ;get key
  210.  Mov Ah, 1              ;reset actual function
  211.  
  212. ;--- save stack
  213.  
  214. Inter5
  215.  Cs:
  216.  Mov Stack_Seg, Ss      ;segment
  217.  Cs:
  218.  Mov Stack_Off, Sp      ;offset
  219.  
  220. ;--- switch to local stack
  221.  
  222.  Cli
  223.  Push Cs
  224.  Pop Ss                         ;set to local segment
  225.  Mov Sp, Offset Local_Stack     ;set to offset
  226.  Sti
  227.  
  228. ;--- save registers
  229.  
  230.  Pushf
  231.  Push Ax
  232.  Push Bx
  233.  Push Cx
  234.  Push Dx
  235.  Push Di
  236.  Push Si
  237.  Push Bp
  238.  Push Ds
  239.  Push Es
  240.  
  241. ;--- initialize
  242.  
  243.  Push Cs
  244.  Pop Ds         ;set data segment
  245.  Push Cs
  246.  Pop Es         ;set other data segment
  247.  
  248.  Cli
  249.  Fnsave State_Area      ;save the 8087 state
  250.  Fwait                  ;synchronize
  251.  Sti
  252.  
  253.  Cld                    ;normal direction
  254.  Mov IntFunc, Ah        ;save the function for termination
  255.  Call Video_Init        ;initialize display data
  256.  
  257.  Call Video_Cget        ;get the cursor location
  258.  Mov CurLoc, Dx         ;save it
  259.  
  260. ;--- save the screen area
  261.  
  262.  Mov Dh, StartRow               ;first row
  263.  Mov Di, Offset Save_Area       ;screen save area
  264.  
  265. Inter6
  266.  Mov Dl, StartCol       ;first column
  267.  
  268. Inter7
  269.  Call Video_Cset        ;move cursor
  270.  
  271.  Mov Ah, 8              ;function
  272.  Mov Bh, Video_Page     ;get the page
  273.  Push Di
  274.  Int 10h                ;execute, get character
  275.  Pop Di
  276.  Stosw                  ;store AH and AL
  277.  Inc Dl                 ;next column
  278.  
  279.  Cmp Dl, StartCol+Cols  ;check if past end
  280.  Jb Inter7              ;loop back if not
  281.  Inc Dh                 ;next row
  282.  
  283.  Cmp Dh, StartRow+Rows  ;check if past end
  284.  Jb Inter6              ;loop back if not
  285.  
  286. ;--- show main display
  287.  
  288.  Mov Bl, Atr_Set                                ;attribute
  289.  Mov Cx, StartRow*256+StartCol                  ;upper left corner
  290.  Mov Dx, (StartRow+Rows-1*256)+StartCol+Cols-1  ;lower right corner
  291.  Call Video_Cpag                                ;clear screen area
  292.  Mov Si, Offset Display1                ;main display string
  293.  Call Video_Wstr                        ;write to screen
  294.  
  295. ;--- show stats
  296.  
  297.  Call Display_State     ;show state
  298.  
  299. ;--- wait for key
  300.  
  301.  Mov Dx, (StartRow+Rows-1*256)+StartCol+Cols-1  ;lower right corner
  302.  Call Video_Cset                                ;move cursor there
  303.  
  304.  Sub Ah, Ah             ;function number
  305.  Pushf
  306.  Call Original16        ;get a key
  307.  
  308. ;--- restore the screen area
  309.  
  310.  Mov Dh, StartRow               ;first row
  311.  Mov Si, Offset Save_Area       ;screen save area
  312.  
  313. Inter8
  314.  Mov Dl, StartCol       ;first column
  315.  
  316. Inter9
  317.  Call Video_Cset        ;move cursor
  318.  
  319.  Lodsw                  ;load character and attribute
  320.  Mov Bl, Ah             ;attribute
  321.  Mov Ah, 9              ;function
  322.  Mov Bh, Video_Page     ;get the page
  323.  Mov Cx, 1              ;count
  324.  Push Si
  325.  Int 10h                ;execute, get character
  326.  Pop Si
  327.  
  328.  Inc Dl
  329.  Cmp Dl, StartCol+Cols  ;check if past end
  330.  Jb Inter9              ;loop back if not
  331.  Inc Dh                 ;next row
  332.  
  333.  Cmp Dh, StartRow+Rows  ;check if past end
  334.  Jb Inter8              ;loop back if not
  335.  
  336. ;--- finished
  337.  
  338.  Mov Dx, CurLoc         ;get cursor location
  339.  Call Video_Cset        ;set it
  340.  
  341.  Frstor State_Area      ;restore state
  342.  
  343.  Pop Es
  344.  Pop Ds
  345.  Pop Bp
  346.  Pop Si
  347.  Pop Di
  348.  Pop Dx
  349.  Pop Cx
  350.  Pop Bx
  351.  Pop Ax
  352.  Popf
  353.  
  354. ;--- restore original stack
  355.  
  356.  Cli
  357.  Cs:
  358.  Mov Ss, Stack_Seg      ;segment
  359.  Cs:
  360.  Mov Sp, Stack_Off      ;offset
  361.  Sti
  362.  
  363. ;--- transfer to interrupt 16H as if nothing had happened
  364.  
  365.  Cs:
  366.  Mov Ah, IntFunc        ;save the function for termination
  367.  Cs:
  368.  Jmp Original16         ;transfer to INT 16
  369.  Endp                   ;Interrupt16
  370.  
  371. ;================================================
  372. ; Display the 8087 state.
  373.  
  374. Display_State Proc Near
  375.  
  376. ;--- instruction pointer
  377.  
  378.  Mov Ax, State_Area+6   ;instruction pointer, lower 16 bits
  379.  Mov Bx, State_Area+8   ;                     upper 4 bits
  380.  Mov Cl, 12
  381.  Shr Bx, Cl             ;put the bits in the bottom
  382.  Mov Cx, 5*256+16       ;display width and base
  383.  Mov Dx, 1*256+11       ;display location offset
  384.  Call Display_Number    ;display
  385.  
  386. ;--- operand pointer
  387.  
  388.  Mov Ax, State_Area+10  ;operand pointer, lower 16 bits
  389.  Mov Bx, State_Area+12  ;                 upper 4 bits
  390.  Push Cx
  391.  Mov Cl, 12
  392.  Shr Bx, Cl             ;put the bits in the bottom
  393.  Pop Cx
  394.  Inc Dh                 ;next row
  395.  Call Display_Number    ;display
  396.  
  397. ;--- op code
  398.  
  399.  Mov Ax, State_Area+8           ;get the op code
  400.  And Ax, 0000011111111111b      ;mask out bits
  401.  Or Ax, 1101100000000000b       ;set implicit bits
  402.  Sub Bx, Bx                     ;clear high word
  403.  Mov Ch, 4                      ;new display width
  404.  Inc Dh                         ;next row
  405.  Inc Dl                         ;next column
  406.  Call Display_Number            ;display
  407.  
  408. ;--- control word
  409.  
  410.  Mov Ax, State_Area     ;control word
  411.  Inc Dh                 ;next row
  412.  Call Display_Number    ;display
  413.  
  414. ;--- status word
  415.  
  416.  Mov Ax, State_Area+2   ;status word
  417.  Inc Dh                 ;next row
  418.  Call Display_Number    ;display
  419.  
  420. ;--- tag word
  421.  
  422.  Mov Ax, State_Area+4   ;tag word
  423.  Inc Dh                 ;next row
  424.  Call Display_Number    ;display
  425.  
  426. ;--- stack top
  427.  
  428.  Call Get_Stack         ;get the stack top
  429.  Sub Ah, Ah
  430.  Add Dx, 0203h          ;add two to the rows and add three to the columns
  431.  Mov Cx, 1*256+10       ;display width and base
  432.  Call Display_Number    ;display
  433.  
  434. ;--- precision
  435.  
  436.  Mov Bl, State_Area+1   ;high word of control
  437.  And Bl, 11b            ;mask bits
  438.  Sub Bh, Bh
  439.  Mov Cl, 2              ;width
  440.  Mov Dx, 1*256+29               ;display location offset
  441.  Mov Di, Offset Dissta3b        ;table
  442.  Call Display_Istr              ;display string
  443.  
  444. ;--- rounding
  445.  
  446.  Mov Bl, State_Area+1   ;high word of control
  447.  And Bl, 1100b          ;mask bits
  448.  Sub Bh, Bh
  449.  Shr Bx
  450.  Shr Bx
  451.  Mov Cl, 5              ;width
  452.  Inc Dh
  453.  Sub Dl, 3                      ;display location offset
  454.  Mov Di, Offset Dissta4b        ;table
  455.  Call Display_Istr              ;display string
  456.  
  457. ;--- infinity
  458.  
  459.  Mov Bl, State_Area+1   ;high word of control
  460.  And Bl, 10000b         ;mask bit
  461.  Sub Bh, Bh
  462.  Mov Cl, 4
  463.  Shr Bx, Cl
  464.  Mov Cl, 5                      ;width
  465.  Inc Dh                         ;next row
  466.  Mov Di, Offset Dissta5b        ;table
  467.  Call Display_Istr              ;display string
  468.  
  469. ;--- condition codes
  470.  
  471.  Mov Al, State_Area+3   ;high byte of status
  472.  Call Adjst_Codes       ;adjust the condition codes
  473.  Sub Bx, Bx             ;clear high word
  474.  Mov Cx, 4*256+2        ;display width and base
  475.  Add Dx, 0201h          ;new location
  476.  Call Display_Number    ;display
  477.  
  478. ;--- comparison and test
  479.  
  480.  Call Get_Comp                  ;get the index
  481.  Mov Cl, 1                      ;width
  482.  Add Dx, 0103h                  ;location
  483.  Mov Di, Offset Dissta1b        ;table
  484.  Call Display_Istr              ;display string
  485.  
  486.  Inc Dh
  487.  Mov Di, Offset Dissta2b        ;table
  488.  Call Display_Istr              ;display string
  489.  
  490. ;--- examine
  491.  
  492.  Mov Al, State_Area+3   ;high byte of status
  493.  Inc Dh
  494.  Sub Dl, 5              ;location
  495.  Call Display_Exam      ;display
  496.  
  497. ;--- exception bit settings
  498.  
  499.  Mov Al, State_Area+2   ;get the bits
  500.  Mov Dx, 10*256+10      ;display offset
  501.  Call Display_Bits      ;display
  502.  
  503. ;--- mask bit settings
  504.  
  505.  Mov Al, State_Area     ;get the bits
  506.  Mov Dx, 10*256+41      ;display offset
  507.  Call Display_Bits      ;display
  508.  
  509. ;--- interrupts
  510.  
  511.  Mov Ax, State_Area     ;control word
  512.  Shl Ax                 ;shift bit to high byte
  513.  And Ah, 1b             ;mask
  514.  Mov Bl, Ah
  515.  Sub Bh, Bh
  516.  Mov Cl, -8             ;width
  517.  Mov Dx, 10*256+66      ;display offset
  518.  Mov Di, Offset Dissta6b        ;table
  519.  Call Display_Istr              ;display string
  520.  
  521. ;--- show stack data
  522.  
  523.  Call Display_Stack     ;show stack values
  524.  Ret
  525.  
  526. ;--- data
  527.  
  528. Dissta1a Db '>',0, '<',0, '=',0, '?',0
  529. Dissta1b Dw Offset Dissta1a, Offset Dissta1a+2,
  530.          Dw Offset Dissta1a+4, Offset Dissta1a+6
  531.  
  532. Dissta2a Db '+',0, '-',0, '0',0, '?',0
  533. Dissta2b Dw Offset Dissta2a, Offset Dissta2a+2,
  534.          Dw Offset Dissta2a+4, Offset Dissta2a+6
  535.  
  536. Dissta3a Db '24',0, '??',0, '53',0, '64',0
  537. Dissta3b Dw Offset Dissta3a, Offset Dissta3a+3,
  538.          Dw Offset Dissta3a+6, Offset Dissta3a+9
  539.  
  540. Dissta4a Db 'Near',0, 'Up',0, 'Down',0, 'Trunc',0
  541. Dissta4b Dw Offset Dissta4a, Offset Dissta4a+5,
  542.          Dw Offset Dissta4a+8, Offset Dissta4a+13
  543.  
  544. Dissta5a Db 'Proj',0, 'Affin',0
  545. Dissta5b Dw Offset Dissta5a, Offset Dissta5a+5
  546.  
  547. Dissta6a Db 'Enabled',0, 'Disabled',0
  548. Dissta6b Dw Offset Dissta6a, Offset Dissta6a+8
  549.  Endp           ;Display_State
  550.  
  551. ;================================================
  552. ; Display of the settings of six consecutive
  553. ; bits.
  554. ;
  555. ; In: AL= bit pattern; DX= row and column display
  556. ; offset.
  557.  
  558. Display_Bits Proc Near
  559.  Mov Ah, Al
  560.  Mov Bh, 20h                    ;first bit to check
  561.  Mov Cx, 6                      ;bits to check
  562.  Add Dx, StartRow*256+StartCol  ;real screen location
  563.  
  564. ;--- loop for each bit
  565.  
  566. Disbit1
  567.  Mov Al, '-'    ;not set sign
  568.  Test Ah, Bh    ;check if set
  569.  Jz Disbit2
  570.  Mov Al, '+'    ;set sign
  571.  
  572. Disbit2
  573.  Call Display_Char      ;display character
  574.  Shr Bh                 ;shift bit to test
  575.  Add Dl, 2              ;next location
  576.  Loop Disbit1
  577.  
  578.  Ret
  579.  Endp           ;Display_Bits
  580.  
  581. ;================================================
  582. ; Display the stack values.
  583.  
  584. Display_Stack Proc Near
  585.  Std
  586.  Mov Bx, Offset State_Area      ;save area
  587.  Add Bx, 14                     ;skip to numbers
  588.  Mov Cx, 8                      ;8087 stack entries
  589.  Mov Dh, StartRow+1             ;first display row
  590.  
  591. ;=== display a number
  592.  
  593. Disstk1
  594.  Push Bx
  595.  Push Cx
  596.  
  597.  Fld Tbyte [Bx]         ;load number
  598.  
  599. ;--- get number type or set to empty
  600.  
  601.  Push Cx                ;save stack number
  602.  Call Get_Stack         ;get the stack top
  603.  Mov Cl, Al
  604.  Mov Ax, State_Area+4   ;get the tag word
  605.  Shl Cl                 ;two bits for each tag
  606.  Ror Ax, Cl             ;adjust so first tag is in low bits
  607.  Pop Cx
  608.  Mov Ch, 8
  609.  Sub Ch, Cl
  610.  Shl Ch                 ;bits to shift to put set tag low
  611.  Mov Cl, Ch
  612.  Shr Ax, Cl             ;tag bits to lower bit locations 0 and 1
  613.  And Ax, 11b            ;mask bits
  614.  
  615. ;--- check type
  616.  
  617.  Cmp Ax, 11b            ;check if empty
  618.  Je Disstk2
  619.  
  620.  Fxam                   ;check number type
  621.  Fstsw Status87         ;store status
  622.  
  623.  Cmp Ax, 10b            ;check if special
  624.  Je Disstk3             ;jump if so
  625.  
  626. ;--- normal value
  627.  
  628.  Call Display_Float     ;display decimal number
  629.  Jmps Disstk4
  630.  
  631. ;--- empty
  632.  
  633. Disstk2
  634.  Mov Status87, 0ffffh   ;set all bits
  635.  
  636. ;--- special number
  637.  
  638. Disstk3
  639.  Call Display_Hex       ;display hexadecimal bit pattern
  640.  
  641. ;--- finished with a single stack number
  642.  
  643. Disstk4
  644.  Mov Al, Byte Status87+1        ;high byte of status
  645.  Call Display_Exam              ;display
  646.  Pop Cx
  647.  Pop Bx
  648.  
  649.  Add Bx, 10             ;next stack entry
  650.  Inc Dh                 ;next row
  651.  Loop Disstk1           ;loop for each entry
  652.  
  653.  Cld
  654.  Ret
  655.  Endp           ;Display_Stack
  656.  
  657. ;================================================
  658. ; Display a decimal floating point number.
  659. ;
  660. ; In: ST(0)= number; DH= row.
  661. ;
  662. ; Out: DX= row and column one space after number.
  663.  
  664. Display_Float Proc Near
  665.  
  666. ;--- convert number and store
  667.  
  668.  Mov Ax, Sig_Bits               ;number of significant bits
  669.  Call Flt2dec                   ;convert to decimal
  670.  Mov Si, Offset Number_Store    ;storage for number
  671.  Fbstp Tbyte [Si]               ;save number string
  672.  
  673. ;--- display the mantissa sign
  674.  
  675.  Push Ax                ;save the exponent
  676.  Mov Dl, StartCol+40    ;column
  677.  
  678.  Add Si, 9              ;goto last byte
  679.  Lodsb                  ;get the sign byte
  680.  Mov Ah, '+'
  681.  Test Al, 80h           ;check if negative
  682.  Jz Disflt1
  683.  Mov Ah, '-'
  684. Disflt1
  685.  Mov Al, Ah             ;sign
  686.  Call Display_Char      ;display character
  687.  
  688. ;--- first two digits and decimal point
  689.  
  690.  Lodsb
  691.  Call Display_Bhi       ;high digit
  692.  Push Ax
  693.  Mov Al, '.'            ;decimal point
  694.  Call Display_Char      ;write point
  695.  Pop Ax
  696.  Call Display_Blo       ;low digit
  697.  
  698. ;--- remaining mantissa digits
  699.  
  700.  Mov Cx, 8              ;remaining number of packed bytes
  701.  
  702. Disflt2
  703.  Lodsb
  704.  Call Display_Bhi       ;high digit
  705.  Call Display_Blo       ;low digit
  706.  Loop Disflt2
  707.  
  708. ;--- exponent sign
  709.  
  710.  Pop Ax
  711.  Inc Dl                 ;skip to exponent location
  712.  
  713.  Mov Cl, '+'            ;plus
  714.  Add Ax, 17             ;adjust for decimal point
  715.  Jns Disflt3            ;jump if not minus
  716.  Mov Cl, '-'            ;minus
  717.  Neg Ax
  718. Disflt3
  719.  Push Ax
  720.  Mov Al, Cl
  721.  Call Display_Char      ;display
  722.  Pop Ax
  723.  
  724. ;--- exponent
  725.  
  726.  Sub Bx, Bx             ;clear high word
  727.  Mov Cx, 5*256+10       ;load width and base
  728.  Call Display_Number    ;display
  729.  Add Dl, 6              ;position cursor at end
  730.  Ret
  731.  
  732. ;------------------------------------------------
  733. ; Display a high packed BCD digit.
  734. ;
  735. ; In: AL= packed BCD digits; BL= attribute.
  736.  
  737. Display_Bhi Proc Near
  738.  Push Ax
  739.  Shr Al
  740.  Shr Al
  741.  Shr Al
  742.  Shr Al                 ;shift the high bits
  743.  Add Al, '0'            ;convert to decimal digit
  744.  Call Display_Char      ;write point
  745.  Pop Ax
  746.  Ret
  747.  Endp           ;Display_Bhi
  748.  
  749. ;------------------------------------------------
  750. ; Display a low packed BCD digit.
  751. ;
  752. ; In: AL= packed BCD digits; BL= attribute.
  753.  
  754. Display_Blo Proc Near
  755.  Push Ax
  756.  And Al, 0fh            ;mask relevant bits
  757.  Add Al, '0'            ;convert to decimal digit
  758.  Call Display_Char      ;write point
  759.  Pop Ax
  760.  Ret
  761.  Endp                   ;Display_Blo
  762.  
  763.  Endp                   ;Display_Float
  764.  
  765. ;================================================
  766. ; Display the bit pattern of a floating point
  767. ; number.
  768. ;
  769. ; In: ST(0)= number; DH= row.
  770. ;
  771. ; Out: DX= row and column one space after number.
  772.  
  773. Display_Hex Proc Near
  774.  Fstp Dishex1           ;store number
  775.  Fwait                  ;wait just in case
  776.  
  777.  Mov Al, '='            ;starting character
  778.  Mov Dl, StartCol+43    ;column
  779.  Call Display_Char      ;display
  780.  
  781.  Mov Cx, 8              ;bytes
  782.  Lea Si, Dishex1+7      ;last byte of mantissa
  783.  Call Display_Byts      ;display
  784.  
  785.  Mov Al, '='            ;starting character
  786.  Add Dl, 2              ;column
  787.  Call Display_Char      ;display
  788.  
  789.  Mov Cx, 2              ;bytes
  790.  Lea Si, Dishex1+9      ;last byte of exponent
  791.  Call Display_Byts      ;display
  792.  
  793.  Inc Dl                 ;next column
  794.  Ret
  795.  
  796. ;--- storage for the tempory real number
  797.  
  798. Dishex1 Label Tbyte
  799.  Ds 10
  800.  
  801. ;------------------------------------------------
  802. ; Display backwards bytes.
  803. ;
  804. ; In: SI= starting location; CX= bytes.
  805.  
  806. Display_Byts Proc Near
  807.  Pushf
  808.  Std
  809.  Sub Ah, Ah             ;clear high byte
  810.  Sub Bx, Bx             ;clear high word
  811.  
  812. Disbys1
  813.  Lodsb                  ;load byte
  814.  Push Cx
  815.  Push Si
  816.  Mov Cx, 2*256+16       ;format
  817.  Call Display_Number    ;display
  818.  Add Dl, 2              ;next location
  819.  Pop Si
  820.  Pop Cx
  821.  Loop Disbys1           ;loop for each byte
  822.  Popf
  823.  Ret
  824.  Endp                   ;Display_Byts
  825.  
  826.  Endp                   ;Display_Hex
  827.  
  828. ;================================================
  829. ; Display an FXAM result.
  830. ;
  831. ; In: AL= high byte of 8087 status; DX= row and
  832. ; column location.
  833.  
  834. Display_Exam Proc Near
  835.  Call Adjst_Codes               ;adjust the condition codes
  836.  Mov Bx, Ax
  837.  Mov Cl, 6                      ;width
  838.  Mov Di, Offset Disexm1b        ;table
  839.  Call Display_Istr              ;display string
  840.  Ret
  841.  
  842. ;--- data
  843.  
  844. Disexm1a Db '+Unorm',0, '+NAN',0, '-Unorm',0, '-NAN',0,
  845.          Db '+Norm',0, '+Infin',0, '-Norm',0, '-Infin',0,
  846.          Db '+0',0, '-0',0, '+Dnorm',0, '-Dnorm',0, 'Empty',0
  847. Disexm1b Dw Offset Disexm1a, Offset Disexm1a+7,
  848.          Dw Offset Disexm1a+12, Offset Disexm1a+19
  849.          Dw Offset Disexm1a+24, Offset Disexm1a+30
  850.          Dw Offset Disexm1a+37, Offset Disexm1a+43
  851.          Dw Offset Disexm1a+50, Offset Disexm1a+70
  852.          Dw Offset Disexm1a+53, Offset Disexm1a+70
  853.          Dw Offset Disexm1a+56, Offset Disexm1a+70
  854.          Dw Offset Disexm1a+63, Offset Disexm1a+70
  855.  
  856.  Endp           ;Display_Exam
  857.  
  858. ;================================================
  859. ; Get the stack top number.
  860. ;
  861. ; Out: AL= stack number.
  862.  
  863. Get_Stack Proc Near
  864.  Mov Al, State_Area+3   ;get the high byte of the status word
  865.  And Al, 00111000b      ;mask out stack
  866.  Shr Al
  867.  Shr Al
  868.  Shr Al                 ;adjust
  869.  Ret
  870.  Endp           ;Get_Stack
  871.  
  872. ;================================================
  873. ; Adjust the condition codes to consecutive bits.
  874. ;
  875. ; In: AL= high byte of status.
  876. ; Out: AX= condition codes in consecutive, least
  877. ; significant bit locations.
  878.  
  879. Adjst_Codes Proc Near
  880.  Mov Ah, Al
  881.  And Al, 00000111b      ;mask C2 to C0 bits
  882.  And Ah, 01000000b      ;mask C3 bit
  883.  Shr Ah
  884.  Shr Ah
  885.  Shr Ah                 ;shift bit over
  886.  Or Al, Ah              ;combine
  887.  Sub Ah, Ah
  888.  Ret
  889.  Endp           ;Adjst_Codes
  890.  
  891. ;================================================
  892. ; Get an index for the comparison and test
  893. ; instructions. Based on the condition codes.
  894. ;
  895. ; Out: BX= index.
  896.  
  897. Get_Comp Proc Near
  898.  Sub Bx, Bx
  899.  Mov Al, State_Area+3   ;high byte of state
  900.  And Al, 01000101b      ;mask C3 C2 and C0
  901.  Cmp Al, 00000000b      ;check if 0 0 0
  902.  Je Getcom1
  903.  Inc Bx
  904.  Cmp Al, 00000001b      ;check if 0 0 1
  905.  Je Getcom1
  906.  Inc Bx
  907.  Cmp Al, 01000000b      ;check if 1 0 0
  908.  Je Getcom1
  909.  Inc Bx
  910.  
  911. Getcom1 Ret
  912.  Endp           ;Get_Comp
  913.  
  914. ;================================================
  915. ; Display a single character.
  916. ;
  917. ; In: AL= character; DX= location.
  918.  
  919. Display_Char Proc Near
  920.  Mov Bl, Atr_Set        ;attribute
  921.  Call Video_Cset        ;set cursor location
  922.  Call Video_Wchr        ;write character
  923.  Inc Dl                 ;next column
  924.  Ret
  925.  Endp                   ;Display_Char
  926.  
  927. ;================================================
  928. ; Display a zero padded number to a location.
  929. ;
  930. ; In: BX:AX= number; CL= number base; CH= the
  931. ; display width; DX= location.
  932.  
  933. Display_Number Proc Near
  934.  Push Ax
  935.  Push Cx
  936.  Push Dx
  937.  Add Dx, StartRow*256+StartCol  ;real screen location
  938.  Call Video_Cset                ;move cursor
  939.  
  940.  Push Cx
  941.  Sub Ch, Ch
  942.  Mov Dx, Bx                     ;high word
  943.  Mov Di, Offset Number_Store    ;place to store
  944.  Call Convert_Num               ;convert to string
  945.  Pop Cx
  946.  
  947.  Mov Al, '0'            ;pad character
  948.  Mov Cl, Ch
  949.  Sub Ch, Ch
  950.  Mov Si, Di
  951.  Call Video_Wstrr       ;display number
  952.  Pop Dx
  953.  Pop Cx
  954.  Pop Ax
  955.  Ret
  956.  Endp           ;Display_Number
  957.  
  958. ;================================================
  959. ; Given an index and a table, displays a space
  960. ; padded string to a location.
  961. ;
  962. ; In: BX= index; DI= table offset; CL= width, if
  963. ; negative, the string is right justified instead
  964. ; of left; DX= location.
  965.  
  966. Display_Istr Proc Near
  967.  Push Ax
  968.  Push Bx
  969.  Push Cx
  970.  Push Dx
  971.  Push Si
  972.  
  973. ;--- locate cursor
  974.  
  975.  Add Dx, StartRow*256+StartCol  ;real screen location
  976.  Call Video_Cset                ;move cursor
  977.  
  978. ;--- display string
  979.  
  980.  Mov Al, ' '            ;pad with spaces
  981.  Shl Bx                 ;two bytes for offset
  982.  Sub Ch, Ch
  983.  Mov Si, [Di+Bx]        ;get the string location
  984.  
  985.  Cmp Cl, 0
  986.  Jg Disist1
  987.  
  988.  Neg Cl                 ;absolute value
  989.  Call Video_Wstrl       ;display, left justified
  990.  Jmps Disist2
  991.  
  992. Disist1
  993.  Call Video_Wstrr       ;display, right justified
  994.  
  995. Disist2
  996.  Pop Si
  997.  Pop Dx
  998.  Pop Cx
  999.  Pop Bx
  1000.  Pop Ax
  1001.  Ret
  1002.  Endp           ;Display_Istr
  1003.  
  1004. ;================================================
  1005. ; External files.
  1006.  
  1007.  Include 'Video1.Inc'
  1008.  Include 'Video2.Inc'
  1009.  Include 'Convert1.Inc'
  1010.  Include 'Convert2.Inc'
  1011.  
  1012. ;================================================
  1013. ; Data.
  1014.  
  1015. ;--- program status
  1016.  
  1017. Status1 Equ 01h         ;execute in memory resident mode
  1018.  
  1019. Status Db 0
  1020.  
  1021. ;--- original interrupt 16H
  1022.  
  1023. Original16 Label Dword
  1024.  Dw ?                   ;offset
  1025.  Dw ?                   ;segment
  1026.  
  1027. ;--- shell parameter block
  1028.  
  1029. Parameter_Blk Label Word
  1030.  Dw 0                           ;use default environment
  1031.  Dw Offset CmdTail              ;command tail
  1032.  Dw ?                           ;present segment
  1033.  Dw -1                  ;
  1034.  Dw -1                  ;
  1035.  Dw -1                  ;-- no FCB'S
  1036.  Dw -1                  ;
  1037.  
  1038. CmdTail Db 0, 13
  1039.  
  1040. ;--- saved stack addresses
  1041.  
  1042. Prog_Off Dw ?           ;-- save area through EXEC function
  1043. Prog_Seg Dw ?           ;
  1044.  
  1045. Stack_Off Dw ?          ;-- save area for alternate int 16
  1046. Stack_Seg Dw ?          ;
  1047.  
  1048. ;--- other data
  1049.  
  1050. CmdLoc Dw ?             ;offset of command processor in environment
  1051. Intfunc Db ?            ;int 16 request
  1052. CurLoc Dw ?             ;saved cursor location
  1053.  
  1054. ;--- main display string
  1055.                                               
  1056. Display1 Label Byte
  1057.  Db FrmAtr, Atr_Bor
  1058.  Db FrmLoc, StartRow, StartCol, 219, FrmHor, 223, Cols-2, 219
  1059.  Db FrmLoc, StartRow+1, StartCol, FrmVer, 219, Rows-2
  1060.  Db FrmLoc, StartRow+1, StartCol+Cols-1, FrmVer, 219, Rows-2
  1061.  Db FrmLoc, StartRow+Rows-1, StartCol, 219, FrmHor, 220, Cols-2, 219
  1062.  
  1063.  Db FrmAtr, Atr_Lin
  1064.  Db FrmLoc, StartRow+9, StartCol+2, FrmHor, 196, 72
  1065.  Db FrmLoc, StartRow+1, StartCol+32, FrmVer, 179, 8, 193
  1066. ;this prints some other lines, but I decided it looked better without them
  1067. ; Db FrmLoc, StartRow+1, StartCol+17, FrmVer, 179, 8
  1068. ; Db FrmLoc, StartRow+7, StartCol+2, FrmHor, 196, 15, 180
  1069. ; Db FrmLoc, StartRow+4, StartCol+17, 195, FrmHor, 196, 13
  1070.  
  1071.  Db FrmAtr, Atr_Mes
  1072.  Db FrmLoc, StartRow+1, StartCol, '8'
  1073.  Db FrmLoc, StartRow+2, StartCol, '0'
  1074.  Db FrmLoc, StartRow+3, StartCol, '8'
  1075.  Db FrmLoc, StartRow+4, StartCol, '7'
  1076.  Db FrmLoc, StartRow+6, StartCol, 'S'
  1077.  Db FrmLoc, StartRow+7, StartCol, 'T'
  1078.  Db FrmLoc, StartRow+8, StartCol, 'A'
  1079.  Db FrmLoc, StartRow+9, StartCol, 'T'
  1080.  Db FrmLoc, StartRow+10, StartCol, 'E'
  1081.  
  1082.  Db FrmLoc, StartRow+1, StartCol+Cols-1, 'S'
  1083.  Db FrmLoc, StartRow+2, StartCol+Cols-1, 'H'
  1084.  Db FrmLoc, StartRow+3, StartCol+Cols-1, 'O'
  1085.  Db FrmLoc, StartRow+4, StartCol+Cols-1, 'W'
  1086.  Db FrmLoc, StartRow+5, StartCol+Cols-1, '8'
  1087.  Db FrmLoc, StartRow+6, StartCol+Cols-1, '7'
  1088.  Db FrmLoc, StartRow+8, StartCol+Cols-1, Ver_Hi\10+'0'
  1089.  Db FrmLoc, StartRow+9, StartCol+Cols-1, Ver_Lo/10+'0'
  1090.  Db FrmLoc, StartRow+10, StartCol+Cols-1, Ver_Lo\10+'0'
  1091.  
  1092.  Db FrmAtr, Atr_Tex
  1093.  Db FrmLoc, StartRow+1, StartCol+2, 'Ins Ptr'
  1094.  Db FrmLoc, StartRow+2, StartCol+2, 'Opr Ptr'
  1095.  Db FrmLoc, StartRow+3, StartCol+2, 'Op Code'
  1096.  Db FrmLoc, StartRow+4, StartCol+2, 'Control'
  1097.  Db FrmLoc, StartRow+5, StartCol+2, 'Status'
  1098.  Db FrmLoc, StartRow+6, StartCol+2, 'Tag'
  1099.  
  1100.  Db FrmLoc, StartRow+8, StartCol+2, 'Stack Top'
  1101.  
  1102.  Db FrmLoc, StartRow+1, StartCol+19, 'Prec'
  1103.  Db FrmLoc, StartRow+2, StartCol+19, 'Round'
  1104.  Db FrmLoc, StartRow+3, StartCol+19, 'Infin'
  1105.  
  1106.  Db FrmLoc, StartRow+5, StartCol+19, 'Cond'
  1107.  Db FrmLoc, StartRow+6, StartCol+19, 'Comp'
  1108.  Db FrmLoc, StartRow+7, StartCol+19, 'Test'
  1109.  Db FrmLoc, StartRow+8, StartCol+19, 'Exam'
  1110.  
  1111.  Db FrmLoc, StartRow+1, StartCol+34, 'ST(0)'
  1112.  Db FrmLoc, StartRow+2, StartCol+34, 'ST(1)'
  1113.  Db FrmLoc, StartRow+3, StartCol+34, 'ST(2)'
  1114.  Db FrmLoc, StartRow+4, StartCol+34, 'ST(3)'
  1115.  Db FrmLoc, StartRow+5, StartCol+34, 'ST(4)'
  1116.  Db FrmLoc, StartRow+6, StartCol+34, 'ST(5)'
  1117.  Db FrmLoc, StartRow+7, StartCol+34, 'ST(6)'
  1118.  Db FrmLoc, StartRow+8, StartCol+34, 'ST(7)'
  1119.  
  1120.  Db FrmLoc, StartRow+10, StartCol+2, 'Except'
  1121.  Db FrmLoc, StartRow+10, StartCol+9, FrmStr, Offset Display2
  1122.  Db FrmLoc, StartRow+10, StartCol+30, 'Intr Mask'
  1123.  Db FrmLoc, StartRow+10, StartCol+40, FrmStr, Offset Display2
  1124.  Db FrmLoc, StartRow+10, StartCol+61, 'Ints'
  1125.  
  1126.  
  1127.  Db FrmAtr, Atr_Set
  1128.  Db 0
  1129.  
  1130. Display2 Db 'P  U  O  Z  D  I', 0
  1131.  
  1132. ;--- exit message
  1133.  
  1134. Closemes Db 13,10,'SHOW87 is removed from memory.',13,10,'$'
  1135. Errormes Db 13,10,'Error: Could not install SHOW87', 13,10,'$'
  1136.  
  1137. ;================================================
  1138. ; Uninitialized data.
  1139.  
  1140. Save_Area Label Byte            ;screen data
  1141.  Org +(Rows * Cols * 2)
  1142. State_Area Label Anysize        ;area to save the 8087 state
  1143.  Org +94
  1144. Status87 Label Word             ;8087 status storage for checking numbers
  1145.  Org +2
  1146. Number_Store Label Byte         ;storage for decimal number strings
  1147.  Org +11
  1148.  Org +100h
  1149. Local_Stack Label Byte          ;local stack for state display
  1150.  Org +100h
  1151. Program_Stack Label Byte        ;main program stack
  1152.  
  1153.  Org Offset Save_Area   ;fix location
  1154.  
  1155. ;================================================
  1156. ; Transient code.  Exists in unitialized data 
  1157. ; area, must be executed before the data area is
  1158. ; used.
  1159.  
  1160. ;--- display opening message
  1161.  
  1162. Init
  1163.  Mov Dx, Offset Openmes         ;message
  1164.  Mov Ah, 9                      ;function
  1165.  Int 21h                        ;display
  1166.  
  1167. ;--- find command processor
  1168.  
  1169.  Push Es
  1170.  Mov Cx, 8              ;string length
  1171.  Sub Di, Di             ;starting offset of environment
  1172.  Mov Es, [2ch]          ;environment segment
  1173.  
  1174. ;--- loop for each string in the environment
  1175.  
  1176. Init1
  1177.  Es:
  1178.  Cmp Byte [Di], 0       ;check if end of environment
  1179.  Je Init8
  1180.  
  1181.  Mov Cx, 8              ;string length
  1182.  Mov Si, Offset Comspec ;string location
  1183.  
  1184.  Repe
  1185.  Cmpsb          ;compare bytes
  1186.  Je Init3       ;jump if found
  1187.  
  1188. Init2
  1189.  Es:
  1190.  Cmp Byte [Di-1], 0     ;see if stopped on end of string
  1191.  Je Init1
  1192.  Inc Di                 ;next byte
  1193.  Jmps Init2
  1194.  
  1195. Init3
  1196.  Mov CmdLoc, Di        ;save location
  1197.  Pop Es
  1198.  
  1199. ;--- set resident flag
  1200.  
  1201.  Mov Si, 80h            ;command tail
  1202.  Lodsb                  ;get the length
  1203.  Or Al, Al              ;check if none
  1204.  Jz Init6
  1205.  Mov Cl, Al
  1206.  Sub Ch, Ch             ;put count in CX
  1207.  
  1208. ;--- loop through characters in command tail
  1209.  
  1210. Init4
  1211.  Lodsb                  ;load next byte
  1212.  Cmp Al, '/'            ;check if switch
  1213.  Je Init7               ;jump if so
  1214. Init5
  1215.  Loop Init4             ;otherwise loop back
  1216.  
  1217. Init6
  1218.  Jmp Start
  1219.  
  1220. ;--- found slash
  1221.  
  1222. Init7
  1223.  Dec Cx                 ;reduce count
  1224.  Jz Init6               ;jump if no more bytes
  1225.  
  1226.  Lodsb                  ;load command character
  1227.  Sub Al, 'a'-'A'        ;convert to upper-case
  1228.  Cmp Al, 'R'            ;check if R
  1229.  Jne Init5              ;if not, go back to loop
  1230.  Xor Status, Status1    ;set (or clear) flag
  1231.  Jmp Start
  1232.  
  1233. ;--- could not find COMSPEC=
  1234.  
  1235. Init8
  1236.  Mov Dx, Offset Errormes        ;error message
  1237.  Mov Ah, 9                      ;function
  1238.  Int 21h                        ;show message
  1239.  
  1240.  Mov Ax, 4cffh          ;exit function
  1241.  Int 21h                ;execute
  1242.  
  1243. ;--- transient data
  1244.  
  1245. Openmes Db 13,10
  1246.         Db 'SHOW87, Version '
  1247.         Db Ver_Hi\10+'0', '.', Ver_Lo/10+'0', Ver_Lo\10+'0', 13, 10
  1248.         Db 'Copyright (c) 1987-1988 Eric Tauck',13,10
  1249.         Db 'All rights reserved',13,10,'$'
  1250.  
  1251. ;--- command environment string
  1252.  
  1253. Comspec Db 'COMSPEC='
  1254.