home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / audiopdd.zip / whelper.h < prev   
C/C++ Source or Header  |  1999-05-16  |  7KB  |  298 lines

  1. //
  2. // whelper.h
  3. // 25-Jan-99
  4. // helper pragma aux
  5.  
  6. // ---------------
  7. // use _cli_/_sti_
  8. // instead of cli()/sti() in case ever need to manage SMP,
  9. // but must always use in pairs since pushf/popf
  10. // can still use cli()/sti()
  11.  
  12.  void _cli_(void);
  13.  #pragma aux _cli_ = \
  14.    "pushf" \
  15.    "cli"   \
  16.   parm nomemory \
  17.   modify nomemory exact [];
  18.  
  19.  void _sti_(void);
  20.  #pragma aux _sti_ = \
  21.    "popf" \
  22.   parm nomemory \
  23.   modify nomemory exact [];
  24.  
  25.  
  26. // -------------------------------------------------------------------
  27. // MEMSET() is a 16-bit version of the memset()
  28. // MEMCPY() is new, based on the MEMSET() done here (will have a 386 CPU)
  29. // cld expected to be in force since not done here
  30. // -------------------------------------------------------------------
  31. // ASM_MEMSET() dword-aligns on destination
  32. // ASM_MEMCPY() dword-aligns on destination (overlapped is not allowed)
  33. // -------------------------------------------------------------------
  34.  
  35.  VOID ASM_MEMSET(CHAR _far *destPtr, USHORT value, USHORT length);
  36.  #define MEMSET(strg,value,length)  ASM_MEMSET((CHAR _far *)strg,(USHORT)value,(USHORT)length)
  37.  
  38. // will use value as a 16-bit value so can write 7FFF,
  39. // so send 16-bit value (unless count is odd AND count >=32 then only byte is used)
  40. // if count is < 32 then WORD is always used (unless only 1 byte!)
  41.  
  42.  #pragma aux ASM_MEMSET=\
  43.          "cld"          \
  44.          "test cx,cx"   \
  45.          "jz SX"        \
  46.          "cmp cx,32"    /* 1-31 bytes then by words */ \
  47.          "jb SW"        \
  48.          "test cx,1"    \  
  49.          "jz L16"       \
  50.          "mov ah,al"     /* odd then only byte is used */ \
  51.  "L16:    mov bx,ax"    \
  52.          "shl eax,16"   \
  53.          "mov ax,bx"    \
  54.          "test di,3"    \
  55.          "jz LX"        /* dest is dword aligned */ \
  56.          "test di,1"    \
  57.          "jz LW"        /* dest is word aligned */  \
  58.  "LB:     stosb"        /* dest is byte aligned */  \
  59.          "dec cx"       \
  60.          "test di,2"    \  
  61.          "jz LX"        /* dest is dword aligned */ \
  62.  "LW:     stosw"        \
  63.          "sub cx,2"     \
  64.  "LX:     mov bl,cl"    \
  65.          "shr cx,2"     \
  66.          "rep stosd"    \
  67.          "and bl,3"     \
  68.          "jz SX"        /* all data written */ \
  69.          "mov cl,bl"    \
  70.  "SW:     shr cx,1"     \
  71.          "rep stosw"    /* write word, if available (not done if cx=0)*/ \
  72.          "jnc SX"       \
  73.  "SB:     stosb"        /* write last byte */ \
  74.  "SX:" \
  75.   parm nomemory [es di][ax][cx] \
  76.   modify [bx];
  77.  
  78.  // ----------------------------------------------------------------
  79.  // have to use [dx si] since [ds si] not valid for this memory model
  80.  // note: source is probably more likely to be aligned...and since always
  81.  // dwording bytes, destination should also be!
  82.  
  83.  VOID ASM_MEMCPY(CHAR _far *destPtr, CHAR _far *srcPtr, USHORT length);
  84.  #define MEMCPY(dPtr,sPtr,length) ASM_MEMCPY((CHAR _far *)dPtr,(CHAR _far *)sPtr,(USHORT)length)
  85.  
  86.  #pragma aux ASM_MEMCPY=\
  87.          "cld"          \
  88.          "push ds"      \
  89.          "mov ds,dx"    \
  90.          "test cx,cx"   \
  91.          "jz SX"        \
  92.          "test cx,32"   \
  93.          "jb SB"        \
  94.          "test di,3"    \
  95.          "jz LX"        \
  96.          "test di,1"    \
  97.          "jz LW"        \
  98.  "LB:     movsb"        \
  99.          "dec cx"       \
  100.          "test di,2"    \
  101.          "jz LX"        \
  102.  "LW:     movsw"        \
  103.          "sub cx,2"     \
  104.  "LX:     mov bl,cl"    \
  105.          "shr cx,2"     \
  106.          "rep movsd"    \
  107.          "and bl,3"     \
  108.          "jz SX"        \
  109.          "mov cl,bl"    \
  110.  "SB:     rep movsb"    \
  111.  "SX:     pop ds"       \
  112.   parm nomemory [es di][dx si][cx] \
  113.   modify [bx];
  114.  
  115.  
  116. USHORT IsRing3(VOID);
  117. #pragma aux IsRing3=\
  118.        "push cs"  \
  119.        "pop ax "  \
  120.        "and ax,3" \
  121.  value [ax]       \
  122.  parm nomemory    \
  123.  modify nomemory;
  124.  
  125. USHORT CanCPUID(VOID);
  126. #pragma aux CanCPUID=\
  127.        "push ebx"    \
  128.        "pushfd"      \
  129.        "pop eax"     \
  130.        "mov ebx,eax" \
  131.        "xor eax,200000h" /* toggle bit21 */ \
  132.        "push eax"    \
  133.        "popfd"       \
  134.        "pushfd"      \
  135.        "pop eax"     \
  136.        "cmp eax,ebx" \
  137.        "mov ax,0"    \
  138.        "jz NoID"     \
  139.        "inc ax"      \
  140. "NoID:  pop ebx"     \
  141.  parm nomemory       \
  142.  value [ax]          \
  143.  modify nomemory;
  144.  
  145. USHORT CanRDTSC(VOID);
  146. #pragma aux CanRDTSC = \
  147.        "push ebx"   \
  148.        "push ecx"   \
  149.        "push edx"   \
  150.        "sub eax,eax"\
  151.        "db 0Fh,0A2h"\
  152.        "cmp eax,1"  \
  153.        "mov ax,0"   \
  154.        "jb NoGo"    \
  155.        "mov eax,1"  \
  156.        "db 0Fh,0A2h"\
  157.        "test dl,10h"\
  158.        "mov ax,0"   \
  159.        "jz NoGo"    \
  160.        "inc ax"     \
  161. "NoGo:  pop edx"    \
  162.        "pop ecx"    \
  163.        "pop ebx"    \
  164.  parm nomemory      \
  165.  value [ax]         \
  166.  modify nomemory;
  167.  
  168.  
  169. // set ticks to max (have to), but especially to count-by-1 (mode 2)
  170. // only call once, at driver init (suppose that's safe), but probably only really when testing
  171.  
  172. USHORT ResetTimer0(VOID);
  173. #pragma aux ResetTimer0 = \
  174.        "pushf"       \
  175.        "cli"         \
  176.        "mov al,34h"  \
  177.        "out 43h,al"  \
  178.        "sub al,al"   \
  179.        "out 40h,al"  \
  180.        "out 40h,al"  \
  181.        "popf"        \
  182.  parm nomemory       \
  183.  value [ax]          \
  184.  modify nomemory;
  185.  
  186.  
  187. USHORT ReadTimer0(VOID);
  188. #pragma aux ReadTimer0 = \
  189.        "sub al,al"   \
  190.        "push cx"     \
  191.        "pushf"       \
  192.        "cli"         \
  193.        "out 43h,al"  \
  194.        "in  al,40h"  \
  195.        "mov ah,al"   \
  196.        "in  al,40h"  \
  197.        "popf"        \
  198.        "pop cx"      \
  199.        "xchg al,ah"  \
  200.  parm nomemory       \
  201.  value [ax]          \
  202.  modify nomemory;
  203.  
  204.  
  205. void pushAX(void);
  206. #pragma aux pushAX = \
  207.    "push ax" \
  208.    parm nomemory \
  209.    modify nomemory exact [];
  210.  
  211. void pushBX(void);
  212. #pragma aux pushBX = \
  213.    "push bx" \
  214.    parm nomemory \
  215.    modify nomemory exact [];
  216.  
  217. void pushCX(void);
  218. #pragma aux pushCX = \
  219.    "push cx" \
  220.    parm nomemory \
  221.    modify nomemory exact [];
  222.  
  223. void pushDX(void);
  224. #pragma aux pushDX = \
  225.    "push dx" \
  226.    parm nomemory \
  227.    modify nomemory exact [];
  228.  
  229. void pushSI(void);
  230. #pragma aux pushSI = \
  231.    "push si" \
  232.    parm nomemory \
  233.    modify nomemory exact [];
  234.  
  235. void pushDI(void);
  236. #pragma aux pushDI = \
  237.    "push di" \
  238.    parm nomemory \
  239.    modify nomemory exact [];
  240.  
  241. void pushBP(void);
  242. #pragma aux pushBP = \
  243.    "push bp" \
  244.    parm nomemory \
  245.    modify nomemory exact [];
  246.  
  247.  
  248. void popAX(void);
  249. #pragma aux popAX = \
  250.    "pop ax" \
  251.    parm nomemory \
  252.    modify nomemory exact [];
  253.  
  254. void popBX(void);
  255. #pragma aux popBX = \
  256.    "pop bx" \
  257.    parm nomemory \
  258.    modify nomemory exact [];
  259.  
  260. void popCX(void);
  261. #pragma aux popCX = \
  262.    "pop cx" \
  263.    parm nomemory \
  264.    modify nomemory exact [];
  265.  
  266. void popDX(void);
  267. #pragma aux popDX = \
  268.    "pop dx" \
  269.    parm nomemory \
  270.    modify nomemory exact [];
  271.  
  272. void popSI(void);
  273. #pragma aux popSI = \
  274.    "pop si" \
  275.    parm nomemory \
  276.    modify nomemory exact [];
  277.  
  278. void popDI(void);
  279. #pragma aux popDI = \
  280.    "pop di" \
  281.    parm nomemory \
  282.    modify nomemory exact [];
  283.  
  284. void popBP(void);
  285. #pragma aux popBP = \
  286.    "pop bp" \
  287.    parm nomemory \
  288.    modify nomemory exact [];
  289.  
  290. void nop(void);
  291. #pragma aux nop = \
  292.    "nop" \
  293.    parm nomemory \
  294.    modify nomemory exact [];
  295.  
  296.  
  297.  
  298.