home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR13 / OS2ASM.ZIP / FPUTC.ASM < prev    next >
Assembly Source File  |  1991-07-28  |  3KB  |  180 lines

  1. ;_ FPUTC.ASM   Modified by Joe Huffman August 16, 1990
  2. ; Copyright (C) 1985-1989 by Walter Bright
  3. ; All Rights Reserved
  4. ; Written by Walter Bright
  5.  
  6. ;CAUTION!  This code is highly optimized.  It does not fully utilize the
  7. ;macros 'uses' and 'unuse' for register preservation.  If registers other than
  8. ;EBX, ESI, and EDI (and of course EBP, DS, and ES) must be preserved examine 
  9. ;this module carefully.
  10.  
  11.     include macros.asm
  12.     include stdio.asm
  13.  
  14.     extrn    __flushbu:near
  15.     extrn    __fillbuf:near
  16.     extrn    _fflush:near
  17.  
  18.     ifdef _MT
  19.     extrn    ___fp_lock:near,___fp_unlock:near
  20.     endif
  21.  
  22.     begcode fputc
  23.  
  24.     public    _fputc
  25.  
  26. ;;;;;;;;;;;;;;;;;;;;;;;;;
  27. ;    fputc(c,fp);
  28.  
  29. _fputc    proc    near
  30.  
  31.     ifdef _MT
  32.     ;The idea with the multi-threaded version is to lock the
  33.     ;stream, call the locked version of fputc, and then
  34.     ;unlock the stream.
  35.  
  36.     push    EBP
  37.     mov    EBP,ESP
  38.     sub    ESP,4
  39.     push    P+4[EBP]
  40.     call    ___fp_lock
  41.     push    P+0[EBP]
  42.     call    near ptr _fputc_nlock
  43.     add    SP,4            ;clean off c, but not fp
  44.     mov    -4[EBP],EAX        ;save return value
  45.     call    ___fp_unlock
  46.     mov    EAX,-4[EBP]
  47.     mov    ESP,EBP
  48.     pop    EBP
  49.     ret
  50.     endif
  51.  
  52.     public    __fputc_nlock
  53. __fputc_nlock:
  54.  
  55.     movzx    EAX,byte ptr PS[ESP]    ;get c (don't let c sign-extend to
  56.                         ; produce wrong EOF)
  57.     mov    ECX,PS+4[ESP]        ;get fp
  58. ifdef DOS386
  59.     _ifs    AL e 10, L4    ;if LF
  60. endif
  61.  
  62. ; Input:
  63. ;    AL = c
  64. ;    ECX = fp
  65. ; Output:
  66. ;    EAX = c & 0xFF
  67. ;    ECX = fp
  68.  
  69. L1:
  70. _putit:
  71.     dec    dword ptr _cnt[ECX]
  72.     js    short L2
  73. L5:
  74.     mov    EDX,_ptr[ECX]
  75.     mov    [EDX],AL
  76.         inc    EDX
  77.     mov    _ptr[ECX],EDX
  78.     ret
  79.  
  80. ifdef DOS386
  81. L4:    test    byte ptr _flag+1[ECX],_IOTRAN/256
  82.     jz    short L3    ;if not translated mode
  83.     mov    AL,13        ;CR first
  84.     call    _putit
  85.     mov    AL,10        ;Reload LF into AL.
  86. endif
  87.  
  88. L3:    test    byte ptr _flag[ECX],_IOLBF    ;line buffered?
  89.     jz    short L1            ;no
  90.  
  91.     call    _putit
  92.     push    EAX
  93.     push    ECX        ;offset of fp
  94.     call    _fflush
  95.     add    ESP,SIZEPTR
  96.     tst    EAX        ;did fflush succeed?
  97.     pop    EAX        ;EAX = c & 0xFF
  98.     jz    short L6    ;it succeeded
  99.     mov    EAX,-1        ;fflush failed, return EOF
  100. L6:    ret
  101.  
  102. L2:
  103.     push    ECX        ;Save a copy of fp.
  104.     push    ECX        ;push fp, for use by _flushbu
  105.     push    EAX        ;push c
  106.     call    __flushbu
  107.     add    ESP,4+SIZEPTR
  108.     pop    ECX        ;pop fp, copy needed if called by putit.
  109.  
  110.     ret
  111. _fputc    endp
  112.  
  113. ;;;;;;;;;;;;;;;;;;;;;;;;;;
  114. ; fgetc(fp);
  115.  
  116.     public    _fgetc
  117.  
  118.     _align
  119. _fgetc    proc    near
  120.  
  121.     ifdef _MT
  122.     ;The idea with the multi-threaded version is to lock the
  123.     ;stream, call the locked version of fgetc, and then
  124.     ;unlock the stream.
  125.  
  126.     push    EBP
  127.     mov    EBP,ESP
  128.     sub    ESP,4
  129.     push    P+0[EBP]
  130.     call    ___fp_lock
  131.     call    near ptr _fgetc_nlock
  132.     mov    -4[EBP],EAX        ;save return value
  133.     call    ___fp_unlock
  134.     mov    EAX,-4[EBP]
  135.     mov    ESP,EBP
  136.     pop    EBP
  137.     ret
  138.     endif
  139.  
  140.     public    __fgetc_nlock
  141. __fgetc_nlock:
  142.  
  143. G4:    mov    ECX,PS[ESP]
  144. G1:    dec    dword ptr _cnt[ECX]
  145.     js    short G2    ;if out of chars in buffer
  146.  
  147. G6:
  148.     mov    EDX,_ptr[ECX]
  149.     movzx    EAX,byte ptr [EDX]    ;get char from buffer
  150.     inc    EDX
  151.     mov    _ptr[ECX],EDX        ;updated pointer
  152.  
  153. ifdef DOS386
  154.     test    byte ptr _flag+1[ECX],_IOTRAN/256    ;translated mode?
  155.     je    short G3            ;no
  156.     _ifs    AL e 13, G1            ;ignore CRs
  157.     _ifs    AL e 26, G5            ;^Z marks end of file
  158. endif
  159. G3:    ret
  160.  
  161. G2:
  162.     _ifs    <dword ptr _cnt[ECX]> ne -1, G6
  163.     push    ECX
  164.     call    __fillbuf        ;fill buffer (_fillbuf(fp))
  165.     add    ESP,4
  166.     tst    EAX            ;EOF?
  167.     jz    short G4        ;no
  168.     ret                ;return EOF
  169.  
  170. G5:    mov    EAX,EOF
  171.     or    byte ptr _flag[ECX],_IOEOF    ;set EOF flag bit
  172.     mov    dword ptr _cnt[ECX],0        ;0 chars left in buffer
  173.     ret
  174.  
  175. _fgetc    endp
  176.  
  177.     endcode fputc
  178.     end
  179.  
  180.