00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
00450
00451 if (dma->control & DCON_ST)
00452 outpw(channel ? PCB_D1CON : PCB_D0CON, dma->control | DCON_START);
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 void AMD_EnableDrq(int channel, int onoff)
00465 {
00466 int pio = channel ? 13 : 12;
00467 if (onoff) {
00468
00469 AMD_SetPioMode(1<<pio, 0);
00470 AMD_SetPioDir (1<<pio, 0);
00471 } else {
00472
00473 AMD_SetPioDir (1<<pio, 1<<pio);
00474 AMD_SetPioMode(1<<pio, 0);
00475 }
00476 }
00477