home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR24 / MFKASM.ZIP / 386_DOS.MAC < prev    next >
Text File  |  1992-07-29  |  24KB  |  828 lines

  1. ;------------------------------------------------------
  2. ;386_dos.mac Begun:Mon  05-04-1992  Revised:Tue  07-28-1992
  3. ;M. F. Kaplon
  4. ;Macros using the DOSxxxx calls of OS/2 2.0
  5. ;Since using the Library that uses C-calling convention must push
  6. ;parameters in reverse order and reset the stack pointer.
  7. ;All Macro Names begin with $ and are followed in all
  8. ;cases of a DOS.... call with the name of the call
  9. ;Each DOS call macro resets the stack pointer based on number of pushes
  10. ;and the type of the push ( DWORDs)
  11. ;------------------------------------------------------
  12.  
  13. EXTRN    DosAllocMem:near,DosBeep:near,DosCreateThread:near,DosDevIOCtl:near
  14. EXTRN    DosExecPgm:near,DosExit:near,DosFreeMem:near,DosFreeModule:near
  15. EXTRN    DosGetInfoBlocks:near,DosKillThread:near
  16. EXTRN    DosLoadModule:near,DosOpen:near,DosPutMessage:near
  17. EXTRN    DosQueryModuleHandle:near,DosQueryModuleName:near,DosQueryProcAddr:near
  18. EXTRN    DosQueryProcType:near,DosRead:near,DosSleep:near,DosWrite:near
  19.  
  20. ;-------------------------- STRUCTURES --------------------------
  21.  
  22. KbdDataIn       STRUCT      ;structure for KbdCharIn and KbdPeek
  23.     Char        BYTE   ?
  24.     Scan        BYTE   ?
  25.     Status      BYTE   ?    ;Bits defined p 574 Duncan
  26.     Rsvd        BYTE   0
  27.     Shift       WORD   ?    ;Keyboard Shift State   Bits defined p 574 Duncan
  28.     Time        DWORD  ?    ;msec since system turned on/restarted
  29. KbdDataIn       ENDS        ;Usable ONLY in OS/2 FullScreen Window
  30.  
  31. DateTime        STRUCT       ;structure for DateTime Info
  32.     Hour        BYTE   ?     ;0-23
  33.     Minute      BYTE   ?     ;0-59
  34.     Second      BYTE   ?     ;0-59
  35.     Hundrs      BYTE   ?     ;0-99 hundredths of a second
  36.     Day         BYTE   ?     ;1-31
  37.     Month       BYTE   ?     ;1-12
  38.     Year        WORD   ?     ;1980-2079
  39.     TimeZone    WORD   ?     ;TimeZone(minutes± GMT, 300 = US EST,-1=undefined)
  40. DateTime        ENDS
  41.  
  42. ;------------------------- General Purpose Macros --------------------------
  43.  
  44. $Alarm  MACRO     ;Makes a nice up and down sound
  45.     $DosBeep 300,300
  46.     $DosBeep 600,300
  47.     $DosBeep 300,300
  48. ENDM
  49.  
  50. $BufLength MACRO  BufAdr  ;returns length of ASCII0 String at BufAdr in AX
  51.     push    esi
  52.     push    ebx
  53.     xor     ebx,ebx
  54.     mov     esi,BufAdr
  55.     .WHILE  byte ptr [esi+ebx] != 0
  56.             inc     ebx
  57. ;            .IF ebx > 64
  58. ;               $DosWriteMsg <nl,"exceeded 64 bytes long",nl>
  59. ;               $DosExit
  60. ;            .ENDIF
  61.     .ENDW
  62.      mov    eax,ebx
  63.      pop    ebx
  64.      pop    esi
  65. ENDM
  66.  
  67. $CLS  MACRO     ;clear screen with DosWrite
  68.     local c0
  69.     mov         cx,24
  70.     c0:
  71.                 $DosWriteMsg nl
  72.     loop        c0
  73. ENDM
  74.  
  75. ; Concantenate String S2 to end of String S1 and place at S3
  76. ; S3 buffer must be long enough to hold S1+S2. S3 is 0 terminates
  77. ; copy S1 to buffer S3 and then add S2 at end
  78. $ConcantS1andS2toS3  MACRO  S1,S2,S3
  79.      pusha
  80.      mov     edi,offset S3
  81.      mov     esi,offset S1
  82.      mov     ecx,LENGTHOF S1
  83.      rep     movsb
  84.      mov     esi,offset S2
  85.      mov     ecx,LENGTHOF S2
  86.      rep     movsb
  87.      inc     edi
  88.      mov     byte ptr [edi],0    ;NULL Terminate
  89.      popa
  90. ENDM
  91.  
  92. $DefineDosBufs MACRO    ;Define Buffers used by Dosroutines
  93.     nwritten   DWORD  ?      ;for those  programs requiring # written storage
  94.     ReadBuf     BYTE  5 dup(?)
  95. ENDM
  96.  
  97. $DefineNumBufs  MACRO    ;Define Buffers used for Storage for Num conversion
  98.     B_Buf       BYTE  3 dup(?)
  99.     W_Buf       BYTE  5 dup(?)
  100.     DW_Buf      BYTE 10 dup(0)
  101.     Bit8Str     BYTE  8 dup(?)
  102.     Bit16Str    BYTE  16 dup(?)
  103.     Bit32Str    BYTE  32 dup(?)
  104.     ten        DWORD  10         ;used for AsciiToWord
  105.     lth        DWORD  ?          ;used for AsciiToWord
  106.     errId      DWORD  ?
  107. ENDM
  108.  
  109. ; Display at current row + 1 Err_Num " Error Calling DOS Function FuncName"
  110. $DosErrMsg  MACRO  FuncName   ;FuncName passed in calling macros
  111.     $DWordToAscii eax,DW_Buf
  112.     $NewLine
  113.     $NewLine
  114.     $DosWriteMsgAT DW_Buf
  115.     $DosWriteMsg " Error calling Dos CP Function "
  116.     $DosWriteMsg FuncName
  117.     $DosBeep  500,500
  118. ENDM
  119.  
  120. $GetCmdLine  MACRO  ;on return esi has offset of Command Line
  121.     .DATA
  122.     IFNDEF  ppTIB
  123.         ppTIB    DWORD  ?   ;To Hold Address of Thread   InfoBlock
  124.         ppPIB    DWORD  ?   ;To Hold Address of  Process InfoBlock
  125.     ENDIF
  126.     .CODE
  127.     push      offset ppPIB
  128.     push      offset ppTIB
  129.     call      DosGetInfoBlocks
  130.     add       esp,8          ;update ESP
  131.     mov       ebx,[ppPIB]    ;ebx = address of the PIB
  132.     mov       esi,[ebx+12]   ;esi is offset of command line
  133. ENDM
  134.  
  135. $KbdData MACRO
  136.     .DATA
  137.     IFNDEF KbdData
  138.         KbdData  KbdDataIn  {,,,,}
  139.         KbdParm   WORD           1   ;1 record requested, wait for input
  140.         KbdPInOut DWORD          2   ; 2 bytes passed
  141.         KbdDInOut DWORD          0   ; 0 bytes passed on input
  142.     ENDIF
  143.     .CODE
  144.     $DosDevIoctl Offset KbdDInOut,10,Offset KbdData,Offset KbdPInOut,2,Offset KbdParm,74h,4,Handle,"Kbd - 74h"
  145. ENDM
  146.  
  147. $NewLine     equ    $DosWriteMsg <cr,lf>
  148.  
  149. $Printf0 MACRO  typ,prm  ;typ : b/w/s = BYTE/WORD/STRING whose value is val
  150.     local    msgname,xit     ;bb/bw/ = 8bitstring,16bitstring representation of #
  151.     pusha                    ;bx/wx/dwx =  Byte/Word/DWord to Hex
  152.     IFIDNI  <typ>,<x>    ;default - nothing entered - exit
  153.         jmp   xit
  154.     ENDIF
  155.     IFIDNI  <typ>,<b>    ;b/w/ followed by b/h is in Binary/Hex representation
  156.         xor  edx,edx
  157.         mov  dl,prm
  158.         $DWordToAscii edx,DW_Buf
  159.         $DosWriteMsgAT DW_Buf
  160.         jmp   xit
  161.     ENDIF
  162.     IFIDNI  <typ>,<w>
  163.         xor  edx,edx
  164.         mov  dx,prm
  165.         $DWordToAscii edx,DW_Buf
  166.         $DosWriteMsgAT DW_Buf
  167.         jmp   xit
  168.     ENDIF
  169.     IFIDNI  <typ>,<dw>
  170.         $DWordToAscii prm,DW_Buf
  171.         $DosWriteMsgAT DW_Buf
  172.         jmp   xit
  173.     ENDIF
  174.     IFIDNI  <typ>,<bx>    ;b/w/ followed by b/h is in Binary/Hex representation
  175.         xor  edx,edx
  176.         mov  dl,prm
  177.         $DWordToHex edx,DW_Buf
  178.         $DosWriteMsgAT DW_Buf
  179.         jmp   xit
  180.     ENDIF
  181.     IFIDNI  <typ>,<wx>
  182.         xor  edx,edx
  183.         mov  dx,prm
  184.         $DWordToHex edx,DW_Buf
  185.         $DosWriteMsgAT DW_Buf
  186.         jmp   xit
  187.     ENDIF
  188.     IFIDNI  <typ>,<dwx>
  189.         $DWordToHex prm,DW_Buf
  190.         $DosWriteMsgAT DW_Buf
  191.         jmp   xit
  192.     ENDIF
  193.     IFIDNI  <typ>,<bb>
  194.         mov   al,prm
  195.         $ByteToBitString
  196.         $DosWriteMsgAT  Bit8Str
  197.         jmp   xit
  198.     ENDIF
  199.     IFIDNI  <typ>, <wb>
  200.         mov   ax,prm
  201.         $WordToBitString
  202.         $DosWriteMsgAT  Bit16Str
  203.         jmp   xit
  204.     ENDIF
  205.     IFIDNI  <typ>, <s>
  206.     $DosWriteMsg prm
  207.         jmp   xit
  208.     ENDIF
  209. xit:popa
  210. ENDM
  211.  
  212. $Printf MACRO  t1,p1,t2:=<x>,p2,t3:=<x>,p3,t4:=<x>,p4,t5:=<x>,p5,t6:=<x>,p6,t7:=<x>,p7
  213.     $Printf0  t1,p1
  214.     $Printf0  t2,p2
  215.     $Printf0  t3,p3
  216.     $Printf0  t4,p4
  217.     $Printf0  t5,p5
  218.     $Printf0  t6,p6
  219.     $Printf0  t7,p7
  220. ENDM
  221.  
  222. $Wait  MACRO  ;Beeps and Displays Message "Press <CR> to Continue"
  223.     .DATA
  224.     IFNDEF  OneCharIn
  225.         OneCharIn  BYTE  ?
  226.     ENDIF
  227.     .CODE
  228.     $DosBeep 500,500
  229.     $DosWriteMsg <cr,lf,cr,lf,"                         Press <CR> to Continue",cr,lf>
  230.     $DosReadKB  2,OneCharIn
  231. ENDM
  232.  
  233. ;------------------------- DOS.... Macros --------------------------
  234.  
  235. $DosAllocMem  MACRO  flags,objsize,pbaseaddr
  236.     push     flags
  237.     push     objsize
  238.     push     offset pbaseaddr
  239.     call     DosAllocMem
  240.     add      esp,12                ;restore stack pointer
  241.     .IF eax != 0
  242.        IFDEF  NOWIN
  243.           $DosErrMsg  <" DosAllocMem",nl>
  244.           $DosExit
  245.        ELSE
  246.           $WinErrorMessage msgDosAllocMem
  247.        ENDIF
  248.     .ENDIF
  249. ENDM
  250.  
  251. ; Sound the bell
  252. $DosBeep  MACRO  beepf,beepd
  253.     pushd    beepd     ;duration in milliseconds
  254.     pushd    beepf     ;frequency in Hz
  255.     call     DosBeep
  256.     add      esp,8     ;restore stack pointer before return
  257. ENDM
  258.  
  259. $DosCreateThread  MACRO  arg0,arg1,arg2,arg3,arg4
  260.     push     arg4       ;StackSize in bytes of Thread
  261.     push     arg3       ;Thread Flags Bit 0 = 0/1  is start immed/suspended state;Bit 1 = 0/1 is Default methof for stack/precommits all pages in stack
  262.     push     arg2       ;Argument to be passed to thread - can be pointer
  263.     push     arg1       ;Address of Code to be executed when thread begins
  264.     push     arg0       ;Address of DWORD to store ThreadID
  265.     call     DosCreateThread
  266.     add      esp,20      ;reset stack
  267.     .IF eax != 0
  268.        IFDEF  NOWIN
  269.           $DosErrMsg  <" DosCreateThread",nl>
  270.           $DosExit
  271.        ELSE
  272.           $WinErrorMessage msgDosCreateThread
  273.        ENDIF
  274.     .ENDIF
  275. ENDM
  276.  
  277. ;pdataarea and pparmlist are set up so that if NULL pointer just enter 0, otherwise enter "offset name" when passing
  278. $DosDevIOCtl MACRO arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8
  279.     push    arg8    ;input/output Pointer
  280.     push    arg7    ;ULONG input , Length in Bytes of Data Area
  281.     push    arg6    ;input Address of Data Area
  282.     push    arg5    ;input/output pointer to Length in Bytes of parms passed/returned
  283.     push    arg4    ;ULONG input - length in bytes of parm list MaxLnth returned
  284.     push    arg3    ;input Address of command specific argument list
  285.     push    arg2    ;ULONG input Device specific function code
  286.     push    arg1    ;ULONG input Device Category range 0 -255
  287.     push    arg0    ;HFILE=ULONG input Device Handle value returned by dos Open
  288.     call     DosDevIOCtl
  289.     add     esp,36
  290.     .IF eax != 0
  291.        IFDEF NOWIN
  292.          $DosErrMsg  <" DosDevIOCtl">
  293.          $DosExit
  294.        ELSE
  295.          $WinErrorMessage msgDosDevIOCtl
  296.        ENDIF
  297.     .ENDIF
  298. ENDM
  299.  
  300. $DosExecPgm  MACRO  ExecMode,Args,ChildExec
  301.      .Data
  302.      IFNDEF ObjName
  303.          ObjName  BYTE  100 dup(0)  ;receives name of dynlink causing failure
  304.      ENDIF
  305.      IFNDEF RetCode
  306.          RetCode  DWORD  ?,?
  307.      ENDIF
  308.      .CODE
  309.      push   offset ChildExec
  310.      push   offset RetCode
  311.      pushd  0                 ;environment pointer 0 is pass parents
  312.      push   Offset Args       ;
  313.      pushd  ExecMode          ;Exec Flags - how executed
  314.      pushd  LENGTHOF ObjName  ;length in bytes of said buffer
  315.      push   offset ObjName    ;buffer to hold name of object casing failure
  316.      call   DosExecPgm
  317.     .IF eax != 0
  318.        $DosErrMsg  "DosExecPgm"
  319.        $DosExit
  320.     .ENDIF
  321.     add     esp,28
  322. ENDM
  323.  
  324. ; Exit Program
  325. $DosExit  MACRO
  326.     pushd    0         ;value returned
  327.     pushd    1         ;terminate process (all threads) (0 = current thread)
  328.     call     DosExit
  329. ENDM
  330.  
  331. $DosFreeMem  MACRO  pbaseaddr
  332.     push     pbaseaddr
  333.     call     DosFreeMem
  334.     .IF eax != 0
  335.        IFDEF NOWIN
  336.          $DosErrMsg  <" DosFreeMem",nl>
  337.          $DosExit
  338.        ELSE
  339.          $WinErrorMessage msgDosFreeMem
  340.        ENDIF
  341.     .ENDIF
  342.     add      esp,4                ;restore stack pointer
  343. ENDM
  344.  
  345. $DosFreeModule  MACRO  arg
  346.      push   arg            ;module handle
  347.      call   DosFreeModule
  348.      add    esp,4
  349.     .IF eax != 0
  350.        IFDEF   NOWIN
  351.            $DosErrMsg  <"  DosFreeModule",nl>
  352.            $DosExit
  353.        ELSE
  354.            $WinErrorMessage  msgDosFreeModule
  355.        ENDIF
  356.     .ENDIF
  357. ENDM
  358.  
  359. ;TIB and PIB are BLocks, of DWORD items
  360. $DosGetPIB MACRO  ;GET Process Information Blocks Info
  361. .DATA
  362. IFNDEF   ppPIB
  363.     ppPIB   DWORD   ?  ;Address of pointer to PIB
  364.     ppTIB   DWORD   ?  ;Address of pointer to TIB
  365.     PID     DWORD   ?  ;Process ID
  366.     PPID    DWORD   ?  ;Process ID of parent
  367.     ModHnd  DWORD   ?  ;Module Handle
  368.     CmdLn   DWORD   ?  ;Address of Command Line
  369.     Envrn   DWORD   ?  ;Address of Environment
  370.     Pstat   DWORD   ?  ;Status of Current Process
  371.     Ptype   DWORD   ?  ;Type of Current Process
  372. ENDIF
  373. .CODE
  374.     push    offset ppPIB
  375.     push    offset ppTIB
  376.     call    DosGetInfoBlocks
  377.     add     esp,8
  378.     mov     ebx,[ppPIB]     ;get PID
  379.     mov     eax,[ebx]
  380.     mov     PID,eax
  381.     mov     eax,[ebx+4]     ;get PPID
  382.     mov     PPID,eax
  383.     mov     eax,[ebx+8]     ;get Module Handle
  384.     mov     ModHnd,eax
  385.     mov     eax,[ebx+12]    ;get CmdLn
  386.     mov     CmdLn,eax
  387.     mov     eax,[ebx+16]    ;get environment address
  388.     mov     Envrn,eax
  389.     mov     eax,[ebx+20]    ;get Status of current Process
  390.     mov     Pstat,eax
  391.     mov     eax,[ebx+24]    ;get Type of Current Process
  392.     mov     Ptype,eax
  393. ENDM
  394.  
  395. $DosKillThread MACRO  arg
  396.     push    arg             ;ThreadID
  397.     call    DosKillThread
  398.     add     esp,4
  399.     .IF eax != 0
  400.        IFDEF   NOWIN
  401.            $DosErrMsg  <"  DosKillThread",nl>
  402.            $DosExit
  403.        ELSE
  404.            $WinErrorMessage  msgDosKillThread
  405.        ENDIF
  406.     .ENDIF
  407. ENDM
  408.  
  409. $DosLoadModule  MACRO  arg0,arg1,arg2,arg3
  410.     push    arg3    ;offset of module handle variable
  411.     push    arg2    ;offset of name of dll file
  412.     push    arg1    ;Buffer Length of DllLoadError
  413.     push    arg0    ;offset of DllLoadError buffer
  414.     call    DosLoadModule
  415.     add     esp,16
  416.     .IF eax != 0
  417.        IFDEF   NOWIN
  418.            $DosErrMsg  "  DosLoadModule Error"
  419.            $DosExit
  420.        ELSE
  421.          ;  $DWordToAscii eax,DW_Buf
  422.          ;  $ConcantS1andS2ToS3 DW_Buf,msgDosLoadModule,Concanted
  423.            $WinErrorMessage  msgDosLoadModule
  424.  
  425.        ENDIF
  426.     .ENDIF
  427. ENDM
  428.  
  429. $DosMonOpen  MACRO   arg1,arg2   ;this is in doscalla.dll
  430.     push    arg2        ;address of  variable to hold handle
  431.     push    arg1        ;address of device name string ASCZ11
  432.     call    DosMonOpen
  433.     add     esp,8
  434.     .IF eax != 0
  435.         $DosErrMsg  <"  DosMonoPen Error",nl>
  436.         $DosExit
  437.     .ENDIF
  438. ENDM
  439.  
  440. $DosOpen MACRO arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7
  441.     push    arg7    ;I/O     ULONG Pointer to address Extended Attr Bits 0 if not used
  442.     push    arg6    ;Input   ULONG Open Mode bits
  443.     push    arg5    ;Input   ULONG Oprm Flag bits
  444.     push    arg4    ;Input   ULONG FileAttribute Bits
  445.     push    arg3    ;Input   ULONG Logical file of size
  446.     push    arg2    ;Output  ULONG Address of variable to receive action taken
  447.     push    arg1    ;Output  Address for Handle of file/device
  448.     push    arg0    ;Input   Address of ASCIIZ name of file/device
  449.     call DosOpen
  450.     add      esp,32
  451.     .IF eax != 0
  452.        IFDEF NOWIN
  453.          $DosErrMsg  " DosOpen"    ;<" DosOpen",nl>
  454.          $DosExit
  455.        ELSE
  456.          $WinErrorMessage msgDosOpen
  457.        ENDIF
  458.     .ENDIF
  459. ENDM
  460.  
  461. $DosPutMessage  MACRO   buffer
  462.     local putmsg
  463.     .DATA
  464.           putmsg   BYTE  buffer
  465.     .CODE
  466.     push    offset putmsg
  467.     push    SIZEOF putmsg
  468.     push    stdout
  469.     call    DosPutMessage
  470. ;    .IF eax != 0
  471. ;       $DosErrMsg  "DosPutMessage"
  472. ;       $DosExit
  473. ;    .ENDIF
  474.     add      esp,12
  475. ENDM
  476.  
  477. $DosQueryModuleHandle  MACRO   arg1,arg2
  478.      push   arg2           ;address of DWORD to hold handle returned
  479.      push   arg1           ;address of ASCIIZ holding full path name of dll
  480.      call   DosQueryModuleHandle
  481.      add    esp,8
  482. ;    .IF eax != 0
  483. ;       IFDEF   NOWIN
  484. ;           $DosErrMsg  <"  DosQueryModuleHandle",nl>
  485. ;           $DosExit
  486. ;       ELSE
  487. ;           $WinErrorMessage msgDosQueryModuleHandle
  488. ;       ENDIF
  489. ;    .ENDIF
  490. ENDM
  491.  
  492. $DosQueryProcAddr   MACRO   arg0,arg1,arg2,arg3
  493.      push   arg3           ;pointer to DWORD var to hold address
  494.      push   arg2           ;address of ASCIIZ string holding procedure name
  495.      push   arg1           ;ordinal # of procedure whose address is desired 0 if name provided
  496.      push   arg0           ;handle of dynamic link module containing procedure
  497.      call   DosQueryProcAddr
  498.      add     esp,16
  499.     .IF eax != 0
  500.        IFDEF   NOWIN
  501.            $DosErrMsg  "  DosQueryProcAddr"
  502.            $DosExit
  503.        ELSE
  504.            $WinErrorMessage msgDosQueryProcAddr
  505.        ENDIF
  506.     .ENDIF
  507. ENDM
  508.  
  509. $DosQueryProcType  MACRO  arg0,arg1,arg2,arg3
  510.      push   arg3           ;pointer to DWORD var to hold Proc Type
  511.      push   arg2           ;address of ASCIIZ string holding procedure name
  512.      push   arg1           ;ordinal # of procedure whose address is desired 0 if name provided
  513.      push   arg0           ;handle of dynamic link module containing procedure
  514.      call   DosQueryProcType  ;returns 0 if 16 bit, 1 if 32 bit
  515.      add     esp,16
  516.     .IF eax != 0
  517.        IFDEF   NOWIN
  518.            $DosErrMsg  "  DosQueryProcType"
  519.            $DosExit
  520.        ELSE
  521.            $WinErrorMessage msgDosQueryProcType
  522.        ENDIF
  523.     .ENDIF
  524. ENDM
  525.  
  526. $DosRead MACRO  bytesread, numreq, address, handle
  527.     push     offset bytesread
  528.     push     numreq
  529.     push     address
  530.     push     handle
  531.     call     DosRead
  532.     add      esp,16      ;restore stack pointer
  533. ENDM
  534.  
  535. $DosReadKB MACRO  numreq,char_in_buf
  536.     .DATA
  537.     IFNDEF    bytesread
  538.         bytesread DWORD   0
  539.     ENDIF
  540.     .CODE
  541.     push     offset bytesread
  542.     pushd    numreq
  543.     push     offset char_in_buf
  544.     pushd     stdin
  545.     call     DosRead
  546.     add      esp,16
  547. ENDM
  548.  
  549. $DosSleep MACRO delta  ;in microseconds
  550.     push     delta
  551.     call     DosSleep
  552.     add      esp,4
  553. ENDM
  554.  
  555. $DosWrite MACRO  lenth ,address,handle
  556.     push     offset nwritten
  557.     push     lenth
  558.     push     address
  559.     pushd    handle      ;unsigned long
  560.     call     DosWrite
  561.     add      esp,16      ;restore stack pointer
  562. ENDM
  563.  
  564. ; Write a message to console at current cursor
  565. $DosWriteMsg MACRO  messag
  566.     local    idmessag
  567.     .DATA
  568. ;    IFNDEF   messag
  569.       idmessag   BYTE  messag
  570. ;    ENDIF
  571.     .CODE
  572.     push     offset nwritten
  573.     push     LENGTHOF idmessag
  574.     push     offset idmessag
  575.     push     stdout      ;unsigned long
  576.     call     DosWrite
  577.     add      esp,16      ;restore stack pointer
  578. ENDM
  579.  
  580.  
  581. ; Write a message to console at current cursor
  582. ;$DosWriteMsg MACRO  arg
  583. ;    local    msgname
  584. ;    .DATA
  585. ;    IFNDEF   messag
  586. ;        msgname  BYTE   arg
  587. ;    ENDIF
  588. ;    .CODE
  589. ;    push     offset nwritten
  590. ;    push     LENGTHOF msgname
  591. ;    push     offset msgname
  592. ;    push     stdout      ;unsigned long
  593. ;    call     DosWrite
  594. ;    add      esp,16      ;restore stack pointer
  595. ;ENDM
  596.  
  597. ; Write to console the message stored AT location
  598. ; ofset is the offset from start of string "location" to start writing
  599. ; devised to get around printing leading spaces in numerical conversions
  600. $DosWriteMsgAT MACRO  location ,ofset:=<0>   ;0 is default
  601.     push     offset nwritten
  602.     mov      eax,LENGTHOF location
  603.     sub      eax,ofset
  604.     push     eax
  605.     mov      eax,offset location
  606.     add      eax,ofset
  607.     push     eax
  608.     pushd    stdout      ;unsigned long
  609.     call     DosWrite
  610.     add      esp,16      ;restore stack pointer
  611. ENDM
  612.  
  613.  
  614. IFDEF NUMBUFS
  615. ;-------------------- Binary -> Ascii and Ascii -> Binary --------------------
  616. ;Is Passed buffer name - tests to see if all characters in buffer are digits
  617. ;If not returns error message and aborts else returns number in eax
  618. ;skips over leading and trailing spaces
  619. $GetNumDigits MACRO  digbuf
  620.     push     esi
  621.     push     edi
  622.     mov      esi,offset digbuf
  623.     mov      edi,0
  624.     .WHILE 1
  625.         .WHILE byte ptr [esi] == 32    ;skip over leading spaces
  626.             inc esi
  627.         .ENDW
  628.         .IF  byte  ptr [esi] >= 30h
  629.             .IF byte ptr [esi] <= 39h
  630.                 inc edi
  631.                 inc esi
  632.              .ELSE
  633.                 .BREAK
  634.             .ENDIF
  635.          .ELSE
  636.             .BREAK
  637.          .ENDIF
  638.     .ENDW           ;on exit edi has number of bytes read
  639.     .IF edi == 0    ;no valid input
  640.          $DosBeep 500,500
  641.          $DosWriteMsg <nl,"Invalid Input for ASCIIToDWord - Aborting",nl>
  642.          $DosExit
  643.     .ENDIF
  644.     mov    eax,edi
  645.     pop    edi
  646.     pop    esi
  647. ENDM
  648.  
  649. ;Convert DWORD to ASCII string at 10 BYTE buffer at digits
  650. ;Number to convert moved into EAX, esi points to buffer
  651. $DWordToAscii MACRO  num,buf
  652.     pusha
  653.     mov      eax,num
  654.     mov      esi,offset buf
  655.     call     DWordToAscii
  656.     popa
  657. ENDM
  658.  
  659. ;Convert DWORD to Hex string at 10 BYTE buffer at digits
  660. ;Number to convert moved into EAX, esi points to buffer
  661. $DWordToHex MACRO  num,buf
  662.     pusha
  663.     mov      eax,num
  664.     mov      esi,offset buf
  665.     call     DWordToHex
  666.     popa
  667. ENDM
  668.  
  669. ;convert string representing BYTE in BUFF to numeric DWORD
  670. ;result returned in EAX)
  671. $AsciiToDWord  MACRO  Buff
  672.     $GetNumDigits Buff  ;checks on validity of characters in buffer as well
  673.     mov      lth,eax
  674.     push     ebx
  675.     push     ecx
  676.     push     edx
  677.     push     edi
  678.     push     esi
  679.     mov      esi,offset Buff
  680.     call     AsciitoDWord
  681.     pop      esi
  682.     pop      edi
  683.     pop      edx
  684.     pop      ecx
  685.     pop      ebx
  686. ENDM
  687.  
  688. ;Convert BYTE to Binary Bit String
  689. ;Byte to convert in AL
  690. $ByteToBitString MACRO
  691.     pusha
  692.     mov     edi,offset Bit8Str
  693.     call    ByteToBitString
  694.     popa
  695. ENDM
  696.  
  697. ;Byte to convert in AX
  698. $WordToBitString MACRO
  699.     pusha
  700.     mov     edi,offset Bit16Str
  701.     call    WordToBitString
  702.     popa
  703. ENDM
  704.  
  705.  
  706.  
  707. ;----------- Procedures here ---------------
  708.  
  709. .CODE
  710. ;--- Call with esi pointing to buffer to store digit string
  711. DWordToAScii  Proc
  712.     mov      edi,10
  713.     xor      edx,edx
  714.     mov      ecx,10
  715. d0: div      edi
  716.     add      edx,30h
  717.     push     edx           ;save on stack
  718.     xor      edx,edx
  719.     loop     d0           ;on exit top of stack has first digit, etc.
  720.     mov      ecx,10
  721. d1: pop      edx
  722.     mov      [esi],dl     ;esi has address of buffer
  723.     inc      esi
  724.     loop     d1
  725.     ; now get rid of leading 0's
  726.     sub      esi,10         ;back to start of string
  727.     mov      ecx,10
  728.     .WHILE   byte ptr [esi] == "0"
  729.          mov byte ptr [esi]," "
  730.          inc esi
  731.          dec ecx
  732.     .ENDW
  733.     .IF  cx == 0   ; all spaces
  734.          dec esi
  735.          mov byte ptr [esi] ,'0'
  736.     .ENDIF
  737.      ret
  738. DWordToAscii   endp
  739.  
  740. AsciiToDWord  proc
  741.     mov      eax,1
  742.     xor      edi,edi
  743.     xor      ebx,ebx
  744. ;    mov      esi,offset Buff
  745.     mov      ecx,lth
  746. ;    .WHILE   byte ptr [esi] == ' '  ;replace leading spaces with '0'
  747. ;             mov  byte ptr [esi],'0'
  748. ;             inc  esi
  749. ;    .ENDW
  750.     dec      lth
  751.     add      esi,lth       ;offset is lnth -1 from 0
  752. w0: push     eax
  753.     sub      byte ptr [esi],30h
  754.     mov      bl,[esi]
  755.     mul      bl        ;result in EAX
  756.     add      edi,eax
  757.     pop      eax
  758.     mul      ten        ;10 x previous value in AX now
  759.     dec      esi
  760.     loopd    w0
  761.     mov      eax,edi
  762.     ret
  763. AsciiToDWord  endp
  764.  
  765. ;--- Call with esi pointing to buffer to store digit string
  766. DWordToHex  Proc
  767.     mov      edi,16
  768.     xor      edx,edx
  769.     mov      ecx,8
  770. d0: div      edi
  771.     .IF      edx <= 9
  772.         add      edx,30h
  773.     .ELSE
  774.         add      edx,55    ;use caps
  775.     .ENDIF
  776.     push     edx           ;save on stack
  777.     xor      edx,edx
  778.     loop     d0           ;on exit top of stack has first digit, etc.
  779.     mov      ecx,8
  780. d1: pop      edx
  781.     mov      [esi],dl     ;esi has address of buffer
  782.     inc      esi
  783.     loop     d1
  784.     mov      byte ptr [esi],'H'
  785.     ; now get rid of leading 0's
  786.     ;sub      esi,10         ;back to start of string
  787.     ;mov      ecx,10
  788.     ;.WHILE   byte ptr [esi] == "0"
  789.     ;     mov byte ptr [esi]," "
  790.     ;     inc esi
  791.     ;     dec ecx
  792.     ;.ENDW
  793.     ;.IF  cx == 0   ; all spaces
  794.     ;     dec esi
  795.     ;     mov byte ptr [esi] ,'0'
  796.     ;.ENDIF
  797.      ret
  798. DWordToHex   endp
  799.  
  800. WordToBitString  proc  ;called with edi set to offset of string and # in ax
  801.     mov     cx,16
  802.     dec     edi
  803. wb0:inc     edi
  804.     shl     ax,1             ;move most significant bit to carry flag
  805.     jc      wb1              ;if set copy '1'
  806.     mov     byte ptr [edi],'0'       ;else copy '0'
  807.     jmp     wb2
  808. wb1:mov     byte ptr [edi],'1'
  809. wb2:loop    wb0
  810.     ret
  811. WordToBitString endp
  812.  
  813. .CODE
  814. ByteToBitString  proc        ; al has the number
  815.     mov     cx,8             ;called with edi set to offset of string
  816.     dec     edi
  817. bb0:inc     edi
  818.     shl     al,1             ;move most significant bit to carry flag
  819.     jc      bb1              ;if set copy '1'
  820.     mov     byte ptr [edi],'0'       ;else copy '0'
  821.     jmp     bb2
  822. bb1:mov     byte ptr [edi],'1'
  823. bb2:loop    bb0
  824.     ret
  825. ByteToBitString  endp
  826.  
  827. ENDIF
  828.