home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HOOKKBS.ZIP / doswin32.mac < prev    next >
Text File  |  1992-09-17  |  18KB  |  595 lines

  1. ;--------------------------------------------------------------------
  2. ;doswin32.mac  Begun:Sat  08-22-1992  Revised:Tue  09-15-1992
  3. ;
  4. ;These Macros are more general purpose in definition and serve both
  5. ;DOS and WIN calls
  6. ;
  7. ;--------------------------------------------------------------------
  8. ;---------------- Switch List Structures in PMSHL.INC
  9. ;SWCNTRL STRUC   ;size = 96                        ;OFFSET FROM 0
  10. ;swctl_hwnd      DD      ?                              8
  11. ;swctl_hwndIcon  DD      ?                             12
  12. ;swctl_hprog     DD      ?                             16
  13. ;swctl_idProcess DD      ?                             20
  14. ;swctl_idSession DD      ?                             24
  15. ;swctl_uchVisibility     DD      ?                     28
  16. ;swctl_fbJump    DD      ?                             32
  17. ;swctl_szSwtitle DB      MAXNAMEL+4 DUP (?)            36  this is 60 long
  18. ;swctl_bProgType DD      ?                             96
  19. ;SWCNTRL ENDS
  20.  
  21. ;SWENTRY STRUC   ;size = 4 + 96
  22. ;swent_hswitch   DD      ?                              4 SwitchListEntryHandle
  23. ;swent_swctl     DB      SIZE SWCNTRL DUP (?)           8
  24. ;SWENTRY ENDS
  25.  
  26. ;SWBLOCK STRUC   ;size = 4 + (4+96)                ;
  27. ;swblk_cswentry  DD      ?                         ;    0  Count of Entries
  28. ;swblk_aswentry  DB      SIZE SWENTRY * 1 DUP (?)  ;    4
  29. ;SWBLOCK ENDS
  30. swblksize          equ  100     ; Size of SwitchList Structure
  31.  
  32. ;equates related to message structure
  33. hwnd           equ   quemsg.qmsg_hwnd
  34. msg            equ   quemsg.qmsg_msg
  35. mp1            equ   quemsg.qmsg_mp1
  36. mp2            equ   quemsg.qmsg_mp2
  37.  
  38. HWND_DESKTOP   equ   1               ;needed for  WinErrorMessage macro
  39. msgBoxErrStyle equ   (MB_ERROR OR MB_CANCEL)
  40.  
  41. ;---------------- I/O DOS Calls Only---------------
  42. stdin          equ   0
  43. stdout         equ   1
  44. stderr         equ   2
  45.  
  46. ;---------------- Useful ---------------
  47. cr             equ   0dh
  48. lf             equ   0ah
  49. nl             equ   0dh,0ah   ;cr+lf
  50. BEL            equ   07h
  51. NULL           equ   0000h
  52.  
  53. ;External declarations for DOS (Control Program) Functions (Used So Far)
  54. EXTRN    DosAllocMem:near,DosAllocSharedMem:near,DosBeep:near,DosClose:near
  55. EXTRN    DosCreateThread:near,DosDevConfig:near,DosDevIOCtl:near
  56. EXTRN    DosExecPgm:near,DosExit:near,DosFreeMem:near,DosFreeModule:near
  57. EXTRN    DosGetInfoBlocks:near,DosGetNamedSharedMem:near,DosKillThread:near
  58. EXTRN    DosLoadModule:near,DosOpen:near,DosPutMessage:near
  59. EXTRN    DosQueryModuleHandle:near,DosQueryModuleName:near,DosQueryProcAddr:near
  60. EXTRN    DosQueryProcType:near,DosRead:near,DosSleep:near,DosSetFilePtr:near
  61. EXTRN    DosStartSession:near,DosSetPriority:near,DosWrite:near
  62.  
  63. ;External declarations for Window (PM) Functions (Used So Far)
  64. EXTRN    WinAlarm:near,WinBeginPaint:near,WinBroadcastMsg:near,WinChangeSwitchEntry:near
  65. EXTRN    WinCreateMsgQueue:near,WinCreateStdWindow:near,WinDefWindowProc:near
  66. EXTRN    WinDestroyMsgQueue:near,WinDestroyWindow:near,WinDispatchMsg:near
  67. EXTRN    WinDrawText:near,WinEndPaint:near,WinFillRect:near,WinFocusChange:near
  68. EXTRN    WinFreeErrorInfo:near
  69. EXTRN    WinGetCurrentTime:near,WinGetErrorInfo:near,WinGetKeyState:near
  70. EXTRN    WinGetMsg:near,WinGetLastError:near,WinInitialize:near,WinMessageBox:near
  71. EXTRN    WinOpenWindowDC:near,WinPostMsg:near
  72. EXTRN    WinQueryDesktopWindow:near,WinQueryFocus:near,WinQueryMsgTime:near
  73. EXTRN    WinQuerySwitchList:near,WinQueryWindowRect:near
  74. EXTRN    WinRegisterClass:near,WinReleaseHook:near,WinReleasePS:near
  75. EXTRN    WinSetFocus:near,WinSetHook:near,WinSendMsg:near
  76. EXTRN    WinSwitchToProgram:near,WinTerminate:near
  77.  
  78. ;----------------------------------------------------------
  79. ;DEFINE Macros for DATA SEgment
  80.  
  81. ;Define Buffers used for Storage and for Num conversion
  82. $DefineNumBufs  MACRO
  83.     B_Buf       BYTE  3 dup(?)
  84.     W_Buf       BYTE  5 dup(?)
  85.     DW_Buf      BYTE 10 dup(0)
  86.     Bit8Str     BYTE  8 dup(?)
  87.     Bit16Str    BYTE  16 dup(?)
  88.     Bit32Str    BYTE  32 dup(?)
  89.     ten        DWORD  10         ;used for AsciiToWord
  90.     lth        DWORD  ?          ;used for AsciiToWord
  91.     errId      DWORD  ?
  92. ENDM
  93.  
  94. ;some standard strings and other vars for Data segment
  95. $DOSErrorMessages  MACRO
  96.     DosErrorMsg     BYTE   " Error calling Dos CP Function "
  97.     DosErrOpts      BYTE   "Enter Q to Quit Program - Any other Key to Continue"
  98.     DosReadErr      BYTE   ?,?    ;required for DOS read
  99.     newline         BYTE   13,10
  100.     nwritten       DWORD   ?      ;required for DOS Write
  101. ENDM
  102.  
  103. ;This macro allows the calling of any function subject only to the fact
  104. ;that it has no more than 10 parameters and that all are either DWORD
  105. ;long or are 32 bit offsets - i.e. it is a Full PUSH
  106. ;Enter Arguments in same order as listed in OS/2 2.0 Technical Library
  107. $Call MACRO fname,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9
  108.     ctr = 0
  109.     IFNB <arg9>
  110.        push  arg9
  111.        ctr = ctr + 4
  112.     ENDIF
  113.     IFNB <arg8>
  114.        push  arg8
  115.        ctr = ctr + 4
  116.     ENDIF
  117.     IFNB <arg7>
  118.        push  arg7
  119.        ctr = ctr + 4
  120.     ENDIF
  121.     IFNB <arg6>
  122.        push  arg6
  123.        ctr = ctr + 4
  124.     ENDIF
  125.     IFNB <arg5>
  126.        push  arg5
  127.        ctr = ctr + 4
  128.     ENDIF
  129.     IFNB <arg4>
  130.        push  arg4
  131.        ctr = ctr + 4
  132.     ENDIF
  133.     IFNB <arg3>
  134.        push  arg3
  135.        ctr = ctr + 4
  136.     ENDIF
  137.     IFNB <arg2>
  138.        push  arg2
  139.        ctr = ctr + 4
  140.     ENDIF
  141.     IFNB <arg1>
  142.        push  arg1
  143.        ctr = ctr + 4
  144.     ENDIF
  145.     IFNB <arg0>
  146.        push  arg0
  147.        ctr = ctr + 4
  148.     ENDIF
  149.     call   fname
  150.     add    esp,ctr
  151. ENDM
  152.  
  153. $NewLine     equ    $DosWriteMsg <cr,lf>
  154.  
  155. $Printf0 MACRO  typ,prm  ;typ : b/w/s = BYTE/WORD/STRING whose value is val
  156.     local    msgname,xit     ;bb/bw/ = 8bitstring,16bitstring representation of #
  157.     pusha                    ;bx/wx/dwx =  Byte/Word/DWord to Hex
  158.     IFIDNI  <typ>,<x>    ;default - nothing entered - exit
  159.         jmp   xit
  160.     ENDIF
  161.     IFIDNI  <typ>,<b>    ;b/w/ followed by b/h is in Binary/Hex representation
  162.         xor  edx,edx
  163.         mov  dl,prm
  164.         $DWordToAscii edx,DW_Buf
  165.         $DosWriteMsgAT DW_Buf
  166.         jmp   xit
  167.     ENDIF
  168.     IFIDNI  <typ>,<w>
  169.         xor  edx,edx
  170.         mov  dx,prm
  171.         $DWordToAscii edx,DW_Buf
  172.         $DosWriteMsgAT DW_Buf
  173.         jmp   xit
  174.     ENDIF
  175.     IFIDNI  <typ>,<dw>
  176.         $DWordToAscii prm,DW_Buf
  177.         $DosWriteMsgAT DW_Buf
  178.         jmp   xit
  179.     ENDIF
  180.     IFIDNI  <typ>,<bx>    ;b/w/ followed by b/h is in Binary/Hex representation
  181.         xor  edx,edx
  182.         mov  dl,prm
  183.         $DWordToHex edx,DW_Buf
  184.         $DosWriteMsgAT DW_Buf
  185.         jmp   xit
  186.     ENDIF
  187.     IFIDNI  <typ>,<wx>
  188.         xor  edx,edx
  189.         mov  dx,prm
  190.         $DWordToHex edx,DW_Buf
  191.         $DosWriteMsgAT DW_Buf
  192.         jmp   xit
  193.     ENDIF
  194.     IFIDNI  <typ>,<dwx>
  195.         $DWordToHex prm,DW_Buf
  196.         $DosWriteMsgAT DW_Buf
  197.         jmp   xit
  198.     ENDIF
  199.     IFIDNI  <typ>,<bb>
  200.         mov   al,prm
  201.         $ByteToBitString
  202.         $DosWriteMsgAT  Bit8Str
  203.         jmp   xit
  204.     ENDIF
  205.     IFIDNI  <typ>, <wb>
  206.         mov   ax,prm
  207.         $WordToBitString
  208.         $DosWriteMsgAT  Bit16Str
  209.         jmp   xit
  210.     ENDIF
  211.     IFIDNI  <typ>, <s>
  212.     $DosWriteMsg prm
  213.         jmp   xit
  214.     ENDIF
  215. xit:popa
  216. ENDM
  217.  
  218. $Printf MACRO  t1,p1,t2:=<x>,p2,t3:=<x>,p3,t4:=<x>,p4,t5:=<x>,p5,t6:=<x>,p6,t7:=<x>,p7
  219.     $Printf0  t1,p1
  220.     $Printf0  t2,p2
  221.     $Printf0  t3,p3
  222.     $Printf0  t4,p4
  223.     $Printf0  t5,p5
  224.     $Printf0  t6,p6
  225.     $Printf0  t7,p7
  226. ENDM
  227.  
  228.  
  229. $CLS  MACRO     ;clear screen with DosWrite
  230.     local c0
  231.     mov         cx,24
  232.     c0:
  233.                 $DosWriteMsg cr
  234.                 $DosWriteMsg lf
  235.     loop        c0
  236. ENDM
  237.  
  238. $DosReadKB MACRO  numreq,char_in_buf
  239.     .DATA
  240.     IFNDEF    bytesread
  241.         bytesread DWORD   0
  242.     ENDIF
  243.     .CODE
  244.     push     offset bytesread
  245.     pushd    numreq
  246.     push     offset char_in_buf
  247.     pushd     stdin
  248.     call     DosRead
  249.     add      esp,16
  250. ENDM
  251.  
  252. ; Write a message to console at current cursor
  253. $DosWriteMsg MACRO  messag
  254.     local    idmessag
  255.     .DATA
  256.     IFNDEF   messag
  257.       idmessag   BYTE  messag
  258.     ENDIF
  259.     .CODE
  260.     push     offset nwritten
  261.     push     LENGTHOF idmessag
  262.     push     offset idmessag
  263.     push     stdout      ;unsigned long
  264.     call     DosWrite
  265.     add      esp,16      ;restore stack pointer
  266. ENDM
  267.  
  268. ; Write to console the message stored AT location
  269. ; ofset is the offset from start of string "location" to start writing
  270. ; devised to get around printing leading spaces in numerical conversions
  271. $DosWriteMsgAT MACRO  location ,ofset:=<0>   ;0 is default
  272.     push     offset nwritten
  273.     mov      eax,LENGTHOF location
  274.     sub      eax,ofset
  275.     push     eax
  276.     mov      eax,offset location
  277.     add      eax,ofset
  278.     push     eax
  279.     pushd    stdout      ;unsigned long
  280.     call     DosWrite
  281.     add      esp,16      ;restore stack pointer
  282. ENDM
  283.  
  284.  
  285. $Alarm  MACRO     ;Makes a nice up and down sound
  286.     $Call DosBeep,300,300
  287.     $Call DosBeep,600,300
  288.     $Call DosBeep,300,300
  289. ENDM
  290.  
  291. ; Concantenate String S2 to end of String S1 and place at S3
  292. ; S3 buffer must be long enough to hold S1+S2. S3 is 0 terminated
  293. ; copy S1 to buffer S3 and then add S2 at end
  294. $ConcantS1andS2toS3  MACRO  S1,S2,S3
  295.      pusha
  296.      mov     edi,offset S3
  297.      mov     esi,offset S1
  298.      mov     ecx,LENGTHOF S1
  299.      rep     movsb
  300.      mov     esi,offset S2
  301.      mov     ecx,LENGTHOF S2
  302.      rep     movsb
  303.      inc     edi
  304.      mov     byte ptr [edi],0    ;NULL Terminate
  305.      popa
  306. ENDM
  307.  
  308. ;This is useful for BEEPING
  309. ;$DosBeep equ  $Call DosBeep,500,500   ;frequency,duration
  310.  
  311. ;Useful for exiting
  312. $DosExit equ  $Call DosExit,1,0  ;return 0 and all threads
  313.  
  314. ;useful for Carriage ReturnLine Feeds - requires newline definition in .DATA
  315. $NewLine equ  $Call DosWrite,stdout,offset newline,LENGTHOF newline,offset nwritten
  316.  
  317. $NumSwitchListEntries  equ  $Call  WinQuerySwitchList,hab,0,0    ;eax has number of entries
  318.  
  319. ;Used for Displaying Error Messages forDOS functions
  320. ;Called right after a $Call call of a DOS function if Error trapping desired
  321. ;The user passes the FuncName to be displayed
  322. ;It should be the Name of the Function used in $Call
  323. ;If error is detected, after displaying error number and function
  324. ;User is offered option of exiting or continuing
  325. $DosErrMsg  MACRO  FuncName   ;FuncName passed in calling macros
  326.     local  exitDEM,  msgFuncName
  327.     .IF  eax == 0
  328.         jmp  exitDEM
  329.     .ENDIF
  330.     IFNDEF  FuncName
  331.       .DATA
  332.        msgFuncName   BYTE FuncName
  333.       .CODE
  334.     ENDIF
  335.     $DWordToAscii eax,DW_Buf
  336.     $NewLine
  337.     $Call DosWrite,stdout,offset DW_Buf,LENGTHOF DW_BUF,offset nwritten
  338.     $Call DosWrite,stdout,offset DosErrorMsg,LENGTHOF DosErrorMsg,offset nwritten
  339.     $Call DosWrite,stdout,offset msgFuncName,LENGTHOF msgFuncName,offset nwritten
  340.     $DosBeep
  341.     $NewLine
  342.     $Call DosWrite,stdout,offset DosErrOpts,LENGTHOF DosErrOpts,offset nwritten
  343.     $Call DosRead,stdin,offset DosReadErr,1,offset nwritten
  344.     mov    al,DosReadErr
  345. .IF     al == 'q' || al == 'Q'
  346.      $DosExit
  347. .ENDIF
  348. exitDEM:
  349. ENDM
  350.  
  351. $WinDebugMessage MACRO arg      ;Display Message = arg # in eax before call
  352.     pusha
  353.     $DWordToAscii eax,DW_Buf
  354.     $Alarm
  355.     $ConcantS1andS2ToS3 DW_Buf,arg,Concanted
  356.     $Call WinMessageBox,HWND_DESKTOP,HWND_DESKTOP,offset Concanted,offset msgInfo,0,MB_ENTER    ;msgBoxErrStyle
  357.     popa
  358. ENDM
  359.  
  360. ;Error Message for PM applications - Pass the Function name as String in ""
  361. $WinErrMsg MACRO FuncName      ;sound alarm and display error box
  362.     local   msgFuncName
  363.     $Call WinGetLastError,hab    ;gets error number for code
  364.     IFNDEF  FuncName
  365.       .DATA
  366.        msgFuncName   BYTE FuncName
  367.     ENDIF
  368.    .CODE
  369.     $DWordToAscii eax,DW_Buf
  370.     $Alarm
  371.     $ConcantS1andS2ToS3 DW_Buf,msgFuncName,Concanted
  372.     $Call WinMessageBox,HWND_DESKTOP,HWND_DESKTOP,offset Concanted,NULL,0,msgBoxErrStyle
  373. ENDM
  374.  
  375. $GetCmdLine  MACRO  ;on return esi has offset of Command Line
  376.     .DATA
  377.     IFNDEF  ppTIB
  378.         ppTIB    DWORD  ?   ;To Hold Address of Thread   InfoBlock
  379.         ppPIB    DWORD  ?   ;To Hold Address of  Process InfoBlock
  380.     ENDIF
  381.     .CODE
  382.     push      offset ppPIB
  383.     push      offset ppTIB
  384.     call      DosGetInfoBlocks
  385.     add       esp,8          ;update ESP
  386.     mov       ebx,[ppPIB]    ;ebx = address of the PIB
  387.     mov       esi,[ebx+12]   ;esi is offset of command line
  388. ENDM
  389.  
  390. IFDEF NUMBUFS
  391. ;---------- Binary -> Ascii and Ascii -> Binary Conversions  ---------------
  392. ;Is Passed buffer name - tests to see if all characters in buffer are digits
  393. ;If not returns error message and aborts else returns number in eax
  394. ;skips over leading and trailing spaces
  395. $GetNumDigits MACRO  digbuf
  396.     push     esi
  397.     push     edi
  398.     mov      esi,offset digbuf
  399.     mov      edi,0
  400.     .WHILE 1
  401.         .WHILE byte ptr [esi] == 32    ;skip over leading spaces
  402.             inc esi
  403.         .ENDW
  404.         .IF  byte  ptr [esi] >= 30h
  405.             .IF byte ptr [esi] <= 39h
  406.                 inc edi
  407.                 inc esi
  408.              .ELSE
  409.                 .BREAK
  410.             .ENDIF
  411.          .ELSE
  412.             .BREAK
  413.          .ENDIF
  414.     .ENDW           ;on exit edi has number of bytes read
  415.     .IF edi == 0    ;no valid input
  416.          $DosBeep 500,500
  417.          IFDEF NOWIN    ;not a PM application
  418.              $NewLine
  419.              $Call DosWrite,"Invalid Input for ASCIIToDWord - Aborting"
  420.              $NewLine
  421.              $DosExit
  422.          ELSE
  423.              mov   eax,0
  424.              $WinDebugMessage
  425.              call ExitWin
  426.              $DosExit
  427.          ENDIF
  428.     .ENDIF
  429.     mov    eax,edi
  430.     pop    edi
  431.     pop    esi
  432. ENDM
  433.  
  434. ;Convert DWORD to ASCII string at 10 BYTE buffer at digits
  435. ;Number to convert moved into EAX, esi points to buffer
  436. $DWordToAscii MACRO  num,buf
  437.     pusha
  438.     mov      eax,num
  439.     mov      esi,offset buf
  440.     call     DWordToAscii
  441.     popa
  442. ENDM
  443.  
  444. ;Convert DWORD to Hex string at 10 BYTE buffer at digits
  445. ;Number to convert moved into EAX, esi points to buffer
  446. $DWordToHex MACRO  num,buf
  447.     pusha
  448.     mov      eax,num
  449.     mov      esi,offset buf
  450.     call     DWordToHex
  451.     popa
  452. ENDM
  453.  
  454. ;convert string representing BYTE in BUFF to numeric DWORD
  455. ;result returned in EAX)
  456. $AsciiToDWord  MACRO  Buff
  457.     $GetNumDigits Buff  ;checks on validity of characters in buffer as well
  458.     mov      lth,eax
  459.     push     ebx
  460.     push     ecx
  461.     push     edx
  462.     push     edi
  463.     push     esi
  464.     mov      esi,offset Buff
  465.     call     AsciitoDWord
  466.     pop      esi
  467.     pop      edi
  468.     pop      edx
  469.     pop      ecx
  470.     pop      ebx
  471. ENDM
  472.  
  473. ;Convert BYTE to Binary Bit String
  474. ;Byte to convert in AL
  475. $ByteToBitString MACRO
  476.     pusha
  477.     mov     edi,offset Bit8Str
  478.     call    ByteToBitString
  479.     popa
  480. ENDM
  481.  
  482. ;Byte to convert in AX
  483. $WordToBitString MACRO
  484.     pusha
  485.     mov     edi,offset Bit16Str
  486.     call    WordToBitString
  487.     popa
  488. ENDM
  489.  
  490. ;----------- Procedures here ---------------
  491.  
  492. .CODE
  493. ;--- Call with esi pointing to buffer to store digit string
  494. DWordToAScii  Proc
  495.     mov      edi,10
  496.     xor      edx,edx
  497.     mov      ecx,10
  498. d0: div      edi
  499.     add      edx,30h
  500.     push     edx          ;save on stack
  501.     xor      edx,edx
  502.     loop     d0           ;on exit top of stack has first digit, etc.
  503.     mov      ecx,10
  504. d1: pop      edx
  505.     mov      [esi],dl     ;esi has address of buffer
  506.     inc      esi
  507.     loop     d1
  508.     ; now get rid of leading 0's
  509.     sub      esi,10       ;back to start of string
  510.     mov      ecx,10
  511.     .WHILE   byte ptr [esi] == "0"
  512.          mov byte ptr [esi]," "
  513.          inc esi
  514.          dec ecx
  515.     .ENDW
  516.     .IF  cx == 0          ; all spaces
  517.          dec esi
  518.          mov byte ptr [esi] ,'0'
  519.     .ENDIF
  520.      ret
  521. DWordToAscii   endp
  522.  
  523. AsciiToDWord  proc
  524.     mov      eax,1
  525.     xor      edi,edi
  526.     xor      ebx,ebx
  527.     mov      ecx,lth
  528.     dec      lth
  529.     add      esi,lth       ;offset is lnth -1 from 0
  530. w0: push     eax
  531.     sub      byte ptr [esi],30h
  532.     mov      bl,[esi]
  533.     mul      bl            ;result in EAX
  534.     add      edi,eax
  535.     pop      eax
  536.     mul      ten        ;10 x previous value in AX now
  537.     dec      esi
  538.     loopd    w0
  539.     mov      eax,edi
  540.     ret
  541. AsciiToDWord  endp
  542.  
  543. ;--- Call with esi pointing to buffer to store digit string
  544. DWordToHex  Proc
  545.     mov      edi,16
  546.     xor      edx,edx
  547.     mov      ecx,8
  548. d0: div      edi
  549.     .IF      edx <= 9
  550.         add      edx,30h
  551.     .ELSE
  552.         add      edx,55   ;use caps
  553.     .ENDIF
  554.     push     edx          ;save on stack
  555.     xor      edx,edx
  556.     loop     d0           ;on exit top of stack has first digit, etc.
  557.     mov      ecx,8
  558. d1: pop      edx
  559.     mov      [esi],dl     ;esi has address of buffer
  560.     inc      esi
  561.     loop     d1
  562.     mov      byte ptr [esi],'H'
  563.      ret
  564. DWordToHex   endp
  565.  
  566. WordToBitString  proc  ;called with edi set to offset of string and # in ax
  567.     mov     cx,16
  568.     dec     edi
  569. wb0:inc     edi
  570.     shl     ax,1             ;move most significant bit to carry flag
  571.     jc      wb1              ;if set copy '1'
  572.     mov     byte ptr [edi],'0'       ;else copy '0'
  573.     jmp     wb2
  574. wb1:mov     byte ptr [edi],'1'
  575. wb2:loop    wb0
  576.     ret
  577. WordToBitString endp
  578.  
  579. .CODE
  580. ByteToBitString  proc        ; al has the number
  581.     mov     cx,8             ;called with edi set to offset of string
  582.     dec     edi
  583. bb0:inc     edi
  584.     shl     al,1             ;move most significant bit to carry flag
  585.     jc      bb1              ;if set copy '1'
  586.     mov     byte ptr [edi],'0'       ;else copy '0'
  587.     jmp     bb2
  588. bb1:mov     byte ptr [edi],'1'
  589. bb2:loop    bb0
  590.     ret
  591. ByteToBitString  endp
  592.  
  593. ENDIF
  594.  
  595.