Subversion Repositories Kolibri OS

Rev

Rev 410 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. format binary
  2. use32
  3.         db      'MENUET01'
  4.         dd      1
  5.         dd      start
  6.         dd      i_end
  7.         dd      used_mem
  8.         dd      used_mem
  9.         dd      i_param
  10.         dd      0
  11.  
  12. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GUI ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  15.  
  16. data_width equ 80
  17. data_x_pos equ 12
  18. data_x_size equ data_width*6
  19.  
  20. title_x_pos equ 30
  21. title_y_pos equ 32
  22. title_y_size equ 10
  23.  
  24. registers_x_pos equ data_x_pos
  25. registers_y_pos equ (title_y_pos + title_y_size)
  26. registers_y_size equ 30
  27.  
  28. dump_y_pos equ (registers_y_pos + registers_y_size + 5)
  29. dump_height equ 4
  30. dump_y_size equ (dump_height*10)
  31.  
  32. disasm_y_pos equ (dump_y_pos + dump_y_size + 4)
  33. disasm_height equ 16
  34. disasm_y_size equ (disasm_height*10)
  35.  
  36. messages_width equ data_width
  37. messages_height equ 12
  38. messages_x_pos equ data_x_pos
  39. messages_y_pos equ (disasm_y_pos + disasm_y_size + 4)
  40. messages_x_size equ messages_width*6
  41. messages_y_size equ messages_height*10
  42.  
  43. cmdline_width equ data_width
  44. cmdline_x_pos equ data_x_pos
  45. cmdline_y_pos equ (messages_y_pos + messages_y_size + 10)
  46. cmdline_x_size equ messages_x_size
  47. cmdline_y_size equ 10
  48.  
  49. wnd_x_size equ (data_x_pos + messages_x_size + data_x_pos)
  50. wnd_y_size equ (cmdline_y_pos + cmdline_y_size + data_x_pos)
  51.  
  52. start:
  53.         mov     edi, messages
  54.         mov     ecx, messages_width*messages_height
  55.         mov     al, ' '
  56.         rep     stosb
  57.         xor     eax, eax
  58.         mov     [messages_pos], eax
  59.         mov     [cmdline_len], eax
  60.         mov     [cmdline_pos], eax
  61.         mov     edi, needzerostart
  62.         mov     ecx, (needzeroend-needzerostart+3)/4
  63.         rep     stosd
  64.         mov     esi, begin_str
  65.         call    put_message_nodraw
  66. ; set event mask - default events and debugging events
  67.         push    40
  68.         pop     eax
  69.         mov     ebx, 0x107
  70.         int     40h
  71. ; set debug messages buffer
  72.         mov     ecx, dbgbufsize
  73.         mov     dword [ecx], 256
  74.         xor     ebx, ebx
  75.         mov     [ecx+4], ebx
  76.         mov     al, 69
  77.         int     40h
  78.         mov     esi, i_param
  79.         call    skip_spaces
  80.         test    al, al
  81.         jz      dodraw
  82.         push    esi
  83.         call    draw_window
  84.         pop     esi
  85.         call    OnLoadInit
  86.         jmp     waitevent
  87. dodraw:
  88.         call    draw_window
  89. waitevent:
  90.         push    10
  91.         pop     eax
  92.         int     40h
  93.         cmp     al, 9
  94.         jz      debugmsg
  95.         dec     eax
  96.         jz      dodraw
  97.         dec     eax
  98.         jz      keypressed
  99.         dec     eax
  100.         jnz     waitevent
  101. ; button pressed - we have only one button (close)
  102.         push    -1
  103.         pop     eax
  104.         int     40h
  105. keypressed:
  106.         mov     al, 2
  107.         int     40h
  108.         shr     eax, 8
  109.         cmp     al, 8
  110.         jz      .backspace
  111.         cmp     al, 0xB0
  112.         jz      .left
  113.         cmp     al, 0xB3
  114.         jz      .right
  115.         cmp     al, 0x0D
  116.         jz      .enter
  117.         cmp     al, 0xB6
  118.         jz      .del
  119.         cmp     al, 0xB4
  120.         jz      .home
  121.         cmp     al, 0xB5
  122.         jz      .end
  123.         cmp     al, 0xB1
  124.         jz      .down
  125.         cmp     al, 0xB2
  126.         jz      .up
  127.         cmp     al, 0xD8
  128.         jz      CtrlF7
  129.         cmp     al, 0xD9
  130.         jz      CtrlF8
  131.         cmp     [cmdline_len], cmdline_width
  132.         jae     waitevent
  133.         push    eax
  134.         call    clear_cmdline_end
  135.         pop     eax
  136.         mov     edi, cmdline
  137.         mov     ecx, [cmdline_len]
  138.         add     edi, ecx
  139.         lea     esi, [edi-1]
  140.         sub     ecx, [cmdline_pos]
  141.         std
  142.         rep     movsb
  143.         cld
  144.         stosb
  145.         inc     [cmdline_len]
  146.         call    draw_cmdline_end
  147.         inc     [cmdline_pos]
  148.         call    draw_cursor
  149.         jmp     waitevent
  150. .backspace:
  151.         cmp     [cmdline_pos], 0
  152.         jz      waitevent
  153.         dec     [cmdline_pos]
  154. .delchar:
  155.         call    clear_cmdline_end
  156.         mov     edi, [cmdline_pos]
  157.         dec     [cmdline_len]
  158.         mov     ecx, [cmdline_len]
  159.         sub     ecx, edi
  160.         add     edi, cmdline
  161.         lea     esi, [edi+1]
  162.         rep     movsb
  163.         call    draw_cmdline_end
  164.         call    draw_cursor
  165.         jmp     waitevent
  166. .del:
  167.         mov     eax, [cmdline_pos]
  168.         cmp     eax, [cmdline_len]
  169.         jae     waitevent
  170.         jmp     .delchar
  171. .left:
  172.         cmp     [cmdline_pos], 0
  173.         jz      waitevent
  174.         call    hide_cursor
  175.         dec     [cmdline_pos]
  176.         call    draw_cursor
  177.         jmp     waitevent
  178. .right:
  179.         mov     eax, [cmdline_pos]
  180.         cmp     eax, [cmdline_len]
  181.         jae     waitevent
  182.         call    hide_cursor
  183.         inc     [cmdline_pos]
  184.         call    draw_cursor
  185.         jmp     waitevent
  186. .home:
  187.         call    hide_cursor
  188.         and     [cmdline_pos], 0
  189.         call    draw_cursor
  190.         jmp     waitevent
  191. .end:
  192.         call    hide_cursor
  193.         mov     eax, [cmdline_len]
  194.         mov     [cmdline_pos], eax
  195.         call    draw_cursor
  196. .up:
  197. .down:
  198.         jmp     waitevent
  199. .enter:
  200.         mov     ecx, [cmdline_len]
  201.         test    ecx, ecx
  202.         jz      waitevent
  203.         mov     esi, cmdline
  204.         mov     byte [esi+ecx], 0
  205.         and     [cmdline_pos], 0
  206.         push    esi
  207.         call    clear_cmdline_end
  208.         call    draw_cursor
  209.         pop     esi
  210.         and     [cmdline_len], 0
  211. ; skip leading spaces
  212.         call    skip_spaces
  213.         cmp     al, 0
  214.         jz      waitevent
  215. ; now esi points to command
  216.         push    esi
  217.         mov     esi, prompt
  218.         call    put_message_nodraw
  219.         pop     esi
  220.         push    esi
  221.         call    put_message_nodraw
  222. z1:     mov     esi, newline
  223.         call    put_message
  224.         pop     esi
  225.         push    esi
  226.         call    get_arg
  227.         mov     [curarg], esi
  228.         pop     edi
  229.         mov     esi, commands
  230.         call    find_cmd
  231.         mov     eax, aUnknownCommand
  232.         jc      .x11
  233. ; check command requirements
  234. ; flags field:
  235. ; &1: command may be called without parameters
  236. ; &2: command may be called with parameters
  237. ; &4: command may be called without loaded program
  238. ; &8: command may be called with loaded program
  239.         mov     eax, [esi+8]
  240.         mov     ecx, [curarg]
  241.         cmp     byte [ecx], 0
  242.         jz      .noargs
  243.         test    byte [esi+16], 2
  244.         jz      .x11
  245.         jmp     @f
  246. .noargs:
  247.         test    byte [esi+16], 1
  248.         jz      .x11
  249. @@:
  250.         cmp     [debuggee_pid], 0
  251.         jz      .nodebuggee
  252.         mov     eax, aAlreadyLoaded
  253.         test    byte [esi+16], 8
  254.         jz      .x11
  255.         jmp     .x9
  256. .nodebuggee:
  257.         mov     eax, need_debuggee
  258.         test    byte [esi+16], 4
  259.         jnz     .x9
  260. .x11:
  261.         xchg    esi, eax
  262.         call    put_message
  263. .x10:
  264.         jmp     waitevent
  265. .x9:
  266.         call    dword [esi+4]
  267.         jmp     .x10
  268.  
  269. find_cmd:
  270. ; all commands are case-insensitive
  271.         push    edi
  272. .x4:
  273.         mov     al, [edi]
  274.         cmp     al, 0
  275.         jz      .x5
  276.         cmp     al, 'A'
  277.         jb      @f
  278.         cmp     al, 'Z'
  279.         ja      @f
  280.         or      al, 20h
  281. @@:
  282.         stosb
  283.         jmp     .x4
  284. .x5:
  285. ; find command
  286.         pop     edi
  287. .x6:
  288.         cmp     dword [esi], 0
  289.         jz      .x7
  290.         push    esi
  291.         mov     esi, [esi]
  292.         lodsb
  293.         movzx   ecx, al
  294.         push    edi
  295.         repz    cmpsb
  296.         pop     edi
  297.         pop     esi
  298.         jz      .x8
  299.         add     esi, 17
  300.         jmp     .x6
  301. .x7:
  302.         stc
  303. .x8:
  304.         ret
  305.  
  306. get_arg:
  307.         lodsb
  308.         cmp     al, ' '
  309.         ja      get_arg
  310.         mov     byte [esi-1], 0
  311.         cmp     al, 0
  312.         jnz     skip_spaces
  313.         dec     esi
  314. skip_spaces:
  315.         lodsb
  316.         cmp     al, 0
  317.         jz      @f
  318.         cmp     al, ' '
  319.         jbe     skip_spaces
  320. @@:     dec     esi
  321.         ret
  322.  
  323. clear_cmdline_end:
  324.         mov     ebx, [cmdline_pos]
  325.         mov     ecx, [cmdline_len]
  326.         sub     ecx, ebx
  327.         push    13
  328.         pop     eax
  329.         imul    ebx, 6
  330.         imul    ecx, 6
  331.         inc     ecx
  332.         add     ebx, cmdline_x_pos
  333.         shl     ebx, 16
  334.         or      ebx, ecx
  335.         mov     ecx, cmdline_y_pos*10000h + cmdline_y_size
  336.         mov     edx, 0xFFFFFF
  337.         int     40h
  338.         ret
  339.  
  340. draw_cmdline:
  341.         xor     ebx, ebx
  342.         jmp     @f
  343. draw_cmdline_end:
  344.         mov     ebx, [cmdline_pos]
  345. @@:
  346.         mov     esi, [cmdline_len]
  347.         sub     esi, ebx
  348.         push    4
  349.         pop     eax
  350.         xor     ecx, ecx
  351.         lea     edx, [cmdline+ebx]
  352.         imul    ebx, 6
  353.         add     ebx, cmdline_x_pos
  354.         shl     ebx, 16
  355.         or      ebx, cmdline_y_pos+1
  356.         int     40h
  357.         ret
  358.  
  359. put_message_nodraw:
  360. ; in: esi->ASCIZ message
  361.         mov     edx, [messages_pos]
  362. .m:
  363.         lea     edi, [messages+edx]
  364. .l:
  365.         lodsb
  366.         cmp     al, 0
  367.         jz      .done
  368.         call    test_scroll
  369.         cmp     al, 10
  370.         jz      .newline
  371.         cmp     al, '%'
  372.         jnz     @f
  373.         cmp     dword [esp], z1
  374.         jnz     .format
  375. @@:
  376.         stosb
  377.         inc     edx
  378.         jmp     .l
  379. .newline:
  380.         push    edx
  381.         mov     ecx, messages_width
  382.         xor     eax, eax
  383.         xchg    eax, edx
  384.         div     ecx
  385.         xchg    eax, edx
  386.         pop     edx
  387.         test    eax, eax
  388.         jz      .m
  389.         sub     edx, eax
  390.         add     edx, ecx
  391.         jmp     .m
  392. .done:
  393.         mov     [messages_pos], edx
  394.         ret
  395. .format:
  396. ; at moment all format specs must be %<digit>X
  397.         lodsb   ; get <digit>
  398.         sub     al, '0'
  399.         movzx   ecx, al
  400.         lodsb
  401.         pop     eax
  402.         pop     ebp
  403.         push    eax
  404. ; write number in ebp with ecx digits
  405.         dec     ecx
  406.         shl     ecx, 2
  407. .writenibble:
  408.         push    ecx
  409.         call    test_scroll
  410.         pop     ecx
  411.         mov     eax, ebp
  412.         shr     eax, cl
  413.         and     al, 0xF
  414.         cmp     al, 10
  415.         sbb     al, 69h
  416.         das
  417.         stosb
  418.         inc     edx
  419.         sub     ecx, 4
  420.         jns     .writenibble
  421.         jmp     .l
  422.  
  423. test_scroll:
  424.         cmp     edx, messages_width*messages_height
  425.         jnz     .ret
  426.         push    esi
  427.         mov     edi, messages
  428.         lea     esi, [edi+messages_width]
  429.         mov     ecx, (messages_height-1)*messages_width/4
  430.         rep     movsd
  431.         push    eax
  432.         mov     al, ' '
  433.         push    edi
  434.         push    messages_width
  435.         pop     ecx
  436.         sub     edx, ecx
  437.         rep     stosb
  438.         pop     edi
  439.         pop     eax
  440.         pop     esi
  441. .ret:   ret
  442.  
  443. put_message:
  444.         call    put_message_nodraw
  445.  
  446. draw_messages:
  447.         push    13
  448.         pop     eax
  449.         mov     edx, 0xFFFFFF
  450.         mov     ebx, messages_x_pos*10000h+messages_x_size
  451.         mov     ecx, messages_y_pos*10000h+messages_y_size
  452.         int     40h
  453.         mov     edx, messages
  454.         push    messages_width
  455.         pop     esi
  456.         xor     ecx, ecx
  457.         mov     al, 4
  458.         mov     ebx, messages_x_pos*10000h+messages_y_pos
  459. @@:
  460.         int     40h
  461.         add     edx, esi
  462.         add     ebx, 10
  463.         cmp     edx, messages+messages_width*messages_height
  464.         jb      @b
  465.         ret
  466.  
  467. draw_cursor:
  468.         push    38
  469.         pop     eax
  470.         mov     ecx, cmdline_y_pos*10001h+cmdline_y_size-1
  471.         mov     ebx, [cmdline_pos]
  472.         imul    ebx, 6
  473.         add     ebx, cmdline_x_pos
  474.         mov     edx, ebx
  475.         shl     ebx, 16
  476.         or      ebx, edx
  477.         xor     edx, edx
  478.         int     40h
  479.         ret
  480. hide_cursor:
  481.         mov     ebx, [cmdline_pos]
  482.         push    13
  483.         pop     eax
  484.         imul    ebx, 6
  485.         add     ebx, cmdline_x_pos
  486.         shl     ebx, 16
  487.         inc     ebx
  488.         mov     ecx, cmdline_y_pos*10000h + cmdline_y_size
  489.         mov     edx, 0xFFFFFF
  490.         int     40h
  491.         mov     ebx, [cmdline_pos]
  492.         cmp     ebx, [cmdline_len]
  493.         jae     .ret
  494.         mov     al, 4
  495.         xor     ecx, ecx
  496.         lea     edx, [cmdline+ebx]
  497.         imul    ebx, 6
  498.         add     ebx, cmdline_x_pos
  499.         shl     ebx, 16
  500.         or      ebx, cmdline_y_pos+1
  501.         push    1
  502.         pop     esi
  503.         int     40h
  504. .ret:
  505.         ret
  506.  
  507. redraw_title:
  508.         push    13
  509.         pop     eax
  510.         mov     edx, 0xFFFFFF
  511.         mov     ebx, title_x_pos*10000h + data_x_pos+data_x_size-title_x_pos
  512.         mov     ecx, title_y_pos*10000h + title_y_size
  513.         int     40h
  514. draw_title:
  515.         mov     al, 38
  516.         mov     ebx, (data_x_pos-2)*10000h + title_x_pos-5
  517.         mov     ecx, (title_y_pos+5)*10001h
  518.         xor     edx, edx
  519.         int     40h
  520.         push    NoPrgLoaded_len
  521.         pop     esi
  522.         cmp     [debuggee_pid], 0
  523.         jz      @f
  524.         mov     esi, [prgname_len]
  525. @@:     imul    ebx, esi, 6
  526.         add     ebx, title_x_pos+4
  527.         shl     ebx, 16
  528.         mov     bx, data_x_pos+data_x_size-10-5-6*7
  529.         cmp     [bSuspended], 0
  530.         jz      @f
  531.         add     ebx, 6
  532. @@:
  533.         int     40h
  534.         mov     ebx, (data_x_pos+data_x_size-10+4)*0x10000 + data_x_pos+data_x_size+2
  535.         int     40h
  536.         mov     al, 4
  537.         mov     ebx, title_x_pos*10000h+title_y_pos
  538.         xor     ecx, ecx
  539.         mov     edx, NoPrgLoaded_str
  540.         cmp     [debuggee_pid], 0
  541.         jz      @f
  542.         mov     edx, [prgname_ptr]
  543. @@:
  544.         int     40h
  545.         cmp     [debuggee_pid], 0
  546.         jz      .nodebuggee
  547.         mov     ebx, (data_x_pos+data_x_size-10-6*7)*10000h + title_y_pos
  548.         mov     edx, aRunning
  549.         push    7
  550.         pop     esi
  551.         cmp     [bSuspended], 0
  552.         jz      @f
  553.         add     ebx, 6*10000h
  554.         mov     edx, aPaused
  555.         dec     esi
  556. @@:
  557.         int     40h
  558.         ret
  559. .nodebuggee:
  560.         mov     al, 38
  561.         mov     ebx, (data_x_pos+data_x_size-10-6*7-5)*0x10000 + data_x_pos+data_x_size+2
  562.         mov     ecx, (title_y_pos+5)*10001h
  563.         xor     edx, edx
  564.         jmp     @b
  565.  
  566. draw_register:
  567. ; in: esi->value, edx->string, ecx=string len, ebx=coord
  568.         push    edx
  569.         push    ecx
  570.         push    esi
  571.         mov     eax, esi
  572.         mov     esi, ecx
  573. ; color
  574.         mov     ecx, 808080h
  575.         cmp     [debuggee_pid], 0
  576.         jz      .cd
  577.         cmp     [bSuspended], 0
  578.         jz      .cd
  579.         xor     ecx, ecx
  580.         mov     edi, [eax]
  581.         cmp     dword [eax+oldcontext-context], edi
  582.         jz      .cd
  583.         mov     ecx, 0x00AA00
  584. .cd:
  585.         push    4
  586.         pop     eax
  587.         int     40h
  588.         imul    esi, 60000h
  589.         lea     edx, [ebx+esi]
  590.         mov     al, 47
  591.         mov     ebx, 80101h
  592.         mov     esi, ecx
  593.         pop     ecx
  594.         int     40h
  595.         lea     ebx, [edx+60000h*18]
  596.         mov     esi, ecx
  597.         pop     ecx
  598.         pop     edx
  599.         add     edx, ecx
  600.         ret
  601. draw_flag:
  602.         movzx   edi, byte [edx+7]
  603.         bt      [_eflags], edi
  604.         jc      .on
  605.         or      byte [edx], 20h
  606.         jmp     .onoff
  607. .on:
  608.         and     byte [edx], not 20h
  609. .onoff:
  610.         mov     ecx, 808080h
  611.         cmp     [debuggee_pid], 0
  612.         jz      .doit
  613.         cmp     [bSuspended], 0
  614.         jz      .doit
  615.         xor     ecx, ecx
  616.         bt      [_eflags], edi
  617.         lahf
  618.         bt      dword [_eflags + oldcontext - context], edi
  619.         rcl     ah, 1
  620.         test    ah, 3
  621.         jp      .doit
  622.         mov     ecx, 0x00AA00
  623. .doit:
  624.         mov     ah, 0
  625.         int     40h
  626.         ret
  627.  
  628. redraw_registers:
  629.         push    13
  630.         pop     eax
  631.         mov     edx, 0xFFFFFF
  632.         mov     ebx, data_x_pos*10000h + data_x_size
  633.         mov     ecx, registers_y_pos*10000h + registers_y_size
  634.         int     40h
  635. draw_registers:
  636.         mov     esi, _eax
  637.         push    4
  638.         pop     ecx
  639.         mov     edx, regs_strs
  640.         mov     ebx, registers_x_pos*10000h+registers_y_pos
  641.         call    draw_register
  642.         add     esi, _ebx-_eax
  643.         call    draw_register
  644.         add     esi, _ecx-_ebx
  645.         call    draw_register
  646.         add     esi, _edx-_ecx
  647.         call    draw_register
  648.         mov     ebx, registers_x_pos*10000h+registers_y_pos+10
  649.         add     esi, _esi-_edx
  650.         call    draw_register
  651.         add     esi, _edi-_esi
  652.         call    draw_register
  653.         add     esi, _ebp-_edi
  654.         call    draw_register
  655.         add     esi, _esp-_ebp
  656.         call    draw_register
  657.         mov     ebx, registers_x_pos*10000h+registers_y_pos+20
  658.         add     esi, _eip-_esp
  659.         call    draw_register
  660.         mov     cl, 7
  661.         add     esi, _eflags-_eip
  662.         call    draw_register
  663.         mov     al, 4
  664.         mov     ecx, 808080h
  665.         cmp     [debuggee_pid], 0
  666.         jz      @f
  667.         cmp     [bSuspended], 0
  668.         jz      @f
  669.         xor     ecx, ecx
  670. @@:
  671.         mov     edx, aColon
  672.         xor     esi, esi
  673.         inc     esi
  674.         mov     ebx, (registers_x_pos+37*6)*10000h + registers_y_pos+20
  675.         int     40h
  676.         mov     edx, flags
  677. @@:
  678.         add     ebx, 2*6*10000h
  679.         call    draw_flag
  680.         inc     edx
  681.         cmp     dl, flags_bits and 0xFF
  682.         jnz     @b
  683.         ret
  684.  
  685. redraw_dump:
  686.         push    13
  687.         pop     eax
  688.         mov     edx, 0xFFFFFF
  689.         mov     ebx, data_x_pos*10000h + data_x_size
  690.         mov     ecx, dump_y_pos*10000h + dump_y_size
  691.         int     40h
  692. draw_dump:
  693. ; addresses
  694.         mov     al, 47
  695.         mov     ebx, 80100h
  696.         mov     edx, data_x_pos*10000h + dump_y_pos
  697.         mov     ecx, [dumppos]
  698.         mov     esi, 808080h
  699.         cmp     [debuggee_pid], 0
  700.         jz      @f
  701.         cmp     [bSuspended], 0
  702.         jz      @f
  703.         xor     esi, esi
  704. @@:
  705.         int     40h
  706.         add     ecx, 10h
  707.         add     edx, 10
  708.         cmp     dl, dump_y_pos + dump_y_size
  709.         jb      @b
  710. ; hex dump of data
  711.         mov     ebx, 20101h
  712.         mov     ecx, dumpdata
  713.         push    ecx
  714.         xor     edi, edi
  715.         mov     edx, (data_x_pos+12*6)*10000h + dump_y_pos
  716.         cmp     [dumpread], edi
  717.         jz      .hexdumpdone1
  718. .hexdumploop1:
  719.         int     40h
  720.         add     edx, 3*6*10000h
  721.         inc     ecx
  722.         inc     edi
  723.         test    edi, 15
  724.         jz      .16
  725.         test    edi, 7
  726.         jnz     @f
  727.         add     edx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h
  728. .16:
  729.         add     edx, 10 - 6*(3*10h+2)*10000h
  730. @@:
  731.         cmp     edi, [dumpread]
  732.         jb      .hexdumploop1
  733. .hexdumpdone1:
  734.         mov     al, 4
  735.         mov     ecx, esi
  736.         mov     ebx, edx
  737.         push    2
  738.         pop     esi
  739.         mov     edx, aQuests
  740. .hexdumploop2:
  741.         cmp     edi, dump_height*10h
  742.         jae     .hexdumpdone2
  743.         int     40h
  744.         add     ebx, 3*6*10000h
  745.         inc     edi
  746.         test    edi, 15
  747.         jz      .16x
  748.         test    edi, 7
  749.         jnz     .hexdumploop2
  750.         add     ebx, 2*6*10000h - 10 + 6*(3*10h+2)*10000h
  751. .16x:
  752.         add     ebx, 10 - 6*(3*10h+2)*10000h
  753.         jmp     .hexdumploop2
  754. .hexdumpdone2:
  755.         dec     esi
  756. ; colon, minus signs
  757.         mov     ebx, (data_x_pos+8*6)*10000h + dump_y_pos
  758.         mov     edx, aColon
  759. @@:
  760.         int     40h
  761.         add     ebx, 10
  762.         cmp     bl, dump_y_pos+dump_height*10
  763.         jb      @b
  764.         mov     ebx, (data_x_pos+(12+3*8)*6)*10000h + dump_y_pos
  765.         mov     edx, aMinus
  766. @@:
  767.         int     40h
  768.         add     ebx, 10
  769.         cmp     bl, dump_y_pos+dump_height*10
  770.         jb      @b
  771. ; ASCII data
  772.         mov     ebx, (data_x_pos+(12+3*10h+2+2)*6)*10000h + dump_y_pos
  773.         mov     edi, dump_height*10h
  774.         pop     edx
  775. .asciiloop:
  776.         push    edx
  777.         cmp     byte [edx], 20h
  778.         jae     @f
  779.         mov     edx, aPoint
  780. @@:
  781.         int     40h
  782.         pop     edx
  783.         inc     edx
  784.         add     ebx, 6*10000h
  785.         dec     edi
  786.         jz      .asciidone
  787.         test    edi, 15
  788.         jnz     .asciiloop
  789.         add     ebx, 10 - 6*10h*10000h
  790.         jmp     .asciiloop
  791. .asciidone:
  792.         ret
  793.  
  794. redraw_disasm:
  795.         push    13
  796.         pop     eax
  797.         mov     edx, 0xFFFFFF
  798.         mov     ebx, data_x_pos*10000h + data_x_size
  799.         mov     ecx, (disasm_y_pos-1)*10000h + (disasm_y_size+1)
  800.         int     40h
  801. draw_disasm:
  802.         mov     eax, [disasm_start_pos]
  803.         mov     [disasm_cur_pos], eax
  804.         and     [disasm_cur_str], 0
  805. .loop:
  806.         push    [disasm_cur_pos]
  807.         call    disasm_instr
  808.         pop     ebp
  809.         jc      .loopend
  810.         xor     esi, esi        ; default color: black
  811.         mov     ebx, data_x_pos*10000h + data_x_size
  812.         mov     ecx, [disasm_cur_str]
  813.         imul    ecx, 10*10000h
  814.         add     ecx, (disasm_y_pos-1)*10000h + 10
  815.         mov     eax, ebp
  816.         pushad
  817.         call    find_enabled_breakpoint
  818.         popad
  819.         jnz     .nored
  820.         push    13
  821.         pop     eax
  822.         mov     edx, 0xFF0000
  823.         int     40h
  824. .nored:
  825.         mov     eax, [_eip]
  826.         cmp     eax, ebp
  827.         jnz     .noblue
  828.         push    13
  829.         pop     eax
  830.         mov     edx, 0x0000FF
  831.         int     40h
  832.         mov     esi, 0xFFFFFF   ; on blue bgr, use white color
  833. .noblue:
  834.         push    47
  835.         pop     eax
  836.         mov     ebx, 80100h
  837.         mov     edx, [disasm_cur_str]
  838.         imul    edx, 10
  839.         add     edx, data_x_pos*10000h + disasm_y_pos
  840.         mov     ecx, ebp
  841.         int     40h
  842.         mov     al, 4
  843.         lea     ebx, [edx+8*6*10000h]
  844.         mov     ecx, esi
  845.         push    1
  846.         pop     esi
  847.         mov     edx, aColon
  848.         int     40h
  849.         push    9
  850.         pop     edi
  851.         lea     edx, [ebx+2*6*10000h]
  852.         mov     esi, ecx
  853.         mov     al, 47
  854.         mov     ebx, 20101h
  855.         mov     ecx, ebp
  856.         sub     ecx, [disasm_start_pos]
  857.         add     ecx, disasm_buffer
  858. .drawhex:
  859.         int     40h
  860.         add     edx, 6*3*10000h
  861.         inc     ecx
  862.         inc     ebp
  863.         cmp     ebp, [disasm_cur_pos]
  864.         jae     .hexdone
  865.         dec     edi
  866.         jnz     .drawhex
  867.         push    esi
  868.         mov     esi, [disasm_cur_pos]
  869.         dec     esi
  870.         cmp     esi, ebp
  871.         pop     esi
  872.         jbe     .drawhex
  873.         mov     al, 4
  874.         lea     ebx, [edx-6*10000h]
  875.         mov     ecx, esi
  876.         push    3
  877.         pop     esi
  878.         mov     edx, aDots
  879.         int     40h
  880.         mov     esi, ecx
  881. .hexdone:
  882.         xor     eax, eax
  883.         mov     edi, disasm_string
  884.         mov     edx, edi
  885.         or      ecx, -1
  886.         repnz   scasb
  887.         not     ecx
  888.         dec     ecx
  889.         xchg    ecx, esi
  890.         mov     ebx, [disasm_cur_str]
  891.         imul    ebx, 10
  892.         add     ebx, (data_x_pos+6*40)*10000h+disasm_y_pos
  893.         mov     al, 4
  894.         int     40h
  895.         inc     [disasm_cur_str]
  896.         cmp     [disasm_cur_str], disasm_height
  897.         jb      .loop
  898. .loopend:
  899.         ret
  900.  
  901. update_disasm_eip:
  902. ; test if instruction at eip is showed
  903.         mov     ecx, disasm_height
  904.         mov     eax, [disasm_start_pos]
  905.         mov     [disasm_cur_pos], eax
  906. @@:
  907.         mov     eax, [_eip]
  908.         cmp     [disasm_cur_pos], eax
  909.         jz      redraw_disasm
  910.         push    ecx
  911.         call    disasm_instr
  912.         pop     ecx
  913.         jc      @f
  914.         loop    @b
  915. @@:
  916. update_disasm_eip_force:
  917.         mov     eax, [_eip]
  918.         mov     [disasm_start_pos], eax
  919. update_disasm:
  920.         cmp     [debuggee_pid], 0
  921.         jz      .no
  922.         push    69
  923.         pop     eax
  924.         push    6
  925.         pop     ebx
  926.         mov     ecx, [debuggee_pid]
  927.         mov     edi, disasm_buffer
  928.         mov     edx, 256
  929.         mov     esi, [disasm_start_pos]
  930.         int     40h
  931.         cmp     eax, -1
  932.         jnz     @f
  933.         mov     esi, read_mem_err
  934.         call    put_message
  935. .no:
  936.         xor     eax, eax
  937. @@:
  938.         mov     [disasm_buf_size], eax
  939.         call    restore_from_breaks
  940.         jmp     redraw_disasm
  941.  
  942. draw_window:
  943. ; start redraw
  944.         push    12
  945.         pop     eax
  946.         push    1
  947.         pop     ebx
  948.         int     40h
  949. ; define window
  950.         xor     eax, eax
  951.         mov     ebx, wnd_x_size
  952.         mov     ecx, wnd_y_size
  953.         mov     edx, 3FFFFFFh
  954.         int     40h
  955. ; caption
  956.         mov     al, 4
  957.         mov     ecx, 0xFFFFFF
  958.         mov     ebx, 80008h
  959.         mov     edx, caption_str
  960.         push    caption_len
  961.         pop     esi
  962.         int     40h
  963. ; messages frame
  964.         mov     al, 38
  965.         mov     ebx, (messages_x_pos-2)*10000h + (messages_x_pos+messages_x_size+2)
  966.         push    ebx
  967.         mov     ecx, (messages_y_pos-2)*10001h
  968.         xor     edx, edx
  969.         int     40h
  970.         mov     ecx, (messages_y_pos+messages_y_size+2)*10001h
  971.         int     40h
  972.         mov     ebx, (messages_x_pos-2)*10001h
  973.         push    ebx
  974.         mov     ecx, (messages_y_pos-2)*10000h + (messages_y_pos+messages_y_size+2)
  975.         int     40h
  976.         mov     ebx, (messages_x_pos+messages_x_size+2)*10001h
  977.         push    ebx
  978.         int     40h
  979. ; command line frame
  980.         mov     ecx, (cmdline_y_pos-2)*10000h + (cmdline_y_pos+cmdline_y_size+2)
  981.         pop     ebx
  982.         int     40h
  983.         pop     ebx
  984.         int     40h
  985.         pop     ebx
  986.         mov     ecx, (cmdline_y_pos+cmdline_y_size+2)*10001h
  987.         int     40h
  988.         mov     ecx, (cmdline_y_pos-2)*10001h
  989.         int     40h
  990. ; messages
  991.         call    draw_messages
  992. ; command line & cursor
  993.         call    draw_cmdline
  994.         call    draw_cursor
  995. ; title & registers & dump & disasm
  996.         mov     al, 38
  997.         mov     ebx, (data_x_pos-2)*10001h
  998.         mov     ecx, (title_y_pos+5)*10000h + (messages_y_pos-2)
  999.         int     40h
  1000.         mov     ebx, (data_x_pos+data_x_size+2)*10001h
  1001.         int     40h
  1002.         mov     ebx, (data_x_pos-2)*10000h + (data_x_pos+data_x_size+2)
  1003.         mov     ecx, (dump_y_pos-3)*10001h
  1004.         int     40h
  1005.         mov     ecx, (disasm_y_pos-4)*10001h
  1006.         int     40h
  1007.         call    draw_title
  1008.         call    draw_registers
  1009.         call    draw_dump
  1010.         call    draw_disasm
  1011. ; end redraw
  1012.         mov     al, 12
  1013.         push    2
  1014.         pop     ebx
  1015.         int     40h
  1016.         ret
  1017.  
  1018. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1019. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DEBUGGING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1020. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1021.  
  1022. OnHelp:
  1023.         mov     esi, help_msg
  1024.         mov     edi, [curarg]
  1025.         cmp     byte [edi], 0
  1026.         jz      .x
  1027.         mov     esi, help_groups
  1028.         call    find_cmd
  1029.         jc      .nocmd
  1030.         mov     esi, [esi+12]
  1031. .x:
  1032.         jmp     put_message
  1033. .nocmd:
  1034.         mov     esi, aUnknownCommand
  1035.         jmp     .x
  1036.  
  1037. OnQuit:
  1038.         xor     eax, eax
  1039.         dec     eax
  1040.         int     40h
  1041.  
  1042. get_new_context:
  1043.         mov     esi, context
  1044.         mov     edi, oldcontext
  1045.         mov     ecx, 10
  1046.         rep     movsd
  1047. get_context:
  1048.         push    1
  1049.         pop     ebx
  1050.         push    69
  1051.         pop     eax
  1052.         mov     ecx, [debuggee_pid]
  1053.         mov     esi, context
  1054.         push    28h
  1055.         pop     edx
  1056.         int     40h
  1057.         ret
  1058. set_context:
  1059.         push    2
  1060.         pop     ebx
  1061.         push    69
  1062.         pop     eax
  1063.         mov     ecx, [debuggee_pid]
  1064.         mov     esi, context
  1065.         push    28h
  1066.         pop     edx
  1067.         int     40h
  1068.         ret
  1069.  
  1070. get_dump:
  1071.         mov     edi, dumpdata
  1072.         mov     esi, [edi-4]
  1073.         mov     edx, dump_height*10h
  1074.         mov     ecx, edx
  1075.         xor     eax, eax
  1076.         push    edi
  1077.         rep     stosb
  1078.         pop     edi
  1079.         mov     ecx, [debuggee_pid]
  1080.         mov     al, 69
  1081.         push    6
  1082.         pop     ebx
  1083.         int     40h
  1084.         cmp     eax, -1
  1085.         jnz     @f
  1086.         mov     esi, read_mem_err
  1087.         call    put_message
  1088.         xor     eax, eax
  1089. @@:
  1090.         mov     [edi-8], eax
  1091. ;       call    restore_from_breaks
  1092. ;       ret
  1093. restore_from_breaks:
  1094. ; in: edi=buffer,eax=size,esi=address
  1095.         mov     ebx, breakpoints
  1096. @@:
  1097.         test    byte [ebx+4], 1
  1098.         jz      .cont           ; ignore invalid
  1099.         test    byte [ebx+4], 2 or 8
  1100.         jnz     .cont           ; ignore disabled and memory breaks
  1101.         mov     ecx, [ebx]
  1102.         sub     ecx, esi
  1103.         cmp     ecx, eax
  1104.         jae     .cont
  1105.         mov     dl, [ebx+5]
  1106.         mov     [edi+ecx], dl
  1107. .cont:
  1108.         add     ebx, 6
  1109.         cmp     ebx, breakpoints+breakpoints_n*6
  1110.         jb      @b
  1111.         ret
  1112.  
  1113. OnLoad:
  1114.         mov     esi, [curarg]
  1115. OnLoadInit:
  1116.         mov     edi, loadname
  1117.         or      [prgname_len], -1
  1118.         mov     [prgname_ptr], edi
  1119. .copyname:
  1120.         lodsb
  1121.         stosb
  1122.         inc     [prgname_len]
  1123.         cmp     al, '/'
  1124.         jnz     @f
  1125.         or      [prgname_len], -1
  1126.         mov     [prgname_ptr], edi
  1127. @@:
  1128.         cmp     al, ' '
  1129.         ja      .copyname
  1130.         mov     byte [edi-1], 0
  1131.         and     [load_params], 0
  1132.         dec     esi
  1133.         call    skip_spaces
  1134.         cmp     al, 0
  1135.         jz      @f
  1136.         mov     [load_params], esi
  1137. @@:
  1138.         and     [dumppos], 0
  1139. do_reload:
  1140.         push    18
  1141.         pop     eax
  1142.         push    7
  1143.         pop     ebx
  1144.         int     40h
  1145.         mov     [dbgwnd], eax
  1146.         xchg    ecx, eax
  1147.         push    70
  1148.         pop     eax
  1149.         mov     ebx, fn70_load_block
  1150.         int     40h
  1151.         test    eax, eax
  1152.         jns     .load_ok
  1153. .load_err:
  1154.         push    eax
  1155.         mov     esi, load_err_msg
  1156.         call    put_message
  1157.         pop     eax
  1158.         not     eax
  1159.         cmp     eax, 0x20
  1160.         jae     .unk_err
  1161.         mov     esi, [load_err_msgs+eax*4]
  1162.         test    esi, esi
  1163.         jnz     put_message
  1164. .unk_err:
  1165.         mov     esi, unk_err_msg
  1166.         inc     eax
  1167.         push    eax
  1168.         call    put_message_nodraw
  1169.         jmp     draw_messages
  1170. .load_ok:
  1171.         mov     [debuggee_pid], eax
  1172.         mov     [bSuspended], 1
  1173.         push    ecx
  1174.         call    get_context
  1175.         mov     edi, oldcontext
  1176.         mov     ecx, 10
  1177.         rep     movsd
  1178. ; activate debugger window
  1179.         pop     ecx
  1180.         mov     bl, 3
  1181.         push    18
  1182.         pop     eax
  1183.         int     40h
  1184.         call    redraw_title
  1185.         call    redraw_registers
  1186.         call    get_dump
  1187.         call    redraw_dump
  1188.         call    update_disasm_eip_force
  1189.         mov     esi, load_succ_msg
  1190.         push    [debuggee_pid]
  1191.         call    put_message_nodraw
  1192.         call    draw_messages
  1193. ; now test for packed progs
  1194.         cmp     [disasm_buf_size], 100h
  1195.         jz      @f
  1196.         ret
  1197. @@:
  1198.         mov     esi, mxp_nrv_sig
  1199.         mov     ebp, disasm_buffer
  1200.         mov     edi, ebp
  1201.         push    3
  1202.         pop     ecx
  1203.         repz    cmpsb
  1204.         jnz     .not_mxp_nrv
  1205.         cmpsb
  1206.         mov     cl, mxp_nrv_sig_size-4
  1207.         repz    cmpsb
  1208.         mov     esi, mxp_nrv_name
  1209.         jz      .packed
  1210. .not_mxp_nrv:
  1211.         mov     esi, mxp_sig
  1212.         mov     edi, ebp
  1213.         mov     cl, mxp_sig_size
  1214.         repz    cmpsb
  1215.         mov     esi, mxp_name
  1216.         jz      .packed
  1217. .not_mxp:
  1218.         mov     esi, mxp_lzo_sig1
  1219.         mov     edi, ebp
  1220.         mov     cl, mxp_lzo_sig1_size
  1221.         repz    cmpsb
  1222.         mov     esi, mxp_lzo_name
  1223.         jz      .packed
  1224.         mov     esi, mxp_lzo_sig2
  1225.         mov     edi, ebp
  1226.         mov     cl, 8
  1227.         repz    cmpsb
  1228.         jnz     .not_mxp_lzo
  1229.         cmpsb
  1230.         mov     cl, mxp_lzo_sig2_size - 9
  1231.         repz    cmpsb
  1232.         mov     esi, mxp_lzo_name
  1233.         jz      .packed
  1234. .not_mxp_lzo:
  1235.         mov     esi, mtappack_name
  1236.         cmp     dword [ebp], 0xBF5E246A
  1237.         jnz     .not_mtappack
  1238.         cmp     dword [ebp+8], 0xEC4E8B57
  1239.         jnz     .not_mtappack1
  1240.         cmp     dword [ebp+12], 0x8D5EA4F3
  1241.         jnz     .not_mtappack1
  1242.         cmp     byte [ebp+12h], 0xE9
  1243.         jz      .packed
  1244. .not_mtappack1:
  1245.         cmp     word [ebp+8], 0xB957
  1246.         jnz     .not_mtappack
  1247.         cmp     dword [ebp+14], 0x575EA4F3
  1248.         jnz     .not_mtappack2
  1249.         cmp     byte [ebp+17h], 0xE9
  1250.         jz      .packed
  1251. .not_mtappack2:
  1252.         cmp     dword [ebp+14], 0x5F8DA4F3
  1253.         jnz     .not_mtappack3
  1254.         cmp     word [ebp+18], 0xE9FC
  1255.         jz      .packed
  1256. .not_mtappack3:
  1257.         cmp     word [ebp+14], 0xA4F3
  1258.         jnz     .not_mtappack
  1259.         cmp     byte [ebp+15h], 0xE9
  1260.         jz      .packed
  1261. .not_mtappack:
  1262.         ret
  1263. .packed:
  1264.         push    esi
  1265.         mov     esi, aPacked1
  1266.         call    put_message_nodraw
  1267.         pop     esi
  1268.         call    put_message_nodraw
  1269.         mov     esi, aPacked2
  1270.         call    put_message
  1271.         call    hide_cursor
  1272.         push    40
  1273.         pop     eax
  1274.         push    7
  1275.         pop     ebx
  1276.         int     40h
  1277. .wait:
  1278.         push    10
  1279.         pop     eax
  1280.         int     40h
  1281.         dec     eax
  1282.         jz      .redraw
  1283.         dec     eax
  1284.         jz      .key
  1285.         or      eax, -1
  1286.         int     40h
  1287. .redraw:
  1288.         call    draw_window
  1289.         call    hide_cursor
  1290.         jmp     .wait
  1291. .key:
  1292.         mov     al, 2
  1293.         int     40h
  1294.         cmp     ah, 'y'
  1295.         jz      .yes
  1296.         cmp     ah, 'Y'
  1297.         jz      .yes
  1298.         cmp     ah, 0xD
  1299.         jz      .yes
  1300.         cmp     ah, 'n'
  1301.         jz      .no
  1302.         cmp     ah, 'N'
  1303.         jnz     .wait
  1304. .no:
  1305.         push    40
  1306.         pop     eax
  1307.         mov     ebx, 0x107
  1308.         int     40h
  1309.         call    draw_cursor
  1310.         mov     esi, aN_str
  1311.         jmp     put_message
  1312. .yes:
  1313.         push    40
  1314.         pop     eax
  1315.         mov     ebx, 0x107
  1316.         int     40h
  1317.         call    draw_cursor
  1318.         mov     esi, aY_str
  1319.         call    put_message
  1320.         call    OnUnpack
  1321.         ret
  1322.  
  1323. mxp_nrv_sig:
  1324.         xor     eax, eax
  1325.         mov     ecx, 0x95       ; 0xA1 for programs with parameters
  1326.         mov     [eax], ecx
  1327.         add     ecx, [eax+24h]
  1328.         push    40h
  1329.         pop     esi
  1330.         mov     edi, [eax+20h]
  1331.         push    edi
  1332.         rep     movsb
  1333.         jmp     dword [esp]
  1334.         pop     esi
  1335.         add     esi, [eax]
  1336.         xor     edi, edi
  1337. mxp_nrv_sig_size = $ - mxp_nrv_sig
  1338.  
  1339. mxp_sig:
  1340.         mov     ecx, 1CBh
  1341.         push    46h
  1342.         pop     esi
  1343.         mov     edi, [20h]
  1344.         rep     movsb
  1345.         mov     ecx, [24h]
  1346.         rep     movsb
  1347.         jmp     dword [20h]
  1348.         mov     eax, [20h]
  1349.         add     eax, 1CBh
  1350.         push    eax
  1351.         push    dword [24h]
  1352.         push    0
  1353.         push    8
  1354.         call    $+0x25
  1355. mxp_sig_size = $ - mxp_sig
  1356.  
  1357. mxp_lzo_sig1:
  1358.         xor     eax, eax
  1359.         mov     ebp, 0FFh
  1360.         mov     ecx, 175h
  1361.         mov     [eax], ecx
  1362.         add     ecx, [eax+24h]
  1363.         push    45h
  1364.         pop     esi
  1365.         mov     edi, [eax+20h]
  1366.         push    edi
  1367.         rep     movsb
  1368.         jmp     dword [esp]
  1369.         pop     ebx
  1370.         add     ebx, [eax]
  1371.         xor     edi, edi
  1372.         cmp     byte [ebx], 11h
  1373.         jbe     $+0x1A
  1374. mxp_lzo_sig1_size = $ - mxp_lzo_sig1
  1375. mxp_lzo_sig2:
  1376.         xor     eax, eax
  1377.         mov     ebp, 0FFh
  1378.         mov     ecx, 188h       ; or 177h
  1379.         mov     [eax], ecx
  1380.         add     ecx, [eax+24h]
  1381.         push    44h
  1382.         pop     esi
  1383.         mov     edi, [eax+20h]
  1384.         rep     movsb
  1385.         jmp     dword [eax+20h]
  1386.         mov     ebx, [eax+20h]
  1387.         add     ebx, [eax]
  1388. mxp_lzo_sig2_size = $ - mxp_lzo_sig2
  1389.  
  1390. OnReload:
  1391.         cmp     [debuggee_pid], 0
  1392.         jnz     terminate_reload
  1393.         mov     esi, need_debuggee
  1394.         cmp     byte [loadname], 0
  1395.         jnz     do_reload
  1396.         jz      put_message
  1397. terminate_reload:
  1398.         mov     [bReload], 1
  1399. OnTerminate:
  1400.         mov     ecx, [debuggee_pid]
  1401.         push    8
  1402.         pop     ebx
  1403.         push    69
  1404.         pop     eax
  1405.         int     40h
  1406.         ret
  1407.  
  1408. AfterSuspend:
  1409.         mov     [bSuspended], 1
  1410.         call    get_new_context
  1411.         call    get_dump
  1412.         call    redraw_title
  1413.         call    redraw_registers
  1414.         call    redraw_dump
  1415.         call    update_disasm_eip
  1416.         ret
  1417.  
  1418. OnSuspend:
  1419.         mov     ecx, [debuggee_pid]
  1420.         push    4
  1421.         pop     ebx
  1422.         push    69
  1423.         pop     eax
  1424.         int     40h
  1425.         call    AfterSuspend
  1426.         mov     esi, aSuspended
  1427.         jmp     put_message
  1428. DoResume:
  1429.         mov     ecx, [debuggee_pid]
  1430.         push    5
  1431.         pop     ebx
  1432.         push    69
  1433.         pop     eax
  1434.         int     40h
  1435.         mov     [bSuspended], 0
  1436.         ret
  1437. OnResume:
  1438.         mov     esi, [curarg]
  1439.         cmp     byte [esi], 0
  1440.         jz      GoOn
  1441.         call    calc_expression
  1442.         jc      .ret
  1443.         mov     eax, ebp
  1444.         push    eax
  1445.         call    find_enabled_breakpoint
  1446.         pop     eax
  1447.         jz      GoOn
  1448.         mov     bl, 5   ; valid enabled one-shot
  1449.         call    add_breakpoint
  1450.         jnc     GoOn
  1451.         mov     esi, aBreakpointLimitExceeded
  1452.         call    put_message
  1453. .ret:
  1454.         ret
  1455. GoOn:
  1456. ; test for enabled breakpoint at eip
  1457.         mov     eax, [_eip]
  1458.         call    find_enabled_breakpoint
  1459.         jnz     .nobreak
  1460. ; temporarily disable breakpoint, make step, enable breakpoint, continue
  1461.         inc     eax
  1462.         mov     [temp_break], eax
  1463.         mov     [bAfterGo], 1
  1464.         dec     eax
  1465.         call    disable_breakpoint
  1466.         call    get_context
  1467.         or      byte [_eflags+1], 1             ; set TF
  1468.         call    set_context
  1469.         and     byte [_eflags+1], not 1
  1470.         call    DoResume
  1471.         ret
  1472. .nobreak:
  1473.         call    DoResume
  1474.         call    redraw_title
  1475.         call    redraw_registers
  1476.         call    redraw_dump
  1477.         ret
  1478. OnDetach:
  1479.         mov     ecx, [debuggee_pid]
  1480.         push    3
  1481.         pop     ebx
  1482.         push    69
  1483.         pop     eax
  1484.         int     40h
  1485.         and     [debuggee_pid], 0
  1486.         call    redraw_title
  1487.         call    redraw_registers
  1488.         call    redraw_dump
  1489.         mov     esi, aContinued
  1490.         jmp     put_message
  1491.  
  1492. after_go_exception:
  1493.         push    eax
  1494.         mov     eax, [temp_break]
  1495.         dec     eax
  1496.         push    esi
  1497.         call    enable_breakpoint
  1498. ; in any case, clear TF and RF
  1499.         call    get_new_context
  1500.         and     [_eflags], not 10100h           ; clear TF,RF
  1501.         call    set_context
  1502.         xor     edx, edx
  1503.         mov     [temp_break], edx
  1504.         xchg    dl, [bAfterGo]
  1505.         pop     esi
  1506.         pop     eax
  1507.         cmp     dl, 2
  1508.         jnz     @f
  1509.         lodsd
  1510.         push    esi
  1511.         call    get_dump
  1512.         jmp     exception.done
  1513. @@:     test    eax, eax
  1514.         jz      .notint1
  1515. ; if exception is result of single step, simply ignore it and continue
  1516.         test    dword [esi], 0xF
  1517.         jnz     dbgmsgstart.5
  1518.         lodsd
  1519.         push    esi
  1520.         mov     esi, oldcontext
  1521.         mov     edi, context
  1522.         mov     ecx, 28h/4
  1523.         rep     movsd
  1524.         call    DoResume
  1525.         jmp     dbgmsgend
  1526. .notint1:
  1527. ; in other case, work as without temp_break
  1528.         lodsd
  1529.         push    esi
  1530.         push    eax
  1531.         jmp     exception.4
  1532. .notour:
  1533.  
  1534. debugmsg:
  1535.         neg     [dbgbufsize]
  1536.         mov     esi, dbgbuf
  1537. dbgmsgstart:
  1538.         lodsd
  1539. ;       push    eax esi
  1540. ;       push    dword [esi]
  1541. ;       mov     esi, dbgmsg_str
  1542. ;       call    put_message_nodraw
  1543. ;       pop     esi eax
  1544.         add     esi, 4
  1545.         dec     eax
  1546.         jz      exception
  1547.         dec     eax
  1548.         jz      terminated
  1549.         mov     [bSuspended], 1
  1550.         cmp     [bAfterGo], 0
  1551.         jnz     after_go_exception
  1552.         push    esi
  1553.         call    get_new_context
  1554.         and     [_eflags], not 10100h           ; clear TF,RF
  1555.         call    set_context
  1556.         pop     esi
  1557. .5:
  1558.         push    esi
  1559.         call    get_dump
  1560.         pop     esi
  1561.         lodsd
  1562.         xor     ecx, ecx
  1563. .6:
  1564.         bt      eax, ecx
  1565.         jnc     .7
  1566.         mov     ebx, [drx_break+ecx*4]
  1567.         test    ebx, ebx
  1568.         jz      .7
  1569.         pushad
  1570.         dec     ebx
  1571.         push    ebx
  1572.         mov     esi, aBreakStop
  1573.         call    put_message_nodraw
  1574.         popad
  1575. .7:
  1576.         inc     ecx
  1577.         cmp     cl, 4
  1578.         jb      .6
  1579.         push    esi
  1580.         jmp     exception.done_draw
  1581. terminated:
  1582.         push    esi
  1583.         mov     esi, terminated_msg
  1584.         call    put_message
  1585.         and     [debuggee_pid], 0
  1586.         and     [temp_break], 0
  1587.         mov     [bAfterGo], 0
  1588.         xor     eax, eax
  1589.         mov     ecx, breakpoints_n*6/4+4
  1590.         mov     edi, breakpoints
  1591.         rep     stosd
  1592.         cmp     [bReload], 1
  1593.         sbb     [bReload], -1
  1594.         jmp     exception.done
  1595. exception:
  1596.         mov     [bSuspended], 1
  1597.         cmp     [bAfterGo], 0
  1598.         jnz     after_go_exception
  1599.         lodsd
  1600.         push    esi
  1601.         push    eax
  1602.         call    get_new_context
  1603.         and     [_eflags], not 10100h           ; clear TF,RF
  1604.         call    set_context
  1605. .4:
  1606.         call    get_dump
  1607.         pop     eax
  1608. ; int3 command generates exception 0D, #GP
  1609.         push    eax
  1610.         cmp     al, 0Dh
  1611.         jnz     .notdbg
  1612. ; check for 0xCC byte at eip
  1613.         push    0
  1614.         push    69
  1615.         pop     eax
  1616.         push    6
  1617.         pop     ebx
  1618.         mov     ecx, [debuggee_pid]
  1619.         mov     edi, esp
  1620.         mov     esi, [_eip]
  1621.         push    1
  1622.         pop     edx
  1623.         int     40h
  1624.         pop     eax
  1625.         cmp     al, 0xCC
  1626.         jnz     .notdbg
  1627. ; this is either dbg breakpoint or int3 cmd in debuggee
  1628.         mov     eax, [_eip]
  1629.         call    find_enabled_breakpoint
  1630.         jnz     .user_int3
  1631. ; dbg breakpoint; clear if one-shot
  1632.         pop     ecx
  1633.         push    eax
  1634.         mov     esi, aBreakStop
  1635.         test    byte [edi+4], 4
  1636.         jz      .put_msg_eax
  1637.         pop     ecx
  1638.         call    clear_breakpoint
  1639.         jmp     .done
  1640. .user_int3:
  1641.         mov     eax, [_eip]
  1642.         inc     [_eip]
  1643.         pop     ecx
  1644.         push    eax
  1645.         call    set_context
  1646.         mov     esi, aUserBreak
  1647.         jmp     .put_msg_eax
  1648. .notdbg:
  1649.         mov     esi, aException
  1650. .put_msg_eax:
  1651.         call    put_message_nodraw
  1652. .done_draw:
  1653.         call    draw_messages
  1654. .done:
  1655.         push    18
  1656.         pop     eax
  1657.         push    3
  1658.         pop     ebx
  1659.         mov     ecx, [dbgwnd]
  1660.         int     40h     ; activate dbg window
  1661.         call    redraw_title
  1662.         call    redraw_registers
  1663.         call    redraw_dump
  1664.         call    update_disasm_eip
  1665. dbgmsgend:
  1666.         pop     esi
  1667.         mov     ecx, [dbgbuflen]
  1668.         add     ecx, dbgbuf
  1669.         cmp     esi, ecx
  1670.         jnz     dbgmsgstart
  1671.         and     [dbgbuflen], 0
  1672.         neg     [dbgbufsize]
  1673.         cmp     [bReload], 2
  1674.         jnz     @f
  1675.         mov     [bReload], 0
  1676.         call    do_reload
  1677. @@:
  1678.         jmp     waitevent
  1679.  
  1680. CtrlF7:
  1681.         cmp     [debuggee_pid], 0
  1682.         jz      .no
  1683.         call    OnStep
  1684. .no:
  1685.         jmp     waitevent
  1686. CtrlF8:
  1687.         cmp     [debuggee_pid], 0
  1688.         jz      CtrlF7.no
  1689.         call    OnProceed
  1690.         jmp     CtrlF7.no
  1691.  
  1692. OnStep:
  1693.         cmp     [bSuspended], 0
  1694.         jz      .running
  1695.         call    get_context
  1696.         or      byte [_eflags+1], 1             ; set TF
  1697.         call    set_context
  1698.         and     byte [_eflags+1], not 1
  1699. ; if instruction at eip is "int xx", set one-shot breakpoint immediately after
  1700.         mov     eax, [_eip]
  1701.         call    find_enabled_breakpoint
  1702.         jnz     @f
  1703.         cmp     byte [edi+5], 0xCD
  1704.         jz      .int
  1705. @@:
  1706.         push    0
  1707.         push    69
  1708.         pop     eax
  1709.         push    6
  1710.         pop     ebx
  1711.         mov     ecx, [debuggee_pid]
  1712.         push    3
  1713.         pop     edx
  1714.         mov     edi, esp
  1715.         mov     esi, [_eip]
  1716.         int     40h
  1717.         cmp     eax, edx
  1718.         pop     eax
  1719.         jnz     .doit
  1720.         cmp     al, 0xCD
  1721.         jz      .int
  1722. ; resume process
  1723. .doit:
  1724.         call    GoOn
  1725.         cmp     [bAfterGo], 0
  1726.         jz      @f
  1727.         mov     [bAfterGo], 2
  1728. @@:
  1729.         ret
  1730. .int:
  1731.         mov     eax, [_eip]
  1732.         inc     eax
  1733.         inc     eax
  1734.         push    eax
  1735.         call    find_enabled_breakpoint
  1736.         pop     eax
  1737.         jz      .doit
  1738. ; there is no enabled breakpoint yet; set temporary breakpoint
  1739.         mov     bl, 5
  1740.         call    add_breakpoint
  1741.         jmp     .doit
  1742. .running:
  1743.         mov     esi, aRunningErr
  1744.         jmp     put_message
  1745.  
  1746. OnProceed:
  1747.         cmp     [bSuspended], 0
  1748.         jz      OnStep.running
  1749.         mov     esi, [_eip]
  1750. @@:
  1751.         call    get_byte_nobreak
  1752.         jc      OnStep
  1753.         inc     esi
  1754. ; skip prefixes
  1755.         call    is_prefix
  1756.         jz      @b
  1757.         cmp     al, 0xE8        ; call
  1758.         jnz     @f
  1759.         add     esi, 4
  1760.         jmp     .doit
  1761. @@:     ; A4,A5 = movs, A6,A7=cmps
  1762.         cmp     al, 0xA4
  1763.         jb      @f
  1764.         cmp     al, 0xA8
  1765.         jb      .doit
  1766. @@:     ; AA,AB=stos, AC,AD=lods, AE,AF=scas
  1767.         cmp     al, 0xAA
  1768.         jb      @f
  1769.         cmp     al, 0xB0
  1770.         jb      .doit
  1771. @@:     ; E0=loopnz,E1=loopz,E2=loop
  1772.         cmp     al, 0xE0
  1773.         jb      .noloop
  1774.         cmp     al, 0xE2
  1775.         ja      .noloop
  1776.         inc     esi
  1777.         jmp     .doit
  1778. .noloop:        ; FF /2 = call
  1779.         cmp     al, 0xFF
  1780.         jnz     OnStep
  1781.         call    get_byte_nobreak
  1782.         jc      OnStep
  1783.         inc     esi
  1784.         mov     cl, al
  1785.         and     al, 00111000b
  1786.         cmp     al, 00010000b
  1787.         jnz     OnStep
  1788. ; skip instruction
  1789.         mov     al, cl
  1790.         and     eax, 7
  1791.         shr     cl, 6
  1792.         jz      .mod0
  1793.         jp      .doit
  1794.         cmp     al, 4
  1795.         jnz     @f
  1796.         inc     esi
  1797. @@:
  1798.         inc     esi
  1799.         dec     cl
  1800.         jz      @f
  1801.         add     esi, 3
  1802. @@:
  1803.         jmp     .doit
  1804. .mod0:
  1805.         cmp     al, 4
  1806.         jnz     @f
  1807.         call    get_byte_nobreak
  1808.         jc      OnStep
  1809.         inc     esi
  1810.         and     al, 7
  1811. @@:
  1812.         cmp     al, 5
  1813.         jnz     .doit
  1814.         add     esi, 4
  1815. .doit:
  1816. ; insert one-shot breakpoint at esi and resume
  1817.         call    get_byte_nobreak
  1818.         jc      OnStep
  1819.         mov     eax, esi
  1820.         call    find_enabled_breakpoint
  1821.         jz      .ret
  1822.         mov     eax, esi
  1823.         mov     bl, 5
  1824.         call    add_breakpoint
  1825.         jmp     OnStep.doit
  1826. .ret:
  1827.         ret
  1828.  
  1829. get_byte_nobreak:
  1830.         mov     eax, esi
  1831.         call    find_enabled_breakpoint
  1832.         jnz     .nobreak
  1833.         mov     al, [edi+5]
  1834.         clc
  1835.         ret
  1836. .nobreak:
  1837.         push    69
  1838.         pop     eax
  1839.         push    6
  1840.         pop     ebx
  1841.         mov     ecx, [debuggee_pid]
  1842.         xor     edx, edx
  1843.         push    edx
  1844.         inc     edx
  1845.         mov     edi, esp
  1846.         int     40h
  1847.         dec     eax
  1848.         clc
  1849.         jz      @f
  1850.         stc
  1851. @@:     pop     eax
  1852.         ret
  1853.  
  1854. is_prefix:
  1855.         cmp     al, 0x64        ; fs:
  1856.         jz      .ret
  1857.         cmp     al, 0x65        ; gs:
  1858.         jz      .ret
  1859.         cmp     al, 0x66        ; use16/32
  1860.         jz      .ret
  1861.         cmp     al, 0x67        ; addr16/32
  1862.         jz      .ret
  1863.         cmp     al, 0xF0        ; lock
  1864.         jz      .ret
  1865.         cmp     al, 0xF2        ; repnz
  1866.         jz      .ret
  1867.         cmp     al, 0xF3        ; rep(z)
  1868.         jz      .ret
  1869.         cmp     al, 0x2E        ; cs:
  1870.         jz      .ret
  1871.         cmp     al, 0x36        ; ss:
  1872.         jz      .ret
  1873.         cmp     al, 0x3E        ; ds:
  1874.         jz      .ret
  1875.         cmp     al, 0x26        ; es:
  1876. .ret:   ret
  1877.  
  1878. token_end       equ     1
  1879. token_reg       equ     2
  1880. token_hex       equ     3
  1881. token_add       equ     4
  1882. token_sub       equ     5
  1883. token_mul       equ     6
  1884. token_div       equ     7
  1885. token_lp        equ     8
  1886. token_rp        equ     9
  1887. token_err       equ     -1
  1888.  
  1889. is_hex_digit:
  1890.         cmp     al, '0'
  1891.         jb      .no
  1892.         cmp     al, '9'
  1893.         jbe     .09
  1894.         cmp     al, 'A'
  1895.         jb      .no
  1896.         cmp     al, 'F'
  1897.         jbe     .AF
  1898.         cmp     al, 'a'
  1899.         jb      .no
  1900.         cmp     al, 'f'
  1901.         jbe     .af
  1902. .no:
  1903.         stc
  1904.         ret
  1905. .09:
  1906.         sub     al, '0'
  1907. ;       clc
  1908.         ret
  1909. .AF:
  1910.         sub     al, 'A'-10
  1911. ;       clc
  1912.         ret
  1913. .af:
  1914.         sub     al, 'a'-10
  1915. ;       clc
  1916.         ret
  1917.  
  1918. find_reg:
  1919.         mov     edi, reg_table
  1920. .findreg:
  1921.         movzx   ecx, byte [edi]
  1922.         stc
  1923.         jecxz   .regnotfound
  1924.         inc     edi
  1925.         push    esi edi ecx
  1926. @@:
  1927.         lodsb
  1928.         or      al, 20h
  1929.         scasb
  1930.         loopz   @b
  1931.         pop     ecx edi esi
  1932.         lea     edi, [edi+ecx+1]
  1933.         jnz     .findreg
  1934.         movzx   edi, byte [edi-1]
  1935.         add     esi, ecx
  1936. .regnotfound:
  1937.         ret
  1938.  
  1939. expr_get_token:
  1940.         lodsb
  1941.         cmp     al, 0
  1942.         jz      .end_token
  1943.         cmp     al, ' '
  1944.         jbe     expr_get_token
  1945.         cmp     al, '+'
  1946.         jz      .add
  1947.         cmp     al, '-'
  1948.         jz      .sub
  1949.         cmp     al, '*'
  1950.         jz      .mul
  1951.         cmp     al, '/'
  1952.         jz      .div
  1953.         cmp     al, '('
  1954.         jz      .lp
  1955.         cmp     al, ')'
  1956.         jnz     .notsign
  1957. .rp:
  1958.         mov     al, token_rp
  1959.         ret
  1960. .div:
  1961.         mov     al, token_div
  1962.         ret
  1963. .end_token:
  1964.         mov     al, token_end
  1965.         ret
  1966. .add:
  1967.         mov     al, token_add
  1968.         ret
  1969. .sub:
  1970.         mov     al, token_sub
  1971.         ret
  1972. .mul:
  1973.         mov     al, token_mul
  1974.         ret
  1975. .lp:
  1976.         mov     al, token_lp
  1977.         ret
  1978. .notsign:
  1979.         dec     esi
  1980.         call    find_reg
  1981.         jc      .regnotfound
  1982.         mov     al, token_reg
  1983.         ret
  1984. .regnotfound:
  1985. ; test for hex number
  1986.         xor     ecx, ecx
  1987.         xor     edi, edi
  1988.         xor     eax, eax
  1989. @@:
  1990.         lodsb
  1991.         call    is_hex_digit
  1992.         jc      @f
  1993.         shl     edi, 4
  1994.         or      edi, eax
  1995.         inc     ecx
  1996.         jmp     @b
  1997. @@:
  1998.         dec     esi
  1999.         jecxz   .err
  2000.         cmp     ecx, 8
  2001.         ja      .err
  2002.         mov     al, token_hex
  2003.         ret
  2004. .err:
  2005.         mov     al, token_err
  2006.         mov     esi, aParseError
  2007.         ret
  2008.  
  2009. expr_read2:
  2010.         cmp     al, token_hex
  2011.         jz      .hex
  2012.         cmp     al, token_reg
  2013.         jz      .reg
  2014.         cmp     al, token_lp
  2015.         jz      .lp
  2016.         mov     al, token_err
  2017.         mov     esi, aParseError
  2018.         ret
  2019. .hex:
  2020.         mov     ebp, edi
  2021. .ret:
  2022.         jmp     expr_get_token
  2023. .reg:
  2024.         cmp     edi, 24
  2025.         jz      .eip
  2026.         sub     edi, 4
  2027.         jb      .8lo
  2028.         sub     edi, 4
  2029.         jb      .8hi
  2030.         sub     edi, 8
  2031.         jb      .16
  2032.         mov     ebp, [_eax+edi*4]
  2033.         jmp     .ret
  2034. .16:
  2035.         movzx   ebp, word [_eax+(edi+8)*4]
  2036.         jmp     .ret
  2037. .8lo:
  2038.         movzx   ebp, byte [_eax+(edi+4)*4]
  2039.         jmp     .ret
  2040. .8hi:
  2041.         movzx   ebp, byte [_eax+(edi+4)*4+1]
  2042.         jmp     .ret
  2043. .eip:
  2044.         mov     ebp, [_eip]
  2045.         jmp     .ret
  2046. .lp:
  2047.         call    expr_get_token
  2048.         call    expr_read0
  2049.         cmp     al, token_err
  2050.         jz      @f
  2051.         cmp     al, token_rp
  2052.         jz      expr_get_token
  2053.         mov     al, token_err
  2054.         mov     esi, aParseError
  2055. @@:     ret
  2056.  
  2057. expr_read1:
  2058.         call    expr_read2
  2059. .1:
  2060.         cmp     al, token_mul
  2061.         jz      .mul
  2062.         cmp     al, token_div
  2063.         jz      .div
  2064.         ret
  2065. .mul:
  2066.         push    ebp
  2067.         call    expr_get_token
  2068.         call    expr_read2
  2069.         pop     edx
  2070. ; ebp := edx*ebp
  2071.         imul    ebp, edx
  2072.         jmp     .1
  2073. .div:
  2074.         push    ebp
  2075.         call    expr_get_token
  2076.         call    expr_read2
  2077.         pop     edx
  2078. ; ebp := edx/ebp
  2079.         test    ebp, ebp
  2080.         jz      .div0
  2081.         push    eax
  2082.         xor     eax, eax
  2083.         xchg    eax, edx
  2084.         div     ebp
  2085.         xchg    eax, ebp
  2086.         pop     eax
  2087.         jmp     .1
  2088. .div0:
  2089.         mov     al, token_err
  2090.         mov     esi, aDivByZero
  2091.         ret
  2092.  
  2093. expr_read0:
  2094.         xor     ebp, ebp
  2095.         cmp     al, token_add
  2096.         jz      .add
  2097.         cmp     al, token_sub
  2098.         jz      .sub
  2099.         call    expr_read1
  2100. .1:
  2101.         cmp     al, token_add
  2102.         jz      .add
  2103.         cmp     al, token_sub
  2104.         jz      .sub
  2105.         ret
  2106. .add:
  2107.         push    ebp
  2108.         call    expr_get_token
  2109.         call    expr_read1
  2110.         pop     edx
  2111. ; ebp := edx+ebp
  2112.         add     ebp, edx
  2113.         jmp     .1
  2114. .sub:
  2115.         push    ebp
  2116.         call    expr_get_token
  2117.         call    expr_read1
  2118.         pop     edx
  2119. ; ebp := edx-ebp
  2120.         xchg    edx, ebp
  2121.         sub     ebp, edx
  2122.         jmp     .1
  2123.  
  2124. calc_expression:
  2125. ; in: esi->expression
  2126. ; out: CF=1 if error
  2127. ;      CF=0 and ebp=value if ok
  2128.         call    expr_get_token
  2129.         call    expr_read0
  2130.         cmp     al, token_end
  2131.         jz      .end
  2132.         cmp     al, token_err
  2133.         jz      @f
  2134.         mov     esi, aParseError
  2135. @@:
  2136.         call    put_message
  2137.         stc
  2138.         ret
  2139. .end:
  2140.         clc
  2141.         ret
  2142.  
  2143. OnCalc:
  2144.         mov     esi, [curarg]
  2145.         call    calc_expression
  2146.         jc      .ret
  2147.         push    ebp
  2148.         mov     esi, calc_string
  2149.         call    put_message_nodraw
  2150.         jmp     draw_messages
  2151. .ret:
  2152.         ret
  2153.  
  2154. OnDump:
  2155.         mov     esi, [curarg]
  2156.         cmp     byte [esi], 0
  2157.         jnz     .param
  2158.         add     [dumppos], dump_height*10h
  2159.         jmp     .doit
  2160. .param:
  2161.         call    calc_expression
  2162.         jc      .ret
  2163.         mov     [dumppos], ebp
  2164. .doit:
  2165.         call    get_dump
  2166.         call    redraw_dump
  2167. .ret:
  2168.         ret
  2169.  
  2170. OnUnassemble:
  2171.         mov     esi, [curarg]
  2172.         cmp     byte [esi], 0
  2173.         jnz     .param
  2174.         mov     eax, [disasm_start_pos]
  2175.         mov     ecx, disasm_height
  2176.         mov     [disasm_cur_pos], eax
  2177. @@:
  2178.         push    ecx
  2179.         call    disasm_instr
  2180.         pop     ecx
  2181.         jc      .err
  2182.         loop    @b
  2183.         mov     eax, [disasm_cur_pos]
  2184.         jmp     .doit
  2185. .param:
  2186.         call    calc_expression
  2187.         jc      .ret
  2188.         mov     eax, ebp
  2189. .doit:
  2190.         push    eax
  2191.         push    [disasm_start_pos]
  2192.         mov     [disasm_start_pos], eax
  2193.         call    update_disasm
  2194.         pop     [disasm_start_pos]
  2195.         pop     eax
  2196.         cmp     [disasm_cur_str], 0
  2197.         jz      @f
  2198.         mov     [disasm_start_pos], eax
  2199. .ret:
  2200.         ret
  2201. @@:
  2202.         call    update_disasm
  2203. .err:
  2204.         mov     esi, aInvAddr
  2205.         jmp     put_message
  2206.  
  2207. OnReg:
  2208.         mov     esi, [curarg]
  2209.         call    skip_spaces
  2210.         call    find_reg
  2211.         jnc     @f
  2212. .err:
  2213.         mov     esi, RSyntax
  2214.         jmp     put_message
  2215. @@:
  2216.         call    skip_spaces
  2217.         test    al, al
  2218.         jz      .err
  2219.         cmp     al, '='
  2220.         jnz     @f
  2221.         inc     esi
  2222.         call    skip_spaces
  2223.         test    al, al
  2224.         jz      .err
  2225. @@:
  2226.         push    edi
  2227.         call    calc_expression
  2228.         pop     edi
  2229.         jc      .ret
  2230. ; now edi=register id, ebp=value
  2231.         cmp     [bSuspended], 0
  2232.         mov     esi, aRunningErr
  2233.         jz      put_message
  2234.         xchg    eax, ebp
  2235.         cmp     edi, 24
  2236.         jz      .eip
  2237.         sub     edi, 4
  2238.         jb      .8lo
  2239.         sub     edi, 4
  2240.         jb      .8hi
  2241.         sub     edi, 8
  2242.         jb      .16
  2243.         mov     [_eax+edi*4], eax
  2244.         jmp     .ret
  2245. .16:
  2246.         mov     word [_eax+(edi+8)*4], ax
  2247.         jmp     .ret
  2248. .8lo:
  2249.         mov     byte [_eax+(edi+4)*4], al
  2250.         jmp     .ret
  2251. .8hi:
  2252.         mov     byte [_eax+(edi+4)*4+1], al
  2253.         jmp     .ret
  2254. .eip:
  2255.         mov     [_eip], eax
  2256.         call    update_disasm_eip
  2257. .ret:
  2258.         call    set_context
  2259.         jmp     redraw_registers
  2260.  
  2261. ; Breakpoints manipulation
  2262. OnBp:
  2263.         mov     esi, [curarg]
  2264.         call    calc_expression
  2265.         jc      .ret
  2266.         xchg    eax, ebp
  2267.         push    eax
  2268.         call    find_breakpoint
  2269.         inc     eax
  2270.         pop     eax
  2271.         jz      .notfound
  2272.         mov     esi, aDuplicateBreakpoint
  2273.         jmp     .sayerr
  2274. .notfound:
  2275.         mov     bl, 1
  2276.         call    add_breakpoint
  2277.         jnc     .ret
  2278.         mov     esi, aBreakpointLimitExceeded
  2279. .sayerr:
  2280.         call    put_message
  2281. .ret:
  2282.         jmp     redraw_disasm
  2283.  
  2284. OnBpmb:
  2285.         mov     dh, 0011b
  2286.         jmp     DoBpm
  2287. OnBpmw:
  2288.         mov     dh, 0111b
  2289.         jmp     DoBpm
  2290. OnBpmd:
  2291.         mov     dh, 1111b
  2292. DoBpm:
  2293.         mov     esi, [curarg]
  2294.         cmp     byte [esi], 'w'
  2295.         jnz     @f
  2296.         and     dh, not 2
  2297.         inc     esi
  2298. @@:
  2299.         push    edx
  2300.         call    calc_expression
  2301.         pop     edx
  2302.         jnc     @f
  2303.         ret
  2304. @@:
  2305. ; ebp=expression, dh=flags
  2306.         movzx   eax, dh
  2307.         shr     eax, 2
  2308.         test    ebp, eax
  2309.         jz      @f
  2310.         mov     esi, aUnaligned
  2311.         jmp     put_message
  2312. @@:
  2313.         mov     eax, ebp
  2314.         mov     bl, 0Bh
  2315.         call    add_breakpoint
  2316.         jnc     @f
  2317.         mov     esi, aBreakpointLimitExceeded
  2318.         jmp     put_message
  2319. @@:
  2320. ; now find index
  2321.         push    eax
  2322.         xor     ecx, ecx
  2323. .l1:
  2324.         cmp     [drx_break+ecx*4], 0
  2325.         jnz     .l2
  2326.         push    69
  2327.         pop     eax
  2328.         push    ecx
  2329.         mov     dl, cl
  2330.         mov     ecx, [debuggee_pid]
  2331.         mov     esi, ebp
  2332.         push    9
  2333.         pop     ebx
  2334.         int     40h
  2335.         test    eax, eax
  2336.         jz      .ok
  2337.         pop     ecx
  2338. .l2:
  2339.         inc     ecx
  2340.         cmp     ecx, 4
  2341.         jb      .l1
  2342.         pop     eax
  2343.         call    clear_breakpoint
  2344.         mov     esi, aBreakpointLimitExceeded
  2345.         jmp     put_message
  2346. .ok:
  2347.         pop     ecx
  2348.         pop     eax
  2349.         and     byte [edi], not 2       ; breakpoint is enabled
  2350.         shl     dl, 6
  2351.         or      dl, dh
  2352.         mov     byte [edi+1], dl
  2353.         inc     eax
  2354.         mov     [drx_break+ecx*4], eax
  2355.         ret
  2356.  
  2357. OnBc:
  2358.         mov     esi, [curarg]
  2359. @@:     call    get_hex_number
  2360.         jc      OnBp.ret
  2361.         call    clear_breakpoint
  2362.         jmp     @b
  2363.  
  2364. OnBd:
  2365.         mov     esi, [curarg]
  2366. @@:     call    get_hex_number
  2367.         jc      OnBp.ret
  2368.         call    disable_breakpoint
  2369.         jmp     @b
  2370.  
  2371. OnBe:
  2372.         mov     esi, [curarg]
  2373. @@:     call    get_hex_number
  2374.         jc      OnBp.ret
  2375.         push    eax
  2376.         call    find_enabled_breakpoint
  2377.         pop     eax
  2378.         jz      .err
  2379.         call    enable_breakpoint
  2380.         jmp     @b
  2381. .err:
  2382.         mov     esi, OnBeErrMsg
  2383.         jmp     put_message
  2384.  
  2385. get_hex_number:
  2386.         call    skip_spaces
  2387.         xor     ecx, ecx
  2388.         xor     edx, edx
  2389. @@:
  2390.         lodsb
  2391.         call    is_hex_digit
  2392.         jc      .ret
  2393.         shl     edx, 4
  2394.         or      dl, al
  2395.         inc     ecx
  2396.         jmp     @b
  2397. .ret:
  2398.         dec     esi
  2399.         cmp     ecx, 1
  2400.         xchg    eax, edx
  2401.         ret
  2402.  
  2403. OnBl:
  2404.         mov     esi, [curarg]
  2405.         cmp     byte [esi], 0
  2406.         jz      .listall
  2407.         call    get_hex_number
  2408.         jc      .ret
  2409.         cmp     eax, breakpoints_n
  2410.         jae     .err
  2411.         push    eax
  2412.         add     eax, eax
  2413.         lea     edi, [breakpoints + eax + eax*2]
  2414.         pop     eax
  2415.         test    byte [edi+4], 1
  2416.         jz      .err
  2417.         call    show_break_info
  2418. .ret:
  2419.         ret
  2420. .err:
  2421.         mov     esi, aInvalidBreak
  2422.         jmp     put_message
  2423. .listall:
  2424.         mov     edi, breakpoints
  2425.         xor     eax, eax
  2426. @@:
  2427.         test    byte [edi+4], 1
  2428.         jz      .cont
  2429.         push    edi eax
  2430.         call    show_break_info
  2431.         pop     eax edi
  2432. .cont:
  2433.         add     edi, 6
  2434.         inc     eax
  2435.         cmp     eax, breakpoints_n
  2436.         jb      @b
  2437.         ret
  2438.  
  2439. show_break_info:
  2440.         push    edi
  2441.         test    byte [edi+4], 8
  2442.         jnz     .dr
  2443.         push    dword [edi]
  2444.         push    eax
  2445.         mov     esi, aBreakNum
  2446.         call    put_message_nodraw
  2447.         jmp     .cmn
  2448. .dr:
  2449.         push    eax
  2450.         mov     esi, aMemBreak1
  2451.         call    put_message_nodraw
  2452.         pop     edi
  2453.         push    edi
  2454.         mov     esi, aMemBreak2
  2455.         test    byte [edi+5], 2
  2456.         jz      @f
  2457.         mov     esi, aMemBreak3
  2458. @@:
  2459.         call    put_message_nodraw
  2460.         pop     edi
  2461.         push    edi
  2462.         mov     esi, aMemBreak6
  2463.         test    byte [edi+5], 8
  2464.         jnz     @f
  2465.         mov     esi, aMemBreak5
  2466.         test    byte [edi+5], 4
  2467.         jnz     @f
  2468.         mov     esi, aMemBreak4
  2469. @@:
  2470.         call    put_message_nodraw
  2471.         pop     edi
  2472.         push    edi
  2473.         push    dword [edi]
  2474.         mov     esi, aMemBreak7
  2475.         call    put_message_nodraw
  2476. .cmn:
  2477.         pop     edi
  2478.         test    byte [edi+4], 2
  2479.         jz      @f
  2480.         push    edi
  2481.         mov     esi, aDisabled
  2482.         call    put_message_nodraw
  2483.         pop     edi
  2484. @@:
  2485.         test    byte [edi+4], 4
  2486.         jz      @f
  2487.         mov     esi, aOneShot
  2488.         call    put_message_nodraw
  2489. @@:
  2490.         mov     esi, newline
  2491.         jmp     put_message
  2492.  
  2493. add_breakpoint:
  2494. ; in: eax=address, bl=flags
  2495. ; out: CF=1 => error, CF=0 => eax=breakpoint number
  2496.         xor     ecx, ecx
  2497.         mov     edi, breakpoints
  2498. @@:
  2499.         test    byte [edi+4], 1
  2500.         jz      .found
  2501.         add     edi, 6
  2502.         inc     ecx
  2503.         cmp     ecx, breakpoints_n
  2504.         jb      @b
  2505.         stc
  2506.         ret
  2507. .found:
  2508.         stosd
  2509.         xchg    eax, ecx
  2510.         mov     [edi], bl
  2511.         test    bl, 2
  2512.         jnz     @f
  2513.         or      byte [edi], 2
  2514.         push    eax
  2515.         call    enable_breakpoint
  2516.         pop     eax
  2517. @@:
  2518.         clc
  2519.         ret
  2520.  
  2521. clear_breakpoint:
  2522.         cmp     eax, breakpoints_n
  2523.         jae     .ret
  2524.         mov     ecx, 4
  2525.         inc     eax
  2526. .1:
  2527.         cmp     [drx_break-4+ecx*4], eax
  2528.         jnz     @f
  2529.         and     [drx_break-4+ecx*4], 0
  2530. @@:     loop    .1
  2531.         dec     eax
  2532.         push    eax
  2533.         add     eax, eax
  2534.         lea     edi, [breakpoints + eax + eax*2 + 4]
  2535.         test    byte [edi], 1
  2536.         pop     eax
  2537.         jz      .ret
  2538.         push    edi
  2539.         call    disable_breakpoint
  2540.         pop     edi
  2541.         mov     byte [edi], 0
  2542. .ret:
  2543.         ret
  2544.  
  2545. disable_breakpoint:
  2546.         cmp     eax, breakpoints_n
  2547.         jae     .ret
  2548.         add     eax, eax
  2549.         lea     edi, [breakpoints + eax + eax*2 + 5]
  2550.         test    byte [edi-1], 1
  2551.         jz      .ret
  2552.         test    byte [edi-1], 2
  2553.         jnz     .ret
  2554.         or      byte [edi-1], 2
  2555.         test    byte [edi-1], 8
  2556.         jnz     .dr
  2557.         push    esi
  2558.         push    7
  2559.         pop     ebx
  2560.         push    69
  2561.         pop     eax
  2562.         mov     ecx, [debuggee_pid]
  2563.         xor     edx, edx
  2564.         inc     edx
  2565.         mov     esi, [edi-5]
  2566.         int     40h
  2567.         pop     esi
  2568. .ret:
  2569.         ret
  2570. .dr:
  2571.         mov     dl, [edi]
  2572.         shr     dl, 6
  2573.         mov     dh, 80h
  2574.         push    69
  2575.         pop     eax
  2576.         push    9
  2577.         pop     ebx
  2578.         mov     ecx, [debuggee_pid]
  2579.         int     40h
  2580.         ret
  2581.  
  2582. enable_breakpoint:
  2583.         push    esi
  2584.         cmp     eax, breakpoints_n
  2585.         jae     .ret
  2586.         add     eax, eax
  2587.         lea     edi, [breakpoints + eax + eax*2 + 5]
  2588.         test    byte [edi-1], 1
  2589.         jz      .ret
  2590.         test    byte [edi-1], 2
  2591.         jz      .ret
  2592.         and     byte [edi-1], not 2
  2593.         test    byte [edi-1], 8
  2594.         jnz     .dr
  2595.         push    6
  2596.         pop     ebx
  2597.         push    69
  2598.         pop     eax
  2599.         mov     esi, [edi-5]
  2600.         mov     ecx, [debuggee_pid]
  2601.         xor     edx, edx
  2602.         inc     edx
  2603.         int     40h
  2604.         dec     eax
  2605.         jnz     .err
  2606.         mov     al, 69
  2607.         push    0xCC
  2608.         mov     edi, esp
  2609.         inc     ebx
  2610.         int     40h
  2611.         pop     eax
  2612. .ret:
  2613.         pop     esi
  2614.         ret
  2615. .err:
  2616.         or      byte [edi-1], 2
  2617.         mov     esi, aBreakErr
  2618.         call    put_message
  2619.         pop     esi
  2620.         ret
  2621. .dr:
  2622.         push    9
  2623.         pop     ebx
  2624.         push    69
  2625.         pop     eax
  2626.         mov     esi, [edi-5]
  2627.         mov     ecx, [debuggee_pid]
  2628.         mov     dl, [edi]
  2629.         shr     dl, 6
  2630.         mov     dh, [edi]
  2631.         and     dh, 0xF
  2632.         int     40h
  2633.         test    eax, eax
  2634.         jnz     .err
  2635.         pop     esi
  2636.         ret
  2637.  
  2638. find_breakpoint:
  2639.         xor     ecx, ecx
  2640.         xchg    eax, ecx
  2641.         mov     edi, breakpoints
  2642. @@:
  2643.         test    byte [edi+4], 1
  2644.         jz      .cont
  2645.         test    byte [edi+4], 8
  2646.         jnz     .cont
  2647.         cmp     [edi], ecx
  2648.         jz      .found
  2649. .cont:
  2650.         add     edi, 6
  2651.         inc     eax
  2652.         cmp     eax, breakpoints_n
  2653.         jb      @b
  2654.         or      eax, -1
  2655. .found:
  2656.         ret
  2657.  
  2658. find_enabled_breakpoint:
  2659.         xor     ecx, ecx
  2660.         xchg    eax, ecx
  2661.         mov     edi, breakpoints
  2662. @@:
  2663.         test    byte [edi+4], 1
  2664.         jz      .cont
  2665.         test    byte [edi+4], 2 or 8
  2666.         jnz     .cont
  2667.         cmp     [edi], ecx
  2668.         jz      .found
  2669. .cont:
  2670.         add     edi, 6
  2671.         inc     eax
  2672.         cmp     eax, breakpoints_n
  2673.         jb      @b
  2674.         or      eax, -1
  2675. .found:
  2676.         ret
  2677.  
  2678. OnUnpack:
  2679. ; program must be loaded - checked when command was parsed
  2680. ; program must be stopped
  2681.         mov     esi, aRunningErr
  2682.         cmp     [bSuspended], 0
  2683.         jz      put_message
  2684. ; all breakpoints must be disabled
  2685.         mov     edi, breakpoints
  2686. @@:
  2687.         test    byte [edi+4], 1
  2688.         jz      .cont
  2689.         test    byte [edi+4], 2
  2690.         jnz     .cont
  2691.         mov     esi, aEnabledBreakErr
  2692.         jmp     put_message
  2693. .cont:
  2694.         add     edi, 6
  2695.         cmp     edi, breakpoints+breakpoints_n*6
  2696.         jb      @b
  2697. ; ok, now do it
  2698. ; set breakpoint on 0xC dword access
  2699.         push    9
  2700.         pop     ebx
  2701.         mov     ecx, [debuggee_pid]
  2702.         mov     dx, 1111b*256
  2703.         push    0xC
  2704.         pop     esi
  2705. @@:
  2706.         push    69
  2707.         pop     eax
  2708.         int     40h
  2709.         test    eax, eax
  2710.         jz      .breakok
  2711.         inc     edx
  2712.         cmp     dl, 4
  2713.         jb      @b
  2714. .breakok:
  2715.         call    GoOn
  2716. ; now wait for event
  2717. .wait:
  2718.         push    10
  2719.         pop     eax
  2720.         int     40h
  2721.         dec     eax
  2722.         jz      .redraw
  2723.         dec     eax
  2724.         jz      .key
  2725.         dec     eax
  2726.         jnz     .debug
  2727. ; button; we have only one button, close
  2728.         or      eax, -1
  2729.         int     40h
  2730. .redraw:
  2731.         call    draw_window
  2732.         jmp     .wait
  2733. .key:
  2734.         mov     al, 2
  2735.         int     40h
  2736.         cmp     ah, 3   ; Ctrl+C
  2737.         jnz     .wait
  2738. .userbreak:
  2739.         mov     esi, aInterrupted
  2740. .x1:
  2741.         push    edx esi
  2742.         call    put_message
  2743.         pop     esi edx
  2744.         or      dh, 80h
  2745.         push    69
  2746.         pop     eax
  2747.         push    9
  2748.         pop     ebx
  2749.         mov     ecx, [debuggee_pid]
  2750.         int     40h
  2751.         cmp     esi, aUnpacked
  2752.         jnz     OnSuspend
  2753.         jmp     AfterSuspend
  2754. .debug:
  2755.         cmp     [dbgbuflen], 4*3
  2756.         jnz     .notour
  2757.         cmp     dword [dbgbuf], 3
  2758.         jnz     .notour
  2759.         test    byte [dbgbuf+8], 1
  2760.         jnz     .our
  2761. .notour:
  2762.         mov     esi, aInterrupted
  2763.         push    edx
  2764.         call    put_message
  2765.         pop     edx
  2766.         or      dh, 80h
  2767.         push    69
  2768.         pop     eax
  2769.         push    9
  2770.         pop     ebx
  2771.         mov     ecx, [debuggee_pid]
  2772.         int     40h
  2773.         jmp     debugmsg
  2774. .our:
  2775.         and     [dbgbuflen], 0
  2776.         push    edx
  2777.         call    get_context
  2778.         push    eax
  2779.         mov     al, 69
  2780.         mov     bl, 6
  2781.         mov     ecx, [debuggee_pid]
  2782.         mov     edi, esp
  2783.         push    4
  2784.         pop     edx
  2785.         push    0xC
  2786.         pop     esi
  2787.         int     40h
  2788.         pop     eax
  2789.         pop     edx
  2790.         cmp     eax, [_eip]
  2791.         jz      .done
  2792.         call    DoResume
  2793.         jmp     .wait
  2794. .done:
  2795.         mov     esi, aUnpacked
  2796.         jmp     .x1
  2797.  
  2798. disasm_get_byte:
  2799. ; out: al=byte
  2800.         push    ecx
  2801.         mov     ecx, [disasm_cur_pos]
  2802.         sub     ecx, [disasm_start_pos]
  2803.         cmp     ecx, [disasm_buf_size]
  2804.         jae     disasm_err
  2805.         mov     al, [disasm_buffer+ecx]
  2806.         pop     ecx