Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

amd186.cpp

Go to the documentation of this file.
00001 /*  amd186.cpp
00002     Low-level AMD186ED functions
00003 
00004     18.06.2001: tk, assembly implementations for all PIO functions.
00005     12.04.2000: tk, initial implementation.
00006 
00007     Copyright (c)2000 by Thomas Kindler, thomas.kindler@gmx.de
00008 
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of
00012     the License, or (at your option) any later version. Read the
00013     full License at http://www.gnu.org/copyleft for more details.
00014 */
00015 
00016 // include files -----
00017 //
00018 #include <iostream>
00019 #include <dos.h>
00020 #include <stdio.h>
00021 #include "clib/hwapi.h"
00022 #include "amd186.h"
00023 
00024 
00032 void REP_INSB( int port, void *dest, int numBytes )
00033 {
00034   asm  {
00035     pushf
00036     push cx
00037     push dx
00038     push di
00039     push es
00040     cld
00041 
00042     mov  cx, numBytes
00043     mov  dx, port
00044     les  di, dword ptr [dest]
00045     rep  insb
00046 
00047     pop  es
00048     pop  di
00049     pop  dx
00050     pop  cx
00051     popf
00052   }
00053 }
00054 
00055 
00063 void REP_INSW( int port, void *dest, int numWords )
00064 {
00065   asm  {
00066     pushf
00067     push cx
00068     push dx
00069     push di
00070     push es
00071     cld
00072 
00073     mov  cx, numWords
00074     mov  dx, port
00075     les  di, dword ptr[dest]
00076     rep  insw
00077 
00078     pop  es
00079     pop  di
00080     pop  dx
00081     pop  cx
00082     popf
00083   }
00084 }
00085 
00086 
00094 void REP_OUTSB( int port, void *src, int numBytes )
00095 {
00096   asm  {
00097     pushf
00098     push cx
00099     push dx
00100     push di
00101     push ds
00102     cld
00103 
00104     mov  cx, numBytes
00105     mov  dx, port
00106     lds  si, dword ptr [src]
00107     rep  outsb
00108 
00109     pop  ds
00110     pop  di
00111     pop  dx
00112     pop  cx
00113     popf
00114   }
00115 }
00116 
00117 
00125 void REP_OUTSW( int port, void *src, int numWords )
00126 {
00127   asm  {
00128     pushf
00129     push cx
00130     push dx
00131     push di
00132     push ds
00133     cld
00134 
00135     mov  cx, numWords
00136     mov  dx, port
00137     lds  si, dword ptr [src]
00138     rep  outsw
00139 
00140     pop  ds
00141     pop  di
00142     pop  dx
00143     pop  cx
00144     popf
00145   }
00146 }
00147 
00148 
00159 void usleep(unsigned us)
00160 {
00161   asm {
00162       push  cx
00163       mov   cx, us
00164     l1:
00165       nop
00166       nop
00167       loop  l1
00168       pop   cx
00169   }
00170 }
00171 
00172 
00182 void AMD_TestPios()
00183 {
00184   for (int i=0; i<=13; i++) {
00185     pfe_enable_pio(1<<i, PIO_O0);
00186     unsigned long a = AMD_GetPioDir();
00187     if (i == 13)
00188       pfe_enable_pio(1<<i, PIO_IPD);
00189     else
00190       pfe_enable_pio(1<<i, PIO_IPU);
00191     unsigned long b = AMD_GetPioDir();
00192 
00193     int j;
00194     for (j=0; j<32; j++)
00195       if ((a^b) & (1<<j)) break;
00196 
00197     printf( "%d -> %d, 0x%08lxL\n", i, j, a^b);
00198   }
00199 }
00200 
00201 
00212 void AMD_SetPioData(unsigned long mask, unsigned long data)
00213 {
00214   asm {
00215     push  ax
00216     push  bx
00217     push  cx
00218     push  dx
00219     
00220     mov   dx, PCB_PDATA0
00221     mov   bx, word ptr data
00222     mov   cx, word ptr mask
00223     and   bx, cx
00224     not   cx
00225     in    ax, dx
00226     and   ax, cx
00227     or    ax, bx
00228     out   dx, ax
00229 
00230     mov   dx, PCB_PDATA1
00231     mov   bx, word ptr data+2
00232     mov   cx, word ptr mask+2
00233     and   bx, cx
00234     not   cx
00235     in    ax, dx
00236     and   ax, cx
00237     or    ax, bx
00238     out   dx, ax
00239 
00240     pop   dx
00241     pop   cx
00242     pop   bx
00243     pop   ax
00244   }
00245 }
00246 
00247 
00258 void AMD_SetPioDir(unsigned long mask, unsigned long dir)
00259 {
00260   asm {
00261     push  ax
00262     push  bx
00263     push  cx
00264     push  dx
00265 
00266     mov   dx, PCB_PDIR0
00267     mov   bx, word ptr dir
00268     mov   cx, word ptr mask
00269     and   bx, cx
00270     not   cx
00271     in    ax, dx
00272     and   ax, cx
00273     or    ax, bx
00274     out   dx, ax
00275 
00276     mov   dx, PCB_PDIR1
00277     mov   bx, word ptr dir+2
00278     mov   cx, word ptr mask+2
00279     and   bx, cx
00280     not   cx
00281     in    ax, dx
00282     and   ax, cx
00283     or    ax, bx
00284     out   dx, ax
00285 
00286     pop   dx
00287     pop   cx
00288     pop   bx
00289     pop   ax
00290   }
00291 }
00292 
00293 
00304 void AMD_SetPioMode(unsigned long mask, unsigned long mode)
00305 {
00306   asm {
00307     push  ax
00308     push  bx
00309     push  cx
00310     push  dx
00311 
00312     mov   dx, PCB_PIOMODE0
00313     mov   bx, word ptr mode
00314     mov   cx, word ptr mask
00315     and   bx, cx
00316     not   cx
00317     in    ax, dx
00318     and   ax, cx
00319     or    ax, bx
00320     out   dx, ax
00321 
00322     mov   dx, PCB_PIOMODE1
00323     mov   bx, word ptr mode+2
00324     mov   cx, word ptr mask+2
00325     and   bx, cx
00326     not   cx
00327     in    ax, dx
00328     and   ax, cx
00329     or    ax, bx
00330     out   dx, ax
00331 
00332     pop   dx
00333     pop   cx
00334     pop   bx
00335     pop   ax
00336   }
00337 }
00338 
00339 
00350 void AMD_SetPcsWaitStates(int waitstates)
00351 {
00352   const int pacsBits[] = {
00353      0,  1,  2,  3,  8,  8,  9,  9,
00354     10, 10, 11, 11, 11, 11, 11, 11
00355   };
00356 
00357   if (waitstates > 15)  waitstates = 15;
00358   if (waitstates <  0)  waitstates =  0;
00359 
00360   outpw(PCB_PACS, (inpw(PCB_PACS) & 0xfff4) | pacsBits[waitstates]);
00361 }
00362 
00363 
00372 void  AMD_StartDma(int channel, DmaInfo *dma)
00373 {
00374   unsigned long src, dst;
00375   if (dma->control & DCON_SMIO)
00376     src = FP_SEG(dma->srcMem)*16L + FP_OFF(dma->srcMem);
00377   else
00378     src = dma->srcPort;
00379 
00380   if (dma->control & DCON_DMIO)
00381     dst = FP_SEG(dma->dstMem)*16L + FP_OFF(dma->dstMem);
00382   else
00383     dst = dma->dstPort;
00384 
00385   // stop previous transfer first
00386   //
00387   outpw(channel ? PCB_D1CON  : PCB_D0CON,  DCON_STOP);
00388 
00389   outpw(channel ? PCB_D1SRCL : PCB_D0SRCL, (unsigned)src);
00390   outpw(channel ? PCB_D1SRCH : PCB_D0SRCH, (unsigned)(src>>16));
00391   outpw(channel ? PCB_D1DSTL : PCB_D0DSTL, (unsigned)dst);
00392   outpw(channel ? PCB_D1DSTH : PCB_D0DSTH, (unsigned)(dst>>16));
00393   outpw(channel ? PCB_D1TC   : PCB_D0TC,   dma->length);
00394   outpw(channel ? PCB_D1CON  : PCB_D0CON,  dma->control | DCON_START);
00395 }
00396 
00397 
00403 void AMD_StopDma(int channel)
00404 {
00405   unsigned control;
00406 
00407   control = inpw(channel ? PCB_D1CON : PCB_D0CON);
00408   control = (control & ~DCON_START) | DCON_STOP;
00409   outpw(channel ? PCB_D1CON : PCB_D0CON,  control);
00410 }
00411 
00412 
00424 void AMD_GetDmaInfo(int channel, DmaInfo *dma)
00425 {
00426   // Stop DMA channel first..
00427   //
00428   dma->control = inpw(channel ? PCB_D1CON : PCB_D0CON);
00429   outpw(channel ? PCB_D1CON : PCB_D0CON,
00430         (dma->control & ~DCON_START) | DCON_STOP);
00431 
00432   unsigned  sh, sl, dh, dl;
00433   sh = inpw(channel ? PCB_D1SRCH : PCB_D0SRCH);
00434   sl = inpw(channel ? PCB_D1SRCL : PCB_D0SRCL);
00435   dh = inpw(channel ? PCB_D1SRCH : PCB_D0SRCH);
00436   dl = inpw(channel ? PCB_D1DSTL : PCB_D0DSTL);
00437   dma->length  = inpw(channel ? PCB_D1TC  : PCB_D0TC);
00438 
00439   if (dma->control & DCON_SMIO)
00440     dma->srcMem = MK_FP(sh << 12, sl);
00441   else
00442     dma->srcPort = sl;
00443 
00444   if (dma->control & DCON_DMIO)
00445     dma->dstMem = MK_FP(dh << 12, dl);
00446   else
00447     dma->dstPort = dl;
00448 
00449   // Restart DMA channel
00450   //
00451   if (dma->control & DCON_ST)
00452     outpw(channel ? PCB_D1CON : PCB_D0CON, dma->control | DCON_START);
00453 }
00454 
00455 
00456 /*
00457  * Enable/Disable DMA request pin.
00458  * This function switches the DRQ pin between normal
00459  * operation and PIO input with pullup.
00460  *
00461  * \param channel DMA channel, either 0 or 1
00462  * \param onoff   enable/disable DRQ
00463  */
00464 void AMD_EnableDrq(int channel, int onoff)
00465 {
00466   int pio = channel ? 13 : 12;
00467   if (onoff) {
00468     // mode 0, dir 0 - normal operation
00469     AMD_SetPioMode(1<<pio, 0);
00470     AMD_SetPioDir (1<<pio, 0);
00471   } else {
00472     // mode 0, dir 1 - input with pullup
00473     AMD_SetPioDir (1<<pio, 1<<pio);
00474     AMD_SetPioMode(1<<pio, 0);
00475   }
00476 }
00477 

Generated on Sun Aug 4 21:47:26 2002 for k/os mp3v2 by doxygen1.2.16