;****************************************************************************
;       DOS32  DOS   EXTENDER
;
;    Example program demonstrating the Debugger.
;
; See DOS32 documentaion for details on Debug32.
;
;
; to build type;
;
;      tasm example.asm
;      dlink -c example.obj,,,debug.lib
;
;  Don't forget to link in DEBUG.LIB
;
;
;
;****************************************************************************
.386p
.387
.model flat,c
.stack 65*1024                                   ; Define a 65Kb stack

assume gs:_TEXT,fs:_TEXT                         ; For some reson the
                                                 ; assembler needs this line


EXTRN   Debug   :Near                           ; Define external symbol
extrn  syscall print_float2:near


.DATA?
My_Array                DD 8000h dup (?)


.CODE

_48bit_pointer  df   00

Program_base    dd   ?
My_varible      db   0

g1 db '11111111111111$'
g2 db '11111111111111$'
buf db 32 dup('y')

tmpee dw 0


;---labels only for x87 opcode parade
shorts     label dword
shortreals label dword
shortreal  label dword
shortarray label dword
mem16      label word
int16      label word
warray     label word
darray     label dword
double     label dword
doubles    label dword
longreal   label qword
longs      label qword
quads      label qword
longint    label qword
tempreal   label tbyte
tempreals  label tbyte
packbcd    label tbyte
bcds       label tbyte
ctrlword   label word
statword   label word
cobuffer   label word

test_big dt 8.80E-3
test_80f dt 8.80
test_64f dq 64.64
test_32f dd 32.32
test_16i dw 16

Intro_mesg   db    'Press any key to start the debugger ',10,13,36

Start32:                                        ; Start of program
public main
main:

;
;  Print intro message
;
        mov     edx,offset Intro_mesg
        mov     ah,9
        int     21h

        mov      ah,0
        int      16h


;
;  Must start the debugger with a call.
;

ww:



        call    Debug
        jmp     L224


        jz L223
        jc L223
        jo L223
        js L223
        nop
nop
nop
L223:
        jnz  ww

L224:

        finit
        fld test_big
        fld test_64f
        fld test_32f
;        mov eax,offset test_big
;        mov edx,offset buf
;        call print_float2


        jmp L225
;************* x87 instruction parade: to test the opcode decode routine
;??? all addressing that contains bx, bp, di or si all garbage-extended to
;    ebx, ebp, edi, and esi. Is this decoder bug, or masm 6.0 bug?
;    In some addressing below, I was forced to use 32-bit regs, otherwise
;    the code won't compile.


;taken directly from masm's alang.hlp's x87 examples
 f2xm1
 fabs
 fadd   st,st(2)
 fadd   st(5),st
 fadd
 faddp  st(6),st
 fadd   QWORD PTR fs:[ebx*8+edx]
 fadd   shortreal
 fiadd  int16
 fiadd  warray[edi]
 fiadd  double
 fchs
 fclex
 fcom   st(2)
 fcom
 fcomp  st(7)
 fcomp
 fcompp
 fcom   shortreals[edi]
 fcom   longreal
 fcomp  longreal
 fcomp  shorts[edi]
 ficom  double
 ficom  warray[edi]
 ficomp WORD PTR [ebp+6]
 ficomp darray[edi]
 fsin
 fcos
 fsincos
 fincstp  ;??? decoded as ftstenv st(7)
 fdecstp  ;??? decoded as ftstenv st(6)
 fdisi    ;??? not recognized (you don't include this in opcodes.inc)
 feni     ;??? not recognized (ditto)
 fdiv   st,st(2)   ;??? not recognized
 fdiv   st(5),st   ;??? not recognized
 fdiv
 fdivp  st(6),st
 fdiv   DWORD PTR [ebx]
 fdiv   shortreal[edi]
 fdiv   longreal        ;??? not recognized
 fidiv  int16
 fidiv  warray[edi]
 fidiv  double
 fdivr  st,st(2)
 fdivr  st(5),st
 fdivr
 fdivrp st(6),st
 fdivr  longreal
 fdivr  shortreal[edi]
 fidivr double
 fidivr warray[edi]
 ffree  st(3)           ;??? decoded as fld st(3)
 finit
 fld   st(3)
 fld   longreal
 fld   shortarray[ebx+edi]
 fld   tempreal
 fild  mem16
 fild  DWORD PTR [ebx]
 fild  quads[esi]
 fbld  packbcd
 fld1
 fldz
 fldpi
 fldl2e
 fldl2t
 fldlg2
 fldln2
 fldcw  ctrlword
 fstcw  ctrlword
 fldenv [ebp+10]
 fstenv [ebp-14]
 fmul   st,st(2)
 fmul   st(5),st
 fmul
 fmulp  st(6),st
 fmul   DWORD PTR [ebx]
 fmul   shortreal[edi+3]
 fmul   longreal
 fimul  int16
 fimul  warray[edi]
 fimul  double
 fnop
 fpatan
 fptan
 fprem
 fprem1
 frndint
 fsave  [ebp-94]
 fsave  cobuffer
 frstor [ebp-94]
 fscale
 fsetpm           ;??? decoded as finit
 fsqrt
 fst    st(6)
 fst    st
 fstp   st
 fstp   st(3)
 fst    shortreal
 fst    longs[ebx]
 fstp   longreal
 fstp   tempreals[ebx]
 fist   int16
 fist   doubles[8]
 fistp  longint
 fistp  doubles[ebx]      ;??? decoded as fstp doubles[ebx]
 fbstp  bcds[ebx]
 fstsw  statword
 fstsw  ax               ;??? decoded as fbld st(0)
 fsub   st,st(2)         ;??? decoded as fsub st(2)
 fsub   st(5),st
 fsub
 fsubp  st(6),st
 fsub   longreal
 fsub   shortreals[edi]
 fisub  double
 fisub  warray[edi]
 fsubr  st,st(2)
 fsubr  st(5),st
 fsubr
 fsubrp st(6),st
 fsubr  QWORD PTR [ebx]
 fsubr  shortreal[edi]
 fsubr  longreal
 fisubr int16
 fisubr warray[edi]
 fisubr double
 ftst
 fucom  st(2)
 fucom
 fucomp st(7)
 fucomp
 fucompp     ;??? detected as fisubr st(1)
 fwait
 fxam
 fxch   st(3)
 fxch
 fxtract
 fyl2x
 fyl2xp1
;************* end of decode test

L225:

        mov     ax,0EE02h
        int     31h
        nop
        nop
        mov     Program_base,ebx
        cbw
        cwd
        cwde
        cdq

        imul    eax,ebx,12345678h
        mov     edx,offset test_32f

;        fldenv [edx]
;        fld    [edx]

        fdiv   st,st(2)
        fdiv   st(2),st
        fdivr   st,st(2)
        fdivr   st(2),st

        fsub   st,st(2)
        fsub   st(2),st
        fsubr   st,st(2)
        fsubr   st(2),st

        fld     test_32f
        fld     test_64f
        fld     test_80f
        fild     test_16i
        fild     test_32f
        fild     test_64f
        fld     st(0)
        fld     st(1)
        fld     st(7)

        fst     test_32f
        fst     test_64f
        fst     st(0)
        fst     st(1)
        fst     st(7)
        fbld   test_80f



        push    ds
        pop     ds


        mov   edx,offset  g1
        mov   ah,9
        int   21h
        mov   edx,offset  g2
        int   21h


            mov ax,0
            mov fs,ax


;
;       Some instrucions just to show off the debugger.
;


        xor     eax,eax
        mov     edi,Offset My_Array
        xor     eax,eax
        mov     ecx,30
        cld

        rep     stosd


        mov     eax,1
        mov     ebp,2
        mov     ecx,3
        mov     edx,4
        mov     edi,5
        mov     esi,6
        mov     ebp,7

        pushad

        mov     ecx,10
        loop $

        push    00000000h
        push    11111111h
        push    22222222h
        push    33333333h

        mov     eax,ds:[1]
     ;   int     3                        ; put in a breakpoint
        mov     eax,ds:[2]

        call    test_proc

        sub     edx,edx                 ; Load NUL selectors in FS and ES
        mov     fs,dx
        mov     es,dx
        stc
        std
        clc
        sti
        nop
        mov     edx,-1
        mov     ebp,1
        movzx   eax,word ptr gs:[edx+2*ebp+00000004ah]
        mov     edx,eax

        lea     eax,fs:[edx+ebp*8+333]
      ;  mov     ax,word ptr [bx+di]
        imul    eax,ebx,12345678h

        mov     dword ptr _48bit_pointer,offset  far_jump
        mov     word ptr _48bit_pointer+4,cs


        jmp     fword ptr cs:[_48bit_pointer]



test_proc       proc
        stc
        std
        clc
        sti
        nop
        smsw  dx
        ret
test_proc       endp





far_jump:





;
;  Load in the debug registers and set breakpoint registers 0 and 2.
;


    ;
    ;  Load DR0 with breakpoint address
    ;
        mov     eax,offset My_varible  ; first get offset and add the
        add     eax,Program_base       ; segment base to give linear address.
        mov     DR0,eax               ; Load 32bit Linear address

   ;
   ;  Load DR2 with breakpoint address
   ;

        mov     eax,offset  brkpt2    ; first get offset and add the
        add     eax,Program_base      ; segment base to give linear address
        mov     DR2,eax               ; Load 32bit Linear address


    ;
    ; Load   DR7      (See Intel docs for register description)
    ;

;                W0 = 1                W2 = 0
;                R0 = 1                R2 = 0
;                LEN0 = 0              LEN2 = 0
;                G0 = 1                G2 = 1
;                GE = 1
;                all other fields are zero

        mov     eax,000030222h
        mov     DR7,eax



;
;  Do some instrucions that should invoke the breakpoint registers.
;

        mov     ebp,2
        mov     ecx,3
        mov     edx,4
        mov     edi,5
brkpt2: mov     ebp,0          ;<- this instrucion will cause breakpoint 2
        mov     ecx,3
        mov     edx,4
        mov     edi,5
        mov     al,[My_varible]   ;<- this data read will cause breakpoint 0
        mov     esi,6
        mov     ebp,7

        mov     ah,4ch          ; Terminate  Program
        int     21h




END Start32

