home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / MFKASM.ZIP / 286_DOS.MAC next >
Text File  |  1992-07-18  |  44KB  |  1,544 lines

  1. ;------------------------------------------------------
  2. ;286_dos.mac Begun:Fri  05-15-1992   Revised:Sun  06-28-1992
  3. ;M. F. Kaplon
  4. ;Macros using the DOSxxxx calls of OS/2 2.0 .286 library
  5. ;This Library uses the PASCAL convention so that
  6. ;parameters are pushed in order and stack pointer reset by callee.
  7. ;All Macro Names begin with $ and are followed in all
  8. ;cases of a DOS.... call with the name of the call
  9. ;All system calls in 16 bit code are FAR in OS/2 independent of model
  10. ;------------------------------------------------------
  11.  
  12. ;---------------------- EXTRN definitions ------------------------
  13. EXTRN      DosAllocSeg:far,DosBeep:far,DosDevIOCtl:far,DosExecPgm:far
  14. EXTRN      DosFreeSeg:far,DosExit:far,DosCreateThread:far,DosSetPrty:far
  15. EXTRN      DosGetDateTime:far,DosGetEnv:far,DosGetInfoSeg:far
  16. EXTRN      DosOpen:far,DosRead:far,DosSleep:far,DosWrite:far,DosShutdown:far
  17. EXTRN      DosMonClose:far,DosMonOpen:far,DosMonRead:far,DosMonReg:far,DosMonWrite:far
  18.  
  19. EXTRN      KbdCharIn:far,KbdFlushBuffer:far,KbdGetStatus:far,KbdSetStatus:far
  20. EXTRN      KbdStringIn:far
  21.  
  22. EXTRN      VioGetBuf:far,VioShowBuf:far
  23. EXTRN      VioGetConfig:far,VioGetCurPos:far,VioGetMode:far,VioReadCellStr:far
  24. EXTRN      VioReadCharStr:far,VioScrollDn:far,VioSetCurPos:far,VioSetMode:far
  25. EXTRN      VioWrtCellStr:far,VioWrtCharStr:far,VioWrtCharStrAtt:far,VioWrtNAttr:far
  26. EXTRN      VioWrtNCell:far,VioWrtNChar:far,VioWrtTTY:far
  27. EXTRN     VioGetPhysBuf:far,VioScrLock:far,VioSetAnsi:far
  28.  
  29. EXTRN      WinInitialize:far,WinTerminate:far,WinQuerySwitchList:far
  30. EXTRN      WinChangeSwitchEntry:far  ;,Win16ChangeSwitchEntry:far
  31.  
  32. ;-------------------- Macro Type equates --------------------
  33.  
  34. $ClearScreen   equ   $VioWrtNCell " ",FGDflt,BGDflt,4000,0,0  ;Clear The Screen with Current Attributes
  35. $NewLine       equ   $DosWriteMsg  nl    ;Just What It Says
  36. $Wait          equ   $PopMsg -1,-1,"Press Esc or CR to Return",HRed,HWhite
  37. ;-------------------- Structures -------------------
  38.  
  39. DateTime        STRUCT      ;structure for DateTime Info
  40.     Hour        BYTE   ?    ;0-23
  41.     Minute      BYTE   ?    ;0-59
  42.     Second      BYTE   ?    ;0-59
  43.     Hundrs      BYTE   ?    ;0-99 hundredths of a second
  44.     Day         BYTE   ?    ;1-31
  45.     Month       BYTE   ?    ;1-12
  46.     Year        WORD   ?    ;1980-2079
  47.     TimeZone    WORD   ?    ;TimeZone(minutes± GMT, 300 = US EST,-1=undefined)
  48.     DayofWeek   BYTE   ?    ;0=Sunday,1=Monday, etc.
  49. DateTime        ENDS
  50.  
  51. KbdDataIn       STRUCT      ;structure for KbdCharIn and KbdPeek
  52.     Char        BYTE   ?
  53.     Scan        BYTE   ?
  54.     Status      BYTE   ?    ;Bits defined p 574 Duncan
  55.     Rsvd        BYTE   0
  56.     Shift       WORD   ?    ;Keyboard Shift State   Bits defined p 574 Duncan
  57.     Time        DWORD  ?    ;msec since system turned on/restarted
  58. KbdDataIn       ENDS
  59.  
  60. KbdStatus       STRUCT    2 ;structure for KbdGetStatus,KbdSetStatus
  61.     BufSize     WORD   10   ;10 in vs. 1.1,1.2,1.3, 2.0
  62.     KBStateMask WORD   0    ;defined p576 Duncan
  63.     TurnArndCh  WORD   0
  64.     IntFlags    WORD   0    ;defined p576 Duncan
  65.     ShiftState  WORD   0    ;defined p576 Duncan
  66. KbdStatus       ENDS
  67.  
  68. KbdMonPacket    STRUCT      ;structure for Kbd Monitor Data Packet
  69.     MonFlags     BYTE   ?
  70.     OrigScanCode BYTE   ?
  71.     TransltdChar BYTE   ?
  72.     TransltdSC   BYTE   ?
  73.     DBCSStatus   BYTE   ?
  74.     DBCSShift    BYTE   ?
  75.     ShiftState   WORD   ?   ;Same definsitions as KbdCharIn
  76.     TimeStamp    DWORD  ?
  77.     KBDriverFlag WORD   ?
  78. KbdMonPacket     ENDS
  79.  
  80. VioConfigStat   STRUCT      ;structure for Get Config
  81.     BufSize     WORD   10
  82.     Adapter     WORD   ?    ;defined on p/599 of Duncan
  83.     Display     WORD   ?    ;defined on p/599 of Duncan
  84.     VideoMem    DWORD  ?    ;Bytes of Memory on Video Adapter
  85. VioConfigStat   ENDS
  86.  
  87. VioModeStat     STRUCT      ;status of Video Mode
  88.     BufSize     WORD   14   ;Size of buffer
  89.     ModeType    BYTE   ?    ;p. 602/614 of Duncan for definitions
  90.     Colors      BYTE   ?    ;p. 602/614 of Duncan for definitions
  91.     TextCols    WORD   ?    ;# Text Columns
  92.     TextRows    WORD   ?    ;# Text Rows
  93.     HorPixels   WORD   ?    ;# Horizontal Resolution in Pixels
  94.     VerPixels   WORD   ?    ;# Vertical Resolution in Pixels
  95.     Reserved    WORD   0    ; Reserved
  96. VioModeStat     ENDS
  97.  
  98. ;------ General Macros -------
  99.  
  100. $CLS  MACRO     ;clear screen with DosWrite
  101.     local c0
  102.     mov         cx,24
  103.     c0:
  104.                 $DosWriteMsg nl
  105.     loop        c0
  106. ENDM
  107.  
  108. $DefineNumBufs  MACRO    ;Define Buffers used for Storage for Num conversion
  109.     B_Buf       BYTE  3 dup(?)
  110.     W_Buf       BYTE  5 dup(?)
  111.     DW_Buf      BYTE 10 dup(0)
  112.     Bit8Str     BYTE  8 dup(?)
  113.     Bit16Str    BYTE  16 dup(?)
  114. ENDM
  115.  
  116. $DefineDosBufs MACRO    ;Define Buffers used by Dosroutines
  117.     nwritten    WORD  ?           ;forr those  programs requiring ptr to # written
  118.     ReadBuf     BYTE  5 dup(?)
  119. ENDM
  120.  
  121. $DefineKbdBufs MACRO    ;Define Buffers used for Kbd Routines
  122.     KbdData      KbdDataIn  {,,,,,}
  123.     KbdStatusCur KbdStatus  {10,0,0,0,0}  ;need size of buffer
  124.     Key          WORD  ?
  125.     ShftState    WORD  ?
  126.     KBStatus     WORD  ?
  127.     ShiftState   WORD  ?
  128. ENDM
  129.  
  130. $DefineVioBufs MACRO     ;Define Buffers used by VIO routines
  131.     attrib      BYTE  ?           ;used by $Attrib
  132. ENDM
  133.  
  134. $DefineWinBufs  MACRO    ;Define Buffers used for WIN routines
  135.     hab         WORD  ?           ;wininitialize
  136.     numitems    WORD  ?
  137. ENDM
  138.  
  139. $Attrib MACRO  FG,BG     ;Requires DefineVioBufs
  140.     mov   al,BG
  141.     shl   al,4           ;move into upper 4 bits
  142.     add   al,FG
  143.     mov   attrib,al
  144. ENDM
  145.  
  146. $BufLength MACRO  BufAdr  ;returns length of ASCII0 String at BufAdr in AX
  147.     push    si
  148.     push    bx
  149.     xor     bx,bx
  150.     mov     si,BufAdr
  151.     .WHILE  byte ptr [si+bx] != 0
  152.             inc     bx
  153.     .ENDW
  154.     mov    ax,bx
  155.     pop    bx
  156.     pop    si
  157. ENDM
  158.  
  159. ; Display at current row + 1 Err_Num " Error Calling DOS Function FuncName"
  160. $DosErrMsg  MACRO  FuncName   ;FuncName passed in calling macros
  161.     $WordToAscii ax
  162.     $NewLine
  163.     $NewLine
  164.     $DosWriteMsgAT W_Buf
  165.     $DosWriteMsg <" Error calling Dos CP Function ",FuncName>
  166.     $DosBeep  500,500
  167. ENDM
  168.  
  169. ; Gets Key Code formatted as a WORD = HIgh Byte:Scan Code,LowByte:CharCode
  170. ; Code returned in variable Key
  171. ; Returns Shift Status in ShftState
  172. $GetKey  MACRO
  173.     pusha
  174.     $KbdCharIn
  175.     mov     ah,KbdData.Scan
  176.     mov     al,KbdData.Char
  177.     mov     Key,ax
  178.     mov     ax,KbdData.Shift
  179.     mov     ShftState,ax
  180.     popa
  181. ENDM
  182.  
  183. $GetKBStatus  MACRO
  184.      $KbdGetStatus
  185.      mov   ax,KbdStatusCur.KBStateMask
  186.      mov   KBStatus,ax
  187.      mov   ax,KbdStatusCur.ShiftState
  188.      mov   ShiftState,ax
  189. ENDM
  190.  
  191. ;Displays Message in a double line Box Anchored at row,col with Text
  192. ;centered in the Box. If row/col = -1 Box is centered vertically/horizontally
  193. ;Saves and Restores Underlying Screen
  194. ;for simplicity save and restore a rectangle 3 rows high and 80 cols wide
  195. ;to a dedicated memory location
  196. $PopMsg  MACRO  row,col,Msg,FG,BG
  197.     local  MsgName,lnth
  198.     .DATA
  199.          MsgName   BYTE  " ",Msg," "  ;spaces between Left/Right Vertical
  200.     IFNDEF  scol0
  201.          srow      WORD   ?      ;storage for row and col
  202.          srow0     WORD   ?      ;init row
  203.          srowe     WORD   ?      ;endrow
  204.          scol      WORD   ?
  205.          scol0     WORD   ?      ;storage for Center Col
  206.          LocBufSz  WORD   ?      ;ptr for storage for underlying screen
  207.     ENDIF
  208.     .CODE
  209.     pusha
  210.     mov   ax,LENGTHOF MsgName
  211.     .IF  ax > 76
  212.         lnth = 76
  213.     .ELSE
  214.         lnth = LENGTHOF MsgName
  215.     .ENDIF
  216.     mov   ax,row            ;in case row/col are defined in terms
  217.     mov   srow,ax           ;of memory variables
  218.     mov   ax,col
  219.     mov   scol,ax
  220.     .IF  srow == -1         ;Center Vertically
  221.           mov   srow,11
  222.     .ENDIF
  223.     .IF   srow > 22
  224.           mov   srow,22
  225.     .ENDIF
  226.     mov   bx,srow
  227.     mov   srow0,bx          ;Save for restore screen
  228.     add   bx,3
  229.     mov   srowe,bx
  230.     $ScreenSave srow0,0,srowe,79,LocBufSz
  231.      mov    ax,col          ;need for case col not centered
  232.      mov    scol0,ax
  233.     .IF scol == -1          ;Center Horizontally
  234.         mov   scol,80
  235.         sub   scol,lnth
  236.         shr   scol,1        ;divide by 2
  237.         mov   ax,scol
  238.         mov   scol0,ax
  239.     .ENDIF
  240.     $VioWrtNCell BoxCharUL,FG,BG,1,srow,scol
  241.     inc   scol
  242.     $VioWrtNCell BoxCharH,FG,BG,lnth,srow,scol
  243.     add   scol,lnth
  244.     $VioWrtNCell BoxCharUR,FG,BG,1,srow,scol   ;Write Upper Right Character
  245.     inc   srow
  246.     $VioWrtNCell BoxCharV,FG,BG,1,srow,scol    ;Write Right End Vert Char
  247.     mov   ax,scol0
  248.     mov   scol,ax                              ;Back to orig col
  249.     $VioWrtNCell BoxCharV,FG,BG,1,srow,scol    ;Write Left Side Vert Char
  250.     inc   srow                                 ;Bottom row
  251.     $VioWrtNCell BoxCharLL,FG,BG,1,srow,scol   ;Write Lower Left Anchor character
  252.     inc   scol
  253.     $VioWrtNCell BoxCharH,FG,BG,lnth,srow,scol ;Write Bottom Box Horiz Char
  254.     add   scol,lnth
  255.     $VioWrtNCell BoxCharLR,FG,BG,1,srow,scol   ;Write Lower Right Character
  256.     dec   srow
  257.     mov   ax,scol0
  258.     mov   scol,ax
  259.     inc   scol
  260.     $VioWrtCharStrAtt MsgName,srow,scol,FG,BG
  261.     .WHILE 1
  262.         $DosBeep 500,500
  263.         $GetKey
  264. ;        $KbdCharIn        ;pause
  265.         .IF Key == K_ESC  ; KbdData.Char == 27           ;Esc
  266.              .BREAK
  267.         .ENDIF
  268.         .IF KEY == K_ENTER  ;KbdData.Char == 13           ;CR
  269.              .BREAK
  270.         .ENDIF
  271.     .ENDW
  272.     $ScreenRest srow0 ,0,srowe,79,LocBufSz
  273.     popa
  274. ENDM
  275.  
  276. $Printf0 MACRO  typ,prm  ;typ : b/w/s = BYTE/WORD/STRING whose value is val
  277.     local    msgname     ;bb/bw/ = 8bitstring,16bitstring representation of #
  278.     IFIDNI  <typ>,<x>    ;default - nothing entered - exit
  279.         EXITM
  280.     ENDIF
  281.     IFIDNI  <typ>,<b>    ;b/w/ followed by b/h is in Binary/Hex representation
  282.          $ByteToAscii prm  ;converts to Ascii
  283.          $DosWriteMsgAT B_Buf  ;TTY write at current cursor
  284.         EXITM
  285.     ENDIF
  286.     IFIDNI  <typ>,<w>
  287.         $WordToAscii prm     ;converts to Ascii in W_Buf
  288.         $DosWriteMsgAT W_Buf   ;TTY write at current cursor
  289.         EXITM
  290.     ENDIF
  291.     IFIDNI  <typ>,<dw>
  292.         mov  ax,word ptr [prm]
  293.         mov  dx,word ptr [prm+2]
  294.         $DWordToAscii
  295.         $DosWriteMsgAT DW_Buf
  296.         EXITM
  297.     ENDIF
  298.     IFIDNI  <typ> ,<bb>
  299.         mov   al,prm
  300.         $ByteToBitString
  301.         $DosWriteMsgAT  Bit8Str
  302.         EXITM
  303.     ENDIF
  304.     IFIDNI  <typ>, <wb>
  305.         mov   ax,prm
  306.         $WordToBitString
  307.         $DosWriteMsgAT  Bit16Str
  308.         EXITM
  309.     ENDIF
  310.     IFIDNI  <typ>, <s>
  311.     .DATA
  312.     msgname  BYTE   prm
  313.     .CODE
  314.     push     stdout
  315.     push     ds
  316.     push     offset msgname
  317.     push     LENGTHOF msgname
  318.     push     ds
  319.     push     offset nwritten
  320.     call     DosWrite
  321.         EXITM
  322.     ENDIF
  323. ENDM
  324.  
  325. $Printf MACRO  t1,p1,t2:=<x>,p2,t3:=<x>,p3,t4:=<x>,p4,t5:=<x>,p5,t6:=<x>,p6,t7:=<x>,p7
  326.     $Printf0  t1,p1
  327.     $Printf0  t2,p2
  328.     $Printf0  t3,p3
  329.     $Printf0  t4,p4
  330.     $Printf0  t5,p5
  331.     $Printf0  t6,p6
  332.     $Printf0  t7,p7
  333. ENDM
  334.  
  335. $ResetByteBuffer MACRO  Buffer, Bvar           ;reset a BYTE buffer to Bvar
  336.     local   b0
  337.     push    si
  338.     mov     cx,LENGTHOF Buffer
  339.     mov     si,offset Buffer
  340. b0: mov     byte ptr [si],Bvar
  341.     inc     si
  342.     loop    b0
  343.     pop     si
  344. ENDM
  345.  
  346. $ResetWordBuffer MACRO  Buffer, Wvar   ;reset a WORD buffer to Wvar
  347.     local   b0
  348.     push    si
  349.     mov     cx,LENGTHOF Buffer         ;returns number of elements of WORDS
  350.     mov     si,offset Buffer
  351. b0: mov     word ptr [si],Wvar
  352.     add     si,2                       ;scale for WORD array
  353.     loop    b0
  354.     pop     si
  355. ENDM
  356.  
  357. ;---- Restores Rectangular Area on Screen ------
  358. ;---- Buffer is Handle to Buffer assigned by DosAllocSeg
  359. ;---- Have to write out row by row
  360. $ScreenRest  MACRO top,left,bottom,right,Buffer
  361.     local  b0
  362.     mov    cx,bottom
  363.     sub    cx,top
  364.     inc    cx               ;number of rows to copy
  365.     mov    bx,right
  366.     sub    bx,left
  367.     inc    bx               ;length of a line
  368.     shl    bx,1             ;allow for char-attr pairs
  369.     xor    dx,dx            ; ax gets changed at each call
  370.     mov    si,top
  371. b0: push   Buffer           ;ds of Memory Block
  372.     push   dx               ;offset into block
  373.     push   bx               ;length of line
  374.     push   si               ;row
  375.     push   left             ;start column - is fixed
  376.     push   0                ;default Video Handle
  377.     call   VioWrtCellStr
  378.     inc    si               ;next row
  379.     add    dx,bx            ;increment offset
  380.     loop   b0
  381. ENDM
  382.  
  383. ;----- To save a rectangular block read a series of lines into the block
  384. ;----- A handle to the memory block is passed to the function and is
  385. ;----- assigned by the call - that handle is used to release the block
  386. $ScreenSave  MACRO top,left,bottom,right,Buffer  ;Buffer is PTR WORD handle
  387.     local  b0
  388.     .DATA
  389.     IFNDEF Llnth
  390.            Llnth  WORD   ?      ;for  LIne Length storage
  391.     ENDIF
  392.     .CODE
  393.     mov    ax,right  ; calculate length from start-end coordinates
  394.     sub    ax,left
  395.     inc    ax               ;al has number of columns
  396.     mov    bx,bottom
  397.     sub    bx,top
  398.     inc    bx               ;bl has number of rows
  399.     mul    bx               ;rows * cols = ax
  400.     shl    ax,1             ; x 2 for byte-attr pair
  401. ;----- now alloc memory block of size in ax -----
  402.     push   ax               ;size of memory block
  403.     push   ds
  404.     push   offset Buffer    ;receive selector
  405.     push   0000000000000000b;Sharing OPtion
  406.     call   DosAllocSeg      ;memory ds = Buffer and Offset = 0
  407. ;----- now save screen block to allocated memory segment
  408.     mov    cx,bottom
  409.     sub    cx,top
  410.     inc    cx               ;number of rows to copy
  411.     mov    Llnth,right
  412.     sub    Llnth,left
  413.     inc    Llnth            ;length of a line
  414.     shl    Llnth,1          ;allow for char-attr pairs
  415.     mov    bx,Llnth
  416.     xor    dx,dx            ;ax gets changed
  417.     mov    si,top
  418. b0: push   Buffer           ;selector of allocated segment
  419.     push   dx               ;offset
  420.     push   ds               ;offset of Llnth
  421.     push   offset Llnth     ;line length
  422.     push   si               ;row - changes
  423.     push   left             ;column - remains same
  424.     push   0                ;default video handle
  425.     call   VioReadCellStr
  426.     inc    si               ;next row
  427.     add    dx,bx            ;new offset into buffer
  428.     mov    Llnth,bx         ;reset length
  429.     loop   b0
  430. ENDM
  431.  
  432. $SetColor  MACRO FG,BG            ;uses ANSI sequences
  433.     .DATA
  434.     IFNDEF color_code
  435.        color_code BYTE 01bh,'[!FGm',01bh,'[!BGm'
  436.        _written   WORD  ?
  437.     ENDIF
  438.     .CODE
  439. ;    $DosWrite _written,LENGTHOF color_code,offset color_code,stdout
  440.     push   ds
  441.     push   offset color_code
  442.     push   LENGTHOF color_code
  443.     push   0
  444.     call   VioWrtTTY
  445. ENDM
  446.  
  447. $String MACRO  id,string  ;enters a string into DATA
  448.     .DATA
  449.     IFNDEF  id
  450.        id  BYTE string
  451.     ENDIF
  452.     .CODE
  453. ENDM
  454. ;----- DOS Calls or directly related DOS -------
  455.  
  456. ; Sound the bell
  457. $DosBeep  MACRO  beepd,beepf
  458.     push    beepf     ;frequency in Hz
  459.     push    beepd     ;duration in milliseconds frequency in Hz
  460.     call    DosBeep
  461. ENDM
  462. ; If use Proto route do not need the EXTERN definition works OK
  463. ; DosBeep Proto far Pascal var1:WORD,var2:WORD
  464. ; Call as Invoke DosBeep,500,500  for instance
  465.  
  466. ;pdataarea and pparmlist are set up so that if NULL pointer just enter 0, otherwise enter offset name when passing
  467. $DosDevIOCtl MACRO get_func_data,func_parms,funcnum,funccateg,handle
  468.     push     ds
  469.     push     offset get_func_data
  470.     push     ds
  471.     push     offset func_parms
  472.     push     funcnum
  473.     push     funccateg
  474.     push     handle
  475.     call     DosDevIOCtl
  476.     .IF ax != 0
  477.        $DosErrMsg  "DosDevIOCtl"
  478.        $DosExit
  479.     .ENDIF
  480. ENDM
  481.  
  482. $DosExecPgm  MACRO  ExecMode,Args,ChildExec
  483.      .Data
  484.      IFNDEF ObjName
  485.          ObjName  BYTE  64 dup(0)  ;receives name of dynlink causing failure
  486.      ENDIF
  487.      IFNDEF RetCode
  488.          RetCode  DWORD  ?
  489.      ENDIF
  490.      .CODE
  491.      push   ds
  492.      push   offset ObjName
  493.      push   LENGTHOF ObjName
  494.      push   ExecMode
  495.      push   ds
  496.      push   Offset Args
  497.      push   0                 ;address of environment
  498.      push   0                 ;inherit parents
  499.      push   ds
  500.      push   offset RetCode
  501.      push   ds
  502.      push   offset ChildExec
  503.      call   DosExecPgm
  504.     .IF ax != 0
  505.        $DosErrMsg  "DosExecPgm"
  506.        $DosExit
  507.     .ENDIF
  508. ENDM
  509.  
  510. ; Exit Program
  511. $DosExit  MACRO
  512.     push    1         ;terminate process (all threads) (0 = current thread)
  513.     push    0         ;exit result code (0 is normal exit)
  514.     call    DosExit
  515. ENDM
  516.  
  517. $DosFreeSeg MACRO  Sel
  518.     push    Sel
  519.     call    DosFreeSeg
  520. ENDM
  521.  
  522. $DosGetDateTime  MACRO
  523.     .DATA
  524.     IFNDEF DateTimeData
  525.          DateTimeData  DateTime {,,,,,,,,}
  526.     ENDIF
  527.     .CODE
  528.     push    ds
  529.     push    offset DateTimeData
  530.     call    DosGetDateTime
  531. ENDM
  532.  
  533. $DosGetEnv  MACRO
  534.     .DATA
  535.     IFNDEF  EnvSel
  536.        EnvSel  WORD    ?    ;selector for environment
  537.        CmdLine WORD    ?    ;Offset at end of environment
  538.     ENDIF
  539.     .CODE
  540.     push    ds
  541.     push    offset EnvSel
  542.     push    ds
  543.     push    offset CmdLine
  544.     call    DosGetEnv
  545.     .IF ax != 0
  546.        $DosErrMsg  "DosGetEnv"
  547.        $DosExit
  548.     .ENDIF
  549. ENDM
  550.  
  551. $DosGetInfoSeg  MACRO
  552.     .DATA
  553.     IFNDEF  GlobalInfoSeg
  554.         GlobalInfoSeg  WORD  ?  ;pointer for global infoseg
  555.         LocalInfoSeg   WORD  ?  ;pointer to local infoseg
  556.     ENDIF
  557.     .CODE
  558.     push     ds
  559.     push     offset GlobalInfoSeg
  560.     push     ds
  561.     push     offset LocalInfoSeg
  562.     call     DosGetInfoSeg
  563.     .IF ax != 0
  564.        $DosErrMsg  "DosGetInfoSeg"
  565.        $DosExit
  566.     .ENDIF
  567. ENDM
  568.  
  569. $DosMonCloseKB  MACRO
  570.     push   KBMonHandle
  571.     call   DosMonClose
  572. ENDM
  573.  
  574. $DosMonOpenKB  MACRO ;open KB MOnitor
  575.     .DATA
  576.     IFNDEF  KBDevice
  577.         KBDevice     BYTE  "KBD$",0
  578.         KBMonHandle  WORD   0
  579.         CurSessNum   WORD   ?      ;needed for DosMonRegKB
  580.     ENDIF
  581.     .CODE
  582.     push     ds
  583.     push     offset KBDevice
  584.     push     ds
  585.     push     offset KBMonHandle
  586.     call     DosMonOpen
  587.     .IF ax != 0
  588.        $DosErrMsg  "DosMonOpenKB"
  589.        $DosExit
  590.     .ENDIF
  591. ENDM
  592.  
  593. $DosMonReadKB  MACRO  ;call only after $DosMonOpenKB $DosMonRegKB
  594.      .DATA
  595.      IFNDEF KbdMonData
  596.          KbdMonData   BYTE        128;128   ;KbdMonPacket  {,,,,,,,,}
  597.          PacketLnth   WORD        ?
  598.      ENDIF
  599.      .CODE
  600.      mov     PacketLnth,128 ;PacketLnth-KbdMonData
  601.      push    ds
  602.      push    offset KBMonInBuf
  603.      push    0          ;wait till data is ready
  604.      push    ds
  605.      push    offset KbdMonData
  606.      push    ds
  607.      push    offset PacketLnth         ;length of DataPacket Buffer
  608.      call    DosMonRead
  609.     .IF ax != 0
  610.        $DosErrMsg  "DosMonReadKB"
  611.        $DosExit
  612.     .ENDIF
  613. ENDM
  614.  
  615. $DosMonRegKB  MACRO
  616.     .DATA
  617.     IFNDEF   KBMonInBuf
  618.         KBMonInBuf   WORD   128,64 dup(0)   ;length is 128 bytes
  619.         KBMonOutBuf  WORD   128,64 dup(0)
  620.     ENDIF
  621.     .CODE                        ;from DosMonOPen
  622.     push     KBMonHandle         ;Monitor Must be opened first
  623.     push     ds
  624.     push     offset KBMonInBuf
  625.     push     ds
  626.     push     offset KBMonOutBuf
  627.     push     1                   ;Head of Chain
  628.     push     CurSessNum          ;session Num for Keyboard
  629.     call     DosMonReg
  630.     .IF ax != 0
  631.        $DosErrMsg  "DosMonRegKB"
  632.        $DosExit
  633.     .ENDIF
  634. ENDM
  635.  
  636. $DosMonWriteKB  MACRO
  637.     push     ds
  638.     push     offset KBMonOutBuf
  639.     push     ds
  640.     push     offset KbdMonData
  641.     push     14; PacketLnth    ;amount actually readin
  642.     call     DosMonWrite
  643.    .IF ax != 0
  644.        $DosErrMsg  "DosMonWriteKB"
  645.        $DosExit
  646.     .ENDIF
  647. ENDM
  648.  
  649. $DosMonWriteKBBack  MACRO  char,scan,timehigh,timelow
  650.      IFNDEF KbdMonDataBack
  651.          KbdMonDataBack  KbdMonPacket  {0,0,,,01000000b,0,0,,0}
  652. ;         PacketLnth   WORD        ?
  653.      ENDIF
  654.     mov      KbdMonDataBack.TransltdChar,char
  655.     mov      KbdMonDataBack.TransltdSc,scan
  656.     mov      ax,timehigh
  657.     mov      word ptr KbdMonDataBack.TimeStamp,ax
  658.     mov      ax,timelow
  659.     mov      word ptr [KbdMonDataBack.TimeStamp+2],ax
  660.     push     ds
  661.     push     offset KBMonOutBuf
  662.     push     ds
  663.     push     offset KbdMonDataBack
  664.     push     14; PacketLnth    ;amount to go back
  665.     call     DosMonWrite
  666.    .IF ax != 0
  667.        $DosErrMsg  "DosMonWriteKB"
  668.        $DosExit
  669.     .ENDIF
  670. ENDM
  671.  
  672. $DosOpen MACRO filename,handle,openaction,filealloc1,fileattrib,openflag,openmode
  673.     push     ds
  674.     push     offset filename
  675.     push     ds
  676.     push     offset handle
  677.     push     ds
  678.     push     offset openaction
  679.     push     word ptr [filealloc1]   ;DWORD
  680.     push     word ptr [filealloc1+2]
  681.     push     fileattrib
  682.     push     openflag
  683.     push     openmode
  684.     push     0      ;DWORD 0
  685.     push     0
  686.     call DosOpen
  687.     .IF ax != 0
  688.        $DosErrMsg  "DosOpen"
  689.        $DosExit
  690.     .ENDIF
  691. ENDM
  692.  
  693. $DosRead MACRO  bytesread, numreq, address, handle
  694.     push     handle
  695.     push     ds
  696.     push     address
  697.     push     numreq
  698.     push     ds
  699.     push     offset bytesread
  700.     call     DosRead
  701. ENDM
  702.  
  703. $DosReadKB MACRO  numreq
  704.     push     stdin
  705.     push     ds
  706.     push     offset Read_Buf     ;defined in DefineDosBufs
  707.     push     numreq
  708.     push     ds
  709.     push     offset nwritten
  710.     call     DosRead
  711. ENDM
  712.  
  713. $DosShutdown  MACRO    ;shut down system
  714.     push     0
  715.     push     0
  716.     call     DosShutdown
  717.     .IF ax != 0
  718.        $DosErrMsg  "DosShutdown"
  719.        $DosExit
  720.     .ELSE
  721.        $Printf s"ShutDown Completed - Reboot or Turn System Off"
  722.     .ENDIF
  723. ENDM
  724.  
  725. $DosSleep MACRO  THigh,TLow
  726.     push     Thigh
  727.     push     TLow
  728.     call     DosSleep
  729. ENDM
  730.  
  731. $DosWrite MACRO  lenth ,address,handle
  732.     push     handle
  733.     push     ds
  734.     push     address
  735.     push     lenth
  736.     push     ds
  737.     push     offset nwritten
  738.     call     DosWrite
  739. ENDM
  740.  
  741. ; Write a message to console at current cursor
  742. $DosWriteMsg MACRO  message    ;message passed on calling line
  743.     local    msgname
  744.     .DATA
  745.     msgname  BYTE   message
  746.     .CODE
  747.     pusha
  748.     push     stdout
  749.     push     ds
  750.     push     offset msgname
  751.     push     LENGTHOF msgname
  752.     push     ds
  753.     push     offset nwritten
  754.     call     DosWrite
  755.     popa
  756. ENDM
  757.  
  758. ; Write to console the message stored AT location
  759. ; ofset is the offset from start of string "location" to start writing
  760. ; devised to get around printing leading spaces in numerical conversions
  761. $DosWriteMsgAT MACRO  buffer,ofset:=<0>    ;message defined in .DATA buffer
  762.     pusha
  763.     push     stdout
  764.     push     ds
  765.     mov      ax,offset buffer
  766.     add      ax,ofset        ;adjusted offset
  767.     push     ax
  768.     mov      ax,LENGTHOF buffer
  769.     sub      ax,ofset        ;modified length
  770.     push     ax
  771.     push     ds
  772.     push     offset nwritten
  773.     call     DosWrite
  774.     popa
  775. ENDM
  776.  
  777. ;----- KbdCalls ------
  778.  
  779. $KbdCharIn  MACRO   ;Name of Buffer is KbdData - a common buffer
  780.     push     ds
  781.     push     offset KbdData   ;buffer
  782.     push     0                ;wait for character
  783.     push     0                ;Kbd Handle
  784.     call     KbdCharIn
  785. ENDM
  786.  
  787. $KbdFlushBuffer  MACRO
  788.     push     stdin     ;default KB handle
  789.     call     KbdFlushBuffer
  790. ENDM
  791.  
  792. $KbdGetStatus  MACRO ;  uses standard buffer named KbdStatusCur
  793.     push     ds
  794.     push     offset KbdStatusCur   ;status_buf
  795.     push     stdin       ;default KB handle
  796.     call     KbdGetStatus
  797.     .IF ax != 0
  798.        $DosErrMsg  "KbdGetStatus"
  799.        $DosExit
  800.     .ENDIF
  801. ENDM
  802.  
  803. $KbdSetStatus  MACRO  ; uses standard buffer KbdStatusCur
  804.     push     ds
  805.     push     offset KbdStatusCur   ;status_buf
  806.     push     stdin       ;default KB handle
  807.     call     KbdSetStatus
  808.     .IF ax != 0
  809.        $DosErrMsg  "KbdSetStatus"
  810.        $DosExit
  811.     .ENDIF
  812. ENDM
  813.  
  814. $KbdStringIn MACRO  str_buf,info_buf,wait_nowait
  815.     push     ds
  816.     push     offset  str_buf
  817.     push     ds
  818.     push     offset  info_buf
  819.     push     wait_nowait
  820.     push     stdin          ;default  KB handle
  821.     call     KbdStringIn
  822. ENDM
  823.  
  824. ;----- Vio Calls ------
  825.  
  826. $VioGetConfig  MACRO
  827.     .DATA
  828.     IFNDEF  VioConfig
  829.          VioConfig  VioConfigStat {,,,}
  830.     ENDIF
  831.     .CODE
  832.     push      0
  833.     push      ds
  834.     push      offset VioConfig
  835.     push      0                ;default Video Handle
  836.     call      VioGetConfig
  837. ENDM
  838.  
  839. $VioGetCurPos  MACRO  row:=<c_row>,col:=<c_col>   ;values returned in variables c_row,c_col
  840.     .DATA
  841.     IFNDEF row
  842.          row    WORD   ?
  843.     ENDIF
  844.     IFNDEF col
  845.          col    WORD   ?
  846.     ENDIF
  847.     .CODE
  848.     push     ds
  849.     push     offset row
  850.     push     ds
  851.     push     offset col
  852.     push     0            ;video handle
  853.     call     VioGetCurPos
  854. ENDM
  855.  
  856. $VioGetBuf  MACRO  ;get handle to logical video buffer
  857.    .DATA
  858.    IFNDEF    LVB        ;[LVB] is offset ,[LVB+2] is Selector
  859.        LVB   DWORD  ?   ;Pointer to Logical Video Buffer offset:ds
  860.        LVB_S WORD   ?   ;Size of LVB in BYTES
  861.    ENDIF
  862.    .CODE
  863.    push      ds
  864.    push      offset LVB
  865.    push      ds
  866.    push      offset LVB_S
  867.    push      0          ;Default Video Handle
  868.    call      VioGetBuf
  869.     .IF ax != 0
  870.        $DosErrMsg  "VioGetBuf"
  871.        $DosExit
  872.     .ENDIF
  873. ENDM
  874.  
  875. $VioShowBuf MACRO  ;StartPos,Length ;called only if $VioGetBuf called first
  876.     push     word ptr [LVB]   ;offset into LVB
  877.     push     LVB_S            ;size of LVB
  878.     push     0                ;default Video Handle
  879.     call     VioShowBuf
  880.     .IF ax != 0
  881.        $DosErrMsg  "VioShowBuf"
  882.        $DosExit
  883.     .ENDIF
  884. ENDM
  885.  
  886. ;$VioReadCellStrLVB  MACRO  Buffer,BufLength,row,col
  887. ;    .DATA
  888. ;    IFNDEF   ScreenSize
  889. ;       ScreenSize  WORD   ?
  890. ;    ENDIF
  891. ;    .CODE
  892. ;    mov      ScreenSize,BufLength
  893. ;    push     ds
  894. ;    push     offset Buffer
  895. ;    push     ds
  896. ;    push     Offset ScreenSize
  897. ;    push     row
  898. ;    push     col
  899. ;    push     0        ;default video handle
  900. ;    call     VioReadCellStr
  901. ;ENDM
  902.  
  903. $VioWrtNAttrLVB   MACRO  FG,BG,replicate
  904.     local    r0
  905.     pusha
  906.     $Attrib  &FG,&BG
  907.     mov      di,word ptr [LVB]     ;offset set before resetting ds
  908.     push     es             ;save current segment
  909.     mov      ax, word ptr [LVB+2] ;assign LVB DS
  910.     mov      es,ax
  911.     inc      di             ;point to attribute
  912.     mov      cx,replicate
  913.     mov      al,attrib
  914. r0: mov      byte ptr es:[di],al
  915.     add      di,2
  916.     loop     r0
  917.     pop      es             ;get ds back
  918.     $VioShowBuf
  919.     popa
  920. ENDM
  921.  
  922. $VioWrtCharStrLVB  MACRO  message,row,col
  923.     local    msg,d0
  924.     .DATA
  925.         msg  BYTE  message
  926.     .CODE
  927.     pusha
  928.     push     es                      ;save es
  929.     mov      ax,word ptr [LVB+2]     ;segment of Logical Buffer
  930.     mov      es,ax
  931.     mov      di,word ptr [LVB]       ;offset of  Logical buffer
  932.     mov      ax,row
  933.     mov      bl,160                  ;160 bytes per row
  934.     mul      bl
  935.     add      di,ax                   ;offset for row
  936.     add      di,col                  ;need 2*80 to allow for attribute byte
  937.     add      di,col                  ;offset for column
  938.     mov      si,offset msg
  939.     mov      cx,LENGTHOF msg
  940. d0: mov      al,byte ptr ds:[si]
  941.     mov      es:[di],al
  942.     inc      si
  943.     add      di,2                    ;better than 2 inc
  944.     loop     d0
  945.     pop      es                      ;get back es
  946.     $VioShowBuf                      ;update Physical Buf
  947.     popa
  948. ENDM
  949.  
  950. $VioWrtCharStrAttrLVB  MACRO  message,row,col,FG,BG
  951.     local    msg0,d0
  952.     $Attrib  &FG,&BG
  953.     .DATA
  954.         msg0  BYTE  message
  955.     .CODE
  956.     pusha
  957.     push     es                      ;save es
  958.     mov      ax,word ptr [LVB+2]     ;segment of Logical Buffer
  959.     mov      es,ax
  960.     mov      di,word ptr [LVB]       ;offset of  Logical buffer
  961.     mov      ax,row
  962.     mov      bl,160                  ;160 bytes per row
  963.     mul      bl
  964.     add      di,ax                   ;offset for row
  965.     add      di,col                  ;2*col bytes   column offset
  966.     add      di,col                  ;offset for column
  967.     mov      si,offset msg0
  968.     mov      cx,LENGTHOF msg0
  969.     mov      ah,Attrib
  970. d0: mov      al,byte ptr ds:[si]
  971.     mov      es:[di],ax
  972.     inc      si
  973.     add      di,2
  974.     loop     d0
  975.     pop      es                      ;get back es
  976.     $VioShowBuf                      ;update Physical Buf
  977.     popa
  978. ENDM
  979.  
  980.  
  981. $VioGetMode   MACRO
  982.     .DATA
  983.     IFNDEF  VioMode
  984.          VioMode  VioModeStat {,,,,,,,}
  985.     ENDIF
  986.     .CODE
  987.     push     ds
  988.     push     offset VioMode
  989.     push     0          ;default video handle
  990.     call     VioGetMode
  991. ENDM
  992.  
  993. $VioReadCellStr  MACRO  Buffer,BufLength,row,col
  994.     .DATA
  995.     IFNDEF   ScreenSize
  996.        ScreenSize  WORD   ?
  997.     ENDIF
  998.     .CODE
  999.     mov      ScreenSize,BufLength
  1000.     push     ds
  1001.     push     offset Buffer
  1002.     push     ds
  1003.     push     Offset ScreenSize
  1004.     push     row
  1005.     push     col
  1006.     push     0        ;default video handle
  1007.     call     VioReadCellStr
  1008. ENDM
  1009.  
  1010. $VioReadCharStr  MACRO  Buffer,BufLength,row,col
  1011.     .DATA
  1012.     IFNDEF   ScreenSize
  1013.        ScreenSize  WORD   ?
  1014.     ENDIF
  1015.     .CODE
  1016.     mov      ScreenSize,BufLength
  1017.     push     ds
  1018.     push     offset Buffer
  1019.     push     ds
  1020.     push     ScreenSize
  1021.     push     row
  1022.     push     col
  1023.     push     0        ;default video handle
  1024.     call     VioReadCellStr
  1025. ENDM
  1026.  
  1027. $VioSetCurPos  MACRO  row,col
  1028.     push     row
  1029.     push     col
  1030.     push     0     ;video handle 0 = default
  1031.     call     VioSetCurPos
  1032. ENDM
  1033.  
  1034. $VioSetMode MACRO
  1035.     .DATA
  1036.     IFNDEF  VioMode
  1037.          VioMode  VioModeStat  {14,00000001b,4,80,25,?,?,0}
  1038.     ENDIF
  1039.     .CODE
  1040.     push    ds
  1041.     push    offset VioMode
  1042.     push    0         ;Default Video Handle
  1043.     call    VioSetMode
  1044. ;    .IF ax != 0    ;for some crazy reason this gives ERR message
  1045. ;       $DosErrMsg  "VioSetMode"
  1046. ;       $DosExit
  1047. ;    .ENDIF
  1048. ENDM
  1049.  
  1050. $VioWrtCellStr MACRO  buffer,Length,row,col
  1051.     push     ds
  1052.     push     offset buffer
  1053.     push     Length
  1054.     push     row
  1055.     push     col
  1056.     push     0                ;default video handle
  1057.     call     VioWrtCellStr
  1058. ENDM
  1059.  
  1060. $VioWrtCharStr   MACRO   buffer,row,col   ;buffer defined in .DATA
  1061.     push     ds
  1062.     push     offset buffer
  1063.     push     LENGTHOF buffer
  1064.     push     row
  1065.     push     col
  1066.     push     0                 ;video handle 0 = default
  1067.     call     VioWrtCharStr
  1068. ENDM
  1069.  
  1070. $VioWrtCharStrAtt   MACRO   buffer,row,col,FG,BG   ;buffer defined in .DATA
  1071.     $Attrib  &FG,&BG
  1072.     push     ds
  1073.     push     offset buffer
  1074.     push     LENGTHOF buffer
  1075.     push     row
  1076.     push     col
  1077.     push     ds
  1078.     push     offset Attrib
  1079.     push     0                 ;video handle 0 = default
  1080.     call     VioWrtCharStrAttr
  1081. ENDM
  1082.  
  1083. $VioWrtNAttr   MACRO  FG,BG,replicate,row,col
  1084.     $Attrib  &FG,&BG
  1085.     push     ds
  1086.     push     offset attrib
  1087.     push     replicate
  1088.     push     row
  1089.     push     col
  1090.     push     0                 ;video handle 0 = default
  1091.     call     VioWrtNAttr
  1092. ENDM
  1093.  
  1094. $VioWrtCharStrAtt MACRO  buffer,row,col,FG,BG
  1095.     $Attrib  FG,BG
  1096.     push     ds
  1097.     push     offset buffer
  1098.     push     LENGTHOF buffer
  1099.     push     row
  1100.     push     col
  1101.     push     ds
  1102.     push     offset attrib
  1103.     push     0                ;default video handle
  1104.     call     VioWrtCharStrAtt
  1105. ENDM
  1106.  
  1107. $VioWrtNCell   MACRO  char,FG,BG,replicate,row,col
  1108.     $Attrib &FG,&BG
  1109.     .DATA
  1110.     IFNDEF   char_attr
  1111.          char_attr WORD  ?
  1112.     ENDIF
  1113.     .CODE
  1114.     pusha
  1115.     mov      al,char
  1116.     mov      ah,Attrib
  1117.     mov      char_attr,ax
  1118.     push     ds
  1119.     push     offset char_attr
  1120.     push     replicate
  1121.     push     row
  1122.     push     col
  1123.     push     0                 ;video handle 0 = default
  1124.     call     VioWrtNCell
  1125.     popa
  1126. ENDM
  1127.  
  1128. $VioWrtNChar MACRO wchar,replicate,row,col
  1129.     .DATA
  1130.     IFNDEF   nchar
  1131.         nchar  BYTE  ?
  1132.     ENDIF
  1133.     .CODE
  1134.     pusha
  1135.     mov      al,wchar
  1136.     mov      nchar,al
  1137.     push     ds
  1138.     push     offset nchar
  1139.     push     replicate
  1140.     push     row
  1141.     push     col
  1142.     push     0
  1143.     call     VioWrtNChar
  1144.     popa
  1145. ENDM
  1146.  
  1147. $VioWrtTTY   MACRO   message   ;pass message on calling line
  1148.     local    msgname
  1149.     .DATA
  1150.     msgname  BYTE   message
  1151.     .CODE
  1152.     push     ds
  1153.     push     offset msgname
  1154.     push     LENGTHOF msgname
  1155.     push     0                 ;video handle 0 = default
  1156.     call     VioWrtTTY
  1157. ENDM
  1158.  
  1159. $VioWrtTTYAttr   MACRO   message,FG:=<FGDflt>,BG:=<BGDflt>   ;pass message on calling line
  1160.     local    msgname
  1161.     .DATA
  1162.     msgname  BYTE   message
  1163.     .CODE
  1164.     pusha
  1165.     $VioGetCurPos row0,col0
  1166.     push     ds
  1167.     push     offset msgname
  1168.     push     LENGTHOF msgname
  1169.     push     0                 ;video handle 0 = default
  1170.     call     VioWrtTTY
  1171.     $VioGetCurPos row1,col1
  1172.     mov      ax,row1
  1173.     sub      ax,row0
  1174.     inc      ax
  1175.     mov      bl,80
  1176.     mul      bl
  1177.     $VioWrtNAttr FG,BG,ax,row0,0  ; #rows * 80
  1178.     $VioSetCurPos row1,col1
  1179.     popa
  1180. ENDM
  1181.  
  1182. $VioWrtTTYAT   MACRO   message   ;message_name on calling line
  1183.     push     ds
  1184.     push     offset message
  1185.     push     LENGTHOF message
  1186.     push     0                 ;video handle 0 = default
  1187.     call     VioWrtTTY
  1188. ENDM
  1189.  
  1190. $VioWrtTTYAttrAT  MACRO  message,FG:=<FGDflt>,BG:=<BGDflt>   ;message_name on calling line
  1191.     pusha
  1192.     $VioGetCurPos  row0,col0
  1193.     push     ds
  1194.     push     offset message
  1195.     push     LENGTHOF message
  1196.     push     0                 ;video handle 0 = default
  1197.     call     VioWrtTTY
  1198.     $VioGetCurPos row1,col1
  1199.     mov      ax,row1
  1200.     sub      ax,row0
  1201.     inc      ax
  1202.     mov      bl,80
  1203.     mul      bl
  1204.     $VioWrtNAttr FG,BG,ax,row0,0  ; #rows * 80
  1205.     $VioSetCurPos row1,col1
  1206.     popa
  1207. ENDM
  1208.  
  1209. ;-------------- WIN........... Calls
  1210.  
  1211. $WinInitialize MACRO
  1212.     push     0
  1213.     call     WinInitialize
  1214.     mov      hab,ax           ;hab defined in $DefineBufs
  1215. ENDM
  1216.  
  1217. $WinChangeSwitchEntry  MACRO  hswitchh,hswitchl,segmt,ofset
  1218.      push    hswitchh
  1219.      push    hswitchl
  1220.      push    segmt
  1221.      push    ofset     ;offset of SWCNTRL STRUCture
  1222.      call    WinChangeSwitchEntry
  1223.     .IF ax != NULL
  1224.         $DosErrMsg  "WinChangeSwitchEntry"
  1225.         $DosExit
  1226.     .ENDIF
  1227. ENDM
  1228.  
  1229. $WinQuerySwitchList  MACRO  ancblk,tseg,tasklist,listsize
  1230.     push     numitems      ;defined in DefineWinBufs
  1231.     push     ancblk
  1232.     push     tseg          ;segment  for tasklist
  1233.     push     tasklist      ;offset
  1234.     push     listsize
  1235.     call     WinQuerySwitchList
  1236.     .IF ax == 0
  1237.        $DosErrMsg  "WinQuerySwitchList"
  1238.        $DosExit
  1239.     .ENDIF
  1240.     mov      numitems,ax
  1241. ENDM
  1242.  
  1243. $WinTerminate  MACRO
  1244.     push     hab
  1245.     call     WinTerminate
  1246. ENDM
  1247.  
  1248.  
  1249.  
  1250. ;------------- Numeric to AScii and Ascii to Numeric routines --------------
  1251.  
  1252. ;Convert WORD to ASCII string at 5 BYTE buffer at W_Buf
  1253. ;Number to convert moved to AX
  1254. $WordToAscii MACRO  num
  1255.     pusha
  1256.     mov      ax,num
  1257.     mov      si,offset W_Buf
  1258.     call     WordToAScii
  1259.     popa
  1260. ENDM
  1261.  
  1262. ;Convert BYTE to Binary Bit String
  1263. ;Byte to convert in AL
  1264. $ByteToBitString MACRO
  1265.     local  bb0,bb1,bb2
  1266.     mov     di,offset Bit8Str
  1267.     call    ByteToBitString
  1268. ENDM
  1269.  
  1270. ;Byte to convert in AX
  1271. $WordToBitString MACRO
  1272.     mov     di,offset Bit16Str
  1273.     call    WordToBitString
  1274. ENDM
  1275.  
  1276. ;Convert BYTE to ASCII string at 3 BYTE buffer at B_Buf
  1277. ;Number to convert in AL and si = offset B_Buf
  1278. $ByteToAscii MACRO  num
  1279.     local    b0,b1,b2,b3
  1280.     pusha
  1281.     mov      al,num
  1282.     mov      si,offset B_Buf
  1283.     call     ByteToAScii
  1284.     popa
  1285. ENDM
  1286.  
  1287. ;convert string representing BYTE in BUFF to numeric
  1288. ;result returned in AL (contained in AX)
  1289. $AsciiToBYTE  MACRO  Buff
  1290.     local d0,lnth
  1291.     lnth equ LENGTHOF Buff
  1292.     pusha
  1293.     mov      ax,1
  1294.     xor      di,di
  1295.     mov      bl,10
  1296.     mov      si,offset Buff
  1297.     mov      cx,lnth
  1298.     .WHILE   byte ptr [si] == ' '  ;replace leading spaces with '0'
  1299.              mov  byte ptr [si],'0'
  1300.              inc  si
  1301.     .ENDW
  1302.     mov      si,offset Buff  ;reposition si
  1303.     add      si,lnth-1       ;offset is lnth -1 from 0
  1304. d0: push     ax
  1305.     sub      byte ptr [si],30h
  1306.     push     cx
  1307.     xor      cx,cx
  1308.     mov      cl,[si]
  1309.     mul      cl        ;result in AX but DX = 0 this case
  1310.     add      di,ax
  1311.     pop      cx
  1312.     pop      ax
  1313.     mul      bl        ;10 x previous value in AX now
  1314.     dec      si
  1315.     loop     d0
  1316.     mov      ax,di
  1317.     popa
  1318. ENDM
  1319.  
  1320. ;convert string representing WORD in BUFF to numeric
  1321. ;result returned in AX
  1322. $AsciiToWORD  MACRO  Buff
  1323.     local d0,lnth
  1324.     lnth equ LENGTHOF Buff
  1325.     pusha
  1326.     mov      ax,1
  1327.     xor      di,di
  1328.     xor      dx,dx
  1329.     mov      bx,10
  1330.     mov      si,offset Buff
  1331.     mov      cx,lnth
  1332.     .WHILE   byte ptr [si] == " "  ; replace leading spaces with '0'
  1333.              mov  byte ptr [si],"0"
  1334.              inc  si
  1335.     .ENDW
  1336.     mov      si,offset Buff  ;reposition si
  1337.     add      si,lnth-1       ;offset is lnth -1 from 0
  1338. d0: push     ax
  1339.     sub      byte ptr [si],30h
  1340.     push     cx
  1341.     xor      cx,cx
  1342.     mov      cl,[si]
  1343.     mul      cx        ;result in DX:AX but DX = 0 this case
  1344.     add      di,ax
  1345.     pop      cx
  1346.     pop      ax
  1347.     mul      bx        ;10 x previous value in AX now
  1348.     dec      si
  1349.     loop     d0
  1350.     mov      ax,di
  1351.     popa
  1352. ENDM
  1353.  
  1354. $DwordToAscii  MACRO  num   ;dx:ax has number
  1355.     local    dw2,dw3
  1356.     pusha
  1357.     IFDEF   num
  1358.        mov      dx,[num+2]
  1359.        mov      ax,num
  1360.     ENDIF
  1361.     mov      si,offset DW_Buf
  1362.     mov      bl,10             ;radix
  1363.     call     Dword_To_Asc
  1364.     mov      si,offset DW_Buf  ;fixup
  1365.     mov      cx,10
  1366. dw2:.IF  byte ptr [si] == "0"
  1367.         mov byte ptr [si]," "
  1368.         inc si
  1369.      .ELSE
  1370.         jmp  dw3
  1371.     .ENDIF
  1372.             loop    dw2
  1373. dw3:.IF  cx == 0      ;all spaces
  1374.         dec    si
  1375.         mov    byte ptr [si],"0"
  1376.    .ENDIF
  1377.    popa
  1378. ENDM
  1379.  
  1380. ;FUNC:  DWORD_TO_ASC
  1381. ;DESC:    Converts an unsigned dword to an ASCIIZ string of the given radix
  1382. ;IN:    DX;AX        unsigned dword ("dword")
  1383. ;    BL        radix of resulting ASCII string, 2-36 ("radix")
  1384. ;       si_reg           address to store resulting string ("outstr")
  1385. ;OUT:    "outstr"    ASCII digits generated from "dword", followed by
  1386. ;               a NULL
  1387. ;-----------------------------------------------------------------------
  1388. .CODE
  1389. dword_to_asc    proc
  1390.         push    bx
  1391.         push    ax
  1392.         push    dx
  1393. $dw_to_asce_20:
  1394.         push    cx
  1395.         push    bp
  1396.         xor     bh,bh
  1397.         xor     bp,bp           ;set count to zero
  1398.         cmp     bl,2            ;is radix less than 2?
  1399.          jb     dw_to_a_800     ;  y: exit, n: cont. with routine
  1400. dw_to_a_020:    call   div_dw   ;div unsigned dword by radix
  1401.         push    cx              ;keep remainder
  1402.         inc     bp              ;count number of remainders on stack
  1403.         mov     cx,dx
  1404.         or      cx,ax           ;is quotient zero?
  1405.         jnz     dw_to_a_020     ;  n: loop again
  1406. dw_to_a_030:pop     ax              ;get next remainder
  1407.         add     al,"0"          ;convert to decimal
  1408.         cmp     al,"9"          ;convert AL for A to Z?
  1409.         jna     dw_to_a_050     ;  n: skip alpha conversion
  1410.         add     al,7h           ;  y: convert to alpha
  1411. dw_to_a_050:mov [si],al         ;write digit to end of string
  1412.         inc     si
  1413.         dec     bp              ;decrement count of remaining digits
  1414.         jnz     dw_to_a_030     ;if count=0, stop; else loop again
  1415. dw_to_a_800:    pop bp
  1416.         pop cx
  1417.         pop dx
  1418.         pop ax
  1419.         pop bx
  1420.         ret
  1421. dword_to_asc   endp
  1422.  
  1423.  
  1424. ;FUNC:  DIV_DW
  1425. ;DESC:    Divides an unsigned dword by an unsigned word, returning an
  1426. ;    unsigned dword result.
  1427. ;IN:    DX;AX        unsigned dword dividend
  1428. ;    BX        unsigned word divisor
  1429. ;OUT:    DX;AX        unsigned dword quotient
  1430. ;    CX        unsigned word remainder
  1431. ;-----------------------------------------------------------------------
  1432. .CODE
  1433. div_dw       proc
  1434.         or      bx,bx           ;trying to divide by zero?
  1435.         jz      div_dw_090      ;  y: can't do it, quit
  1436.         xor     cx,cx
  1437.         cmp     dx,bx           ;is a divide overflow possible?
  1438.         jb      div_dw_070      ;  n: only need to divide once
  1439.         xchg    ax,cx           ;DX;AX = 0;high word
  1440.         xchg    ax,dx           ;CX = low word
  1441.         div     bx              ;divide 0;high word by divisor
  1442.         xchg    ax,cx           ;DX;AX = rem of high divide;low word
  1443. div_dw_070:div  bx              ;CX = high word of quotient
  1444.         xchg    dx,cx           ;return DX;AX = quotient, CX = rem
  1445. div_dw_090:    ret
  1446. div_dw  endp
  1447.  
  1448. .CODE
  1449. WordToBitString  proc  ;called with di set to offset of string
  1450.     mov     cx,16
  1451.     dec     di
  1452. wb0:inc     di
  1453.     shl     ax,1             ;move most significant bit to carry flag
  1454.     jc      wb1              ;if set copy '1'
  1455.     mov     byte ptr [di],'0'       ;else copy '0'
  1456.     jmp     wb2
  1457. wb1:mov     byte ptr [di],'1'
  1458. wb2:loop    wb0
  1459.     ret
  1460. WordToBitString endp
  1461.  
  1462. .CODE
  1463. ByteToBitString  proc
  1464.     mov     cx,8             ;called with di set to offset of string
  1465.     dec     di
  1466. bb0:inc     di
  1467.     shl     al,1             ;move most significant bit to carry flag
  1468.     jc      bb1              ;if set copy '1'
  1469.     mov     byte ptr [di],'0'       ;else copy '0'
  1470.     jmp     bb2
  1471. bb1:mov     byte ptr [di],'1'
  1472. bb2:loop    bb0
  1473.     ret
  1474. ByteToBitString  endp
  1475.  
  1476. ByteToAscii   proc
  1477.     xor      ah,ah
  1478.     mov      dx,10
  1479.     xor      bx,bx
  1480.     mov      cx,3
  1481. b0: div      dl
  1482.     mov      bl,ah        ;get remainnder
  1483.     add      bl,30h
  1484.     push     bx           ;save on stack
  1485.     xor      ah,ah        ;prepare for next division
  1486.     loop     b0           ;on exit top of stack has first digit, etc.
  1487.     mov      cx,3
  1488.     mov      si,offset B_Buf
  1489. b1: pop      ax
  1490.     mov      [si],al
  1491.     inc      si
  1492.     loop     b1
  1493.     ; now get rid of leading 0's
  1494.     sub      si,3         ;back to start of string
  1495.     mov      cx,3
  1496. b2: .IF  byte ptr [si] == "0"
  1497.         mov byte ptr [si]," "
  1498.         inc si
  1499.      .ELSE
  1500.         jmp  b3
  1501.     .ENDIF
  1502.     loop    b2
  1503. b3: .IF  cx == 0      ;all spaces
  1504.         dec    si
  1505.         mov    byte ptr [si],"0"
  1506.    .ENDIF
  1507.    ret
  1508. ByteToAScii  Endp
  1509.  
  1510. ;Convert WORD to ASCII string at 5 BYTE buffer at digits
  1511. ;Number to convert in AX,offset to buffer in si
  1512.    .CODE
  1513. WordToAscii  proc
  1514.     mov      di,10
  1515.     xor      dx,dx
  1516.     mov      cx,5
  1517. w0: div      di
  1518.     add      dx,30h
  1519.     push     dx           ;save on stack
  1520.     xor      dx,dx
  1521.     loop     w0           ;on exit top of stack has first digit, etc.
  1522.     mov      cx,5
  1523. w1: pop      dx
  1524.     mov      [si],dl
  1525.     inc      si
  1526.     loop     w1
  1527.     ; now get rid of leading 0's
  1528.      sub      si,5         ;back to start of string
  1529.      mov      cx,5
  1530.  w2: .IF  byte ptr [si] == "0"
  1531.          mov byte ptr [si]," "
  1532.          inc si
  1533.       .ELSE
  1534.          jmp  w3
  1535.      .ENDIF
  1536.      loop    w2
  1537. w3: .IF  cx == 0      ;all spaces
  1538.          dec    si
  1539.          mov    byte ptr [si],"0"
  1540.     .ENDIF
  1541.     ret
  1542. WordToAscii   endp
  1543.  
  1544.