Prethodna tema :: Sljedeća tema |
Autor/ica |
Poruka |
grossi Forumaš(ica)
Pridružen/a: 22. 04. 2004. (16:33:41) Postovi: (5D)16
Spol:
Lokacija: Delta Neretva
|
|
[Vrh] |
|
ZELENIZUBNAPLANETIDO SADE Forumaš(ica)
Pridružen/a: 04. 03. 2004. (19:56:15) Postovi: (54F)16
Lokacija: hm?
|
Postano: 11:36 čet, 10. 6. 2004 Naslov: Re: portovi, malo pitanje iz C-a |
|
|
[quote="grossi"]Zanima me kako mogu napisati program koji ce skenirati port od tipkovnice i zatim to pisati u text datoteku.[/quote]
Davno to bi kada sam to cinio za neki unit u pascalu, al mislim da je port u pitanju 60h. Pascal je to handleao preko necega sto se ponasalo kao niz i sluzilo je za citanje/pisanje portova.
Signali koje ces dobiti sa 60h nece biti ascii znakovi nego scan codevi koji se prenose u ascii preko ne-bas-najurednije tablice, tako da .. :?
Mislim da se u C-u radi sa headerom asm/io.h :?: pa bi to bilo dobro mjesto za pogledati dalje?
Opet nazalost, sve sto sam radio sa portovima sam radio na i386 stroju u real modu, tako da vjerujem da je stvar, npr pod linuxom malo kompliciranija, no za to postoji howto..
[url]http://www.tldp.org/HOWTO/IO-Port-Programming.html#toc2[/url]
dodatak: pogledaj man stranice za inb_p(), ioperm() i iopl() i sadrzaj headera asm/io.h. U linuxu za tu svrhu postoj device node /dev/port kojem se pristupa preko lseek() read() i write() procedura.
Sretno
btw: sto ce ti to ? :)
grossi (napisa): | Zanima me kako mogu napisati program koji ce skenirati port od tipkovnice i zatim to pisati u text datoteku. |
Davno to bi kada sam to cinio za neki unit u pascalu, al mislim da je port u pitanju 60h. Pascal je to handleao preko necega sto se ponasalo kao niz i sluzilo je za citanje/pisanje portova.
Signali koje ces dobiti sa 60h nece biti ascii znakovi nego scan codevi koji se prenose u ascii preko ne-bas-najurednije tablice, tako da ..
Mislim da se u C-u radi sa headerom asm/io.h pa bi to bilo dobro mjesto za pogledati dalje?
Opet nazalost, sve sto sam radio sa portovima sam radio na i386 stroju u real modu, tako da vjerujem da je stvar, npr pod linuxom malo kompliciranija, no za to postoji howto..
http://www.tldp.org/HOWTO/IO-Port-Programming.html#toc2
dodatak: pogledaj man stranice za inb_p(), ioperm() i iopl() i sadrzaj headera asm/io.h. U linuxu za tu svrhu postoj device node /dev/port kojem se pristupa preko lseek() read() i write() procedura.
Sretno
btw: sto ce ti to ?
_________________
Pupoljak nije negiran. Rekao sam to i ponovit cu to jos jedanput. Pupoljak NIJE negirAn.
MADD
(Mothers Against Dirty Dialectics)
Based on a true story. NOT.
Ko ih sljivi, mi sviramo punk
|
|
[Vrh] |
|
vsego Site Admin
Pridružen/a: 06. 10. 2002. (22:07:09) Postovi: (3560)16
Spol:
Lokacija: /sbin/init
|
|
[Vrh] |
|
ZELENIZUBNAPLANETIDO SADE Forumaš(ica)
Pridružen/a: 04. 03. 2004. (19:56:15) Postovi: (54F)16
Lokacija: hm?
|
Postano: 16:11 čet, 10. 6. 2004 Naslov: |
|
|
[quote="vsego"]Mislis, postoji i dnevni mirror HOWTO-a... :shock:[/quote]
:doh: :D
vsego (napisa): | Mislis, postoji i dnevni mirror HOWTO-a... |
_________________
Pupoljak nije negiran. Rekao sam to i ponovit cu to jos jedanput. Pupoljak NIJE negirAn.
MADD
(Mothers Against Dirty Dialectics)
Based on a true story. NOT.
Ko ih sljivi, mi sviramo punk
|
|
[Vrh] |
|
grossi Forumaš(ica)
Pridružen/a: 22. 04. 2004. (16:33:41) Postovi: (5D)16
Spol:
Lokacija: Delta Neretva
|
|
[Vrh] |
|
grossi Forumaš(ica)
Pridružen/a: 22. 04. 2004. (16:33:41) Postovi: (5D)16
Spol:
Lokacija: Delta Neretva
|
|
[Vrh] |
|
ZELENIZUBNAPLANETIDO SADE Forumaš(ica)
Pridružen/a: 04. 03. 2004. (19:56:15) Postovi: (54F)16
Lokacija: hm?
|
Postano: 8:21 uto, 22. 6. 2004 Naslov: |
|
|
Pod kojim OS-om/arhitekturom?
Pod kojim OS-om/arhitekturom?
_________________
Pupoljak nije negiran. Rekao sam to i ponovit cu to jos jedanput. Pupoljak NIJE negirAn.
MADD
(Mothers Against Dirty Dialectics)
Based on a true story. NOT.
Ko ih sljivi, mi sviramo punk
|
|
[Vrh] |
|
grossi Forumaš(ica)
Pridružen/a: 22. 04. 2004. (16:33:41) Postovi: (5D)16
Spol:
Lokacija: Delta Neretva
|
|
[Vrh] |
|
ZELENIZUBNAPLANETIDO SADE Forumaš(ica)
Pridružen/a: 04. 03. 2004. (19:56:15) Postovi: (54F)16
Lokacija: hm?
|
Postano: 10:36 uto, 22. 6. 2004 Naslov: |
|
|
i386 i presume :)
Princip je, mislim, isti kao i kod starih dos strojeva. Windowsi ne dopustaju direktan pristup hardveru kao takvom ali imaju neku vrstu emulacije za takve stvari... :?
Pronadjem stare kodove u "arhivi" pa ih danas-sutra postam na webu.. Nazalost nema C kodova nego pascal/asm, al princip je isti samo su komadne drukcije..
PS tvoj kompajler dopusta inlajnanje assembler koda? (borlandovi kompajleri za dos su svojevremeno imali kljucnu rijec asm za nestanje assembler kodova unutar C/C++ koda, za novije kompajlere ne znam, al to bi ti bilo korisno)
btw: sto uopce pokusavas napraviti? Pogadjam... Pokusavas napraviti igricu ali ne mozes postici da nekoliko ljudi stiska botune istovremeno? ako ti to treba, to ces morati raditi u asm-u.
zapravo.. nekako imam dojam da ti treba dosta vise od citanja keyova direktno sa porta, ako bi rekao sto pokusavas napraviti rado bi ti to malo elaborirao..
Evo korisni link:
najopsirnija baza podataka za lowlevel DOS/console programiranje:
[url=http://www.ctyme.com/rbrown.htm]Ralph Brown's Interrupt Primer[/url]
i pocetnica "naprednog" C-a, ima poglavlje o I/O port programiranju.. [url]http://goforit.unk.edu/cprogram/advcw1.htm[/url]
i386 i presume
Princip je, mislim, isti kao i kod starih dos strojeva. Windowsi ne dopustaju direktan pristup hardveru kao takvom ali imaju neku vrstu emulacije za takve stvari...
Pronadjem stare kodove u "arhivi" pa ih danas-sutra postam na webu.. Nazalost nema C kodova nego pascal/asm, al princip je isti samo su komadne drukcije..
PS tvoj kompajler dopusta inlajnanje assembler koda? (borlandovi kompajleri za dos su svojevremeno imali kljucnu rijec asm za nestanje assembler kodova unutar C/C++ koda, za novije kompajlere ne znam, al to bi ti bilo korisno)
btw: sto uopce pokusavas napraviti? Pogadjam... Pokusavas napraviti igricu ali ne mozes postici da nekoliko ljudi stiska botune istovremeno? ako ti to treba, to ces morati raditi u asm-u.
zapravo.. nekako imam dojam da ti treba dosta vise od citanja keyova direktno sa porta, ako bi rekao sto pokusavas napraviti rado bi ti to malo elaborirao..
Evo korisni link:
najopsirnija baza podataka za lowlevel DOS/console programiranje:
Ralph Brown's Interrupt Primer
i pocetnica "naprednog" C-a, ima poglavlje o I/O port programiranju.. http://goforit.unk.edu/cprogram/advcw1.htm
_________________
Pupoljak nije negiran. Rekao sam to i ponovit cu to jos jedanput. Pupoljak NIJE negirAn.
MADD
(Mothers Against Dirty Dialectics)
Based on a true story. NOT.
Ko ih sljivi, mi sviramo punk
Zadnja promjena: ZELENIZUBNAPLANETIDOSADE; 10:54 uto, 22. 6. 2004; ukupno mijenjano 2 put/a.
|
|
[Vrh] |
|
grossi Forumaš(ica)
Pridružen/a: 22. 04. 2004. (16:33:41) Postovi: (5D)16
Spol:
Lokacija: Delta Neretva
|
|
[Vrh] |
|
ZELENIZUBNAPLANETIDO SADE Forumaš(ica)
Pridružen/a: 04. 03. 2004. (19:56:15) Postovi: (54F)16
Lokacija: hm?
|
Postano: 11:41 uto, 22. 6. 2004 Naslov: |
|
|
A-HA.....
Dakle: mali background..
Pod DOS/console-om se stvari desavaju na malo primitivniji nacin..
BTW: ako si nestrpljiv potrazi dole tocno sto treba napraviti, pa ako ti to djeluje kao magija, vrati se ovdje.
[b]CPU registri[/b]
CPU, ovisno o arhitekturi, ima odredjen skup sistemskih registara. Nama trebaju samo prastari 16-bitni registri za sada pa cu se na njih koncentrirati:
AX, BX, CX, DX su registri opce namijene. Njih ces najvise koristiti. AX se tradicionalno koristi za slanje informacija o tome koju tocno proceduru unutar soft. interrupta zelimo pozvati. CX se tradicionalno koristi kod petlji (Counter Register se jos zove). DX i BX uglavnom salju parametre soft. interrupt funkcijama.
Postoje i AH, AL, BH, BL, ...., DH, DL registri koji sluze za direktan pristup gornjim, tj. donjim 8bitovima tih registara. Npr. AH=12h;AL=34h; je isto kao i AX=1234h, OK?
ES:DI, DS:SI parovi se koriste za operacije sa pointerima (i DX:AX par se koristi za pointere ali rijetko). Nekim registrima nije moguce prici direktno. Npr. da bi promjenio ES registar ces cesto morati najprije zadati vrijednost AX registru i onda tu vrijednost iz AX preslikati u ES :?
Ovi drugi ti za sada nisu toliko bitni, ali i do njih ces doci...
[b]Interrupti[/b]
postoje tri vrste interrupta koje dijelimo po pozivatelju: CPU interrupt (samo jedan), hardverski i softverski interrupti.
Na pocetnoj adresi sistemske memorije (0000h:0000h) se nalazi tzv Interrupt Vector Table (toliko o NULL pointeru.... ;)). To je niz od 256 pointera na procedure. Kada npr., pritisak gumba na tastaturi pozove interrupt 9h, onda se poziva procedura adresirana 9-tim mjestom u tom nizu. (jos jedan korisan hrdw. interrupt je 1Ch koji se poziva sam od sebe 18.2-19 puta u sekundi)
Softverski interrupti se pozivaju, jel softverski :) i koriste CPU registre za primanje parametara i vracanje rezultata funkcije, npr: namjestis li AL registar na 02h i pozoves softverski interrupt 16h, AL ce poprimiti bit vrijednosti koje ce ti reci da li je stisnut lijevi ili desni shift, control, alt itd. koje inace ne bi mogao registrirati.
ASM:[code:1]MOV AL, 02h
INT 16h[/code:1]
C: [code:1]#include <dos.h>
#include <stdio.h>
#include <process.h>
union REGS regs;
....
regs.h.al = 0x02;
int86( 0x16, ®s, ®s);[/code:1]
(ovo je malo izmijenjen primjer sa one stranice iz proslog posta koji radi istu stvar kao onaj komad asm koda)
E sad.. Sto je tvoj problem?
Stisne se gumb na tastaturi, hardver poziva interrupt 9h. Interrupt procedure pi 9h najprije aplicira tzv "typematic delay", tj. ceka (npr 0.5-1s) ignorirajuci cinjenicu da je trenutni gumb jos uvijek stisnut prije nego pocne (da bi mogao normalno pisati, iskljucivanje typematic delaya rezultira desetinama znakova ispisanih na ekranu pri svakom pritisku gumba) puniti keyboard buffer sa njime. To je, bar za igre, lose. Jer ti zelis da kada netko legne npr. na pucanje da nema nikakvog delaya.
S druge strane keyboard buffer stvara dodatne probleme. To je tampon zona izmedju tastature i ostatka sustava i tamo se spremaju znakovi prije no sto se procesuiraju. Dobro ako imas zastoje u radu zbog prevelikog opterecenja pa ti se ne gube znakovi "po putu". Lose sto beepa ako se napuni a za igre ti ni ne treba.
[b]Dakle[/b]: rijesenje je iz pocetka prepisati keyboard interrupt. Buduci da ti treba stroga kontrola sto pise gdje u kojem CPU registru u trenutku pocetka i zavrsetka rada interrupt procedure, to moras napraviti u assembleru i onda pomocu C-a tu proceduru ubaciti u IVT. Nadalje, treba biti oprezan jer ce ti sustav hangat ako zaboravis aplicirati neke ne-bas-najbolje dokumentirane promjene cpu registrima koje M$ aplikacije i OS ocekuju od jednog kulturnog keyboard interrupta.
[b]Ideja:[/b]
napraviti alternativni interrupt handler tako da na nove znakove koji dolaze sa porta ne filtrira kroz typematic delay i ne sprema u buffer, nego u niz od 256 znakova u kojima su vrijednosti 0, tj. 1 ako je tipka stisnuta te samo u tom nizu azurirati podatke o stisnutim tipkama. To moze biti obicni char[256] niz.
U igri tada u svakom ciklusu provjeravas da li je neki botun stisnut i apliciras promjene na svakog igraca shodno tomu.
Da bi natjerao sustav da poziva tvoj interrupt handler umjesto onog uobicajenog moras element 9h niza (IVT-a) promjeniti u adresu tvoje procedura, ali tako da najprije sacuvas adresu starog handlera.
Prije gasenja programa vrati vrijednost tog pointera na staru vrijednost interrupt handlera (tako da pointer u IVT-u kojeg poziva tastatura opet pokazuje na stari keyboard handler).
Ako ti je sve ovo too much, imam to gotovo negdje, al moram potraziti pa postam...
PS mozda ce ti windoze prijaviti access violation ako pokusas pisati direktvno po IVT-u, pa ti je mozda bolje okoristiti se sa dvije soft. interrupt procedure koje tomu sluze. Ne sijecam se dobro ni interrupta ni parametara kojima ju se poziva pa ti preporucam mali search po Ralphovom interrupt primeru...
A-HA.....
Dakle: mali background..
Pod DOS/console-om se stvari desavaju na malo primitivniji nacin..
BTW: ako si nestrpljiv potrazi dole tocno sto treba napraviti, pa ako ti to djeluje kao magija, vrati se ovdje.
CPU registri
CPU, ovisno o arhitekturi, ima odredjen skup sistemskih registara. Nama trebaju samo prastari 16-bitni registri za sada pa cu se na njih koncentrirati:
AX, BX, CX, DX su registri opce namijene. Njih ces najvise koristiti. AX se tradicionalno koristi za slanje informacija o tome koju tocno proceduru unutar soft. interrupta zelimo pozvati. CX se tradicionalno koristi kod petlji (Counter Register se jos zove). DX i BX uglavnom salju parametre soft. interrupt funkcijama.
Postoje i AH, AL, BH, BL, ...., DH, DL registri koji sluze za direktan pristup gornjim, tj. donjim 8bitovima tih registara. Npr. AH=12h;AL=34h; je isto kao i AX=1234h, OK?
ES:DI, DS:SI parovi se koriste za operacije sa pointerima (i DX:AX par se koristi za pointere ali rijetko). Nekim registrima nije moguce prici direktno. Npr. da bi promjenio ES registar ces cesto morati najprije zadati vrijednost AX registru i onda tu vrijednost iz AX preslikati u ES
Ovi drugi ti za sada nisu toliko bitni, ali i do njih ces doci...
Interrupti
postoje tri vrste interrupta koje dijelimo po pozivatelju: CPU interrupt (samo jedan), hardverski i softverski interrupti.
Na pocetnoj adresi sistemske memorije (0000h:0000h) se nalazi tzv Interrupt Vector Table (toliko o NULL pointeru.... ). To je niz od 256 pointera na procedure. Kada npr., pritisak gumba na tastaturi pozove interrupt 9h, onda se poziva procedura adresirana 9-tim mjestom u tom nizu. (jos jedan korisan hrdw. interrupt je 1Ch koji se poziva sam od sebe 18.2-19 puta u sekundi)
Softverski interrupti se pozivaju, jel softverski i koriste CPU registre za primanje parametara i vracanje rezultata funkcije, npr: namjestis li AL registar na 02h i pozoves softverski interrupt 16h, AL ce poprimiti bit vrijednosti koje ce ti reci da li je stisnut lijevi ili desni shift, control, alt itd. koje inace ne bi mogao registrirati.
ASM:
C: Kod: | #include <dos.h>
#include <stdio.h>
#include <process.h>
union REGS regs;
....
regs.h.al = 0x02;
int86( 0x16, ®s, ®s); |
(ovo je malo izmijenjen primjer sa one stranice iz proslog posta koji radi istu stvar kao onaj komad asm koda)
E sad.. Sto je tvoj problem?
Stisne se gumb na tastaturi, hardver poziva interrupt 9h. Interrupt procedure pi 9h najprije aplicira tzv "typematic delay", tj. ceka (npr 0.5-1s) ignorirajuci cinjenicu da je trenutni gumb jos uvijek stisnut prije nego pocne (da bi mogao normalno pisati, iskljucivanje typematic delaya rezultira desetinama znakova ispisanih na ekranu pri svakom pritisku gumba) puniti keyboard buffer sa njime. To je, bar za igre, lose. Jer ti zelis da kada netko legne npr. na pucanje da nema nikakvog delaya.
S druge strane keyboard buffer stvara dodatne probleme. To je tampon zona izmedju tastature i ostatka sustava i tamo se spremaju znakovi prije no sto se procesuiraju. Dobro ako imas zastoje u radu zbog prevelikog opterecenja pa ti se ne gube znakovi "po putu". Lose sto beepa ako se napuni a za igre ti ni ne treba.
Dakle: rijesenje je iz pocetka prepisati keyboard interrupt. Buduci da ti treba stroga kontrola sto pise gdje u kojem CPU registru u trenutku pocetka i zavrsetka rada interrupt procedure, to moras napraviti u assembleru i onda pomocu C-a tu proceduru ubaciti u IVT. Nadalje, treba biti oprezan jer ce ti sustav hangat ako zaboravis aplicirati neke ne-bas-najbolje dokumentirane promjene cpu registrima koje M$ aplikacije i OS ocekuju od jednog kulturnog keyboard interrupta.
Ideja:
napraviti alternativni interrupt handler tako da na nove znakove koji dolaze sa porta ne filtrira kroz typematic delay i ne sprema u buffer, nego u niz od 256 znakova u kojima su vrijednosti 0, tj. 1 ako je tipka stisnuta te samo u tom nizu azurirati podatke o stisnutim tipkama. To moze biti obicni char[256] niz.
U igri tada u svakom ciklusu provjeravas da li je neki botun stisnut i apliciras promjene na svakog igraca shodno tomu.
Da bi natjerao sustav da poziva tvoj interrupt handler umjesto onog uobicajenog moras element 9h niza (IVT-a) promjeniti u adresu tvoje procedura, ali tako da najprije sacuvas adresu starog handlera.
Prije gasenja programa vrati vrijednost tog pointera na staru vrijednost interrupt handlera (tako da pointer u IVT-u kojeg poziva tastatura opet pokazuje na stari keyboard handler).
Ako ti je sve ovo too much, imam to gotovo negdje, al moram potraziti pa postam...
PS mozda ce ti windoze prijaviti access violation ako pokusas pisati direktvno po IVT-u, pa ti je mozda bolje okoristiti se sa dvije soft. interrupt procedure koje tomu sluze. Ne sijecam se dobro ni interrupta ni parametara kojima ju se poziva pa ti preporucam mali search po Ralphovom interrupt primeru...
_________________
Pupoljak nije negiran. Rekao sam to i ponovit cu to jos jedanput. Pupoljak NIJE negirAn.
MADD
(Mothers Against Dirty Dialectics)
Based on a true story. NOT.
Ko ih sljivi, mi sviramo punk
|
|
[Vrh] |
|
grossi Forumaš(ica)
Pridružen/a: 22. 04. 2004. (16:33:41) Postovi: (5D)16
Spol:
Lokacija: Delta Neretva
|
|
[Vrh] |
|
ZELENIZUBNAPLANETIDO SADE Forumaš(ica)
Pridružen/a: 04. 03. 2004. (19:56:15) Postovi: (54F)16
Lokacija: hm?
|
Postano: 11:58 uto, 22. 6. 2004 Naslov: |
|
|
Moram jurit, al probaj potrazit na googleu "keyboard handler 9h +DOS", pa mozda nesto nadjes? (sa ili bez "C header" ili nesto sl. u search stringu?)
Moram jurit, al probaj potrazit na googleu "keyboard handler 9h +DOS", pa mozda nesto nadjes? (sa ili bez "C header" ili nesto sl. u search stringu?)
_________________
Pupoljak nije negiran. Rekao sam to i ponovit cu to jos jedanput. Pupoljak NIJE negirAn.
MADD
(Mothers Against Dirty Dialectics)
Based on a true story. NOT.
Ko ih sljivi, mi sviramo punk
|
|
[Vrh] |
|
grossi Forumaš(ica)
Pridružen/a: 22. 04. 2004. (16:33:41) Postovi: (5D)16
Spol:
Lokacija: Delta Neretva
|
|
[Vrh] |
|
|