home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / packetdrivers.tar.gz / pd.tar / src / io8.asm < prev    next >
Assembly Source File  |  1995-06-25  |  2KB  |  97 lines

  1. ;put into the public domain by Russell Nelson, nelson@clutx.clarkson.edu
  2.  
  3. ;input a word from IO port
  4. inw    macro
  5.     in    al, dx            ;read low address byte
  6.     mov    ah, al            ;save byte
  7.     in    al,61h            ;wait a bit.
  8.     inc    dx            ;next IO address
  9.     in    al, dx            ;read high address byte
  10.     xchg    ah, al            ;swap bytes 
  11.     dec    dx            ;restore IO address
  12.     endm
  13.  
  14. ;write a word to an IO port
  15. outw    macro
  16.     out    dx, al            ;write low address byte
  17.     push    ax            ;wait a little bit.
  18.     in    al,61h
  19.     pop    ax
  20.     xchg    ah, al            ;get next byte
  21.     inc    dx            ;next IO address
  22.     out    dx, al            ;write high address byte
  23.     xchg    ah, al            ;restore AX
  24.     dec    dx            ;restore DX
  25.     endm
  26.  
  27. ;this code is exactly like the "rep insb" instruction.  It works even if
  28. ;you've got an 8088.
  29.  
  30.     extrn    is_186: byte        ;=0 if 808[68], =1 if 80[123]86.
  31.  
  32. repinsb:
  33.     cmp    is_186,0        ; Can we use rep insb?
  34.     je    repinsb_1        ; no - have to do it slowly.
  35.     .286
  36.     rep    insb
  37.     .8086
  38.     jmp    short icnteven
  39. repinsb_1:
  40. ; If buffer doesn't begin on a word boundary, get the first byte
  41.     test    di,1            ; if(buf & 1){
  42.     jz    ibufeven        ;
  43.     in    al,dx            ; al = in(dx);
  44.     stosb                ; *di++ = al
  45.     dec    cx            ; cx--;
  46. ibufeven:
  47.     shr    cx,1            ; cx = cnt >> 1; (convert to word count)
  48. ; Do the bulk of the buffer, a word at a time
  49.     jcxz    inobuf            ; if(cx != 0){
  50. rb:    in    al,dx            ; do { al = in(dx);
  51.     mov    ah,al
  52.     in    al,dx            ; ah = in(dx);
  53.     xchg    al,ah
  54.     stosw                ; *si++ = ax; (di is word pointer)
  55.     loop    rb            ; } while(--cx != 0);
  56. ; now check for odd trailing byte
  57. inobuf:
  58.     jnc    icnteven
  59.     in    al,dx
  60.     stosb                ; *di++ = al
  61. icnteven:
  62.     ret
  63.  
  64.  
  65. ;this code is exactly like the "rep outsb" instruction.  It works even if
  66. ;you've got an 8088.
  67.  
  68. repoutsb:
  69.     cmp    is_186,0        ; Can we use rep outsb?
  70.     je    out86            ; no - have to do it slowly.
  71.     .286
  72.     rep    outsb
  73.     .8086
  74.     jmp    short ocnteven
  75. out86:
  76.     test    si,1            ; (buf & 1) ?
  77.     jz    obufeven        ; no
  78.     lodsb                ; al = *si++;
  79.     out    dx,al            ; out(dx,al);
  80.     dec    cx            ; cx--;
  81. obufeven:
  82.     shr    cx,1            ; cx = cnt >> 1; (convert to word count)
  83. ; Do the bulk of the buffer, a word at a time
  84.     jcxz    onobuf            ; if(cx != 0){
  85. xb:    lodsw                ; do { ax = *si++; (si is word pointer)
  86.     out    dx,al            ; out(dx,lowbyte(ax));
  87.     mov    al,ah
  88.     out    dx,al            ; out(dx,hibyte(ax));
  89.     loop    xb            ; } while(--cx != 0); }
  90. ; now check for odd trailing byte
  91. onobuf:
  92.     jnc    ocnteven
  93.     lodsb                ;   out(dx,*si++);
  94.     out    dx,al
  95. ocnteven:
  96.     ret
  97.