PC alaplapi dma programozása

Ez a téma lezárásra került a moderátor által. A lezárás oka: 1 t�ma - 1 k�rd�s
PC alaplapi dma programozása
2013-05-15T08:06:28+02:00
2015-02-10T10:34:41+01:00
2022-12-02T04:05:37+01:00
Gábor_123
Üdv Mindenkinek!

Egyszerű hw építése során felmerült probléma megoldásához kérem a hozzáértők segítségét.
Az alaplapi DMA felhasználásával:

ES:DI címre
DX portról
CX db byte-ot szeretnék beolvastatni byte-os átvitellel hs nélkül,( azaz úgy amit kap a port) DMA szabad csatornáinak valamelyikével, masm rutinnal.

Kellene az a pár sor amivel a DMA felprogramozható erre a feladatra.

Minden segítséget előre is nagyon szépen köszönök!
Mutasd a teljes hozzászólást!
Örömmel jelentem működik a DMA folyamat. Szépen megy a busz órajelének sebességével byte-os adatátvitel.
Amire így utólag érdemes felhívnom a figyelmet az a DMA-nak a 0Bh port címen elérhető parancs regiszterébe írandó értékek.
Mert ugye a leírásokban szereplő írást a memóriába írásként és az olvasást a portra való írásként értelmezik
( ; 0bh -ra 64+csat szignál
; 128+csat blokkos
; + 4 memóriába
; + 8 portra
; +16 automata ciklus ismétlés
; +32 csökkenő cím számláló)
.

Valamint az auto üzemben a maszk feloldásától, egy újabb maszkolásig folyamatosan működik a csatorna.
(És persze a CLI STI megszakítás tiltás feloldás utasításpár alkalmazását sem célszerű elfelejteni.)
Szóval összességében ha tudjuk, hogy a regisztereket out műveletekkel érjük el, és a hw a DMA chip leírásával ellentétes előjelű jelet is kérhet illetve produkálhat, akkor viszonylag egyszerűen kezelhető a DMA.
Még talán annyit érdemes megjegyezni, hogy mivel a DMA a laphatárokat nem tudja átlépni, érdemes erre odafigyelni a lap és offset címek tervezésénél.

Na ha már ilyen jó lett, volna még egy kérdésem

Valaki nem tudja véletlenül, hogy a másodlagos IDE vezérlő melyik DMA csatornát használja?

(Ugyanis azzal még ötször ekkora frekvenciával és két byte-os adatokat is be lehetne olvasni. És akkor a 16 bites DAC-okat akár 33 MHz sebességgel is rá lehetne kötni a PC-re.)
Mutasd a teljes hozzászólást!

  • Védett módban csak úgy nem fogod tudni elérni..
    OS függő lesz.

    WinApi DMA Programming
    Soha nem foglalkoztam ilyesmivel, bele sem néztem, h mi van benne, de talán segít.
    Mutasd a teljes hozzászólást!
  • Nagyon szépen köszönöm a válaszodat.
    Sima DOS -al futó gépre kellene, tasm fordító alá. (Olvastam leírásokat, de ez nekem túl kínai. Mindenről írnak, csak azt nem látom, hogy melyik portra, milyen sorrendben, mit vár a DMA, és mitől indítja az átvitelt.)
    Mutasd a teljes hozzászólást!
  • Mutasd a teljes hozzászólást!
  • Ezt is köszönöm szépen!

    Úgy látszik nagyon béna vagyok ehhez, mert azt leszámítva, hogy a linken lévő cikk végén az írója elhárít mindent magáról azt írva, hogy "csak úgy átvette, ellenőrzés nélkül" a hivatkozott részeket, így sem értem.

    Az világos a többi forrásból, hogy a DMA-nak üzemmód kódot, cél memória címet, port címet és blokkos üzemben az adatsor hosszát "oda kell adni".
    Na de hogyan? Mit, hova kell ehhez tölteni, azt már nem értem.
    de ettől még köszönöm szépen!
    Mutasd a teljes hozzászólást!
  • Mi az oka annak, hogy a PC-t kínzod ezzel? Vagyis mit akarsz és hová átpakolni DMA-val?
    Mutasd a teljes hozzászólást!
  • A régi PC-ket sorra dobáljuk a szemétbe, miközben egy-egy olyan műszert-eszközt súlyos ezrekért vesztegetnek, amiket némi külső kiegészítővel bármelyik régebbi gépből összeállíthatunk. Ilyen eszközöket készítgetek és most értem egy olyan pontra ahol a processzoros például:
    d1k1: in al,dx
    mov es:byte ptr [di],al
    inc di
    loop d1k1
    rutinnál picivel gyorsabb átvitel kellene. A DMA-t pedig erre találták ki, ezért kellene.
    Gondoltam, hogy itt a sok profi programozó között akad valaki aki már életében egyszer felprogramozott egy PC-s DMA-t.
    Mutasd a teljes hozzászólást!
  • Mutasd a teljes hozzászólást!
  • Neked is köszönöm szépen!
    Sajnos ebben a leírásban csak az alapok vannak benne és a DMA-t csak fogalmi szinten említi, de semmi konkrétumot nem ír róla.
    Mutasd a teljes hozzászólást!
  • Konkrét programrészek vannak benne, a megfelelő 'outportb' utasításokkal!
    Mi lenne ha szépen kinyomtatnád, és rászánnád azt a pár órai munkát, ami ahhoz kell, hogy megértsed, miről van szó?
    Mutasd a teljes hozzászólást!
  • Igazából megtettem. Rászántam. De ha tévednék, örömmel olvasnám azt a részletét amelyben szerinted a DMA felprogramozásáról konkrét példát írt.
    Egyébként pedig azóta én magam is "lázasan" olvasgatom a programozói oldalakat és ezt találtam:

    Mutasd a teljes hozzászólást!
    Csatolt állomány
  • Mondjuk keresd meg benne a StartDMA részt.
    Mutasd a teljes hozzászólást!
  • Igen, és mit tegyek vele? Nekem ez zagyva.
    A megtalált kis program amit csatoltam, még az sem működik, pedig abból már legalább annyit le lehet szűrni, hogy a DMA egyes csatornáit 00h, 08h, 09h, 0ch valamint 83h és 87h portokra kiírt adatokkal lehet piszkálni.
    Az is látszik, hogy nincs semmilyen külön retesz. Egy-egy portra egyszerűen egymás után kiírunk al,ah sorrendben például AX-ben lévő adatokat.
    Vélelmezem, hogy ezen portok közül 0ah-ra az alsó négy (0,1,2,3) csatorna maszkolását végző "számot" küldjük.
    Ha jól értelmezem akkor a 0ah-val kijelölt csatornákhoz tartozó regiszterek 0ch portra küldött 0h értékkel törölhetők, azaz leállítható a DMA-nak a maszkkal kijelölt csatornája.
    Ugyanakkor az egyik forrás szerint a 0ah felső bitjeit nem szabad módosítani, más források szerint pedig éppen ezekkel a felső bitekkel kell például a blokk módot beállítani.
    Összefoglalva, nem megtanulni szeretném a DMA programozásának rejtelmeit, hanem az a nyamvadt pár sor kellene amitől
    CX darab byte-ot, DX portról, ES:DI címre odamásol.
    A többi "finomság" nem tud felizgatni.

    Ha tudsz ebben segíteni, akkor megköszönöm.
    Mutasd a teljes hozzászólást!
  • Szia. Ez talán segít.
    Mutasd a teljes hozzászólást!
  • Szia! Hú, de ügyes vagy! Ez nagyon jónak látszik! Köszönöm szépen! Ezt még nem láttam. Nagyon jó!
    Mutasd a teljes hozzászólást!
  • Hú annak idején (kb 10 évvel ezelőtt) én is mit szenvedtem a dma programozgatásával meg időzített etetésével. Régi sound blaster hangkártyákat kellett dmaval etetni. (Ha csak nem akartál másodpercenként 11000 irq-t)
    De már semmire sem emlékszem belőle :D
    Mutasd a teljes hozzászólást!
  • Szívesen
    Mutasd a teljes hozzászólást!
  • Az 1989-es kiadású "Az IBM PC-k belső felépítése" LSI kiadvány szentel néhány oldalt az alaplapi DMA működésének:

    152. oldal
    153. oldal
    154. oldal
    155. oldal
    156. oldal
    157. oldal
    158. oldal

    Ebből kiderül, hogy 2 db - kaszkádba kapcsolt - 8237A vezérlőn keresztül vezérli a DMA-t, amit még kiegészítettek a 24 bites címzéshez egy 74LS612-vel. Ezek adatlapjai:
    8237A
    74LS612

    Az eddigiek tükrében - gondolom - már hasznosnak bizonyul az a link is amit "**G**" adott korábban.

    Mutasd a teljes hozzászólást!
  • Neked is nagyon szépen köszönöm a segítségedet!

    Elkészítettem a rutinokat, de ... a beillesztéskor jöttem rá, hogy valami nagyon hiányzik:

    A 360h portról kellene olvasni, viszont nem tudom, hogy a port címet hova kellene kiküldeni: (0 csat.-ra érvényes, blokkos olvasás, amit a DMA leírásokban memóriába írásnak neveznek.)

    dma: sub al,al
    out 0Ch,al
    mov al,4
    out 0ah,al
    sub al,al
    out 0ch,al
    mov al,132
    out 0bh,al

    mov ax,0 ; 0000h offset a page címtől.
    mov cx,word ptr[byte_szam]
    mov dx,0
    out dx,al
    mov al,ah
    out dx,al

    inc dl
    mov al,cl
    out dx,al
    mov al,ch
    out dx,al

    mov al,byte ptr [dpage]
    mov dx,87h
    out dx,al

    sub al,al
    out 0ah,al

    RET

    Úgyhogy:
    Mindenkinek nagyon szépen köszönöm az eddigi igyekezetét!

    Csak sajnos nem megy

    Ezért ha valakinek lenne még ötlete a forrás port címét hova írjam, akkor azért is nagyon hálás lennék!
    Mutasd a teljes hozzászólást!
  • Ahogy én látom, DMA esetén nincsenek IO-címek, a hardware-ed küld egy DRQ jelet, a DMA vezérlő elkapja a buszt, küld egy DACK jelet, a hardware beküldi az adatot, a DMA tárolja a memóriában, azután jöhet a következő.
    Mutasd a teljes hozzászólást!
  • Szia! Az lehet. Viszont az egész gépben egyetlen DRQ vezeték van. Honnan tudja a DMA azt, hogy melyik portról kapja az adatot?
    Vagy a DACK vezeték L szintjén bárki lekötheti az adatbuszt?
    És akkor mi van a RAM-RAM átvitelkor? Ott nincs is DRQ érzékelő eszköz.
    nem értem én ezt... Több helyen írják, hogy van olyan üzemmód is amikor az órajel H értékénél a CPU, L értékénél a DMA használja a buszokat. Az ilyen üzemet hol lehet beállítani?

    Tetejében a DACK jel L szintjénél az A0-A9 címek és változnak a Neg(IOR) és a Neg(IOW) jelekkel együtt. Mintha valaki címezgetné a portokat. Csak az AEN marad H szinten. :( nagyon nem értem én ezt.

    Mert ugye, ha HW HS áramkörrel lehúzzuk a DRQ vezetéket, akkor ezt akár például a HDD DMA kérésével egy időben is megtehetjük. Ezért csak az látszik, hogy valaki küldött egy DRQ-t.
    Az is lehet, hogy a DRQ-ra a DMA küld egy busz kérelmet a CPU-nak, de az csak órajelekkel később nyugtázza. Vagyis honnan tudhatja a HS áramkör azt, hogy a DACK válasz neki szól?

    Nem lehet mondjuk olyan, hogy a DMA portjai között valamelyikre adatfüzért kell küldeni amelyikben sorban ott vannak a memória, az io címek?
    (Mondjuk azt is jó lenne tudni, hogy milyen alakban, sorrendben kellene küldeni.)
    Mutasd a teljes hozzászólást!
  • > Viszont az egész gépben egyetlen DRQ vezeték van.

    Egy kicsit jobban meg kellene számolni... Az ISA-buszon elérhető a DRQ 0-3,5-7, az hét darab.

    > Honnan tudja a DMA azt, hogy melyik portról kapja az adatot?

    Nem portról, hanem az adatbuszról kapja.

    > Vagy a DACK vezeték L szintjén bárki lekötheti az adatbuszt?
    Az a bizonyos HW, akihez az a DACKi tartozik.

    > És akkor mi van a RAM-RAM átvitelkor? Ott nincs is DRQ érzékelő eszköz.

    Nincs, ott a DMA két csatornája egymásba kapaszkodik, és másolnak szorgalmasan.

    > Több helyen írják, hogy van olyan üzemmód is amikor az órajel H értékénél a CPU, L értékénél a DMA használja a buszokat. Az ilyen üzemet hol lehet beállítani?

    Kétlem, hogy a PC-hardware-en ez menne, ahhoz jóval lassabb órajel kellene.
    Mutasd a teljes hozzászólást!
  • Köszönöm szépen! Ez egészen jó!
    Már csak egy dolog nem világos: A DMA honnan tudja, hogy elveheti az adatot a buszról, illetve a HW kártya mikor engedje el a buszt?
    Mutasd a teljes hozzászólást!
  • Mutasd a teljes hozzászólást!
  • Köszönöm szépen! (Ezt a másodikat már kerestem, de eddig nem találtam.)
    Ha jól értem, akkor sima io olvasáskor AEN L+ IOR L (vagy IOW L) + cím dekódolás választja ki a kártya portját, DMA idején csak az adatátvitelre felprogramozott DMA ad például DACK1 L jelet a DRQ1 L szintjére válaszul és ezzel kell kapuzni a kártya TS kimenetét, ilyenkor még a címdekódolás sem kell.:)
    Nagyon nagyot segítettél! Köszönöm szépen! :)
    Mutasd a teljes hozzászólást!
  • Mivel kezdettől fogva DMA-ról esett szó, ez minket is bevitt az erdőbe, s emiatt egy picit "félretájékoztattunk" téged.

    Pontosabban nekem is csak a minap, amikor a 80286 utasításkészletét böngésztem - valami egészen más miatt -, akkor tünt fel, hogy az I/O-nál is vannak "stringműveletek"!

    Azaz a 286-os procitól kezdve (a 8086 és 8088 még nem tudja) léteznek:

    INSB
    OUTSB
    INSW
    OUTSW

    Ezek a LODS és STOS-hoz hasonlóan működnek, de nem az AL/AX-re, hanem a DX-ben megadott port-ra, és hasznáható előttük a REP prefix, azaz CX-ben megadott számúszor hajtja végre az utasítást (D bitre figyelni!).

    Ílymódon ez már egy picivel gyorsabb, mint az általad megadott kódsorozat, és nincs szükség DMA-ra és HW-es átalakításra. Bár azért a DMA-nál nincs gyorsabb.

    Persze, ha pl. 20-25 évvel ezelőtti XT alaplapjaid vannak, akkor bizony azzal (a 8088-as miatt) nem fog menni...
    Mutasd a teljes hozzászólást!
  • Szia! Hogy ez mekkoraa ötlet! Szuper! Rögvest kipróbálom! Nagyon szépen köszönöm, hogy felhívtad rá a figyelmemet!
    Ami a DMA-t illeti, közben elkészítettem a kezelő progiját ami már jól működik:
    ; ---------------------------------------------------------------------
    ; 2-3, 4-5, 6-7 azaz dmacsat*2
    ; 0ah -ra 4+csat kikapcs
    ; 0+csat bekapcs
    ; 0bh -ra 64+csat szign l
    ; 128+csat blokkos
    ; +4 mem˘ri ba
    ; +8 portra
    ; 0ch-ra nulla a RESET

    ; dh = mode kod 68 64v128 + 4v8 + dmacsat 4 memoriaba, 8 portra
    ; ax = address 64 szignal v. 128 blokkos
    ; cx = length= thosszl
    ; dl = dpage
    ; DMAcsat: db 0h
    ; dpage: dw 00h ; dl,dh sorrend
    ; dpageport: dw 00h ; dpagec: db 131,129,130
    ; address: dw 00h azaz az offset nagysaga
    ; addressport: dw 00h


    dma: mov al,byte ptr[DMAcsat]
    cmp al,1
    jne dma2
    mov word ptr [dpageport],83h
    jmp dma4
    dma2: cmp al,2
    jne dma3
    mov word ptr [dpageport],81h
    jmp dma4
    dma3: cmp al,3
    jne dmae
    mov word ptr [dpageport],82h
    jmp dma4

    dmae: jmp error

    dma4: mov bx,word ptr[kipu]
    mov bl,bh
    sub bh,bh
    mov cl,4
    shl bx,cl
    mov bl,bh
    mov word ptr[dpage],bx

    mov bx,word ptr[kipu]
    shr bx,cl
    mov word ptr[address],bx

    mov al,byte ptr[DMAcsat]
    add al,al ; 0,2,4,6 azaz 2*0 v. 2*1...
    xor ah,ah
    mov word ptr[addressport],ax
    mov ax,word ptr[address]
    mov cx,word ptr[thosszl]

    mov dh,68 ; mod kod kepzes 64+4+dmacsat
    add dh,byte ptr[DMAcsat]

    ;******************************

    sub al,al
    out 0Ch,al ; clr byte ptr

    mov bx,ax
    mov al,4
    add al,byte ptr[DMAcsat]
    out 0Ah,al ; mask reg bit DMA csatorna kikapcsolasa

    sub al,al
    out 0Ch,al ; clr byte ptr DMA csatorna regisztereinek torlese

    mov al,dh ; mod kod
    out 0Bh,al ; set mode reg


    mov dx,word ptr[addressport]
    mov al,bl
    out dx,al ; set address offset low
    mov al,bh
    out dx,al ; set address offset high

    inc dx ; igy DX-ben a hossz port cime

    mov al,cl
    out dx,al ; set length low byte
    mov al,ch
    out dx,al ; set length high byte

    mov al,byte ptr [dpage]
    mov dx,word ptr [dpageport]
    out dx,al ; set DMA page reg

    mov al,byte ptr[DMAcsat]
    out 0Ah,al ; unmask (activate) dma channel
    jmp end2

    Már "csak" a hw-rel kell megküzdenem..

    De a te ötleted nagyon szuper! Kipróbálom! Köszönöm
    Mutasd a teljes hozzászólást!
  • Tisztelettel jelentem, hogy kipróbáltam a rep insb változatot! :)
    Vélhetően a proci-busz időzítések miatt azonos számú byte-ot olvasott be, mint a lépésenként leírt változat. De ettől még újra köszönöm szépen az ötletet! :)
    Mutasd a teljes hozzászólást!
  • Feltételezem - ezek után -, hogy nem 20 éves alaplapokról van szó, és elképzelhető, hogy azért nem változott a sebesség, mert a kód a nagyon gyors cache memóriában futott, és a sima memóriát csak az adatátvitel terhelte. A BUS-on tehát csak az I/O művelet, és a memóriaírás jelent meg.

    Ez reményt ad arra, hogy DMA esetén - I/O-port ciklus hiányában - felgyorsul valamennyire az átvitel. Ám ha mégsem teljesen, akkor még megkísérelhető 16 (vagy 32 bites) bites átvitel, ám ez már valószínűleg komolyabb HW módosítást igényelne, és a DMA felprogramozása is bizonyára más lenne.

    Megjegyzem még - elismerésként -, hogy ritka az olyan ember, aki a HW-t és SW-t közel egyformán bírja. Vagy talán team-ben dolgozol?...
    Mutasd a teljes hozzászólást!
  • Köszönöm a kedves elismerő szavaidat, de sajnos nem szolgáltam rá, mert mindkettőt csak "kóstolgatom". (Éppen ez a gondom :( , mert ha menne akkor én segíthetnék másoknak és nem én szorulnék a segítségetekre.)
    Mutasd a teljes hozzászólást!
Ez a téma lezárásra került a moderátor által. A lezárás oka: 1 t�ma - 1 k�rd�s
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd